ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/integrators/NVT.cpp
Revision: 2071
Committed: Sat Mar 7 21:41:51 2015 UTC (10 years, 3 months ago) by gezelter
File size: 8224 byte(s)
Log Message:
Reducing the number of warnings when using g++ to compile.

File Contents

# User Rev Content
1 gezelter 507 /*
2 gezelter 246 * 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 246 * 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 246 * 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 gezelter 1879 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 gezelter 1782 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 gezelter 246 */
42    
43     #include "integrators/NVT.hpp"
44     #include "primitives/Molecule.hpp"
45 tim 3 #include "utils/simError.h"
46 gezelter 1390 #include "utils/PhysicalConstants.hpp"
47 gezelter 2
48 gezelter 1390 namespace OpenMD {
49 gezelter 2
50 gezelter 2071 NVT::NVT(SimInfo* info) : VelocityVerletIntegrator(info), maxIterNum_(4),
51     chiTolerance_(1e-6) {
52 gezelter 2
53 gezelter 246 Globals* simParams = info_->getSimParams();
54 gezelter 2
55 tim 665 if (!simParams->getUseIntialExtendedSystemState()) {
56 gezelter 1782 Snapshot* snap = info_->getSnapshotManager()->getCurrentSnapshot();
57     snap->setThermostat(make_pair(0.0, 0.0));
58 gezelter 246 }
59    
60     if (!simParams->haveTargetTemp()) {
61 gezelter 507 sprintf(painCave.errMsg, "You can't use the NVT integrator without a targetTemp_!\n");
62     painCave.isFatal = 1;
63 gezelter 1390 painCave.severity = OPENMD_ERROR;
64 gezelter 507 simError();
65 gezelter 246 } else {
66 gezelter 507 targetTemp_ = simParams->getTargetTemp();
67 gezelter 246 }
68 gezelter 2
69 gezelter 1277 // We must set tauThermostat.
70 gezelter 2
71 gezelter 246 if (!simParams->haveTauThermostat()) {
72 gezelter 507 sprintf(painCave.errMsg, "If you use the constant temperature\n"
73 gezelter 1277 "\tintegrator, you must set tauThermostat.\n");
74 gezelter 2
75 gezelter 1390 painCave.severity = OPENMD_ERROR;
76 gezelter 507 painCave.isFatal = 1;
77     simError();
78 gezelter 246 } else {
79 gezelter 507 tauThermostat_ = simParams->getTauThermostat();
80 gezelter 2 }
81    
82 gezelter 1782 updateSizes();
83 gezelter 507 }
84 gezelter 2
85 gezelter 1782 void NVT::doUpdateSizes() {
86 gezelter 246 oldVel_.resize(info_->getNIntegrableObjects());
87 gezelter 1782 oldJi_.resize(info_->getNIntegrableObjects());
88 gezelter 507 }
89 gezelter 1782
90 gezelter 507 void NVT::moveA() {
91 gezelter 246 SimInfo::MoleculeIterator i;
92     Molecule::IntegrableObjectIterator j;
93     Molecule* mol;
94 gezelter 1782 StuntDouble* sd;
95 gezelter 246 Vector3d Tb;
96     Vector3d ji;
97 tim 963 RealType mass;
98 gezelter 246 Vector3d vel;
99     Vector3d pos;
100     Vector3d frc;
101 gezelter 2
102 gezelter 1782 pair<RealType, RealType> thermostat = snap->getThermostat();
103    
104 gezelter 246 // We need the temperature at time = t for the chi update below:
105 gezelter 2
106 tim 963 RealType instTemp = thermo.getTemperature();
107 gezelter 2
108 gezelter 1782 for (mol = info_->beginMolecule(i); mol != NULL;
109     mol = info_->nextMolecule(i)) {
110 gezelter 2
111 gezelter 1782 for (sd = mol->beginIntegrableObject(j); sd != NULL;
112     sd = mol->nextIntegrableObject(j)) {
113 gezelter 2
114 gezelter 1782 vel = sd->getVel();
115     pos = sd->getPos();
116     frc = sd->getFrc();
117 gezelter 2
118 gezelter 1782 mass = sd->getMass();
119    
120     // velocity half step (use chi from previous step here):
121     vel += dt2 *PhysicalConstants::energyConvert/mass*frc
122     - dt2*thermostat.first*vel;
123 gezelter 246
124     // position whole step
125     pos += dt * vel;
126 gezelter 2
127 gezelter 1782 sd->setVel(vel);
128     sd->setPos(pos);
129 gezelter 2
130 gezelter 1782 if (sd->isDirectional()) {
131 gezelter 2
132 gezelter 507 //convert the torque to body frame
133 gezelter 1782 Tb = sd->lab2Body(sd->getTrq());
134 gezelter 2
135 gezelter 507 // get the angular momentum, and propagate a half step
136 gezelter 2
137 gezelter 1782 ji = sd->getJ();
138 gezelter 2
139 gezelter 1782 ji += dt2*PhysicalConstants::energyConvert*Tb
140     - dt2*thermostat.first *ji;
141 gezelter 2
142 gezelter 1782 rotAlgo_->rotate(sd, ji, dt);
143    
144     sd->setJ(ji);
145 gezelter 246 }
146 gezelter 507 }
147 gezelter 2
148     }
149 gezelter 246
150 gezelter 1782 flucQ_->moveA();
151     rattle_->constraintA();
152 gezelter 2
153 gezelter 246 // Finally, evolve chi a half step (just like a velocity) using
154     // temperature at time t, not time t+dt/2
155 gezelter 2
156 gezelter 1782 thermostat.first += dt2 * (instTemp / targetTemp_ - 1.0)
157     / (tauThermostat_ * tauThermostat_);
158     thermostat.second += thermostat.first * dt2;
159 gezelter 2
160 gezelter 1782 snap->setThermostat(thermostat);
161 gezelter 507 }
162 gezelter 2
163 gezelter 507 void NVT::moveB() {
164 gezelter 246 SimInfo::MoleculeIterator i;
165     Molecule::IntegrableObjectIterator j;
166     Molecule* mol;
167 gezelter 1782 StuntDouble* sd;
168 gezelter 246
169     Vector3d Tb;
170     Vector3d ji;
171     Vector3d vel;
172     Vector3d frc;
173 tim 963 RealType mass;
174     RealType instTemp;
175 gezelter 246 int index;
176     // Set things up for the iteration:
177 gezelter 2
178 gezelter 1782 pair<RealType, RealType> thermostat = snap->getThermostat();
179     RealType oldChi = thermostat.first;
180 tim 963 RealType prevChi;
181 gezelter 2
182 gezelter 246 index = 0;
183 gezelter 1782 for (mol = info_->beginMolecule(i); mol != NULL;
184     mol = info_->nextMolecule(i)) {
185 gezelter 2
186 gezelter 1782 for (sd = mol->beginIntegrableObject(j); sd != NULL;
187     sd = mol->nextIntegrableObject(j)) {
188    
189     oldVel_[index] = sd->getVel();
190    
191     if (sd->isDirectional())
192     oldJi_[index] = sd->getJ();
193    
194 gezelter 507 ++index;
195 gezelter 1782 }
196 gezelter 2 }
197    
198 gezelter 246 // do the iteration:
199 gezelter 2
200 gezelter 246 for(int k = 0; k < maxIterNum_; k++) {
201 gezelter 507 index = 0;
202     instTemp = thermo.getTemperature();
203 gezelter 2
204 gezelter 507 // evolve chi another half step using the temperature at t + dt/2
205 gezelter 2
206 gezelter 1782 prevChi = thermostat.first;
207     thermostat.first = oldChi + dt2 * (instTemp / targetTemp_ - 1.0)
208     / (tauThermostat_ * tauThermostat_);
209 gezelter 2
210 gezelter 1782 for (mol = info_->beginMolecule(i); mol != NULL;
211     mol = info_->nextMolecule(i)) {
212    
213     for (sd = mol->beginIntegrableObject(j); sd != NULL;
214     sd = mol->nextIntegrableObject(j)) {
215 gezelter 2
216 gezelter 1782 frc = sd->getFrc();
217     mass = sd->getMass();
218 gezelter 2
219 gezelter 507 // velocity half step
220 gezelter 1782
221     vel = oldVel_[index]
222     + dt2/mass*PhysicalConstants::energyConvert * frc
223     - dt2*thermostat.first*oldVel_[index];
224 gezelter 246
225 gezelter 1782 sd->setVel(vel);
226 gezelter 2
227 gezelter 1782 if (sd->isDirectional()) {
228 gezelter 2
229 gezelter 507 // get and convert the torque to body frame
230 gezelter 2
231 gezelter 1782 Tb = sd->lab2Body(sd->getTrq());
232 gezelter 2
233 gezelter 1782 ji = oldJi_[index] + dt2*PhysicalConstants::energyConvert*Tb
234     - dt2*thermostat.first *oldJi_[index];
235 gezelter 2
236 gezelter 1782 sd->setJ(ji);
237 gezelter 507 }
238 gezelter 2
239    
240 gezelter 507 ++index;
241     }
242     }
243 gezelter 2
244 gezelter 1782 rattle_->constraintB();
245 gezelter 2
246 gezelter 1782 if (fabs(prevChi - thermostat.first) <= chiTolerance_)
247 gezelter 507 break;
248 gezelter 2
249 gezelter 246 }
250 gezelter 2
251 gezelter 1782 flucQ_->moveB();
252 gezelter 2
253 gezelter 1782 thermostat.second += dt2 * thermostat.first;
254     snap->setThermostat(thermostat);
255 gezelter 507 }
256 gezelter 2
257 tim 546 void NVT::resetIntegrator() {
258 gezelter 1782 snap->setThermostat(make_pair(0.0, 0.0));
259 tim 546 }
260    
261 tim 963 RealType NVT::calcConservedQuantity() {
262 gezelter 2
263 gezelter 1782 pair<RealType, RealType> thermostat = snap->getThermostat();
264 tim 963 RealType conservedQuantity;
265     RealType fkBT;
266     RealType Energy;
267     RealType thermostat_kinetic;
268     RealType thermostat_potential;
269 gezelter 246
270 gezelter 1390 fkBT = info_->getNdf() *PhysicalConstants::kB *targetTemp_;
271 gezelter 2
272 gezelter 1782 Energy = thermo.getTotalEnergy();
273 gezelter 2
274 gezelter 1782 thermostat_kinetic = fkBT * tauThermostat_ * tauThermostat_ * thermostat.first * thermostat.first / (2.0 * PhysicalConstants::energyConvert);
275 gezelter 2
276 gezelter 1782 thermostat_potential = fkBT * thermostat.second / PhysicalConstants::energyConvert;
277 gezelter 2
278 gezelter 246 conservedQuantity = Energy + thermostat_kinetic + thermostat_potential;
279 gezelter 2
280 gezelter 246 return conservedQuantity;
281 gezelter 507 }
282 gezelter 2
283    
284 gezelter 1390 }//end namespace OpenMD

Properties

Name Value
svn:keywords Author Id Revision Date