diff --git a/external_codes/github_actions/auto_rebase.sh b/external_codes/github_actions/auto-rebase.sh similarity index 100% rename from external_codes/github_actions/auto_rebase.sh rename to external_codes/github_actions/auto-rebase.sh diff --git a/src/Estimators/CSEnergyEstimator.cpp b/src/Estimators/CSEnergyEstimator.cpp index c874e0ac27..618062e639 100644 --- a/src/Estimators/CSEnergyEstimator.cpp +++ b/src/Estimators/CSEnergyEstimator.cpp @@ -27,7 +27,7 @@ namespace qmcplusplus * @param h QMCHamiltonian to define the components * @param hcopy number of copies of QMCHamiltonians */ -CSEnergyEstimator::CSEnergyEstimator(QMCHamiltonian& h, int hcopy) +CSEnergyEstimator::CSEnergyEstimator(const QMCHamiltonian& h, int hcopy) { int NumObservables = h.sizeOfObservables(); @@ -45,6 +45,25 @@ CSEnergyEstimator::CSEnergyEstimator(QMCHamiltonian& h, int hcopy) scalars_saved.resize(scalars.size()); } +CSEnergyEstimator::CSEnergyEstimator(CSLocalEnergyInput&& input, const QMCHamiltonian& h) : input_(input) +{ + int NumObservables = h.sizeOfObservables(); + + NumCopies = input_.get_n_psi(); + FirstHamiltonian = h.startIndex(); + LastHamiltonian = FirstHamiltonian + NumObservables; + + //add names + h_components.push_back("LocEne"); + h_components.push_back("LocPot"); + for (int i = 0; i < NumObservables; ++i) + h_components.push_back(h.getObservableName(i)); + + scalars.resize(NumCopies + h_components.size() * (NumCopies + NumCopies * (NumCopies - 1) / 2)); + scalars_saved.resize(scalars.size()); +} + + CSEnergyEstimator* CSEnergyEstimator::clone() { return new CSEnergyEstimator(*this); } /** add the local energy, variance and all the Hamiltonian components to the scalar record container diff --git a/src/Estimators/CSEnergyEstimator.h b/src/Estimators/CSEnergyEstimator.h index 761a03d332..cc656b7020 100644 --- a/src/Estimators/CSEnergyEstimator.h +++ b/src/Estimators/CSEnergyEstimator.h @@ -2,12 +2,13 @@ // This file is distributed under the University of Illinois/NCSA Open Source License. // See LICENSE file in top directory for details. // -// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers. +// Copyright (c) 2022 QMCPACK developers. // // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory // // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign ////////////////////////////////////////////////////////////////////////////////////// @@ -17,6 +18,7 @@ #define QMCPLUSPLUS_CORRELATEDLOCALENERGYESTIMATOR_H #include "Estimators/ScalarEstimatorBase.h" +#include "ScalarEstimatorInputs.h" namespace qmcplusplus { @@ -46,11 +48,14 @@ struct CSEnergyEstimator : public ScalarEstimatorBase Matrix tmp_data; ///name of hamiltonian components std::vector h_components; + const CSLocalEnergyInput input_; /** constructor * @param h QMCHamiltonian to define the components * @param hcopy number of copies of QMCHamiltonians */ - CSEnergyEstimator(QMCHamiltonian& h, int hcopy = 1); + CSEnergyEstimator(const QMCHamiltonian& h, int hcopy = 1); + + CSEnergyEstimator(CSLocalEnergyInput&& input, const QMCHamiltonian& h); inline RealType getUmbrellaWeight(int ipsi) { @@ -83,8 +88,10 @@ struct CSEnergyEstimator : public ScalarEstimatorBase void add2Record(RecordNamedProperty& record) override; void registerObservables(std::vector& h5dec, hid_t gid) override; CSEnergyEstimator* clone() override; - + const std::string& getSubTypeStr() const override { return input_.get_type(); } void evaluateDiff(); + // CSEnergyEstimator is the main estimator for + bool isMainEstimator() const override { return true; } }; } // namespace qmcplusplus diff --git a/src/Estimators/CollectablesEstimator.h b/src/Estimators/CollectablesEstimator.h index ad656a1ae4..294d57d14c 100644 --- a/src/Estimators/CollectablesEstimator.h +++ b/src/Estimators/CollectablesEstimator.h @@ -50,6 +50,9 @@ class CollectablesEstimator : public ScalarEstimatorBase for (int i = 0; i < data.size(); ++i) scalars[i](data[i], wgt); } + + const std::string type_str = "ColletiblesEstimatorNotSupportedInBatchedVersion"; + const std::string& getSubTypeStr() const override { return type_str; } }; } // namespace qmcplusplus #endif diff --git a/src/Estimators/EstimatorInput.h b/src/Estimators/EstimatorInput.h index 74b1486452..a9685b57c0 100644 --- a/src/Estimators/EstimatorInput.h +++ b/src/Estimators/EstimatorInput.h @@ -20,17 +20,16 @@ * Many variables have default values we don't want overwritten and that we want expressed in native c++ * Define macro to avoid repeating code for this lambda */ -#define LAMBDA_setIfInInput [&](auto& var, const std::string& tag) -> bool { return input_section_.setIfInInput(var, tag); } +#define LAMBDA_setIfInInput \ + [&](auto& var, const std::string& tag) -> bool { return input_section_.setIfInInput(var, tag); } namespace qmcplusplus { - namespace estimatorinput { void checkCenterCorner(InputSection& input_section, const std::string& error_tag); - } // namespace estimatorinput } // namespace qmcplusplus #endif diff --git a/src/Estimators/EstimatorManagerInput.cpp b/src/Estimators/EstimatorManagerInput.cpp index b6ca42815a..1a7734945c 100644 --- a/src/Estimators/EstimatorManagerInput.cpp +++ b/src/Estimators/EstimatorManagerInput.cpp @@ -22,17 +22,35 @@ EstimatorManagerInput::EstimatorManagerInput(xmlNodePtr cur) { readXML(cur); } void EstimatorManagerInput::readXML(xmlNodePtr cur) { const std::string error_tag{"EstimatorManager input:"}; - xmlNodePtr child = cur->xmlChildrenNode; + std::string cur_name{lowerCase(castXMLCharToChar(cur->name))}; + xmlNodePtr child; + if (cur_name == "estimators") + child = cur->xmlChildrenNode; + else + child = cur; while (child != NULL) { std::string cname{lowerCase(castXMLCharToChar(child->name))}; if (cname == "estimator") { std::string atype(lowerCase(getXMLAttributeValue(child, "type"))); - if (atype == "localenergy") + std::string aname(lowerCase(getXMLAttributeValue(child, "name"))); + if (atype.empty() && !aname.empty()) + atype = aname; + if (aname.empty() && !atype.empty()) + aname = atype; + if (atype == "localenergy" || atype == "elocal") appendScalarEstimatorInput(child); else if (atype == "cslocalenergy") + { appendScalarEstimatorInput(child); + app_warning() << "CSLocalEnergyEstimator support is at best experimental with batch drivers"; + } + else if (atype == "rmc") + { + appendScalarEstimatorInput(child); + app_warning() << "RMCLocalEnergyEstimator support is at best experimental with batch drivers"; + } else if (atype == "onebodydensitymatrices") appendEstimatorInput(child); else if (atype == "spindensity") @@ -40,12 +58,23 @@ void EstimatorManagerInput::readXML(xmlNodePtr cur) else if (atype == "momentumdistribution") appendEstimatorInput(child); else - throw UniformCommunicateError(error_tag + "unparsable child node, name: " + cname + " type: " + atype + + throw UniformCommunicateError(error_tag + "unparsable node, name: " + aname + " type: " + atype + " in Estimators input."); } - else + else if (cname != "text") + { + std::string atype(lowerCase(getXMLAttributeValue(child, "type"))); + std::string aname(lowerCase(getXMLAttributeValue(child, "name"))); throw UniformCommunicateError(error_tag + " can only contain nodes"); - child = child->next; + } + + if (cur_name == "estimators") + child = child->next; + else + { + app_summary() << " nodes not contained in is a deprecated input xml idiom"; + break; + } } } diff --git a/src/Estimators/EstimatorManagerInput.h b/src/Estimators/EstimatorManagerInput.h index b83d4c7132..bfbe96d80f 100644 --- a/src/Estimators/EstimatorManagerInput.h +++ b/src/Estimators/EstimatorManagerInput.h @@ -46,7 +46,8 @@ using EstimatorInputs = std::vector; */ class LocalEnergyInput; class CSLocalEnergyInput; -using ScalarEstimatorInput = std::variant; +class RMCLocalEnergyInput; +using ScalarEstimatorInput = std::variant; using ScalarEstimatorInputs = std::vector; /** Input type for EstimatorManagerNew @@ -62,8 +63,10 @@ class EstimatorManagerInput EstimatorManagerInput(xmlNodePtr cur); EstimatorInputs& get_estimator_inputs() { return estimator_inputs_; } ScalarEstimatorInputs& get_scalar_estimator_inputs() { return scalar_estimator_inputs_; } - /** read node - * Note that this can be done multiple times to combine global and section local estimator inputs. + + /** read node or ( node for legacy support) + * This can be done multiple times with nodes + * or with nodes to support deprecated bare definitions */ void readXML(xmlNodePtr cur); @@ -76,14 +79,12 @@ class EstimatorManagerInput void appendEstimatorInput(Args&&... args) { estimator_inputs_.emplace_back(std::in_place_type, std::forward(args)...); - ; } template void appendScalarEstimatorInput(Args&&... args) { scalar_estimator_inputs_.emplace_back(std::in_place_type, std::forward(args)...); - ; } friend class testing::EstimatorManagerInputTests; diff --git a/src/Estimators/LocalEnergyEstimator.cpp b/src/Estimators/LocalEnergyEstimator.cpp index 141f48876a..ecbdfcdf8b 100644 --- a/src/Estimators/LocalEnergyEstimator.cpp +++ b/src/Estimators/LocalEnergyEstimator.cpp @@ -17,7 +17,7 @@ namespace qmcplusplus { -LocalEnergyEstimator::LocalEnergyEstimator(QMCHamiltonian& h, bool use_hdf5) : UseHDF5(use_hdf5), refH(h) +LocalEnergyEstimator::LocalEnergyEstimator(const QMCHamiltonian& h, bool use_hdf5) : UseHDF5(use_hdf5), refH(h) { SizeOfHamiltonians = h.sizeOfObservables(); FirstHamiltonian = h.startIndex(); @@ -25,6 +25,14 @@ LocalEnergyEstimator::LocalEnergyEstimator(QMCHamiltonian& h, bool use_hdf5) : U scalars_saved.resize(SizeOfHamiltonians + LE_MAX); } +LocalEnergyEstimator::LocalEnergyEstimator(LocalEnergyInput&& input, const QMCHamiltonian& h) : UseHDF5(input.get_use_hdf5()), refH(h), input_(input) +{ + SizeOfHamiltonians = h.sizeOfObservables(); + FirstHamiltonian = h.startIndex(); + scalars.resize(SizeOfHamiltonians + LE_MAX); + scalars_saved.resize(SizeOfHamiltonians + LE_MAX); +} + LocalEnergyEstimator* LocalEnergyEstimator::clone() { return new LocalEnergyEstimator(*this); } void LocalEnergyEstimator::registerObservables(std::vector& h5desc, hid_t gid) diff --git a/src/Estimators/LocalEnergyEstimator.h b/src/Estimators/LocalEnergyEstimator.h index c63dced19f..1a162fa57d 100644 --- a/src/Estimators/LocalEnergyEstimator.h +++ b/src/Estimators/LocalEnergyEstimator.h @@ -2,11 +2,12 @@ // This file is distributed under the University of Illinois/NCSA Open Source License. // See LICENSE file in top directory for details. // -// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers. +// Copyright (c) 2022 QMCPACK developers. // // File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory // // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign ////////////////////////////////////////////////////////////////////////////////////// @@ -18,6 +19,7 @@ #include "QMCHamiltonians/QMCHamiltonian.h" #include "QMCDrivers/WalkerProperties.h" #include "QMCHamiltonians/ObservableHelper.h" +#include "ScalarEstimatorInputs.h" namespace qmcplusplus { @@ -40,13 +42,18 @@ class LocalEnergyEstimator : public ScalarEstimatorBase int SizeOfHamiltonians; bool UseHDF5; const QMCHamiltonian& refH; + const LocalEnergyInput input_; public: /** constructor * @param h QMCHamiltonian to define the components */ - LocalEnergyEstimator(QMCHamiltonian& h, bool use_hdf5); - + LocalEnergyEstimator(const QMCHamiltonian& h, bool use_hdf5); + /** Construct from LocalEnergyInput and const reference to hamiltonian. + * \param[in] LocalEnergyInput contains input parameters for LocalEnergyEstimator + * \param[in] is taken as a local reference and used to size scalars data + */ + LocalEnergyEstimator(LocalEnergyInput&& input, const QMCHamiltonian& ham); /** accumulation per walker * @param awalker current walker * @param wgt weight @@ -83,6 +90,10 @@ class LocalEnergyEstimator : public ScalarEstimatorBase for (MCPWalker& walker : walkers) accumulate(walker, 1.0); } + + /// LocalEnergyEstimator is the main estimator for VMC and DMC + bool isMainEstimator() const override { return true; } + const std::string& getSubTypeStr() const override { return input_.get_type(); } }; } // namespace qmcplusplus #endif diff --git a/src/Estimators/LocalEnergyOnlyEstimator.h b/src/Estimators/LocalEnergyOnlyEstimator.h index 033890a47a..efd6bc8926 100644 --- a/src/Estimators/LocalEnergyOnlyEstimator.h +++ b/src/Estimators/LocalEnergyOnlyEstimator.h @@ -66,6 +66,9 @@ struct LocalEnergyOnlyEstimator : public ScalarEstimatorBase } LocalEnergyOnlyEstimator* clone() override { return new LocalEnergyOnlyEstimator(); } + + const std::string type_str = "LocalEnergyOnlyEstimatorNotSupportedInBatchedVersion"; + const std::string& getSubTypeStr() const override { return type_str; } }; } // namespace qmcplusplus #endif diff --git a/src/Estimators/RMCLocalEnergyEstimator.cpp b/src/Estimators/RMCLocalEnergyEstimator.cpp index a3c386516e..d8e3b55fd9 100644 --- a/src/Estimators/RMCLocalEnergyEstimator.cpp +++ b/src/Estimators/RMCLocalEnergyEstimator.cpp @@ -16,11 +16,20 @@ namespace qmcplusplus { -RMCLocalEnergyEstimator::RMCLocalEnergyEstimator(QMCHamiltonian& h, int nobs) : refH(h), NObs(nobs) +RMCLocalEnergyEstimator::RMCLocalEnergyEstimator(QMCHamiltonian& ham, int nobs) : refH(ham), NObs(nobs) { - SizeOfHamiltonians = h.sizeOfObservables(); - FirstHamiltonian = h.startIndex(); - RMCSpecificTerms = 8; + resizeBasedOnHamiltonian(ham); +} + +RMCLocalEnergyEstimator::RMCLocalEnergyEstimator(RMCLocalEnergyInput&& input, const QMCHamiltonian& ham) : refH(ham), NObs(input.get_n_obs()), input_(input) +{ + resizeBasedOnHamiltonian(ham); +} + +void RMCLocalEnergyEstimator::resizeBasedOnHamiltonian(const QMCHamiltonian& ham) +{ + SizeOfHamiltonians = ham.sizeOfObservables(); + FirstHamiltonian = ham.startIndex(); scalars.resize(2 * SizeOfHamiltonians + RMCSpecificTerms); scalars_saved.resize(2 * SizeOfHamiltonians + RMCSpecificTerms); } diff --git a/src/Estimators/RMCLocalEnergyEstimator.h b/src/Estimators/RMCLocalEnergyEstimator.h index c5210adb99..c94784459a 100644 --- a/src/Estimators/RMCLocalEnergyEstimator.h +++ b/src/Estimators/RMCLocalEnergyEstimator.h @@ -2,7 +2,7 @@ // This file is distributed under the University of Illinois/NCSA Open Source License. // See LICENSE file in top directory for details. // -// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers. +// Copyright (c) 2022 QMCPACK developers. // // File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory @@ -18,7 +18,7 @@ #include "QMCHamiltonians/QMCHamiltonian.h" #include "Particle/Reptile.h" #include "QMCDrivers/WalkerProperties.h" - +#include "ScalarEstimatorInputs.h" namespace qmcplusplus { /** Class to accumulate the local energy and components @@ -32,14 +32,21 @@ class RMCLocalEnergyEstimator : public ScalarEstimatorBase int SizeOfHamiltonians; const QMCHamiltonian& refH; int NObs; - int RMCSpecificTerms; + int RMCSpecificTerms = 8; + // This is just to allow compilation batched version does not support RMC at this time. + const RMCLocalEnergyInput input_; public: /** constructor * @param h QMCHamiltonian to define the components */ - RMCLocalEnergyEstimator(QMCHamiltonian& h, int nobs = 2); - + RMCLocalEnergyEstimator(QMCHamiltonian& ham, int nobs = 2); + /** Construct from LocalEnergyInput and const reference to hamiltonian. + * \param[in] RMCLocalEnergyEstimatorInput contains input parameters for RMCLocalEnergyEstimator + * \param[in] is taken as a local reference and used to size scalars data and to get obs output names + */ + RMCLocalEnergyEstimator(RMCLocalEnergyInput&& input, const QMCHamiltonian& ham); + /** accumulation per walker * @param awalker current walker * @param wgt weight @@ -52,7 +59,6 @@ class RMCLocalEnergyEstimator : public ScalarEstimatorBase { throw std::runtime_error("RMC not supported by Unified Driver interfaces"); } - /*@{*/ inline void accumulate(const MCWalkerConfiguration& W, WalkerIterator first, WalkerIterator last, @@ -144,7 +150,12 @@ class RMCLocalEnergyEstimator : public ScalarEstimatorBase void add2Record(RecordListType& record) override; void registerObservables(std::vector& h5dec, hid_t gid) override {} RMCLocalEnergyEstimator* clone() override; - /*@}*/ + const std::string& getSubTypeStr() const override { return input_.get_type(); } + /// RMCLocalEnergyEstimator is the main estimator type for RMC driver + bool isMainEstimator() const override { return true; } + +private: + void resizeBasedOnHamiltonian(const QMCHamiltonian& ham); }; } // namespace qmcplusplus #endif diff --git a/src/Estimators/ScalarEstimatorBase.h b/src/Estimators/ScalarEstimatorBase.h index 03a4f4eb89..e94c3961de 100644 --- a/src/Estimators/ScalarEstimatorBase.h +++ b/src/Estimators/ScalarEstimatorBase.h @@ -2,7 +2,7 @@ // This file is distributed under the University of Illinois/NCSA Open Source License. // See LICENSE file in top directory for details. // -// Copyright (c) 2020 QMCPACK developers. +// Copyright (c) 2022 QMCPACK developers. // // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign @@ -61,6 +61,9 @@ struct ScalarEstimatorBase virtual ~ScalarEstimatorBase() {} + /// Is this estimator a main estimator i.e. the estimator required for a particular driver. + virtual bool isMainEstimator() const { return false; } + ///return average of the inline RealType average(int i = 0) const { return scalars_saved[i].mean(); } ///return a variance @@ -162,6 +165,9 @@ struct ScalarEstimatorBase ///clone the object virtual ScalarEstimatorBase* clone() = 0; + + /// String representation of the derived type of the ScalarEstimator + virtual const std::string& getSubTypeStr() const = 0; }; } // namespace qmcplusplus diff --git a/src/Estimators/ScalarEstimatorInputs.cpp b/src/Estimators/ScalarEstimatorInputs.cpp index 44940a92cb..c89feebfa6 100644 --- a/src/Estimators/ScalarEstimatorInputs.cpp +++ b/src/Estimators/ScalarEstimatorInputs.cpp @@ -9,24 +9,54 @@ // Some code refactored from: EstimatorManagerNew.cpp ////////////////////////////////////////////////////////////////////////////////////// -#include "EstimatorInput.h" #include "ScalarEstimatorInputs.h" +#include "InputSection.h" +#include "EstimatorInput.h" namespace qmcplusplus { +/** make input class state consistent with legacy ignoring the distinction + * between the name and type of estimator for scalar estimators. + * + * \param [in] input_section_ naming here is to allow reuse of LAMBDA_setIfInInput macro + * \param [inout] name output param but assumed to be unset + * \param [inout] type output param but assumed to be unset + */ +void readNameTypeLikeLegacy(InputSection& input_section_, std::string& name, std::string& type) +{ + auto setIfInInput = LAMBDA_setIfInInput; + setIfInInput(type, "type"); + setIfInInput(name, "name"); + if (name.empty()) + name = type; + if (type.empty()) + type = name; +} LocalEnergyInput::LocalEnergyInput(xmlNodePtr cur) { input_section_.readXML(cur); + readNameTypeLikeLegacy(input_section_, name_, type_); auto setIfInInput = LAMBDA_setIfInInput; setIfInInput(use_hdf5_, "hdf5"); + if (lowerCase(type_) == "elocal") + type_ = "localenergy"; } CSLocalEnergyInput::CSLocalEnergyInput(xmlNodePtr cur) { input_section_.readXML(cur); + readNameTypeLikeLegacy(input_section_, name_, type_); auto setIfInInput = LAMBDA_setIfInInput; setIfInInput(n_psi_, "npsi"); } +RMCLocalEnergyInput::RMCLocalEnergyInput(xmlNodePtr cur) +{ + input_section_.readXML(cur); + readNameTypeLikeLegacy(input_section_, name_, type_); + auto setIfInInput = LAMBDA_setIfInInput; + setIfInInput(n_obs_, "nobs"); } + +} // namespace qmcplusplus diff --git a/src/Estimators/ScalarEstimatorInputs.h b/src/Estimators/ScalarEstimatorInputs.h index 79dcc68f51..fe882e929e 100644 --- a/src/Estimators/ScalarEstimatorInputs.h +++ b/src/Estimators/ScalarEstimatorInputs.h @@ -9,11 +9,38 @@ // File refactored from: EstimatorManagerNew.h ////////////////////////////////////////////////////////////////////////////////////// +#ifndef QMCPLUSPLUS_SCALAR_ESTIMATOR_INPUTS_H +#define QMCPLUSPLUS_SCALAR_ESTIMATOR_INPUTS_H + #include "InputSection.h" +/** \file + * This file contains the input classes for the + * supported "main estimator" classes derived from ScalarEstimatorBase. + * + * see: LocalEnergyEstimator.h, CSEnergyEstimator.h, RMCLocalEnergyEstimator.h + * + * The legacy input format used the name attribute instead of the type attribute + * to indicate the type of the scalar estimators. There would otherwise be no reason to + * retain the name attribute reading or native input variable. + * + * The current implementation sets the native type_ or name_ equal in value to + * match if only name or attribute is present in input. If both are present name is + * ignored and only type is used for type determination. The name can be set to anything + * as is typical of name attributes in the input but at the moment that name is not + * used in output or anywhere else. + * + * EstimatorManagerInput will delegate parsing of scalar estimator inputs to these + * classes based on the type of the estimator as determined by reading the type attribute in the + * raw input. We still fixup the name_ and type_ in the implementation to create input classes + * consistent with the expected "input state." + */ + namespace qmcplusplus { +class LocalEnergyEstimator; + class LocalEnergyInput { class LocalEnergyInputSection : public InputSection @@ -22,21 +49,29 @@ class LocalEnergyInput LocalEnergyInputSection() { section_name = "LocalEnergy"; - attributes = {"type", "hdf5"}; + attributes = {"name", "type", "hdf5"}; bools = {"hdf5"}; - strings = {"type"}; + strings = {"name", "type"}; }; }; public: + using Consumer = LocalEnergyEstimator; + LocalEnergyInput() = default; LocalEnergyInput(xmlNodePtr cur); bool get_use_hdf5() const { return use_hdf5_; } + const std::string& get_name() const { return name_; } + const std::string& get_type() const { return type_; } private: + std::string name_; + std::string type_; LocalEnergyInputSection input_section_; bool use_hdf5_ = true; }; +struct CSEnergyEstimator; + class CSLocalEnergyInput { class CSLocalEnergyInputSection : public InputSection @@ -45,19 +80,57 @@ class CSLocalEnergyInput CSLocalEnergyInputSection() { section_name = "CSLocalEnergy"; - attributes = {"npsi", "type"}; + attributes = {"name", "npsi", "type"}; integers = {"npsi"}; - strings = {"type"}; + strings = {"name", "type"}; } }; public: + using Consumer = CSEnergyEstimator; + CSLocalEnergyInput() = default; CSLocalEnergyInput(xmlNodePtr cur); int get_n_psi() const { return n_psi_; } + const std::string& get_name() const { return name_; } + const std::string& get_type() const { return type_; } private: + std::string name_; + std::string type_; CSLocalEnergyInputSection input_section_; int n_psi_ = 1; }; +class RMCLocalEnergyEstimator; + +class RMCLocalEnergyInput +{ + class RMCLocalEnergyInputSection : public InputSection + { + public: + RMCLocalEnergyInputSection() + { + section_name = "RMCLocalEnergy"; + attributes = {"name", "nobs", "type"}; + integers = {"nobs"}; + strings = {"name", "type"}; + } + }; + +public: + using Consumer = RMCLocalEnergyEstimator; + RMCLocalEnergyInput() = default; + RMCLocalEnergyInput(xmlNodePtr cur); + int get_n_obs() const { return n_obs_; } + const std::string& get_name() const { return name_; } + const std::string& get_type() const { return type_; } +private: + std::string name_; + std::string type_; + RMCLocalEnergyInputSection input_section_; + int n_obs_ = 1; +}; + } // namespace qmcplusplus + +#endif diff --git a/src/Estimators/tests/CMakeLists.txt b/src/Estimators/tests/CMakeLists.txt index f1c8460e19..28b0bfbf87 100644 --- a/src/Estimators/tests/CMakeLists.txt +++ b/src/Estimators/tests/CMakeLists.txt @@ -31,6 +31,7 @@ set(SRCS test_SpinDensityNew.cpp test_InputSection.cpp test_EstimatorManagerInput.cpp + test_ScalarEstimatorInputs.cpp ) # OneBodyDensityMatrices are not tested with legacy CUDA diff --git a/src/Estimators/tests/EstimatorManagerInputTest.cpp b/src/Estimators/tests/EstimatorManagerInputTest.cpp new file mode 100644 index 0000000000..fee5e2f981 --- /dev/null +++ b/src/Estimators/tests/EstimatorManagerInputTest.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source License. +// See LICENSE file in top directory for details. +// +// Copyright (c) 2022 QMCPACK developers. +// +// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab +// +// File refactored from: Refactored from test_manager.cpp +////////////////////////////////////////////////////////////////////////////////////// +#include "EstimatorManagerInputTest.h" + +#include "catch.hpp" + +#include "ValidOneBodyDensityMatricesInput.h" +#include "ValidSpinDensityInput.h" +#include "ValidMomentumDistributionInput.h" +#include "ValidScalarEstimatorInput.h" + +namespace qmcplusplus +{ +namespace testing +{ + +Libxml2Document createEstimatorManagerNewInputXML() +{ + const int max_node_recurse = 3; + Libxml2Document estimators_doc; + estimators_doc.newDoc("Estimators"); + { + using namespace testing::onebodydensitymatrices; + Libxml2Document doc; + bool okay = doc.parseFromString(valid_one_body_density_matrices_input_sections[0]); + REQUIRE(okay); + xmlNodePtr node = doc.getRoot(); + estimators_doc.addChild(xmlCopyNode(node, max_node_recurse)); + } + { + Libxml2Document doc; + bool okay = doc.parseFromString(valid_spin_density_input_sections[0]); + REQUIRE(okay); + xmlNodePtr node = doc.getRoot(); + estimators_doc.addChild(xmlCopyNode(node, max_node_recurse)); + } + { + Libxml2Document doc; + bool okay = doc.parseFromString(valid_momentum_distribution_input_sections[0]); + REQUIRE(okay); + xmlNodePtr node = doc.getRoot(); + estimators_doc.addChild(xmlCopyNode(node, max_node_recurse)); + } + for (auto& input_xml : valid_scalar_estimator_input_sections) + { + Libxml2Document doc; + bool okay = doc.parseFromString(input_xml); + REQUIRE(okay); + xmlNodePtr node = doc.getRoot(); + estimators_doc.addChild(xmlCopyNode(node, max_node_recurse)); + } + + return estimators_doc; +} + +} // namespace testing +} // namespace qmcplusplus diff --git a/src/Estimators/tests/EstimatorManagerInputTest.h b/src/Estimators/tests/EstimatorManagerInputTest.h new file mode 100644 index 0000000000..070e196b65 --- /dev/null +++ b/src/Estimators/tests/EstimatorManagerInputTest.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////////////////// +// This file is distributed under the University of Illinois/NCSA Open Source License. +// See LICENSE file in top directory for details. +// +// Copyright (c) 2022 QMCPACK developers. +// +// File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory +// +// File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory +////////////////////////////////////////////////////////////////////////////////////// + +#ifndef QMCPLUSPLUS_ESTIMATOR_MANAGER_INPUT_TEST_H +#define QMCPLUSPLUS_ESTIMATOR_MANAGER_INPUT_TEST_H + +#include "OhmmsData/Libxml2Doc.h" + +namespace qmcplusplus +{ +namespace testing +{ + +Libxml2Document createEstimatorManagerNewInputXML(); + +} +} +#endif diff --git a/src/Estimators/tests/FakeEstimator.h b/src/Estimators/tests/FakeEstimator.h index b6312b2874..984686f53d 100644 --- a/src/Estimators/tests/FakeEstimator.h +++ b/src/Estimators/tests/FakeEstimator.h @@ -2,9 +2,10 @@ // This file is distributed under the University of Illinois/NCSA Open Source License. // See LICENSE file in top directory for details. // -// Copyright (c) 2019 QMCPACK developers. +// Copyright (c) 2022 QMCPACK developers. // // File developed by: Mark Dewing, mdewin@anl.gov, Argonne National Laboratory +// Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory // // Refactored from test_manager.cpp ////////////////////////////////////////////////////////////////////////////////////// @@ -17,6 +18,7 @@ namespace qmcplusplus { class FakeEstimator : public ScalarEstimatorBase { +public: void accumulate(const MCWalkerConfiguration& W, WalkerIterator first, WalkerIterator last, RealType wgt) override {} void accumulate(const RefVector& walkers) override {} @@ -26,6 +28,9 @@ class FakeEstimator : public ScalarEstimatorBase void registerObservables(std::vector& h5dec, hid_t gid) override {} FakeEstimator* clone() override { return new FakeEstimator; } + + std::string type_{"fake"}; + const std::string& getSubTypeStr() const override { return type_; } }; } // namespace qmcplusplus diff --git a/src/Estimators/tests/ValidScalarEstimatorInput.h b/src/Estimators/tests/ValidScalarEstimatorInput.h index fd0f907250..5a3c199247 100644 --- a/src/Estimators/tests/ValidScalarEstimatorInput.h +++ b/src/Estimators/tests/ValidScalarEstimatorInput.h @@ -19,16 +19,28 @@ namespace qmcplusplus namespace testing { -constexpr std::array valid_scalar_estimator_input_sections{ +constexpr std::array valid_scalar_estimator_input_sections{ R"XML( - )XML", + )XML", R"XML( - )XML"}; + )XML", + R"XML( + + )XML", + R"XML( + + )XML", + R"XML( + + )XML"}; -constexpr int local_energy_input = 0; -constexpr int cs_local_energy_input = 1; +constexpr int local_energy_input = 0; +constexpr int cs_local_energy_input = 1; +constexpr int cs_local_energy_input_legacy = 2; +constexpr int local_energy_input_legacy = 3; +constexpr int rmc_local_energy_input = 4; } // namespace testing } // namespace qmcplusplus diff --git a/src/Estimators/tests/test_EstimatorManagerInput.cpp b/src/Estimators/tests/test_EstimatorManagerInput.cpp index 246c380879..9d04e0dc22 100644 --- a/src/Estimators/tests/test_EstimatorManagerInput.cpp +++ b/src/Estimators/tests/test_EstimatorManagerInput.cpp @@ -116,7 +116,7 @@ TEST_CASE("EstimatorManagerInput::readXML", "[estimators]") EstimatorManagerInput emi(estimators_doc.getRoot()); CHECK(emi.get_estimator_inputs().size() == 3); - CHECK(emi.get_scalar_estimator_inputs().size() == 2); + CHECK(emi.get_scalar_estimator_inputs().size() == 5); // CHECK EMI throws if unparsable estimators are in input. Libxml2Document doc; diff --git a/src/Estimators/tests/test_EstimatorManagerNew.cpp b/src/Estimators/tests/test_EstimatorManagerNew.cpp index 7e55d8bf8f..3c2a671c8d 100644 --- a/src/Estimators/tests/test_EstimatorManagerNew.cpp +++ b/src/Estimators/tests/test_EstimatorManagerNew.cpp @@ -2,7 +2,7 @@ // This file is distributed under the University of Illinois/NCSA Open Source License. // See LICENSE file in top directory for details. // -// Copyright (c) 2020 QMCPACK developers. +// Copyright (c) 2022 QMCPACK developers. // // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab // diff --git a/src/Estimators/tests/test_ScalarEstimatorInputs.cpp b/src/Estimators/tests/test_ScalarEstimatorInputs.cpp index 3b0b78ca52..d3cb16ca11 100644 --- a/src/Estimators/tests/test_ScalarEstimatorInputs.cpp +++ b/src/Estimators/tests/test_ScalarEstimatorInputs.cpp @@ -2,7 +2,7 @@ // This file is distributed under the University of Illinois/NCSA Open Source License. // See LICENSE file in top directory for details. // -// Copyright (c) 2021 QMCPACK developers. +// Copyright (c) 2022 QMCPACK developers. // // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab // @@ -12,13 +12,14 @@ #include "catch.hpp" +#include "OhmmsData/Libxml2Doc.h" #include "ScalarEstimatorInputs.h" -#include "ValidScalarEsimtatorInput.h" +#include "ValidScalarEstimatorInput.h" namespace qmcplusplus { -TEST_CASE("LocalEnergy Scalar Estimator Input"."[estimators]") +TEST_CASE("Scalar Estimator Input", "[estimators]") { using namespace testing; @@ -28,8 +29,30 @@ TEST_CASE("LocalEnergy Scalar Estimator Input"."[estimators]") bool okay = doc.parseFromString(input); REQUIRE(okay); xmlNodePtr node = doc.getRoot(); - std::string type_name(lowerCase(getXMLAttributeValue(node, "type"))); - if (type_name == "localenergy") {} + std::string atype(lowerCase(getXMLAttributeValue(node, "type"))); + std::string aname(lowerCase(getXMLAttributeValue(node, "name"))); + // Since legacy inconsistently used name instead of type attribute to specify scalar estimator type + if (atype.empty() && ! aname.empty()) + atype = aname; + if (aname.empty() && ! atype.empty()) + aname = atype; + if (atype == "localenergy" || atype == "elocal") + { + LocalEnergyInput lei(node); + CHECK(lowerCase(lei.get_type()) == "localenergy"); + } + else if (atype == "cslocalenergy") { + CSLocalEnergyInput cslei(node); + CHECK(lowerCase(cslei.get_type()) == "cslocalenergy"); + } + else if (atype == "rmc") { + RMCLocalEnergyInput rmclei(node); + CHECK(lowerCase(rmclei.get_type()) == "rmc"); + } + else + { + FAIL( "Unhandled scalar estimator " << atype ); + } } }