QMCPACK
TrialWaveFunction.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) 2020 QMCPACK developers.
6 //
7 // File developed by: Bryan Clark, bclark@Princeton.edu, Princeton University
8 // Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
9 // Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
10 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
11 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 // Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
13 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
14 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
15 //
16 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
17 //////////////////////////////////////////////////////////////////////////////////////
18 
19 #include <stdexcept>
20 
21 #include "TrialWaveFunction.h"
22 #include "ResourceCollection.h"
24 #include "Concurrency/Info.hpp"
26 #include "NaNguard.h"
28 
29 namespace qmcplusplus
30 {
31 typedef enum
32 {
33  V_TIMER = 0,
42 } TimerEnum;
43 
44 static const std::vector<std::string> suffixes{"V", "VGL", "accept", "NLratio",
45  "recompute", "buffer", "derivs", "preparegroup"};
46 
47 static TimerNameList_t<TimerEnum> create_names(std::string_view myName)
48 {
49  TimerNameList_t<TimerEnum> timer_names;
50  std::string prefix = std::string("WaveFunction:").append(myName).append("::");
51  for (std::size_t i = 0; i < suffixes.size(); ++i)
52  timer_names.push_back({static_cast<TimerEnum>(i), prefix + suffixes[i]});
53  return timer_names;
54 }
55 
56 TrialWaveFunction::TrialWaveFunction(const RuntimeOptions& runtime_options, const std::string_view aname, bool tasking)
57  : runtime_options_(runtime_options),
58  myNode_(NULL),
59  spomap_(std::make_shared<SPOMap>()),
60  myName(aname),
61  BufferCursor(0),
62  BufferCursor_scalar(0),
63  PhaseValue(0.0),
64  PhaseDiff(0.0),
65  log_real_(0.0),
66  OneOverM(1.0),
67  use_tasking_(tasking),
69 {
70  if (suffixes.size() != TIMER_SKIP)
71  throw std::runtime_error("TrialWaveFunction::TrialWaveFunction mismatched timer enums and suffixes");
72 }
73 
74 /** Destructor
75 *
76 *@warning Have not decided whether Z is cleaned up by TrialWaveFunction
77 * or not. It will depend on I/O implementation.
78 */
80 {
81  if (myNode_ != NULL)
82  xmlFreeNode(myNode_);
83 }
84 
85 /** Takes owndership of aterm
86  */
87 void TrialWaveFunction::addComponent(std::unique_ptr<WaveFunctionComponent>&& aterm)
88 {
89  std::string aname = aterm->getClassName();
90  if (!aterm->getName().empty())
91  aname += ":" + aterm->getName();
92 
93  if (aterm->isFermionic())
94  app_log() << " Added a fermionic WaveFunctionComponent " << aname << std::endl;
95 
96  for (auto& suffix : suffixes)
97  WFC_timers_.push_back(createGlobalTimer(aname + "::" + suffix));
98 
99  Z.emplace_back(std::move(aterm));
100 }
101 
102 const SPOSet& TrialWaveFunction::getSPOSet(const std::string& name) const
103 {
104  auto spoit = spomap_->find(name);
105  if (spoit == spomap_->end())
106  throw std::runtime_error("SPOSet " + name + " cannot be found!");
107  return *spoit->second;
108 }
109 
111 {
113  for (auto& component : Z)
114  if (auto* comp_ptr = dynamic_cast<MultiSlaterDetTableMethod*>(component.get()); comp_ptr)
115  refs.push_back(*comp_ptr);
116  return refs;
117 }
118 
119 /** return log(|psi|)
120 *
121 * PhaseValue is the phase for the complex wave function
122 */
124 {
126  P.G = 0.0;
127  P.L = 0.0;
128  LogValue logpsi(0.0);
129  for (int i = 0; i < Z.size(); ++i)
130  {
132 #ifndef NDEBUG
133  // Best way I've found yet to quickly see if WFC made it over the wire successfully
134  auto subterm = Z[i]->evaluateLog(P, P.G, P.L);
135  // std::cerr << "evaluate log Z element:" << i << " value: " << subterm << '\n';
136  logpsi += subterm;
137 #else
138  logpsi += Z[i]->evaluateLog(P, P.G, P.L);
139 #endif
140  }
141 
142  G = P.G;
143  L = P.L;
144 
145  log_real_ = std::real(logpsi);
146  PhaseValue = std::imag(logpsi);
147  return log_real_;
148 }
149 
151  const RefVectorWithLeader<ParticleSet>& p_list)
152 {
153  auto& wf_leader = wf_list.getLeader();
154  auto& p_leader = p_list.getLeader();
155  ScopedTimer local_timer(wf_leader.TWF_timers_[RECOMPUTE_TIMER]);
156 
157  constexpr RealType czero(0);
158  const auto g_list(TrialWaveFunction::extractGRefList(wf_list));
159  const auto l_list(TrialWaveFunction::extractLRefList(wf_list));
160 
161  // due to historic design issue, ParticleSet holds G and L instead of TrialWaveFunction.
162  // TrialWaveFunction now also holds G and L to move forward but they need to be copied to P.G and P.L
163  // to be compatible with legacy use pattern.
164  const int num_particles = p_leader.getTotalNum();
165  auto initGandL = [num_particles, czero](TrialWaveFunction& twf, ParticleSet::ParticleGradient& grad,
167  grad.resize(num_particles);
168  lapl.resize(num_particles);
169  grad = czero;
170  lapl = czero;
171  twf.log_real_ = czero;
172  twf.PhaseValue = czero;
173  };
174  for (int iw = 0; iw < wf_list.size(); iw++)
175  initGandL(wf_list[iw], g_list[iw], l_list[iw]);
176 
177  auto& wavefunction_components = wf_leader.Z;
178  const int num_wfc = wf_leader.Z.size();
179  for (int i = 0; i < num_wfc; ++i)
180  {
181  ScopedTimer z_timer(wf_leader.WFC_timers_[RECOMPUTE_TIMER + TIMER_SKIP * i]);
182  const auto wfc_list(extractWFCRefList(wf_list, i));
183  wavefunction_components[i]->mw_evaluateLog(wfc_list, p_list, g_list, l_list);
184  }
185 
186  for (int iw = 0; iw < wf_list.size(); iw++)
187  {
188  ParticleSet& pset = p_list[iw];
189  TrialWaveFunction& twf = wf_list[iw];
190 
191  for (int i = 0; i < num_wfc; ++i)
192  {
193  twf.log_real_ += std::real(twf.Z[i]->get_log_value());
194  twf.PhaseValue += std::imag(twf.Z[i]->get_log_value());
195  }
196 
197  // Ye: temporal workaround to have P.G/L always defined.
198  // remove when KineticEnergy use WF.G/L instead of P.G/L
199  pset.G = twf.G;
200  pset.L = twf.L;
201  }
202 }
203 
205 {
207  for (int i = 0; i < Z.size(); ++i)
208  {
210  Z[i]->recompute(P);
211  }
212 }
213 
215  const RefVectorWithLeader<ParticleSet>& p_list,
216  const std::vector<bool>& recompute)
217 {
218  auto& wf_leader = wf_list.getLeader();
219  auto& p_leader = p_list.getLeader();
220  ScopedTimer local_timer(wf_leader.TWF_timers_[RECOMPUTE_TIMER]);
221 
222  auto& wavefunction_components = wf_leader.Z;
223  const int num_wfc = wf_leader.Z.size();
224  for (int i = 0; i < num_wfc; ++i)
225  {
226  ScopedTimer z_timer(wf_leader.WFC_timers_[RECOMPUTE_TIMER + TIMER_SKIP * i]);
227  const auto wfc_list(extractWFCRefList(wf_list, i));
228  wavefunction_components[i]->mw_recompute(wfc_list, p_list, recompute);
229  }
230 }
231 
233 {
235  P.G = 0.0;
236  P.L = 0.0;
237  LogValue logpsi(0.0);
238  for (int i = 0; i < Z.size(); ++i)
239  {
241  if (Z[i]->isOptimizable())
242  logpsi += Z[i]->evaluateLog(P, P.G, P.L);
243  }
244  log_real_ = std::real(logpsi);
245  PhaseValue = std::imag(logpsi);
246 
247  //In case we need to recompute orbitals, initialize dummy vectors for G and L.
248  //evaluateLog dumps into these variables, and logPsi contribution is discarded.
249  //Only called for non-optimizable orbitals.
250  if (recomputeall)
251  {
254 
255  for (int i = 0; i < Z.size(); ++i)
256  {
257  //update orbitals if its not flagged optimizable, AND recomputeall is true
258  if (!Z[i]->isOptimizable())
259  Z[i]->evaluateLog(P, dummyG, dummyL);
260  }
261  }
262  return log_real_;
263 }
264 
266  RealType& logpsi_fixed_r,
267  RealType& logpsi_opt_r,
270 {
272  P.G = 0.0;
273  P.L = 0.0;
274  fixedL = 0.0;
275  fixedG = 0.0;
276  LogValue logpsi_fixed(0.0);
277  LogValue logpsi_opt(0.0);
278 
279  for (int i = 0; i < Z.size(); ++i)
280  {
282  if (Z[i]->isOptimizable())
283  logpsi_opt += Z[i]->evaluateLog(P, P.G, P.L);
284  else
285  logpsi_fixed += Z[i]->evaluateLog(P, fixedG, fixedL);
286  }
287  P.G += fixedG;
288  P.L += fixedL;
289  convertToReal(logpsi_fixed, logpsi_fixed_r);
290  convertToReal(logpsi_opt, logpsi_opt_r);
291 }
292 
293 
295  const RefVectorWithLeader<ParticleSet>& p_list,
296  std::vector<RealType>& logpsi_fixed_list,
297  std::vector<RealType>& logpsi_opt_list,
300 {
301  auto& wf_leader = wf_list.getLeader();
302  auto& p_leader = p_list.getLeader();
303  ScopedTimer local_timer(wf_leader.TWF_timers_[RECOMPUTE_TIMER]);
304  constexpr RealType czero(0);
305  const int num_particles = p_leader.getTotalNum();
306  const auto g_list(TrialWaveFunction::extractGRefList(wf_list));
307  const auto l_list(TrialWaveFunction::extractLRefList(wf_list));
308 
309  auto initGandL = [num_particles, czero](TrialWaveFunction& twf, ParticleSet::ParticleGradient& grad,
311  grad.resize(num_particles);
312  lapl.resize(num_particles);
313  grad = czero;
314  lapl = czero;
315  twf.log_real_ = czero;
316  twf.PhaseValue = czero;
317  };
318  for (int iw = 0; iw < wf_list.size(); iw++)
319  initGandL(wf_list[iw], g_list[iw], l_list[iw]);
320  auto& wavefunction_components = wf_leader.Z;
321  const int num_wfc = wf_leader.Z.size();
322  for (int i = 0; i < num_wfc; ++i)
323  {
324  ScopedTimer z_timer(wf_leader.WFC_timers_[RECOMPUTE_TIMER + TIMER_SKIP * i]);
325  const auto wfc_list(extractWFCRefList(wf_list, i));
326  if (wavefunction_components[i]->isOptimizable())
327  {
328  wavefunction_components[i]->mw_evaluateLog(wfc_list, p_list, g_list, l_list);
329  for (int iw = 0; iw < wf_list.size(); iw++)
330  logpsi_opt_list[iw] += std::real(wfc_list[iw].get_log_value());
331  }
332  else
333  {
334  wavefunction_components[i]->mw_evaluateLog(wfc_list, p_list, fixedG_list, fixedL_list);
335  for (int iw = 0; iw < wf_list.size(); iw++)
336  logpsi_fixed_list[iw] += std::real(wfc_list[iw].get_log_value());
337  }
338  }
339 
340  // Temporary workaround to have P.G/L always defined.
341  // remove when KineticEnergy use WF.G/L instead of P.G/L
342  auto addAndCopyToP = [](ParticleSet& pset, TrialWaveFunction& twf, ParticleSet::ParticleGradient& grad,
344  pset.G = twf.G + grad;
345  pset.L = twf.L + lapl;
346  };
347  for (int iw = 0; iw < wf_list.size(); iw++)
348  addAndCopyToP(p_list[iw], wf_list[iw], fixedG_list[iw], fixedL_list[iw]);
349 }
350 
351 
353  const RefVectorWithLeader<ParticleSet>& p_list,
354  std::vector<RealType>& logpsi_list,
357  bool recompute)
358 {
359  auto& p_leader = p_list.getLeader();
360  auto& wf_leader = wf_list.getLeader();
361  ScopedTimer local_timer(wf_leader.TWF_timers_[RECOMPUTE_TIMER]);
362  constexpr RealType czero(0);
363  int num_particles = p_leader.getTotalNum();
364  const auto g_list(TrialWaveFunction::extractGRefList(wf_list));
365  const auto l_list(TrialWaveFunction::extractLRefList(wf_list));
366 
367  // Initialize various members of the wavefunction, grad, and laplacian
368  auto initGandL = [num_particles, czero](TrialWaveFunction& twf, ParticleSet::ParticleGradient& grad,
370  grad.resize(num_particles);
371  lapl.resize(num_particles);
372  grad = czero;
373  lapl = czero;
374  twf.log_real_ = czero;
375  twf.PhaseValue = czero;
376  };
377  for (int iw = 0; iw < wf_list.size(); iw++)
378  initGandL(wf_list[iw], g_list[iw], l_list[iw]);
379 
380  // Get wavefunction components (assumed the same for every WF in the list)
381  auto& wavefunction_components = wf_leader.Z;
382  const int num_wfc = wf_leader.Z.size();
383 
384  // Loop over the wavefunction components
385  for (int i = 0; i < num_wfc; ++i)
386  if (wavefunction_components[i]->isOptimizable())
387  {
388  ScopedTimer z_timer(wf_leader.WFC_timers_[RECOMPUTE_TIMER + TIMER_SKIP * i]);
389  const auto wfc_list(extractWFCRefList(wf_list, i));
390  wavefunction_components[i]->mw_evaluateLog(wfc_list, p_list, g_list, l_list);
391  for (int iw = 0; iw < wf_list.size(); iw++)
392  logpsi_list[iw] += std::real(wfc_list[iw].get_log_value());
393  }
394 
395  // Temporary workaround to have P.G/L always defined.
396  // remove when KineticEnergy use WF.G/L instead of P.G/L
397  auto copyToP = [](ParticleSet& pset, TrialWaveFunction& twf) {
398  pset.G = twf.G;
399  pset.L = twf.L;
400  };
401  for (int iw = 0; iw < wf_list.size(); iw++)
402  copyToP(p_list[iw], wf_list[iw]);
403 
404  // Recompute is usually used to prepare the wavefunction for NLPP derivatives.
405  // (e.g compute the matrix inverse for determinants)
406  // Call mw_evaluateLog for the wavefunction components that were skipped previously.
407  // Ignore logPsi, G and L.
408  if (recompute)
409  for (int i = 0; i < num_wfc; ++i)
410  if (!wavefunction_components[i]->isOptimizable())
411  {
412  ScopedTimer z_timer(wf_leader.WFC_timers_[RECOMPUTE_TIMER + TIMER_SKIP * i]);
413  const auto wfc_list(extractWFCRefList(wf_list, i));
414  wavefunction_components[i]->mw_evaluateLog(wfc_list, p_list, dummyG_list, dummyL_list);
415  }
416 }
417 
418 
419 /*void TrialWaveFunction::evaluateHessian(ParticleSet & P, int iat, HessType& grad_grad_psi)
420 {
421  std::vector<WaveFunctionComponent*>::iterator it(Z.begin());
422  std::vector<WaveFunctionComponent*>::iterator it_end(Z.end());
423 
424  grad_grad_psi=0.0;
425 
426  for (; it!=it_end; ++it)
427  {
428  HessType tmp_hess;
429  (*it)->evaluateHessian(P, iat, tmp_hess);
430  grad_grad_psi+=tmp_hess;
431  }
432 }*/
433 
435 {
436  grad_grad_psi.resize(P.getTotalNum());
437 
438  for (int i = 0; i < Z.size(); i++)
439  {
440  HessVector tmp_hess(grad_grad_psi);
441  tmp_hess = 0.0;
442  Z[i]->evaluateHessian(P, tmp_hess);
443  grad_grad_psi += tmp_hess;
444  // app_log()<<"TrialWavefunction::tmp_hess = "<<tmp_hess<< std::endl;
445  // app_log()<< std::endl<< std::endl;
446  }
447  // app_log()<<" TrialWavefunction::Hessian = "<<grad_grad_psi<< std::endl;
448 }
449 
451 {
452  ScopedTimer local_timer(TWF_timers_[V_TIMER]);
453  PsiValue r(1.0);
454  for (int i = 0; i < Z.size(); i++)
455  if (ct == ComputeType::ALL || (Z[i]->isFermionic() && ct == ComputeType::FERMIONIC) ||
456  (!Z[i]->isFermionic() && ct == ComputeType::NONFERMIONIC))
457  {
458  ScopedTimer z_timer(WFC_timers_[V_TIMER + TIMER_SKIP * i]);
459  r *= Z[i]->ratio(P, iat);
460  }
461 
462  NaNguard::checkOneParticleRatio(r, "TWF::calcRatio at particle " + std::to_string(iat));
463  return static_cast<ValueType>(r);
464 }
465 
467  const RefVectorWithLeader<ParticleSet>& p_list,
468  int iat,
469  std::vector<PsiValue>& ratios,
470  ComputeType ct)
471 {
472  const int num_wf = wf_list.size();
473  ratios.resize(num_wf);
474  std::fill(ratios.begin(), ratios.end(), PsiValue(1));
475 
476  auto& wf_leader = wf_list.getLeader();
477  ScopedTimer local_timer(wf_leader.TWF_timers_[V_TIMER]);
478  const int num_wfc = wf_leader.Z.size();
479  auto& wavefunction_components = wf_leader.Z;
480 
481  std::vector<PsiValue> ratios_z(num_wf);
482  for (int i = 0; i < num_wfc; i++)
483  {
484  if (ct == ComputeType::ALL || (wavefunction_components[i]->isFermionic() && ct == ComputeType::FERMIONIC) ||
485  (!wavefunction_components[i]->isFermionic() && ct == ComputeType::NONFERMIONIC))
486  {
487  ScopedTimer z_timer(wf_leader.WFC_timers_[V_TIMER + TIMER_SKIP * i]);
488  const auto wfc_list(extractWFCRefList(wf_list, i));
489  wavefunction_components[i]->mw_calcRatio(wfc_list, p_list, iat, ratios_z);
490  for (int iw = 0; iw < wf_list.size(); iw++)
491  ratios[iw] *= ratios_z[iw];
492  }
493  }
494 
495  for (int iw = 0; iw < wf_list.size(); iw++)
496  {
497  NaNguard::checkOneParticleRatio(ratios[iw], "TWF::mw_calcRatio at particle " + std::to_string(iat));
498  wf_list[iw].PhaseDiff = std::arg(ratios[iw]);
499  }
500 }
501 
503 {
504  for (int i = 0; i < Z.size(); ++i)
505  Z[i]->prepareGroup(P, ig);
506 }
507 
509  const RefVectorWithLeader<ParticleSet>& p_list,
510  int ig)
511 {
512  auto& wf_leader = wf_list.getLeader();
513  ScopedTimer local_timer(wf_leader.TWF_timers_[PREPAREGROUP_TIMER]);
514  const int num_wfc = wf_leader.Z.size();
515  auto& wavefunction_components = wf_leader.Z;
516 
517  for (int i = 0; i < num_wfc; i++)
518  {
519  ScopedTimer z_timer(wf_leader.WFC_timers_[PREPAREGROUP_TIMER + TIMER_SKIP * i]);
520  const auto wfc_list(extractWFCRefList(wf_list, i));
521  wavefunction_components[i]->mw_prepareGroup(wfc_list, p_list, ig);
522  }
523 }
524 
526 {
527  ScopedTimer local_timer(TWF_timers_[VGL_TIMER]);
528  GradType grad_iat;
529  for (int i = 0; i < Z.size(); ++i)
530  {
532  grad_iat += Z[i]->evalGrad(P, iat);
533  }
534  NaNguard::checkOneParticleGradients(grad_iat, "TWF::evalGrad at particle " + std::to_string(iat));
535  return grad_iat;
536 }
537 
539 {
540  ScopedTimer local_timer(TWF_timers_[VGL_TIMER]);
541  GradType grad_iat;
542  spingrad = 0;
543  for (int i = 0; i < Z.size(); ++i)
544  {
546  grad_iat += Z[i]->evalGradWithSpin(P, iat, spingrad);
547  }
548  NaNguard::checkOneParticleGradients(grad_iat, "TWF::evalGradWithSpin at particle " + std::to_string(iat));
549  return grad_iat;
550 }
551 
552 template<CoordsType CT>
554  const RefVectorWithLeader<ParticleSet>& p_list,
555  int iat,
556  TWFGrads<CT>& grads)
557 {
558  const int num_wf = wf_list.size();
559  grads = TWFGrads<CT>(num_wf); //ensure elements are set to zero
560 
561  auto& wf_leader = wf_list.getLeader();
562  ScopedTimer local_timer(wf_leader.TWF_timers_[VGL_TIMER]);
563  // Right now mw_evalGrad can only be called through an concrete instance of a wavefunctioncomponent
564  const int num_wfc = wf_leader.Z.size();
565  auto& wavefunction_components = wf_leader.Z;
566 
567  TWFGrads<CT> grads_z(num_wf);
568  for (int i = 0; i < num_wfc; i++)
569  {
570  ScopedTimer localtimer(wf_leader.WFC_timers_[VGL_TIMER + TIMER_SKIP * i]);
571  const auto wfc_list(extractWFCRefList(wf_list, i));
572  wavefunction_components[i]->mw_evalGrad(wfc_list, p_list, iat, grads_z);
573  grads += grads_z;
574  }
575 
576  for (const GradType& grads : grads.grads_positions)
577  NaNguard::checkOneParticleGradients(grads, "TWF::mw_evalGrad at particle " + std::to_string(iat));
578 }
579 
580 // Evaluates the gradient w.r.t. to the source of the Laplacian
581 // w.r.t. to the electrons of the wave function.
583 {
584  GradType grad_iat = GradType();
585  for (int i = 0; i < Z.size(); ++i)
586  grad_iat += Z[i]->evalGradSource(P, source, iat);
587  return grad_iat;
588 }
589 
591  ParticleSet& P,
592  ParticleSet& source,
593  int iat,
596 {
597  GradType grad_iat = GradType();
598  for (int dim = 0; dim < OHMMS_DIM; dim++)
599  for (int i = 0; i < grad_grad[0].size(); i++)
600  {
601  grad_grad[dim][i] = GradType();
602  lapl_grad[dim][i] = 0.0;
603  }
604  for (int i = 0; i < Z.size(); ++i)
605  grad_iat += Z[i]->evalGradSource(P, source, iat, grad_grad, lapl_grad);
606  return grad_iat;
607 }
608 
610 {
611  ScopedTimer local_timer(TWF_timers_[VGL_TIMER]);
612  grad_iat = 0.0;
613  PsiValue r(1.0);
614  if (use_tasking_)
615  {
616  std::vector<GradType> grad_components(Z.size(), GradType(0.0));
617  std::vector<PsiValue> ratio_components(Z.size(), 0.0);
618  PRAGMA_OMP_TASKLOOP("omp taskloop default(shared)")
619  for (int i = 0; i < Z.size(); ++i)
620  {
622  ratio_components[i] = Z[i]->ratioGrad(P, iat, grad_components[i]);
623  }
624 
625  for (int i = 0; i < Z.size(); ++i)
626  {
627  grad_iat += grad_components[i];
628  r *= ratio_components[i];
629  }
630  }
631  else
632  for (int i = 0; i < Z.size(); ++i)
633  {
635  r *= Z[i]->ratioGrad(P, iat, grad_iat);
636  }
637 
638  NaNguard::checkOneParticleRatio(r, "TWF::calcRatioGrad at particle " + std::to_string(iat));
639  if (r != PsiValue(0)) // grad_iat is meaningful only when r is strictly non-zero
640  NaNguard::checkOneParticleGradients(grad_iat, "TWF::calcRatioGrad at particle " + std::to_string(iat));
641  LogValue logratio = convertValueToLog(r);
642  PhaseDiff = std::imag(logratio);
643  return static_cast<ValueType>(r);
644 }
645 
647  int iat,
648  GradType& grad_iat,
649  ComplexType& spingrad_iat)
650 {
651  ScopedTimer local_timer(TWF_timers_[VGL_TIMER]);
652  grad_iat = 0.0;
653  spingrad_iat = 0.0;
654  PsiValue r(1.0);
655  for (int i = 0; i < Z.size(); ++i)
656  {
658  r *= Z[i]->ratioGradWithSpin(P, iat, grad_iat, spingrad_iat);
659  }
660 
661  NaNguard::checkOneParticleRatio(r, "TWF::calcRatioGradWithSpin at particle " + std::to_string(iat));
662  if (r != PsiValue(0)) // grad_iat is meaningful only when r is strictly non-zero
663  NaNguard::checkOneParticleGradients(grad_iat, "TWF::calcRatioGradWithSpin at particle " + std::to_string(iat));
664  LogValue logratio = convertValueToLog(r);
665  PhaseDiff = std::imag(logratio);
666  return static_cast<ValueType>(r);
667 }
668 
669 template<CoordsType CT>
671  const RefVectorWithLeader<ParticleSet>& p_list,
672  int iat,
673  std::vector<PsiValue>& ratios,
674  TWFGrads<CT>& grad_new)
675 {
676  const int num_wf = wf_list.size();
677  ratios.resize(num_wf);
678  std::fill(ratios.begin(), ratios.end(), PsiValue(1));
679  grad_new = TWFGrads<CT>(num_wf);
680 
681  auto& wf_leader = wf_list.getLeader();
682  ScopedTimer local_timer(wf_leader.TWF_timers_[VGL_TIMER]);
683  const int num_wfc = wf_leader.Z.size();
684  auto& wavefunction_components = wf_leader.Z;
685 
686  if (wf_leader.use_tasking_)
687  {
688  std::vector<std::vector<PsiValue>> ratios_components(num_wfc, std::vector<PsiValue>(wf_list.size()));
689  std::vector<TWFGrads<CT>> grads_components(num_wfc, TWFGrads<CT>(num_wf));
690  PRAGMA_OMP_TASKLOOP("omp taskloop default(shared)")
691  for (int i = 0; i < num_wfc; ++i)
692  {
693  ScopedTimer z_timer(wf_leader.WFC_timers_[VGL_TIMER + TIMER_SKIP * i]);
694  const auto wfc_list(extractWFCRefList(wf_list, i));
695  wavefunction_components[i]->mw_ratioGrad(wfc_list, p_list, iat, ratios_components[i], grads_components[i]);
696  }
697 
698  for (int i = 0; i < num_wfc; ++i)
699  {
700  grad_new += grads_components[i];
701  for (int iw = 0; iw < wf_list.size(); iw++)
702  ratios[iw] *= ratios_components[i][iw];
703  }
704  }
705  else
706  {
707  std::vector<PsiValue> ratios_z(wf_list.size());
708  for (int i = 0; i < num_wfc; ++i)
709  {
710  ScopedTimer z_timer(wf_leader.WFC_timers_[VGL_TIMER + TIMER_SKIP * i]);
711  const auto wfc_list(extractWFCRefList(wf_list, i));
712  wavefunction_components[i]->mw_ratioGrad(wfc_list, p_list, iat, ratios_z, grad_new);
713  for (int iw = 0; iw < wf_list.size(); iw++)
714  ratios[iw] *= ratios_z[iw];
715  }
716  }
717  for (int iw = 0; iw < wf_list.size(); iw++)
718  {
719  wf_list[iw].PhaseDiff = std::arg(ratios[iw]);
720  NaNguard::checkOneParticleRatio(ratios[iw], "TWF::mw_calcRatioGrad at particle " + std::to_string(iat));
721  if (ratios[iw] != PsiValue(0))
722  NaNguard::checkOneParticleGradients(grad_new.grads_positions[iw],
723  "TWF::mw_calcRatioGrad at particle " + std::to_string(iat));
724  }
725 }
726 
728 {
729  std::ostringstream o;
730  o << "--- reporting " << tag << std::endl << " ---" << std::endl;
731  for (int iat = 0; iat < L.size(); iat++)
732  o << "index: " << std::fixed << iat << std::scientific << " G: " << G[iat][0] << " " << G[iat][1] << " "
733  << G[iat][2] << " L: " << L[iat] << std::endl;
734  o << "--- end ---" << std::endl;
735  std::cout << o.str();
736 }
737 
738 /** restore to the original state
739  * @param iat index of the particle with a trial move
740  *
741  * The proposed move of the iath particle is rejected.
742  * All the temporary data should be restored to the state prior to the move.
743  */
745 {
746  for (int i = 0; i < Z.size(); i++)
747  Z[i]->restore(iat);
748  PhaseDiff = 0;
749 }
750 
751 /** update the state with the new data
752  * @param P ParticleSet
753  * @param iat index of the particle with a trial move
754  *
755  * The proposed move of the iath particle is accepted.
756  * All the temporary data should be incorporated so that the next move is valid.
757  */
758 void TrialWaveFunction::acceptMove(ParticleSet& P, int iat, bool safe_to_delay)
759 {
760  ScopedTimer local_timer(TWF_timers_[ACCEPT_TIMER]);
761  PRAGMA_OMP_TASKLOOP("omp taskloop default(shared) if (use_tasking_)")
762  for (int i = 0; i < Z.size(); i++)
763  {
765  Z[i]->acceptMove(P, iat, safe_to_delay);
766  }
768  PhaseDiff = 0.0;
769  log_real_ = 0;
770  for (int i = 0; i < Z.size(); i++)
771  log_real_ += std::real(Z[i]->get_log_value());
772 }
773 
775  const RefVectorWithLeader<ParticleSet>& p_list,
776  int iat,
777  const std::vector<bool>& isAccepted,
778  bool safe_to_delay)
779 {
780  auto& wf_leader = wf_list.getLeader();
781  ScopedTimer local_timer(wf_leader.TWF_timers_[ACCEPT_TIMER]);
782  const int num_wfc = wf_leader.Z.size();
783  auto& wavefunction_components = wf_leader.Z;
784 
785  for (int iw = 0; iw < wf_list.size(); iw++)
786  if (isAccepted[iw])
787  {
788  wf_list[iw].log_real_ = 0;
789  wf_list[iw].PhaseValue = 0;
790  }
791 
792  PRAGMA_OMP_TASKLOOP("omp taskloop default(shared) if (wf_leader.use_tasking_)")
793  for (int i = 0; i < num_wfc; i++)
794  {
795  ScopedTimer z_timer(wf_leader.WFC_timers_[ACCEPT_TIMER + TIMER_SKIP * i]);
796  const auto wfc_list(extractWFCRefList(wf_list, i));
797  wavefunction_components[i]->mw_accept_rejectMove(wfc_list, p_list, iat, isAccepted, safe_to_delay);
798  for (int iw = 0; iw < wf_list.size(); iw++)
799  if (isAccepted[iw])
800  {
801  wf_list[iw].log_real_ += std::real(wfc_list[iw].get_log_value());
802  wf_list[iw].PhaseValue += std::imag(wfc_list[iw].get_log_value());
803  }
804  }
805 }
806 
808 {
809  ScopedTimer local_timer(TWF_timers_[ACCEPT_TIMER]);
810  for (int i = 0; i < Z.size(); i++)
811  {
813  Z[i]->completeUpdates();
814  }
815 }
816 
818 {
819  auto& wf_leader = wf_list.getLeader();
820  ScopedTimer local_timer(wf_leader.TWF_timers_[ACCEPT_TIMER]);
821  const int num_wfc = wf_leader.Z.size();
822  auto& wavefunction_components = wf_leader.Z;
823 
824  for (int i = 0; i < num_wfc; i++)
825  {
826  ScopedTimer z_timer(wf_leader.WFC_timers_[ACCEPT_TIMER + TIMER_SKIP * i]);
827  const auto wfc_list(extractWFCRefList(wf_list, i));
828  wavefunction_components[i]->mw_completeUpdates(wfc_list);
829  }
830 }
831 
833 {
834  ScopedTimer local_timer(TWF_timers_[BUFFER_TIMER]);
835  P.G = 0.0;
836  P.L = 0.0;
837  LogValue logpsi(0.0);
838  for (int i = 0; i < Z.size(); ++i)
839  {
841  logpsi += Z[i]->evaluateGL(P, P.G, P.L, fromscratch);
842  }
843 
844  // Ye: temporal workaround to have WF.G/L always defined.
845  // remove when KineticEnergy use WF.G/L instead of P.G/L
846  G = P.G;
847  L = P.L;
848  log_real_ = std::real(logpsi);
849  PhaseValue = std::imag(logpsi);
850  return logpsi;
851 }
852 
854  const RefVectorWithLeader<ParticleSet>& p_list,
855  bool fromscratch)
856 {
857  auto& p_leader = p_list.getLeader();
858  auto& wf_leader = wf_list.getLeader();
859  ScopedTimer local_timer(wf_leader.TWF_timers_[BUFFER_TIMER]);
860 
861  constexpr RealType czero(0);
862  const auto g_list(TrialWaveFunction::extractGRefList(wf_list));
863  const auto l_list(TrialWaveFunction::extractLRefList(wf_list));
864 
865  const int num_particles = p_leader.getTotalNum();
866  for (TrialWaveFunction& wfs : wf_list)
867  {
868  wfs.G.resize(num_particles);
869  wfs.L.resize(num_particles);
870  wfs.G = czero;
871  wfs.L = czero;
872  wfs.log_real_ = czero;
873  wfs.PhaseValue = czero;
874  }
875 
876  auto& wavefunction_components = wf_leader.Z;
877  const int num_wfc = wf_leader.Z.size();
878 
879  for (int i = 0; i < num_wfc; ++i)
880  {
881  ScopedTimer z_timer(wf_leader.WFC_timers_[BUFFER_TIMER + TIMER_SKIP * i]);
882  const auto wfc_list(extractWFCRefList(wf_list, i));
883  wavefunction_components[i]->mw_evaluateGL(wfc_list, p_list, g_list, l_list, fromscratch);
884  }
885 
886  for (int iw = 0; iw < wf_list.size(); iw++)
887  {
888  ParticleSet& pset = p_list[iw];
889  TrialWaveFunction& twf = wf_list[iw];
890 
891  for (int i = 0; i < num_wfc; ++i)
892  {
893  twf.log_real_ += std::real(twf.Z[i]->get_log_value());
894  twf.PhaseValue += std::imag(twf.Z[i]->get_log_value());
895  }
896 
897  // Ye: temporal workaround to have P.G/L always defined.
898  // remove when KineticEnergy use WF.G/L instead of P.G/L
899  pset.G = twf.G;
900  pset.L = twf.L;
901  }
902 }
903 
905 {
906  UniqueOptObjRefs opt_obj_refs;
907  for (int i = 0; i < Z.size(); i++)
908  Z[i]->extractOptimizableObjectRefs(opt_obj_refs);
909  return opt_obj_refs;
910 }
911 
913 {
914  auto opt_obj_refs = extractOptimizableObjectRefs();
915  for (OptimizableObject& obj : opt_obj_refs)
916  obj.checkInVariablesExclusive(active);
917 }
918 
920 {
921  for (int i = 0; i < Z.size(); i++)
922  if (Z[i]->isOptimizable())
923  Z[i]->checkOutVariables(active);
924 }
925 
927 {
928  auto opt_obj_refs = extractOptimizableObjectRefs();
929  for (OptimizableObject& obj : opt_obj_refs)
930  obj.resetParametersExclusive(active);
931 }
932 
933 void TrialWaveFunction::reportStatus(std::ostream& os)
934 {
935  auto opt_obj_refs = extractOptimizableObjectRefs();
936  for (OptimizableObject& obj : opt_obj_refs)
937  obj.reportStatus(os);
938 }
939 
940 void TrialWaveFunction::getLogs(std::vector<RealType>& lvals)
941 {
942  lvals.resize(Z.size(), 0);
943  for (int i = 0; i < Z.size(); i++)
944  {
945  lvals[i] = std::real(Z[i]->get_log_value());
946  }
947 }
948 
949 void TrialWaveFunction::getPhases(std::vector<RealType>& pvals)
950 {
951  pvals.resize(Z.size(), 0);
952  for (int i = 0; i < Z.size(); i++)
953  {
954  pvals[i] = std::imag(Z[i]->get_log_value());
955  }
956 }
957 
959 {
960  ScopedTimer local_timer(TWF_timers_[BUFFER_TIMER]);
961  //save the current position
962  BufferCursor = buf.current();
964  for (int i = 0; i < Z.size(); ++i)
965  {
967  Z[i]->registerData(P, buf);
968  }
969  buf.add(PhaseValue);
970  buf.add(log_real_);
971 }
972 
974 {
975 #ifndef NDEBUG
976  if (buffer.size() < buffer.current() + buffer.current_scalar() * sizeof(FullPrecRealType))
977  {
978  std::ostringstream assert_message;
979  assert_message << "On thread:" << Concurrency::getWorkerId<>() << " buf_list[iw].get().size():" << buffer.size()
980  << " < buf_list[iw].get().current():" << buffer.current()
981  << " + buf.current_scalar():" << buffer.current_scalar()
982  << " * sizeof(FullPrecRealType):" << sizeof(FullPrecRealType) << '\n';
983  throw std::runtime_error(assert_message.str());
984  }
985 #endif
986 }
987 
989 {
990  ScopedTimer local_timer(TWF_timers_[BUFFER_TIMER]);
991  P.G = 0.0;
992  P.L = 0.0;
994  LogValue logpsi(0.0);
995  for (int i = 0; i < Z.size(); ++i)
996  {
998  logpsi += Z[i]->updateBuffer(P, buf, fromscratch);
999  }
1000 
1001  G = P.G;
1002  L = P.L;
1003 
1004  log_real_ = std::real(logpsi);
1005  PhaseValue = std::imag(logpsi);
1006  //printGL(P.G,P.L);
1007  buf.put(PhaseValue);
1008  buf.put(log_real_);
1009  // Ye: temperal added check, to be removed
1010  debugOnlyCheckBuffer(buf);
1011  return log_real_;
1012 }
1013 
1015 {
1016  ScopedTimer local_timer(TWF_timers_[BUFFER_TIMER]);
1018  for (int i = 0; i < Z.size(); ++i)
1019  {
1021  Z[i]->copyFromBuffer(P, buf);
1022  }
1023  //get the gradients and laplacians from the buffer
1024  buf.get(PhaseValue);
1025  buf.get(log_real_);
1026  debugOnlyCheckBuffer(buf);
1027 }
1028 
1029 void TrialWaveFunction::evaluateRatios(const VirtualParticleSet& VP, std::vector<ValueType>& ratios, ComputeType ct)
1030 {
1031  ScopedTimer local_timer(TWF_timers_[NL_TIMER]);
1032  assert(VP.getTotalNum() == ratios.size());
1033  std::vector<ValueType> t(ratios.size());
1034  std::fill(ratios.begin(), ratios.end(), 1.0);
1035  for (int i = 0; i < Z.size(); ++i)
1036  if (ct == ComputeType::ALL || (Z[i]->isFermionic() && ct == ComputeType::FERMIONIC) ||
1037  (!Z[i]->isFermionic() && ct == ComputeType::NONFERMIONIC))
1038  {
1039  ScopedTimer z_timer(WFC_timers_[NL_TIMER + TIMER_SKIP * i]);
1040  Z[i]->evaluateRatios(VP, t);
1041  for (int j = 0; j < ratios.size(); ++j)
1042  ratios[j] *= t[j];
1043  }
1044 }
1045 
1046 void TrialWaveFunction::evaluateSpinorRatios(const VirtualParticleSet& VP, const std::pair<ValueVector, ValueVector>& spinor_multiplier, std::vector<ValueType>& ratios) const
1047 {
1048  ScopedTimer local_timer(TWF_timers_[NL_TIMER]);
1049  assert(VP.getTotalNum() == ratios.size());
1050  std::vector<ValueType> t(ratios.size());
1051  std::fill(ratios.begin(), ratios.end(), 1.0);
1052  for (int i = 0; i < Z.size(); ++i)
1053  {
1054  ScopedTimer z_timer(WFC_timers_[NL_TIMER + TIMER_SKIP * i]);
1055  Z[i]->evaluateSpinorRatios(VP, spinor_multiplier, t);
1056  for (int j = 0; j < ratios.size(); ++j)
1057  ratios[j] *= t[j];
1058  }
1059 }
1060 
1063  const RefVector<std::vector<ValueType>>& ratios_list,
1064  ComputeType ct)
1065 {
1066  auto& wf_leader = wf_list.getLeader();
1067  ScopedTimer local_timer(wf_leader.TWF_timers_[NL_TIMER]);
1068  auto& wavefunction_components = wf_leader.Z;
1069  std::vector<std::vector<ValueType>> t(ratios_list.size());
1070  for (int iw = 0; iw < wf_list.size(); iw++)
1071  {
1072  std::vector<ValueType>& ratios = ratios_list[iw];
1073  assert(vp_list[iw].getTotalNum() == ratios.size());
1074  std::fill(ratios.begin(), ratios.end(), 1.0);
1075  t[iw].resize(ratios.size());
1076  }
1077 
1078  for (int i = 0; i < wavefunction_components.size(); i++)
1079  if (ct == ComputeType::ALL || (wavefunction_components[i]->isFermionic() && ct == ComputeType::FERMIONIC) ||
1080  (!wavefunction_components[i]->isFermionic() && ct == ComputeType::NONFERMIONIC))
1081  {
1082  ScopedTimer z_timer(wf_leader.WFC_timers_[NL_TIMER + TIMER_SKIP * i]);
1083  const auto wfc_list(extractWFCRefList(wf_list, i));
1084  wavefunction_components[i]->mw_evaluateRatios(wfc_list, vp_list, t);
1085  for (int iw = 0; iw < wf_list.size(); iw++)
1086  {
1087  std::vector<ValueType>& ratios = ratios_list[iw];
1088  for (int j = 0; j < ratios.size(); ++j)
1089  ratios[j] *= t[iw][j];
1090  }
1091  }
1092 }
1093 
1095  const opt_variables_type& optvars,
1096  std::vector<ValueType>& ratios,
1097  Matrix<ValueType>& dratio)
1098 {
1099  std::fill(ratios.begin(), ratios.end(), 1.0);
1100  std::fill(dratio.begin(), dratio.end(), 0.0);
1101  std::vector<ValueType> t(ratios.size());
1102  for (int i = 0; i < Z.size(); ++i)
1103  {
1105  Z[i]->evaluateDerivRatios(VP, optvars, t, dratio);
1106  for (int j = 0; j < ratios.size(); ++j)
1107  ratios[j] *= t[j];
1108  }
1109 }
1110 
1111 bool TrialWaveFunction::put(xmlNodePtr cur) { return true; }
1112 
1113 std::unique_ptr<TrialWaveFunction> TrialWaveFunction::makeClone(ParticleSet& tqp) const
1114 {
1115  auto myclone = std::make_unique<TrialWaveFunction>(runtime_options_, myName, use_tasking_);
1116  myclone->BufferCursor = BufferCursor;
1117  myclone->BufferCursor_scalar = BufferCursor_scalar;
1118  for (int i = 0; i < Z.size(); ++i)
1119  myclone->addComponent(Z[i]->makeClone(tqp));
1120  myclone->OneOverM = OneOverM;
1121  return myclone;
1122 }
1123 
1124 /** evaluate derivatives of KE wrt optimizable varibles
1125  *
1126  * @todo WaveFunctionComponent objects should take the mass into account.
1127  */
1129  const opt_variables_type& optvars,
1130  Vector<ValueType>& dlogpsi,
1131  Vector<ValueType>& dhpsioverpsi)
1132 {
1133  // // First, zero out derivatives
1134  // This should only be done for some variables.
1135  // for (int j=0; j<dlogpsi.size(); j++)
1136  // dlogpsi[j] = dhpsioverpsi[j] = 0.0;
1137  for (int i = 0; i < Z.size(); i++)
1138  {
1140  Z[i]->evaluateDerivatives(P, optvars, dlogpsi, dhpsioverpsi);
1141  }
1142  //orbitals do not know about mass of particle.
1143  for (int i = 0; i < dhpsioverpsi.size(); i++)
1144  dhpsioverpsi[i] *= OneOverM;
1145 }
1146 
1148  const RefVectorWithLeader<ParticleSet>& p_list,
1149  const opt_variables_type& optvars,
1150  RecordArray<ValueType>& dlogpsi,
1151  RecordArray<ValueType>& dhpsioverpsi)
1152 {
1153  const int nparam = dlogpsi.getNumOfParams();
1154  for (int iw = 0; iw < wf_list.size(); iw++)
1155  {
1156  Vector<ValueType> dlogpsi_record_view(dlogpsi[iw], nparam);
1157  Vector<ValueType> dhpsioverpsi_record_view(dhpsioverpsi[iw], nparam);
1158 
1159  wf_list[iw].evaluateDerivatives(p_list[iw], optvars, dlogpsi_record_view, dhpsioverpsi_record_view);
1160  }
1161 }
1162 
1163 
1165  const opt_variables_type& optvars,
1166  Vector<ValueType>& dlogpsi)
1167 {
1168  for (int i = 0; i < Z.size(); i++)
1169  {
1171  Z[i]->evaluateDerivativesWF(P, optvars, dlogpsi);
1172  }
1173 }
1174 
1176  std::vector<ValueType>& dgradlogpsi)
1177 {
1178  for (int i = 0; i < Z.size(); i++)
1179  Z[i]->evaluateGradDerivatives(G_in, dgradlogpsi);
1180 }
1181 
1183 {
1184  RealType sum = 0.0;
1185  for (int i = 0; i < Z.size(); ++i)
1186  sum += Z[i]->KECorrection();
1187  return sum;
1188 }
1189 
1190 void TrialWaveFunction::evaluateRatiosAlltoOne(ParticleSet& P, std::vector<ValueType>& ratios)
1191 {
1192  ScopedTimer local_timer(TWF_timers_[V_TIMER]);
1193  std::fill(ratios.begin(), ratios.end(), 1.0);
1194  std::vector<ValueType> t(ratios.size());
1195  for (int i = 0; i < Z.size(); ++i)
1196  {
1197  ScopedTimer local_timer(WFC_timers_[V_TIMER + TIMER_SKIP * i]);
1198  Z[i]->evaluateRatiosAlltoOne(P, t);
1199  for (int j = 0; j < t.size(); ++j)
1200  ratios[j] *= t[j];
1201  }
1202 }
1203 
1205 {
1206  for (int i = 0; i < Z.size(); ++i)
1207  Z[i]->createResource(collection);
1208 }
1209 
1212 {
1213  auto& wf_leader = wf_list.getLeader();
1214  auto& wavefunction_components = wf_leader.Z;
1215  const int num_wfc = wf_leader.Z.size();
1216  for (int i = 0; i < num_wfc; ++i)
1217  {
1218  const auto wfc_list(extractWFCRefList(wf_list, i));
1219  wavefunction_components[i]->acquireResource(collection, wfc_list);
1220  }
1221 }
1222 
1225 {
1226  auto& wf_leader = wf_list.getLeader();
1227  auto& wavefunction_components = wf_leader.Z;
1228  const int num_wfc = wf_leader.Z.size();
1229  for (int i = 0; i < num_wfc; ++i)
1230  {
1231  const auto wfc_list(extractWFCRefList(wf_list, i));
1232  wavefunction_components[i]->releaseResource(collection, wfc_list);
1233  }
1234 }
1235 
1238  int id)
1239 {
1240  RefVectorWithLeader<WaveFunctionComponent> wfc_list(*wf_list.getLeader().Z[id]);
1241  wfc_list.reserve(wf_list.size());
1242  for (TrialWaveFunction& wf : wf_list)
1243  wfc_list.push_back(*wf.Z[id]);
1244  return wfc_list;
1245 }
1246 
1247 std::vector<WaveFunctionComponent*> TrialWaveFunction::extractWFCPtrList(const UPtrVector<TrialWaveFunction>& g, int id)
1248 {
1249  std::vector<WaveFunctionComponent*> WFC_list;
1250  WFC_list.reserve(g.size());
1251  for (auto& WF : g)
1252  WFC_list.push_back(WF->Z[id].get());
1253  return WFC_list;
1254 }
1255 
1258 {
1260  for (TrialWaveFunction& wf : wf_list)
1261  g_list.push_back(wf.G);
1262  return g_list;
1263 }
1264 
1267 {
1269  for (TrialWaveFunction& wf : wf_list)
1270  l_list.push_back(wf.L);
1271  return l_list;
1272 }
1273 
1275 {
1276  for (int i = 0; i < Z.size(); ++i)
1277  {
1278  if (Z[i]->isFermionic())
1279  {
1280  //OK, so this is a hack only for SlaterDeterminant objects.
1281  //Needs a bit of logic and protection before this reaches production.
1282  //SlaterDet* det = dynamic_cast<SlaterDet*>(Z[i].get());
1283  //det->registerTWFFastDerivWrapper(P, twf);
1284  Z[i]->registerTWFFastDerivWrapper(P, twf);
1285  }
1286  else
1287  twf.addJastrow(Z[i].get());
1288  }
1289 }
1290 
1291 //explicit instantiations
1292 template void TrialWaveFunction::mw_evalGrad<CoordsType::POS>(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
1293  const RefVectorWithLeader<ParticleSet>& p_list,
1294  int iat,
1295  TWFGrads<CoordsType::POS>& grads);
1296 template void TrialWaveFunction::mw_evalGrad<CoordsType::POS_SPIN>(
1298  const RefVectorWithLeader<ParticleSet>& p_list,
1299  int iat,
1301 template void TrialWaveFunction::mw_calcRatioGrad<CoordsType::POS>(
1303  const RefVectorWithLeader<ParticleSet>& p_list,
1304  int iat,
1305  std::vector<PsiValue>& ratios,
1306  TWFGrads<CoordsType::POS>& grads);
1307 template void TrialWaveFunction::mw_calcRatioGrad<CoordsType::POS_SPIN>(
1309  const RefVectorWithLeader<ParticleSet>& p_list,
1310  int iat,
1311  std::vector<PsiValue>& ratios,
1313 
1314 } // namespace qmcplusplus
base class for Single-particle orbital sets
Definition: SPOSet.h:46
size_t BufferCursor_scalar
starting index of the scalar buffer
RealType evaluateLog(ParticleSet &P)
evalaute the log (internally gradients and laplacian) of the trial wavefunction.
WaveFunctionComponent::PsiValue PsiValue
WaveFunctionComponent::RealType RealType
Container_t::iterator begin()
Definition: OhmmsMatrix.h:89
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
void rejectMove(int iat)
restore to the original state
void evaluateSpinorRatios(const VirtualParticleSet &VP, const std::pair< ValueVector, ValueVector > &spinor_multiplier, std::vector< ValueType > &ratios) const
Used by SOECPComponent to do faster SOC evaluation.
ValueType calcRatio(ParticleSet &P, int iat, ComputeType ct=ComputeType::ALL)
compute psi(R_new) / psi(R_current) ratio It returns a complex value if the wavefunction is complex...
void evaluateRatiosAlltoOne(ParticleSet &P, std::vector< ValueType > &ratios)
void copyFromBuffer(ParticleSet &P, WFBufferType &buf)
copy all the wavefunction components from buffer.
Abstraction of information on executor environments.
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
WaveFunctionComponent::GradType GradType
void getLogs(std::vector< RealType > &lvals)
void createResource(ResourceCollection &collection) const
initialize a shared resource and hand it to a collection
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &optvars, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi)
evaluate derivatives of KE wrt optimizable varibles
std::vector< TimerIDName_t< T > > TimerNameList_t
Definition: TimerManager.h:156
size_t getTotalNum() const
Definition: ParticleSet.h:493
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false)
update the state with the new data
void evaluateHessian(ParticleSet &P, HessVector &all_grad_grad_psi)
evaluate the hessian w.r.t.
static void mw_prepareGroup(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, int ig)
batched version of prepareGroup
std::ostream & app_log()
Definition: OutputManager.h:65
void evaluateDerivativesWF(ParticleSet &P, const opt_variables_type &optvars, Vector< ValueType > &dlogpsi)
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
static void mw_calcRatioGrad(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios, TWFGrads< CT > &grads)
batched version of ratioGrad
void resetParameters(const opt_variables_type &active)
Set values of parameters in each component from the global list.
RealType PhaseDiff
diff of the phase of the trial wave function during ratio calls
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
WaveFunctionComponent::LogValue LogValue
void convertToReal(const T1 &in, T2 &out)
generic conversion from type T1 to type T2 using implicit conversion
Definition: ConvertToReal.h:32
const bool use_tasking_
if true, using internal tasking implementation
const SPOSet & getSPOSet(const std::string &name) const
look up SPOSet named &#39;name&#39;, if not found, throw exception.
TrialWaveFunction(const RuntimeOptions &runtime_options, const std::string_view aname="psi0", bool tasking=false)
ParticleAttrib< QTFull::ValueType > ParticleLaplacian
Definition: Configuration.h:96
void printGL(ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L, std::string tag="GL")
ParticleSet::ParticleLaplacian L
differential laplacians
std::vector< std::unique_ptr< T > > UPtrVector
WaveFunctionComponent::ValueType ValueType
static RefVectorWithLeader< WaveFunctionComponent > extractWFCRefList(const RefVectorWithLeader< TrialWaveFunction > &wf_list, int id)
std::complex< T > convertValueToLog(const std::complex< T > &logpsi)
evaluate log(psi) as log(|psi|) and phase
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
TWFFastDerivWrapper is a wrapper class for TrialWavefunction that provides separate and low level acc...
static RefVector< ParticleSet::ParticleGradient > extractGRefList(const RefVectorWithLeader< TrialWaveFunction > &wf_list)
}@
static void mw_accept_rejectMove(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, const std::vector< bool > &isAccepted, bool safe_to_delay=false)
RealType updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false)
update all the wavefunction components in buffer.
#define OHMMS_DIM
Definition: config.h:64
std::unique_ptr< TrialWaveFunction > makeClone(ParticleSet &tqp) const
RefVector< MultiSlaterDetTableMethod > findMSD() const
find MSD WFCs if exist
void recompute(const ParticleSet &P)
recompute the value of the orbitals which require critical accuracy
void evaluateDeltaLogSetup(ParticleSet &P, RealType &logpsi_fixed, RealType &logpsi_opt, ParticleSet::ParticleGradient &fixedG, ParticleSet::ParticleLaplacian &fixedL)
evaluate the sum of log value of optimizable many-body wavefunctions
UniqueOptObjRefs extractOptimizableObjectRefs()
extract underlying OptimizableObject references
ParticleSet::ParticleGradient G
differential gradients
RealType PhaseValue
sign of the trial wave function
static void mw_evaluateGL(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, bool fromscratch)
WaveFunctionComponent::ComplexType ComplexType
LogValue evaluateGL(ParticleSet &P, bool fromscratch)
compute gradients and laplacian of the TWF with respect to each particle.
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
std::vector< std::unique_ptr< WaveFunctionComponent > > Z
a list of WaveFunctionComponents constituting many-body wave functions
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
size_type size() const
return the current size
Definition: OhmmsVector.h:162
GradType evalGradWithSpin(ParticleSet &P, int iat, ComplexType &spingrad)
compute d/ds ln(psi) spin gradient at current particle position for iat electron
void evaluateGradDerivatives(const ParticleSet::ParticleGradient &G_in, std::vector< ValueType > &dgradlogpsi)
WaveFunctionComponent::FullPrecRealType FullPrecRealType
static void mw_evaluateParameterDerivatives(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, const opt_variables_type &optvars, RecordArray< ValueType > &dlogpsi, RecordArray< ValueType > &dhpsioverpsi)
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
static void mw_calcRatio(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, std::vector< PsiValue > &ratios, ComputeType ct=ComputeType::ALL)
batched version of calcRatio
const std::shared_ptr< SPOMap > spomap_
Owned SPOSets. Once a TWF is fully built, SPOSet lookup should be done via TWF.
RealType log_real_
real part of trial wave function log
NewTimer & createGlobalTimer(const std::string &myname, timer_levels mylevel)
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
GradType evalGradSource(ParticleSet &P, ParticleSet &source, int iat)
Returns the logarithmic gradient of the trial wave function with respect to the iat^th atom of the so...
static void mw_evaluateDeltaLog(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, std::vector< RealType > &logpsi_list, RefVector< ParticleSet::ParticleGradient > &dummyG_list, RefVector< ParticleSet::ParticleLaplacian > &dummyL_list, bool recompute=false)
evaluate the log value for optimizable parts of a many-body wave function
void registerData(ParticleSet &P, WFBufferType &buf)
register all the wavefunction components in buffer.
ComputeType
enum type for computing partial WaveFunctionComponents
xmlNodePtr myNode_
XML input node for a many-body wavefunction.
static void checkOneParticleRatio(const PsiValue &ratio, const std::string_view info)
check if ratio is NaN and throw an error if yes.
Definition: NaNguard.cpp:18
void checkOutVariables(const opt_variables_type &o)
Check out optimizable variables Assign index mappings from global list (o) to local values in each co...
static const std::vector< std::string > suffixes
static void mw_evalGrad(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, int iat, TWFGrads< CT > &grads)
batched version of evalGrad
static void mw_evaluateDeltaLogSetup(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, std::vector< RealType > &logpsi_fixed_list, std::vector< RealType > &logpsi_opt_list, RefVector< ParticleSet::ParticleGradient > &fixedG_list, RefVector< ParticleSet::ParticleLaplacian > &fixedL_list)
evaluate the sum of log value of optimizable many-body wavefunctions
static void debugOnlyCheckBuffer(WFBufferType &buffer)
static void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< TrialWaveFunction > &wf_list)
acquire external resource Note: use RAII ResourceCollectionLock whenever possible ...
static std::vector< WaveFunctionComponent * > extractWFCPtrList(const UPtrVector< TrialWaveFunction > &wf_list, int id)
helper function for extracting a list of WaveFunctionComponent from a list of TrialWaveFunction ...
void getPhases(std::vector< RealType > &pvals)
static void mw_completeUpdates(const RefVectorWithLeader< TrialWaveFunction > &wf_list)
static TimerNameList_t< TimerEnum > create_names(std::string_view myName)
WaveFunctionComponent::HessVector HessVector
Declaration of a TrialWaveFunction.
TimerList_t TWF_timers_
timers at TrialWaveFunction function call level
size_type current() const
Definition: PooledMemory.h:76
std::vector< std::reference_wrapper< T > > RefVector
static void mw_recompute(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, const std::vector< bool > &recompute)
batched version of recompute
size_type size() const
return the size of the data
Definition: PooledMemory.h:73
void reportStatus(std::ostream &os)
print out state of the trial wavefunction
RealType evaluateDeltaLog(ParticleSet &P, bool recompute=false)
evaluate the log value of a many-body wave function
Class to represent a many-body trial wave function.
static RefVector< ParticleSet::ParticleLaplacian > extractLRefList(const RefVectorWithLeader< TrialWaveFunction > &wf_list)
GradType evalGrad(ParticleSet &P, int iat)
static void checkOneParticleGradients(const GradType &grads, const std::string_view info)
check if any gradient component (x,y,z) is NaN and throw an error if yes.
Definition: NaNguard.cpp:29
RealType OneOverM
One over mass of target particleset, needed for Local Energy Derivatives.
bool put(xmlNodePtr cur)
read from xmlNode
ParticleAttrib< QTFull::GradType > ParticleGradient
Definition: Configuration.h:95
ValueType calcRatioGradWithSpin(ParticleSet &P, int iat, GradType &grad_iat, ComplexType &spingrad_iat)
compute psi(R_new) / psi(R_current) ratio and d/ds ln(psi(R_new)) spin gradient It returns a complex ...
const RuntimeOptions & runtime_options_
top-level runtime options from project data information > WaveFunctionPool
void evaluateDerivRatios(const VirtualParticleSet &VP, const opt_variables_type &optvars, std::vector< ValueType > &ratios, Matrix< ValueType > &dratio)
compute both ratios and deriatives of ratio with respect to the optimizables
TimerManager< NewTimer > & getGlobalTimerManager()
size_t BufferCursor
starting index of the buffer
size_type current_scalar() const
Definition: PooledMemory.h:79
static void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< TrialWaveFunction > &wf_list)
release external resource Note: use RAII ResourceCollectionLock whenever possible ...
Container_t::iterator end()
Definition: OhmmsMatrix.h:90
void prepareGroup(ParticleSet &P, int ig)
Prepare internal data for updating WFC correspond to a particle group Particle groups usually corresp...
const std::string myName
getName is in the way
std::vector< std::reference_wrapper< NewTimer > > WFC_timers_
timers at WaveFunctionComponent function call level
void rewind(size_type cur=0, size_type cur_scalar=0)
set the cursors
Definition: PooledMemory.h:85
void put(std::complex< T1 > &x)
Definition: PooledMemory.h:165
ValueType calcRatioGrad(ParticleSet &P, int iat, GradType &grad_iat)
compute psi(R_new) / psi(R_current) ratio and ln(psi(R_new)) gradients It returns a complex value if...
static void mw_evaluateRatios(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< const VirtualParticleSet > &Vp_list, const RefVector< std::vector< ValueType >> &ratios_list, ComputeType ct=ComputeType::ALL)
batched version of evaluateRatios Note: unlike other mw_ static functions, *this is the batch leader ...
void evaluateRatios(const VirtualParticleSet &VP, std::vector< ValueType > &ratios, ComputeType ct=ComputeType::ALL)
compulte multiple ratios to handle non-local moves and other virtual moves
void completeUpdates()
complete all the delayed or asynchronous operations before leaving the p-by-p move region...
void addComponent(std::unique_ptr< WaveFunctionComponent > &&aterm)
add a WaveFunctionComponent
static void mw_evaluateLog(const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list)
batched version of evaluateLog.
void checkInVariables(opt_variables_type &o)
Check in an optimizable parameter.
void initializeTWFFastDerivWrapper(const ParticleSet &P, TWFFastDerivWrapper &twf) const
Initialize a TWF wrapper for fast derivative evaluation.
void add(std::complex< T1 > &x)
Definition: PooledMemory.h:113
void get(std::complex< T1 > &x)
Definition: PooledMemory.h:132