ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/integrators/NVT.cpp
Revision: 1867
Committed: Tue Dec 7 23:08:14 2004 UTC (19 years, 7 months ago) by tim
File size: 7367 byte(s)
Log Message:
NPT in progress

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::doUpdate() {
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 double chi = currentSnapshot_->getChi();
63 double integralOfChidt = currentSnapshot_->getIntegralOfChiDt();
64
65 // We need the temperature at time = t for the chi update below:
66
67 double instTemp = thermo.getTemperature();
68
69 for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {
70 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
71 integrableObject = mol->nextIntegrableObject(j)) {
72
73 vel = integrableObject->getVel();
74 pos = integrableObject->getPos();
75 frc = integrableObject->getFrc();
76
77 mass = integrableObject->getMass();
78
79 // velocity half step (use chi from previous step here):
80 //vel[j] += dt2 * ((frc[j] / mass ) * OOPSEConstant::energyConvert - vel[j]*chi);
81 vel += dt2 *OOPSEConstant::energyConvert/mass*frc - dt2*chi*vel;
82
83 // position whole step
84 //pos[j] += dt * vel[j];
85 pos += dt * vel;
86
87 integrableObject->setVel(vel);
88 integrableObject->setPos(pos);
89
90 if (integrableObject->isDirectional()) {
91
92 // get and convert the torque to body frame
93
94 Tb = integrableObject->getTrq();
95 integrableObject->lab2Body(Tb);
96
97 // get the angular momentum, and propagate a half step
98
99 ji = integrableObject->getJ();
100
101 //ji[j] += dt2 * (Tb[j] * OOPSEConstant::energyConvert - ji[j]*chi);
102 ji += dt2*OOPSEConstant::energyConvert*Tb - dt2*chi *ji;
103 rotAlgo->rotate(integrableObject, ji, dt);
104
105 integrableObject->setJ(ji);
106 }
107 }
108
109 }
110
111 //constraintAlgorithm->doConstrainA();
112
113 // Finally, evolve chi a half step (just like a velocity) using
114 // temperature at time t, not time t+dt/2
115
116
117 chi += dt2 * (instTemp / targetTemp_ - 1.0) / (tauThermostat_ * tauThermostat_);
118 integralOfChidt += chi * dt2;
119
120 currentSnapshot_->setChi(chi);
121 currentSnapshot_->setIntegralOfChiDt(integralOfChidt);
122 }
123
124 void NVT::moveB() {
125 SimInfo::MoleculeIterator i;
126 Molecule::IntegrableObjectIterator j;
127 Molecule* mol;
128 StuntDouble* integrableObject;
129
130 Vector3d Tb;
131 Vector3d ji;
132 Vector3d vel;
133 Vector3d frc;
134 double mass;
135 double instTemp;
136 int index;
137 // Set things up for the iteration:
138
139 double chi = currentSnapshot_->getChi();
140 double oldChi = chi;
141 double prevChi;
142 double integralOfChidt = currentSnapshot_->getIntegralOfChiDt();
143
144 index = 0;
145 for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {
146 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
147 integrableObject = mol->nextIntegrableObject(j)) {
148 oldVel_[index] = integrableObject->getVel();
149 oldJi_[index] = integrableObject->getJ();
150 }
151 ++index;
152 }
153
154 // do the iteration:
155
156 for(int k = 0; k < maxIterNum_; k++) {
157 index = 0;
158 instTemp = thermo.getTemperature();
159
160 // evolve chi another half step using the temperature at t + dt/2
161
162 prevChi = chi;
163 chi = oldChi + dt2 * (instTemp / targetTemp_ - 1.0) / (tauThermostat_ * tauThermostat_);
164
165 for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) {
166 for (integrableObject = mol->beginIntegrableObject(j); integrableObject != NULL;
167 integrableObject = mol->nextIntegrableObject(j)) {
168
169 frc = integrableObject->getFrc();
170 vel = integrableObject->getVel();
171
172 mass = integrableObject->getMass();
173
174 // velocity half step
175 //for(j = 0; j < 3; j++)
176 // vel[j] = oldVel_[3*i+j] + dt2 * ((frc[j] / mass ) * OOPSEConstant::energyConvert - oldVel_[3*i + j]*chi);
177 vel = oldVel_[index] + dt2/mass*OOPSEConstant::energyConvert * frc - dt2*chi*oldVel_[index];
178
179 integrableObject->setVel(vel);
180
181 if (integrableObject->isDirectional()) {
182
183 // get and convert the torque to body frame
184
185 Tb = integrableObject->getTrq();
186 integrableObject->lab2Body(Tb);
187
188 //for(j = 0; j < 3; j++)
189 // ji[j] = oldJi_[3*i + j] + dt2 * (Tb[j] * OOPSEConstant::energyConvert - oldJi_[3*i+j]*chi);
190 ji += dt2*OOPSEConstant::energyConvert*Tb - dt2*chi *oldJi_[index];
191
192 integrableObject->setJ(ji);
193 }
194
195
196 ++index;
197 }
198 }
199
200
201 //constraintAlgorithm->doConstrainB();
202
203 if (fabs(prevChi - chi) <= chiTolerance_)
204 break;
205
206 }
207
208 integralOfChidt += dt2 * chi;
209
210 currentSnapshot_->setChi(chi);
211 currentSnapshot_->setIntegralOfChiDt(integralOfChidt);
212 }
213
214
215 double NVT::calcConservedQuantity() {
216
217 double chi = currentSnapshot_->getChi();
218 double integralOfChidt = currentSnapshot_->getIntegralOfChiDt();
219 double conservedQuantity;
220 double fkBT;
221 double Energy;
222 double thermostat_kinetic;
223 double thermostat_potential;
224
225 fkBT = info_->getNdf() *OOPSEConstant::kB *targetTemp_;
226
227 Energy = thermo.getTotalE();
228
229 thermostat_kinetic = fkBT * tauThermostat_ * tauThermostat_ * chi * chi / (2.0 * OOPSEConstant::energyConvert);
230
231 thermostat_potential = fkBT * integralOfChidt / OOPSEConstant::energyConvert;
232
233 conservedQuantity = Energy + thermostat_kinetic + thermostat_potential;
234
235 return conservedQuantity;
236 }
237
238
239 }//end namespace oopse