Skip to content

Commit d27cab8

Browse files
authored
Merge pull request #4800 from PDoakORNL/reference_points
Class for handling reference points in EnergyDensityEstimator
2 parents 42c1712 + e48ea4d commit d27cab8

9 files changed

+917
-3
lines changed

src/Estimators/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ set(QMCEST_SRC
3333
MagnetizationDensity.cpp
3434
MagnetizationDensityInput.cpp
3535
PerParticleHamiltonianLoggerInput.cpp
36-
PerParticleHamiltonianLogger.cpp)
36+
PerParticleHamiltonianLogger.cpp
37+
ReferencePointsInput.cpp
38+
NEReferencePoints.cpp)
3739

3840
####################################
3941
# create libqmcestimators

src/Estimators/NEReferencePoints.cpp

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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) 2023 QMCPACK developers.
6+
//
7+
// File developed by: Jaron T. Krogel, [email protected], Oak Ridge National Laboratory
8+
// Mark A. Berrill, [email protected], Oak Ridge National Laboratory
9+
// Peter W. Doak. [email protected], Oak Ridge National Laboratory
10+
//
11+
// File refactored from: QMCHamiltonian/ReferencePoints.cpp
12+
//////////////////////////////////////////////////////////////////////////////////////
13+
14+
15+
#include "NEReferencePoints.h"
16+
#include "Utilities/string_utils.h"
17+
#include "OhmmsData/AttributeSet.h"
18+
#include "QMCHamiltonians/ObservableHelper.h"
19+
20+
namespace qmcplusplus
21+
{
22+
23+
NEReferencePoints::NEReferencePoints(const ReferencePointsInput& rp_input,
24+
const ParticleSet& pset,
25+
RefVector<ParticleSet>& ref_psets)
26+
: input_(rp_input)
27+
{
28+
processParticleSets(pset, ref_psets);
29+
for (int i = 0; i < OHMMS_DIM; i++)
30+
for (int d = 0; d < OHMMS_DIM; d++)
31+
axes(d, i) = pset.getLattice().a(i)[d];
32+
Axes crd;
33+
// no need to handle error here rp_input will have a valid value for coord_form
34+
switch (input_.get_coord_form())
35+
{
36+
case Coord::CELL:
37+
crd = axes;
38+
break;
39+
case Coord::CARTESIAN:
40+
for (int i = 0; i < OHMMS_DIM; i++)
41+
for (int d = 0; d < OHMMS_DIM; d++)
42+
if (d == i)
43+
crd(i, i) = 1.0;
44+
else
45+
crd(d, i) = 0.0;
46+
break;
47+
}
48+
49+
for (const auto& [key, value] : input_.get_points())
50+
points_[key] = dot(crd, value);
51+
}
52+
53+
void NEReferencePoints::processParticleSets(const ParticleSet& P, RefVector<ParticleSet>& Psets)
54+
{
55+
//get axes and origin information from the ParticleSet
56+
points_["zero"] = 0 * P.getLattice().a(0);
57+
points_["a1"] = P.getLattice().a(0);
58+
points_["a2"] = P.getLattice().a(1);
59+
points_["a3"] = P.getLattice().a(2);
60+
//points_["center"]= .5*(P.getLattice().a(0)+P.getLattice().a(1)+P.Lattice.a(2))
61+
//set points_ on face centers
62+
points_["f1p"] = points_["zero"] + .5 * points_["a1"];
63+
points_["f1m"] = points_["zero"] - .5 * points_["a1"];
64+
points_["f2p"] = points_["zero"] + .5 * points_["a2"];
65+
points_["f2m"] = points_["zero"] - .5 * points_["a2"];
66+
points_["f3p"] = points_["zero"] + .5 * points_["a3"];
67+
points_["f3m"] = points_["zero"] - .5 * points_["a3"];
68+
//set points_ on cell corners
69+
points_["cmmm"] = points_["zero"] + .5 * (-1 * points_["a1"] - points_["a2"] - points_["a3"]);
70+
points_["cpmm"] = points_["zero"] + .5 * (points_["a1"] - points_["a2"] - points_["a3"]);
71+
points_["cmpm"] = points_["zero"] + .5 * (-1 * points_["a1"] + points_["a2"] - points_["a3"]);
72+
points_["cmmp"] = points_["zero"] + .5 * (-1 * points_["a1"] - points_["a2"] + points_["a3"]);
73+
points_["cmpp"] = points_["zero"] + .5 * (-1 * points_["a1"] + points_["a2"] + points_["a3"]);
74+
points_["cpmp"] = points_["zero"] + .5 * (points_["a1"] - points_["a2"] + points_["a3"]);
75+
points_["cppm"] = points_["zero"] + .5 * (points_["a1"] + points_["a2"] - points_["a3"]);
76+
points_["cppp"] = points_["zero"] + .5 * (points_["a1"] + points_["a2"] + points_["a3"]);
77+
//get points from requested particle sets
78+
int cshift = 1;
79+
for (ParticleSet& pset : Psets)
80+
{
81+
for (int p = 0; p < pset.getTotalNum(); p++)
82+
{
83+
std::stringstream ss;
84+
ss << p + cshift;
85+
points_[pset.getName() + ss.str()] = pset.R[p];
86+
}
87+
}
88+
}
89+
90+
void NEReferencePoints::write_description(std::ostream& os, const std::string& indent) const
91+
{
92+
os << indent + "reference_points" << std::endl;
93+
std::map<std::string, Point>::const_iterator it, end = points_.end();
94+
for (it = points_.begin(); it != end; ++it)
95+
{
96+
os << indent + " " << it->first << ": " << it->second << std::endl;
97+
}
98+
os << indent + "end reference_points" << std::endl;
99+
return;
100+
}
101+
102+
void NEReferencePoints::write(hdf_archive& file) const
103+
{
104+
file.push(std::string_view("reference_points"));
105+
for (auto it = points_.cbegin(); it != points_.cend(); ++it)
106+
file.write(const_cast<Point&>(it->second), it->first);
107+
file.pop();
108+
}
109+
110+
std::ostream& operator<<(std::ostream& out, const NEReferencePoints& rhs)
111+
{
112+
rhs.write_description(out, "");
113+
return out;
114+
}
115+
116+
} // namespace qmcplusplus

