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: 1490
Committed: Fri Sep 24 04:16:43 2004 UTC (19 years, 9 months ago) by gezelter
Original Path: trunk/OOPSE-2.0/src/integrators/NVT.cpp
File size: 6724 byte(s)
Log Message:
Import of OOPSE v. 2.0

File Contents

# User Rev Content
1 gezelter 1490 #include <math.h>
2    
3     #include "Atom.hpp"
4     #include "SRI.hpp"
5     #include "AbstractClasses.hpp"
6     #include "SimInfo.hpp"
7     #include "ForceFields.hpp"
8     #include "Thermo.hpp"
9     #include "ReadWrite.hpp"
10     #include "Integrator.hpp"
11     #include "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     DoubleData * chiValue;
21     DoubleData * 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<DoubleData*>(data);
39     }
40    
41     data = info->getProperty(INTEGRALOFCHIDT_ID);
42     if(data){
43     integralOfChidtValue = dynamic_cast<DoubleData*>(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     }