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 558 by mmeineke, Thu Jun 19 19:21:23 2003 UTC vs.
Revision 567 by mmeineke, Wed Jun 25 21:12:14 2003 UTC

# Line 1 | Line 1
1   #include <iostream>
2   #include <cstdlib>
3 + #include <cmath>
4  
5   #ifdef IS_MPI
6   #include "mpiSimulation.hpp"
# Line 10 | Line 11 | Integrator::Integrator( SimInfo* theInfo, ForceFields*
11   #include "simError.h"
12  
13  
14 < Integrator::Integrator( SimInfo* theInfo, ForceFields* the_ff ){
14 > Integrator::Integrator( SimInfo *theInfo, ForceFields* the_ff ){
15    
16    info = theInfo;
17    myFF = the_ff;
# Line 33 | Line 34 | Integrator::Integrator( SimInfo* theInfo, ForceFields*
34    constrainedDsqr = NULL;
35    moving          = NULL;
36    moved           = NULL;
37 <  prePos          = NULL;
37 >  oldPos          = NULL;
38    
39    nConstrained = 0;
40  
# Line 48 | Line 49 | Integrator::~Integrator() {
49      delete[] constrainedDsqr;
50      delete[] moving;
51      delete[] moved;
52 <    delete[] prePos;
52 < k
52 >    delete[] oldPos;
53    }
54    
55   }
# Line 137 | Line 137 | void Integrator::checkConstraints( void ){
137        constrainedA[i] = temp_con[i].get_a();
138        constrainedB[i] = temp_con[i].get_b();
139        constrainedDsqr[i] = temp_con[i].get_dsqr();
140 +
141      }
142  
143      
# Line 147 | Line 148 | void Integrator::checkConstraints( void ){
148      moving = new int[nAtoms];
149      moved  = new int[nAtoms];
150  
151 <    prePos = new double[nAtoms*3];
151 >    oldPos = new double[nAtoms*3];
152    }
153    
154    delete[] temp_con;
# Line 157 | Line 158 | void Integrator::integrate( void ){
158   void Integrator::integrate( void ){
159  
160    int i, j;                         // loop counters
160  double kE = 0.0;                  // the kinetic energy  
161  double rot_kE;
162  double trans_kE;
163  int tl;                        // the time loop conter
164  double dt2;                       // half the dt
161  
166  double vx, vy, vz;    // the velocities
167  double vx2, vy2, vz2; // the square of the velocities
168  double rx, ry, rz;    // the postitions
169  
170  double ji[3];   // the body frame angular momentum
171  double jx2, jy2, jz2; // the square of the angular momentums
172  double Tb[3];   // torque in the body frame
173  double angle;   // the angle through which to rotate the rotation matrix
174  double A[3][3]; // the rotation matrix
175  double press[9];
176
177  double dt          = info->dt;
162    double runTime     = info->run_time;
163    double sampleTime  = info->sampleTime;
164    double statusTime  = info->statusTime;
# Line 188 | Line 172 | void Integrator::integrate( void ){
172    int calcPot, calcStress;
173    int isError;
174  
175 +
176 +
177    tStats   = new Thermo( info );
178 <  e_out    = new StatWriter( info );
179 <  dump_out = new DumpWriter( info );
178 >  statOut  = new StatWriter( info );
179 >  dumpOut  = new DumpWriter( info );
180  
181 <  Atom** atoms = info->atoms;
181 >  atoms = info->atoms;
182    DirectionalAtom* dAtom;
183 +
184 +  dt = info->dt;
185    dt2 = 0.5 * dt;
186  
187    // initialize the forces before the first step
# Line 205 | Line 193 | void Integrator::integrate( void ){
193      tStats->velocitize();
194    }
195    
196 <  dump_out->writeDump( 0.0 );
197 <  e_out->writeStat( 0.0 );
196 >  dumpOut->writeDump( 0.0 );
197 >  statOut->writeStat( 0.0 );
198    
199    calcPot     = 0;
200    calcStress  = 0;
# Line 215 | Line 203 | void Integrator::integrate( void ){
203    currStatus  = statusTime;
204    currTime    = 0.0;;
205  
206 +
207 +  readyCheck();
208 +
209 + #ifdef IS_MPI
210 +  strcpy( checkPointMsg,
211 +          "The integrator is ready to go." );
212 +  MPIcheckPoint();
213 + #endif // is_mpi
214 +
215 +
216 +  pos  = Atom::getPosArray();
217 +  vel  = Atom::getVelArray();
218 +  frc  = Atom::getFrcArray();
219 +  trq  = Atom::getTrqArray();
220 +  Amat = Atom::getAmatArray();
221 +
222    while( currTime < runTime ){
223  
224      if( (currTime+dt) >= currStatus ){
225        calcPot = 1;
226        calcStress = 1;
227      }
228 <    
228 >
229      integrateStep( calcPot, calcStress );
230        
231      currTime += dt;
# Line 234 | Line 238 | void Integrator::integrate( void ){
238      }
239  
240      if( currTime >= currSample ){
241 <      dump_out->writeDump( currTime );
241 >      dumpOut->writeDump( currTime );
242        currSample += sampleTime;
243      }
244  
245      if( currTime >= currStatus ){
246 <      e_out->writeStat( time * dt );
246 >      statOut->writeStat( currTime );
247        calcPot = 0;
248        calcStress = 0;
249        currStatus += statusTime;
250      }
251 +
252 + #ifdef IS_MPI
253 +    strcpy( checkPointMsg,
254 +            "successfully took a time step." );
255 +    MPIcheckPoint();
256 + #endif // is_mpi
257 +
258    }
259  
260 <  dump_out->writeFinal();
260 >  dumpOut->writeFinal();
261  
262 <  delete dump_out;
263 <  delete e_out;
262 >  delete dumpOut;
263 >  delete statOut;
264   }
265  
266   void Integrator::integrateStep( int calcPot, int calcStress ){
267  
268 +
269 +      
270    // Position full step, and velocity half step
271  
272 <  //preMove();
272 >  preMove();
273    moveA();
274    if( nConstrained ) constrainA();
275  
# Line 279 | Line 292 | void Integrator::moveA( void ){
292    DirectionalAtom* dAtom;
293    double Tb[3];
294    double ji[3];
295 +  double angle;
296  
297 +
298 +
299    for( i=0; i<nAtoms; i++ ){
300      atomIndex = i * 3;
301      aMatIndex = i * 9;
302 <    
302 >
303      // velocity half step
304      for( j=atomIndex; j<(atomIndex+3); j++ )
305        vel[j] += ( dt2 * frc[j] / atoms[i]->getMass() ) * eConvert;
306  
307      // position whole step    
308 <    for( j=atomIndex; j<(atomIndex+3); j++ )
309 <      pos[j] += dt * vel[j];
294 <
295 <  
308 >    for( j=atomIndex; j<(atomIndex+3); j++ ) pos[j] += dt * vel[j];
309 >    
310      if( atoms[i]->isDirectional() ){
311  
312        dAtom = (DirectionalAtom *)atoms[i];
# Line 316 | Line 330 | void Integrator::moveA( void ){
330        
331        // rotate about the x-axis      
332        angle = dt2 * ji[0] / dAtom->getIxx();
333 <      this->rotate( 1, 2, angle, ji, &aMat[aMatIndex] );
333 >      this->rotate( 1, 2, angle, ji, &Amat[aMatIndex] );
334        
335        // rotate about the y-axis
336        angle = dt2 * ji[1] / dAtom->getIyy();
337 <      this->rotate( 2, 0, angle, ji, &aMat[aMatIndex] );
337 >      this->rotate( 2, 0, angle, ji, &Amat[aMatIndex] );
338        
339        // rotate about the z-axis
340        angle = dt * ji[2] / dAtom->getIzz();
341 <      this->rotate( 0, 1, angle, ji, &aMat[aMatIndex] );
341 >      this->rotate( 0, 1, angle, ji, &Amat[aMatIndex] );
342        
343        // rotate about the y-axis
344        angle = dt2 * ji[1] / dAtom->getIyy();
345 <      this->rotate( 2, 0, angle, ji, &aMat[aMatIndex] );
345 >      this->rotate( 2, 0, angle, ji, &Amat[aMatIndex] );
346        
347         // rotate about the x-axis
348        angle = dt2 * ji[0] / dAtom->getIxx();
349 <      this->rotate( 1, 2, angle, ji, &aMat[aMatIndex] );
349 >      this->rotate( 1, 2, angle, ji, &Amat[aMatIndex] );
350        
351        dAtom->setJx( ji[0] );
352        dAtom->setJy( ji[1] );
# Line 376 | Line 390 | void Integrator::moveB( void ){
390        ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * eConvert;
391        ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * eConvert;
392        
379      jx2 = ji[0] * ji[0];
380      jy2 = ji[1] * ji[1];
381      jz2 = ji[2] * ji[2];
382      
393        dAtom->setJx( ji[0] );
394        dAtom->setJy( ji[1] );
395        dAtom->setJz( ji[2] );
# Line 392 | Line 402 | void Integrator::preMove( void ){
402    int i;
403  
404    if( nConstrained ){
405 <    if( oldAtoms != nAtoms ){
396 <      
397 <      // save oldAtoms to check for lode balanceing later on.
398 <      
399 <      oldAtoms = nAtoms;
400 <      
401 <      delete[] moving;
402 <      delete[] moved;
403 <      delete[] oldPos;
404 <      
405 <      moving = new int[nAtoms];
406 <      moved  = new int[nAtoms];
407 <      
408 <      oldPos = new double[nAtoms*3];
409 <    }
410 <  
405 >
406      for(i=0; i<(nAtoms*3); i++) oldPos[i] = pos[i];
407    }
408   }  
# Line 418 | Line 413 | void Integrator::constrainA(){
413    int done;
414    double pxab, pyab, pzab;
415    double rxab, ryab, rzab;
416 <  int a, b;
416 >  int a, b, ax, ay, az, bx, by, bz;
417    double rma, rmb;
418    double dx, dy, dz;
419 +  double rpab;
420    double rabsq, pabsq, rpabsq;
421    double diffsq;
422    double gab;
# Line 433 | Line 429 | void Integrator::constrainA(){
429      moving[i] = 0;
430      moved[i]  = 1;
431    }
432 <  
437 <  
432 >
433    iteration = 0;
434    done = 0;
435    while( !done && (iteration < maxIteration )){
# Line 444 | Line 439 | void Integrator::constrainA(){
439  
440        a = constrainedA[i];
441        b = constrainedB[i];
442 <    
442 >      
443 >      ax = (a*3) + 0;
444 >      ay = (a*3) + 1;
445 >      az = (a*3) + 2;
446 >
447 >      bx = (b*3) + 0;
448 >      by = (b*3) + 1;
449 >      bz = (b*3) + 2;
450 >
451        if( moved[a] || moved[b] ){
452          
453 <        pxab = pos[3*a+0] - pos[3*b+0];
454 <        pyab = pos[3*a+1] - pos[3*b+1];
455 <        pzab = pos[3*a+2] - pos[3*b+2];
453 >        pxab = pos[ax] - pos[bx];
454 >        pyab = pos[ay] - pos[by];
455 >        pzab = pos[az] - pos[bz];
456  
457 <        //periodic boundary condition
457 >        //periodic boundary condition
458          pxab = pxab - info->box_x * copysign(1, pxab)
459 <          * int(pxab / info->box_x + 0.5);
460 <        pyab = pyab - info->box_y * copysign(1, pyab)
461 <          * int(pyab / info->box_y + 0.5);
462 <        pzab = pzab - info->box_z * copysign(1, pzab)
463 <          * int(pzab / info->box_z + 0.5);
461 <      
462 <        pabsq = pxab * pxab + pyab * pyab + pzab * pzab;
463 <        rabsq = constraintedDsqr[i];
464 <        diffsq = pabsq - rabsq;
459 >          * (int)( fabs(pxab / info->box_x) + 0.5);
460 >        pyab = pyab - info->box_y * copysign(1, pyab)
461 >          * (int)( fabs(pyab / info->box_y) + 0.5);
462 >        pzab = pzab - info->box_z * copysign(1, pzab)
463 >          * (int)( fabs(pzab / info->box_z) + 0.5);
464  
465 +        pabsq = pxab * pxab + pyab * pyab + pzab * pzab;
466 +
467 +        rabsq = constrainedDsqr[i];
468 +        diffsq = rabsq - pabsq;
469 +
470          // the original rattle code from alan tidesley
471 <        if (fabs(diffsq) > tol*rabsq*2) {
472 <          rxab = oldPos[3*a+0] - oldPos[3*b+0];
473 <          ryab = oldPos[3*a+1] - oldPos[3*b+1];
474 <          rzab = oldPos[3*a+2] - oldPos[3*b+2];
475 <
471 >        if (fabs(diffsq) > (tol*rabsq*2)) {
472 >          rxab = oldPos[ax] - oldPos[bx];
473 >          ryab = oldPos[ay] - oldPos[by];
474 >          rzab = oldPos[az] - oldPos[bz];
475 >
476            rxab = rxab - info->box_x * copysign(1, rxab)
477 <            * int(rxab / info->box_x + 0.5);
477 >            * (int)( fabs(rxab / info->box_x) + 0.5);
478            ryab = ryab - info->box_y * copysign(1, ryab)
479 <            * int(ryab / info->box_y + 0.5);
479 >            * (int)( fabs(ryab / info->box_y) + 0.5);
480            rzab = rzab - info->box_z * copysign(1, rzab)
481 <            * int(rzab / info->box_z + 0.5);
481 >            * (int)( fabs(rzab / info->box_z) + 0.5);
482  
483            rpab = rxab * pxab + ryab * pyab + rzab * pzab;
484 +
485            rpabsq = rpab * rpab;
486  
487  
488            if (rpabsq < (rabsq * -diffsq)){
489 +
490   #ifdef IS_MPI
491              a = atoms[a]->getGlobalIndex();
492              b = atoms[b]->getGlobalIndex();
493   #endif //is_mpi
494              sprintf( painCave.errMsg,
495 <                     "Constraint failure in constrainA at atom %d and %d\n.",
495 >                     "Constraint failure in constrainA at atom %d and %d.\n",
496                       a, b );
497              painCave.isFatal = 1;
498              simError();
# Line 494 | Line 500 | void Integrator::constrainA(){
500  
501            rma = 1.0 / atoms[a]->getMass();
502            rmb = 1.0 / atoms[b]->getMass();
503 <          
503 >
504            gab = diffsq / ( 2.0 * ( rma + rmb ) * rpab );
505 +
506            dx = rxab * gab;
507            dy = ryab * gab;
508            dz = rzab * gab;
509  
510 <          pos[3*a+0] += rma * dx;
511 <          pos[3*a+1] += rma * dy;
512 <          pos[3*a+2] += rma * dz;
510 >          pos[ax] += rma * dx;
511 >          pos[ay] += rma * dy;
512 >          pos[az] += rma * dz;
513  
514 <          pos[3*b+0] -= rmb * dx;
515 <          pos[3*b+1] -= rmb * dy;
516 <          pos[3*b+2] -= rmb * dz;
514 >          pos[bx] -= rmb * dx;
515 >          pos[by] -= rmb * dy;
516 >          pos[bz] -= rmb * dz;
517  
518            dx = dx / dt;
519            dy = dy / dt;
520            dz = dz / dt;
521  
522 <          vel[3*a+0] += rma * dx;
523 <          vel[3*a+1] += rma * dy;
524 <          vel[3*a+2] += rma * dz;
522 >          vel[ax] += rma * dx;
523 >          vel[ay] += rma * dy;
524 >          vel[az] += rma * dz;
525  
526 <          vel[3*b+0] -= rmb * dx;
527 <          vel[3*b+1] -= rmb * dy;
528 <          vel[3*b+2] -= rmb * dz;
526 >          vel[bx] -= rmb * dx;
527 >          vel[by] -= rmb * dy;
528 >          vel[bz] -= rmb * dz;
529  
530            moving[a] = 1;
531            moving[b] = 1;
# Line 538 | Line 545 | void Integrator::constrainA(){
545  
546    if( !done ){
547  
548 <    sprintf( painCae.errMsg,
548 >    sprintf( painCave.errMsg,
549               "Constraint failure in constrainA, too many iterations: %d\n",
550 <             iterations );
550 >             iteration );
551      painCave.isFatal = 1;
552      simError();
553    }
# Line 553 | Line 560 | void Integrator::constrainB( void ){
560    int done;
561    double vxab, vyab, vzab;
562    double rxab, ryab, rzab;
563 <  int a, b;
563 >  int a, b, ax, ay, az, bx, by, bz;
564    double rma, rmb;
565    double dx, dy, dz;
566    double rabsq, pabsq, rvab;
# Line 561 | Line 568 | void Integrator::constrainB( void ){
568    double gab;
569    int iteration;
570  
571 <  for(i=0; i<nAtom; i++){
571 >  for(i=0; i<nAtoms; i++){
572      moving[i] = 0;
573      moved[i] = 1;
574    }
575  
576    done = 0;
577 +  iteration = 0;
578    while( !done && (iteration < maxIteration ) ){
579  
580 +    done = 1;
581 +
582      for(i=0; i<nConstrained; i++){
583        
584        a = constrainedA[i];
585        b = constrainedB[i];
586  
587 +      ax = (a*3) + 0;
588 +      ay = (a*3) + 1;
589 +      az = (a*3) + 2;
590 +
591 +      bx = (b*3) + 0;
592 +      by = (b*3) + 1;
593 +      bz = (b*3) + 2;
594 +
595        if( moved[a] || moved[b] ){
596          
597 <        vxab = vel[3*a+0] - vel[3*b+0];
598 <        vyab = vel[3*a+1] - vel[3*b+1];
599 <        vzab = vel[3*a+2] - vel[3*b+2];
597 >        vxab = vel[ax] - vel[bx];
598 >        vyab = vel[ay] - vel[by];
599 >        vzab = vel[az] - vel[bz];
600  
601 <        rxab = pos[3*a+0] - pos[3*b+0];q
602 <        ryab = pos[3*a+1] - pos[3*b+1];
603 <        rzab = pos[3*a+2] - pos[3*b+2];
601 >        rxab = pos[ax] - pos[bx];
602 >        ryab = pos[ay] - pos[by];
603 >        rzab = pos[az] - pos[bz];
604          
605 +
606          rxab = rxab - info->box_x * copysign(1, rxab)
607 <          * int(rxab / info->box_x + 0.5);
607 >          * (int)( fabs(rxab / info->box_x) + 0.5);
608          ryab = ryab - info->box_y * copysign(1, ryab)
609 <          * int(ryab / info->box_y + 0.5);
609 >          * (int)( fabs(ryab / info->box_y) + 0.5);
610          rzab = rzab - info->box_z * copysign(1, rzab)
611 <          * int(rzab / info->box_z + 0.5);
612 <
611 >          * (int)( fabs(rzab / info->box_z) + 0.5);
612 >        
613          rma = 1.0 / atoms[a]->getMass();
614          rmb = 1.0 / atoms[b]->getMass();
615  
616          rvab = rxab * vxab + ryab * vyab + rzab * vzab;
617            
618 <        gab = -rvab / ( ( rma + rmb ) * constraintsDsqr[i] );
618 >        gab = -rvab / ( ( rma + rmb ) * constrainedDsqr[i] );
619  
620          if (fabs(gab) > tol) {
621            
# Line 604 | Line 623 | void Integrator::constrainB( void ){
623            dy = ryab * gab;
624            dz = rzab * gab;
625            
626 <          vel[3*a+0] += rma * dx;
627 <          vel[3*a+1] += rma * dy;
628 <          vel[3*a+2] += rma * dz;
626 >          vel[ax] += rma * dx;
627 >          vel[ay] += rma * dy;
628 >          vel[az] += rma * dz;
629  
630 <          vel[3*b+0] -= rmb * dx;
631 <          vel[3*b+1] -= rmb * dy;
632 <          vel[3*b+2] -= rmb * dz;
630 >          vel[bx] -= rmb * dx;
631 >          vel[by] -= rmb * dy;
632 >          vel[bz] -= rmb * dz;
633            
634            moving[a] = 1;
635            moving[b] = 1;
# Line 630 | Line 649 | void Integrator::constrainB( void ){
649    if( !done ){
650  
651    
652 <    sprintf( painCae.errMsg,
652 >    sprintf( painCave.errMsg,
653               "Constraint failure in constrainB, too many iterations: %d\n",
654 <             iterations );
654 >             iteration );
655      painCave.isFatal = 1;
656      simError();
657    }
# Line 646 | Line 665 | void Integrator::rotate( int axes1, int axes2, double
665  
666  
667   void Integrator::rotate( int axes1, int axes2, double angle, double ji[3],
668 <                         double A[3][3] ){
668 >                         double A[9] ){
669  
670    int i,j,k;
671    double sinAngle;
# Line 662 | Line 681 | void Integrator::rotate( int axes1, int axes2, double
681  
682    for(i=0; i<3; i++){
683      for(j=0; j<3; j++){
684 <      tempA[j][i] = A[i][j];
684 >      tempA[j][i] = A[3*i + j];
685      }
686    }
687  
# Line 713 | Line 732 | void Integrator::rotate( int axes1, int axes2, double
732    //            A[][] = A[][] * transpose(rot[][])
733  
734  
735 <  // NOte for as yet unknown reason, we are setting the performing the
735 >  // NOte for as yet unknown reason, we are performing the
736    // calculation as:
737    //                transpose(A[][]) = transpose(A[][]) * transpose(rot[][])
738  
739    for(i=0; i<3; i++){
740      for(j=0; j<3; j++){
741 <      A[j][i] = 0.0;
741 >      A[3*j + i] = 0.0;
742        for(k=0; k<3; k++){
743 <        A[j][i] += tempA[i][k] * rot[j][k];
743 >        A[3*j + i] += tempA[i][k] * rot[j][k];
744        }
745      }
746    }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines