QMCPACK
HamiltonianFactory Class Reference

Factory class to build a many-body wavefunction. More...

+ Inheritance diagram for HamiltonianFactory:
+ Collaboration diagram for HamiltonianFactory:

Public Types

using PSetMap = std::map< std::string, const std::unique_ptr< ParticleSet > >
 
using PsiPoolType = std::map< std::string, const std::unique_ptr< TrialWaveFunction > >
 
- Public Types inherited from MPIObjectBase
using mpi_comm_type = Communicate::mpi_comm_type
 

Public Member Functions

 HamiltonianFactory (const std::string &hName, ParticleSet &qp, const PSetMap &pset, const PsiPoolType &oset, Communicate *c)
 constructor More...
 
bool put (xmlNodePtr cur)
 read from xmlNode More...
 
void renameProperty (const std::string &a, const std::string &b)
 add a property whose name will be renamed by b More...
 
void renameProperty (std::string &a)
 renamd a property More...
 
QMCHamiltoniangetH () const
 get targetH More...
 
- Public Member Functions inherited from MPIObjectBase
 MPIObjectBase (Communicate *c)
 constructor with communicator More...
 
int rank () const
 return the rank of the communicator More...
 
int getGroupID () const
 return the group id of the communicator More...
 
CommunicategetCommunicator () const
 return myComm More...
 
CommunicategetCommRef () const
 return a TEMPORARY reference to Communicate More...
 
mpi_comm_type getMPI () const
 return MPI communicator if one wants to use MPI directly More...
 
bool is_manager () const
 return true if the rank == 0 More...
 
const std::string & getName () const
 return the name More...
 
void setName (const std::string &aname)
 

Private Member Functions

bool build (xmlNodePtr cur)
 process xmlNode to populate targetPsi More...
 
void addCoulombPotential (xmlNodePtr cur)
 
void addForceHam (xmlNodePtr cur)
 
void addPseudoPotential (xmlNodePtr cur)
 
void addMPCPotential (xmlNodePtr cur, bool physical=false)
 

Private Attributes

int PBCType
 type of the lattice. 0=non-periodic, 1=periodic More...
 
std::unique_ptr< QMCHamiltoniantargetH
 many-body wavefunction object More...
 
ParticleSettargetPtcl
 target ParticleSet More...
 
const PSetMapptclPool
 reference to the PSetMap More...
 
const PsiPoolTypepsiPool
 reference to the TrialWaveFunction Pool More...
 
std::string psiName
 name of the TrialWaveFunction More...
 
std::map< std::string, std::string > RenamedProperty
 list of the old to new name More...
 

Additional Inherited Members

- Protected Attributes inherited from MPIObjectBase
CommunicatemyComm
 pointer to Communicate More...
 
std::string ClassName
 class Name More...
 
std::string myName
 name of the object More...
 

Detailed Description

Factory class to build a many-body wavefunction.

Definition at line 28 of file HamiltonianFactory.h.

Member Typedef Documentation

◆ PSetMap

using PSetMap = std::map<std::string, const std::unique_ptr<ParticleSet> >

Definition at line 31 of file HamiltonianFactory.h.

◆ PsiPoolType

using PsiPoolType = std::map<std::string, const std::unique_ptr<TrialWaveFunction> >

Definition at line 32 of file HamiltonianFactory.h.

Constructor & Destructor Documentation

◆ HamiltonianFactory()

HamiltonianFactory ( const std::string &  hName,
ParticleSet qp,
const PSetMap pset,
const PsiPoolType oset,
Communicate c 
)

constructor

Definition at line 56 of file HamiltonianFactory.cpp.

References MPIObjectBase::ClassName, ParticleSet::getLattice(), MPIObjectBase::myName, HamiltonianFactory::PBCType, ParticleSet::set_quantum(), and HamiltonianFactory::targetPtcl.

61  : MPIObjectBase(c),
62  targetH(std::make_unique<QMCHamiltonian>(hName)),
63  targetPtcl(qp),
64  ptclPool(pset),
65  psiPool(oset),
66  psiName("psi0")
67 {
68  //PBCType is zero or 1 but should be generalized
69  PBCType = targetPtcl.getLattice().SuperCellEnum;
70  ClassName = "HamiltonianFactory";
71  myName = hName;
73 }
std::string myName
name of the object
Definition: MPIObjectBase.h:67
int PBCType
type of the lattice. 0=non-periodic, 1=periodic
const PsiPoolType & psiPool
reference to the TrialWaveFunction Pool
std::string ClassName
class Name
Definition: MPIObjectBase.h:65
std::unique_ptr< QMCHamiltonian > targetH
many-body wavefunction object
const PSetMap & ptclPool
reference to the PSetMap
std::string psiName
name of the TrialWaveFunction
ParticleSet & targetPtcl
target ParticleSet
const auto & getLattice() const
Definition: ParticleSet.h:251
MPIObjectBase(Communicate *c)
constructor with communicator

