ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/constraints/Shake.cpp
Revision: 1983
Committed: Tue Apr 15 20:36:19 2014 UTC (11 years ago) by gezelter
File size: 9536 byte(s)
Log Message:
Fixes for ConstraintWriter in parallel, some cppcheck cleanup
starting preparation for 2.2 release

File Contents

# User Rev Content
1 gezelter 1748 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     *
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31     *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38 gezelter 1879 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 gezelter 1748 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41     */
42    
43     #include "constraints/Shake.hpp"
44     #include "primitives/Molecule.hpp"
45     #include "utils/simError.h"
46     namespace OpenMD {
47    
48 gezelter 1983 Shake::Shake(SimInfo* info) : info_(info), maxConsIteration_(10),
49     consTolerance_(1.0e-6), doShake_(false),
50     currConstraintTime_(0.0) {
51 gezelter 1748
52 gezelter 1982 if (info_->getNGlobalConstraints() > 0)
53 gezelter 1748 doShake_ = true;
54    
55 gezelter 1982 Globals* simParams = info_->getSimParams();
56    
57 gezelter 1748 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
58 gezelter 1982 if (simParams->haveConstraintTime()){
59     constraintTime_ = simParams->getConstraintTime();
60     } else {
61     constraintTime_ = simParams->getStatusTime();
62     }
63    
64 gezelter 1983 constraintOutputFile_ = getPrefix(info_->getFinalConfigFileName()) +
65     ".constraintForces";
66 gezelter 1982
67     // create ConstraintWriter
68 gezelter 1983 constraintWriter_ = new ConstraintWriter(info_,
69     constraintOutputFile_.c_str());
70 gezelter 1982
71     if (!constraintWriter_){
72     sprintf(painCave.errMsg, "Failed to create ConstraintWriter\n");
73     painCave.isFatal = 1;
74     simError();
75     }
76 gezelter 1748 }
77    
78     void Shake::constraintR() {
79     if (!doShake_) return;
80     doConstraint(&Shake::constraintPairR);
81     }
82     void Shake::constraintF() {
83     if (!doShake_) return;
84     doConstraint(&Shake::constraintPairF);
85 gezelter 1982
86     if (currentSnapshot_->getTime() >= currConstraintTime_){
87     Molecule* mol;
88     SimInfo::MoleculeIterator mi;
89     ConstraintPair* consPair;
90     Molecule::ConstraintPairIterator cpi;
91     std::list<ConstraintPair*> constraints;
92     for (mol = info_->beginMolecule(mi); mol != NULL;
93     mol = info_->nextMolecule(mi)) {
94     for (consPair = mol->beginConstraintPair(cpi); consPair != NULL;
95     consPair = mol->nextConstraintPair(cpi)) {
96    
97     constraints.push_back(consPair);
98     }
99     }
100    
101     constraintWriter_->writeConstraintForces(constraints);
102     currConstraintTime_ += constraintTime_;
103     }
104 gezelter 1748 }
105    
106     void Shake::doConstraint(ConstraintPairFuncPtr func) {
107     if (!doShake_) return;
108    
109     Molecule* mol;
110     SimInfo::MoleculeIterator mi;
111     ConstraintElem* consElem;
112     Molecule::ConstraintElemIterator cei;
113     ConstraintPair* consPair;
114     Molecule::ConstraintPairIterator cpi;
115    
116 gezelter 1982 for (mol = info_->beginMolecule(mi); mol != NULL;
117     mol = info_->nextMolecule(mi)) {
118     for (consElem = mol->beginConstraintElem(cei); consElem != NULL;
119     consElem = mol->nextConstraintElem(cei)) {
120 gezelter 1748 consElem->setMoved(true);
121     consElem->setMoving(false);
122     }
123     }
124    
125     //main loop of constraint algorithm
126     bool done = false;
127     int iteration = 0;
128     while(!done && iteration < maxConsIteration_){
129     done = true;
130    
131     //loop over every constraint pair
132    
133 gezelter 1982 for (mol = info_->beginMolecule(mi); mol != NULL;
134     mol = info_->nextMolecule(mi)) {
135     for (consPair = mol->beginConstraintPair(cpi); consPair != NULL;
136     consPair = mol->nextConstraintPair(cpi)) {
137    
138 gezelter 1748
139     //dispatch constraint algorithm
140     if(consPair->isMoved()) {
141     int exeStatus = (this->*func)(consPair);
142    
143     switch(exeStatus){
144     case consFail:
145     sprintf(painCave.errMsg,
146 gezelter 1982 "Constraint failure in Shake::constrainA, "
147     "Constraint Fail\n");
148 gezelter 1748 painCave.isFatal = 1;
149     simError();
150    
151     break;
152     case consSuccess:
153 gezelter 1982 // constrain the pair by moving two elements
154 gezelter 1748 done = false;
155     consPair->getConsElem1()->setMoving(true);
156     consPair->getConsElem2()->setMoving(true);
157     break;
158     case consAlready:
159 gezelter 1982 // current pair is already constrained, do not need to
160     // move the elements
161 gezelter 1748 break;
162     default:
163 gezelter 1982 sprintf(painCave.errMsg, "ConstraintAlgorithm::doConstraint() "
164     "Error: unrecognized status");
165 gezelter 1748 painCave.isFatal = 1;
166     simError();
167     break;
168     }
169     }
170     }
171     }//end for(iter->first())
172    
173    
174 gezelter 1982 for (mol = info_->beginMolecule(mi); mol != NULL;
175     mol = info_->nextMolecule(mi)) {
176     for (consElem = mol->beginConstraintElem(cei); consElem != NULL;
177     consElem = mol->nextConstraintElem(cei)) {
178 gezelter 1748 consElem->setMoved(consElem->getMoving());
179     consElem->setMoving(false);
180     }
181     }
182    
183     iteration++;
184     }//end while
185    
186     if (!done){
187     sprintf(painCave.errMsg,
188 gezelter 1982 "Constraint failure in Shake::constrainA, "
189     "too many iterations: %d\n",
190 gezelter 1748 iteration);
191     painCave.isFatal = 1;
192     simError();
193     }
194     }
195    
196     /**
197     * remove constraint force along the bond direction
198     */
199     int Shake::constraintPairR(ConstraintPair* consPair){
200    
201     ConstraintElem* consElem1 = consPair->getConsElem1();
202     ConstraintElem* consElem2 = consPair->getConsElem2();
203    
204     Vector3d posA = consElem1->getPos();
205     Vector3d posB = consElem2->getPos();
206    
207     Vector3d pab = posA -posB;
208    
209     //periodic boundary condition
210    
211     currentSnapshot_->wrapVector(pab);
212    
213     RealType pabsq = pab.lengthSquare();
214    
215     RealType rabsq = consPair->getConsDistSquare();
216     RealType diffsq = rabsq - pabsq;
217    
218     // the original rattle code from alan tidesley
219     if (fabs(diffsq) > (consTolerance_ * rabsq * 2)){
220    
221     Vector3d oldPosA = consElem1->getPrevPos();
222     Vector3d oldPosB = consElem2->getPrevPos();
223    
224     Vector3d rab = oldPosA - oldPosB;
225    
226     currentSnapshot_->wrapVector(rab);
227    
228     RealType rpab = dot(rab, pab);
229     RealType rpabsq = rpab * rpab;
230    
231     if (rpabsq < (rabsq * -diffsq)){
232     return consFail;
233     }
234    
235     RealType rma = 1.0 / consElem1->getMass();
236     RealType rmb = 1.0 / consElem2->getMass();
237    
238     RealType gab = diffsq / (2.0 * (rma + rmb) * rpab);
239    
240     Vector3d delta = rab * gab;
241    
242     //set atom1's position
243     posA += rma * delta;
244     consElem1->setPos(posA);
245    
246     //set atom2's position
247     posB -= rmb * delta;
248     consElem2->setPos(posB);
249 gezelter 1982
250     // report the constraint force back to the constraint pair:
251     consPair->setConstraintForce(gab);
252 gezelter 1748 return consSuccess;
253     }
254     else
255     return consAlready;
256     }
257    
258     /**
259     * remove constraint force along the bond direction
260     */
261     int Shake::constraintPairF(ConstraintPair* consPair){
262     ConstraintElem* consElem1 = consPair->getConsElem1();
263     ConstraintElem* consElem2 = consPair->getConsElem2();
264    
265     Vector3d posA = consElem1->getPos();
266     Vector3d posB = consElem2->getPos();
267    
268     Vector3d rab = posA - posB;
269    
270     currentSnapshot_->wrapVector(rab);
271    
272     Vector3d frcA = consElem1->getFrc();
273     Vector3d frcB = consElem2->getFrc();
274    
275     RealType rma = 1.0 / consElem1->getMass();
276     RealType rmb = 1.0 / consElem2->getMass();
277    
278     Vector3d fpab = frcA * rma - frcB * rmb;
279    
280     RealType gab = fpab.lengthSquare();
281     if (gab < 1.0) gab = 1.0;
282    
283     RealType rabsq = rab.lengthSquare();
284     RealType rfab = dot(rab, fpab);
285    
286     if (fabs(rfab) > sqrt(rabsq*gab) * consTolerance_){
287     gab = -rfab / (rabsq * (rma + rmb));
288    
289     frcA += rab*gab;
290     frcB -= rab*gab;
291    
292     consElem1->setFrc(frcA);
293     consElem2->setFrc(frcB);
294    
295 gezelter 1982 // report the constraint force back to the constraint pair:
296     consPair->setConstraintForce(gab);
297 gezelter 1748 return consSuccess;
298     }
299     else
300     return consAlready;
301     }
302     }

Properties

Name Value
svn:eol-style native
svn:executable *