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

Comparing trunk/OOPSE/libmdtools/NPTi.cpp (file contents):
Revision 577 by gezelter, Wed Jul 9 01:41:11 2003 UTC vs.
Revision 611 by gezelter, Tue Jul 15 17:10:50 2003 UTC

# Line 1 | Line 1
1 + #include <cmath>
2   #include "Atom.hpp"
3   #include "SRI.hpp"
4   #include "AbstractClasses.hpp"
# Line 32 | Line 33 | void NPTi::moveA() {
33  
34   void NPTi::moveA() {
35    
36 <  int i,j,k;
36 <  int atomIndex, aMatIndex;
36 >  int i, j;
37    DirectionalAtom* dAtom;
38 <  double Tb[3];
39 <  double ji[3];
38 >  double Tb[3], ji[3];
39 >  double A[3][3], I[3][3];
40 >  double angle, mass;
41 >  double vel[3], pos[3], frc[3];
42 >
43    double rj[3];
44    double instaTemp, instaPress, instaVol;
45 <  double tt2, tb2;
43 <  double angle;
45 >  double tt2, tb2, scaleFactor;
46  
47    tt2 = tauThermostat * tauThermostat;
48    tb2 = tauBarostat * tauBarostat;
# Line 49 | Line 51 | void NPTi::moveA() {
51    instaPress = tStats->getPressure();
52    instaVol = tStats->getVolume();
53    
54 <  // first evolve chi a half step
54 >   // first evolve chi a half step
55    
56    chi += dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
57 <  eta += dt2 * ( instaVol * (instaPress - targetPressure) / (NkBT*tb2));
57 >  eta += dt2 * ( instaVol * (instaPress - targetPressure) /
58 >                 (p_convert*NkBT*tb2));
59  
60    for( i=0; i<nAtoms; i++ ){
61 <    atomIndex = i * 3;
62 <    aMatIndex = i * 9;
63 <    
61 <    // velocity half step
62 <    for( j=atomIndex; j<(atomIndex+3); j++ )
63 <      vel[j] += dt2 * ((frc[j]/atoms[i]->getMass())*eConvert
64 <                       - vel[j]*(chi+eta));
61 >    atoms[i]->getVel( vel );
62 >    atoms[i]->getPos( pos );
63 >    atoms[i]->getFrc( frc );
64  
65 <    // position whole step    
65 >    mass = atoms[i]->getMass();
66  
67 <    rj[0] = pos[atomIndex];
68 <    rj[1] = pos[atomIndex+1];
69 <    rj[2] = pos[atomIndex+2];
70 <    
67 >    for (j=0; j < 3; j++) {
68 >      vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*(chi+eta));
69 >      rj[j] = pos[j];
70 >    }
71 >
72 >    atoms[i]->setVel( vel );
73 >
74      info->wrapVector(rj);
75  
76 <    pos[atomIndex] += dt * (vel[atomIndex] + eta*rj[0]);
77 <    pos[atomIndex+1] += dt * (vel[atomIndex+1] + eta*rj[1]);
78 <    pos[atomIndex+2] += dt * (vel[atomIndex+2] + eta*rj[2]);
79 <  
76 >    for (j = 0; j < 3; j++)
77 >      pos[j] += dt * (vel[j] + eta*rj[j]);
78 >
79 >
80 >    atoms[i]->setPos( pos );
81 >
82 >
83      if( atoms[i]->isDirectional() ){
84  
85        dAtom = (DirectionalAtom *)atoms[i];
86            
87        // get and convert the torque to body frame
88        
89 <      Tb[0] = dAtom->getTx();
85 <      Tb[1] = dAtom->getTy();
86 <      Tb[2] = dAtom->getTz();
87 <      
89 >      dAtom->getTrq( Tb );
90        dAtom->lab2Body( Tb );
91        
92        // get the angular momentum, and propagate a half step
93  
94 <      ji[0] = dAtom->getJx();
95 <      ji[1] = dAtom->getJy();
96 <      ji[2] = dAtom->getJz();
94 >      dAtom->getJ( ji );
95 >
96 >      for (j=0; j < 3; j++)
97 >        ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);
98        
96      ji[0] += dt2 * (Tb[0] * eConvert - ji[0]*chi);
97      ji[1] += dt2 * (Tb[1] * eConvert - ji[1]*chi);
98      ji[2] += dt2 * (Tb[2] * eConvert - ji[2]*chi);
99      
99        // use the angular velocities to propagate the rotation matrix a
100        // full time step
101 <      
101 >
102 >      dAtom->getA(A);
103 >      dAtom->getI(I);
104 >    
105        // rotate about the x-axis      
106 <      angle = dt2 * ji[0] / dAtom->getIxx();
107 <      this->rotate( 1, 2, angle, ji, &Amat[aMatIndex] );
108 <      
106 >      angle = dt2 * ji[0] / I[0][0];
107 >      this->rotate( 1, 2, angle, ji, A );
108 >
109        // rotate about the y-axis
110 <      angle = dt2 * ji[1] / dAtom->getIyy();
111 <      this->rotate( 2, 0, angle, ji, &Amat[aMatIndex] );
110 >      angle = dt2 * ji[1] / I[1][1];
111 >      this->rotate( 2, 0, angle, ji, A );
112        
113        // rotate about the z-axis
114 <      angle = dt * ji[2] / dAtom->getIzz();
115 <      this->rotate( 0, 1, angle, ji, &Amat[aMatIndex] );
114 >      angle = dt * ji[2] / I[2][2];
115 >      this->rotate( 0, 1, angle, ji, A);
116        
117        // rotate about the y-axis
118 <      angle = dt2 * ji[1] / dAtom->getIyy();
119 <      this->rotate( 2, 0, angle, ji, &Amat[aMatIndex] );
118 >      angle = dt2 * ji[1] / I[1][1];
119 >      this->rotate( 2, 0, angle, ji, A );
120        
121         // rotate about the x-axis
122 <      angle = dt2 * ji[0] / dAtom->getIxx();
123 <      this->rotate( 1, 2, angle, ji, &Amat[aMatIndex] );
122 >      angle = dt2 * ji[0] / I[0][0];
123 >      this->rotate( 1, 2, angle, ji, A );
124        
125 <      dAtom->setJx( ji[0] );
126 <      dAtom->setJy( ji[1] );
127 <      dAtom->setJz( ji[2] );
128 <    }
127 <    
125 >      dAtom->setJ( ji );
126 >      dAtom->setA( A  );    
127 >    }                
128 >
129    }
130 +
131    // Scale the box after all the positions have been moved:
132 +  
133 +  scaleFactor = exp(dt*eta);
134  
135 <  info->scaleBox(exp(dt*eta));
136 <
135 >  if (scaleFactor > 1.1 || scaleFactor < 0.9) {
136 >    sprintf( painCave.errMsg,
137 >             "NPTi error: Attempting a Box scaling of more than 10 percent"
138 >             " check your tauBarostat, as it is probably too small!\n"
139 >             " eta = %lf, scaleFactor = %lf\n", eta, scaleFactor
140 >             );
141 >    painCave.isFatal = 1;
142 >    simError();
143 >  } else {        
144 >    info->scaleBox(exp(dt*eta));      
145 >  }
146   }
147  
148   void NPTi::moveB( void ){
149 <  int i,j,k;
150 <  int atomIndex;
149 >
150 >  int i, j;
151    DirectionalAtom* dAtom;
152 <  double Tb[3];
153 <  double ji[3];
152 >  double Tb[3], ji[3];
153 >  double vel[3], frc[3];
154 >  double mass;
155 >
156    double instaTemp, instaPress, instaVol;
157    double tt2, tb2;
158    
# Line 149 | Line 164 | void NPTi::moveB( void ){
164    instaVol = tStats->getVolume();
165  
166    chi += dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
167 <  eta += dt2 * ( instaVol * (instaPress - targetPressure) / (NkBT*tb2));
167 >  eta += dt2 * ( instaVol * (instaPress - targetPressure) /
168 >                 (p_convert*NkBT*tb2));
169    
170    for( i=0; i<nAtoms; i++ ){
171 <    atomIndex = i * 3;
172 <    
171 >
172 >    atoms[i]->getVel( vel );
173 >    atoms[i]->getFrc( frc );
174 >
175 >    mass = atoms[i]->getMass();
176 >
177      // velocity half step
178 <    for( j=atomIndex; j<(atomIndex+3); j++ )
179 <    for( j=atomIndex; j<(atomIndex+3); j++ )
160 <      vel[j] += dt2 * ((frc[j]/atoms[i]->getMass())*eConvert
161 <                       - vel[j]*(chi+eta));
178 >    for (j=0; j < 3; j++)
179 >      vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*(chi+eta));
180      
181 +    atoms[i]->setVel( vel );
182 +
183      if( atoms[i]->isDirectional() ){
184 <      
184 >
185        dAtom = (DirectionalAtom *)atoms[i];
186 <      
187 <      // get and convert the torque to body frame
188 <      
189 <      Tb[0] = dAtom->getTx();
170 <      Tb[1] = dAtom->getTy();
171 <      Tb[2] = dAtom->getTz();
172 <      
186 >
187 >      // get and convert the torque to body frame      
188 >
189 >      dAtom->getTrq( Tb );
190        dAtom->lab2Body( Tb );
191 <      
192 <      // get the angular momentum, and complete the angular momentum
193 <      // half step
194 <      
195 <      ji[0] = dAtom->getJx();
196 <      ji[1] = dAtom->getJy();
197 <      ji[2] = dAtom->getJz();
198 <      
199 <      ji[0] += dt2 * (Tb[0] * eConvert - ji[0]*chi);
183 <      ji[1] += dt2 * (Tb[1] * eConvert - ji[1]*chi);
184 <      ji[2] += dt2 * (Tb[2] * eConvert - ji[2]*chi);
185 <      
186 <      dAtom->setJx( ji[0] );
187 <      dAtom->setJy( ji[1] );
188 <      dAtom->setJz( ji[2] );
191 >
192 >      // get the angular momentum, and propagate a half step
193 >
194 >      dAtom->getJ( ji );
195 >
196 >      for (j=0; j < 3; j++)
197 >        ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);    
198 >
199 >      dAtom->setJ( ji );
200      }
201    }
202   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines