29 app_log() <<
" ECPComponentBuilder::buildSemiLocalAndLocal " << std::endl;
33 if (semiPtr.size() > 1)
35 std::stringstream err_msg;
36 err_msg <<
"ECPComponentBuilder::buildSemiLocalAndLocal. " 37 <<
"We have more than one semilocal sections in the PP xml file";
42 std::string eunits(
"hartree");
43 std::string format(
"r*V");
50 int local_channel = -1;
51 aAttrib.
add(eunits,
"units");
52 aAttrib.
add(format,
"format");
53 aAttrib.
add(ndown,
"npots-down");
54 aAttrib.
add(nup,
"npots-up");
55 aAttrib.
add(local_channel,
"l-local");
56 aAttrib.
add(quad_rule,
"nrule");
58 aAttrib.
add(nso,
"npots-so");
60 xmlNodePtr cur_semilocal = semiPtr[0];
61 aAttrib.
put(cur_semilocal);
64 if (quad_rule > -1 &&
Nrule > -1)
66 app_warning() <<
" Nrule setting found in both qmcpack input (Nrule = " <<
Nrule 67 <<
") and pseudopotential file (Nrule = " << quad_rule <<
")." 68 <<
" Using nrule setting in qmcpack input file." << std::endl;
70 else if (quad_rule > -1 &&
Nrule == -1)
72 app_log() <<
" Nrule setting found in pseudopotential file and used." << std::endl;
75 else if (quad_rule == -1 &&
Nrule > -1)
76 app_log() <<
" Nrule setting found in qmcpack input file and used." << std::endl;
107 app_warning() <<
"Nrule was not determined from qmcpack input or pseudopotential file. Setting sensible default." 113 if (eunits.find(
"ydberg") < eunits.size())
115 app_log() <<
" Input energy unit = Rydberg " << std::endl;
120 app_log() <<
" Assuming Hartree unit" << std::endl;
122 bool is_r_times_V(
true);
125 else if (format ==
"V")
126 is_r_times_V =
false;
129 std::stringstream err_msg;
130 err_msg <<
"ECPComponentBuilder::buildSemiLocalAndLocal." 131 <<
"Unrecognized format \"" << format <<
"\" in PP file.\n";
137 std::vector<int> angList;
138 std::vector<int> angListSO;
139 std::vector<xmlNodePtr> vpsPtr;
140 std::vector<xmlNodePtr> vpsoPtr;
144 xmlNodePtr cur_vps = cur_semilocal->children;
145 while (cur_vps != NULL)
147 std::string vname((
const char*)cur_vps->name);
151 std::string lstr(
"s");
153 aAttrib.
add(lstr,
"l");
154 aAttrib.
add(rc,
"cutoff");
155 aAttrib.
put(cur_vps);
156 rmax = std::max(rmax, rc);
159 std::stringstream err_msg;
160 err_msg <<
"ECPComponentBuilder::buildSemiLocalAndLocal. " 161 <<
"Requested angular momentum " << lstr <<
" not available.\n";
165 angList.push_back(l);
166 vpsPtr.push_back(cur_vps);
169 else if (vname ==
"vps_so")
172 std::string lstr(
"s");
174 aAttrib.
add(lstr,
"l");
175 aAttrib.
add(rc,
"cutoff");
176 aAttrib.
put(cur_vps);
177 rmax = std::max(rmax, rc);
180 std::stringstream err_msg;
181 err_msg <<
"ECPComponentBuilder::buildSemiLocalAndLocal. " 182 <<
"Requested angular momentum " << lstr <<
" not available for SO.\n";
186 angListSO.push_back(l);
187 vpsoPtr.push_back(cur_vps);
190 cur_vps = cur_vps->next;
197 if (local_channel > -1 &&
Llocal > -1)
199 app_warning() <<
" l-local setting found in both qmcpack input (l-local = " <<
Llocal 200 <<
") and pseudopotential file (l-local = " << local_channel <<
")." 201 <<
" Using l-local setting in qmcpack input file." << std::endl;
203 else if (local_channel > -1 &&
Llocal == -1)
205 app_log() <<
" l-local setting found in pseudopotential file and used." << std::endl;
208 else if (local_channel == -1 &&
Llocal > -1)
209 app_log() <<
" l-local setting found in qmcpack input file and used." << std::endl;
210 else if (angList.size() == 1)
213 app_log() <<
" Only one vps is found. Set the local component=" <<
Lmax << std::endl;
217 app_error() <<
"The local channel is specified in neither the pseudopotential file nor the input file.\n" 218 <<
"Please add \'l-local=\"n\"\' attribute to either file.\n";
222 if (angListSO.size() != nso)
224 std::stringstream ssout;
225 ssout <<
"Error. npots-so=" << angListSO.size() <<
" while declared number of SO channels is " << nso << std::endl;
226 std::string outstring(
"");
227 outstring = ssout.str();
233 for (
int l = 0; l < angList.size(); l++)
235 std::vector<mRealType> vt(npts);
236 xmlNodePtr c = vpsPtr[l]->children;
239 if (xmlStrEqual(c->name, (
const xmlChar*)
"radfunc"))
241 xmlNodePtr c1 = c->children;
244 if (xmlStrEqual(c1->name, (
const xmlChar*)
"data"))
252 copy(vt.begin(), vt.end(), vnn[angList[l]]);
257 for (
int l = 0; l < angListSO.size(); l++)
259 std::vector<mRealType> vtso(npts);
260 xmlNodePtr c = vpsoPtr[l]->children;
263 if (xmlStrEqual(c->name, (
const xmlChar*)
"radfunc"))
265 xmlNodePtr c1 = c->children;
268 if (xmlStrEqual(c1->name, (
const xmlChar*)
"data"))
279 copy(vtso.begin(), vtso.end(), vnnso[l]);
288 app_log() <<
" Input pseudopotential is converted into r*V" << std::endl;
289 for (
int i = 0; i < vnn.rows(); i++)
290 for (
int j = 0; j < npts; j++)
292 for (
int i = 0; i < vnnso.rows(); i++)
293 for (
int j = 0; j < npts; j++)
296 app_log() <<
" Number of angular momentum channels " << angList.size() << std::endl;
297 app_log() <<
" Maximum angular momentum channel (Lmax) " <<
Lmax << std::endl;
298 doBreakUp(angList, vnn, rmax, Vprefactor);
302 buildSO(angListSO, vnnso, rmax, 1.0);
318 const int max_points = 100000;
319 app_log() <<
" Creating a Linear Grid Rmax=" << rmax << std::endl;
322 auto agrid = std::make_unique<LinearGrid<RealType>>();
328 if (ng <= max_points)
332 agrid->set(0.0, rmax, ng);
335 agrid->set(0.0, rmax, max_points);
339 ng =
std::min(max_points, static_cast<int>(rmax / d) + 1);
340 agrid->set(0, rmax, ng);
345 int ngIn = vnnso.
cols() - 2;
346 std::vector<RealType> newP(ng);
347 std::vector<mRealType> newPin(ngIn);
348 for (
int l = 0; l < angList.size(); l++)
351 for (
int i = 0; i < ngIn; i++)
352 newPin[i] = Vprefactor * vp[i];
355 infunc.
spline(0, 0.0, ngIn - 1, 0.0);
356 for (
int i = 1; i < ng - 1; i++)
359 newP[i] = infunc.splint(r) / r;
365 pp_so->add(angList[l], app);
367 NumSO = angList.size();
368 pp_so->setRmax(rmax);
373 app_log() <<
" Start ECPComponentBuilder::parseCasino" << std::endl;
378 aAttrib.
add(rmax,
"cutoff");
384 std::ifstream fin(fname.c_str(), std::ios_base::in);
387 app_error() <<
"Could not open file " << fname << std::endl;
391 pp_nonloc = std::make_unique<NonLocalECPComponent>();
393 int npts = 0, idummy;
394 std::string eunits(
"rydberg");
395 app_log() <<
" ECPComponentBuilder::parseCasino" << std::endl;
396 aParser.skiplines(fin, 1);
397 aParser.skiplines(fin, 1);
400 aParser.skiplines(fin, 1);
401 aParser.getValue(fin, eunits);
402 app_log() <<
" Unit of the potentials = " << eunits << std::endl;
403 mRealType Vprefactor = (eunits ==
"rydberg") ? 0.5 : 1.0;
404 aParser.skiplines(fin, 1);
405 aParser.getValue(fin, idummy);
408 aParser.skiplines(fin, 1);
409 aParser.skiplines(fin, 1);
410 aParser.skiplines(fin, 1);
411 aParser.getValue(fin, npts);
412 app_log() <<
" Input Grid size = " << npts << std::endl;
413 std::vector<mRealType> temp(npts);
414 aParser.skiplines(fin, 1);
415 aParser.getValues(fin, temp.begin(), temp.end());
417 grid_global = std::make_unique<NumericalGrid<mRealType>>(temp);
419 for (
int l = 0; l <=
Lmax; l++)
421 aParser.skiplines(fin, 1);
422 aParser.getValues(fin, vnn[l], vnn[l] + npts);
424 std::vector<int> angList(
Lmax + 1);
425 for (
int l = 0; l <=
Lmax; l++)
430 const double tolerance = 1.0e-5;
432 for (
int j = npts - 1; j > 0; j--)
434 bool closeEnough =
true;
435 for (
int i = 0; i < vnn.rows(); i++)
436 for (
int k = i + 1; k < vnn.rows(); k++)
437 if (
std::abs(vnn[i][j] - vnn[k][j]) > tolerance)
445 app_log() <<
" Maxium cutoff for non-local pseudopotentials " << rc_check << std::endl;
447 doBreakUp(angList, vnn, rmax, Vprefactor);
449 app_log() <<
" Non-local pseudopotential parameters" << std::endl;
469 const int max_points = 100000;
470 app_log() <<
" Creating a Linear Grid Rmax=" << rmax << std::endl;
473 auto agrid = std::make_unique<LinearGrid<RealType>>();
479 if (ng <= max_points)
483 agrid->set(0.0, rmax, ng);
486 agrid->set(0.0, rmax, max_points);
490 ng =
std::min(max_points, static_cast<int>(rmax / d) + 1);
491 agrid->set(0, rmax, ng);
496 int ngIn = vnn.
cols() - 2;
498 assert(angList.size() > 0 &&
"ECPComponentBuilder::doBreakUp angList cannot be empty!");
501 for (
int l = 0; l < angList.size(); l++)
504 std::vector<RealType> newP(ng);
505 std::vector<mRealType> newPin(ngIn);
506 for (
int l = 0; l < angList.size(); l++)
510 const mRealType* restrict vp = vnn[angList[l]];
511 const mRealType* restrict vpLoc = vnn[iLlocal];
513 for (
int i = 0; i < ngIn; i++)
514 newPin[i] = Vprefactor * (vp[i] - vpLoc[i]);
516 infunc.
spline(0, 0.0, ngIn - 1, 0.0);
517 for (
int i = 1; i < ng - 1; i++)
520 newP[i] = infunc.splint(r) / r;
545 const mRealType* restrict vpLoc = vnn[iLlocal];
546 for (
int i = 0; i < ngIn; i++)
547 newPin[i] = vfac * vpLoc[i];
548 double dy0 = (newPin[1] - newPin[0]) / ((*
grid_global)[1] - (*grid_global)[0]);
550 infunc.
spline(0, dy0, ngIn - 1, 0.0);
554 loc_max = (nloc - 1) * d;
555 auto grid_loc = std::make_unique<LinearGrid<RealType>>();
556 grid_loc->set(0.0, loc_max, nloc);
557 app_log() <<
" Making L=" <<
Llocal <<
" a local potential with a radial cutoff of " << loc_max << std::endl;
558 std::vector<RealType> newPloc(nloc);
559 for (
int i = 1; i < nloc - 1; i++)
562 newPloc[i] = infunc.splint(r);
565 newPloc[nloc - 1] = 1.0;
566 pp_loc = std::make_unique<RadialPotentialType>(std::move(grid_loc), newPloc);
567 pp_loc->spline(0, dy0, nloc - 1, 0.0);
std::ostream & app_warning()
helper functions for EinsplineSetBuilder
QTBase::RealType RealType
void SetQuadratureRule(int rule)
std::map< std::string, int > angMon
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
bool put(xmlNodePtr cur)
assign attributes to the set
std::ostream & app_error()
void spline(int imin, value_type yp1, int imax, value_type ypn) override
Evaluate the 2nd derivative on the grid points.
std::unique_ptr< NonLocalECPComponent > pp_nonloc
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
std::unique_ptr< mGridType > grid_global
std::unique_ptr< SOECPComponent > pp_so
MakeReturn< UnaryNode< FnCeil, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t ceil(const Vector< T1, C1 > &l)
Communicate * myComm
pointer to Communicate
Declaration of a builder class for an ECP component for an ionic type.
class to handle a set of attributes of an xmlNode
bool parseCasino(const std::string &fname, xmlNodePtr cur)
std::unique_ptr< RadialPotentialType > pp_loc
LocalECPotential::RadialPotentialType RadialPotentialType
ParticleSet::Scalar_t mRealType
bool putContent(T &a, xmlNodePtr cur)
replaces a's value with the first "element" in the "string" returned by XMLNodeString{cur}.
void buildSemiLocalAndLocal(std::vector< xmlNodePtr > &semiPtr)
void doBreakUp(const std::vector< int > &angList, const Matrix< mRealType > &vnn, RealType rmax, mRealType Vprefactor=1.0)
Separate local from non-local potentials.
void barrier_and_abort(const std::string &msg) const
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
void buildSO(const std::vector< int > &angList, const Matrix< mRealType > &vnnso, RealType rmax, mRealType Vprefactor=1.0)
brief buildSO - takes the previously parsed angular momenta and spin-orbit tabulated potentials and u...
MakeReturn< UnaryNode< FnFloor, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t floor(const Vector< T1, C1 > &l)