48#include "FluctuatingChargeLangevin.hpp"
53#include "utils/Constants.hpp"
54#include "utils/simError.h"
58 FluctuatingChargeLangevin::FluctuatingChargeLangevin(
SimInfo* info) :
60 snap_(info->getSnapshotManager()->getCurrentSnapshot()),
61 randNumGen_(info->getRandomNumberGenerator()) {}
63 void FluctuatingChargeLangevin::initialize() {
64 FluctuatingChargePropagator::initialize();
66 if (info_->getSimParams()->haveDt()) {
67 dt_ = info_->getSimParams()->getDt();
70 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
71 "FluctuatingChargeLangevin Error: dt is not set\n");
76 if (!fqParams_->haveTargetTemp()) {
77 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
78 "You can't use the FluctuatingChargeLangevin "
79 "propagator without a flucQ.targetTemp!\n");
81 painCave.severity = OPENMD_ERROR;
84 targetTemp_ = fqParams_->getTargetTemp();
89 if (!fqParams_->haveDragCoefficient()) {
90 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
91 "If you use the FluctuatingChargeLangevin\n"
92 "\tpropagator, you must set flucQ.dragCoefficient .\n");
94 painCave.severity = OPENMD_ERROR;
98 drag_ = fqParams_->getDragCoefficient();
103 std::sqrt(2.0 * Constants::kb * targetTemp_ * drag_ / dt_);
105 forceDistribution_ = std::normal_distribution<RealType>(0.0, stdDev);
108 void FluctuatingChargeLangevin::moveA() {
109 if (!hasFlucQ_)
return;
111 SimInfo::MoleculeIterator i;
112 Molecule::FluctuatingChargeIterator j;
115 RealType cvel, cpos, cfrc, cmass;
117 for (mol = info_->beginMolecule(i); mol != NULL;
118 mol = info_->nextMolecule(i)) {
119 for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
120 atom = mol->nextFluctuatingCharge(j)) {
121 cvel = atom->getFlucQVel();
122 cpos = atom->getFlucQPos();
123 cfrc = atom->getFlucQFrc();
124 cmass = atom->getChargeMass();
127 cvel += dt2_ * cfrc / cmass;
131 atom->setFlucQVel(cvel);
132 atom->setFlucQPos(cpos);
137 void FluctuatingChargeLangevin::applyConstraints() {
138 if (!hasFlucQ_)
return;
140 SimInfo::MoleculeIterator i;
141 Molecule::FluctuatingChargeIterator j;
144 RealType cvel, cfrc, cmass, randomForce, frictionForce;
145 RealType velStep, oldFF;
147 for (mol = info_->beginMolecule(i); mol != NULL;
148 mol = info_->nextMolecule(i)) {
149 for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
150 atom = mol->nextFluctuatingCharge(j)) {
151 randomForce = forceDistribution_(*randNumGen_);
152 atom->addFlucQFrc(randomForce);
161 cvel = atom->getFlucQVel();
166 cfrc = atom->getFlucQFrc();
167 cmass = atom->getChargeMass();
168 velStep = cvel + dt2_ * cfrc / cmass;
174 for (
int k = 0; k < maxIterNum_; k++) {
175 oldFF = frictionForce;
176 frictionForce = -drag_ * velStep;
179 velStep = cvel + dt2_ * (cfrc + frictionForce) / cmass;
183 if (fabs(frictionForce - oldFF) <= forceTolerance_)
186 atom->addFlucQFrc(frictionForce);
189 fqConstraints_->applyConstraints();
192 void FluctuatingChargeLangevin::moveB() {
193 if (!hasFlucQ_)
return;
194 SimInfo::MoleculeIterator i;
195 Molecule::FluctuatingChargeIterator j;
198 RealType cfrc, cvel, cmass;
200 for (mol = info_->beginMolecule(i); mol != NULL;
201 mol = info_->nextMolecule(i)) {
202 for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
203 atom = mol->nextFluctuatingCharge(j)) {
204 cvel = atom->getFlucQVel();
205 cfrc = atom->getFlucQFrc();
206 cmass = atom->getChargeMass();
209 cvel += (dt2_ * cfrc) / cmass;
211 atom->setFlucQVel(cvel);
abstract class for propagating fluctuating charge variables
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.