QMCPACK
SPOSetBuilder.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 #include "SPOSetBuilder.h"
16 #include "OhmmsData/AttributeSet.h"
19 
20 namespace qmcplusplus
21 {
22 SPOSetBuilder::SPOSetBuilder(const std::string& type_name, Communicate* comm)
23  : MPIObjectBase(comm), legacy(true), type_name_(type_name)
24 {
26 }
27 
28 
30 {
31  int sets_needed = nsets - states.size();
32  if (sets_needed > 0)
33  for (int s = 0; s < sets_needed; ++s)
34  states.push_back(std::make_unique<SPOSetInfo>());
35 }
36 
37 
38 std::unique_ptr<SPOSet> SPOSetBuilder::createSPOSet(xmlNodePtr cur, SPOSetInputInfo& input_info)
39 {
40  myComm->barrier_and_abort("BasisSetBase::createSPOSet(cur,input_info) has not been implemented");
41  return 0;
42 }
43 
44 
45 std::unique_ptr<SPOSet> SPOSetBuilder::createSPOSet(xmlNodePtr cur)
46 {
47  std::string spo_object_name;
48  std::string optimize("no");
49 
50  OhmmsAttributeSet attrib;
51  attrib.add(spo_object_name, "id");
52  attrib.add(spo_object_name, "name");
53  attrib.add(optimize, "optimize");
54  attrib.put(cur);
55 
56  app_summary() << std::endl;
57  app_summary() << " Single particle orbitals (SPO)" << std::endl;
58  app_summary() << " ------------------------------" << std::endl;
59  app_summary() << " Name: " << spo_object_name << " Type: " << type_name_
60  << " Builder class name: " << ClassName << std::endl;
61  app_summary() << std::endl;
62 
63  if (spo_object_name.empty())
64  myComm->barrier_and_abort("SPOSet object \"name\" attribute not given in the input!");
65 
66  // read specialized sposet construction requests
67  // and translate them into a set of orbital indices
68  SPOSetInputInfo input_info(cur);
69 
70  // process general sposet construction requests
71  // and preserve legacy interface
72  std::unique_ptr<SPOSet> sposet;
73 
74  try
75  {
76  if (legacy && input_info.legacy_request)
77  sposet = createSPOSetFromXML(cur);
78  else
79  sposet = createSPOSet(cur, input_info);
80  }
81  catch (const UniformCommunicateError& ue)
82  {
83  myComm->barrier_and_abort(ue.what());
84  }
85 
86  if (!sposet)
87  myComm->barrier_and_abort("SPOSetBuilder::createSPOSet sposet creation failed");
88 
89  if (optimize == "rotation" || optimize == "yes")
90  {
91  app_warning() << "Specifying orbital rotation via optimize tag is deprecated. Use the rotated_spo element instead"
92  << std::endl;
93 
94  sposet->storeParamsBeforeRotation();
95  // create sposet with rotation
96  auto& sposet_ref = *sposet;
97  app_log() << " SPOSet " << sposet_ref.getName() << " is optimizable\n";
98  if (!sposet_ref.isRotationSupported())
99  myComm->barrier_and_abort("Orbital rotation not supported with '" + sposet_ref.getName() + "' of type '" +
100  sposet_ref.getClassName() + "'.");
101  auto rot_spo = std::make_unique<RotatedSPOs>(sposet_ref.getName(), std::move(sposet));
102  xmlNodePtr tcur = cur->xmlChildrenNode;
103  while (tcur != NULL)
104  {
105  std::string cname((const char*)(tcur->name));
106  if (cname == "opt_vars")
107  {
108  std::vector<RealType> params;
109  putContent(params, tcur);
110  rot_spo->setRotationParameters(params);
111  }
112  tcur = tcur->next;
113  }
114  sposet = std::move(rot_spo);
115  }
116 
117  if (sposet->getName().empty())
118  app_warning() << "SPOSet object doesn't have a name." << std::endl;
119  if (!spo_object_name.empty() && sposet->getName() != spo_object_name)
120  app_warning() << "SPOSet object name mismatched! input name: " << spo_object_name
121  << " object name: " << sposet->getName() << std::endl;
122 
123  sposet->checkObject();
124  return sposet;
125 }
126 
127 std::unique_ptr<SPOSet> SPOSetBuilder::createRotatedSPOSet(xmlNodePtr cur)
128 {
129  std::string spo_object_name;
130  std::string method;
131  OhmmsAttributeSet attrib;
132  attrib.add(spo_object_name, "name");
133  attrib.add(method, "method", {"global", "history"});
134  attrib.put(cur);
135 
136  std::unique_ptr<SPOSet> sposet;
137  processChildren(cur, [&](const std::string& cname, const xmlNodePtr element) {
138  if (cname == "sposet")
139  {
140  sposet = createSPOSet(element);
141  }
142  });
143 
144  if (!sposet)
145  myComm->barrier_and_abort("Rotated SPO needs an SPOset");
146 
147  if (!sposet->isRotationSupported())
148  myComm->barrier_and_abort("Orbital rotation not supported with '" + sposet->getName() + "' of type '" +
149  sposet->getClassName() + "'.");
150 
151  sposet->storeParamsBeforeRotation();
152  auto rot_spo = std::make_unique<RotatedSPOs>(spo_object_name, std::move(sposet));
153 
154  if (method == "history")
155  rot_spo->set_use_global_rotation(false);
156 
157  processChildren(cur, [&](const std::string& cname, const xmlNodePtr element) {
158  if (cname == "opt_vars")
159  {
160  std::vector<RealType> params;
161  putContent(params, element);
162  rot_spo->setRotationParameters(params);
163  }
164  });
165  return rot_spo;
166 }
167 
168 } // namespace qmcplusplus
std::ostream & app_warning()
Definition: OutputManager.h:69
Base class for any object which needs to know about a MPI communicator.
Definition: MPIObjectBase.h:26
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
class to read state range information from sposet input
std::unique_ptr< SPOSet > createSPOSet(xmlNodePtr cur)
create an sposet from xml and save the resulting SPOSet
std::ostream & app_log()
Definition: OutputManager.h:65
void reserve_states(int nsets=1)
reserve space for states (usually only one set, multiple for e.g. spin dependent einspline) ...
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
std::vector< std::unique_ptr< SPOSetInfo > > states
state info of all possible states available in the basis
Definition: SPOSetBuilder.h:57
SPOSetBuilder(const std::string &type_name, Communicate *comm)
Wrapping information on parallelism.
Definition: Communicate.h:68
Declaration of a base class of SPOSet Builders.
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
This a subclass for runtime errors that will occur on all ranks.
std::string ClassName
class Name
Definition: MPIObjectBase.h:65
const std::string type_name_
type name of the SPO objects built by this builder.
Definition: SPOSetBuilder.h:87
bool putContent(T &a, xmlNodePtr cur)
replaces a&#39;s value with the first "element" in the "string" returned by XMLNodeString{cur}.
Definition: libxmldefs.h:88
void processChildren(const xmlNodePtr cur, const F &functor)
process through all the children of an XML element F is a lambda or functor void F/[](const std::stri...
Definition: libxmldefs.h:175
virtual std::unique_ptr< SPOSet > createSPOSetFromXML(xmlNodePtr cur)=0
create an sposet from xml (legacy)
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
Definition: AttributeSet.h:42
std::unique_ptr< SPOSet > createRotatedSPOSet(xmlNodePtr cur)
create orbital rotation transformation from xml and save the resulting SPOSet
bool legacy
whether implementation conforms only to legacy standard
Definition: SPOSetBuilder.h:54