ScalarField Real(const complexScalarField& C) { const GridInfo& gInfo = C->gInfo; ScalarField R; nullToZero(R, gInfo); callPref(eblas_daxpy)(gInfo.nr, C->scale, (const double*)C->dataPref(false), 2, R->dataPref(false), 1); R->scale = 1; return R; }
void Dump::dumpRsol(ScalarField nbound, string fname) { //Compute normalization factor for the partition: int nAtomsTot = 0; for(const auto& sp: e->iInfo.species) nAtomsTot += sp->atpos.size(); const double nFloor = 1e-5/nAtomsTot; //lower cap on densities to prevent Nyquist noise in low density regions ScalarField nAtomicTot; for(const auto& sp: e->iInfo.species) { RadialFunctionG nRadial; logSuspend(); sp->getAtom_nRadial(0,0, nRadial, true); logResume(); for(unsigned atom=0; atom<sp->atpos.size(); atom++) { ScalarField nAtomic = radialFunction(e->gInfo, nRadial, sp->atpos[atom]); double nMin, nMax; callPref(eblas_capMinMax)(e->gInfo.nr, nAtomic->dataPref(), nMin, nMax, nFloor); nAtomicTot += nAtomic; } } ScalarField nboundByAtomic = (nbound*nbound) * inv(nAtomicTot); ScalarField rInv0(ScalarFieldData::alloc(e->gInfo)); { logSuspend(); WignerSeitz ws(e->gInfo.R); logResume(); threadLaunch(set_rInv, e->gInfo.nr, e->gInfo.S, e->gInfo.RTR, &ws, rInv0->data()); } //Compute bound charge 1/r and 1/r^2 expectation values weighted by atom-density partition: FILE* fp = fopen(fname.c_str(), "w"); fprintf(fp, "#Species rMean +/- rSigma [bohrs] (rMean +/- rSigma [Angstrom]) sqrt(Int|nbound^2|) in partition\n"); for(const auto& sp: e->iInfo.species) { RadialFunctionG nRadial; logSuspend(); sp->getAtom_nRadial(0,0, nRadial, true); logResume(); for(unsigned atom=0; atom<sp->atpos.size(); atom++) { ScalarField w = radialFunction(e->gInfo, nRadial, sp->atpos[atom]) * nboundByAtomic; //Get r centered at current atom: ScalarFieldTilde trans; nullToZero(trans, e->gInfo); initTranslation(trans, e->gInfo.R*sp->atpos[atom]); ScalarField rInv = I(trans * J(rInv0), true); //Compute moments: double wNorm = integral(w); double rInvMean = integral(w * rInv) / wNorm; double rInvSqMean = integral(w * rInv * rInv) / wNorm; double rInvSigma = sqrt(rInvSqMean - rInvMean*rInvMean); double rMean = 1./rInvMean; double rSigma = rInvSigma / (rInvMean*rInvMean); //Print stats: fprintf(fp, "Rsol %s %.2lf +/- %.2lf ( %.2lf +/- %.2lf A ) Qrms: %.1le\n", sp->name.c_str(), rMean, rSigma, rMean/Angstrom, rSigma/Angstrom, sqrt(wNorm)); } } fclose(fp); }
double Fex_ScalarEOS::compute(const ScalarFieldTilde* Ntilde, ScalarFieldTilde* Phi_Ntilde) const { //Polarizability-averaged density: double alphaTot = 0.; ScalarFieldTilde NavgTilde; for(unsigned i=0; i<molecule.sites.size(); i++) { const Molecule::Site& s = *(molecule.sites[i]); NavgTilde += s.alpha * Ntilde[i]; alphaTot += s.alpha * s.positions.size(); } NavgTilde *= (1./alphaTot); //Compute LJatt weighted density: ScalarField Nbar = I(fex_LJatt*NavgTilde); //Evaluated weighted density functional: ScalarField Aex, Aex_Nbar; nullToZero(Aex, gInfo); nullToZero(Aex_Nbar, gInfo); callPref(eos.evaluate)(gInfo.nr, Nbar->dataPref(), Aex->dataPref(), Aex_Nbar->dataPref(), Vhs); //Convert gradients: ScalarField Navg = I(NavgTilde); ScalarFieldTilde IdagAex = Idag(Aex); for(unsigned i=0; i<molecule.sites.size(); i++) { const Molecule::Site& s = *(molecule.sites[i]); Phi_Ntilde[i] += (fex_LJatt*Idag(Navg*Aex_Nbar) + IdagAex) * (s.alpha/alphaTot); } return gInfo.dV*dot(Navg,Aex); }