31 const std::string& objectName,
36 int ncenter = info.
rows();
37 app_log() <<
"Reading cusp info from : " << cuspInfoFile << std::endl;
39 if (!adoc.
parse(cuspInfoFile))
41 app_log() <<
"Could not find precomputed cusp data for spo set: " << objectName << std::endl;
42 app_log() <<
"Recalculating data.\n";
45 xmlNodePtr head = adoc.
getRoot();
46 head = head->children;
47 xmlNodePtr cur = NULL, ctr;
51 if (cname ==
"sposet")
55 spoAttrib.
add(name,
"name");
57 if (name == objectName)
67 app_log() <<
"Could not find precomputed cusp data for spo set: " << objectName << std::endl;
68 app_log() <<
"Recalculating data.\n";
73 app_log() <<
"Found precomputed cusp data for spo set: " << objectName << std::endl;
79 if (cname ==
"center")
83 Attrib.
add(num,
"num");
85 if (num < 0 || num >= ncenter)
87 APP_ABORT(
"Error with cusp info xml block. incorrect center number. \n");
93 if (cname ==
"orbital")
98 orbAttrib.
add(orb,
"num");
99 orbAttrib.
add(a1,
"redo");
100 orbAttrib.
add(a2,
"C");
101 orbAttrib.
add(a3,
"sg");
102 orbAttrib.
add(a4,
"rc");
103 orbAttrib.
add(a5,
"a1");
104 orbAttrib.
add(a6,
"a2");
105 orbAttrib.
add(a7,
"a3");
106 orbAttrib.
add(a8,
"a4");
107 orbAttrib.
add(a9,
"a5");
109 if (orb < OrbitalSetSize)
111 info(num, orb).redo = a1;
112 info(num, orb).C = a2;
113 info(num, orb).sg = a3;
114 info(num, orb).Rc = a4;
115 info(num, orb).alpha[0] = a5;
116 info(num, orb).alpha[1] = a6;
117 info(num, orb).alpha[2] = a7;
118 info(num, orb).alpha[3] = a8;
119 info(num, orb).alpha[4] = a9;
132 const int num_centers = info.
rows();
133 const int orbital_set_size = info.
cols();
134 xmlDocPtr
doc = xmlNewDoc((
const xmlChar*)
"1.0");
135 xmlNodePtr cuspRoot = xmlNewNode(NULL, BAD_CAST
"qmcsystem");
136 xmlNodePtr spo = xmlNewNode(NULL, (
const xmlChar*)
"sposet");
137 xmlNewProp(spo, (
const xmlChar*)
"name", (
const xmlChar*)
id.c_str());
138 xmlAddChild(cuspRoot, spo);
139 xmlDocSetRootElement(
doc, cuspRoot);
141 for (
int center_idx = 0; center_idx < num_centers; center_idx++)
143 xmlNodePtr ctr = xmlNewNode(NULL, (
const xmlChar*)
"center");
144 std::ostringstream num;
146 xmlNewProp(ctr, (
const xmlChar*)
"num", (
const xmlChar*)num.str().c_str());
148 for (
int mo_idx = 0; mo_idx < orbital_set_size; mo_idx++)
150 std::ostringstream num0,
C, sg, rc, a1, a2, a3, a4, a5;
151 xmlNodePtr orb = xmlNewNode(NULL, (
const xmlChar*)
"orbital");
153 xmlNewProp(orb, (
const xmlChar*)
"num", (
const xmlChar*)num0.str().c_str());
156 C.setf(std::ios::scientific, std::ios::floatfield);
158 C << info(center_idx, mo_idx).C;
159 sg.setf(std::ios::scientific, std::ios::floatfield);
161 sg << info(center_idx, mo_idx).sg;
162 rc.setf(std::ios::scientific, std::ios::floatfield);
164 rc << info(center_idx, mo_idx).Rc;
165 a1.setf(std::ios::scientific, std::ios::floatfield);
167 a1 << info(center_idx, mo_idx).alpha[0];
168 a2.setf(std::ios::scientific, std::ios::floatfield);
170 a2 << info(center_idx, mo_idx).alpha[1];
171 a3.setf(std::ios::scientific, std::ios::floatfield);
173 a3 << info(center_idx, mo_idx).alpha[2];
174 a4.setf(std::ios::scientific, std::ios::floatfield);
176 a4 << info(center_idx, mo_idx).alpha[3];
177 a5.setf(std::ios::scientific, std::ios::floatfield);
179 a5 << info(center_idx, mo_idx).alpha[4];
180 xmlNewProp(orb, (
const xmlChar*)
"C", (
const xmlChar*)
C.str().c_str());
181 xmlNewProp(orb, (
const xmlChar*)
"sg", (
const xmlChar*)sg.str().c_str());
182 xmlNewProp(orb, (
const xmlChar*)
"rc", (
const xmlChar*)rc.str().c_str());
183 xmlNewProp(orb, (
const xmlChar*)
"a1", (
const xmlChar*)a1.str().c_str());
184 xmlNewProp(orb, (
const xmlChar*)
"a2", (
const xmlChar*)a2.str().c_str());
185 xmlNewProp(orb, (
const xmlChar*)
"a3", (
const xmlChar*)a3.str().c_str());
186 xmlNewProp(orb, (
const xmlChar*)
"a4", (
const xmlChar*)a4.str().c_str());
187 xmlNewProp(orb, (
const xmlChar*)
"a5", (
const xmlChar*)a5.str().c_str());
188 xmlAddChild(ctr, orb);
190 xmlAddChild(spo, ctr);
193 app_log() <<
"Saving resulting cusp Info xml block to: " << filename << std::endl;
194 xmlSaveFormatFile(filename.c_str(),
doc, 1);
201 std::vector<double> buffer(9);
202 buffer[0] = param.
Rc;
204 buffer[2] = param.
sg;
205 buffer[3] = param.
alpha[0];
206 buffer[4] = param.
alpha[1];
207 buffer[5] = param.
alpha[2];
208 buffer[6] = param.
alpha[3];
209 buffer[7] = param.
alpha[4];
210 buffer[8] = param.
redo;
212 Comm.comm.broadcast(buffer.begin(), buffer.end(), root);
214 param.
Rc = buffer[0];
216 param.
sg = buffer[2];
217 param.
alpha[0] = buffer[3];
218 param.
alpha[1] = buffer[4];
219 param.
alpha[2] = buffer[5];
220 param.
alpha[3] = buffer[6];
221 param.
alpha[4] = buffer[7];
222 param.
redo = buffer[8] == 0.0 ? 0 : 1;
230 std::vector<bool> is_s_orbital(Phi.
myBasisSet->BasisSetSize,
false);
231 std::vector<bool> correct_this_center(corrCenter.size(),
false);
232 correct_this_center[center] = corrCenter[center];
234 Phi.
myBasisSet->queryOrbitalsForSType(correct_this_center, is_s_orbital);
239 for (
int i = 0; i < bss; i++)
243 auto& cref(*(Eta.
C));
244 for (
int k = 0; k < nOrbs; k++)
249 auto& cref(*(Phi.
C));
250 for (
int k = 0; k < nOrbs; k++)
260 std::vector<bool> is_s_orbital(Phi.
myBasisSet->BasisSetSize,
false);
262 Phi.
myBasisSet->queryOrbitalsForSType(corrCenter, is_s_orbital);
267 for (
int i = 0; i < bss; i++)
271 auto& cref(*(Phi.
C));
272 for (
int k = 0; k < nOrbs; k++)
293 for (
int i = 0; i < xgrid.
size(); i++)
295 rad_orb[i] =
phiBar(cusp, xgrid[i], phiMO);
305 RealType beta[7] = {3.25819, -15.0126, 33.7308, -42.8705, 31.2276, -12.1316, 1.94692};
308 for (
int i = 0; i < 7; i++)
310 idealEL += beta[i] * r1;
313 return idealEL * Z * Z;
322 beta0 = (ELorigAtRc - tmp) / (Z * Z);
323 for (
int i = 0; i < pos.size(); i++)
341 X[1] = gradRc[0] / (valRc -
C);
342 X[2] = (lapRc - 2.0 * gradRc[0] / Rc) / (valRc -
C);
343 X[3] = -Z * (valAtZero + eta0) / (valAtZero -
C);
350 RealType RcInv = 1.0 / Rc, RcInv2 = RcInv * RcInv;
353 alpha[2] = 6.0 * X[0] * RcInv2 - 3.0 * X[1] * RcInv + X[2] * 0.5 - 3.0 * X[3] * RcInv - 6.0 * X[4] * RcInv2 -
355 alpha[3] = -8.0 * X[0] * RcInv2 * RcInv + 5.0 * X[1] * RcInv2 - X[2] * RcInv + 3.0 * X[3] * RcInv2 +
356 8.0 * X[4] * RcInv2 * RcInv + X[1] * X[1] * RcInv;
357 alpha[4] = 3.0 * X[0] * RcInv2 * RcInv2 - 2.0 * X[1] * RcInv2 * RcInv + 0.5 * X[2] * RcInv2 - X[3] * RcInv2 * RcInv -
358 3.0 * X[4] * RcInv2 * RcInv2 - 0.5 * X[1] * X[1] * RcInv2;
386 phiMO.
phi_vgl(Rc, val, grad, lap);
387 RealType dE = originalELatRc - (-0.5 * lap / val - Zeff / Rc);
388 for (
int i = 0; i < pos.size(); i++)
396 ELcurr[i] = -0.5 * cusp.
Rr(r) * (2.0 * dp / r + cusp.
d2pr(r) + dp * dp) / (offset +
phiBar(cusp, r, phiMO)) -
401 phiMO.
phi_vgl(pos[i], val, grad, lap);
402 ELcurr[i] = -0.5 * lap / val - Zeff / r + dE;
419 for (
int i = 0; i < pos.size(); i++)
422 phiMO.
phi_vgl(r, val, grad, lap);
423 ELorig[i] = -0.5 * lap / val - Zeff / r;
426 phiMO.
phi_vgl(Rc, val, grad, lap);
427 return -0.5 * lap / val - Zeff / Rc;
434 assert(ELcurr.size() == ELideal.size());
437 for (
int i = 0; i < ELcurr.size(); i++)
439 RealType diff = ELcurr[i] - ELideal[i];
464 cusp.
cparam.
sg = phi0 > 0.0 ? 1.0 : -1.0;
465 cusp.
cparam.
C = (phiAtRc.
val * phi0 < 0.0) ? 1.5 * phiAtRc.
val : 0.0;
500 return evaluateForPhi0Body(x, pos, ELcurr, ELideal, cusp, phiMO, vglAtRc, eta0, ELorigAtRc, Z);
504 catch (
const std::runtime_error&
e)
506 APP_ABORT(
"Bracketing minimum failed for finding phi0. \n");
511 return evaluateForPhi0Body(x, pos, ELcurr, ELideal, cusp, phiMO, vglAtRc, eta0, ELorigAtRc, Z);
515 start_phi0 = min_res.first;
517 return min_res.second;
545 catch (
const std::runtime_error&
e)
547 APP_ABORT(
"Bracketing minimum failed for finding rc. \n");
573 const std::string&
id)
575 const int num_centers = info.
rows();
576 const int orbital_set_size = info.
cols();
589 std::vector<bool> corrCenter(num_centers,
"true");
592 auto radial_grid = std::make_unique<LogGrid<RealType>>();
593 radial_grid->set(0.000001, 100.0, 1001);
598 xgrid.
resize(radial_grid->size());
599 rad_orb.
resize(radial_grid->size());
600 for (
int ig = 0; ig < radial_grid->size(); ig++)
602 xgrid[ig] = radial_grid->r(ig);
605 for (
int ic = 0; ic < num_centers; ic++)
614 auto cot = std::make_unique<CuspCorrectionAtomicBasis<RealType>>();
615 cot->initializeRadialSet(*radial_grid, orbital_set_size);
622 for (
int mo_idx = 0; mo_idx < orbital_set_size; mo_idx++)
624 computeRadialPhiBar(&targetPtcl, &sourcePtcl, mo_idx, ic, &phi, xgrid, rad_orb, info(ic, mo_idx));
625 RealType yprime_i = (rad_orb[1] - rad_orb[0]) / (radial_grid->r(1) - radial_grid->r(0));
627 radial_spline.
spline(0, yprime_i, rad_orb.
size() - 1, 0.0);
628 cot->addSpline(mo_idx, radial_spline);
635 RealType dx = info(ic, mo_idx).Rc * 1.2 / nElms;
640 for (
int i = 0; i < nElms; i++)
642 pos[i] = (i + 1.0) * dx;
644 computeRadialPhiBar(&targetPtcl, &sourcePtcl, mo_idx, ic, &phi, pos, output_orb, info(ic, mo_idx));
645 std::string filename =
"soaOrbs." +
id +
".C" + std::to_string(ic) +
".MO" + std::to_string(mo_idx);
646 std::cout <<
"Writing to " << filename << std::endl;
647 std::ofstream out(filename.c_str());
648 out <<
"# r phiBar(r)" << std::endl;
649 for (
int i = 0; i < nElms; i++)
651 out << pos[i] <<
" " << output_orb[i] << std::endl;
656 cusp.
add(ic, std::move(cot));
665 const std::string&
id,
668 const int num_centers = info.
rows();
669 const int orbital_set_size = info.
cols();
676 ScopedTimer createCuspTimerWrapper(cuspCreateTimer);
684 std::vector<bool> corrCenter(num_centers,
"true");
690 std::vector<int> offset;
693 int start_mo = offset[Comm.
rank()];
694 int end_mo = offset[Comm.
rank() + 1];
695 app_log() <<
" Number of molecular orbitals to compute correction on this rank: " << end_mo - start_mo << std::endl;
699 #pragma omp parallel for schedule(dynamic) collapse(2) 700 for (
int center_idx = 0; center_idx < num_centers; center_idx++)
702 for (
int mo_idx = start_mo; mo_idx < end_mo; mo_idx++)
707 LCAOrbitalSet local_phi(
"local_phi", std::unique_ptr<LCAOrbitalSet::basis_type>(phi.myBasisSet->makeClone()),
708 phi.getOrbitalSetSize(), phi.isIdentity(), phi.isOMPoffload());
710 LCAOrbitalSet local_eta(
"local_eta", std::unique_ptr<LCAOrbitalSet::basis_type>(eta.myBasisSet->makeClone()),
711 eta.getOrbitalSetSize(), eta.isIdentity(), eta.isOMPoffload());
714 app_log() <<
" Working on MO: " << mo_idx <<
" Center: " << center_idx << std::endl;
719 *local_eta.C = *lcao.
C;
720 *local_phi.C = *lcao.
C;
721 splitPhiEta(center_idx, corrCenter, local_phi, local_eta);
725 auto& cref(*(local_phi.C));
726 for (
int ip = 0; ip < cref.cols(); ip++)
754 for (
int i = 0; i < npts; i++)
756 pos[i] = (i + 1.0) * dx;
764 minimizeForRc(cusp, phiMO, Z, rc, Rc_max, eta0, pos, ELcurr, ELideal);
769 info(center_idx, mo_idx) = cusp.
cparam;
774 for (
int root = 0; root < Comm.
size(); root++)
776 int start_mo = offset[root];
777 int end_mo = offset[root + 1];
778 for (
int mo_idx = start_mo; mo_idx < end_mo; mo_idx++)
780 for (
int center_idx = 0; center_idx < num_centers; center_idx++)
base class for Single-particle orbital sets
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Convert CorrectingOrbitalBasisSet using MultiQuinticSpline1D<T>
class that handles xmlDoc
TinyVector< ValueType, 5 > alpha
The coefficients of the polynomial in Eq 8.
One-Dimensional linear-grid.
void minimizeForRc(CuspCorrection &cusp, OneMolecularOrbital &phiMO, RealType Z, RealType Rc_init, RealType Rc_max, RealType eta0, ValueVector &pos, ValueVector &ELcurr, ValueVector &ELideal)
Minimize chi2 with respect to Rc and phi at zero.
helper functions for EinsplineSetBuilder
int rank() const
return the rank
int getBasisSetSize() const
return the size of the basis set
QTBase::RealType RealType
RealType dpr(RealType r) const
RealType phiBar(const CuspCorrection &cusp, RealType r, OneMolecularOrbital &phiMO)
Cusp correction parameters.
Bracket_min_t< T > bracket_minimum(const F &f, T initial_value, T bound_max=-1.0)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
RealType evaluateForPhi0Body(RealType phi0, ValueVector &pos, ValueVector &ELcurr, ValueVector &ELideal, CuspCorrection &cusp, OneMolecularOrbital &phiMO, ValGradLap phiAtRc, RealType etaAtZero, RealType ELorigAtRc, RealType Z)
RealType sg
The sign of the wavefunction at the nucleus.
CuspCorrectionParameters cparam
RealType Rc
The cutoff radius.
bool put(xmlNodePtr cur)
assign attributes to the set
void getCurrentLocalEnergy(const ValueVector &pos, RealType Zeff, RealType Rc, RealType originalELatRc, CuspCorrection &cusp, OneMolecularOrbital &phiMO, ValueVector &ELcurr)
Compute effective local energy at vector of points.
RealType Rr(RealType r) const
std::unique_ptr< basis_type > myBasisSet
pointer to the basis set
LatticeGaussianProduct::GradType GradType
Timer accumulates time and call counts.
void evalX(RealType valRc, GradType gradRc, ValueType lapRc, RealType Rc, RealType Z, RealType C, RealType valAtZero, RealType eta0, TinyVector< ValueType, 5 > &X)
Evaluate various orbital quantities that enter as constraints on the correction.
void saveCusp(const std::string &filename, const Matrix< CuspCorrectionParameters > &info, const std::string &id)
save cusp correction info to a file.
int addAttribute(const std::string &aname)
for a new attribute, allocate the data, !More often used to get the index of a species ...
void broadcastCuspInfo(CuspCorrectionParameters ¶m, Communicate &Comm, int root)
Broadcast cusp correction parameters.
OrbitalSetTraits< ValueType >::ValueVector ValueVector
int size() const
return the number of tasks
void applyCuspCorrection(const Matrix< CuspCorrectionParameters > &info, ParticleSet &targetPtcl, ParticleSet &sourcePtcl, LCAOrbitalSet &lcao, SoaCuspCorrection &cusp, const std::string &id)
OutputManagerClass outputManager(Verbosity::HIGH)
ParticleIndex GroupID
Species ID.
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
int redo
Flag to indicate the correction should be recalculated.
An abstract base class to implement a One-Dimensional grid.
bool readCuspInfo(const std::string &cuspInfoFile, const std::string &objectName, int OrbitalSetSize, Matrix< CuspCorrectionParameters > &info)
Read cusp correction parameters from XML file.
void getIdealLocalEnergy(const ValueVector &pos, RealType Z, RealType Rc, RealType ELorigAtRc, ValueVector &ELideal)
Ideal local energy at a vector of points.
Wrapping information on parallelism.
RealType getOriginalLocalEnergy(const ValueVector &pos, RealType Zeff, RealType Rc, OneMolecularOrbital &phiMO, ValueVector &ELorig)
Local energy from uncorrected orbital.
Specialized paritlce class for atomistic simulations.
void removeSTypeOrbitals(const std::vector< bool > &corrCenter, LCAOrbitalSet &Phi)
Remove S atomic orbitals from all molecular orbitals on all centers.
A collection of functions for dividing fairly.
size_type size() const
return the current size
RealType d2pr(RealType r) const
class to handle a set of attributes of an xmlNode
void changeOrbital(int centerIdx, int orbIdx)
std::pair< T, T > find_minimum(const F &f, Bracket_min_t< T > &bracket)
void generateCuspInfo(Matrix< CuspCorrectionParameters > &info, const ParticleSet &targetPtcl, const ParticleSet &sourcePtcl, const LCAOrbitalSet &lcao, const std::string &id, Communicate &Comm)
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
std::shared_ptr< OffloadValueMatrix > C
pointer to matrix containing the coefficients
A localized basis set derived from BasisSetBase<typename COT::ValueType>
Formulas for applying the cusp correction.
int getOrbitalSetSize() const
return the size of the orbitals
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
RealType getOneIdealLocalEnergy(RealType r, RealType Z, RealType beta0)
Ideal local energy at one point.
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
MakeReturn< UnaryNode< FnLog, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t log(const Vector< T1, C1 > &l)
QMCTraits::RealType RealType
bool isDebugActive() const
void computeRadialPhiBar(ParticleSet *targetP, ParticleSet *sourceP, int curOrb_, int curCenter_, SPOSet *Phi, Vector< QMCTraits::RealType > &xgrid, Vector< QMCTraits::RealType > &rad_orb, const CuspCorrectionParameters &data)
Compute the radial part of the corrected wavefunction.
void add(int icenter, std::unique_ptr< COT > aos)
add a new set of Centered Atomic Orbitals
bool parse(const std::string &fname)
void X2alpha(const TinyVector< ValueType, 5 > &X, RealType Rc, TinyVector< ValueType, 5 > &alpha)
Convert constraints to polynomial parameters.
LatticeGaussianProduct::ValueType ValueType
RealType minimizeForPhiAtZero(CuspCorrection &cusp, OneMolecularOrbital &phiMO, RealType Z, RealType eta0, ValueVector &pos, ValueVector &ELcurr, ValueVector &ELideal, RealType start_phi0)
Minimize chi2 with respect to phi at zero for a fixed Rc.
class to handle linear combinations of basis orbitals used to evaluate the Dirac determinants.
Custom container for set of attributes for a set of species.
RealType C
A shift to keep correction to a single sign.
void spline(int imin, value_type yp1, int imax, value_type ypn) override
bool isOMPoffload() const override
Query if this SPOSet uses OpenMP offload.
A derived class from BasisSetBase.
void phi_vgl(RealType r, RealType &val, GradType &grad, RealType &lap)
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
RealType getZeff(RealType Z, RealType etaAtZero, RealType phiBarAtZero)
Effective nuclear charge to keep effective local energy finite at zero.
std::string getNodeName(xmlNodePtr cur)
RealType getELchi2(const ValueVector &ELcurr, const ValueVector &ELideal)
Sum of squares difference between the current and ideal local energies This is the objective function...
void splitPhiEta(int center, const std::vector< bool > &corrCenter, LCAOrbitalSet &Phi, LCAOrbitalSet &Eta)
Divide molecular orbital into atomic S-orbitals on this center (phi), and everything else (eta)...
Assume that coeffs.D1 and the LogLightGrid r_values.size() are equal Therefore r must be < r_max...