--- trunk/OOPSE/libmdtools/Integrator.cpp 2003/06/20 20:29:36 561 +++ trunk/OOPSE/libmdtools/Integrator.cpp 2003/08/22 20:04:39 711 @@ -11,7 +11,7 @@ Integrator::Integrator( SimInfo *theInfo, ForceFields* #include "simError.h" -Integrator::Integrator( SimInfo *theInfo, ForceFields* the_ff ){ +template Integrator::Integrator( SimInfo *theInfo, ForceFields* the_ff ) { info = theInfo; myFF = the_ff; @@ -41,7 +41,7 @@ Integrator::~Integrator() { checkConstraints(); } -Integrator::~Integrator() { +template Integrator::~Integrator() { if( nConstrained ){ delete[] constrainedA; @@ -54,7 +54,7 @@ void Integrator::checkConstraints( void ){ } -void Integrator::checkConstraints( void ){ +template void Integrator::checkConstraints( void ){ isConstrained = 0; @@ -72,9 +72,9 @@ void Integrator::checkConstraints( void ){ for(int j=0; jis_constrained(); - + if(constrained){ - + dummy_plug = theArray[j]->get_constraint(); temp_con[nConstrained].set_a( dummy_plug->get_a() ); temp_con[nConstrained].set_b( dummy_plug->get_b() ); @@ -82,7 +82,7 @@ void Integrator::checkConstraints( void ){ nConstrained++; constrained = 0; - } + } } theArray = (SRI**) molecules[i].getMyBends(); @@ -137,6 +137,7 @@ void Integrator::checkConstraints( void ){ constrainedA[i] = temp_con[i].get_a(); constrainedB[i] = temp_con[i].get_b(); constrainedDsqr[i] = temp_con[i].get_dsqr(); + } @@ -154,7 +155,7 @@ void Integrator::integrate( void ){ } -void Integrator::integrate( void ){ +template void Integrator::integrate( void ){ int i, j; // loop counters @@ -166,13 +167,10 @@ void Integrator::integrate( void ){ double currSample; double currThermal; double currStatus; - double currTime; int calcPot, calcStress; int isError; - - tStats = new Thermo( info ); statOut = new StatWriter( info ); dumpOut = new DumpWriter( info ); @@ -185,23 +183,22 @@ void Integrator::integrate( void ){ // initialize the forces before the first step - myFF->doForces(1,1); - + calcForce(1, 1); + // myFF->doForces(1,1); + if( info->setTemp ){ - tStats->velocitize(); + thermalize(); } - dumpOut->writeDump( 0.0 ); - statOut->writeStat( 0.0 ); - calcPot = 0; calcStress = 0; - currSample = sampleTime; - currThermal = thermalTime; - currStatus = statusTime; - currTime = 0.0;; + currSample = sampleTime + info->getTime(); + currThermal = thermalTime+ info->getTime(); + currStatus = statusTime + info->getTime(); + dumpOut->writeDump( info->getTime() ); + statOut->writeStat( info->getTime() ); readyCheck(); @@ -211,38 +208,31 @@ void Integrator::integrate( void ){ MPIcheckPoint(); #endif // is_mpi + while( info->getTime() < runTime ){ - pos = Atom::getPosArray(); - vel = Atom::getVelArray(); - frc = Atom::getFrcArray(); - trq = Atom::getTrqArray(); - Amat = Atom::getAmatArray(); - - while( currTime < runTime ){ - - if( (currTime+dt) >= currStatus ){ + if( (info->getTime()+dt) >= currStatus ){ calcPot = 1; calcStress = 1; } integrateStep( calcPot, calcStress ); - currTime += dt; + info->incrTime(dt); if( info->setTemp ){ - if( currTime >= currThermal ){ - tStats->velocitize(); + if( info->getTime() >= currThermal ){ + thermalize(); currThermal += thermalTime; } } - if( currTime >= currSample ){ - dumpOut->writeDump( currTime ); + if( info->getTime() >= currSample ){ + dumpOut->writeDump( info->getTime() ); currSample += sampleTime; } - if( currTime >= currStatus ){ - statOut->writeStat( currTime ); + if( info->getTime() >= currStatus ){ + statOut->writeStat( info->getTime() ); calcPot = 0; calcStress = 0; currStatus += statusTime; @@ -256,13 +246,13 @@ void Integrator::integrate( void ){ } - dumpOut->writeFinal(); + dumpOut->writeFinal(info->getTime()); delete dumpOut; delete statOut; } -void Integrator::integrateStep( int calcPot, int calcStress ){ +template void Integrator::integrateStep( int calcPot, int calcStress ){ @@ -272,163 +262,185 @@ void Integrator::integrateStep( int calcPot, int calcS moveA(); if( nConstrained ) constrainA(); + +#ifdef IS_MPI + strcpy( checkPointMsg, "Succesful moveA\n" ); + MPIcheckPoint(); +#endif // is_mpi + + // calc forces - myFF->doForces(calcPot,calcStress); + calcForce(calcPot,calcStress); + +#ifdef IS_MPI + strcpy( checkPointMsg, "Succesful doForces\n" ); + MPIcheckPoint(); +#endif // is_mpi + // finish the velocity half step moveB(); if( nConstrained ) constrainB(); - + +#ifdef IS_MPI + strcpy( checkPointMsg, "Succesful moveB\n" ); + MPIcheckPoint(); +#endif // is_mpi + + } -void Integrator::moveA( void ){ +template void Integrator::moveA( void ){ - int i,j,k; - int atomIndex, aMatIndex; + int i, j; DirectionalAtom* dAtom; - double Tb[3]; - double ji[3]; + double Tb[3], ji[3]; + double A[3][3], I[3][3]; double angle; + double vel[3], pos[3], frc[3]; + double mass; for( i=0; igetMass() ) * eConvert; - // position whole step - for( j=atomIndex; j<(atomIndex+3); j++ ) + atoms[i]->getVel( vel ); + atoms[i]->getPos( pos ); + atoms[i]->getFrc( frc ); + + mass = atoms[i]->getMass(); + + for (j=0; j < 3; j++) { + // velocity half step + vel[j] += ( dt2 * frc[j] / mass ) * eConvert; + // position whole step pos[j] += dt * vel[j]; + } - + atoms[i]->setVel( vel ); + atoms[i]->setPos( pos ); + if( atoms[i]->isDirectional() ){ dAtom = (DirectionalAtom *)atoms[i]; // get and convert the torque to body frame - Tb[0] = dAtom->getTx(); - Tb[1] = dAtom->getTy(); - Tb[2] = dAtom->getTz(); - + dAtom->getTrq( Tb ); dAtom->lab2Body( Tb ); - + // get the angular momentum, and propagate a half step + + dAtom->getJ( ji ); + + for (j=0; j < 3; j++) + ji[j] += (dt2 * Tb[j]) * eConvert; - ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * eConvert; - ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * eConvert; - ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * eConvert; - // use the angular velocities to propagate the rotation matrix a // full time step - + + dAtom->getA(A); + dAtom->getI(I); + // rotate about the x-axis - angle = dt2 * ji[0] / dAtom->getIxx(); - this->rotate( 1, 2, angle, ji, &Amat[aMatIndex] ); - + angle = dt2 * ji[0] / I[0][0]; + this->rotate( 1, 2, angle, ji, A ); + // rotate about the y-axis - angle = dt2 * ji[1] / dAtom->getIyy(); - this->rotate( 2, 0, angle, ji, &Amat[aMatIndex] ); + angle = dt2 * ji[1] / I[1][1]; + this->rotate( 2, 0, angle, ji, A ); // rotate about the z-axis - angle = dt * ji[2] / dAtom->getIzz(); - this->rotate( 0, 1, angle, ji, &Amat[aMatIndex] ); + angle = dt * ji[2] / I[2][2]; + this->rotate( 0, 1, angle, ji, A); // rotate about the y-axis - angle = dt2 * ji[1] / dAtom->getIyy(); - this->rotate( 2, 0, angle, ji, &Amat[aMatIndex] ); + angle = dt2 * ji[1] / I[1][1]; + this->rotate( 2, 0, angle, ji, A ); // rotate about the x-axis - angle = dt2 * ji[0] / dAtom->getIxx(); - this->rotate( 1, 2, angle, ji, &Amat[aMatIndex] ); + angle = dt2 * ji[0] / I[0][0]; + this->rotate( 1, 2, angle, ji, A ); - dAtom->setJx( ji[0] ); - dAtom->setJy( ji[1] ); - dAtom->setJz( ji[2] ); - } - + + dAtom->setJ( ji ); + dAtom->setA( A ); + + } } } -void Integrator::moveB( void ){ - int i,j,k; - int atomIndex; +template void Integrator::moveB( void ){ + int i, j; DirectionalAtom* dAtom; - double Tb[3]; - double ji[3]; + double Tb[3], ji[3]; + double vel[3], frc[3]; + double mass; for( i=0; igetVel( vel ); + atoms[i]->getFrc( frc ); - // velocity half step - for( j=atomIndex; j<(atomIndex+3); j++ ) - vel[j] += ( dt2 * frc[j] / atoms[i]->getMass() ) * eConvert; + mass = atoms[i]->getMass(); + // velocity half step + for (j=0; j < 3; j++) + vel[j] += ( dt2 * frc[j] / mass ) * eConvert; + + atoms[i]->setVel( vel ); + if( atoms[i]->isDirectional() ){ - + dAtom = (DirectionalAtom *)atoms[i]; - - // get and convert the torque to body frame - - Tb[0] = dAtom->getTx(); - Tb[1] = dAtom->getTy(); - Tb[2] = dAtom->getTz(); - + + // get and convert the torque to body frame + + dAtom->getTrq( Tb ); dAtom->lab2Body( Tb ); + + // get the angular momentum, and propagate a half step + + dAtom->getJ( ji ); + + for (j=0; j < 3; j++) + ji[j] += (dt2 * Tb[j]) * eConvert; - // get the angular momentum, and complete the angular momentum - // half step - - ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * eConvert; - ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * eConvert; - ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * eConvert; - - dAtom->setJx( ji[0] ); - dAtom->setJy( ji[1] ); - dAtom->setJz( ji[2] ); + + dAtom->setJ( ji ); } } - } -void Integrator::preMove( void ){ - int i; +template void Integrator::preMove( void ){ + int i, j; + double pos[3]; if( nConstrained ){ -// if( oldAtoms != nAtoms ){ - -// // save oldAtoms to check for lode balanceing later on. - -// oldAtoms = nAtoms; - -// delete[] moving; -// delete[] moved; -// delete[] oldPos; - -// moving = new int[nAtoms]; -// moved = new int[nAtoms]; - -// oldPos = new double[nAtoms*3]; -// } - - for(i=0; i<(nAtoms*3); i++) oldPos[i] = pos[i]; - } -} + for(i=0; i < nAtoms; i++) { + + atoms[i]->getPos( pos ); -void Integrator::constrainA(){ + for (j = 0; j < 3; j++) { + oldPos[3*i + j] = pos[j]; + } + } + } +} + +template void Integrator::constrainA(){ + int i,j,k; int done; - double pxab, pyab, pzab; - double rxab, ryab, rzab; - int a, b; + double posA[3], posB[3]; + double velA[3], velB[3]; + double pab[3]; + double rab[3]; + int a, b, ax, ay, az, bx, by, bz; double rma, rmb; double dx, dy, dz; double rpab; @@ -437,15 +449,11 @@ void Integrator::constrainA(){ double gab; int iteration; - - - for( i=0; igetPos( posA ); + atoms[b]->getPos( posB ); + + for (j = 0; j < 3; j++ ) + pab[j] = posA[j] - posB[j]; + + //periodic boundary condition - //periodic boundary condition - pxab = pxab - info->box_x * copysign(1, pxab) - * int( fabs(pxab) / info->box_x + 0.5); - pyab = pyab - info->box_y * copysign(1, pyab) - * int( fabs(pyab) / info->box_y + 0.5); - pzab = pzab - info->box_z * copysign(1, pzab) - * int( fabs(pzab) / info->box_z + 0.5); - - pabsq = pxab * pxab + pyab * pyab + pzab * pzab; + info->wrapVector( pab ); + + pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2]; + rabsq = constrainedDsqr[i]; - diffsq = pabsq - rabsq; + diffsq = rabsq - pabsq; // the original rattle code from alan tidesley - if (fabs(diffsq) > tol*rabsq*2) { - rxab = oldPos[3*a+0] - oldPos[3*b+0]; - ryab = oldPos[3*a+1] - oldPos[3*b+1]; - rzab = oldPos[3*a+2] - oldPos[3*b+2]; - - rxab = rxab - info->box_x * copysign(1, rxab) - * int( fabs(rxab) / info->box_x + 0.5); - ryab = ryab - info->box_y * copysign(1, ryab) - * int( fabs(ryab) / info->box_y + 0.5); - rzab = rzab - info->box_z * copysign(1, rzab) - * int( fabs(rzab) / info->box_z + 0.5); + if (fabs(diffsq) > (tol*rabsq*2)) { + rab[0] = oldPos[ax] - oldPos[bx]; + rab[1] = oldPos[ay] - oldPos[by]; + rab[2] = oldPos[az] - oldPos[bz]; - rpab = rxab * pxab + ryab * pyab + rzab * pzab; + info->wrapVector( rab ); + + rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2]; + rpabsq = rpab * rpab; if (rpabsq < (rabsq * -diffsq)){ + #ifdef IS_MPI a = atoms[a]->getGlobalIndex(); b = atoms[b]->getGlobalIndex(); #endif //is_mpi sprintf( painCave.errMsg, - "Constraint failure in constrainA at atom %d and %d\n.", + "Constraint failure in constrainA at atom %d and %d.\n", a, b ); painCave.isFatal = 1; simError(); @@ -505,32 +517,45 @@ void Integrator::constrainA(){ rma = 1.0 / atoms[a]->getMass(); rmb = 1.0 / atoms[b]->getMass(); - + gab = diffsq / ( 2.0 * ( rma + rmb ) * rpab ); - dx = rxab * gab; - dy = ryab * gab; - dz = rzab * gab; - pos[3*a+0] += rma * dx; - pos[3*a+1] += rma * dy; - pos[3*a+2] += rma * dz; + dx = rab[0] * gab; + dy = rab[1] * gab; + dz = rab[2] * gab; - pos[3*b+0] -= rmb * dx; - pos[3*b+1] -= rmb * dy; - pos[3*b+2] -= rmb * dz; + posA[0] += rma * dx; + posA[1] += rma * dy; + posA[2] += rma * dz; + atoms[a]->setPos( posA ); + + posB[0] -= rmb * dx; + posB[1] -= rmb * dy; + posB[2] -= rmb * dz; + + atoms[b]->setPos( posB ); + dx = dx / dt; dy = dy / dt; dz = dz / dt; - vel[3*a+0] += rma * dx; - vel[3*a+1] += rma * dy; - vel[3*a+2] += rma * dz; + atoms[a]->getVel( velA ); - vel[3*b+0] -= rmb * dx; - vel[3*b+1] -= rmb * dy; - vel[3*b+2] -= rmb * dz; + velA[0] += rma * dx; + velA[1] += rma * dy; + velA[2] += rma * dz; + atoms[a]->setVel( velA ); + + atoms[b]->getVel( velB ); + + velB[0] -= rmb * dx; + velB[1] -= rmb * dy; + velB[2] -= rmb * dz; + + atoms[b]->setVel( velB ); + moving[a] = 1; moving[b] = 1; done = 0; @@ -558,13 +583,15 @@ void Integrator::constrainB( void ){ } -void Integrator::constrainB( void ){ +template void Integrator::constrainB( void ){ int i,j,k; int done; + double posA[3], posB[3]; + double velA[3], velB[3]; double vxab, vyab, vzab; - double rxab, ryab, rzab; - int a, b; + double rab[3]; + int a, b, ax, ay, az, bx, by, bz; double rma, rmb; double dx, dy, dz; double rabsq, pabsq, rvab; @@ -581,48 +608,62 @@ void Integrator::constrainB( void ){ iteration = 0; while( !done && (iteration < maxIteration ) ){ + done = 1; + for(i=0; ibox_x * copysign(1, rxab) - * int( fabs(rxab) / info->box_x + 0.5); - ryab = ryab - info->box_y * copysign(1, ryab) - * int( fabs(ryab) / info->box_y + 0.5); - rzab = rzab - info->box_z * copysign(1, rzab) - * int( fabs(rzab) / info->box_z + 0.5); + atoms[a]->getVel( velA ); + atoms[b]->getVel( velB ); + + vxab = velA[0] - velB[0]; + vyab = velA[1] - velB[1]; + vzab = velA[2] - velB[2]; + atoms[a]->getPos( posA ); + atoms[b]->getPos( posB ); + + for (j = 0; j < 3; j++) + rab[j] = posA[j] - posB[j]; + + info->wrapVector( rab ); + rma = 1.0 / atoms[a]->getMass(); rmb = 1.0 / atoms[b]->getMass(); - rvab = rxab * vxab + ryab * vyab + rzab * vzab; + rvab = rab[0] * vxab + rab[1] * vyab + rab[2] * vzab; gab = -rvab / ( ( rma + rmb ) * constrainedDsqr[i] ); if (fabs(gab) > tol) { - dx = rxab * gab; - dy = ryab * gab; - dz = rzab * gab; - - vel[3*a+0] += rma * dx; - vel[3*a+1] += rma * dy; - vel[3*a+2] += rma * dz; + dx = rab[0] * gab; + dy = rab[1] * gab; + dz = rab[2] * gab; + + velA[0] += rma * dx; + velA[1] += rma * dy; + velA[2] += rma * dz; - vel[3*b+0] -= rmb * dx; - vel[3*b+1] -= rmb * dy; - vel[3*b+2] -= rmb * dz; + atoms[a]->setVel( velA ); + + velB[0] -= rmb * dx; + velB[1] -= rmb * dy; + velB[2] -= rmb * dz; + + atoms[b]->setVel( velB ); moving[a] = 1; moving[b] = 1; @@ -638,7 +679,7 @@ void Integrator::constrainB( void ){ iteration++; } - + if( !done ){ @@ -651,15 +692,9 @@ void Integrator::constrainB( void ){ } +template void Integrator::rotate( int axes1, int axes2, double angle, double ji[3], + double A[3][3] ){ - - - - - -void Integrator::rotate( int axes1, int axes2, double angle, double ji[3], - double A[9] ){ - int i,j,k; double sinAngle; double cosAngle; @@ -674,7 +709,7 @@ void Integrator::rotate( int axes1, int axes2, double for(i=0; i<3; i++){ for(j=0; j<3; j++){ - tempA[j][i] = A[3*i + j]; + tempA[j][i] = A[i][j]; } } @@ -731,10 +766,19 @@ void Integrator::rotate( int axes1, int axes2, double for(i=0; i<3; i++){ for(j=0; j<3; j++){ - A[3*j + i] = 0.0; + A[j][i] = 0.0; for(k=0; k<3; k++){ - A[3*j + i] += tempA[i][k] * rot[j][k]; + A[j][i] += tempA[i][k] * rot[j][k]; } } } } + +template void Integrator::calcForce( int calcPot, int calcStress ){ + myFF->doForces(calcPot,calcStress); + +} + +template void Integrator::thermalize(){ + tStats->velocitize(); +}