Member Function Documentation

◆ addCoulombPotential()

void addCoulombPotential ( xmlNodePtr  cur)
private

Definition at line 78 of file CoulombPotentialFactory.cpp.

References OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_log(), qmcplusplus::app_summary(), PlatformSelector< KIND >::candidate_values(), qmcplusplus::DC_POS_OFFLOAD, ERRORMSG, ParticleSet::get(), ParticleSet::getCoordinates(), DynamicCoordinates::getKind(), OhmmsElementBase::getName(), ParticleSet::getTotalNum(), qmcplusplus::OMPTARGET, HamiltonianFactory::PBCType, HamiltonianFactory::ptclPool, OhmmsAttributeSet::put(), PlatformSelector< KIND >::selectPlatform(), HamiltonianFactory::targetH, and HamiltonianFactory::targetPtcl.

Referenced by HamiltonianFactory::build().

79 {
81  std::string targetInp(targetPtcl.getName());
82  std::string sourceInp(targetPtcl.getName());
83  std::string title("ElecElec"), pbc("yes");
84  std::string forces("no");
85  std::string use_gpu;
86  bool physical = true;
87  OhmmsAttributeSet hAttrib;
88  hAttrib.add(title, "id");
89  hAttrib.add(title, "name");
90  hAttrib.add(targetInp, "target");
91  hAttrib.add(sourceInp, "source");
92  hAttrib.add(pbc, "pbc");
93  hAttrib.add(physical, "physical");
94  hAttrib.add(forces, "forces");
95  hAttrib.add(use_gpu, "gpu", CPUOMPTargetSelector::candidate_values);
96  hAttrib.put(cur);
97  const bool applyPBC = (PBCType && pbc == "yes");
98  const bool doForces = (forces == "yes") || (forces == "true");
99 
100  app_summary() << std::endl;
101  app_summary() << " Coulomb Potential" << std::endl;
102  app_summary() << " -----------------" << std::endl;
103  app_summary() << " Name: " << title << " Type: " << (sourceInp == targetInp ? "AA" : "AB")
104  << " PBC: " << (applyPBC ? "yes" : "no") << std::endl;
105  app_summary() << std::endl;
106 
107  ParticleSet* ptclA = &targetPtcl;
108  if (sourceInp != targetPtcl.getName())
109  {
110  //renameProperty(sourceInp);
111  auto pit(ptclPool.find(sourceInp));
112  if (pit == ptclPool.end())
113  {
114  ERRORMSG("Missing source ParticleSet" << sourceInp);
115  APP_ABORT("HamiltonianFactory::addCoulombPotential");
116  return;
117  }
118  ptclA = pit->second.get();
119  }
120 
121  if (sourceInp == targetInp) // AA type
122  {
123  if (!applyPBC && ptclA->getTotalNum() == 1)
124  {
125  app_log() << " CoulombAA for " << sourceInp << " is not created. Number of particles == 1 and nonPeriodic"
126  << std::endl;
127  return;
128  }
129  bool quantum = (sourceInp == targetPtcl.getName());
130  if (applyPBC)
131  {
132  if (use_gpu.empty())
133  use_gpu = ptclA->getCoordinates().getKind() == DynamicCoordinateKind::DC_POS_OFFLOAD ? "yes" : "no";
134 
135  const bool use_offload = CPUOMPTargetSelector::selectPlatform(use_gpu) == PlatformKind::OMPTARGET;
136  if (use_offload)
137  app_summary() << " Running OpenMP offload code path." << std::endl;
138  if (use_offload && ptclA->getCoordinates().getKind() != DynamicCoordinateKind::DC_POS_OFFLOAD)
139  throw std::runtime_error("Requested OpenMP offload in CoulombPBCAA but the particle set has gpu=no.");
140 
141  targetH->addOperator(std::make_unique<CoulombPBCAA>(*ptclA, quantum, doForces, use_offload), title, physical);
142  }
143  else
144  {
145  targetH->addOperator(std::make_unique<CoulombPotential<Return_t>>(*ptclA, quantum, doForces), title, physical);
146  }
147  }
148  else //X-e type, for X=some other source
149  {
150  if (applyPBC)
151  targetH->addOperator(std::make_unique<CoulombPBCAB>(*ptclA, targetPtcl), title);
152  else
153  targetH->addOperator(std::make_unique<CoulombPotential<Return_t>>(*ptclA, targetPtcl, true), title);
154  }
155 }
#define ERRORMSG(msg)
Definition: OutputManager.h:86
const std::string & getName() const
return the name
std::ostream & app_log()
Definition: OutputManager.h:65
QMCTraits::FullPrecRealType FullPrecRealType
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
int PBCType
type of the lattice. 0=non-periodic, 1=periodic
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
static PlatformKind selectPlatform(std::string_view value)
std::unique_ptr< QMCHamiltonian > targetH
many-body wavefunction object
const PSetMap & ptclPool
reference to the PSetMap
ParticleSet & targetPtcl
target ParticleSet
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
BareKineticEnergy::Return_t Return_t
const std::vector< std::string > candidate_values

