QMCPACK
test_coulomb_pbcAB.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: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
8 // Peter W. Doak, doakpw@ornl.gov, Oak Ridge 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 <ResourceCollection.h>
17 #include "OhmmsData/Libxml2Doc.h"
18 #include "OhmmsPETE/OhmmsMatrix.h"
19 #include "Particle/ParticleSet.h"
23 #include "TestListenerFunction.h"
25 
26 #include <stdio.h>
27 #include <string>
28 
29 using std::string;
30 
31 namespace qmcplusplus
32 {
33 
34 using QMCT = QMCTraits;
35 using Real = QMCT::RealType;
36 
37 TEST_CASE("Coulomb PBC A-B", "[hamiltonian]")
38 {
40 
42  lattice.BoxBConds = true; // periodic
43  lattice.R.diagonal(1.0);
44  lattice.reset();
45 
46  const SimulationCell simulation_cell(lattice);
47  ParticleSet ions(simulation_cell);
48  ParticleSet elec(simulation_cell);
49 
50  ions.setName("ion");
51  ions.create({1});
52  ions.R[0] = {0.0, 0.0, 0.0};
53  SpeciesSet& ion_species = ions.getSpeciesSet();
54  int pIdx = ion_species.addSpecies("H");
55  int pChargeIdx = ion_species.addAttribute("charge");
56  ion_species(pChargeIdx, pIdx) = 1;
57  ions.createSK();
58  ions.update();
59 
60 
61  elec.setName("elec");
62  elec.create({1});
63  elec.R[0] = {0.5, 0.0, 0.0};
64  SpeciesSet& tspecies = elec.getSpeciesSet();
65  int upIdx = tspecies.addSpecies("u");
66  int chargeIdx = tspecies.addAttribute("charge");
67  int massIdx = tspecies.addAttribute("mass");
68  tspecies(chargeIdx, upIdx) = -1;
69  tspecies(massIdx, upIdx) = 1.0;
70 
71  elec.resetGroups();
72  elec.createSK();
73  elec.addTable(ions);
74  elec.update();
75 
76 
77  CoulombPBCAB cab(ions, elec);
78 
79  // Self energy plus Background charge term
80  CHECK(cab.myConst == Approx(2 * 0.0506238028)); // not validated
81 
82  double val_ei = cab.evaluate(elec);
83  CHECK(val_ei == Approx(-0.005314032183 + 2 * 0.0506238028)); // not validated
84 
85  CoulombPBCAA caa_elec(elec, true, false, false);
86  CoulombPBCAA caa_ion(ions, false, false, false);
87  double val_ee = caa_elec.evaluate(elec);
88  double val_ii = caa_ion.evaluate(ions);
89  double sum = val_ee + val_ii + val_ei;
90  CHECK(sum == Approx(-2.741363553)); // Can be validated via Ewald summation elsewhere
91  // -2.74136517454081
92 }
93 
94 TEST_CASE("Coulomb PBC A-B BCC H", "[hamiltonian]")
95 {
97 
99  lattice.BoxBConds = true; // periodic
100  lattice.R.diagonal(3.77945227);
101  lattice.reset();
102 
103  const SimulationCell simulation_cell(lattice);
104  ParticleSet ions(simulation_cell);
105  ParticleSet elec(simulation_cell);
106 
107  ions.setName("ion");
108  ions.create({2});
109  ions.R[0] = {0.0, 0.0, 0.0};
110  ions.R[1] = {1.88972614, 1.88972614, 1.88972614};
111  SpeciesSet& ion_species = ions.getSpeciesSet();
112  int pIdx = ion_species.addSpecies("H");
113  int pChargeIdx = ion_species.addAttribute("charge");
114  ion_species(pChargeIdx, pIdx) = 1;
115  ions.createSK();
116  ions.update();
117 
118  elec.setName("elec");
119  elec.create({2});
120  elec.R[0] = {0.5, 0.0, 0.0};
121  elec.R[1] = {0.0, 0.5, 0.0};
122  SpeciesSet& tspecies = elec.getSpeciesSet();
123  int upIdx = tspecies.addSpecies("u");
124  int chargeIdx = tspecies.addAttribute("charge");
125  int massIdx = tspecies.addAttribute("mass");
126  tspecies(chargeIdx, upIdx) = -1;
127  tspecies(massIdx, upIdx) = 1.0;
128 
129  elec.resetGroups();
130  elec.createSK();
131  elec.addTable(ions);
132  elec.update();
133 
134  CoulombPBCAB cab(ions, elec);
135 
136  // Background charge term
137  double consts = cab.evalConsts(elec);
138  CHECK(consts == Approx(0.0267892759 * 4)); // not validated
139 
140 
141  double val_ei = cab.evaluate(elec);
142  CHECK(val_ei == Approx(-2.219665062 + 0.0267892759 * 4)); // not validated
143 
144 
145  CoulombPBCAA caa_elec(elec, false, false, false);
146  CoulombPBCAA caa_ion(ions, false, false, false);
147  double val_ee = caa_elec.evaluate(elec);
148  double val_ii = caa_ion.evaluate(ions);
149  double sum = val_ee + val_ii + val_ei;
150  CHECK(sum == Approx(-3.143491064)); // Can be validated via Ewald summation elsewhere
151  // -3.14349127313640
152 }
153 
154 TEST_CASE("CoulombAB::Listener", "[hamiltonian]")
155 {
157 
159 
161  lattice.BoxBConds = true; // periodic
162  lattice.R.diagonal(3.77945227);
163  lattice.reset();
164 
165  const SimulationCell simulation_cell(lattice);
166 
167  ParticleSet ions(simulation_cell);
168 
169  ions.setName("ion");
170  ions.create({2});
171  ions.R[0] = {0.0, 0.0, 0.0};
172  ions.R[1] = {1.88972614, 1.88972614, 1.88972614};
173  SpeciesSet& ion_species = ions.getSpeciesSet();
174  int pIdx = ion_species.addSpecies("H");
175  int pChargeIdx = ion_species.addAttribute("charge");
176  ion_species(pChargeIdx, pIdx) = 1;
177  ions.createSK();
178  ions.update();
179  ions.turnOnPerParticleSK();
180 
181  ParticleSet ions2(ions);
182  ions2.update();
183 
184  ParticleSet elec(simulation_cell);
185 
186  elec.setName("elec");
187  elec.create({2});
188  elec.R[0] = {0.0, 0.5, 0.0};
189  elec.R[1] = {0.0, 0.5, 0.0};
190  SpeciesSet& tspecies = elec.getSpeciesSet();
191  int upIdx = tspecies.addSpecies("u");
192  int chargeIdx = tspecies.addAttribute("charge");
193  int massIdx = tspecies.addAttribute("mass");
194  tspecies(chargeIdx, upIdx) = -1;
195  tspecies(massIdx, upIdx) = 1.0;
196 
197  elec.createSK();
198  elec.update();
199  elec.turnOnPerParticleSK();
200 
201  ParticleSet elec2(elec);
202 
203  elec2.R[0] = {0.0, 0.5, 0.1};
204  elec2.R[1] = {0.6, 0.05, -0.1};
205  elec2.update();
206 
207  CoulombPBCAB cab(ions, elec, false);
208  CoulombPBCAB cab2(ions2, elec2, false);
209  RefVector<OperatorBase> cabs{cab, cab2};
210  RefVectorWithLeader<OperatorBase> o_list(cab, cabs);
211  // Self-energy correction, no background charge for e-e interaction
212  double consts = cab.evalConsts(elec);
213  CHECK(consts == Approx(0.0267892759 * 4));
214  RefVector<ParticleSet> ptcls{elec, elec2};
215  RefVectorWithLeader<ParticleSet> p_list(elec, ptcls);
216 
217  RefVector<ParticleSet> ion_ptcls{ions, ions2};
218  RefVectorWithLeader<ParticleSet> ion_p_list(ions, ion_ptcls);
219 
220  RuntimeOptions runtime_options;
221  TrialWaveFunction psi(runtime_options);
222  TrialWaveFunction psi_clone(runtime_options);
223  RefVectorWithLeader<TrialWaveFunction> twf_list(psi, {psi, psi_clone});
224 
225  Matrix<Real> local_pots(2);
226  Matrix<Real> local_pots2(2);
227 
228  ResourceCollection cab_res("test_cab_res");
229  cab.createResource(cab_res);
230  ResourceCollectionTeamLock<OperatorBase> cab_lock(cab_res, o_list);
231 
232  ResourceCollection pset_res("test_pset_res");
233  elec.createResource(pset_res);
234  ResourceCollectionTeamLock<ParticleSet> pset_lock(pset_res, p_list);
235 
236  std::vector<ListenerVector<Real>> listeners;
237  listeners.emplace_back("localpotential", getParticularListener(local_pots));
238  listeners.emplace_back("localpotential", getParticularListener(local_pots2));
239 
240  Matrix<Real> ion_pots(2);
241  Matrix<Real> ion_pots2(2);
242 
243  std::vector<ListenerVector<Real>> ion_listeners;
244  ion_listeners.emplace_back("localpotential", getParticularListener(ion_pots));
245  ion_listeners.emplace_back("localpotential", getParticularListener(ion_pots2));
246 
247  ParticleSet::mw_update(p_list);
248  cab.mw_evaluatePerParticle(o_list, twf_list, p_list, listeners, ion_listeners);
249  CHECK(cab.getValue() == Approx(-2.219665062 + 0.0267892759 * 4));
250  CHECK(cab2.getValue() == Approx(-1.7222343352));
251  // Check that the sum of the particle energies == the total
252  Real elec_ion_sum = std::accumulate(local_pots.begin(), local_pots.begin() + local_pots.cols(), 0.0);
253  CHECK(elec_ion_sum == Approx(-1.0562537047));
254  CHECK(elec_ion_sum + std::accumulate(ion_pots.begin(), ion_pots.begin() + ion_pots.cols(), 0.0) ==
255  Approx(-2.219665062 + 0.0267892759 * 4));
256  elec_ion_sum = std::accumulate(local_pots[1], local_pots[1] + local_pots.cols(), 0.0);
257  CHECK(elec_ion_sum == Approx(-0.8611171676));
258  CHECK(elec_ion_sum + std::accumulate(ion_pots[1], ion_pots[1] + ion_pots.cols(), 0.0) == Approx(-1.7222343352));
259 }
260 
261 
262 } // namespace qmcplusplus
a class that defines a supercell in D-dimensional Euclean space.
void setName(const std::string &aname)
Definition: ParticleSet.h:237
Container_t::iterator begin()
Definition: OhmmsMatrix.h:89
Return_t evaluate(ParticleSet &P) override
Evaluate the local energy contribution of this component.
Calculates the AA Coulomb potential using PBCs.
Definition: CoulombPBCAA.h:38
Return_t myConst
const energy after breakup
Definition: CoulombPBCAB.h:61
int addSpecies(const std::string &aname)
When a name species does not exist, add a new species.
Definition: SpeciesSet.cpp:33
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
Calculates the AA Coulomb potential using PBCs.
Definition: CoulombPBCAB.h:38
QTBase::RealType RealType
Definition: Configuration.h:58
TEST_CASE("complex_helper", "[type_traits]")
void createResource(ResourceCollection &collection) const
initialize a shared resource and hand it to a collection
void update(bool skipSK=false)
update the internal data
static std::unique_ptr< LRHandlerType > CoulombHandler
Stores the energ optimized LR handler.
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
ForceBase::Real Real
Definition: ForceBase.cpp:26
size_type cols() const
Definition: OhmmsMatrix.h:78
void turnOnPerParticleSK()
Turn on per particle storage in Structure Factor.
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
void createResource(ResourceCollection &collection) const override
initialize a shared resource and hand it to a collection
ParticlePos R
Position.
Definition: ParticleSet.h:79
auto getParticularListener(Matrix< T > &local_pots)
Return_t getValue() const noexcept
get a copy of value_
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
void create(const std::vector< int > &agroup)
create grouped particles
Declaration of a TrialWaveFunction.
std::vector< std::reference_wrapper< T > > RefVector
Class to represent a many-body trial wave function.
static void mw_update(const RefVectorWithLeader< ParticleSet > &p_list, bool skipSK=false)
batched version of update
CHECK(log_values[0]==ComplexApprox(std::complex< double >{ 5.603777579195571, -6.1586603331188225 }))
handles acquire/release resource by the consumer (RefVectorWithLeader type).
void createSK()
create Structure Factor with PBCs
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
void mw_evaluatePerParticle(const RefVectorWithLeader< OperatorBase > &o_list, const RefVectorWithLeader< TrialWaveFunction > &wf_list, const RefVectorWithLeader< ParticleSet > &p_list, const std::vector< ListenerVector< RealType >> &listeners, const std::vector< ListenerVector< RealType >> &ion_listeners) const override
Evaluate the contribution of this component of multiple walkers per particle reporting to registered ...
Return_t evaluate(ParticleSet &P) override
Evaluate the local energy contribution of this component.
Return_t evalConsts(const ParticleSet &P, bool report=true)
Evaluates madelung and background contributions to total energy.