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 559 by mmeineke, Thu Jun 19 22:02:44 2003 UTC vs.
Revision 643 by mmeineke, Mon Jul 21 21:27:40 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 >    delete[] oldPos;
53    }
54    
55   }
# Line 71 | Line 72 | void Integrator::checkConstraints( void ){
72      for(int j=0; j<molecules[i].getNBonds(); j++){
73        
74        constrained = theArray[j]->is_constrained();
75 <      
75 >
76        if(constrained){
77 <        
77 >
78          dummy_plug = theArray[j]->get_constraint();
79          temp_con[nConstrained].set_a( dummy_plug->get_a() );
80          temp_con[nConstrained].set_b( dummy_plug->get_b() );
# Line 81 | Line 82 | void Integrator::checkConstraints( void ){
82          
83          nConstrained++;
84          constrained = 0;
85 <      }
85 >      }
86      }
87  
88      theArray = (SRI**) molecules[i].getMyBends();
# Line 136 | 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 146 | 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 156 | Line 158 | void Integrator::integrate( void ){
158   void Integrator::integrate( void ){
159  
160    int i, j;                         // loop counters
159  double kE = 0.0;                  // the kinetic energy  
160  double rot_kE;
161  double trans_kE;
162  int tl;                        // the time loop conter
163  double dt2;                       // half the dt
161  
165  double vx, vy, vz;    // the velocities
166  double vx2, vy2, vz2; // the square of the velocities
167  double rx, ry, rz;    // the postitions
168  
169  double ji[3];   // the body frame angular momentum
170  double jx2, jy2, jz2; // the square of the angular momentums
171  double Tb[3];   // torque in the body frame
172  double angle;   // the angle through which to rotate the rotation matrix
173  double A[3][3]; // the rotation matrix
174  double press[9];
175
176  double dt          = info->dt;
162    double runTime     = info->run_time;
163    double sampleTime  = info->sampleTime;
164    double statusTime  = info->statusTime;
# Line 182 | Line 167 | void Integrator::integrate( void ){
167    double currSample;
168    double currThermal;
169    double currStatus;
185  double currTime;
170  
171    int calcPot, calcStress;
172    int isError;
173  
174    tStats   = new Thermo( info );
175 <  e_out    = new StatWriter( info );
176 <  dump_out = new DumpWriter( info );
175 >  statOut  = new StatWriter( info );
176 >  dumpOut  = new DumpWriter( info );
177  
178 <  Atom** atoms = info->atoms;
178 >  atoms = info->atoms;
179    DirectionalAtom* dAtom;
180 +
181 +  dt = info->dt;
182    dt2 = 0.5 * dt;
183  
184    // initialize the forces before the first step
# Line 204 | Line 190 | void Integrator::integrate( void ){
190      tStats->velocitize();
191    }
192    
207  dump_out->writeDump( 0.0 );
208  e_out->writeStat( 0.0 );
209  
193    calcPot     = 0;
194    calcStress  = 0;
195    currSample  = sampleTime;
196    currThermal = thermalTime;
197    currStatus  = statusTime;
215  currTime    = 0.0;;
198  
199 +  dumpOut->writeDump( info->getTime() );
200 +  statOut->writeStat( info->getTime() );
201  
202    readyCheck();
203  
# Line 223 | Line 207 | void Integrator::integrate( void ){
207    MPIcheckPoint();
208   #endif // is_mpi
209  
210 <  while( currTime < runTime ){
210 >  while( info->getTime() < runTime ){
211  
212 <    if( (currTime+dt) >= currStatus ){
212 >    if( (info->getTime()+dt) >= currStatus ){
213        calcPot = 1;
214        calcStress = 1;
215      }
216 <    
216 >
217      integrateStep( calcPot, calcStress );
218        
219 <    currTime += dt;
219 >    info->incrTime(dt);
220  
221      if( info->setTemp ){
222 <      if( currTime >= currThermal ){
222 >      if( info->getTime() >= currThermal ){
223          tStats->velocitize();
224          currThermal += thermalTime;
225        }
226      }
227  
228 <    if( currTime >= currSample ){
229 <      dump_out->writeDump( currTime );
228 >    if( info->getTime() >= currSample ){
229 >      dumpOut->writeDump( info->getTime() );
230        currSample += sampleTime;
231      }
232  
233 <    if( currTime >= currStatus ){
234 <      e_out->writeStat( time * dt );
233 >    if( info->getTime() >= currStatus ){
234 >      statOut->writeStat( info->getTime() );
235        calcPot = 0;
236        calcStress = 0;
237        currStatus += statusTime;
# Line 261 | Line 245 | void Integrator::integrate( void ){
245  
246    }
247  
248 <  dump_out->writeFinal();
248 >  dumpOut->writeFinal(info->getTime());
249  
250 <  delete dump_out;
251 <  delete e_out;
250 >  delete dumpOut;
251 >  delete statOut;
252   }
253  
254   void Integrator::integrateStep( int calcPot, int calcStress ){
255  
256 +
257 +      
258    // Position full step, and velocity half step
259  
260 <  //preMove();
260 >  preMove();
261    moveA();
262    if( nConstrained ) constrainA();
263  
264 +  
265 + #ifdef IS_MPI
266 +  strcpy( checkPointMsg, "Succesful moveA\n" );
267 +  MPIcheckPoint();
268 + #endif // is_mpi
269 +  
270 +
271    // calc forces
272  
273    myFF->doForces(calcPot,calcStress);
274  
275 + #ifdef IS_MPI
276 +  strcpy( checkPointMsg, "Succesful doForces\n" );
277 +  MPIcheckPoint();
278 + #endif // is_mpi
279 +  
280 +
281    // finish the velocity  half step
282    
283    moveB();
284    if( nConstrained ) constrainB();
285 <  
285 >  
286 > #ifdef IS_MPI
287 >  strcpy( checkPointMsg, "Succesful moveB\n" );
288 >  MPIcheckPoint();
289 > #endif // is_mpi
290 >  
291 >
292   }
293  
294  
295   void Integrator::moveA( void ){
296    
297 <  int i,j,k;
293 <  int atomIndex, aMatIndex;
297 >  int i, j;
298    DirectionalAtom* dAtom;
299 <  double Tb[3];
300 <  double ji[3];
299 >  double Tb[3], ji[3];
300 >  double A[3][3], I[3][3];
301 >  double angle;
302 >  double vel[3], pos[3], frc[3];
303 >  double mass;
304  
305    for( i=0; i<nAtoms; i++ ){
299    atomIndex = i * 3;
300    aMatIndex = i * 9;
301    
302    // velocity half step
303    for( j=atomIndex; j<(atomIndex+3); j++ )
304      vel[j] += ( dt2 * frc[j] / atoms[i]->getMass() ) * eConvert;
306  
307 <    // position whole step    
308 <    for( j=atomIndex; j<(atomIndex+3); j++ )
307 >    atoms[i]->getVel( vel );
308 >    atoms[i]->getPos( pos );
309 >    atoms[i]->getFrc( frc );
310 >
311 >    mass = atoms[i]->getMass();
312 >
313 >    for (j=0; j < 3; j++) {
314 >      // velocity half step
315 >      vel[j] += ( dt2 * frc[j] / mass ) * eConvert;
316 >      // position whole step
317        pos[j] += dt * vel[j];
318 +    }
319  
320 <  
320 >    atoms[i]->setVel( vel );
321 >    atoms[i]->setPos( pos );
322 >
323      if( atoms[i]->isDirectional() ){
324  
325        dAtom = (DirectionalAtom *)atoms[i];
326            
327        // get and convert the torque to body frame
328        
329 <      Tb[0] = dAtom->getTx();
318 <      Tb[1] = dAtom->getTy();
319 <      Tb[2] = dAtom->getTz();
320 <      
329 >      dAtom->getTrq( Tb );
330        dAtom->lab2Body( Tb );
331 <      
331 >
332        // get the angular momentum, and propagate a half step
333 <      
334 <      ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * eConvert;
335 <      ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * eConvert;
336 <      ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * eConvert;
333 >
334 >      dAtom->getJ( ji );
335 >
336 >      for (j=0; j < 3; j++)
337 >        ji[j] += (dt2 * Tb[j]) * eConvert;
338        
339        // use the angular velocities to propagate the rotation matrix a
340        // full time step
341 <      
341 >
342 >      dAtom->getA(A);
343 >      dAtom->getI(I);
344 >    
345        // rotate about the x-axis      
346 <      angle = dt2 * ji[0] / dAtom->getIxx();
347 <      this->rotate( 1, 2, angle, ji, &aMat[aMatIndex] );
348 <      
346 >      angle = dt2 * ji[0] / I[0][0];
347 >      this->rotate( 1, 2, angle, ji, A );
348 >
349        // rotate about the y-axis
350 <      angle = dt2 * ji[1] / dAtom->getIyy();
351 <      this->rotate( 2, 0, angle, ji, &aMat[aMatIndex] );
350 >      angle = dt2 * ji[1] / I[1][1];
351 >      this->rotate( 2, 0, angle, ji, A );
352        
353        // rotate about the z-axis
354 <      angle = dt * ji[2] / dAtom->getIzz();
355 <      this->rotate( 0, 1, angle, ji, &aMat[aMatIndex] );
354 >      angle = dt * ji[2] / I[2][2];
355 >      this->rotate( 0, 1, angle, ji, A);
356        
357        // rotate about the y-axis
358 <      angle = dt2 * ji[1] / dAtom->getIyy();
359 <      this->rotate( 2, 0, angle, ji, &aMat[aMatIndex] );
358 >      angle = dt2 * ji[1] / I[1][1];
359 >      this->rotate( 2, 0, angle, ji, A );
360        
361         // rotate about the x-axis
362 <      angle = dt2 * ji[0] / dAtom->getIxx();
363 <      this->rotate( 1, 2, angle, ji, &aMat[aMatIndex] );
362 >      angle = dt2 * ji[0] / I[0][0];
363 >      this->rotate( 1, 2, angle, ji, A );
364        
365 <      dAtom->setJx( ji[0] );
366 <      dAtom->setJy( ji[1] );
367 <      dAtom->setJz( ji[2] );
368 <    }
369 <    
365 >
366 >      dAtom->setJ( ji );
367 >      dAtom->setA( A  );
368 >          
369 >    }    
370    }
371   }
372  
373  
374   void Integrator::moveB( void ){
375 <  int i,j,k;
363 <  int atomIndex;
375 >  int i, j;
376    DirectionalAtom* dAtom;
377 <  double Tb[3];
378 <  double ji[3];
377 >  double Tb[3], ji[3];
378 >  double vel[3], frc[3];
379 >  double mass;
380  
381    for( i=0; i<nAtoms; i++ ){
382 <    atomIndex = i * 3;
382 >
383 >    atoms[i]->getVel( vel );
384 >    atoms[i]->getFrc( frc );
385  
386 <    // velocity half step
372 <    for( j=atomIndex; j<(atomIndex+3); j++ )
373 <      vel[j] += ( dt2 * frc[j] / atoms[i]->getMass() ) * eConvert;
386 >    mass = atoms[i]->getMass();
387  
388 +    // velocity half step
389 +    for (j=0; j < 3; j++)
390 +      vel[j] += ( dt2 * frc[j] / mass ) * eConvert;
391 +    
392 +    atoms[i]->setVel( vel );
393 +
394      if( atoms[i]->isDirectional() ){
395 <      
395 >
396        dAtom = (DirectionalAtom *)atoms[i];
397 <      
398 <      // get and convert the torque to body frame
399 <      
400 <      Tb[0] = dAtom->getTx();
382 <      Tb[1] = dAtom->getTy();
383 <      Tb[2] = dAtom->getTz();
384 <      
397 >
398 >      // get and convert the torque to body frame      
399 >
400 >      dAtom->getTrq( Tb );
401        dAtom->lab2Body( Tb );
402 +
403 +      // get the angular momentum, and propagate a half step
404 +
405 +      dAtom->getJ( ji );
406 +
407 +      for (j=0; j < 3; j++)
408 +        ji[j] += (dt2 * Tb[j]) * eConvert;
409        
410 <      // get the angular momentum, and complete the angular momentum
411 <      // half step
389 <      
390 <      ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * eConvert;
391 <      ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * eConvert;
392 <      ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * eConvert;
393 <      
394 <      jx2 = ji[0] * ji[0];
395 <      jy2 = ji[1] * ji[1];
396 <      jz2 = ji[2] * ji[2];
397 <      
398 <      dAtom->setJx( ji[0] );
399 <      dAtom->setJy( ji[1] );
400 <      dAtom->setJz( ji[2] );
410 >
411 >      dAtom->setJ( ji );
412      }
413    }
403
414   }
415  
416   void Integrator::preMove( void ){
417 <  int i;
417 >  int i, j;
418 >  double pos[3];
419  
420    if( nConstrained ){
421 <    if( oldAtoms != nAtoms ){
422 <      
423 <      // save oldAtoms to check for lode balanceing later on.
424 <      
425 <      oldAtoms = nAtoms;
426 <      
427 <      delete[] moving;
428 <      delete[] moved;
429 <      delete[] oldPos;
419 <      
420 <      moving = new int[nAtoms];
421 <      moved  = new int[nAtoms];
422 <      
423 <      oldPos = new double[nAtoms*3];
421 >
422 >    for(i=0; i < nAtoms; i++) {
423 >
424 >      atoms[i]->getPos( pos );
425 >
426 >      for (j = 0; j < 3; j++) {        
427 >        oldPos[3*i + j] = pos[j];
428 >      }
429 >
430      }
431 <  
432 <    for(i=0; i<(nAtoms*3); i++) oldPos[i] = pos[i];
427 <  }
428 < }  
431 >  }  
432 > }
433  
434   void Integrator::constrainA(){
435  
436    int i,j,k;
437    int done;
438 <  double pxab, pyab, pzab;
439 <  double rxab, ryab, rzab;
440 <  int a, b;
438 >  double posA[3], posB[3];
439 >  double velA[3], velB[3];
440 >  double pab[3];
441 >  double rab[3];
442 >  int a, b, ax, ay, az, bx, by, bz;
443    double rma, rmb;
444    double dx, dy, dz;
445 +  double rpab;
446    double rabsq, pabsq, rpabsq;
447    double diffsq;
448    double gab;
449    int iteration;
450  
451 <
445 <  
446 <  for( i=0; i<nAtoms; i++){
447 <    
451 >  for( i=0; i<nAtoms; i++){    
452      moving[i] = 0;
453      moved[i]  = 1;
454    }
455 <  
452 <  
455 >
456    iteration = 0;
457    done = 0;
458    while( !done && (iteration < maxIteration )){
# Line 459 | Line 462 | void Integrator::constrainA(){
462  
463        a = constrainedA[i];
464        b = constrainedB[i];
465 <    
465 >      
466 >      ax = (a*3) + 0;
467 >      ay = (a*3) + 1;
468 >      az = (a*3) + 2;
469 >
470 >      bx = (b*3) + 0;
471 >      by = (b*3) + 1;
472 >      bz = (b*3) + 2;
473 >
474        if( moved[a] || moved[b] ){
475 <        
476 <        pxab = pos[3*a+0] - pos[3*b+0];
477 <        pyab = pos[3*a+1] - pos[3*b+1];
478 <        pzab = pos[3*a+2] - pos[3*b+2];
475 >        
476 >        atoms[a]->getPos( posA );
477 >        atoms[b]->getPos( posB );
478 >        
479 >        for (j = 0; j < 3; j++ )
480 >          pab[j] = posA[j] - posB[j];
481 >        
482 >        //periodic boundary condition
483  
484 <        //periodic boundary condition
470 <        pxab = pxab - info->box_x * copysign(1, pxab)
471 <          * int(pxab / info->box_x + 0.5);
472 <        pyab = pyab - info->box_y * copysign(1, pyab)
473 <          * int(pyab / info->box_y + 0.5);
474 <        pzab = pzab - info->box_z * copysign(1, pzab)
475 <          * int(pzab / info->box_z + 0.5);
476 <      
477 <        pabsq = pxab * pxab + pyab * pyab + pzab * pzab;
478 <        rabsq = constraintedDsqr[i];
479 <        diffsq = pabsq - rabsq;
484 >        info->wrapVector( pab );
485  
486 +        pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
487 +
488 +        rabsq = constrainedDsqr[i];
489 +        diffsq = rabsq - pabsq;
490 +
491          // the original rattle code from alan tidesley
492 <        if (fabs(diffsq) > tol*rabsq*2) {
493 <          rxab = oldPos[3*a+0] - oldPos[3*b+0];
494 <          ryab = oldPos[3*a+1] - oldPos[3*b+1];
495 <          rzab = oldPos[3*a+2] - oldPos[3*b+2];
486 <
487 <          rxab = rxab - info->box_x * copysign(1, rxab)
488 <            * int(rxab / info->box_x + 0.5);
489 <          ryab = ryab - info->box_y * copysign(1, ryab)
490 <            * int(ryab / info->box_y + 0.5);
491 <          rzab = rzab - info->box_z * copysign(1, rzab)
492 <            * int(rzab / info->box_z + 0.5);
492 >        if (fabs(diffsq) > (tol*rabsq*2)) {
493 >          rab[0] = oldPos[ax] - oldPos[bx];
494 >          rab[1] = oldPos[ay] - oldPos[by];
495 >          rab[2] = oldPos[az] - oldPos[bz];
496  
497 <          rpab = rxab * pxab + ryab * pyab + rzab * pzab;
497 >          info->wrapVector( rab );
498 >
499 >          rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
500 >
501            rpabsq = rpab * rpab;
502  
503  
504            if (rpabsq < (rabsq * -diffsq)){
505 +
506   #ifdef IS_MPI
507              a = atoms[a]->getGlobalIndex();
508              b = atoms[b]->getGlobalIndex();
509   #endif //is_mpi
510              sprintf( painCave.errMsg,
511 <                     "Constraint failure in constrainA at atom %d and %d\n.",
511 >                     "Constraint failure in constrainA at atom %d and %d.\n",
512                       a, b );
513              painCave.isFatal = 1;
514              simError();
# Line 509 | Line 516 | void Integrator::constrainA(){
516  
517            rma = 1.0 / atoms[a]->getMass();
518            rmb = 1.0 / atoms[b]->getMass();
519 <          
519 >
520            gab = diffsq / ( 2.0 * ( rma + rmb ) * rpab );
514          dx = rxab * gab;
515          dy = ryab * gab;
516          dz = rzab * gab;
521  
522 <          pos[3*a+0] += rma * dx;
523 <          pos[3*a+1] += rma * dy;
524 <          pos[3*a+2] += rma * dz;
522 >          dx = rab[0] * gab;
523 >          dy = rab[1] * gab;
524 >          dz = rab[2] * gab;
525  
526 <          pos[3*b+0] -= rmb * dx;
527 <          pos[3*b+1] -= rmb * dy;
528 <          pos[3*b+2] -= rmb * dz;
526 >          posA[0] += rma * dx;
527 >          posA[1] += rma * dy;
528 >          posA[2] += rma * dz;
529  
530 +          atoms[a]->setPos( posA );
531 +
532 +          posB[0] -= rmb * dx;
533 +          posB[1] -= rmb * dy;
534 +          posB[2] -= rmb * dz;
535 +
536 +          atoms[b]->setPos( posB );
537 +
538            dx = dx / dt;
539            dy = dy / dt;
540            dz = dz / dt;
541  
542 <          vel[3*a+0] += rma * dx;
531 <          vel[3*a+1] += rma * dy;
532 <          vel[3*a+2] += rma * dz;
542 >          atoms[a]->getVel( velA );
543  
544 <          vel[3*b+0] -= rmb * dx;
545 <          vel[3*b+1] -= rmb * dy;
546 <          vel[3*b+2] -= rmb * dz;
544 >          velA[0] += rma * dx;
545 >          velA[1] += rma * dy;
546 >          velA[2] += rma * dz;
547  
548 +          atoms[a]->setVel( velA );
549 +
550 +          atoms[b]->getVel( velB );
551 +
552 +          velB[0] -= rmb * dx;
553 +          velB[1] -= rmb * dy;
554 +          velB[2] -= rmb * dz;
555 +
556 +          atoms[b]->setVel( velB );
557 +
558            moving[a] = 1;
559            moving[b] = 1;
560            done = 0;
# Line 553 | Line 573 | void Integrator::constrainA(){
573  
574    if( !done ){
575  
576 <    sprintf( painCae.errMsg,
576 >    sprintf( painCave.errMsg,
577               "Constraint failure in constrainA, too many iterations: %d\n",
578 <             iterations );
578 >             iteration );
579      painCave.isFatal = 1;
580      simError();
581    }
# Line 566 | Line 586 | void Integrator::constrainB( void ){
586    
587    int i,j,k;
588    int done;
589 +  double posA[3], posB[3];
590 +  double velA[3], velB[3];
591    double vxab, vyab, vzab;
592 <  double rxab, ryab, rzab;
593 <  int a, b;
592 >  double rab[3];
593 >  int a, b, ax, ay, az, bx, by, bz;
594    double rma, rmb;
595    double dx, dy, dz;
596    double rabsq, pabsq, rvab;
# Line 576 | Line 598 | void Integrator::constrainB( void ){
598    double gab;
599    int iteration;
600  
601 <  for(i=0; i<nAtom; i++){
601 >  for(i=0; i<nAtoms; i++){
602      moving[i] = 0;
603      moved[i] = 1;
604    }
605  
606    done = 0;
607 +  iteration = 0;
608    while( !done && (iteration < maxIteration ) ){
609  
610 +    done = 1;
611 +
612      for(i=0; i<nConstrained; i++){
613        
614        a = constrainedA[i];
615        b = constrainedB[i];
616  
617 +      ax = (a*3) + 0;
618 +      ay = (a*3) + 1;
619 +      az = (a*3) + 2;
620 +
621 +      bx = (b*3) + 0;
622 +      by = (b*3) + 1;
623 +      bz = (b*3) + 2;
624 +
625        if( moved[a] || moved[b] ){
593        
594        vxab = vel[3*a+0] - vel[3*b+0];
595        vyab = vel[3*a+1] - vel[3*b+1];
596        vzab = vel[3*a+2] - vel[3*b+2];
626  
627 <        rxab = pos[3*a+0] - pos[3*b+0];q
628 <        ryab = pos[3*a+1] - pos[3*b+1];
629 <        rzab = pos[3*a+2] - pos[3*b+2];
630 <        
631 <        rxab = rxab - info->box_x * copysign(1, rxab)
632 <          * int(rxab / info->box_x + 0.5);
604 <        ryab = ryab - info->box_y * copysign(1, ryab)
605 <          * int(ryab / info->box_y + 0.5);
606 <        rzab = rzab - info->box_z * copysign(1, rzab)
607 <          * int(rzab / info->box_z + 0.5);
627 >        atoms[a]->getVel( velA );
628 >        atoms[b]->getVel( velB );
629 >          
630 >        vxab = velA[0] - velB[0];
631 >        vyab = velA[1] - velB[1];
632 >        vzab = velA[2] - velB[2];
633  
634 +        atoms[a]->getPos( posA );
635 +        atoms[b]->getPos( posB );
636 +
637 +        for (j = 0; j < 3; j++)
638 +          rab[j] = posA[j] - posB[j];
639 +          
640 +        info->wrapVector( rab );
641 +        
642          rma = 1.0 / atoms[a]->getMass();
643          rmb = 1.0 / atoms[b]->getMass();
644  
645 <        rvab = rxab * vxab + ryab * vyab + rzab * vzab;
645 >        rvab = rab[0] * vxab + rab[1] * vyab + rab[2] * vzab;
646            
647 <        gab = -rvab / ( ( rma + rmb ) * constraintsDsqr[i] );
647 >        gab = -rvab / ( ( rma + rmb ) * constrainedDsqr[i] );
648  
649          if (fabs(gab) > tol) {
650            
651 <          dx = rxab * gab;
652 <          dy = ryab * gab;
653 <          dz = rzab * gab;
654 <          
655 <          vel[3*a+0] += rma * dx;
656 <          vel[3*a+1] += rma * dy;
657 <          vel[3*a+2] += rma * dz;
651 >          dx = rab[0] * gab;
652 >          dy = rab[1] * gab;
653 >          dz = rab[2] * gab;
654 >        
655 >          velA[0] += rma * dx;
656 >          velA[1] += rma * dy;
657 >          velA[2] += rma * dz;
658  
659 <          vel[3*b+0] -= rmb * dx;
660 <          vel[3*b+1] -= rmb * dy;
661 <          vel[3*b+2] -= rmb * dz;
659 >          atoms[a]->setVel( velA );
660 >
661 >          velB[0] -= rmb * dx;
662 >          velB[1] -= rmb * dy;
663 >          velB[2] -= rmb * dz;
664 >
665 >          atoms[b]->setVel( velB );
666            
667            moving[a] = 1;
668            moving[b] = 1;
# Line 641 | Line 678 | void Integrator::constrainB( void ){
678      
679      iteration++;
680    }
681 <
681 >  
682    if( !done ){
683  
684    
685 <    sprintf( painCae.errMsg,
685 >    sprintf( painCave.errMsg,
686               "Constraint failure in constrainB, too many iterations: %d\n",
687 <             iterations );
687 >             iteration );
688      painCave.isFatal = 1;
689      simError();
690    }
691  
692   }
693  
657
658
659
660
661
662
694   void Integrator::rotate( int axes1, int axes2, double angle, double ji[3],
695                           double A[3][3] ){
696  
# Line 728 | Line 759 | void Integrator::rotate( int axes1, int axes2, double
759    //            A[][] = A[][] * transpose(rot[][])
760  
761  
762 <  // NOte for as yet unknown reason, we are setting the performing the
762 >  // NOte for as yet unknown reason, we are performing the
763    // calculation as:
764    //                transpose(A[][]) = transpose(A[][]) * transpose(rot[][])
765  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines