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 : }
|