LCOV - code coverage report
Current view: top level - coupling/services - CouplingCellService.cpph (source / functions) Hit Total Coverage
Test: coverage.info Lines: 46 195 23.6 %
Date: 2025-10-27 21:19:12 Functions: 2 21 9.5 %

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

Generated by: LCOV version 1.14