QMCPACK
SpinorSet.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) 2022 QMCPACK developers
6 //
7 // File developed by: Raymond Clay III, rclay@sandia.gov, Sandia National Laboratories
8 // Cody A. Melton, cmelton@sandia.gov, Sandia National Laboratories
9 //
10 // File created by: Raymond Clay III, rclay@sandia.gov, Sandia National Laboratories
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 #include "SpinorSet.h"
17 
18 namespace qmcplusplus
19 {
21 {
24  std::unique_ptr<Resource> makeClone() const override { return std::make_unique<SpinorSetMultiWalkerResource>(*this); }
26  std::vector<ValueType> up_ratios, dn_ratios;
27  std::vector<GradType> up_grads, dn_grads;
28  std::vector<RealType> spins;
29 };
30 
31 SpinorSet::SpinorSet(const std::string& my_name) : SPOSet(my_name), spo_up(nullptr), spo_dn(nullptr) {}
32 SpinorSet::~SpinorSet() = default;
33 
35 {
36  spo_up->storeParamsBeforeRotation();
37  spo_dn->storeParamsBeforeRotation();
38 }
39 
40 void SpinorSet::applyRotation(const ValueMatrix& rot_mat, bool use_stored_copy)
41 {
42  spo_up->applyRotation(rot_mat, use_stored_copy);
43  spo_dn->applyRotation(rot_mat, use_stored_copy);
44 }
45 
46 void SpinorSet::set_spos(std::unique_ptr<SPOSet>&& up, std::unique_ptr<SPOSet>&& dn)
47 {
48  //Sanity check for input SPO's. They need to be the same size or
49  IndexType spo_size_up = up->getOrbitalSetSize();
50  IndexType spo_size_down = dn->getOrbitalSetSize();
51 
52  if (spo_size_up != spo_size_down)
53  throw std::runtime_error("SpinorSet::set_spos(...): up and down SPO components have different sizes.");
54 
55  setOrbitalSetSize(spo_size_up);
56 
57  spo_up = std::move(up);
58  spo_dn = std::move(dn);
59 }
60 
61 void SpinorSet::setOrbitalSetSize(int norbs) { OrbitalSetSize = norbs; };
62 
63 
64 void SpinorSet::evaluateValue(const ParticleSet& P, int iat, ValueVector& psi)
65 {
66  const size_t norb_requested = psi.size();
67  psi_work_up.resize(norb_requested);
68  psi_work_down.resize(norb_requested);
69  psi_work_up = 0.0;
70  psi_work_down = 0.0;
71 
72  spo_up->evaluateValue(P, iat, psi_work_up);
73  spo_dn->evaluateValue(P, iat, psi_work_down);
74 
76 
77  RealType coss(0.0), sins(0.0);
78 
79  coss = std::cos(s);
80  sins = std::sin(s);
81 
82  //This is only supported in the complex build, so ValueType is some complex number depending on the precision.
83  ValueType eis(coss, sins);
84  ValueType emis(coss, -sins);
85 
86  psi = eis * psi_work_up + emis * psi_work_down;
87 }
88 
90  ValueVector& psi,
91  const std::pair<ValueVector, ValueVector>& spinor_multiplier,
92  const ValueVector& psiinv,
93  std::vector<ValueType>& ratios)
94 {
95  assert(psi.size() == psiinv.size());
96  const size_t norb_requested = psi.size();
97  psi_work_up.resize(norb_requested);
98  psi_work_down.resize(norb_requested);
99 
100  for (size_t iat = 0.0; iat < VP.getTotalNum(); iat++)
101  {
102  psi_work_up = 0.0;
103  psi_work_down = 0.0;
104  spo_up->evaluateValue(VP, iat, psi_work_up);
105  spo_dn->evaluateValue(VP, iat, psi_work_down);
106 
108  RealType coss = std::cos(s);
109  RealType sins = std::sin(s);
110 
111  ValueType eis(coss, sins);
112  ValueType emis(coss, -sins);
113 
114  psi = spinor_multiplier.first[iat] * eis * psi_work_up + spinor_multiplier.second[iat] * emis * psi_work_down;
115  ratios[iat] = simd::dot(psi.data(), psiinv.data(), psi.size());
116  }
117 }
118 
119 void SpinorSet::evaluateVGL(const ParticleSet& P, int iat, ValueVector& psi, GradVector& dpsi, ValueVector& d2psi)
120 {
121  const size_t norb_requested = psi.size();
122  psi_work_up.resize(norb_requested);
123  psi_work_down.resize(norb_requested);
124  dpsi_work_up.resize(norb_requested);
125  dpsi_work_down.resize(norb_requested);
126  d2psi_work_up.resize(norb_requested);
127  d2psi_work_down.resize(norb_requested);
128  psi_work_up = 0.0;
129  psi_work_down = 0.0;
130  dpsi_work_up = 0.0;
131  dpsi_work_down = 0.0;
132  d2psi_work_up = 0.0;
133  d2psi_work_down = 0.0;
134 
135  spo_up->evaluateVGL(P, iat, psi_work_up, dpsi_work_up, d2psi_work_up);
136  spo_dn->evaluateVGL(P, iat, psi_work_down, dpsi_work_down, d2psi_work_down);
137 
139 
140  RealType coss(0.0), sins(0.0);
141 
142  coss = std::cos(s);
143  sins = std::sin(s);
144 
145  ValueType eis(coss, sins);
146  ValueType emis(coss, -sins);
147 
148  psi = eis * psi_work_up + emis * psi_work_down;
149  dpsi = eis * dpsi_work_up + emis * dpsi_work_down;
150  d2psi = eis * d2psi_work_up + emis * d2psi_work_down;
151 }
152 
154  int iat,
155  ValueVector& psi,
156  GradVector& dpsi,
157  ValueVector& d2psi,
158  ValueVector& dspin)
159 {
160  const size_t norb_requested = psi.size();
161  psi_work_up.resize(norb_requested);
162  psi_work_down.resize(norb_requested);
163  dpsi_work_up.resize(norb_requested);
164  dpsi_work_down.resize(norb_requested);
165  d2psi_work_up.resize(norb_requested);
166  d2psi_work_down.resize(norb_requested);
167  psi_work_up = 0.0;
168  psi_work_down = 0.0;
169  dpsi_work_up = 0.0;
170  dpsi_work_down = 0.0;
171  d2psi_work_up = 0.0;
172  d2psi_work_down = 0.0;
173 
174  spo_up->evaluateVGL(P, iat, psi_work_up, dpsi_work_up, d2psi_work_up);
175  spo_dn->evaluateVGL(P, iat, psi_work_down, dpsi_work_down, d2psi_work_down);
176 
178 
179  RealType coss(0.0), sins(0.0);
180 
181  coss = std::cos(s);
182  sins = std::sin(s);
183 
184  ValueType eis(coss, sins);
185  ValueType emis(coss, -sins);
186  ValueType eye(0, 1.0);
187 
188  psi = eis * psi_work_up + emis * psi_work_down;
189  dpsi = eis * dpsi_work_up + emis * dpsi_work_down;
190  d2psi = eis * d2psi_work_up + emis * d2psi_work_down;
191  dspin = eye * (eis * psi_work_up - emis * psi_work_down);
192 }
193 
195  const RefVectorWithLeader<ParticleSet>& P_list,
196  int iat,
197  const RefVector<ValueVector>& psi_v_list,
198  const RefVector<GradVector>& dpsi_v_list,
199  const RefVector<ValueVector>& d2psi_v_list,
200  OffloadMatrix<ComplexType>& mw_dspin) const
201 {
202  auto& spo_leader = spo_list.getCastedLeader<SpinorSet>();
203  auto& P_leader = P_list.getLeader();
204  assert(this == &spo_leader);
205 
206  IndexType nw = spo_list.size();
207  auto [up_spo_list, dn_spo_list] = extractSpinComponentRefList(spo_list);
208  auto& up_spo_leader = up_spo_list.getLeader();
209  auto& dn_spo_leader = dn_spo_list.getLeader();
210 
211  RefVector<ValueVector> up_psi_v_list, dn_psi_v_list;
212  RefVector<GradVector> up_dpsi_v_list, dn_dpsi_v_list;
213  RefVector<ValueVector> up_d2psi_v_list, dn_d2psi_v_list;
214  for (int iw = 0; iw < nw; iw++)
215  {
216  auto& spo = spo_list.getCastedElement<SpinorSet>(iw);
217  auto& psi = psi_v_list[iw].get();
218  const size_t norb_requested = psi.size();
219 
220  spo.psi_work_up.resize(norb_requested);
221  spo.psi_work_down.resize(norb_requested);
222  spo.dpsi_work_up.resize(norb_requested);
223  spo.dpsi_work_down.resize(norb_requested);
224  spo.d2psi_work_up.resize(norb_requested);
225  spo.d2psi_work_down.resize(norb_requested);
226 
227  up_psi_v_list.push_back(spo.psi_work_up);
228  dn_psi_v_list.push_back(spo.psi_work_down);
229  up_dpsi_v_list.push_back(spo.dpsi_work_up);
230  dn_dpsi_v_list.push_back(spo.dpsi_work_down);
231  up_d2psi_v_list.push_back(spo.d2psi_work_up);
232  dn_d2psi_v_list.push_back(spo.d2psi_work_down);
233  }
234 
235  up_spo_leader.mw_evaluateVGL(up_spo_list, P_list, iat, up_psi_v_list, up_dpsi_v_list, up_d2psi_v_list);
236  dn_spo_leader.mw_evaluateVGL(dn_spo_list, P_list, iat, dn_psi_v_list, dn_dpsi_v_list, dn_d2psi_v_list);
237 
238  for (int iw = 0; iw < nw; iw++)
239  {
240  ParticleSet::Scalar_t s = P_list[iw].activeSpin(iat);
241  RealType coss = std::cos(s);
242  RealType sins = std::sin(s);
243 
244  ValueType eis(coss, sins);
245  ValueType emis(coss, -sins);
246  ValueType eye(0, 1.0);
247 
248  psi_v_list[iw].get() = eis * up_psi_v_list[iw].get() + emis * dn_psi_v_list[iw].get();
249  dpsi_v_list[iw].get() = eis * up_dpsi_v_list[iw].get() + emis * dn_dpsi_v_list[iw].get();
250  d2psi_v_list[iw].get() = eis * up_d2psi_v_list[iw].get() + emis * dn_d2psi_v_list[iw].get();
251  for (int iorb = 0; iorb < mw_dspin.cols(); iorb++)
252  mw_dspin(iw, iorb) = eye * (eis * (up_psi_v_list[iw].get())[iorb] - emis * (dn_psi_v_list[iw].get())[iorb]);
253  }
254  //Data above is all on host, but since mw_dspin is DualMatrix we need to sync the host and device
255  mw_dspin.updateTo();
256 }
257 
259  const RefVectorWithLeader<ParticleSet>& P_list,
260  int iat,
261  const std::vector<const ValueType*>& invRow_ptr_list,
262  OffloadMWVGLArray& phi_vgl_v,
263  std::vector<ValueType>& ratios,
264  std::vector<GradType>& grads,
265  std::vector<ValueType>& spingrads) const
266 {
267  auto& spo_leader = spo_list.getCastedLeader<SpinorSet>();
268  auto& P_leader = P_list.getLeader();
269  assert(this == &spo_leader);
270  assert(phi_vgl_v.size(0) == DIM_VGL);
271  assert(phi_vgl_v.size(1) == spo_list.size());
272  const size_t nw = spo_list.size();
273  const size_t norb_requested = phi_vgl_v.size(2);
274 
275  auto& mw_res = spo_leader.mw_res_handle_.getResource();
276  auto& up_phi_vgl_v = mw_res.up_phi_vgl_v;
277  auto& dn_phi_vgl_v = mw_res.dn_phi_vgl_v;
278  auto& up_ratios = mw_res.up_ratios;
279  auto& dn_ratios = mw_res.dn_ratios;
280  auto& up_grads = mw_res.up_grads;
281  auto& dn_grads = mw_res.dn_grads;
282  auto& spins = mw_res.spins;
283 
284  up_phi_vgl_v.resize(DIM_VGL, nw, norb_requested);
285  dn_phi_vgl_v.resize(DIM_VGL, nw, norb_requested);
286  up_ratios.resize(nw);
287  dn_ratios.resize(nw);
288  up_grads.resize(nw);
289  dn_grads.resize(nw);
290  spins.resize(nw);
291 
292  auto [up_spo_list, dn_spo_list] = extractSpinComponentRefList(spo_list);
293  auto& up_spo_leader = up_spo_list.getLeader();
294  auto& dn_spo_leader = dn_spo_list.getLeader();
295 
296  up_spo_leader.mw_evaluateVGLandDetRatioGrads(up_spo_list, P_list, iat, invRow_ptr_list, up_phi_vgl_v, up_ratios,
297  up_grads);
298  dn_spo_leader.mw_evaluateVGLandDetRatioGrads(dn_spo_list, P_list, iat, invRow_ptr_list, dn_phi_vgl_v, dn_ratios,
299  dn_grads);
300  for (int iw = 0; iw < nw; iw++)
301  {
302  ParticleSet::Scalar_t s = P_list[iw].activeSpin(iat);
303  spins[iw] = s;
304  RealType coss = std::cos(s);
305  RealType sins = std::sin(s);
306 
307  ValueType eis(coss, sins);
308  ValueType emis(coss, -sins);
309  ValueType eye(0, 1.0);
310 
311  ratios[iw] = eis * up_ratios[iw] + emis * dn_ratios[iw];
312  grads[iw] = (eis * up_grads[iw] * up_ratios[iw] + emis * dn_grads[iw] * dn_ratios[iw]) / ratios[iw];
313  spingrads[iw] = eye * (eis * up_ratios[iw] - emis * dn_ratios[iw]) / ratios[iw];
314  }
315 
316  auto* spins_ptr = spins.data();
317  //This data lives on the device
318  auto* phi_vgl_ptr = phi_vgl_v.data();
319  auto* up_phi_vgl_ptr = up_phi_vgl_v.data();
320  auto* dn_phi_vgl_ptr = dn_phi_vgl_v.data();
321  PRAGMA_OFFLOAD("omp target teams distribute map(to:spins_ptr[0:nw])")
322  for (int iw = 0; iw < nw; iw++)
323  {
324  RealType c, s;
325  omptarget::sincos(spins_ptr[iw], &s, &c);
326  ValueType eis(c, s), emis(c, -s);
327  PRAGMA_OFFLOAD("omp parallel for collapse(2)")
328  for (int idim = 0; idim < DIM_VGL; idim++)
329  for (int iorb = 0; iorb < norb_requested; iorb++)
330  {
331  auto offset = idim * nw * norb_requested + iw * norb_requested + iorb;
332  phi_vgl_ptr[offset] = eis * up_phi_vgl_ptr[offset] + emis * dn_phi_vgl_ptr[offset];
333  }
334  }
335 }
336 
338  int first,
339  int last,
340  ValueMatrix& logdet,
341  GradMatrix& dlogdet,
342  ValueMatrix& d2logdet)
343 {
344  IndexType nelec = P.getTotalNum();
345 
346  const size_t norb_requested = logdet.cols();
347 
348  logpsi_work_up.resize(nelec, norb_requested);
349  logpsi_work_down.resize(nelec, norb_requested);
350 
351  dlogpsi_work_up.resize(nelec, norb_requested);
352  dlogpsi_work_down.resize(nelec, norb_requested);
353 
354  d2logpsi_work_up.resize(nelec, norb_requested);
355  d2logpsi_work_down.resize(nelec, norb_requested);
356 
357  spo_up->evaluate_notranspose(P, first, last, logpsi_work_up, dlogpsi_work_up, d2logpsi_work_up);
358  spo_dn->evaluate_notranspose(P, first, last, logpsi_work_down, dlogpsi_work_down, d2logpsi_work_down);
359 
360 
361  for (int iat = first; iat < last; iat++)
362  {
364 
365  RealType coss(0.0), sins(0.0);
366 
367  coss = std::cos(s);
368  sins = std::sin(s);
369 
370  ValueType eis(coss, sins);
371  ValueType emis(coss, -sins);
372 
373  for (int no = 0; no < norb_requested; no++)
374  {
375  logdet(iat, no) = eis * logpsi_work_up(iat, no) + emis * logpsi_work_down(iat, no);
376  dlogdet(iat, no) = eis * dlogpsi_work_up(iat, no) + emis * dlogpsi_work_down(iat, no);
377  d2logdet(iat, no) = eis * d2logpsi_work_up(iat, no) + emis * d2logpsi_work_down(iat, no);
378  }
379  }
380 }
381 
383  const RefVectorWithLeader<ParticleSet>& P_list,
384  int first,
385  int last,
386  const RefVector<ValueMatrix>& logdet_list,
387  const RefVector<GradMatrix>& dlogdet_list,
388  const RefVector<ValueMatrix>& d2logdet_list) const
389 {
390  auto& spo_leader = spo_list.getCastedLeader<SpinorSet>();
391  auto& P_leader = P_list.getLeader();
392  assert(this == &spo_leader);
393 
394  IndexType nw = spo_list.size();
395  IndexType nelec = P_leader.getTotalNum();
396 
397  auto [up_spo_list, dn_spo_list] = extractSpinComponentRefList(spo_list);
398  auto& up_spo_leader = up_spo_list.getLeader();
399  auto& dn_spo_leader = dn_spo_list.getLeader();
400 
401  std::vector<ValueMatrix> mw_up_logdet, mw_dn_logdet;
402  std::vector<GradMatrix> mw_up_dlogdet, mw_dn_dlogdet;
403  std::vector<ValueMatrix> mw_up_d2logdet, mw_dn_d2logdet;
404  mw_up_logdet.reserve(nw);
405  mw_dn_logdet.reserve(nw);
406  mw_up_dlogdet.reserve(nw);
407  mw_dn_dlogdet.reserve(nw);
408  mw_up_d2logdet.reserve(nw);
409  mw_dn_d2logdet.reserve(nw);
410 
411  RefVector<ValueMatrix> up_logdet_list, dn_logdet_list;
412  RefVector<GradMatrix> up_dlogdet_list, dn_dlogdet_list;
413  RefVector<ValueMatrix> up_d2logdet_list, dn_d2logdet_list;
414  up_logdet_list.reserve(nw);
415  dn_logdet_list.reserve(nw);
416  up_dlogdet_list.reserve(nw);
417  dn_dlogdet_list.reserve(nw);
418  up_d2logdet_list.reserve(nw);
419  dn_d2logdet_list.reserve(nw);
420 
421  const size_t norb_requested = logdet_list.front().get().cols();
422  ValueMatrix tmp_val_mat(nelec, norb_requested);
423  GradMatrix tmp_grad_mat(nelec, norb_requested);
424  for (int iw = 0; iw < nw; iw++)
425  {
426  mw_up_logdet.emplace_back(tmp_val_mat);
427  up_logdet_list.emplace_back(mw_up_logdet.back());
428  mw_dn_logdet.emplace_back(tmp_val_mat);
429  dn_logdet_list.emplace_back(mw_dn_logdet.back());
430 
431  mw_up_dlogdet.emplace_back(tmp_grad_mat);
432  up_dlogdet_list.emplace_back(mw_up_dlogdet.back());
433  mw_dn_dlogdet.emplace_back(tmp_grad_mat);
434  dn_dlogdet_list.emplace_back(mw_dn_dlogdet.back());
435 
436  mw_up_d2logdet.emplace_back(tmp_val_mat);
437  up_d2logdet_list.emplace_back(mw_up_d2logdet.back());
438  mw_dn_d2logdet.emplace_back(tmp_val_mat);
439  dn_d2logdet_list.emplace_back(mw_dn_d2logdet.back());
440  }
441 
442  up_spo_leader.mw_evaluate_notranspose(up_spo_list, P_list, first, last, up_logdet_list, up_dlogdet_list,
443  up_d2logdet_list);
444  dn_spo_leader.mw_evaluate_notranspose(dn_spo_list, P_list, first, last, dn_logdet_list, dn_dlogdet_list,
445  dn_d2logdet_list);
446 
447  for (int iw = 0; iw < nw; iw++)
448  for (int iat = first; iat < last; iat++)
449  {
450  ParticleSet::Scalar_t s = P_list[iw].activeSpin(iat);
451  RealType coss = std::cos(s);
452  RealType sins = std::sin(s);
453  ValueType eis(coss, sins);
454  ValueType emis(coss, -sins);
455 
456  for (int no = 0; no < norb_requested; no++)
457  {
458  logdet_list[iw].get()(iat, no) =
459  eis * up_logdet_list[iw].get()(iat, no) + emis * dn_logdet_list[iw].get()(iat, no);
460  dlogdet_list[iw].get()(iat, no) =
461  eis * up_dlogdet_list[iw].get()(iat, no) + emis * dn_dlogdet_list[iw].get()(iat, no);
462  d2logdet_list[iw].get()(iat, no) =
463  eis * up_d2logdet_list[iw].get()(iat, no) + emis * dn_d2logdet_list[iw].get()(iat, no);
464  }
465  }
466 }
467 
469  int first,
470  int last,
471  ValueMatrix& logdet,
472  GradMatrix& dlogdet,
473  ValueMatrix& d2logdet,
474  ValueMatrix& dspinlogdet)
475 {
476  IndexType nelec = P.getTotalNum();
477 
478  const size_t norb_requested = logdet.cols();
479  logpsi_work_up.resize(nelec, norb_requested);
480  logpsi_work_down.resize(nelec, norb_requested);
481 
482  dlogpsi_work_up.resize(nelec, norb_requested);
483  dlogpsi_work_down.resize(nelec, norb_requested);
484 
485  d2logpsi_work_up.resize(nelec, norb_requested);
486  d2logpsi_work_down.resize(nelec, norb_requested);
487 
488  spo_up->evaluate_notranspose(P, first, last, logpsi_work_up, dlogpsi_work_up, d2logpsi_work_up);
489  spo_dn->evaluate_notranspose(P, first, last, logpsi_work_down, dlogpsi_work_down, d2logpsi_work_down);
490 
491 
492  for (int iat = 0; iat < nelec; iat++)
493  {
495 
496  RealType coss(0.0), sins(0.0);
497 
498  coss = std::cos(s);
499  sins = std::sin(s);
500 
501  ValueType eis(coss, sins);
502  ValueType emis(coss, -sins);
503  ValueType eye(0, 1.0);
504 
505  for (int no = 0; no < norb_requested; no++)
506  {
507  logdet(iat, no) = eis * logpsi_work_up(iat, no) + emis * logpsi_work_down(iat, no);
508  dlogdet(iat, no) = eis * dlogpsi_work_up(iat, no) + emis * dlogpsi_work_down(iat, no);
509  d2logdet(iat, no) = eis * d2logpsi_work_up(iat, no) + emis * d2logpsi_work_down(iat, no);
510  dspinlogdet(iat, no) = eye * (eis * logpsi_work_up(iat, no) - emis * logpsi_work_down(iat, no));
511  }
512  }
513 }
514 
515 
516 void SpinorSet::evaluate_spin(const ParticleSet& P, int iat, ValueVector& psi, ValueVector& dpsi)
517 {
518  const size_t norb_requested = psi.size();
519  psi_work_up.resize(norb_requested);
520  psi_work_down.resize(norb_requested);
521  psi_work_up = 0.0;
522  psi_work_down = 0.0;
523 
524  spo_up->evaluateValue(P, iat, psi_work_up);
525  spo_dn->evaluateValue(P, iat, psi_work_down);
526 
528 
529  RealType coss(0.0), sins(0.0);
530 
531  coss = std::cos(s);
532  sins = std::sin(s);
533 
534  ValueType eis(coss, sins);
535  ValueType emis(coss, -sins);
536  ValueType eye(0, 1.0);
537 
538  psi = eis * psi_work_up + emis * psi_work_down;
539  dpsi = eye * (eis * psi_work_up - emis * psi_work_down);
540 }
541 
543  int first,
544  int last,
545  const ParticleSet& source,
546  int iat_src,
547  GradMatrix& gradphi)
548 {
549  IndexType nelec = P.getTotalNum();
550 
551  const size_t norb_requested = gradphi.size();
552  GradMatrix gradphi_up(nelec, norb_requested);
553  GradMatrix gradphi_dn(nelec, norb_requested);
554  spo_up->evaluateGradSource(P, first, last, source, iat_src, gradphi_up);
555  spo_dn->evaluateGradSource(P, first, last, source, iat_src, gradphi_dn);
556 
557  for (int iat = first; iat < last; iat++)
558  {
560  RealType coss = std::cos(s);
561  RealType sins = std::sin(s);
562  ValueType eis(coss, sins);
563  ValueType emis(coss, -sins);
564  for (int imo = 0; imo < norb_requested; imo++)
565  gradphi(iat, imo) = gradphi_up(iat, imo) * eis + gradphi_dn(iat, imo) * emis;
566  }
567 }
568 
569 std::unique_ptr<SPOSet> SpinorSet::makeClone() const
570 {
571  auto myclone = std::make_unique<SpinorSet>(my_name_);
572  std::unique_ptr<SPOSet> cloneup(spo_up->makeClone());
573  std::unique_ptr<SPOSet> clonedn(spo_dn->makeClone());
574  myclone->set_spos(std::move(cloneup), std::move(clonedn));
575  return myclone;
576 }
577 
579 {
580  spo_up->createResource(collection);
581  spo_dn->createResource(collection);
582  auto index = collection.addResource(std::make_unique<SpinorSetMultiWalkerResource>());
583 }
584 
586 {
587  auto [up_spo_list, dn_spo_list] = extractSpinComponentRefList(spo_list);
588  auto& spo_leader = spo_list.getCastedLeader<SpinorSet>();
589  auto& up_spo_leader = up_spo_list.getLeader();
590  auto& dn_spo_leader = dn_spo_list.getLeader();
591  up_spo_leader.acquireResource(collection, up_spo_list);
592  dn_spo_leader.acquireResource(collection, dn_spo_list);
593  spo_leader.mw_res_handle_ = collection.lendResource<SpinorSetMultiWalkerResource>();
594 }
595 
597 {
598  auto [up_spo_list, dn_spo_list] = extractSpinComponentRefList(spo_list);
599  auto& spo_leader = spo_list.getCastedLeader<SpinorSet>();
600  auto& up_spo_leader = up_spo_list.getLeader();
601  auto& dn_spo_leader = dn_spo_list.getLeader();
602  up_spo_leader.releaseResource(collection, up_spo_list);
603  dn_spo_leader.releaseResource(collection, dn_spo_list);
604  collection.takebackResource(spo_leader.mw_res_handle_);
605 }
606 
608  const RefVectorWithLeader<SPOSet>& spo_list) const
609 {
610  auto& spo_leader = spo_list.getCastedLeader<SpinorSet>();
611  IndexType nw = spo_list.size();
612  SPOSet& up_spo_leader = *(spo_leader.spo_up);
613  SPOSet& dn_spo_leader = *(spo_leader.spo_dn);
614  RefVectorWithLeader<SPOSet> up_spo_list(up_spo_leader);
615  RefVectorWithLeader<SPOSet> dn_spo_list(dn_spo_leader);
616  up_spo_list.reserve(nw);
617  dn_spo_list.reserve(nw);
618  for (int iw = 0; iw < nw; iw++)
619  {
620  SpinorSet& spinor = spo_list.getCastedElement<SpinorSet>(iw);
621  up_spo_list.emplace_back(*(spinor.spo_up));
622  dn_spo_list.emplace_back(*(spinor.spo_dn));
623  }
624  return std::make_pair(up_spo_list, dn_spo_list);
625 }
626 
627 } // namespace qmcplusplus
std::pair< RefVectorWithLeader< SPOSet >, RefVectorWithLeader< SPOSet > > extractSpinComponentRefList(const RefVectorWithLeader< SPOSet > &spo_list) const
Definition: SpinorSet.cpp:607
base class for Single-particle orbital sets
Definition: SPOSet.h:46
std::unique_ptr< SPOSet > makeClone() const override
make a clone of itself every derived class must implement this to have threading working correctly...
Definition: SpinorSet.cpp:569
Class for Melton & Mitas style Spinors.
Definition: SpinorSet.h:24
void evaluateVGL_spin(const ParticleSet &P, int iat, ValueVector &psi, GradVector &dpsi, ValueVector &d2psi, ValueVector &dspin) override
evaluate the values, gradients and laplacians of this single-particle orbital set ...
Definition: SpinorSet.cpp:153
void createResource(ResourceCollection &collection) const override
initialize a shared resource and hand it to collection
Definition: SpinorSet.cpp:578
ValueVector psi_work_up
Definition: SpinorSet.h:204
size_t addResource(std::unique_ptr< Resource > &&res, bool noprint=false)
void takebackResource(ResourceHandle< RS > &res_handle)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
const std::string my_name_
name of the object, unique identifier
Definition: SPOSet.h:564
void evaluate_spin(const ParticleSet &P, int iat, ValueVector &psi, ValueVector &dpsi) override
Evaluate the values, spin gradients, and spin laplacians of single particle spinors corresponding to ...
Definition: SpinorSet.cpp:516
T dot(const T *restrict a, const T *restrict b, int n, TRES res=TRES())
dot product
QTBase::RealType RealType
Definition: Configuration.h:58
void storeParamsBeforeRotation() override
store parameters before getting destroyed by rotation.
Definition: SpinorSet.cpp:34
ValueMatrix logpsi_work_up
Definition: SpinorSet.h:216
void setOrbitalSetSize(int norbs) override
set the OrbitalSetSize
Definition: SpinorSet.cpp:61
void mw_evaluateVGLandDetRatioGradsWithSpin(const RefVectorWithLeader< SPOSet > &spo_list, const RefVectorWithLeader< ParticleSet > &P_list, int iat, const std::vector< const ValueType *> &invRow_ptr_list, OffloadMWVGLArray &phi_vgl_v, std::vector< ValueType > &ratios, std::vector< GradType > &grads, std::vector< ValueType > &spingrads) const override
evaluate the values, gradients and laplacians of this single-particle orbital sets and determinant ra...
Definition: SpinorSet.cpp:258
void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< SPOSet > &spo_list) const override
return a shared resource to collection
Definition: SpinorSet.cpp:596
size_t getTotalNum() const
Definition: ParticleSet.h:493
MakeReturn< UnaryNode< FnSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sin(const Vector< T1, C1 > &l)
ValueVector d2psi_work_down
Definition: SpinorSet.h:213
Type_t * data()
Definition: OhmmsArray.h:87
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
std::unique_ptr< SPOSet > spo_up
Definition: SpinorSet.h:200
GradVector dpsi_work_up
Definition: SpinorSet.h:208
OrbitalSetTraits< ValueType >::ValueMatrix ValueMatrix
Definition: SPOSet.h:50
void evaluate_notranspose(const ParticleSet &P, int first, int last, ValueMatrix &logdet, GradMatrix &dlogdet, ValueMatrix &d2logdet) override
evaluate the values, gradients and laplacians of this single-particle orbital for [first...
Definition: SpinorSet.cpp:337
int size() const
return the size of the orbital set Ye: this needs to be replaced by getOrbitalSetSize(); ...
Definition: SPOSet.h:75
ValueVector d2psi_work_up
Definition: SpinorSet.h:212
void mw_evaluate_notranspose(const RefVectorWithLeader< SPOSet > &spo_list, const RefVectorWithLeader< ParticleSet > &P_list, int first, int last, const RefVector< ValueMatrix > &logdet_list, const RefVector< GradMatrix > &dlogdet_list, const RefVector< ValueMatrix > &d2logdet_list) const override
Definition: SpinorSet.cpp:382
void evaluateVGL(const ParticleSet &P, int iat, ValueVector &psi, GradVector &dpsi, ValueVector &d2psi) override
evaluate the values, gradients and laplacians of this single-particle orbital set ...
Definition: SpinorSet.cpp:119
void evaluateValue(const ParticleSet &P, int iat, ValueVector &psi) override
evaluate the values of this spinor set
Definition: SpinorSet.cpp:64
void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< SPOSet > &spo_list) const override
acquire a shared resource from collection
Definition: SpinorSet.cpp:585
const Scalar_t & activeSpin(int iat) const
return the active spin value if the particle is active or return the current spin value if not ...
Definition: ParticleSet.h:272
size_type cols() const
Definition: OhmmsMatrix.h:78
OrbitalSetTraits< ValueType >::GradMatrix GradMatrix
Definition: SPOSet.h:52
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
std::unique_ptr< Resource > makeClone() const override
Definition: SpinorSet.cpp:24
void updateTo(size_type size=0, std::ptrdiff_t offset=0)
Definition: OhmmsMatrix.h:371
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
QTBase::ValueType ValueType
Definition: Configuration.h:60
ValueMatrix d2logpsi_work_up
Definition: SpinorSet.h:222
GradMatrix dlogpsi_work_down
Definition: SpinorSet.h:220
void applyRotation(const ValueMatrix &rot_mat, bool use_stored_copy) override
apply rotation to all the orbitals
Definition: SpinorSet.cpp:40
OrbitalSetTraits< ValueType >::ValueVector ValueVector
Definition: SPOSet.h:49
CASTTYPE & getCastedElement(size_t i) const
SpinorSet(const std::string &my_name)
constructor
Definition: SpinorSet.cpp:31
size_t size() const
Definition: OhmmsArray.h:57
IndexType OrbitalSetSize
number of Single-particle orbitals
Definition: SPOSet.h:566
std::unique_ptr< SPOSet > spo_dn
Definition: SpinorSet.h:201
ValueMatrix logpsi_work_down
Definition: SpinorSet.h:217
GradMatrix dlogpsi_work_up
Definition: SpinorSet.h:219
OHMMS_INDEXTYPE IndexType
define other types
Definition: Configuration.h:65
std::vector< std::reference_wrapper< T > > RefVector
virtual void evaluateGradSource(const ParticleSet &P, int first, int last, const ParticleSet &source, int iat_src, GradMatrix &gradphi) override
evaluate the gradients of this single-particle orbital for [first,last) target particles with respect...
Definition: SpinorSet.cpp:542
void mw_evaluateVGLWithSpin(const RefVectorWithLeader< SPOSet > &spo_list, const RefVectorWithLeader< ParticleSet > &P_list, int iat, const RefVector< ValueVector > &psi_v_list, const RefVector< GradVector > &dpsi_v_list, const RefVector< ValueVector > &d2psi_v_list, OffloadMatrix< ComplexType > &mw_dspin) const override
evaluate the values, gradients and laplacians and spin gradient of this single-particle orbital sets ...
Definition: SpinorSet.cpp:194
SpinorSetMultiWalkerResource(const SpinorSetMultiWalkerResource &)
Definition: SpinorSet.cpp:23
void sincos(T a, T *restrict s, T *restrict c)
sincos function wrapper
Definition: math.hpp:62
GradVector dpsi_work_down
Definition: SpinorSet.h:209
handle math function mapping inside OpenMP offload regions.
void evaluateDetSpinorRatios(const VirtualParticleSet &VP, ValueVector &psi, const std::pair< ValueVector, ValueVector > &spinor_multipler, const ValueVector &invrow, std::vector< ValueType > &ratios) override
evaluate determinant ratios for virtual moves, specifically for Spinor SPOSets
Definition: SpinorSet.cpp:89
ResourceHandle< RS > lendResource()
void set_spos(std::unique_ptr< SPOSet > &&up, std::unique_ptr< SPOSet > &&dn)
Definition: SpinorSet.cpp:46
ValueVector psi_work_down
Definition: SpinorSet.h:205
A D-dimensional Array class based on PETE.
Definition: OhmmsArray.h:25
void evaluate_notranspose_spin(const ParticleSet &P, int first, int last, ValueMatrix &logdet, GradMatrix &dlogdet, ValueMatrix &d2logdet, ValueMatrix &dspinlogdet) override
evaluate the values, gradients and laplacians of this single-particle orbital for [first...
Definition: SpinorSet.cpp:468
ValueMatrix d2logpsi_work_down
Definition: SpinorSet.h:223