ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/integrators/Velocitizer.cpp
Revision: 1665
Committed: Tue Nov 22 20:38:56 2011 UTC (13 years, 9 months ago) by gezelter
File size: 7642 byte(s)
Log Message:
updated copyright notices

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

Properties

Name Value
svn:keywords Author Id Revision Date