void SC::addExplicitInteraction(AtomType* atype1, AtomType* atype2, RealType epsilon, RealType m, RealType n, RealType alpha) { // in case these weren't already in the map addType(atype1); addType(atype2); SCInteractionData mixer; mixer.epsilon = epsilon; mixer.m = m; mixer.n = n; mixer.alpha = alpha; mixer.rCut = 2.0 * mixer.alpha; 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 = true; int sctid1 = SCtids[ atype1->getIdent() ]; int sctid2 = SCtids[ atype2->getIdent() ]; MixingMap[sctid1][sctid2] = mixer; if (sctid2 != sctid1) { MixingMap[sctid2][sctid1] = mixer; } return; }
void EAM::addExplicitInteraction(AtomType* atype1, AtomType* atype2, RealType dr, int nr, vector<RealType> phiVals) { // in case these weren't already in the map addType(atype1); addType(atype2); EAMInteractionData mixer; CubicSpline* cs = new CubicSpline(); vector<RealType> rVals; for (int i = 0; i < nr; i++) rVals.push_back(i * dr); cs->addPoints(rVals, phiVals); mixer.phi = cs; mixer.rcut = mixer.phi->getLimits().second; mixer.explicitlySet = true; int eamtid1 = EAMtids[ atype1->getIdent() ]; int eamtid2 = EAMtids[ atype2->getIdent() ]; MixingMap[eamtid1][eamtid2] = mixer; if (eamtid2 != eamtid1) { MixingMap[eamtid2][eamtid1] = mixer; } return; }
CubicSpline* EAM::getPhi(AtomType* atomType1, AtomType* atomType2) { EAMAdapter ea1 = EAMAdapter(atomType1); EAMAdapter ea2 = EAMAdapter(atomType2); CubicSpline* z1 = ea1.getZ(); CubicSpline* z2 = ea2.getZ(); // Thise prefactors convert the charge-charge interactions into // kcal / mol all were computed assuming distances are measured in // angstroms Charge-Charge, assuming charges are measured in // electrons. Matches value in Electrostatics.cpp pre11_ = 332.0637778; // make the r grid: // we need phi out to the largest value we'll encounter in the radial space; RealType rmax = 0.0; rmax = max(rmax, ea1.getRcut()); rmax = max(rmax, ea1.getNr() * ea1.getDr()); rmax = max(rmax, ea2.getRcut()); rmax = max(rmax, ea2.getNr() * ea2.getDr()); // use the smallest dr (finest grid) to build our grid: RealType dr = min(ea1.getDr(), ea2.getDr()); int nr = int(rmax/dr + 0.5); vector<RealType> rvals; for (int i = 0; i < nr; i++) rvals.push_back(RealType(i*dr)); // construct the pair potential: vector<RealType> phivals; RealType phi; RealType r; RealType zi, zj; phivals.push_back(0.0); for (unsigned int i = 1; i < rvals.size(); i++ ) { r = rvals[i]; // only use z(r) if we're inside this atom's cutoff radius, // otherwise, we'll use zero for the charge. This effectively // means that our phi grid goes out beyond the cutoff of the // pair potential zi = r <= ea1.getRcut() ? z1->getValueAt(r) : 0.0; zj = r <= ea2.getRcut() ? z2->getValueAt(r) : 0.0; phi = pre11_ * (zi * zj) / r; phivals.push_back(phi); } CubicSpline* cs = new CubicSpline(); cs->addPoints(rvals, phivals); return cs; }
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; }