ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/integrators/Velocitizer.cpp
Revision: 1313
Committed: Wed Oct 22 20:01:49 2008 UTC (16 years, 6 months ago) by gezelter
Original Path: trunk/src/integrators/Velocitizer.cpp
File size: 7534 byte(s)
Log Message:
General bug-fixes and other changes to make particle pots work with
the Helfand Energy correlation function

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     * 1. Acknowledgement of the program authors must be made in any
10     * publication of scientific results based in part on use of the
11     * program. An acceptable form of acknowledgement is citation of
12     * the article in which the program was described (Matthew
13     * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14     * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15     * Parallel Simulation Engine for Molecular Dynamics,"
16     * J. Comput. Chem. 26, pp. 252-271 (2005))
17     *
18     * 2. Redistributions of source code must retain the above copyright
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 3. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in the
23     * documentation and/or other materials provided with the
24     * distribution.
25     *
26     * This software is provided "AS IS," without a warranty of any
27     * kind. All express or implied conditions, representations and
28     * warranties, including any implied warranty of merchantability,
29     * fitness for a particular purpose or non-infringement, are hereby
30     * excluded. The University of Notre Dame and its licensors shall not
31     * be liable for any damages suffered by licensee as a result of
32     * using, modifying or distributing the software or its
33     * derivatives. In no event will the University of Notre Dame or its
34     * licensors be liable for any lost revenue, profit or data, or for
35     * direct, indirect, special, consequential, incidental or punitive
36     * damages, however caused and regardless of the theory of liability,
37     * arising out of the use of or inability to use software, even if the
38     * University of Notre Dame has been advised of the possibility of
39     * such damages.
40     */
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     namespace oopse {
61    
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     }