ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/integrators/Velocitizer.cpp
Revision: 1874
Committed: Wed May 15 15:09:35 2013 UTC (11 years, 11 months ago) by gezelter
File size: 6631 byte(s)
Log Message:
Fixed a bunch of cppcheck warnings.

File Contents

# Content
1 /*
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 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 * [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 "integrators/Velocitizer.hpp"
44 #include "math/SquareMatrix3.hpp"
45 #include "primitives/Molecule.hpp"
46 #include "primitives/StuntDouble.hpp"
47
48 #ifndef IS_MPI
49 #include "math/SeqRandNumGen.hpp"
50 #else
51 #include "math/ParallelRandNumGen.hpp"
52 #endif
53
54 namespace OpenMD {
55
56 Velocitizer::Velocitizer(SimInfo* info) : info_(info), thermo(info) {
57
58
59 Globals * simParams = info->getSimParams();
60
61 #ifndef IS_MPI
62 if (simParams->haveSeed()) {
63 int seedValue = simParams->getSeed();
64 randNumGen_ = new SeqRandNumGen(seedValue);
65 }else {
66 randNumGen_ = new SeqRandNumGen();
67 }
68 #else
69 if (simParams->haveSeed()) {
70 int seedValue = simParams->getSeed();
71 randNumGen_ = new ParallelRandNumGen(seedValue);
72 }else {
73 randNumGen_ = new ParallelRandNumGen();
74 }
75 #endif
76 }
77
78 Velocitizer::~Velocitizer() {
79 delete randNumGen_;
80 }
81
82 void Velocitizer::velocitize(RealType temperature) {
83 Vector3d aVel;
84 Vector3d aJ;
85 Mat3x3d I;
86 int l, m, n;
87 Vector3d vdrift;
88 RealType vbar;
89 /**@todo refactor kb */
90 const RealType kb = 8.31451e-7; // kb in amu, angstroms, fs, etc.
91 RealType av2;
92 RealType kebar;
93
94 Globals * simParams = info_->getSimParams();
95
96 SimInfo::MoleculeIterator i;
97 Molecule::IntegrableObjectIterator j;
98 Molecule * mol;
99 StuntDouble * sd;
100
101 kebar = kb * temperature * info_->getNdfRaw() / (2.0 * info_->getNdf());
102
103 for( mol = info_->beginMolecule(i); mol != NULL;
104 mol = info_->nextMolecule(i) ) {
105
106 for( sd = mol->beginIntegrableObject(j); sd != NULL;
107 sd = mol->nextIntegrableObject(j) ) {
108
109 // uses equipartition theory to solve for vbar in angstrom/fs
110
111 av2 = 2.0 * kebar / sd->getMass();
112 vbar = sqrt(av2);
113
114 // picks random velocities from a gaussian distribution
115 // centered on vbar
116
117 for( int k = 0; k < 3; k++ ) {
118 aVel[k] = vbar * randNumGen_->randNorm(0.0, 1.0);
119 }
120 sd->setVel(aVel);
121
122 if (sd->isDirectional()) {
123 I = sd->getI();
124
125 if (sd->isLinear()) {
126 l = sd->linearAxis();
127 m = (l + 1) % 3;
128 n = (l + 2) % 3;
129
130 aJ[l] = 0.0;
131 vbar = sqrt(2.0 * kebar * I(m, m));
132 aJ[m] = vbar * randNumGen_->randNorm(0.0, 1.0);
133 vbar = sqrt(2.0 * kebar * I(n, n));
134 aJ[n] = vbar * randNumGen_->randNorm(0.0, 1.0);
135 } else {
136 for( int k = 0; k < 3; k++ ) {
137 vbar = sqrt(2.0 * kebar * I(k, k));
138 aJ[k] = vbar *randNumGen_->randNorm(0.0, 1.0);
139 }
140 }
141
142 sd->setJ(aJ);
143 }
144 }
145 }
146
147 removeComDrift();
148
149 // Remove angular drift if we are not using periodic boundary
150 // conditions:
151
152 if(!simParams->getUsePeriodicBoundaryConditions()) removeAngularDrift();
153 }
154
155 void Velocitizer::removeComDrift() {
156 // Get the Center of Mass drift velocity.
157 Vector3d vdrift = thermo.getComVel();
158
159 SimInfo::MoleculeIterator i;
160 Molecule::IntegrableObjectIterator j;
161 Molecule * mol;
162 StuntDouble * sd;
163
164 // Corrects for the center of mass drift.
165 // sums all the momentum and divides by total mass.
166 for( mol = info_->beginMolecule(i); mol != NULL;
167 mol = info_->nextMolecule(i) ) {
168
169 for( sd = mol->beginIntegrableObject(j); sd != NULL;
170 sd = mol->nextIntegrableObject(j) ) {
171
172 sd->setVel(sd->getVel() - vdrift);
173
174 }
175 }
176 }
177
178 void Velocitizer::removeAngularDrift() {
179 // Get the Center of Mass drift velocity.
180
181 Vector3d vdrift;
182 Vector3d com;
183
184 thermo.getComAll(com, vdrift);
185
186 Mat3x3d inertiaTensor;
187 Vector3d angularMomentum;
188 Vector3d omega;
189
190 thermo.getInertiaTensor(inertiaTensor, angularMomentum);
191
192 // We now need the inverse of the inertia tensor.
193 inertiaTensor = inertiaTensor.inverse();
194 omega = inertiaTensor * angularMomentum;
195
196 SimInfo::MoleculeIterator i;
197 Molecule::IntegrableObjectIterator j;
198 Molecule* mol;
199 StuntDouble* sd;
200 Vector3d tempComPos;
201
202 // Corrects for the center of mass angular drift by summing all
203 // the angular momentum and dividing by the total mass.
204
205 for( mol = info_->beginMolecule(i); mol != NULL;
206 mol = info_->nextMolecule(i) ) {
207
208 for( sd = mol->beginIntegrableObject(j); sd != NULL;
209 sd = mol->nextIntegrableObject(j) ) {
210
211 tempComPos = sd->getPos() - com;
212 sd->setVel((sd->getVel() - vdrift) - cross(omega, tempComPos));
213
214 }
215 }
216 }
217 }

Properties

Name Value
svn:keywords Author Id Revision Date