1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 //                    Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 //                    Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 //                    Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
11 //                    Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #ifndef QMCPLUSPLUS_NONLOCAL_ECPOTENTIAL_H
18 #define QMCPLUSPLUS_NONLOCAL_ECPOTENTIAL_H
19 #include "QMCHamiltonians/NonLocalTOperator.h"
20 #include "QMCHamiltonians/ForceBase.h"
21 #include "QMCHamiltonians/NonLocalECPComponent.h"
22 #include "Particle/NeighborLists.h"
23 
24 namespace qmcplusplus
25 {
26 template<typename T>
27 struct NLPPJob;
28 
29 struct NonLocalECPotentialMultiWalkerResource;
30 
31 /** @ingroup hamiltonian
32  * \brief Evaluate the semi local potentials
33  */
34 class NonLocalECPotential : public OperatorBase, public ForceBase
35 {
36 public:
37   NonLocalECPotential(ParticleSet& ions, ParticleSet& els, TrialWaveFunction& psi, bool computeForces, bool enable_DLA);
38   ~NonLocalECPotential();
39 
40   void resetTargetParticleSet(ParticleSet& P) override;
41 
42 #if !defined(REMOVE_TRACEMANAGER)
43   virtual void contribute_particle_quantities() override;
44   virtual void checkout_particle_quantities(TraceManager& tm) override;
45   virtual void delete_particle_quantities() override;
46 #endif
47 
48   Return_t evaluate(ParticleSet& P) override;
49   Return_t evaluateDeterministic(ParticleSet& P) override;
50   void mw_evaluate(const RefVectorWithLeader<OperatorBase>& O_list,
51                    const RefVectorWithLeader<ParticleSet>& P_list) const override;
52 
53   Return_t evaluateWithToperator(ParticleSet& P) override;
54 
55   void mw_evaluateWithToperator(const RefVectorWithLeader<OperatorBase>& O_list,
56                                 const RefVectorWithLeader<ParticleSet>& P_list) const override;
57 
58   Return_t evaluateWithIonDerivs(ParticleSet& P,
59                                  ParticleSet& ions,
60                                  TrialWaveFunction& psi,
61                                  ParticleSet::ParticlePos_t& hf_terms,
62                                  ParticleSet::ParticlePos_t& pulay_terms) override;
63 
64   /** set non local moves options
65    * @param cur the xml input
66    */
setNonLocalMoves(xmlNodePtr cur)67   void setNonLocalMoves(xmlNodePtr cur) { UseTMove = nonLocalOps.put(cur); }
68 
setNonLocalMoves(const std::string & non_local_move_option,const double tau,const double alpha,const double gamma)69   void setNonLocalMoves(const std::string& non_local_move_option,
70                         const double tau,
71                         const double alpha,
72                         const double gamma)
73   {
74     UseTMove = nonLocalOps.thingsThatShouldBeInMyConstructor(non_local_move_option, tau, alpha, gamma);
75   }
76   /** make non local moves with particle-by-particle moves
77    * @param P particle set
78    * @return the number of accepted moves
79    */
80   int makeNonLocalMovesPbyP(ParticleSet& P);
81 
82   Return_t evaluateValueAndDerivatives(ParticleSet& P,
83                                        const opt_variables_type& optvars,
84                                        const std::vector<ValueType>& dlogpsi,
85                                        std::vector<ValueType>& dhpsioverpsi) override;
86 
87   /** Do nothing */
put(xmlNodePtr cur)88   bool put(xmlNodePtr cur) override { return true; }
89 
get(std::ostream & os)90   bool get(std::ostream& os) const override
91   {
92     os << "NonLocalECPotential: " << IonConfig.getName();
93     return true;
94   }
95 
96   /** initialize a shared resource and hand it to a collection
97    */
98   void createResource(ResourceCollection& collection) const override;
99 
100   /** acquire a shared resource from a collection
101    */
102   void acquireResource(ResourceCollection& collection) override;
103 
104   /** return a shared resource to a collection
105    */
106   void releaseResource(ResourceCollection& collection) override;
107 
108   OperatorBase* makeClone(ParticleSet& qp, TrialWaveFunction& psi) override;
109 
110   void addComponent(int groupID, std::unique_ptr<NonLocalECPComponent>&& pp);
111 
112   /** set the internal RNG pointer as the given pointer
113    * @param rng input RNG pointer
114    */
setRandomGenerator(RandomGenerator_t * rng)115   void setRandomGenerator(RandomGenerator_t* rng) override { myRNG = rng; }
116 
117   void addObservables(PropertySetType& plist, BufferType& collectables) override;
118 
119   void setObservables(PropertySetType& plist) override;
120 
121   void setParticlePropertyList(PropertySetType& plist, int offset) override;
122 
123   void registerObservables(std::vector<observable_helper*>& h5list, hid_t gid) const override;
124 
125 protected:
126   ///random number generator
127   RandomGenerator_t* myRNG;
128   ///the set of local-potentials (one for each ion)
129   std::vector<NonLocalECPComponent*> PP;
130   ///unique NonLocalECPComponent to remove
131   std::vector<std::unique_ptr<NonLocalECPComponent>> PPset;
132   ///reference to the center ion
133   ParticleSet& IonConfig;
134   ///target TrialWaveFunction
135   TrialWaveFunction& Psi;
136   ///true if we should compute forces
137   bool ComputeForces;
138   ///true, determinant localization approximation(DLA) is enabled
139   bool use_DLA;
140 
141 private:
142   ///number of ions
143   int NumIons;
144   ///index of distance table for the ion-el pair
145   int myTableIndex;
146   ///reference to the electrons
147   ParticleSet& Peln;
148   ///neighborlist of electrons
149   NeighborLists ElecNeighborIons;
150   ///neighborlist of ions
151   NeighborLists IonNeighborElecs;
152   ///use T-moves
153   int UseTMove;
154   ///ture if an electron is affected by other electrons moved by T-moves
155   std::vector<bool> elecTMAffected;
156   ///non local operator
157   NonLocalTOperator nonLocalOps;
158   ///Pulay force vector
159   ParticleSet::ParticlePos_t PulayTerm;
160 #if !defined(REMOVE_TRACEMANAGER)
161   ///single particle trace samples
162   Array<TraceReal, 1>* Ve_sample;
163   Array<TraceReal, 1>* Vi_sample;
164 #endif
165   ///NLPP job list of ion-electron pairs by spin group
166   std::vector<std::vector<NLPPJob<RealType>>> nlpp_jobs;
167   /// mult walker shared resource
168   std::unique_ptr<NonLocalECPotentialMultiWalkerResource> mw_res_;
169 
170   /** the actual implementation, used by evaluate and evaluateWithToperator
171    * @param P particle set
172    * @param Tmove whether Txy for Tmove is updated
173    * @param keepGrid.  If true, does not randomize the quadrature grid before evaluation.
174    */
175   void evaluateImpl(ParticleSet& P, bool Tmove, bool keepGrid = false);
176 
177   /** the actual implementation for batched walkers, used by mw_evaluate and mw_evaluateWithToperator
178    * @param O_list the list of NonLocalECPotential in a walker batch
179    * @param P_list the list of ParticleSet in a walker batch
180    * @param Tmove whether Txy for Tmove is updated
181    */
182   static void mw_evaluateImpl(const RefVectorWithLeader<OperatorBase>& O_list,
183                               const RefVectorWithLeader<ParticleSet>& P_list,
184                               bool Tmove);
185 
186   /** compute the T move transition probability for a given electron
187    * member variable nonLocalOps.Txy is updated
188    * @param P particle set
189    * @param ref_elec reference electron id
190    */
191   void computeOneElectronTxy(ParticleSet& P, const int ref_elec);
192 
193   /** mark all the electrons affected by Tmoves and update ElecNeighborIons and IonNeighborElecs
194    * @param myTable electron ion distance table
195    * @param iel reference electron
196    * Note this function should be called before acceptMove for a Tmove
197    */
198   void markAffectedElecs(const DistanceTableData& myTable, int iel);
199 };
200 } // namespace qmcplusplus
201 #endif
202