ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/integrators/NVT.cpp
Revision: 1821
Committed: Thu Dec 2 00:26:23 2004 UTC (19 years, 7 months ago) by tim
File size: 7413 byte(s)
Log Message:
NVT get built

File Contents

# Content
1 #include "integrators/NVT.hpp"
2 #include "primitives/Molecule.hpp"
3 #include "utils/simError.h"
4 #include "utils/OOPSEConstant.hpp"
5 namespace oopse {
6
7 NVT::NVT(SimInfo* info) : VelocityVerletIntegrator(info), chiTolerance_ (1e-6) {
8
9 Globals* globals = info_->getGlobals();
10
11 if (globals->getUseInitXSstate()) {
12 Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
13 currSnapshot->setChi(0.0);
14 currSnapshot->setIntegralOfChiDt(0.0);
15 }
16
17 if (!globals->haveTargetTemp()) {
18 sprintf(painCave.errMsg, "You can't use the NVT integrator without a targetTemp_!\n");
19 painCave.isFatal = 1;
20 painCave.severity = OOPSE_ERROR;
21 simError();
22 } else {
23 targetTemp_ = globals->getTargetTemp();
24 }
25
26 // We must set tauThermostat_.
27
28 if (!globals->haveTauThermostat()) {
29 sprintf(painCave.errMsg, "If you use the constant temperature\n"
30 "\tintegrator, you must set tauThermostat_.\n");
31
32 painCave.severity = OOPSE_ERROR;
33 painCave.isFatal = 1;
34 simError();
35 } else {
36 tauThermostat_ = globals->getTauThermostat();
37 }
38
39 update();
40 }
41
42 void NVT::update() {
43 oldVel_.resize(info_->getNIntegrableObjects());
44 oldJi_.resize(info_->getNIntegrableObjects());
45 }
46 void NVT::moveA() {
47 SimInfo::MoleculeIterator i;
48 Molecule::IntegrableObjectIterator j;
49 Molecule* mol;
50 StuntDouble* integrableObject;
51 Vector3d Tb;
52 Vector3d ji;
53 double mass;
54 Vector3d vel;
55 Vector3d pos;
56 Vector3d frc;
57
58 Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
59 double chi = currSnapshot->getChi();
60 double integralOfChidt = currSnapshot->getIntegralOfChiDt();
61
62 // We need the temperature at time = t for the chi update below:
63
64 double instTemp = thermo.getTemperature();
65
66 for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {
67 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
68 integrableObject = mol->nextIntegrableObject(j)) {
69
70 vel = integrableObject->getVel();
71 pos = integrableObject->getPos();
72 frc = integrableObject->getFrc();
73
74 mass = integrableObject->getMass();
75
76 // velocity half step (use chi from previous step here):
77 //vel[j] += dt2 * ((frc[j] / mass ) * OOPSEConstant::energyConvert - vel[j]*chi);
78 vel = dt2 *OOPSEConstant::energyConvert/mass*frc - dt2*chi*vel;
79
80 // position whole step
81 //pos[j] += dt * vel[j];
82 pos += dt * vel;
83
84 integrableObject->setVel(vel);
85 integrableObject->setPos(pos);
86
87 if (integrableObject->isDirectional()) {
88
89 // get and convert the torque to body frame
90
91 Tb = integrableObject->getTrq();
92 integrableObject->lab2Body(Tb);
93
94 // get the angular momentum, and propagate a half step
95
96 ji = integrableObject->getJ();
97
98 //ji[j] += dt2 * (Tb[j] * OOPSEConstant::energyConvert - ji[j]*chi);
99 ji += dt2*OOPSEConstant::energyConvert*Tb - dt2*chi *ji;
100 rotAlgo->rotate(integrableObject, ji, dt);
101
102 integrableObject->setJ(ji);
103 }
104 }
105
106 }
107
108 //constraintAlgorithm->doConstrainA();
109
110 // Finally, evolve chi a half step (just like a velocity) using
111 // temperature at time t, not time t+dt/2
112
113
114 chi += dt2 * (instTemp / targetTemp_ - 1.0) / (tauThermostat_ * tauThermostat_);
115 integralOfChidt += chi * dt2;
116
117 currSnapshot->setChi(chi);
118 currSnapshot->setIntegralOfChiDt(integralOfChidt);
119 }
120
121 void NVT::moveB() {
122 SimInfo::MoleculeIterator i;
123 Molecule::IntegrableObjectIterator j;
124 Molecule* mol;
125 StuntDouble* integrableObject;
126
127 Vector3d Tb;
128 Vector3d ji;
129 Vector3d vel;
130 Vector3d frc;
131 double mass;
132 double instTemp;
133 int index;
134 // Set things up for the iteration:
135
136 Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
137 double chi = currSnapshot->getChi();
138 double oldChi = chi;
139 double prevChi;
140 double integralOfChidt = currSnapshot->getIntegralOfChiDt();
141
142 index = 0;
143 for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {
144 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
145 integrableObject = mol->nextIntegrableObject(j)) {
146 oldVel_[index] = integrableObject->getVel();
147 oldJi_[index] = integrableObject->getJ();
148 }
149 ++index;
150 }
151
152 // do the iteration:
153
154 for(int k = 0; k < maxIterNum_; k++) {
155 index = 0;
156 instTemp = thermo.getTemperature();
157
158 // evolve chi another half step using the temperature at t + dt/2
159
160 prevChi = chi;
161 chi = oldChi + dt2 * (instTemp / targetTemp_ - 1.0) / (tauThermostat_ * tauThermostat_);
162
163 for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {
164 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
165 integrableObject = mol->nextIntegrableObject(j)) {
166
167 frc = integrableObject->getFrc();
168 vel = integrableObject->getVel();
169
170 mass = integrableObject->getMass();
171
172 // velocity half step
173 //for(j = 0; j < 3; j++)
174 // vel[j] = oldVel_[3*i+j] + dt2 * ((frc[j] / mass ) * OOPSEConstant::energyConvert - oldVel_[3*i + j]*chi);
175 vel = oldVel_[index] + dt2/mass*OOPSEConstant::energyConvert * frc - dt2*chi*oldVel_[index];
176
177 integrableObject->setVel(vel);
178
179 if (integrableObject->isDirectional()) {
180
181 // get and convert the torque to body frame
182
183 Tb = integrableObject->getTrq();
184 integrableObject->lab2Body(Tb);
185
186 //for(j = 0; j < 3; j++)
187 // ji[j] = oldJi_[3*i + j] + dt2 * (Tb[j] * OOPSEConstant::energyConvert - oldJi_[3*i+j]*chi);
188 ji += dt2*OOPSEConstant::energyConvert*Tb - dt2*chi *oldJi_[index];
189
190 integrableObject->setJ(ji);
191 }
192 }
193 }
194
195
196 //constraintAlgorithm->doConstrainB();
197
198 if (fabs(prevChi - chi) <= chiTolerance_)
199 break;
200
201 ++index;
202 }
203
204 integralOfChidt += dt2 * chi;
205
206 currSnapshot->setChi(chi);
207 currSnapshot->setIntegralOfChiDt(integralOfChidt);
208 }
209
210
211 double NVT::calcConservedQuantity() {
212 Snapshot* currSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
213 double chi = currSnapshot->getChi();
214 double integralOfChidt = currSnapshot->getIntegralOfChiDt();
215 double conservedQuantity;
216 double fkBT;
217 double Energy;
218 double thermostat_kinetic;
219 double thermostat_potential;
220
221 fkBT = info_->getNdf() *OOPSEConstant::kB *targetTemp_;
222
223 Energy = thermo.getTotalE();
224
225 thermostat_kinetic = fkBT * tauThermostat_ * tauThermostat_ * chi * chi / (2.0 * OOPSEConstant::energyConvert);
226
227 thermostat_potential = fkBT * integralOfChidt / OOPSEConstant::energyConvert;
228
229 conservedQuantity = Energy + thermostat_kinetic + thermostat_potential;
230
231 return conservedQuantity;
232 }
233
234
235 }//end namespace oopse