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

Generated by: LCOV version 1.14