QMCPACK
test_PairCorrEstimator.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: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
8 //
9 // File created by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "catch.hpp"
14 #include "OhmmsData/Libxml2Doc.h"
15 #include "Lattice/CrystalLattice.h"
16 #include "Particle/ParticleSet.h"
17 #include "Particle/DistanceTable.h"
20 
21 #include <stdio.h>
22 #include <string>
23 
24 using std::string;
25 
26 
27 /*
28  Minimal input block (based off HEG problem).
29  This is a dumb way to construct a test, but I can't figure out
30  the right way to initialize a ParticleSet, so instead hijack
31  the ParticleSetPool class to make a ParticleSet for me.
32 
33  NB: Hardcoded 8 particles (4 each of u/d) on a B1 (NaCl) lattice.
34 */
35 
36 // Lattice block
37 const char* lat_xml = R"(<simulationcell>
38  <parameter name="lattice" units="bohr">
39  2.0 0.0 0.0
40  0.0 2.0 0.0
41  0.0 0.0 2.0
42  </parameter>
43  <parameter name="bconds">
44  p p p
45  </parameter>
46  <parameter name="LR_dim_cutoff" > 6 </parameter>
47  </simulationcell>)";
48 
49 // Particleset block
50 const char* pset_xml = R"(<particleset name="e" random="yes">
51  <group name="u" size="4" mass="1.0">
52  <parameter name="charge" > -1 </parameter>
53  <parameter name="mass" > 1.0 </parameter>
54  </group>
55  <group name="d" size="4" mass="1.0">
56  <parameter name="charge" > -1 </parameter>
57  <parameter name="mass" > 1.0 </parameter>
58  </group>
59  </particleset>)";
60 
61 // PairCorrEstimator block
62 const char* gofr_xml = R"(<estimator type="gofr" name="gofr" rmax="2.0" num_bin="99" />)";
63 
64 
65 namespace qmcplusplus
66 {
67 TEST_CASE("Pair Correlation", "[hamiltonian]")
68 {
69  std::cout << std::fixed;
70  std::cout << std::setprecision(8);
72 
74 
75  // XML parser
77 
78  std::cout << "\n\n\ntest_paircorr:: START\n";
79 
80  // TEST new idea: ParticlesetPool to make a ParticleSet
81  bool lat_okay = doc.parseFromString(lat_xml);
82  REQUIRE(lat_okay);
83  xmlNodePtr lat_xml_root = doc.getRoot();
84 
85  ParticleSetPool pset_builder(c, "pset_builder");
86  pset_builder.readSimulationCellXML(lat_xml_root); // Builds lattice
87 
88  bool pset_okay = doc.parseFromString(pset_xml);
89  REQUIRE(pset_okay);
90  xmlNodePtr pset_xml_root = doc.getRoot();
91  pset_builder.put(pset_xml_root); // Builds ParticleSet
92 
93  // Get the (now assembled) ParticleSet, do simple sanity checks, then print info
94  ParticleSet* elec = pset_builder.getParticleSet("e");
95 
96  std::cout << "cheeeee " << elec->getLattice().R << std::endl;
97  REQUIRE(elec->isSameMass());
98  REQUIRE(elec->getName() == "e");
99 
100  // Move the particles manually onto B1 lattice
101  // NB: Spins are grouped contiguously
102  // Up spins
103  elec->R[0][0] = 0.0;
104  elec->R[0][1] = 0.0;
105  elec->R[0][2] = 0.0;
106  elec->R[1][0] = 1.0;
107  elec->R[1][1] = 1.0;
108  elec->R[1][2] = 0.0;
109  elec->R[2][0] = 1.0;
110  elec->R[2][1] = 0.0;
111  elec->R[2][2] = 1.0;
112  elec->R[3][0] = 0.0;
113  elec->R[3][1] = 1.0;
114  elec->R[3][2] = 1.0;
115 
116  // Down spins
117  elec->R[4][0] = 1.0;
118  elec->R[4][1] = 0.0;
119  elec->R[4][2] = 0.0;
120  elec->R[5][0] = 0.0;
121  elec->R[5][1] = 1.0;
122  elec->R[5][2] = 0.0;
123  elec->R[6][0] = 0.0;
124  elec->R[6][1] = 0.0;
125  elec->R[6][2] = 1.0;
126  elec->R[7][0] = 1.0;
127  elec->R[7][1] = 1.0;
128  elec->R[7][2] = 1.0;
129 
130  elec->get(std::cout); // print particleset info to stdout
131 
132  // Set up the distance table, match expected layout
133  const int ee_table_id = elec->addTable(*elec);
134 
135  const auto& dii(elec->getDistTable(ee_table_id));
136  elec->update(); // distance table evaluation here
137 
138  // Make a PairCorrEstimator, call put() to set up internals
139  std::string name = elec->getName();
140  PairCorrEstimator paircorr(*elec, name);
141  bool gofr_okay = doc.parseFromString(gofr_xml);
142  REQUIRE(gofr_okay);
143  xmlNodePtr gofr_xml_root = doc.getRoot();
144  paircorr.put(gofr_xml_root);
145  paircorr.addObservables(elec->PropertyList, elec->Collectables);
146 
147  // Compute g(r) then print it to stdout
148  // NB: Hardcoded to match hardcoded xml above. ***Fragile!!!***
149  paircorr.evaluate(*elec);
150 
151  // Hardcoded gofr parameters - MUST match xml input for PairCorrEstimator!!!
152  // This might cause a segfault if it does not match xml input!
153  const RealType Rmax = 2.0;
154  const int Nbins = 99;
155  const RealType deltaR = Rmax / static_cast<RealType>(Nbins);
156 
157  auto gofr = elec->Collectables;
158  std::cout << "\n";
159  std::cout << "gofr:\n";
160  std::cout << std::fixed;
161  std::cout << std::setprecision(6);
162  std::cout << std::setw(4) << "i"
163  << " " << std::setw(12) << "r"
164  << " " << std::setw(12) << "uu"
165  << " " << std::setw(12) << "ud"
166  << " " << std::setw(12) << "dd"
167  << "\n";
168  std::cout << "============================================================\n";
169 
170  for (int i = 0; i < Nbins; i++)
171  {
172  std::cout << std::setw(4) << i << " " << std::setw(12) << i * deltaR << " " << std::setw(12) << gofr[i] << " "
173  << std::setw(12) << gofr[i + Nbins] << " " << std::setw(12) << gofr[i + 2 * Nbins] << "\n";
174  }
175 
176  // Verify against analytic result.
177  // NB: At the moment the tolerance is fairly loose because there
178  // is about 0.08-0.01 disagreement between QMCPACK and analytic
179  // result, depending on the bin. I'm not sure about the source
180  // of the disagreement because norm_factor is now exact.
181  // The only thing left is the distance table (I think)...
182  const RealType eps = 1E-02; // tolerance
183 
184  // Nearest neighbor peak (ud) | Distance = 1
185  const int bin_nn = 49;
186  REQUIRE(std::fabs(gofr[49] - 0.00000000) < eps);
187  REQUIRE(std::fabs(gofr[148] - 23.6361163) < eps);
188  REQUIRE(std::fabs(gofr[247] - 0.00000000) < eps);
189 
190  // 2nd-nearest neighbor peak (uu/dd) | Distance = sqrt(2)
191  const int bin_2n = 70;
192  REQUIRE(std::fabs(gofr[70] - 15.536547) < eps);
193  REQUIRE(std::fabs(gofr[169] - 0.0000000) < eps);
194  REQUIRE(std::fabs(gofr[268] - 15.536547) < eps);
195 
196  // 3rd-nearest neighbor peak (ud) | Distance = sqrt(3)
197  REQUIRE(std::fabs(gofr[85] - 0.00000000) < eps);
198  REQUIRE(std::fabs(gofr[184] - 2.6408410) < eps);
199  REQUIRE(std::fabs(gofr[283] - 0.0000000) < eps);
200 
201  std::cout << "test_paircorr:: STOP\n";
202 }
203 
204 TEST_CASE("Pair Correlation Pair Index", "[hamiltonian]")
205 {
206  // Check generation of pair id for 2 species groups
211 
212  // Check generation of pair id for 3 species groups
222 }
223 } // namespace qmcplusplus
class that handles xmlDoc
Definition: Libxml2Doc.h:76
const std::string & getName() const
return the name
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
bool put(xmlNodePtr cur)
process an xml element
Return_t evaluate(ParticleSet &P) override
Evaluate the local energy contribution of this component.
TEST_CASE("complex_helper", "[type_traits]")
xmlNodePtr getRoot()
Definition: Libxml2Doc.h:88
bool put(xmlNodePtr cur) override
Read the input parameter.
void update(bool skipSK=false)
update the internal data
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
Declaration of CrystalLattice<T,D>
PropertySetType PropertyList
name-value map of Walker Properties
Definition: ParticleSet.h:112
Wrapping information on parallelism.
Definition: Communicate.h:68
const char * gofr_xml
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
REQUIRE(std::filesystem::exists(filename))
ParticleSet * getParticleSet(const std::string &pname)
get a named ParticleSet
Manage a collection of ParticleSet objects.
ParticlePos R
Position.
Definition: ParticleSet.h:79
void addObservables(PropertySetType &plist)
auto & getDistTable(int table_ID) const
get a distance table by table_ID
Definition: ParticleSet.h:190
Buffer_t Collectables
observables in addition to those registered in Properties/PropertyList
Definition: ParticleSet.h:126
const char * lat_xml
bool readSimulationCellXML(xmlNodePtr cur)
initialize the supercell shared by all the particle sets
const char * pset_xml
bool parseFromString(const std::string_view data)
Definition: Libxml2Doc.cpp:204
static int gen_pair_id(const int ig, const int jg, const int ns)
generate the unique pair id from the group ids of particle i and j and the number of species ...
const auto & getLattice() const
Definition: ParticleSet.h:251
bool get(std::ostream &os) const override
dummy. For satisfying OhmmsElementBase.
Declaration of ParticleSetPool.