OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ZconstraintForceModifier.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45#include "constraints/ZconstraintForceModifier.hpp"
46
47#include <cmath>
48
49#ifdef IS_MPI
50#include <mpi.h>
51#endif
52
53#include "integrators/Integrator.hpp"
54#include "utils/Constants.hpp"
55#include "utils/StringUtils.hpp"
56#include "utils/simError.h"
57
58namespace OpenMD {
59
60 ZConstraintForceModifier::ZConstraintForceModifier(SimInfo* info) :
61 ForceModifier {info}, infiniteTime {1e31} {
62 Globals* simParam = info_->getSimParams();
63 currSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
64 currZconsTime_ = currSnapshot_->getTime();
65
66 if (simParam->haveDt()) {
67 dt_ = simParam->getDt();
68 } else {
69 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
70 "ZconstraintForceManager Error: dt is not set\n");
71 painCave.isFatal = 1;
72 simError();
73 }
74
75 if (simParam->haveZconsTime()) {
76 zconsTime_ = simParam->getZconsTime();
77 } else {
78 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
79 "ZconstraintForceManager error: If you use a ZConstraint,\n"
80 "\tyou must set zconsTime.\n");
81 painCave.isFatal = 1;
82 simError();
83 }
84
85 if (simParam->haveZconsTol()) {
86 zconsTol_ = simParam->getZconsTol();
87 } else {
88 zconsTol_ = 0.01;
89 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
90 "ZconstraintForceManager Warning: Tolerance for z-constraint "
91 "method is not specified.\n"
92 "\tOpenMD will use a default value of %f.\n"
93 "\tTo set the tolerance, use the zconsTol variable.\n",
94 zconsTol_);
95 painCave.isFatal = 0;
96 simError();
97 }
98
99 // set zcons gap
100 if (simParam->haveZconsGap()) {
101 usingZconsGap_ = true;
102 zconsGap_ = simParam->getZconsGap();
103 } else {
104 usingZconsGap_ = false;
105 zconsGap_ = 0.0;
106 }
107
108 // set zcons fixtime
109 if (simParam->haveZconsFixtime()) {
110 zconsFixingTime_ = simParam->getZconsFixtime();
111 } else {
112 zconsFixingTime_ = infiniteTime;
113 }
114
115 // set zconsUsingSMD
116 if (simParam->haveZconsUsingSMD()) {
117 usingSMD_ = simParam->getZconsUsingSMD();
118 } else {
119 usingSMD_ = false;
120 }
121
122 zconsOutput_ = getPrefix(info_->getFinalConfigFileName()) + ".fz";
123
124 // estimate the force constant of harmonical potential
125 Mat3x3d hmat = currSnapshot_->getHmat();
126 RealType halfOfLargestBox =
127 std::max(hmat(0, 0), std::max(hmat(1, 1), hmat(2, 2))) / 2;
128 RealType targetTemp;
129 if (simParam->haveTargetTemp()) {
130 targetTemp = simParam->getTargetTemp();
131 } else {
132 targetTemp = 298.0;
133 }
134 RealType zforceConstant =
135 Constants::kb * targetTemp / (halfOfLargestBox * halfOfLargestBox);
136
137 int nZconstraints = simParam->getNZconsStamps();
138 std::vector<ZConsStamp*> stamp = simParam->getZconsStamps();
139
140 for (int i = 0; i < nZconstraints; i++) {
141 ZconstraintParam param;
142 int zmolIndex = stamp[i]->getMolIndex();
143 if (stamp[i]->haveZpos()) {
144 param.zTargetPos = stamp[i]->getZpos();
145 } else {
146 param.zTargetPos = getZTargetPos(zmolIndex);
147 }
148
149 param.kz = zforceConstant * stamp[i]->getKratio();
150
151 if (stamp[i]->haveCantVel()) {
152 param.cantVel = stamp[i]->getCantVel();
153 } else {
154 param.cantVel = 0.0;
155 }
156
157 allZMolIndices_.insert(std::make_pair(zmolIndex, param));
158 }
159
160 // create fixedMols_, movingMols_ and unconsMols lists
161 update();
162
163 // calculate mass of unconstrained molecules in the whole system
164 // (never changes during the simulation)
165
166 totMassUnconsMols_ = 0.0;
167 std::vector<Molecule*>::iterator j;
168 for (j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
169 totMassUnconsMols_ += (*j)->getMass();
170 }
171#ifdef IS_MPI
172 MPI_Allreduce(MPI_IN_PLACE, &totMassUnconsMols_, 1, MPI_REALTYPE, MPI_SUM,
173 MPI_COMM_WORLD);
174#endif
175
176 // Zero out the velocities of center of mass of unconstrained
177 // molecules and the velocities of center of mass of every single
178 // z-constrained molecueles
179 zeroVelocity();
180
181 // create zconsWriter
182 fzOut = new ZConsWriter(info_, zconsOutput_.c_str());
183
184 if (!fzOut) {
185 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
186 "ZconstraintForceManager:: Failed to create ZConsWriter\n");
187 painCave.isFatal = 1;
188 simError();
189 }
190 }
191
192 ZConstraintForceModifier::~ZConstraintForceModifier() { delete fzOut; }
193
194 RealType ZConstraintForceModifier::getZTargetPos(int index) {
195 RealType zTargetPos;
196#ifndef IS_MPI
197 Molecule* mol = info_->getMoleculeByGlobalIndex(index);
198 assert(mol);
199 Vector3d com = mol->getCom();
200 zTargetPos = com[whichDirection];
201#else
202 int whichProc = info_->getMolToProc(index);
203 if (whichProc == worldRank) {
204 Molecule* mol = info_->getMoleculeByGlobalIndex(index);
205 Vector3d com = mol->getCom();
206 zTargetPos = com[whichDirection];
207 MPI_Bcast(&zTargetPos, 1, MPI_REALTYPE, whichProc, MPI_COMM_WORLD);
208 } else {
209 MPI_Bcast(&zTargetPos, 1, MPI_REALTYPE, whichProc, MPI_COMM_WORLD);
210 }
211#endif
212 return zTargetPos;
213 }
214
215 void ZConstraintForceModifier::update() {
216 fixedZMols_.clear();
217 movingZMols_.clear();
218 unzconsMols_.clear();
219
220 for (std::map<int, ZconstraintParam>::iterator i = allZMolIndices_.begin();
221 i != allZMolIndices_.end(); ++i) {
222#ifdef IS_MPI
223 if (info_->getMolToProc(i->first) == worldRank) {
224#endif
225 ZconstraintMol zmol;
226 zmol.mol = info_->getMoleculeByGlobalIndex(i->first);
227 assert(zmol.mol);
228 zmol.param = i->second;
229 zmol.cantPos = zmol.param.zTargetPos; /**@todo fix me when
230 zmol migrates, it is
231 incorrect*/
232 Vector3d com = zmol.mol->getCom();
233 Vector3d d = Vector3d(0.0, 0.0, zmol.param.zTargetPos) - com;
234 currSnapshot_->wrapVector(d);
235 RealType diff = fabs(d[whichDirection]);
236
237 if (diff < zconsTol_) {
238 fixedZMols_.push_back(zmol);
239 } else {
240 movingZMols_.push_back(zmol);
241 }
242
243#ifdef IS_MPI
244 }
245#endif
246 }
247
248 calcTotalMassMovingZMols();
249
250 std::set<int> zmolSet;
251 for (std::list<ZconstraintMol>::iterator i = movingZMols_.begin();
252 i != movingZMols_.end(); ++i) {
253 zmolSet.insert(i->mol->getGlobalIndex());
254 }
255
256 for (std::list<ZconstraintMol>::iterator i = fixedZMols_.begin();
257 i != fixedZMols_.end(); ++i) {
258 zmolSet.insert(i->mol->getGlobalIndex());
259 }
260
261 SimInfo::MoleculeIterator mi;
262 Molecule* mol;
263 for (mol = info_->beginMolecule(mi); mol != NULL;
264 mol = info_->nextMolecule(mi)) {
265 if (zmolSet.find(mol->getGlobalIndex()) == zmolSet.end()) {
266 unzconsMols_.push_back(mol);
267 }
268 }
269 }
270
271 void ZConstraintForceModifier::calcTotalMassMovingZMols() {
272 totMassMovingZMols_ = 0.0;
273 std::list<ZconstraintMol>::iterator i;
274 for (i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
275 totMassMovingZMols_ += i->mol->getMass();
276 }
277
278#ifdef IS_MPI
279 MPI_Allreduce(MPI_IN_PLACE, &totMassMovingZMols_, 1, MPI_REALTYPE, MPI_SUM,
280 MPI_COMM_WORLD);
281#endif
282 }
283
284 bool ZConstraintForceModifier::isZMol(Molecule* mol) {
285 return allZMolIndices_.find(mol->getGlobalIndex()) ==
286 allZMolIndices_.end() ?
287 false :
288 true;
289 }
290
291 void ZConstraintForceModifier::modifyForces() {
292 currSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
293
294 if (usingZconsGap_) { updateZPos(); }
295
296 if (checkZConsState()) {
297 calcTotalMassMovingZMols();
298 zeroVelocity();
299 }
300
301 // do zconstraint force;
302 if (haveFixedZMols()) { doZconstraintForce(); }
303
304 // use external force to move the molecules to the specified positions
305 if (haveMovingZMols()) { doHarmonic(); }
306
307 // write out forces and current positions of z-constraint molecules
308 if (currSnapshot_->getTime() >= currZconsTime_) {
309 std::list<ZconstraintMol>::iterator i;
310 Vector3d com;
311 for (i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
312 com = i->mol->getCom();
313 i->zpos = com[whichDirection];
314 }
315
316 fzOut->writeFZ(fixedZMols_);
317 currZconsTime_ += zconsTime_;
318 }
319 }
320
321 void ZConstraintForceModifier::updateZPos() {
322 std::list<ZconstraintMol>::iterator i;
323 for (i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
324 i->param.zTargetPos += zconsGap_;
325 }
326 }
327
328 bool ZConstraintForceModifier::checkZConsState() {
329 Vector3d com;
330 RealType diff;
331 int changed = 0;
332
333 std::list<ZconstraintMol>::iterator i;
334 std::list<ZconstraintMol>::iterator j;
335
336 std::list<ZconstraintMol> newMovingZMols;
337 for (i = fixedZMols_.begin(); i != fixedZMols_.end();) {
338 com = i->mol->getCom();
339 Vector3d d = com - Vector3d(0.0, 0.0, i->param.zTargetPos);
340 currSnapshot_->wrapVector(d);
341
342 RealType diff = fabs(d[whichDirection]);
343
344 if (diff > zconsTol_) {
345 if (usingZconsGap_) { i->endFixingTime = infiniteTime; }
346 j = i++;
347 newMovingZMols.push_back(*j);
348 fixedZMols_.erase(j);
349 changed = 1;
350 } else {
351 ++i;
352 }
353 }
354
355 std::list<ZconstraintMol> newFixedZMols;
356 for (i = movingZMols_.begin(); i != movingZMols_.end();) {
357 com = i->mol->getCom();
358 Vector3d d = com - Vector3d(0.0, 0.0, i->param.zTargetPos);
359 currSnapshot_->wrapVector(d);
360 diff = fabs(d[whichDirection]);
361
362 if (diff <= zconsTol_) {
363 if (usingZconsGap_) {
364 i->endFixingTime = currSnapshot_->getTime() + zconsFixingTime_;
365 }
366 // This moving zconstraint molecule is now fixed
367 j = i++;
368 newFixedZMols.push_back(*j);
369 movingZMols_.erase(j);
370 changed = 1;
371 } else {
372 ++i;
373 }
374 }
375
376 // merge the lists
377 fixedZMols_.insert(fixedZMols_.end(), newFixedZMols.begin(),
378 newFixedZMols.end());
379 movingZMols_.insert(movingZMols_.end(), newMovingZMols.begin(),
380 newMovingZMols.end());
381
382#ifdef IS_MPI
383 MPI_Allreduce(MPI_IN_PLACE, &changed, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
384#endif
385
386 return (changed > 0);
387 }
388
389 void ZConstraintForceModifier::zeroVelocity() {
390 Vector3d comVel;
391 Vector3d vel;
392 std::list<ZconstraintMol>::iterator i;
393 Molecule* mol;
394 StuntDouble* sd;
395 Molecule::IntegrableObjectIterator ii;
396
397 // Zero out the velocities of center of mass of fixed
398 // z-constrained molecules
399 for (i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
400 mol = i->mol;
401 comVel = mol->getComVel();
402
403 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
404 sd = mol->nextIntegrableObject(ii)) {
405 vel = sd->getVel();
406 vel[whichDirection] -= comVel[whichDirection];
407 sd->setVel(vel);
408 }
409 }
410
411 // Calculate the vz of center of mass of moving molecules
412 // (including unconstrained molecules and moving z-constrained
413 // molecules)
414
415 RealType pzMovingMols = 0.0;
416
417 for (i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
418 mol = i->mol;
419 comVel = mol->getComVel();
420 pzMovingMols += mol->getMass() * comVel[whichDirection];
421 }
422
423 std::vector<Molecule*>::iterator j;
424 for (j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
425 mol = *j;
426 comVel = mol->getComVel();
427 pzMovingMols += mol->getMass() * comVel[whichDirection];
428 }
429
430#ifdef IS_MPI
431 MPI_Allreduce(MPI_IN_PLACE, &pzMovingMols, 1, MPI_REALTYPE, MPI_SUM,
432 MPI_COMM_WORLD);
433#endif
434
435 RealType vzMovingMols =
436 pzMovingMols / (totMassMovingZMols_ + totMassUnconsMols_);
437
438 // Modify the velocities of moving z-constrained molecules
439
440 for (i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
441 mol = i->mol;
442
443 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
444 sd = mol->nextIntegrableObject(ii)) {
445 vel = sd->getVel();
446 vel[whichDirection] -= vzMovingMols;
447 sd->setVel(vel);
448 }
449 }
450
451 // Modify the velocites of unconstrained molecules
452 for (j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
453 mol = *j;
454
455 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
456 sd = mol->nextIntegrableObject(ii)) {
457 vel = sd->getVel();
458 vel[whichDirection] -= vzMovingMols;
459 sd->setVel(vel);
460 }
461 }
462 }
463
464 bool ZConstraintForceModifier::haveFixedZMols() {
465 int haveFixed = fixedZMols_.empty() ? 0 : 1;
466
467#ifdef IS_MPI
468 MPI_Allreduce(MPI_IN_PLACE, &haveFixed, 1, MPI_INT, MPI_SUM,
469 MPI_COMM_WORLD);
470#endif
471
472 return haveFixed > 0;
473 }
474
475 /// Constrains the molecules which have reached their specified
476 /// positions.
477 void ZConstraintForceModifier::doZconstraintForce() {
478 RealType totalFZ(0.0);
479
480 // Calculate the total z-contraint force on the fixed molecules:
481
482 std::list<ZconstraintMol>::iterator i;
483 Molecule* mol;
484 StuntDouble* sd;
485 Molecule::IntegrableObjectIterator ii;
486
487 for (i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
488 mol = i->mol;
489 i->fz = 0.0;
490
491 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
492 sd = mol->nextIntegrableObject(ii)) {
493 i->fz += (sd->getFrc())[whichDirection];
494 }
495
496 totalFZ += i->fz;
497 }
498
499#ifdef IS_MPI
500 // collect the total z-constraint force
501 MPI_Allreduce(MPI_IN_PLACE, &totalFZ, 1, MPI_REALTYPE, MPI_SUM,
502 MPI_COMM_WORLD);
503#endif
504
505 // apply negative force to fixed z-constrained molecules:
506 for (i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
507 mol = i->mol;
508
509 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
510 sd = mol->nextIntegrableObject(ii)) {
511 Vector3d force(0.0);
512 force[whichDirection] = -getZFOfFixedZMols(mol, sd, i->fz);
513
514 sd->addFrc(force);
515 }
516 }
517
518 // modify the forces of the currently moving z-constrained
519 // molecules so that system stays fixed:
520 for (i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
521 mol = i->mol;
522
523 Vector3d force(0.0);
524 force[whichDirection] = -getZFOfMovingMols(mol, totalFZ);
525
526 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
527 sd = mol->nextIntegrableObject(ii)) {
528 sd->addFrc(force);
529 }
530 }
531
532 // modify the forces of unconstrained molecules so that the system
533 // stays fixed:
534 std::vector<Molecule*>::iterator j;
535 for (j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
536 mol = *j;
537
538 Vector3d force(0.0);
539 force[whichDirection] = -getZFOfMovingMols(mol, totalFZ);
540
541 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
542 sd = mol->nextIntegrableObject(ii)) {
543 sd->addFrc(force);
544 }
545 }
546 }
547
548 /// Calculates how to distribute constraint force onto StuntDoubles
549 /// in a constrained molecule.
550 RealType ZConstraintForceModifier::getZFOfFixedZMols(Molecule* mol,
551 StuntDouble* sd,
552 RealType totalForce) {
553 return totalForce * sd->getMass() / mol->getMass();
554 }
555
556 /// Calculates how to distribute constraint forces onto
557 /// unconstrained or moving molecules.
558 RealType ZConstraintForceModifier::getZFOfMovingMols(Molecule* mol,
559 RealType totalForce) {
560 return totalForce * mol->getMass() /
561 (totMassUnconsMols_ + totMassMovingZMols_);
562 }
563
564 bool ZConstraintForceModifier::haveMovingZMols() {
565 int haveMoving = movingZMols_.empty() ? 0 : 1;
566
567#ifdef IS_MPI
568 MPI_Allreduce(MPI_IN_PLACE, &haveMoving, 1, MPI_INT, MPI_SUM,
569 MPI_COMM_WORLD);
570#endif
571
572 return haveMoving > 0;
573 }
574
575 /// Applies a restraint force to the molecules which are not at
576 /// their specified positions.
577 void ZConstraintForceModifier::doHarmonic() {
578 RealType totalFZ(0.0);
579 Vector3d force(0.0);
580 Vector3d com;
581 RealType restPot(0.0);
582 std::list<ZconstraintMol>::iterator i;
583 StuntDouble* sd;
584 Molecule::IntegrableObjectIterator ii;
585 Molecule* mol;
586
587 RealType pe = currSnapshot_->getPotentialEnergy();
588 currSnapshot_->setRawPotential(pe);
589
590 for (i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
591 mol = i->mol;
592 Vector3d com = mol->getCom();
593 RealType resPos = usingSMD_ ? i->cantPos : i->param.zTargetPos;
594 Vector3d d = com - Vector3d(0.0, 0.0, resPos);
595 currSnapshot_->wrapVector(d);
596
597 RealType diff = d[whichDirection];
598
599 restPot += 0.5 * i->param.kz * diff * diff;
600
601 RealType harmonicF = -(i->param.kz * diff);
602 totalFZ += harmonicF;
603
604 // adjust force
605 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
606 sd = mol->nextIntegrableObject(ii)) {
607 force[whichDirection] = getHFOfFixedZMols(mol, sd, harmonicF);
608 sd->addFrc(force);
609 }
610 }
611
612#ifdef IS_MPI
613 MPI_Allreduce(MPI_IN_PLACE, &restPot, 1, MPI_REALTYPE, MPI_SUM,
614 MPI_COMM_WORLD);
615 MPI_Allreduce(MPI_IN_PLACE, &totalFZ, 1, MPI_REALTYPE, MPI_SUM,
616 MPI_COMM_WORLD);
617#endif
618
619 RealType rp = currSnapshot_->getRestraintPotential();
620 currSnapshot_->setRestraintPotential(rp + restPot);
621
622 currSnapshot_->setPotentialEnergy(pe + restPot);
623
624 // modify the forces of unconstrained molecules
625 std::vector<Molecule*>::iterator j;
626 for (j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
627 mol = *j;
628 force[whichDirection] = getHFOfUnconsMols(mol, totalFZ);
629
630 for (sd = mol->beginIntegrableObject(ii); sd != NULL;
631 sd = mol->nextIntegrableObject(ii)) {
632 sd->addFrc(force);
633 }
634 }
635 }
636
637 RealType ZConstraintForceModifier::getHFOfFixedZMols(Molecule* mol,
638 StuntDouble* sd,
639 RealType totalForce) {
640 return totalForce * sd->getMass() / mol->getMass();
641 }
642
643 RealType ZConstraintForceModifier::getHFOfUnconsMols(Molecule* mol,
644 RealType totalForce) {
645 return totalForce * mol->getMass() / totMassUnconsMols_;
646 }
647
648 // void ZConstraintForceModifier::updateCantPos() {
649 // std::list<ZconstraintMol>::iterator i;
650 // for (i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
651 // i->cantPos += i->param.cantVel * dt_;
652 // }
653 // }
654} // namespace OpenMD
Abstract class for external ForceModifier classes.
RealType getMass()
get total mass of this molecule
Definition Molecule.cpp:266
int getGlobalIndex()
Returns the global index of this molecule.
Definition Molecule.hpp:107
Vector3d getComVel()
Returns the velocity of center of mass of this molecule.
Definition Molecule.cpp:351
Vector3d getCom()
Returns the current center of mass position of this molecule.
Definition Molecule.cpp:298
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:93
Molecule * getMoleculeByGlobalIndex(int index)
Finds a molecule with a specified global index.
Definition SimInfo.hpp:300
int getMolToProc(int globalIndex)
Finds the processor where a molecule resides.
Definition SimInfo.hpp:667
Molecule * beginMolecule(MoleculeIterator &i)
Returns the first molecule in this SimInfo and intialize the iterator.
Definition SimInfo.cpp:240
Molecule * nextMolecule(MoleculeIterator &i)
Returns the next avaliable Molecule based on the iterator.
Definition SimInfo.cpp:245
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
Definition SimInfo.hpp:248
void wrapVector(Vector3d &v)
Wrapping the vector according to periodic boundary condition.
Definition Snapshot.cpp:337
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
"Don't move, or you're dead! Stand up! Captain, we've got them!"
Vector3d getVel()
Returns the current velocity of this stuntDouble.
RealType getMass()
Returns the mass of this stuntDouble.
void setVel(const Vector3d &vel)
Sets the current velocity of this stuntDouble.
Vector3d getFrc()
Returns the current force of this stuntDouble.
void addFrc(const Vector3d &frc)
Adds force into the current force of this stuntDouble.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)
RealType zTargetPos
target zconstraint position
RealType kz
force constant
RealType cantVel
The velocity of cantilever.