2424#include " Utilities/ProgressReportEngine.h"
2525#include " OhmmsData/AttributeSet.h"
2626#include " PlatformSelector.hpp"
27+ #include < Message/UniformCommunicateError.h>
2728
2829#include " QMCWaveFunctions/Fermion/SlaterDet.h"
2930#include " QMCWaveFunctions/Fermion/MultiSlaterDetTableMethod.h"
@@ -62,8 +63,7 @@ std::unique_ptr<WaveFunctionComponent> SlaterDetBuilder::buildComponent(xmlNodeP
6263{
6364 ReportEngine PRE (ClassName, " put(xmlNodePtr)" );
6465 // /save the current node
65- xmlNodePtr curRoot = cur;
66- bool multiDet = false ;
66+ bool multiDet = false ;
6767 std::string msd_algorithm;
6868
6969 std::unique_ptr<WaveFunctionComponent> built_singledet_or_multidets;
@@ -75,23 +75,20 @@ std::unique_ptr<WaveFunctionComponent> SlaterDetBuilder::buildComponent(xmlNodeP
7575 app_warning () << " !!!!!!! Deprecated input style: creating SPO set inside determinantset. Support for this usage "
7676 " will soon be removed. SPO sets should be built outside using sposet_collection."
7777 << std::endl;
78- legacy_input_sposet_builder = sposet_builder_factory_.createSPOSetBuilder (curRoot );
78+ legacy_input_sposet_builder = sposet_builder_factory_.createSPOSetBuilder (cur );
7979 }
8080
81- // check the basis set and backflow transformation
81+ // check the basisset and backflow transformation
8282 std::unique_ptr<BackflowTransformation> BFTrans;
83- cur = curRoot->children ;
84- while (cur != NULL ) // check the basis set
85- {
86- std::string cname (getNodeName (cur));
83+ processChildren (cur, [&](const std::string& cname, const xmlNodePtr element) {
8784 if (cname == sposet_tag)
8885 {
8986 app_warning () << " !!!!!!! Deprecated input style: creating SPO set inside determinantset. Support for this usage "
9087 " will soon be removed. SPO sets should be built outside using sposet_collection."
9188 << std::endl;
9289 app_log () << " Creating SPOSet in SlaterDetBuilder::put(xmlNodePtr cur).\n " ;
9390 assert (legacy_input_sposet_builder);
94- sposet_builder_factory_.addSPOSet (legacy_input_sposet_builder->createSPOSet (cur ));
91+ sposet_builder_factory_.addSPOSet (legacy_input_sposet_builder->createSPOSet (element ));
9592 }
9693 else if (cname == backflow_tag)
9794 {
@@ -104,15 +101,40 @@ std::unique_ptr<WaveFunctionComponent> SlaterDetBuilder::buildComponent(xmlNodeP
104101 " Please collect all transformations into a single block." );
105102
106103 BackflowBuilder bfbuilder (targetPtcl, ptclPool);
107- BFTrans = bfbuilder.buildBackflowTransformation (cur );
104+ BFTrans = bfbuilder.buildBackflowTransformation (element );
108105 }
109- cur = cur->next ;
110- }
106+ });
111107
112- cur = curRoot->children ;
113- while (cur != NULL )
108+ if (sposet_builder_factory_.empty ())
114109 {
115- std::string cname (getNodeName (cur));
110+ processChildren (cur, [&](const std::string& cname, const xmlNodePtr element) {
111+ if (cname == sd_tag)
112+ {
113+ // look for sposet inside slaterdeterminant and nested determinant tag
114+ processChildren (element, [&](const std::string& cname, const xmlNodePtr element) {
115+ if (cname == det_tag)
116+ {
117+ app_warning () << " !!!!!!! Deprecated input style: creating SPO set inside slaterdeterminant and nested "
118+ " determinant tags. Support for this usage "
119+ " will soon be removed. SPO sets should be built outside using sposet_collection."
120+ << std::endl;
121+ auto sposet_name = getXMLAttributeValue (element, " sposet" );
122+ if (sposet_name.empty ())
123+ sposet_name = getXMLAttributeValue (element, " id" );
124+ if (sposet_name.empty ())
125+ sposet_name = " 0" ;
126+
127+ app_log () << " Create a new SPOSet " << sposet_name << std::endl;
128+ assert (legacy_input_sposet_builder);
129+ auto sposet = legacy_input_sposet_builder->createSPOSet (element);
130+ sposet_builder_factory_.addSPOSet (std::move (sposet));
131+ }
132+ });
133+ }
134+ });
135+ }
136+
137+ processChildren (cur, [&](const std::string& cname, const xmlNodePtr element) {
116138 if (cname == sd_tag)
117139 {
118140 app_summary () << std::endl;
@@ -124,23 +146,20 @@ std::unique_ptr<WaveFunctionComponent> SlaterDetBuilder::buildComponent(xmlNodeP
124146
125147 std::vector<std::unique_ptr<DiracDeterminantBase>> dirac_dets;
126148 size_t spin_group = 0 ;
127- xmlNodePtr tcur = cur->children ;
128- while (tcur != NULL )
129- {
130- std::string tname (getNodeName (tcur));
131- if (tname == det_tag || tname == rn_tag)
149+ processChildren (element, [&](const std::string& cname, const xmlNodePtr element) {
150+ if (cname == det_tag || cname == rn_tag)
132151 {
133152 if (spin_group >= targetPtcl.groups ())
134153 {
135154 std::ostringstream err_msg;
136155 err_msg << " Need only " << targetPtcl.groups () << " determinant input elements. Found more." << std::endl;
137156 throw std::runtime_error (err_msg.str ());
138157 }
139- dirac_dets.push_back (putDeterminant (tcur , spin_group, legacy_input_sposet_builder , BFTrans));
158+ dirac_dets.push_back (putDeterminant (element , spin_group, BFTrans));
140159 spin_group++;
141160 }
142- tcur = tcur-> next ;
143- }
161+ }) ;
162+
144163 if (spin_group < targetPtcl.groups ())
145164 {
146165 std::ostringstream err_msg;
@@ -186,7 +205,7 @@ std::unique_ptr<WaveFunctionComponent> SlaterDetBuilder::buildComponent(xmlNodeP
186205 }
187206 spoAttrib.add (fastAlg, " Fast" , {" " , " yes" , " no" }, TagStatus::DELETED);
188207 spoAttrib.add (msd_algorithm, " algorithm" , {" precomputed_table_method" , " table_method" });
189- spoAttrib.put (cur );
208+ spoAttrib.put (element );
190209
191210 // new format
192211 std::vector<std::unique_ptr<SPOSet>> spo_clones;
@@ -213,7 +232,7 @@ std::unique_ptr<WaveFunctionComponent> SlaterDetBuilder::buildComponent(xmlNodeP
213232 else
214233 app_summary () << " Using the table method without precomputing. Slower." << std::endl;
215234
216- auto msd_fast = createMSDFast (cur , targetPtcl, std::move (spo_clones), targetPtcl.isSpinor (),
235+ auto msd_fast = createMSDFast (element , targetPtcl, std::move (spo_clones), targetPtcl.isSpinor (),
217236 msd_algorithm == " precomputed_table_method" );
218237
219238 // The primary purpose of this function is to create all the optimizable orbital rotation parameters.
@@ -222,8 +241,7 @@ std::unique_ptr<WaveFunctionComponent> SlaterDetBuilder::buildComponent(xmlNodeP
222241 msd_fast->buildOptVariables ();
223242 built_singledet_or_multidets = std::move (msd_fast);
224243 }
225- cur = cur->next ;
226- }
244+ });
227245
228246 if (built_singledet_or_multidets)
229247 return built_singledet_or_multidets;
@@ -248,7 +266,6 @@ magnetic system
248266std::unique_ptr<DiracDeterminantBase> SlaterDetBuilder::putDeterminant (
249267 xmlNodePtr cur,
250268 int spin_group,
251- const std::unique_ptr<SPOSetBuilder>& legacy_input_sposet_builder,
252269 const std::unique_ptr<BackflowTransformation>& BFTrans)
253270{
254271 ReportEngine PRE (ClassName, " putDeterminant(xmlNodePtr,int)" );
@@ -331,16 +348,13 @@ std::unique_ptr<DiracDeterminantBase> SlaterDetBuilder::putDeterminant(
331348
332349 const SPOSet* psi = sposet_builder_factory_.getSPOSet (sposet_name);
333350 // check if the named sposet exists
334- if (psi == 0 )
351+ if (psi == nullptr )
335352 {
336- app_warning () << " !!!!!!! Deprecated input style: creating SPO set inside determinantset. Support for this usage "
337- " will soon be removed. SPO sets should be built outside using sposet_collection."
338- << std::endl;
339- app_log () << " Create a new SPO set " << sposet_name << std::endl;
340- assert (legacy_input_sposet_builder);
341- auto sposet = legacy_input_sposet_builder->createSPOSet (cur);
342- psi = sposet.get ();
343- sposet_builder_factory_.addSPOSet (std::move (sposet));
353+ std::ostringstream err_msg;
354+ err_msg << " A sposet named \" " << sposet_name
355+ << " \" cannot be found for constructing a Slater determinant! Please check the xml input file!"
356+ << std::endl;
357+ throw UniformCommunicateError (err_msg.str ());
344358 }
345359
346360 std::unique_ptr<SPOSet> psi_clone (psi->makeClone ());
0 commit comments