45#include "integrators/Integrator.hpp"
50#include "brains/Snapshot.hpp"
51#include "flucq/FluctuatingChargeDamped.hpp"
52#include "flucq/FluctuatingChargeLangevin.hpp"
53#include "flucq/FluctuatingChargeNVE.hpp"
54#include "flucq/FluctuatingChargeNVT.hpp"
55#include "integrators/DLM.hpp"
56#include "rnemd/MethodFactory.hpp"
57#include "rnemd/RNEMD.hpp"
58#include "rnemd/SPFForceManager.hpp"
59#include "utils/CI_String.hpp"
60#include "utils/CaseConversion.hpp"
61#include "utils/simError.h"
65 Integrator::Integrator(
SimInfo* info) :
66 info_(info), forceMan_(NULL), rotAlgo_(NULL), flucQ_(NULL), rattle_(NULL),
67 velocitizer_(nullptr), needPotential(false), needVirial(false),
68 needReset(false), needVelocityScaling(false), useRNEMD(false),
69 dumpWriter(NULL), statWriter(NULL), thermo(info_),
70 snap(info_->getSnapshotManager()->getCurrentSnapshot()) {
71 simParams = info->getSimParams();
73 if (simParams->haveDt()) {
74 dt = simParams->getDt();
77 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
78 "Integrator Error: dt is not set\n");
83 if (simParams->haveRunTime()) {
84 runTime = simParams->getRunTime();
86 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
87 "Integrator Error: runTime is not set\n");
93 if (simParams->haveSampleTime()) {
94 sampleTime = simParams->getSampleTime();
95 statusTime = sampleTime;
97 sampleTime = simParams->getRunTime();
98 statusTime = sampleTime;
101 if (simParams->haveStatusTime()) {
102 statusTime = simParams->getStatusTime();
105 if (simParams->haveThermalTime()) {
106 thermalTime = simParams->getThermalTime();
108 thermalTime = simParams->getRunTime();
111 if (!simParams->getUseInitalTime()) { snap->setTime(0.0); }
113 if (simParams->haveResetTime()) {
115 resetTime = simParams->getResetTime();
119 needVelocityScaling =
false;
120 if (simParams->haveTempSet()) {
121 needVelocityScaling = simParams->getTempSet();
124 if (needVelocityScaling) {
125 if (simParams->haveTargetTemp()) {
126 targetScalingTemp = simParams->getTargetTemp();
128 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
129 "Integrator Error: Target Temperature must be set to turn on "
131 painCave.isFatal = 1;
138 velocitizer_ = std::make_unique<Velocitizer>(info);
140 if (simParams->getRNEMDParameters()->haveUseRNEMD()) {
141 useRNEMD = simParams->getRNEMDParameters()->getUseRNEMD();
145 if (Utils::traits_cast<Utils::ci_char_traits>(
146 simParams->getRNEMDParameters()->getMethod()) ==
"SPF") {
147 if (toUpperCopy(simParams->getEnsemble()) !=
"SPF") {
148 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
149 "The SPF RNEMD method requires the SPF Ensemble.\n");
150 painCave.isFatal = 1;
154 forceMan_ =
new RNEMD::SPFForceManager(info);
157 RNEMD::MethodFactory rnemdMethod {
158 simParams->getRNEMDParameters()->getMethod()};
159 rnemd_ = rnemdMethod.create(info, forceMan_);
161 if (simParams->getRNEMDParameters()->haveExchangeTime()) {
163 simParams->getRNEMDParameters()->getExchangeTime();
166 RealType newET = ceil(RNEMD_exchangeTime / dt) * dt;
167 if (fabs(newET - RNEMD_exchangeTime) > 1e-6) {
168 RNEMD_exchangeTime = newET;
174 if (forceMan_ == NULL) forceMan_ =
new ForceManager(info);
176 rotAlgo_ =
new DLM();
177 rattle_ =
new Rattle(info);
179 if (simParams->getFluctuatingChargeParameters()->havePropagator()) {
180 std::string prop = toUpperCopy(
181 simParams->getFluctuatingChargeParameters()->getPropagator());
182 if (prop.compare(
"NVT") == 0) {
184 }
else if (prop.compare(
"NVE") == 0) {
186 }
else if (prop.compare(
"LANGEVIN") == 0) {
188 }
else if (prop.compare(
"DAMPED") == 0) {
191 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
192 "Integrator Error: Unknown Fluctuating Charge propagator (%s) "
194 simParams->getFluctuatingChargeParameters()
197 painCave.isFatal = 1;
201 flucQ_->setForceManager(forceMan_);
214 void Integrator::updateSizes() {
216 flucQ_->updateSizes();
219 void Integrator::setVelocitizer(std::unique_ptr<Velocitizer> velocitizer) {
220 velocitizer_ = std::move(velocitizer);
223 void Integrator::setFluctuatingChargePropagator(
225 if (prop != flucQ_ && flucQ_ != NULL) {
delete flucQ_; }
227 if (forceMan_ != NULL) { flucQ_->setForceManager(forceMan_); }
231 if (algo != rotAlgo_ && rotAlgo_ != NULL) {
delete rotAlgo_; }
236 void Integrator::setRNEMD(std::unique_ptr<RNEMD::RNEMD> rnemd) {
237 rnemd_ = std::move(rnemd);
240 void Integrator::integrate() {
243 while (snap->getTime() <= runTime) {
252 void Integrator::saveConservedQuantity() {
253 snap->setConservedQuantity(calcConservedQuantity());
256 void Integrator::initialize() {
261 if(simParams->getConserveLinearMomentum())
262 velocitizer_->removeComDrift();
265 flucQ_->initialize();
270 if (info_->getNGlobalConstraints() > 0) {
271 rattle_->constraintA();
273 rattle_->constraintB();
278 if (needVelocityScaling) { velocitizer_->randomize(targetScalingTemp); }
280 dumpWriter = createDumpWriter();
281 statWriter = createStatWriter();
282 dumpWriter->writeDumpAndEor();
284 progressBar = std::make_unique<ProgressBar>();
287 saveConservedQuantity();
288 stats->collectStats();
290 if (useRNEMD) rnemd_->getStarted();
292 statWriter->writeStat();
294 currSample = sampleTime + snap->getTime();
295 currStatus = statusTime + snap->getTime();
296 currThermal = thermalTime + snap->getTime();
297 if (needReset) { currReset = resetTime + snap->getTime(); }
298 if (useRNEMD) { currRNEMD = RNEMD_exchangeTime + snap->getTime(); }
299 needPotential =
false;
303 void Integrator::preStep() {
304 RealType difference = snap->getTime() + dt - currStatus;
306 if (difference > 0 || fabs(difference) <= OpenMD::epsilon) {
307 needPotential =
true;
312 void Integrator::calcForce() {
313 forceMan_->calcForces();
314 flucQ_->applyConstraints();
317 void Integrator::postStep() {
320 saveConservedQuantity();
322 if (needVelocityScaling) {
323 difference = snap->getTime() - currThermal;
325 if (difference > 0 || fabs(difference) <= OpenMD::epsilon) {
326 velocitizer_->randomize(targetScalingTemp);
327 currThermal += thermalTime;
332 difference = snap->getTime() - currRNEMD;
334 if (difference > 0 || fabs(difference) <= OpenMD::epsilon) {
336 currRNEMD += RNEMD_exchangeTime;
338 rnemd_->collectData();
341 difference = snap->getTime() - currSample;
343 if (difference > 0 || fabs(difference) <= OpenMD::epsilon) {
344 dumpWriter->writeDumpAndEor();
345 currSample += sampleTime;
348 difference = snap->getTime() - currStatus;
350 if (difference > 0 || fabs(difference) <= OpenMD::epsilon) {
351 stats->collectStats();
353 if (useRNEMD) { rnemd_->writeOutputFile(); }
355 statWriter->writeStat();
357 progressBar->setStatus(snap->getTime(), runTime);
358 progressBar->update();
360 needPotential =
false;
362 currStatus += statusTime;
365 difference = snap->getTime() - currReset;
367 if (needReset && (difference > 0 || fabs(difference) <= OpenMD::epsilon)) {
369 currReset += resetTime;
375 snap->increaseTime(dt);
378 void Integrator::finalize() {
379 dumpWriter->writeEor();
380 if (useRNEMD) { rnemd_->writeOutputFile(); }
381 progressBar->setStatus(runTime, runTime);
382 progressBar->update();
384 statWriter->writeStatReport();
390 stats =
new Stats(info_);
391 statWriter =
new StatWriter(info_->getStatFileName(), stats);
392 statWriter->setReportFileName(info_->getReportFileName());
abstract class for propagating fluctuating charge variables
ForceManager is responsible for calculating both the short range (bonded) interactions and long range...
virtual ~Integrator()
Default Destructor.
virtual void step()=0
Computes an integration step from t to t+dt.
Velocity Verlet Constraint Algorithm.
abstract class for rotation
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
A configurable Statistics Writer.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.