QMCPACK
CoulombPotential.h
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: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
11 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #ifndef QMCPLUSPLUS_COULOMBPOTENTIAL_H
18 #define QMCPLUSPLUS_COULOMBPOTENTIAL_H
19 #include "ParticleSet.h"
20 #include "DistanceTable.h"
21 #include "MCWalkerConfiguration.h"
25 #include <numeric>
26 
27 namespace qmcplusplus
28 {
30 
31 /** CoulombPotential
32  * @tparam T type of the elementary data
33  *
34  * Hamiltonian operator for the Coulomb interaction for both AA and AB type for open systems.
35  */
36 template<typename T>
37 struct CoulombPotential : public OperatorBase, public ForceBase
38 {
39  ///source particle set
41  ///target particle set
43  ///distance table index
44  const int myTableIndex;
45  ///true if the table is AA
46  const bool is_AA;
47  ///true, if CoulombAA for quantum particleset
48  bool is_active;
49  ///number of centers
50  int nCenters;
51 #if !defined(REMOVE_TRACEMANAGER)
52  ///single particle trace samples
55 #endif
56 
57  /// Flag for whether to compute forces or not
59 
60  /** constructor for AA
61  * @param s source particleset
62  * @param active if true, new Value is computed whenver evaluate is used.
63  * @param computeForces if true, computes forces between inactive species
64  */
65  inline CoulombPotential(ParticleSet& s, bool active, bool computeForces, bool copy = false)
66  : ForceBase(s, s),
67  Pa(s),
68  Pb(s),
70  is_AA(true),
71  is_active(active),
72  ComputeForces(computeForces)
73  {
76  nCenters = s.getTotalNum();
77  prefix_ = "F_AA";
78 
79  if (!is_active) //precompute the value
80  {
81  if (!copy)
82  s.update();
83  value_ = evaluateAA(s.getDistTableAA(myTableIndex), s.Z.first_address());
84  if (ComputeForces)
85  evaluateAAForces(s.getDistTableAA(myTableIndex), s.Z.first_address());
86  }
87  }
88 
89  /** constructor for AB
90  * @param s source particleset
91  * @param t target particleset
92  * @param active if true, new Value is computed whenver evaluate is used.
93  * @param ComputeForces is not implemented for AB
94  */
95  inline CoulombPotential(ParticleSet& s, ParticleSet& t, bool active, bool copy = false)
96  : ForceBase(s, t),
97  Pa(s),
98  Pb(t),
99  myTableIndex(t.addTable(s)),
100  is_AA(false),
101  is_active(active),
102  ComputeForces(false)
103  {
106  nCenters = s.getTotalNum();
107  }
108 
109  std::string getClassName() const override { return "CoulombPotential"; }
110 
111 #if !defined(REMOVE_TRACEMANAGER)
113 
115  {
118  {
119  Va_sample = tm.checkout_real<1>(name_, Pa);
120  if (!is_AA)
121  {
122  Vb_sample = tm.checkout_real<1>(name_, Pb);
123  }
124  else if (!is_active)
125  evaluate_spAA(Pa.getDistTableAA(myTableIndex), Pa.Z.first_address());
126  }
127  }
128 
129  void deleteParticleQuantities() override
130  {
132  {
133  delete Va_sample;
134  if (!is_AA)
135  delete Vb_sample;
136  }
137  }
138 #endif
139 
140  inline void addObservables(PropertySetType& plist, BufferType& collectables) override
141  {
142  addValue(plist);
143  if (ComputeForces)
144  addObservablesF(plist);
145  }
146 
147  /** evaluate AA-type interactions */
148  inline T evaluateAA(const DistanceTableAA& d, const ParticleScalar* restrict Z)
149  {
150  T res = 0.0;
151 #if !defined(REMOVE_TRACEMANAGER)
153  res = evaluate_spAA(d, Z);
154  else
155 #endif
156  for (size_t iat = 1; iat < nCenters; ++iat)
157  {
158  const auto& dist = d.getDistRow(iat);
159  T q = Z[iat];
160  for (size_t j = 0; j < iat; ++j)
161  res += q * Z[j] / dist[j];
162  }
163  return res;
164  }
165 
166 
167  /** evaluate AA-type forces */
168  inline void evaluateAAForces(const DistanceTableAA& d, const ParticleScalar* restrict Z)
169  {
170  forces_ = 0.0;
171  for (size_t iat = 1; iat < nCenters; ++iat)
172  {
173  const auto& dist = d.getDistRow(iat);
174  const auto& displ = d.getDisplRow(iat);
175  T q = Z[iat];
176  for (size_t j = 0; j < iat; ++j)
177  {
178  forces_[iat] += -q * Z[j] * displ[j] / (dist[j] * dist[j] * dist[j]);
179  forces_[j] -= -q * Z[j] * displ[j] / (dist[j] * dist[j] * dist[j]);
180  }
181  }
182  }
183 
184 
185  /** JNKIM: Need to check the precision */
186  inline T evaluateAB(const DistanceTableAB& d, const ParticleScalar* restrict Za, const ParticleScalar* restrict Zb)
187  {
188  constexpr T czero(0);
189  T res = czero;
190 #if !defined(REMOVE_TRACEMANAGER)
192  res = evaluate_spAB(d, Za, Zb);
193  else
194 #endif
195  {
196  const size_t nTargets = d.targets();
197  for (size_t b = 0; b < nTargets; ++b)
198  {
199  const auto& dist = d.getDistRow(b);
200  T e = czero;
201  for (size_t a = 0; a < nCenters; ++a)
202  e += Za[a] / dist[a];
203  res += e * Zb[b];
204  }
205  }
206  return res;
207  }
208 
209 
210 #if !defined(REMOVE_TRACEMANAGER)
211  /** evaluate AA-type interactions */
212  inline T evaluate_spAA(const DistanceTableAA& d, const ParticleScalar* restrict Z)
213  {
214  T res = 0.0;
215  T pairpot;
216  Array<RealType, 1>& Va_samp = *Va_sample;
217  Va_samp = 0.0;
218  for (size_t iat = 1; iat < nCenters; ++iat)
219  {
220  const auto& dist = d.getDistRow(iat);
221  T q = Z[iat];
222  for (size_t j = 0; j < iat; ++j)
223  {
224  pairpot = 0.5 * q * Z[j] / dist[j];
225  Va_samp(iat) += pairpot;
226  Va_samp(j) += pairpot;
227  res += pairpot;
228  }
229  }
230  res *= 2.0;
231 #if defined(TRACE_CHECK)
232  auto sptmp = streaming_particles_;
233  streaming_particles_ = false;
234  T Vnow = res;
235  T Vsum = Va_samp.sum();
236  T Vorig = evaluateAA(d, Z);
237  if (std::abs(Vorig - Vnow) > TraceManager::trace_tol)
238  {
239  app_log() << "versiontest: CoulombPotential::evaluateAA()" << std::endl;
240  app_log() << "versiontest: orig:" << Vorig << std::endl;
241  app_log() << "versiontest: mod:" << Vnow << std::endl;
242  APP_ABORT("Trace check failed");
243  }
244  if (std::abs(Vsum - Vnow) > TraceManager::trace_tol)
245  {
246  app_log() << "accumtest: CoulombPotential::evaluateAA()" << std::endl;
247  app_log() << "accumtest: tot:" << Vnow << std::endl;
248  app_log() << "accumtest: sum:" << Vsum << std::endl;
249  APP_ABORT("Trace check failed");
250  }
251  streaming_particles_ = sptmp;
252 #endif
253  return res;
254  }
255 
256 
257  inline T evaluate_spAB(const DistanceTableAB& d, const ParticleScalar* restrict Za, const ParticleScalar* restrict Zb)
258  {
259  T res = 0.0;
260  T pairpot;
261  Array<RealType, 1>& Va_samp = *Va_sample;
262  Array<RealType, 1>& Vb_samp = *Vb_sample;
263  Va_samp = 0.0;
264  Vb_samp = 0.0;
265  const size_t nTargets = d.targets();
266  for (size_t b = 0; b < nTargets; ++b)
267  {
268  const auto& dist = d.getDistRow(b);
269  T z = 0.5 * Zb[b];
270  for (size_t a = 0; a < nCenters; ++a)
271  {
272  pairpot = z * Za[a] / dist[a];
273  Va_samp(a) += pairpot;
274  Vb_samp(b) += pairpot;
275  res += pairpot;
276  }
277  }
278  res *= 2.0;
279 
280 #if defined(TRACE_CHECK)
281  auto sptmp = streaming_particles_;
282  streaming_particles_ = false;
283  T Vnow = res;
284  T Vasum = Va_samp.sum();
285  T Vbsum = Vb_samp.sum();
286  T Vsum = Vasum + Vbsum;
287  T Vorig = evaluateAB(d, Za, Zb);
288  if (std::abs(Vorig - Vnow) > TraceManager::trace_tol)
289  {
290  app_log() << "versiontest: CoulombPotential::evaluateAB()" << std::endl;
291  app_log() << "versiontest: orig:" << Vorig << std::endl;
292  app_log() << "versiontest: mod:" << Vnow << std::endl;
293  APP_ABORT("Trace check failed");
294  }
295  if (std::abs(Vsum - Vnow) > TraceManager::trace_tol)
296  {
297  app_log() << "accumtest: CoulombPotential::evaluateAB()" << std::endl;
298  app_log() << "accumtest: tot:" << Vnow << std::endl;
299  app_log() << "accumtest: sum:" << Vsum << std::endl;
300  APP_ABORT("Trace check failed");
301  }
302  if (std::abs(Vasum - Vbsum) > TraceManager::trace_tol)
303  {
304  app_log() << "sharetest: CoulombPotential::evaluateAB()" << std::endl;
305  app_log() << "sharetest: a share:" << Vasum << std::endl;
306  app_log() << "sharetest: b share:" << Vbsum << std::endl;
307  APP_ABORT("Trace check failed");
308  }
309  streaming_particles_ = sptmp;
310 #endif
311  return res;
312  }
313 #endif
314 
315 
317  {
318  //myTableIndex is the same
319  }
320 
321  ~CoulombPotential() override {}
322 
323  void updateSource(ParticleSet& s) override
324  {
325  if (is_AA)
326  {
327  value_ = evaluateAA(s.getDistTableAA(myTableIndex), s.Z.first_address());
328  }
329  }
330 
331  inline Return_t evaluate(ParticleSet& P) override
332  {
333  if (is_active)
334  {
335  if (is_AA)
336  value_ = evaluateAA(P.getDistTableAA(myTableIndex), P.Z.first_address());
337  else
338  value_ = evaluateAB(P.getDistTableAB(myTableIndex), Pa.Z.first_address(), P.Z.first_address());
339  }
340  return value_;
341  }
342 
344  ParticleSet& ions,
345  TrialWaveFunction& psi,
346  ParticleSet::ParticlePos& hf_terms,
347  ParticleSet::ParticlePos& pulay_terms) override
348  {
349  if (is_active)
350  value_ = evaluate(P); // No forces for the active
351  else
352  hf_terms -= forces_; // No Pulay here
353  return value_;
354  }
355 
356  bool put(xmlNodePtr cur) override { return true; }
357 
358  bool get(std::ostream& os) const override
359  {
360  if (myTableIndex)
361  os << "CoulombAB source=" << Pa.getName() << std::endl;
362  else
363  os << "CoulombAA source/target " << Pa.getName() << std::endl;
364  return true;
365  }
366 
367  void setObservables(PropertySetType& plist) override
368  {
370  if (ComputeForces)
371  setObservablesF(plist);
372  }
373 
374  void setParticlePropertyList(PropertySetType& plist, int offset) override
375  {
377  if (ComputeForces)
378  setParticleSetF(plist, offset);
379  }
380 
381 
382  std::unique_ptr<OperatorBase> makeClone(ParticleSet& qp, TrialWaveFunction& psi) override
383  {
384  if (is_AA)
385  {
386  if (is_active)
387  return std::make_unique<CoulombPotential>(qp, true, ComputeForces);
388  else
389  // Ye Luo April 16th, 2015
390  // avoid recomputing ion-ion DistanceTable when reusing ParticleSet
391  return std::make_unique<CoulombPotential>(Pa, false, ComputeForces, true);
392  }
393  else
394  return std::make_unique<CoulombPotential>(Pa, qp, true);
395  }
396 };
397 
398 } // namespace qmcplusplus
399 #endif
void twoBodyQuantumDomain(const ParticleSet &P)
set quantum domain for two-body operator
T evaluate_spAB(const DistanceTableAB &d, const ParticleScalar *restrict Za, const ParticleScalar *restrict Zb)
void deleteParticleQuantities() override
std::string getClassName() const override
return class name
const std::string & getName() const
return the name
void addObservables(PropertySetType &plist, BufferType &collectables) override
named values to the property list Default implementaton uses addValue(plist_)
Return_t evaluateWithIonDerivs(ParticleSet &P, ParticleSet &ions, TrialWaveFunction &psi, ParticleSet::ParticlePos &hf_terms, ParticleSet::ParticlePos &pulay_terms) override
Evaluate contribution to local energy and derivatives w.r.t ionic coordinates from OperatorBase...
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
const DistanceTableAA & getDistTableAA(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAA
bool streaming_array(const std::string &name)
Definition: TraceManager.h:249
void contributeParticleQuantities() override
void checkoutParticleQuantities(TraceManager &tm) override
const DistRow & getDistRow(int iel) const
return a row of distances for a given target particle
ParticleSet::ParticlePos forces_
Definition: ForceBase.h:87
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::ostream & app_log()
Definition: OutputManager.h:65
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
bool put(xmlNodePtr cur) override
Read the input parameter.
const int myTableIndex
distance table index
ParticleSet & Pa
source particle set
Declaration of OperatorBase.
const bool is_AA
true if the table is AA
void addObservablesF(QMCTraits::PropertySetType &plist)
Definition: ForceBase.cpp:47
Vectorized record engine for scalar properties.
T evaluate_spAA(const DistanceTableAA &d, const ParticleScalar *restrict Z)
evaluate AA-type interactions
Attaches a unit to a Vector for IO.
void resetTargetParticleSet(ParticleSet &P) override
Reset the data with the target ParticleSet.
std::string prefix_
Definition: ForceBase.h:96
TraceRequest request_
whether traces are being collected
Definition: OperatorBase.h:531
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
Definition: Blitz.h:639
const DistanceTableAB & getDistTableAB(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAB
std::string name_
name of this object
Definition: OperatorBase.h:527
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
void setObservables(PropertySetType &plist) override
Set the values evaluated by this object to plist Default implementation is to assign Value which is u...
Return_t evaluate(ParticleSet &P) override
Evaluate the local energy contribution of this component.
WalkerProperties::Indexes WP
Definition: ParticleSet.cpp:34
CoulombPotential(ParticleSet &s, bool active, bool computeForces, bool copy=false)
constructor for AA
AB type of DistanceTable containing storage.
size_t targets() const
returns the number of centers
Definition: DistanceTable.h:94
Array< TraceReal, 1 > * Va_sample
single particle trace samples
ParticleSet & Pb
target particle set
std::unique_ptr< OperatorBase > makeClone(ParticleSet &qp, TrialWaveFunction &psi) override
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void setEnergyDomain(EnergyDomains edomain)
Set the Energy Domain.
void setParticleSetF(QMCTraits::PropertySetType &plist, int offset)
Definition: ForceBase.cpp:113
const DistRow & getDistRow(int iel) const
return a row of distances for a given target particle
void addValue(PropertySetType &plist)
named values to the property list
Array< TraceReal, 1 > * Vb_sample
ParticleScalar Z
charge of each particle
Definition: ParticleSet.h:89
AA type of DistanceTable containing storage.
Array< TraceReal, D > * checkout_real(const std::string &name, int n1=1, int n2=0, int n3=0, int n4=0)
ParticleSet::Scalar_t ParticleScalar
typedef for the ParticleScalar
Definition: OperatorBase.h:81
An abstract class for Local Energy operators.
Definition: OperatorBase.h:59
FullPrecRealType Return_t
type of return value of evaluate
Definition: OperatorBase.h:64
const DisplRow & getDisplRow(int iel) const
return a row of displacements for a given target particle
Type_t sum() const
Definition: OhmmsArray.h:214
virtual void setParticlePropertyList(PropertySetType &plist, int offset)
void setObservablesF(QMCTraits::PropertySetType &plist)
Definition: ForceBase.cpp:86
Class to represent a many-body trial wave function.
bool is_active
true, if CoulombAA for quantum particleset
Return_t value_
current value
Definition: OperatorBase.h:524
void setParticlePropertyList(PropertySetType &plist, int offset) override
Indexes
an enum denoting index of physical properties
void evaluateAAForces(const DistanceTableAA &d, const ParticleScalar *restrict Z)
evaluate AA-type forces
T evaluateAA(const DistanceTableAA &d, const ParticleScalar *restrict Z)
evaluate AA-type interactions
CoulombPotential(ParticleSet &s, ParticleSet &t, bool active, bool copy=false)
constructor for AB
void contribute_array(const std::string &name, bool default_quantity=false)
Definition: TraceManager.h:198
bool ComputeForces
Flag for whether to compute forces or not.
virtual void setObservables(PropertySetType &plist)
Set the values evaluated by this object to plist Default implementation is to assign Value which is u...
T evaluateAB(const DistanceTableAB &d, const ParticleScalar *restrict Za, const ParticleScalar *restrict Zb)
JNKIM: Need to check the precision.
int nCenters
number of centers
whether full table needs to be ready at anytime or not after donePbyP Optimization can be implemented...
Declaration of a MCWalkerConfiguration.
void updateSource(ParticleSet &s) override
Update data associated with a particleset.