QMCPACK
test_counting_jastrow.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) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Brett Van Der Goetz, bvdg@berkeley.edu, University of California at Berkeley
8 //
9 // File created by: Brett Van Der Goetz, bvdg@berkeley.edu, University of California at Berkeley
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #include "catch.hpp"
13 
14 #include "Configuration.h"
15 #include "OhmmsData/Libxml2Doc.h"
16 #include "Particle/ParticleSet.h"
17 #include "VariableSet.h"
18 
23 
24 #include <stdio.h>
25 
26 namespace qmcplusplus
27 {
28 
29 // CountingGaussian unit tests
30 TEST_CASE("Gaussian Functor", "[wavefunction]")
31 {
34  using TensorType = QMCTraits::TensorType;
35 
36  CountingGaussian gf_abc("gf_abc");
37  CountingGaussian gf_adk("gf_adk");
38 
39  // test parse/put for both input modes
40  const char* gaussian_xml_abc = R"(<function id="g0">
41  <var name="A" opt="true">-1.5 0.353553390593273 -0.353553390593273 -2.25 -0.75 -2.25</var>
42  <var name="B" opt="true">-1.5 0.353553390593273 -0.353553390593273</var>
43  <var name="C" opt="true">-1.5</var>
44  </function>)";
45  const char* gaussian_xml_adk = R"(<function id="g1">
46  <var name="A" opt="true">-1.5 0.353553390593273 -0.353553390593273 -2.25 -0.75 -2.25</var>
47  <var name="D" opt="true">1.0 0.0 0.0</var>
48  <var name="K" opt="true">0.0</var>
49  </function>)";
50  Libxml2Document doc_abc, doc_adk;
51  bool parse_abc = doc_abc.parseFromString(gaussian_xml_abc);
52  bool parse_adk = doc_adk.parseFromString(gaussian_xml_adk);
53  xmlNodePtr root_abc = doc_abc.getRoot();
54  xmlNodePtr root_adk = doc_adk.getRoot();
55  bool put_abc = gf_abc.put(root_abc);
56  bool put_adk = gf_adk.put(root_adk);
57  REQUIRE((parse_abc && parse_adk && put_abc && put_adk) == true);
58 
59  // test points
60  PosType r1(1, 0, 0);
61  PosType r2(1.707106781186547, 0.5, -0.5);
62  PosType r3(0.4714617144631338, 0.1499413068889379, 0.2932213074999387);
63 
64  // return variables
65  RealType fval, lval, llap, flap;
66  PosType fgrad, lgrad;
67  opt_variables_type opt_vars;
68 
69  std::vector<RealType> dfval;
70  std::vector<PosType> dfgrad;
71  std::vector<RealType> dflap;
72  dfval.resize(10);
73  dfgrad.resize(10);
74  dflap.resize(10);
75 
76  // value tests for ADK input
77  gf_adk.evaluate(r1, fval, fgrad, flap);
78  gf_adk.evaluateLog(r1, lval, lgrad, llap);
79  CHECK(fval == Approx(1));
80  CHECK(fgrad[0] == Approx(0));
81  CHECK(fgrad[1] == Approx(0));
82  CHECK(fgrad[2] == Approx(0));
83  CHECK(flap == Approx(-12));
84  CHECK(lval == Approx(0));
85  CHECK(lgrad[0] == Approx(0));
86  CHECK(lgrad[1] == Approx(0));
87  CHECK(lgrad[2] == Approx(0));
88  CHECK(llap == Approx(-12));
89  // value tests for ABC input
90  gf_abc.evaluate(r1, fval, fgrad, flap);
91  gf_abc.evaluateLog(r1, lval, lgrad, llap);
92  CHECK(fval == Approx(1));
93  CHECK(fgrad[0] == Approx(0));
94  CHECK(fgrad[1] == Approx(0));
95  CHECK(fgrad[2] == Approx(0));
96  CHECK(flap == Approx(-12));
97  CHECK(lval == Approx(0));
98  CHECK(lgrad[0] == Approx(0));
99  CHECK(lgrad[1] == Approx(0));
100  CHECK(lgrad[2] == Approx(0));
101  CHECK(llap == Approx(-12));
102  // evaluateDerivatives
103  gf_abc.evaluateDerivatives(r3, dfval, dfgrad, dflap);
104  CHECK(dfval[0] == Approx(0.113120472934));
105  CHECK(dfval[1] == Approx(0.071952529875));
106  CHECK(dfval[2] == Approx(0.140708490047));
107  CHECK(dfval[3] == Approx(0.011441709933));
108  CHECK(dfval[4] == Approx(0.044750218821));
109  CHECK(dfval[5] == Approx(0.043756180154));
110  CHECK(dfval[6] == Approx(-0.47987130010));
111  CHECK(dfval[7] == Approx(-0.15261584911));
112  CHECK(dfval[8] == Approx(-0.29845157248));
113  CHECK(dfval[9] == Approx(0.508918630484));
114  // evaluateLogDerivatives
115  gf_abc.evaluateLogDerivatives(r3, dfval, dfgrad, dflap);
116  CHECK(dfval[0] == Approx(0.222276148205));
117  CHECK(dfval[1] == Approx(0.141383171229));
118  CHECK(dfval[2] == Approx(0.276485240702));
119  CHECK(dfval[3] == Approx(0.022482395511));
120  CHECK(dfval[4] == Approx(0.087931972108));
121  CHECK(dfval[5] == Approx(0.085978735172));
122  CHECK(dfval[6] == Approx(-0.94292342892));
123  CHECK(dfval[7] == Approx(-0.29988261377));
124  CHECK(dfval[8] == Approx(-0.58644261500));
125  CHECK(dfval[9] == Approx(1));
126 }
127 
128 TEST_CASE("CountingJastrow", "[wavefunction]")
129 {
130  using PosType = QMCTraits::PosType;
134  using VariableSet = optimize::VariableSet;
135  using LogValue = std::complex<QMCTraits::QTFull::RealType>;
136 
138 
139  // initialize particle sets
140  const SimulationCell simulation_cell;
141  ParticleSet elec(simulation_cell);
142  std::vector<int> egroup(1);
143  int num_els = 4;
144  egroup[0] = num_els;
145  elec.setName("e");
146  elec.create(egroup);
147  PosType Re[] = {PosType(2.4601162537, 6.7476360528, -1.9073129953),
148  PosType(2.2585811248, 2.1282254384, 0.051545776028),
149  PosType(0.84796873937, 5.1735597110, 0.84642416761),
150  PosType(3.1597337850, 5.1079432473, 1.0545953717)};
151  for (int i = 0; i < num_els; ++i)
152  for (int k = 0; k < 3; ++k)
153  elec.R[i][k] = Re[i][k];
154 
155  ParticleSet ion0(simulation_cell);
156  std::vector<int> igroup(1);
157  int num_ion = 4;
158  igroup[0] = num_ion;
159  ion0.setName("ion0");
160  ion0.create(igroup);
161  PosType Ri[] = {PosType(2.61363352510301, 5.01928226905281, 0.0), PosType(3.74709851167814, 3.70007145722224, 0.0),
162  PosType(6.11011670934565, 1.66504047681825, 0.0), PosType(8.10584803421091, 7.78608266172472, 0.0)};
163 
164  for (int i = 0; i < num_ion; ++i)
165  for (int k = 0; k < 3; ++k)
166  ion0.R[i][k] = Ri[i][k];
167 
168  const char* cj_normgauss_xml = R"(<jastrow name="ncjf_normgauss" type="Counting">
169  <var name="F" opt="true">
170  4.4903e-01 5.3502e-01 5.2550e-01 6.8081e-01
171  5.1408e-01 4.8658e-01 6.2182e-01
172  2.7189e-01 9.4951e-01
173  0.0000e+00
174  </var>
175  <region type="normalized_gaussian" reference_id="g0" opt="true" >
176  <function id="g0">
177  <var name="A" opt="False">-1.0 -0.0 -0.0 -1.0 -0.0 -1.0</var>
178  <var name="B" opt="False">-2.6136335251 -5.01928226905 0.0</var>
179  <var name="C" opt="False">-32.0242747</var>
180  </function>
181  <function id="g1">
182  <var name="A" opt="true">-1.0 -0.0 -0.0 -1.0 -0.0 -1.0</var>
183  <var name="B" opt="true">-3.74709851168 -3.70007145722 0.0</var>
184  <var name="C" opt="true">-27.7312760448</var>
185  </function>
186  <function id="g2">
187  <var name="A" opt="true">-1.0 -0.0 -0.0 -1.0 -0.0 -1.0</var>
188  <var name="B" opt="true">-6.11011670935 -1.66504047682 0.0</var>
189  <var name="C" opt="true">-40.1058859913</var>
190  </function>
191  <function id="g3">
192  <var name="A" opt="true">-1.0 -0.0 -0.0 -1.0 -0.0 -1.0</var>
193  <var name="B" opt="true">-8.10584803421 -7.78608266172 0.0</var>
194  <var name="C" opt="true">-126.327855569</var>
195  </function>
196  </region>
197  </jastrow>)";
198  // test put for normalized_gaussian
200  bool parse_cj = doc.parseFromString(cj_normgauss_xml);
201  REQUIRE(parse_cj);
202 
203  xmlNodePtr cj_root = doc.getRoot();
204  CountingJastrowBuilder cjb(c, elec);
205 
206  auto cj_uptr = cjb.buildComponent(cj_root);
208 
209  // reference for evaluateLog, evalGrad
210  RealType Jval_exact = 7.8100074447e+00;
211  PosType Jgrad_exact[] = {PosType(3.6845037054e-04, -4.2882992861e-04, 0),
212  PosType(2.2032083234e-02, -2.5647245917e-02, 0),
213  PosType(6.0625112202e-04, -7.0560012380e-04, 0),
214  PosType(1.0622511249e-01, -1.2363268199e-01, 0)};
215  RealType Jlap_exact[] = {1.9649428566e-03, -1.1385706794e-01, 3.2312809658e-03, 4.0668060285e-01};
216 
217 
218  // test evaluateLog for cj
219  LogValue logval = cj->evaluateLog(elec, elec.G, elec.L);
220  for (int i = 0; i < num_els; ++i)
221  {
222  for (int k = 0; k < 3; ++k)
223  CHECK(Jgrad_exact[i][k] == Approx(std::real(elec.G[i][k])));
224  CHECK(Jlap_exact[i] == Approx(std::real(elec.L[i])));
225  }
226  CHECK(ComplexApprox(Jval_exact) == logval);
227 
228  // test automatic/minimal voronoi generator
229  const char* cj_voronoi_xml = R"(<jastrow name="ncjf_voronoi" type="Counting" source="ion0">
230  <var name="F" opt="true">
231  4.4903e-01 5.3502e-01 5.2550e-01 6.8081e-01
232  5.1408e-01 4.8658e-01 6.2182e-01
233  2.7189e-01 9.4951e-01
234  0.0000e+00
235  </var>
236  <region type="voronoi" opt="true">
237  <var name="alpha">1.0</var>
238  </region>
239  </jastrow>)";
240  // test put
241  Libxml2Document doc2;
242  bool parse_cjv = doc2.parseFromString(cj_voronoi_xml);
243  REQUIRE(parse_cjv);
244 
245  xmlNodePtr cjv_root = doc2.getRoot();
246  CountingJastrowBuilder cjvb(c, elec, ion0);
247 
248  // test evaluateLog for cjv
249  auto cjv_uptr = cjvb.buildComponent(cjv_root);
251 
252  for (int i = 0; i < num_els; ++i)
253  {
254  for (int k = 0; k < 3; ++k)
255  elec.G[i][k] = 0;
256  elec.L[i] = 0;
257  }
258 
259  logval = cjv->evaluateLog(elec, elec.G, elec.L);
260  for (int i = 0; i < num_els; ++i)
261  {
262  for (int k = 0; k < 3; ++k)
263  CHECK(Jgrad_exact[i][k] == Approx(std::real(elec.G[i][k])));
264  CHECK(Jlap_exact[i] == Approx(std::real(elec.L[i])));
265  }
266  CHECK(ComplexApprox(Jval_exact) == logval);
267 
268  // test evalGrad
269  for (int iat = 0; iat < num_els; ++iat)
270  {
271  GradType Jgrad_iat = cj->evalGrad(elec, iat);
272  for (int k = 0; k < 3; ++k)
273  CHECK(Jgrad_exact[iat][k] == Approx(std::real(Jgrad_iat[k])));
274  }
275 
276  // reference for ratio, ratioGrad, acceptMove
277  PosType dr[] = {PosType(0.0984629815, 0.0144420719, 0.1334309321),
278  PosType(-0.1026409581, 0.2289767772, 0.490138058592),
279  PosType(0.03517477469, 0.2693941041, 0.16922043039),
280  PosType(0.3851116893, -0.1387760973, 0.1980082182)};
281 
282  RealType ratioval_exact[] = {1.00003304765, 0.987624289443, 0.999873210738, 1.09014860194};
283 
284  PosType Jgrad_t_exact[] = {PosType(4.4329270315e-04, -5.1593699287e-04, 0),
285  PosType(4.8722465115e-02, -5.6707785196e-02, 0),
286  PosType(3.2691265772e-04, -3.8048525335e-04, 0),
287  PosType(2.0373800011e-01, -2.3712542045e-01, 0)};
288 
289  // test ratio, ratioGrad, acceptMove
290  for (int iat = 0; iat < num_els; ++iat)
291  {
292  elec.makeMoveAndCheck(iat, dr[iat]);
293 
294  RealType ratioval = std::real(cj->ratio(elec, iat));
295  CHECK(ratioval_exact[iat] == Approx(std::real(ratioval)));
296 
297  GradType grad_iat(0, 0, 0);
298  RealType gradratioval = std::real(cj->ratioGrad(elec, iat, grad_iat));
299  CHECK(ratioval_exact[iat] == Approx(gradratioval));
300  for (int k = 0; k < 3; ++k)
301  CHECK(Jgrad_t_exact[iat][k] == Approx(std::real(grad_iat[k])));
302 
303  cj->acceptMove(elec, iat);
304  }
305 
306 #ifndef QMC_COMPLEX
307  // setup and reference for evaluateDerivatives
308  PosType R2[] = {PosType(4.3280064837, 2.4657709845, 6.3466520181e-01),
309  PosType(9.7075155012, 7.2984775093, -8.1975111678e-01),
310  PosType(5.7514912378, 5.2001615327, 6.6673589235e-01),
311  PosType(8.3805220665, 7.9424368608, -3.5106422506e-02)};
312  PosType G2[] = {PosType(3.3480105792e-01, 2.1316369526e-01, -4.1812914940e-01),
313  PosType(-7.0561066397e-01, 1.7863210008e-01, 3.5677994771e-01),
314  PosType(-9.2302398033e-01, -5.0740272660e-01, -2.6078603626e-01),
315  PosType(-8.3764545416e-01, -4.9181684009e-01, 1.0675382607e-01)};
316  for (int i = 0; i < num_els; ++i)
317  for (int k = 0; k < 3; ++k)
318  {
319  elec.R[i][k] = R2[i][k];
320  elec.G[i][k] = G2[i][k];
321  }
322 
323  int num_derivs = 39;
324  RealType dlogpsi_exact[] = {7.0982172306e-04, 9.8329357367e-02, 6.6879065207e-03, 1.0670293004e-01,
325  3.4053136887e+00, 4.6322726464e-01, 7.3906096412e+00, 1.5753284303e-02,
326  5.0267496641e-01, -1.3874695168e+00, -2.6249136239e+00, -4.2223002567e+00,
327  -3.0798330637e+00, 3.7905326800e+00, 8.4038996349e+00, 2.2816901707e+00,
328  4.1911712810e+00, -9.3658177215e+00, -1.2434457046e+01, 1.6771424507e+00,
329  2.3712452266e+00, 3.6980955070e+00, 2.5407601111e+00, 1.8976924460e-01,
330  -1.0446470315e+00, -1.2992491105e+00, -8.5624882767e-01, 9.8686287993e+00,
331  1.1847431541e+01, -2.5193792283e-01, -3.0763224769e-01, 1.2429858182e-01,
332  1.3295440602e-02, 6.4178676394e-02, 1.2758462324e-01, 7.5131761426e-02,
333  1.1629004831e-01, 3.9639061816e-01, 6.7088705514e-01};
334  RealType dhpsioverpsi_exact[] = {-1.6695881381e-02, -4.8902571790e-01, -1.2725397012e-01, -6.6714806635e-01,
335  6.9379259933e+00, -4.8393983437e+00, 7.4947765640e+00, -8.8373306290e-01,
336  -6.8244030879e+00, 7.9150085031e-01, -1.4313255643e+00, 3.7225112718e+01,
337  1.7787191536e+01, -1.6672327906e+01, -4.1705496948e+01, -9.9674671566e+00,
338  -2.0150790757e+01, 1.1226368249e+02, 1.2744525474e+02, -1.5801247401e+01,
339  -1.3618595564e+01, -2.8161585388e+01, -1.4057266918e+01, 1.7626748997e+00,
340  7.8913447811e+00, 9.2144952390e+00, 4.6068416473e+00, -9.3975889104e+01,
341  -8.8298321426e+01, 1.5097063606e+01, 1.8605794463e+01, -7.3647009565e+00,
342  -5.9114663448e-01, -3.9243955679e+00, -7.8630886487e+00, -4.4437106408e+00,
343  -7.0313362338e+00, -2.3986142270e+01, -4.0724297500e+01};
344  Vector<ValueType> dlogpsi;
345  Vector<ValueType> dhpsioverpsi;
346  dlogpsi.resize(num_derivs);
347  dhpsioverpsi.resize(num_derivs);
348  std::fill(dlogpsi.begin(), dlogpsi.end(), 0);
349  std::fill(dhpsioverpsi.begin(), dhpsioverpsi.end(), 0);
350 
351  // prepare variable set
352  VariableSet optVars;
353  optVars.clear();
354  cj->checkInVariablesExclusive(optVars);
355  optVars.resetIndex();
356  cj->checkInVariablesExclusive(optVars);
357  cj->checkOutVariables(optVars);
358  optVars.print(std::cout);
359 
360  // test evaluateDerivatives
361  cj->evaluateDerivatives(elec, optVars, dlogpsi, dhpsioverpsi);
362  for (int p = 0; p < num_derivs; ++p)
363  {
364  CHECK(dlogpsi_exact[p] == Approx(std::real(dlogpsi[p])).epsilon(1e-3));
365  CHECK(dhpsioverpsi_exact[p] == Approx(std::real(dhpsioverpsi[p])).epsilon(1e-3));
366  }
367 
368 
369  // test makeClone
370  auto cj2_uptr = cj->makeClone(elec);
372  std::fill(dlogpsi.begin(), dlogpsi.end(), 0);
373  std::fill(dhpsioverpsi.begin(), dhpsioverpsi.end(), 0);
374 
375  // prepare variable set
376  VariableSet optVars2;
377  optVars2.clear();
378  cj2->checkInVariablesExclusive(optVars2);
379  optVars2.resetIndex();
380  cj2->checkInVariablesExclusive(optVars2);
381  cj2->checkOutVariables(optVars2);
382  optVars2.print(std::cout);
383 
384  cj2->evaluateDerivatives(elec, optVars2, dlogpsi, dhpsioverpsi);
385  for (int p = 0; p < num_derivs; ++p)
386  {
387  CHECK(dlogpsi_exact[p] == Approx(std::real(dlogpsi[p])).epsilon(1e-3));
388  CHECK(dhpsioverpsi_exact[p] == Approx(std::real(dhpsioverpsi[p])).epsilon(1e-3));
389  }
390 
391  // test resetParameters, recompute
392  for (int p = 0; p < num_derivs; ++p)
393  optVars[p] = 0;
394  cj->resetParametersExclusive(optVars);
395  cj->recompute(elec);
396  REQUIRE(cj->get_log_value() == LogValue(0));
397 #endif
398 }
399 
400 } //namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
void setName(const std::string &aname)
Definition: ParticleSet.h:237
class that handles xmlDoc
Definition: Libxml2Doc.h:76
PsiValue ratioGrad(ParticleSet &P, int iat, GradType &grad_iat) override
evaluate the ratio of the new to old WaveFunctionComponent value and the new gradient ...
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::GradType GradType
Definition: Configuration.h:62
QTBase::RealType RealType
Definition: Configuration.h:58
void resetParametersExclusive(const opt_variables_type &active) override
reset the parameters during optimizations.
void checkInVariablesExclusive(opt_variables_type &active) final
check in variational parameters to the global list of parameters used by the optimizer.
PsiValue ratio(ParticleSet &P, int iat) override
evaluate the ratio of the new to old WaveFunctionComponent value
void evaluateDerivatives(PosType r, std::vector< RealType > &dfval, std::vector< GradType > &dfgrad, std::vector< RealType > &dflap)
TEST_CASE("complex_helper", "[type_traits]")
GradType evalGrad(ParticleSet &P, int iat) override
return the current gradient for the iat-th particle
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
LatticeGaussianProduct::GradType GradType
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
std::unique_ptr< WaveFunctionComponent > makeClone(ParticleSet &tqp) const override
make clone
Wrapping information on parallelism.
Definition: Communicate.h:68
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
void evaluateLogDerivatives(PosType r, std::vector< RealType > &dlval, std::vector< GradType > &dlgrad, std::vector< RealType > &dllap)
QTBase::ValueType ValueType
Definition: Configuration.h:60
REQUIRE(std::filesystem::exists(filename))
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false) override
a move for iat-th particle is accepted.
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
std::unique_ptr< WaveFunctionComponent > buildComponent(xmlNodePtr cur) override
process a xml node at cur
ParticlePos R
Position.
Definition: ParticleSet.h:79
QTBase::PosType PosType
Definition: Configuration.h:61
void recompute(const ParticleSet &P) override
recompute the value of the WaveFunctionComponents which require critical accuracy.
void evaluateLog(PosType r, RealType &lval, GradType &lgrad, RealType &llap)
void create(const std::vector< int > &agroup)
create grouped particles
void evaluate(PosType r, RealType &fval, GradType &fgrad, RealType &flap)
LogValue evaluateLog(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) override
evaluate the value of the WaveFunctionComponent from scratch
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
LatticeGaussianProduct::ValueType ValueType
bool makeMoveAndCheck(Index_t iat, const SingleParticlePos &displ)
move the iat-th particle to active_pos_
std::complex< double > LogValue
QTBase::TensorType TensorType
Definition: Configuration.h:63
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &active, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi) override
void checkOutVariables(const opt_variables_type &active) override
check out variational optimizable variables