ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/integrators/NVT.cpp
(Generate patch)

Comparing branches/new_design/OOPSE-3.0/src/integrators/NVT.cpp (file contents):
Revision 1683, Thu Oct 28 22:34:02 2004 UTC vs.
Revision 1695 by tim, Mon Nov 1 22:52:57 2004 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines