ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/integrators/Velocitizer.cpp
(Generate patch)

Comparing:
trunk/src/integrators/Velocitizer.cpp (file contents), Revision 246 by gezelter, Wed Jan 12 22:41:40 2005 UTC vs.
branches/development/src/integrators/Velocitizer.cpp (file contents), Revision 1665 by gezelter, Tue Nov 22 20:38:56 2011 UTC

# Line 1 | Line 1
1 < /*
1 > /*
2   * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3   *
4   * The University of Notre Dame grants you ("Licensee") a
# Line 6 | Line 6
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
9 > * 1. Redistributions of source code must retain the above copyright
10   *    notice, this list of conditions and the following disclaimer.
11   *
12 < * 3. Redistributions in binary form must reproduce the above copyright
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.
# Line 37 | Line 28
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 <  
42 >
43   #include "integrators/Velocitizer.hpp"
44   #include "math/SquareMatrix3.hpp"
45   #include "primitives/Molecule.hpp"
46   #include "primitives/StuntDouble.hpp"
46 #include "math/randomSPRNG.hpp"
47  
48 < namespace oopse {
48 > #ifndef IS_MPI
49 > #include "math/SeqRandNumGen.hpp"
50 > #else
51 > #include "math/ParallelRandNumGen.hpp"
52 > #endif
53  
54 < void Velocitizer::velocitize(double temperature) {
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;
# Line 55 | Line 94 | void Velocitizer::velocitize(double temperature) {
94      int m;
95      int n;
96      Vector3d vdrift;
97 <    double vbar;
97 >    RealType vbar;
98      /**@todo refactory kb */
99 <    const double kb = 8.31451e-7; // kb in amu, angstroms, fs, etc.
100 <    double av2;
101 <    double kebar;
102 <
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;
68    gaussianSPRNG gaussStream(info_->getSeed());
109  
110      kebar = kb * temperature * info_->getNdfRaw() / (2.0 * info_->getNdf());
71
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 * gaussStream.getGaussian();
127 <            }
128 <
129 <            integrableObject->setVel(aVel);
130 <
131 <            if (integrableObject->isDirectional()) {
132 <                I = integrableObject->getI();
133 <
134 <                if (integrableObject->isLinear()) {
135 <                    l = integrableObject->linearAxis();
136 <                    m = (l + 1) % 3;
137 <                    n = (l + 2) % 3;
138 <
139 <                    aJ[l] = 0.0;
140 <                    vbar = sqrt(2.0 * kebar * I(m, m));
141 <                    aJ[m] = vbar * gaussStream.getGaussian();
142 <                    vbar = sqrt(2.0 * kebar * I(n, n));
143 <                    aJ[n] = vbar * gaussStream.getGaussian();
144 <                } else {
145 <                    for( int k = 0; k < 3; k++ ) {
146 <                        vbar = sqrt(2.0 * kebar * I(k, k));
147 <                        aJ[k] = vbar * gaussStream.getGaussian();
148 <                    }
149 <                } // else isLinear
150 <
151 <                integrableObject->setJ(aJ);
152 <            }     //isDirectional
114 <        }
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 <
154 >    
155 >    
156 >    
157      removeComDrift();
158 <
159 < }
160 <
161 <
162 <
163 < void Velocitizer::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      
# Line 134 | Line 174 | void Velocitizer::removeComDrift() {
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 <        }
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 <
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   }
146
147 }

Comparing:
trunk/src/integrators/Velocitizer.cpp (property svn:keywords), Revision 246 by gezelter, Wed Jan 12 22:41:40 2005 UTC vs.
branches/development/src/integrators/Velocitizer.cpp (property svn:keywords), Revision 1665 by gezelter, Tue Nov 22 20:38:56 2011 UTC

# Line 0 | Line 1
1 + Author Id Revision Date

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines