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 857 by mmeineke, Fri Nov 7 17:09:48 2003 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 +  // 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*nAtoms];
66    oldVel = new double[3*nAtoms];
67    oldJi = new double[3*nAtoms];
# Line 55 | Line 80 | template<typename T> void NPT<T>::moveA() {
80   }
81  
82   template<typename T> void NPT<T>::moveA() {
83 <
83 >
84    //new version of NPT
85    int i, j, k;
86    DirectionalAtom* dAtom;
# Line 66 | Line 91 | template<typename T> void NPT<T>::moveA() {
91    double COM[3];
92  
93    instaTemp = tStats->getTemperature();
94 <  instaPress = tStats->getPressure();
94 >  tStats->getPressureTensor( press );
95 >  instaPress = p_convert * (press[0][0] + press[1][1] + press[2][2]) / 3.0;
96    instaVol = tStats->getVolume();
97 <  
97 >
98    tStats->getCOM(COM);
99 <  
99 >
100    //evolve velocity half step
101 +
102 +  calcVelScale();
103 +  
104    for( i=0; i<nAtoms; i++ ){
105  
106      atoms[i]->getVel( vel );
# Line 82 | Line 111 | template<typename T> void NPT<T>::moveA() {
111      getVelScaleA( sc, vel );
112  
113      for (j=0; j < 3; j++) {
114 <      
114 >
115        // velocity half step  (use chi from previous step here):
116        vel[j] += dt2 * ((frc[j] / mass ) * eConvert - sc[j]);
117 <  
117 >
118      }
119  
120      atoms[i]->setVel( vel );
121 <  
121 >
122      if( atoms[i]->isDirectional() ){
123  
124        dAtom = (DirectionalAtom *)atoms[i];
125  
126        // get and convert the torque to body frame
127 <      
127 >
128        dAtom->getTrq( Tb );
129        dAtom->lab2Body( Tb );
130 <      
130 >
131        // get the angular momentum, and propagate a half step
132  
133        dAtom->getJ( ji );
134  
135 <      for (j=0; j < 3; j++)
135 >      for (j=0; j < 3; j++)
136          ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);
137 <      
137 >
138        this->rotationPropagation( dAtom, ji );
139 <      
139 >
140        dAtom->setJ( ji );
141 <    }    
141 >    }
142    }
143  
144    // evolve chi and eta  half step
145 <  
145 >
146    evolveChiA();
147    evolveEtaA();
148  
# Line 126 | Line 155 | template<typename T> void NPT<T>::moveA() {
155      for(j = 0; j < 3; j++)
156        oldPos[i*3 + j] = pos[j];
157    }
158 <  
159 <  //the first estimation of r(t+dt) is equal to  r(t)
160 <    
158 >
159 >  //the first estimation of r(t+dt) is equal to  r(t)
160 >
161    for(k = 0; k < 5; k ++){
162  
163      for(i =0 ; i < nAtoms; i++){
# Line 137 | Line 166 | template<typename T> void NPT<T>::moveA() {
166        atoms[i]->getPos(pos);
167  
168        this->getPosScale( pos, COM, i, sc );
169 <  
169 >
170        for(j = 0; j < 3; j++)
171          pos[j] = oldPos[i*3 + j] + dt*(vel[j] + sc[j]);
172  
173        atoms[i]->setPos( pos );
174      }
175 <    
175 >
176      if (nConstrained){
177        constrainA();
178      }
179    }
151    
180  
181 +
182    // Scale the box after all the positions have been moved:
183 <  
183 >
184    this->scaleSimBox();
185   }
186  
187   template<typename T> void NPT<T>::moveB( void ){
188 <  
188 >
189    //new version of NPT
190    int i, j, k;
191    DirectionalAtom* dAtom;
192    double Tb[3], ji[3], sc[3];
193    double vel[3], frc[3];
194    double mass;
195 <  
195 >
196    // Set things up for the iteration:
197  
198    for( i=0; i<nAtoms; i++ ){
# Line 188 | Line 217 | template<typename T> void NPT<T>::moveB( void ){
217    // do the iteration:
218  
219    instaVol = tStats->getVolume();
220 <  
220 >
221    for (k=0; k < 4; k++) {
222 <    
222 >
223      instaTemp = tStats->getTemperature();
224      instaPress = tStats->getPressure();
225  
# Line 198 | Line 227 | template<typename T> void NPT<T>::moveB( void ){
227  
228      this->evolveChiB();
229      this->evolveEtaB();
230 <    
230 >    this->calcVelScale();
231 >
232      for( i=0; i<nAtoms; i++ ){
233  
234        atoms[i]->getFrc( frc );
235        atoms[i]->getVel(vel);
236 <      
236 >
237        mass = atoms[i]->getMass();
238 <      
238 >
239        getVelScaleB( sc, i );
240  
241        // velocity half step
242 <      for (j=0; j < 3; j++)
242 >      for (j=0; j < 3; j++)
243          vel[j] = oldVel[3*i+j] + dt2 * ((frc[j] / mass ) * eConvert - sc[j]);
244 <      
244 >
245        atoms[i]->setVel( vel );
246 <      
246 >
247        if( atoms[i]->isDirectional() ){
248  
249          dAtom = (DirectionalAtom *)atoms[i];
250 <  
251 <        // get and convert the torque to body frame      
252 <  
250 >
251 >        // get and convert the torque to body frame
252 >
253          dAtom->getTrq( Tb );
254 <        dAtom->lab2Body( Tb );      
255 <            
256 <        for (j=0; j < 3; j++)
254 >        dAtom->lab2Body( Tb );
255 >
256 >        for (j=0; j < 3; j++)
257            ji[j] = oldJi[3*i + j] + dt2 * (Tb[j] * eConvert - oldJi[3*i+j]*chi);
258 <      
258 >
259            dAtom->setJ( ji );
260        }
261      }
262 <    
262 >
263      if (nConstrained){
264        constrainB();
265 <    }    
266 <    
265 >    }
266 >
267      if ( this->chiConverged() && this->etaConverged() ) break;
268    }
269  
# Line 254 | Line 284 | template<typename T> void NPT<T>::evolveChiB() {
284   }
285  
286   template<typename T> void NPT<T>::evolveChiB() {
287 <  
287 >
288    prevChi = chi;
289    chi = oldChi + dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
290   }
291  
292   template<typename T> bool NPT<T>::chiConverged() {
293 <  
294 <  return ( fabs( prevChi - chi ) <= chiTolerance );  
293 >
294 >  return ( fabs( prevChi - chi ) <= chiTolerance );
295   }
296  
297   template<typename T> int NPT<T>::readyCheck() {
# Line 269 | Line 299 | template<typename T> int NPT<T>::readyCheck() {
299    //check parent's readyCheck() first
300    if (T::readyCheck() == -1)
301      return -1;
302 <
303 <  // First check to see if we have a target temperature.
304 <  // Not having one is fatal.
305 <  
302 >
303 >  // First check to see if we have a target temperature.
304 >  // Not having one is fatal.
305 >
306    if (!have_target_temp) {
307      sprintf( painCave.errMsg,
308               "NPT error: You can't use the NPT integrator\n"
# Line 292 | Line 322 | template<typename T> int NPT<T>::readyCheck() {
322      simError();
323      return -1;
324    }
325 <  
325 >
326    // We must set tauThermostat.
327 <  
327 >
328    if (!have_tau_thermostat) {
329      sprintf( painCave.errMsg,
330               "NPT error: If you use the NPT\n"
# Line 302 | Line 332 | template<typename T> int NPT<T>::readyCheck() {
332      painCave.isFatal = 1;
333      simError();
334      return -1;
335 <  }    
335 >  }
336  
337    // We must set tauBarostat.
338 <  
338 >
339    if (!have_tau_barostat) {
340      sprintf( painCave.errMsg,
341               "NPT error: If you use the NPT\n"
# Line 313 | Line 343 | template<typename T> int NPT<T>::readyCheck() {
343      painCave.isFatal = 1;
344      simError();
345      return -1;
346 <  }    
346 >  }
347  
348    if (!have_chi_tolerance) {
349      sprintf( painCave.errMsg,
# Line 322 | Line 352 | template<typename T> int NPT<T>::readyCheck() {
352      have_chi_tolerance = 1;
353      painCave.isFatal = 0;
354      simError();
355 <  }
355 >  }
356  
357    if (!have_eta_tolerance) {
358      sprintf( painCave.errMsg,
# Line 331 | Line 361 | template<typename T> int NPT<T>::readyCheck() {
361      have_eta_tolerance = 1;
362      painCave.isFatal = 0;
363      simError();
364 <  }
365 <  
364 >  }
365 >
366    // We need NkBT a lot, so just set it here: This is the RAW number
367    // of particles, so no subtraction or addition of constraints or
368    // orientational degrees of freedom:
369 <  
369 >
370    NkBT = (double)Nparticles * kB * targetTemp;
371 <  
371 >
372    // fkBT is used because the thermostat operates on more degrees of freedom
373    // than the barostat (when there are particles with orientational degrees
374    // of freedom).  ndf = 3 * (n_atoms + n_oriented -1) - n_constraint - nZcons
375 <  
375 >
376    fkBT = (double)info->ndf * kB * targetTemp;
377  
378    tt2 = tauThermostat * tauThermostat;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines