QMCPACK
test_ecp.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) 2017 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
8 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
9 //
10 // File created by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #include "catch.hpp"
15 
16 #include "Configuration.h"
17 #include "Numerics/Quadrature.h"
22 
23 //for wavefunction
24 #include "OhmmsData/Libxml2Doc.h"
31 //for nonlocal moves
33 
34 
35 //for Hamiltonian manipulations.
36 #include "Particle/ParticleSet.h"
38 
39 //This is for the spinor test.
41 
42 namespace qmcplusplus
43 {
44 QMCTraits::RealType getSplinedSOPot(SOECPComponent* so_comp, int l, double r) { return so_comp->sopp_m_[l]->splint(r); }
45 
46 TEST_CASE("ReadFileBuffer_no_file", "[hamiltonian]")
47 {
48  ReadFileBuffer buf(NULL);
49  bool open_okay = buf.open_file("does_not_exist");
50  REQUIRE(open_okay == false);
51 }
52 
53 TEST_CASE("ReadFileBuffer_simple_serial", "[hamiltonian]")
54 {
55  // Initializing with no Communicate pointer under MPI,
56  // this will read the file on every node. Should be okay
57  // for testing purposes.
58  ReadFileBuffer buf(NULL);
59  bool open_okay = buf.open_file("simple.txt");
60  REQUIRE(open_okay == true);
61 
62  bool read_okay = buf.read_contents();
63  REQUIRE(read_okay);
64  REQUIRE(buf.length == 14);
65  REQUIRE(std::string("File contents\n") == buf.contents());
66 }
67 
68 TEST_CASE("ReadFileBuffer_simple_mpi", "[hamiltonian]")
69 {
71 
72  ReadFileBuffer buf(c);
73  bool open_okay = buf.open_file("simple.txt");
74  REQUIRE(open_okay == true);
75 
76  bool read_okay = buf.read_contents();
77  REQUIRE(read_okay);
78  REQUIRE(buf.length == 14);
79  REQUIRE(std::string("File contents\n") == buf.contents());
80 }
81 
82 TEST_CASE("ReadFileBuffer_ecp", "[hamiltonian]")
83 {
85 
86  ECPComponentBuilder ecp("test_read_ecp", c, 4, 1);
87 
88  bool okay = ecp.read_pp_file("C.BFD.xml");
89  REQUIRE(okay);
90 
91  REQUIRE(ecp.Zeff == 4);
92 
93  // TODO: add more checks that pseudopotential file was read correctly
94 }
95 
96 TEST_CASE("ReadFileBuffer_sorep", "[hamiltonian]")
97 {
99 
100  ECPComponentBuilder ecp("test_read_sorep", c);
101 
102  bool okay = ecp.read_pp_file("so_ecp_test.xml");
103  REQUIRE(okay);
104 
105  REQUIRE(ecp.Zeff == 13);
106 
107  double rlist[5] = {0.001, 0.500, 1.000, 2.000, 10.000};
108  double so_p[5] = {0.999999000005, 0.778800783071, 0.3678794411714, 0.01831563888873418, 0.000};
109  double so_d[5] = {9.99998000e-01, 6.06530660e-01, 1.35335283e-01, 3.35462628e-04, 0.000};
110  double so_f[5] = {9.99997000e-01, 4.72366553e-01, 4.97870684e-02, 6.14421235e-06, 0.000};
111 
112  for (int i = 0; i < 5; i++)
113  {
114  double r = rlist[i];
115  double so_p_ref = so_p[i];
116  double so_d_ref = so_d[i];
117  double so_f_ref = so_f[i];
118 
119  double so_p_val = getSplinedSOPot(ecp.pp_so.get(), 0, r);
120  double so_d_val = getSplinedSOPot(ecp.pp_so.get(), 1, r);
121  double so_f_val = getSplinedSOPot(ecp.pp_so.get(), 2, r);
122 
123  CHECK(so_p_val == Approx(so_p_ref));
124  CHECK(so_d_val == Approx(so_d_ref));
125  CHECK(so_f_val == Approx(so_f_ref));
126  }
127 
128  // TODO: add more checks that pseudopotential file was read correctly
129 }
130 
131 
132 TEST_CASE("ReadFileBuffer_reopen", "[hamiltonian]")
133 {
134  // Initializing with no Communicate pointer under MPI,
135  // this will read the file on every node. Should be okay
136  // for testing purposes.
137  ReadFileBuffer buf(NULL);
138  bool open_okay = buf.open_file("simple.txt");
139  REQUIRE(open_okay == true);
140 
141  bool read_okay = buf.read_contents();
142  REQUIRE(read_okay);
143  REQUIRE(buf.length == 14);
144 
145  open_okay = buf.open_file("C.BFD.xml");
146  REQUIRE(open_okay == true);
147 
148  read_okay = buf.read_contents();
149  REQUIRE(read_okay);
150  REQUIRE(buf.length > 14);
151 }
152 
155 
156 TEST_CASE("Evaluate_ecp", "[hamiltonian]")
157 {
160  using PosType = QMCTraits::PosType;
161 
163 
164  //Cell definition:
165 
167  lattice.BoxBConds = true; // periodic
168  lattice.R.diagonal(20);
169  lattice.LR_dim_cutoff = 15;
170  lattice.reset();
171 
172  const SimulationCell simulation_cell(lattice);
173  ParticleSet ions(simulation_cell);
174  ParticleSet elec(simulation_cell);
175 
176  ions.setName("ion0");
177  ions.create({2});
178  ions.R[0] = {0.0, 0.0, 0.0};
179  ions.R[1] = {6.0, 0.0, 0.0};
180  SpeciesSet& ion_species = ions.getSpeciesSet();
181  int pIdx = ion_species.addSpecies("Na");
182  int pChargeIdx = ion_species.addAttribute("charge");
183  int iatnumber = ion_species.addAttribute("atomic_number");
184  ion_species(pChargeIdx, pIdx) = 1;
185  ion_species(iatnumber, pIdx) = 11;
186  ions.createSK();
187 
188  elec.setName("e");
189  std::vector<int> agroup(2, 1);
190  elec.create(agroup);
191  elec.R[0] = {2.0, 0.0, 0.0};
192  elec.R[1] = {3.0, 0.0, 0.0};
193  SpeciesSet& tspecies = elec.getSpeciesSet();
194  int upIdx = tspecies.addSpecies("u");
195  int downIdx = tspecies.addSpecies("d");
196  int chargeIdx = tspecies.addAttribute("charge");
197  int massIdx = tspecies.addAttribute("mass");
198  tspecies(chargeIdx, upIdx) = -1;
199  tspecies(chargeIdx, downIdx) = -1;
200  tspecies(massIdx, upIdx) = 1.0;
201  tspecies(massIdx, downIdx) = 1.0;
202 
203  elec.createSK();
204 
205  ions.resetGroups();
206 
207  // The call to resetGroups is needed transfer the SpeciesSet
208  // settings to the ParticleSet
209  elec.resetGroups();
210 
211  //Cool. Now to construct a wavefunction with 1 and 2 body jastrow (no determinant)
212  RuntimeOptions runtime_options;
213  TrialWaveFunction psi(runtime_options);
214 
215  //Add the two body jastrow
216  const char* particles = R"(<tmp>
217  <jastrow name="J2" type="Two-Body" function="Bspline" print="yes" gpu="no">
218  <correlation speciesA="u" speciesB="d" rcut="10" size="8">
219  <coefficients id="ud" type="Array"> 2.015599059 1.548994099 1.17959447 0.8769687661 0.6245736507 0.4133517767 0.2333851935 0.1035636904</coefficients>
220  </correlation>
221  </jastrow>
222  </tmp>
223  )";
225  bool okay = doc.parseFromString(particles);
226  REQUIRE(okay);
227 
228  xmlNodePtr root = doc.getRoot();
229 
230  xmlNodePtr jas2 = xmlFirstElementChild(root);
231 
232  RadialJastrowBuilder jastrow(c, elec);
233  psi.addComponent(jastrow.buildComponent(jas2));
234  // Done with two body jastrow.
235 
236  //Add the one body jastrow.
237  const char* particles2 = R"(<tmp>
238  <jastrow name="J1" type="One-Body" function="Bspline" source="ion0" print="yes">
239  <correlation elementType="Na" rcut="10" size="10" cusp="0">
240  <coefficients id="eNa" type="Array"> 1.244201343 -1.188935609 -1.840397253 -1.803849126 -1.612058635 -1.35993202 -1.083353212 -0.8066295188 -0.5319252448 -0.3158819772</coefficients>
241  </correlation>
242  </jastrow>
243  </tmp>
244  )";
245  bool okay3 = doc.parseFromString(particles2);
246  REQUIRE(okay3);
247 
248  root = doc.getRoot();
249 
250  xmlNodePtr jas1 = xmlFirstElementChild(root);
251 
252  RadialJastrowBuilder jastrow1bdy(c, elec, ions);
253  psi.addComponent(jastrow1bdy.buildComponent(jas1));
254 
255  //Now we set up the nonlocal ECP component.
256  ECPComponentBuilder ecp("test_read_ecp", c);
257 
258  bool okay2 = ecp.read_pp_file("Na.BFD.xml");
259 
260  NonLocalECPComponent* nlpp = ecp.pp_nonloc.get();
261 
262  REQUIRE(nlpp != nullptr);
263 
264  //This line is required because the randomized quadrature Lattice is set by
265  //random number generator in NonLocalECPotential. We take the unrotated
266  //quadrature Lattice instead...
268 
269  const int myTableIndex = elec.addTable(ions);
270 
271  const auto& myTable = elec.getDistTableAB(myTableIndex);
272 
273  // update all distance tables
274  ions.update();
275  elec.update();
276 
277  //Need to set up temporary data for this configuration in trial wavefunction. Needed for ratios.
278  double logpsi = psi.evaluateLog(elec);
279  CHECK(logpsi == Approx(5.1497823982));
280 
281  auto test_evaluateOne = [&]() {
282  double Value1(0.0);
283  //Using SoA distance tables, hence the guard.
284  for (int jel = 0; jel < elec.getTotalNum(); jel++)
285  {
286  const auto& dist = myTable.getDistRow(jel);
287  const auto& displ = myTable.getDisplRow(jel);
288  for (int iat = 0; iat < ions.getTotalNum(); iat++)
289  if (nlpp != nullptr && dist[iat] < nlpp->getRmax())
290  Value1 += nlpp->evaluateOne(elec, iat, psi, jel, dist[iat], -displ[iat], false);
291  }
292  //These numbers are validated against an alternate code path via wavefunction tester.
293  CHECK(Value1 == Approx(6.9015710211e-02));
294  };
295 
296  {
297  nlpp->initVirtualParticle(elec);
298  test_evaluateOne();
299  nlpp->deleteVirtualParticle();
300  test_evaluateOne();
301  }
302 
303  opt_variables_type optvars;
304  Vector<ValueType> dlogpsi;
305  Vector<ValueType> dhpsioverpsi;
306 
307  psi.checkInVariables(optvars);
308  optvars.resetIndex();
309  const int NumOptimizables(optvars.size());
310  psi.checkOutVariables(optvars);
311  auto test_evaluateValueAndDerivatives = [&]() {
312  dlogpsi.resize(NumOptimizables, ValueType(0));
313  dhpsioverpsi.resize(NumOptimizables, ValueType(0));
314  psi.evaluateDerivatives(elec, optvars, dlogpsi, dhpsioverpsi);
315  CHECK(std::real(dlogpsi[0]) == Approx(-0.2211666667));
316  CHECK(std::real(dlogpsi[2]) == Approx(-0.1215));
317  CHECK(std::real(dlogpsi[3]) == Approx(0.0));
318  CHECK(std::real(dlogpsi[9]) == Approx(-0.0853333333));
319  CHECK(std::real(dlogpsi[10]) == Approx(-0.745));
320 
321  CHECK(std::real(dhpsioverpsi[0]) == Approx(-0.6463306581));
322  CHECK(std::real(dhpsioverpsi[2]) == Approx(1.5689981479));
323  CHECK(std::real(dhpsioverpsi[3]) == Approx(0.0));
324  CHECK(std::real(dhpsioverpsi[9]) == Approx(0.279561213));
325  CHECK(std::real(dhpsioverpsi[10]) == Approx(-0.3968828778));
326 
327  double Value1 = 0.0;
328  //Using SoA distance tables, hence the guard.
329  for (int jel = 0; jel < elec.getTotalNum(); jel++)
330  {
331  const auto& dist = myTable.getDistRow(jel);
332  const auto& displ = myTable.getDisplRow(jel);
333  for (int iat = 0; iat < ions.getTotalNum(); iat++)
334  if (nlpp != nullptr && dist[iat] < nlpp->getRmax())
335  Value1 += nlpp->evaluateValueAndDerivatives(elec, iat, psi, jel, dist[iat], -displ[iat], optvars, dlogpsi,
336  dhpsioverpsi);
337  }
338  CHECK(Value1 == Approx(6.9015710211e-02));
339 
340  CHECK(std::real(dhpsioverpsi[0]) == Approx(-0.6379341942));
341  CHECK(std::real(dhpsioverpsi[2]) == Approx(1.5269279991));
342  CHECK(std::real(dhpsioverpsi[3]) == Approx(-0.0355730676));
343  CHECK(std::real(dhpsioverpsi[9]) == Approx(0.279561213));
344  CHECK(std::real(dhpsioverpsi[10]) == Approx(-0.3968763604));
345  };
346 
347  {
348  nlpp->initVirtualParticle(elec);
349  test_evaluateValueAndDerivatives();
350  nlpp->deleteVirtualParticle();
351  test_evaluateValueAndDerivatives();
352  }
353 
354  double Value2(0.0);
355  double Value3(0.0);
356  ParticleSet::ParticlePos PulayTerm, HFTerm, HFTerm2;
357  HFTerm.resize(ions.getTotalNum());
358  HFTerm2.resize(ions.getTotalNum());
359  PulayTerm.resize(ions.getTotalNum());
360  HFTerm = 0;
361  HFTerm2 = 0;
362  PulayTerm = 0;
363 
364  for (int jel = 0; jel < elec.getTotalNum(); jel++)
365  {
366  const auto& dist = myTable.getDistRow(jel);
367  const auto& displ = myTable.getDisplRow(jel);
368  for (int iat = 0; iat < ions.getTotalNum(); iat++)
369  if (nlpp != nullptr && dist[iat] < nlpp->getRmax())
370  {
371  Value2 += nlpp->evaluateOneWithForces(elec, iat, psi, jel, dist[iat], -displ[iat], HFTerm[iat]);
372  Value3 +=
373  nlpp->evaluateOneWithForces(elec, ions, iat, psi, jel, dist[iat], -displ[iat], HFTerm2[iat], PulayTerm);
374  }
375  }
376  //These values are validated against print statements.
377  //Two-body jastrow-only wave functions agree with finite difference of NLPP to machine precision.
378  // These numbers assume the Hellman Feynmann implementation is correct, and dump the values
379  // when a one body term is added in.
380 
381  CHECK(Value2 == Approx(6.9015710211e-02));
382  CHECK(Value3 == Approx(6.9015710211e-02));
383 
384  //The total force (HFTerm+PulayTerm) is validated against finite difference of nonlocal PP w.r.t
385  //ion coordinates. delta=1e-6. Should be good up to 7th or 8th sig fig. These are:
386  // F[0][0]= 0.3474359
387  // F[0][1]= 0
388  // F[0][2]= 0
389  // F[1][0]=-0.002734064
390  // F[1][1]= 0
391  // F[1][2]= 0
392 
393  CHECK(HFTerm[0][0] == Approx(-0.3557369031));
394  CHECK(HFTerm[0][1] == Approx(0.0));
395  CHECK(HFTerm[0][2] == Approx(0.0));
396  CHECK(HFTerm[1][0] == Approx(0.001068673105));
397  CHECK(HFTerm[1][1] == Approx(0.0));
398  CHECK(HFTerm[1][2] == Approx(0.0));
399 
400  CHECK(HFTerm2[0][0] == Approx(-0.3557369031));
401  CHECK(HFTerm2[0][1] == Approx(0.0));
402  CHECK(HFTerm2[0][2] == Approx(0.0));
403  CHECK(HFTerm2[1][0] == Approx(0.001068673105));
404  CHECK(HFTerm2[1][1] == Approx(0.0));
405  CHECK(HFTerm2[1][2] == Approx(0.0));
406 
407  CHECK(PulayTerm[0][0] == Approx(0.008300993315));
408  CHECK(PulayTerm[0][1] == Approx(0.0));
409  CHECK(PulayTerm[0][2] == Approx(0.0));
410  CHECK(PulayTerm[1][0] == Approx(0.001665391103));
411  CHECK(PulayTerm[1][1] == Approx(0.0));
412  CHECK(PulayTerm[1][2] == Approx(0.0));
413 
414  //Comparing against finite difference results above, here's what we get.
415  //HFTerm[0][0]+PulayTerm[0][0] = −0.34743591
416  //HFTerm[0][1]+PulayTerm[0][1] = 0.0
417  //HFTerm[0][2]+PulayTerm[0][2] = 0.0
418  //HFTerm[1][0]+PulayTerm[1][0] = 0.002734064
419  //HFTerm[1][1]+PulayTerm[1][1] = 0.0
420  //HFTerm[1][2]+PulayTerm[1][2] = 0.0
421 }
422 
423 #ifdef QMC_COMPLEX
424 TEST_CASE("Evaluate_soecp", "[hamiltonian]")
425 {
426  app_log() << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
427  app_log() << "!!!! Evaluate SOECPComponent !!!!\n";
428  app_log() << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
431  using PosType = QMCTraits::PosType;
432 
434 
435  //Cell definition:
436 
437  CrystalLattice<OHMMS_PRECISION, OHMMS_DIM> lattice;
438  lattice.BoxBConds = false; // periodic
439  lattice.R.diagonal(20);
440  lattice.LR_dim_cutoff = 15;
441  lattice.reset();
442 
443  const SimulationCell simulation_cell(lattice);
444  auto ions_uptr = std::make_unique<ParticleSet>(simulation_cell);
445  auto elec_uptr = std::make_unique<ParticleSet>(simulation_cell);
446  ParticleSet& ions(*ions_uptr);
447  ParticleSet& elec(*elec_uptr);
448 
449  ions.setName("ion0");
450  ions.create({1});
451  ions.R[0] = {0.0, 0.0, 0.0};
452 
453 
454  SpeciesSet& ion_species = ions.getSpeciesSet();
455  int pIdx = ion_species.addSpecies("H");
456  int pChargeIdx = ion_species.addAttribute("charge");
457  int iatnumber = ion_species.addAttribute("atomic_number");
458  ion_species(pChargeIdx, pIdx) = 0;
459  ion_species(iatnumber, pIdx) = 1;
460  ions.createSK();
461 
462 
463  elec.setName("e");
464  elec.setSpinor(true);
465  elec.create({2});
466  elec.R[0] = {0.138, -0.24, 0.216};
467  elec.R[1] = {-0.216, 0.24, -0.138};
468  elec.spins = {0.2, 0.51};
469 
470  SpeciesSet& tspecies = elec.getSpeciesSet();
471  int upIdx = tspecies.addSpecies("u");
472  int chargeIdx = tspecies.addAttribute("charge");
473  int massIdx = tspecies.addAttribute("mass");
474  tspecies(chargeIdx, upIdx) = -1;
475  tspecies(massIdx, upIdx) = 1.0;
476 
477  elec.createSK();
478 
479  ions.resetGroups();
480  elec.resetGroups();
481 
482  RuntimeOptions runtime_options;
483  TrialWaveFunction psi(runtime_options);
484 
485  std::vector<PosType> kup, kdn;
486  std::vector<RealType> k2up, k2dn;
487  QMCTraits::IndexType nelec = elec.getTotalNum();
488  REQUIRE(nelec == 2);
489 
490  kup.resize(nelec);
491  kup[0] = PosType(1, 1, 1);
492  kup[1] = PosType(2, 2, 2);
493 
494  kdn.resize(nelec);
495  kdn[0] = PosType(2, 2, 2);
496  kdn[1] = PosType(1, 1, 1);
497 
498  auto spo_up = std::make_unique<FreeOrbital>("free_orb_up", kup);
499  auto spo_dn = std::make_unique<FreeOrbital>("free_orb_dn", kdn);
500 
501  auto spinor_set = std::make_unique<SpinorSet>("free_orb_spinor");
502  spinor_set->set_spos(std::move(spo_up), std::move(spo_dn));
503  QMCTraits::IndexType norb = spinor_set->getOrbitalSetSize();
504  REQUIRE(norb == 2);
505 
506  auto dd = std::make_unique<DiracDeterminant<>>(std::move(spinor_set), 0, nelec);
507 
508  psi.addComponent(std::move(dd));
509 
510  //Add the two body jastrow, parameters from test_J2_bspline
511  //adding jastrow will allow for adding WF parameter derivatives since FreeOrbital doesn't
512  //support that
513  const char* particles = R"(<tmp>
514  <jastrow name="J2" type="Two-Body" function="Bspline" print="yes" gpu="no">
515  <correlation speciesA="u" speciesB="u" rcut="5" size="5">
516  <coefficients id="uu" type="Array"> 0.02904699284 -0.1004179 -0.1752703883 -0.2232576505 -0.2728029201</coefficients>
517  </correlation>
518  </jastrow>
519  </tmp>
520  )";
522  bool okay = doc.parseFromString(particles);
523  REQUIRE(okay);
524  xmlNodePtr root = doc.getRoot();
525  xmlNodePtr jas2 = xmlFirstElementChild(root);
526  RadialJastrowBuilder jastrow(c, elec);
527  psi.addComponent(jastrow.buildComponent(jas2));
528  // Done with two body jastrow.
529 
530  //Now we set up the SO ECP component.
531  ECPComponentBuilder ecp("test_read_soecp", c);
532 
533  bool okay2 = ecp.read_pp_file("so_ecp_test.xml");
534  REQUIRE(okay2);
535 
536  SOECPComponent* sopp = ecp.pp_so.get();
537  REQUIRE(sopp != nullptr);
539 
540  const int myTableIndex = elec.addTable(ions);
541 
542  const auto& myTable = elec.getDistTableAB(myTableIndex);
543 
544  // update all distance tables
545  ions.update();
546  elec.update();
547 
548  //Need to set up temporary data for this configuration in trial wavefunction. Needed for ratios.
549  auto logpsi = psi.evaluateLog(elec);
550 
551  auto test_evaluateOne = [&]() {
552  RealType Value1(0.0);
553  for (int jel = 0; jel < elec.getTotalNum(); jel++)
554  {
555  const auto& dist = myTable.getDistRow(jel);
556  const auto& displ = myTable.getDisplRow(jel);
557  for (int iat = 0; iat < ions.getTotalNum(); iat++)
558  if (sopp != nullptr && dist[iat] < sopp->getRmax())
559  Value1 += sopp->evaluateOne(elec, iat, psi, jel, dist[iat], RealType(-1) * displ[iat]);
560  }
561  REQUIRE(Value1 == Approx(-3.530511241));
562  };
563 
564  {
565  //test with VPs
566  sopp->initVirtualParticle(elec);
567  test_evaluateOne();
568  sopp->deleteVirtualParticle();
569  //test without VPs
570  test_evaluateOne();
571  }
572 
573  //Check evaluateValueAndDerivatives
574  opt_variables_type optvars;
575  Vector<ValueType> dlogpsi;
576  Vector<ValueType> dhpsioverpsi;
577 
578  psi.checkInVariables(optvars);
579  optvars.resetIndex();
580  const int NumOptimizables(optvars.size());
581  psi.checkOutVariables(optvars);
582 
583 
584  //Ref Values from soecp_eval_ref.cpp in the print_dlogpsi using finite differences
585  std::vector<RealType> dlogpsi_refs = {-0.2622341567, -0.64168132, -0.09608452334, -2.486899575e-14, -2.486899575e-14};
586  //These weren't independently validated in soecp_eval_ref.cpp
587  //trusting current values from evaluateDerivatives...which should be correct if the
588  //dlogpsi comes out correct
589  std::vector<RealType> dkinpsioverpsi_refs = {-3.807451601, 0.1047251267, 3.702726474, 0, 0};
590  //These were independently validated in soecp_eval_ref.cpp, includes the contribution
591  //from dkinpsioverpsi_refs
592  std::vector<RealType> dhpsioverpsi_refs = {-3.855727438, 0.202618546, 3.653108892, -8.169955304e-14,
593  -8.169955304e-14};
594 
595 
596  auto test_evaluateValueAndDerivatives = [&]() {
597  dlogpsi.resize(NumOptimizables, ValueType(0));
598  dhpsioverpsi.resize(NumOptimizables, ValueType(0));
599  psi.evaluateDerivatives(elec, optvars, dlogpsi, dhpsioverpsi);
600  for (int ip = 0; ip < NumOptimizables; ip++)
601  {
602  CHECK(std::real(dlogpsi[ip]) == Approx(dlogpsi_refs[ip]));
603  CHECK(std::real(dhpsioverpsi[ip]) == Approx(dkinpsioverpsi_refs[ip]));
604  }
605 
606  double Value1 = 0.0;
607  //Using SoA distance tables, hence the guard.
608  for (int jel = 0; jel < elec.getTotalNum(); jel++)
609  {
610  const auto& dist = myTable.getDistRow(jel);
611  const auto& displ = myTable.getDisplRow(jel);
612  for (int iat = 0; iat < ions.getTotalNum(); iat++)
613  if (sopp != nullptr && dist[iat] < sopp->getRmax())
614  Value1 += sopp->evaluateValueAndDerivatives(elec, iat, psi, jel, dist[iat], -displ[iat], optvars, dlogpsi,
615  dhpsioverpsi);
616  }
617  REQUIRE(Value1 == Approx(-3.530511241).epsilon(2.e-5));
618 
619  for (int ip = 0; ip < NumOptimizables; ip++)
620  CHECK(std::real(dhpsioverpsi[ip]) == Approx(dhpsioverpsi_refs[ip]));
621  };
622 
623  {
624  sopp->initVirtualParticle(elec);
625  test_evaluateValueAndDerivatives();
626  sopp->deleteVirtualParticle();
627  test_evaluateValueAndDerivatives();
628  }
629 }
630 #endif
631 
632 
633 } // namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
a class that defines a supercell in D-dimensional Euclean space.
RealType evaluateLog(ParticleSet &P)
evalaute the log (internally gradients and laplacian) of the trial wavefunction.
void setName(const std::string &aname)
Definition: ParticleSet.h:237
Contains a set of radial grid potentials around a center.
class that handles xmlDoc
Definition: Libxml2Doc.h:76
int addSpecies(const std::string &aname)
When a name species does not exist, add a new species.
Definition: SpeciesSet.cpp:33
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &optvars, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi)
evaluate derivatives of KE wrt optimizable varibles
QTBase::RealType RealType
Definition: Configuration.h:58
size_t getTotalNum() const
Definition: ParticleSet.h:493
std::ostream & app_log()
Definition: OutputManager.h:65
TEST_CASE("complex_helper", "[type_traits]")
std::unique_ptr< WaveFunctionComponent > buildComponent(xmlNodePtr cur) override
process a xml node at cur
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
JastrowBuilder using an analytic 1d functor Should be able to eventually handle all one and two body ...
Declaration of NonLocalTOperator.
class SOECPComponent brief Computes the nonlocal spin-orbit interaction .
void resetIndex()
reset Index
void update(bool skipSK=false)
update the internal data
Attaches a unit to a Vector for IO.
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
int addAttribute(const std::string &aname)
for a new attribute, allocate the data, !More often used to get the index of a species ...
Definition: SpeciesSet.cpp:45
std::unique_ptr< NonLocalECPComponent > pp_nonloc
const DistanceTableAB & getDistTableAB(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAB
QMCTraits::PosType PosType
Wrapping information on parallelism.
Definition: Communicate.h:68
bool open_file(const std::string &fname)
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > lattice
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
RealType evaluateValueAndDerivatives(ParticleSet &P, int iat, TrialWaveFunction &psi, int iel, RealType r, const PosType &dr, const opt_variables_type &optvars, const Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi)
evaluate the non-local potential of the iat-th ionic center
SpherGridType rrotsgrid_m
randomized spherical grid
std::unique_ptr< SOECPComponent > pp_so
QTBase::ValueType ValueType
Definition: Configuration.h:60
REQUIRE(std::filesystem::exists(filename))
Declaration of a builder class for an ECP component for an ionic type.
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
ParticlePos R
Position.
Definition: ParticleSet.h:79
QTBase::PosType PosType
Definition: Configuration.h:61
RealType evaluateOne(ParticleSet &W, int iat, TrialWaveFunction &Psi, int iel, RealType r, const PosType &dr, bool use_DLA)
Evaluate the nonlocal pp contribution via randomized quadrature grid to total energy from ion "iat" a...
void checkOutVariables(const opt_variables_type &o)
Check out optimizable variables Assign index mappings from global list (o) to local values in each co...
optimize::VariableSet opt_variables_type
OHMMS_INDEXTYPE IndexType
define other types
Definition: Configuration.h:65
size_type size() const
return the size
Definition: VariableSet.h:88
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
std::vector< RadialPotentialType * > sopp_m_
Non-Local part of the pseudo-potential.
void create(const std::vector< int > &agroup)
create grouped particles
bool read_pp_file(const std::string &fname)
Declaration of a TrialWaveFunction.
QMCTraits::RealType RealType
Class to represent a many-body trial wave function.
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
TinyVector< double, 3 > PosType
RealType evaluateOneWithForces(ParticleSet &W, int iat, TrialWaveFunction &Psi, int iel, RealType r, const PosType &dr, PosType &force_iat)
Evaluate the nonlocal pp contribution via randomized quadrature grid to total energy from ion "iat" a...
LatticeGaussianProduct::ValueType ValueType
Declaration of DiracDeterminant with a S(ingle)P(article)O(rbital)Set.
void createSK()
create Structure Factor with PBCs
void initVirtualParticle(const ParticleSet &qp)
Declaration of WaveFunctionComponent.
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
void copyGridUnrotatedForTest(NonLocalECPComponent &nlpp)
Definition: test_ecp.cpp:153
QMCTraits::RealType getSplinedSOPot(SOECPComponent *so_comp, int l, double r)
Definition: test_ecp.cpp:44
SpherGridType sgridxyz_m
fixed Spherical Grid for species
void addComponent(std::unique_ptr< WaveFunctionComponent > &&aterm)
add a WaveFunctionComponent
void checkInVariables(opt_variables_type &o)
Check in an optimizable parameter.