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 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(); // 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; }