QMCPACK
ParticleSetPool.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) 2020 QMCPACK developers.
6 //
7 // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
13 //////////////////////////////////////////////////////////////////////////////////////
14 
15 
16 /**@file ParticleSetPool.cpp
17  * @brief Implements ParticleSetPool operators.
18  */
19 #include "ParticleSetPool.h"
22 #include "ParticleIO/LatticeIO.h"
24 #include "OhmmsData/AttributeSet.h"
25 #include "OhmmsData/Libxml2Doc.h"
29 #include <PlatformSelector.hpp>
30 
31 namespace qmcplusplus
32 {
34  : MPIObjectBase(c), simulation_cell_(std::make_unique<SimulationCell>())
35 {
36  ClassName = "ParticleSetPool";
37  myName = aname;
38 }
39 
41  : MPIObjectBase(other.myComm), simulation_cell_(std::move(other.simulation_cell_)), myPool(std::move(other.myPool))
42 {
43  ClassName = other.ClassName;
44  myName = other.myName;
45 }
46 
48 
49 ParticleSet* ParticleSetPool::getParticleSet(const std::string& pname)
50 {
51  if (auto pit = myPool.find(pname); pit == myPool.end())
52  return nullptr;
53  else
54  return pit->second.get();
55 }
56 
58 {
59  auto mc = dynamic_cast<MCWalkerConfiguration*>(getParticleSet(pname));
60  if (mc == nullptr)
61  {
62  throw std::runtime_error("ParticleSePool::getWalkerSet missing " + pname);
63  }
64  return mc;
65 }
66 
67 void ParticleSetPool::addParticleSet(std::unique_ptr<ParticleSet>&& p)
68 {
69  const auto pit(myPool.find(p->getName()));
70  if (pit == myPool.end())
71  {
72  auto& pname = p->getName();
73  LOGMSG(" Adding " << pname << " ParticleSet to the pool")
74  if (&p->getSimulationCell() != simulation_cell_.get())
75  throw std::runtime_error("Bug detected! ParticleSetPool::addParticleSet requires p created with the simulation "
76  "cell from ParticleSetPool.");
77  myPool.emplace(pname, std::move(p));
78  }
79  else
80  throw std::runtime_error(p->getName() + " exists. Cannot be added again.");
81 }
82 
84 {
85  ReportEngine PRE("ParticleSetPool", "putLattice");
86 
87  bool lattice_defined = false;
88  try
89  {
90  LatticeParser a(simulation_cell_->lattice_);
91  lattice_defined = a.put(cur);
92  }
93  catch (const UniformCommunicateError& ue)
94  {
95  myComm->barrier_and_abort(ue.what());
96  }
97 
98  if (lattice_defined)
99  {
100  app_log() << " Overwriting global supercell " << std::endl;
101  simulation_cell_->resetLRBox();
103  simulation_cell_->lattice_.print(app_log(), 2);
104  else
105  simulation_cell_->lattice_.print(app_summary(), 1);
106  }
107  return lattice_defined;
108 }
109 
110 /** process an xml element
111  * @param cur current xmlNodePtr
112  * @return true, if successful.
113  *
114  * Creating MCWalkerConfiguration for all the ParticleSet
115  * objects.
116  */
117 bool ParticleSetPool::put(xmlNodePtr cur)
118 {
119  ReportEngine PRE("ParticleSetPool", "put");
120  std::string id("e");
121  std::string role("none");
122  std::string randomR("no");
123  std::string randomsrc;
124  std::string useGPU;
125  std::string spinor;
126  OhmmsAttributeSet pAttrib;
127  pAttrib.add(id, "id");
128  pAttrib.add(id, "name");
129  pAttrib.add(role, "role");
130  pAttrib.add(randomR, "random");
131  pAttrib.add(randomsrc, "randomsrc");
132  pAttrib.add(randomsrc, "random_source");
133  pAttrib.add(spinor, "spinor", {"no", "yes"});
134  pAttrib.add(useGPU, "gpu", CPUOMPTargetSelector::candidate_values);
135  pAttrib.put(cur);
136  //backward compatibility
137  if (id == "e" && role == "none")
138  role = "MC";
139  ParticleSet* pTemp = getParticleSet(id);
140  if (pTemp == 0)
141  {
142  const bool use_offload = CPUOMPTargetSelector::selectPlatform(useGPU) == PlatformKind::OMPTARGET;
143  app_summary() << std::endl;
144  app_summary() << " Particle Set" << std::endl;
145  app_summary() << " ------------" << std::endl;
146  app_summary() << " Name: " << id << " Offload : " << (use_offload ? "yes" : "no") << std::endl;
147  app_summary() << std::endl;
148 
149  // select OpenMP offload implementation in ParticleSet.
150  if (use_offload)
152  else
154 
155  myPool.emplace(id, pTemp);
156 
157  try
158  {
159  XMLParticleParser pread(*pTemp);
160  pread.readXML(cur);
161  }
162  catch (const UniformCommunicateError& ue)
163  {
164  myComm->barrier_and_abort(ue.what());
165  }
166 
167  //if random_source is given, create a node <init target="" soruce=""/>
168  if (randomR == "yes" && !randomsrc.empty())
169  {
170  xmlNodePtr anode = xmlNewNode(NULL, (const xmlChar*)"init");
171  xmlNewProp(anode, (const xmlChar*)"source", (const xmlChar*)randomsrc.c_str());
172  xmlNewProp(anode, (const xmlChar*)"target", (const xmlChar*)id.c_str());
173  randomize_nodes.push_back(anode);
174  }
175  pTemp->setName(id);
176  pTemp->setSpinor(spinor == "yes");
177  app_summary() << " Particle set size: " << pTemp->getTotalNum() << " Groups : " << pTemp->groups() << std::endl;
178  app_summary() << std::endl;
179  return true;
180  }
181  else
182  {
183  app_warning() << "Particle set " << id << " is already created. Ignoring this section." << std::endl;
184  }
185  app_summary() << std::endl;
186  return true;
187 }
188 
190 {
191  app_log() << "ParticleSetPool::randomize " << randomize_nodes.size() << " ParticleSet"
192  << (randomize_nodes.size() == 1 ? "" : "s") << "." << std::endl;
193  bool success = true;
194  for (int i = 0; i < randomize_nodes.size(); ++i)
195  {
196  InitMolecularSystem moinit(*this);
197  success &= moinit.put(randomize_nodes[i]);
198  xmlFreeNode(randomize_nodes[i]);
199  }
200  randomize_nodes.clear();
201  if (!success)
202  throw std::runtime_error("ParticleSePool::randomize failed to randomize some Particlesets!");
203 }
204 
205 bool ParticleSetPool::get(std::ostream& os) const
206 {
207  os << "ParticleSetPool has: " << std::endl << std::endl;
208  os.setf(std::ios::scientific, std::ios::floatfield);
209  os.precision(14);
210  for (const auto& [name, pset] : myPool)
212  pset->print(os, 0);
213  else
214  pset->print(os, 10 /* maxParticlesToPrint */);
215  return true;
216 }
217 
219 {
220  xmlNodePtr particles_info = doc.addChild(root, "particles");
221  PoolType::const_iterator it(myPool.begin()), it_end(myPool.end());
222  while (it != it_end)
223  {
224  xmlNodePtr particle = doc.addChild(particles_info, "particle");
225  doc.addChild(particle, "name", (*it).second->getName());
226  doc.addChild(particle, "size", (*it).second->getTotalNum());
227  ++it;
228  }
229 }
230 
231 /** reset is used to initialize and evaluate the distance tables
232  */
234 {
235  for (const auto& [key, pset] : myPool)
236  pset->update();
237 }
238 
239 } // namespace qmcplusplus
MCWalkerConfiguration * getWalkerSet(const std::string &pname)
get a named MCWalkerConfiguration
void setName(const std::string &aname)
Definition: ParticleSet.h:237
class that handles xmlDoc
Definition: Libxml2Doc.h:76
ParticleSetPool(Communicate *c, const char *aname="particleset")
constructor
A set of walkers that are to be advanced by Metropolis Monte Carlo.
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
void reset()
reset is used to initialize and evaluate the distance tables
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
bool put(xmlNodePtr cur)
process an xml element
bool isHighActive() const
Definition: OutputManager.h:47
size_t getTotalNum() const
Definition: ParticleSet.h:493
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
Definition: LatticeIO.cpp:32
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
std::string myName
name of the object
Definition: MPIObjectBase.h:67
void addParticleSet(std::unique_ptr< ParticleSet > &&p)
add a ParticleSet* to the pool with its ownership transferred ParticleSet built outside the ParticleS...
OutputManagerClass outputManager(Verbosity::HIGH)
void output_particleset_info(Libxml2Document &doc, xmlNodePtr root)
Wrapping information on parallelism.
Definition: Communicate.h:68
int groups() const
return the number of groups
Definition: ParticleSet.h:511
std::unique_ptr< SimulationCell > simulation_cell_
global simulation cell
bool get(std::ostream &os) const
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
Declaration of InitMolecularSystem.
ParticleSet * getParticleSet(const std::string &pname)
get a named ParticleSet
Final class and should not be derived.
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.
declaration of ProgressReportEngine
Manage a collection of ParticleSet objects.
std::string ClassName
class Name
Definition: MPIObjectBase.h:65
bool readXML(xmlNodePtr cur)
process xmlnode <particleset/> which contains everything about the particle set to initialize ...
std::vector< xmlNodePtr > randomize_nodes
xml node for random initialization.
static PlatformKind selectPlatform(std::string_view value)
bool readSimulationCellXML(xmlNodePtr cur)
initialize the supercell shared by all the particle sets
bool isDebugActive() const
Definition: OutputManager.h:45
void randomize()
randomize a particleset particleset/=&#39;yes&#39; && particleset exists
void addChild(xmlNodePtr newnode)
Definition: Libxml2Doc.cpp:111
Define a LRHandler with two template parameters.
void setSpinor(bool is_spinor)
Definition: ParticleSet.h:257
void barrier_and_abort(const std::string &msg) const
bool get(std::ostream &os) const override
dummy. For satisfying OhmmsElementBase.
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
bool put(std::istream &is) override
read from std::istream
PoolType myPool
List of ParticleSet owned.
#define LOGMSG(msg)
Definition: OutputManager.h:82
Declaration of ParticleSetPool.
const std::vector< std::string > candidate_values