ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NPT.cpp
(Generate patch)

Comparing trunk/OOPSE/libmdtools/NPT.cpp (file contents):
Revision 778 by mmeineke, Fri Sep 19 20:00:27 2003 UTC vs.
Revision 1129 by tim, Thu Apr 22 03:29:30 2004 UTC

# Line 1 | Line 1
1 < #include <cmath>
1 > #include <math.h>
2 >
3   #include "Atom.hpp"
4   #include "SRI.hpp"
5   #include "AbstractClasses.hpp"
# Line 7 | Line 8
8   #include "Thermo.hpp"
9   #include "ReadWrite.hpp"
10   #include "Integrator.hpp"
11 < #include "simError.h"
11 > #include "simError.h"
12  
13   #ifdef IS_MPI
14   #include "mpiSimulation.hpp"
# Line 18 | Line 19
19   // modification of the Hoover algorithm:
20   //
21   //    Melchionna, S., Ciccotti, G., and Holian, B. L., 1993,
22 < //       Molec. Phys., 78, 533.
22 > //       Molec. Phys., 78, 533.
23   //
24   //           and
25 < //
25 > //
26   //    Hoover, W. G., 1986, Phys. Rev. A, 34, 2499.
27  
28   template<typename T> NPT<T>::NPT ( SimInfo *theInfo, ForceFields* the_ff):
29    T( theInfo, the_ff )
30   {
31 +  GenericData* data;
32 +  DoubleData * chiValue;
33 +  DoubleData * integralOfChidtValue;
34 +
35 +  chiValue = NULL;
36 +  integralOfChidtValue = NULL;
37 +
38    chi = 0.0;
39    integralOfChidt = 0.0;
40    have_tau_thermostat = 0;
# Line 37 | Line 45 | template<typename T> NPT<T>::NPT ( SimInfo *theInfo, F
45    have_eta_tolerance = 0;
46    have_pos_iter_tolerance = 0;
47  
48 <  oldPos = new double[3*nAtoms];
49 <  oldVel = new double[3*nAtoms];
50 <  oldJi = new double[3*nAtoms];
51 < #ifdef IS_MPI
52 <  Nparticles = mpiSim->getTotAtoms();
45 < #else
46 <  Nparticles = theInfo->n_atoms;
47 < #endif
48 >  // retrieve chi and integralOfChidt from simInfo
49 >  data = info->getProperty(CHIVALUE_ID);
50 >  if(data){
51 >    chiValue = dynamic_cast<DoubleData*>(data);
52 >  }
53  
54 +  data = info->getProperty(INTEGRALOFCHIDT_ID);
55 +  if(data){
56 +    integralOfChidtValue = dynamic_cast<DoubleData*>(data);
57 +  }
58 +
59 +  // chi and integralOfChidt should appear by pair
60 +  if(chiValue && integralOfChidtValue){
61 +    chi = chiValue->getData();
62 +    integralOfChidt = integralOfChidtValue->getData();
63 +  }
64 +
65 +  oldPos = new double[3*integrableObjects.size()];
66 +  oldVel = new double[3*integrableObjects.size()];
67 +  oldJi = new double[3*integrableObjects.size()];
68 +
69   }
70  
71   template<typename T> NPT<T>::~NPT() {
# Line 55 | Line 75 | template<typename T> void NPT<T>::moveA() {
75   }
76  
77   template<typename T> void NPT<T>::moveA() {
78 <
78 >
79    //new version of NPT
80    int i, j, k;
61  DirectionalAtom* dAtom;
81    double Tb[3], ji[3];
82    double mass;
83    double vel[3], pos[3], frc[3];
# Line 66 | Line 85 | template<typename T> void NPT<T>::moveA() {
85    double COM[3];
86  
87    instaTemp = tStats->getTemperature();
88 <  instaPress = tStats->getPressure();
88 >  tStats->getPressureTensor( press );
89 >  instaPress = p_convert * (press[0][0] + press[1][1] + press[2][2]) / 3.0;
90    instaVol = tStats->getVolume();
91 <  
91 >
92    tStats->getCOM(COM);
93 <  
93 >
94    //evolve velocity half step
75  for( i=0; i<nAtoms; i++ ){
95  
96 <    atoms[i]->getVel( vel );
97 <    atoms[i]->getFrc( frc );
96 >  calcVelScale();
97 >  
98 >  for( i=0; i<integrableObjects.size(); i++ ){
99  
100 <    mass = atoms[i]->getMass();
100 >    integrableObjects[i]->getVel( vel );
101 >    integrableObjects[i]->getFrc( frc );
102  
103 +    mass = integrableObjects[i]->getMass();
104 +
105      getVelScaleA( sc, vel );
106  
107      for (j=0; j < 3; j++) {
108 <      
108 >
109        // velocity half step  (use chi from previous step here):
110        vel[j] += dt2 * ((frc[j] / mass ) * eConvert - sc[j]);
111 <  
111 >
112      }
113  
114 <    atoms[i]->setVel( vel );
92 <  
93 <    if( atoms[i]->isDirectional() ){
114 >    integrableObjects[i]->setVel( vel );
115  
116 <      dAtom = (DirectionalAtom *)atoms[i];
116 >    if( integrableObjects[i]->isDirectional() ){
117  
118        // get and convert the torque to body frame
119 <      
120 <      dAtom->getTrq( Tb );
121 <      dAtom->lab2Body( Tb );
122 <      
119 >
120 >      integrableObjects[i]->getTrq( Tb );
121 >      integrableObjects[i]->lab2Body( Tb );
122 >
123        // get the angular momentum, and propagate a half step
124  
125 <      dAtom->getJ( ji );
125 >      integrableObjects[i]->getJ( ji );
126  
127 <      for (j=0; j < 3; j++)
127 >      for (j=0; j < 3; j++)
128          ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);
129 <      
130 <      this->rotationPropagation( dAtom, ji );
131 <      
132 <      dAtom->setJ( ji );
133 <    }    
129 >
130 >      this->rotationPropagation( integrableObjects[i], ji );
131 >
132 >      integrableObjects[i]->setJ( ji );
133 >    }
134    }
135  
136    // evolve chi and eta  half step
137 <  
137 >
138    evolveChiA();
139    evolveEtaA();
140  
# Line 121 | Line 142 | template<typename T> void NPT<T>::moveA() {
142    integralOfChidt += dt2*chi;
143  
144    //save the old positions
145 <  for(i = 0; i < nAtoms; i++){
146 <    atoms[i]->getPos(pos);
145 >  for(i = 0; i < integrableObjects.size(); i++){
146 >    integrableObjects[i]->getPos(pos);
147      for(j = 0; j < 3; j++)
148        oldPos[i*3 + j] = pos[j];
149    }
150 <  
151 <  //the first estimation of r(t+dt) is equal to  r(t)
152 <    
150 >
151 >  //the first estimation of r(t+dt) is equal to  r(t)
152 >
153    for(k = 0; k < 5; k ++){
154  
155 <    for(i =0 ; i < nAtoms; i++){
155 >    for(i =0 ; i < integrableObjects.size(); i++){
156  
157 <      atoms[i]->getVel(vel);
158 <      atoms[i]->getPos(pos);
157 >      integrableObjects[i]->getVel(vel);
158 >      integrableObjects[i]->getPos(pos);
159  
160        this->getPosScale( pos, COM, i, sc );
161 <  
161 >
162        for(j = 0; j < 3; j++)
163          pos[j] = oldPos[i*3 + j] + dt*(vel[j] + sc[j]);
164  
165 <      atoms[i]->setPos( pos );
165 >      integrableObjects[i]->setPos( pos );
166      }
167 <    
167 >
168      if (nConstrained){
169        constrainA();
170      }
171    }
151    
172  
173 +
174    // Scale the box after all the positions have been moved:
175 <  
175 >
176    this->scaleSimBox();
177   }
178  
179   template<typename T> void NPT<T>::moveB( void ){
180 <  
180 >
181    //new version of NPT
182    int i, j, k;
162  DirectionalAtom* dAtom;
183    double Tb[3], ji[3], sc[3];
184    double vel[3], frc[3];
185    double mass;
186 <  
186 >
187    // Set things up for the iteration:
188  
189 <  for( i=0; i<nAtoms; i++ ){
189 >  for( i=0; i<integrableObjects.size(); i++ ){
190  
191 <    atoms[i]->getVel( vel );
191 >    integrableObjects[i]->getVel( vel );
192  
193      for (j=0; j < 3; j++)
194        oldVel[3*i + j]  = vel[j];
195  
196 <    if( atoms[i]->isDirectional() ){
196 >    if( integrableObjects[i]->isDirectional() ){
197  
198 <      dAtom = (DirectionalAtom *)atoms[i];
198 >      integrableObjects[i]->getJ( ji );
199  
180      dAtom->getJ( ji );
181
200        for (j=0; j < 3; j++)
201          oldJi[3*i + j] = ji[j];
202  
# Line 188 | Line 206 | template<typename T> void NPT<T>::moveB( void ){
206    // do the iteration:
207  
208    instaVol = tStats->getVolume();
209 <  
209 >
210    for (k=0; k < 4; k++) {
211 <    
211 >
212      instaTemp = tStats->getTemperature();
213      instaPress = tStats->getPressure();
214  
# Line 198 | Line 216 | template<typename T> void NPT<T>::moveB( void ){
216  
217      this->evolveChiB();
218      this->evolveEtaB();
219 <    
202 <    for( i=0; i<nAtoms; i++ ){
219 >    this->calcVelScale();
220  
221 <      atoms[i]->getFrc( frc );
222 <      atoms[i]->getVel(vel);
223 <      
224 <      mass = atoms[i]->getMass();
225 <      
221 >    for( i=0; i<integrableObjects.size(); i++ ){
222 >
223 >      integrableObjects[i]->getFrc( frc );
224 >      integrableObjects[i]->getVel(vel);
225 >
226 >      mass = integrableObjects[i]->getMass();
227 >
228        getVelScaleB( sc, i );
229  
230        // velocity half step
231 <      for (j=0; j < 3; j++)
231 >      for (j=0; j < 3; j++)
232          vel[j] = oldVel[3*i+j] + dt2 * ((frc[j] / mass ) * eConvert - sc[j]);
214      
215      atoms[i]->setVel( vel );
216      
217      if( atoms[i]->isDirectional() ){
233  
234 <        dAtom = (DirectionalAtom *)atoms[i];
235 <  
236 <        // get and convert the torque to body frame      
237 <  
238 <        dAtom->getTrq( Tb );
239 <        dAtom->lab2Body( Tb );      
240 <            
241 <        for (j=0; j < 3; j++)
234 >      integrableObjects[i]->setVel( vel );
235 >
236 >      if( integrableObjects[i]->isDirectional() ){
237 >
238 >        // get and convert the torque to body frame
239 >
240 >        integrableObjects[i]->getTrq( Tb );
241 >        integrableObjects[i]->lab2Body( Tb );
242 >
243 >        for (j=0; j < 3; j++)
244            ji[j] = oldJi[3*i + j] + dt2 * (Tb[j] * eConvert - oldJi[3*i+j]*chi);
245 <      
246 <          dAtom->setJ( ji );
245 >
246 >          integrableObjects[i]->setJ( ji );
247        }
248      }
249 <    
249 >
250      if (nConstrained){
251        constrainB();
252 <    }    
253 <    
252 >    }
253 >
254      if ( this->chiConverged() && this->etaConverged() ) break;
255    }
256  
# Line 254 | Line 271 | template<typename T> void NPT<T>::evolveChiB() {
271   }
272  
273   template<typename T> void NPT<T>::evolveChiB() {
274 <  
274 >
275    prevChi = chi;
276    chi = oldChi + dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
277   }
278  
279   template<typename T> bool NPT<T>::chiConverged() {
280 <  
281 <  return ( fabs( prevChi - chi ) <= chiTolerance );  
280 >
281 >  return ( fabs( prevChi - chi ) <= chiTolerance );
282   }
283  
284   template<typename T> int NPT<T>::readyCheck() {
# Line 269 | Line 286 | template<typename T> int NPT<T>::readyCheck() {
286    //check parent's readyCheck() first
287    if (T::readyCheck() == -1)
288      return -1;
289 <
290 <  // First check to see if we have a target temperature.
291 <  // Not having one is fatal.
292 <  
289 >
290 >  // First check to see if we have a target temperature.
291 >  // Not having one is fatal.
292 >
293    if (!have_target_temp) {
294      sprintf( painCave.errMsg,
295               "NPT error: You can't use the NPT integrator\n"
# Line 292 | Line 309 | template<typename T> int NPT<T>::readyCheck() {
309      simError();
310      return -1;
311    }
312 <  
312 >
313    // We must set tauThermostat.
314 <  
314 >
315    if (!have_tau_thermostat) {
316      sprintf( painCave.errMsg,
317               "NPT error: If you use the NPT\n"
# Line 302 | Line 319 | template<typename T> int NPT<T>::readyCheck() {
319      painCave.isFatal = 1;
320      simError();
321      return -1;
322 <  }    
322 >  }
323  
324    // We must set tauBarostat.
325 <  
325 >
326    if (!have_tau_barostat) {
327      sprintf( painCave.errMsg,
328               "NPT error: If you use the NPT\n"
# Line 313 | Line 330 | template<typename T> int NPT<T>::readyCheck() {
330      painCave.isFatal = 1;
331      simError();
332      return -1;
333 <  }    
333 >  }
334  
335    if (!have_chi_tolerance) {
336      sprintf( painCave.errMsg,
# Line 322 | Line 339 | template<typename T> int NPT<T>::readyCheck() {
339      have_chi_tolerance = 1;
340      painCave.isFatal = 0;
341      simError();
342 <  }
342 >  }
343  
344    if (!have_eta_tolerance) {
345      sprintf( painCave.errMsg,
# Line 331 | Line 348 | template<typename T> int NPT<T>::readyCheck() {
348      have_eta_tolerance = 1;
349      painCave.isFatal = 0;
350      simError();
351 <  }
352 <  
351 >  }
352 >
353    // We need NkBT a lot, so just set it here: This is the RAW number
354 <  // of particles, so no subtraction or addition of constraints or
354 >  // of integrableObjects, so no subtraction or addition of constraints or
355    // orientational degrees of freedom:
356 <  
357 <  NkBT = (double)Nparticles * kB * targetTemp;
358 <  
356 >
357 >  NkBT = (double)(info->getTotIntegrableObjects()) * kB * targetTemp;
358 >
359    // fkBT is used because the thermostat operates on more degrees of freedom
360    // than the barostat (when there are particles with orientational degrees
361 <  // of freedom).  ndf = 3 * (n_atoms + n_oriented -1) - n_constraint - nZcons
345 <  
346 <  fkBT = (double)info->ndf * kB * targetTemp;
361 >  // of freedom).  
362  
363 +  fkBT = (double)(info->getNDF()) * kB * targetTemp;
364 +
365    tt2 = tauThermostat * tauThermostat;
366    tb2 = tauBarostat * tauBarostat;
367  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines