ls1-MarDyn
ls1-MarDyn molecular dynamics code
MettDeamon.h
1/*
2 * MettDeamon.h
3 *
4 * Created on: 03.04.2017
5 * Author: thet
6 */
7
8#ifndef METTDEAMON_H_
9#define METTDEAMON_H_
10
11#include "../PluginBase.h"
12#include "molecules/Molecule.h"
13#include "Domain.h"
14#include "utils/CommVar.h"
15//#include "NEMD/Request.h"
16
17#include <map>
18#include <array>
19#include <fstream>
20#include <utility>
21#include <vector>
22#include <cstdint>
23#include <limits>
24#include <algorithm>
25#include <memory>
26
27// shuffle velocity list for each process before usage
28#include <random>
29#include <vector>
30template < typename T > void shuffle( std::list<T>& lst ); // shuffle contents of a list
31
32void create_rand_vec_ones(const uint64_t& nCount, const double& percent, std::vector<int>& v);
33void update_velocity_vectors(std::unique_ptr<Random>& rnd, const uint64_t& numSamples, const double&T, const double&D, const double&v_neg, const double&e_neg,
34 std::vector<double>& vxi, std::vector<double>& vyi, std::vector<double>& vzi);
35
36#define FORMAT_SCI_MAX_DIGITS std::setw(24) << std::scientific << std::setprecision(std::numeric_limits<double>::digits10)
37
38enum ReadReservoirMethods : uint8_t
39{
40 RRM_UNKNOWN = 0,
41 RRM_READ_FROM_FILE = 1,
42 RRM_READ_FROM_FILE_BINARY = 2,
43 RRM_READ_FROM_MEMORY = 3,
44 RRM_AMBIGUOUS = 4,
45 RRM_EMPTY = 5,
46};
47
48enum MovingDirections : uint8_t
49{
50 MD_UNKNOWN = 0,
51 MD_LEFT_TO_RIGHT = 1,
52 MD_RIGHT_TO_LEFT = 2,
53};
54
55enum FeedRateMethod : uint8_t
56{
57 FRM_UNKNOWN = 0,
58 FRM_DELETED_MOLECULES = 1,
59 FRM_CHANGED_MOLECULES = 2,
60 FRM_DENSITY = 3,
61 FRM_CONSTANT = 4,
62 FRM_DIRECTED = 5
63};
64
65enum Zone2Method : uint8_t
66{
67 Z2M_UNKNOWN = 0,
68 Z2M_RESET_ALL = 1,
69 Z2M_RESET_YPOS_ONLY = 2,
70};
71
72enum ReleaseVelocityMethod : uint32_t
73{
74 RVM_UNKNOWN = 0,
75 RVM_UNCHANGED = 1,
76 RVM_FIX_VALUE = 2,
77 RVM_ADD_FIX_VALUE = 3,
78 RVM_NORM_DISTR = 4,
79 RVM_NORM_DISTR_GENERATOR = 5
80};
81
82enum MoleculeFormat : uint32_t {
83 ICRVQD, IRV, ICRV
84};
85
87{
88 uint32_t nBindindex;
89 double dYsum;
90};
91
93{
94 double temperature, drift;
95 double a_neg, a_pos, v_neg, v_pos, e_neg, e_pos;
96 std::string fpath;
97};
98
100{
101 uint32_t cid_target;
102 uint32_t log_freq;
103
105 {
106 double init;
107 double actual;
108 double target;
109 double sum;
110
111 } feed;
112
114 {
115 uint32_t method;
116 double fix_value;
117 ParamsNormMB normMB;
118 std::vector<double> vx;
119 std::vector<double> vy;
120 std::vector<double> vz;
121 uint64_t numSamples;
122 } release_velo;
123
125 {
126 CommVar<uint64_t> inserted;
127 CommVar<uint64_t> deleted;
128 CommVar<uint64_t> changed_to;
129 CommVar<uint64_t> changed_from;
130 } numMolecules;
131
132 // rand vector, containing 100 values 0|1 for insertion part of trapped particles
133 std::vector<int> vec_rand_ins;
134};
135
136class Domain;
137class Ensemble;
138class DomainDecompBase;
140class XMLfileUnits;
141
142class Reservoir;
143class MettDeamon : public PluginBase
144{
145public:
146 MettDeamon();
147 ~~MettDeamon() override = default;
148
193 void readXML(XMLfileUnits& xmlconfig) override;
194 void init(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp, Domain* domain) override;
195 void beforeEventNewTimestep(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp, unsigned long simstep) override;
196 void beforeForces(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp, unsigned long simstep) override;
197 void siteWiseForces(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp, unsigned long simstep) override {};
198 void afterForces(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp, unsigned long simstep) override;
199 void endStep(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp, Domain* domain, unsigned long simstep) override {};
200 void finish(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp, Domain* domain) override {};
201 std::string getPluginName() override {return std::string("MettDeamon");}
202 static PluginBase* createInstance() {return new MettDeamon();}
203
204 uint64_t getnNumMoleculesDeleted( DomainDecompBase* domainDecomposition){return _nNumMoleculesDeletedGlobalAlltime;}
205 uint64_t getnNumMoleculesDeleted2( DomainDecompBase* domainDecomposition);
206 uint8_t getMovingDirection() {return _nMovingDirection;}
207 double getTransitionPlanePosY() {return _dTransitionPlanePosY;}
208
209 void prepare_start(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer, double cutoffRadius);
210 void init_positionMap(ParticleContainer* particleContainer);
211 void preForce_action(ParticleContainer* particleContainer, double cutoffRadius);
212 void postForce_action(ParticleContainer* particleContainer, DomainDecompBase* domainDecomposition);
213
214 // connection to DensityControl
215 uint32_t getFeedRateTargetComponentID() {return _feedrate.cid_target;}
216 void IncrementInsertedMoleculesLocal() {_feedrate.numMolecules.inserted.local++;}
217 void IncrementDeletedMoleculesLocal() {_feedrate.numMolecules.deleted.local++;}
218 void IncrementChangedToMoleculesLocal() {_feedrate.numMolecules.changed_to.local++;}
219 void IncrementChangedFromMoleculesLocal() {_feedrate.numMolecules.changed_from.local++;}
220 void StoreDensity(const double& dVal) {_vecDensityValues.push_back(dVal);}
221 void StoreValuesCV(const double& dDensity, const double& dVolume) {_dDensityTarget = dDensity; _dVolumeCV = dVolume;}
222
223 // connection to other general plugins
224 void setActualFeedrate(const double& feed_actual) {
225 _feedrate.feed.actual = feed_actual;
226 global_log->info() << "[MettDeamon]: Set new feedrate by MDFRD to vf= " << _feedrate.feed.actual << std::endl;
227 }
228 void setInitFeedrate(const double& feed_init) {
229 _feedrate.feed.init = feed_init;
230 global_log->info() << "[MettDeamon]: Set init feedrate by MDFRD to vf= " << _feedrate.feed.init << std::endl;
231 }
232 double getInvDensityArea() {return _dInvDensityArea;}
233
234private:
235 void findMaxMoleculeID(DomainDecompBase* domainDecomp);
236 void writeRestartfile();
237 void logFeedrate();
238 void logReleased();
239 void logReleasedVelocities();
240 void calcDeltaY();
241 void calcDeltaYbyDensity();
242 // Check if molecule is a trapped one
243 bool IsTrappedMolecule(const uint8_t& cid) {return cid != _vecChangeCompIDsUnfreeze.at(cid);}
244 bool IsBehindTransitionPlane(const double& dPosY) {
245 bool bRet = ( MD_LEFT_TO_RIGHT == _nMovingDirection && dPosY > _dTransitionPlanePosY ) ||
246 ( MD_RIGHT_TO_LEFT == _nMovingDirection && dPosY < _dTransitionPlanePosY );
247 return bRet;
248 }
249 bool IsInsideOuterReservoirSlab(const double& dPosY, const double& dBoxY);
250 void releaseTrappedMolecule(Molecule* mol, bool& bDeleteParticle);
251 void resetPositionAndOrientation(Molecule* mol, const double& dBoxY);
252 void resetVelocity(Molecule* mol);
253
254 void InitTransitionPlane(Domain* domain);
255 void getAvailableParticleIDs(ParticleContainer* particleContainer, DomainDecompBase* domainDecomp,
256 CommVar<std::vector<uint64_t> >& particleIDs_available, const CommVar<uint64_t>& numParticleIDs);
257 void updateReservoir(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer);
258 void InsertReservoirSlab(ParticleContainer* particleContainer);
259 void initRestart();
260
261 // stat. evap
262 void readNormDistr();
263
264 // rand vector for trapped particle insertion
265 void updateRandVecTrappedIns();
266
267private:
268 std::unique_ptr<Reservoir> _reservoir;
269 bool _bIsRestart; // simulation is a restart?
270 bool _bInitFeedrateLog;
271 bool _bInitRestartLog;
272 double _dAreaXZ;
273 double _dInvDensityArea;
274 double _dDeletedMolsPerTimestep;
275 double _dInvNumTimestepsSummation;
276 double _dTransitionPlanePosY;
277 double _dDensityTarget;
278 double _dVolumeCV;
279 uint64_t _nUpdateFreq;
280 uint64_t _nWriteFreqRestart;
281 CommVar<uint64_t> _nMaxMoleculeID;
282 uint64_t _nMaxReservoirMoleculeID;
283 uint64_t _nNumMoleculesDeletedGlobalAlltime;
284 CommVar<uint64_t> _nNumMoleculesTooFast;
285 uint8_t _nMovingDirection;
286 uint8_t _nFeedRateMethod;
287 uint8_t _nZone2Method;
288 uint32_t _nNumValsSummation;
289 int64_t _numDeletedMolsSum;
290 uint64_t _nDeleteNonVolatile;
291 std::map<uint64_t, std::array<double,10> > _storePosition; //Map for frozen particle position storage <"id, position">
292 std::list<uint64_t> _listDeletedMolecules;
293 // identity change (by component ID)
294 std::vector<uint32_t> _vecChangeCompIDsFreeze;
295 std::vector<uint32_t> _vecChangeCompIDsUnfreeze;
296 // keep gas phase density
297 std::vector<double> _vecDensityValues;
298
299 RestartInfoType _restartInfo;
300 struct{
301 double ymin, ymax;
302 uint32_t cid_ub;
303 } _manipfree;
304 FeedRateStruct _feedrate;
305
306 // stat. evap.
307 struct{
308 bool enabled;
309 uint32_t type; // 1|2 : left|right or liq|vap
310 double pos_y;
311 struct{
312 struct{
313 uint32_t pos;
314 uint32_t neg;
315 } left;
316 struct{
317 uint32_t pos;
318 uint32_t neg;
319 } right;
320 } cid;
321 } _vap_trans_plane;
322
323 struct NormMB{
325 std::string vxz;
326 std::string vy;
327 } fname;
328 std::list<double> vxz;
329 std::list<double> vy;
330 } _norm;
331
332 struct{
333 CommVar<uint64_t> count;
334 CommVar<uint64_t> deleted;
335 uint64_t log_freq;
336 uint64_t log_freq_vel;
337 bool init_file;
338 bool init_file_vel;
339 std::vector<std::array<double,3> > log_v;
340 } _released;
341
342 std::unique_ptr<Random> _rnd;
343};
344
346{
347 std::string data;
348 std::string header;
349};
350
352{
353 double volume;
354 std::array<double,3> length;
355};
356
358{
359 CommVar<uint64_t> numMolecules;
360 double density;
361};
362
363class BinQueue;
366{
367public:
368 Reservoir(MettDeamon* parent);
369 ~~Reservoir();
370
371 void readXML(XMLfileUnits& xmlconfig);
372
373 // read particle data
374 void readParticleData(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer);
375 void updateParticleData(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer);
376private:
377 void readFromMemory(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer);
378 void readFromFile(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer);
379 void readFromFileBinary(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer);
380 void readFromFileBinaryHeader();
381 void sortParticlesToBins(DomainDecompBase* domainDecomp, ParticleContainer* particleContainer);
382
383public:
384 // Getters, Setters
385 double getDensity(const uint32_t& cid) {return _density.at(cid).density;}
386 void setDensity(const uint32_t& cid, const double& dVal) {_density.at(cid).density = dVal;}
387 double getBoxLength(const uint32_t& nDim) {return _box.length.at(nDim);}
388 void setBoxLength(const uint32_t& nDim, const double& dVal) {_box.length.at(nDim)=dVal;}
389 double getVolume() {return _box.volume;}
390 void setVolume(const double& dVal) {_box.volume = dVal;}
391 double getBinWidth() {return _dBinWidth;}
392 double GetInsPercent() {return _dInsPercent;}
393 void setInsPercent(const double& dVal) {_dInsPercent = dVal;}
394 uint8_t getReadMethod() {return _nReadMethod;}
395
396 // queue methods
397 uint32_t getActualBinIndex();
398 uint64_t getNumMoleculesLocal();
399 uint32_t getNumBins();
400 std::vector<Molecule>& getParticlesActualBin();
401 bool nextBin(uint64_t& nMaxID);
402 uint64_t getMaxMoleculeID();
403 bool activateBin(uint32_t nBinIndex);
404 void clearBinQueue();
405 void printBinQueueInfo();
406
407private:
408 void calcPartialDensities(DomainDecompBase* domainDecomp);
409 void changeComponentID(Molecule& mol, const uint32_t& cid);
410 bool isRelevant(DomainDecompBase* domainDecomp, Domain* domain, Molecule& mol);
411
412private:
413 MettDeamon* _parent;
414 std::unique_ptr<MoleculeDataReader> _moleculeDataReader;
415 std::unique_ptr<BinQueue> _binQueue;
416 uint64_t _numMoleculesRead;
417 uint64_t _nMaxMoleculeID;
418 uint32_t _nMoleculeFormat;
419 uint8_t _nReadMethod;
420 double _dReadWidthY;
421 double _dBinWidthInit;
422 double _dBinWidth;
423 double _dInsPercent; // only insert percentage of reservoir density
424 std::vector<Molecule> _particleVector;
425 std::vector<uint32_t> _vecChangeCompIDs;
426 std::vector<DensityStruct> _density;
427 FilepathStruct _filepath;
428 BoxStruct _box;
429 bool _bUpdateBinQueue; // BinQueue have to be updated if bounding boxes changes, e.g. in case of using kd-decomposition
430};
431
432
433
435{
436 class Bin
437 {
438 friend class BinQueue;
439 public:
440 Bin(const std::vector<Molecule>& vec, uint32_t nIndex) : _next(nullptr), _nIndex(nIndex)
441 {
442 for(const auto& p:vec)
443 _particles.push_back(p);
444 }
445 uint32_t getIndex() {return _nIndex;}
446 uint64_t getNumParticles() {return _particles.size();}
447 Bin* _next;
448 uint32_t _nIndex;
449 std::vector<Molecule> _particles;
450 };
451private:
452 Bin *_first, *_last, *_actual;
453 uint32_t _numBins;
454 uint32_t _nRoundCount;
455 uint64_t _numParticles;
456 uint64_t _maxID;
457
458
459public:
460 BinQueue() :
461 _first(nullptr),
462 _last(nullptr),
463 _actual(nullptr),
464 _numBins(0),
465 _nRoundCount(0),
466 _numParticles(0),
467 _maxID(0)
468 {
469 }
470
471 BinQueue(std::vector<Molecule> vec) :
472 _first(nullptr),
473 _last(nullptr),
474 _actual(nullptr),
475 _numBins(0),
476 _nRoundCount(0),
477 _numParticles(0),
478 _maxID(0)
479 {
480 enque(std::move(vec));
481 }
482
483 ~~BinQueue() {
484 if(_last){
485 // break connection of last element to first element (established via connectTailToHead())
486 _last->_next = nullptr;
487 }
488 auto ptr = _first;
489 while (ptr) {
490 // as long as ptr isn't nullptr we continue to delete the next element.
491 auto ptr_next = ptr->_next;
492 delete ptr;
493 ptr = ptr_next;
494 }
495 }
496
497 bool isEmpty() {
498 return _first == nullptr;
499 }
500
501 void enque(std::vector<Molecule> vec)
502 {
503 Bin* ptr = new Bin(vec, _numBins);
504 if (isEmpty()) {
505 _last = ptr;
506 _first = ptr;
507 _actual = ptr;
508 } else {
509 _last->_next = ptr;
510 _last = ptr;
511 }
512 _last->_next = _first; // connect tail to head
513 _numBins++;
514 _numParticles += vec.size();
515 // update max particle ID
516 if(_numParticles > 0)
517 {
518 std::vector<Molecule>::iterator it;
519 if(vec.empty())
520 it = vec.end();
521 else if(vec.size() == 1)
522 it = vec.begin();
523 else
524 it = max_element(vec.begin(), vec.end(), molecule_id_compare);
525
526 if(it != vec.end() )
527 _maxID = ( (*it).getID()>_maxID ? (*it).getID() : _maxID);
528 }
529 else
530 _maxID = 0;
531 }
532
533 void deque()
534 {
535 if (isEmpty()) {
536 return;
537 }
538 else if (_first == _last) {
539 _numParticles -= _first->getNumParticles();
540 delete _first;
541 _first = _last = nullptr;
542 _numBins--;
543 }
544 else {
545 Bin* ptr = _first;
546 while(ptr->_next != _last) {
547 ptr = ptr->_next;
548 }
549 _numParticles -= ptr->_next->getNumParticles();
550 delete ptr->_next;
551 ptr->_next = nullptr;
552 _last = ptr;
553 _numBins--;
554 _last->_next = _first; // connect tail to head
555 }
556 }
557
558 void clear()
559 {
560 while (!isEmpty()) {
561 deque();
562 }
563 }
564
565 std::vector<Molecule>& head() {
566 return _first->_particles;
567 }
568
569 std::vector<Molecule>& getParticlesActualBin() {
570 return _actual->_particles;
571 }
572
573 void showActualBin() {
574 for(auto& p:_actual->_particles)
575 std::cout << p << ", ";
576 std::cout << endl;
577 }
578
579 void connectTailToHead()
580 {
581 _last->_next=_first;
582 _actual = _first;
583 }
584
585 bool next()
586 {
587 _actual = _actual->_next;
588 if(_actual == _first)
589 _nRoundCount++;
590 bool bSuccess = dynamic_cast<Bin*>(_actual);
591 return bSuccess;
592 }
593
594 bool activateBin(uint32_t nBinIndex)
595 {
596 Bin* ptr = _first;
597 while(ptr != nullptr)
598 {
599 if(ptr->_nIndex == nBinIndex) {
600 _actual = ptr;
601 return true;
602 }
603 ptr = ptr->_next;
604 if(ptr == _first)
605 break;
606 }
607 return false;
608 }
609
610 uint32_t getActualBinIndex() {return _actual->_nIndex;}
611 uint32_t getNumBins() {return _numBins;}
612 uint32_t getRoundCount() {return _nRoundCount;}
613 uint64_t getNumParticles() {return _numParticles;}
614 uint64_t getMaxID() {return _maxID;}
615
616private:
617 static bool molecule_id_compare(Molecule a, Molecule b)
618 {
619 return (a.getID() < b.getID());
620 }
621 void determineMaxID()
622 {
623 _maxID = 0;
624 Bin* ptr = _first;
625 while(ptr != nullptr)
626 {
627 std::vector<Molecule> vec = ptr->_particles;
628 auto it = max_element(vec.begin(), vec.end(), molecule_id_compare);
629 _maxID = ( (*it).getID()>_maxID ? (*it).getID() : _maxID);
630 ptr = ptr->_next;
631 if(ptr == _first)
632 break;
633 }
634 }
635};
636
637#endif /* METTDEAMON_H_ */
638
Definition: MettDeamon.h:435
Definition: CommVar.h:17
handle boundary region and multiple processes
Definition: DomainDecompBase.h:51
This class is used to read in the phasespace and to handle macroscopic values.
Definition: Domain.h:47
Base class for ensembles.
Definition: EnsembleBase.h:47
FullMolecule modeled as LJ sphere with point polarities.
Definition: FullMolecule.h:18
unsigned long getID() const override
Definition: FullMolecule.h:41
Definition: MettDeamon.h:144
void finish(ParticleContainer *particleContainer, DomainDecompBase *domainDecomp, Domain *domain) override
Method finish will be called at the end of the simulation.
Definition: MettDeamon.h:200
std::string getPluginName() override
return the name of the plugin
Definition: MettDeamon.h:201
void init(ParticleContainer *particleContainer, DomainDecompBase *domainDecomp, Domain *domain) override
Method init will be called at the begin of the simulation.
Definition: MettDeamon.cpp:443
void afterForces(ParticleContainer *particleContainer, DomainDecompBase *domainDecomp, unsigned long simstep) override
Method afterForces will be called after forcefields have been applied no sitewise Forces can be appli...
Definition: MettDeamon.cpp:457
void siteWiseForces(ParticleContainer *particleContainer, DomainDecompBase *domainDecomp, unsigned long simstep) override
Method siteWiseForces will be called before forcefields have been applied alterations to sitewise for...
Definition: MettDeamon.h:197
void readXML(XMLfileUnits &xmlconfig) override
Read in XML configuration for MettDeamon and all its included objects.
Definition: MettDeamon.cpp:266
void endStep(ParticleContainer *particleContainer, DomainDecompBase *domainDecomp, Domain *domain, unsigned long simstep) override
Method endStep will be called at the end of each time step.
Definition: MettDeamon.h:199
void beforeForces(ParticleContainer *particleContainer, DomainDecompBase *domainDecomp, unsigned long simstep) override
Method beforeForces will be called before forcefields have been applied no alterations w....
Definition: MettDeamon.cpp:452
void beforeEventNewTimestep(ParticleContainer *particleContainer, DomainDecompBase *domainDecomp, unsigned long simstep) override
Method will be called first thing in a new timestep.
Definition: MettDeamon.cpp:448
Definition: ReplicaGenerator.h:84
This Interface is used to get access to particles and pairs of particles.
Definition: ParticleContainer.h:69
The PluginBase class provides the interface for any kind of output/plugin classes - called "(output) ...
Definition: PluginBase.h:47
Definition: MettDeamon.h:366
XML file with unit attributes abstraction.
Definition: xmlfileUnits.h:25
Enumeration class corresponding to the type schema type.
Definition: vtk-unstructured.h:1746
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
Definition: vtk-punstructured.h:270
Definition: MettDeamon.h:352
Definition: MettDeamon.h:358
Definition: MettDeamon.h:105
Definition: MettDeamon.h:114
Definition: MettDeamon.h:125
Definition: MettDeamon.h:100
Definition: MettDeamon.h:346
Definition: MettDeamon.h:324
Definition: MettDeamon.h:93
Definition: MettDeamon.h:87
Definition: FakedOptFFT.h:23