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) 2020 QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 //                    Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
9 //                    Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 //                    Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //                    Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
12 //                    Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
13 //                    Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
14 //
15 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
16 //////////////////////////////////////////////////////////////////////////////////////
17 
18 
19 /**@file TrialWaveFunction.h
20  *@brief Declaration of a TrialWaveFunction
21  */
22 #ifndef QMCPLUSPLUS_TRIALWAVEFUNCTION_H
23 #define QMCPLUSPLUS_TRIALWAVEFUNCTION_H
24 
25 #include "Message/MPIObjectBase.h"
26 #include "Particle/VirtualParticleSet.h"
27 #include "QMCWaveFunctions/WaveFunctionComponent.h"
28 #include "QMCWaveFunctions/DiffWaveFunctionComponent.h"
29 #include "Utilities/TimerManager.h"
30 #include "type_traits/template_types.hpp"
31 #include "Containers/MinimalContainers/RecordArray.hpp"
32 #ifdef QMC_CUDA
33 #include "type_traits/CUDATypes.h"
34 #endif
35 
36 /**@defgroup MBWfs Many-body wave function group
37  * @brief Classes to handle many-body trial wave functions
38  */
39 
40 namespace qmcplusplus
41 {
42 /** @ingroup MBWfs
43  * @brief Class to represent a many-body trial wave function
44  *
45  *A many-body trial wave function is represented by
46  *\f$\Psi({\bf R}) = \prod_i \psi_i({\bf R})\f$,
47  *where each function \f$\psi_i({\bf R})\f$ is an WaveFunctionComponent
48  (see WaveFunctionComponent).
49  *A Composite Pattern is used to handle \f$\prod\f$ operations.
50  *Each WaveFunctionComponent should provide proper evaluate functions
51  *for the value, gradient and laplacian values.
52  *
53  * mw_ prefix is a function name signature indicating it is for handling
54  * a batch of TrialWaveFunction objects in a lock-step fashion. These functions
55  * are defined statically because they should not have access to a
56  * concrete TWF object except through the passed RefVectorWithLeader<TWF>&.
57  * It dispatches to mw_ functions of WaveFunctionComponent
58  */
59 class TrialWaveFunction
60 {
61 public:
62   // derived types from WaveFunctionComponent
63   typedef WaveFunctionComponent::RealType RealType;
64   typedef WaveFunctionComponent::ComplexType ComplexType;
65   using FullPrecRealType = WaveFunctionComponent::FullPrecRealType;
66   typedef WaveFunctionComponent::ValueType ValueType;
67   typedef WaveFunctionComponent::PosType PosType;
68   typedef WaveFunctionComponent::GradType GradType;
69   typedef WaveFunctionComponent::BufferType BufferType;
70   typedef WaveFunctionComponent::WFBufferType WFBufferType;
71   typedef WaveFunctionComponent::HessType HessType;
72   typedef WaveFunctionComponent::HessVector_t HessVector_t;
73   using LogValueType = WaveFunctionComponent::LogValueType;
74   using PsiValueType = WaveFunctionComponent::PsiValueType;
75 
76 #ifdef QMC_CUDA
77   using CTS = CUDAGlobalTypes;
78   typedef WaveFunctionComponent::RealMatrix_t RealMatrix_t;
79   typedef WaveFunctionComponent::ValueMatrix_t ValueMatrix_t;
80   typedef WaveFunctionComponent::GradMatrix_t GradMatrix_t;
81   typedef ParticleSet::Walker_t Walker_t;
82 #endif
83 
84   /// enum type for computing partial WaveFunctionComponents
85   enum class ComputeType
86   {
87     ALL,
88     FERMIONIC,
89     NONFERMIONIC
90   };
91 
92   ///differential gradients
93   ParticleSet::ParticleGradient_t G;
94   ///differential laplacians
95   ParticleSet::ParticleLaplacian_t L;
96 
97   TrialWaveFunction(const std::string& aname = "psi0", bool tasking = false, bool create_local_resource = true);
98 
99   // delete copy constructor
100   TrialWaveFunction(const TrialWaveFunction&) = delete;
101   // deleteFassign operator
102   TrialWaveFunction& operator=(const TrialWaveFunction&) = delete;
103 
104   ~TrialWaveFunction();
105 
size()106   inline int size() const { return Z.size(); }
getPhase()107   inline RealType getPhase() const { return PhaseValue; }
108 
setPhase(RealType PhaseValue_new)109   inline void setPhase(RealType PhaseValue_new) { PhaseValue = PhaseValue_new; }
110   void getLogs(std::vector<RealType>& lvals);
111   void getPhases(std::vector<RealType>& pvals);
112 
getPhaseDiff()113   inline RealType getPhaseDiff() const { return PhaseDiff; }
resetPhaseDiff()114   inline void resetPhaseDiff() { PhaseDiff = 0.0; }
getLogPsi()115   inline RealType getLogPsi() const { return LogValue; }
setLogPsi(RealType LogPsi_new)116   inline void setLogPsi(RealType LogPsi_new) { LogValue = LogPsi_new; }
117 
118   /** add a WaveFunctionComponent
119    * @param aterm a WaveFunctionComponent pointer
120    */
121   void addComponent(WaveFunctionComponent* aterm);
122 
123   ///read from xmlNode
124   bool put(xmlNodePtr cur);
125   ///implement the virtual function
126   void reset();
127   /** set WaveFunctionComponent::IsOptimizing to true */
128   void startOptimization();
129   /** set WaveFunctionComponent::IsOptimizing to flase */
130   void stopOptimization();
131   /** check in an optimizable parameter
132    * * @param o a super set of optimizable variables
133    *
134    * Update myOptIndex if o is found among the "active" paramemters.
135    */
136   void checkInVariables(opt_variables_type& o);
137   /** check out optimizable variables
138    */
139   void checkOutVariables(const opt_variables_type& o);
140   ///reset member data
141   void resetParameters(const opt_variables_type& active);
142   /** print out state of the trial wavefunction
143    */
144   void reportStatus(std::ostream& os);
145 
146   /** evalaute the log (internally gradients and laplacian) of the trial wavefunction. gold reference */
147   RealType evaluateLog(ParticleSet& P);
148 
149   /** batched version of evaluateLog. gold reference */
150   static void mw_evaluateLog(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
151                              const RefVectorWithLeader<ParticleSet>& p_list);
152 
153   /** recompute the value of the orbitals which require critical accuracy */
154   void recompute(const ParticleSet& P);
155 
156   /** batched version of recompute*/
157   static void mw_recompute(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
158                            const RefVectorWithLeader<ParticleSet>& p_list,
159                            const std::vector<bool>& recompute);
160 
161   /** evaluate the log value of a many-body wave function
162    * @param P input configuration containing N particles
163    * @param recomputeall recompute all orbitals from scratch
164    * @return the value of \f$ \log( \Pi_i \Psi_i) \f$  many-body wave function
165    *
166    * @if recompute == true
167    *   all orbitals have "evaluateLog" called on them, including the non-optimized ones.
168    * @else
169    *   default value.  call evaluateLog only on optimizable orbitals.  OK if nonlocal pp's aren't used.
170    *
171    * To save time, logpsi, G, and L are only computed for orbitals that change over the course of the optimization.
172    * It is assumed that the fixed components are stored elsewhere.  See evaluateDeltaLog(P,logpsi_fixed_r,logpsi_opt,fixedG,fixedL)
173    * defined below.  Nonlocal pseudopotential evaluation requires temporary information like matrix inverses, so while
174    * the logpsi, G, and L don't change, evaluateLog is called anyways to compute these auxiliary quantities from scratch.
175    * logpsi, G, and L associated with these non-optimizable orbitals are discarded explicitly and with dummy variables.
176    */
177 
178   RealType evaluateDeltaLog(ParticleSet& P, bool recompute = false);
179 
180   /** evaluate the sum of log value of optimizable many-body wavefunctions
181    * @param P  input configuration containing N particles
182    * @param logpsi_fixed log(std::abs(psi)) of the invariant orbitals
183    * @param logpsi_opt log(std::abs(psi)) of the variable orbitals
184    * @param fixedG gradients of log(psi) of the fixed wave functions
185    * @param fixedL laplacians of log(psi) of the fixed wave functions
186    *
187    * This function is introduced for optimization only.
188    * fixedG and fixedL save the terms coming from the wave functions
189    * that are invariant during optimizations.
190    * It is expected that evaluateDeltaLog(P,false) is called later
191    * and the external object adds the varying G and L and the fixed terms.
192    */
193   void evaluateDeltaLog(ParticleSet& P,
194                         RealType& logpsi_fixed,
195                         RealType& logpsi_opt,
196                         ParticleSet::ParticleGradient_t& fixedG,
197                         ParticleSet::ParticleLaplacian_t& fixedL);
198 
199   /** evaluate the sum of log value of optimizable many-body wavefunctions
200    * @param wf_list vector of wavefunctions
201    * @param p_list vector of input particle configurations
202    * @param logpsi_fixed_list vector of log(std::abs(psi)) of the invariant orbitals
203    * @param logpsi_opt_list vector of log(std::abs(psi)) of the variable orbitals
204    * @param fixedG_list vector of gradients of log(psi) of the fixed wave functions
205    * @param fixedL_list vector of laplacians of log(psi) of the fixed wave functions
206    *
207    * For wavefunction optimization, it can speed evaluation to split the log value,
208    * the gradient, and the laplacian computed from wavefunction components with optimizable
209    * parameters from components that do not.  This function computes the log value of
210    * both parts, and the gradient and laplacian of the fixed components.
211    * During correlated sampling steps only the components with optimizable
212    * parameters need to have the gradient and laplacian re-evaluated.
213    *
214    * Parameters fixedG_list and fixedL_list save the terms coming from the components
215    * that do not have optimizable parameters.
216    * It is expected that mw_evaluateDeltaLog(P,false) is called later
217    * and the external object adds the varying G and L and the fixed terms.
218    */
219   static void mw_evaluateDeltaLogSetup(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
220                                        const RefVectorWithLeader<ParticleSet>& p_list,
221                                        std::vector<RealType>& logpsi_fixed_list,
222                                        std::vector<RealType>& logpsi_opt_list,
223                                        RefVector<ParticleSet::ParticleGradient_t>& fixedG_list,
224                                        RefVector<ParticleSet::ParticleLaplacian_t>& fixedL_list);
225 
226   /** evaluate the log value for optimizable parts of a many-body wave function
227    * @param wf_list vector of wavefunctions
228    * @param p_list vector of input particle configurations
229    * @param logpsi_list vector of log(std::abs(psi)) of the variable orbitals
230    * @param dummyG_list vector of gradients of log(psi) of the fixed wave functions.
231    * @param dummyL_list vector of laplacians of log(psi) of the fixed wave functions
232    *
233    * The dummyG_list and dummyL_list are only referenced if recompute is true.
234    * If recompute is false, the storage of these lists are needed, but the values can be discarded.
235    *
236    * @if recompute == true
237    *   all orbitals have "evaluateLog" called on them, including the non-optimized ones.
238    * @else
239    *   default value.  call evaluateLog only on optimizable orbitals.  OK if nonlocal pp's aren't used.
240    *
241    * To save time, logpsi, G, and L are only computed for orbitals that change over the course of the optimization.
242    * It is assumed that the fixed components are stored elsewhere.  See mw_evaluateDeltaLogSetup defined above.
243    * Nonlocal pseudopotential evaluation requires temporary information like matrix inverses, so while
244    * the logpsi, G, and L don't change, evaluateLog is called anyways to compute these auxiliary quantities from scratch.
245    * logpsi, G, and L associated with these non-optimizable orbitals are discarded explicitly and with dummy variables.
246    */
247 
248 
249   static void mw_evaluateDeltaLog(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
250                                   const RefVectorWithLeader<ParticleSet>& p_list,
251                                   std::vector<RealType>& logpsi_list,
252                                   RefVector<ParticleSet::ParticleGradient_t>& dummyG_list,
253                                   RefVector<ParticleSet::ParticleLaplacian_t>& dummyL_list,
254                                   bool recompute = false);
255 
256 
257   /** compute psi(R_new) / psi(R_current) ratio
258    * It returns a complex value if the wavefunction is complex.
259    * @param P the active ParticleSet
260    * @param iat the index of a particle moved to the new position.
261    * @param ct select ComputeType
262    * @return ratio value
263    */
264   ValueType calcRatio(ParticleSet& P, int iat, ComputeType ct = ComputeType::ALL);
265 
266   /** batched version of calcRatio */
267   static void mw_calcRatio(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
268                            const RefVectorWithLeader<ParticleSet>& p_list,
269                            int iat,
270                            std::vector<PsiValueType>& ratios,
271                            ComputeType ct = ComputeType::ALL);
272 
273   /** compulte multiple ratios to handle non-local moves and other virtual moves
274    */
275   void evaluateRatios(const VirtualParticleSet& VP, std::vector<ValueType>& ratios, ComputeType ct = ComputeType::ALL);
276   /** batched version of evaluateRatios
277    * Note: unlike other mw_ static functions, *this is the batch leader instead of wf_list[0].
278    */
279   static void mw_evaluateRatios(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
280                                 const RefVector<const VirtualParticleSet>& Vp_list,
281                                 const RefVector<std::vector<ValueType>>& ratios_list,
282                                 ComputeType ct = ComputeType::ALL);
283 
284   /** compute both ratios and deriatives of ratio with respect to the optimizables*/
285   void evaluateDerivRatios(VirtualParticleSet& P,
286                            const opt_variables_type& optvars,
287                            std::vector<ValueType>& ratios,
288                            Matrix<ValueType>& dratio);
289 
290   void printGL(ParticleSet::ParticleGradient_t& G, ParticleSet::ParticleLaplacian_t& L, std::string tag = "GL");
291 
292   /** Returns the logarithmic gradient of the trial wave function
293    *  with respect to the iat^th atom of the source ParticleSet. */
294   GradType evalGradSource(ParticleSet& P, ParticleSet& source, int iat);
295   /** Returns the logarithmic gradient of the w.r.t. the iat^th atom
296    * of the source ParticleSet of the sum of laplacians w.r.t. the
297    * electrons (target ParticleSet) of the trial wave function. */
298   GradType evalGradSource(ParticleSet& P,
299                           ParticleSet& source,
300                           int iat,
301                           TinyVector<ParticleSet::ParticleGradient_t, OHMMS_DIM>& grad_grad,
302                           TinyVector<ParticleSet::ParticleLaplacian_t, OHMMS_DIM>& lapl_grad);
303 
304   /** compute psi(R_new) / psi(R_current) ratio and \nabla ln(psi(R_new)) gradients
305    * It returns a complex value if the wavefunction is complex.
306    * @param P the active ParticleSet
307    * @param iat the index of a particle moved to the new position.
308    * @param grad_iat gradients
309    * @return ratio value
310    */
311   ValueType calcRatioGrad(ParticleSet& P, int iat, GradType& grad_iat);
312 
313   /** compute psi(R_new) / psi(R_current) ratio and d/ds ln(psi(R_new)) spin gradient
314    * It returns a complex value if the wavefunction is complex.
315    * @param P the active ParticleSet
316    * @param iat the index of a particle moved to the new position.
317    * @param grad_iat real space gradient for iat
318    * @param spingrad_iat spin gradient for iat
319    * @return ratio value
320    */
321   ValueType calcRatioGradWithSpin(ParticleSet& P, int iat, GradType& grad_iat, ComplexType& spingrad_iat);
322 
323   /** batched version of ratioGrad
324    *
325    *  all vector sizes must match
326    */
327   static void mw_calcRatioGrad(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
328                                const RefVectorWithLeader<ParticleSet>& p_list,
329                                int iat,
330                                std::vector<PsiValueType>& ratios,
331                                std::vector<GradType>& grad_new);
332 
333   /** Prepare internal data for updating WFC correspond to a particle group
334    *  Particle groups usually correspond to determinants of different spins.
335    *  This call can be used to handle precomputation for PbyP moves.
336    * @param P quantum particle set
337    * @param ig particle group index
338    */
339   void prepareGroup(ParticleSet& P, int ig);
340   /** batched version of prepareGroup
341    *
342    *  all vector sizes must match
343    */
344   static void mw_prepareGroup(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
345                               const RefVectorWithLeader<ParticleSet>& p_list,
346                               int ig);
347 
348   GradType evalGrad(ParticleSet& P, int iat);
349 
350   /** compute d/ds ln(psi) spin gradient at current particle position for iat electron
351    *
352    * @param P active particle set.
353    * @param iat index of the particle moved to the new position.
354    * @param spingrad spingrad value.  Zeroed out first, then filled with d/ds ln(psi).
355    * @return \nabla ln(psi) (complex)
356    *
357    */
358   GradType evalGradWithSpin(ParticleSet& P, int iat, ComplexType& spingrad);
359 
360   /** batched version of evalGrad
361     *
362     * This is static because it should have no direct access
363     * to any TWF.
364     */
365   static void mw_evalGrad(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
366                           const RefVectorWithLeader<ParticleSet>& p_list,
367                           int iat,
368                           std::vector<GradType>& grad_now);
369 
370   void rejectMove(int iat);
371 
372   void acceptMove(ParticleSet& P, int iat, bool safe_to_delay = false);
373   /* batched version of acceptMove */
374   static void mw_accept_rejectMove(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
375                                    const RefVectorWithLeader<ParticleSet>& p_list,
376                                    int iat,
377                                    const std::vector<bool>& isAccepted,
378                                    bool safe_to_delay = false);
379   void completeUpdates();
380   /* batched version of completeUpdates.  */
381   static void mw_completeUpdates(const RefVectorWithLeader<TrialWaveFunction>& wf_list);
382 
383   /** compute gradients and laplacian of the TWF with respect to each particle.
384    *  See WaveFunctionComponent::evaluateGL for more detail */
385   LogValueType evaluateGL(ParticleSet& P, bool fromscratch);
386   /* batched version of evaluateGL.
387    */
388   static void mw_evaluateGL(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
389                             const RefVectorWithLeader<ParticleSet>& p_list,
390                             bool fromscratch);
391 
392   /** register all the wavefunction components in buffer.
393    *  See WaveFunctionComponent::registerData for more detail */
394   void registerData(ParticleSet& P, WFBufferType& buf);
395 
396   /** update all the wavefunction components in buffer.
397    *  See WaveFunctionComponent::updateBuffer for more detail */
398   RealType updateBuffer(ParticleSet& P, WFBufferType& buf, bool fromscratch = false);
399 
400   /** copy all the wavefunction components from buffer.
401    *  See WaveFunctionComponent::updateBuffer for more detail */
402   void copyFromBuffer(ParticleSet& P, WFBufferType& buf);
403 
404   /// initialize a shared resource and hand it to a collection
405   void createResource(ResourceCollection& collection) const;
406   /** acquire external resource
407    * Note: use RAII ResourceCollectionLock whenever possible
408    */
409   void acquireResource(ResourceCollection& collection);
410   /** release external resource
411    * Note: use RAII ResourceCollectionLock whenever possible
412    */
413   void releaseResource(ResourceCollection& collection);
414 
415   RealType KECorrection() const;
416 
417   void evaluateDerivatives(ParticleSet& P,
418                            const opt_variables_type& optvars,
419                            std::vector<ValueType>& dlogpsi,
420                            std::vector<ValueType>& dhpsioverpsi,
421                            bool project = false);
422 
423   static void mw_evaluateParameterDerivatives(const RefVectorWithLeader<TrialWaveFunction>& wf_list,
424                                               const RefVectorWithLeader<ParticleSet>& p_list,
425                                               const opt_variables_type& optvars,
426                                               RecordArray<ValueType>& dlogpsi,
427                                               RecordArray<ValueType>& dhpsioverpsi);
428 
429   void evaluateDerivativesWF(ParticleSet& P, const opt_variables_type& optvars, std::vector<ValueType>& dlogpsi);
430 
431   void evaluateGradDerivatives(const ParticleSet::ParticleGradient_t& G_in, std::vector<ValueType>& dgradlogpsi);
432 
433   /** evaluate the hessian w.r.t. electronic coordinates of particle iat **/
434   // void evaluateHessian(ParticleSet & P, int iat, HessType& grad_grad_psi);
435   /** evaluate the hessian hessian w.r.t. electronic coordinates of particle iat **/
436   void evaluateHessian(ParticleSet& P, HessVector_t& all_grad_grad_psi);
437 
438   TrialWaveFunction* makeClone(ParticleSet& tqp) const;
439 
getOrbitals()440   std::vector<WaveFunctionComponent*>& getOrbitals() { return Z; }
441 
442   void evaluateRatiosAlltoOne(ParticleSet& P, std::vector<ValueType>& ratios);
443 
setTwist(std::vector<RealType> t)444   void setTwist(std::vector<RealType> t) { myTwist = t; }
twist()445   const std::vector<RealType> twist() { return myTwist; }
446 
setMassTerm(ParticleSet & P)447   inline void setMassTerm(ParticleSet& P)
448   {
449     OneOverM = 1.0 / P.Mass[0];
450     //SpeciesSet tspecies(P.getSpeciesSet());
451     //int massind=tspecies.addAttribute("mass");
452     //RealType mass = tspecies(massind,0);
453     //OneOverM = 1.0/mass;
454   }
455 
getReciprocalMass()456   RealType getReciprocalMass() { return OneOverM; }
457 
getName()458   const std::string& getName() const { return myName; }
459 
use_tasking()460   bool use_tasking() const { return use_tasking_; }
461 
462 private:
463   static void debugOnlyCheckBuffer(WFBufferType& buffer);
464 
465   ///getName is in the way
466   const std::string myName;
467 
468   ///starting index of the buffer
469   size_t BufferCursor;
470 
471   ///starting index of the scalar buffer
472   size_t BufferCursor_scalar;
473 
474   ///sign of the trial wave function
475   RealType PhaseValue;
476 
477   ///diff of the phase of the trial wave function during ratio calls
478   RealType PhaseDiff;
479 
480   ///log of the trial wave function
481   RealType LogValue;
482 
483   ///One over mass of target particleset, needed for Local Energy Derivatives
484   RealType OneOverM;
485 
486   /// if true, using internal tasking implementation
487   const bool use_tasking_;
488 
489   ///a list of WaveFunctionComponents constituting many-body wave functions
490   std::vector<WaveFunctionComponent*> Z;
491 
492   /// timers at TrialWaveFunction function call level
493   TimerList_t TWF_timers_;
494   /// timers at WaveFunctionComponent function call level
495   TimerList_t WFC_timers_;
496   std::vector<RealType> myTwist;
497 
498   /** @{
499    *  @brief helper function for extracting a list of WaveFunctionComponent from a list of TrialWaveFunction
500    */
501   static std::vector<WaveFunctionComponent*> extractWFCPtrList(const UPtrVector<TrialWaveFunction>& wf_list, int id);
502 
503   static RefVectorWithLeader<WaveFunctionComponent> extractWFCRefList(
504       const RefVectorWithLeader<TrialWaveFunction>& wf_list,
505       int id);
506   /** }@ */
507 
508   // helper function for extrating a list of gradients from a list of TrialWaveFunction
509   static RefVector<ParticleSet::ParticleGradient_t> extractGRefList(
510       const RefVectorWithLeader<TrialWaveFunction>& wf_list);
511 
512   // helper function for extracting a list of laplacian from a list of TrialWaveFunction
513   static RefVector<ParticleSet::ParticleLaplacian_t> extractLRefList(
514       const RefVectorWithLeader<TrialWaveFunction>& wf_list);
515 
516   ///////////////////////////////////////////
517   // Vectorized version for GPU evaluation //
518   ///////////////////////////////////////////
519 #ifdef QMC_CUDA
520 private:
521   gpu::device_host_vector<CTS::ValueType> GPUratios;
522   gpu::device_host_vector<CTS::GradType> GPUgrads;
523   gpu::device_host_vector<CTS::ValueType> GPUlapls;
524   int ndelay; // delay rank
525 
526 public:
527   void freeGPUmem();
528 
529   void recompute(MCWalkerConfiguration& W, bool firstTime = true);
530 
531   void reserve(PointerPool<gpu::device_vector<CTS::ValueType>>& pool, bool onlyOptimizable = false, int kblocksize = 1);
532   void getGradient(MCWalkerConfiguration& W, int iat, std::vector<GradType>& grad);
533   void calcGradient(MCWalkerConfiguration& W, int iat, int k, std::vector<GradType>& grad);
calcGradient(MCWalkerConfiguration & W,int iat,std::vector<GradType> & grad)534   void calcGradient(MCWalkerConfiguration& W, int iat, std::vector<GradType>& grad) { calcGradient(W, iat, 0, grad); }
535   void addGradient(MCWalkerConfiguration& W, int iat, std::vector<GradType>& grad);
536   void evaluateLog(MCWalkerConfiguration& W, std::vector<RealType>& logPsi);
537   void ratio(MCWalkerConfiguration& W, int iat, std::vector<ValueType>& psi_ratios);
538   void ratio(MCWalkerConfiguration& W, int iat, std::vector<ValueType>& psi_ratios, std::vector<GradType>& newG);
539   void ratio(MCWalkerConfiguration& W,
540              int iat,
541              std::vector<ValueType>& psi_ratios,
542              std::vector<GradType>& newG,
543              std::vector<ValueType>& newL);
544   void calcRatio(MCWalkerConfiguration& W,
545                  int iat,
546                  std::vector<ValueType>& psi_ratios,
547                  std::vector<GradType>& newG,
548                  std::vector<ValueType>& newL);
549   void addRatio(MCWalkerConfiguration& W,
550                 int iat,
551                 int k,
552                 std::vector<ValueType>& psi_ratios,
553                 std::vector<GradType>& newG,
554                 std::vector<ValueType>& newL);
addRatio(MCWalkerConfiguration & W,int iat,std::vector<ValueType> & psi_ratios,std::vector<GradType> & newG,std::vector<ValueType> & newL)555   void addRatio(MCWalkerConfiguration& W,
556                 int iat,
557                 std::vector<ValueType>& psi_ratios,
558                 std::vector<GradType>& newG,
559                 std::vector<ValueType>& newL)
560   {
561     addRatio(W, iat, 0, psi_ratios, newG, newL);
562   }
563   void det_lookahead(MCWalkerConfiguration& W,
564                      std::vector<ValueType>& psi_ratios,
565                      std::vector<GradType>& grad,
566                      std::vector<ValueType>& lapl,
567                      int iat,
568                      int k,
569                      int kd,
570                      int nw);
571 
572 #ifdef QMC_COMPLEX
573   void convertRatiosFromComplexToReal(std::vector<ValueType>& psi_ratios, std::vector<RealType>& psi_ratios_real);
574 #endif
575   void ratio(std::vector<Walker_t*>& walkers,
576              std::vector<int>& iatList,
577              std::vector<PosType>& rNew,
578              std::vector<ValueType>& psi_ratios,
579              std::vector<GradType>& newG,
580              std::vector<ValueType>& newL);
581 
582   void NLratios(MCWalkerConfiguration& W,
583                 gpu::device_vector<CUDA_PRECISION*>& Rlist,
584                 gpu::device_vector<int*>& ElecList,
585                 gpu::device_vector<int>& NumCoreElecs,
586                 gpu::device_vector<CUDA_PRECISION*>& QuadPosList,
587                 gpu::device_vector<CUDA_PRECISION*>& RatioList,
588                 int numQuadPoints,
589                 ComputeType ct = ComputeType::ALL);
590 
591   void NLratios(MCWalkerConfiguration& W,
592                 std::vector<NLjob>& jobList,
593                 std::vector<PosType>& quadPoints,
594                 std::vector<ValueType>& psi_ratios,
595                 ComputeType ct = ComputeType::ALL);
596 
597   void update(MCWalkerConfiguration* W, std::vector<Walker_t*>& walkers, int iat, std::vector<bool>* acc, int k);
update(std::vector<Walker_t * > & walkers,int iat)598   void update(std::vector<Walker_t*>& walkers, int iat) { update(NULL, walkers, iat, NULL, 0); }
599   void update(const std::vector<Walker_t*>& walkers, const std::vector<int>& iatList);
600 
601   void gradLapl(MCWalkerConfiguration& W, GradMatrix_t& grads, ValueMatrix_t& lapl);
602 
603 
604   void evaluateDeltaLog(MCWalkerConfiguration& W, std::vector<RealType>& logpsi_opt);
605 
606   void evaluateDeltaLog(MCWalkerConfiguration& W,
607                         std::vector<RealType>& logpsi_fixed,
608                         std::vector<RealType>& logpsi_opt,
609                         GradMatrix_t& fixedG,
610                         ValueMatrix_t& fixedL);
611 
612   void evaluateOptimizableLog(MCWalkerConfiguration& W,
613                               std::vector<RealType>& logpsi_opt,
614                               GradMatrix_t& optG,
615                               ValueMatrix_t& optL);
616 
617   void evaluateDerivatives(MCWalkerConfiguration& W,
618                            const opt_variables_type& optvars,
619                            RealMatrix_t& dlogpsi,
620                            RealMatrix_t& dhpsioverpsi);
621 
622 
setndelay(int delay)623   void setndelay(int delay) { ndelay = delay; }
624 
getndelay()625   int getndelay() { return ndelay; }
626 #endif
627 };
628 /**@}*/
629 } // namespace qmcplusplus
630 #endif
631