QMCPACK
ACForce.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) 2019 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Raymond Clay, Sandia National Laboratories
8 //
9 // File created by: Raymond Clay, rclay@sandia.gov, Sandia National Laboratories
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 /**@file ACForce.cpp
14  *@brief Implementation of ACForce, Assaraf-Caffarel ZVZB style force estimation.
15  */
16 #include "ACForce.h"
17 #include "OhmmsData/AttributeSet.h"
19 
20 namespace qmcplusplus
21 {
23  : delta_(1e-4),
24  ions_(source),
25  elns_(target),
26  psi_(psi_in),
27  ham_(H),
28  first_force_index_(-1),
29  useSpaceWarp_(false),
30  fastDerivatives_(false),
31  swt_(target, source),
32  reg_epsilon_(0.0),
33  f_epsilon_(1.0)
34 {
35  setName("ACForce");
36 
37  const std::size_t nIons = ions_.getTotalNum();
38  hf_force_.resize(nIons);
39  pulay_force_.resize(nIons);
40  wf_grad_.resize(nIons);
41  sw_pulay_.resize(nIons);
42  sw_grad_.resize(nIons);
44 };
45 
46 std::unique_ptr<OperatorBase> ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi)
47 {
48  APP_ABORT("ACForce::makeClone(ParticleSet&,TrialWaveFunction&) shouldn't be called");
49  return nullptr;
50 }
51 
52 std::unique_ptr<OperatorBase> ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi_in, QMCHamiltonian& ham_in)
53 {
54  std::unique_ptr<ACForce> myclone = std::make_unique<ACForce>(ions_, qp, psi_in, ham_in);
55  myclone->fastDerivatives_ = fastDerivatives_;
56  myclone->useSpaceWarp_ = useSpaceWarp_;
57  myclone->first_force_index_ = first_force_index_;
58  myclone->reg_epsilon_ = reg_epsilon_;
59  myclone->delta_ = delta_;
60  return myclone;
61 }
62 
63 bool ACForce::put(xmlNodePtr cur)
64 {
65  std::string ionionforce("yes");
66  RealType swpow(4);
67  OhmmsAttributeSet attr;
68  attr.add(useSpaceWarp_, "spacewarp", {false}); //"yes" or "no"
69  attr.add(swpow, "swpow"); //Real number"
70  attr.add(delta_, "delta"); //Real number"
71  attr.add(reg_epsilon_, "epsilon");
72  attr.add(fastDerivatives_, "fast_derivatives", {false});
73  attr.put(cur);
74  if (reg_epsilon_ < 0)
75  throw std::runtime_error("ACForce::put(): epsilon<0 not allowed.");
76  if (fastDerivatives_)
77  app_log() << "ACForce is using the fast force algorithm\n";
78  else
79  app_log() << "ACForce is using the default algorithm\n";
80  swt_.setPow(swpow);
81 
82  if (useSpaceWarp_)
83  app_log() << "ACForce is using space warp with power=" << swpow << std::endl;
84  else
85  app_log() << "ACForce is not using space warp\n";
86 
87  return true;
88 }
89 
90 bool ACForce::get(std::ostream& os) const { return true; }
91 
93 {
94  //The following line is modified
95  std::unique_ptr<OperatorBase> myclone = makeClone(qp, psi, ham_in);
96  if (myclone)
97  {
98  ham_in.addOperator(std::move(myclone), name_, update_mode_[PHYSICAL]);
99  }
100 }
102 {
103  hf_force_ = 0;
104  pulay_force_ = 0;
105  wf_grad_ = 0;
106  sw_pulay_ = 0;
107  sw_grad_ = 0;
108 
109 
110  //This function returns d/dR of the sum of all observables in the physical hamiltonian.
111  //Note that the sign will be flipped based on definition of force = -d/dR.
112  if (fastDerivatives_)
114  else
116 
117  if (useSpaceWarp_)
118  {
119  Forces el_grad;
120  el_grad.resize(P.getTotalNum());
121  el_grad = 0;
122 
123  ham_.evaluateElecGrad(P, psi_, el_grad, delta_);
124  swt_.computeSWT(P, ions_, el_grad, P.G, sw_pulay_, sw_grad_);
125  }
126 
127  //Now we compute the regularizer.
128  //WE ASSUME THAT psi_.evaluateLog(P) HAS ALREADY BEEN CALLED AND Grad(logPsi)
129  //IS ALREADY UP TO DATE FOR THIS CONFIGURATION.
130 
132 
133 
134  return 0.0;
135 };
136 
138 
140 {
141  if (first_force_index_ < 0)
142  first_force_index_ = plist.size();
143  for (int iat = 0; iat < ions_.getTotalNum(); iat++)
144  {
145  const std::string iatStr(std::to_string(iat));
146 
147  for (int x = 0; x < OHMMS_DIM; x++)
148  {
149  const std::string xStr(std::to_string(x));
150 
151  const std::string hfname("ACForce_hf_" + iatStr + "_" + xStr);
152  const std::string pulayname("ACForce_pulay_" + iatStr + "_" + xStr);
153  const std::string wfgradname1("ACForce_Ewfgrad_" + iatStr + "_" + xStr);
154  const std::string wfgradname2("ACForce_wfgrad_" + iatStr + "_" + xStr);
155 
156  plist.add(hfname);
157  plist.add(pulayname);
158  plist.add(wfgradname1);
159  plist.add(wfgradname2);
160  }
161  }
162 };
164 {
165  // TODO : bounds check for plist
166 
167  int myindex = first_force_index_;
168  for (int iat = 0; iat < ions_.getTotalNum(); iat++)
169  {
170  for (int iondim = 0; iondim < OHMMS_DIM; iondim++)
171  {
172  //Flipping the sign, since these terms currently store d/dR values.
173  // add the minus one to be a force.
174  plist[myindex++] = -hf_force_[iat][iondim] * f_epsilon_;
175  plist[myindex++] = -(pulay_force_[iat][iondim] + sw_pulay_[iat][iondim]) * f_epsilon_;
176  plist[myindex++] = -value_ * (wf_grad_[iat][iondim] + sw_grad_[iat][iondim]) * f_epsilon_;
177  plist[myindex++] = -(wf_grad_[iat][iondim] + sw_grad_[iat][iondim]) * f_epsilon_;
178  }
179  }
180 };
182 {
183  int myindex = first_force_index_ + offset;
184  for (int iat = 0; iat < ions_.getTotalNum(); iat++)
185  {
186  for (int iondim = 0; iondim < OHMMS_DIM; iondim++)
187  {
188  plist[myindex++] = -hf_force_[iat][iondim] * f_epsilon_;
189  plist[myindex++] = -(pulay_force_[iat][iondim] + sw_pulay_[iat][iondim]) * f_epsilon_;
190  plist[myindex++] = -value_ * (wf_grad_[iat][iondim] + sw_grad_[iat][iondim]) * f_epsilon_;
191  plist[myindex++] = -(wf_grad_[iat][iondim] + sw_grad_[iat][iondim]) * f_epsilon_;
192  }
193  }
194 };
195 
197 {
198  //epsilon=0 corresponds to no regularization. However, since
199  //epsilon ends up in denominators, return 1 here.
200  if (std::abs(epsilon) < 1e-6)
201  return 1.0;
202 
203  RealType gdotg = 0.0;
204 #if defined(QMC_COMPLEX)
205  gdotg = Dot_CC(G, G);
206 #else
207  gdotg = Dot(G, G);
208 #endif
209 
210  RealType gmag = std::sqrt(gdotg);
211  RealType x;
212 
213  RealType regvalue = 0.0;
214  //x = grad(logpsi)/|grad(logpsi)|^2 = 1/|grad(logpsi)|.
215  //
216  //Argument of polynomial is x/epsilon=1/(epsilon*|grad(logpsi)|)
217  double xovereps = 1.0 / (epsilon * gmag);
218  if (xovereps >= 1.0)
219  regvalue = 1.0;
220  else
221  {
222  //There's a discrepancy between AIP Advances 10, 085213 (2020) and arXiv:2002.01434 for polynomial.
223  //We choose the arXiv, because f(x=1)=1, as opposed to f(x=1)=-4.
224  regvalue = 7.0 * std::pow(xovereps, 6.0) - 15.0 * std::pow(xovereps, 4.0) + 9.0 * std::pow(xovereps, 2.0);
225  }
226  return regvalue;
227 };
228 } // namespace qmcplusplus
RealType f_epsilon_
Definition: ACForce.h:100
FullPrecRealType evaluateIonDerivsDeterministicFast(ParticleSet &P, ParticleSet &ions, TrialWaveFunction &psi_in, TWFFastDerivWrapper &psi_wrapper, ParticleSet::ParticlePos &dedr, ParticleSet::ParticlePos &wf_grad)
evaluate local energy and derivatives w.r.t ionic coordinates, but deterministically.
static RealType compute_regularizer_f(const ParticleGradient &G, const RealType epsilon)
Computes multiplicative regularizer f(G,epsilon) according to Pathak-Wagner arXiv:2002.01434 .
Definition: ACForce.cpp:196
Return_t evaluate(ParticleSet &P) final
Evaluate.
Definition: ACForce.cpp:101
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
void addOperator(std::unique_ptr< OperatorBase > &&h, const std::string &aname, bool physical=true)
add an operator
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
size_t getTotalNum() const
Definition: ParticleSet.h:493
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
RealType delta_
Finite difference timestep.
Definition: ACForce.h:78
Collection of Local Energy Operators.
bool get(std::ostream &os) const final
write about the class
Definition: ACForce.cpp:90
void setPow(RealType swpow_in)
Sets the exponent for power law space warp transformation.
Vectorized record engine for scalar properties.
void addObservables(PropertySetType &plist, BufferType &collectables) final
named values to the property list Default implementaton uses addValue(plist_)
Definition: ACForce.cpp:139
Attaches a unit to a Vector for IO.
SpaceWarpTransformation swt_
The space warp transformation class.
Definition: ACForce.h:96
ParticleSet::ParticlePos Forces
Definition: ACForce.h:29
void setObservables(PropertySetType &plist) final
Set the values evaluated by this object to plist Default implementation is to assign Value which is u...
Definition: ACForce.cpp:163
#define OHMMS_DIM
Definition: config.h:64
T Dot(const ParticleAttrib< TinyVector< T, D >> &pa, const ParticleAttrib< TinyVector< T, D >> &pb)
void setParticlePropertyList(PropertySetType &plist, int offset) final
Definition: ACForce.cpp:181
ParticleSet::ParticleGradient G
differential gradients
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
std::string name_
name of this object
Definition: OperatorBase.h:527
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
void computeSWT(ParticleSet &elec, const ParticleSet &ions, Force_t &dEl, ParticleGradient &dlogpsi, Force_t &el_contribution, Force_t &psi_contribution)
Takes in precomputed grad(E_L) and grad(logPsi) and computes the ZV and ZB space warp contributions t...
int add(const std::string &aname)
bool put(xmlNodePtr cur) final
I/O Routines.
Definition: ACForce.cpp:63
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
ACForce(ParticleSet &source, ParticleSet &target, TrialWaveFunction &psi, QMCHamiltonian &H)
Constructor.
Definition: ACForce.cpp:22
FullPrecRealType evaluateIonDerivsDeterministic(ParticleSet &P, ParticleSet &ions, TrialWaveFunction &psi, ParticleSet::ParticlePos &hf_terms, ParticleSet::ParticlePos &pulay_terms, ParticleSet::ParticlePos &wf_grad)
evaluate local energy and derivatives w.r.t ionic coordinates, but deterministically.
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void setName(const std::string name) noexcept
Set my_name member, uses small string optimization (pass by value)
QMCHamiltonian & ham_
Definition: ACForce.h:86
void evaluateElecGrad(ParticleSet &P, TrialWaveFunction &psi, ParticleSet::ParticlePos &EGrad, RealType delta=1e-5)
Evaluate the electron gradient of the local energy.
FullPrecRealType Return_t
type of return value of evaluate
Definition: OperatorBase.h:64
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
Class to represent a many-body trial wave function.
Return_t value_
current value
Definition: OperatorBase.h:524
double Dot_CC(const ParticleAttrib< TinyVector< std::complex< double >, D >> &pa, const ParticleAttrib< TinyVector< std::complex< double >, D >> &pb)
Declaraton of ParticleAttrib<T>
void add2Hamiltonian(ParticleSet &qp, TrialWaveFunction &psi, QMCHamiltonian &targetH) final
Since we store a reference to QMCHamiltonian, the baseclass method add2Hamiltonian isn&#39;t sufficient...
Definition: ACForce.cpp:92
RealType reg_epsilon_
Definition: ACForce.h:99
void resetTargetParticleSet(ParticleSet &P) final
Initialization/assignment.
Definition: ACForce.cpp:137
Declaration of ACForce, Assaraf-Caffarel ZVZB style force estimation.
IndexType first_force_index_
For indexing observables.
Definition: ACForce.h:89
TWFFastDerivWrapper psi_wrapper_
Definition: ACForce.h:110
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 useSpaceWarp_
Algorithm/feature switches.
Definition: ACForce.h:92
Forces hf_force_
Temporary Nion x 3 dimensional arrays for force storage.
Definition: ACForce.h:103
std::unique_ptr< OperatorBase > makeClone(ParticleSet &qp, TrialWaveFunction &psi) final
Cloning.
Definition: ACForce.cpp:46
std::bitset< 8 > update_mode_
set the current update mode
Definition: OperatorBase.h:521
ParticleSet & ions_
Definition: ACForce.h:83
TrialWaveFunction & psi_
Definition: ACForce.h:85
ParticleSet & elns_
Definition: ACForce.h:84
void initializeTWFFastDerivWrapper(const ParticleSet &P, TWFFastDerivWrapper &twf) const
Initialize a TWF wrapper for fast derivative evaluation.