ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/constraints/Shake.cpp
Revision: 1879
Committed: Sun Jun 16 15:15:42 2013 UTC (11 years, 10 months ago) by gezelter
File size: 7762 byte(s)
Log Message:
MERGE OpenMD development 1783:1878 into trunk

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     Shake::Shake(SimInfo* info) : info_(info), maxConsIteration_(10), consTolerance_(1.0e-6), doShake_(false) {
49    
50     if (info_->getNConstraints() > 0)
51     doShake_ = true;
52    
53     currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
54     }
55    
56     void Shake::constraintR() {
57     if (!doShake_) return;
58     doConstraint(&Shake::constraintPairR);
59     }
60     void Shake::constraintF() {
61     if (!doShake_) return;
62     doConstraint(&Shake::constraintPairF);
63     }
64    
65     void Shake::doConstraint(ConstraintPairFuncPtr func) {
66     if (!doShake_) return;
67    
68     Molecule* mol;
69     SimInfo::MoleculeIterator mi;
70     ConstraintElem* consElem;
71     Molecule::ConstraintElemIterator cei;
72     ConstraintPair* consPair;
73     Molecule::ConstraintPairIterator cpi;
74    
75     for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
76     for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) {
77     consElem->setMoved(true);
78     consElem->setMoving(false);
79     }
80     }
81    
82     //main loop of constraint algorithm
83     bool done = false;
84     int iteration = 0;
85     while(!done && iteration < maxConsIteration_){
86     done = true;
87    
88     //loop over every constraint pair
89    
90     for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
91     for (consPair = mol->beginConstraintPair(cpi); consPair != NULL; consPair = mol->nextConstraintPair(cpi)) {
92    
93    
94     //dispatch constraint algorithm
95     if(consPair->isMoved()) {
96     int exeStatus = (this->*func)(consPair);
97    
98     switch(exeStatus){
99     case consFail:
100     sprintf(painCave.errMsg,
101     "Constraint failure in Shake::constrainA, Constraint Fail\n");
102     painCave.isFatal = 1;
103     simError();
104    
105     break;
106     case consSuccess:
107     //constrain the pair by moving two elements
108     done = false;
109     consPair->getConsElem1()->setMoving(true);
110     consPair->getConsElem2()->setMoving(true);
111     break;
112     case consAlready:
113     //current pair is already constrained, do not need to move the elements
114     break;
115     default:
116     sprintf(painCave.errMsg, "ConstraintAlgorithm::doConstrain() Error: unrecognized status");
117     painCave.isFatal = 1;
118     simError();
119     break;
120     }
121     }
122     }
123     }//end for(iter->first())
124    
125    
126     for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
127     for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) {
128     consElem->setMoved(consElem->getMoving());
129     consElem->setMoving(false);
130     }
131     }
132    
133     iteration++;
134     }//end while
135    
136     if (!done){
137     sprintf(painCave.errMsg,
138     "Constraint failure in Shake::constrainA, too many iterations: %d\n",
139     iteration);
140     painCave.isFatal = 1;
141     simError();
142     }
143     }
144    
145     /**
146     * remove constraint force along the bond direction
147     */
148     int Shake::constraintPairR(ConstraintPair* consPair){
149    
150     ConstraintElem* consElem1 = consPair->getConsElem1();
151     ConstraintElem* consElem2 = consPair->getConsElem2();
152    
153     Vector3d posA = consElem1->getPos();
154     Vector3d posB = consElem2->getPos();
155    
156     Vector3d pab = posA -posB;
157    
158     //periodic boundary condition
159    
160     currentSnapshot_->wrapVector(pab);
161    
162     RealType pabsq = pab.lengthSquare();
163    
164     RealType rabsq = consPair->getConsDistSquare();
165     RealType diffsq = rabsq - pabsq;
166    
167     // the original rattle code from alan tidesley
168     if (fabs(diffsq) > (consTolerance_ * rabsq * 2)){
169    
170     Vector3d oldPosA = consElem1->getPrevPos();
171     Vector3d oldPosB = consElem2->getPrevPos();
172    
173     Vector3d rab = oldPosA - oldPosB;
174    
175     currentSnapshot_->wrapVector(rab);
176    
177     RealType rpab = dot(rab, pab);
178     RealType rpabsq = rpab * rpab;
179    
180     if (rpabsq < (rabsq * -diffsq)){
181     return consFail;
182     }
183    
184     RealType rma = 1.0 / consElem1->getMass();
185     RealType rmb = 1.0 / consElem2->getMass();
186    
187     RealType gab = diffsq / (2.0 * (rma + rmb) * rpab);
188    
189     Vector3d delta = rab * gab;
190    
191     //set atom1's position
192     posA += rma * delta;
193     consElem1->setPos(posA);
194    
195     //set atom2's position
196     posB -= rmb * delta;
197     consElem2->setPos(posB);
198     return consSuccess;
199     }
200     else
201     return consAlready;
202     }
203    
204     /**
205     * remove constraint force along the bond direction
206     */
207     int Shake::constraintPairF(ConstraintPair* consPair){
208     ConstraintElem* consElem1 = consPair->getConsElem1();
209     ConstraintElem* consElem2 = consPair->getConsElem2();
210    
211     Vector3d posA = consElem1->getPos();
212     Vector3d posB = consElem2->getPos();
213    
214     Vector3d rab = posA - posB;
215    
216     currentSnapshot_->wrapVector(rab);
217    
218     Vector3d frcA = consElem1->getFrc();
219     Vector3d frcB = consElem2->getFrc();
220    
221     RealType rma = 1.0 / consElem1->getMass();
222     RealType rmb = 1.0 / consElem2->getMass();
223    
224     Vector3d fpab = frcA * rma - frcB * rmb;
225    
226     RealType gab = fpab.lengthSquare();
227     if (gab < 1.0) gab = 1.0;
228    
229     RealType rabsq = rab.lengthSquare();
230     RealType rfab = dot(rab, fpab);
231    
232     if (fabs(rfab) > sqrt(rabsq*gab) * consTolerance_){
233     gab = -rfab / (rabsq * (rma + rmb));
234    
235     frcA += rab*gab;
236     frcB -= rab*gab;
237    
238     consElem1->setFrc(frcA);
239     consElem2->setFrc(frcB);
240    
241     return consSuccess;
242     }
243     else
244     return consAlready;
245     }
246     }

Properties

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