LCOV - code coverage report
Current view: top level - coupling/interface/impl/SimpleMD - SimpleMDSimulation.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 45.3 % 64 29
Test Date: 2026-08-21 15:14:06 Functions: 78.6 % 14 11

            Line data    Source code
       1              : #pragma once
       2              : #include "coupling/interface/MDSimulation.h"
       3              : #include "coupling/interface/MamicoInterfaceProvider.h"
       4              : #include "simplemd/MolecularDynamicsSimulation.h"
       5              : #include "simplemd/molecule-mappings/ConvertForcesFloatToFixedMapping.h"
       6              : #include "simplemd/molecule-mappings/ConvertForcesFixedToFloatMapping.h"
       7              : #include "simplemd/molecule-mappings/WriteCheckPointMapping.h"
       8              : 
       9              : namespace coupling {
      10              : namespace interface {
      11              : /** defines a MDsimulation based on simplemd::MolecularDynamicsSimulation but for coupled MD simulations.
      12              :  * Thus, the implementation of one timestep slightly differs from the one of the base class.
      13              :  *      @brief defines MD simulation from default simple MD code.
      14              :  *  @author Philipp Neumann
      15              :  */
      16              : class SimpleMDSimulation : public coupling::interface::MDSimulation, public simplemd::MolecularDynamicsSimulation {
      17              : public:
      18           12 :   SimpleMDSimulation(const simplemd::configurations::MolecularDynamicsConfiguration& configuration)
      19           12 :       : coupling::interface::MDSimulation(), simplemd::MolecularDynamicsSimulation(configuration), _couplingCellService(NULL), _couplingSwitchedOn(true) {}
      20              : 
      21           12 :   virtual ~SimpleMDSimulation() {}
      22              : 
      23           16 :   virtual void switchOffCoupling() { _couplingSwitchedOn = false; }
      24              : 
      25            8 :   virtual void switchOnCoupling() { _couplingSwitchedOn = true; }
      26              : 
      27           24 :   virtual void simulateTimesteps(const unsigned int& numberTimesteps, const unsigned int& firstTimestep) {
      28          144 :     for (unsigned int t = firstTimestep; t < firstTimestep + numberTimesteps; t++) {
      29          120 :       simulateOneCouplingTimestep(t);
      30              :     }
      31           24 :   }
      32              : 
      33          120 :   void simulateOneCouplingTimestep(const unsigned int& t) {
      34              :     // if coupling is switched off, perform "normal" MD timestep
      35          120 :     if (!_couplingSwitchedOn) {
      36          120 :       simulateOneTimestep(t);
      37          120 :       return;
      38              :     }
      39            0 :     if (_parallelTopologyService->isIdle()) {
      40              :       return;
      41              :     }
      42              : 
      43            0 :     _boundaryTreatment->putBoundaryParticlesToInnerCellsAndFillBoundaryCells(_localBoundary, *_parallelTopologyService);
      44              : 
      45              :     // call to synchronise data in cells; needs to be at this point of the
      46              :     // coupling algorithm as the particles need to be placed inside the correct
      47              :     // sampling volumes (hence: after communication with neighbours and molecule
      48              :     // updates); do it BEFORE quantities are manipulated as we can then also do
      49              :     // some pre-processing here.
      50            0 :     _couplingCellService->processInnerCouplingCellAfterMDTimestep();
      51              :     // ------------ coupling step: distribute mass ---------------------
      52            0 :     _couplingCellService->distributeMass(t);
      53              :     // for isothermal simulations: apply thermostat
      54            0 :     _couplingCellService->applyTemperatureToMolecules(t);
      55              : 
      56              :     // ---------- from here: go on with usual MD algorithm
      57              :     // ------------------------------
      58              : 
      59              :     // compute forces. After this step, each molecule has received all force
      60              :     // contributions from its neighbors.
      61              : #if (TARCH_DEBUG == TARCH_YES)
      62            0 :     _moleculeService->getContainer().iterateMolecules(_convertForcesFloatToFixedMapping);
      63              : #endif
      64            0 :     _moleculeService->getContainer().iterateCellPairs(*_lennardJonesForce);
      65              : #if (TARCH_DEBUG == TARCH_YES)
      66            0 :     _moleculeService->getContainer().iterateMolecules(_convertForcesFixedToFloatMapping);
      67              : #endif
      68              : 
      69              :     // distribute momentum -> some methods require modification of force terms,
      70              :     // therefore we call it AFTER the force computation and before everything else
      71            0 :     _couplingCellService->distributeMomentum(t);
      72              :     // apply boundary forces
      73            0 :     _couplingCellService->applyBoundaryForce(t);
      74              :     // evaluate statistics
      75            0 :     evaluateStatistics(t);
      76              : 
      77            0 :     _boundaryTreatment->emptyGhostBoundaryCells();
      78              : 
      79              :     // plot VTK output
      80            0 :     if ((_configuration.getVTKConfiguration().getWriteEveryTimestep() != 0) && (t % _configuration.getVTKConfiguration().getWriteEveryTimestep() == 0)) {
      81            0 :       _vtkMoleculeWriter->setTimestep(t);
      82            0 :       _moleculeService->getContainer().iterateMolecules(*_vtkMoleculeWriter);
      83              :     }
      84              : 
      85              : // plot ADIOS2 output
      86              : #if BUILD_WITH_ADIOS2
      87              :     if ((_configuration.getAdios2Configuration().getWriteEveryTimestep() != 0) && (t % _configuration.getAdios2Configuration().getWriteEveryTimestep() == 0)) {
      88              :       _Adios2Writer->setTimestep(t);
      89              :       _moleculeService->getContainer().iterateMolecules(*_Adios2Writer);
      90              :     }
      91              : #endif
      92              : 
      93              :     // write checkpoint
      94            0 :     if ((_configuration.getCheckpointConfiguration().getWriteEveryTimestep() != 0) &&
      95            0 :         (t % _configuration.getCheckpointConfiguration().getWriteEveryTimestep() == 0)) {
      96            0 :       simplemd::moleculemappings::WriteCheckPointMapping writeCheckPointMapping(*_parallelTopologyService,
      97            0 :                                                                                 _configuration.getCheckpointConfiguration().getFilename(), t);
      98            0 :       _moleculeService->getContainer().iterateMolecules(writeCheckPointMapping);
      99            0 :     }
     100              :     // plot also coupling cell information
     101            0 :     _couplingCellService->plotEveryMicroscopicTimestep(t);
     102              : 
     103              :     // time integration. After this step, the velocities and the positions of the
     104              :     // molecules have been updated.
     105            0 :     _moleculeService->getContainer().iterateMolecules(*_timeIntegrator);
     106              : 
     107              :     // sort molecules into linked cells
     108            0 :     _moleculeService->getContainer().sort();
     109              :   }
     110              : 
     111            0 :   virtual void sortMoleculesIntoCells() {
     112              :     // nop required, since the linked cells are very tightly linked to mamico
     113            0 :   }
     114              : 
     115            0 :   virtual void setCouplingCellService(coupling::services::CouplingCellService<MDSIMULATIONFACTORY_DIMENSION>* couplingCellService) {
     116            0 :     _couplingCellService = couplingCellService;
     117              :     // set the cell service also in singleton of mamico interface provider ->
     118              :     // typically not required in coupling, but makes the simulation state more
     119              :     // consistent compared to using LAMMPS
     120            0 :     coupling::interface::MamicoInterfaceProvider<simplemd::LinkedCell, MDSIMULATIONFACTORY_DIMENSION>::getInstance().setCouplingCellService(
     121              :         couplingCellService);
     122            0 :   }
     123              : 
     124            0 :   virtual void init() { initServices(); }
     125              : 
     126           12 :   virtual void init(const tarch::utils::MultiMDService<MDSIMULATIONFACTORY_DIMENSION>& multiMDService, unsigned int localMDSimulation) {
     127           12 :     initServices(multiMDService, localMDSimulation);
     128           12 :   }
     129              : 
     130           12 :   virtual void shutdown() { shutdownServices(); }
     131              : 
     132            4 :   virtual void writeCheckpoint(const std::string& filestem, const unsigned int& t) {
     133            4 :     simplemd::moleculemappings::WriteCheckPointMapping writeCheckPointMapping(getParallelTopologyService(), filestem, t);
     134            4 :     _moleculeService->getContainer().iterateMolecules(writeCheckPointMapping);
     135            4 :   }
     136              : 
     137              :   // function particularly needed to init MD solver interface -> should only be
     138              :   // called from factory
     139           12 :   simplemd::BoundaryTreatment& getBoundaryTreatment() { return *_boundaryTreatment; }
     140           16 :   simplemd::services::ParallelTopologyService& getParallelTopologyService() { return *_parallelTopologyService; }
     141           12 :   simplemd::services::MoleculeService& getMoleculeService() {
     142              : #if (COUPLING_MD_ERROR == COUPLING_MD_YES)
     143           12 :     if (_moleculeService == NULL) {
     144            0 :       std::cout << "ERROR coupling::interface::MDSimulation::getMoleculeService(): _moleculeService == NULL " << std::endl;
     145            0 :       exit(1);
     146              :     }
     147              : #endif
     148           12 :     return *_moleculeService;
     149              :   }
     150           12 :   const simplemd::services::MolecularPropertiesService& getMolecularPropertiesService() {
     151              : #if (COUPLING_MD_ERROR == COUPLING_MD_YES)
     152           12 :     if (_molecularPropertiesService == NULL) {
     153            0 :       std::cout << "ERROR coupling::interface::MDSimulation::getMolecularPropertiesService(): _molecularPropertiesService == NULL " << std::endl;
     154            0 :       exit(1);
     155              :     }
     156              : #endif
     157           12 :     return *_molecularPropertiesService;
     158              :   }
     159              : 
     160              : private:
     161              :   /** @brief the coupling cell service for the coupled md simulation  */
     162              :   coupling::services::CouplingCellService<MD_DIM>* _couplingCellService;
     163              :   /** @brief bool holding the current state of the coupling: true - coupled
     164              :    * simulation and false - independent md simulation */
     165              :   bool _couplingSwitchedOn;
     166              : #if (TARCH_DEBUG == TARCH_YES)
     167              :   simplemd::moleculemappings::ConvertForcesFloatToFixedMapping _convertForcesFloatToFixedMapping;
     168              :   simplemd::moleculemappings::ConvertForcesFixedToFloatMapping _convertForcesFixedToFloatMapping;
     169              : #endif
     170              : };
     171              : } // namespace interface
     172              : } // namespace coupling
        

Generated by: LCOV version 2.0-1