diff --git a/src/QMCWaveFunctions/CMakeLists.txt b/src/QMCWaveFunctions/CMakeLists.txt index a17c49bfa9..b1f86e739b 100644 --- a/src/QMCWaveFunctions/CMakeLists.txt +++ b/src/QMCWaveFunctions/CMakeLists.txt @@ -35,6 +35,7 @@ set(WFBASE_SRCS SPOSet.cpp SPOSetT.cpp CompositeSPOSet.cpp + CompositeSPOSetT.cpp HarmonicOscillator/SHOSet.cpp HarmonicOscillator/SHOSetT.cpp HarmonicOscillator/SHOSetBuilder.cpp diff --git a/src/QMCWaveFunctions/CompositeSPOSetT.cpp b/src/QMCWaveFunctions/CompositeSPOSetT.cpp new file mode 100644 index 0000000000..1d635e8a41 --- /dev/null +++ b/src/QMCWaveFunctions/CompositeSPOSetT.cpp @@ -0,0 +1,193 @@ +////////////////////////////////////////////////////////////////////////////////////// +// 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. +// +// File developed by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National +// Laboratory +// Jeongnim Kim, jeongnim.kim@gmail.com, University of +// Illinois at Urbana-Champaign Mark A. Berrill, +// berrillma@ornl.gov, Oak Ridge National Laboratory +// +// File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois +// at Urbana-Champaign +////////////////////////////////////////////////////////////////////////////////////// + +#include "CompositeSPOSetT.h" + +#include "OhmmsData/AttributeSet.h" +#include "QMCWaveFunctions/SPOSetBuilderFactory.h" +#include "Utilities/IteratorUtility.h" + +#include + +namespace qmcplusplus +{ +namespace MatrixOperators +{ +/** copy a small matrix (N, M1) to a big matrix (N, M2), M2>M1 + * @param small input matrix + * @param big outout matrix + * @param offset_c column offset + * + * @todo smater and more efficient matrix, move up for others + * The columns [0,M1) are inserted into [offset_c,offset_c+M1). + */ +template +inline void +insert_columns(const MAT1& small, MAT2& big, int offset_c) +{ + const int c = small.cols(); + for (int i = 0; i < small.rows(); ++i) + std::copy(small[i], small[i] + c, big[i] + offset_c); +} +} // namespace MatrixOperators + +template +CompositeSPOSetT::CompositeSPOSetT(const std::string& my_name) : + SPOSetT(my_name) +{ + this->OrbitalSetSize = 0; + component_offsets.reserve(4); +} + +template +CompositeSPOSetT::CompositeSPOSetT(const CompositeSPOSetT& other) : + SPOSetT(other) +{ + for (auto& element : other.components) { + this->add(element->makeClone()); + } +} + +template +CompositeSPOSetT::~CompositeSPOSetT() = default; + +template +void +CompositeSPOSetT::add(std::unique_ptr> component) +{ + if (components.empty()) + component_offsets.push_back(0); // add 0 + + int norbs = component->size(); + components.push_back(std::move(component)); + component_values.emplace_back(norbs); + component_gradients.emplace_back(norbs); + component_laplacians.emplace_back(norbs); + + this->OrbitalSetSize += norbs; + component_offsets.push_back(this->OrbitalSetSize); +} + +template +void +CompositeSPOSetT::report() +{ + app_log() << "CompositeSPOSetT" << std::endl; + app_log() << " ncomponents = " << components.size() << std::endl; + app_log() << " components" << std::endl; + for (int i = 0; i < components.size(); ++i) { + app_log() << " " << i << std::endl; + components[i]->basic_report(" "); + } +} + +template +std::unique_ptr> +CompositeSPOSetT::makeClone() const +{ + return std::make_unique>(*this); +} + +template +void +CompositeSPOSetT::evaluateValue( + const ParticleSet& P, int iat, ValueVector& psi) +{ + int n = 0; + for (int c = 0; c < components.size(); ++c) { + SPOSetT& component = *components[c]; + ValueVector& values = component_values[c]; + component.evaluateValue(P, iat, values); + std::copy(values.begin(), values.end(), psi.begin() + n); + n += component.size(); + } +} + +template +void +CompositeSPOSetT::evaluateVGL(const ParticleSet& P, int iat, + ValueVector& psi, GradVector& dpsi, ValueVector& d2psi) +{ + int n = 0; + for (int c = 0; c < components.size(); ++c) { + SPOSetT& component = *components[c]; + ValueVector& values = component_values[c]; + GradVector& gradients = component_gradients[c]; + ValueVector& laplacians = component_laplacians[c]; + component.evaluateVGL(P, iat, values, gradients, laplacians); + std::copy(values.begin(), values.end(), psi.begin() + n); + std::copy(gradients.begin(), gradients.end(), dpsi.begin() + n); + std::copy(laplacians.begin(), laplacians.end(), d2psi.begin() + n); + n += component.size(); + } +} + +template +void +CompositeSPOSetT::evaluate_notranspose(const ParticleSet& P, int first, + int last, ValueMatrix& logdet, GradMatrix& dlogdet, ValueMatrix& d2logdet) +{ + const int nat = last - first; + for (int c = 0; c < components.size(); ++c) { + int norb = components[c]->size(); + ValueMatrix v(nat, norb); + GradMatrix g(nat, norb); + ValueMatrix l(nat, norb); + components[c]->evaluate_notranspose(P, first, last, v, g, l); + int n = component_offsets[c]; + MatrixOperators::insert_columns(v, logdet, n); + MatrixOperators::insert_columns(g, dlogdet, n); + MatrixOperators::insert_columns(l, d2logdet, n); + } +} + +template +void +CompositeSPOSetT::evaluate_notranspose(const ParticleSet& P, int first, + int last, ValueMatrix& logdet, GradMatrix& dlogdet, + HessMatrix& grad_grad_logdet) +{ + const int nat = last - first; + for (int c = 0; c < components.size(); ++c) { + int norb = components[c]->size(); + ValueMatrix v(nat, norb); + GradMatrix g(nat, norb); + HessMatrix h(nat, norb); + components[c]->evaluate_notranspose(P, first, last, v, g, h); + int n = component_offsets[c]; + MatrixOperators::insert_columns(v, logdet, n); + MatrixOperators::insert_columns(g, dlogdet, n); + MatrixOperators::insert_columns(h, grad_grad_logdet, n); + } +} + +template +void +CompositeSPOSetT::evaluate_notranspose(const ParticleSet& P, int first, + int last, ValueMatrix& logdet, GradMatrix& dlogdet, + HessMatrix& grad_grad_logdet, GGGMatrix& grad_grad_grad_logdet) +{ + not_implemented( + "evaluate_notranspose(P,first,last,logdet,dlogdet,ddlogdet,dddlogdet)"); +} + +// Class concrete types from ValueType +template class CompositeSPOSetT; +template class CompositeSPOSetT; +template class CompositeSPOSetT>; +template class CompositeSPOSetT>; + +} // namespace qmcplusplus diff --git a/src/QMCWaveFunctions/CompositeSPOSetT.h b/src/QMCWaveFunctions/CompositeSPOSetT.h new file mode 100644 index 0000000000..c8d156ac0c --- /dev/null +++ b/src/QMCWaveFunctions/CompositeSPOSetT.h @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////////////////// +// 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. +// +// File developed by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National +// Laboratory +// Jeongnim Kim, jeongnim.kim@gmail.com, University of +// Illinois at Urbana-Champaign Mark A. Berrill, +// berrillma@ornl.gov, Oak Ridge National Laboratory +// +// File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois +// at Urbana-Champaign +////////////////////////////////////////////////////////////////////////////////////// + +#ifndef QMCPLUSPLUS_COMPOSITE_SPOSETT_H +#define QMCPLUSPLUS_COMPOSITE_SPOSETT_H + +#include "QMCWaveFunctions/BasisSetBase.h" +#include "QMCWaveFunctions/SPOSetBuilder.h" +#include "QMCWaveFunctions/SPOSetBuilderFactory.h" +#include "QMCWaveFunctions/SPOSetT.h" + +namespace qmcplusplus +{ +template +class CompositeSPOSetT : public SPOSetT +{ +public: + using ValueVector = typename SPOSetT::ValueVector; + using GradVector = typename SPOSetT::GradVector; + using ValueMatrix = typename SPOSetT::ValueMatrix; + using GradMatrix = typename SPOSetT::GradMatrix; + using HessMatrix = typename SPOSetT::HessMatrix; + using GGGMatrix = typename SPOSetT::GGGMatrix; + + /// component SPOSets + std::vector>> components; + /// temporary storage for values + std::vector component_values; + /// temporary storage for gradients + std::vector component_gradients; + /// temporary storage for laplacians + std::vector component_laplacians; + /// store the precomputed offsets + std::vector component_offsets; + + CompositeSPOSetT(const std::string& my_name); + /** + * @TODO: do we want template copy constructor + * (i.e., copy from other with different type argument)? + */ + CompositeSPOSetT(const CompositeSPOSetT& other); + ~CompositeSPOSetT() override; + + std::string + getClassName() const override + { + return "CompositeSPOSetT"; + } + + /// add a sposet component to this composite sposet + void + add(std::unique_ptr> component); + + /// print out component info + void + report(); + + // SPOSet interface methods + /// size is determined by component sposets and nothing else + inline void + setOrbitalSetSize(int norbs) override + { + } + + std::unique_ptr> + makeClone() const override; + + void + evaluateValue(const ParticleSet& P, int iat, ValueVector& psi) override; + + void + evaluateVGL(const ParticleSet& P, int iat, ValueVector& psi, + GradVector& dpsi, ValueVector& d2psi) override; + + /// unimplemented functions call this to abort + inline void + not_implemented(const std::string& method) + { + APP_ABORT("CompositeSPOSetT::" + method + " has not been implemented"); + } + + // methods to be implemented in the future (possibly) + void + evaluate_notranspose(const ParticleSet& P, int first, int last, + ValueMatrix& logdet, GradMatrix& dlogdet, + ValueMatrix& d2logdet) override; + void + evaluate_notranspose(const ParticleSet& P, int first, int last, + ValueMatrix& logdet, GradMatrix& dlogdet, + HessMatrix& ddlogdet) override; + void + evaluate_notranspose(const ParticleSet& P, int first, int last, + ValueMatrix& logdet, GradMatrix& dlogdet, HessMatrix& ddlogdet, + GGGMatrix& dddlogdet) override; +}; + +} // namespace qmcplusplus + +#endif