QMCPACK
CoulombPotentialFactory.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: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
9 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 /**@file HamiltonianFactory.cpp
16  *@brief Manage instantiation of Coulomb-related potentials
17  */
24 #include "OhmmsData/AttributeSet.h"
25 #include <PlatformSelector.hpp>
26 
27 #if OHMMS_DIM == 3
33 #if defined(HAVE_LIBFFTW)
34 #include "QMCHamiltonians/MPC.h"
35 #endif
36 #endif
37 
38 //#include <iostream>
39 namespace qmcplusplus
40 {
41 void HamiltonianFactory::addMPCPotential(xmlNodePtr cur, bool isphysical)
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 }
76 
77 
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 }
156 
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 }
232 
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 }
285 
286 } // namespace qmcplusplus
#define ERRORMSG(msg)
Definition: OutputManager.h:86
const std::string & getName() const
return the name
std::ostream & app_warning()
Definition: OutputManager.h:69
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
size_t getTotalNum() const
Definition: ParticleSet.h:493
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
const PsiPoolType & psiPool
reference to the TrialWaveFunction Pool
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
DynamicCoordinateKind getKind() const
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
Declaration of a HamiltonianFactory.
#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
void renameProperty(const std::string &a, const std::string &b)
add a property whose name will be renamed by b
const DynamicCoordinates & getCoordinates() const
Definition: ParticleSet.h:246
const PSetMap & ptclPool
reference to the PSetMap
Class to represent a many-body trial wave function.
std::string psiName
name of the TrialWaveFunction
bool put(xmlNodePtr cur)
read from xmlNode
ParticleSet & targetPtcl
target ParticleSet
void addMPCPotential(xmlNodePtr cur, bool physical=false)
Declaration of ACForce, Assaraf-Caffarel ZVZB style force estimation.
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
BareKineticEnergy::Return_t Return_t
Declaration of QMCHamiltonian.
const std::vector< std::string > candidate_values