src/Estimators/NEReferencePoints.h

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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) 2023 QMCPACK developers.
6+
//
7+
// File developed by: Jaron T. Krogel, [email protected], Oak Ridge National Laboratory
8+
// Mark A. Berrill, [email protected], Oak Ridge National Laboratory
9+
// Peter W. Doak. [email protected], Oak Ridge National Laboratory
10+
//
11+
// File refactored from: QMCHamiltonian/ReferencePoints.h
12+
//////////////////////////////////////////////////////////////////////////////////////
13+
14+
#ifndef QMCPLUSPLUS_NEREFERENCE_POINTS_H
15+
#define QMCPLUSPLUS_NEREFERENCE_POINTS_H
16+
17+
/** @file
18+
* \todo When QMCHamiltonian/ReferencePoints is removed rename this class to ReferencePoints
19+
*/
20+
21+
#include <Configuration.h>
22+
#include "OhmmsData/OhmmsElementBase.h"
23+
#include "Particle/ParticleSet.h"
24+
#include "QMCHamiltonians/ObservableHelper.h"
25+
#include "OhmmsPETE/Tensor.h"
26+
#include "ReferencePointsInput.h"
27+
28+
namespace qmcplusplus
29+
{
30+
31+
/** This class creates, contains, and writes both user and machine readable referencepoints.
32+
* they are derived from the lattice of the pset passed and the particle positions in the ref_psets
33+
* an arbitrary number of additional points can be defined in the input that ReferencePointsInput
34+
* presents as native input.
35+
* It is a dependency of Estimators/NESpaceGrid and Estimatorss/EnergyDensityEstimator
36+
*/
37+
class NEReferencePoints
38+
{
39+
public:
40+
using Real = QMCTraits::RealType;
41+
using Axes = Tensor<Real, OHMMS_DIM>;
42+
using Point = TinyVector<Real, OHMMS_DIM>;
43+
using Points = std::map<std::string, Point>;
44+
using Coord = typename ReferencePointsInput::Coord;
45+
/** Usual constructor
46+
* \param[in] rp_input Input object for reference points which can contain and arbitrary set of points beyond
47+
* those take from the pset, and ref_psets
48+
* \param[in] pset pset that supplies the lattice information for reference points
49+
* \param[in] ref_psets pset reference vector the particle points in this/these psets are reference points
50+
*/
51+
NEReferencePoints(const ReferencePointsInput& rp_input, const ParticleSet& pset, RefVector<ParticleSet>& ref_psets);
52+
NEReferencePoints(const NEReferencePoints& nerp) = default;
53+
54+
/** writes a human readable representation of the reference points.
55+
* \param[inout] os ostream to write description to
56+
* \param[in] indent spaces or other text to preface each line of output with. needed to preserve
57+
* legacy output format.
58+
*/
59+
void write_description(std::ostream& os, const std::string& indent) const;
60+
61+
/** machine readable output
62+
* \param[inout] file hdf5 file to write to. Respects current state of file.
63+
*/
64+
void write(hdf_archive& file) const;
65+
66+
/** return const ref to map of reference points.
67+
* labeling scheme unchanged from legacy
68+
*/
69+
const Points& get_points() const { return points_; }
70+
71+
protected:
72+
Points points_;
73+
private:
74+
void processParticleSets(const ParticleSet& P, RefVector<ParticleSet>& Pref);
75+
Axes axes;
76+
ReferencePointsInput input_;
77+
};
78+
79+
std::ostream& operator<<(std::ostream& out, const NEReferencePoints& rhs);
80+
81+
}
82+
#endif
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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: Jaron T. Krogel, [email protected], Oak Ridge National Laboratory
8+
// Mark A. Berrill, [email protected], Oak Ridge National Laboratory
9+
// Peter W. Doak, [email protected], Oak Ridge National Laboratory
10+
//
11+
// Some code refactored from: QMCHamiltonians/ReferencePoints.cpp
12+
//////////////////////////////////////////////////////////////////////////////////////
13+
14+
#include "ReferencePointsInput.h"
15+
16+
#include <sstream>
17+
18+
#include "EstimatorInput.h"
19+
#include "ModernStringUtils.hpp"
20+
21+
namespace qmcplusplus
22+
{
23+
24+
ReferencePointsInput::ReferencePointsInput(xmlNodePtr cur)
25+
{
26+
input_section_.readXML(cur);
27+
auto setIfInInput = LAMBDA_setIfInInput;
28+
setIfInInput(coord_form_, "coord");
29+
readRefPointsXML(cur);
30+
}
31+
32+
// ReferencePointsInput::ReferencePointsInput(const Points& points, const CoordForm coord_form)
33+
// : points_(points), coord_form_(coord_form)
34+
// {}
35+
36+
void ReferencePointsInput::readRefPointsXML(xmlNodePtr cur)
37+
{
38+
using modernstrutil::split;
39+
using modernstrutil::strip;
40+
41+
// read refpoints values they are some sequence of value nodes
42+
std::string node_str{XMLNodeString{cur}};
43+
std::vector<std::string_view> lines = split(strip(node_str), "\n");
44+
for (int i = 0; i < lines.size(); i++)
45+
{
46+
auto stripped_line = strip(lines[i]);
47+
std::vector<std::string_view> tokens = split(stripped_line, " ");
48+
if (tokens.size() != OHMMS_DIM + 1)
49+
{
50+
std::ostringstream error;
51+
error << error_tag << "reference point has 4 entries, given " << tokens.size() << ": " << lines[i];
52+
throw UniformCommunicateError(error.str());
53+
}
54+
else
55+
{
56+
Point rp;
57+
for (int d = 0; d < OHMMS_DIM; d++)
58+
{
59+
try
60+
{
61+
rp[d] = std::stod(std::string(tokens[d + 1].begin(), tokens[d + 1].size()));
62+
}
63+
catch (const std::invalid_argument& ia)
64+
{
65+
throw UniformCommunicateError(ia.what());
66+
}
67+
}
68+
69+
// This must be done in constructor of ReferencePoints
70+
// rp = dot(crd, rp);
71+
points_[std::string(tokens[0].begin(), tokens[0].size())] = rp;
72+
}
73+
}
74+
}
75+
76+
std::any ReferencePointsInput::ReferencePointsInputSection::assignAnyEnum(const std::string& name) const
77+
{
78+
return lookupAnyEnum(name, get<std::string>(name), lookup_input_enum_value);
79+
}
80+
81+
std::any makeReferencePointsInput(xmlNodePtr cur, std::string& value_label)
82+
{
83+
ReferencePointsInput rpi{cur};
84+
value_label = "referencepoints";
85+
return rpi;
86+
}
87+
88+
} // namespace qmcplusplus

0 commit comments

Comments
 (0)