29 template<
typename COT>
33 expandlm(GAUSSIAN_EXPAND),
36 basisType(
"Numerical"),
51 ReportEngine PRE(
"AtomicBasisBuilder",
"put(xmlNodePtr)");
54 aAttrib.
add(basisType,
"type");
55 aAttrib.
add(sph,
"angular");
56 aAttrib.
add(addsignforM,
"expM");
57 aAttrib.
add(Morder,
"expandYlm");
58 aAttrib.
add(Normalized,
"normalized");
61 if (sph ==
"spherical")
64 if (Morder ==
"gaussian")
65 expandlm = GAUSSIAN_EXPAND;
66 else if (Morder ==
"natural")
67 expandlm = NATURAL_EXPAND;
68 else if (Morder ==
"no")
69 expandlm = DONOT_EXPAND;
70 else if (Morder ==
"pyscf")
72 expandlm = MOD_NATURAL_EXPAND;
74 if (sph !=
"spherical")
76 myComm->barrier_and_abort(
" Error: expandYlm='pyscf' only compatible with angular='spherical'. Aborting.\n");
80 if (sph ==
"cartesian" || Morder ==
"Gamess")
82 expandlm = CARTESIAN_EXPAND;
86 if (Morder ==
"Dirac")
88 expandlm = DIRAC_CARTESIAN_EXPAND;
90 if (sph !=
"cartesian")
91 myComm->barrier_and_abort(
" Error: expandYlm='Dirac' only compatible with angular='cartesian'. Aborting\n");
95 if (basisType ==
"Numerical")
96 myComm->barrier_and_abort(
"Purely numerical atomic orbitals are not supported any longer.");
105 std::string CenterID, basisName;
107 if (myComm->rank() == 0)
109 hin.
read(sph,
"angular");
110 hin.
read(CenterID,
"elementType");
111 hin.
read(Normalized,
"normalized");
112 hin.
read(Morder,
"expandYlm");
113 hin.
read(basisName,
"name");
117 myComm->bcast(Morder);
118 myComm->bcast(CenterID);
119 myComm->bcast(Normalized);
120 myComm->bcast(basisName);
121 myComm->bcast(basisType);
122 myComm->bcast(addsignforM);
124 if (sph ==
"spherical")
127 if (Morder ==
"gaussian")
128 expandlm = GAUSSIAN_EXPAND;
129 else if (Morder ==
"natural")
130 expandlm = NATURAL_EXPAND;
131 else if (Morder ==
"no")
132 expandlm = DONOT_EXPAND;
133 else if (Morder ==
"pyscf")
135 expandlm = MOD_NATURAL_EXPAND;
137 if (sph !=
"spherical")
139 myComm->barrier_and_abort(
" Error: expandYlm='pyscf' only compatible with angular='spherical'. Aborting.\n");
143 if (sph ==
"cartesian" || Morder ==
"Gamess")
145 expandlm = CARTESIAN_EXPAND;
149 if (Morder ==
"Dirac")
151 expandlm = DIRAC_CARTESIAN_EXPAND;
153 if (sph !=
"cartesian")
154 myComm->barrier_and_abort(
" Error: expandYlm='Dirac' only compatible with angular='cartesian'. Aborting\n");
156 app_log() << R
"(<input node="atomicBasisSet" name=")" << basisName << "\" expandYlm=\"" << Morder <<
"\" angular=\"" 157 << sph <<
"\" elementType=\"" << CenterID <<
"\" normalized=\"" << Normalized <<
"\" type=\"" << basisType
158 <<
"\" expM=\"" << addsignforM <<
"\" />" << std::endl;
164 template<
typename COT>
167 ReportEngine PRE(
"AtomicBasisBuilder",
"createAOSet(xmlNodePtr)");
168 app_log() <<
" AO BasisSet for " << elementType <<
"\n";
170 if (expandlm != CARTESIAN_EXPAND)
173 app_log() <<
" Spherical Harmonics contain (-1)^m factor" << std::endl;
175 app_log() <<
" Spherical Harmonics DO NOT contain (-1)^m factor" << std::endl;
180 case (GAUSSIAN_EXPAND):
181 app_log() <<
" Angular momentum m expanded according to Gaussian" << std::endl;
183 case (NATURAL_EXPAND):
184 app_log() <<
" Angular momentum m expanded as -l, ... ,l" << std::endl;
186 case (MOD_NATURAL_EXPAND):
187 app_log() <<
" Angular momentum m expanded as -l, ... ,l, with the exception of L=1 (1,-1,0)" << std::endl;
189 case (CARTESIAN_EXPAND):
190 app_log() <<
" Angular momentum expanded in cartesian functions x^lx y^ly z^lz according to Gamess" << std::endl;
192 case (DIRAC_CARTESIAN_EXPAND):
193 app_log() <<
" Angular momentum expanded in cartesian functions in DIRAC ordering" << std::endl;
196 app_log() <<
" Angular momentum m is explicitly given." << std::endl;
204 std::vector<xmlNodePtr> radGroup;
205 xmlNodePtr cur1 = cur->xmlChildrenNode;
209 std::string cname1((
const char*)(cur1->name));
210 if (cname1 ==
"basisGroup")
212 radGroup.push_back(cur1);
214 Lmax = std::max(Lmax, l);
216 if (expandlm == CARTESIAN_EXPAND || expandlm == DIRAC_CARTESIAN_EXPAND)
217 num += (l + 1) * (l + 2) / 2;
223 else if (cname1 ==
"grid")
232 auto aos = std::make_unique<COT>(Lmax, addsignforM);
238 radFuncBuilder.
Normalized = (Normalized ==
"yes");
239 radFuncBuilder.
addGrid(gptr, basisType);
240 std::vector<xmlNodePtr>::iterator it(radGroup.begin());
241 std::vector<xmlNodePtr>::iterator it_end(radGroup.end());
242 std::vector<int> all_nl;
246 xmlAttrPtr att = cur1->properties;
249 std::string aname((
const char*)(att->name));
250 if (aname ==
"rid" || aname ==
"id")
253 rnl = (
const char*)(att->children->content);
257 std::map<std::string, int>::iterator iit = nlms_id.find(aname);
258 if (iit != nlms_id.end())
261 nlms[(*iit).second] = atoi((
const char*)(att->children->content));
267 app_log() <<
" R(n,l,m,s) " << nlms[0] <<
" " << nlms[1] <<
" " << nlms[2] <<
" " << nlms[3] << std::endl;
268 std::map<std::string, int>::iterator rnl_it = RnlID.find(rnl);
269 if (rnl_it == RnlID.end())
271 int nl = aos->RnlID.
size();
274 all_nl.push_back(nl);
278 all_nl.push_back((*rnl_it).second);
283 if (expandYlm(aos.get(), all_nl, expandlm) != num)
284 myComm->barrier_and_abort(
"expandYlm doesn't match the number of basis.");
287 app_log() <<
" Maximum Angular Momentum = " << aos->Ylm.lmax() << std::endl
288 <<
" Number of Radial functors = " << aos->RnlID.size() << std::endl
289 <<
" Basis size = " << aos->getBasisSetSize() <<
"\n\n";
294 template<
typename COT>
297 ReportEngine PRE(
"AOBasisBuilder:",
"createAOSetH5(std::string)");
298 app_log() <<
" AO BasisSet for " << elementType <<
"\n";
300 if (expandlm != CARTESIAN_EXPAND)
303 app_log() <<
" Spherical Harmonics contain (-1)^m factor" << std::endl;
305 app_log() <<
" Spherical Harmonics DO NOT contain (-1)^m factor" << std::endl;
310 case (GAUSSIAN_EXPAND):
311 app_log() <<
" Angular momentum m expanded according to Gaussian" << std::endl;
313 case (NATURAL_EXPAND):
314 app_log() <<
" Angular momentum m expanded as -l, ... ,l" << std::endl;
316 case (MOD_NATURAL_EXPAND):
317 app_log() <<
" Angular momentum m expanded as -l, ... ,l, with the exception of L=1 (1,-1,0)" << std::endl;
319 case (CARTESIAN_EXPAND):
320 app_log() <<
" Angular momentum expanded in cartesian functions x^lx y^ly z^lz according to Gamess" << std::endl;
322 case (DIRAC_CARTESIAN_EXPAND):
323 app_log() <<
" Angular momentum expanded in cartesian functions in DIRAC ordering" << std::endl;
326 app_log() <<
" Angular momentum m is explicitly given." << std::endl;
334 int numbasisgroups(0);
335 if (myComm->rank() == 0)
337 if (!hin.
readEntry(numbasisgroups,
"NbBasisGroups"))
338 PRE.
error(
"Could not read NbBasisGroups in H5; Probably Corrupt H5 file",
true);
340 myComm->bcast(numbasisgroups);
342 for (
int i = 0; i < numbasisgroups; i++)
344 std::string basisGroupID =
"basisGroup" + std::to_string(i);
346 if (myComm->rank() == 0)
348 hin.
push(basisGroupID);
354 Lmax = std::max(Lmax, l);
356 if (expandlm == CARTESIAN_EXPAND || expandlm == DIRAC_CARTESIAN_EXPAND)
357 num += (l + 1) * (l + 2) / 2;
366 auto aos = std::make_unique<COT>(Lmax, addsignforM);
372 radFuncBuilder.
Normalized = (Normalized ==
"yes");
374 std::vector<int> all_nl;
375 for (
int i = 0; i < numbasisgroups; i++)
377 std::string basisGroupID =
"basisGroup" + std::to_string(i);
378 if (myComm->rank() == 0)
380 hin.
push(basisGroupID);
381 hin.
read(rnl,
"rid");
382 hin.
read(nlms[0],
"n");
383 hin.
read(nlms[1],
"l");
386 myComm->bcast(nlms[0]);
387 myComm->bcast(nlms[1]);
390 app_log() <<
" R(n,l,m,s) " << nlms[0] <<
" " << nlms[1] <<
" " << nlms[2] <<
" " << nlms[3] << std::endl;
391 std::map<std::string, int>::iterator rnl_it = RnlID.find(rnl);
392 if (rnl_it == RnlID.end())
394 int nl = aos->RnlID.
size();
397 all_nl.push_back(nl);
401 all_nl.push_back((*rnl_it).second);
404 if (myComm->rank() == 0)
408 if (expandYlm(aos.get(), all_nl, expandlm) != num)
409 myComm->barrier_and_abort(
"expandYlm doesn't match the number of basis.");
412 app_log() <<
" Maximum Angular Momentum = " << aos->Ylm.lmax() << std::endl
413 <<
" Number of Radial functors = " << aos->RnlID.size() << std::endl
414 <<
" Basis size = " << aos->getBasisSetSize() <<
"\n\n";
419 template<
typename COT>
423 if (expandlm == GAUSSIAN_EXPAND)
425 app_log() <<
"Expanding Ylm according to Gaussian98" << std::endl;
426 for (
int nl = 0; nl < aos->RnlID.size(); nl++)
428 int l = aos->RnlID[nl][
q_l];
429 app_log() <<
"Adding " << 2 * l + 1 <<
" spherical orbitals for l= " << l << std::endl;
433 aos->LM[num] = aos->Ylm.index(0, 0);
438 aos->LM[num] = aos->Ylm.index(1, 1);
441 aos->LM[num] = aos->Ylm.index(1, -1);
444 aos->LM[num] = aos->Ylm.index(1, 0);
449 aos->LM[num] = aos->Ylm.index(l, 0);
452 for (
int tm = 1; tm <= l; tm++)
454 aos->LM[num] = aos->Ylm.index(l, tm);
457 aos->LM[num] = aos->Ylm.index(l, -tm);
465 else if (expandlm == MOD_NATURAL_EXPAND)
467 app_log() <<
"Expanding Ylm as L=1 as (1,-1,0) and L>1 as -l,-l+1,...,l-1,l" << std::endl;
468 for (
int nl = 0; nl < aos->RnlID.size(); nl++)
470 int l = aos->RnlID[nl][
q_l];
471 app_log() <<
" Adding " << 2 * l + 1 <<
" spherical orbitals" << std::endl;
475 aos->LM[num] = aos->Ylm.index(1, 1);
478 aos->LM[num] = aos->Ylm.index(1, -1);
481 aos->LM[num] = aos->Ylm.index(1, 0);
487 for (
int tm = -l; tm <= l; tm++, num++)
489 aos->LM[num] = aos->Ylm.index(l, tm);
495 else if (expandlm == NATURAL_EXPAND)
497 app_log() <<
"Expanding Ylm as -l,-l+1,...,l-1,l" << std::endl;
498 for (
int nl = 0; nl < aos->RnlID.size(); nl++)
500 int l = aos->RnlID[nl][
q_l];
501 app_log() <<
" Adding " << 2 * l + 1 <<
" spherical orbitals" << std::endl;
502 for (
int tm = -l; tm <= l; tm++, num++)
504 aos->LM[num] = aos->Ylm.index(l, tm);
509 else if (expandlm == CARTESIAN_EXPAND)
511 app_log() <<
"Expanding Ylm (angular function) according to Gamess using cartesian gaussians" << std::endl;
512 for (
int nl = 0; nl < aos->RnlID.size(); nl++)
514 int l = aos->RnlID[nl][
q_l];
515 app_log() <<
"Adding " << (l + 1) * (l + 2) / 2 <<
" cartesian gaussian orbitals for l= " << l << std::endl;
517 for (
int i = 0; i < l; i++)
518 nbefore += (i + 1) * (i + 2) / 2;
519 for (
int i = 0; i < (l + 1) * (l + 2) / 2; i++)
521 aos->LM[num] = nbefore + i;
527 else if (expandlm == DIRAC_CARTESIAN_EXPAND)
529 app_log() <<
"Expanding Ylm (angular function) according to DIRAC using cartesian gaussians" << std::endl;
530 for (
int nl = 0; nl < aos->RnlID.size(); nl++)
532 int l = aos->RnlID[nl][
q_l];
533 app_log() <<
"Adding " << (l + 1) * (l + 2) / 2 <<
" cartesian gaussian orbitals for l= " << l << std::endl;
535 for (
int i = 0; i < l; i++)
536 nbefore += (i + 1) * (i + 2) / 2;
540 aos->LM[num] = nbefore + 0;
545 aos->LM[num] = nbefore + 0;
548 aos->LM[num] = nbefore + 1;
551 aos->LM[num] = nbefore + 2;
556 aos->LM[num] = nbefore + 0;
559 aos->LM[num] = nbefore + 3;
562 aos->LM[num] = nbefore + 4;
565 aos->LM[num] = nbefore + 1;
568 aos->LM[num] = nbefore + 5;
571 aos->LM[num] = nbefore + 2;
576 aos->LM[num] = nbefore + 0;
579 aos->LM[num] = nbefore + 3;
582 aos->LM[num] = nbefore + 4;
585 aos->LM[num] = nbefore + 5;
588 aos->LM[num] = nbefore + 9;
591 aos->LM[num] = nbefore + 7;
594 aos->LM[num] = nbefore + 1;
597 aos->LM[num] = nbefore + 6;
600 aos->LM[num] = nbefore + 8;
603 aos->LM[num] = nbefore + 2;
608 aos->LM[num] = nbefore + 0;
611 aos->LM[num] = nbefore + 3;
614 aos->LM[num] = nbefore + 4;
617 aos->LM[num] = nbefore + 9;
620 aos->LM[num] = nbefore + 12;
623 aos->LM[num] = nbefore + 10;
626 aos->LM[num] = nbefore + 5;
629 aos->LM[num] = nbefore + 13;
632 aos->LM[num] = nbefore + 14;
635 aos->LM[num] = nbefore + 7;
638 aos->LM[num] = nbefore + 1;
641 aos->LM[num] = nbefore + 6;
644 aos->LM[num] = nbefore + 11;
647 aos->LM[num] = nbefore + 8;
650 aos->LM[num] = nbefore + 2;
655 aos->LM[num] = nbefore + 0;
658 aos->LM[num] = nbefore + 3;
661 aos->LM[num] = nbefore + 4;
664 aos->LM[num] = nbefore + 9;
667 aos->LM[num] = nbefore + 15;
670 aos->LM[num] = nbefore + 10;
673 aos->LM[num] = nbefore + 11;
676 aos->LM[num] = nbefore + 18;
679 aos->LM[num] = nbefore + 19;
682 aos->LM[num] = nbefore + 13;
685 aos->LM[num] = nbefore + 5;
688 aos->LM[num] = nbefore + 16;
691 aos->LM[num] = nbefore + 20;
694 aos->LM[num] = nbefore + 17;
697 aos->LM[num] = nbefore + 7;
700 aos->LM[num] = nbefore + 1;
703 aos->LM[num] = nbefore + 6;
706 aos->LM[num] = nbefore + 12;
709 aos->LM[num] = nbefore + 14;
712 aos->LM[num] = nbefore + 8;
715 aos->LM[num] = nbefore + 2;
720 aos->LM[num] = nbefore + 0;
723 aos->LM[num] = nbefore + 3;
726 aos->LM[num] = nbefore + 4;
729 aos->LM[num] = nbefore + 9;
732 aos->LM[num] = nbefore + 15;
735 aos->LM[num] = nbefore + 10;
738 aos->LM[num] = nbefore + 18;
741 aos->LM[num] = nbefore + 21;
744 aos->LM[num] = nbefore + 22;
747 aos->LM[num] = nbefore + 19;
750 aos->LM[num] = nbefore + 11;
753 aos->LM[num] = nbefore + 23;
756 aos->LM[num] = nbefore + 27;
759 aos->LM[num] = nbefore + 25;
762 aos->LM[num] = nbefore + 13;
765 aos->LM[num] = nbefore + 5;
768 aos->LM[num] = nbefore + 16;
771 aos->LM[num] = nbefore + 24;
774 aos->LM[num] = nbefore + 26;
777 aos->LM[num] = nbefore + 17;
780 aos->LM[num] = nbefore + 7;
783 aos->LM[num] = nbefore + 1;
786 aos->LM[num] = nbefore + 6;
789 aos->LM[num] = nbefore + 12;
792 aos->LM[num] = nbefore + 20;
795 aos->LM[num] = nbefore + 14;
798 aos->LM[num] = nbefore + 8;
801 aos->LM[num] = nbefore + 2;
806 myComm->barrier_and_abort(
"Cartesian Tensor only defined up to Lmax=6. Aborting\n");
813 for (
int ind = 0; ind < all_nl.size(); ind++)
815 int nl = all_nl[ind];
816 int l = aos->RnlID[nl][
q_l];
817 int m = aos->RnlID[nl][
q_m];
819 aos->LM[num] = aos->Ylm.index(l,
m);
void echo(xmlNodePtr cur, bool recursive=false)
Base class for any object which needs to know about a MPI communicator.
helper functions for EinsplineSetBuilder
bool put(xmlNodePtr cur)
assign attributes to the set
Build a set of radial orbitals at the origin.
SoaSphericalTensor that evaluates the Real Spherical Harmonics.
bool addGrid(xmlNodePtr cur, const std::string &rad_type)
add a grid
Wrapping information on parallelism.
bool addGridH5(hdf_archive &hin)
Final class and should not be derived.
void finalize()
This is when the radial orbitals are actually created.
class to handle a set of attributes of an xmlNode
declaration of ProgressReportEngine
bool addRadialOrbital(xmlNodePtr cur, const std::string &m_infunctype, const QuantumNumberType &nlms)
add a radial functor
std::string getXMLAttributeValue(const xmlNodePtr cur, const std::string_view name)
get the value string for attribute name if name is unfound in cur you get an empty string back this i...
AOBasisBuilder(const std::string &eName, Communicate *comm)
void push(const std::string &gname, bool createit=true)
push a group to the group stack
std::unique_ptr< COT > createAOSet(xmlNodePtr cur)
void error(const std::string &msg, bool fatal=false)
std::map< std::string, int > nlms_id
map for (n,l,m,s) to its quantum number index
void read(T &data, const std::string &aname)
read the data from the group aname and check status runtime error is issued on I/O error ...
std::unique_ptr< COT > createAOSetH5(hdf_archive &hin)
bool readEntry(T &data, const std::string &aname)
read the data from the group aname and return status use read() for inbuilt error checking ...
int expandYlm(COT *aos, std::vector< int > &all_nl, int expandlm=DONOT_EXPAND)
CartesianTensor according to Gamess order.
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
bool Normalized
true, if the RadialOrbitalType is normalized
bool addRadialOrbitalH5(hdf_archive &hin, const std::string &radtype, const QuantumNumberType &nlms)
bool putH5(hdf_archive &hin)
Assume that coeffs.D1 and the LogLightGrid r_values.size() are equal Therefore r must be < r_max...