◆ addForceHam()

void addForceHam ( xmlNodePtr  cur)
private

Definition at line 157 of file CoulombPotentialFactory.cpp.

References OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_log(), ERRORMSG, ParticleSet::get(), OhmmsElementBase::getName(), HamiltonianFactory::PBCType, HamiltonianFactory::psiPool, HamiltonianFactory::ptclPool, OhmmsAttributeSet::put(), TrialWaveFunction::put(), HamiltonianFactory::renameProperty(), HamiltonianFactory::targetH, and HamiltonianFactory::targetPtcl.

Referenced by HamiltonianFactory::build().

158 {
159 #if OHMMS_DIM == 3
160  std::string a("ion0"), targetName("e"), title("ForceBase"), pbc("yes"), PsiName = "psi0";
161  OhmmsAttributeSet hAttrib;
162  std::string mode("bare");
163  //hAttrib.add(title,"id");
164  hAttrib.add(title, "name");
165  hAttrib.add(a, "source");
166  hAttrib.add(targetName, "target");
167  hAttrib.add(pbc, "pbc");
168  hAttrib.add(mode, "mode");
169  hAttrib.add(PsiName, "psi");
170  hAttrib.put(cur);
171  app_log() << "HamFac forceBase mode " << mode << std::endl;
172  bool applyPBC = (PBCType && pbc == "yes");
173 
174  bool quantum = (a == targetPtcl.getName());
175 
176  renameProperty(a);
177  auto pit(ptclPool.find(a));
178  if (pit == ptclPool.end())
179  {
180  ERRORMSG("Missing source ParticleSet" << a)
181  return;
182  }
183  ParticleSet* source = pit->second.get();
184  pit = ptclPool.find(targetName);
185  if (pit == ptclPool.end())
186  {
187  ERRORMSG("Missing target ParticleSet" << targetName)
188  return;
189  }
190  ParticleSet* target = pit->second.get();
191  //bool applyPBC= (PBCType && pbc=="yes");
192  if (mode == "bare")
193  {
194  std::unique_ptr<BareForce> bareforce = std::make_unique<BareForce>(*source, *target);
195  bareforce->put(cur);
196  targetH->addOperator(std::move(bareforce), title, false);
197  }
198  else if (mode == "cep")
199  {
200  if (applyPBC == true)
201  {
202  std::unique_ptr<ForceChiesaPBCAA> force_chi = std::make_unique<ForceChiesaPBCAA>(*source, *target, true);
203  force_chi->put(cur);
204  targetH->addOperator(std::move(force_chi), title, false);
205  }
206  else
207  {
208  std::unique_ptr<ForceCeperley> force_cep = std::make_unique<ForceCeperley>(*source, *target);
209  force_cep->put(cur);
210  targetH->addOperator(std::move(force_cep), title, false);
211  }
212  }
213  else if (mode == "acforce")
214  {
215  app_log() << "Adding Assaraf-Caffarel total force.\n";
216  auto psi_it(psiPool.find(PsiName));
217  if (psi_it == psiPool.end())
218  {
219  APP_ABORT("Unknown psi \"" + PsiName + "\" for zero-variance force.");
220  }
221  TrialWaveFunction& psi = *psi_it->second;
222  std::unique_ptr<ACForce> acforce = std::make_unique<ACForce>(*source, *target, psi, *targetH);
223  acforce->put(cur);
224  targetH->addOperator(std::move(acforce), title, false);
225  }
226  else
227  {
228  ERRORMSG("Failed to recognize Force mode " << mode);
229  }
230 #endif
231 }
#define ERRORMSG(msg)
Definition: OutputManager.h:86
const std::string & getName() const
return the name
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
int PBCType
type of the lattice. 0=non-periodic, 1=periodic
const PsiPoolType & psiPool
reference to the TrialWaveFunction Pool
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
std::unique_ptr< QMCHamiltonian > targetH
many-body wavefunction object
void renameProperty(const std::string &a, const std::string &b)
add a property whose name will be renamed by b
const PSetMap & ptclPool
reference to the PSetMap
ParticleSet & targetPtcl
target ParticleSet
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

◆ addMPCPotential()

void addMPCPotential ( xmlNodePtr  cur,
bool  physical = false 
)
private

