LCOV - code coverage report
Current view: top level - coupling/services - CouplingCellService.cpph (source / functions) Coverage Total Hit
Test: coverage.info Lines: 22.8 % 193 44
Test Date: 2026-08-21 15:14:06 Functions: 10.0 % 20 2

            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              : #include <stdexcept>
       7              : #include <sys/time.h>
       8              : 
       9              : template <class LinkedCell, unsigned int dim>
      10            4 : coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::CouplingCellServiceImpl(
      11              :     unsigned int ID, coupling::interface::MDSolverInterface<LinkedCell, dim>* mdSolverInterface,
      12              :     coupling::interface::MacroscopicSolverInterface<dim>* macroscopicSolverInterface, tarch::la::Vector<dim, unsigned int> numberProcesses, unsigned int rank,
      13              :     const coupling::configurations::ParticleInsertionConfiguration& particleInsertionConfiguration,
      14              :     const coupling::configurations::MomentumInsertionConfiguration<dim>& momentumInsertionConfiguration,
      15              :     const coupling::configurations::BoundaryForceConfiguration<dim>& boundaryForceConfiguration,
      16              :     const coupling::configurations::TransferStrategyConfiguration<dim>& transferStrategyConfiguration,
      17              :     const coupling::configurations::ParallelTopologyConfiguration& parallelTopologyConfiguration,
      18              :     const coupling::configurations::ThermostatConfiguration& thermostatConfiguration, unsigned int numberMDTimestepsPerCouplingCycle,
      19              :     const coupling::configurations::CouplingCellConfiguration<dim>& couplingCellConfiguration, const char* filterPipelineConfiguration,
      20              :     const tarch::utils::MultiMDService<dim>& multiMDService, unsigned int topologyOffset, int tws)
      21            4 :     : coupling::services::CouplingCellService<dim>(ID, topologyOffset), _numberMDTimestepsPerCouplingCycle(numberMDTimestepsPerCouplingCycle),
      22              :       // initialise interface pointers before coupling cells are initialised
      23            4 :       _mdSolverInterface(mdSolverInterface), _macroscopicSolverInterface(macroscopicSolverInterface),
      24            4 :       _deFromMacro2MD(_macroscopicSolverInterface, topologyOffset, ID), _deFromAllMacro2MD(_macroscopicSolverInterface, topologyOffset, ID),
      25            4 :       _enableInnerImposition(false), _deFromMD2Macro(_macroscopicSolverInterface, topologyOffset, ID),
      26            8 :       _couplingCells(couplingCellConfiguration.getNumberLinkedCellsPerCouplingCell(), mdSolverInterface), _filterPipeline(nullptr),
      27            4 :       _filterPipelineConfiguration(filterPipelineConfiguration), _multiMDService(multiMDService),
      28            4 :       _momentumInsertion(momentumInsertionConfiguration.interpreteConfiguration(mdSolverInterface, _couplingCells.getLinkedCellContainer(),
      29              :                                                                                 numberMDTimestepsPerCouplingCycle)),
      30            4 :       _momentumInsertionType(momentumInsertionConfiguration.getMomentumInsertionType()),
      31            4 :       _particleInsertion(particleInsertionConfiguration.interpreteConfiguration<LinkedCell, dim>(mdSolverInterface)),
      32            4 :       _numberLinkedCellsPerCouplingCell(couplingCellConfiguration.getNumberLinkedCellsPerCouplingCell()),
      33            4 :       _particleInsertionType(particleInsertionConfiguration.getParticleInsertionType()),
      34            4 :       _transferStrategy(transferStrategyConfiguration.interpreteConfiguration(mdSolverInterface, numberMDTimestepsPerCouplingCycle)),
      35            4 :       _kineticEnergyController(mdSolverInterface), _boundaryForceController(boundaryForceConfiguration.interpreteConfiguration(mdSolverInterface)),
      36            4 :       _momentumController(mdSolverInterface), _applyAccordingToConfiguration(initCorrectApplicationOfThermostat(thermostatConfiguration)),
      37            4 :       _microscopicFilename(couplingCellConfiguration.getMicroscopicFilename()),
      38            4 :       _writeEveryMicroscopicTimestep(couplingCellConfiguration.getWriteEveryMicroscopicTimestep()),
      39            4 :       _macroscopicFilename(couplingCellConfiguration.getMacroscopicFilename()),
      40          136 :       _writeEveryMacroscopicTimestep(couplingCellConfiguration.getWriteEveryMacroscopicTimestep()) {
      41              :   // check for NULL pointers
      42            4 :   if (_particleInsertion == NULL) {
      43            0 :     std::cout << "ERROR "
      44              :                  "coupling::services::CouplingCellServiceImpl::"
      45              :                  "CouplingCellServiceImpl(): _particleInsertion==NULL!"
      46            0 :               << std::endl;
      47            0 :     exit(EXIT_FAILURE);
      48              :   }
      49            4 :   if (_momentumInsertion == NULL) {
      50            0 :     std::cout << "ERROR "
      51              :                  "coupling::services::CouplingCellServiceImpl::"
      52              :                  "CouplingCellServiceImpl(): _momentumInsertion==NULL!"
      53            0 :               << std::endl;
      54            0 :     exit(EXIT_FAILURE);
      55              :   }
      56            4 :   if (_transferStrategy == NULL) {
      57            0 :     std::cout << "ERROR "
      58              :                  "coupling::services::CouplingCellServiceImpl::"
      59              :                  "CouplingCellServiceImpl(): _transferStrategy==NULL!"
      60            0 :               << std::endl;
      61            0 :     exit(EXIT_FAILURE);
      62              :   }
      63            4 :   if (_boundaryForceController == NULL) {
      64            0 :     std::cout << "ERROR "
      65              :                  "coupling::services::CouplingCellServiceImpl::"
      66              :                  "CouplingCellServiceImpl(): _boundaryForceController==NULL!"
      67            4 :               << std::endl;
      68              :   }
      69              : 
      70              :   // init Usher parameters
      71            4 :   initIndexVectors4Usher();
      72              : 
      73              :   // init vector of inner (MD Domain/non-ghost) cells and their indices
      74              :   // TODO: REMOVE
      75              :   // initInnerCouplingCells(_couplingCells.getCouplingCells());
      76            4 : }
      77              : 
      78            0 : template <class LinkedCell, unsigned int dim> coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::~CouplingCellServiceImpl() {
      79              :   // free memory and delete objects
      80            0 :   if (_particleInsertion != NULL) {
      81            0 :     delete _particleInsertion;
      82            0 :     _particleInsertion = NULL;
      83              :   }
      84            0 :   if (_momentumInsertion != NULL) {
      85            0 :     delete _momentumInsertion;
      86            0 :     _momentumInsertion = NULL;
      87              :   }
      88            0 :   if (_transferStrategy != NULL) {
      89            0 :     delete _transferStrategy;
      90            0 :     _transferStrategy = NULL;
      91              :   }
      92            0 :   if (_boundaryForceController != NULL) {
      93            0 :     delete _boundaryForceController;
      94            0 :     _boundaryForceController = NULL;
      95              :   }
      96            0 :   if (_filterPipeline != nullptr) {
      97            0 :     delete _filterPipeline;
      98              :   }
      99            0 : }
     100              : 
     101            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::sendFromMacro2MDPreProcess() {
     102            0 :   Wrapper4ProcessInnerCouplingCellBeforeReceivingMacroscopicSolverData wrapper1(this);
     103            0 :   Wrapper4ProcessOuterCouplingCellBeforeReceivingMacroscopicSolverData wrapper2(this);
     104              : 
     105              :   // pre-process coupling cells of coupling tool
     106            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(wrapper1);
     107            0 :   _couplingCells.applyToLocalGhostCouplingCellsWithLinkedCells(wrapper2);
     108            0 : }
     109              : 
     110            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::sendFromMacro2MDPostProcess() {
     111            0 :   Wrapper4ProcessInnerCouplingCellAfterReceivingMacroscopicSolverData wrapper3(this);
     112            0 :   Wrapper4ProcessOuterCouplingCellAfterReceivingMacroscopicSolverData wrapper4(this);
     113              : 
     114              :   // post-process inner coupling cells after receiving information from macroscopic solver
     115            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(wrapper3);
     116            0 :   _couplingCells.applyToLocalGhostCouplingCellsWithLinkedCells(wrapper4);
     117            0 : }
     118              : 
     119              : template <class LinkedCell, unsigned int dim>
     120            0 : void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::sendFromMacro2MD(
     121              :     const coupling::datastructures::FlexibleCellContainer<dim>& macro2MDBuffer) {
     122              : 
     123            0 :   Wrapper4ProcessInnerCouplingCellBeforeReceivingMacroscopicSolverData wrapper1(this);
     124            0 :   Wrapper4ProcessOuterCouplingCellBeforeReceivingMacroscopicSolverData wrapper2(this);
     125            0 :   Wrapper4ProcessInnerCouplingCellAfterReceivingMacroscopicSolverData wrapper3(this);
     126            0 :   Wrapper4ProcessOuterCouplingCellAfterReceivingMacroscopicSolverData wrapper4(this);
     127              : 
     128              :   // pre-process coupling cells of coupling tool
     129            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(wrapper1);
     130            0 :   _couplingCells.applyToLocalGhostCouplingCellsWithLinkedCells(wrapper2);
     131              : 
     132              :   // carry out send-receive steps
     133            0 :   if (_enableInnerImposition)
     134            0 :     _fromMacro2MD.sendFromMacro2MD(_deFromAllMacro2MD, _couplingCells, macro2MDBuffer);
     135              :   else
     136            0 :     _fromMacro2MD.sendFromMacro2MD(_deFromMacro2MD, _couplingCells, macro2MDBuffer);
     137              : 
     138              :   // post-process inner coupling cells after receiving information from
     139              :   // macroscopic solver
     140            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(wrapper3);
     141            0 :   _couplingCells.applyToLocalGhostCouplingCellsWithLinkedCells(wrapper4);
     142            0 : }
     143              : 
     144            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::sendFromMD2MacroPreProcess() {
     145              :   // transfer strategy
     146            0 :   Wrapper4ProcessInnerCouplingCellBeforeSendingMDSolverData wrapper1(this);
     147            0 :   Wrapper4ProcessOuterCouplingCellBeforeSendingMDSolverData wrapper2(this);
     148              : 
     149              :   // pre-process data before sending to macroscopic solver
     150            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(wrapper1);
     151            0 :   _couplingCells.applyToLocalGhostCouplingCellsWithLinkedCells(wrapper2);
     152            0 : }
     153              : 
     154            0 : template <class LinkedCell, unsigned int dim> double coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::applyFilterPipeline() {
     155              : #ifdef DEBUG_FILTER_PIPELINE
     156              :   std::cout << "FP: Now applying per-instance filter pipeline for service ID: " << coupling::services::CouplingCellService<dim>::getID() << std::endl;
     157              : #endif
     158            0 :   return (*_filterPipeline)();
     159              : }
     160              : 
     161              : template <class LinkedCell, unsigned int dim>
     162            0 : double coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::sendFromMD2Macro(
     163              :     const coupling::datastructures::FlexibleCellContainer<dim>& couplingCellContainerFromMacroscopicSolver) {
     164            0 :   sendFromMD2MacroPreProcess();
     165              : 
     166            0 :   double runtime = applyFilterPipeline();
     167              : 
     168              :   // carry out send-receive steps
     169            0 :   _fromMD2Macro.sendFromMD2Macro(_deFromMD2Macro, _couplingCells, couplingCellContainerFromMacroscopicSolver);
     170            0 :   return runtime;
     171              : }
     172              : 
     173            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::processInnerCouplingCellAfterMDTimestep() {
     174            0 :   Wrapper4ProcessInnerCouplingCellAfterMDTimestep wrapper(this);
     175            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(wrapper);
     176            0 : }
     177              : 
     178            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::distributeMomentum(unsigned int t) {
     179            0 :   if (_momentumInsertionType == coupling::configurations::MomentumInsertionConfiguration<3>::NO_INSERTION) {
     180            0 :     return;
     181              :   }
     182              : 
     183            0 :   Wrapper4ComputeAndSetCurrentVelocity computeAndSetCurrentVelocity(this);
     184            0 :   Wrapper4DistributeMomentum distributeMomentum(this, t);
     185              : 
     186              :   // compute current velocity in all cells
     187            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(computeAndSetCurrentVelocity);
     188              :   // distribute momentum and synchronize molecules between processes
     189            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(distributeMomentum);
     190            0 :   _mdSolverInterface->synchronizeMoleculesAfterMomentumModification();
     191            0 : }
     192              : 
     193              : template <class LinkedCell, unsigned int dim>
     194            0 : void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::computeAndStoreTemperature(double temperature) {
     195            0 :   Wrapper4ComputeAndStoreTemperature wrapper(this, temperature);
     196            0 :   _applyAccordingToConfiguration(wrapper);
     197            0 : }
     198              : 
     199            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::perturbateVelocity() {
     200            0 :   Wrapper4PerturbateVelocity wrapper(this);
     201            0 :   _couplingCells.applyToLocalNonGhostCouplingCellsWithLinkedCells(wrapper);
     202            0 : }
     203              : 
     204            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::applyTemperatureToMolecules(unsigned int t) {
     205            0 :   Wrapper4ApplyTemperature wrapper(this);
     206            0 :   _applyAccordingToConfiguration(wrapper);
     207            0 : }
     208              : 
     209            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::applyBoundaryForce(unsigned int t) {
     210            0 :   Wrapper4ApplyBoundaryForce wrapper(this);
     211            0 :   _couplingCells.applyToFirstLayerOfGlobalNonGhostCellsWithLinkedCells(wrapper);
     212            0 : }
     213              : 
     214            4 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::initIndexVectors4Usher() {
     215              : 
     216            4 :   const tarch::la::Vector<dim, unsigned int> firstNonGhostCouplingCell(1);
     217              : 
     218            4 :   const tarch::la::Vector<3, unsigned int> start(0);
     219            4 :   const tarch::la::Vector<3, unsigned int> end = coupling::initRange<dim>(tarch::la::Vector<dim, unsigned int>(2));
     220            4 :   tarch::la::Vector<3, unsigned int> loop(0);
     221            4 :   unsigned int loopCounter = 0;
     222              : 
     223           12 :   for (loop[2] = start[2]; loop[2] < end[2]; loop[2]++) {
     224           24 :     for (loop[1] = start[1]; loop[1] < end[1]; loop[1]++) {
     225           48 :       for (loop[0] = start[0]; loop[0] < end[0]; loop[0]++) {
     226          128 :         for (unsigned int d = 0; d < dim; d++) {
     227           96 :           _usherCellOffset[loopCounter][d] = loop[d];
     228           96 :           _usherCellStart[loopCounter][d] = firstNonGhostCouplingCell[d] + loop[d] * (I10::numberCellsInDomain[d] / 2);
     229           96 :           _usherCellEnd[loopCounter][d] =
     230           96 :               firstNonGhostCouplingCell[d] + (1 - loop[d]) * (I10::numberCellsInDomain[d] / 2) + loop[d] * I10::numberCellsInDomain[d];
     231           96 :           _usherRange[loopCounter][d] = _usherCellEnd[loopCounter][d] - _usherCellStart[loopCounter][d];
     232              :         }
     233           32 :         for (unsigned int d = dim; d < 3; d++) {
     234              :           _usherCellOffset[loopCounter][d] = 0;
     235              :           _usherCellStart[loopCounter][d] = 0;
     236              :           _usherCellEnd[loopCounter][d] = 1;
     237              :         }
     238              : 
     239           32 :         loopCounter++;
     240              :       }
     241              :     }
     242              :   } // loop over all staggered versions (-> (0,0,0), (0,0,1), (0,1,0),....,
     243              :     // (1,1,1) )
     244            4 : }
     245              : 
     246              : template <class LinkedCell, unsigned int dim>
     247            0 : tarch::la::Vector<dim, double> coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::getPositionOfFirstLocalGhostCell() const {
     248            0 :   tarch::la::Vector<dim, double> position = I03{{0, 0, 0}}.getCellMidPoint() - 0.5 * IDXS.getCouplingCellSize();
     249            0 :   return position;
     250              : }
     251              : 
     252            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::distributeMass(unsigned int t) {
     253              :   // nop if there is no particle insertion
     254            0 :   if (_particleInsertionType == coupling::configurations::ParticleInsertionConfiguration::NO_INSERTION) {
     255            0 :     return;
     256              :   }
     257              :   // only insert mass every X time steps
     258            0 :   if (!_particleInsertion->insertDeleteMassAtTimestep(t)) {
     259              :     return;
     260              :   }
     261              : 
     262              :   // compute mean potential energy over all coupling cells and set the value
     263              :   // in the coupling cell
     264            0 :   coupling::cellmappings::ComputeMeanPotentialEnergyMapping<LinkedCell, dim> computeMeanPotentialEnergyMapping(_mdSolverInterface, *_boundaryForceController);
     265              :   // coupling cell access
     266            0 :   coupling::datastructures::CouplingCellWithLinkedCells<LinkedCell, dim>* const couplingCells = _couplingCells.getLinkedCellContainer();
     267              :   // start coordinate of first (ghost) cell
     268            0 :   const tarch::la::Vector<dim, double> startPosition = getPositionOfFirstLocalGhostCell();
     269              :   // buffers for temperature,momentum,mean velocity,pot. energy
     270            0 :   double temperature(0.0);
     271            0 :   tarch::la::Vector<dim, double> momentum(0.0);
     272            0 :   tarch::la::Vector<dim, double> meanVelocity(0.0);
     273            0 :   double potentialEnergy = 0.0;
     274              :   // buffer for insertion/deletion action that has been carried out
     275              :   typename coupling::ParticleInsertion<LinkedCell, dim>::Action particleInsertionAction;
     276              :   // true, if the costly operation of contructing the energy landscape is really
     277              :   // required
     278              :   bool constructEnergyLandscape;
     279              : 
     280              :   // variables for internal looping --------------------------
     281              :   // cellIndex used as loop counter
     282            0 :   tarch::la::Vector<3, unsigned int> cellIndex(0);
     283              :   // loop over coupling cell domain (within MD domain) in a 2^dim-colour
     284              :   // manner: For parallel simulations with an odd number of processes and
     285              :   // periodic boundary conditions, a simple staggered loop over all coupling
     286              :   // cells would imply that we insert particles on both sides of the global MD
     287              :   // boundary in the same traversal. This can lead to strong forces and
     288              :   // potential fields between inserted particles! So, we introduce another loop
     289              :   // which subdivides each local domain into 2^D blocks and traverse each block
     290              :   // in one loop traversal first.
     291            0 :   for (unsigned int j = 0; j < (1 << dim); j++) {
     292              :     // we have to at least carry out the construction of the energy landscape
     293              :     // once for each sub-domain (since we do not know a priori if we need to
     294              :     // insert particles or not)
     295            0 :     constructEnergyLandscape = true;
     296              :     // reduce size of usherCellStart-vector to be consistent with
     297              :     // MDSolverInterface
     298            0 :     const tarch::la::Vector<dim, unsigned int> usherCellStart = coupling::initDimVector<dim>(_usherCellStart[j]);
     299              : 
     300              :     // loop over the block again in a 2^dim-colour manner: For each particle
     301              :     // insertion within a coupling cell, the potential energy landscape needs
     302              :     // to be reconstructed in the surrounding of the respective cell. This
     303              :     // implies: - reset energy for molecules in this cell and the neighbours
     304              :     //               - compute energy for all molecules of this cell and the
     305              :     //               neighbours (= consider 5^dim cells!)
     306              :     // So, it becomes apparent that re-computing the potential energy becomes
     307              :     // quite expensive. Therefore, we loop over each block in a red-black
     308              :     // manner. Doing so, each loop iteration over one "colour" of cells can be
     309              :     // done without any re-computation of the potential energy as the molecules
     310              :     // under consideration are independent from each other.
     311            0 :     for (unsigned int i = 0; i < (1 << dim); i++) {
     312              :       // setup potential energy landscape (i.e. computes the potential energy
     313              :       // for all relevant molecules; here, we need to sweep over all molecules
     314              :       // contained in the coupling cells of interest and compute their
     315              :       // current potential energy). Only carry out this costly operation, if
     316              :       // there have been modifications to the MD system OR this is the first
     317              :       // consideration of this sub-domain. Besides, we skip this operation if
     318              :       // the particle insertion does not require it (e.g. in case of rarefied
     319              :       // gases, we possibly can come up with something better than USHER)
     320            0 :       if (constructEnergyLandscape && _particleInsertion->requiresPotentialEnergyLandscape()) {
     321            0 :         _mdSolverInterface->setupPotentialEnergyLandscape(usherCellStart, _usherRange[j], _numberLinkedCellsPerCouplingCell);
     322              :         // reset flag
     323              :         constructEnergyLandscape = false;
     324              :       }
     325              : 
     326              :       // loop over all respective coupling cells (incrementing by 2 for
     327              :       // 2^dim-colour-traversal)
     328            0 :       for (cellIndex[2] = _usherCellStart[j][2] + _usherCellOffset[i][2]; cellIndex[2] < _usherCellEnd[j][2]; cellIndex[2] = cellIndex[2] + 2) {
     329            0 :         for (cellIndex[1] = _usherCellStart[j][1] + _usherCellOffset[i][1]; cellIndex[1] < _usherCellEnd[j][1]; cellIndex[1] = cellIndex[1] + 2) {
     330            0 :           for (cellIndex[0] = _usherCellStart[j][0] + _usherCellOffset[i][0]; cellIndex[0] < _usherCellEnd[j][0]; cellIndex[0] = cellIndex[0] + 2) {
     331              :             // determine coupling cell index
     332              :             // coupling::indexing::CellIndex<3, vector, coupling::indexing::IndexTrait::local>
     333            0 :             I03 localCellIndex{(tarch::la::Vector<dim, int>)cellIndex};
     334            0 :             const unsigned int index = I02{localCellIndex}.get();
     335              : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
     336              :             std::cout << "coupling::services::CouplingCellServiceImpl::"
     337              :                          "distributeMass(): Insert mass in cell "
     338              :                       << index << std::endl;
     339              : #endif
     340              :             // compute cell position
     341            0 :             tarch::la::Vector<dim, double> couplingCellPosition = startPosition;
     342            0 :             auto dx = coupling::indexing::IndexingService<3>::getInstance().getCouplingCellSize();
     343            0 :             for (unsigned int d = 0; d < dim; d++) {
     344            0 :               couplingCellPosition[d] += dx[d] * cellIndex[d];
     345              :             }
     346              : 
     347              :             // compute current momentum and energy
     348            0 :             _momentumController.computeMomentumAndMeanVelocity(couplingCells[index], momentum, meanVelocity);
     349            0 :             temperature = couplingCells[index].getTemperature();
     350              :             // compute potential energy for this coupling cell and store it
     351            0 :             couplingCells[index].iterateConstCells(computeMeanPotentialEnergyMapping);
     352            0 :             potentialEnergy = computeMeanPotentialEnergyMapping.getPotentialEnergy();
     353            0 :             couplingCells[index].setPotentialEnergy(potentialEnergy);
     354              : 
     355              :             // insert/ delete mass
     356              :             particleInsertionAction =
     357            0 :                 _particleInsertion->insertDeleteMass(couplingCells[index], couplingCellPosition, dx, meanVelocity, temperature, *_boundaryForceController);
     358              :             // if insertion/ deletion was successful...
     359            0 :             if (particleInsertionAction != coupling::ParticleInsertion<LinkedCell, dim>::NoAction) {
     360              :               // ... determine new potential energy of the system (assumption:
     361              :               // symmetric potential energy)
     362            0 :               couplingCells[index].iterateConstCells(computeMeanPotentialEnergyMapping);
     363              : 
     364              :               // ... reset momentum and temperature
     365            0 :               _momentumController.setMomentum(couplingCells[index], momentum);
     366            0 :               _kineticEnergyController.setTemperature(couplingCells[index], temperature);
     367              :               // ... set flag to construct energy landscape for next insertion
     368              :               // try
     369              :               constructEnergyLandscape = true;
     370              :             }
     371              : 
     372              :           } // cellIndex(0)
     373              :         } // cellIndex(1)
     374              :       } // cellIndex(2)
     375              :     } // 2^dim-colour single cells (1<<dim)
     376              : 
     377              :     // synchronize molecules between processes
     378            0 :     _mdSolverInterface->synchronizeMoleculesAfterMassModification();
     379              : 
     380              :   } // 2^dim-colour whole domain (1<<dim)
     381              : 
     382              : #ifdef USHER_DEBUG
     383              :   coupling::UsherParticleInsertion<LinkedCell, dim>* p = ((coupling::UsherParticleInsertion<LinkedCell, dim>*)_particleInsertion);
     384              :   std::cout << "_particlesInserted = " << p->_particlesInserted << std::endl;
     385              :   std::cout << "_energyInserted     = " << p->_energyInserted << std::endl;
     386              :   std::cout << "_ZhouEnergyInserted = " << p->_ZhouEnergyInserted << std::endl;
     387              :   std::cout << "and" << std::endl;
     388              :   std::cout << "_particlesRemoved  = " << p->_particlesRemoved << std::endl;
     389              :   std::cout << "_energyRemoved      = " << p->_energyRemoved << std::endl;
     390              :   std::cout << "_ZhouEnergyRemoved  = " << p->_ZhouEnergyRemoved << std::endl;
     391              :   std::cout << "Energy inserted per Operation: "
     392              :             << ((p->_energyInserted + p->_ZhouEnergyInserted) - (p->_energyRemoved + p->_ZhouEnergyRemoved)) / (p->_particlesInserted + p->_particlesRemoved)
     393              :             << std::endl;
     394              :   std::cout << std::endl;
     395              : #endif
     396            0 : }
     397              : 
     398            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::plotEveryMicroscopicTimestep(unsigned int t) {
     399              :   // trigger plotting
     400            0 :   if ((_writeEveryMicroscopicTimestep != 0) && (t % _writeEveryMicroscopicTimestep == 0)) {
     401            0 :     coupling::CouplingCellPlotter<LinkedCell, dim> plotter(coupling::services::CouplingCellService<dim>::getID(), _microscopicFilename, IDXS.getRank(), t,
     402            0 :                                                            _couplingCells, _mdSolverInterface);
     403              :   }
     404            0 : }
     405              : 
     406            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::plotEveryMacroscopicTimestep(unsigned int t) {
     407              :   // trigger plotting
     408            0 :   if ((_writeEveryMacroscopicTimestep != 0) && (t % _writeEveryMacroscopicTimestep == 0)) {
     409            0 :     coupling::CouplingCellPlotter<LinkedCell, dim> plotter(coupling::services::CouplingCellService<dim>::getID(), _macroscopicFilename, IDXS.getRank(), t,
     410            0 :                                                            _couplingCells, _mdSolverInterface);
     411              :   }
     412            0 : }
     413              : 
     414            0 : template <class LinkedCell, unsigned int dim> void coupling::services::CouplingCellServiceImpl<LinkedCell, dim>::setInnerMomentumImposition(bool enable) {
     415            0 :   _enableInnerImposition = enable;
     416            0 :   _momentumInsertion->setInnerImposition(enable);
     417            0 : }
        

Generated by: LCOV version 2.0-1