--- trunk/src/brains/SimInfo.cpp 2005/11/16 23:10:02 749 +++ trunk/src/brains/SimInfo.cpp 2006/07/03 13:18:43 998 @@ -59,11 +59,12 @@ #include "UseTheForce/DarkSide/fSwitchingFunctionType.h" #include "UseTheForce/doForces_interface.h" #include "UseTheForce/DarkSide/electrostatic_interface.h" -#include "UseTheForce/notifyCutoffs_interface.h" #include "UseTheForce/DarkSide/switcheroo_interface.h" #include "utils/MemoryUtils.hpp" #include "utils/simError.h" #include "selection/SelectionManager.hpp" +#include "io/ForceFieldOptions.hpp" +#include "UseTheForce/ForceField.hpp" #ifdef IS_MPI #include "UseTheForce/mpiComponentPlan.h" @@ -81,18 +82,15 @@ namespace oopse { return result; } - SimInfo::SimInfo(MakeStamps* stamps, std::vector >& molStampPairs, - ForceField* ff, Globals* simParams) : - stamps_(stamps), forceField_(ff), simParams_(simParams), - ndf_(0), ndfRaw_(0), ndfTrans_(0), nZconstraint_(0), + SimInfo::SimInfo(ForceField* ff, Globals* simParams) : + forceField_(ff), simParams_(simParams), + ndf_(0), fdf_local(0), ndfRaw_(0), ndfTrans_(0), nZconstraint_(0), nGlobalMols_(0), nGlobalAtoms_(0), nGlobalCutoffGroups_(0), nGlobalIntegrableObjects_(0), nGlobalRigidBodies_(0), nAtoms_(0), nBonds_(0), nBends_(0), nTorsions_(0), nRigidBodies_(0), nIntegrableObjects_(0), nCutoffGroups_(0), nConstraints_(0), - sman_(NULL), fortranInitialized_(false) { + sman_(NULL), fortranInitialized_(false), calcBoxDipole_(false) { - - std::vector >::iterator i; MoleculeStamp* molStamp; int nMolWithSameStamp; int nCutoffAtoms = 0; // number of atoms belong to cutoff groups @@ -100,23 +98,23 @@ namespace oopse { CutoffGroupStamp* cgStamp; RigidBodyStamp* rbStamp; int nRigidAtoms = 0; - - for (i = molStampPairs.begin(); i !=molStampPairs.end(); ++i) { - molStamp = i->first; - nMolWithSameStamp = i->second; + std::vector components = simParams->getComponents(); + + for (std::vector::iterator i = components.begin(); i !=components.end(); ++i) { + molStamp = (*i)->getMoleculeStamp(); + nMolWithSameStamp = (*i)->getNMol(); addMoleculeStamp(molStamp, nMolWithSameStamp); //calculate atoms in molecules nGlobalAtoms_ += molStamp->getNAtoms() *nMolWithSameStamp; - //calculate atoms in cutoff groups int nAtomsInGroups = 0; int nCutoffGroupsInStamp = molStamp->getNCutoffGroups(); for (int j=0; j < nCutoffGroupsInStamp; j++) { - cgStamp = molStamp->getCutoffGroup(j); + cgStamp = molStamp->getCutoffGroupStamp(j); nAtomsInGroups += cgStamp->getNMembers(); } @@ -129,7 +127,7 @@ namespace oopse { int nRigidBodiesInStamp = molStamp->getNRigidBodies(); for (int j=0; j < nRigidBodiesInStamp; j++) { - rbStamp = molStamp->getRigidBody(j); + rbStamp = molStamp->getRigidBodyStamp(j); nAtomsInRigidBodies += rbStamp->getNMembers(); } @@ -168,7 +166,6 @@ namespace oopse { } molecules_.clear(); - delete stamps_; delete sman_; delete simParams_; delete forceField_; @@ -275,8 +272,8 @@ namespace oopse { } } - }//end for (integrableObject) - }// end for (mol) + } + } // n_constraints is local, so subtract them on each processor ndf_local -= nConstraints_; @@ -293,6 +290,15 @@ namespace oopse { } + int SimInfo::getFdf() { +#ifdef IS_MPI + MPI_Allreduce(&fdf_local,&fdf_,1,MPI_INT,MPI_SUM, MPI_COMM_WORLD); +#else + fdf_ = fdf_local; +#endif + return fdf_; + } + void SimInfo::calcNdfRaw() { int ndfRaw_local; @@ -596,6 +602,7 @@ namespace oopse { setupElectrostaticSummationMethod( isError ); setupSwitchingFunction(); + setupAccumulateBoxDipole(); if(isError){ sprintf( painCave.errMsg, @@ -655,6 +662,8 @@ namespace oopse { int usePBC = simParams_->getUsePeriodicBoundaryConditions(); int useRF; int useSF; + int useSP; + int useBoxDipole; std::string myMethod; // set the useRF logical @@ -665,14 +674,18 @@ namespace oopse { if (simParams_->haveElectrostaticSummationMethod()) { std::string myMethod = simParams_->getElectrostaticSummationMethod(); toUpper(myMethod); - if (myMethod == "REACTION_FIELD") { + if (myMethod == "REACTION_FIELD"){ useRF=1; - } else { - if (myMethod == "SHIFTED_FORCE") { - useSF = 1; - } + } else if (myMethod == "SHIFTED_FORCE"){ + useSF = 1; + } else if (myMethod == "SHIFTED_POTENTIAL"){ + useSP = 1; } } + + if (simParams_->haveAccumulateBoxDipole()) + if (simParams_->getAccumulateBoxDipole()) + useBoxDipole = 1; //loop over all of the atom types for (i = atomTypes.begin(); i != atomTypes.end(); ++i) { @@ -743,7 +756,13 @@ namespace oopse { MPI_Allreduce(&temp, &useRF, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD); temp = useSF; - MPI_Allreduce(&temp, &useSF, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD); + MPI_Allreduce(&temp, &useSF, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD); + + temp = useSP; + MPI_Allreduce(&temp, &useSP, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD); + + temp = useBoxDipole; + MPI_Allreduce(&temp, &useBoxDipole, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD); #endif @@ -762,6 +781,8 @@ namespace oopse { fInfo_.SIM_uses_FLARB = useFLARB; fInfo_.SIM_uses_RF = useRF; fInfo_.SIM_uses_SF = useSF; + fInfo_.SIM_uses_SP = useSP; + fInfo_.SIM_uses_BoxDipole = useBoxDipole; if( myMethod == "REACTION_FIELD") { @@ -793,14 +814,14 @@ namespace oopse { } //calculate mass ratio of cutoff group - std::vector mfact; + std::vector mfact; SimInfo::MoleculeIterator mi; Molecule* mol; Molecule::CutoffGroupIterator ci; CutoffGroup* cg; Molecule::AtomIterator ai; Atom* atom; - double totalMass; + RealType totalMass; //to avoid memory reallocation, reserve enough space for mfact mfact.reserve(getNCutoffGroups()); @@ -923,86 +944,21 @@ namespace oopse { #endif - double SimInfo::calcMaxCutoffRadius() { + void SimInfo::setupCutoff() { + + ForceFieldOptions& forceFieldOptions_ = forceField_->getForceFieldOptions(); + // Check the cutoff policy + int cp = TRADITIONAL_CUTOFF_POLICY; // Set to traditional by default - std::set atomTypes; - std::set::iterator i; - std::vector cutoffRadius; - - //get the unique atom types - atomTypes = getUniqueAtomTypes(); - - //query the max cutoff radius among these atom types - for (i = atomTypes.begin(); i != atomTypes.end(); ++i) { - cutoffRadius.push_back(forceField_->getRcutFromAtomType(*i)); + std::string myPolicy; + if (forceFieldOptions_.haveCutoffPolicy()){ + myPolicy = forceFieldOptions_.getCutoffPolicy(); + }else if (simParams_->haveCutoffPolicy()) { + myPolicy = simParams_->getCutoffPolicy(); } - double maxCutoffRadius = *(std::max_element(cutoffRadius.begin(), cutoffRadius.end())); -#ifdef IS_MPI - //pick the max cutoff radius among the processors -#endif - - return maxCutoffRadius; - } - - void SimInfo::getCutoff(double& rcut, double& rsw) { - - if (fInfo_.SIM_uses_Charges | fInfo_.SIM_uses_Dipoles | fInfo_.SIM_uses_RF) { - - if (!simParams_->haveCutoffRadius()){ - sprintf(painCave.errMsg, - "SimCreator Warning: No value was set for the cutoffRadius.\n" - "\tOOPSE will use a default value of 15.0 angstroms" - "\tfor the cutoffRadius.\n"); - painCave.isFatal = 0; - simError(); - rcut = 15.0; - } else{ - rcut = simParams_->getCutoffRadius(); - } - - if (!simParams_->haveSwitchingRadius()){ - sprintf(painCave.errMsg, - "SimCreator Warning: No value was set for switchingRadius.\n" - "\tOOPSE will use a default value of\n" - "\t0.85 * cutoffRadius for the switchingRadius\n"); - painCave.isFatal = 0; - simError(); - rsw = 0.85 * rcut; - } else{ - rsw = simParams_->getSwitchingRadius(); - } - - } else { - // if charge, dipole or reaction field is not used and the cutofff radius is not specified in - //meta-data file, the maximum cutoff radius calculated from forcefiled will be used - - if (simParams_->haveCutoffRadius()) { - rcut = simParams_->getCutoffRadius(); - } else { - //set cutoff radius to the maximum cutoff radius based on atom types in the whole system - rcut = calcMaxCutoffRadius(); - } - - if (simParams_->haveSwitchingRadius()) { - rsw = simParams_->getSwitchingRadius(); - } else { - rsw = rcut; - } - - } - } - - void SimInfo::setupCutoff() { - getCutoff(rcut_, rsw_); - double rnblist = rcut_ + 1; // skin of neighbor list - - //Pass these cutoff radius etc. to fortran. This function should be called once and only once - - int cp = TRADITIONAL_CUTOFF_POLICY; - if (simParams_->haveCutoffPolicy()) { - std::string myPolicy = simParams_->getCutoffPolicy(); + if (!myPolicy.empty()){ toUpper(myPolicy); if (myPolicy == "MIX") { cp = MIX_CUTOFF_POLICY; @@ -1021,16 +977,93 @@ namespace oopse { } } } - } + } + notifyFortranCutoffPolicy(&cp); - + // Check the Skin Thickness for neighborlists + RealType skin; if (simParams_->haveSkinThickness()) { - double skinThickness = simParams_->getSkinThickness(); - } + skin = simParams_->getSkinThickness(); + notifyFortranSkinThickness(&skin); + } + + // Check if the cutoff was set explicitly: + if (simParams_->haveCutoffRadius()) { + rcut_ = simParams_->getCutoffRadius(); + if (simParams_->haveSwitchingRadius()) { + rsw_ = simParams_->getSwitchingRadius(); + } else { + if (fInfo_.SIM_uses_Charges | + fInfo_.SIM_uses_Dipoles | + fInfo_.SIM_uses_RF) { + + rsw_ = 0.85 * rcut_; + sprintf(painCave.errMsg, + "SimCreator Warning: No value was set for the switchingRadius.\n" + "\tOOPSE will use a default value of 85 percent of the cutoffRadius.\n" + "\tswitchingRadius = %f. for this simulation\n", rsw_); + painCave.isFatal = 0; + simError(); + } else { + rsw_ = rcut_; + sprintf(painCave.errMsg, + "SimCreator Warning: No value was set for the switchingRadius.\n" + "\tOOPSE will use the same value as the cutoffRadius.\n" + "\tswitchingRadius = %f. for this simulation\n", rsw_); + painCave.isFatal = 0; + simError(); + } + } + + notifyFortranCutoffs(&rcut_, &rsw_); + + } else { + + // For electrostatic atoms, we'll assume a large safe value: + if (fInfo_.SIM_uses_Charges | fInfo_.SIM_uses_Dipoles | fInfo_.SIM_uses_RF) { + sprintf(painCave.errMsg, + "SimCreator Warning: No value was set for the cutoffRadius.\n" + "\tOOPSE will use a default value of 15.0 angstroms" + "\tfor the cutoffRadius.\n"); + painCave.isFatal = 0; + simError(); + rcut_ = 15.0; + + if (simParams_->haveElectrostaticSummationMethod()) { + std::string myMethod = simParams_->getElectrostaticSummationMethod(); + toUpper(myMethod); + if (myMethod == "SHIFTED_POTENTIAL" || myMethod == "SHIFTED_FORCE") { + if (simParams_->haveSwitchingRadius()){ + sprintf(painCave.errMsg, + "SimInfo Warning: A value was set for the switchingRadius\n" + "\teven though the electrostaticSummationMethod was\n" + "\tset to %s\n", myMethod.c_str()); + painCave.isFatal = 1; + simError(); + } + } + } + + if (simParams_->haveSwitchingRadius()){ + rsw_ = simParams_->getSwitchingRadius(); + } else { + sprintf(painCave.errMsg, + "SimCreator Warning: No value was set for switchingRadius.\n" + "\tOOPSE will use a default value of\n" + "\t0.85 * cutoffRadius for the switchingRadius\n"); + painCave.isFatal = 0; + simError(); + rsw_ = 0.85 * rcut_; + } + notifyFortranCutoffs(&rcut_, &rsw_); + } else { + // We didn't set rcut explicitly, and we don't have electrostatic atoms, so + // We'll punt and let fortran figure out the cutoffs later. + + notifyFortranYouAreOnYourOwn(); - notifyFortranCutoffs(&rcut_, &rsw_, &rnblist, &cp); - // also send cutoff notification to electrostatics - setElectrostaticCutoffRadius(&rcut_, &rsw_); + } + } } void SimInfo::setupElectrostaticSummationMethod( int isError ) { @@ -1038,8 +1071,8 @@ namespace oopse { int errorOut; int esm = NONE; int sm = UNDAMPED; - double alphaVal; - double dielectric; + RealType alphaVal; + RealType dielectric; errorOut = isError; alphaVal = simParams_->getDampingAlpha(); @@ -1065,7 +1098,11 @@ namespace oopse { } else { // throw error sprintf( painCave.errMsg, - "SimInfo error: Unknown electrostaticSummationMethod. (Input file specified %s .)\n\telectrostaticSummationMethod must be one of: \"none\", \"shifted_potential\", \"shifted_force\", or \"reaction_field\".", myMethod.c_str() ); + "SimInfo error: Unknown electrostaticSummationMethod.\n" + "\t(Input file specified %s .)\n" + "\telectrostaticSummationMethod must be one of: \"none\",\n" + "\t\"shifted_potential\", \"shifted_force\", or \n" + "\t\"reaction_field\".\n", myMethod.c_str() ); painCave.isFatal = 1; simError(); } @@ -1086,14 +1123,18 @@ namespace oopse { if (!simParams_->haveDampingAlpha()) { //throw error sprintf( painCave.errMsg, - "SimInfo warning: dampingAlpha was not specified in the input file. A default value of %f (1/ang) will be used.", alphaVal); + "SimInfo warning: dampingAlpha was not specified in the input file.\n" + "\tA default value of %f (1/ang) will be used.\n", alphaVal); painCave.isFatal = 0; simError(); } } else { // throw error sprintf( painCave.errMsg, - "SimInfo error: Unknown electrostaticScreeningMethod. (Input file specified %s .)\n\telectrostaticScreeningMethod must be one of: \"undamped\" or \"damped\".", myScreen.c_str() ); + "SimInfo error: Unknown electrostaticScreeningMethod.\n" + "\t(Input file specified %s .)\n" + "\telectrostaticScreeningMethod must be one of: \"undamped\"\n" + "or \"damped\".\n", myScreen.c_str() ); painCave.isFatal = 1; simError(); } @@ -1102,10 +1143,11 @@ namespace oopse { // let's pass some summation method variables to fortran setElectrostaticSummationMethod( &esm ); + setFortranElectrostaticMethod( &esm ); setScreeningMethod( &sm ); setDampingAlpha( &alphaVal ); setReactionFieldDielectric( &dielectric ); - initFortranFF( &esm, &errorOut ); + initFortranFF( &errorOut ); } void SimInfo::setupSwitchingFunction() { @@ -1134,6 +1176,17 @@ namespace oopse { } + void SimInfo::setupAccumulateBoxDipole() { + + // we only call setAccumulateBoxDipole if the accumulateBoxDipole parameter is true + if ( simParams_->haveAccumulateBoxDipole() ) + if ( simParams_->getAccumulateBoxDipole() ) { + setAccumulateBoxDipole(); + calcBoxDipole_ = true; + } + + } + void SimInfo::addProperty(GenericData* genData) { properties_.addProperty(genData); } @@ -1190,20 +1243,20 @@ namespace oopse { Molecule* mol; Vector3d comVel(0.0); - double totalMass = 0.0; + RealType totalMass = 0.0; for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) { - double mass = mol->getMass(); + RealType mass = mol->getMass(); totalMass += mass; comVel += mass * mol->getComVel(); } #ifdef IS_MPI - double tmpMass = totalMass; + RealType tmpMass = totalMass; Vector3d tmpComVel(comVel); - MPI_Allreduce(&tmpMass,&totalMass,1,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); - MPI_Allreduce(tmpComVel.getArrayPointer(), comVel.getArrayPointer(),3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(&tmpMass,&totalMass,1,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(tmpComVel.getArrayPointer(), comVel.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); #endif comVel /= totalMass; @@ -1216,19 +1269,19 @@ namespace oopse { Molecule* mol; Vector3d com(0.0); - double totalMass = 0.0; + RealType totalMass = 0.0; for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) { - double mass = mol->getMass(); + RealType mass = mol->getMass(); totalMass += mass; com += mass * mol->getCom(); } #ifdef IS_MPI - double tmpMass = totalMass; + RealType tmpMass = totalMass; Vector3d tmpCom(com); - MPI_Allreduce(&tmpMass,&totalMass,1,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); - MPI_Allreduce(tmpCom.getArrayPointer(), com.getArrayPointer(),3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(&tmpMass,&totalMass,1,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(tmpCom.getArrayPointer(), com.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); #endif com /= totalMass; @@ -1252,23 +1305,23 @@ namespace oopse { Molecule* mol; - double totalMass = 0.0; + RealType totalMass = 0.0; for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) { - double mass = mol->getMass(); + RealType mass = mol->getMass(); totalMass += mass; com += mass * mol->getCom(); comVel += mass * mol->getComVel(); } #ifdef IS_MPI - double tmpMass = totalMass; + RealType tmpMass = totalMass; Vector3d tmpCom(com); Vector3d tmpComVel(comVel); - MPI_Allreduce(&tmpMass,&totalMass,1,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); - MPI_Allreduce(tmpCom.getArrayPointer(), com.getArrayPointer(),3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); - MPI_Allreduce(tmpComVel.getArrayPointer(), comVel.getArrayPointer(),3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(&tmpMass,&totalMass,1,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(tmpCom.getArrayPointer(), com.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(tmpComVel.getArrayPointer(), comVel.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); #endif com /= totalMass; @@ -1287,12 +1340,12 @@ namespace oopse { void SimInfo::getInertiaTensor(Mat3x3d &inertiaTensor, Vector3d &angularMomentum){ - double xx = 0.0; - double yy = 0.0; - double zz = 0.0; - double xy = 0.0; - double xz = 0.0; - double yz = 0.0; + RealType xx = 0.0; + RealType yy = 0.0; + RealType zz = 0.0; + RealType xy = 0.0; + RealType xz = 0.0; + RealType yz = 0.0; Vector3d com(0.0); Vector3d comVel(0.0); @@ -1304,7 +1357,7 @@ namespace oopse { Vector3d thisq(0.0); Vector3d thisv(0.0); - double thisMass = 0.0; + RealType thisMass = 0.0; @@ -1342,8 +1395,8 @@ namespace oopse { #ifdef IS_MPI Mat3x3d tmpI(inertiaTensor); Vector3d tmpAngMom; - MPI_Allreduce(tmpI.getArrayPointer(), inertiaTensor.getArrayPointer(),9,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); - MPI_Allreduce(tmpAngMom.getArrayPointer(), angularMomentum.getArrayPointer(),3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(tmpI.getArrayPointer(), inertiaTensor.getArrayPointer(),9,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(tmpAngMom.getArrayPointer(), angularMomentum.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); #endif return; @@ -1364,7 +1417,7 @@ namespace oopse { Vector3d thisr(0.0); Vector3d thisp(0.0); - double thisMass; + RealType thisMass; for (mol = beginMolecule(i); mol != NULL; mol = nextMolecule(i)) { thisMass = mol->getMass(); @@ -1377,7 +1430,7 @@ namespace oopse { #ifdef IS_MPI Vector3d tmpAngMom; - MPI_Allreduce(tmpAngMom.getArrayPointer(), angularMomentum.getArrayPointer(),3,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD); + MPI_Allreduce(tmpAngMom.getArrayPointer(), angularMomentum.getArrayPointer(),3,MPI_REALTYPE,MPI_SUM, MPI_COMM_WORLD); #endif return angularMomentum;