Definition at line 41 of file CoulombPotentialFactory.cpp.

References OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_summary(), Communicate::barrier_and_abort(), ParticleSet::Density_G, MPIObjectBase::myComm, OhmmsAttributeSet::put(), HamiltonianFactory::renameProperty(), HamiltonianFactory::targetH, and HamiltonianFactory::targetPtcl.

Referenced by HamiltonianFactory::build().

42 {
43 #if OHMMS_DIM == 3 && defined(HAVE_LIBFFTW)
44  std::string a("e"), title("MPC"), physical("no");
45  OhmmsAttributeSet hAttrib;
46  double cutoff = 30.0;
47  hAttrib.add(title, "id");
48  hAttrib.add(title, "name");
49  hAttrib.add(cutoff, "cutoff");
50  hAttrib.add(physical, "physical");
51  hAttrib.put(cur);
52  renameProperty(a);
53  isphysical = (physical == "yes" || physical == "true");
54 
55  app_summary() << std::endl;
56  app_summary() << " MPC Potential" << std::endl;
57  app_summary() << " -------------" << std::endl;
58  app_summary() << " Name: " << title << " Physical : " << physical << std::endl;
59  app_summary() << std::endl;
60 
61  if (targetPtcl.Density_G.size() == 0)
62  myComm->barrier_and_abort("HamiltonianFactory::addMPCPotential\n"
63  "************************\n"
64  "** Error in MPC setup **\n"
65  "************************\n"
66  " The electron density was not setup by the "
67  "wave function builder.\n");
68 
69  auto mpc = std::make_unique<MPC>(targetPtcl, cutoff);
70  targetH->addOperator(std::move(mpc), "MPC", isphysical);
71 #else
72  APP_ABORT(
73  "HamiltonianFactory::addMPCPotential MPC is disabled because FFTW3 was not found during the build process.");
74 #endif // defined(HAVE_LIBFFTW)
75 }
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
std::vector< ComplexType > Density_G
Definition: ParticleSet.h:98
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
std::unique_ptr< QMCHamiltonian > targetH
many-body wavefunction object
void renameProperty(const std::string &a, const std::string &b)
add a property whose name will be renamed by b
ParticleSet & targetPtcl
target ParticleSet
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

◆ addPseudoPotential()

void addPseudoPotential ( xmlNodePtr  cur)
private

Definition at line 233 of file CoulombPotentialFactory.cpp.

References OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_summary(), qmcplusplus::app_warning(), ERRORMSG, ParticleSet::get(), MPIObjectBase::myComm, HamiltonianFactory::psiName, HamiltonianFactory::psiPool, HamiltonianFactory::ptclPool, ECPotentialBuilder::put(), OhmmsAttributeSet::put(), HamiltonianFactory::renameProperty(), HamiltonianFactory::targetH, and HamiltonianFactory::targetPtcl.

Referenced by HamiltonianFactory::build().

234 {
235 #if OHMMS_DIM == 3
236  std::string src("i"), title("PseudoPot"), wfname("invalid"), format("xml");
237  OhmmsAttributeSet pAttrib;
238  pAttrib.add(title, "name");
239  pAttrib.add(src, "source");
240  pAttrib.add(wfname, "wavefunction");
241  pAttrib.add(format, "format"); //temperary tag to switch between format
242  pAttrib.put(cur);
243  if (format == "old")
244  {
245  APP_ABORT("pseudopotential Table format is not supported.");
246  }
247  renameProperty(src);
248  renameProperty(wfname);
249  auto pit(ptclPool.find(src));
250  if (pit == ptclPool.end())
251  {
252  ERRORMSG("Missing source ParticleSet" << src)
253  return;
254  }
255  ParticleSet* ion = pit->second.get();
256  auto oit(psiPool.find(wfname));
257  TrialWaveFunction* psi = 0;
258  if (oit == psiPool.end())
259  {
260  if (psiPool.empty())
261  return;
262  app_warning() << " Cannot find " << wfname << " in the Wavefunction pool. Using the first wavefunction."
263  << std::endl;
264  psi = psiPool.begin()->second.get();
265  }
266  else
267  {
268  psi = (*oit).second.get();
269  }
270  //remember the TrialWaveFunction used by this pseudopotential
271  psiName = wfname;
272 
273  app_summary() << std::endl;
274  app_summary() << " Pseudo Potential" << std::endl;
275  app_summary() << " ----------------" << std::endl;
276  app_summary() << " Name: " << title << " Wavefunction : " << psiName << std::endl;
277  app_summary() << std::endl;
278 
279  ECPotentialBuilder ecp(*targetH, *ion, targetPtcl, *psi, myComm);
280  ecp.put(cur);
281 #else
282  APP_ABORT("HamiltonianFactory::addPseudoPotential\n pairpot@type=\"pseudo\" is invalid if DIM != 3");
283 #endif
284 }
#define ERRORMSG(msg)
Definition: OutputManager.h:86
std::ostream & app_warning()
Definition: OutputManager.h:69
std::ostream & app_summary()
Definition: OutputManager.h:63
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
const PsiPoolType & psiPool
reference to the TrialWaveFunction Pool
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
std::unique_ptr< QMCHamiltonian > targetH
many-body wavefunction object
void renameProperty(const std::string &a, const std::string &b)
add a property whose name will be renamed by b
const PSetMap & ptclPool
reference to the PSetMap
std::string psiName
name of the TrialWaveFunction
ParticleSet & targetPtcl
target ParticleSet
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

