QMCPACK
JeeIOrbitalSoA.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) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #ifndef QMCPLUSPLUS_EEIJASTROW_OPTIMIZED_SOA_H
14 #define QMCPLUSPLUS_EEIJASTROW_OPTIMIZED_SOA_H
15 #include "Configuration.h"
16 #if !defined(QMC_BUILD_SANDBOX_ONLY)
18 #endif
19 #include "Particle/DistanceTable.h"
21 #include "CPU/SIMD/algorithm.hpp"
22 #include <map>
23 #include <numeric>
24 #include <memory>
25 
26 namespace qmcplusplus
27 {
28 /** @ingroup WaveFunctionComponent
29  * @brief Specialization for three-body Jastrow function using multiple functors
30  *
31  *Each pair-type can have distinct function \f$u(r_{ij})\f$.
32  *For electrons, distinct pair correlation functions are used
33  *for spins up-up/down-down and up-down/down-up.
34  */
35 template<class FT>
37 {
38  ///type of each component U, dU, d2U;
39  using valT = typename FT::real_type;
40  ///element position type
42  ///use the same container
45  ///table index for el-el
46  const int ee_Table_ID_;
47  ///table index for i-el
48  const int ei_Table_ID_;
49  //number of particles
50  int Nelec, Nion;
51  ///number of particles + padded
52  size_t Nelec_padded;
53  //number of groups of the target particleset
55  ///reference to the sources (ions)
56  const ParticleSet& Ions;
57  ///diff value
59 
60  ///\f$Uat[i] = sum_(j) u_{i,j}\f$
62  ///\f$dUat[i] = sum_(j) du_{i,j}\f$
65  ///\f$d2Uat[i] = sum_(j) d2u_{i,j}\f$
67  /// current values during PbyP
70  ///container for the Jastrow functions
72 
73  std::map<std::string, std::unique_ptr<FT>> J3Unique;
74  //YYYY
75  std::map<FT*, int> J3UniqueIndex;
76 
77  /// the cutoff for e-I pairs
78  std::vector<valT> Ion_cutoff;
79  /// the electrons around ions within the cutoff radius, grouped by species
83  /// the ids of ions within the cutoff radius of an electron on which a move is proposed
84  std::vector<int> ions_nearby_old, ions_nearby_new;
85 
86  /// work buffer size
87  size_t Nbuffer;
88  /// compressed distances
90  std::vector<int> DistIndice_k;
91  /// compressed displacements
93  /// work result buffer
95 
96  // Used for evaluating derivatives with respect to the parameters
101 
102  // Temporary store for parameter derivatives of functor
103  // The first index is the functor index in J3Unique. The second is the parameter index w.r.t. to that
104  // functor
105  std::vector<std::vector<RealType>> du_dalpha;
106  std::vector<std::vector<PosType>> dgrad_dalpha;
107  std::vector<std::vector<Tensor<RealType, 3>>> dhess_dalpha;
108 
110  {
112  gradLogPsi.resize(myVars.size(), Nelec);
114 
115  du_dalpha.resize(J3Unique.size());
116  dgrad_dalpha.resize(J3Unique.size());
117  dhess_dalpha.resize(J3Unique.size());
118 
119  int ifunc = 0;
120  for (auto& j3UniquePair : J3Unique)
121  {
122  auto functorPtr = j3UniquePair.second.get();
123  J3UniqueIndex[functorPtr] = ifunc;
124  const int numParams = functorPtr->getNumParameters();
125  du_dalpha[ifunc].resize(numParams);
126  dgrad_dalpha[ifunc].resize(numParams);
127  dhess_dalpha[ifunc].resize(numParams);
128  ifunc++;
129  }
130  }
131 
132  /// compute G and L from internally stored data
134  {
135  for (int iat = 0; iat < Nelec; ++iat)
136  {
137  G[iat] += dUat[iat];
138  L[iat] += d2Uat[iat];
139  }
140  return -0.5 * simd::accumulate_n(Uat.data(), Nelec, QTFull::RealType());
141  }
142 
143 
144 public:
145  ///alias FuncType
146  using FuncType = FT;
147 
148  JeeIOrbitalSoA(const std::string& obj_name, const ParticleSet& ions, ParticleSet& elecs)
149  : WaveFunctionComponent(obj_name),
152  Ions(ions)
153  {
154  if (my_name_.empty())
155  throw std::runtime_error("JeeIOrbitalSoA object name cannot be empty!");
156  init(elecs);
157  }
158 
159  std::string getClassName() const override { return "JeeIOrbitalSoA"; }
160 
161  std::unique_ptr<WaveFunctionComponent> makeClone(ParticleSet& elecs) const override
162  {
163  auto eeIcopy = std::make_unique<JeeIOrbitalSoA<FT>>(my_name_, Ions, elecs);
164  std::map<const FT*, FT*> fcmap;
165  for (int iG = 0; iG < iGroups; iG++)
166  for (int eG1 = 0; eG1 < eGroups; eG1++)
167  for (int eG2 = 0; eG2 < eGroups; eG2++)
168  {
169  if (F(iG, eG1, eG2) == nullptr)
170  continue;
171  auto fit = fcmap.find(F(iG, eG1, eG2));
172  if (fit == fcmap.end())
173  {
174  auto fc = std::make_unique<FT>(*F(iG, eG1, eG2));
175  fcmap[F(iG, eG1, eG2)] = fc.get();
176  eeIcopy->addFunc(iG, eG1, eG2, std::move(fc));
177  }
178  }
179  // Ye: I don't like the following memory allocated by default.
180  eeIcopy->myVars.clear();
181  eeIcopy->myVars.insertFrom(myVars);
182  eeIcopy->VarOffset = VarOffset;
183  return eeIcopy;
184  }
185 
186  void init(ParticleSet& p)
187  {
188  Nelec = p.getTotalNum();
189  Nelec_padded = getAlignedSize<valT>(Nelec);
190  Nion = Ions.getTotalNum();
192  eGroups = p.groups();
193 
194  Uat.resize(Nelec);
195  dUat.resize(Nelec);
196  d2Uat.resize(Nelec);
197 
198  oldUk.resize(Nelec);
201  newUk.resize(Nelec);
204 
206  F = nullptr;
210  ions_nearby_old.resize(Nion);
211  ions_nearby_new.resize(Nion);
212  Ion_cutoff.resize(Nion, 0.0);
213 
214  //initialize buffers
215  Nbuffer = Nelec;
217  Distjk_Compressed.resize(Nbuffer);
218  DistjI_Compressed.resize(Nbuffer);
219  DistkI_Compressed.resize(Nbuffer);
223  DistIndice_k.resize(Nbuffer);
224  }
225 
226  void addFunc(int iSpecies, int eSpecies1, int eSpecies2, std::unique_ptr<FT> j)
227  {
228  if (eSpecies1 == eSpecies2)
229  {
230  //if only up-up is specified, assume spin-unpolarized correlations
231  if (eSpecies1 == 0)
232  for (int eG1 = 0; eG1 < eGroups; eG1++)
233  for (int eG2 = 0; eG2 < eGroups; eG2++)
234  {
235  if (F(iSpecies, eG1, eG2) == 0)
236  F(iSpecies, eG1, eG2) = j.get();
237  }
238  }
239  else
240  {
241  F(iSpecies, eSpecies1, eSpecies2) = j.get();
242  F(iSpecies, eSpecies2, eSpecies1) = j.get();
243  }
244  if (j)
245  {
246  RealType rcut = 0.5 * j->cutoff_radius;
247  for (int i = 0; i < Nion; i++)
248  if (Ions.GroupID[i] == iSpecies)
249  Ion_cutoff[i] = rcut;
250  }
251  else
252  {
253  APP_ABORT("JeeIOrbitalSoA::addFunc Jastrow function pointer is NULL");
254  }
255  std::stringstream aname;
256  aname << iSpecies << "_" << eSpecies1 << "_" << eSpecies2;
257  J3Unique.emplace(aname.str(), std::move(j));
258  }
259 
260 
261  /** check that correlation information is complete
262  */
264  {
265  //check that correlation pointers are either all 0 or all assigned
266  bool complete = true;
267  for (int i = 0; i < iGroups; ++i)
268  {
269  int nfilled = 0;
270  bool partial;
271  for (int e1 = 0; e1 < eGroups; ++e1)
272  for (int e2 = 0; e2 < eGroups; ++e2)
273  if (F(i, e1, e2) != 0)
274  nfilled++;
275  partial = nfilled > 0 && nfilled < eGroups * eGroups;
276  if (partial)
277  app_log() << "J3 eeI is missing correlation for ion " << i << std::endl;
278  complete = complete && !partial;
279  }
280  if (!complete)
281  {
282  APP_ABORT("JeeIOrbitalSoA::check_complete J3 eeI is missing correlation components\n see preceding messages "
283  "for details");
284  }
285  //first set radii
286  for (int i = 0; i < Nion; ++i)
287  {
288  FT* f = F(Ions.GroupID[i], 0, 0);
289  if (f != 0)
290  Ion_cutoff[i] = .5 * f->cutoff_radius;
291  }
292  //then check radii
293  bool all_radii_match = true;
294  for (int i = 0; i < iGroups; ++i)
295  {
296  if (F(i, 0, 0) != 0)
297  {
298  bool radii_match = true;
299  RealType rcut = F(i, 0, 0)->cutoff_radius;
300  for (int e1 = 0; e1 < eGroups; ++e1)
301  for (int e2 = 0; e2 < eGroups; ++e2)
302  radii_match = radii_match && F(i, e1, e2)->cutoff_radius == rcut;
303  if (!radii_match)
304  app_log() << "eeI functors for ion species " << i << " have different radii" << std::endl;
305  all_radii_match = all_radii_match && radii_match;
306  }
307  }
308  if (!all_radii_match)
309  {
310  APP_ABORT("JeeIOrbitalSoA::check_radii J3 eeI are inconsistent for some ion species\n see preceding messages "
311  "for details");
312  }
313  }
314 
315  bool isOptimizable() const override { return true; }
316 
317  void extractOptimizableObjectRefs(UniqueOptObjRefs& opt_obj_refs) override
318  {
319  for (auto& [key, functor] : J3Unique)
320  opt_obj_refs.push_back(*functor);
321  }
322 
323  /** check out optimizable variables
324  */
325  void checkOutVariables(const opt_variables_type& active) override
326  {
327  myVars.clear();
328 
329  for (auto& ftPair : J3Unique)
330  {
331  ftPair.second->myVars.getIndex(active);
332  myVars.insertFrom(ftPair.second->myVars);
333  }
334 
335  myVars.getIndex(active);
336  const size_t NumVars = myVars.size();
337  if (NumVars)
338  {
340  int varoffset = myVars.Index[0];
341  for (int ig = 0; ig < iGroups; ig++)
342  for (int jg = 0; jg < eGroups; jg++)
343  for (int kg = 0; kg < eGroups; kg++)
344  {
345  FT* func_ijk = F(ig, jg, kg);
346  if (func_ijk == nullptr)
347  continue;
348  VarOffset(ig, jg, kg).first = func_ijk->myVars.Index.front() - varoffset;
349  VarOffset(ig, jg, kg).second = func_ijk->myVars.Index.size() + VarOffset(ig, jg, kg).first;
350  }
351  }
352  }
353 
355  {
356  const auto& eI_dists = P.getDistTableAB(ei_Table_ID_).getDistances();
357  const auto& eI_displs = P.getDistTableAB(ei_Table_ID_).getDisplacements();
358 
359  for (int iat = 0; iat < Nion; ++iat)
360  for (int jg = 0; jg < eGroups; ++jg)
361  {
362  elecs_inside(jg, iat).clear();
363  elecs_inside_dist(jg, iat).clear();
364  elecs_inside_displ(jg, iat).clear();
365  }
366 
367  for (int jg = 0; jg < eGroups; ++jg)
368  for (int jel = P.first(jg); jel < P.last(jg); jel++)
369  for (int iat = 0; iat < Nion; ++iat)
370  if (eI_dists[jel][iat] < Ion_cutoff[iat])
371  {
372  elecs_inside(jg, iat).push_back(jel);
373  elecs_inside_dist(jg, iat).push_back(eI_dists[jel][iat]);
374  elecs_inside_displ(jg, iat).push_back(eI_displs[jel][iat]);
375  }
376  }
377 
380  ParticleSet::ParticleLaplacian& L) override
381  {
382  recompute(P);
383  return log_value_ = computeGL(G, L);
384  }
385 
386  PsiValue ratio(ParticleSet& P, int iat) override
387  {
389 
390  const auto& eI_table = P.getDistTableAB(ei_Table_ID_);
391  const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
392  cur_Uat = computeU(P, iat, P.GroupID[iat], eI_table.getTempDists(), ee_table.getTempDists(), ions_nearby_new);
393  DiffVal = Uat[iat] - cur_Uat;
394  return std::exp(static_cast<PsiValue>(DiffVal));
395  }
396 
397  void evaluateRatios(const VirtualParticleSet& VP, std::vector<ValueType>& ratios) override
398  {
399  assert(VP.getTotalNum() == ratios.size());
400  for (int k = 0; k < ratios.size(); ++k)
401  ratios[k] = std::exp(Uat[VP.refPtcl] -
402  computeU(VP.getRefPS(), VP.refPtcl, VP.getRefPS().GroupID[VP.refPtcl],
405  }
406 
407  void evaluateRatiosAlltoOne(ParticleSet& P, std::vector<ValueType>& ratios) override
408  {
409  const auto& eI_table = P.getDistTableAB(ei_Table_ID_);
410  const auto& eI_dists = eI_table.getDistances();
411  const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
412 
413  for (int jg = 0; jg < eGroups; ++jg)
414  {
415  const valT sumU = computeU(P, -1, jg, eI_table.getTempDists(), ee_table.getTempDists(), ions_nearby_new);
416 
417  for (int j = P.first(jg); j < P.last(jg); ++j)
418  {
419  // remove self-interaction
420  valT Uself(0);
421  for (int iat = 0; iat < Nion; ++iat)
422  {
423  const valT& r_Ij = eI_table.getTempDists()[iat];
424  const valT& r_Ik = eI_dists[j][iat];
425  if (r_Ij < Ion_cutoff[iat] && r_Ik < Ion_cutoff[iat])
426  {
427  const int ig = Ions.GroupID[iat];
428  Uself += F(ig, jg, jg)->evaluate(ee_table.getTempDists()[j], r_Ij, r_Ik);
429  }
430  }
431  ratios[j] = std::exp(Uat[j] + Uself - sumU);
432  }
433  }
434  }
435 
436  GradType evalGrad(ParticleSet& P, int iat) override { return GradType(dUat[iat]); }
437 
438  PsiValue ratioGrad(ParticleSet& P, int iat, GradType& grad_iat) override
439  {
441 
442  const auto& eI_table = P.getDistTableAB(ei_Table_ID_);
443  const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
444  computeU3(P, iat, eI_table.getTempDists(), eI_table.getTempDispls(), ee_table.getTempDists(),
445  ee_table.getTempDispls(), cur_Uat, cur_dUat, cur_d2Uat, newUk, newdUk, newd2Uk, ions_nearby_new);
446  DiffVal = Uat[iat] - cur_Uat;
447  grad_iat += cur_dUat;
448  return std::exp(static_cast<PsiValue>(DiffVal));
449  }
450 
451  inline void restore(int iat) override {}
452 
453  void acceptMove(ParticleSet& P, int iat, bool safe_to_delay = false) override
454  {
455  const auto& eI_table = P.getDistTableAB(ei_Table_ID_);
456  const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
457  // get the old value, grad, lapl
458  computeU3(P, iat, eI_table.getDistRow(iat), eI_table.getDisplRow(iat), ee_table.getOldDists(),
459  ee_table.getOldDispls(), Uat[iat], dUat_temp, d2Uat[iat], oldUk, olddUk, oldd2Uk, ions_nearby_old);
460  if (UpdateMode == ORB_PBYP_RATIO)
461  { //ratio-only during the move; need to compute derivatives
462  computeU3(P, iat, eI_table.getTempDists(), eI_table.getTempDispls(), ee_table.getTempDists(),
463  ee_table.getTempDispls(), cur_Uat, cur_dUat, cur_d2Uat, newUk, newdUk, newd2Uk, ions_nearby_new);
464  }
465 
466 #pragma omp simd
467  for (int jel = 0; jel < Nelec; jel++)
468  {
469  Uat[jel] += newUk[jel] - oldUk[jel];
470  d2Uat[jel] += newd2Uk[jel] - oldd2Uk[jel];
471  }
472  for (int idim = 0; idim < OHMMS_DIM; ++idim)
473  {
474  valT* restrict save_g = dUat.data(idim);
475  const valT* restrict new_g = newdUk.data(idim);
476  const valT* restrict old_g = olddUk.data(idim);
477 #pragma omp simd aligned(save_g, new_g, old_g : QMC_SIMD_ALIGNMENT)
478  for (int jel = 0; jel < Nelec; jel++)
479  save_g[jel] += new_g[jel] - old_g[jel];
480  }
481 
482  log_value_ += Uat[iat] - cur_Uat;
483  Uat[iat] = cur_Uat;
484  dUat(iat) = cur_dUat;
485  d2Uat[iat] = cur_d2Uat;
486 
487  const int ig = P.GroupID[iat];
488  // update compact list elecs_inside
489  // if the old position exists in elecs_inside
490  for (int iind = 0; iind < ions_nearby_old.size(); iind++)
491  {
492  int jat = ions_nearby_old[iind];
493  auto iter = std::find(elecs_inside(ig, jat).begin(), elecs_inside(ig, jat).end(), iat);
494  auto iter_dist = elecs_inside_dist(ig, jat).begin() + std::distance(elecs_inside(ig, jat).begin(), iter);
495  auto iter_displ = elecs_inside_displ(ig, jat).begin() + std::distance(elecs_inside(ig, jat).begin(), iter);
496 // sentinel code
497 #ifndef NDEBUG
498  if (iter == elecs_inside(ig, jat).end())
499  {
500  std::cerr << std::setprecision(std::numeric_limits<valT>::digits10 + 1) << "updating electron iat = " << iat
501  << " near ion " << jat << " dist " << eI_table.getDistRow(iat)[jat] << std::endl;
502  throw std::runtime_error("BUG electron not found in elecs_inside");
503  }
504  else if (std::abs(eI_table.getDistRow(iat)[jat] - *iter_dist) >= std::numeric_limits<valT>::epsilon())
505  {
506  std::cerr << std::setprecision(std::numeric_limits<valT>::digits10 + 1) << "inconsistent electron iat = " << iat
507  << " near ion " << jat << " dist " << eI_table.getDistRow(iat)[jat]
508  << " stored value = " << *iter_dist << std::endl;
509  throw std::runtime_error("BUG eI distance stored value elecs_inside_dist not matching distance table");
510  }
511 #endif
512 
513  if (eI_table.getTempDists()[jat] < Ion_cutoff[jat]) // the new position is still inside
514  {
515  *iter_dist = eI_table.getTempDists()[jat];
516  *iter_displ = eI_table.getTempDispls()[jat];
517  *std::find(ions_nearby_new.begin(), ions_nearby_new.end(), jat) = -1;
518  }
519  else
520  {
521  *iter = elecs_inside(ig, jat).back();
522  elecs_inside(ig, jat).pop_back();
523  *iter_dist = elecs_inside_dist(ig, jat).back();
524  elecs_inside_dist(ig, jat).pop_back();
525  *iter_displ = elecs_inside_displ(ig, jat).back();
526  elecs_inside_displ(ig, jat).pop_back();
527  }
528  }
529 
530  // if the old position doesn't exist in elecs_inside but the new position do
531  for (int iind = 0; iind < ions_nearby_new.size(); iind++)
532  {
533  int jat = ions_nearby_new[iind];
534  if (jat >= 0)
535  {
536  elecs_inside(ig, jat).push_back(iat);
537  elecs_inside_dist(ig, jat).push_back(eI_table.getTempDists()[jat]);
538  elecs_inside_displ(ig, jat).push_back(eI_table.getTempDispls()[jat]);
539  }
540  }
541  }
542 
543  inline void recompute(const ParticleSet& P) override
544  {
545  const auto& eI_table = P.getDistTableAB(ei_Table_ID_);
546  const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
547 
549 
550  for (int jel = 0; jel < Nelec; ++jel)
551  {
552  computeU3(P, jel, eI_table.getDistRow(jel), eI_table.getDisplRow(jel), ee_table.getDistRow(jel),
553  ee_table.getDisplRow(jel), Uat[jel], dUat_temp, d2Uat[jel], newUk, newdUk, newd2Uk, ions_nearby_new,
554  true);
555  dUat(jel) = dUat_temp;
556 // add the contribution from the upper triangle
557 #pragma omp simd
558  for (int kel = 0; kel < jel; kel++)
559  {
560  Uat[kel] += newUk[kel];
561  d2Uat[kel] += newd2Uk[kel];
562  }
563  for (int idim = 0; idim < OHMMS_DIM; ++idim)
564  {
565  valT* restrict save_g = dUat.data(idim);
566  const valT* restrict new_g = newdUk.data(idim);
567 #pragma omp simd aligned(save_g, new_g : QMC_SIMD_ALIGNMENT)
568  for (int kel = 0; kel < jel; kel++)
569  save_g[kel] += new_g[kel];
570  }
571  }
572  }
573 
574  inline valT computeU(const ParticleSet& P,
575  int jel,
576  int jg,
577  const DistRow& distjI,
578  const DistRow& distjk,
579  std::vector<int>& ions_nearby)
580  {
581  ions_nearby.clear();
582  for (int iat = 0; iat < Nion; ++iat)
583  if (distjI[iat] < Ion_cutoff[iat])
584  ions_nearby.push_back(iat);
585 
586  valT Uj = valT(0);
587  for (int kg = 0; kg < eGroups; ++kg)
588  {
589  int kel_counter = 0;
590  for (int iind = 0; iind < ions_nearby.size(); ++iind)
591  {
592  const int iat = ions_nearby[iind];
593  const int ig = Ions.GroupID[iat];
594  const valT r_jI = distjI[iat];
595  for (int kind = 0; kind < elecs_inside(kg, iat).size(); kind++)
596  {
597  const int kel = elecs_inside(kg, iat)[kind];
598  if (kel != jel)
599  {
600  DistkI_Compressed[kel_counter] = elecs_inside_dist(kg, iat)[kind];
601  Distjk_Compressed[kel_counter] = distjk[kel];
602  DistjI_Compressed[kel_counter] = r_jI;
603  kel_counter++;
604  if (kel_counter == Nbuffer)
605  {
606  const FT& feeI(*F(ig, jg, kg));
607  Uj += feeI.evaluateV(kel_counter, Distjk_Compressed.data(), DistjI_Compressed.data(),
608  DistkI_Compressed.data());
609  kel_counter = 0;
610  }
611  }
612  }
613  if ((iind + 1 == ions_nearby.size() || ig != Ions.GroupID[ions_nearby[iind + 1]]) && kel_counter > 0)
614  {
615  const FT& feeI(*F(ig, jg, kg));
616  Uj +=
617  feeI.evaluateV(kel_counter, Distjk_Compressed.data(), DistjI_Compressed.data(), DistkI_Compressed.data());
618  kel_counter = 0;
619  }
620  }
621  }
622  return Uj;
623  }
624 
625  inline void computeU3_engine(const ParticleSet& P,
626  const FT& feeI,
627  int kel_counter,
628  valT& Uj,
629  posT& dUj,
630  valT& d2Uj,
631  Vector<valT>& Uk,
632  gContainer_type& dUk,
633  Vector<valT>& d2Uk)
634  {
635  constexpr valT czero(0);
636  constexpr valT cone(1);
637  constexpr valT ctwo(2);
638  constexpr valT lapfac = OHMMS_DIM - cone;
639 
640  valT* restrict val = mVGL.data(0);
641  valT* restrict gradF0 = mVGL.data(1);
642  valT* restrict gradF1 = mVGL.data(2);
643  valT* restrict gradF2 = mVGL.data(3);
644  valT* restrict hessF00 = mVGL.data(4);
645  valT* restrict hessF11 = mVGL.data(5);
646  valT* restrict hessF22 = mVGL.data(6);
647  valT* restrict hessF01 = mVGL.data(7);
648  valT* restrict hessF02 = mVGL.data(8);
649 
650  feeI.evaluateVGL(kel_counter, Distjk_Compressed.data(), DistjI_Compressed.data(), DistkI_Compressed.data(), val,
651  gradF0, gradF1, gradF2, hessF00, hessF11, hessF22, hessF01, hessF02);
652 
653  // compute the contribution to jel, kel
654  Uj = simd::accumulate_n(val, kel_counter, Uj);
655  valT gradF0_sum = simd::accumulate_n(gradF0, kel_counter, czero);
656  valT gradF1_sum = simd::accumulate_n(gradF1, kel_counter, czero);
657  valT hessF00_sum = simd::accumulate_n(hessF00, kel_counter, czero);
658  valT hessF11_sum = simd::accumulate_n(hessF11, kel_counter, czero);
659  d2Uj -= hessF00_sum + hessF11_sum + lapfac * (gradF0_sum + gradF1_sum);
660  std::fill_n(hessF11, kel_counter, czero);
661  for (int idim = 0; idim < OHMMS_DIM; ++idim)
662  {
663  valT* restrict jk = Disp_jk_Compressed.data(idim);
664  valT* restrict jI = Disp_jI_Compressed.data(idim);
665  valT* restrict kI = Disp_kI_Compressed.data(idim);
666  valT dUj_x(0);
667 #pragma omp simd aligned(gradF0, gradF1, gradF2, hessF11, jk, jI, kI : QMC_SIMD_ALIGNMENT) reduction(+ : dUj_x)
668  for (int kel_index = 0; kel_index < kel_counter; kel_index++)
669  {
670  // recycle hessF11
671  hessF11[kel_index] += kI[kel_index] * jk[kel_index];
672  dUj_x += gradF1[kel_index] * jI[kel_index];
673  // destroy jk, kI
674  const valT temp = jk[kel_index] * gradF0[kel_index];
675  dUj_x += temp;
676  jk[kel_index] *= jI[kel_index];
677  kI[kel_index] = kI[kel_index] * gradF2[kel_index] - temp;
678  }
679  dUj[idim] += dUj_x;
680 
681  valT* restrict jk0 = Disp_jk_Compressed.data(0);
682  if (idim > 0)
683  {
684 #pragma omp simd aligned(jk, jk0 : QMC_SIMD_ALIGNMENT)
685  for (int kel_index = 0; kel_index < kel_counter; kel_index++)
686  jk0[kel_index] += jk[kel_index];
687  }
688 
689  valT* restrict dUk_x = dUk.data(idim);
690  for (int kel_index = 0; kel_index < kel_counter; kel_index++)
691  dUk_x[DistIndice_k[kel_index]] += kI[kel_index];
692  }
693  valT sum(0);
694  valT* restrict jk0 = Disp_jk_Compressed.data(0);
695 #pragma omp simd aligned(jk0, hessF01 : QMC_SIMD_ALIGNMENT) reduction(+ : sum)
696  for (int kel_index = 0; kel_index < kel_counter; kel_index++)
697  sum += hessF01[kel_index] * jk0[kel_index];
698  d2Uj -= ctwo * sum;
699 
700 #pragma omp simd aligned(hessF00, hessF22, gradF0, gradF2, hessF02, hessF11 : QMC_SIMD_ALIGNMENT)
701  for (int kel_index = 0; kel_index < kel_counter; kel_index++)
702  hessF00[kel_index] = hessF00[kel_index] + hessF22[kel_index] + lapfac * (gradF0[kel_index] + gradF2[kel_index]) -
703  ctwo * hessF02[kel_index] * hessF11[kel_index];
704 
705  for (int kel_index = 0; kel_index < kel_counter; kel_index++)
706  {
707  const int kel = DistIndice_k[kel_index];
708  Uk[kel] += val[kel_index];
709  d2Uk[kel] -= hessF00[kel_index];
710  }
711  }
712 
713  inline void computeU3(const ParticleSet& P,
714  int jel,
715  const DistRow& distjI,
716  const DisplRow& displjI,
717  const DistRow& distjk,
718  const DisplRow& displjk,
719  valT& Uj,
720  posT& dUj,
721  valT& d2Uj,
722  Vector<valT>& Uk,
723  gContainer_type& dUk,
724  Vector<valT>& d2Uk,
725  std::vector<int>& ions_nearby,
726  bool triangle = false)
727  {
728  constexpr valT czero(0);
729 
730  Uj = czero;
731  dUj = posT();
732  d2Uj = czero;
733 
734  const int jg = P.GroupID[jel];
735 
736  const int kelmax = triangle ? jel : Nelec;
737  std::fill_n(Uk.data(), kelmax, czero);
738  std::fill_n(d2Uk.data(), kelmax, czero);
739  for (int idim = 0; idim < OHMMS_DIM; ++idim)
740  std::fill_n(dUk.data(idim), kelmax, czero);
741 
742  ions_nearby.clear();
743  for (int iat = 0; iat < Nion; ++iat)
744  if (distjI[iat] < Ion_cutoff[iat])
745  ions_nearby.push_back(iat);
746 
747  for (int kg = 0; kg < eGroups; ++kg)
748  {
749  int kel_counter = 0;
750  for (int iind = 0; iind < ions_nearby.size(); ++iind)
751  {
752  const int iat = ions_nearby[iind];
753  const int ig = Ions.GroupID[iat];
754  const valT r_jI = distjI[iat];
755  const posT disp_Ij = displjI[iat];
756  for (int kind = 0; kind < elecs_inside(kg, iat).size(); kind++)
757  {
758  const int kel = elecs_inside(kg, iat)[kind];
759  if (kel < kelmax && kel != jel)
760  {
761  DistkI_Compressed[kel_counter] = elecs_inside_dist(kg, iat)[kind];
762  DistjI_Compressed[kel_counter] = r_jI;
763  Distjk_Compressed[kel_counter] = distjk[kel];
764  Disp_kI_Compressed(kel_counter) = elecs_inside_displ(kg, iat)[kind];
765  Disp_jI_Compressed(kel_counter) = disp_Ij;
766  Disp_jk_Compressed(kel_counter) = displjk[kel];
767  DistIndice_k[kel_counter] = kel;
768  kel_counter++;
769  if (kel_counter == Nbuffer)
770  {
771  const FT& feeI(*F(ig, jg, kg));
772  computeU3_engine(P, feeI, kel_counter, Uj, dUj, d2Uj, Uk, dUk, d2Uk);
773  kel_counter = 0;
774  }
775  }
776  }
777  if ((iind + 1 == ions_nearby.size() || ig != Ions.GroupID[ions_nearby[iind + 1]]) && kel_counter > 0)
778  {
779  const FT& feeI(*F(ig, jg, kg));
780  computeU3_engine(P, feeI, kel_counter, Uj, dUj, d2Uj, Uk, dUk, d2Uk);
781  kel_counter = 0;
782  }
783  }
784  }
785  }
786 
787  inline void registerData(ParticleSet& P, WFBufferType& buf) override
788  {
789  if (Bytes_in_WFBuffer == 0)
790  {
791  Bytes_in_WFBuffer = buf.current();
792  buf.add(Uat.begin(), Uat.end());
793  buf.add(dUat.data(), dUat.end());
794  buf.add(d2Uat.begin(), d2Uat.end());
796  // free local space
797  Uat.free();
798  dUat.free();
799  d2Uat.free();
800  }
801  else
802  {
804  }
805  }
806 
807  inline LogValue updateBuffer(ParticleSet& P, WFBufferType& buf, bool fromscratch = false) override
808  {
809  log_value_ = computeGL(P.G, P.L);
811  return log_value_;
812  }
813 
814  inline void copyFromBuffer(ParticleSet& P, WFBufferType& buf) override
815  {
820  }
821 
825  bool fromscratch = false) override
826  {
827  return log_value_ = computeGL(G, L);
828  }
829 
831  const opt_variables_type& optvars,
832  Vector<ValueType>& dlogpsi,
833  Vector<ValueType>& dhpsioverpsi) override
834  {
836 
837  bool recalculate(false);
838  for (int k = 0; k < myVars.size(); ++k)
839  {
840  int kk = myVars.where(k);
841  if (kk < 0)
842  continue;
843  if (optvars.recompute(kk))
844  recalculate = true;
845  }
846 
847  if (recalculate)
848  {
849  constexpr valT czero(0);
850  constexpr valT cone(1);
851  constexpr valT cminus(-1);
852  constexpr valT ctwo(2);
853  constexpr valT lapfac = OHMMS_DIM - cone;
854 
855  const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
856  const auto& ee_dists = ee_table.getDistances();
857  const auto& ee_displs = ee_table.getDisplacements();
858 
860 
861  dLogPsi = czero;
862  gradLogPsi = PosType();
863  lapLogPsi = czero;
864 
865  for (int iat = 0; iat < Nion; ++iat)
866  {
867  const int ig = Ions.GroupID[iat];
868  for (int jg = 0; jg < eGroups; ++jg)
869  for (int jind = 0; jind < elecs_inside(jg, iat).size(); jind++)
870  {
871  const int jel = elecs_inside(jg, iat)[jind];
872  const valT r_Ij = elecs_inside_dist(jg, iat)[jind];
873  const posT disp_Ij = cminus * elecs_inside_displ(jg, iat)[jind];
874  const valT r_Ij_inv = cone / r_Ij;
875 
876  for (int kg = 0; kg < eGroups; ++kg)
877  for (int kind = 0; kind < elecs_inside(kg, iat).size(); kind++)
878  {
879  const int kel = elecs_inside(kg, iat)[kind];
880  if (kel < jel)
881  {
882  const valT r_Ik = elecs_inside_dist(kg, iat)[kind];
883  const posT disp_Ik = cminus * elecs_inside_displ(kg, iat)[kind];
884  const valT r_Ik_inv = cone / r_Ik;
885 
886  const valT r_jk = ee_dists[jel][kel];
887  const posT disp_jk = ee_displs[jel][kel];
888  const valT r_jk_inv = cone / r_jk;
889 
890  FT& func = *F(ig, jg, kg);
891  int idx = J3UniqueIndex[F(ig, jg, kg)];
892  func.evaluateDerivatives(r_jk, r_Ij, r_Ik, du_dalpha[idx], dgrad_dalpha[idx], dhess_dalpha[idx]);
893  int first = VarOffset(ig, jg, kg).first;
894  int last = VarOffset(ig, jg, kg).second;
895  std::vector<RealType>& dlog = du_dalpha[idx];
896  std::vector<PosType>& dgrad = dgrad_dalpha[idx];
897  std::vector<Tensor<RealType, 3>>& dhess = dhess_dalpha[idx];
898 
899  for (int p = first, ip = 0; p < last; p++, ip++)
900  {
901  RealType& dval = dlog[ip];
902  PosType& dg = dgrad[ip];
903  Tensor<RealType, 3>& dh = dhess[ip];
904 
905  dg[0] *= r_jk_inv;
906  dg[1] *= r_Ij_inv;
907  dg[2] *= r_Ik_inv;
908 
909  PosType gr_ee = dg[0] * disp_jk;
910 
911  gradLogPsi(p, jel) -= dg[1] * disp_Ij - gr_ee;
912  lapLogPsi(p, jel) -=
913  (dh(0, 0) + lapfac * dg[0] - ctwo * dh(0, 1) * dot(disp_jk, disp_Ij) * r_jk_inv * r_Ij_inv +
914  dh(1, 1) + lapfac * dg[1]);
915 
916  gradLogPsi(p, kel) -= dg[2] * disp_Ik + gr_ee;
917  lapLogPsi(p, kel) -=
918  (dh(0, 0) + lapfac * dg[0] + ctwo * dh(0, 2) * dot(disp_jk, disp_Ik) * r_jk_inv * r_Ik_inv +
919  dh(2, 2) + lapfac * dg[2]);
920 
921  dLogPsi[p] -= dval;
922  }
923  }
924  }
925  }
926  }
927 
928  for (int k = 0; k < myVars.size(); ++k)
929  {
930  int kk = myVars.where(k);
931  if (kk < 0)
932  continue;
933  dlogpsi[kk] = (ValueType)dLogPsi[k];
934  RealType sum = 0.0;
935  for (int i = 0; i < Nelec; i++)
936  {
937 #if defined(QMC_COMPLEX)
938  sum -= 0.5 * lapLogPsi(k, i);
939  for (int jdim = 0; jdim < OHMMS_DIM; ++jdim)
940  sum -= P.G[i][jdim].real() * gradLogPsi(k, i)[jdim];
941 #else
942  sum -= 0.5 * lapLogPsi(k, i) + dot(P.G[i], gradLogPsi(k, i));
943 #endif
944  }
945  dhpsioverpsi[kk] = (ValueType)sum;
946  }
947  }
948  }
949 
950  void evaluateDerivativesWF(ParticleSet& P, const opt_variables_type& optvars, Vector<ValueType>& dlogpsi) override
951  {
953 
954  bool recalculate(false);
955  for (int k = 0; k < myVars.size(); ++k)
956  {
957  int kk = myVars.where(k);
958  if (kk < 0)
959  continue;
960  if (optvars.recompute(kk))
961  recalculate = true;
962  }
963 
964  if (recalculate)
965  {
966  constexpr valT czero(0);
967  constexpr valT cone(1);
968  constexpr valT cminus(-1);
969  constexpr valT ctwo(2);
970  constexpr valT lapfac = OHMMS_DIM - cone;
971 
972  const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
973  const auto& ee_dists = ee_table.getDistances();
974  const auto& ee_displs = ee_table.getDisplacements();
975 
977 
978  dLogPsi = czero;
979  gradLogPsi = PosType();
980  lapLogPsi = czero;
981 
982  for (int iat = 0; iat < Nion; ++iat)
983  {
984  const int ig = Ions.GroupID[iat];
985  for (int jg = 0; jg < eGroups; ++jg)
986  for (int jind = 0; jind < elecs_inside(jg, iat).size(); jind++)
987  {
988  const int jel = elecs_inside(jg, iat)[jind];
989  const valT r_Ij = elecs_inside_dist(jg, iat)[jind];
990  const posT disp_Ij = cminus * elecs_inside_displ(jg, iat)[jind];
991  const valT r_Ij_inv = cone / r_Ij;
992 
993  for (int kg = 0; kg < eGroups; ++kg)
994  for (int kind = 0; kind < elecs_inside(kg, iat).size(); kind++)
995  {
996  const int kel = elecs_inside(kg, iat)[kind];
997  if (kel < jel)
998  {
999  const valT r_Ik = elecs_inside_dist(kg, iat)[kind];
1000  const posT disp_Ik = cminus * elecs_inside_displ(kg, iat)[kind];
1001  const valT r_Ik_inv = cone / r_Ik;
1002 
1003  const valT r_jk = ee_dists[jel][kel];
1004  const posT disp_jk = ee_displs[jel][kel];
1005  const valT r_jk_inv = cone / r_jk;
1006 
1007  FT& func = *F(ig, jg, kg);
1008  int idx = J3UniqueIndex[F(ig, jg, kg)];
1009  func.evaluateDerivatives(r_jk, r_Ij, r_Ik, du_dalpha[idx], dgrad_dalpha[idx], dhess_dalpha[idx]);
1010  int first = VarOffset(ig, jg, kg).first;
1011  int last = VarOffset(ig, jg, kg).second;
1012  std::vector<RealType>& dlog = du_dalpha[idx];
1013 
1014  for (int p = first, ip = 0; p < last; p++, ip++)
1015  {
1016  RealType& dval = dlog[ip];
1017  dLogPsi[p] -= dval;
1018  }
1019  }
1020  }
1021  }
1022  }
1023 
1024  for (int k = 0; k < myVars.size(); ++k)
1025  {
1026  int kk = myVars.where(k);
1027  if (kk < 0)
1028  continue;
1029  dlogpsi[kk] = (ValueType)dLogPsi[k];
1030  }
1031  }
1032  }
1033 
1035  const opt_variables_type& optvars,
1036  std::vector<ValueType>& ratios,
1037  Matrix<ValueType>& dratios) override
1038  {
1039  assert(VP.getTotalNum() == ratios.size());
1040  evaluateRatios(VP, ratios);
1041 
1042  bool recalculate(false);
1043  for (int k = 0; k < myVars.size(); ++k)
1044  {
1045  int kk = myVars.where(k);
1046  if (kk < 0)
1047  continue;
1048  if (optvars.recompute(kk))
1049  recalculate = true;
1050  }
1051 
1052  if (recalculate)
1053  {
1054  constexpr valT czero(0);
1055 
1056  const auto& refPS = VP.getRefPS();
1057  const auto& ee_dists = refPS.getDistTableAA(ee_Table_ID_).getDistances();
1058  const auto& ei_dists = refPS.getDistTableAB(ei_Table_ID_).getDistances();
1059 
1060  const auto& vpe_dists = VP.getDistTableAB(ee_Table_ID_).getDistances();
1061  const auto& vpi_dists = VP.getDistTableAB(ei_Table_ID_).getDistances();
1062 
1063  const int nVP = VP.getTotalNum();
1064  std::vector<Vector<RealType>> dLogPsi_vp(nVP);
1065  for (auto& dLogPsi : dLogPsi_vp)
1066  {
1068  dLogPsi = czero;
1069  }
1070 
1071  const int kel = VP.refPtcl;
1072  const int kg = refPS.getGroupID(kel);
1073 
1074  for (int iat = 0; iat < Nion; ++iat)
1075  {
1076  const int ig = Ions.getGroupID(iat);
1077  for (int jg = 0; jg < eGroups; ++jg)
1078  {
1079  FT& func = *F(ig, jg, kg);
1080  const size_t nparams = func.getNumParameters();
1081  std::vector<RealType> dlog_ref(nparams), dlog(nparams);
1082  for (int jind = 0; jind < elecs_inside(jg, iat).size(); jind++)
1083  {
1084  const int jel = elecs_inside(jg, iat)[jind];
1085  if (jel == kel)
1086  continue;
1087  const valT r_Ij = elecs_inside_dist(jg, iat)[jind];
1088  const valT r_Ik_ref = ei_dists[kel][iat];
1089  const valT r_jk_ref = jel < kel ? ee_dists[kel][jel] : ee_dists[jel][kel];
1090 
1091  if (!func.evaluateDerivatives(r_jk_ref, r_Ij, r_Ik_ref, dlog_ref))
1092  std::fill(dlog_ref.begin(), dlog_ref.end(), czero);
1093 
1094  for (int ivp = 0; ivp < nVP; ivp++)
1095  {
1096  const valT r_Ik = vpi_dists[ivp][iat];
1097  const valT r_jk = vpe_dists[ivp][jel];
1098  if (!func.evaluateDerivatives(r_jk, r_Ij, r_Ik, dlog))
1099  std::fill(dlog.begin(), dlog.end(), czero);
1100  const int first = VarOffset(ig, jg, kg).first;
1101  const int last = VarOffset(ig, jg, kg).second;
1102  for (int p = first, ip = 0; p < last; p++, ip++)
1103  dLogPsi_vp[ivp][p] -= dlog[ip] - dlog_ref[ip];
1104  }
1105  }
1106  }
1107  }
1108 
1109  for (int k = 0; k < myVars.size(); ++k)
1110  {
1111  int kk = myVars.where(k);
1112  if (kk < 0)
1113  continue;
1114  for (int ivp = 0; ivp < nVP; ivp++)
1115  dratios[ivp][kk] = (ValueType)dLogPsi_vp[ivp][k];
1116  }
1117  }
1118  }
1119 
1120  inline GradType evalGradSource(ParticleSet& P, ParticleSet& source, int isrc) override
1121  {
1124  tempG.resize(P.getTotalNum());
1125  tempL.resize(P.getTotalNum());
1126  QTFull::RealType delta = 0.00001;
1127  QTFull::RealType c1 = 1.0 / delta / 2.0;
1128  QTFull::RealType c2 = 1.0 / delta / delta;
1129 
1130  GradType g_return(0.0);
1131  // GRAD TEST COMPUTATION
1132  PosType rI = source.R[isrc];
1133  for (int iondim = 0; iondim < 3; iondim++)
1134  {
1135  source.R[isrc][iondim] = rI[iondim] + delta;
1136  source.update();
1137  P.update();
1138 
1139  LogValue log_p = evaluateLog(P, tempG, tempL);
1140 
1141  source.R[isrc][iondim] = rI[iondim] - delta;
1142  source.update();
1143  P.update();
1144  LogValue log_m = evaluateLog(P, tempG, tempL);
1145 
1146  QTFull::RealType log_p_r(0.0), log_m_r(0.0);
1147 
1148  log_p_r = log_p.real();
1149  log_m_r = log_m.real();
1150  //symmetric finite difference formula for gradient.
1151  g_return[iondim] = c1 * (log_p_r - log_m_r);
1152 
1153  //reset everything to how it was.
1154  source.R[isrc][iondim] = rI[iondim];
1155  }
1156  // this last one makes sure the distance tables and internal neighbourlist correspond to unperturbed source.
1157  source.update();
1158  P.update();
1159  build_compact_list(P);
1160  return g_return;
1161  }
1162 
1164  ParticleSet& source,
1165  int isrc,
1168  {
1169  ParticleSet::ParticleGradient Gp, Gm, dG;
1170  ParticleSet::ParticleLaplacian Lp, Lm, dL;
1171  Gp.resize(P.getTotalNum());
1172  Gm.resize(P.getTotalNum());
1173  dG.resize(P.getTotalNum());
1174  Lp.resize(P.getTotalNum());
1175  Lm.resize(P.getTotalNum());
1176  dL.resize(P.getTotalNum());
1177 
1178  QTFull::RealType delta = 0.00001;
1179  QTFull::RealType c1 = 1.0 / delta / 2.0;
1180  QTFull::RealType c2 = 1.0 / delta / delta;
1181  GradType g_return(0.0);
1182  // GRAD TEST COMPUTATION
1183  PosType rI = source.R[isrc];
1184  for (int iondim = 0; iondim < 3; iondim++)
1185  {
1186  Lp = 0;
1187  Gp = 0;
1188  Lm = 0;
1189  Gm = 0;
1190  source.R[isrc][iondim] = rI[iondim] + delta;
1191  source.update();
1192  P.update();
1193 
1194  LogValue log_p = evaluateLog(P, Gp, Lp);
1195 
1196  source.R[isrc][iondim] = rI[iondim] - delta;
1197  source.update();
1198  P.update();
1199  LogValue log_m = evaluateLog(P, Gm, Lm);
1200  QTFull::RealType log_p_r(0.0), log_m_r(0.0);
1201 
1202  log_p_r = log_p.real();
1203  log_m_r = log_m.real();
1204  dG = Gp - Gm;
1205  dL = Lp - Lm;
1206  //symmetric finite difference formula for gradient.
1207  g_return[iondim] = c1 * (log_p_r - log_m_r);
1208  grad_grad[iondim] += c1 * dG;
1209  lapl_grad[iondim] += c1 * dL;
1210  //reset everything to how it was.
1211  source.R[isrc][iondim] = rI[iondim];
1212  }
1213  // this last one makes sure the distance tables and internal neighbourlist correspond to unperturbed source.
1214  source.update();
1215  P.update();
1216  build_compact_list(P);
1217  return g_return;
1218  }
1219 };
1220 
1221 } // namespace qmcplusplus
1222 #endif
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
GradType evalGrad(ParticleSet &P, int iat) override
return the current gradient for the iat-th particle
T2 accumulate_n(const T1 *restrict in, size_t n, T2 res)
Definition: algorithm.hpp:26
std::map< FT *, int > J3UniqueIndex
gContainer_type Disp_kI_Compressed
size_t Nelec_padded
number of particles + padded
LogValue evaluateGL(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L, bool fromscratch=false) override
compute gradients and laplacian of the TWF with respect to each particle.
const std::vector< DistRow > & getDistances() const
return full table distances
bool recompute(int i) const
Definition: VariableSet.h:206
std::vector< T, aligned_allocator< T > > aligned_vector
const std::string my_name_
Name of the object It is required to be different for objects of the same derived type like multiple ...
const ParticleSet & getRefPS() const
ParticleSet this object refers to.
Array< RealType, 2 > lapLogPsi
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void registerData(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
const DistanceTableAA & getDistTableAA(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAA
QTBase::GradType GradType
Definition: Configuration.h:62
const int ee_Table_ID_
table index for el-el
void addFunc(int iSpecies, int eSpecies1, int eSpecies2, std::unique_ptr< FT > j)
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &optvars, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi) override
const DistRow & getDistRow(int iel) const
return a row of distances for a given target particle
std::vector< int > DistIndice_k
void build_compact_list(const ParticleSet &P)
void forward(size_type n)
Definition: PooledMemory.h:162
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
void fill_n(T *x, size_t count, const T &value)
Definition: OMPstd.hpp:21
gContainer_type Disp_jk_Compressed
compressed displacements
std::ostream & app_log()
Definition: OutputManager.h:65
const std::vector< DisplRow > & getDisplacements() const
return full table displacements
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
For distance tables of virtual particle (VP) sets constructed based on this table, whether full table is needed on host The corresponding DT of VP need to set MW_EVALUATE_RESULT_NO_TRANSFER_TO_HOST accordingly.
constexpr std::complex< float > cone
Definition: BLAS.hpp:50
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
TinyVector< valT, OHMMS_DIM > posT
element position type
VectorSoaContainer< RealType, DIM > DisplRow
Definition: DistanceTable.h:47
int refPtcl
Reference particle.
std::vector< int > Index
store locator of the named variable
Definition: VariableSet.h:65
SoA adaptor class for Vector<TinyVector<T,D> >
void extractOptimizableObjectRefs(UniqueOptObjRefs &opt_obj_refs) override
extract underlying OptimizableObject references
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
void free()
free
Definition: OhmmsVector.h:196
QTFull::RealType computeGL(ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) const
compute G and L from internally stored data
std::vector< int > ions_nearby_old
the ids of ions within the cutoff radius of an electron on which a move is proposed ...
void update(bool skipSK=false)
update the internal data
Attaches a unit to a Vector for IO.
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
void resize(const std::array< SIZET, D > &dims)
Resize the container.
Definition: OhmmsArray.h:65
aligned_vector< valT > DistjI_Compressed
void check_complete()
check that correlation information is complete
JeeIOrbitalSoA(const std::string &obj_name, const ParticleSet &ions, ParticleSet &elecs)
#define OHMMS_DIM
Definition: config.h:64
ParticleIndex GroupID
Species ID.
Definition: ParticleSet.h:77
std::unique_ptr< WaveFunctionComponent > makeClone(ParticleSet &elecs) const override
make clone
opt_variables_type myVars
list of variables this WaveFunctionComponent handles
std::complex< QTFull::RealType > LogValue
int getTotalNum() const
return the number of species
Definition: SpeciesSet.h:55
const DistanceTableAB & getDistTableAB(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAB
void restore(int iat) override
If a move for iat-th particle is rejected, restore to the content.
int groups() const
return the number of groups
Definition: ParticleSet.h:511
An abstract class for a component of a many-body trial wave function.
void attachReference(T *ref, size_type n)
Definition: OhmmsVector.h:131
Array< std::vector< posT >, 2 > elecs_inside_displ
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
void recompute(const ParticleSet &P) override
recompute the value of the WaveFunctionComponents which require critical accuracy.
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
QTBase::ValueType ValueType
Definition: Configuration.h:60
GradType evalGradSource(ParticleSet &P, ParticleSet &source, int isrc, TinyVector< ParticleSet::ParticleGradient, OHMMS_DIM > &grad_grad, TinyVector< ParticleSet::ParticleLaplacian, OHMMS_DIM > &lapl_grad) override
Adds the gradient w.r.t.
Array< std::vector< valT >, 2 > elecs_inside_dist
std::vector< valT > Ion_cutoff
the cutoff for e-I pairs
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
LogValue evaluateLog(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) override
evaluate the value of the WaveFunctionComponent from scratch
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
void computeU3(const ParticleSet &P, int jel, const DistRow &distjI, const DisplRow &displjI, const DistRow &distjk, const DisplRow &displjk, valT &Uj, posT &dUj, valT &d2Uj, Vector< valT > &Uk, gContainer_type &dUk, Vector< valT > &d2Uk, std::vector< int > &ions_nearby, bool triangle=false)
gContainer_type Disp_jI_Compressed
int where(int i) const
return the locator of the i-th Index
Definition: VariableSet.h:90
size_t size() const
Definition: OhmmsArray.h:57
VectorSoaContainer< valT, 9 > mVGL
work result buffer
GradType evalGradSource(ParticleSet &P, ParticleSet &source, int isrc) override
return the logarithmic gradient for the iat-th particle of the source particleset ...
ParticlePos R
Position.
Definition: ParticleSet.h:79
QTBase::PosType PosType
Definition: Configuration.h:61
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
size_t Nbuffer
work buffer size
int last(int igroup) const
return the last index of a group i
Definition: ParticleSet.h:517
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
const int ei_Table_ID_
table index for i-el
bool isOptimizable() const override
if true, this contains optimizable components
std::map< std::string, std::unique_ptr< FT > > J3Unique
void computeU3_engine(const ParticleSet &P, const FT &feeI, int kel_counter, valT &Uj, posT &dUj, valT &d2Uj, Vector< valT > &Uk, gContainer_type &dUk, Vector< valT > &d2Uk)
typename FT::real_type valT
type of each component U, dU, d2U;
void evaluateDerivRatios(const VirtualParticleSet &VP, const opt_variables_type &optvars, std::vector< ValueType > &ratios, Matrix< ValueType > &dratios) override
Array< std::pair< int, int >, 3 > VarOffset
void clear()
clear the variable set
Definition: VariableSet.cpp:28
size_type size() const
return the size
Definition: VariableSet.h:88
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
size_type current() const
Definition: PooledMemory.h:76
std::vector< int > ions_nearby_new
const ParticleSet & Ions
reference to the sources (ions)
LogValue updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false) override
For particle-by-particle move.
whether full table needs to be ready at anytime or not during PbyP Optimization can be implemented du...
OHMMS_PRECISION real_type
Vector< RealType, aligned_allocator< RealType > > DistRow
Definition: DistanceTable.h:46
std::vector< std::vector< Tensor< RealType, 3 > > > dhess_dalpha
Array< FT *, 3 > F
container for the Jastrow functions
void evaluateRatiosAlltoOne(ParticleSet &P, std::vector< ValueType > &ratios) override
void evaluateDerivativesWF(ParticleSet &P, const opt_variables_type &optvars, Vector< ValueType > &dlogpsi) override
const std::vector< DistRow > & getDistances() const
return full table distances
Vector< RealType > dLogPsi
Precision RealType
Definition: QMCTypes.h:37
void evaluateRatios(const VirtualParticleSet &VP, std::vector< ValueType > &ratios) override
Array< std::vector< int >, 2 > elecs_inside
the electrons around ions within the cutoff radius, grouped by species
Container_t::iterator begin()
Definition: OhmmsArray.h:80
void free()
free allocated memory and clear status variables
std::vector< std::vector< PosType > > dgrad_dalpha
aligned_vector< valT > DistkI_Compressed
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
void checkOutVariables(const opt_variables_type &active) override
check out optimizable variables
aligned_vector< valT > Distjk_Compressed
compressed distances
void insertFrom(const VariableSet &input)
insert a VariableSet to the list
Definition: VariableSet.cpp:37
Declaration of WaveFunctionComponent.
valT cur_Uat
current values during PbyP
void init(ParticleSet &p)
RealType DiffVal
diff value
void resize(size_type n)
resize myData
std::vector< std::vector< RealType > > du_dalpha
PsiValue ratioGrad(ParticleSet &P, int iat, GradType &grad_iat) override
evaluate the ratio of the new to old WaveFunctionComponent value and the new gradient ...
size_t Bytes_in_WFBuffer
Bytes in WFBuffer.
valT computeU(const ParticleSet &P, int jel, int jg, const DistRow &distjI, const DistRow &distjk, std::vector< int > &ions_nearby)
Array< PosType, 2 > gradLogPsi
FT FuncType
alias FuncType
void attachReference(size_type n, size_type n_padded, T *ptr)
attach to pre-allocated data
SIMD version of functions in algorithm.
int getIndex(const std::string &vname) const
return the Index vaule for the named parameter
T1 * lendReference(size_type n)
Definition: PooledMemory.h:154
void push_back(OptimizableObject &obj)
whether temporary data set on the host is updated or not when a move is proposed. ...
Specialization for three-body Jastrow function using multiple functors.
PsiValue ratio(ParticleSet &P, int iat) override
evaluate the ratio of the new to old WaveFunctionComponent value
void copyFromBuffer(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
int getGroupID(int iat) const
return the group id of a given particle in the particle set.
Definition: ParticleSet.h:520
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false) override
a move for iat-th particle is accepted.
void add(std::complex< T1 > &x)
Definition: PooledMemory.h:113
std::string getClassName() const override
return class name