RealType GofRTheta::evaluateAngle(StuntDouble* sd1, StuntDouble* sd2) { bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); Vector3d pos1 = sd1->getPos(); Vector3d pos2 = sd2->getPos(); Vector3d r12 = pos2 - pos1; if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(r12); r12.normalize(); Vector3d vec; if (!sd1->isDirectional()) { sprintf(painCave.errMsg, "GofRTheta: attempted to use a non-directional object: %s\n", sd1->getType().c_str()); painCave.isFatal = 1; simError(); } if (sd1->isAtom()) { AtomType* atype1 = static_cast<Atom*>(sd1)->getAtomType(); MultipoleAdapter ma1 = MultipoleAdapter(atype1); if (ma1.isDipole() ) vec = sd1->getDipole(); else vec = sd1->getA().transpose() * V3Z; } else { vec = sd1->getA().transpose() * V3Z; } vec.normalize(); return dot(r12, vec); }
void GofRAngle::writeRdf() { std::ofstream ofs(outputFilename_.c_str()); if (ofs.is_open()) { Revision r; ofs << "# " << getAnalysisType() << "\n"; ofs << "# OpenMD " << r.getFullRevision() << "\n"; ofs << "# " << r.getBuildDate() << "\n"; ofs << "# selection script1: \"" << selectionScript1_ ; ofs << "\"\tselection script2: \"" << selectionScript2_ << "\""; if (doSele3_) { ofs << "\tselection script3: \"" << selectionScript3_ << "\"\n"; } else { ofs << "\n"; } if (!paramString_.empty()) ofs << "# parameters: " << paramString_ << "\n"; for (unsigned int i = 0; i < avgGofr_.size(); ++i) { // RealType r = deltaR_ * (i + 0.5); for(unsigned int j = 0; j < avgGofr_[i].size(); ++j) { // RealType cosAngle = -1.0 + (j + 0.5)*deltaCosAngle_; ofs << avgGofr_[i][j]/nProcessed_ << "\t"; } ofs << "\n"; } } else { sprintf(painCave.errMsg, "GofRAngle: unable to open %s\n", outputFilename_.c_str()); painCave.isFatal = 1; simError(); } ofs.close(); }
void DensityPlot::writeDensity() { std::ofstream ofs(outputFilename_.c_str(), std::ios::binary); if (ofs.is_open()) { ofs << "#g(x, y, z)\n"; ofs << "#selection: (" << selectionScript_ << ")\n"; ofs << "#cmSelection:(" << cmSelectionScript_ << ")\n"; ofs << "#nRBins = " << nRBins_ << "\t maxLen = " << len_ << "\tdeltaR = " << deltaR_ <<"\n"; for (unsigned int i = 0; i < histogram_.size(); ++i) { ofs << i*deltaR_ - halfLen_ <<"\t" << density_[i]<< std::endl; } } else { sprintf(painCave.errMsg, "DensityPlot: unable to open %s\n", outputFilename_.c_str()); painCave.isFatal = 1; simError(); } ofs.close(); }
RealType LineSearch::update(DynamicVector<RealType>& params, const DynamicVector<RealType>& direction, RealType beta, const Constraint& constraint) { RealType diff=beta; DynamicVector<RealType> newParams = params + diff*direction; bool valid = constraint.test(newParams); int icount = 0; while (!valid) { if (icount > 200) { sprintf(painCave.errMsg, "can't update linesearch\n"); painCave.isFatal = 1; painCave.severity = OPENMD_ERROR; simError(); } diff *= 0.5; icount ++; newParams = params + diff*direction; valid = constraint.test(newParams); } params += diff*direction; return diff; }
Shape* ShapeBuilder::internalCreateShape(DirectionalAtom* datom) { AtomType* atomType = datom->getAtomType(); Shape* currShape = NULL; LennardJonesAdapter lja = LennardJonesAdapter(atomType); GayBerneAdapter gba = GayBerneAdapter(atomType); if (gba.isGayBerne()) { currShape = new Ellipsoid(datom->getPos(), gba.getL()/2.0, gba.getD()/2.0, datom->getA()); } else if (lja.isLennardJones()) { currShape = new Sphere(datom->getPos(), lja.getSigma()/2.0); } else { int obanum = etab.GetAtomicNum((datom->getType()).c_str()); if (obanum != 0) { currShape = new Sphere(datom->getPos(), etab.GetVdwRad(obanum)); } else { sprintf( painCave.errMsg, "Could not find atom type in default element.txt\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } } return currShape; }
DirectionalAtom::DirectionalAtom(AtomType* dAtomType) : Atom(dAtomType) { objType_= otDAtom; DirectionalAdapter da = DirectionalAdapter(dAtomType); I_ = da.getI(); MultipoleAdapter ma = MultipoleAdapter(dAtomType); if (ma.isDipole()) { dipole_ = ma.getDipole(); } if (ma.isQuadrupole()) { quadrupole_ = ma.getQuadrupole(); } // Check if one of the diagonal inertia tensor of this directional // atom is zero: int nLinearAxis = 0; Mat3x3d inertiaTensor = getI(); for (int i = 0; i < 3; i++) { if (fabs(inertiaTensor(i, i)) < OpenMD::epsilon) { linear_ = true; linearAxis_ = i; ++ nLinearAxis; } } if (nLinearAxis > 1) { sprintf( painCave.errMsg, "Directional Atom warning.\n" "\tOpenMD found more than one axis in this directional atom with a vanishing \n" "\tmoment of inertia."); painCave.isFatal = 0; simError(); } }
ConstraintWriter::ConstraintWriter(SimInfo* info, const std::string& filename): info_(info) { //use master - slave mode, only master node writes to disk #ifdef IS_MPI if(worldRank == 0){ #endif output_.open(filename.c_str()); if(!output_){ sprintf( painCave.errMsg, "Could not open %s for Constraint output\n", filename.c_str()); painCave.isFatal = 1; simError(); } output_ << "#time(fs)\t" << "Index of atom 1\t" << "Index of atom 2\tconstraint force" << std::endl; #ifdef IS_MPI } #endif }
void Shake::doConstraint(ConstraintPairFuncPtr func) { if (!doShake_) return; Molecule* mol; SimInfo::MoleculeIterator mi; ConstraintElem* consElem; Molecule::ConstraintElemIterator cei; ConstraintPair* consPair; Molecule::ConstraintPairIterator cpi; for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) { consElem->setMoved(true); consElem->setMoving(false); } } //main loop of constraint algorithm int done = 0; int iteration = 0; while(!done && iteration < maxConsIteration_){ done = 1; //loop over every constraint pair for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consPair = mol->beginConstraintPair(cpi); consPair != NULL; consPair = mol->nextConstraintPair(cpi)) { //dispatch constraint algorithm if(consPair->isMoved()) { int exeStatus = (this->*func)(consPair); switch(exeStatus){ case consFail: sprintf(painCave.errMsg, "Constraint failure in Shake::constrainA, " "Constraint Fail\n"); painCave.isFatal = 1; simError(); break; case consSuccess: // constrain the pair by moving two elements done = 0; consPair->getConsElem1()->setMoving(true); consPair->getConsElem2()->setMoving(true); break; case consAlready: // current pair is already constrained, do not need to // move the elements break; default: sprintf(painCave.errMsg, "ConstraintAlgorithm::doConstraint() " "Error: unrecognized status"); painCave.isFatal = 1; simError(); break; } } } }//end for(iter->first()) #ifdef IS_MPI MPI_Allreduce(MPI_IN_PLACE, &done, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD); #endif errorCheckPoint(); for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { for (consElem = mol->beginConstraintElem(cei); consElem != NULL; consElem = mol->nextConstraintElem(cei)) { consElem->setMoved(consElem->getMoving()); consElem->setMoving(false); } } iteration++; }//end while if (!done){ sprintf(painCave.errMsg, "Constraint failure in Shake::constrainA, " "too many iterations: %d\n", iteration); painCave.isFatal = 1; simError(); } errorCheckPoint(); }
LangevinHullForceManager::LangevinHullForceManager(SimInfo* info) : ForceManager(info) { simParams = info->getSimParams(); veloMunge = new Velocitizer(info); // Create Hull, Convex Hull for now, other options later. stringToEnumMap_["Convex"] = hullConvex; stringToEnumMap_["AlphaShape"] = hullAlphaShape; stringToEnumMap_["Unknown"] = hullUnknown; const std::string ht = simParams->getHULL_Method(); std::map<std::string, HullTypeEnum>::iterator iter; iter = stringToEnumMap_.find(ht); hullType_ = (iter == stringToEnumMap_.end()) ? LangevinHullForceManager::hullUnknown : iter->second; switch(hullType_) { case hullConvex : surfaceMesh_ = new ConvexHull(); break; case hullAlphaShape : surfaceMesh_ = new AlphaHull(simParams->getAlpha()); break; case hullUnknown : default : sprintf(painCave.errMsg, "LangevinHallForceManager: Unknown Hull_Method was requested!\n"); painCave.isFatal = 1; simError(); break; } doThermalCoupling_ = true; doPressureCoupling_ = true; /* Check that the simulation has target pressure and target temperature set */ if (!simParams->haveTargetTemp()) { sprintf(painCave.errMsg, "LangevinHullForceManager: no targetTemp (K) was set.\n" "\tOpenMD is turning off the thermal coupling to the bath.\n"); painCave.isFatal = 0; painCave.severity = OPENMD_INFO; simError(); doThermalCoupling_ = false; } else { targetTemp_ = simParams->getTargetTemp(); if (!simParams->haveViscosity()) { sprintf(painCave.errMsg, "LangevinHullForceManager: no viscosity was set.\n" "\tOpenMD is turning off the thermal coupling to the bath.\n"); painCave.isFatal = 0; painCave.severity = OPENMD_INFO; simError(); doThermalCoupling_ = false; }else{ viscosity_ = simParams->getViscosity(); if ( fabs(viscosity_) < 1e-6 ) { sprintf(painCave.errMsg, "LangevinHullDynamics: The bath viscosity was set lower\n" "\tthan 1e-6 poise. OpenMD is turning off the thermal\n" "\tcoupling to the bath.\n"); painCave.isFatal = 0; painCave.severity = OPENMD_INFO; simError(); doThermalCoupling_ = false; } } } if (!simParams->haveTargetPressure()) { sprintf(painCave.errMsg, "LangevinHullForceManager: no targetPressure (atm) was set.\n" "\tOpenMD is turning off the pressure coupling to the bath.\n"); painCave.isFatal = 0; painCave.severity = OPENMD_INFO; simError(); doPressureCoupling_ = false; } else { // Convert pressure from atm -> amu/(fs^2*Ang) targetPressure_ = simParams->getTargetPressure() / PhysicalConstants::pressureConvert; } if (simParams->getUsePeriodicBoundaryConditions()) { sprintf(painCave.errMsg, "LangevinHallForceManager: You can't use the Langevin Hull\n" "\tintegrator with periodic boundary conditions turned on!\n"); painCave.isFatal = 1; simError(); } dt_ = simParams->getDt(); if (doThermalCoupling_) variance_ = 2.0 * PhysicalConstants::kb * targetTemp_ / dt_; // Build a vector of integrable objects to determine if the are // surface atoms Molecule* mol; StuntDouble* sd; SimInfo::MoleculeIterator i; Molecule::IntegrableObjectIterator j; for (mol = info_->beginMolecule(i); mol != NULL; mol = info_->nextMolecule(i)) { for (sd = mol->beginIntegrableObject(j); sd != NULL; sd = mol->nextIntegrableObject(j)) { localSites_.push_back(sd); } } // We need to make an initial guess at the bounding box in order // to compute long range forces in ForceMatrixDecomposition: // Compute surface Mesh surfaceMesh_->computeHull(localSites_); }
void ContactAngle1::doFrame(int frame) { StuntDouble* sd; int i; if (evaluator1_.isDynamic()) { seleMan1_.setSelectionSet(evaluator1_.evaluate()); } RealType mtot = 0.0; Vector3d com(V3Zero); RealType mass; for (sd = seleMan1_.beginSelected(i); sd != NULL; sd = seleMan1_.nextSelected(i)) { mass = sd->getMass(); mtot += mass; com += sd->getPos() * mass; } com /= mtot; RealType dz = com.z() - solidZ_; if (dz < 0.0) { sprintf(painCave.errMsg, "ContactAngle1: Z-center of mass of selection, %lf, was\n" "\tlocated below the solid reference plane, %lf\n", com.z(), solidZ_); painCave.isFatal = 1; painCave.severity = OPENMD_ERROR; simError(); } if (dz > dropletRadius_) { values_.push_back(180.0); } else { RealType k = pow(2.0, -4.0/3.0) * dropletRadius_; RealType z2 = dz*dz; RealType z3 = z2 * dz; RealType k2 = k*k; RealType k3 = k2*k; Polynomial<RealType> poly; poly.setCoefficient(4, z3 + k3); poly.setCoefficient(3, 8.0*z3 + 8.0*k3); poly.setCoefficient(2, 24.0*z3 + 18.0*k3); poly.setCoefficient(1, 32.0*z3 ); poly.setCoefficient(0, 16.0*z3 - 27.0*k3); vector<RealType> realRoots = poly.FindRealRoots(); RealType ct; vector<RealType>::iterator ri; RealType maxct = -1.0; for (ri = realRoots.begin(); ri !=realRoots.end(); ++ri) { ct = *ri; if (ct > 1.0) ct = 1.0; if (ct < -1.0) ct = -1.0; // use the largest magnitude of ct that it finds: if (ct > maxct) { maxct = ct; } } values_.push_back( acos(maxct)*(180.0/M_PI) ); } }
void SC::addType(AtomType* atomType){ SuttonChenAdapter sca = SuttonChenAdapter(atomType); SCAtomData scAtomData; scAtomData.c = sca.getC(); scAtomData.m = sca.getM(); scAtomData.n = sca.getN(); scAtomData.alpha = sca.getAlpha(); scAtomData.epsilon = sca.getEpsilon(); scAtomData.rCut = 2.0 * scAtomData.alpha; // add it to the map: int atid = atomType->getIdent(); int sctid = SCtypes.size(); pair<set<int>::iterator,bool> ret; ret = SCtypes.insert( atid ); if (ret.second == false) { sprintf( painCave.errMsg, "SC already had a previous entry with ident %d\n", atid ); painCave.severity = OPENMD_INFO; painCave.isFatal = 0; simError(); } SCtids[atid] = sctid; SCdata[sctid] = scAtomData; MixingMap[sctid].resize(nSC_); // Now, iterate over all known types and add to the mixing map: std::set<int>::iterator it; for( it = SCtypes.begin(); it != SCtypes.end(); ++it) { int sctid2 = SCtids[ (*it) ]; AtomType* atype2 = forceField_->getAtomType( (*it) ); SCInteractionData mixer; mixer.alpha = getAlpha(atomType, atype2); mixer.rCut = 2.0 * mixer.alpha; mixer.epsilon = getEpsilon(atomType, atype2); mixer.m = getM(atomType, atype2); mixer.n = getN(atomType, atype2); RealType dr = mixer.rCut / (np_ - 1); vector<RealType> rvals; vector<RealType> vvals; vector<RealType> phivals; rvals.push_back(0.0); vvals.push_back(0.0); phivals.push_back(0.0); for (int k = 1; k < np_; k++) { RealType r = dr * k; rvals.push_back(r); vvals.push_back( mixer.epsilon * pow(mixer.alpha/r, mixer.n) ); phivals.push_back( pow(mixer.alpha/r, mixer.m) ); } mixer.vCut = mixer.epsilon * pow(mixer.alpha/mixer.rCut, mixer.n); CubicSpline* V = new CubicSpline(); V->addPoints(rvals, vvals); CubicSpline* phi = new CubicSpline(); phi->addPoints(rvals, phivals); mixer.V = V; mixer.phi = phi; mixer.explicitlySet = false; MixingMap[sctid2].resize( nSC_ ); MixingMap[sctid][sctid2] = mixer; if (sctid2 != sctid) { MixingMap[sctid2][sctid] = mixer; } } return; }
void FluctuatingChargeAtomTypesSectionParser::parseLine(ForceField& ff, const string& line, int lineNo){ StringTokenizer tokenizer(line); int nTokens = tokenizer.countTokens(); if (nTokens < 3) { sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: " "Not enough tokens at line %d\n", lineNo); painCave.isFatal = 1; simError(); } string atomTypeName = tokenizer.nextToken(); AtomType* atomType = ff.getAtomType(atomTypeName); if (atomType != NULL) { FixedChargeAdapter fca = FixedChargeAdapter(atomType); // All fluctuating charges are charges, and if we haven't // already set values for the charge, then start with zero. if (! fca.isFixedCharge()) { RealType charge = 0.0; fca.makeFixedCharge(charge); } } else { sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: Atom Type [%s] " "has not been created yet\n", atomTypeName.c_str()); painCave.isFatal = 1; simError(); } RealType chargeMass = tokenizer.nextTokenAsDouble(); FluctuatingTypeEnum fqt = getFluctuatingTypeEnum(tokenizer.nextToken()); nTokens -= 3; switch(fqt) { case fqtHardness: // For Rick, Stuart, Berne style fluctuating charges, there's a // self charge potential defined by electronegativity and // hardness. On molecular structures, the slater-type overlap // integral is used to compute the hardness. // atomTypeName, chargeMass, Hardness, electronegativity, // hardness (Jii), slaterN, slaterZeta if (nTokens < 4) { sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: " "Not enough tokens at line %d\n", lineNo); painCave.isFatal = 1; simError(); } else { RealType chi = tokenizer.nextTokenAsDouble(); RealType Jii = tokenizer.nextTokenAsDouble(); int slaterN = tokenizer.nextTokenAsInt(); RealType slaterZeta = tokenizer.nextTokenAsDouble(); FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType); fqa.makeFluctuatingCharge(chargeMass, chi, Jii, slaterN, slaterZeta); } break; case fqtMultipleMinima: if (nTokens < 4 || nTokens % 2 != 0) { sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: " "Not enough tokens at line %d\n", lineNo); painCave.isFatal = 1; simError(); } else { std::vector<std::pair<RealType, RealType> > diabaticStates; RealType curvature = tokenizer.nextTokenAsDouble(); RealType coupling = tokenizer.nextTokenAsDouble(); nTokens -= 2; int nStates = nTokens / 2; RealType charge; RealType ionizationEnergy; for (int i = 0; i < nStates; ++i) { charge = tokenizer.nextTokenAsDouble(); ionizationEnergy = tokenizer.nextTokenAsDouble(); diabaticStates.push_back( std::make_pair( charge, ionizationEnergy )); } FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType); fqa.makeFluctuatingCharge(chargeMass, curvature, coupling, diabaticStates); } break; case fqtMetal: if (nTokens < 5 || nTokens % 2 != 1) { sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: " "Not enough tokens at line %d\n", lineNo); painCave.isFatal = 1; simError(); } else { int nValence = tokenizer.nextTokenAsInt(); nTokens -= 1; std::vector<std::pair<RealType, RealType> > diabaticStates; RealType curvature = tokenizer.nextTokenAsDouble(); RealType coupling = tokenizer.nextTokenAsDouble(); nTokens -= 2; int nStates = nTokens / 2; RealType charge; RealType ionizationEnergy; for (int i = 0; i < nStates; ++i) { charge = tokenizer.nextTokenAsDouble(); ionizationEnergy = tokenizer.nextTokenAsDouble(); diabaticStates.push_back( std::make_pair( charge, ionizationEnergy )); } FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType); fqa.makeFluctuatingCharge(chargeMass, nValence, curvature, coupling, diabaticStates); } break; case fqtUnknown: default: sprintf(painCave.errMsg, "FluctuatingChargeAtomTypesSectionParser Error: " "Unknown Fluctuating Charge Type at line %d\n", lineNo); painCave.isFatal = 1; simError(); break; } }
void InteractionManager::initialize() { if (initialized_) return; ForceField* forceField_ = info_->getForceField(); lj_->setForceField(forceField_); gb_->setForceField(forceField_); sticky_->setForceField(forceField_); eam_->setForceField(forceField_); sc_->setForceField(forceField_); morse_->setForceField(forceField_); electrostatic_->setSimInfo(info_); electrostatic_->setForceField(forceField_); maw_->setForceField(forceField_); repulsivePower_->setForceField(forceField_); ForceField::AtomTypeContainer* atomTypes = forceField_->getAtomTypes(); int nTypes = atomTypes->size(); sHash_.resize(nTypes); iHash_.resize(nTypes); interactions_.resize(nTypes); ForceField::AtomTypeContainer::MapTypeIterator i1, i2; AtomType* atype1; AtomType* atype2; int atid1, atid2; // We only need to worry about the types that are actually in the // simulation: set<AtomType*> atypes = info_->getSimulatedAtomTypes(); lj_->setSimulatedAtomTypes(atypes); gb_->setSimulatedAtomTypes(atypes); sticky_->setSimulatedAtomTypes(atypes); eam_->setSimulatedAtomTypes(atypes); sc_->setSimulatedAtomTypes(atypes); morse_->setSimulatedAtomTypes(atypes); electrostatic_->setSimInfo(info_); electrostatic_->setSimulatedAtomTypes(atypes); maw_->setSimulatedAtomTypes(atypes); repulsivePower_->setSimulatedAtomTypes(atypes); set<AtomType*>::iterator at; for (at = atypes.begin(); at != atypes.end(); ++at) { atype1 = *at; atid1 = atype1->getIdent(); iHash_[atid1].resize(nTypes); interactions_[atid1].resize(nTypes); // add it to the map: pair<map<int,AtomType*>::iterator,bool> ret; ret = typeMap_.insert( pair<int, AtomType*>(atid1, atype1) ); if (ret.second == false) { sprintf( painCave.errMsg, "InteractionManager already had a previous entry with ident %d\n", atype1->getIdent()); painCave.severity = OPENMD_INFO; painCave.isFatal = 0; simError(); } if (atype1->isLennardJones()) { sHash_[atid1] |= LJ_INTERACTION; } if (atype1->isElectrostatic()) { sHash_[atid1] |= ELECTROSTATIC_INTERACTION; } if (atype1->isSticky()) { sHash_[atid1] |= STICKY_INTERACTION; } if (atype1->isStickyPower()) { sHash_[atid1] |= STICKY_INTERACTION; } if (atype1->isEAM()) { sHash_[atid1] |= EAM_INTERACTION; } if (atype1->isSC()) { sHash_[atid1] |= SC_INTERACTION; } if (atype1->isGayBerne()) { sHash_[atid1] |= GB_INTERACTION; } } // Now, iterate over all known types and add to the interaction map: map<int, AtomType*>::iterator it1, it2; for (it1 = typeMap_.begin(); it1 != typeMap_.end(); ++it1) { atype1 = (*it1).second; atid1 = atype1->getIdent(); for( it2 = typeMap_.begin(); it2 != typeMap_.end(); ++it2) { atype2 = (*it2).second; atid2 = atype2->getIdent(); iHash_[atid1][atid2] = 0; if (atype1->isLennardJones() && atype2->isLennardJones()) { interactions_[atid1][atid2].insert(lj_); iHash_[atid1][atid2] |= LJ_INTERACTION; } if (atype1->isElectrostatic() && atype2->isElectrostatic() ) { interactions_[atid1][atid2].insert(electrostatic_); iHash_[atid1][atid2] |= ELECTROSTATIC_INTERACTION; } if (atype1->isSticky() && atype2->isSticky() ) { interactions_[atid1][atid2].insert(sticky_); iHash_[atid1][atid2] |= STICKY_INTERACTION; } if (atype1->isStickyPower() && atype2->isStickyPower() ) { interactions_[atid1][atid2].insert(sticky_); iHash_[atid1][atid2] |= STICKY_INTERACTION; } if (atype1->isEAM() && atype2->isEAM() ) { interactions_[atid1][atid2].insert(eam_); iHash_[atid1][atid2] |= EAM_INTERACTION; } if (atype1->isSC() && atype2->isSC() ) { interactions_[atid1][atid2].insert(sc_); iHash_[atid1][atid2] |= SC_INTERACTION; } if (atype1->isGayBerne() && atype2->isGayBerne() ) { interactions_[atid1][atid2].insert(gb_); iHash_[atid1][atid2] |= GB_INTERACTION; } if ((atype1->isGayBerne() && atype2->isLennardJones()) || (atype1->isLennardJones() && atype2->isGayBerne())) { interactions_[atid1][atid2].insert(gb_); iHash_[atid1][atid2] |= GB_INTERACTION; } // look for an explicitly-set non-bonded interaction type using the // two atom types. NonBondedInteractionType* nbiType = forceField_->getNonBondedInteractionType(atype1->getName(), atype2->getName()); if (nbiType != NULL) { bool vdwExplicit = false; bool metExplicit = false; // bool hbExplicit = false; if (nbiType->isLennardJones()) { // We found an explicit Lennard-Jones interaction. // override all other vdw entries for this pair of atom types: set<NonBondedInteraction*>::iterator it; for (it = interactions_[atid1][atid2].begin(); it != interactions_[atid1][atid2].end(); ++it) { InteractionFamily ifam = (*it)->getFamily(); if (ifam == VANDERWAALS_FAMILY) { interactions_[atid1][atid2].erase(*it); iHash_[atid1][atid2] ^= (*it)->getHash(); } } interactions_[atid1][atid2].insert(lj_); iHash_[atid1][atid2] |= LJ_INTERACTION; LennardJonesInteractionType* ljit = dynamic_cast<LennardJonesInteractionType*>(nbiType); lj_->addExplicitInteraction(atype1, atype2, ljit->getSigma(), ljit->getEpsilon()); vdwExplicit = true; } if (nbiType->isMorse()) { if (vdwExplicit) { sprintf( painCave.errMsg, "InteractionManager::initialize found more than one " "explicit \n" "\tvan der Waals interaction for atom types %s - %s\n", atype1->getName().c_str(), atype2->getName().c_str()); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } // We found an explicit Morse interaction. // override all other vdw entries for this pair of atom types: set<NonBondedInteraction*>::iterator it; for (it = interactions_[atid1][atid2].begin(); it != interactions_[atid1][atid2].end(); ++it) { InteractionFamily ifam = (*it)->getFamily(); if (ifam == VANDERWAALS_FAMILY) { interactions_[atid1][atid2].erase(*it); iHash_[atid1][atid2] ^= (*it)->getHash(); } } interactions_[atid1][atid2].insert(morse_); iHash_[atid1][atid2] |= MORSE_INTERACTION; MorseInteractionType* mit = dynamic_cast<MorseInteractionType*>(nbiType); morse_->addExplicitInteraction(atype1, atype2, mit->getD(), mit->getR(), mit->getBeta(), mit->getInteractionType()); vdwExplicit = true; } if (nbiType->isRepulsivePower()) { if (vdwExplicit) { sprintf( painCave.errMsg, "InteractionManager::initialize found more than one " "explicit \n" "\tvan der Waals interaction for atom types %s - %s\n", atype1->getName().c_str(), atype2->getName().c_str()); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } // We found an explicit RepulsivePower interaction. // override all other vdw entries for this pair of atom types: set<NonBondedInteraction*>::iterator it; for (it = interactions_[atid1][atid2].begin(); it != interactions_[atid1][atid2].end(); ++it) { InteractionFamily ifam = (*it)->getFamily(); if (ifam == VANDERWAALS_FAMILY) { interactions_[atid1][atid2].erase(*it); iHash_[atid1][atid2] ^= (*it)->getHash(); } } interactions_[atid1][atid2].insert(repulsivePower_); iHash_[atid1][atid2] |= REPULSIVEPOWER_INTERACTION; RepulsivePowerInteractionType* rpit = dynamic_cast<RepulsivePowerInteractionType*>(nbiType); repulsivePower_->addExplicitInteraction(atype1, atype2, rpit->getSigma(), rpit->getEpsilon(), rpit->getNrep()); vdwExplicit = true; } if (nbiType->isEAM()) { // We found an explicit EAM interaction. // override all other metallic entries for this pair of atom types: set<NonBondedInteraction*>::iterator it; for (it = interactions_[atid1][atid2].begin(); it != interactions_[atid1][atid2].end(); ++it) { InteractionFamily ifam = (*it)->getFamily(); if (ifam == METALLIC_FAMILY) { interactions_[atid1][atid2].erase(*it); iHash_[atid1][atid2] ^= (*it)->getHash(); } } interactions_[atid1][atid2].insert(eam_); iHash_[atid1][atid2] |= EAM_INTERACTION; metExplicit = true; } if (nbiType->isSC()) { if (metExplicit) { sprintf( painCave.errMsg, "InteractionManager::initialize found more than one " "explicit\n" "\tmetallic interaction for atom types %s - %s\n", atype1->getName().c_str(), atype2->getName().c_str()); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } // We found an explicit Sutton-Chen interaction. // override all other metallic entries for this pair of atom types: set<NonBondedInteraction*>::iterator it; for (it = interactions_[atid1][atid2].begin(); it != interactions_[atid1][atid2].end(); ++it) { InteractionFamily ifam = (*it)->getFamily(); if (ifam == METALLIC_FAMILY) { interactions_[atid1][atid2].erase(*it); iHash_[atid1][atid2] ^= (*it)->getHash(); } } interactions_[atid1][atid2].insert(sc_); iHash_[atid1][atid2] |= SC_INTERACTION; metExplicit = true; } if (nbiType->isMAW()) { if (vdwExplicit) { sprintf( painCave.errMsg, "InteractionManager::initialize found more than one " "explicit\n" "\tvan der Waals interaction for atom types %s - %s\n", atype1->getName().c_str(), atype2->getName().c_str()); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } // We found an explicit MAW interaction. // override all other vdw entries for this pair of atom types: set<NonBondedInteraction*>::iterator it; for (it = interactions_[atid1][atid2].begin(); it != interactions_[atid1][atid2].end(); ++it) { InteractionFamily ifam = (*it)->getFamily(); if (ifam == VANDERWAALS_FAMILY) { interactions_[atid1][atid2].erase(*it); iHash_[atid1][atid2] ^= (*it)->getHash(); } } interactions_[atid1][atid2].insert(maw_); iHash_[atid1][atid2] |= MAW_INTERACTION; MAWInteractionType* mit = dynamic_cast<MAWInteractionType*>(nbiType); maw_->addExplicitInteraction(atype1, atype2, mit->getD(), mit->getBeta(), mit->getR(), mit->getCA1(), mit->getCB1()); vdwExplicit = true; } } } } // Make sure every pair of atom types in this simulation has a // non-bonded interaction. If not, just inform the user. set<AtomType*> simTypes = info_->getSimulatedAtomTypes(); set<AtomType*>::iterator it, jt; for (it = simTypes.begin(); it != simTypes.end(); ++it) { atype1 = (*it); atid1 = atype1->getIdent(); for (jt = it; jt != simTypes.end(); ++jt) { atype2 = (*jt); atid2 = atype2->getIdent(); if (interactions_[atid1][atid2].size() == 0) { sprintf( painCave.errMsg, "InteractionManager could not find a matching non-bonded\n" "\tinteraction for atom types %s - %s\n" "\tProceeding without this interaction.\n", atype1->getName().c_str(), atype2->getName().c_str()); painCave.severity = OPENMD_INFO; painCave.isFatal = 0; simError(); } } } initialized_ = true; }
void SwitchingFunction::setSwitch(RealType rinner, RealType router) { if (router < rinner) { sprintf( painCave.errMsg, "SwitchingFunction::setSwitch was given rinner (%lf) which was\n" "\tlarger than router (%lf).\n", rinner, router); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } if (router < 0.0) { sprintf( painCave.errMsg, "SwitchingFunction::setSwitch was given router (%lf) which was\n" "\tless than zero.\n", router); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } if (rinner < 0.0) { sprintf( painCave.errMsg, "SwitchingFunction::setSwitch was given rinner (%lf) which was\n" "\tless than zero.\n", router); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } rin_ = rinner; rout_ = router; rin2_ = rin_ * rin_; rout2_ = rout_ * rout_; if ((router - rinner) < 1.0e-8) { // no reason to set up spline if the switching region is tiny return; } // setup r -> sw lookup spline if (functionType_ == fifth_order_poly) { isCubic_ = false; RealType c0 = 1.0; RealType c3 = -10.0; RealType c4 = 15.0; RealType c5 = -6.0; RealType dx, r, yval, rval, rval2, rval3, rval4, rval5; RealType rvaldi, rvaldi2, rvaldi3, rvaldi4, rvaldi5; dx = (rout_ - rin_) / RealType(np_-1); for (int i = 0; i < np_; i++) { r = rin_ + RealType(i)*dx; rval = ( r - rin_ ); rval2 = rval*rval; rval3 = rval2*rval; rval4 = rval2*rval2; rval5 = rval3*rval2; rvaldi = 1.0 / ( rout_ - rin_ ); rvaldi2 = rvaldi*rvaldi; rvaldi3 = rvaldi2*rvaldi; rvaldi4 = rvaldi2*rvaldi2; rvaldi5 = rvaldi3*rvaldi2; yval= c0 + c3*rval3*rvaldi3 + c4*rval4*rvaldi4 + c5*rval5*rvaldi5; switchSpline_->addPoint(r, yval); } } else { // cubic splines only need 2 points to do a cubic switching function... isCubic_ = true; switchSpline_->addPoint(rin_, 1.0); switchSpline_->addPoint(rout_, 0.0); } haveSpline_ = true; return; }
void TetrahedralityParam::writeOrderParameter() { int nSelected = 0; for (int i = 0; i < nBins_; ++i) { nSelected = nSelected + int(Q_histogram_[i]*deltaQ_); } std::ofstream osq((getOutputFileName() + "Q").c_str()); if (osq.is_open()) { osq << "# Tetrahedrality Parameters\n"; osq << "# selection: (" << selectionScript_ << ")\n"; osq << "# \n"; // Normalize by number of frames and write it out: for (int i = 0; i < nBins_; ++i) { RealType Qval = MinQ_ + (i + 0.5) * deltaQ_; osq << Qval; osq << "\t" << (RealType) (Q_histogram_[i]/deltaQ_)/nSelected; osq << "\n"; } osq.close(); }else { sprintf(painCave.errMsg, "TetrahedralityParam: unable to open %s\n", (getOutputFileName() + "q").c_str()); painCave.isFatal = 1; simError(); } DumpReader reader(info_, dumpFilename_); int nFrames = reader.getNFrames(); if (nFrames == 1) { std::vector<StuntDouble*>::iterator iter; std::ofstream osd((getOutputFileName() + "dxyz").c_str()); if (osd.is_open()) { osd << Distorted_.size() << "\n"; osd << "\n"; for (iter = Distorted_.begin(); iter != Distorted_.end(); ++iter) { Vector3d position; position = (*iter)->getPos(); osd << "O " << "\t"; for (unsigned int z = 0; z < position.size(); z++) { osd << position[z] << " " << "\t"; } osd << "\n"; } osd.close(); } std::ofstream ost((getOutputFileName() + "txyz").c_str()); if (ost.is_open()) { ost << Tetrahedral_.size() << "\n"; ost << "\n"; for (iter = Tetrahedral_.begin(); iter != Tetrahedral_.end(); ++iter) { Vector3d position; position = (*iter)->getPos(); ost << "O " << "\t"; for (unsigned int z = 0; z < position.size(); z++) { ost << position[z] << " " << "\t"; } ost << "\n"; } ost.close(); } } }
void DensityPlot::process() { Molecule* mol; RigidBody* rb; SimInfo::MoleculeIterator mi; Molecule::RigidBodyIterator rbIter; DumpReader reader(info_, dumpFilename_); int nFrames = reader.getNFrames(); for (int i = 0; i < nFrames; i += step_) { reader.readFrame(i); currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot(); for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { //change the positions of atoms which belong to the rigidbodies for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { rb->updateAtoms(); } } if (evaluator_.isDynamic()) { seleMan_.setSelectionSet(evaluator_.evaluate()); } if (cmEvaluator_.isDynamic()) { cmSeleMan_.setSelectionSet(cmEvaluator_.evaluate()); } Vector3d origin = calcNewOrigin(); Mat3x3d hmat = currentSnapshot_->getHmat(); RealType slabVolume = deltaR_ * hmat(0, 0) * hmat(1, 1); int k; for (StuntDouble* sd = seleMan_.beginSelected(k); sd != NULL; sd = seleMan_.nextSelected(k)) { if (!sd->isAtom()) { sprintf( painCave.errMsg, "Can not calculate electron density if it is not atom\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } Atom* atom = static_cast<Atom*>(sd); GenericData* data = atom->getAtomType()->getPropertyByName("nelectron"); if (data == NULL) { sprintf( painCave.errMsg, "Can not find Parameters for nelectron\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } DoubleGenericData* doubleData = dynamic_cast<DoubleGenericData*>(data); if (doubleData == NULL) { sprintf( painCave.errMsg, "Can not cast GenericData to DoubleGenericData\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } RealType nelectron = doubleData->getData(); LennardJonesAdapter lja = LennardJonesAdapter(atom->getAtomType()); RealType sigma = lja.getSigma() * 0.5; RealType sigma2 = sigma * sigma; Vector3d pos = sd->getPos() - origin; for (int j =0; j < nRBins_; ++j) { Vector3d tmp(pos); RealType zdist =j * deltaR_ - halfLen_; tmp[2] += zdist; if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(tmp); RealType wrappedZdist = tmp.z() + halfLen_; if (wrappedZdist < 0.0 || wrappedZdist > len_) { continue; } int which = int(wrappedZdist / deltaR_); density_[which] += nelectron * exp(-zdist*zdist/(sigma2*2.0)) /(slabVolume* sqrt(2*NumericConstant::PI*sigma*sigma)); } } } int nProcessed = nFrames /step_; std::transform(density_.begin(), density_.end(), density_.begin(), std::bind2nd(std::divides<RealType>(), nProcessed)); writeDensity(); }
void EAM::initialize() { // set up the mixing method: ForceFieldOptions& fopts = forceField_->getForceFieldOptions(); string EAMMixMeth = fopts.getEAMMixingMethod(); toUpper(EAMMixMeth); if (EAMMixMeth == "JOHNSON") mixMeth_ = eamJohnson; else if (EAMMixMeth == "DAW") mixMeth_ = eamDaw; else mixMeth_ = eamUnknown; // find all of the EAM atom Types: EAMtypes.clear(); EAMtids.clear(); EAMdata.clear(); MixingMap.clear(); nEAM_ = 0; EAMtids.resize( forceField_->getNAtomType(), -1); set<AtomType*>::iterator at; for (at = simTypes_.begin(); at != simTypes_.end(); ++at) { if ((*at)->isEAM()) nEAM_++; } EAMdata.resize(nEAM_); MixingMap.resize(nEAM_); for (at = simTypes_.begin(); at != simTypes_.end(); ++at) { if ((*at)->isEAM()) addType(*at); } // find all of the explicit EAM interactions (setfl): ForceField::NonBondedInteractionTypeContainer* nbiTypes = forceField_->getNonBondedInteractionTypes(); ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j; NonBondedInteractionType* nbt; for (nbt = nbiTypes->beginType(j); nbt != NULL; nbt = nbiTypes->nextType(j)) { if (nbt->isEAM()) { pair<AtomType*, AtomType*> atypes = nbt->getAtomTypes(); GenericData* data = nbt->getPropertyByName("EAM"); if (data == NULL) { sprintf( painCave.errMsg, "EAM::rebuildMixingMap could not find\n" "\tEAM parameters for %s - %s interaction.\n", atypes.first->getName().c_str(), atypes.second->getName().c_str()); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } EAMMixingData* eamData = dynamic_cast<EAMMixingData*>(data); if (eamData == NULL) { sprintf( painCave.errMsg, "EAM::rebuildMixingMap could not convert GenericData to\n" "\tEAMMixingData for %s - %s interaction.\n", atypes.first->getName().c_str(), atypes.second->getName().c_str()); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } EAMMixingParam eamParam = eamData->getData(); vector<RealType> phiAB = eamParam.phi; RealType dr = eamParam.dr; int nr = eamParam.nr; addExplicitInteraction(atypes.first, atypes.second, dr, nr, phiAB); } } initialized_ = true; }
void EAM::calcForce(InteractionData &idat) { if (!initialized_) initialize(); if (haveCutoffRadius_) if ( *(idat.rij) > eamRcut_) return; int eamtid1 = EAMtids[idat.atid1]; int eamtid2 = EAMtids[idat.atid2]; EAMAtomData &data1 = EAMdata[eamtid1]; EAMAtomData &data2 = EAMdata[eamtid2]; // get type-specific cutoff radii RealType rci = data1.rcut; RealType rcj = data2.rcut; RealType rha(0.0), drha(0.0), rhb(0.0), drhb(0.0); RealType pha(0.0), dpha(0.0), phb(0.0), dphb(0.0); RealType phab(0.0), dvpdr(0.0); RealType drhoidr, drhojdr, dudr; if ( *(idat.rij) < rci) { data1.rho->getValueAndDerivativeAt( *(idat.rij), rha, drha); CubicSpline* phi = MixingMap[eamtid1][eamtid1].phi; phi->getValueAndDerivativeAt( *(idat.rij), pha, dpha); } if ( *(idat.rij) < rcj) { data2.rho->getValueAndDerivativeAt( *(idat.rij), rhb, drhb ); CubicSpline* phi = MixingMap[eamtid2][eamtid2].phi; phi->getValueAndDerivativeAt( *(idat.rij), phb, dphb); } switch(mixMeth_) { case eamJohnson: if ( *(idat.rij) < rci) { phab = phab + 0.5 * (rhb / rha) * pha; dvpdr = dvpdr + 0.5*((rhb/rha)*dpha + pha*((drhb/rha) - (rhb*drha/rha/rha))); } if ( *(idat.rij) < rcj) { phab = phab + 0.5 * (rha / rhb) * phb; dvpdr = dvpdr + 0.5 * ((rha/rhb)*dphb + phb*((drha/rhb) - (rha*drhb/rhb/rhb))); } break; case eamDaw: if ( *(idat.rij) < MixingMap[eamtid1][eamtid2].rcut) { MixingMap[eamtid1][eamtid2].phi->getValueAndDerivativeAt( *(idat.rij), phab, dvpdr); } break; case eamUnknown: default: sprintf(painCave.errMsg, "EAM::calcForce hit a mixing method it doesn't know about!\n" ); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } drhoidr = drha; drhojdr = drhb; dudr = drhojdr* *(idat.dfrho1) + drhoidr* *(idat.dfrho2) + dvpdr; *(idat.f1) += *(idat.d) * dudr / *(idat.rij); if (idat.doParticlePot) { // particlePot is the difference between the full potential and // the full potential without the presence of a particular // particle (atom1). // // This reduces the density at other particle locations, so we // need to recompute the density at atom2 assuming atom1 didn't // contribute. This then requires recomputing the density // functional for atom2 as well. *(idat.particlePot1) += data2.F->getValueAt( *(idat.rho2) - rha ) - *(idat.frho2); *(idat.particlePot2) += data1.F->getValueAt( *(idat.rho1) - rhb) - *(idat.frho1); } (*(idat.pot))[METALLIC_FAMILY] += phab; *(idat.vpair) += phab; return; }
void ElementsTable::Init() { if (init_) return; init_ = true; std::string buffer, subbuffer; ifstrstream ifs1, ifs2, ifs3, ifs4, *ifsP; // First, look for an environment variable if (getenv(envvar_.c_str()) != NULL) { buffer = getenv(envvar_.c_str()); buffer += FILE_SEP_CHAR; if (!subdir_.empty()) { subbuffer = buffer; subbuffer += subdir_; subbuffer += FILE_SEP_CHAR; } buffer += filename_; subbuffer += filename_; ifs1.open(subbuffer.c_str()); ifsP= &ifs1; if (!(ifsP->is_open())) { ifs2.open(buffer.c_str()); ifsP = &ifs2; } } else { sprintf( painCave.errMsg, "ElementsTable error.\n" "\tunable to open datafile %s \n", filename_.c_str()); painCave.isFatal = 0; simError(); } if ((*ifsP)) { char charBuffer[BUFF_SIZE]; while(ifsP->getline(charBuffer,BUFF_SIZE)) ParseLine(charBuffer); if (ifs1) ifs1.close(); if (ifs2) ifs2.close(); if (ifs3) ifs3.close(); if (ifs4) ifs4.close(); if (GetSize() == 0) { sprintf( painCave.errMsg, "ElementsTable error.\n" "\tCannot initialize database %s \n", filename_.c_str()); painCave.isFatal = 0; simError(); } } }
void P2OrderParameter::process() { Molecule* mol; RigidBody* rb; SimInfo::MoleculeIterator mi; Molecule::RigidBodyIterator rbIter; StuntDouble* sd1; StuntDouble* sd2; int ii; int jj; int vecCount; bool usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions(); DumpReader reader(info_, dumpFilename_); int nFrames = reader.getNFrames(); for (int i = 0; i < nFrames; i += step_) { reader.readFrame(i); currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot(); for (mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) { //change the positions of atoms which belong to the rigidbodies for (rb = mol->beginRigidBody(rbIter); rb != NULL; rb = mol->nextRigidBody(rbIter)) { rb->updateAtoms(); } } Mat3x3d orderTensor(0.0); vecCount = 0; seleMan1_.setSelectionSet(evaluator1_.evaluate()); if (doVect_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { if (sd1->isDirectional()) { Vector3d vec = sd1->getA().transpose()*V3Z; vec.normalize(); orderTensor += outProduct(vec, vec); vecCount++; } } orderTensor /= vecCount; } else { if (doOffset_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { // This will require careful rewriting if StaticProps is // ever parallelized. For an example, see // Thermo::getTaggedAtomPairDistance int sd2Index = sd1->getGlobalIndex() + seleOffset_; sd2 = info_->getIOIndexToIntegrableObject(sd2Index); Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); orderTensor +=outProduct(vec, vec); vecCount++; } orderTensor /= vecCount; } else { seleMan2_.setSelectionSet(evaluator2_.evaluate()); if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount() ) { sprintf( painCave.errMsg, "In frame %d, the number of selected StuntDoubles are\n" "\tnot the same in --sele1 and sele2\n", i); painCave.severity = OPENMD_INFO; painCave.isFatal = 0; simError(); } for (sd1 = seleMan1_.beginSelected(ii), sd2 = seleMan2_.beginSelected(jj); sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii), sd2 = seleMan2_.nextSelected(jj)) { Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); orderTensor +=outProduct(vec, vec); vecCount++; } orderTensor /= vecCount; } } if (vecCount == 0) { sprintf( painCave.errMsg, "In frame %d, the number of selected vectors was zero.\n" "\tThis will not give a meaningful order parameter.", i); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } orderTensor -= (RealType)(1.0/3.0) * Mat3x3d::identity(); Vector3d eigenvalues; Mat3x3d eigenvectors; Mat3x3d::diagonalize(orderTensor, eigenvalues, eigenvectors); int which(-1); RealType maxEval = 0.0; for(int k = 0; k< 3; k++) { if(fabs(eigenvalues[k]) > maxEval) { which = k; maxEval = fabs(eigenvalues[k]); } } RealType p2 = 1.5 * maxEval; //the eigen vector is already normalized in SquareMatrix3::diagonalize Vector3d director = eigenvectors.getColumn(which); if (director[0] < 0) { director.negate(); } RealType angle = 0.0; vecCount = 0; if (doVect_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { if (sd1->isDirectional()) { Vector3d vec = sd1->getA().transpose()*V3Z; vec.normalize(); angle += acos(dot(vec, director)); vecCount++; } } angle = angle/(vecCount*NumericConstant::PI)*180.0; } else { if (doOffset_) { for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL; sd1 = seleMan1_.nextSelected(ii)) { // This will require careful rewriting if StaticProps is // ever parallelized. For an example, see // Thermo::getTaggedAtomPairDistance int sd2Index = sd1->getGlobalIndex() + seleOffset_; sd2 = info_->getIOIndexToIntegrableObject(sd2Index); Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); angle += acos(dot(vec, director)) ; vecCount++; } angle = angle / (vecCount * NumericConstant::PI) * 180.0; } else { for (sd1 = seleMan1_.beginSelected(ii), sd2 = seleMan2_.beginSelected(jj); sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii), sd2 = seleMan2_.nextSelected(jj)) { Vector3d vec = sd1->getPos() - sd2->getPos(); if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(vec); vec.normalize(); angle += acos(dot(vec, director)) ; vecCount++; } angle = angle / (vecCount * NumericConstant::PI) * 180.0; } } OrderParam param; param.p2 = p2; param.director = director; param.angle = angle; orderParams_.push_back(param); } writeP2(); }
void EAM::addType(AtomType* atomType){ EAMAdapter ea = EAMAdapter(atomType); EAMAtomData eamAtomData; eamAtomData.rho = ea.getRho(); eamAtomData.F = ea.getF(); eamAtomData.Z = ea.getZ(); eamAtomData.rcut = ea.getRcut(); FluctuatingChargeAdapter fqa = FluctuatingChargeAdapter(atomType); if (fqa.isFluctuatingCharge()) { if (fqa.isMetallic()) { eamAtomData.isFluctuatingCharge = true; eamAtomData.nValence = fqa.getNValence(); } else { eamAtomData.isFluctuatingCharge = false; } } // add it to the map: int atid = atomType->getIdent(); int eamtid = EAMtypes.size(); pair<set<int>::iterator,bool> ret; ret = EAMtypes.insert( atid ); if (ret.second == false) { sprintf( painCave.errMsg, "EAM already had a previous entry with ident %d\n", atid); painCave.severity = OPENMD_INFO; painCave.isFatal = 0; simError(); } EAMtids[atid] = eamtid; EAMdata[eamtid] = eamAtomData; MixingMap[eamtid].resize(nEAM_); // Now, iterate over all known types and add to the mixing map: std::set<int>::iterator it; for( it = EAMtypes.begin(); it != EAMtypes.end(); ++it) { int eamtid2 = EAMtids[ (*it) ]; AtomType* atype2 = forceField_->getAtomType( (*it) ); EAMInteractionData mixer; mixer.phi = getPhi(atomType, atype2); mixer.rcut = mixer.phi->getLimits().second; mixer.explicitlySet = false; MixingMap[eamtid2].resize( nEAM_ ); MixingMap[eamtid][eamtid2] = mixer; if (eamtid2 != eamtid) { MixingMap[eamtid2][eamtid] = mixer; } } return; }