From d6759c37a8e37abe5ebc0caa7d5625d4f054f7ca Mon Sep 17 00:00:00 2001 From: rcclay Date: Fri, 18 Dec 2020 14:16:16 -0700 Subject: [PATCH 01/22] Output SWCT data to scalar.dat --- src/QMCHamiltonians/ACForce.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index e1a7bcae6f..57391668c8 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -71,14 +71,20 @@ void ACForce::addObservables(PropertySetType& plist, BufferType& collectables) std::ostringstream pulayname; std::ostringstream wfgradname1; std::ostringstream wfgradname2; + std::ostringstream swctname1; + std::ostringstream swctname2; hfname << prefix << "_hf_" << iat << "_" << x; pulayname << prefix << "_pulay_" << iat << "_" << x; wfgradname1 << prefix << "_Ewfgrad_" << iat << "_" << x; wfgradname2 << prefix << "_wfgrad_" << iat << "_" << x; + swctname1 << prefix << "_swct1_" << iat << "_" << x; + swctname2 << prefix << "_swct2_" << iat << "_" << x; plist.add(hfname.str()); plist.add(pulayname.str()); plist.add(wfgradname1.str()); plist.add(wfgradname2.str()); + plist.add(swctname1.str()); + plist.add(swctname2.str()); } } }; @@ -95,6 +101,8 @@ void ACForce::setObservables(PropertySetType& plist) plist[myindex++] = -pulay_force[iat][iondim]; plist[myindex++] = -Value * wf_grad[iat][iondim]; plist[myindex++] = -wf_grad[iat][iondim]; + plist[myindex++] = 0; + plist[myindex++] = 0; } } }; @@ -109,6 +117,8 @@ void ACForce::setParticlePropertyList(PropertySetType& plist, int offset) plist[myindex++] = -pulay_force[iat][iondim]; plist[myindex++] = -Value * wf_grad[iat][iondim]; plist[myindex++] = -wf_grad[iat][iondim]; + plist[myindex++] = 0; + plist[myindex++] = 0; } } }; From 7fe36e0d6add9ff15f8f71e854f0f03e5620a102 Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 21 Dec 2020 09:40:12 -0700 Subject: [PATCH 02/22] New evaluate routine that doesn't randomize the pseudo grid --- src/QMCHamiltonians/NonLocalECPotential.cpp | 11 ++++++++-- src/QMCHamiltonians/NonLocalECPotential.h | 4 ++-- src/QMCHamiltonians/OperatorBase.cpp | 4 ++++ src/QMCHamiltonians/OperatorBase.h | 1 + src/QMCHamiltonians/QMCHamiltonian.cpp | 23 +++++++++++++++++++++ src/QMCHamiltonians/QMCHamiltonian.h | 2 +- 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/QMCHamiltonians/NonLocalECPotential.cpp b/src/QMCHamiltonians/NonLocalECPotential.cpp index aac72ae155..74ea6d5812 100644 --- a/src/QMCHamiltonians/NonLocalECPotential.cpp +++ b/src/QMCHamiltonians/NonLocalECPotential.cpp @@ -104,6 +104,12 @@ NonLocalECPotential::Return_t NonLocalECPotential::evaluate(ParticleSet& P) return Value; } +NonLocalECPotential::Return_t NonLocalECPotential::evaluate2(ParticleSet& P) +{ + evaluateImpl(P, false, true); + return Value; +} + void NonLocalECPotential::mw_evaluate(const RefVector& O_list, const RefVector& P_list) { mw_evaluateImpl(O_list, P_list, false); @@ -127,7 +133,7 @@ void NonLocalECPotential::mw_evaluateWithToperator(const RefVector mw_evaluateImpl(O_list, P_list, false); } -void NonLocalECPotential::evaluateImpl(ParticleSet& P, bool Tmove) +void NonLocalECPotential::evaluateImpl(ParticleSet& P, bool Tmove, bool keepGrid) { if (Tmove) nonLocalOps.reset(); @@ -144,7 +150,8 @@ void NonLocalECPotential::evaluateImpl(ParticleSet& P, bool Tmove) #endif for (int ipp = 0; ipp < PPset.size(); ipp++) if (PPset[ipp]) - PPset[ipp]->randomize_grid(*myRNG); + if(!keepGrid) + PPset[ipp]->randomize_grid(*myRNG); //loop over all the ions const auto& myTable = P.getDistTable(myTableIndex); // clear all the electron and ion neighbor lists diff --git a/src/QMCHamiltonians/NonLocalECPotential.h b/src/QMCHamiltonians/NonLocalECPotential.h index 9eac0dfd40..c77c0d4464 100644 --- a/src/QMCHamiltonians/NonLocalECPotential.h +++ b/src/QMCHamiltonians/NonLocalECPotential.h @@ -45,7 +45,7 @@ class NonLocalECPotential : public OperatorBase, public ForceBase #endif Return_t evaluate(ParticleSet& P) override; - + Return_t evaluate2(ParticleSet& P) override; void mw_evaluate(const RefVector& O_list, const RefVector& P_list) override; Return_t evaluateWithToperator(ParticleSet& P) override; @@ -154,7 +154,7 @@ class NonLocalECPotential : public OperatorBase, public ForceBase * @param P particle set * @param Tmove whether Txy for Tmove is updated */ - void evaluateImpl(ParticleSet& P, bool Tmove); + void evaluateImpl(ParticleSet& P, bool Tmove, bool keepGrid=false); /** the actual implementation for batched walkers, used by mw_evaluate and mw_evaluateWithToperator * @param O_list the list of NonLocalECPotential in a walker batch diff --git a/src/QMCHamiltonians/OperatorBase.cpp b/src/QMCHamiltonians/OperatorBase.cpp index d6e570b09b..cd97f61669 100644 --- a/src/QMCHamiltonians/OperatorBase.cpp +++ b/src/QMCHamiltonians/OperatorBase.cpp @@ -35,6 +35,10 @@ OperatorBase::OperatorBase() : myIndex(-1), Dependants(0), Value(0.0), tWalker(0 UpdateMode.set(PRIMARY, 1); } +OperatorBase::Return_t OperatorBase::evaluate2(ParticleSet& P) +{ + return evaluate(P); +} /** Take o_list and p_list update evaluation result variables in o_list? * * really should reduce vector of local_energies. matching the ordering and size of o list diff --git a/src/QMCHamiltonians/OperatorBase.h b/src/QMCHamiltonians/OperatorBase.h index 1c42f3c9f7..31c6441834 100644 --- a/src/QMCHamiltonians/OperatorBase.h +++ b/src/QMCHamiltonians/OperatorBase.h @@ -246,6 +246,7 @@ struct OperatorBase : public QMCTraits *@return the value of the Hamiltonian component */ virtual Return_t evaluate(ParticleSet& P) = 0; + virtual Return_t evaluate2(ParticleSet& P); /** Evaluate the contribution of this component of multiple walkers */ virtual void mw_evaluate(const RefVector& O_list, const RefVector& P_list); diff --git a/src/QMCHamiltonians/QMCHamiltonian.cpp b/src/QMCHamiltonians/QMCHamiltonian.cpp index bc5d557bd3..77c2c50283 100644 --- a/src/QMCHamiltonians/QMCHamiltonian.cpp +++ b/src/QMCHamiltonians/QMCHamiltonian.cpp @@ -501,6 +501,29 @@ QMCHamiltonian::FullPrecRealType QMCHamiltonian::evaluate(ParticleSet& P) return LocalEnergy; } +QMCHamiltonian::FullPrecRealType QMCHamiltonian::evaluate2(ParticleSet& P) +{ + ScopedTimer local_timer(ham_timer_); + LocalEnergy = 0.0; + for (int i = 0; i < H.size(); ++i) + { + ScopedTimer h_timer(my_timers_[i]); + const auto LocalEnergyComponent = H[i]->evaluate2(P); + if (std::isnan(LocalEnergyComponent)) + APP_ABORT("QMCHamiltonian::evaluate component " + H[i]->myName + " returns NaN\n"); + LocalEnergy += LocalEnergyComponent; + H[i]->setObservables(Observables); +#if !defined(REMOVE_TRACEMANAGER) + H[i]->collect_scalar_traces(); +#endif + H[i]->setParticlePropertyList(P.PropertyList, myIndex); + } + KineticEnergy = H[0]->Value; + P.PropertyList[WP::LOCALENERGY] = LocalEnergy; + P.PropertyList[WP::LOCALPOTENTIAL] = LocalEnergy - KineticEnergy; + // auxHevaluate(P); + return LocalEnergy; +} void QMCHamiltonian::updateNonKinetic(OperatorBase& op, QMCHamiltonian& ham, ParticleSet& pset) { if (std::isnan(op.Value)) diff --git a/src/QMCHamiltonians/QMCHamiltonian.h b/src/QMCHamiltonians/QMCHamiltonian.h index 07eb40a93b..221569bd9d 100644 --- a/src/QMCHamiltonians/QMCHamiltonian.h +++ b/src/QMCHamiltonians/QMCHamiltonian.h @@ -230,7 +230,7 @@ class QMCHamiltonian * P.R, P.G and P.L are used to evaluate the LocalEnergy. */ FullPrecRealType evaluate(ParticleSet& P); - + FullPrecRealType evaluate2(ParticleSet& P); //This is the same as evaluate(), but doesn't update the quadrature grid for a PP point. /** batched version of evaluate for LocalEnergy * * Encapsulation is ignored for H_list hamiltonians method uses its status as QMCHamiltonian to break encapsulation. From fb3af863e518bdf59c06dc395c0315546473557c Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 21 Dec 2020 15:26:18 -0700 Subject: [PATCH 03/22] Add Space warp transformation skeleton class --- src/QMCHamiltonians/CMakeLists.txt | 1 + .../SpaceWarpTransformation.cpp | 11 ++++++ src/QMCHamiltonians/SpaceWarpTransformation.h | 36 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 src/QMCHamiltonians/SpaceWarpTransformation.cpp create mode 100644 src/QMCHamiltonians/SpaceWarpTransformation.h diff --git a/src/QMCHamiltonians/CMakeLists.txt b/src/QMCHamiltonians/CMakeLists.txt index c67775208f..c18c6f7367 100644 --- a/src/QMCHamiltonians/CMakeLists.txt +++ b/src/QMCHamiltonians/CMakeLists.txt @@ -42,6 +42,7 @@ SET(HAMSRCS SpinDensity.cpp SpeciesKineticEnergy.cpp LatticeDeviationEstimator.cpp + SpaceWarpTransformation.cpp ) IF(OHMMS_DIM MATCHES 3) diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.cpp b/src/QMCHamiltonians/SpaceWarpTransformation.cpp new file mode 100644 index 0000000000..4a06feb02b --- /dev/null +++ b/src/QMCHamiltonians/SpaceWarpTransformation.cpp @@ -0,0 +1,11 @@ +#include "QMCHamiltonians/SpaceWarpTransformation.h" + +namespace qmcplusplus +{ + +SpaceWarpTransformation::RealType SpaceWarpTransformation::f(RealType r) +{ + return 1.0/(r*r*r*r); +} + +} diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.h b/src/QMCHamiltonians/SpaceWarpTransformation.h new file mode 100644 index 0000000000..5b0e650656 --- /dev/null +++ b/src/QMCHamiltonians/SpaceWarpTransformation.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////////////////// +// 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: Raymond Clay +// +// File created by: Raymond Clay, Sandia National Laboratory, rclay@sandia.gov +////////////////////////////////////////////////////////////////////////////////////// + + +#ifndef QMCPLUSPLUS_SPACEWARP_H +#define QMCPLUSPLUS_SPACEWARP_H + +#include "Configuration.h" + +namespace qmcplusplus +{ +/** @ingroup hamiltonian + *\brief Calculates the AA Coulomb potential using PBCs + * + * Functionally identical to CoulombPBCAB but uses a templated version of + * LRHandler. + */ +struct SpaceWarpTransformation : public QMCTraits +{ + SpaceWarpTransformation(){}; + ~SpaceWarpTransformation(){}; + + RealType f(RealType r); +}; +} +#endif + + From bb5c9218f77c7e8a0e40485496847e720f6966b2 Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 21 Dec 2020 15:26:44 -0700 Subject: [PATCH 04/22] Start evaluating components needed for spacewarp in ACForce --- src/QMCHamiltonians/ACForce.cpp | 39 +++++++++++++++++++++++++++++++++ src/QMCHamiltonians/ACForce.h | 6 +++++ 2 files changed, 45 insertions(+) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 57391668c8..2c3d25c69c 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -24,9 +24,12 @@ ACForce::ACForce(ParticleSet& source, ParticleSet& target, TrialWaveFunction& ps prefix = "ACForce"; myName = prefix; Nions = ions.getTotalNum(); + hf_force.resize(Nions); pulay_force.resize(Nions); wf_grad.resize(Nions); + sw_force.resize(elns.getTotalNum()); + delta=1e-5; }; OperatorBase* ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi) @@ -56,6 +59,8 @@ ACForce::Return_t ACForce::evaluate(ParticleSet& P) //This function returns d/dR of the sum of all observables in the physical hamiltonian. //Note that the sign will be flipped based on definition of force = -d/dR. Value = ham.evaluateIonDerivs(P, ions, psi, hf_force, pulay_force, wf_grad); + computeElecGradEL(P,sw_force); + app_log()< Date: Tue, 22 Dec 2020 14:04:12 -0700 Subject: [PATCH 05/22] Initial bugged implementation of space warp --- src/QMCHamiltonians/ACForce.cpp | 30 ++++-- src/QMCHamiltonians/ACForce.h | 3 +- .../SpaceWarpTransformation.cpp | 98 ++++++++++++++++++- src/QMCHamiltonians/SpaceWarpTransformation.h | 24 ++++- 4 files changed, 142 insertions(+), 13 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 2c3d25c69c..6b95d9df93 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -19,7 +19,7 @@ namespace qmcplusplus { ACForce::ACForce(ParticleSet& source, ParticleSet& target, TrialWaveFunction& psi_in, QMCHamiltonian& H) - : ions(source), elns(target), psi(psi_in), ham(H), FirstForceIndex(-1), Nions(0) + : ions(source), elns(target), psi(psi_in), ham(H), FirstForceIndex(-1), Nions(0), swt(target,source) { prefix = "ACForce"; myName = prefix; @@ -28,8 +28,9 @@ ACForce::ACForce(ParticleSet& source, ParticleSet& target, TrialWaveFunction& ps hf_force.resize(Nions); pulay_force.resize(Nions); wf_grad.resize(Nions); - sw_force.resize(elns.getTotalNum()); - delta=1e-5; + sw_pulay.resize(Nions); + sw_grad.resize(Nions); + delta=1e-6; }; OperatorBase* ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi) @@ -55,12 +56,16 @@ ACForce::Return_t ACForce::evaluate(ParticleSet& P) hf_force = 0; pulay_force = 0; wf_grad = 0; - + sw_pulay = 0; + sw_grad = 0; + Force_t el_grad; + el_grad.resize(P.getTotalNum()); + el_grad=0; //This function returns d/dR of the sum of all observables in the physical hamiltonian. //Note that the sign will be flipped based on definition of force = -d/dR. Value = ham.evaluateIonDerivs(P, ions, psi, hf_force, pulay_force, wf_grad); - computeElecGradEL(P,sw_force); - app_log()< warpval; //Nelec x Nion matrix of F(|r_i-R_J|) + Matrix gradval; //Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) }; } #endif From 6f082a85ba9c4ee0dd474339b0117bd49548bb74 Mon Sep 17 00:00:00 2001 From: rcclay Date: Wed, 23 Dec 2020 12:25:17 -0700 Subject: [PATCH 06/22] Fix bug. Tentatively working and ready for testing --- src/QMCHamiltonians/ACForce.cpp | 7 +++---- src/QMCHamiltonians/SpaceWarpTransformation.cpp | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 6b95d9df93..b683c7c73c 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -30,7 +30,7 @@ ACForce::ACForce(ParticleSet& source, ParticleSet& target, TrialWaveFunction& ps wf_grad.resize(Nions); sw_pulay.resize(Nions); sw_grad.resize(Nions); - delta=1e-6; + delta=1e-4; }; OperatorBase* ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi) @@ -143,18 +143,17 @@ void ACForce::computeElecGradEL(ParticleSet& P, ACForce::Force_t& Egrad) int nelec=P.getTotalNum(); RealType ep(0.0); RealType em(0.0); - + RealType e0(0.0); for(int iel=0; iel +#include "OhmmsData/AttributeSet.h" namespace qmcplusplus { ACForce::ACForce(ParticleSet& source, ParticleSet& target, TrialWaveFunction& psi_in, QMCHamiltonian& H) - : ions(source), elns(target), psi(psi_in), ham(H), FirstForceIndex(-1), Nions(0), swt(target,source) + : ions(source), elns(target), psi(psi_in), ham(H), FirstForceIndex(-1), Nions(0), useSpaceWarp(false), swt(target,source) { prefix = "ACForce"; myName = prefix; @@ -44,6 +45,25 @@ OperatorBase* ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi_in, QMC OperatorBase* myclone = new ACForce(qp, ions, psi_in, ham_in); return myclone; } + +bool ACForce::put(xmlNodePtr cur) +{ + std::string useSpaceWarpString("no"); + std::string ionionforce("yes"); + RealType swpow(4); + OhmmsAttributeSet attr; + attr.add(useSpaceWarpString,"spacewarp"); //"yes" or "no" + attr.add(swpow, "swpow"); //REal number" + attr.put(cur); + + useSpaceWarp = (useSpaceWarpString == "yes") || (useSpaceWarpString == "true"); + swt.setPow(swpow); + + if(useSpaceWarp) app_log()<<"ACForce is using space warp with power="<second->getTWF(); ACForce* acforce = new ACForce(*source, *target, psi, *targetH); + acforce->put(cur); targetH->addOperator(acforce, title, false); } else diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.cpp b/src/QMCHamiltonians/SpaceWarpTransformation.cpp index 22d45d589c..c6e6c7bbe9 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.cpp +++ b/src/QMCHamiltonians/SpaceWarpTransformation.cpp @@ -5,23 +5,22 @@ namespace qmcplusplus { SpaceWarpTransformation::SpaceWarpTransformation(ParticleSet& elns, ParticleSet& ions): - myTableIndex(elns.addTable(ions)) + myTableIndex(elns.addTable(ions)), swpow(4.0) { Nelec=elns.getTotalNum(); Nions=ions.getTotalNum(); warpval.resize(Nelec,Nions); gradval.resize(Nelec,Nions); - app_log()<<"SpaceWarp transformation with 1/r^4 initialized\n"; } -SpaceWarpTransformation::RealType SpaceWarpTransformation::f(RealType r) +SpaceWarpTransformation::RealType SpaceWarpTransformation::f(RealType r, RealType inpow) { - return 1.0/(r*r*r*r); + return std::pow(r,-inpow); } -SpaceWarpTransformation::RealType SpaceWarpTransformation::df(RealType r) +SpaceWarpTransformation::RealType SpaceWarpTransformation::df(RealType r, RealType inpow) { - return -4.0/(r*r*r*r*r); + return -inpow*std::pow(r,-(inpow+1)); } void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, ParticleSet& ions) @@ -33,8 +32,8 @@ void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, ParticleSe const auto& dr = d_ab.getDisplRow(iel); for (size_t ionid = 0; ionid < Nions; ++ionid) { - warpval[iel][ionid]=f(dist[ionid]); - gradval[iel][ionid]=-dr[ionid]*(df(dist[ionid])/dist[ionid]); //because there's a -1 in distance table displacement definition. R-r :(. + warpval[iel][ionid]=f(dist[ionid],swpow); + gradval[iel][ionid]=-dr[ionid]*(df(dist[ionid],swpow)/dist[ionid]); //because there's a -1 in distance table displacement definition. R-r :(. } } diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.h b/src/QMCHamiltonians/SpaceWarpTransformation.h index 0048dbb29f..3ce62ea343 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.h +++ b/src/QMCHamiltonians/SpaceWarpTransformation.h @@ -33,9 +33,10 @@ struct SpaceWarpTransformation : public QMCTraits SpaceWarpTransformation(ParticleSet& elns, ParticleSet& ions); ~SpaceWarpTransformation(){}; - RealType f(RealType r); - RealType df(RealType r); + RealType f(RealType r, RealType a); + RealType df(RealType r, RealType a); + void setPow(RealType swpow_in){swpow=swpow_in;}; void computeSWTIntermediates(ParticleSet& P, ParticleSet& ions); //This computes the intermediate matrices required to build all //space warp components and gradients. @@ -49,6 +50,8 @@ struct SpaceWarpTransformation : public QMCTraits int myTableIndex; int Nelec; int Nions; + + RealType swpow; //Power of space warp transformation. Right now, r^{-swpow}. Matrix warpval; //Nelec x Nion matrix of F(|r_i-R_J|) Matrix gradval; //Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) }; From 9af3f0bfdd48f50b4dcdf057ec157c3ed1ce250b Mon Sep 17 00:00:00 2001 From: rcclay Date: Wed, 23 Dec 2020 17:52:06 -0700 Subject: [PATCH 08/22] Add unit test for spacewarp --- .../SpaceWarpTransformation.cpp | 12 +- src/QMCHamiltonians/SpaceWarpTransformation.h | 4 +- src/QMCHamiltonians/tests/CMakeLists.txt | 7 + src/QMCHamiltonians/tests/Na2.structure.xml | 31 +++++ src/QMCHamiltonians/tests/test_spacewarp.cpp | 127 ++++++++++++++++++ 5 files changed, 173 insertions(+), 8 deletions(-) create mode 100644 src/QMCHamiltonians/tests/Na2.structure.xml create mode 100644 src/QMCHamiltonians/tests/test_spacewarp.cpp diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.cpp b/src/QMCHamiltonians/SpaceWarpTransformation.cpp index c6e6c7bbe9..0ebecbb7e8 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.cpp +++ b/src/QMCHamiltonians/SpaceWarpTransformation.cpp @@ -13,14 +13,14 @@ SpaceWarpTransformation::SpaceWarpTransformation(ParticleSet& elns, ParticleSet& gradval.resize(Nelec,Nions); } -SpaceWarpTransformation::RealType SpaceWarpTransformation::f(RealType r, RealType inpow) +SpaceWarpTransformation::RealType SpaceWarpTransformation::f(RealType r) { - return std::pow(r,-inpow); + return std::pow(r,-swpow); } -SpaceWarpTransformation::RealType SpaceWarpTransformation::df(RealType r, RealType inpow) +SpaceWarpTransformation::RealType SpaceWarpTransformation::df(RealType r) { - return -inpow*std::pow(r,-(inpow+1)); + return -swpow*std::pow(r,-(swpow+1)); } void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, ParticleSet& ions) @@ -32,8 +32,8 @@ void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, ParticleSe const auto& dr = d_ab.getDisplRow(iel); for (size_t ionid = 0; ionid < Nions; ++ionid) { - warpval[iel][ionid]=f(dist[ionid],swpow); - gradval[iel][ionid]=-dr[ionid]*(df(dist[ionid],swpow)/dist[ionid]); //because there's a -1 in distance table displacement definition. R-r :(. + warpval[iel][ionid]=f(dist[ionid]); + gradval[iel][ionid]=-dr[ionid]*(df(dist[ionid])/dist[ionid]); //because there's a -1 in distance table displacement definition. R-r :(. } } diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.h b/src/QMCHamiltonians/SpaceWarpTransformation.h index 3ce62ea343..fb786a364e 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.h +++ b/src/QMCHamiltonians/SpaceWarpTransformation.h @@ -33,8 +33,8 @@ struct SpaceWarpTransformation : public QMCTraits SpaceWarpTransformation(ParticleSet& elns, ParticleSet& ions); ~SpaceWarpTransformation(){}; - RealType f(RealType r, RealType a); - RealType df(RealType r, RealType a); + RealType f(RealType r); + RealType df(RealType r); void setPow(RealType swpow_in){swpow=swpow_in;}; void computeSWTIntermediates(ParticleSet& P, ParticleSet& ions); //This computes the intermediate matrices required to build all diff --git a/src/QMCHamiltonians/tests/CMakeLists.txt b/src/QMCHamiltonians/tests/CMakeLists.txt index 31bca07eed..b87faf2287 100644 --- a/src/QMCHamiltonians/tests/CMakeLists.txt +++ b/src/QMCHamiltonians/tests/CMakeLists.txt @@ -31,6 +31,7 @@ SET(SRCS test_bare_kinetic.cpp test_force.cpp test_force_ewald.cpp test_stress.cpp + test_spacewarp.cpp test_ecp.cpp test_hamiltonian_pool.cpp test_hamiltonian_factory.cpp @@ -45,6 +46,12 @@ IF(QMC_CUDA) ) ENDIF() +SET(FILES_TO_COPY Na2.structure.xml) + +FOREACH(fname ${FILES_TO_COPY}) + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/${fname}" ${UTEST_DIR}) +ENDFOREACH() + EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory "${UTEST_DIR}") EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/simple.txt" ${UTEST_DIR}) EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy "${qmcpack_SOURCE_DIR}/tests/pseudopotentials_for_tests/C.BFD.xml" ${UTEST_DIR}) diff --git a/src/QMCHamiltonians/tests/Na2.structure.xml b/src/QMCHamiltonians/tests/Na2.structure.xml new file mode 100644 index 0000000000..a2c45ab636 --- /dev/null +++ b/src/QMCHamiltonians/tests/Na2.structure.xml @@ -0,0 +1,31 @@ + + + + + 1 + 1 + 11 + + + 0.0000000000e+00 0.0000000000e+00 0.0000000000e+00 + 5.9999995664e+00 0.0000000000e+00 0.0000000000e+00 + + + Na Na + + + + + -1 + + 5.6362539350e-01 9.5600940368e-01 -1.1525504049e+00 + + + + -1 + + 5.7820981934e+00 -1.0984181325e+00 1.1428020817e+00 + + + + diff --git a/src/QMCHamiltonians/tests/test_spacewarp.cpp b/src/QMCHamiltonians/tests/test_spacewarp.cpp new file mode 100644 index 0000000000..93f7e70e38 --- /dev/null +++ b/src/QMCHamiltonians/tests/test_spacewarp.cpp @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////////////////// +// 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: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign +// +// File created by: Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign +////////////////////////////////////////////////////////////////////////////////////// + + +#include "catch.hpp" + +#include "OhmmsData/Libxml2Doc.h" +#include "OhmmsPETE/OhmmsMatrix.h" +#include "Particle/ParticleSet.h" +#include "Particle/ParticleSetPool.h" +#include "ParticleIO/XMLParticleIO.h" +#include "QMCHamiltonians/SpaceWarpTransformation.h" +//#include "QMCWaveFunctions/SPOSetBuilderFactory.h" +//#include "QMCHamiltonians/ForceChiesaPBCAA.h" +//#include "QMCHamiltonians/ForceCeperley.h" +//#include "QMCHamiltonians/CoulombPotential.h" +//#include "QMCHamiltonians/CoulombPBCAA.h" +//#include "QMCHamiltonians/CoulombPBCAB.h" +//#include "QMCWaveFunctions/TrialWaveFunction.h" +//#include "QMCWaveFunctions/Fermion/DiracDeterminant.h" +//#include "QMCWaveFunctions/Fermion/SlaterDet.h" + +#include +#include + +using std::string; + +namespace qmcplusplus +{ +using RealType = QMCTraits::RealType; +TEST_CASE("SpaceWarp", "[hamiltonian]") +{ + Communicate* c = OHMMS::Controller; + + Libxml2Document doc; + bool okay = doc.parse("Na2.structure.xml"); + REQUIRE(okay); + xmlNodePtr root = doc.getRoot(); + Tensor tmat; + tmat(0, 0) = 1; + tmat(1, 1) = 1; + tmat(2, 2) = 1; + + ParticleSet ions; + XMLParticleParser parse_ions(ions, tmat); + OhmmsXPathObject particleset_ion("//particleset[@name='ion0']", doc.getXPathContext()); + REQUIRE(particleset_ion.size() == 1); + parse_ions.put(particleset_ion[0]); + + REQUIRE(ions.groups() == 1); + REQUIRE(ions.R.size() == 2); + ions.update(); + + ParticleSet elec; + XMLParticleParser parse_elec(elec, tmat); + OhmmsXPathObject particleset_elec("//particleset[@name='e']", doc.getXPathContext()); + REQUIRE(particleset_elec.size() == 1); + parse_elec.put(particleset_elec[0]); + + REQUIRE(elec.groups() == 2); + REQUIRE(elec.R.size() == 2); + + elec.addTable(ions); + elec.update(); + + //Now build the wavefunction. This will be needed to test \Nabla_i E_L and \Nabla_i logPsi contributions. + //For now, just take them from a reference calculation. + + using Force_t = ParticleSet::ParticlePos_t; + Force_t dE_L; + Force_t el_contribution; + Force_t psi_contribution; + + dE_L.resize(elec.getTotalNum()); + el_contribution.resize(ions.getTotalNum()); + psi_contribution.resize(ions.getTotalNum()); + + dE_L[0][0]=-0.0328339806050; + dE_L[0][1]=-0.0834441565340; + dE_L[0][2]= 0.0997813066140; + dE_L[1][0]=-0.0140597469190; + dE_L[1][1]= 0.0591827022730; + dE_L[1][2]=-0.0622852142310; + + elec.G[0][0]= 0.4167938814700; + elec.G[0][1]= 0.2878426639600; + elec.G[0][2]=-0.3470187402100; + elec.G[1][0]=-0.2946265813200; + elec.G[1][1]=-0.3606166249000; + elec.G[1][2]= 0.3751881159300; + + SpaceWarpTransformation swt(elec,ions); + swt.setPow(3.0); + + REQUIRE( swt.f(2.0) == Approx(0.125) ); + REQUIRE( swt.df(2.0) == Approx(-0.1875) ); + + swt.setPow(4.0); + REQUIRE( swt.f(2.0) == Approx(0.0625)); + REQUIRE( swt.df(2.0) == Approx(-0.125)); + + swt.computeSWT(elec, ions, dE_L, elec.G, el_contribution, psi_contribution); + app_log()<<"EL_Contribution: "< Date: Wed, 23 Dec 2020 18:30:26 -0700 Subject: [PATCH 09/22] Move grad(E_L) computation to QMCHamiltonian --- src/QMCHamiltonians/ACForce.cpp | 38 ++------------------------ src/QMCHamiltonians/ACForce.h | 1 - src/QMCHamiltonians/QMCHamiltonian.cpp | 34 ++++++++++++++++++++++- src/QMCHamiltonians/QMCHamiltonian.h | 9 ++++++ 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 7a394941ef..3ea1f775e4 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -53,7 +53,8 @@ bool ACForce::put(xmlNodePtr cur) RealType swpow(4); OhmmsAttributeSet attr; attr.add(useSpaceWarpString,"spacewarp"); //"yes" or "no" - attr.add(swpow, "swpow"); //REal number" + attr.add(swpow, "swpow"); //Real number" + attr.add(delta, "delta"); //Real number" attr.put(cur); useSpaceWarp = (useSpaceWarpString == "yes") || (useSpaceWarpString == "true"); @@ -87,7 +88,7 @@ ACForce::Return_t ACForce::evaluate(ParticleSet& P) if(useSpaceWarp) { - computeElecGradEL(P,el_grad); + ham.evaluateElecGrad(P,psi,el_grad,delta); swt.computeSWT(P,ions,el_grad,P.G,sw_pulay,sw_grad); } return 0.0; @@ -173,37 +174,4 @@ void ACForce::setParticlePropertyList(PropertySetType& plist, int offset) } }; -void ACForce::computeElecGradEL(ParticleSet& P, ACForce::Force_t& Egrad) -{ - int nelec=P.getTotalNum(); - RealType ep(0.0); - RealType em(0.0); - RealType e0(0.0); - for(int iel=0; iel QMCHamiltonian::flex_evaluateWithT } return local_energies; } - +void QMCHamiltonian::evaluateElecGrad(ParticleSet& P, TrialWaveFunction& psi, ParticleSet::ParticlePos_t& Egrad, RealType delta) +{ + int nelec=P.getTotalNum(); + RealType ep(0.0); + RealType em(0.0); + RealType e0(0.0); + for(int iel=0; iel& dhpsioverpsi); + /** Evaluate the electron gradient of the local energy. + * @param psi Trial Wave Function + * @param P electron particle set + * @param EGrad an Nelec x 3 real array which corresponds to d/d[r_i]_j E_L + * @param A finite difference step size if applicable. Default is to use finite diff with delta=1e-5. + * @return EGrad. Function itself returns nothing. + */ + void evaluateElecGrad(ParticleSet& P, TrialWaveFunction& psi, ParticleSet::ParticlePos_t& EGrad, RealType delta=1e-5); + /** evaluate local energy and derivatives w.r.t ionic coordinates. * @param P target particle set (electrons) * @param ions source particle set (ions) From 678e4d5e68d68c1ed60424ba9ea3782b730bb6b5 Mon Sep 17 00:00:00 2001 From: rcclay Date: Wed, 23 Dec 2020 18:58:00 -0700 Subject: [PATCH 10/22] Eliminate extra SW variables in scalar.dat. --- src/QMCHamiltonians/ACForce.cpp | 63 +++++++++++++++++---------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 3ea1f775e4..3a4b1447e0 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -116,18 +116,19 @@ void ACForce::addObservables(PropertySetType& plist, BufferType& collectables) plist.add(wfgradname1.str()); plist.add(wfgradname2.str()); - if(useSpaceWarp) - { - std::ostringstream swctname1; - std::ostringstream swctname2; - std::ostringstream swctname3; - swctname1 << prefix << "_swct1_" << iat << "_" << x; - swctname2 << prefix << "_swct2_" << iat << "_" << x; - swctname3 << prefix << "_swct3_" << iat << "_" << x; - plist.add(swctname1.str()); - plist.add(swctname2.str()); - plist.add(swctname3.str()); - } + //Remove when ACForce is production ready. +// if(useSpaceWarp) +// { +// std::ostringstream swctname1; +// std::ostringstream swctname2; +// std::ostringstream swctname3; +// swctname1 << prefix << "_swct1_" << iat << "_" << x; +// swctname2 << prefix << "_swct2_" << iat << "_" << x; +// swctname3 << prefix << "_swct3_" << iat << "_" << x; +// plist.add(swctname1.str()); +// plist.add(swctname2.str()); +// plist.add(swctname3.str()); +// } } } }; @@ -141,15 +142,17 @@ void ACForce::setObservables(PropertySetType& plist) //Flipping the sign, since these terms currently store d/dR values. // add the minus one to be a force. plist[myindex++] = -hf_force[iat][iondim]; - plist[myindex++] = -pulay_force[iat][iondim]; - plist[myindex++] = -Value * wf_grad[iat][iondim]; - plist[myindex++] = -wf_grad[iat][iondim]; - if(useSpaceWarp) - { - plist[myindex++] = -sw_pulay[iat][iondim]; - plist[myindex++] = -Value*sw_grad[iat][iondim]; - plist[myindex++] = -sw_grad[iat][iondim]; - } + plist[myindex++] = -(pulay_force[iat][iondim]+sw_pulay[iat][iondim]); + plist[myindex++] = -Value * (wf_grad[iat][iondim]+sw_grad[iat][iondim]); + plist[myindex++] = -(wf_grad[iat][iondim]+sw_grad[iat][iondim]); + + //Remove when ACForce is production ready +// if(useSpaceWarp) +// { +// plist[myindex++] = -sw_pulay[iat][iondim]; +// plist[myindex++] = -Value*sw_grad[iat][iondim]; +// plist[myindex++] = -sw_grad[iat][iondim]; +// } } } }; @@ -161,15 +164,15 @@ void ACForce::setParticlePropertyList(PropertySetType& plist, int offset) for (int iondim = 0; iondim < OHMMS_DIM; iondim++) { plist[myindex++] = -hf_force[iat][iondim]; - plist[myindex++] = -pulay_force[iat][iondim]; - plist[myindex++] = -Value * wf_grad[iat][iondim]; - plist[myindex++] = -wf_grad[iat][iondim]; - if(useSpaceWarp) - { - plist[myindex++] = -sw_pulay[iat][iondim]; - plist[myindex++] = -Value*sw_grad[iat][iondim]; - plist[myindex++] = -sw_grad[iat][iondim]; - } + plist[myindex++] = -(pulay_force[iat][iondim]+sw_pulay[iat][iondim]); + plist[myindex++] = -Value * (wf_grad[iat][iondim]+sw_grad[iat][iondim]); + plist[myindex++] = -(wf_grad[iat][iondim]+sw_grad[iat][iondim]); +// if(useSpaceWarp) +// { +// plist[myindex++] = -sw_pulay[iat][iondim]; +// plist[myindex++] = -Value*sw_grad[iat][iondim]; +// plist[myindex++] = -sw_grad[iat][iondim]; +// } } } }; From f79c6404697f4477b6ecc3ca70c0db127a1ad1d1 Mon Sep 17 00:00:00 2001 From: rcclay Date: Wed, 23 Dec 2020 19:12:15 -0700 Subject: [PATCH 11/22] Add some documentation --- .../SpaceWarpTransformation.cpp | 25 +++++-------------- src/QMCHamiltonians/SpaceWarpTransformation.h | 13 +++++----- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.cpp b/src/QMCHamiltonians/SpaceWarpTransformation.cpp index 0ebecbb7e8..a1e9a69a01 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.cpp +++ b/src/QMCHamiltonians/SpaceWarpTransformation.cpp @@ -22,7 +22,9 @@ SpaceWarpTransformation::RealType SpaceWarpTransformation::df(RealType r) { return -swpow*std::pow(r,-(swpow+1)); } - +//Space warp functions have the form w_I(r_i) = F(|r_i-R_I)/Sum_J F(|r_i-R_J|). Hence the intermediate we will +//precompute is the matrix "warpval[i][J] = F(|r_i-R_J|) and gradval[i][J]=Grad(F(|r_i-R_J|)). +//This allows the calculation of any space warp value or gradient by a matrix lookup, combined with a sum over columns. void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, ParticleSet& ions) { const DistanceTableData& d_ab(P.getDistTable(myTableIndex)); @@ -39,6 +41,8 @@ void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, ParticleSe } +//This function handles parsing of the intermediate matrices and construction of the w_I(r_i) and Grad_i(w_I(r_i)) functions +// that appear in the space warp transformation formulas. void SpaceWarpTransformation::getSWT(int iat, ParticleScalar_t& w, Force_t& grad_w) { for(size_t iel=0; iel Date: Wed, 23 Dec 2020 19:37:09 -0700 Subject: [PATCH 12/22] rename evaluate2 to evaluateDeterministic --- src/QMCHamiltonians/NonLocalECPotential.cpp | 2 +- src/QMCHamiltonians/NonLocalECPotential.h | 2 +- src/QMCHamiltonians/OperatorBase.cpp | 2 +- src/QMCHamiltonians/OperatorBase.h | 2 +- src/QMCHamiltonians/QMCHamiltonian.cpp | 8 ++++---- src/QMCHamiltonians/QMCHamiltonian.h | 8 +++++++- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/QMCHamiltonians/NonLocalECPotential.cpp b/src/QMCHamiltonians/NonLocalECPotential.cpp index 74ea6d5812..47bba0d9a0 100644 --- a/src/QMCHamiltonians/NonLocalECPotential.cpp +++ b/src/QMCHamiltonians/NonLocalECPotential.cpp @@ -104,7 +104,7 @@ NonLocalECPotential::Return_t NonLocalECPotential::evaluate(ParticleSet& P) return Value; } -NonLocalECPotential::Return_t NonLocalECPotential::evaluate2(ParticleSet& P) +NonLocalECPotential::Return_t NonLocalECPotential::evaluateDeterministic(ParticleSet& P) { evaluateImpl(P, false, true); return Value; diff --git a/src/QMCHamiltonians/NonLocalECPotential.h b/src/QMCHamiltonians/NonLocalECPotential.h index c77c0d4464..6d3f130a94 100644 --- a/src/QMCHamiltonians/NonLocalECPotential.h +++ b/src/QMCHamiltonians/NonLocalECPotential.h @@ -45,7 +45,7 @@ class NonLocalECPotential : public OperatorBase, public ForceBase #endif Return_t evaluate(ParticleSet& P) override; - Return_t evaluate2(ParticleSet& P) override; + Return_t evaluateDeterministic(ParticleSet& P) override; void mw_evaluate(const RefVector& O_list, const RefVector& P_list) override; Return_t evaluateWithToperator(ParticleSet& P) override; diff --git a/src/QMCHamiltonians/OperatorBase.cpp b/src/QMCHamiltonians/OperatorBase.cpp index cd97f61669..35d6268a2a 100644 --- a/src/QMCHamiltonians/OperatorBase.cpp +++ b/src/QMCHamiltonians/OperatorBase.cpp @@ -35,7 +35,7 @@ OperatorBase::OperatorBase() : myIndex(-1), Dependants(0), Value(0.0), tWalker(0 UpdateMode.set(PRIMARY, 1); } -OperatorBase::Return_t OperatorBase::evaluate2(ParticleSet& P) +OperatorBase::Return_t OperatorBase::evaluateDeterministic(ParticleSet& P) { return evaluate(P); } diff --git a/src/QMCHamiltonians/OperatorBase.h b/src/QMCHamiltonians/OperatorBase.h index 31c6441834..e6ab7563ff 100644 --- a/src/QMCHamiltonians/OperatorBase.h +++ b/src/QMCHamiltonians/OperatorBase.h @@ -246,7 +246,7 @@ struct OperatorBase : public QMCTraits *@return the value of the Hamiltonian component */ virtual Return_t evaluate(ParticleSet& P) = 0; - virtual Return_t evaluate2(ParticleSet& P); + virtual Return_t evaluateDeterministic(ParticleSet& P); /** Evaluate the contribution of this component of multiple walkers */ virtual void mw_evaluate(const RefVector& O_list, const RefVector& P_list); diff --git a/src/QMCHamiltonians/QMCHamiltonian.cpp b/src/QMCHamiltonians/QMCHamiltonian.cpp index aae7b104ed..5175035b05 100644 --- a/src/QMCHamiltonians/QMCHamiltonian.cpp +++ b/src/QMCHamiltonians/QMCHamiltonian.cpp @@ -501,14 +501,14 @@ QMCHamiltonian::FullPrecRealType QMCHamiltonian::evaluate(ParticleSet& P) return LocalEnergy; } -QMCHamiltonian::FullPrecRealType QMCHamiltonian::evaluate2(ParticleSet& P) +QMCHamiltonian::FullPrecRealType QMCHamiltonian::evaluateDeterministic(ParticleSet& P) { ScopedTimer local_timer(ham_timer_); LocalEnergy = 0.0; for (int i = 0; i < H.size(); ++i) { ScopedTimer h_timer(my_timers_[i]); - const auto LocalEnergyComponent = H[i]->evaluate2(P); + const auto LocalEnergyComponent = H[i]->evaluateDeterministic(P); if (std::isnan(LocalEnergyComponent)) APP_ABORT("QMCHamiltonian::evaluate component " + H[i]->myName + " returns NaN\n"); LocalEnergy += LocalEnergyComponent; @@ -834,14 +834,14 @@ void QMCHamiltonian::evaluateElecGrad(ParticleSet& P, TrialWaveFunction& psi, Pa P.R[iel][dim]=rp; P.update(); psi.evaluateLog(P); - ep=evaluate2(P); + ep=evaluateDeterministic(P); //minus RealType rm=r0-delta; P.R[iel][dim]=rm; P.update(); psi.evaluateLog(P); - em=evaluate2(P); + em=evaluateDeterministic(P); Egrad[iel][dim]=(ep-em)/(2.0*delta); P.R[iel][dim]=r0; diff --git a/src/QMCHamiltonians/QMCHamiltonian.h b/src/QMCHamiltonians/QMCHamiltonian.h index 0260168a00..6ccacbe5b7 100644 --- a/src/QMCHamiltonians/QMCHamiltonian.h +++ b/src/QMCHamiltonians/QMCHamiltonian.h @@ -230,7 +230,13 @@ class QMCHamiltonian * P.R, P.G and P.L are used to evaluate the LocalEnergy. */ FullPrecRealType evaluate(ParticleSet& P); - FullPrecRealType evaluate2(ParticleSet& P); //This is the same as evaluate(), but doesn't update the quadrature grid for a PP point. + + /** evaluate Local Energy deterministically. Defaults to evaluate(P) for operators without a stochastic component. For the nonlocal PP, the quadrature grid is not rerandomized. + * @param P ParticleSet + * @return Local energy. + * + */ + FullPrecRealType evaluateDeterministic(ParticleSet& P); /** batched version of evaluate for LocalEnergy * * Encapsulation is ignored for H_list hamiltonians method uses its status as QMCHamiltonian to break encapsulation. From b90dd26f750d3254fa2846e061b2cd94b18ac66f Mon Sep 17 00:00:00 2001 From: rcclay Date: Wed, 23 Dec 2020 20:15:40 -0700 Subject: [PATCH 13/22] Add return value to put --- src/QMCHamiltonians/ACForce.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 3a4b1447e0..ef57490925 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -62,7 +62,8 @@ bool ACForce::put(xmlNodePtr cur) if(useSpaceWarp) app_log()<<"ACForce is using space warp with power="< Date: Mon, 4 Jan 2021 10:20:40 -0700 Subject: [PATCH 14/22] Swap ordering of source/target args :| --- src/QMCHamiltonians/ACForce.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index ef57490925..7f49f0241f 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -42,7 +42,7 @@ OperatorBase* ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi) OperatorBase* ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi_in, QMCHamiltonian& ham_in) { - OperatorBase* myclone = new ACForce(qp, ions, psi_in, ham_in); + OperatorBase* myclone = new ACForce(ions, qp, psi_in, ham_in); return myclone; } From cb0e22513508a34ea5ed4b5ab8ae03cdc906b17d Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 10:21:15 -0700 Subject: [PATCH 15/22] Make SpaceWarp members and args const --- src/QMCHamiltonians/SpaceWarpTransformation.cpp | 10 ++++------ src/QMCHamiltonians/SpaceWarpTransformation.h | 12 ++++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.cpp b/src/QMCHamiltonians/SpaceWarpTransformation.cpp index a1e9a69a01..8aa142f612 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.cpp +++ b/src/QMCHamiltonians/SpaceWarpTransformation.cpp @@ -4,11 +4,9 @@ namespace qmcplusplus { -SpaceWarpTransformation::SpaceWarpTransformation(ParticleSet& elns, ParticleSet& ions): - myTableIndex(elns.addTable(ions)), swpow(4.0) +SpaceWarpTransformation::SpaceWarpTransformation(ParticleSet& elns, const ParticleSet& ions): + myTableIndex(elns.addTable(ions)), Nelec(elns.getTotalNum()), Nions(ions.getTotalNum()), swpow(4.0) { - Nelec=elns.getTotalNum(); - Nions=ions.getTotalNum(); warpval.resize(Nelec,Nions); gradval.resize(Nelec,Nions); } @@ -25,7 +23,7 @@ SpaceWarpTransformation::RealType SpaceWarpTransformation::df(RealType r) //Space warp functions have the form w_I(r_i) = F(|r_i-R_I)/Sum_J F(|r_i-R_J|). Hence the intermediate we will //precompute is the matrix "warpval[i][J] = F(|r_i-R_J|) and gradval[i][J]=Grad(F(|r_i-R_J|)). //This allows the calculation of any space warp value or gradient by a matrix lookup, combined with a sum over columns. -void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, ParticleSet& ions) +void SpaceWarpTransformation::computeSWTIntermediates(ParticleSet& P, const ParticleSet& ions) { const DistanceTableData& d_ab(P.getDistTable(myTableIndex)); for (size_t iel = 0; iel < Nelec; ++iel) @@ -59,7 +57,7 @@ void SpaceWarpTransformation::getSWT(int iat, ParticleScalar_t& w, Force_t& grad } } //This function returns Sum_i w_I(r_i) Grad_i(E_L) (as el_contribution) and Sum_i[ w_I(r_i)Grad_i(logpsi)+0.5*Grad_i(w_I(r_i)) (as psi_contribution). See Eq (15) and (16) respectively. -void SpaceWarpTransformation::computeSWT(ParticleSet& P, ParticleSet& ions, Force_t& dEl, ParticleGradient_t& dlogpsi, Force_t& el_contribution, Force_t& psi_contribution) +void SpaceWarpTransformation::computeSWT(ParticleSet& P, const ParticleSet& ions, Force_t& dEl, ParticleGradient_t& dlogpsi, Force_t& el_contribution, Force_t& psi_contribution) { el_contribution=0; psi_contribution=0; diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.h b/src/QMCHamiltonians/SpaceWarpTransformation.h index aacd89a293..64195e4c67 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.h +++ b/src/QMCHamiltonians/SpaceWarpTransformation.h @@ -29,7 +29,7 @@ struct SpaceWarpTransformation : public QMCTraits typedef ParticleSet::ParticlePos_t Force_t; typedef ParticleSet::ParticleGradient_t ParticleGradient_t; - SpaceWarpTransformation(ParticleSet& elns, ParticleSet& ions); + SpaceWarpTransformation(ParticleSet& elns, const ParticleSet& ions); ~SpaceWarpTransformation(){}; @@ -38,19 +38,19 @@ struct SpaceWarpTransformation : public QMCTraits void setPow(RealType swpow_in){swpow=swpow_in;}; //This sets the exponent for the power law space warp transformation. - void computeSWTIntermediates(ParticleSet& P, ParticleSet& ions); //This computes the intermediate matrices required to build all + void computeSWTIntermediates(ParticleSet& P, const ParticleSet& ions); //This computes the intermediate matrices required to build all //space warp components and gradients. void getSWT(int iat, ParticleScalar_t& w, Force_t& grad_w); //For each ion component iat, this generates all the required space warp quantities to //generate the "space warp" contribution to the iat-th force component. - void computeSWT(ParticleSet& elec, ParticleSet& ions, Force_t& dEl, ParticleGradient_t& dlogpsi, Force_t& el_contribution, Force_t& psi_contribution); //Takes in precomputed grad(E_L) and grad(logPsi), and uses + void computeSWT(ParticleSet& elec, const ParticleSet& ions, Force_t& dEl, ParticleGradient_t& dlogpsi, Force_t& el_contribution, Force_t& psi_contribution); //Takes in precomputed grad(E_L) and grad(logPsi), and uses //this to compute the ZV (el_contribution) and ZB (psi_contribution) //space warp contributions. - int myTableIndex; - int Nelec; - int Nions; + const int myTableIndex; + const int Nelec; + const int Nions; RealType swpow; //Power of space warp transformation. Right now, r^{-swpow}. Matrix warpval; //Nelec x Nion matrix of F(|r_i-R_J|) From 92b865ac8a8500873d56329abff133427e0997ba Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 10:26:16 -0700 Subject: [PATCH 16/22] clang-format everything --- src/QMCHamiltonians/ACForce.cpp | 105 ++++++----- src/QMCHamiltonians/NonLocalECPotential.cpp | 2 +- src/QMCHamiltonians/QMCHamiltonian.cpp | 32 ++-- src/QMCHamiltonians/QMCHamiltonian.h | 9 +- .../SpaceWarpTransformation.cpp | 92 +++++----- src/QMCHamiltonians/SpaceWarpTransformation.h | 41 +++-- src/QMCHamiltonians/tests/test_spacewarp.cpp | 172 +++++++++--------- 7 files changed, 238 insertions(+), 215 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 7f49f0241f..311033cbeb 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -20,18 +20,25 @@ namespace qmcplusplus { ACForce::ACForce(ParticleSet& source, ParticleSet& target, TrialWaveFunction& psi_in, QMCHamiltonian& H) - : ions(source), elns(target), psi(psi_in), ham(H), FirstForceIndex(-1), Nions(0), useSpaceWarp(false), swt(target,source) + : ions(source), + elns(target), + psi(psi_in), + ham(H), + FirstForceIndex(-1), + Nions(0), + useSpaceWarp(false), + swt(target, source) { prefix = "ACForce"; myName = prefix; Nions = ions.getTotalNum(); - + hf_force.resize(Nions); pulay_force.resize(Nions); wf_grad.resize(Nions); sw_pulay.resize(Nions); sw_grad.resize(Nions); - delta=1e-4; + delta = 1e-4; }; OperatorBase* ACForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi) @@ -52,18 +59,20 @@ bool ACForce::put(xmlNodePtr cur) std::string ionionforce("yes"); RealType swpow(4); OhmmsAttributeSet attr; - attr.add(useSpaceWarpString,"spacewarp"); //"yes" or "no" - attr.add(swpow, "swpow"); //Real number" - attr.add(delta, "delta"); //Real number" - attr.put(cur); + attr.add(useSpaceWarpString, "spacewarp"); //"yes" or "no" + attr.add(swpow, "swpow"); //Real number" + attr.add(delta, "delta"); //Real number" + attr.put(cur); useSpaceWarp = (useSpaceWarpString == "yes") || (useSpaceWarpString == "true"); swt.setPow(swpow); - - if(useSpaceWarp) app_log()<<"ACForce is using space warp with power="<randomize_grid(*myRNG); //loop over all the ions const auto& myTable = P.getDistTable(myTableIndex); diff --git a/src/QMCHamiltonians/QMCHamiltonian.cpp b/src/QMCHamiltonians/QMCHamiltonian.cpp index 5175035b05..d8caf547df 100644 --- a/src/QMCHamiltonians/QMCHamiltonian.cpp +++ b/src/QMCHamiltonians/QMCHamiltonian.cpp @@ -817,34 +817,38 @@ std::vector QMCHamiltonian::flex_evaluateWithT } return local_energies; } -void QMCHamiltonian::evaluateElecGrad(ParticleSet& P, TrialWaveFunction& psi, ParticleSet::ParticlePos_t& Egrad, RealType delta) +void QMCHamiltonian::evaluateElecGrad(ParticleSet& P, + TrialWaveFunction& psi, + ParticleSet::ParticlePos_t& Egrad, + RealType delta) { - int nelec=P.getTotalNum(); + int nelec = P.getTotalNum(); RealType ep(0.0); RealType em(0.0); RealType e0(0.0); - for(int iel=0; iel warpval; //Nelec x Nion matrix of F(|r_i-R_J|) - Matrix gradval; //Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) + RealType swpow; //Power of space warp transformation. Right now, r^{-swpow}. + Matrix warpval; //Nelec x Nion matrix of F(|r_i-R_J|) + Matrix gradval; //Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) }; -} +} // namespace qmcplusplus #endif - - diff --git a/src/QMCHamiltonians/tests/test_spacewarp.cpp b/src/QMCHamiltonians/tests/test_spacewarp.cpp index 93f7e70e38..8359562285 100644 --- a/src/QMCHamiltonians/tests/test_spacewarp.cpp +++ b/src/QMCHamiltonians/tests/test_spacewarp.cpp @@ -35,93 +35,93 @@ using std::string; namespace qmcplusplus { -using RealType = QMCTraits::RealType; +using RealType = QMCTraits::RealType; TEST_CASE("SpaceWarp", "[hamiltonian]") { - Communicate* c = OHMMS::Controller; - - Libxml2Document doc; - bool okay = doc.parse("Na2.structure.xml"); - REQUIRE(okay); - xmlNodePtr root = doc.getRoot(); - Tensor tmat; - tmat(0, 0) = 1; - tmat(1, 1) = 1; - tmat(2, 2) = 1; - - ParticleSet ions; - XMLParticleParser parse_ions(ions, tmat); - OhmmsXPathObject particleset_ion("//particleset[@name='ion0']", doc.getXPathContext()); - REQUIRE(particleset_ion.size() == 1); - parse_ions.put(particleset_ion[0]); - - REQUIRE(ions.groups() == 1); - REQUIRE(ions.R.size() == 2); - ions.update(); - - ParticleSet elec; - XMLParticleParser parse_elec(elec, tmat); - OhmmsXPathObject particleset_elec("//particleset[@name='e']", doc.getXPathContext()); - REQUIRE(particleset_elec.size() == 1); - parse_elec.put(particleset_elec[0]); - - REQUIRE(elec.groups() == 2); - REQUIRE(elec.R.size() == 2); - - elec.addTable(ions); - elec.update(); - - //Now build the wavefunction. This will be needed to test \Nabla_i E_L and \Nabla_i logPsi contributions. - //For now, just take them from a reference calculation. - - using Force_t = ParticleSet::ParticlePos_t; - Force_t dE_L; - Force_t el_contribution; - Force_t psi_contribution; - - dE_L.resize(elec.getTotalNum()); - el_contribution.resize(ions.getTotalNum()); - psi_contribution.resize(ions.getTotalNum()); - - dE_L[0][0]=-0.0328339806050; - dE_L[0][1]=-0.0834441565340; - dE_L[0][2]= 0.0997813066140; - dE_L[1][0]=-0.0140597469190; - dE_L[1][1]= 0.0591827022730; - dE_L[1][2]=-0.0622852142310; - - elec.G[0][0]= 0.4167938814700; - elec.G[0][1]= 0.2878426639600; - elec.G[0][2]=-0.3470187402100; - elec.G[1][0]=-0.2946265813200; - elec.G[1][1]=-0.3606166249000; - elec.G[1][2]= 0.3751881159300; - - SpaceWarpTransformation swt(elec,ions); - swt.setPow(3.0); - - REQUIRE( swt.f(2.0) == Approx(0.125) ); - REQUIRE( swt.df(2.0) == Approx(-0.1875) ); - - swt.setPow(4.0); - REQUIRE( swt.f(2.0) == Approx(0.0625)); - REQUIRE( swt.df(2.0) == Approx(-0.125)); - - swt.computeSWT(elec, ions, dE_L, elec.G, el_contribution, psi_contribution); - app_log()<<"EL_Contribution: "< tmat; + tmat(0, 0) = 1; + tmat(1, 1) = 1; + tmat(2, 2) = 1; + + ParticleSet ions; + XMLParticleParser parse_ions(ions, tmat); + OhmmsXPathObject particleset_ion("//particleset[@name='ion0']", doc.getXPathContext()); + REQUIRE(particleset_ion.size() == 1); + parse_ions.put(particleset_ion[0]); + + REQUIRE(ions.groups() == 1); + REQUIRE(ions.R.size() == 2); + ions.update(); + + ParticleSet elec; + XMLParticleParser parse_elec(elec, tmat); + OhmmsXPathObject particleset_elec("//particleset[@name='e']", doc.getXPathContext()); + REQUIRE(particleset_elec.size() == 1); + parse_elec.put(particleset_elec[0]); + + REQUIRE(elec.groups() == 2); + REQUIRE(elec.R.size() == 2); + + elec.addTable(ions); + elec.update(); + + //Now build the wavefunction. This will be needed to test \Nabla_i E_L and \Nabla_i logPsi contributions. + //For now, just take them from a reference calculation. + + using Force_t = ParticleSet::ParticlePos_t; + Force_t dE_L; + Force_t el_contribution; + Force_t psi_contribution; + + dE_L.resize(elec.getTotalNum()); + el_contribution.resize(ions.getTotalNum()); + psi_contribution.resize(ions.getTotalNum()); + + dE_L[0][0] = -0.0328339806050; + dE_L[0][1] = -0.0834441565340; + dE_L[0][2] = 0.0997813066140; + dE_L[1][0] = -0.0140597469190; + dE_L[1][1] = 0.0591827022730; + dE_L[1][2] = -0.0622852142310; + + elec.G[0][0] = 0.4167938814700; + elec.G[0][1] = 0.2878426639600; + elec.G[0][2] = -0.3470187402100; + elec.G[1][0] = -0.2946265813200; + elec.G[1][1] = -0.3606166249000; + elec.G[1][2] = 0.3751881159300; + + SpaceWarpTransformation swt(elec, ions); + swt.setPow(3.0); + + REQUIRE(swt.f(2.0) == Approx(0.125)); + REQUIRE(swt.df(2.0) == Approx(-0.1875)); + + swt.setPow(4.0); + REQUIRE(swt.f(2.0) == Approx(0.0625)); + REQUIRE(swt.df(2.0) == Approx(-0.125)); + + swt.computeSWT(elec, ions, dE_L, elec.G, el_contribution, psi_contribution); + app_log() << "EL_Contribution: " << el_contribution << std::endl; + app_log() << "PSi_Contribution: " << psi_contribution << std::endl; + REQUIRE(el_contribution[0][0] == Approx(-0.0326934696861)); + REQUIRE(el_contribution[0][1] == Approx(-0.0826080664130)); + REQUIRE(el_contribution[0][2] == Approx(0.0988243408507)); + REQUIRE(el_contribution[1][0] == Approx(-0.0142002578379)); + REQUIRE(el_contribution[1][1] == Approx(0.0583466121520)); + REQUIRE(el_contribution[1][2] == Approx(-0.0613282484677)); + + REQUIRE(psi_contribution[0][0] == Approx(0.4051467191368)); + REQUIRE(psi_contribution[0][1] == Approx(0.2757724717133)); + REQUIRE(psi_contribution[0][2] == Approx(-0.3334287440127)); + REQUIRE(psi_contribution[1][0] == Approx(-0.2829794189868)); + REQUIRE(psi_contribution[1][1] == Approx(-0.3485464326533)); + REQUIRE(psi_contribution[1][2] == Approx(0.3615981197327)); } } //namespace qmcplusplus From eab8162dac6833ebd0311075f1da257560938fbb Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 10:40:50 -0700 Subject: [PATCH 17/22] Make Nions const, also add comments --- src/QMCHamiltonians/ACForce.cpp | 8 ++++---- src/QMCHamiltonians/ACForce.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 311033cbeb..4f91644b22 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -25,13 +25,12 @@ ACForce::ACForce(ParticleSet& source, ParticleSet& target, TrialWaveFunction& ps psi(psi_in), ham(H), FirstForceIndex(-1), - Nions(0), + Nions(ions.getTotalNum()), useSpaceWarp(false), swt(target, source) { prefix = "ACForce"; myName = prefix; - Nions = ions.getTotalNum(); hf_force.resize(Nions); pulay_force.resize(Nions); @@ -126,7 +125,7 @@ void ACForce::addObservables(PropertySetType& plist, BufferType& collectables) plist.add(wfgradname1.str()); plist.add(wfgradname2.str()); - //Remove when ACForce is production ready. + //TODO: Remove when ACForce is production ready. // if(useSpaceWarp) // { // std::ostringstream swctname1; @@ -156,7 +155,7 @@ void ACForce::setObservables(PropertySetType& plist) plist[myindex++] = -Value * (wf_grad[iat][iondim] + sw_grad[iat][iondim]); plist[myindex++] = -(wf_grad[iat][iondim] + sw_grad[iat][iondim]); - //Remove when ACForce is production ready + //TODO: Remove when ACForce is production ready // if(useSpaceWarp) // { // plist[myindex++] = -sw_pulay[iat][iondim]; @@ -177,6 +176,7 @@ void ACForce::setParticlePropertyList(PropertySetType& plist, int offset) plist[myindex++] = -(pulay_force[iat][iondim] + sw_pulay[iat][iondim]); plist[myindex++] = -Value * (wf_grad[iat][iondim] + sw_grad[iat][iondim]); plist[myindex++] = -(wf_grad[iat][iondim] + sw_grad[iat][iondim]); + //TODO: Remove when ACForce is production ready // if(useSpaceWarp) // { // plist[myindex++] = -sw_pulay[iat][iondim]; diff --git a/src/QMCHamiltonians/ACForce.h b/src/QMCHamiltonians/ACForce.h index a0d9b0e9ac..560d78c061 100644 --- a/src/QMCHamiltonians/ACForce.h +++ b/src/QMCHamiltonians/ACForce.h @@ -67,7 +67,7 @@ struct ACForce : public OperatorBase //For indexing observables IndexType FirstForceIndex; - IndexType Nions; + const IndexType Nions; //Temporary Nion x 3 dimensional arrays for force storage. Force_t hf_force; From a324ec3765c3c455d0e7f4bfa296cbf5ca3514d4 Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 11:01:04 -0700 Subject: [PATCH 18/22] Make comments Doxygen friendly --- src/QMCHamiltonians/SpaceWarpTransformation.h | 56 +++++++++++++------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.h b/src/QMCHamiltonians/SpaceWarpTransformation.h index c56f285f1b..25d086f158 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.h +++ b/src/QMCHamiltonians/SpaceWarpTransformation.h @@ -32,40 +32,64 @@ struct SpaceWarpTransformation : public QMCTraits SpaceWarpTransformation(ParticleSet& elns, const ParticleSet& ions); ~SpaceWarpTransformation(){}; + RealType f(RealType r); ///< Space warp transformation function F. Argument is distance. + RealType df(RealType r); ///< The derivative of F w.r.t. r. - RealType f(RealType r); //space warp transformation function F. - RealType df(RealType r); //The gradient of F(r) - - void setPow(RealType swpow_in) + /** Sets the exponent for power law space warp transformation + * + * \param[in] swpow_in the exponent + */ + inline void setPow(RealType swpow_in) { swpow = swpow_in; - }; //This sets the exponent for the power law space warp transformation. + }; + /** Computes intermediate matrices required to build all space warp components and gradients. + * The intermediates calculated are "warpval" and "gradval". + * + * \param[in] P, the electron particle set. + * \param[in] ions, the ion particle set. + */ void computeSWTIntermediates(ParticleSet& P, - const ParticleSet& ions); //This computes the intermediate matrices required to build all - //space warp components and gradients. + const ParticleSet& ions); + + /** Generates required space warp quantities to generate the actual "Space Warp" contribution to the + * iat-th force component. + * \param[in] iat the ion index for the force. + * \param[out] w, w_iat(r_i) for each i, where i is the electron index. + * \param[out] grad_w, grad_i w_iat(r_i) for each i, where i is the electron index. + */ void getSWT(int iat, ParticleScalar_t& w, - Force_t& grad_w); //For each ion component iat, this generates all the required space warp quantities to - //generate the "space warp" contribution to the iat-th force component. - + Force_t& grad_w); + + /** Takes in precomputed grad(E_L) and grad(logPsi) and computes the ZV and ZB space warp contributions + * to the force. + * + * \param[in] elec, electron particle set. + * \param[in] ions, ion particle set. + * \param[in] dEl, grad_i(E_L) for each electron i. E_L is the local energy. + * \param[in] dlogpsi, grad_i(logPsi) for each electron i. + * \param[out] el_contribution, The zero-variance contribution from space warp. + * \param[out] psi_contribution, the zero-bias contribution from space warp. Modifies the grad_I(logPsi) terms. + */ void computeSWT(ParticleSet& elec, const ParticleSet& ions, Force_t& dEl, ParticleGradient_t& dlogpsi, Force_t& el_contribution, - Force_t& psi_contribution); //Takes in precomputed grad(E_L) and grad(logPsi), and uses - //this to compute the ZV (el_contribution) and ZB (psi_contribution) - //space warp contributions. + Force_t& psi_contribution); + + const int myTableIndex; const int Nelec; const int Nions; - RealType swpow; //Power of space warp transformation. Right now, r^{-swpow}. - Matrix warpval; //Nelec x Nion matrix of F(|r_i-R_J|) - Matrix gradval; //Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) + RealType swpow; ///< Power of space warp transformation. Right now, r^{-swpow}. + Matrix warpval; ///< Nelec x Nion matrix of F(|r_i-R_J|) + Matrix gradval; ///< Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) }; } // namespace qmcplusplus #endif From 65091e77c228805d2e66a4bb369f326b8921dfa3 Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 11:17:16 -0700 Subject: [PATCH 19/22] Change SpaceWarpTransformation from struct to class --- src/QMCHamiltonians/SpaceWarpTransformation.h | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.h b/src/QMCHamiltonians/SpaceWarpTransformation.h index 25d086f158..ade59d67c4 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.h +++ b/src/QMCHamiltonians/SpaceWarpTransformation.h @@ -23,12 +23,14 @@ namespace qmcplusplus * J. Chem. Phys., 133, 23411 (2010), https://doi.org/10.1063/1.3516208 * */ -struct SpaceWarpTransformation : public QMCTraits +class SpaceWarpTransformation : public QMCTraits { typedef ParticleSet::ParticleScalar_t ParticleScalar_t; typedef ParticleSet::ParticlePos_t Force_t; typedef ParticleSet::ParticleGradient_t ParticleGradient_t; + public: + SpaceWarpTransformation(ParticleSet& elns, const ParticleSet& ions); ~SpaceWarpTransformation(){}; @@ -44,16 +46,6 @@ struct SpaceWarpTransformation : public QMCTraits swpow = swpow_in; }; - /** Computes intermediate matrices required to build all space warp components and gradients. - * The intermediates calculated are "warpval" and "gradval". - * - * \param[in] P, the electron particle set. - * \param[in] ions, the ion particle set. - */ - void computeSWTIntermediates(ParticleSet& P, - const ParticleSet& ions); - - /** Generates required space warp quantities to generate the actual "Space Warp" contribution to the * iat-th force component. * \param[in] iat the ion index for the force. @@ -81,7 +73,19 @@ struct SpaceWarpTransformation : public QMCTraits Force_t& el_contribution, Force_t& psi_contribution); - + private: + + + /** Computes intermediate matrices required to build all space warp components and gradients. + * The intermediates calculated are "warpval" and "gradval". + * + * \param[in] P, the electron particle set. + * \param[in] ions, the ion particle set. + */ + void computeSWTIntermediates(ParticleSet& P, + const ParticleSet& ions); + + const int myTableIndex; const int Nelec; From 6e8cb4dcc88a790849c8591950dd3f6ccab24ad6 Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 11:18:08 -0700 Subject: [PATCH 20/22] Move space warp temp array allocation within spacewarp block --- src/QMCHamiltonians/ACForce.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.cpp b/src/QMCHamiltonians/ACForce.cpp index 4f91644b22..b3dc1d8dd8 100644 --- a/src/QMCHamiltonians/ACForce.cpp +++ b/src/QMCHamiltonians/ACForce.cpp @@ -88,15 +88,16 @@ ACForce::Return_t ACForce::evaluate(ParticleSet& P) wf_grad = 0; sw_pulay = 0; sw_grad = 0; - Force_t el_grad; - el_grad.resize(P.getTotalNum()); - el_grad = 0; //This function returns d/dR of the sum of all observables in the physical hamiltonian. //Note that the sign will be flipped based on definition of force = -d/dR. Value = ham.evaluateIonDerivs(P, ions, psi, hf_force, pulay_force, wf_grad); if (useSpaceWarp) { + Force_t el_grad; + el_grad.resize(P.getTotalNum()); + el_grad = 0; + ham.evaluateElecGrad(P, psi, el_grad, delta); swt.computeSWT(P, ions, el_grad, P.G, sw_pulay, sw_grad); } From 659156efd95c016dbb19c2ab89de743df50271ac Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 11:19:15 -0700 Subject: [PATCH 21/22] More doxygen stuff --- src/QMCHamiltonians/ACForce.h | 10 +++++++--- src/QMCHamiltonians/OperatorBase.h | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/QMCHamiltonians/ACForce.h b/src/QMCHamiltonians/ACForce.h index 560d78c061..27fbb787fe 100644 --- a/src/QMCHamiltonians/ACForce.h +++ b/src/QMCHamiltonians/ACForce.h @@ -55,7 +55,8 @@ struct ACForce : public OperatorBase /** Evaluate **/ Return_t evaluate(ParticleSet& P); - RealType delta; //finite difference time step + ///Finite difference timestep + RealType delta; //** Internal variables **/ // I'm assuming that psi, ions, elns, and the hamiltonian are bound to this @@ -65,11 +66,11 @@ struct ACForce : public OperatorBase TrialWaveFunction& psi; QMCHamiltonian& ham; - //For indexing observables + ///For indexing observables IndexType FirstForceIndex; const IndexType Nions; - //Temporary Nion x 3 dimensional arrays for force storage. + ///Temporary Nion x 3 dimensional arrays for force storage. Force_t hf_force; Force_t pulay_force; Force_t wf_grad; @@ -77,7 +78,10 @@ struct ACForce : public OperatorBase Force_t sw_grad; bool useSpaceWarp; + + ///The space warp transformation class. SpaceWarpTransformation swt; + //Class info. std::string prefix; //We also set the following from the OperatorBase class. diff --git a/src/QMCHamiltonians/OperatorBase.h b/src/QMCHamiltonians/OperatorBase.h index e6ab7563ff..ea7f8c4550 100644 --- a/src/QMCHamiltonians/OperatorBase.h +++ b/src/QMCHamiltonians/OperatorBase.h @@ -246,6 +246,10 @@ struct OperatorBase : public QMCTraits *@return the value of the Hamiltonian component */ virtual Return_t evaluate(ParticleSet& P) = 0; + /** Evaluate the local energy contribution of this component, deterministically based on current state. + *@param P input configuration containing N particles + *@return the value of the Hamiltonian component + */ virtual Return_t evaluateDeterministic(ParticleSet& P); /** Evaluate the contribution of this component of multiple walkers */ virtual void mw_evaluate(const RefVector& O_list, const RefVector& P_list); From 783225a1f882a0650078dab6d5baecdbda3ee261 Mon Sep 17 00:00:00 2001 From: rcclay Date: Mon, 4 Jan 2021 13:37:43 -0700 Subject: [PATCH 22/22] Last bit of formatting/commenting changes --- src/QMCHamiltonians/NonLocalECPotential.h | 3 +- src/QMCHamiltonians/OperatorBase.cpp | 8 +-- src/QMCHamiltonians/QMCHamiltonian.h | 4 +- src/QMCHamiltonians/SpaceWarpTransformation.h | 54 ++++++++++--------- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/QMCHamiltonians/NonLocalECPotential.h b/src/QMCHamiltonians/NonLocalECPotential.h index 7c67b2b84e..33f51608a6 100644 --- a/src/QMCHamiltonians/NonLocalECPotential.h +++ b/src/QMCHamiltonians/NonLocalECPotential.h @@ -151,8 +151,9 @@ class NonLocalECPotential : public OperatorBase, public ForceBase /** the actual implementation, used by evaluate and evaluateWithToperator * @param P particle set * @param Tmove whether Txy for Tmove is updated + * @param keepGrid. If true, does not randomize the quadrature grid before evaluation. */ - void evaluateImpl(ParticleSet& P, bool Tmove, bool keepGrid=false); + void evaluateImpl(ParticleSet& P, bool Tmove, bool keepGrid = false); /** the actual implementation for batched walkers, used by mw_evaluate and mw_evaluateWithToperator * @param O_list the list of NonLocalECPotential in a walker batch diff --git a/src/QMCHamiltonians/OperatorBase.cpp b/src/QMCHamiltonians/OperatorBase.cpp index 9b7b5d5103..2cf7ee0e74 100644 --- a/src/QMCHamiltonians/OperatorBase.cpp +++ b/src/QMCHamiltonians/OperatorBase.cpp @@ -35,10 +35,10 @@ OperatorBase::OperatorBase() : myIndex(-1), Dependants(0), Value(0.0), tWalker(0 UpdateMode.set(PRIMARY, 1); } -OperatorBase::Return_t OperatorBase::evaluateDeterministic(ParticleSet& P) -{ - return evaluate(P); -} +/** The correct behavior of this routine requires estimators with non-deterministic components + * in their evaluate() function to override this function. + */ +OperatorBase::Return_t OperatorBase::evaluateDeterministic(ParticleSet& P) { return evaluate(P); } /** Take o_list and p_list update evaluation result variables in o_list? * * really should reduce vector of local_energies. matching the ordering and size of o list diff --git a/src/QMCHamiltonians/QMCHamiltonian.h b/src/QMCHamiltonians/QMCHamiltonian.h index a6e9490e04..e1f5fe3cef 100644 --- a/src/QMCHamiltonians/QMCHamiltonian.h +++ b/src/QMCHamiltonians/QMCHamiltonian.h @@ -231,10 +231,10 @@ class QMCHamiltonian */ FullPrecRealType evaluate(ParticleSet& P); - /** evaluate Local Energy deterministically. Defaults to evaluate(P) for operators without a stochastic component. For the nonlocal PP, the quadrature grid is not rerandomized. + /** evaluate Local Energy deterministically. Defaults to evaluate(P) for operators + * without a stochastic component. For the nonlocal PP, the quadrature grid is not rerandomized. * @param P ParticleSet * @return Local energy. - * */ FullPrecRealType evaluateDeterministic(ParticleSet& P); /** batched version of evaluate for LocalEnergy diff --git a/src/QMCHamiltonians/SpaceWarpTransformation.h b/src/QMCHamiltonians/SpaceWarpTransformation.h index ade59d67c4..d5eefaf474 100644 --- a/src/QMCHamiltonians/SpaceWarpTransformation.h +++ b/src/QMCHamiltonians/SpaceWarpTransformation.h @@ -29,22 +29,28 @@ class SpaceWarpTransformation : public QMCTraits typedef ParticleSet::ParticlePos_t Force_t; typedef ParticleSet::ParticleGradient_t ParticleGradient_t; - public: - +public: SpaceWarpTransformation(ParticleSet& elns, const ParticleSet& ions); - ~SpaceWarpTransformation(){}; - RealType f(RealType r); ///< Space warp transformation function F. Argument is distance. - RealType df(RealType r); ///< The derivative of F w.r.t. r. + /** Space warp transformation function F(r). + * + * \param[in] r, the distance + * \param[out] value of F(r) + */ + RealType f(RealType r); + + /** Derivative of space warp transformation function F(r) w.r.t. r. + * + * \param[in] r, the distance + * \param[out] value of F'(r) + */ + RealType df(RealType r); /** Sets the exponent for power law space warp transformation * * \param[in] swpow_in the exponent - */ - inline void setPow(RealType swpow_in) - { - swpow = swpow_in; - }; + */ + inline void setPow(RealType swpow_in) { swpow = swpow_in; }; /** Generates required space warp quantities to generate the actual "Space Warp" contribution to the * iat-th force component. @@ -52,10 +58,8 @@ class SpaceWarpTransformation : public QMCTraits * \param[out] w, w_iat(r_i) for each i, where i is the electron index. * \param[out] grad_w, grad_i w_iat(r_i) for each i, where i is the electron index. */ - void getSWT(int iat, - ParticleScalar_t& w, - Force_t& grad_w); - + void getSWT(int iat, ParticleScalar_t& w, Force_t& grad_w); + /** Takes in precomputed grad(E_L) and grad(logPsi) and computes the ZV and ZB space warp contributions * to the force. * @@ -65,35 +69,35 @@ class SpaceWarpTransformation : public QMCTraits * \param[in] dlogpsi, grad_i(logPsi) for each electron i. * \param[out] el_contribution, The zero-variance contribution from space warp. * \param[out] psi_contribution, the zero-bias contribution from space warp. Modifies the grad_I(logPsi) terms. - */ + */ void computeSWT(ParticleSet& elec, const ParticleSet& ions, Force_t& dEl, ParticleGradient_t& dlogpsi, Force_t& el_contribution, - Force_t& psi_contribution); - - private: + Force_t& psi_contribution); - +private: /** Computes intermediate matrices required to build all space warp components and gradients. * The intermediates calculated are "warpval" and "gradval". * * \param[in] P, the electron particle set. * \param[in] ions, the ion particle set. */ - void computeSWTIntermediates(ParticleSet& P, - const ParticleSet& ions); - + void computeSWTIntermediates(ParticleSet& P, const ParticleSet& ions); + ///The electron-ion table index in electron table. const int myTableIndex; const int Nelec; const int Nions; - RealType swpow; ///< Power of space warp transformation. Right now, r^{-swpow}. - Matrix warpval; ///< Nelec x Nion matrix of F(|r_i-R_J|) - Matrix gradval; ///< Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) + /// Power of space warp transformation. Right now, r^{-swpow}. + RealType swpow; + /// Nelec x Nion matrix of F(|r_i-R_J|) + Matrix warpval; + /// Nelec x Nion matrix of \nabla_i F(|r_i-R_J|) + Matrix gradval; }; } // namespace qmcplusplus #endif