ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-4/src/integrators/NVT.cpp
Revision: 1762
Committed: Fri Nov 19 21:38:22 2004 UTC (19 years, 9 months ago) by tim
File size: 7452 byte(s)
Log Message:
refactory integrator

File Contents

# Content
1 #include <math.h>
2
3 #include "primitives/Atom.hpp"
4 #include "primitives/SRI.hpp"
5 #include "primitives/AbstractClasses.hpp"
6 #include "brains/SimInfo.hpp"
7 #include "UseTheForce/ForceFields.hpp"
8 #include "brains/Thermo.hpp"
9 #include "io/ReadWrite.hpp"
10 #include "integrators/Integrator.hpp"
11 #include "utils/simError.h"
12
13 // Basic thermostating via Hoover, Phys.Rev.A, 1985, Vol. 31 (5) 1695-1697
14
15 template <typename T>NVT<T>::NVT(SimInfo *theInfo, ForceFields *the_ff) :
16 T(theInfo, the_ff) {
17 GenericData *data;
18 DoubleGenericData *chiValue;
19 DoubleGenericData *integralOfChidtValue;
20
21 chiValue = NULL;
22 integralOfChidtValue = NULL;
23
24 chi = 0.0;
25 have_tau_thermostat = 0;
26 have_target_temp = 0;
27 have_chi_tolerance = 0;
28 integralOfChidt = 0.0;
29
30 if (theInfo->useInitXSstate) {
31
32 // retrieve chi and integralOfChidt from simInfo
33 data = info->getPropertyByName(CHIVALUE_ID);
34
35 if (data) {
36 chiValue = dynamic_cast<DoubleGenericData *>(data);
37 }
38
39 data = info->getPropertyByName(INTEGRALOFCHIDT_ID);
40
41 if (data) {
42 integralOfChidtValue = dynamic_cast<DoubleGenericData *>(data);
43 }
44
45 // chi and integralOfChidt should appear by pair
46 if (chiValue && integralOfChidtValue) {
47 chi = chiValue->getData();
48 integralOfChidt = integralOfChidtValue->getData();
49 }
50 }
51
52 oldVel = new double[3 * integrableObjects.size()];
53 oldJi = new double[3 * integrableObjects.size()];
54 }
55
56 template <typename T>NVT<T>::~NVT() {
57 delete [] oldVel;
58 delete [] oldJi;
59 }
60
61 template <typename T>
62 void NVT<T>::moveA() {
63 int i, j;
64 DirectionalAtom *dAtom;
65 Vector3d Tb;
66 Vector3d ji;
67 double mass;
68 Vector3d vel;
69 Vector3d pos;
70 Vector3d frc;
71
72 double instTemp;
73
74 // We need the temperature at time = t for the chi update below:
75
76 instTemp = tStats->getTemperature();
77
78 for(i = 0; i < integrableObjects.size(); i++) {
79 vel = integrableObjects[i]->getVel();
80 pos = integrableObjects[i]->getPos();
81 integrableObjects[i]->getFrc(frc);
82
83 mass = integrableObjects[i]->getMass();
84
85 for(j = 0; j < 3; j++) {
86 // velocity half step (use chi from previous step here):
87 vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*chi);
88
89 // position whole step
90 pos[j] += dt * vel[j];
91 }
92
93 integrableObjects[i]->setVel(vel);
94 integrableObjects[i]->setPos(pos);
95
96 if (integrableObjects[i]->isDirectional()) {
97
98 // get and convert the torque to body frame
99
100 Tb = integrableObjects[i]->getTrq();
101 integrableObjects[i]->lab2Body(Tb);
102
103 // get the angular momentum, and propagate a half step
104
105 ji = integrableObjects[i]->getJ();
106
107 for(j = 0; j < 3; j++)
108 ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);
109
110 this->rotationPropagation(integrableObjects[i], ji);
111
112 integrableObjects[i]->setJ(ji);
113 }
114 }
115
116 if (nConstrained)
117 constrainA();
118
119 // Finally, evolve chi a half step (just like a velocity) using
120 // temperature at time t, not time t+dt/2
121
122 //std::cerr << "targetTemp = " << targetTemp << " instTemp = " << instTemp << " tauThermostat = " << tauThermostat << " integral of Chi = " << integralOfChidt << "\n";
123
124 chi += dt2 * (instTemp / targetTemp - 1.0) / (tauThermostat * tauThermostat);
125 integralOfChidt += chi * dt2;
126 }
127
128 template <typename T>
129 void NVT<T>::moveB(void) {
130 int i, j, k;
131 double Tb[3], ji[3];
132 double vel[3], frc[3];
133 double mass;
134 double instTemp;
135 double oldChi, prevChi;
136
137 // Set things up for the iteration:
138
139 oldChi = chi;
140
141 for(i = 0; i < integrableObjects.size(); i++) {
142 vel = integrableObjects[i]->getVel();
143
144 for(j = 0; j < 3; j++)
145 oldVel[3 * i + j] = vel[j];
146
147 if (integrableObjects[i]->isDirectional()) {
148 ji = integrableObjects[i]->getJ();
149
150 for(j = 0; j < 3; j++)
151 oldJi[3 * i + j] = ji[j];
152 }
153 }
154
155 // do the iteration:
156
157 for(k = 0; k < 4; k++) {
158 instTemp = tStats->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(i = 0; i < integrableObjects.size(); i++) {
166 integrableObjects[i]->getFrc(frc);
167 vel = integrableObjects[i]->getVel();
168
169 mass = integrableObjects[i]->getMass();
170
171 // velocity half step
172 for(j = 0; j < 3; j++)
173 vel[j] = oldVel[3*i+j] + dt2 * ((frc[j] / mass ) * eConvert - oldVel[3*i + j]*chi);
174
175 integrableObjects[i]->setVel(vel);
176
177 if (integrableObjects[i]->isDirectional()) {
178
179 // get and convert the torque to body frame
180
181 Tb = integrableObjects[i]->getTrq();
182 integrableObjects[i]->lab2Body(Tb);
183
184 for(j = 0; j < 3; j++)
185 ji[j] = oldJi[3*i + j] + dt2 * (Tb[j] * eConvert - oldJi[3*i+j]*chi);
186
187 integrableObjects[i]->setJ(ji);
188 }
189 }
190
191 if (nConstrained)
192 constrainB();
193
194 if (fabs(prevChi - chi) <= chiTolerance)
195 break;
196 }
197
198 integralOfChidt += dt2 * chi;
199 }
200
201 template <typename T>
202 void NVT<T>::resetIntegrator(void) {
203 chi = 0.0;
204 integralOfChidt = 0.0;
205 }
206
207 template <typename T>
208 int NVT<T>::readyCheck() {
209
210 //check parent's readyCheck() first
211 if (T::readyCheck() == -1)
212 return -1;
213
214 // First check to see if we have a target temperature.
215 // Not having one is fatal.
216
217 if (!have_target_temp) {
218 sprintf(painCave.errMsg, "You can't use the NVT integrator without a targetTemp!\n");
219 painCave.isFatal = 1;
220 painCave.severity = OOPSE_ERROR;
221 simError();
222 return -1;
223 }
224
225 // We must set tauThermostat.
226
227 if (!have_tau_thermostat) {
228 sprintf(painCave.errMsg, "If you use the constant temperature\n"
229 "\tintegrator, you must set tauThermostat.\n");
230
231 painCave.severity = OOPSE_ERROR;
232 painCave.isFatal = 1;
233 simError();
234 return -1;
235 }
236
237 if (!have_chi_tolerance) {
238 sprintf(painCave.errMsg, "In NVT integrator: setting chi tolerance to 1e-6\n");
239 chiTolerance = 1e - 6;
240 have_chi_tolerance = 1;
241 painCave.severity = OOPSE_INFO;
242 painCave.isFatal = 0;
243 simError();
244 }
245
246 return 1;
247 }
248
249 template <typename T>
250 double NVT<T>::getConservedQuantity(void) {
251 double conservedQuantity;
252 double fkBT;
253 double Energy;
254 double thermostat_kinetic;
255 double thermostat_potential;
256
257 fkBT = (double)(info->ndf) *kB *targetTemp;
258
259 Energy = tStats->getTotalE();
260
261 thermostat_kinetic = fkBT * tauThermostat * tauThermostat * chi * chi / (2.0 * eConvert);
262
263 thermostat_potential = fkBT * integralOfChidt / eConvert;
264
265 conservedQuantity = Energy + thermostat_kinetic + thermostat_potential;
266
267 return conservedQuantity;
268 }
269
270 template <typename T>
271 string NVT<T>::getAdditionalParameters(void) {
272 string parameters;
273 const int BUFFERSIZE = 2000; // size of the read buffer
274 char buffer[BUFFERSIZE];
275
276 sprintf(buffer, "\t%G\t%G;", chi, integralOfChidt);
277 parameters += buffer;
278
279 return parameters;
280 }