◆ build()

bool build ( xmlNodePtr  cur)
private

process xmlNode to populate targetPsi

main hamiltonian build function

Parameters
curelement node <hamiltonian>
buildtreeif true, build xml tree for a reuse

A valid hamiltonian node contains

Definition at line 88 of file HamiltonianFactory.cpp.

References OhmmsAttributeSet::add(), HamiltonianFactory::addCoulombPotential(), HamiltonianFactory::addForceHam(), HamiltonianFactory::addMPCPotential(), HamiltonianFactory::addPseudoPotential(), APP_ABORT, qmcplusplus::app_log(), qmcplusplus::app_summary(), ParticleSet::get(), OhmmsElementBase::getName(), TrialWaveFunction::getSPOMap(), getXMLAttributeValue(), MPIObjectBase::myComm, MPIObjectBase::myName, HamiltonianFactory::PBCType, processChildren(), HamiltonianFactory::psiName, HamiltonianFactory::psiPool, HamiltonianFactory::ptclPool, OhmmsAttributeSet::put(), Communicate::rank(), HamiltonianFactory::renameProperty(), HamiltonianFactory::targetH, and HamiltonianFactory::targetPtcl.

Referenced by HamiltonianFactory::put().

89 {
90  if (cur == NULL)
91  return false;
92 
93  app_summary() << std::endl;
94  app_summary() << " Hamiltonian and observables" << std::endl;
95  app_summary() << " ---------------------------" << std::endl;
96  app_summary() << " Name: " << myName << std::endl;
97  app_summary() << std::endl;
98 
99  std::string htype("generic"), source("i"), defaultKE("yes");
100  OhmmsAttributeSet hAttrib;
101  hAttrib.add(htype, "type");
102  hAttrib.add(source, "source");
103  hAttrib.add(defaultKE, "default");
104  hAttrib.put(cur);
105  renameProperty(source);
106  auto psi_it(psiPool.find(psiName));
107  if (psi_it == psiPool.end())
108  APP_ABORT("Unknown psi \"" + psiName + "\" for target Psi");
109  TrialWaveFunction* targetPsi = psi_it->second.get();
110  // KineticEnergy must be the first element in the hamiltonian array.
111  if (defaultKE != "no")
112  targetH->addOperator(std::make_unique<BareKineticEnergy>(targetPtcl, *targetPsi), "Kinetic");
113 
114  // Virtual particle sets only need to carry distance tables used by the wavefunction.
115  // Other Hamiltonian elements or estimators may add distance tables in particle sets.
116  // Process pseudopotentials first to minimize the needed distance tables in virtual particle sets.
117  processChildren(cur, [&](const std::string& cname, const xmlNodePtr element) {
118  if (cname == "pairpot" && getXMLAttributeValue(element, "type") == "pseudo")
119  addPseudoPotential(element);
120  });
121 
122  processChildren(cur, [&](const std::string& cname, const xmlNodePtr element) {
123  std::string notype = "0";
124  std::string noname = "any";
125  std::string potType(notype);
126  std::string potName(noname);
127  std::string potUnit("hartree");
128  std::string estType("coulomb");
129  std::string sourceInp(targetPtcl.getName());
130  std::string targetInp(targetPtcl.getName());
131  OhmmsAttributeSet attrib;
132  attrib.add(sourceInp, "source");
133  attrib.add(sourceInp, "sources");
134  attrib.add(targetInp, "target");
135  attrib.add(potType, "type");
136  attrib.add(potName, "name");
137  attrib.add(potUnit, "units");
138  attrib.add(estType, "potential");
139  attrib.put(element);
140  renameProperty(sourceInp);
141  renameProperty(targetInp);
142 
143  int nham = targetH->total_size();
144  if (cname == "pairpot")
145  {
146  if (potType == "coulomb")
147  addCoulombPotential(element);
148  else if (potType == "skpot")
149  {
150  std::unique_ptr<SkPot> hs = std::make_unique<SkPot>(targetPtcl);
151  hs->put(element);
152  targetH->addOperator(std::move(hs), "SkPot", true);
153  }
154 #if OHMMS_DIM == 3
155  else if (potType == "MPC" || potType == "mpc")
156  addMPCPotential(element);
157 #endif
158  }
159  else if (cname == "constant")
160  {
161  //just to support old input
162  if (potType == "coulomb")
163  addCoulombPotential(element);
164  }
165  else if (cname == "extpot")
166  {
167  if (potType == "harmonic_ext" || potType == "HarmonicExt")
168  {
169  std::unique_ptr<HarmonicExternalPotential> hs = std::make_unique<HarmonicExternalPotential>(targetPtcl);
170  hs->put(element);
171  targetH->addOperator(std::move(hs), "HarmonicExt", true);
172  }
173  if (potType == "grid")
174  {
175  std::unique_ptr<GridExternalPotential> hs = std::make_unique<GridExternalPotential>(targetPtcl);
176  hs->put(element);
177  targetH->addOperator(std::move(hs), "Grid", true);
178  }
179  }
180  else if (cname == "estimator")
181  {
182  if (potType == "flux")
183  targetH->addOperator(std::make_unique<ConservedEnergy>(), potName, false);
184  else if (potType == "specieskinetic")
185  {
186  std::unique_ptr<SpeciesKineticEnergy> apot = std::make_unique<SpeciesKineticEnergy>(targetPtcl);
187  apot->put(element);
188  targetH->addOperator(std::move(apot), potName, false);
189  }
190  else if (potType == "latticedeviation")
191  {
192  // find target particle set
193  auto pit(ptclPool.find(targetInp));
194  if (pit == ptclPool.end())
195  {
196  APP_ABORT("Unknown target \"" + targetInp + "\" for LatticeDeviation.");
197  }
198 
199  // find source particle set
200  auto spit(ptclPool.find(sourceInp));
201  if (spit == ptclPool.end())
202  {
203  APP_ABORT("Unknown source \"" + sourceInp + "\" for LatticeDeviation.");
204  }
205 
206  // read xml node
207  OhmmsAttributeSet local_attrib;
208  std::string target_group, source_group;
209  local_attrib.add(target_group, "tgroup");
210  local_attrib.add(source_group, "sgroup");
211  local_attrib.put(element);
212 
213  std::unique_ptr<LatticeDeviationEstimator> apot =
214  std::make_unique<LatticeDeviationEstimator>(*pit->second, *spit->second, target_group, source_group);
215  apot->put(element);
216  targetH->addOperator(std::move(apot), potName, false);
217  }
218  else if (potType == "Force")
219  addForceHam(element);
220  else if (potType == "gofr")
221  {
222  std::unique_ptr<PairCorrEstimator> apot = std::make_unique<PairCorrEstimator>(targetPtcl, sourceInp);
223  apot->put(element);
224  targetH->addOperator(std::move(apot), potName, false);
225  }
226  else if (potType == "density")
227  {
228  std::unique_ptr<DensityEstimator> apot = std::make_unique<DensityEstimator>(targetPtcl);
229  apot->put(element);
230  targetH->addOperator(std::move(apot), potName, false);
231  }
232  else if (potType == "spindensity")
233  {
234  app_log() << " Adding SpinDensity" << std::endl;
235  std::unique_ptr<SpinDensity> apot = std::make_unique<SpinDensity>(targetPtcl);
236  apot->put(element);
237  targetH->addOperator(std::move(apot), potName, false);
238  }
239  else if (potType == "structurefactor")
240  {
241  app_log() << " Adding StaticStructureFactor" << std::endl;
242  std::unique_ptr<StaticStructureFactor> apot = std::make_unique<StaticStructureFactor>(targetPtcl);
243  apot->put(element);
244  targetH->addOperator(std::move(apot), potName, false);
245  }
246  else if (potType == "selfhealingoverlap" || potType == "SelfHealingOverlap")
247  {
248  app_log() << " Adding SelfHealingOverlap" << std::endl;
249  std::unique_ptr<SelfHealingOverlapLegacy> apot = std::make_unique<SelfHealingOverlapLegacy>(*targetPsi);
250  apot->put(element);
251  targetH->addOperator(std::move(apot), potName, false);
252  }
253  else if (potType == "orbitalimages")
254  {
255  app_log() << " Adding OrbitalImages" << std::endl;
256  std::unique_ptr<OrbitalImages> apot =
257  std::make_unique<OrbitalImages>(targetPtcl, ptclPool, myComm, targetPsi->getSPOMap());
258  apot->put(element);
259  targetH->addOperator(std::move(apot), potName, false);
260  }
261 #if !defined(REMOVE_TRACEMANAGER)
262  else if (potType == "energydensity" || potType == "EnergyDensity")
263  {
264  app_log() << " Adding EnergyDensityEstimator" << std::endl;
265  std::unique_ptr<EnergyDensityEstimator> apot = std::make_unique<EnergyDensityEstimator>(ptclPool, defaultKE);
266  apot->put(element);
267  targetH->addOperator(std::move(apot), potName, false);
268  }
269  else if (potType == "dm1b")
270  {
271  app_log() << " Adding DensityMatrices1B" << std::endl;
272  std::string source = "";
273  OhmmsAttributeSet attrib;
274  attrib.add(source, "source");
275  attrib.put(element);
276  auto pit(ptclPool.find(source));
277  ParticleSet* Pc = nullptr;
278  if (source == "")
279  Pc = nullptr;
280  else if (pit != ptclPool.end())
281  Pc = pit->second.get();
282  else
283  {
284  APP_ABORT("Unknown source \"" + source + "\" for DensityMatrices1B");
285  }
286  std::unique_ptr<DensityMatrices1B> apot = std::make_unique<DensityMatrices1B>(targetPtcl, *targetPsi, Pc);
287  apot->put(element);
288  targetH->addOperator(std::move(apot), potName, false);
289  }
290 #endif
291  else if (potType == "sk")
292  {
293  if (PBCType) //only if perioidic
294  {
295  std::unique_ptr<SkEstimator> apot = std::make_unique<SkEstimator>(targetPtcl);
296  apot->put(element);
297  targetH->addOperator(std::move(apot), potName, false);
298  app_log() << "Adding S(k) estimator" << std::endl;
299  }
300  }
301 #if OHMMS_DIM == 3
302  else if (potType == "chiesa")
303  {
304  std::string PsiName = "psi0";
305  std::string SourceName = "e";
306  OhmmsAttributeSet hAttrib;
307  hAttrib.add(PsiName, "psi");
308  hAttrib.add(SourceName, "source");
309  hAttrib.put(element);
310  auto pit(ptclPool.find(SourceName));
311  if (pit == ptclPool.end())
312  {
313  APP_ABORT("Unknown source \"" + SourceName + "\" for Chiesa correction.");
314  }
315  ParticleSet& source = *pit->second;
316  auto psi_it(psiPool.find(PsiName));
317  if (psi_it == psiPool.end())
318  {
319  APP_ABORT("Unknown psi \"" + PsiName + "\" for Chiesa correction.");
320  }
321  const TrialWaveFunction& psi = *psi_it->second;
322  std::unique_ptr<ChiesaCorrection> chiesa = std::make_unique<ChiesaCorrection>(source, psi);
323  targetH->addOperator(std::move(chiesa), "KEcorr", false);
324  }
325  else if (potType == "skall")
326  {
327  std::string SourceName = "";
328  OhmmsAttributeSet attrib;
329  attrib.add(SourceName, "source");
330  attrib.put(element);
331 
332  auto pit(ptclPool.find(SourceName));
333  if (pit == ptclPool.end())
334  {
335  APP_ABORT("Unknown source \"" + SourceName + "\" for SkAll.");
336  }
337 
338  if (PBCType)
339  {
340  std::unique_ptr<SkAllEstimator> apot = std::make_unique<SkAllEstimator>(*pit->second, targetPtcl);
341  apot->put(element);
342  targetH->addOperator(std::move(apot), potName, false);
343  app_log() << "Adding S(k) ALL estimator" << std::endl;
344  }
345  }
346 
347 #endif
348  else if (potType == "Pressure")
349  {
350  if (estType == "coulomb")
351  {
352  std::unique_ptr<Pressure> BP = std::make_unique<Pressure>(targetPtcl);
353  BP->put(element);
354  targetH->addOperator(std::move(BP), "Pressure", false);
355  int nlen(100);
356  attrib.add(nlen, "truncateSum");
357  attrib.put(element);
358  // DMCPressureCorr* DMCP = new DMCPressureCorr(targetPtcl,nlen);
359  // targetH->addOperator(DMCP,"PressureSum",false);
360  }
361  }
362  else if (potType == "momentum")
363  {
364  app_log() << " Adding Momentum Estimator" << std::endl;
365  std::string PsiName = "psi0";
366  OhmmsAttributeSet hAttrib;
367  hAttrib.add(PsiName, "wavefunction");
368  hAttrib.put(element);
369  auto psi_it(psiPool.find(PsiName));
370  if (psi_it == psiPool.end())
371  {
372  APP_ABORT("Unknown psi \"" + PsiName + "\" for momentum.");
373  }
374  std::unique_ptr<MomentumEstimator> ME = std::make_unique<MomentumEstimator>(targetPtcl, *psi_it->second);
375  bool rt(myComm->rank() == 0);
376  ME->putSpecial(element, targetPtcl, rt);
377  targetH->addOperator(std::move(ME), "MomentumEstimator", false);
378  }
379  }
380 
381  if (nham < targetH->total_size()) //if(cname!="text" && cname !="comment")
382  {
383  if (potName == noname)
384  {
385  potName = potType;
386  app_log() << "Provide name for hamiltonian element for type " << potType << std::endl;
387  }
388  //APP_ABORT("HamiltonianFactory::build\n a name for operator of type "+cname+" "+potType+" must be provided in the xml input");
389  targetH->addOperatorType(potName, potType);
390  }
391  });
392 
393  //add observables with physical and simple estimators
394  targetH->addObservables(targetPtcl);
395  //do correction
396  bool dmc_correction = false;
397  processChildren(cur, [&](const std::string& cname, const xmlNodePtr element) {
398  std::string potType("0");
399  OhmmsAttributeSet attrib;
400  attrib.add(potType, "type");
401  attrib.put(element);
402  if (cname == "estimator" && potType == "ForwardWalking")
403  {
404  app_log() << " Adding Forward Walking Operator" << std::endl;
405  std::unique_ptr<ForwardWalking> FW = std::make_unique<ForwardWalking>();
406  FW->putSpecial(element, *targetH, targetPtcl);
407  targetH->addOperator(std::move(FW), "ForwardWalking", false);
408  dmc_correction = true;
409  }
410  });
411  //evaluate the observables again
412  if (dmc_correction)
413  targetH->addObservables(targetPtcl);
414  return true;
415 }
const std::string & getName() const
return the name
int rank() const
return the rank
Definition: Communicate.h:116
std::ostream & app_log()
Definition: OutputManager.h:65
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
int PBCType
type of the lattice. 0=non-periodic, 1=periodic
const PsiPoolType & psiPool
reference to the TrialWaveFunction Pool
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
std::unique_ptr< QMCHamiltonian > targetH
many-body wavefunction object
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...
void renameProperty(const std::string &a, const std::string &b)
add a property whose name will be renamed by b
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
const PSetMap & ptclPool
reference to the PSetMap
std::string psiName
name of the TrialWaveFunction
ParticleSet & targetPtcl
target ParticleSet
void addMPCPotential(xmlNodePtr cur, bool physical=false)
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

