QMCPACK
LRRPAHandlerTemp.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: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 /** @file LRHandlerTemp.h
16  * @brief Define a LRHandler with two template parameters
17  */
18 #ifndef QMCPLUSPLUS_LRRPAHANLDERTEMP_H
19 #define QMCPLUSPLUS_LRRPAHANLDERTEMP_H
20 
22 #include "LongRange/LPQHIBasis.h"
23 #include "LongRange/LRBreakup.h"
24 
25 namespace qmcplusplus
26 {
27 /* Templated LRHandler class
28  *
29  * LRHandlerTemp<Func,BreakupBasis> is a modification of LRHandler
30  * and a derived class from LRHanlderBase.
31  * The first template parameter Func is a generic functor, e.g., CoulombFunctor.
32  * The second template parameter is a BreakupBasis and the default is set to LPQHIBasis.
33  * LRHandlerBase is introduced to enable run-time options. See RPAContstraints.h
34  */
35 template<class Func, class BreakupBasis = LPQHIBasis>
37 {
39 
40  //Typedef for the lattice-type.
42  using BreakupBasisType = BreakupBasis;
43 
44  bool FirstTime;
47  BreakupBasisType Basis; //This needs a Lattice for the constructor...
48  Func myFunc;
49 
50  //Constructor
52  : LRHandlerBase(kc_in), FirstTime(true), Basis(ref.getLattice())
53  {
54  LRHandlerBase::ClassName = "LRRPAHandlerTemp";
55  myFunc.reset(ref);
56  }
57 
58  //LRHandlerTemp(ParticleSet& ref, mRealType rs, mRealType kc=-1.0): LRHandlerBase(kc), Basis(ref.getLattice())
59  //{
60  // myFunc.reset(ref,rs);
61  //}
62 
63  /** "copy" constructor
64  * @param aLR LRHandlerTemp
65  * @param ref Particleset
66  *
67  * Copy the content of aLR
68  * References to ParticleSet or ParticleLayoutout_t are not copied.
69  */
71  : LRHandlerBase(aLR), FirstTime(true), Basis(aLR.Basis, ref.getLattice())
72  {
73  myFunc.reset(ref);
74  fillFk(ref.getSimulationCell().getKLists());
75  }
76 
77  LRHandlerBase* makeClone(ParticleSet& ref) const override
78  {
79  return new LRRPAHandlerTemp<Func, BreakupBasis>(*this, ref);
80  }
81 
82  void initBreakup(ParticleSet& ref) override
83  {
84  InitBreakup(ref.getLattice(), 1);
85  fillFk(ref.getSimulationCell().getKLists());
86  LR_rc = Basis.get_rc();
87  }
88 
89  void Breakup(ParticleSet& ref, mRealType rs_ext) override
90  {
91  //ref.getLattice().Volume=ref.getTotalNum()*4.0*M_PI/3.0*rs*rs*rs;
92  if (rs_ext > 0)
93  rs = rs_ext;
94  else
95  rs = std::pow(3.0 / 4.0 / M_PI * ref.getLattice().Volume / static_cast<mRealType>(ref.getTotalNum()), 1.0 / 3.0);
96  myFunc.reset(ref, rs);
97  InitBreakup(ref.getLattice(), 1);
98  fillFk(ref.getSimulationCell().getKLists());
99  LR_rc = Basis.get_rc();
100  }
101 
102  void resetTargetParticleSet(ParticleSet& ref) override { myFunc.reset(ref); }
103 
105 
106  inline mRealType evaluate(mRealType r, mRealType rinv) const override
107  {
108  mRealType v = 0.0;
109  for (int n = 0; n < coefs.size(); n++)
110  v += coefs[n] * Basis.h(n, r);
111  return v;
112  }
113 
114  /** evaluate the first derivative of the short range part at r
115  *
116  * @param r radius
117  * @param rinv 1/r
118  */
119  inline mRealType srDf(mRealType r, mRealType rinv) const override
120  {
121  mRealType df = 0.0;
122  //mRealType df = myFunc.df(r, rinv);
123  for (int n = 0; n < coefs.size(); n++)
124  df += coefs[n] * Basis.dh_dr(n, r);
125  return df;
126  }
127 
128  /** evaluate the contribution from the long-range part for for spline
129  */
130  inline mRealType evaluateLR(mRealType r) const override
131  {
132  mRealType vk = 0.0;
133  return vk;
134  // for(int n=0; n<coefs.size(); n++) v -= coefs[n]*Basis.h(n,r);
135  }
136 
137  // use what is put in fillFk. Multiplies evalFk by -1
138  inline mRealType evaluate_vlr_k(mRealType k) const override { return -1.0 * evalFk(k); }
139 
140 private:
141  inline mRealType evalFk(mRealType k) const
142  {
143  //FatK = 4.0*M_PI/(Basis.get_CellVolume()*k*k)* std::cos(k*Basis.get_rc());
144  mRealType FatK = myFunc.Fk(k, Basis.get_rc());
145  for (int n = 0; n < Basis.NumBasisElem(); n++)
146  FatK += coefs[n] * Basis.c(n, k);
147  return FatK;
148  }
149 
150  inline mRealType evalXk(mRealType k) const
151  {
152  //mRealType FatK;
153  //FatK = -4.0*M_PI/(Basis.get_CellVolume()*k*k)* std::cos(k*Basis.get_rc());
154  //return (FatK);
155  return myFunc.Xk(k, Basis.get_rc());
156  }
157 
158  /** Initialise the basis and coefficients for the long-range beakup.
159  *
160  * We loocally create a breakup handler and pass in the basis
161  * that has been initialised here. We then discard the handler, leaving
162  * basis and coefs in a usable state.
163  * This method can be re-called later if lattice changes shape.
164  */
165  void InitBreakup(const ParticleLayout& ref, int NumFunctions)
166  {
167  //First we send the new Lattice to the Basis, in case it has been updated.
168  Basis.set_Lattice(ref);
169  //Compute RC from box-size - in constructor?
170  //No here...need update if box changes
171  int NumKnots(15);
172  Basis.set_NumKnots(NumKnots);
173  Basis.set_rc(ref.LR_rc);
174  //Initialise the breakup - pass in basis.
175  LRBreakup<BreakupBasis> breakuphandler(Basis);
176  // std::cout<<" finding kc: "<<ref.LR_kc<<" , "<<LR_kc<< std::endl;
177  //Find size of basis from cutoffs
178  kc = (LR_kc < 0) ? ref.LR_kc : LR_kc;
179  //mRealType kc(ref.LR_kc); //User cutoff parameter...
180  //kcut is the cutoff for switching to approximate k-point degeneracies for
181  //better performance in making the breakup. A good bet is 30*K-spacing so that
182  //there are 30 "boxes" in each direction that are treated with exact degeneracies.
183  //Assume orthorhombic cell just for deriving this cutoff - should be insensitive.
184  //K-Spacing = (kpt_vol)**1/3 = 2*pi/(cellvol**1/3)
185  mRealType kcut = (30.0) * 2 * M_PI * std::pow(Basis.get_CellVolume(), -1.0 / 3.0);
186  //Use 3000/LMax here...==6000/rc for non-ortho cells
187  mRealType kmax(6000.0 / ref.LR_rc);
188  // std::cout<<"K_STATS !!! "<<kcut<<" "<<kmax<<std::endl;
189  MaxKshell = static_cast<int>(breakuphandler.SetupKVecs(kc, kcut, kmax));
190  if (FirstTime)
191  {
192  app_log() << " finding kc: " << ref.LR_kc << " , " << LR_kc << std::endl;
193  app_log() << " LRBreakp parameter Kc =" << kc << std::endl;
194  app_log() << " Continuum approximation in k = [" << kcut << "," << kmax << ")" << std::endl;
195  FirstTime = false;
196  }
197  //Set up x_k
198  //This is the FT of -V(r) from r_c to infinity.
199  //This is the only data that the breakup handler needs to do the breakup.
200  //We temporarily store it in Fk, which is replaced with the full FT (0->inf)
201  //of V_l(r) after the breakup has been done.
202  fillXk(breakuphandler.KList);
203  //Allocate the space for the coefficients.
204  coefs.resize(Basis.NumBasisElem()); //This must be after SetupKVecs.
205  breakuphandler.DoBreakup(Fk.data(), coefs.data()); //Fill array of coefficients.
206  }
207 
208  void fillXk(std::vector<TinyVector<mRealType, 2>>& KList)
209  {
210  Fk.resize(KList.size());
211  for (int ki = 0; ki < KList.size(); ki++)
212  {
213  mRealType k = KList[ki][0];
214  Fk[ki] = evalXk(k); //Call derived fn.
215  }
216  }
217 
218  void fillFk(const KContainer& KList)
219  {
220  Fk.resize(KList.kpts_cart.size());
221  const std::vector<int>& kshell(KList.kshell);
222  if (MaxKshell >= kshell.size())
223  MaxKshell = kshell.size() - 1;
225  // std::cout<<"Filling FK :"<<std::endl;
226  for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
227  {
228  mRealType k = std::pow(KList.ksq[ki], 0.5);
229  mRealType uk = -1.0 * evalFk(k);
230  Fk_symm[ks] = uk;
231  // std::cout<<uk<<std::endl;
232  while (ki < KList.kshell[ks + 1] && ki < Fk.size())
233  Fk[ki++] = uk;
234  }
235  //for(int ki=0; ki<KList.kpts_cart.size(); ki++){
236  // mRealType k=dot(KList.kpts_cart[ki],KList.kpts_cart[ki]);
237  // k=std::sqrt(k);
238  // Fk[ki] = evalFk(k); //Call derived fn.
239  //}
240  }
241 };
242 } // namespace qmcplusplus
243 #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.
std::vector< PosType > kpts_cart
K-vector in Cartesian coordinates.
Definition: KContainer.h:53
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
mRealType evalFk(mRealType k) const
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
mRealType evaluate_vlr_k(mRealType k) const override
void Breakup(ParticleSet &ref, mRealType rs_ext) override
mRealType LR_kc
Maximum k cutoff.
Definition: LRHandlerBase.h:37
size_t getTotalNum() const
Definition: ParticleSet.h:493
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
DECLARE_COULOMB_TYPES int MaxKshell
Maxkimum Kshell for the given Kc.
Definition: LRHandlerBase.h:35
EwaldHandler3D::mRealType mRealType
void fillFk(const KContainer &KList)
std::vector< mRealType > coefs
Fourier component for each k-shell Coefficient.
Definition: LRHandlerBase.h:53
void resetTargetParticleSet(ParticleSet &ref, mRealType rs)
void initBreakup(ParticleSet &ref) override
LRHandlerBase * makeClone(ParticleSet &ref) const override
make clone
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 srDf(mRealType r, mRealType rinv) const override
evaluate the first derivative of the short range part at r
size_type size() const
return the current size
Definition: OhmmsVector.h:162
mRealType LR_rc
Maximum r cutoff.
Definition: LRHandlerBase.h:39
mRealType evaluateLR(mRealType r) const override
evaluate the contribution from the long-range part for for spline
Container for k-points.
Definition: KContainer.h:29
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
void fillXk(std::vector< TinyVector< mRealType, 2 >> &KList)
#define DECLARE_COULOMB_TYPES
Definition: coulomb_types.h:18
mRealType DoBreakup(mRealType *Fk, mRealType *t, mRealType *adjust)
Definition: LRBreakup.h:389
mRealType evaluate(mRealType r, mRealType rinv) const override
std::vector< RealType > ksq
squre of kpts in Cartesian coordniates
Definition: KContainer.h:56
void InitBreakup(const ParticleLayout &ref, int NumFunctions)
Initialise the basis and coefficients for the long-range beakup.
const auto & getLattice() const
Definition: ParticleSet.h:251
void resetTargetParticleSet(ParticleSet &ref) override
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
LRRPAHandlerTemp(ParticleSet &ref, mRealType kc_in=-1.0)
LRRPAHandlerTemp(const LRRPAHandlerTemp &aLR, ParticleSet &ref)
"copy" constructor
Define LRHandlerBase and DummyLRHandler<typename Func>
mRealType evalXk(mRealType k) const
Vector< mRealType > Fk_symm
Fourier component for each k-shell.
Definition: LRHandlerBase.h:49