QMCPACK
LRHandlerTemp.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) 2020 QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 // Bryan Clark, bclark@Princeton.edu, Princeton University
9 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
12 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
13 //
14 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
15 //////////////////////////////////////////////////////////////////////////////////////
16 
17 
18 /** @file LRHandlerTemp.h
19  * @brief Define a LRHandler with two template parameters
20  */
21 #ifndef QMCPLUSPLUS_LRHANLDERTEMP_H
22 #define QMCPLUSPLUS_LRHANLDERTEMP_H
23 #include "coulomb_types.h"
25 #include "LongRange/LPQHIBasis.h"
26 #include "LongRange/LRBreakup.h"
27 #include "OhmmsPETE/OhmmsMatrix.h"
28 
29 namespace qmcplusplus
30 {
31 /* Templated LRHandler class
32  *
33  * LRHandlerTemp<Func,BreakupBasis> is a modification of LRHandler
34  * and a derived class from LRHanlderBase.
35  * The first template parameter Func is a generic functor, e.g., CoulombFunctor.
36  * The second template parameter is a BreakupBasis and the default is set to LPQHIBasis.
37  * LRHandlerBase is introduced to enable run-time options. See RPAContstraints.h
38  */
39 template<class Func, class BreakupBasis = LPQHIBasis>
41 {
42 public:
43  //Typedef for the lattice-type.
45  using BreakupBasisType = BreakupBasis;
46 
47  bool FirstTime;
49  BreakupBasisType Basis; //This needs a Lattice for the constructor...
50  Func myFunc;
51 
52 
53  //Constructor
54  LRHandlerTemp(ParticleSet& ref, mRealType kc_in = -1.0) : LRHandlerBase(kc_in), FirstTime(true), Basis(ref.getLRBox())
55  {
56  LRHandlerBase::ClassName = "LRHandlerTemp";
57  myFunc.reset(ref);
58  }
59 
60  //LRHandlerTemp(ParticleSet& ref, mRealType rs, mRealType kc=-1.0): LRHandlerBase(kc), Basis(ref.getLRBox())
61  //{
62  // myFunc.reset(ref,rs);
63  //}
64 
65  /** "copy" constructor
66  * @param aLR LRHandlerTemp
67  * @param ref Particleset
68  *
69  * Copy the content of aLR
70  * References to ParticleSet or ParticleLayoutout_t are not copied.
71  */
73  : LRHandlerBase(aLR), FirstTime(true), Basis(aLR.Basis, ref.getLRBox())
74  {
75  myFunc.reset(ref);
76  }
77 
78  LRHandlerBase* makeClone(ParticleSet& ref) const override
79  {
80  return new LRHandlerTemp<Func, BreakupBasis>(*this, ref);
81  }
82 
83  void initBreakup(ParticleSet& ref) override
84  {
85  InitBreakup(ref.getLRBox(), 1);
86  fillFk(ref.getSimulationCell().getKLists());
87  LR_rc = Basis.get_rc();
88  }
89 
90  void Breakup(ParticleSet& ref, mRealType rs_ext) override
91  {
92  //ref.getLRBox().Volume=ref.getTotalNum()*4.0*M_PI/3.0*rs*rs*rs;
93  rs = rs_ext;
94  myFunc.reset(ref, rs);
95  InitBreakup(ref.getLRBox(), 1);
96  fillFk(ref.getSimulationCell().getKLists());
97  LR_rc = Basis.get_rc();
98  }
99 
100  void resetTargetParticleSet(ParticleSet& ref) override { myFunc.reset(ref); }
101 
103 
104  inline mRealType evaluate(mRealType r, mRealType rinv) const override
105  {
106  mRealType v = 0.0;
107  if (r >= LR_rc)
108  return v;
109  v = myFunc(r, rinv);
110  for (int n = 0; n < coefs.size(); n++)
111  v -= coefs[n] * Basis.h(n, r);
112  return v;
113  }
114 
115  /** evaluate the first derivative of the short range part at r
116  *
117  * @param r radius
118  * @param rinv 1/r
119  */
120  inline mRealType srDf(mRealType r, mRealType rinv) const override
121  {
122  APP_ABORT("LRHandlerTemp::srDF not implemented (missing gcoefs)");
123  mRealType df = 0.0;
124  if (r >= LR_rc)
125  return df;
126  df = myFunc.df(r);
127  //RealType df = myFunc.df(r, rinv);
128  for (int n = 0; n < coefs.size(); n++)
129  df -= gcoefs[n] * Basis.dh_dr(n, r);
130  return df;
131  }
132 
133  inline mRealType evaluate_vlr_k(mRealType k) const override { return evalFk(k); }
134 
135 
136  /** evaluate the contribution from the long-range part for for spline
137  */
138  inline mRealType evaluateLR(mRealType r) const override
139  {
140  mRealType v = 0.0;
141  if (r >= LR_rc)
142  return myFunc(r, 1. / r);
143  for (int n = 0; n < coefs.size(); n++)
144  v += coefs[n] * Basis.h(n, r);
145  return v;
146  }
147 
148  /** evaluate the contribution from the long-range part for for spline
149  */
150  inline mRealType lrDf(mRealType r) const override
151  {
152  APP_ABORT("LRHandlerTemp::lrDF not implemented (missing gcoefs)");
153  mRealType dv = 0.0;
154  if (r < LR_rc)
155  {
156  for (int n = 0; n < coefs.size(); n++)
157  dv += gcoefs[n] * Basis.dh_dr(n, r);
158  }
159  else
160  dv = myFunc.df(r);
161 
162  return dv;
163  }
164 
165 
166  inline mRealType evaluateSR_k0() const override
167  {
168  mRealType v0 = myFunc.integrate_r2(Basis.get_rc());
169  for (int n = 0; n < coefs.size(); n++)
170  v0 -= coefs[n] * Basis.hintr2(n);
171  return v0 * 2.0 * TWOPI / Basis.get_CellVolume();
172  }
173 
174  inline mRealType evaluateLR_r0() const override
175  {
176  mRealType v0 = 0.0;
177  for (int n = 0; n < coefs.size(); n++)
178  v0 += coefs[n] * Basis.h(n, 0.0);
179  return v0;
180  }
181 
182 private:
183  inline mRealType evalFk(mRealType k) const
184  {
185  //FatK = 4.0*M_PI/(Basis.get_CellVolume()*k*k)* std::cos(k*Basis.get_rc());
186  mRealType FatK = myFunc.Fk(k, Basis.get_rc());
187  for (int n = 0; n < Basis.NumBasisElem(); n++)
188  FatK += coefs[n] * Basis.c(n, k);
189  return FatK;
190  }
191  inline mRealType evalXk(mRealType k) const
192  {
193  //RealType FatK;
194  //FatK = -4.0*M_PI/(Basis.get_CellVolume()*k*k)* std::cos(k*Basis.get_rc());
195  //return (FatK);
196  return myFunc.Xk(k, Basis.get_rc());
197  }
198 
199  /** Initialise the basis and coefficients for the long-range beakup.
200  *
201  * We loocally create a breakup handler and pass in the basis
202  * that has been initialised here. We then discard the handler, leaving
203  * basis and coefs in a usable state.
204  * This method can be re-called later if lattice changes shape.
205  */
206  void InitBreakup(const ParticleLayout& ref, int NumFunctions)
207  {
208  //First we send the new Lattice to the Basis, in case it has been updated.
209  Basis.set_Lattice(ref);
210  //Compute RC from box-size - in constructor?
211  //No here...need update if box changes
212  int NumKnots(15);
213  Basis.set_NumKnots(NumKnots);
214  Basis.set_rc(ref.LR_rc);
215  //Initialise the breakup - pass in basis.
216  LRBreakup<BreakupBasis> breakuphandler(Basis);
217  //Find size of basis from cutoffs
218  mRealType kc = (LR_kc < 0) ? ref.LR_kc : LR_kc;
219  LR_kc = kc; // set internal kc
220  //RealType kc(ref.LR_kc); //User cutoff parameter...
221  //kcut is the cutoff for switching to approximate k-point degeneracies for
222  //better performance in making the breakup. A good bet is 30*K-spacing so that
223  //there are 30 "boxes" in each direction that are treated with exact degeneracies.
224  //Assume orthorhombic cell just for deriving this cutoff - should be insensitive.
225  //K-Spacing = (kpt_vol)**1/3 = 2*pi/(cellvol**1/3)
226  mRealType kcut = 60 * M_PI * std::pow(Basis.get_CellVolume(), -1.0 / 3.0);
227  //Use 3000/LMax here...==6000/rc for non-ortho cells
228  mRealType kmax(6000.0 / ref.LR_rc);
229  MaxKshell = static_cast<int>(breakuphandler.SetupKVecs(kc, kcut, kmax));
230  if (FirstTime)
231  {
232  app_log() << " finding kc: " << ref.LR_kc << " , " << LR_kc << std::endl;
233  app_log() << " LRBreakp parameter Kc =" << kc << std::endl;
234  app_log() << " Continuum approximation in k = [" << kcut << "," << kmax << ")" << std::endl;
235  FirstTime = false;
236  }
237  //Set up x_k
238  //This is the FT of -V(r) from r_c to infinity.
239  //This is the only data that the breakup handler needs to do the breakup.
240  //We temporarily store it in Fk, which is replaced with the full FT (0->inf)
241  //of V_l(r) after the breakup has been done.
242  fillXk(breakuphandler.KList);
243  //Allocate the space for the coefficients.
244  coefs.resize(Basis.NumBasisElem()); //This must be after SetupKVecs.
245 
246  mRealType chisqr(0.0);
247  chisqr = breakuphandler.DoBreakup(Fk.data(), coefs.data()); //Fill array of coefficients.
248  //I want this in scientific notation, but I don't want to mess up formatting flags elsewhere.
249  //Save stream state.
250  std::ios_base::fmtflags app_log_flags(app_log().flags());
251  app_log() << std::scientific;
252  app_log().precision(5);
253  app_log() << "\n LR Breakup chi^2 = " << chisqr << std::endl;
254 
255  app_log().flags(app_log_flags);
256  }
257 
258  void fillXk(std::vector<TinyVector<mRealType, 2>>& KList)
259  {
260  Fk.resize(KList.size());
261  for (int ki = 0; ki < KList.size(); ki++)
262  {
263  mRealType k = KList[ki][0];
264  Fk[ki] = evalXk(k); //Call derived fn.
265  }
266  }
267 
268  void fillFk(const KContainer& KList)
269  {
270  Fk.resize(KList.kpts_cart.size());
271  const std::vector<int>& kshell(KList.kshell);
272  if (MaxKshell >= kshell.size())
273  MaxKshell = kshell.size() - 1;
275  for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
276  {
277  mRealType uk = evalFk(std::sqrt(KList.ksq[ki]));
278  Fk_symm[ks] = uk;
279  while (ki < KList.kshell[ks + 1] && ki < Fk.size())
280  Fk[ki++] = uk;
281  }
282  //for(int ki=0; ki<KList.kpts_cart.size(); ki++){
283  // RealType k=dot(KList.kpts_cart[ki],KList.kpts_cart[ki]);
284  // k=std::sqrt(k);
285  // Fk[ki] = evalFk(k); //Call derived fn.
286  //}
287  }
288 };
289 } // namespace qmcplusplus
290 #endif
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
a class that defines a supercell in D-dimensional Euclean space.
const auto & getLRBox() const
Definition: ParticleSet.h:253
std::vector< PosType > kpts_cart
K-vector in Cartesian coordinates.
Definition: KContainer.h:53
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void resetTargetParticleSet(ParticleSet &ref, mRealType rs)
mRealType LR_kc
Maximum k cutoff.
Definition: LRHandlerBase.h:37
void initBreakup(ParticleSet &ref) override
Definition: LRHandlerTemp.h:83
std::ostream & app_log()
Definition: OutputManager.h:65
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > ParticleLayout
Definition: Configuration.h:79
int SetupKVecs(mRealType kc, mRealType kcont, mRealType kmax)
setup KList
Definition: LRBreakup.h:333
LRHandlerBase * makeClone(ParticleSet &ref) const override
make clone
Definition: LRHandlerTemp.h:78
mRealType evaluateLR_r0() const override
evaluate for the self-interaction term
DECLARE_COULOMB_TYPES int MaxKshell
Maxkimum Kshell for the given Kc.
Definition: LRHandlerBase.h:35
EwaldHandler3D::mRealType mRealType
std::vector< mRealType > coefs
Fourier component for each k-shell Coefficient.
Definition: LRHandlerBase.h:53
mRealType evalFk(mRealType k) const
mRealType evaluate_vlr_k(mRealType k) const override
void Breakup(ParticleSet &ref, mRealType rs_ext) override
Definition: LRHandlerTemp.h:90
BreakupBasisType Basis
Definition: LRHandlerTemp.h:49
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)
const auto & getSimulationCell() const
Definition: ParticleSet.h:250
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
mRealType evaluateSR_k0() const override
evaluate
void fillFk(const KContainer &KList)
size_type size() const
return the current size
Definition: OhmmsVector.h:162
void fillXk(std::vector< TinyVector< mRealType, 2 >> &KList)
mRealType lrDf(mRealType r) const override
evaluate the contribution from the long-range part for for spline
mRealType LR_rc
Maximum r cutoff.
Definition: LRHandlerBase.h:39
void InitBreakup(const ParticleLayout &ref, int NumFunctions)
Initialise the basis and coefficients for the long-range beakup.
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
Container for k-points.
Definition: KContainer.h:29
mRealType srDf(mRealType r, mRealType rinv) const override
evaluate the first derivative of the short range part at r
std::vector< int > kshell
kpts which belong to the ith-shell [kshell[i], kshell[i+1])
Definition: KContainer.h:61
Vector< mRealType > Fk
Fourier component for all the k-point.
Definition: LRHandlerBase.h:41
std::vector< mRealType > gcoefs
Coefficient for gradient fit.
Definition: LRHandlerBase.h:55
mRealType DoBreakup(mRealType *Fk, mRealType *t, mRealType *adjust)
Definition: LRBreakup.h:389
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
std::vector< RealType > ksq
squre of kpts in Cartesian coordniates
Definition: KContainer.h:56
mRealType evaluateLR(mRealType r) const override
evaluate the contribution from the long-range part for for spline
mRealType evalXk(mRealType k) const
base class for LRHandlerTemp<FUNC,BASIS> and DummyLRHanlder<typename Func>
Definition: LRHandlerBase.h:30
std::vector< TinyVector< mRealType, 2 > > KList
For each k, KList[k][0] = |k| and KList[k][1] = degeneracy.
Definition: LRBreakup.h:44
mRealType evaluate(mRealType r, mRealType rinv) const override
Define LRHandlerBase and DummyLRHandler<typename Func>
LRHandlerTemp(ParticleSet &ref, mRealType kc_in=-1.0)
Definition: LRHandlerTemp.h:54
void resetTargetParticleSet(ParticleSet &ref) override
LRHandlerTemp(const LRHandlerTemp &aLR, ParticleSet &ref)
"copy" constructor
Definition: LRHandlerTemp.h:72
Vector< mRealType > Fk_symm
Fourier component for each k-shell.
Definition: LRHandlerBase.h:49