◆ getH()

QMCHamiltonian* getH ( ) const
inline

get targetH

Definition at line 58 of file HamiltonianFactory.h.

References HamiltonianFactory::targetH.

Referenced by qmcplusplus::create_CN_Hamiltonian(), and qmcplusplus::TEST_CASE().

58 { return targetH.get(); }
std::unique_ptr< QMCHamiltonian > targetH
many-body wavefunction object

◆ put()

bool put ( xmlNodePtr  cur)

read from xmlNode

Definition at line 429 of file HamiltonianFactory.cpp.

References HamiltonianFactory::build().

Referenced by qmcplusplus::create_CN_Hamiltonian(), and qmcplusplus::TEST_CASE().

430 {
431  bool success = build(cur);
432  return success;
433 }
bool build(xmlNodePtr cur)
process xmlNode to populate targetPsi

◆ renameProperty() [1/2]

void renameProperty ( const std::string &  a,
const std::string &  b 
)

add a property whose name will be renamed by b

Parameters
atarget property whose name should be replaced by b
bnew property name

Definition at line 418 of file HamiltonianFactory.cpp.

References HamiltonianFactory::RenamedProperty.

Referenced by HamiltonianFactory::addForceHam(), HamiltonianFactory::addMPCPotential(), HamiltonianFactory::addPseudoPotential(), and HamiltonianFactory::build().

418 { RenamedProperty[a] = b; }
std::map< std::string, std::string > RenamedProperty
list of the old to new name

◆ renameProperty() [2/2]

void renameProperty ( std::string &  a)

renamd a property

Parameters
acurrent name

If a is found among the RenamedProperty, a is replaced,

Definition at line 420 of file HamiltonianFactory.cpp.

References HamiltonianFactory::RenamedProperty.

421 {
422  std::map<std::string, std::string>::iterator it(RenamedProperty.find(aname));
423  if (it != RenamedProperty.end())
424  {
425  aname = (*it).second;
426  }
427 }
std::map< std::string, std::string > RenamedProperty
list of the old to new name

Member Data Documentation

◆ PBCType

int PBCType
private

◆ psiName

std::string psiName
private

◆ psiPool

const PsiPoolType& psiPool
private

◆ ptclPool

◆ RenamedProperty

std::map<std::string, std::string> RenamedProperty
private

list of the old to new name

Definition at line 85 of file HamiltonianFactory.h.

Referenced by HamiltonianFactory::renameProperty().

◆ targetH

◆ targetPtcl


The documentation for this class was generated from the following files: