5#ifndef _MOLECULARDYNAMICS_COUPLING_SERVICES_MULTIMDCELLSERVICE_H_
6#define _MOLECULARDYNAMICS_COUPLING_SERVICES_MULTIMDCELLSERVICE_H_
15#include "coupling/InstanceHandling.h"
16#include "coupling/configurations/MaMiCoConfiguration.h"
17#include "coupling/indexing/IndexingService.h"
18#include "coupling/interface/MDSimulationFactory.h"
19#include "coupling/services/CouplingCellService.h"
20#include "coupling/services/CouplingCellServiceDummy.h"
34 simplemd::configurations::MolecularDynamicsConfiguration& mdConfiguration,
38 _mamicoConfiguration(mamicoConfiguration), _filterPipelineConfiguration(filterPipelineConfiguration),
40 _topologyOffset = computeTopologyOffset();
41 _localNumberMDSimulations = multiMDService.getLocalNumberOfMDSimulations();
44 _blockOffset = _localNumberMDSimulations * _topologyOffset / _intNumberProcesses;
52 if (mdSolverInterfaces.size() == 0) {
53 std::cout <<
"ERROR: Zero MD instances on rank " <<
_multiMDService.getGlobalRank() <<
". Maybe you forgot to adjust number-md-simulations?" << std::endl;
68 "coupling::services::MultiMDCellService::MultiMDCellService("
69 "...): _couplingCellServices==NULL!"
81 for (
unsigned int i = 0; i < _blockOffset; i++) {
83 (i / _localNumberMDSimulations) * _intNumberProcesses);
86 "coupling::services::MultiMDCellService::MultiMDCellServic"
87 "e(...): _couplingCellServices["
88 << i <<
"]==NULL!" << std::endl;
93 for (
unsigned int i = _blockOffset; i < _localNumberMDSimulations + _blockOffset; i++) {
95 i, mdSolverInterfaces[i - _blockOffset], macroscopicSolverInterface, mdConfiguration.getMPIConfiguration().getNumberOfProcesses(),
100 _filterPipelineConfiguration.c_str(), multiMDService, _topologyOffset,
_tws);
102 std::cout <<
"ERROR "
103 "coupling::services::MultiMDCellService::MultiMDCellServic"
104 "e(...): _couplingCellServices["
105 << i <<
"]==NULL!" << std::endl;
113 (i / _localNumberMDSimulations) * _intNumberProcesses);
115 std::cout <<
"ERROR "
116 "coupling::services::MultiMDCellService::MultiMDCellServic"
117 "e(...): _couplingCellServices["
118 << i <<
"]==NULL!" << std::endl;
123 _mdConfiguration.getDomainConfigurationNonConst().setInitFromCheckpoint(
true);
124 std::stringstream filestem;
125 filestem <<
"restart_checkpoint_" << (
_multiMDService.getGlobalRank()) / computeScalarNumberProcesses() <<
"_0";
126 _mdConfiguration.getDomainConfigurationNonConst().setCheckpointFilestem(filestem.str());
127 _mdConfiguration.getDomainConfigurationNonConst().setInitFromSequentialCheckpoint(
false);
130 ~MultiMDCellService() {
145 for (
auto pair : _couplingCells) {
146 std::tie(cell, idx) = pair;
158 if (localIndex < _localNumberMDSimulations) {
159 return *(
_couplingCellServices[_topologyOffset * _localNumberMDSimulations / _intNumberProcesses + localIndex]);
161 std::cout <<
"ERROR MultiMDCellService::getCouplingCellService(localIndex): "
162 "localIndex >_localNumberMDSimulations-1!"
170 if (
_couplingCellServices[_topologyOffset * _localNumberMDSimulations / _intNumberProcesses + localIndex] ==
nullptr)
172 _couplingCellServices[_topologyOffset * _localNumberMDSimulations / _intNumberProcesses + localIndex]->plotEveryMacroscopicTimestep(cycle);
175 void plotEveryMacroscopicTimestep(
int cycle) {
176 for (
unsigned int i = _blockOffset; i < _blockOffset + _localNumberMDSimulations; ++i) {
183 void setInnerMomentumImposition(
bool enable) {
184 for (
unsigned int i = _blockOffset; i < _blockOffset + _localNumberMDSimulations; ++i) {
191 void computeAndStoreTemperature(
double temp) {
192 for (
unsigned int i = _blockOffset; i < _blockOffset + _localNumberMDSimulations; ++i) {
212#if (COUPLING_MD_PARALLEL == COUPLING_MD_NO)
219 std::vector<std::vector<coupling::datastructures::CouplingCell<dim>*>> allCouplingCellsFromMamico(
_totalNumberMDSimulations);
225 allCouplingCellsFromMamico[i] = v->getCouplingCells().getCouplingCells();
236 fromMacro2MD.bcastFromMacro2MD(allDEs, couplingCellsFromMacroscopicSolver, indices, allCouplingCellsFromMamico);
266 for (
unsigned int i = 0; i < v->getCouplingCells().getCouplingCells().size(); ++i) {
270 _sumCouplingCells[i]->addMacroscopicMass(v->getCouplingCells().getCouplingCells()[i]->getMacroscopicMass());
271 _sumCouplingCells[i]->addMacroscopicMomentum(v->getCouplingCells().getCouplingCells()[i]->getMacroscopicMomentum());
284#if (COUPLING_MD_PARALLEL == COUPLING_MD_NO)
289 const unsigned int size = (
unsigned int)couplingCellsFromMacroscopicSolver.size();
307 couplingCell->setMacroscopicMass(0.0);
312 std::vector<std::vector<coupling::datastructures::CouplingCell<dim>*>> allCouplingCellsFromMamico(
_totalNumberMDSimulations);
315 unsigned int totalNumberEquilibratedMDSimulations = 0;
320 totalNumberEquilibratedMDSimulations += 1;
322 _fromMD2Macro.reduceFromMD2Macro(allDEs, couplingCellsFromMacroscopicSolver, indices,
_sumCouplingCells);
325 for (
unsigned int i = 0; i < size; i++) {
326 _couplingCells[i]->setMacroscopicMass(couplingCellsFromMacroscopicSolver[i]->getMacroscopicMass() / (
double)totalNumberEquilibratedMDSimulations);
327 _couplingCells[i]->setMacroscopicMomentum(1.0 / (
double)totalNumberEquilibratedMDSimulations *
328 couplingCellsFromMacroscopicSolver[i]->getMacroscopicMomentum());
339#ifdef DEBUG_FILTER_PIPELINE
340 std::cout <<
"FP: Now applying post-multi-instance filter pipeline" << std::endl;
346 for (
unsigned int i = 0; i < size; i++) {
347 couplingCellsFromMacroscopicSolver[i]->setMacroscopicMass(_couplingCells[i]->getMacroscopicMass());
348 couplingCellsFromMacroscopicSolver[i]->setMacroscopicMomentum(_couplingCells[i]->getMacroscopicMomentum());
362#if (COUPLING_MD_ERROR == COUPLING_MD_YES)
363 if (_couplingCells.size() != md2macroCouplingCells.
size())
364 throw std::runtime_error(std::string(
"Buffers must have the same size!"));
372 for (
auto pair : _couplingCells) {
373 std::tie(cellA, idx) = pair;
380 unsigned int totalNumberEquilibratedMDSimulations = 0;
387 auto itCouplingCells = _couplingCells.begin();
388 auto itMd2macroCouplingCells = md2macroCouplingCells.
begin();
389 while (itCouplingCells != _couplingCells.end()) {
390 std::tie(cellA, idx) = *itCouplingCells;
391 std::tie(cellB, idx) = *itMd2macroCouplingCells;
395 itMd2macroCouplingCells++;
397 totalNumberEquilibratedMDSimulations += 1;
402 for (
auto pair : _couplingCells) {
403 std::tie(cellA, idx) = pair;
410#ifdef DEBUG_FILTER_PIPELINE
411 std::cout <<
"FP: Now applying post-multi-instance filter pipeline" << std::endl;
417 auto itCouplingCells = _couplingCells.begin();
418 auto itMd2macroCouplingCells = md2macroCouplingCells.
begin();
419 while (itCouplingCells != _couplingCells.end()) {
420 std::tie(cellA, idx) = *itCouplingCells;
421 std::tie(cellB, idx) = *itMd2macroCouplingCells;
425 itMd2macroCouplingCells++;
440 if (_couplingCells.size() == 0) {
444 for (
auto pair : cells) {
445 std::tie(cell, idx) = pair;
447 _couplingCells << std::make_pair(newCell, idx);
463#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
465 std::cout <<
"Rank " <<
_multiMDService.getGlobalRank() <<
": _couplingCellService at " << index <<
" == NULL" << std::endl;
472 if (index >= _blockOffset && index < _blockOffset + _localNumberMDSimulations) {
473 unsigned int iSim = index - _blockOffset;
474#if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
476 std::cout <<
"MultiMDCellService: removing instance " << iSim <<
"..." << std::endl;
491 unsigned int newLocalNumberMDSimulations = _localNumberMDSimulations - 1;
493 unsigned int newBlockOffset = newLocalNumberMDSimulations * _topologyOffset / _intNumberProcesses;
497 for (
unsigned int i = 0; i <
_multiMDService.getNumberLocalComms(); ++i) {
498 for (
unsigned int j = 0; j < newLocalNumberMDSimulations; ++j) {
499 unsigned int index = i * _localNumberMDSimulations + j;
500 unsigned int newIndex = i * newLocalNumberMDSimulations + j;
505 auto pos =
_warmupPhase.begin() + newLocalNumberMDSimulations * i - i;
510 _localNumberMDSimulations = newLocalNumberMDSimulations;
512 _blockOffset = newBlockOffset;
531 unsigned int newLocalNumberMDSimulations = _localNumberMDSimulations + 1;
533 unsigned int newBlockOffset = newLocalNumberMDSimulations * _topologyOffset / _intNumberProcesses;
536 for (
unsigned int i = 0; i <
_multiMDService.getNumberLocalComms(); ++i) {
537 for (
unsigned int j = 0; j < _localNumberMDSimulations; ++j) {
538 unsigned int index = i * _localNumberMDSimulations + j;
539 unsigned int newIndex = i * newLocalNumberMDSimulations + j;
542 newCouplingCellServices[(i + 1) * newLocalNumberMDSimulations - 1] =
nullptr;
544 auto pos =
_warmupPhase.begin() + ((i + 1) * newLocalNumberMDSimulations - 1);
549 _localNumberMDSimulations = newLocalNumberMDSimulations;
551 _blockOffset = newBlockOffset;
564 std::cout <<
"ERROR coupling::services::MultiMDCellService::addMDSimulation(): "
566 << slot <<
"!" << std::endl;
567 std::exit(EXIT_FAILURE);
570 std::cout <<
"ERROR! "
571 "coupling::services::MultiMDCellService::addMDSimulation(): "
573 << slot <<
" already exists!" << std::endl;
574 std::exit(EXIT_FAILURE);
577 std::stringstream filestem;
578 filestem <<
"restart_checkpoint_" <<
_multiMDService.getGlobalRank() / computeScalarNumberProcesses();
581 if (slot < _blockOffset || slot >= _blockOffset + _localNumberMDSimulations) {
586 _mamicoConfiguration.getParallelTopologyConfiguration(), _mamicoConfiguration.getCouplingCellConfiguration(),
587 (slot / _localNumberMDSimulations) * _intNumberProcesses);
590 unsigned localIndex = slot - _blockOffset;
591 auto* mdSolverInterface = instanceHandling.
addMDSimulation(slot, localIndex);
595 _mamicoConfiguration.getParticleInsertionConfiguration(), _mamicoConfiguration.getMomentumInsertionConfiguration(),
596 _mamicoConfiguration.getBoundaryForceConfiguration(), _mamicoConfiguration.getTransferStrategyConfiguration(),
597 _mamicoConfiguration.getParallelTopologyConfiguration(), _mamicoConfiguration.getThermostatConfiguration(),
598 _mdConfiguration.getSimulationConfiguration().getNumberOfTimesteps(), _mamicoConfiguration.getCouplingCellConfiguration(),
612 unsigned int getLocalNumberOfMDSimulations()
const {
return _localNumberMDSimulations; }
619 if (
_warmupPhase[i] == 0 && i >= _blockOffset && i < _blockOffset + _localNumberMDSimulations) {
628 void writeCheckpoint(
const unsigned int& cycle,
const coupling::InstanceHandling<LinkedCell, dim>& instanceHandling)
const {
631 std::stringstream filestem;
632 filestem <<
"restart_checkpoint_" <<
_multiMDService.getGlobalRank() / computeScalarNumberProcesses();
638 void constructFilterPipelines() {
644 if (
dynamic_cast<coupling::services::CouplingCellServiceImpl<LinkedCell, dim>*
>(mcs) ==
nullptr)
647 if (mcs->getFilterPipeline() ==
nullptr) {
648 mcs->initFiltering();
654 unsigned int computeTopologyOffset()
const {
656 const unsigned int intNumberProcesses = computeScalarNumberProcesses();
657 const unsigned int topologyOffset = (
_multiMDService.getGlobalRank() / intNumberProcesses) * intNumberProcesses;
658 return topologyOffset;
661 unsigned int computeScalarNumberProcesses()
const {
662 unsigned int np =
_multiMDService.getNumberProcessesPerMDSimulation()[0];
663 for (
unsigned int d = 1; d < dim; d++) {
669 coupling::services::CouplingCellService<dim>*
670 createCouplingCellServiceDummy(
unsigned int ID, coupling::interface::MacroscopicSolverInterface<dim>* macroscopicSolverInterface,
671 simplemd::configurations::MolecularDynamicsConfiguration& mdConfiguration, tarch::utils::MultiMDService<dim>& multiMDService,
672 coupling::configurations::MaMiCoConfiguration<dim>& mamicoConfiguration,
unsigned int topologyOffset)
const {
673 return new coupling::services::CouplingCellServiceDummy<dim>(
674 ID, macroscopicSolverInterface, mdConfiguration.getMPIConfiguration().getNumberOfProcesses(), multiMDService.getGlobalRank(),
675 mdConfiguration.getDomainConfiguration().getGlobalDomainSize(), mdConfiguration.getDomainConfiguration().getGlobalDomainOffset(),
679 unsigned int _localNumberMDSimulations;
686 unsigned int _topologyOffset;
689 const unsigned int _intNumberProcesses;
697 const std::string _filterPipelineConfiguration;
700 unsigned int _blockOffset;
701 std::vector<bool> _listActiveMDSimulations;
Simulation slots are managed (i.e., added/removed) via this class. Works and interacts with the class...
Definition InstanceHandling.h:35
auto & getSimpleMD() const
Definition InstanceHandling.h:101
void writeCheckpoint(const std::string &filestem, const unsigned int &T) const
Definition InstanceHandling.h:170
void rmMDSimulation(const unsigned int &index)
Definition InstanceHandling.h:253
void switchOnCoupling()
Definition InstanceHandling.h:127
coupling::interface::MDSolverInterface< LinkedCell, dim > * addMDSimulation(unsigned int slot, unsigned int localIndex)
Definition InstanceHandling.h:225
parses all sub-tags for MaMiCo configuration.
Definition MaMiCoConfiguration.h:31
const coupling::configurations::MomentumInsertionConfiguration & getMomentumInsertionConfiguration() const
Definition MaMiCoConfiguration.h:86
const coupling::configurations::ThermostatConfiguration & getThermostatConfiguration() const
Definition MaMiCoConfiguration.h:146
const coupling::configurations::BoundaryForceConfiguration< dim > & getBoundaryForceConfiguration() const
Definition MaMiCoConfiguration.h:99
const coupling::configurations::ParticleInsertionConfiguration & getParticleInsertionConfiguration() const
Definition MaMiCoConfiguration.h:73
const coupling::configurations::ParallelTopologyConfiguration & getParallelTopologyConfiguration() const
Definition MaMiCoConfiguration.h:125
const coupling::configurations::TransferStrategyConfiguration< dim > & getTransferStrategyConfiguration() const
Definition MaMiCoConfiguration.h:112
const coupling::configurations::CouplingCellConfiguration< dim > & getCouplingCellConfiguration() const
Definition MaMiCoConfiguration.h:68
defines the cell type with cell-averaged quantities only (no linked cells).
Definition CouplingCell.h:29
void addMacroscopicMomentum(const tarch::la::Vector< dim, double > &momentum)
Definition CouplingCell.h:85
const tarch::la::Vector< dim, double > & getMacroscopicMomentum() const
Definition CouplingCell.h:64
void addMacroscopicMass(const double &mass)
Definition CouplingCell.h:82
void setMacroscopicMomentum(const tarch::la::Vector< dim, double > &momentum)
Definition CouplingCell.h:61
const double & getMacroscopicMass() const
Definition CouplingCell.h:58
void setMacroscopicMass(const double &mass)
Definition CouplingCell.h:55
provides access to coupling cells, which may belong to different indexing domains
Definition FlexibleCellContainer.h:30
Iterator begin() const
Definition FlexibleCellContainer.h:121
unsigned int size() const
Definition FlexibleCellContainer.h:78
Definition FilterPipeline.h:44
interface to the MD simulation
Definition MDSolverInterface.h:25
interface for the macroscopic, i.e. continuum solver
Definition MacroscopicSolverInterface.h:23
static MamicoInterfaceProvider & getInstance()
Definition MamicoInterfaceProvider.h:28
coupling::interface::MacroscopicSolverInterface< dim > * getMacroscopicSolverInterface()
Definition MamicoInterfaceProvider.h:43
data exchange from the MD solver to the macroscopic solver. Derived from the class coupling::sendrecv...
Definition DataExchangeFromMD2Macro.h:36
data exchange from the macroscopic solver to the MD solver. Derived from the class coupling::sendrecv...
Definition DataExchangeFromMacro2MD.h:36
sends coupling cell information from MaMiCo to the macroscopic solver. Derived from the class couplin...
Definition FromMD2Macro.h:29
SendReceiveBuffer for transfer of quantities from a macroscopic solver to the coupling cells....
Definition FromMacro2MD.h:28
Definition CouplingCellServiceDummy.h:28
Definition CouplingCellService.h:100
Definition CouplingCellService.h:50
Definition MultiMDCellService.h:29
const int _tws
Definition MultiMDCellService.h:688
coupling::filtering::FilterPipeline< I14, dim > * _postMultiInstanceFilterPipeline
Definition MultiMDCellService.h:715
void sendFromMacro2MD(const coupling::datastructures::FlexibleCellContainer< dim > ¯o2mdCouplingCellContainer)
Definition MultiMDCellService.h:200
void removeSimulationBlock()
Definition MultiMDCellService.h:489
void bcastFromMacro2MD(const std::vector< coupling::datastructures::CouplingCell< dim > * > &couplingCellsFromMacroscopicSolver, const I00 *const indices)
Definition MultiMDCellService.h:211
void sumUpCouplingCellsFromMamico()
Definition MultiMDCellService.h:252
double reduceFromMD2Macro(const std::vector< coupling::datastructures::CouplingCell< dim > * > &couplingCellsFromMacroscopicSolver, const I00 *const indices)
Definition MultiMDCellService.h:283
std::vector< int > _warmupPhase
Definition MultiMDCellService.h:705
double sendFromMD2Macro(const coupling::datastructures::FlexibleCellContainer< dim > &md2macroCouplingCells)
Definition MultiMDCellService.h:357
simplemd::configurations::MolecularDynamicsConfiguration & _mdConfiguration
Definition MultiMDCellService.h:695
coupling::services::CouplingCellService< dim > & getCouplingCellService(unsigned int localIndex)
Definition MultiMDCellService.h:157
coupling::services::CouplingCellService< dim > ** _couplingCellServices
Definition MultiMDCellService.h:683
unsigned int rmMDSimulation(coupling::InstanceHandling< LinkedCell, dim > &instanceHandling, const unsigned int &index)
Definition MultiMDCellService.h:462
unsigned int addMDSimulation(coupling::InstanceHandling< LinkedCell, dim > &instanceHandling, coupling::interface::MacroscopicSolverInterface< dim > *macroscopicSolverInterface, const unsigned int &slot)
Definition MultiMDCellService.h:560
unsigned int _totalNumberMDSimulations
Definition MultiMDCellService.h:682
void addSimulationBlock()
Definition MultiMDCellService.h:529
void plotEveryMacroscopicTimestepforCouplingCellService(unsigned int localIndex, int cycle)
Definition MultiMDCellService.h:169
unsigned int _nextFreeBlock
Definition MultiMDCellService.h:703
void preprocessingForMD2Macro(const coupling::datastructures::FlexibleCellContainer< dim > &cells)
Definition MultiMDCellService.h:434
tarch::utils::MultiMDService< dim > & _multiMDService
Definition MultiMDCellService.h:685
coupling::datastructures::FlexibleCellContainer< dim > _sumCouplingCells
Definition MultiMDCellService.h:693
Definition MultiMDService.h:30
everything necessary for coupling operations, is defined in here
Definition AdditiveMomentumInsertion.h:15