QMCPACK
Backflow_ee.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: Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
13 //////////////////////////////////////////////////////////////////////////////////////
14 
15 
16 #ifndef QMCPLUSPLUS_BACKFLOW_E_E_H
17 #define QMCPLUSPLUS_BACKFLOW_E_E_H
20 #include "Message/Communicate.h"
21 #include <cmath>
22 
23 namespace qmcplusplus
24 {
25 template<class FT>
27 {
28 private:
29  /// distance table index
30  const int myTableIndex_;
31 
32 public:
33  //number of groups of the target particleset
34  std::vector<FT*> RadFun;
35  std::vector<std::unique_ptr<FT>> uniqueRadFun;
36  std::vector<int> offsetPrms;
37  int NumGroups;
39  bool first;
40 
42  : BackflowFunctionBase(ions, els),
44  first(true)
45  {
47  NumGroups = els.groups();
49  for (int i = 0; i < NumTargets; ++i)
50  for (int j = 0; j < NumTargets; ++j)
51  PairID(i, j) = els.GroupID[i] * NumGroups + els.GroupID[j];
52  RadFun.resize(NumGroups * NumGroups, 0);
53  offsetPrms.resize(NumGroups * NumGroups, 0);
54  }
55 
56  std::unique_ptr<BackflowFunctionBase> makeClone(ParticleSet& tqp) const override
57  {
58  auto clone = std::make_unique<Backflow_ee<FT>>(tqp, tqp);
59  clone->first = false;
60  clone->resize(NumTargets, NumTargets);
61  clone->offsetPrms = offsetPrms;
62  clone->numParams = numParams;
63  clone->derivs = derivs;
64  clone->offsetPrms = offsetPrms;
65  clone->uniqueRadFun.resize(uniqueRadFun.size());
66  clone->RadFun.resize(RadFun.size());
67  for (int i = 0; i < uniqueRadFun.size(); i++)
68  clone->uniqueRadFun[i] = std::make_unique<FT>(*(uniqueRadFun[i]));
69  for (int i = 0; i < RadFun.size(); i++)
70  {
71  bool done = false;
72  for (int k = 0; k < uniqueRadFun.size(); k++)
73  if (RadFun[i] == uniqueRadFun[k].get())
74  {
75  done = true;
76  clone->RadFun[i] = clone->uniqueRadFun[k].get();
77  break;
78  }
79  if (!done)
80  {
81  APP_ABORT("Error cloning Backflow_ee object. \n");
82  }
83  }
84  return clone;
85  }
86 
87  void addFunc(int ia, int ib, std::unique_ptr<FT> rf)
88  {
89  if (first)
90  {
91  // initialize all with rf the first time
92  for (int i = 0; i < RadFun.size(); i++)
93  RadFun[i] = rf.get();
94  first = false;
95  }
96  else
97  {
98  RadFun[ia * NumGroups + ib] = rf.get();
99  RadFun[ib * NumGroups + ia] = rf.get();
100  }
101  uniqueRadFun.push_back(std::move(rf));
102  }
103 
104  void registerData(WFBufferType& buf) override
105  {
106  FirstOfU = &(UIJ(0, 0)[0]);
108  FirstOfA = &(AIJ(0, 0)[0]);
110  FirstOfB = &(BIJ(0, 0)[0]);
112  buf.add(FirstOfU, LastOfU);
113  buf.add(FirstOfA, LastOfA);
114  buf.add(FirstOfB, LastOfB);
115  }
116 
117  void reportStatus(std::ostream& os) override
118  {
119  for (int i = 0; i < uniqueRadFun.size(); i++)
120  uniqueRadFun[i]->reportStatus(os);
121  }
122 
123  void resetParameters(const opt_variables_type& active) override
124  {
125  for (int i = 0; i < uniqueRadFun.size(); i++)
126  uniqueRadFun[i]->resetParametersExclusive(active);
127  }
128 
129  void checkInVariables(opt_variables_type& active) override
130  {
131  for (int i = 0; i < uniqueRadFun.size(); i++)
132  uniqueRadFun[i]->checkInVariablesExclusive(active);
133  }
134 
135  void checkOutVariables(const opt_variables_type& active) override
136  {
137  for (int i = 0; i < uniqueRadFun.size(); i++)
138  uniqueRadFun[i]->checkOutVariables(active);
139  }
140 
141  inline bool isOptimizable() override
142  {
143  for (int i = 0; i < uniqueRadFun.size(); i++)
144  if (uniqueRadFun[i]->isOptimizable())
145  return true;
146  return false;
147  }
148 
149  inline int indexOffset() override { return RadFun[0]->myVars.where(0); }
150 
151  inline void acceptMove(int iat, int UpdateMode) override
152  {
153  int num;
154  switch (UpdateMode)
155  {
156  case ORB_PBYP_RATIO:
157  num = UIJ.rows();
158  for (int i = 0; i < num; i++)
159  {
160  UIJ(iat, i) = UIJ_temp[i];
161  UIJ(i, iat) = -1.0 * UIJ_temp[i];
162  }
163  break;
164  case ORB_PBYP_PARTIAL:
165  num = UIJ.rows();
166  for (int i = 0; i < num; i++)
167  {
168  UIJ(iat, i) = UIJ_temp[i];
169  UIJ(i, iat) = -1.0 * UIJ_temp[i];
170  }
171  num = AIJ.rows();
172  for (int i = 0; i < num; i++)
173  {
174  AIJ(iat, i) = AIJ_temp[i];
175  AIJ(i, iat) = AIJ_temp[i];
176  }
177  break;
178  case ORB_PBYP_ALL:
179  num = UIJ.rows();
180  for (int i = 0; i < num; i++)
181  {
182  UIJ(iat, i) = UIJ_temp[i];
183  UIJ(i, iat) = -1.0 * UIJ_temp[i];
184  }
185  num = AIJ.rows();
186  for (int i = 0; i < num; i++)
187  {
188  AIJ(iat, i) = AIJ_temp[i];
189  AIJ(i, iat) = AIJ_temp[i];
190  }
191  num = BIJ.rows();
192  for (int i = 0; i < num; i++)
193  {
194  BIJ(iat, i) = BIJ_temp[i];
195  BIJ(i, iat) = -1.0 * BIJ_temp[i];
196  }
197  break;
198  default:
199  num = UIJ.rows();
200  for (int i = 0; i < num; i++)
201  {
202  UIJ(iat, i) = UIJ_temp[i];
203  UIJ(i, iat) = -1.0 * UIJ_temp[i];
204  }
205  num = AIJ.rows();
206  for (int i = 0; i < num; i++)
207  {
208  AIJ(iat, i) = AIJ_temp[i];
209  AIJ(i, iat) = AIJ_temp[i];
210  }
211  num = BIJ.rows();
212  for (int i = 0; i < num; i++)
213  {
214  BIJ(iat, i) = BIJ_temp[i];
215  BIJ(i, iat) = -1.0 * BIJ_temp[i];
216  }
217  break;
218  }
219  UIJ_temp = 0.0;
220  AIJ_temp = 0.0;
221  BIJ_temp = 0.0;
222  }
223 
224  inline void restore(int iat, int UpdateType) override
225  {
226  UIJ_temp = 0.0;
227  AIJ_temp = 0.0;
228  BIJ_temp = 0.0;
229  }
230 
231  /** calculate quasi-particle coordinates only
232  */
233  inline void evaluate(const ParticleSet& P, ParticleSet& QP) override
234  {
235  APP_ABORT("Backflow_ee.h::evaluate(P,QP) not implemented for SoA\n");
236  //RealType du, d2u;
237  //const auto& myTable = P.getDistTableAA(myTableIndex_);
238  //for (int i = 0; i < myTable.sources(); i++)
239  //{
240  // for (int nn = myTable.M[i]; nn < myTable.M[i + 1]; nn++)
241  // {
242  // int j = myTable.J[nn];
243  // RealType uij = RadFun[PairID(i, j)]->evaluate(myTable.r(nn), du, d2u);
244  // PosType u = uij * myTable.dr(nn);
245  // QP.R[i] -= u; // dr(ij) = r_j-r_i
246  // QP.R[j] += u;
247  // UIJ(j, i) = u;
248  // UIJ(i, j) = -1.0 * u;
249  // }
250  //}
251  }
252 
253  inline void evaluate(const ParticleSet& P, ParticleSet& QP, GradVector& Bmat, HessMatrix& Amat)
254  {
255  APP_ABORT("This shouldn't be called: Backflow_ee::evaluate(Bmat)");
256  PosType du, d2u, temp;
257  APP_ABORT("Backflow_ee.h::evaluate(P,QP,Bmat_vec,Amat) not implemented for SoA\n");
258  // const auto& myTable = P.getDistTableAA(myTableIndex_);
259  // for (int i = 0; i < myTable.sources(); i++)
260  // {
261  // for (int nn = myTable.M[i]; nn < myTable.M[i + 1]; nn++)
262  // {
263  // int j = myTable.J[nn];
264  // RealType uij = RadFun[PairID(i, j)]->evaluate(myTable.r(nn), du, d2u);
265  // PosType u = uij * myTable.dr(nn);
266  // // UIJ = eta(r) * (r_i - r_j)
267  // UIJ(j, i) = u;
268  // UIJ(i, j) = -1.0 * u;
269  // du *= myTable.rinv(nn);
270  // QP.R[i] -= u;
271  // QP.R[j] += u;
272  //// Amat(i,j) -= du*(outerProduct(myTable.dr(nn),myTable.dr(nn)));
273  //#if OHMMS_DIM == 3
274  // Amat(i, j)[0] -= uij;
275  // Amat(i, j)[4] -= uij;
276  // Amat(i, j)[8] -= uij;
277  //#elif OHMMS_DIM == 2
278  // Amat(i, j)[0] -= uij;
279  // Amat(i, j)[3] -= uij;
280  //#endif
281  // Amat(j, i) += Amat(i, j);
282  // Amat(i, i) -= Amat(i, j);
283  // Amat(j, j) -= Amat(i, j);
284  // // this will create problems with QMC_COMPLEX, because Bmat is ValueType and dr is RealType
285  // u = 2.0 * (d2u + (OHMMS_DIM + 1.0) * du) * myTable.dr(nn);
286  // Bmat[i] -= u;
287  // Bmat[j] += u;
288  // }
289  // }
290  }
291 
292 
293  /** calculate quasi-particle coordinates, Bmat and Amat
294  */
295  inline void evaluate(const ParticleSet& P, ParticleSet& QP, GradMatrix& Bmat_full, HessMatrix& Amat) override
296  {
297  RealType du, d2u;
298  const auto& myTable = P.getDistTableAA(myTableIndex_);
299  for (int ig = 0; ig < NumGroups; ++ig)
300  {
301  for (int iat = P.first(ig), last = P.last(ig); iat < last; ++iat)
302  {
303  const auto& dist = myTable.getDistRow(iat);
304  const auto& displ = myTable.getDisplRow(iat);
305  for (int jat = 0; jat < iat; ++jat)
306  {
307  if (dist[jat] > 0)
308  {
309  RealType uij = RadFun[PairID(iat, jat)]->evaluate(dist[jat], du, d2u);
310  du /= dist[jat];
311  PosType u = uij * displ[jat];
312  UIJ(jat, iat) = u;
313  UIJ(iat, jat) = -1.0 * u;
314  QP.R[iat] -= u;
315  QP.R[jat] += u;
316  HessType& hess = AIJ(iat, jat);
317  hess = du * outerProduct(displ[jat], displ[jat]);
318 #if OHMMS_DIM == 3
319  hess[0] += uij;
320  hess[4] += uij;
321  hess[8] += uij;
322 #elif OHMMS_DIM == 2
323  hess[0] += uij;
324  hess[3] += uij;
325 #endif
326  AIJ(jat, iat) = hess;
327  Amat(iat, iat) += hess;
328  Amat(jat, jat) += hess;
329  Amat(iat, jat) -= hess;
330  Amat(jat, iat) -= hess;
331  GradType& grad = BIJ(jat, iat); // dr = r_j - r_i
332  grad = (d2u + (OHMMS_DIM + 1) * du) * displ[jat];
333  BIJ(iat, jat) = -1.0 * grad;
334  Bmat_full(iat, iat) -= grad;
335  Bmat_full(jat, jat) += grad;
336  Bmat_full(iat, jat) += grad;
337  Bmat_full(jat, iat) -= grad;
338  }
339  }
340  }
341  }
342  }
343 
344  /** calculate quasi-particle coordinates after pbyp move
345  */
346  inline void evaluatePbyP(const ParticleSet& P,
348  const std::vector<int>& index) override
349  {
350  APP_ABORT("Backflow_ee.h::evaluatePbyP(P,QP,index_vec) not implemented for SoA\n");
351  //RealType du, d2u;
352  //const auto& myTable = P.getDistTableAA(myTableIndex_);
353  //int maxI = index.size();
354  //int iat = index[0];
355  //for (int i = 1; i < maxI; i++)
356  //{
357  // int j = index[i];
358  // RealType uij = RadFun[PairID(iat, j)]->evaluate(myTable.Temp[j].r1, du, d2u);
359  // PosType u = (UIJ_temp[j] = uij * myTable.Temp[j].dr1) - UIJ(iat, j);
360  // newQP[iat] += u;
361  // newQP[j] -= u;
362  //}
363  }
364 
365  /** calculate quasi-particle coordinates after pbyp move
366  */
367  inline void evaluatePbyP(const ParticleSet& P, int iat, ParticleSet::ParticlePos& newQP) override
368  {
369  RealType du, d2u;
370  const auto& myTable = P.getDistTableAA(myTableIndex_);
371  for (int i = 0; i < iat; i++)
372  {
373  // Temp[j].dr1 = (ri - rj)
374  RealType uij = RadFun[PairID(iat, i)]->evaluate(myTable.getTempDists()[i], du, d2u);
375  PosType u = (UIJ_temp[i] = -uij * myTable.getTempDispls()[i]) - UIJ(iat, i);
376  newQP[iat] += u;
377  newQP[i] -= u;
378  }
379  for (int i = iat + 1; i < NumTargets; i++)
380  {
381  // Temp[j].dr1 = (ri - rj)
382  RealType uij = RadFun[PairID(iat, i)]->evaluate(myTable.getTempDists()[i], du, d2u);
383  PosType u = (UIJ_temp[i] = -uij * myTable.getTempDispls()[i]) - UIJ(iat, i);
384  newQP[iat] += u;
385  newQP[i] -= u;
386  }
387  }
388 
389  /** calculate quasi-particle coordinates and Amat after pbyp move
390  */
391  inline void evaluatePbyP(const ParticleSet& P,
393  const std::vector<int>& index,
394  HessMatrix& Amat) override
395  {
396  APP_ABORT("Backflow_ee.h::evaluatePbyP(P,QP,index_vec,Amat) not implemented for SoA\n");
397  // RealType du, d2u;
398  // const auto& myTable = P.getDistTableAA(myTableIndex_);
399  // int maxI = index.size();
400  // int iat = index[0];
401  // for (int i = 1; i < maxI; i++)
402  // {
403  // int j = index[i];
404  // RealType uij = RadFun[PairID(iat, j)]->evaluate(myTable.Temp[j].r1, du, d2u);
405  // PosType u = (UIJ_temp[j] = uij * myTable.Temp[j].dr1) - UIJ(iat, j);
406  // newQP[iat] += u;
407  // newQP[j] -= u;
408  // HessType& hess = AIJ_temp[j];
409  // hess = (du * myTable.Temp[j].rinv1) * outerProduct(myTable.Temp[j].dr1, myTable.Temp[j].dr1);
410  //#if OHMMS_DIM == 3
411  // hess[0] += uij;
412  // hess[4] += uij;
413  // hess[8] += uij;
414  //#elif OHMMS_DIM == 2
415  // hess[0] += uij;
416  // hess[3] += uij;
417  //#endif
418  // HessType dA = hess - AIJ(iat, j);
419  // Amat(iat, iat) += dA;
420  // Amat(j, j) += dA;
421  // Amat(iat, j) -= dA;
422  // Amat(j, iat) -= dA;
423  // }
424  }
425 
426  /** calculate quasi-particle coordinates and Amat after pbyp move
427  */
428  inline void evaluatePbyP(const ParticleSet& P, int iat, ParticleSet::ParticlePos& newQP, HessMatrix& Amat) override
429  {
430  RealType du, d2u;
431  const auto& myTable = P.getDistTableAA(myTableIndex_);
432  for (int j = 0; j < iat; j++)
433  {
434  if (myTable.getTempDists()[j] > 0)
435  {
436  RealType uij = RadFun[PairID(iat, j)]->evaluate(myTable.getTempDists()[j], du, d2u);
437  PosType u = (UIJ_temp[j] = -uij * myTable.getTempDispls()[j]) - UIJ(iat, j);
438  newQP[iat] += u;
439  newQP[j] -= u;
440  HessType& hess = AIJ_temp[j];
441  hess = (du / myTable.getTempDists()[j]) * outerProduct(myTable.getTempDispls()[j], myTable.getTempDispls()[j]);
442 #if OHMMS_DIM == 3
443  hess[0] += uij;
444  hess[4] += uij;
445  hess[8] += uij;
446 #elif OHMMS_DIM == 2
447  hess[0] += uij;
448  hess[3] += uij;
449 #endif
450  HessType dA = hess - AIJ(iat, j);
451  Amat(iat, iat) += dA;
452  Amat(j, j) += dA;
453  Amat(iat, j) -= dA;
454  Amat(j, iat) -= dA;
455  }
456  }
457  for (int j = iat + 1; j < NumTargets; j++)
458  {
459  if (myTable.getTempDists()[j] > 0)
460  {
461  RealType uij = RadFun[PairID(iat, j)]->evaluate(myTable.getTempDists()[j], du, d2u);
462  PosType u = (UIJ_temp[j] = -uij * myTable.getTempDispls()[j]) - UIJ(iat, j);
463  newQP[iat] += u;
464  newQP[j] -= u;
465  HessType& hess = AIJ_temp[j];
466  hess = (du / myTable.getTempDists()[j]) * outerProduct(myTable.getTempDispls()[j], myTable.getTempDispls()[j]);
467 #if OHMMS_DIM == 3
468  hess[0] += uij;
469  hess[4] += uij;
470  hess[8] += uij;
471 #elif OHMMS_DIM == 2
472  hess[0] += uij;
473  hess[3] += uij;
474 #endif
475  HessType dA = hess - AIJ(iat, j);
476  Amat(iat, iat) += dA;
477  Amat(j, j) += dA;
478  Amat(iat, j) -= dA;
479  Amat(j, iat) -= dA;
480  }
481  }
482  }
483 
484  /** calculate quasi-particle coordinates and Amat after pbyp move
485  */
486  inline void evaluatePbyP(const ParticleSet& P,
488  const std::vector<int>& index,
489  GradMatrix& Bmat,
490  HessMatrix& Amat) override
491  {
492  APP_ABORT("Backflow_ee.h::evaluatePbyP(P,QP,index_vec,Bmat,Amat) not implemented for SoA\n");
493  // RealType du, d2u;
494  // const auto& myTable = P.getDistTableAA(myTableIndex_);
495  // int maxI = index.size();
496  // int iat = index[0];
497  // const std::vector<DistanceTable::TempDistType>& TMP = myTable.Temp;
498  // for (int i = 1; i < maxI; i++)
499  // {
500  // int j = index[i];
501  // RealType uij = RadFun[PairID(iat, j)]->evaluate(TMP[j].r1, du, d2u);
502  // PosType u = (UIJ_temp[j] = uij * TMP[j].dr1) - UIJ(iat, j);
503  // newQP[iat] += u;
504  // newQP[j] -= u;
505  // du *= TMP[j].rinv1;
506  // HessType& hess = AIJ_temp[j];
507  // hess = du * outerProduct(TMP[j].dr1, TMP[j].dr1);
508  //#if OHMMS_DIM == 3
509  // hess[0] += uij;
510  // hess[4] += uij;
511  // hess[8] += uij;
512  //#elif OHMMS_DIM == 2
513  // hess[0] += uij;
514  // hess[3] += uij;
515  //#endif
516  // HessType dA = hess - AIJ(iat, j);
517  // Amat(iat, iat) += dA;
518  // Amat(j, j) += dA;
519  // Amat(iat, j) -= dA;
520  // Amat(j, iat) -= dA;
521  // GradType& grad = BIJ_temp[j]; // dr = r_iat - r_j
522  // grad = (d2u + (OHMMS_DIM + 1) * du) * TMP[j].dr1;
523  // GradType dg = grad - BIJ(iat, j);
524  // Bmat(iat, iat) += dg;
525  // Bmat(j, j) -= dg;
526  // Bmat(iat, j) -= dg;
527  // Bmat(j, iat) += dg;
528  // }
529  }
530 
531  /** calculate quasi-particle coordinates and Amat after pbyp move
532  */
533  inline void evaluatePbyP(const ParticleSet& P,
534  int iat,
536  GradMatrix& Bmat,
537  HessMatrix& Amat) override
538  {
539  APP_ABORT("Backflow_ee.h::evaluatePbyP(P,iat,QP,Bmat,Amat) not implemented for SoA\n");
540  // RealType du, d2u;
541  // const auto& myTable = P.getDistTableAA(myTableIndex_);
542  // const std::vector<DistanceTable::TempDistType>& TMP = myTable.Temp;
543  // for (int j = 0; j < iat; j++)
544  // {
545  // RealType uij = RadFun[PairID(iat, j)]->evaluate(TMP[j].r1, du, d2u);
546  // PosType u = (UIJ_temp[j] = uij * TMP[j].dr1) - UIJ(iat, j);
547  // newQP[iat] += u;
548  // newQP[j] -= u;
549  // du *= TMP[j].rinv1;
550  // HessType& hess = AIJ_temp[j];
551  // hess = du * outerProduct(TMP[j].dr1, TMP[j].dr1);
552  //#if OHMMS_DIM == 3
553  // hess[0] += uij;
554  // hess[4] += uij;
555  // hess[8] += uij;
556  //#elif OHMMS_DIM == 2
557  // hess[0] += uij;
558  // hess[3] += uij;
559  //#endif
560  // HessType dA = hess - AIJ(iat, j);
561  // Amat(iat, iat) += dA;
562  // Amat(j, j) += dA;
563  // Amat(iat, j) -= dA;
564  // Amat(j, iat) -= dA;
565  // GradType& grad = BIJ_temp[j]; // dr = r_iat - r_j
566  // grad = (d2u + (OHMMS_DIM + 1) * du) * TMP[j].dr1;
567  // GradType dg = grad - BIJ(iat, j);
568  // Bmat(iat, iat) += dg;
569  // Bmat(j, j) -= dg;
570  // Bmat(iat, j) -= dg;
571  // Bmat(j, iat) += dg;
572  // }
573  // for (int j = iat + 1; j < NumTargets; j++)
574  // {
575  // RealType uij = RadFun[PairID(iat, j)]->evaluate(TMP[j].r1, du, d2u);
576  // PosType u = (UIJ_temp[j] = uij * TMP[j].dr1) - UIJ(iat, j);
577  // newQP[iat] += u;
578  // newQP[j] -= u;
579  // du *= TMP[j].rinv1;
580  // HessType& hess = AIJ_temp[j];
581  // hess = du * outerProduct(TMP[j].dr1, TMP[j].dr1);
582  //#if OHMMS_DIM == 3
583  // hess[0] += uij;
584  // hess[4] += uij;
585  // hess[8] += uij;
586  //#elif OHMMS_DIM == 2
587  // hess[0] += uij;
588  // hess[3] += uij;
589  //#endif
590  // HessType dA = hess - AIJ(iat, j);
591  // Amat(iat, iat) += dA;
592  // Amat(j, j) += dA;
593  // Amat(iat, j) -= dA;
594  // Amat(j, iat) -= dA;
595  // GradType& grad = BIJ_temp[j]; // dr = r_iat - r_j
596  // grad = (d2u + (OHMMS_DIM + 1) * du) * TMP[j].dr1;
597  // GradType dg = grad - BIJ(iat, j);
598  // Bmat(iat, iat) += dg;
599  // Bmat(j, j) -= dg;
600  // Bmat(iat, j) -= dg;
601  // Bmat(j, iat) += dg;
602  // }
603  }
604 
605  /** calculate only Bmat
606  * This is used in pbyp moves, in updateBuffer()
607  */
608  inline void evaluateBmatOnly(const ParticleSet& P, GradMatrix& Bmat_full) override
609  {
610  APP_ABORT("Backflow_ee.h::evaluateBmatOnly(P,QP,Bmat_full) not implemented for SoA\n");
611  //RealType du, d2u;
612  //const auto& myTable = P.getDistTableAA(myTableIndex_);
613  //for (int i = 0; i < myTable.sources(); i++)
614  //{
615  // for (int nn = myTable.M[i]; nn < myTable.M[i + 1]; nn++)
616  // {
617  // int j = myTable.J[nn];
618  // RealType uij = RadFun[PairID(i, j)]->evaluate(myTable.r(nn), du, d2u);
619  // PosType u = (d2u + (OHMMS_DIM + 1) * du * myTable.rinv(nn)) * myTable.dr(nn);
620  // Bmat_full(i, i) -= u;
621  // Bmat_full(j, j) += u;
622  // Bmat_full(i, j) += u;
623  // Bmat_full(j, i) -= u;
624  // }
625  //}
626  }
627 
628  /** calculate quasi-particle coordinates, Bmat and Amat
629  * calculate derivatives wrt to variational parameters
630  */
631  inline void evaluateWithDerivatives(const ParticleSet& P,
632  ParticleSet& QP,
633  GradMatrix& Bmat_full,
634  HessMatrix& Amat,
635  GradMatrix& Cmat,
636  GradMatrix& Ymat,
637  HessArray& Xmat) override
638  {
639  RealType du, d2u;
640  const auto& myTable = P.getDistTableAA(myTableIndex_);
641  for (int ig = 0; ig < NumGroups; ++ig)
642  {
643  for (int iat = P.first(ig), last = P.last(ig); iat < last; ++iat)
644  {
645  const auto& dist = myTable.getDistRow(iat);
646  const auto& displ = myTable.getDisplRow(iat);
647  for (int jat = 0; jat < iat; ++jat)
648  {
649  if (dist[jat] > 0)
650  {
651  RealType uij = RadFun[PairID(iat, jat)]->evaluate(dist[jat], du, d2u);
652  //for(int q=0; q<derivs.size(); q++) derivs[q]=0.0; // I believe this is necessary
653  // std::fill(derivs.begin(),derivs.end(),0.0);
654  int numParamJU = RadFun[PairID(iat, jat)]->NumParams;
655  std::vector<TinyVector<RealType, 3>> derivsju(numParamJU);
656  RadFun[PairID(iat, jat)]->evaluateDerivatives(dist[jat], derivsju);
657  du /= dist[jat];
658  PosType u = uij * displ[jat];
659  UIJ(jat, iat) = u;
660  UIJ(iat, jat) = -1.0 * u;
661  QP.R[iat] -= u;
662  QP.R[jat] += u;
663  HessType op = outerProduct(displ[jat], displ[jat]);
664  HessType& hess = AIJ(iat, jat);
665  hess = du * op;
666 #if OHMMS_DIM == 3
667  hess[0] += uij;
668  hess[4] += uij;
669  hess[8] += uij;
670 #elif OHMMS_DIM == 2
671  hess[0] += uij;
672  hess[3] += uij;
673 #endif
674  Amat(iat, iat) += hess;
675  Amat(jat, jat) += hess;
676  Amat(iat, jat) -= hess;
677  Amat(jat, iat) -= hess;
678  // this will create problems with QMC_COMPLEX, because Bmat is ValueType and dr is RealType
679  // d2u + (ndim+1)*du
680  GradType& grad = BIJ(jat, iat); // dr = r_j - r_i
681  grad = (d2u + (OHMMS_DIM + 1) * du) * displ[jat];
682  BIJ(iat, jat) = -1.0 * grad;
683  Bmat_full(iat, iat) -= grad;
684  Bmat_full(jat, jat) += grad;
685  Bmat_full(iat, jat) += grad;
686  Bmat_full(jat, iat) -= grad;
687  for (int prm = 0, la = indexOfFirstParam + offsetPrms[PairID(iat, jat)]; prm < numParamJU; prm++, la++)
688  {
689  PosType uk = displ[jat] * derivsju[prm][0];
690  Cmat(la, iat) -= uk;
691  Cmat(la, jat) += uk;
692  Xmat(la, iat, jat) -= (derivsju[prm][1] / dist[jat]) * op;
693 #if OHMMS_DIM == 3
694  Xmat(la, iat, jat)[0] -= derivsju[prm][0];
695  Xmat(la, iat, jat)[4] -= derivsju[prm][0];
696  Xmat(la, iat, jat)[8] -= derivsju[prm][0];
697 #elif OHMMS_DIM == 2
698  Xmat(la, iat, jat)[0] -= derivsju[prm][0];
699  Xmat(la, iat, jat)[3] -= derivsju[prm][0];
700 #endif
701  Xmat(la, jat, iat) += Xmat(la, iat, jat);
702  Xmat(la, iat, iat) -= Xmat(la, iat, jat);
703  Xmat(la, jat, jat) -= Xmat(la, iat, jat);
704  uk = 2.0 * (derivsju[prm][2] + (OHMMS_DIM + 1) * derivsju[prm][1] / dist[jat]) * displ[jat];
705  Ymat(la, iat) -= uk;
706  Ymat(la, jat) += uk;
707  }
708  }
709  }
710  }
711  }
712  }
713 };
714 
715 } // namespace qmcplusplus
716 
717 #endif
void evaluate(const ParticleSet &P, ParticleSet &QP, GradVector &Bmat, HessMatrix &Amat)
Definition: Backflow_ee.h:253
int NumTargets
number of quantum particles
void evaluateWithDerivatives(const ParticleSet &P, ParticleSet &QP, GradMatrix &Bmat_full, HessMatrix &Amat, GradMatrix &Cmat, GradMatrix &Ymat, HessArray &Xmat) override
calculate quasi-particle coordinates, Bmat and Amat calculate derivatives wrt to variational paramete...
Definition: Backflow_ee.h:631
std::unique_ptr< BackflowFunctionBase > makeClone(ParticleSet &tqp) const override
Definition: Backflow_ee.h:56
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
const DistanceTableAA & getDistTableAA(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAA
void evaluatePbyP(const ParticleSet &P, ParticleSet::ParticlePos &newQP, const std::vector< int > &index, GradMatrix &Bmat, HessMatrix &Amat) override
calculate quasi-particle coordinates and Amat after pbyp move
Definition: Backflow_ee.h:486
const int myTableIndex_
distance table index
Definition: Backflow_ee.h:30
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.
void acceptMove(int iat, int UpdateMode) override
Definition: Backflow_ee.h:151
Base class for backflow transformations.
int first(int igroup) const
return the first index of a group i
Definition: ParticleSet.h:514
void resize(size_type n, size_type m)
Resize the container.
Definition: OhmmsMatrix.h:99
Attaches a unit to a Vector for IO.
#define OHMMS_DIM
Definition: config.h:64
ParticleIndex GroupID
Species ID.
Definition: ParticleSet.h:77
void evaluatePbyP(const ParticleSet &P, int iat, ParticleSet::ParticlePos &newQP, GradMatrix &Bmat, HessMatrix &Amat) override
calculate quasi-particle coordinates and Amat after pbyp move
Definition: Backflow_ee.h:533
std::vector< std::unique_ptr< FT > > uniqueRadFun
Definition: Backflow_ee.h:35
int groups() const
return the number of groups
Definition: ParticleSet.h:511
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
void evaluate(const ParticleSet &P, ParticleSet &QP, GradMatrix &Bmat_full, HessMatrix &Amat) override
calculate quasi-particle coordinates, Bmat and Amat
Definition: Backflow_ee.h:295
void evaluatePbyP(const ParticleSet &P, ParticleSet::ParticlePos &newQP, const std::vector< int > &index, HessMatrix &Amat) override
calculate quasi-particle coordinates and Amat after pbyp move
Definition: Backflow_ee.h:391
void evaluateBmatOnly(const ParticleSet &P, GradMatrix &Bmat_full) override
calculate only Bmat This is used in pbyp moves, in updateBuffer()
Definition: Backflow_ee.h:608
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > outerProduct(const TinyVector< T1, D > &lhs, const TinyVector< T2, D > &rhs)
Definition: TinyVector.h:211
void reportStatus(std::ostream &os) override
Definition: Backflow_ee.h:117
int indexOffset() override
Definition: Backflow_ee.h:149
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
void checkOutVariables(const opt_variables_type &active) override
Definition: Backflow_ee.h:135
void evaluatePbyP(const ParticleSet &P, int iat, ParticleSet::ParticlePos &newQP) override
calculate quasi-particle coordinates after pbyp move
Definition: Backflow_ee.h:367
ParticlePos R
Position.
Definition: ParticleSet.h:79
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
bool isOptimizable() override
Definition: Backflow_ee.h:141
void evaluate(const ParticleSet &P, ParticleSet &QP) override
calculate quasi-particle coordinates only
Definition: Backflow_ee.h:233
int last(int igroup) const
return the last index of a group i
Definition: ParticleSet.h:517
const DistRow & getDistRow(int iel) const
return a row of distances for a given target particle
size_type rows() const
Definition: OhmmsMatrix.h:77
void checkInVariables(opt_variables_type &active) override
Definition: Backflow_ee.h:129
std::vector< int > offsetPrms
Definition: Backflow_ee.h:36
std::vector< FT * > RadFun
Definition: Backflow_ee.h:34
void registerData(WFBufferType &buf) override
Definition: Backflow_ee.h:104
constexpr double done
Definition: BLAS.hpp:48
Backflow_ee(ParticleSet &ions, ParticleSet &els)
Definition: Backflow_ee.h:41
void addFunc(int ia, int ib, std::unique_ptr< FT > rf)
Definition: Backflow_ee.h:87
std::vector< TinyVector< RealType, 3 > > derivs
Matrix< int > PairID
Definition: Backflow_ee.h:38
void evaluatePbyP(const ParticleSet &P, int iat, ParticleSet::ParticlePos &newQP, HessMatrix &Amat) override
calculate quasi-particle coordinates and Amat after pbyp move
Definition: Backflow_ee.h:428
void resetParameters(const opt_variables_type &active) override
Definition: Backflow_ee.h:123
void restore(int iat, int UpdateType) override
Definition: Backflow_ee.h:224
whether temporary data set on the host is updated or not when a move is proposed. ...
void evaluatePbyP(const ParticleSet &P, ParticleSet::ParticlePos &newQP, const std::vector< int > &index) override
calculate quasi-particle coordinates after pbyp move
Definition: Backflow_ee.h:346
void add(std::complex< T1 > &x)
Definition: PooledMemory.h:113