ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-2.0/src/integrators/NVT.cpp
Revision: 1852
Committed: Sun Dec 5 17:09:27 2004 UTC (19 years, 7 months ago) by tim
File size: 7564 byte(s)
Log Message:
add Integrator.cpp

File Contents

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