ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/integrators/Velocitizer.cpp
Revision: 1465
Committed: Fri Jul 9 23:08:25 2010 UTC (14 years, 9 months ago) by chuckv
File size: 7576 byte(s)
Log Message:
Creating busticated version of OpenMD

File Contents

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

Properties

Name Value
svn:keywords Author Id Revision Date