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