QMCPACK
kSpaceJastrow.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 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
11 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
12 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
13 //
14 // File created by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
15 //////////////////////////////////////////////////////////////////////////////////////
16 
17 
18 #include "kSpaceJastrow.h"
19 #include <sstream>
20 #include <algorithm>
21 #include "LongRange/StructFact.h"
22 #include "CPU/math.hpp"
23 #include "CPU/e2iphi.h"
25 
26 namespace qmcplusplus
27 {
28 void kSpaceJastrow::StructureFactor(PosType G, std::vector<ComplexType>& rho_G)
29 {
30  for (int i = 0; i < NumIonSpecies; i++)
31  rho_G[i] = ComplexType();
32  for (int iat = 0; iat < Ions.getTotalNum(); iat++)
33  {
34  PosType r(Ions.R[iat]);
35  RealType phase = dot(r, G);
36  int id = Ions.GroupID[iat];
37  rho_G[id] += ComplexType(std::cos(phase), std::sin(phase));
38  }
39 }
40 
41 inline bool Include(int i, int j, int k)
42 {
43  if (i > 0)
44  return true;
45  else if (i == 0)
46  {
47  if (j > 0)
48  return true;
49  else if ((j == 0) && (k > 0))
50  return true;
51  }
52  return false;
53 }
54 
55 inline bool Include(int i, int j)
56 {
57  if (i > 0)
58  return true;
59  else if (i == 0)
60  {
61  if (j > 0)
62  return true;
63  }
64  return false;
65 }
66 
67 void kSpaceJastrow::setupGvecs(RealType kc, std::vector<PosType>& gvecs, bool useStructFact)
68 {
69  gvecs.clear();
70  int maxIndex[OHMMS_DIM];
71  for (int i = 0; i < OHMMS_DIM; i++)
72  maxIndex[i] =
73  2 + (int)std::floor(std::sqrt(dot(Ions.getLattice().a(i), Ions.getLattice().a(i))) * kc / (2.0 * M_PI));
74  std::vector<ComplexType> rho_G(NumIonSpecies);
75 #if OHMMS_DIM == 3
76  for (int i = 0; i <= maxIndex[0]; i++)
77  for (int j = -maxIndex[1]; j <= maxIndex[1]; j++)
78  for (int k = -maxIndex[2]; k <= maxIndex[2]; k++)
79  {
80  // Omit half the G-vectors because of time-reversal symmetry
81  if (Include(i, j, k))
82  {
83  PosType G = 2.0 * M_PI *
84  ((RealType)i * Ions.getLattice().Gv[0] + (RealType)j * Ions.getLattice().Gv[1] +
85  (RealType)k * Ions.getLattice().Gv[2]);
86  if (dot(G, G) <= (kc * kc))
87  {
88  bool notZero(false);
89  StructureFactor(G, rho_G);
90  for (int sp = 0; sp < NumIonSpecies; sp++)
91  notZero = notZero || (norm(rho_G[sp]) > 1.0e-12);
92  if (notZero || !useStructFact)
93  gvecs.push_back(G);
94  }
95  }
96  }
97 #elif OHMMS_DIM == 2
98  for (int i = 0; i <= maxIndex[0]; i++)
99  for (int j = -maxIndex[1]; j <= maxIndex[1]; j++)
100  {
101  // Omit half the G-vectors because of time-reversal symmetry
102  if (Include(i, j))
103  {
104  PosType G = 2.0 * M_PI * ((RealType)i * Ions.getLattice().Gv[0] + (RealType)j * Ions.getLattice().Gv[1]);
105  if (dot(G, G) <= (kc * kc))
106  {
107  bool notZero(false);
108  StructureFactor(G, rho_G);
109  for (int sp = 0; sp < NumIonSpecies; sp++)
110  notZero = notZero || (norm(rho_G[sp]) > 1.0e-12);
111  if (notZero || !useStructFact)
112  gvecs.push_back(G);
113  }
114  }
115  }
116 #endif
117 }
118 
119 struct magLess
120 {
121  inline bool operator()(kSpaceJastrow::PosType a, kSpaceJastrow::PosType b) { return dot(a, a) < dot(b, b); }
122 };
123 
125 {
126  if (std::abs(dot(G1, G1) - dot(G2, G2)) > 1.0e-8)
127  return dot(G1, G1) < dot(G2, G2);
128  // if (Equivalent(G1,G2)) return false;
129  std::vector<ComplexType> rho_G1(NumIonSpecies), rho_G2(NumIonSpecies);
130  StructureFactor(G1, rho_G1);
131  StructureFactor(G2, rho_G2);
132  for (int i = 0; i < NumIonSpecies; i++)
133  for (int j = i + 1; j < NumIonSpecies; j++)
134  {
135  ComplexType zG1 = rho_G1[i] * qmcplusplus::conj(rho_G1[j]);
136  ComplexType zG2 = rho_G2[i] * qmcplusplus::conj(rho_G2[j]);
137  RealType SG1 = std::real(zG1);
138  RealType SG2 = std::real(zG2);
139  if (std::abs(SG1 - SG2) > 1.0e-8)
140  return SG1 < SG2;
141  }
142  return false;
143 }
144 
146 {
147  return (!(*this)(G1, G2) && !(*this)(G2, G1));
148  if (std::abs(dot(G1, G1) - dot(G2, G2)) > 1.0e-8)
149  return false;
150  std::vector<ComplexType> rho_G1(NumIonSpecies), rho_G2(NumIonSpecies);
151  StructureFactor(G1, rho_G1);
152  StructureFactor(G2, rho_G2);
153  for (int j = 0; j < NumIonSpecies; j++)
154  for (int i = j; i < NumIonSpecies; i++)
155  {
156  ComplexType zG1 = rho_G1[i] * qmcplusplus::conj(rho_G1[j]);
157  ComplexType zG2 = rho_G2[i] * qmcplusplus::conj(rho_G2[j]);
158  RealType SG1 = std::real(zG1);
159  RealType SG2 = std::real(zG2);
160  if (std::abs(SG1 - SG2) > 1.0e-8)
161  return false;
162  }
163  return true;
164 }
165 
166 template<typename T>
167 void kSpaceJastrow::sortGvecs(std::vector<PosType>& gvecs, std::vector<kSpaceCoef<T>>& coefs, SymmetryType symm)
168 {
169  if (!gvecs.size())
170  return;
171  if (symm == CRYSTAL)
172  {
173  // First pass: sort all the G-vectors into equivalent groups
174  std::sort(gvecs.begin(), gvecs.end(), *this);
175  // Now, look through the sorted G-vectors and group them
176  kSpaceCoef<T> coef;
177  coef.cG = T();
178  coef.firstIndex = coef.lastIndex = 0;
179  for (int i = 1; i < gvecs.size(); i++)
180  if (Equivalent(gvecs[i], gvecs[i - 1]))
181  coef.lastIndex = i;
182  else
183  {
184  coefs.push_back(coef);
185  coef.firstIndex = coef.lastIndex = i;
186  }
187  coefs.push_back(coef);
188  }
189  else if (symm == ISOTROPIC)
190  {
191  magLess comparator;
192  std::sort(gvecs.begin(), gvecs.end(), comparator);
193  RealType curMag2 = dot(gvecs[0], gvecs[0]);
194  kSpaceCoef<T> coef;
195  coef.cG = T();
196  coef.firstIndex = coef.lastIndex = 0;
197  for (int i = 1; i < gvecs.size(); i++)
198  {
199  RealType mag2 = dot(gvecs[i], gvecs[i]);
200  if (std::abs(mag2 - curMag2) < 1.0e-10)
201  coef.lastIndex = i;
202  else
203  {
204  coefs.push_back(coef);
205  coef.firstIndex = coef.lastIndex = i;
206  curMag2 = mag2;
207  }
208  }
209  coefs.push_back(coef);
210  }
211  else if (symm == NOSYMM)
212  {
213  coefs.resize(gvecs.size());
214  for (int i = 0; i < gvecs.size(); i++)
215  {
216  coefs[i].cG = T();
217  coefs[i].firstIndex = coefs[i].lastIndex = i;
218  }
219  }
220  app_log() << "Using a total of " << gvecs.size() << " G-vectors in " << coefs.size() << " symmetry groups.\n";
221  app_log() << "kSpace coefficient groups:\n";
222  for (int i = 0; i < coefs.size(); i++)
223  {
224  app_log() << " Group " << i << ":\n";
225  for (int j = coefs[i].firstIndex; j <= coefs[i].lastIndex; j++)
226  app_log() << " " << gvecs[j] << " " << std::sqrt(dot(gvecs[j], gvecs[j])) << std::endl;
227  }
228 }
229 
230 kSpaceJastrow::kSpaceJastrow(const ParticleSet& ions,
231  ParticleSet& elecs,
232  SymmetryType oneBodySymm,
233  RealType oneBodyCutoff,
234  std::string onebodyid,
235  bool oneBodySpin,
236  SymmetryType twoBodySymm,
237  RealType twoBodyCutoff,
238  std::string twobodyid,
239  bool twoBodySpin)
240  : WaveFunctionComponent(elecs.getName()),
241  OptimizableObject("kspace_" + elecs.getName()),
242  Ions(ions),
243  OneBodyID(onebodyid),
244  TwoBodyID(twobodyid)
245 {
246  Prefactor = 1.0 / elecs.getLattice().Volume;
247  NumIonSpecies = 0;
248  num_elecs = elecs.getTotalNum();
249  for (int iat = 0; iat < ions.getTotalNum(); iat++)
250  NumIonSpecies = std::max(NumIonSpecies, ions.GroupID[iat] + 1);
251  if (oneBodyCutoff > 0.0)
252  {
253  setupGvecs(oneBodyCutoff, OneBodyGvecs, true);
254  sortGvecs(OneBodyGvecs, OneBodySymmCoefs, oneBodySymm);
255  for (int i = 0; i < OneBodySymmCoefs.size(); i++)
256  {
257  std::stringstream name_real, name_imag;
258  name_real << OneBodyID << "_" << 2 * i;
259  name_imag << OneBodyID << "_" << 2 * i + 1;
260  myVars.insert(name_real.str(), OneBodySymmCoefs[i].cG.real(), true, optimize::LOGLINEAR_P);
261  myVars.insert(name_imag.str(), OneBodySymmCoefs[i].cG.imag(), true, optimize::LOGLINEAR_P);
262  //VarMap[name_real.str()] = &(OneBodySymmCoefs[i].cG.real());
263  //VarMap[name_imag.str()] = &(OneBodySymmCoefs[i].cG.imag());
264  }
265  }
266  if (twoBodyCutoff > 0.0)
267  {
268  setupGvecs(twoBodyCutoff, TwoBodyGvecs, false);
269  sortGvecs(TwoBodyGvecs, TwoBodySymmCoefs, twoBodySymm);
270  for (int i = 0; i < TwoBodySymmCoefs.size(); i++)
271  {
272  std::stringstream name;
273  name << TwoBodyID << "_" << i;
274  myVars.insert(name.str(), TwoBodySymmCoefs[i].cG, true, optimize::LOGLINEAR_P);
275  //VarMap[name.str()] = &(TwoBodySymmCoefs[i].cG);
276  }
277  }
278  if (oneBodySpin)
279  app_log() << "One-body k-space Jastrow is spin-dependent.\n";
280  if (twoBodySpin)
281  app_log() << "Two-body k-space Jastrow is spin-dependent.\n";
282  // Now resize all buffers
283  int nOne = OneBodyGvecs.size();
284  OneBodyCoefs.resize(nOne);
285  OneBody_rhoG.resize(nOne);
286  Ion_rhoG.resize(nOne);
287  OneBodyPhase.resize(nOne);
288  OneBody_e2iGr.resize(nOne);
289  int nTwo = TwoBodyGvecs.size();
290  int nelecs = elecs.getTotalNum();
291  TwoBodyCoefs.resize(nTwo);
292  TwoBody_rhoG.resize(nTwo);
293  TwoBodyPhase.resize(nTwo);
294  TwoBody_e2iGr_new.resize(nTwo);
295  TwoBody_e2iGr_old.resize(nTwo);
296  Delta_e2iGr.resize(nelecs, nTwo);
297  for (int iat = 0; iat < nelecs; iat++)
298  for (int i = 0; i < nTwo; i++)
299  Delta_e2iGr(iat, i) = ComplexType();
300  // Set Ion_rhoG
301  for (int i = 0; i < OneBodyGvecs.size(); i++)
302  {
303  Ion_rhoG[0] = ComplexType();
304  for (int iat = 0; iat < ions.getTotalNum(); iat++)
305  {
306  RealType phase = dot(OneBodyGvecs[i], ions.R[iat]);
307  Ion_rhoG[i] += ComplexType(std::cos(phase), std::sin(phase));
308  }
309  }
310 }
311 
312 void kSpaceJastrow::setCoefficients(std::vector<RealType>& oneBodyCoefs, std::vector<RealType>& twoBodyCoefs)
313 {
314  int kk(0);
315  // for (int i=0; i<oneBodyCoefs.size(); i++)
316  // std::cerr << "oneBodyCoefs[" << i << "] = " << oneBodyCoefs[i] << std::endl;
317  if (oneBodyCoefs.size() != 2 * OneBodySymmCoefs.size())
318  {
319  app_warning() << "Warning! Wrong number of coefficients specified in "
320  << "kSpaceJastrow's one-body coefficients.\n"
321  << oneBodyCoefs.size() << " were specified. Should have been " << 2 * OneBodySymmCoefs.size()
322  << std::endl;
323  for (int i = 0; i < OneBodySymmCoefs.size(); i++)
324  {
325  OneBodySymmCoefs[i].cG = ComplexType();
326  myVars[kk++] = 0.0;
327  myVars[kk++] = 0.0;
329  }
330  }
331  else
332  {
333  for (int i = 0; i < OneBodySymmCoefs.size(); i++)
334  {
335  OneBodySymmCoefs[i].cG = ComplexType(oneBodyCoefs[2 * i + 0], oneBodyCoefs[2 * i + 1]);
336  myVars[kk++] = oneBodyCoefs[2 * i + 0];
337  myVars[kk++] = oneBodyCoefs[2 * i + 1];
339  }
340  }
341  if (twoBodyCoefs.size() != TwoBodySymmCoefs.size())
342  {
343  app_warning() << "Warning! Wrong number of coefficients specified in "
344  << "kSpaceJastrow's two-body coefficients.\n"
345  << twoBodyCoefs.size() << " were specified. Should have been " << TwoBodySymmCoefs.size()
346  << std::endl;
347  for (int i = 0; i < TwoBodySymmCoefs.size(); i++)
348  {
349  TwoBodySymmCoefs[i].cG = 0.0;
350  myVars[kk++] = 0.0;
352  }
353  }
354  else
355  {
356  for (int i = 0; i < TwoBodySymmCoefs.size(); i++)
357  {
358  TwoBodySymmCoefs[i].cG = twoBodyCoefs[i];
359  myVars[kk++] = twoBodyCoefs[i];
361  }
362  }
363 }
364 
365 ///////////////////////////////////////////////////////////////
366 // Evaluation functions //
367 ///////////////////////////////////////////////////////////////
368 
372 {
373  RealType J1(0.0), J2(0.0);
374  int N = P.getTotalNum();
375  ComplexType eye(0.0, 1.0);
376  int nOne = OneBodyGvecs.size();
377  for (int iat = 0; iat < N; iat++)
378  {
379  PosType r(P.R[iat]);
380  for (int i = 0; i < nOne; i++)
381  OneBodyPhase[i] = dot(OneBodyGvecs[i], r);
383  for (int i = 0; i < nOne; i++)
384  {
386  J1 += Prefactor * real(z);
387  G[iat] += -Prefactor * real(z * eye) * OneBodyGvecs[i];
388  L[iat] += -Prefactor * dot(OneBodyGvecs[i], OneBodyGvecs[i]) * real(z);
389  }
390  }
391  // Do two-body part
392  int nTwo = TwoBodyGvecs.size();
393  for (int i = 0; i < nTwo; i++)
394  TwoBody_rhoG[i] = ComplexType();
395  for (int iat = 0; iat < N; iat++)
396  {
397  PosType r(P.R[iat]);
398  for (int iG = 0; iG < nTwo; iG++)
399  TwoBodyPhase[iG] = dot(TwoBodyGvecs[iG], r);
401  for (int iG = 0; iG < nTwo; iG++)
402  TwoBody_rhoG[iG] += TwoBody_e2iGr_new[iG];
403  }
404  // std::cerr << "TwoBody_rhoG = ";
405  // for (int i=0; i<nTwo; i++)
406  // std::cerr << TwoBody_rhoG[i] << " ";
407  // std::cerr << std::endl;
408  for (int i = 0; i < nTwo; i++)
409  J2 += Prefactor * TwoBodyCoefs[i] * norm(TwoBody_rhoG[i]);
410  for (int iat = 0; iat < N; iat++)
411  {
412  PosType r(P.R[iat]);
413  for (int i = 0; i < nTwo; i++)
414  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], r);
416  for (int i = 0; i < nTwo; i++)
417  {
418  PosType Gvec(TwoBodyGvecs[i]);
420  G[iat] += -Prefactor * 2.0 * Gvec * TwoBodyCoefs[i] * imag(qmcplusplus::conj(TwoBody_rhoG[i]) * z);
421  L[iat] +=
422  Prefactor * 2.0 * TwoBodyCoefs[i] * dot(Gvec, Gvec) * (-real(z * qmcplusplus::conj(TwoBody_rhoG[i])) + 1.0);
423  }
424  }
425  return J1 + J2;
426 }
427 
428 
430 {
431  // RealType J1(0.0), J2(0.0);
433  int N = P.getTotalNum();
434  ComplexType eye(0.0, 1.0);
435  int nOne = OneBodyGvecs.size();
436  // for (int iat=0; iat<N; iat++) {
437  PosType r(P.R[iat]);
438  for (int i = 0; i < nOne; i++)
439  OneBodyPhase[i] = dot(OneBodyGvecs[i], r);
441  for (int i = 0; i < nOne; i++)
442  {
444  // J1 += Prefactor*real(z);
445  G += -Prefactor * real(z * eye) * OneBodyGvecs[i];
446  // L[iat] += -Prefactor*dot(OneBodyGvecs[i],OneBodyGvecs[i])*real(z);
447  }
448  // }
449  // Do two-body part
450  int nTwo = TwoBodyGvecs.size();
451  for (int i = 0; i < nTwo; i++)
452  TwoBody_rhoG[i] = ComplexType();
453  for (int iat2 = 0; iat2 < N; iat2++)
454  {
455  PosType rp(P.R[iat2]);
456  for (int iG = 0; iG < nTwo; iG++)
457  TwoBodyPhase[iG] = dot(TwoBodyGvecs[iG], rp);
459  for (int iG = 0; iG < nTwo; iG++)
460  TwoBody_rhoG[iG] += TwoBody_e2iGr_new[iG];
461  }
462  // std::cerr << "TwoBody_rhoG = ";
463  // for (int i=0; i<nTwo; i++)
464  // std::cerr << TwoBody_rhoG[i] << " ";
465  // std::cerr << std::endl;
466  // for (int i=0; i<nTwo; i++)
467  // J2 += Prefactor*TwoBodyCoefs[i]*norm(TwoBody_rhoG[i]);
468  // for (int iat=0; iat<N; iat++) {
469  // PosType r(P.R[iat]);
470  for (int i = 0; i < nTwo; i++)
471  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], r);
473  for (int i = 0; i < nTwo; i++)
474  {
475  PosType Gvec(TwoBodyGvecs[i]);
477  G += -Prefactor * 2.0 * Gvec * TwoBodyCoefs[i] * imag(qmcplusplus::conj(TwoBody_rhoG[i]) * z);
478  // L[iat] += Prefactor*2.0*TwoBodyCoefs[i]*dot(Gvec,Gvec)*(-real(z*qmcplusplus::conj(TwoBody_rhoG[i])) + 1.0);
479  }
480  // }
481  return G;
482 }
483 
485 {
486  ComplexType eye(0.0, 1.0);
487  RealType J1new(0.0), J1old(0.0), J2new(0.0), J2old(0.0);
488  const PosType &rnew(P.getActivePos()), &rold(P.R[iat]);
489  // Compute one-body contribution
490  int nOne = OneBodyGvecs.size();
491  for (int i = 0; i < nOne; i++)
492  OneBodyPhase[i] = dot(OneBodyGvecs[i], rnew);
494  for (int i = 0; i < nOne; i++)
495  {
497  J1new += Prefactor * real(z);
498  grad_iat += -Prefactor * real(z * eye) * OneBodyGvecs[i];
499  }
500  for (int i = 0; i < nOne; i++)
501  OneBodyPhase[i] = dot(OneBodyGvecs[i], rold);
503  for (int i = 0; i < nOne; i++)
505  // Now, do two-body part
506  int nTwo = TwoBodyGvecs.size();
507  for (int i = 0; i < nTwo; i++)
508  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], rold);
510  for (int i = 0; i < nTwo; i++)
511  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], rnew);
513  for (int i = 0; i < nTwo; i++)
514  {
515  ComplexType rho_G = TwoBody_rhoG[i];
516  J2old += Prefactor * TwoBodyCoefs[i] * std::norm(rho_G);
517  }
518  for (int i = 0; i < nTwo; i++)
519  {
521  J2new += Prefactor * TwoBodyCoefs[i] * std::norm(rho_G);
522  }
523  for (int i = 0; i < nTwo; i++)
524  {
525  PosType Gvec(TwoBodyGvecs[i]);
527  grad_iat += -Prefactor * 2.0 * TwoBodyGvecs[i] * TwoBodyCoefs[i] *
529  }
530  return std::exp(static_cast<PsiValue>(J1new + J2new - (J1old + J2old)));
531 }
532 
533 /* evaluate the ratio with P.R[iat]
534  *
535  */
537 {
538  RealType J1new(0.0), J1old(0.0), J2new(0.0), J2old(0.0);
539  const PosType &rnew(P.getActivePos()), &rold(P.R[iat]);
540  // Compute one-body contribution
541  int nOne = OneBodyGvecs.size();
542  for (int i = 0; i < nOne; i++)
543  OneBodyPhase[i] = dot(OneBodyGvecs[i], rnew);
545  for (int i = 0; i < nOne; i++)
547  for (int i = 0; i < nOne; i++)
548  OneBodyPhase[i] = dot(OneBodyGvecs[i], rold);
550  for (int i = 0; i < nOne; i++)
552  // Now, do two-body part
553  int nTwo = TwoBodyGvecs.size();
554  for (int i = 0; i < nTwo; i++)
555  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], rold);
557  for (int i = 0; i < nTwo; i++)
558  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], rnew);
560  for (int i = 0; i < nTwo; i++)
561  {
562  ComplexType rho_G = TwoBody_rhoG[i];
563  J2old += Prefactor * TwoBodyCoefs[i] * std::norm(rho_G);
564  }
565  for (int i = 0; i < nTwo; i++)
566  {
568  J2new += Prefactor * TwoBodyCoefs[i] * std::norm(rho_G);
569  }
570  return std::exp(static_cast<PsiValue>(J1new + J2new - (J1old + J2old)));
571 }
572 
573 /** evaluate the ratio
574 */
575 void kSpaceJastrow::evaluateRatiosAlltoOne(ParticleSet& P, std::vector<kSpaceJastrow::ValueType>& ratios)
576 {
577  RealType J1new(0.0);
578  const PosType& rnew(P.getActivePos());
579  // Compute one-body contribution
580  int nOne = OneBodyGvecs.size();
581  for (int i = 0; i < nOne; i++)
582  OneBodyPhase[i] = dot(OneBodyGvecs[i], rnew);
584  // //
585  for (int i = 0; i < nOne; i++)
587  // Now, do two-body part
588  int nTwo = TwoBodyGvecs.size();
589  for (int i = 0; i < nTwo; i++)
590  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], rnew);
592  int N = P.getTotalNum();
593  for (int n = 0; n < N; n++)
594  {
595  RealType J1old(0.0), J2Rat(0.0);
596  const PosType& rold(P.R[n]);
597  for (int i = 0; i < nOne; i++)
598  OneBodyPhase[i] = dot(OneBodyGvecs[i], rold);
600  for (int i = 0; i < nOne; i++)
602  for (int i = 0; i < nTwo; i++)
603  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], rold);
605  for (int i = 0; i < nTwo; i++)
606  {
608  ComplexType rho_G_old = TwoBody_rhoG[i];
609  J2Rat += Prefactor * TwoBodyCoefs[i] * (std::norm(rho_G_new) - std::norm(rho_G_old));
610  }
611  ratios[n] = std::exp(J1new - J1old + J2Rat);
612  }
613 }
614 
615 
617 {
618  //substract the addition in logRatio
619  //if(NeedToRestore) Rhok -= delta_eikr;
620 }
621 
622 void kSpaceJastrow::acceptMove(ParticleSet& P, int iat, bool safe_to_delay)
623 {
624  for (int i = 0; i < TwoBody_e2iGr_new.size(); i++)
625  TwoBody_rhoG[i] += Delta_e2iGr(iat, i);
626  //TwoBody_e2iGr_new[i] - TwoBody_e2iGr_old[i];
627  // copy(eikr_new.data(),eikr_new.data()+MaxK,eikr[iat]);
628  // U += offU;
629  // dU += offdU;
630  // d2U += offd2U;
631 }
632 
634 {
635  log_value_ = evaluateLog(P, P.G, P.L);
636  // eikr.resize(NumPtcls,MaxK);
637  // eikr_new.resize(MaxK);
638  // delta_eikr.resize(MaxK);
639  // for(int iat=0; iat<NumPtcls; iat++)
640  // copy(P.getSK().eikr[iat],P.getSK().eikr[iat]+MaxK,eikr[iat]);
641  // buf.add(Rhok.first_address(), Rhok.last_address());
642  // buf.add(U.first_address(), U.last_address());
643  // buf.add(d2U.first_address(), d2U.last_address());
644  // buf.add(FirstAddressOfdU,LastAddressOfdU);
645  // return LogValue;
646 }
647 
649 {
650  log_value_ = evaluateLog(P, P.G, P.L);
651  // for(int iat=0; iat<NumPtcls; iat++)
652  // copy(P.getSK().eikr[iat],P.getSK().eikr[iat]+MaxK,eikr[iat]);
653  // buf.put(Rhok.first_address(), Rhok.last_address());
654  // buf.put(U.first_address(), U.last_address());
655  // buf.put(d2U.first_address(), d2U.last_address());
656  // buf.put(FirstAddressOfdU,LastAddressOfdU);
657  // return LogValue;
658  return log_value_;
659 }
660 
662 {
663  for (int i = 0; i < TwoBodyCoefs.size(); i++)
664  TwoBody_rhoG[i] = ComplexType();
665  for (int iat = 0; iat < num_elecs; iat++)
666  {
667  for (int i = 0; i < TwoBodyCoefs.size(); i++)
668  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], P.R[iat]);
670  for (int i = 0; i < TwoBodyCoefs.size(); i++)
672  }
673 }
674 
676 {
677  active.insertFrom(myVars);
678  int nOne = OneBodyGvecs.size();
679  int obi = 0;
680  if (nOne)
681  {
682  OneBodyVarMap.resize(nOne);
683  for (int i = 0; i < nOne; i++)
684  {
685  //two coeffs for each of these points, imaginary coefficients.
686  OneBodyVarMap[i] = obi;
687  if (i == OneBodySymmCoefs[obi / 2].lastIndex)
688  obi += 2;
689  }
690  }
691  int nTwo = TwoBodyGvecs.size();
692  TwoBodyVarMap.resize(nTwo);
693  int tbi = 0;
694  for (int i = 0; i < nTwo; i++)
695  {
696  //one coeff for each of these points, real coefficients.
697  TwoBodyVarMap[i] = obi + tbi;
698  if (i == TwoBodySymmCoefs[tbi].lastIndex)
699  tbi += 1;
700  }
701 }
702 
704 
706 {
707  int ii = 0;
708 
709  //Update the one body coefficients.
710  for (int i = 0; i < OneBodySymmCoefs.size(); i++)
711  {
712  //Reset and update the real part of one body term.
713 
714  int loc_r = myVars.where(ii);
715  if (loc_r >= 0)
716  {
717  myVars[ii] = active[loc_r]; //update the optimization parameter
718  //lvalue error with LLVM
719  OneBodySymmCoefs[i].cG = ComplexType(std::real(myVars[ii]), OneBodySymmCoefs[i].cG.imag());
720  //OneBodySymmCoefs[i].cG.real()=myVars[ii]; //update the coefficient from local opt parametr
721  ii++;
722  }
723  //The imaginary part...
724  int loc_i = myVars.where(ii);
725  if (loc_i >= 0)
726  {
727  myVars[ii] = active[loc_i];
728  //lvalue error with LLVM
729  OneBodySymmCoefs[i].cG = ComplexType(OneBodySymmCoefs[i].cG.real(), std::real(myVars[ii]));
730  //OneBodySymmCoefs[i].cG.imag()=myVars[ii];
731  ii++;
732  }
733  }
734 
735  //Update the two-body coefficients
736  for (int i = 0; i < TwoBodySymmCoefs.size(); i++)
737  {
738  int loc = myVars.where(ii);
739  if (loc >= 0)
740  {
741  myVars[ii] = active[loc];
742  TwoBodySymmCoefs[i].cG = std::real(myVars[ii]);
743  }
744  ii++;
745  }
746 
747 
748  for (int i = 0; i < OneBodySymmCoefs.size(); i++)
750  for (int i = 0; i < TwoBodySymmCoefs.size(); i++)
752 }
753 
754 bool kSpaceJastrow::put(xmlNodePtr cur) { return true; }
755 
756 std::unique_ptr<WaveFunctionComponent> kSpaceJastrow::makeClone(ParticleSet& tqp) const
757 {
758  auto kj = std::make_unique<kSpaceJastrow>(Ions);
759  kj->copyFrom(*this);
760  // kSpaceJastrow *kj = new kSpaceJastrow(*this);
761  // kj->VarMap.clear();
762  // for (int i=0; i<OneBodySymmCoefs.size(); i++) {
763  // std::stringstream name_real, name_imag;
764  // name_real << OneBodyID << "_" << 2*i;
765  // name_imag << OneBodyID << "_" << 2*i+1;
766  // kj->VarMap[name_real.str()] = &(kj->OneBodySymmCoefs[i].cG.real());
767  // kj->VarMap[name_imag.str()] = &(kj->OneBodySymmCoefs[i].cG.imag());
768  // }
769  // for (int i=0; i<TwoBodySymmCoefs.size(); i++) {
770  // std::stringstream name;
771  // name << TwoBodyID << "_" << i;
772  // kj->VarMap[name.str()] = &(kj->TwoBodySymmCoefs[i].cG);
773  // }
774  return kj;
775 }
776 
777 /** constructor to initialize Ions
778  */
780  : WaveFunctionComponent(ions.getName()), OptimizableObject("kspace_" + ions.getName()), Ions(ions)
781 {}
782 
784 {
785  CellVolume = old.CellVolume;
787  num_elecs = old.num_elecs;
788  NumSpins = old.NumSpins;
789  NumIons = old.NumIons;
799  Ion_rhoG = old.Ion_rhoG;
807  Delta_e2iGr = old.Delta_e2iGr;
808  OneBodyID = old.OneBodyID;
809  TwoBodyID = old.TwoBodyID;
810  //copy the variable map
811  myVars = old.myVars;
814  Prefactor = old.Prefactor;
815  //for (int i=0; i<OneBodySymmCoefs.size(); i++) {
816  // std::stringstream name_real, name_imag;
817  // name_real << OneBodyID << "_" << 2*i;
818  // name_imag << OneBodyID << "_" << 2*i+1;
819  // VarMap[name_real.str()] = &(OneBodySymmCoefs[i].cG.real());
820  // VarMap[name_imag.str()] = &(OneBodySymmCoefs[i].cG.imag());
821  //}
822  //for (int i=0; i<TwoBodySymmCoefs.size(); i++) {
823  // std::stringstream name;
824  // name << TwoBodyID << "_" << i;
825  // VarMap[name.str()] = &(TwoBodySymmCoefs[i].cG);
826  //}
827 }
828 
830  const opt_variables_type& active,
831  Vector<ValueType>& dlogpsi,
832  Vector<ValueType>& dhpsioverpsi)
833 {
834  bool recalculate(false);
835  for (int k = 0; k < myVars.size(); ++k)
836  {
837  int kk = myVars.where(k);
838  if (kk < 0)
839  continue;
840  if (active.recompute(kk))
841  recalculate = true;
842  }
843  if (recalculate)
844  {
845  int N = P.getTotalNum();
846  ComplexType eye(0.0, 1.0);
847  RealType tmp_dot;
848  int nOne = OneBodyGvecs.size();
849  if (nOne)
850  {
851  for (int iat = 0; iat < N; iat++)
852  {
853  PosType r(P.R[iat]);
854  for (int i = 0; i < nOne; i++)
855  OneBodyPhase[i] = dot(OneBodyGvecs[i], r);
857  for (int i = 0; i < nOne; i++)
858  {
860  int kk = myVars.where(OneBodyVarMap[i]);
861  if (kk >= 0)
862  {
863  //real part of coeff
864  dlogpsi[kk] += ValueType(Prefactor * real(z));
865  //convertToReal(dot(OneBodyGvecs[i],P.G[iat]),tmp_dot);
866  convertToReal(dot(P.G[iat], OneBodyGvecs[i]), tmp_dot);
867  dhpsioverpsi[kk] += ValueType(0.5 * Prefactor * dot(OneBodyGvecs[i], OneBodyGvecs[i]) * real(z) +
868  Prefactor * real(z * eye) * tmp_dot);
869  // + Prefactor*real(z*eye)*real(dot(OneBodyGvecs[i],P.G[iat]));
870  //imaginary part of coeff,
871  dlogpsi[kk + 1] += ValueType(Prefactor * real(eye * z));
872  //mius here due to i*i term
873  //dhpsioverpsi[kk+1] += 0.5*Prefactor*dot(OneBodyGvecs[i],OneBodyGvecs[i])*real(eye*z) - Prefactor*real(z)*real(dot(OneBodyGvecs[i],P.G[iat]));
874  dhpsioverpsi[kk + 1] += ValueType(0.5 * Prefactor * dot(OneBodyGvecs[i], OneBodyGvecs[i]) * real(eye * z) -
875  Prefactor * real(z) * tmp_dot);
876  }
877  }
878  }
879  }
880  // Do two-body part
881  int nTwo = TwoBodyGvecs.size();
882  for (int i = 0; i < nTwo; i++)
883  TwoBody_rhoG[i] = ComplexType();
884  for (int iat = 0; iat < N; iat++)
885  {
886  PosType r(P.R[iat]);
887  for (int iG = 0; iG < nTwo; iG++)
888  TwoBodyPhase[iG] = dot(TwoBodyGvecs[iG], r);
890  for (int iG = 0; iG < nTwo; iG++)
891  TwoBody_rhoG[iG] += TwoBody_e2iGr_new[iG];
892  }
893  for (int i = 0; i < nTwo; i++)
894  {
895  int kk = myVars.where(TwoBodyVarMap[i]);
896  if (kk >= 0)
897  {
898  dlogpsi[kk] += ValueType(Prefactor * norm(TwoBody_rhoG[i]));
899  }
900  }
901  for (int iat = 0; iat < N; iat++)
902  {
903  PosType r(P.R[iat]);
904  for (int i = 0; i < nTwo; i++)
905  TwoBodyPhase[i] = dot(TwoBodyGvecs[i], r);
907  for (int i = 0; i < nTwo; i++)
908  {
909  PosType Gvec(TwoBodyGvecs[i]);
911  int kk = myVars.where(TwoBodyVarMap[i]);
912  if (kk > 0)
913  {
914  convertToReal(dot(P.G[iat], Gvec), tmp_dot);
915  //dhpsioverpsi[kk] -= Prefactor*dot(Gvec,Gvec)*(-real(z*qmcplusplus::conj(TwoBody_rhoG[i])) + 1.0) - Prefactor*2.0*real(dot(P.G[iat],Gvec))*imag(qmcplusplus::conj(TwoBody_rhoG[i])*z);
916  dhpsioverpsi[kk] -=
917  ValueType(Prefactor * dot(Gvec, Gvec) * (-real(z * qmcplusplus::conj(TwoBody_rhoG[i])) + 1.0) -
918  Prefactor * 2.0 * tmp_dot * imag(qmcplusplus::conj(TwoBody_rhoG[i]) * z));
919  }
920  }
921  }
922  }
923 }
924 
925 void kSpaceJastrow::printOneBody(std::ostream& os)
926 {
927  for (int i = 0; i < OneBodyCoefs.size(); i++)
928  {
929  PosType gvec = OneBodyGvecs[i];
930  ComplexType coeff = OneBodyCoefs[i];
931  os << std::fixed << std::setprecision(6) << std::setw(12) << gvec[0] << std::setw(12) << gvec[1] << std::setw(12)
932  << gvec[2] << std::setw(24) << coeff.real() << std::setw(24) << coeff.imag() << std::endl;
933  }
934 }
935 
936 void kSpaceJastrow::printTwoBody(std::ostream& os)
937 {
938  for (int i = 0; i < TwoBodyCoefs.size(); i++)
939  {
940  PosType gvec = TwoBodyGvecs[i];
941  ComplexType coeff = TwoBodyCoefs[i];
942  os << std::fixed << std::setprecision(6) << std::setw(12) << gvec[0] << std::setw(12) << gvec[1] << std::setw(12)
943  << gvec[2] << std::setw(24) << coeff.real() << std::setw(24) << coeff.imag() << std::endl;
944  }
945 }
946 
947 } // namespace qmcplusplus
bool operator()(PosType G1, PosType G2)
void checkInVariablesExclusive(opt_variables_type &active) final
check in variational parameters to the global list of parameters used by the optimizer.
bool recompute(int i) const
Definition: VariableSet.h:206
std::unique_ptr< WaveFunctionComponent > makeClone(ParticleSet &tqp) const override
make clone
std::vector< ComplexType > OneBody_e2iGr
std::ostream & app_warning()
Definition: OutputManager.h:69
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
std::vector< kSpaceCoef< ComplexType > > OneBodySymmCoefs
Definition: kSpaceJastrow.h:95
QTBase::RealType RealType
Definition: Configuration.h:58
void evaluateRatiosAlltoOne(ParticleSet &P, std::vector< ValueType > &ratios) override
evaluate the ratio
void printTwoBody(std::ostream &os)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
GradType evalGrad(ParticleSet &P, int iat) override
return the current gradient for the iat-th particle
void registerData(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
size_t getTotalNum() const
Definition: ParticleSet.h:493
void copyFromBuffer(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
std::ostream & app_log()
Definition: OutputManager.h:65
std::vector< ComplexType > OneBody_rhoG
void restore(int iat) override
If a move for iat-th particle is rejected, restore to the content.
MakeReturn< UnaryNode< FnSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sin(const Vector< T1, C1 > &l)
LogValue updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false) override
For particle-by-particle move.
void convertToReal(const T1 &in, T2 &out)
generic conversion from type T1 to type T2 using implicit conversion
Definition: ConvertToReal.h:32
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
void setCoefficients(std::vector< RealType > &oneBodyCoefs, std::vector< RealType > &twoBodyCoefs)
void resize(size_type n, size_type m)
Resize the container.
Definition: OhmmsMatrix.h:99
Attaches a unit to a Vector for IO.
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
std::vector< int > OneBodyVarMap
#define OHMMS_DIM
Definition: config.h:64
ParticleIndex GroupID
Species ID.
Definition: ParticleSet.h:77
Matrix< ComplexType > Delta_e2iGr
opt_variables_type myVars
list of variables this WaveFunctionComponent handles
std::complex< QTFull::RealType > LogValue
std::vector< ComplexType > TwoBody_e2iGr_new
An abstract class for a component of a many-body trial wave function.
const PosType & getActivePos() const
Definition: ParticleSet.h:261
bool operator()(kSpaceJastrow::PosType a, kSpaceJastrow::PosType b)
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
const ParticleSet & Ions
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &active, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi) override
double norm(const zVec &c)
Definition: VectorOps.h:118
std::vector< PosType > OneBodyGvecs
Definition: kSpaceJastrow.h:90
QTBase::ValueType ValueType
Definition: Configuration.h:60
void insert(const std::string &vname, real_type v, bool enable=true, int type=OTHER_P)
Definition: VariableSet.h:133
void checkOutVariables(const opt_variables_type &active) override
check out variational optimizable variables
bool put(xmlNodePtr cur)
process input file
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
int where(int i) const
return the locator of the i-th Index
Definition: VariableSet.h:90
ParticlePos R
Position.
Definition: ParticleSet.h:79
Declaration of Long-range TwoBody Jastrow.
std::vector< RealType > TwoBodyPhase
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
std::vector< RealType > TwoBodyCoefs
size_type size() const
return the size
Definition: VariableSet.h:88
std::vector< ComplexType > Ion_rhoG
std::complex< RealType > ComplexType
Definition: kSpaceJastrow.h:79
float conj(const float &c)
Workaround to allow conj on scalar to return real instead of complex.
std::vector< ComplexType > OneBodyCoefs
void printOneBody(std::ostream &os)
output jastrow coefficients
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
void copyFrom(const kSpaceJastrow &old)
LogValue evaluateLog(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) override
evaluate the value of the WaveFunctionComponent from scratch
PsiValue ratio(ParticleSet &P, int iat) override
evaluate the ratio of the new to old WaveFunctionComponent value
std::vector< ComplexType > TwoBody_rhoG
kSpaceJastrow(const ParticleSet &ions, ParticleSet &elecs, SymmetryType oneBodySymm, RealType oneBodyCutoff, std::string onebodyid, bool oneBodySpin, SymmetryType twoBodySymm, RealType twoBodyCutoff, std::string twobodyid, bool twoBodySpin)
void sortGvecs(std::vector< PosType > &gvecs, std::vector< kSpaceCoef< T >> &coefs, SymmetryType symm)
const auto & getLattice() const
Definition: ParticleSet.h:251
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
void insertFrom(const VariableSet &input)
insert a VariableSet to the list
Definition: VariableSet.cpp:37
bool Include(int i, int j, int k)
std::vector< kSpaceCoef< RealType > > TwoBodySymmCoefs
Definition: kSpaceJastrow.h:96
std::vector< int > TwoBodyVarMap
void setupGvecs(RealType kcut, std::vector< PosType > &gvecs, bool useStructFact)
std::vector< ComplexType > TwoBody_e2iGr_old
int getIndex(const std::string &vname) const
return the Index vaule for the named parameter
void StructureFactor(PosType G, std::vector< ComplexType > &rho_G)
std::vector< RealType > OneBodyPhase
bool Equivalent(PosType G1, PosType G2)
void eval_e2iphi(int n, const T *restrict phi, T *restrict phase_r, T *restrict phase_i)
Definition: e2iphi.h:61
PsiValue ratioGrad(ParticleSet &P, int iat, GradType &grad_iat) override
evaluate the ratio of the new to old WaveFunctionComponent value and the new gradient ...
std::vector< PosType > TwoBodyGvecs
Definition: kSpaceJastrow.h:91
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false) override
a move for iat-th particle is accepted.
MakeReturn< UnaryNode< FnFloor, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t floor(const Vector< T1, C1 > &l)
void resetParametersExclusive(const opt_variables_type &active) final
reset the parameters during optimizations.