double Fex_H2O_FittedCorrelations::compute(const ScalarFieldTilde* Ntilde, ScalarFieldTilde* Phi_Ntilde) const { double PhiEx = 0.0; //Quadratic part: ScalarFieldTilde V_O = double(gInfo.nr)*(COO*Ntilde[0] + COH*Ntilde[1]); Phi_Ntilde[0] += V_O; ScalarFieldTilde V_H = double(gInfo.nr)*(COH*Ntilde[0] + CHH*Ntilde[1]); Phi_Ntilde[1] += V_H; PhiEx += 0.5*gInfo.dV*(dot(V_O,Ntilde[0]) + dot(V_H,Ntilde[1])); //Compute gaussian weighted densities: ScalarField NObar = I(fex_gauss*Ntilde[0]), Phi_NObar; nullToZero(Phi_NObar, gInfo); ScalarField NHbar = I(fex_gauss*Ntilde[1]), Phi_NHbar; nullToZero(Phi_NHbar, gInfo); //Evaluated weighted density functional: #ifdef GPU_ENABLED ScalarField fex(ScalarFieldData::alloc(gInfo,isGpuEnabled())); Fex_H20_FittedCorrelations_gpu(gInfo.nr, NObar->dataGpu(), NHbar->dataGpu(), fex->dataGpu(), Phi_NObar->dataGpu(), Phi_NHbar->dataGpu()); PhiEx += integral(fex); #else PhiEx += gInfo.dV*threadedAccumulate(Fex_H2O_FittedCorrelations_calc, gInfo.nr, NObar->data(), NHbar->data(), Phi_NObar->data(), Phi_NHbar->data()); #endif //Convert gradients: Phi_Ntilde[0] += fex_gauss*Idag(Phi_NObar); Phi_Ntilde[1] += fex_gauss*Idag(Phi_NHbar); return PhiEx; }
ConvolutionJDFT(const Everything& e, const FluidSolverParams& fsp) : FluidSolver(e, fsp), Adiel_rhoExplicitTilde(0) { //Initialize fluid mixture: fluidMixture = new FluidMixtureJDFT(e, gInfo, fsp.T); fluidMixture->verboseLog = fsp.verboseLog; //Add the fluid components: for(const auto& c: fsp.components) c->addToFluidMixture(fluidMixture); if(fsp.FmixList.size()) { //create fluid mixtures logPrintf("\n------------ Fluid Mixing Functionals ------------\n"); for(const auto& f: fsp.FmixList) { std::shared_ptr<FluidComponent> c1 = f.fluid1; string name1 = c1->molecule.name; std::shared_ptr<FluidComponent> c2 = f.fluid2; string name2 = c2->molecule.name; std::shared_ptr<Fmix> Fmix; if (f.FmixType == GaussianKernel) Fmix = std::make_shared<Fmix_GaussianKernel>(fluidMixture,c1,c2,f.energyScale,f.lengthScale); else if (f.FmixType == LJPotential) Fmix = std::make_shared<Fmix_LJ>(fluidMixture,c1,c2,f.energyScale,f.lengthScale); else die("Valid mixing functional between %s and %s not specified!\n",name1.c_str(),name2.c_str()); FmixPtr.push_back(Fmix); } } fluidMixture->initialize(fsp.P, epsBulk, epsInf); //set fluid exCorr logPrintf("\n------- Fluid Exchange Correlation functional -------\n"); ((ExCorr&)fsp.exCorr).setup(e); //Initialize coupling: coupling = std::make_shared<ConvCoupling>(fluidMixture, fsp.exCorr); //Create van der Waals mixing functional myassert(e.vanDerWaals); vdwCoupling = std::make_shared<VDWCoupling>(fluidMixture, atpos, e.vanDerWaals, e.vanDerWaals->getScaleFactor(fsp.exCorr.getName(), fsp.vdwScale)); //---- G=0 constraints ----- //Electron density in the bulk of the fluid double nFl_bulk = 0.0; for(const auto& c: fsp.components) { for(unsigned i=0; i<c->molecule.sites.size(); i++) { const Molecule::Site& s = *(c->molecule.sites[i]); nFl_bulk += c->idealGas->get_Nbulk()*s.elecKernel(0)*s.positions.size(); } } logPrintf("\nBulk electron density of the liquid: %le bohr^-3\n",nFl_bulk); //calculate G=0 offset due to coupling functional evaluated at bulk fluid density ScalarField nBulk; nullToZero(nBulk,e.gInfo); //initialize constant ScalarField with density nFl_bulk for (int i=0; i<e.gInfo.nr; i++) nBulk->data()[i] = nFl_bulk; ScalarField Vxc_bulk; (coupling->exCorr)(nBulk, &Vxc_bulk, true); logPrintf("Electron deep in fluid experiences coupling potential: %lg H\n\n", Vxc_bulk->data()[0]); coupling->Vxc_bulk = Vxc_bulk->data()[0]; }