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

Comparing trunk/OOPSE/libmdtools/Integrator.cpp (file contents):
Revision 601 by gezelter, Mon Jul 14 23:06:09 2003 UTC vs.
Revision 1452 by tim, Mon Aug 23 15:11:36 2004 UTC

# Line 1 | Line 1
1   #include <iostream>
2 < #include <cstdlib>
3 < #include <cmath>
4 <
2 > #include <stdlib.h>
3 > #include <math.h>
4 > #include "Rattle.hpp"
5 > #include "Roll.hpp"
6   #ifdef IS_MPI
7   #include "mpiSimulation.hpp"
8   #include <unistd.h>
9   #endif //is_mpi
10  
11 + #ifdef PROFILE
12 + #include "mdProfile.hpp"
13 + #endif // profile
14 +
15   #include "Integrator.hpp"
16   #include "simError.h"
17  
18  
19 < Integrator::Integrator( SimInfo *theInfo, ForceFields* the_ff ){
20 <  
19 > template<typename T> Integrator<T>::Integrator(SimInfo* theInfo,
20 >                                               ForceFields* the_ff){
21    info = theInfo;
22    myFF = the_ff;
23    isFirst = 1;
# Line 21 | Line 26 | Integrator::Integrator( SimInfo *theInfo, ForceFields*
26    nMols = info->n_mol;
27  
28    // give a little love back to the SimInfo object
24  
25  if( info->the_integrator != NULL ) delete info->the_integrator;
26  info->the_integrator = this;
29  
30 +  if (info->the_integrator != NULL){
31 +    delete info->the_integrator;
32 +  }
33 +
34    nAtoms = info->n_atoms;
35 +  integrableObjects = info->integrableObjects;
36  
37 <  // check for constraints
37 >  consFramework = new RollFramework(info);
38 >
39 >  if(consFramework == NULL){
40 >    sprintf(painCave.errMsg,
41 >      "Integrator::Intergrator() Error: Memory allocation error for RattleFramework" );
42 >    painCave.isFatal = 1;
43 >    simError();
44 >  }
45    
46 <  constrainedA    = NULL;
47 <  constrainedB    = NULL;
46 > /*
47 >  // check for constraints
48 >
49 >  constrainedA = NULL;
50 >  constrainedB = NULL;
51    constrainedDsqr = NULL;
52 <  moving          = NULL;
53 <  moved           = NULL;
54 <  oldPos          = NULL;
55 <  
52 >  moving = NULL;
53 >  moved = NULL;
54 >  oldPos = NULL;
55 >
56    nConstrained = 0;
57  
58    checkConstraints();
59 + */
60   }
61  
62 < Integrator::~Integrator() {
63 <  
64 <  if( nConstrained ){
62 > template<typename T> Integrator<T>::~Integrator(){
63 >  if (consFramework != NULL)
64 >    delete consFramework;
65 > /*
66 >  if (nConstrained){
67      delete[] constrainedA;
68      delete[] constrainedB;
69      delete[] constrainedDsqr;
# Line 51 | Line 71 | Integrator::~Integrator() {
71      delete[] moved;
72      delete[] oldPos;
73    }
74 <  
74 > */
75   }
76  
77 < void Integrator::checkConstraints( void ){
78 <
59 <
77 > /*
78 > template<typename T> void Integrator<T>::checkConstraints(void){
79    isConstrained = 0;
80  
81 <  Constraint *temp_con;
82 <  Constraint *dummy_plug;
81 >  Constraint* temp_con;
82 >  Constraint* dummy_plug;
83    temp_con = new Constraint[info->n_SRI];
84    nConstrained = 0;
85    int constrained = 0;
86 <  
86 >
87    SRI** theArray;
88 <  for(int i = 0; i < nMols; i++){
89 <    
90 <    theArray = (SRI**) molecules[i].getMyBonds();
91 <    for(int j=0; j<molecules[i].getNBonds(); j++){
73 <      
88 >  for (int i = 0; i < nMols; i++){
89 >
90 >          theArray = (SRI * *) molecules[i].getMyBonds();
91 >    for (int j = 0; j < molecules[i].getNBonds(); j++){
92        constrained = theArray[j]->is_constrained();
93  
94 <      std::cerr << "Is the folowing bond constrained \n";
95 <      theArray[j]->printMe();
96 <      
97 <      if(constrained){
98 <        
81 <        std::cerr << "Yes\n";
94 >      if (constrained){
95 >        dummy_plug = theArray[j]->get_constraint();
96 >        temp_con[nConstrained].set_a(dummy_plug->get_a());
97 >        temp_con[nConstrained].set_b(dummy_plug->get_b());
98 >        temp_con[nConstrained].set_dsqr(dummy_plug->get_dsqr());
99  
100 <        dummy_plug = theArray[j]->get_constraint();
101 <        temp_con[nConstrained].set_a( dummy_plug->get_a() );
102 <        temp_con[nConstrained].set_b( dummy_plug->get_b() );
86 <        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
87 <        
88 <        nConstrained++;
89 <        constrained = 0;
90 <      }
91 <      else std::cerr << "No.\n";
100 >        nConstrained++;
101 >        constrained = 0;
102 >      }
103      }
104  
105 <    theArray = (SRI**) molecules[i].getMyBends();
106 <    for(int j=0; j<molecules[i].getNBends(); j++){
96 <      
105 >    theArray = (SRI * *) molecules[i].getMyBends();
106 >    for (int j = 0; j < molecules[i].getNBends(); j++){
107        constrained = theArray[j]->is_constrained();
108 <      
109 <      if(constrained){
110 <        
111 <        dummy_plug = theArray[j]->get_constraint();
112 <        temp_con[nConstrained].set_a( dummy_plug->get_a() );
113 <        temp_con[nConstrained].set_b( dummy_plug->get_b() );
114 <        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
115 <        
116 <        nConstrained++;
107 <        constrained = 0;
108 >
109 >      if (constrained){
110 >        dummy_plug = theArray[j]->get_constraint();
111 >        temp_con[nConstrained].set_a(dummy_plug->get_a());
112 >        temp_con[nConstrained].set_b(Dummy_plug->get_b());
113 >        temp_con[nConstrained].set_dsqr(dummy_plug->get_dsqr());
114 >
115 >        nConstrained++;
116 >        constrained = 0;
117        }
118      }
119  
120 <    theArray = (SRI**) molecules[i].getMyTorsions();
121 <    for(int j=0; j<molecules[i].getNTorsions(); j++){
113 <      
120 >    theArray = (SRI * *) molecules[i].getMyTorsions();
121 >    for (int j = 0; j < molecules[i].getNTorsions(); j++){
122        constrained = theArray[j]->is_constrained();
123 <      
124 <      if(constrained){
125 <        
126 <        dummy_plug = theArray[j]->get_constraint();
127 <        temp_con[nConstrained].set_a( dummy_plug->get_a() );
128 <        temp_con[nConstrained].set_b( dummy_plug->get_b() );
129 <        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
130 <        
131 <        nConstrained++;
124 <        constrained = 0;
123 >
124 >      if (constrained){
125 >        dummy_plug = theArray[j]->get_constraint();
126 >        temp_con[nConstrained].set_a(dummy_plug->get_a());
127 >        temp_con[nConstrained].set_b(dummy_plug->get_b());
128 >        temp_con[nConstrained].set_dsqr(dummy_plug->get_dsqr());
129 >
130 >        nConstrained++;
131 >        constrained = 0;
132        }
133      }
134    }
135  
136 <  if(nConstrained > 0){
137 <    
136 >
137 >  if (nConstrained > 0){
138      isConstrained = 1;
139  
140 <    if(constrainedA != NULL )    delete[] constrainedA;
141 <    if(constrainedB != NULL )    delete[] constrainedB;
142 <    if(constrainedDsqr != NULL ) delete[] constrainedDsqr;
143 <
144 <    constrainedA =    new int[nConstrained];
145 <    constrainedB =    new int[nConstrained];
140 >    if (constrainedA != NULL)
141 >      delete[] constrainedA;
142 >    if (constrainedB != NULL)
143 >      delete[] constrainedB;
144 >    if (constrainedDsqr != NULL)
145 >      delete[] constrainedDsqr;
146 >
147 >    constrainedA = new int[nConstrained];
148 >    constrainedB = new int[nConstrained];
149      constrainedDsqr = new double[nConstrained];
150 <    
151 <    for( int i = 0; i < nConstrained; i++){
142 <      
150 >
151 >    for (int i = 0; i < nConstrained; i++){
152        constrainedA[i] = temp_con[i].get_a();
153        constrainedB[i] = temp_con[i].get_b();
154        constrainedDsqr[i] = temp_con[i].get_dsqr();
146
155      }
156  
157 <    
158 <    // save oldAtoms to check for lode balanceing later on.
159 <    
157 >
158 >    // save oldAtoms to check for lode balancing later on.
159 >
160      oldAtoms = nAtoms;
161 <    
161 >
162      moving = new int[nAtoms];
163 <    moved  = new int[nAtoms];
163 >    moved = new int[nAtoms];
164  
165 <    oldPos = new double[nAtoms*3];
165 >    oldPos = new double[nAtoms * 3];
166    }
167 <  
167 >
168    delete[] temp_con;
169   }
170 + */
171  
172 + template<typename T> void Integrator<T>::integrate(void){
173  
174 < void Integrator::integrate( void ){
175 <
176 <  int i, j;                         // loop counters
167 <
168 <  double runTime     = info->run_time;
169 <  double sampleTime  = info->sampleTime;
170 <  double statusTime  = info->statusTime;
174 >  double runTime = info->run_time;
175 >  double sampleTime = info->sampleTime;
176 >  double statusTime = info->statusTime;
177    double thermalTime = info->thermalTime;
178 +  double resetTime = info->resetTime;
179  
180 +  double difference;
181    double currSample;
182    double currThermal;
183    double currStatus;
184 <  double currTime;
184 >  double currReset;
185  
186    int calcPot, calcStress;
179  int isError;
187  
188 <  tStats   = new Thermo( info );
189 <  statOut  = new StatWriter( info );
190 <  dumpOut  = new DumpWriter( info );
188 >  tStats = new Thermo(info);
189 >  statOut = new StatWriter(info);
190 >  dumpOut = new DumpWriter(info);
191  
192    atoms = info->atoms;
186  DirectionalAtom* dAtom;
193  
194    dt = info->dt;
195    dt2 = 0.5 * dt;
196  
197 <  // initialize the forces before the first step
197 >  readyCheck();
198  
199 <  myFF->doForces(1,1);
199 >  // remove center of mass drift velocity (in case we passed in a configuration
200 >  // that was drifting
201 >  tStats->removeCOMdrift();
202 >  //tStats->removeAngularMomentum();
203    
204 <  if( info->setTemp ){
205 <    
206 <    tStats->velocitize();
204 >  // initialize the retraints if necessary
205 >  if (info->useSolidThermInt && !info->useLiquidThermInt) {
206 >    myFF->initRestraints();
207    }
208 +
209 +  // initialize the forces before the first step
210 +
211 +  calcForce(1, 1);
212 +
213 +  //execute constraint algorithm to make sure at the very beginning the system is constrained  
214 +  //consFramework->doPreConstraint();
215 +  //consFramework->doConstrainA();
216 +  //calcForce(1, 1);
217 +  //consFramework->doConstrainB();
218    
219 <  dumpOut->writeDump( 0.0 );
220 <  statOut->writeStat( 0.0 );
221 <  
219 >  if (info->setTemp){
220 >    thermalize();
221 >  }
222 >
223    calcPot     = 0;
224    calcStress  = 0;
225 <  currSample  = sampleTime;
226 <  currThermal = thermalTime;
227 <  currStatus  = statusTime;
228 <  currTime    = 0.0;;
225 >  currSample  = sampleTime + info->getTime();
226 >  currThermal = thermalTime+ info->getTime();
227 >  currStatus  = statusTime + info->getTime();
228 >  currReset   = resetTime  + info->getTime();
229  
230 +  dumpOut->writeDump(info->getTime());
231 +  statOut->writeStat(info->getTime());
232  
211  readyCheck();
233  
234   #ifdef IS_MPI
235 <  strcpy( checkPointMsg,
215 <          "The integrator is ready to go." );
235 >  strcpy(checkPointMsg, "The integrator is ready to go.");
236    MPIcheckPoint();
237   #endif // is_mpi
238  
239 <  while( currTime < runTime ){
240 <
241 <    if( (currTime+dt) >= currStatus ){
239 >  while (info->getTime() < runTime && !stopIntegrator()){
240 >    difference = info->getTime() + dt - currStatus;
241 >    if (difference > 0 || fabs(difference) < 1e-4 ){
242        calcPot = 1;
243        calcStress = 1;
244      }
245  
246 <    integrateStep( calcPot, calcStress );
247 <      
248 <    currTime += dt;
246 > #ifdef PROFILE
247 >    startProfile( pro1 );
248 > #endif
249 >    
250 >    integrateStep(calcPot, calcStress);
251  
252 <    if( info->setTemp ){
253 <      if( currTime >= currThermal ){
254 <        tStats->velocitize();
255 <        currThermal += thermalTime;
252 > #ifdef PROFILE
253 >    endProfile( pro1 );
254 >
255 >    startProfile( pro2 );
256 > #endif // profile
257 >
258 >    info->incrTime(dt);
259 >
260 >    if (info->setTemp){
261 >      if (info->getTime() >= currThermal){
262 >        thermalize();
263 >        currThermal += thermalTime;
264        }
265      }
266  
267 <    if( currTime >= currSample ){
268 <      dumpOut->writeDump( currTime );
267 >    if (info->getTime() >= currSample){
268 >      dumpOut->writeDump(info->getTime());
269        currSample += sampleTime;
270      }
271  
272 <    if( currTime >= currStatus ){
273 <      statOut->writeStat( currTime );
274 <      calcPot = 0;
272 >    if (info->getTime() >= currStatus){
273 >      statOut->writeStat(info->getTime());
274 >      calcPot = 0;
275        calcStress = 0;
276        currStatus += statusTime;
277 <    }
277 >    }
278  
279 +    if (info->resetIntegrator){
280 +      if (info->getTime() >= currReset){
281 +        this->resetIntegrator();
282 +        currReset += resetTime;
283 +      }
284 +    }
285 +    
286 + #ifdef PROFILE
287 +    endProfile( pro2 );
288 + #endif //profile
289 +
290   #ifdef IS_MPI
291 <    strcpy( checkPointMsg,
251 <            "successfully took a time step." );
291 >    strcpy(checkPointMsg, "successfully took a time step.");
292      MPIcheckPoint();
293   #endif // is_mpi
254
294    }
295  
296 <  dumpOut->writeFinal(currTime);
296 >  // dump out a file containing the omega values for the final configuration
297 >  if (info->useSolidThermInt && !info->useLiquidThermInt)
298 >    myFF->dumpzAngle();
299 >  
300  
301    delete dumpOut;
302    delete statOut;
303   }
304  
305 < void Integrator::integrateStep( int calcPot, int calcStress ){
305 > template<typename T> void Integrator<T>::integrateStep(int calcPot,
306 >                                                       int calcStress){
307 >  // Position full step, and velocity half step
308  
309 + #ifdef PROFILE
310 +  startProfile(pro3);
311 + #endif //profile
312  
313 <      
314 <  // Position full step, and velocity half step
313 >  //save old state (position, velocity etc)
314 >  consFramework->doPreConstraint();
315  
316 <  preMove();
316 > #ifdef PROFILE
317 >  endProfile(pro3);
318 >
319 >  startProfile(pro4);
320 > #endif // profile
321 >
322    moveA();
271  if( nConstrained ) constrainA();
323  
324 + #ifdef PROFILE
325 +  endProfile(pro4);
326 +  
327 +  startProfile(pro5);
328 + #endif//profile
329 +
330 +
331 + #ifdef IS_MPI
332 +  strcpy(checkPointMsg, "Succesful moveA\n");
333 +  MPIcheckPoint();
334 + #endif // is_mpi
335 +
336    // calc forces
337 +  calcForce(calcPot, calcStress);
338  
339 <  myFF->doForces(calcPot,calcStress);
339 > #ifdef IS_MPI
340 >  strcpy(checkPointMsg, "Succesful doForces\n");
341 >  MPIcheckPoint();
342 > #endif // is_mpi
343  
344 + #ifdef PROFILE
345 +  endProfile( pro5 );
346 +
347 +  startProfile( pro6 );
348 + #endif //profile
349 +
350 +  consFramework->doPreConstraint();
351 +
352    // finish the velocity  half step
353 <  
353 >
354    moveB();
355 <  if( nConstrained ) constrainB();
356 <  
355 >
356 > #ifdef PROFILE
357 >  endProfile(pro6);
358 > #endif // profile
359 >
360 > #ifdef IS_MPI
361 >  strcpy(checkPointMsg, "Succesful moveB\n");
362 >  MPIcheckPoint();
363 > #endif // is_mpi
364   }
365  
366  
367 < void Integrator::moveA( void ){
368 <  
287 <  int i, j;
367 > template<typename T> void Integrator<T>::moveA(void){
368 >  size_t i, j;
369    DirectionalAtom* dAtom;
370    double Tb[3], ji[3];
290  double A[3][3], I[3][3];
291  double angle;
371    double vel[3], pos[3], frc[3];
372    double mass;
373 +  double omega;
374 +
375 +  for (i = 0; i < integrableObjects.size() ; i++){
376 +    integrableObjects[i]->getVel(vel);
377 +    integrableObjects[i]->getPos(pos);
378 +    integrableObjects[i]->getFrc(frc);
379 +    
380 +    mass = integrableObjects[i]->getMass();
381  
382 <  for( i=0; i<nAtoms; i++ ){
296 <
297 <    atoms[i]->getVel( vel );
298 <    atoms[i]->getPos( pos );
299 <    atoms[i]->getFrc( frc );
300 <
301 <    mass = atoms[i]->getMass();
302 <
303 <    for (j=0; j < 3; j++) {
382 >    for (j = 0; j < 3; j++){
383        // velocity half step
384 <      vel[j] += ( dt2 * frc[j] / mass ) * eConvert;
384 >      vel[j] += (dt2 * frc[j] / mass) * eConvert;
385        // position whole step
386        pos[j] += dt * vel[j];
387      }
388  
389 <    atoms[i]->setVel( vel );
390 <    atoms[i]->setPos( pos );
389 >    integrableObjects[i]->setVel(vel);
390 >    integrableObjects[i]->setPos(pos);
391  
392 <    if( atoms[i]->isDirectional() ){
392 >    if (integrableObjects[i]->isDirectional()){
393  
315      dAtom = (DirectionalAtom *)atoms[i];
316          
394        // get and convert the torque to body frame
318      
319      dAtom->getTrq( Tb );
320      dAtom->lab2Body( Tb );
395  
396 +      integrableObjects[i]->getTrq(Tb);
397 +      integrableObjects[i]->lab2Body(Tb);
398 +
399        // get the angular momentum, and propagate a half step
400  
401 <      dAtom->getJ( ji );
401 >      integrableObjects[i]->getJ(ji);
402  
403 <      for (j=0; j < 3; j++)
403 >      for (j = 0; j < 3; j++)
404          ji[j] += (dt2 * Tb[j]) * eConvert;
328      
329      // use the angular velocities to propagate the rotation matrix a
330      // full time step
405  
406 <      dAtom->getA(A);
333 <      dAtom->getI(I);
334 <    
335 <      // rotate about the x-axis      
336 <      angle = dt2 * ji[0] / I[0][0];
337 <      this->rotate( 1, 2, angle, ji, A );
406 >      this->rotationPropagation( integrableObjects[i], ji );
407  
408 <      // rotate about the y-axis
340 <      angle = dt2 * ji[1] / I[1][1];
341 <      this->rotate( 2, 0, angle, ji, A );
342 <      
343 <      // rotate about the z-axis
344 <      angle = dt * ji[2] / I[2][2];
345 <      this->rotate( 0, 1, angle, ji, A);
346 <      
347 <      // rotate about the y-axis
348 <      angle = dt2 * ji[1] / I[1][1];
349 <      this->rotate( 2, 0, angle, ji, A );
350 <      
351 <       // rotate about the x-axis
352 <      angle = dt2 * ji[0] / I[0][0];
353 <      this->rotate( 1, 2, angle, ji, A );
354 <      
408 >      integrableObjects[i]->setJ(ji);
409  
410 <      dAtom->setJ( ji );
357 <      dAtom->setA( A  );
358 <          
359 <    }    
410 >    }
411    }
412 +
413 +  consFramework->doConstrainA();
414   }
415  
416  
417 < void Integrator::moveB( void ){
417 > template<typename T> void Integrator<T>::moveB(void){
418    int i, j;
366  DirectionalAtom* dAtom;
419    double Tb[3], ji[3];
420    double vel[3], frc[3];
421    double mass;
422  
423 <  for( i=0; i<nAtoms; i++ ){
424 <
425 <    atoms[i]->getVel( vel );
374 <    atoms[i]->getFrc( frc );
423 >  for (i = 0; i < integrableObjects.size(); i++){
424 >    integrableObjects[i]->getVel(vel);
425 >    integrableObjects[i]->getFrc(frc);
426  
427 <    mass = atoms[i]->getMass();
427 >    mass = integrableObjects[i]->getMass();
428  
429      // velocity half step
430 <    for (j=0; j < 3; j++)
431 <      vel[j] += ( dt2 * frc[j] / mass ) * eConvert;
381 <    
382 <    atoms[i]->setVel( vel );
383 <
384 <    if( atoms[i]->isDirectional() ){
430 >    for (j = 0; j < 3; j++)
431 >      vel[j] += (dt2 * frc[j] / mass) * eConvert;
432  
433 <      dAtom = (DirectionalAtom *)atoms[i];
433 >    integrableObjects[i]->setVel(vel);
434  
435 <      // get and convert the torque to body frame      
435 >    if (integrableObjects[i]->isDirectional()){
436  
437 <      dAtom->getTrq( Tb );
391 <      dAtom->lab2Body( Tb );
437 >      // get and convert the torque to body frame
438  
439 +      integrableObjects[i]->getTrq(Tb);
440 +      integrableObjects[i]->lab2Body(Tb);
441 +
442        // get the angular momentum, and propagate a half step
443  
444 <      dAtom->getJ( ji );
444 >      integrableObjects[i]->getJ(ji);
445  
446 <      for (j=0; j < 3; j++)
446 >      for (j = 0; j < 3; j++)
447          ji[j] += (dt2 * Tb[j]) * eConvert;
399      
448  
449 <      dAtom->setJ( ji );
449 >
450 >      integrableObjects[i]->setJ(ji);
451      }
452 +
453    }
454 +
455 +  consFramework->doConstrainB();
456   }
457  
458 < void Integrator::preMove( void ){
458 > /*
459 > template<typename T> void Integrator<T>::preMove(void){
460    int i, j;
461    double pos[3];
462  
463 <  if( nConstrained ){
463 >  if (nConstrained){
464 >    for (i = 0; i < nAtoms; i++){
465 >      atoms[i]->getPos(pos);
466  
467 <    for(i=0; i < nAtoms; i++) {
468 <
414 <      atoms[i]->getPos( pos );
415 <
416 <      for (j = 0; j < 3; j++) {        
417 <        oldPos[3*i + j] = pos[j];
467 >      for (j = 0; j < 3; j++){
468 >        oldPos[3 * i + j] = pos[j];
469        }
419
470      }
471 <  }  
471 >  }
472   }
473  
474 < void Integrator::constrainA(){
475 <
426 <  int i,j,k;
474 > template<typename T> void Integrator<T>::constrainA(){
475 >  int i, j;
476    int done;
477    double posA[3], posB[3];
478    double velA[3], velB[3];
# Line 438 | Line 487 | void Integrator::constrainA(){
487    double gab;
488    int iteration;
489  
490 <  for( i=0; i<nAtoms; i++){    
490 >  for (i = 0; i < nAtoms; i++){
491      moving[i] = 0;
492 <    moved[i]  = 1;
492 >    moved[i] = 1;
493    }
494  
495    iteration = 0;
496    done = 0;
497 <  while( !done && (iteration < maxIteration )){
449 <
497 >  while (!done && (iteration < maxIteration)){
498      done = 1;
499 <    for(i=0; i<nConstrained; i++){
452 <
499 >    for (i = 0; i < nConstrained; i++){
500        a = constrainedA[i];
501        b = constrainedB[i];
455      
456      ax = (a*3) + 0;
457      ay = (a*3) + 1;
458      az = (a*3) + 2;
502  
503 <      bx = (b*3) + 0;
504 <      by = (b*3) + 1;
505 <      bz = (b*3) + 2;
503 >      ax = (a * 3) + 0;
504 >      ay = (a * 3) + 1;
505 >      az = (a * 3) + 2;
506  
507 <      if( moved[a] || moved[b] ){
508 <        
509 <        atoms[a]->getPos( posA );
510 <        atoms[b]->getPos( posB );
511 <        
512 <        for (j = 0; j < 3; j++ )
507 >      bx = (b * 3) + 0;
508 >      by = (b * 3) + 1;
509 >      bz = (b * 3) + 2;
510 >
511 >      if (moved[a] || moved[b]){
512 >        atoms[a]->getPos(posA);
513 >        atoms[b]->getPos(posB);
514 >
515 >        for (j = 0; j < 3; j++)
516            pab[j] = posA[j] - posB[j];
471        
472        //periodic boundary condition
517  
518 <        info->wrapVector( pab );
518 >        //periodic boundary condition
519  
520 <        pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
520 >        info->wrapVector(pab);
521  
522 <        rabsq = constrainedDsqr[i];
479 <        diffsq = rabsq - pabsq;
522 >        pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
523  
524 <        // the original rattle code from alan tidesley
525 <        if (fabs(diffsq) > (tol*rabsq*2)) {
483 <          rab[0] = oldPos[ax] - oldPos[bx];
484 <          rab[1] = oldPos[ay] - oldPos[by];
485 <          rab[2] = oldPos[az] - oldPos[bz];
524 >        rabsq = constrainedDsqr[i];
525 >        diffsq = rabsq - pabsq;
526  
527 <          info->wrapVector( rab );
527 >        // the original rattle code from alan tidesley
528 >        if (fabs(diffsq) > (tol * rabsq * 2)){
529 >          rab[0] = oldPos[ax] - oldPos[bx];
530 >          rab[1] = oldPos[ay] - oldPos[by];
531 >          rab[2] = oldPos[az] - oldPos[bz];
532  
533 <          rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
533 >          info->wrapVector(rab);
534  
535 <          rpabsq = rpab * rpab;
535 >          rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
536  
537 +          rpabsq = rpab * rpab;
538  
494          if (rpabsq < (rabsq * -diffsq)){
539  
540 +          if (rpabsq < (rabsq * -diffsq)){
541   #ifdef IS_MPI
542 <            a = atoms[a]->getGlobalIndex();
543 <            b = atoms[b]->getGlobalIndex();
542 >            a = atoms[a]->getGlobalIndex();
543 >            b = atoms[b]->getGlobalIndex();
544   #endif //is_mpi
545 <            sprintf( painCave.errMsg,
546 <                     "Constraint failure in constrainA at atom %d and %d.\n",
547 <                     a, b );
548 <            painCave.isFatal = 1;
549 <            simError();
550 <          }
545 >            sprintf(painCave.errMsg,
546 >                    "Constraint failure in constrainA at atom %d and %d.\n", a,
547 >                    b);
548 >            painCave.isFatal = 1;
549 >            simError();
550 >          }
551  
552 <          rma = 1.0 / atoms[a]->getMass();
553 <          rmb = 1.0 / atoms[b]->getMass();
552 >          rma = 1.0 / atoms[a]->getMass();
553 >          rmb = 1.0 / atoms[b]->getMass();
554  
555 <          gab = diffsq / ( 2.0 * ( rma + rmb ) * rpab );
555 >          gab = diffsq / (2.0 * (rma + rmb) * rpab);
556  
557            dx = rab[0] * gab;
558            dy = rab[1] * gab;
559            dz = rab[2] * gab;
560  
561 <          posA[0] += rma * dx;
562 <          posA[1] += rma * dy;
563 <          posA[2] += rma * dz;
561 >          posA[0] += rma * dx;
562 >          posA[1] += rma * dy;
563 >          posA[2] += rma * dz;
564  
565 <          atoms[a]->setPos( posA );
565 >          atoms[a]->setPos(posA);
566  
567 <          posB[0] -= rmb * dx;
568 <          posB[1] -= rmb * dy;
569 <          posB[2] -= rmb * dz;
567 >          posB[0] -= rmb * dx;
568 >          posB[1] -= rmb * dy;
569 >          posB[2] -= rmb * dz;
570  
571 <          atoms[b]->setPos( posB );
571 >          atoms[b]->setPos(posB);
572  
573            dx = dx / dt;
574            dy = dy / dt;
575            dz = dz / dt;
576  
577 <          atoms[a]->getVel( velA );
577 >          atoms[a]->getVel(velA);
578  
579 <          velA[0] += rma * dx;
580 <          velA[1] += rma * dy;
581 <          velA[2] += rma * dz;
579 >          velA[0] += rma * dx;
580 >          velA[1] += rma * dy;
581 >          velA[2] += rma * dz;
582  
583 <          atoms[a]->setVel( velA );
583 >          atoms[a]->setVel(velA);
584  
585 <          atoms[b]->getVel( velB );
585 >          atoms[b]->getVel(velB);
586  
587 <          velB[0] -= rmb * dx;
588 <          velB[1] -= rmb * dy;
589 <          velB[2] -= rmb * dz;
587 >          velB[0] -= rmb * dx;
588 >          velB[1] -= rmb * dy;
589 >          velB[2] -= rmb * dz;
590  
591 <          atoms[b]->setVel( velB );
591 >          atoms[b]->setVel(velB);
592  
593 <          moving[a] = 1;
594 <          moving[b] = 1;
595 <          done = 0;
596 <        }
593 >          moving[a] = 1;
594 >          moving[b] = 1;
595 >          done = 0;
596 >        }
597        }
598      }
599 <    
600 <    for(i=0; i<nAtoms; i++){
556 <      
599 >
600 >    for (i = 0; i < nAtoms; i++){
601        moved[i] = moving[i];
602        moving[i] = 0;
603      }
# Line 561 | Line 605 | void Integrator::constrainA(){
605      iteration++;
606    }
607  
608 <  if( !done ){
609 <
610 <    sprintf( painCave.errMsg,
611 <             "Constraint failure in constrainA, too many iterations: %d\n",
568 <             iteration );
608 >  if (!done){
609 >    sprintf(painCave.errMsg,
610 >            "Constraint failure in constrainA, too many iterations: %d\n",
611 >            iteration);
612      painCave.isFatal = 1;
613      simError();
614    }
615  
616   }
617  
618 < void Integrator::constrainB( void ){
619 <  
577 <  int i,j,k;
618 > template<typename T> void Integrator<T>::constrainB(void){
619 >  int i, j;
620    int done;
621    double posA[3], posB[3];
622    double velA[3], velB[3];
# Line 583 | Line 625 | void Integrator::constrainB( void ){
625    int a, b, ax, ay, az, bx, by, bz;
626    double rma, rmb;
627    double dx, dy, dz;
628 <  double rabsq, pabsq, rvab;
587 <  double diffsq;
628 >  double rvab;
629    double gab;
630    int iteration;
631  
632 <  for(i=0; i<nAtoms; i++){
632 >  for (i = 0; i < nAtoms; i++){
633      moving[i] = 0;
634      moved[i] = 1;
635    }
636  
637    done = 0;
638    iteration = 0;
639 <  while( !done && (iteration < maxIteration ) ){
599 <
639 >  while (!done && (iteration < maxIteration)){
640      done = 1;
641  
642 <    for(i=0; i<nConstrained; i++){
603 <      
642 >    for (i = 0; i < nConstrained; i++){
643        a = constrainedA[i];
644        b = constrainedB[i];
645  
646 <      ax = (a*3) + 0;
647 <      ay = (a*3) + 1;
648 <      az = (a*3) + 2;
646 >      ax = (a * 3) + 0;
647 >      ay = (a * 3) + 1;
648 >      az = (a * 3) + 2;
649  
650 <      bx = (b*3) + 0;
651 <      by = (b*3) + 1;
652 <      bz = (b*3) + 2;
650 >      bx = (b * 3) + 0;
651 >      by = (b * 3) + 1;
652 >      bz = (b * 3) + 2;
653  
654 <      if( moved[a] || moved[b] ){
654 >      if (moved[a] || moved[b]){
655 >        atoms[a]->getVel(velA);
656 >        atoms[b]->getVel(velB);
657  
658 <        atoms[a]->getVel( velA );
659 <        atoms[b]->getVel( velB );
660 <          
620 <        vxab = velA[0] - velB[0];
621 <        vyab = velA[1] - velB[1];
622 <        vzab = velA[2] - velB[2];
658 >        vxab = velA[0] - velB[0];
659 >        vyab = velA[1] - velB[1];
660 >        vzab = velA[2] - velB[2];
661  
662 <        atoms[a]->getPos( posA );
663 <        atoms[b]->getPos( posB );
662 >        atoms[a]->getPos(posA);
663 >        atoms[b]->getPos(posB);
664  
665 <        for (j = 0; j < 3; j++)
665 >        for (j = 0; j < 3; j++)
666            rab[j] = posA[j] - posB[j];
629          
630        info->wrapVector( rab );
631        
632        rma = 1.0 / atoms[a]->getMass();
633        rmb = 1.0 / atoms[b]->getMass();
667  
668 <        rvab = rab[0] * vxab + rab[1] * vyab + rab[2] * vzab;
636 <          
637 <        gab = -rvab / ( ( rma + rmb ) * constrainedDsqr[i] );
668 >        info->wrapVector(rab);
669  
670 <        if (fabs(gab) > tol) {
671 <          
641 <          dx = rab[0] * gab;
642 <          dy = rab[1] * gab;
643 <          dz = rab[2] * gab;
644 <        
645 <          velA[0] += rma * dx;
646 <          velA[1] += rma * dy;
647 <          velA[2] += rma * dz;
670 >        rma = 1.0 / atoms[a]->getMass();
671 >        rmb = 1.0 / atoms[b]->getMass();
672  
673 <          atoms[a]->setVel( velA );
673 >        rvab = rab[0] * vxab + rab[1] * vyab + rab[2] * vzab;
674  
675 <          velB[0] -= rmb * dx;
652 <          velB[1] -= rmb * dy;
653 <          velB[2] -= rmb * dz;
675 >        gab = -rvab / ((rma + rmb) * constrainedDsqr[i]);
676  
677 <          atoms[b]->setVel( velB );
678 <          
679 <          moving[a] = 1;
680 <          moving[b] = 1;
681 <          done = 0;
682 <        }
677 >        if (fabs(gab) > tol){
678 >          dx = rab[0] * gab;
679 >          dy = rab[1] * gab;
680 >          dz = rab[2] * gab;
681 >
682 >          velA[0] += rma * dx;
683 >          velA[1] += rma * dy;
684 >          velA[2] += rma * dz;
685 >
686 >          atoms[a]->setVel(velA);
687 >
688 >          velB[0] -= rmb * dx;
689 >          velB[1] -= rmb * dy;
690 >          velB[2] -= rmb * dz;
691 >
692 >          atoms[b]->setVel(velB);
693 >
694 >          moving[a] = 1;
695 >          moving[b] = 1;
696 >          done = 0;
697 >        }
698        }
699      }
700  
701 <    for(i=0; i<nAtoms; i++){
701 >    for (i = 0; i < nAtoms; i++){
702        moved[i] = moving[i];
703        moving[i] = 0;
704      }
705 <    
705 >
706      iteration++;
707    }
671  
672  if( !done ){
708  
709 <  
710 <    sprintf( painCave.errMsg,
711 <             "Constraint failure in constrainB, too many iterations: %d\n",
712 <             iteration );
709 >  if (!done){
710 >    sprintf(painCave.errMsg,
711 >            "Constraint failure in constrainB, too many iterations: %d\n",
712 >            iteration);
713      painCave.isFatal = 1;
714      simError();
715 <  }
681 <
715 >  }
716   }
717 + */
718 + template<typename T> void Integrator<T>::rotationPropagation
719 + ( StuntDouble* sd, double ji[3] ){
720  
721 < void Integrator::rotate( int axes1, int axes2, double angle, double ji[3],
722 <                         double A[3][3] ){
721 >  double angle;
722 >  double A[3][3], I[3][3];
723 >  int i, j, k;
724  
725 <  int i,j,k;
725 >  // use the angular velocities to propagate the rotation matrix a
726 >  // full time step
727 >
728 >  sd->getA(A);
729 >  sd->getI(I);
730 >
731 >  if (sd->isLinear()) {
732 >    i = sd->linearAxis();
733 >    j = (i+1)%3;
734 >    k = (i+2)%3;
735 >    
736 >    angle = dt2 * ji[j] / I[j][j];
737 >    this->rotate( k, i, angle, ji, A );
738 >
739 >    angle = dt * ji[k] / I[k][k];
740 >    this->rotate( i, j, angle, ji, A);
741 >
742 >    angle = dt2 * ji[j] / I[j][j];
743 >    this->rotate( k, i, angle, ji, A );
744 >
745 >  } else {
746 >    // rotate about the x-axis
747 >    angle = dt2 * ji[0] / I[0][0];
748 >    this->rotate( 1, 2, angle, ji, A );
749 >    
750 >    // rotate about the y-axis
751 >    angle = dt2 * ji[1] / I[1][1];
752 >    this->rotate( 2, 0, angle, ji, A );
753 >    
754 >    // rotate about the z-axis
755 >    angle = dt * ji[2] / I[2][2];
756 >    sd->addZangle(angle);
757 >    this->rotate( 0, 1, angle, ji, A);
758 >    
759 >    // rotate about the y-axis
760 >    angle = dt2 * ji[1] / I[1][1];
761 >    this->rotate( 2, 0, angle, ji, A );
762 >    
763 >    // rotate about the x-axis
764 >    angle = dt2 * ji[0] / I[0][0];
765 >    this->rotate( 1, 2, angle, ji, A );
766 >    
767 >  }
768 >  sd->setA( A  );
769 > }
770 >
771 > template<typename T> void Integrator<T>::rotate(int axes1, int axes2,
772 >                                                double angle, double ji[3],
773 >                                                double A[3][3]){
774 >  int i, j, k;
775    double sinAngle;
776    double cosAngle;
777    double angleSqr;
# Line 696 | Line 783 | void Integrator::rotate( int axes1, int axes2, double
783  
784    // initialize the tempA
785  
786 <  for(i=0; i<3; i++){
787 <    for(j=0; j<3; j++){
786 >  for (i = 0; i < 3; i++){
787 >    for (j = 0; j < 3; j++){
788        tempA[j][i] = A[i][j];
789      }
790    }
791  
792    // initialize the tempJ
793  
794 <  for( i=0; i<3; i++) tempJ[i] = ji[i];
795 <  
794 >  for (i = 0; i < 3; i++)
795 >    tempJ[i] = ji[i];
796 >
797    // initalize rot as a unit matrix
798  
799    rot[0][0] = 1.0;
# Line 715 | Line 803 | void Integrator::rotate( int axes1, int axes2, double
803    rot[1][0] = 0.0;
804    rot[1][1] = 1.0;
805    rot[1][2] = 0.0;
806 <  
806 >
807    rot[2][0] = 0.0;
808    rot[2][1] = 0.0;
809    rot[2][2] = 1.0;
810 <  
810 >
811    // use a small angle aproximation for sin and cosine
812  
813 <  angleSqr  = angle * angle;
813 >  angleSqr = angle * angle;
814    angleSqrOver4 = angleSqr / 4.0;
815    top = 1.0 - angleSqrOver4;
816    bottom = 1.0 + angleSqrOver4;
# Line 735 | Line 823 | void Integrator::rotate( int axes1, int axes2, double
823  
824    rot[axes1][axes2] = sinAngle;
825    rot[axes2][axes1] = -sinAngle;
826 <  
826 >
827    // rotate the momentum acoording to: ji[] = rot[][] * ji[]
828 <  
829 <  for(i=0; i<3; i++){
828 >
829 >  for (i = 0; i < 3; i++){
830      ji[i] = 0.0;
831 <    for(k=0; k<3; k++){
831 >    for (k = 0; k < 3; k++){
832        ji[i] += rot[i][k] * tempJ[k];
833      }
834    }
835  
836 <  // rotate the Rotation matrix acording to:
836 >  // rotate the Rotation matrix acording to:
837    //            A[][] = A[][] * transpose(rot[][])
838  
839  
# Line 753 | Line 841 | void Integrator::rotate( int axes1, int axes2, double
841    // calculation as:
842    //                transpose(A[][]) = transpose(A[][]) * transpose(rot[][])
843  
844 <  for(i=0; i<3; i++){
845 <    for(j=0; j<3; j++){
844 >  for (i = 0; i < 3; i++){
845 >    for (j = 0; j < 3; j++){
846        A[j][i] = 0.0;
847 <      for(k=0; k<3; k++){
848 <        A[j][i] += tempA[i][k] * rot[j][k];
847 >      for (k = 0; k < 3; k++){
848 >        A[j][i] += tempA[i][k] * rot[j][k];
849        }
850      }
851    }
852   }
853 +
854 + template<typename T> void Integrator<T>::calcForce(int calcPot, int calcStress){
855 +  myFF->doForces(calcPot, calcStress);
856 + }
857 +
858 + template<typename T> void Integrator<T>::thermalize(){
859 +  tStats->velocitize();
860 + }
861 +
862 + template<typename T> double Integrator<T>::getConservedQuantity(void){
863 +  return tStats->getTotalE();
864 + }
865 + template<typename T> string Integrator<T>::getAdditionalParameters(void){
866 +  //By default, return a null string
867 +  //The reason we use string instead of char* is that if we use char*, we will
868 +  //return a pointer point to local variable which might cause problem
869 +  return string();
870 + }
871 +
872 +
873 + template<typename T>  void Integrator<T>::printQuaternion(StuntDouble* sd){
874 +  Mat4x4d S;
875 +  double I[3][3];
876 +  Vector4d j4;
877 +  Vector3d j;
878 +  Vector3d tempJ;
879 +  Vector4d qdot;
880 +  Vector4d omega4;
881 +  Mat4x4d I4;
882 +  Quaternion q;
883 +  double I0;
884 +  Vector4d p_qua;
885 +  
886 +  if (sd->isDirectional()){
887 +    sd->getQ(q.vec);
888 +    sd->getI(I);
889 +    sd->getJ(j.vec);
890 +
891 +    //omega4[0] = 0.0;
892 +    //omega4[1] = j[0]/I[0][0];
893 +    //omega4[2] = j[1]/I[1][1];
894 +    //omega4[3] = j[2]/I[2][2];
895 +
896 +    //S = getS(q);
897 +    //qdot = 0.5 * S * omega4;
898 +
899 +    //I0 = (qdot[1] * q[1] * I[0][0] + qdot[2] * q[2] * I[1][1] + qdot[3] * q[3] * I[2][2])/(qdot[1] * q[1]+ qdot[2] * q[2] + qdot[3] * q[3]);
900 +
901 +    //I4.element[0][0] = I0;
902 +    //I4.element[1][1] = I[0][0];
903 +    //I4.element[2][2] = I[1][1];
904 +    //I4.element[3][3] = I[2][2];
905 +
906 +    S = getS(q);
907 +    j4[0] = 0.0;
908 +    j4[1] = j[0];
909 +    j4[2] = j[1];
910 +    j4[3] = j[2];
911 +    
912 +    p_qua = 2 * S * j4;
913 +
914 +    j4 = 0.5 * S.transpose() * p_qua;
915 +    //cout << "q0^2 + q1^2 + q2^2 + q3^2 = " << q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3] << endl;
916 +    //cout << "q0*q0dot + q1*q1dot + q2 *q2dot + q3*q3dot = " <<q[0]*qdot[0] + q[1]*qdot[1] + q[2]*qdot[2] + q[3]*qdot[3] << endl;
917 +    //cout << "q1*q1dot* Ixx + q2*q2dot* Iyy + q3 *q3dot* Izz = " << qdot[1] * q[1] * I[0][0] + qdot[2] * q[2] * I[1][1] + qdot[3] * q[3] * I[2][2] << endl;
918 +    //cout << "q1*q1dot + q2 *q2dot + q3*q3dot = "  << qdot[1] * q[1]+ qdot[2] * q[2] + qdot[3] * q[3] << endl;
919 +    //cout << "I0 = " << I0 << endl;
920 +    cout << "p_qua[0] = " << p_qua[0] << endl;
921 +  }    
922 + }
923 +
924 + template<typename T> Mat4x4d Integrator<T>::getS(const Quaternion& q){
925 +  Mat4x4d result;
926 +
927 +  result.element[0][0] = q.x;
928 +  result.element[0][1] = -q.y;
929 +  result.element[0][2] = -q.z;
930 +  result.element[0][3] = -q.w;
931 +
932 +  result.element[1][0] = q.y;
933 +  result.element[1][1] = q.x;
934 +  result.element[1][2] = -q.w;
935 +  result.element[1][3] = q.z;
936 +
937 +  result.element[2][0] = q.z;
938 +  result.element[2][1] = q.w;
939 +  result.element[2][2] = q.x;
940 +  result.element[2][3] = -q.y;
941 +
942 +  result.element[3][0] = q.w;
943 +  result.element[3][1] = -q.z;
944 +  result.element[3][2] = q.y;
945 +  result.element[3][3] = q.x;
946 +
947 +  return result;  
948 + }
949 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines