QMCPACK
L2Potential.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 //
9 // File created by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "Particle/ParticleSet.h"
14 #include "DistanceTable.h"
15 #include "L2Potential.h"
17 
18 namespace qmcplusplus
19 {
20 L2Potential::L2Potential(const ParticleSet& ions, ParticleSet& els, TrialWaveFunction& psi) : IonConfig(ions)
21 {
23  twoBodyQuantumDomain(ions, els);
24  NumIons = ions.getTotalNum();
25  myTableIndex = els.addTable(ions);
26  size_t ns = ions.getSpeciesSet().getTotalNum();
27  PPset.resize(ns);
28  PP.resize(NumIons, nullptr);
29  psi_ref = ψ
30 }
31 
33 {
34  int tid = P.addTable(IonConfig);
35  if (tid != myTableIndex)
36  {
37  APP_ABORT(" L2Potential::resetTargetParticleSet found a different distance table index.");
38  }
39 }
40 
41 
42 void L2Potential::add(int groupID, std::unique_ptr<L2RadialPotential>&& ppot)
43 {
44  for (int iat = 0; iat < PP.size(); iat++)
45  if (IonConfig.GroupID[iat] == groupID)
46  PP[iat] = ppot.get();
47  PPset[groupID] = std::move(ppot);
48 }
49 
50 
52 {
53  // compute the Hessian
55  // evaluateHessian gives the Hessian(log(Psi))
56  psi_ref->evaluateHessian(P, D2);
57  // add gradient terms to get (Hessian(Psi))/Psi instead
58  const size_t N = P.getTotalNum();
59  for (size_t n = 0; n < N; n++)
60  for (size_t i = 0; i < DIM; i++)
61  for (size_t j = 0; j < DIM; j++)
62  D2[n](i, j) += P.G[n][i] * P.G[n][j];
63 
64  // compute v_L2(r)*L^2 for all electron-ion pairs
65  const auto& d_table(P.getDistTableAB(myTableIndex));
66  value_ = 0.0;
67  const size_t Nelec = P.getTotalNum();
68  for (size_t iel = 0; iel < Nelec; ++iel)
69  {
70  const auto Le = P.L[iel];
71  const auto& ge = P.G[iel];
72  const auto& D2e = D2[iel];
73  const auto& dist = d_table.getDistRow(iel);
74  const auto& disp = d_table.getDisplRow(iel);
75  Return_t esum = 0.0;
76  for (size_t iat = 0; iat < NumIons; ++iat)
77  {
78  RealType r = dist[iat];
79  if (PP[iat] != nullptr && r < PP[iat]->rcut)
80  {
81  PosType rv = disp[iat]; //SoA rv is r_I-r_e
82  RealType v = -r * r * std::real(Le);
83  for (int i = 0; i < DIM; ++i)
84  v += -r * r * std::real(ge[i] * ge[i]) - 2 * rv[i] * std::real(ge[i]);
85  for (int i = 0; i < DIM; ++i)
86  for (int j = 0; j < DIM; ++j)
87  v += rv[i] * std::real(D2e(i, j)) * rv[j];
88  esum += v * PP[iat]->evaluate(dist[iat]);
89  }
90  }
91  value_ += esum;
92  }
93  return value_;
94 }
95 
96 
98 {
99  K = 0.0;
100  D = 0.0;
101  D.diagonal(1.0);
102 
103  const auto& d_table(P.getDistTableAB(myTableIndex));
104 
105  for (int iat = 0; iat < NumIons; iat++)
106  {
107  L2RadialPotential* ppot = PP[iat];
108  if (ppot == nullptr)
109  continue;
110  RealType r = d_table.getTempDists()[iat];
111  if (r < ppot->rcut)
112  {
113  PosType rv = -1 * d_table.getTempDispls()[iat];
114  RealType vL2 = ppot->evaluate(r);
115  K += 2 * rv * vL2;
116  for (int i = 0; i < DIM; ++i)
117  D(i, i) += 2 * vL2 * r * r;
118  for (int i = 0; i < DIM; ++i)
119  for (int j = 0; j < DIM; ++j)
120  D(i, j) -= 2 * vL2 * rv[i] * rv[j];
121  }
122  }
123 }
124 
125 
127 {
128  D = 0.0;
129  D.diagonal(1.0);
130 
131  const auto& d_table(P.getDistTableAB(myTableIndex));
132 
133  for (int iat = 0; iat < NumIons; iat++)
134  {
135  L2RadialPotential* ppot = PP[iat];
136  if (ppot == nullptr)
137  continue;
138  RealType r = d_table.getTempDists()[iat];
139  if (r < ppot->rcut)
140  {
141  PosType rv = d_table.getTempDispls()[iat];
142  RealType vL2 = ppot->evaluate(r);
143  for (int i = 0; i < DIM; ++i)
144  D(i, i) += 2 * vL2 * r * r;
145  for (int i = 0; i < DIM; ++i)
146  for (int j = 0; j < DIM; ++j)
147  D(i, j) -= 2 * vL2 * rv[i] * rv[j];
148  }
149  }
150 }
151 
152 
153 std::unique_ptr<OperatorBase> L2Potential::makeClone(ParticleSet& qp, TrialWaveFunction& psi)
154 {
155  std::unique_ptr<L2Potential> myclone = std::make_unique<L2Potential>(IonConfig, qp, psi);
156  for (int ig = 0; ig < PPset.size(); ++ig)
157  {
158  if (PPset[ig])
159  {
160  myclone->add(ig, std::unique_ptr<L2RadialPotential>(PPset[ig]->makeClone()));
161  }
162  }
163  return myclone;
164 }
165 
166 } // namespace qmcplusplus
void twoBodyQuantumDomain(const ParticleSet &P)
set quantum domain for two-body operator
void resetTargetParticleSet(ParticleSet &P) override
Reset the data with the target ParticleSet.
Definition: L2Potential.cpp:32
void add(int groupID, std::unique_ptr< L2RadialPotential > &&ppot)
Add a RadialPotentialType of a species.
Definition: L2Potential.cpp:42
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
size_t getTotalNum() const
Definition: ParticleSet.h:493
void evaluateHessian(ParticleSet &P, HessVector &all_grad_grad_psi)
evaluate the hessian w.r.t.
std::unique_ptr< OperatorBase > makeClone(ParticleSet &qp, TrialWaveFunction &psi) final
TrialWaveFunction * psi_ref
Associated trial wavefunction.
Definition: L2Potential.h:70
const ParticleSet & IonConfig
reference to the ionic configuration
Definition: L2Potential.h:60
int myTableIndex
distance table index
Definition: L2Potential.h:64
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
ParticleIndex GroupID
Species ID.
Definition: ParticleSet.h:77
int getTotalNum() const
return the number of species
Definition: SpeciesSet.h:55
const DistanceTableAB & getDistTableAB(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAB
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
Return_t evaluate(ParticleSet &P) override
Evaluate the local energy contribution of this component.
Definition: L2Potential.cpp:51
std::vector< std::unique_ptr< L2RadialPotential > > PPset
unique set of L2 PP to cleanup
Definition: L2Potential.h:66
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
void evaluateD(ParticleSet &P, int iel, TensorType &D)
#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.
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
void diagonal(const T &rhs)
Definition: Tensor.h:205
WaveFunctionComponent::HessVector HessVector
FullPrecRealType Return_t
type of return value of evaluate
Definition: OperatorBase.h:64
Class to represent a many-body trial wave function.
Return_t value_
current value
Definition: OperatorBase.h:524
int NumIons
the number of ions
Definition: L2Potential.h:62
L2Potential(const ParticleSet &ions, ParticleSet &els, TrialWaveFunction &psi)
Definition: L2Potential.cpp:20
RealType evaluate(RealType r)
Definition: L2Potential.h:33
void evaluateDK(ParticleSet &P, int iel, TensorType &D, PosType &K)
Definition: L2Potential.cpp:97
std::vector< L2RadialPotential * > PP
PP[iat] is the L2 potential for the iat-th particle.
Definition: L2Potential.h:68