LCOV - code coverage report
Current view: top level - coupling/transferstrategies - TransferStrategy4NieCoupling.cpph (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 91 0.0 %
Date: 2025-06-25 11:26:37 Functions: 0 10 0.0 %

          Line data    Source code
       1             : // Copyright (C) 2015 Technische Universitaet Muenchen
       2             : // This file is part of the Mamico project. For conditions of distribution
       3             : // and use, please see the copyright notice in Mamico's main folder, or at
       4             : // www5.in.tum.de/mamico
       5             : 
       6             : template <class LinkedCell, unsigned int dim>
       7           0 : coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::TransferStrategy4NieCoupling(
       8             :     coupling::interface::MDSolverInterface<LinkedCell, dim>* const mdSolverInterface, unsigned int numberMDSteps, double shiftTimestep,
       9             :     tarch::la::Vector<2 * dim, bool> massFluxBoundary)
      10           0 :     : coupling::transferstrategies::TransferStrategy<LinkedCell, dim>(mdSolverInterface), _massMapping(mdSolverInterface), _momentumMapping(mdSolverInterface),
      11           0 :       _oldSolution(NULL), _newSolution(NULL), _numberMDSteps(numberMDSteps), _shiftTimestep(shiftTimestep), _numberLocalCells(I02::linearNumberCellsInDomain),
      12           0 :       _excessMass(NULL), _massFluxBoundary(massFluxBoundary) {
      13             :   // allocate arrays for old and new solution (required for linear time
      14             :   // interpolation) and init. them with zero vectors
      15           0 :   _oldSolution = new tarch::la::Vector<dim, double>[_numberLocalCells];
      16           0 :   _newSolution = new tarch::la::Vector<dim, double>[_numberLocalCells];
      17           0 :   _excessMass = new double[_numberLocalCells];
      18           0 :   if ((_oldSolution == NULL) || (_newSolution == NULL) || (_excessMass == NULL)) {
      19           0 :     std::cout << "ERROR "
      20             :                  "coupling::transferstrategies::TransferStrategy4NieCoupling::"
      21             :                  "TransferStrategy4NieCoupling(...): _ptr==NULL!"
      22           0 :               << std::endl;
      23           0 :     exit(EXIT_FAILURE);
      24             :   }
      25           0 :   for (unsigned int i = 0; i < _numberLocalCells; i++) {
      26           0 :     _oldSolution[i] = tarch::la::Vector<dim, double>(0.0);
      27           0 :     _newSolution[i] = tarch::la::Vector<dim, double>(0.0);
      28           0 :     _excessMass[i] = 0.0;
      29             :   }
      30           0 : }
      31             : 
      32           0 : template <class LinkedCell, unsigned int dim> coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::~TransferStrategy4NieCoupling() {
      33             :   // delete arrays
      34           0 :   if (_oldSolution != NULL) {
      35           0 :     delete[] _oldSolution;
      36           0 :     _oldSolution = NULL;
      37             :   }
      38           0 :   if (_newSolution != NULL) {
      39           0 :     delete[] _newSolution;
      40           0 :     _newSolution = NULL;
      41             :   }
      42           0 :   if (_excessMass != NULL) {
      43           0 :     delete[] _excessMass;
      44           0 :     _excessMass = NULL;
      45             :   }
      46           0 : }
      47             : 
      48             : template <class LinkedCell, unsigned int dim>
      49           0 : void coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::beginProcessInnerCouplingCellsBeforeReceivingMacroscopicSolverData() {
      50             :   // reset time counter (always counts from 0 to _numberMDSteps)
      51           0 :   _timestepCounter = 0;
      52             :   //_totalMass=0;
      53             :   //_cellCount=0;
      54             :   // copy new solution to old solution
      55           0 :   for (unsigned int i = 0; i < _numberLocalCells; i++) {
      56           0 :     _oldSolution[i] = _newSolution[i];
      57             :   }
      58           0 : }
      59             : 
      60             : template <class LinkedCell, unsigned int dim>
      61           0 : void coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::processInnerCouplingCellBeforeReceivingMacroscopicSolverData(
      62             :     coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>& cell, I02 index) {
      63             :   // backup old mass that could not be inserted into cells
      64           0 :   _excessMass[index.get()] = cell.getMicroscopicMass();
      65             : 
      66             :   // TODO: remove temporary debug output
      67             :   // if(_excessMass[index.get()] > 0) std::cout << "TransferStrategy4NieCoupling:
      68             :   // _excessMass[" << index << "]: " << _excessMass[index.get()] << std::endl;
      69             :   // TODO: make threshold customizable
      70             :   // const unsigned int threshold = 3;
      71             :   /*if(_excessMass[index.get()] > threshold) {
      72             :         std::cout << "TransferStrategy4NieCoupling: ERROR: Excess mass above
      73             :   threshold (= " << threshold << "): _excessMass[" << index << "] = " <<
      74             :   _excessMass[index.get()] << std::endl; exit(EXIT_FAILURE);
      75             :   }*/
      76             : 
      77             :   // reset cell-mass (would be overwritten anyway; but just to be on safe side)
      78           0 :   cell.setMicroscopicMass(0.0);
      79           0 : }
      80             : 
      81             : template <class LinkedCell, unsigned int dim>
      82           0 : void coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::processInnerCouplingCellAfterReceivingMacroscopicSolverData(
      83             :     coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>& cell, I02 index) {
      84             : 
      85             :   // convert momentum to velocity values for cont->MD transfer
      86           0 :   if (cell.getMicroscopicMass() == 0.0) {
      87           0 :     cell.setMicroscopicMomentum(tarch::la::Vector<dim, double>(0.0));
      88             :   } else {
      89           0 :     cell.setMicroscopicMomentum((1.0 / cell.getMicroscopicMass()) * cell.getMicroscopicMomentum());
      90             :   }
      91             : 
      92             :   // write velocity value to new solution array and interpolate first solution
      93             :   // (= value of old solution)
      94           0 :   _newSolution[index.get()] = cell.getMicroscopicMomentum();
      95           0 :   cell.setMicroscopicMomentum((1.0 - _shiftTimestep) * _oldSolution[index.get()] + _shiftTimestep * _newSolution[index.get()]);
      96             : 
      97           0 :   const tarch::la::Vector<dim, double> velocity = (0.5 - _shiftTimestep) * _oldSolution[index.get()] + (_shiftTimestep + 0.5) * _newSolution[index.get()];
      98             : 
      99             :   // for mass transfer: compute mass flux if required and add excess mass
     100           0 :   const double massFlux = computeMassFlux(cell.getMicroscopicMass(), velocity, index) + _excessMass[index.get()];
     101           0 :   cell.setMicroscopicMass(massFlux);
     102             : 
     103             :   // reset macroscopic solver values (from averaging)
     104           0 :   cell.setMacroscopicMass(0.0);
     105           0 :   cell.setMacroscopicMomentum(tarch::la::Vector<dim, double>(0.0));
     106           0 : }
     107             : 
     108             : // template<class LinkedCell,unsigned int dim>
     109             : // void
     110             : // coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell,dim>::
     111             : // beginProcessInnerCouplingCellsBeforeSendingMDSolverData(){
     112             : // }
     113             : 
     114             : template <class LinkedCell, unsigned int dim>
     115           0 : void coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::processInnerCouplingCellBeforeSendingMDSolverData(
     116             :     coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>& cell, I02 index) {
     117             : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
     118             :   std::cout << "processInnerCouplingCellBeforeSendingMDSolverData(): Data "
     119             :                "before averaging from cell "
     120             :             << index << "Mass: " << cell.getMacroscopicMass() << " , momentum: " << cell.getMacroscopicMomentum() << std::endl;
     121             : #endif
     122             : 
     123             :   // average sampled data from MD
     124           0 :   if (_timestepCounter != 0) {
     125           0 :     const double mass = cell.getMacroscopicMass() / ((double)_timestepCounter);
     126           0 :     const tarch::la::Vector<dim, double> momentum = (1.0 / ((double)_timestepCounter)) * cell.getMacroscopicMomentum();
     127           0 :     cell.setMacroscopicMass(mass);
     128           0 :     cell.setMacroscopicMomentum(momentum);
     129             :   } else {
     130           0 :     cell.setMacroscopicMass(0.0);
     131           0 :     cell.setMacroscopicMomentum(tarch::la::Vector<dim, double>(0.0));
     132             :   }
     133             : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
     134             :   std::cout << "Time step counter=" << _timestepCounter << std::endl;
     135             :   std::cout << "processInnerCouplingCellBeforeSendingMDSolverData(): Data "
     136             :                "from cell "
     137             :             << index << "Mass: " << cell.getMacroscopicMass() << " , momentum: " << cell.getMacroscopicMomentum() << std::endl;
     138             : #endif
     139             : 
     140             :   // cell.iterateConstCells(_massMapping);
     141             :   // _totalMass += _massMapping.getMass();
     142             :   // _totalMass +=  cell.getMicroscopicMass();
     143           0 : }
     144             : 
     145             : // template<class LinkedCell,unsigned int dim>
     146             : // void
     147             : // coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell,dim>::
     148             : // endProcessInnerCouplingCellsBeforeSendingMDSolverData(){
     149             : // std::cout << "Avg massFluxBoundary MD density: " <<
     150             : // _totalMass/(_cellCount*15.625) << std::endl;
     151             : //}
     152             : 
     153             : template <class LinkedCell, unsigned int dim>
     154           0 : void coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::beginProcessInnerCouplingCellsAfterMDTimestep() {
     155             :   // increment time step counter
     156           0 :   _timestepCounter++;
     157           0 : }
     158             : 
     159             : template <class LinkedCell, unsigned int dim>
     160           0 : void coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::processInnerCouplingCellAfterMDTimestep(
     161             :     coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>& cell, I02 index) {
     162             :   // sampling: add up mass and momentum in macroscopic buffers
     163           0 :   cell.iterateConstCells(_massMapping);
     164           0 :   const double mass = _massMapping.getMass();
     165             :   //_totalMass += mass;
     166             :   //_cellCount++;
     167           0 :   cell.iterateConstCells(_momentumMapping);
     168           0 :   const tarch::la::Vector<dim, double> momentum(_momentumMapping.getMomentum());
     169           0 :   cell.addMacroscopicMass(mass);
     170           0 :   cell.addMacroscopicMomentum(momentum);
     171             : 
     172             :   // interpolation of velocity value from old and new solution
     173             :   // we shift the factor by _shiftTimestep time steps and inter- or extrapolate
     174             :   // velocities. A CFD solver will deliver values at t and t+dt and we want to
     175             :   // advance the simulation potentially differently
     176           0 :   const double factor = _shiftTimestep + ((double)_timestepCounter) / ((double)_numberMDSteps);
     177             : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
     178             :   if (factor < _shiftTimestep || factor > 1.0 + _shiftTimestep) {
     179             :     std::cout << "ERROR "
     180             :                  "coupling::transferstrategies::TransferStrategy4NieCoupling<"
     181             :                  "LinkedCell,dim>::processInnerCouplingCellAfterMDTimestep(."
     182             :                  ".): factor out of range!"
     183             :               << std::endl;
     184             :     exit(EXIT_FAILURE);
     185             :   }
     186             : #endif
     187           0 :   const tarch::la::Vector<dim, double> velocity = (1.0 - factor) * _oldSolution[index.get()] + factor * _newSolution[index.get()];
     188           0 :   cell.setMicroscopicMomentum(velocity);
     189           0 : }
     190             : 
     191             : template <class LinkedCell, unsigned int dim>
     192           0 : double coupling::transferstrategies::TransferStrategy4NieCoupling<LinkedCell, dim>::computeMassFlux(const double& mass,
     193             :                                                                                                     const tarch::la::Vector<dim, double>& velocity,
     194             :                                                                                                     const I01 index) {
     195             :   // meshsize and volume of cell
     196           0 :   const tarch::la::Vector<dim, double> meshsize(IDXS.getCouplingCellSize());
     197             :   double volume = 1.0;
     198           0 :   for (unsigned int d = 0; d < dim; d++) {
     199           0 :     volume = volume * meshsize[d];
     200             :   }
     201             : 
     202             :   // mass density of cell
     203           0 :   const double density = mass / volume;
     204             :   // coupling time interval
     205           0 :   const double couplingTimeInterval = coupling::transferstrategies::TransferStrategy<LinkedCell, dim>::_mdSolverInterface->getDt() * _numberMDSteps;
     206             : 
     207           0 :   double massFlux = 0.0;
     208             : 
     209             :   // compute normal vector for this cell, checking whether there is mass flux or
     210             :   // not
     211           0 :   tarch::la::Vector<dim, int> n(0);
     212           0 :   for (unsigned int d = 0; d < dim; d++) {
     213             :     // compute normal vector (pointing inwards MD domain)
     214           0 :     if ((index.get()[d] == 1) && _massFluxBoundary[2 * d]) {
     215           0 :       n[d] = 1; /*_totalMass+=mass;_cellCount++;*/
     216           0 :     } else if ((index.get()[d] == (int)I09::numberCellsInDomain[d]) && _massFluxBoundary[2 * d + 1]) {
     217           0 :       n[d] = -1; /*_totalMass+=mass;_cellCount++;*/
     218             :     }
     219             :   }
     220             : 
     221             :   // compute mass flux for each boundary
     222           0 :   for (unsigned int d = 0; d < dim; d++) {
     223             :     double surface = 1.0;
     224           0 :     for (unsigned int e = 0; e < d; e++) {
     225           0 :       surface = surface * meshsize[e];
     226             :     }
     227           0 :     for (unsigned int e = d + 1; e < dim; e++) {
     228           0 :       surface = surface * meshsize[e];
     229             :     }
     230             : 
     231           0 :     massFlux += n[d] * surface * density * velocity[d] * couplingTimeInterval;
     232             :   }
     233           0 :   return massFlux;
     234             : }

Generated by: LCOV version 1.14