QMCPACK
LRCoulombSingleton.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: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore 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 /** @file LRHandlerTemp.h
18  * @brief Define a LRHandler with two template parameters
19  */
20 #include "LRCoulombSingleton.h"
26 #include <numeric>
27 namespace qmcplusplus
28 {
29 //initialization of the static data
30 std::unique_ptr<LRCoulombSingleton::LRHandlerType> LRCoulombSingleton::CoulombHandler;
31 std::unique_ptr<LRCoulombSingleton::LRHandlerType> LRCoulombSingleton::CoulombDerivHandler;
33 /** CoulombFunctor
34  *
35  * An example for a Func for LRHandlerTemp. Four member functions have to be provided
36  * - reset(T volume) : reset the normalization factor
37  * - operator()(T r, T rinv): return a value of the original function, e.g., 1.0/r
38  * - Fk(T k, T rc)
39  * - Xk(T k, T rc)
40  */
41 template<class T = double>
43 {
45  inline CoulombFunctor() {}
46  void reset(ParticleSet& ref) { NormFactor = 4.0 * M_PI / ref.getLRBox().Volume; }
47  void reset(ParticleSet& ref, T rs) { NormFactor = 4.0 * M_PI / ref.getLRBox().Volume; }
48  inline T operator()(T r, T rinv) const { return rinv; }
49  inline T df(T r) const { return -1.0 / (r * r); }
50  inline T Vk(T k) const { return NormFactor / (k * k); }
51 
52  inline T Fk(T k, T rc) const { return NormFactor / (k * k) * std::cos(k * rc); }
53  inline T Xk(T k, T rc) const { return -NormFactor / (k * k) * std::cos(k * rc); }
54 
55  inline T dVk_dk(T k) const { return -2 * NormFactor / k / k / k; }
56 
57  inline T integrate_r2(T r) const { return 0.5 * r * r; }
58 };
59 
60 std::unique_ptr<LRCoulombSingleton::LRHandlerType> LRCoulombSingleton::getHandler(ParticleSet& ref)
61 {
62  if (CoulombHandler == 0)
63  {
64  if (this_lr_type == ESLER)
65  {
66  app_log() << "\n Creating CoulombHandler with the Esler Optimized Breakup. " << std::endl;
67  CoulombHandler = std::make_unique<LRHandlerTemp<CoulombFunctor<mRealType>, LPQHIBasis>>(ref);
68  }
69  else if (this_lr_type == EWALD)
70  {
71  app_log() << "\n Creating CoulombHandler with the 3D Ewald Breakup. " << std::endl;
72  CoulombHandler = std::make_unique<EwaldHandler3D>(ref);
73  }
74  else if (this_lr_type == NATOLI)
75  {
76  app_log() << "\n Creating CoulombHandler with the Natoli Optimized Breakup. " << std::endl;
77  CoulombHandler = std::make_unique<LRHandlerSRCoulomb<CoulombFunctor<mRealType>, LPQHISRCoulombBasis>>(ref);
78  }
79  else if (this_lr_type == STRICT2D)
80  {
81  app_log() << "\n Creating CoulombHandler with the 2D Ewald Breakup. " << std::endl;
82  CoulombHandler = std::make_unique<EwaldHandler2D>(ref);
83  }
84  else if (this_lr_type == QUASI2D)
85  {
86  app_log() << "\n Creating CoulombHandler using quasi-2D Ewald method for the slab. " << std::endl;
87  CoulombHandler = std::make_unique<EwaldHandlerQuasi2D>(ref);
88  }
89  else
90  {
91  APP_ABORT("\n Long range breakup method not recognized.\n");
92  }
93  CoulombHandler->initBreakup(ref);
94  return std::unique_ptr<LRHandlerType>(CoulombHandler->makeClone(ref));
95  }
96  else
97  {
98  app_log() << " Clone CoulombHandler. " << std::endl;
99  return std::unique_ptr<LRHandlerType>(CoulombHandler->makeClone(ref));
100  }
101 }
102 
103 std::unique_ptr<LRCoulombSingleton::LRHandlerType> LRCoulombSingleton::getDerivHandler(ParticleSet& ref)
104 {
105  //APP_ABORT("SR Coulomb Basis Handler has cloning issues. Stress also has some kinks");
106  if (CoulombDerivHandler == 0)
107  {
108  if (this_lr_type == EWALD)
109  {
110  app_log() << "\n Creating CoulombDerivHandler with the 3D Ewald Breakup. " << std::endl;
111  CoulombDerivHandler = std::make_unique<EwaldHandler3D>(ref);
112  }
113  else if (this_lr_type == NATOLI)
114  {
115  app_log() << "\n Creating CoulombDerivHandler with the Natoli Optimized Breakup. " << std::endl;
116  CoulombDerivHandler = std::make_unique<LRHandlerSRCoulomb<CoulombFunctor<mRealType>, LPQHISRCoulombBasis>>(ref);
117  }
118  else if (this_lr_type == ESLER)
119  {
120  APP_ABORT("\n Derivatives are not supported with Esler Optimized Breakup.\n");
121  }
122  else
123  {
124  APP_ABORT("\n Long range breakup method for derivatives not recognized.\n");
125  }
126  CoulombDerivHandler->initBreakup(ref);
127  return std::unique_ptr<LRHandlerType>(CoulombDerivHandler->makeClone(ref));
128  }
129  else
130  {
131  app_log() << " Clone CoulombDerivHandler. " << std::endl;
132  return std::unique_ptr<LRHandlerType>(CoulombDerivHandler->makeClone(ref));
133  }
134 }
135 
136 template<typename T>
137 std::unique_ptr<OneDimCubicSpline<T>> createSpline4RbyVs_temp(const LRHandlerBase* aLR,
138  T rcut,
139  const LinearGrid<T>& agrid)
140 {
141  using func_type = OneDimCubicSpline<T>;
142  const int ng = agrid.size();
143  std::vector<T> v(ng);
144  T r = agrid[0];
145  //check if the first point is not zero
146  v[0] = (r > std::numeric_limits<T>::epsilon()) ? r * aLR->evaluate(r, 1.0 / r) : 0.0;
147  for (int ig = 1; ig < ng - 1; ig++)
148  {
149  r = agrid[ig];
150  v[ig] = r * aLR->evaluate(r, 1.0 / r);
151  }
152  v[0] = 2.0 * v[1] - v[2];
153  v[ng - 1] = 0.0;
154  auto V0 = std::make_unique<func_type>(agrid.makeClone(), v);
155  T deriv = (v[1] - v[0]) / (agrid[1] - agrid[0]);
156  V0->spline(0, deriv, ng - 1, 0.0);
157  return V0;
158 }
159 
160 template<typename T>
161 std::unique_ptr<OneDimCubicSpline<T>> createSpline4RbyVsDeriv_temp(const LRHandlerBase* aLR,
162  T rcut,
163  const LinearGrid<T>& agrid)
164 {
165  using func_type = OneDimCubicSpline<T>;
166  int ng = agrid.size();
167  std::vector<T> v(ng);
168  T r = agrid[0];
169  //check if the first point is not zero
170  v[0] = (r > std::numeric_limits<T>::epsilon()) ? r * aLR->evaluate(r, 1.0 / r) : 0.0;
171  T v_val(0.0);
172  T v_deriv(0.0);
173 
174  for (int ig = 1; ig < ng - 1; ig++)
175  {
176  r = agrid[ig];
177  v_val = aLR->evaluate(r, 1.0 / r);
178  v_deriv = aLR->srDf(r, 1 / r);
179 
180  v[ig] = v_val + v_deriv * r;
181  }
182  v[0] = 2.0 * v[1] - v[2];
183  v[ng - 1] = 0.0;
184  auto dV0 = std::make_unique<func_type>(agrid.makeClone(), v);
185  T deriv = (v[1] - v[0]) / (agrid[1] - agrid[0]);
186  dV0->spline(0, deriv, ng - 1, 0.0);
187  return dV0;
188 }
189 
190 
191 std::unique_ptr<LRCoulombSingleton::RadFunctorType> LRCoulombSingleton::createSpline4RbyVs(const LRHandlerType* aLR,
192  mRealType rcut,
193  const GridType& agrid)
194 {
195  return createSpline4RbyVs_temp(aLR, static_cast<pRealType>(rcut), agrid);
196 }
197 
198 std::unique_ptr<LRCoulombSingleton::RadFunctorType> LRCoulombSingleton::createSpline4RbyVsDeriv(
199  const LRHandlerType* aLR,
200  mRealType rcut,
201  const GridType& agrid)
202 {
203  return createSpline4RbyVsDeriv_temp(aLR, static_cast<pRealType>(rcut), agrid);
204 }
205 
206 
207 } // namespace qmcplusplus
const auto & getLRBox() const
Definition: ParticleSet.h:253
static std::unique_ptr< LRHandlerType > getDerivHandler(ParticleSet &ref)
This returns a force/stress optimized LR handler. If non existent, it creates one.
One-Dimensional linear-grid.
static std::unique_ptr< LRHandlerType > CoulombDerivHandler
Stores the force/stress optimized LR handler.
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
static std::unique_ptr< RadFunctorType > createSpline4RbyVs(const LRHandlerType *aLR, mRealType rcut, const GridType &agrid)
create a linear spline function
std::ostream & app_log()
Definition: OutputManager.h:65
std::unique_ptr< OneDimGridBase< T, CT > > makeClone() const override
A derivative of LRBasis class to provide the functionality of the LPQHI basis.
EwaldHandler3D::mRealType mRealType
std::unique_ptr< OneDimCubicSpline< T > > createSpline4RbyVs_temp(const LRHandlerBase *aLR, T rcut, const LinearGrid< T > &agrid)
static std::unique_ptr< LRHandlerType > CoulombHandler
Stores the energ optimized LR handler.
mRealType evaluate(const std::vector< int > &kshell, const pRealType *restrict rk1_r, const pRealType *restrict rk1_i, const pRealType *restrict rk2_r, const pRealType *restrict rk2_i) const
evaluate
Definition: LRHandlerBase.h:93
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
A derivative of LRBasis class to provide the functionality of the LPQHI basis.
Definition: LPQHIBasis.h:28
static std::unique_ptr< RadFunctorType > createSpline4RbyVsDeriv(const LRHandlerType *aLR, mRealType rcut, const GridType &agrid)
create a linear spline of the derivative of short-range potential
std::unique_ptr< OneDimCubicSpline< T > > createSpline4RbyVsDeriv_temp(const LRHandlerBase *aLR, T rcut, const LinearGrid< T > &agrid)
Define a LRHandler with two template parameters.
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void reset(ParticleSet &ref)
void reset(ParticleSet &ref, T rs)
int size() const
returns the size of the grid
static std::unique_ptr< LRHandlerType > getHandler(ParticleSet &ref)
This returns an energy optimized LR handler. If non existent, it creates one.
T operator()(T r, T rinv) const
Define a LRHandler with two template parameters.
base class for LRHandlerTemp<FUNC,BASIS> and DummyLRHanlder<typename Func>
Definition: LRHandlerBase.h:30
virtual mRealType srDf(mRealType r, mRealType rinv) const =0
Define a LRHandler with two template parameters.