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 //                    Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
12 //                    Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
13 //
14 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
15 //////////////////////////////////////////////////////////////////////////////////////
16 
17 
18 #ifndef QMCPLUSPLUS_WAVEFUNCTIONCOMPONENT_H
19 #define QMCPLUSPLUS_WAVEFUNCTIONCOMPONENT_H
20 #include "Message/Communicate.h"
21 #include "Configuration.h"
22 #include "Particle/ParticleSet.h"
23 #include "Particle/VirtualParticleSet.h"
24 #include "Particle/DistanceTableData.h"
25 #include "OhmmsData/RecordProperty.h"
26 #include "QMCWaveFunctions/OrbitalSetTraits.h"
27 #include "Particle/MCWalkerConfiguration.h"
28 #include "type_traits/template_types.hpp"
29 #ifdef QMC_CUDA
30 #include "type_traits/CUDATypes.h"
31 #endif
32 
33 /**@file WaveFunctionComponent.h
34  *@brief Declaration of WaveFunctionComponent
35  */
36 namespace qmcplusplus
37 {
38 #ifdef QMC_CUDA
39 struct NLjob
40 {
41   int walker;
42   int elec;
43   int numQuadPoints;
NLjobNLjob44   NLjob(int w, int e, int n) : walker(w), elec(e), numQuadPoints(n) {}
45 };
46 #endif
47 
48 ///forward declaration
49 struct WaveFunctionComponent;
50 struct DiffWaveFunctionComponent;
51 class ResourceCollection;
52 
53 typedef WaveFunctionComponent* WaveFunctionComponentPtr;
54 typedef DiffWaveFunctionComponent* DiffWaveFunctionComponentPtr;
55 
56 /**@defgroup WaveFunctionComponent group
57  * @brief Classes which constitute a many-body trial wave function
58  *
59  * A many-body trial wave function is
60  * \f[
61  \Psi(\{ {\bf R}\}) = \prod_i \psi_{i}(\{ {\bf R}\}),
62  * \f]
63  * where \f$\Psi\f$s are represented by
64  * the derived classes from WaveFunctionComponent.
65  */
66 /** @ingroup WaveFunctionComponent
67  * @brief An abstract class for a component of a many-body trial wave function
68  *
69  * mw_ prefix is a function name signature indicating it is for handling a batch of WaveFunctionComponent objects
70  * which are required to be base class pointers of the same derived class type.
71  * all the mw_ routines must be implemented in a way either stateless or maintains states of every walker.
72  */
73 struct WaveFunctionComponent : public QMCTraits
74 {
75   /** enum for a update mode */
76   enum
77   {
78     ORB_PBYP_RATIO,   /*!< particle-by-particle ratio only */
79     ORB_PBYP_ALL,     /*!< particle-by-particle, update Value-Gradient-Laplacian */
80     ORB_PBYP_PARTIAL, /*!< particle-by-particle, update Value and Grdient */
81     ORB_WALKER,       /*!< walker update */
82     ORB_ALLWALKER     /*!< all walkers update */
83   };
84 
85   typedef ParticleAttrib<ValueType> ValueVectorType;
86   typedef ParticleAttrib<GradType> GradVectorType;
87   typedef ParticleSet::Walker_t Walker_t;
88   typedef Walker_t::WFBuffer_t WFBufferType;
89   typedef Walker_t::Buffer_t BufferType;
90   typedef OrbitalSetTraits<RealType>::ValueMatrix_t RealMatrix_t;
91   typedef OrbitalSetTraits<ValueType>::ValueMatrix_t ValueMatrix_t;
92   typedef OrbitalSetTraits<ValueType>::GradMatrix_t GradMatrix_t;
93   typedef OrbitalSetTraits<ValueType>::HessType HessType;
94   typedef OrbitalSetTraits<ValueType>::HessVector_t HessVector_t;
95 
96   // the value type for log(psi)
97   using LogValueType = std::complex<QTFull::RealType>;
98   // the value type for psi(r')/psi(r)
99   using PsiValueType = QTFull::ValueType;
100 
101   /** flag to set the optimization mode */
102   bool IsOptimizing;
103   /** boolean to set optimization
104    *
105    * If true, this object is actively modified during optimization
106    */
107   bool Optimizable;
108   /** true, if this component is fermionic */
109   bool is_fermionic;
110 
111   /** current update mode */
112   int UpdateMode;
113   /** current \f$\log\phi \f$
114    */
115   LogValueType LogValue;
116   /** Pointer to the differential WaveFunctionComponent of this object
117    *
118    * If dPsi=0, this WaveFunctionComponent is constant with respect to the optimizable variables
119    */
120   DiffWaveFunctionComponentPtr dPsi;
121   /** A vector for \f$ \frac{\partial \nabla \log\phi}{\partial \alpha} \f$
122    */
123   GradVectorType dLogPsi;
124   /** A vector for \f$ \frac{\partial \nabla^2 \log\phi}{\partial \alpha} \f$
125    */
126   ValueVectorType d2LogPsi;
127   /** Name of the class derived from WaveFunctionComponent
128    */
129   const std::string ClassName;
130   /** Name of the object
131    * It is required to be different for objects of the same derived type like multiple J1.
132    * It can be left empty for object which is unique per many-body WF.
133    */
134   const std::string myName;
135   ///list of variables this WaveFunctionComponent handles
136   opt_variables_type myVars;
137   ///Bytes in WFBuffer
138   size_t Bytes_in_WFBuffer;
139 
140   /// default constructor
141   WaveFunctionComponent(const std::string& class_name, const std::string& obj_name = "");
142 
143   ///default destructor
~WaveFunctionComponentWaveFunctionComponent144   virtual ~WaveFunctionComponent() {}
145 
setOptimizableWaveFunctionComponent146   inline void setOptimizable(bool optimizeit) { Optimizable = optimizeit; }
147 
148   ///assign a differential WaveFunctionComponent
149   virtual void setDiffOrbital(DiffWaveFunctionComponentPtr d);
150 
151   ///assembles the full value
getValueWaveFunctionComponent152   PsiValueType getValue() const { return LogToValue<PsiValueType>::convert(LogValue); }
153 
154   /** check in optimizable parameters
155    * @param active a super set of optimizable variables
156    *
157    * Add the paramemters this WaveFunctionComponent manage to active.
158    */
159   virtual void checkInVariables(opt_variables_type& active) = 0;
160 
161   /** check out optimizable variables
162    *
163    * Update myVars index map
164    */
165   virtual void checkOutVariables(const opt_variables_type& active) = 0;
166 
167   /** reset the parameters during optimizations
168    */
169   virtual void resetParameters(const opt_variables_type& active) = 0;
170 
171   /** print the state, e.g., optimizables */
172   virtual void reportStatus(std::ostream& os) = 0;
173 
174   /** evaluate the value of the WaveFunctionComponent from scratch
175    * @param P  active ParticleSet
176    * @param G Gradients, \f$\nabla\ln\Psi\f$
177    * @param L Laplacians, \f$\nabla^2\ln\Psi\f$
178    * @return the log value
179    *
180    * Mainly for walker-by-walker move. The initial stage of particle-by-particle
181    * move also uses this.
182    */
183   virtual LogValueType evaluateLog(const ParticleSet& P,
184                                    ParticleSet::ParticleGradient_t& G,
185                                    ParticleSet::ParticleLaplacian_t& L) = 0;
186 
187   /** evaluate from scratch the same type WaveFunctionComponent of multiple walkers
188    * @param wfc_list the list of WaveFunctionComponent pointers of the same component in a walker batch
189    * @param p_list the list of ParticleSet pointers in a walker batch
190    * @param G_list the list of Gradients pointers in a walker batch, \f$\nabla\ln\Psi\f$
191    * @param L_list the list of Laplacians pointers in a walker batch, \f$\nabla^2\ln\Psi\f$
192    * @param values the log WF values of walkers in a batch
193    */
194   virtual void mw_evaluateLog(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
195                               const RefVectorWithLeader<ParticleSet>& p_list,
196                               const RefVector<ParticleSet::ParticleGradient_t>& G_list,
197                               const RefVector<ParticleSet::ParticleLaplacian_t>& L_list) const;
198 
199   /** recompute the value of the WaveFunctionComponents which require critical accuracy.
200    * needed for Slater Determinants but not needed for most types of WaveFunctionComponents
201    */
202   virtual void recompute(const ParticleSet& P);
203 
204   virtual void mw_recompute(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
205                             const RefVectorWithLeader<ParticleSet>& p_list,
206                             const std::vector<bool>& recompute) const;
207 
208   // virtual void evaluateHessian(ParticleSet& P, IndexType iat, HessType& grad_grad_psi)
209   // {
210   //   APP_ABORT("WaveFunctionComponent::evaluateHessian is not implemented");
211   // }
212 
evaluateHessianWaveFunctionComponent213   virtual void evaluateHessian(ParticleSet& P, HessVector_t& grad_grad_psi_all)
214   {
215     APP_ABORT("WaveFunctionComponent::evaluateHessian is not implemented in " + ClassName + " class.");
216   }
217 
218   /** Prepare internal data for updating WFC correspond to a particle group
219    * It should be called before moving particles of a given group.
220    * This call can be used to handle the precomputation of data used for moving this group of particle.
221    * Such data should be static with respect to the moves of particles within this group.
222    * Particle groups usually correspond to determinants of different spins.
223    * @param P quantum particle set
224    * @param ig particle group index
225    */
prepareGroupWaveFunctionComponent226   virtual void prepareGroup(ParticleSet& P, int ig) {}
227 
228   virtual void mw_prepareGroup(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
229                                const RefVectorWithLeader<ParticleSet>& p_list,
230                                int ig) const;
231 
232   /** return the current gradient for the iat-th particle
233    * @param P quantum particle set
234    * @param iat particle index
235    * @return the gradient of the iat-th particle
236    */
evalGradWaveFunctionComponent237   virtual GradType evalGrad(ParticleSet& P, int iat)
238   {
239     APP_ABORT("WaveFunctionComponent::evalGradient is not implemented in " + ClassName + " class.");
240     return GradType();
241   }
242 
243   /** return the current spin gradient for the iat-th particle
244    * Default implementation assumes that WaveFunctionComponent does not explicitly depend on Spin.
245    * @param P quantum particle set
246    * @param iat particle index
247    * @return the spin gradient of the iat-th particle
248    */
evalGradWithSpinWaveFunctionComponent249   virtual GradType evalGradWithSpin(ParticleSet& P, int iat, ComplexType& spingrad) { return evalGrad(P, iat); }
250 
251   /** compute the current gradients for the iat-th particle of multiple walkers
252    * @param wfc_list the list of WaveFunctionComponent pointers of the same component in a walker batch
253    * @param p_list the list of ParticleSet pointers in a walker batch
254    * @param iat particle index
255    * @param grad_now the list of gradients in a walker batch, \f$\nabla\ln\Psi\f$
256    */
257   virtual void mw_evalGrad(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
258                            const RefVectorWithLeader<ParticleSet>& p_list,
259                            int iat,
260                            std::vector<GradType>& grad_now) const;
261 
262   /** return the logarithmic gradient for the iat-th particle
263    * of the source particleset
264    * @param Pquantum particle set
265    * @param iat particle index
266    * @return the gradient of the iat-th particle
267    */
evalGradSourceWaveFunctionComponent268   virtual GradType evalGradSource(ParticleSet& P, ParticleSet& source, int iat)
269   {
270     // unit_test_hamiltonian calls this function incorrectly; do not abort for now
271     //    APP_ABORT("WaveFunctionComponent::evalGradSource is not implemented");
272     return GradType();
273   }
274 
275   /** Adds the gradient w.r.t. the iat-th particle of the
276    *  source particleset (ions) of the logarithmic gradient
277    *  and laplacian w.r.t. the target paritlceset (electrons).
278    * @param P quantum particle set (electrons)
279    * @param source classical particle set (ions)
280    * @param iat particle index of source (ion)
281    * @param the ion gradient of the elctron gradient
282    * @param the ion gradient of the elctron laplacian.
283    * @return the log gradient of psi w.r.t. the source particle iat
284    */
evalGradSourceWaveFunctionComponent285   virtual GradType evalGradSource(ParticleSet& P,
286                                   ParticleSet& source,
287                                   int iat,
288                                   TinyVector<ParticleSet::ParticleGradient_t, OHMMS_DIM>& grad_grad,
289                                   TinyVector<ParticleSet::ParticleLaplacian_t, OHMMS_DIM>& lapl_grad)
290   {
291     return GradType();
292   }
293 
294 
295   /** evaluate the ratio of the new to old WaveFunctionComponent value and the new gradient
296    * @param P the active ParticleSet
297    * @param iat the index of a particle
298    * @param grad_iat Gradient for the active particle
299    */
300   virtual PsiValueType ratioGrad(ParticleSet& P, int iat, GradType& grad_iat);
301 
302   /** evaluate the ratio of the new to old WaveFunctionComponent value and the new spin gradient
303    * Default implementation assumes that WaveFunctionComponent does not explicitly depend on Spin.
304    * @param P the active ParticleSet
305    * @param iat the index of a particle
306    * @param grad_iat realspace gradient for the active particle
307    * @param spingrad_iat spin gradient for the active particle
308    */
ratioGradWithSpinWaveFunctionComponent309   virtual PsiValueType ratioGradWithSpin(ParticleSet& P, int iat, GradType& grad_iat, ComplexType& spingrad_iat)
310   {
311     return ratioGrad(P, iat, grad_iat);
312   }
313 
314   /** compute the ratio of the new to old WaveFunctionComponent value and the new gradient of multiple walkers
315    * @param wfc_list the list of WaveFunctionComponent pointers of the same component in a walker batch
316    * @param p_list the list of ParticleSet pointers in a walker batch
317    * @param iat particle index
318    * @param ratios the list of WF ratios of a walker batch, \f$ \Psi( \{ {\bf R}^{'} \} )/ \Psi( \{ {\bf R}\})\f$
319    * @param grad_now the list of new gradients in a walker batch, \f$\nabla\ln\Psi\f$
320    */
321   virtual void mw_ratioGrad(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
322                             const RefVectorWithLeader<ParticleSet>& p_list,
323                             int iat,
324                             std::vector<PsiValueType>& ratios,
325                             std::vector<GradType>& grad_new) const;
326 
327   /** a move for iat-th particle is accepted. Update the current content.
328    * @param P target ParticleSet
329    * @param iat index of the particle whose new position was proposed
330    * @param safe_to_delay if true, delayed accept is safe.
331    */
332   virtual void acceptMove(ParticleSet& P, int iat, bool safe_to_delay = false) = 0;
333 
334   /** moves of the iat-th particle on some walkers in a batch is accepted. Update the current content.
335    *  Note that all the lists only include accepted walkers.
336    * @param wfc_list the list of WaveFunctionComponent pointers of the same component in a walker batch
337    * @param p_list the list of ParticleSet pointers in a walker batch
338    * @param iat particle index
339    * @param safe_to_delay if true, delayed accept is safe.
340    */
341   virtual void mw_accept_rejectMove(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
342                                     const RefVectorWithLeader<ParticleSet>& p_list,
343                                     int iat,
344                                     const std::vector<bool>& isAccepted,
345                                     bool safe_to_delay = false) const;
346 
347   /** complete all the delayed updates, must be called after each substep or step during pbyp move
348    */
completeUpdatesWaveFunctionComponent349   virtual void completeUpdates() {}
350 
351   /** complete all the delayed updates for all the walkers in a batch
352    * must be called after each substep or step during pbyp move
353    */
354   virtual void mw_completeUpdates(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list) const;
355 
356   /** If a move for iat-th particle is rejected, restore to the content.
357    * @param iat index of the particle whose new position was proposed
358    *
359    * Ye: hopefully we can gradually move away from restore
360    */
361   virtual void restore(int iat) = 0;
362 
363   /** evaluate the ratio of the new to old WaveFunctionComponent value
364    * @param P the active ParticleSet
365    * @param iat the index of a particle
366    * @return \f$ \psi( \{ {\bf R}^{'} \} )/ \psi( \{ {\bf R}\})\f$
367    *
368    * Specialized for particle-by-particle move
369    */
370   virtual PsiValueType ratio(ParticleSet& P, int iat) = 0;
371 
372   /** compute the ratio of the new to old WaveFunctionComponent value of multiple walkers
373    * @param wfc_list the list of WaveFunctionComponent pointers of the same component in a walker batch
374    * @param p_list the list of ParticleSet pointers in a walker batch
375    * @param iat particle index
376    * @param ratios the list of WF ratios of a walker batch, \f$ \Psi( \{ {\bf R}^{'} \} )/ \Psi( \{ {\bf R}\})\f$
377    */
378   virtual void mw_calcRatio(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
379                             const RefVectorWithLeader<ParticleSet>& p_list,
380                             int iat,
381                             std::vector<PsiValueType>& ratios) const;
382 
383   /** compute gradients and laplacian of the TWF with respect to each particle.
384    * @param P particle set
385    * @param G Gradients, \f$\nabla\ln\Psi\f$
386    * @param L Laplacians, \f$\nabla^2\ln\Psi\f$
387    * @param fromscratch if true, all the internal data are recomputed from scratch
388    * @return log(psi)
389    */
390   virtual LogValueType evaluateGL(const ParticleSet& P,
391                                   ParticleSet::ParticleGradient_t& G,
392                                   ParticleSet::ParticleLaplacian_t& L,
393                                   bool fromscratch);
394 
395   /** evaluate gradients and laplacian of the same type WaveFunctionComponent of multiple walkers
396    * @param wfc_list the list of WaveFunctionComponent pointers of the same component in a walker batch
397    * @param p_list the list of ParticleSet pointers in a walker batch
398    * @param G_list the list of Gradients pointers in a walker batch, \f$\nabla\ln\Psi\f$
399    * @param L_list the list of Laplacians pointers in a walker batch, \f$\nabla^2\ln\Psi\f$
400    * @param fromscratch if true, all the internal data are recomputed from scratch
401    */
402   virtual void mw_evaluateGL(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
403                              const RefVectorWithLeader<ParticleSet>& p_list,
404                              const RefVector<ParticleSet::ParticleGradient_t>& G_list,
405                              const RefVector<ParticleSet::ParticleLaplacian_t>& L_list,
406                              bool fromscratch) const;
407 
408   /** For particle-by-particle move. Requests space in the buffer
409    *  based on the data type sizes of the objects in this class.
410    * @param P particle set
411    * @param buf Anonymous storage
412    */
413   virtual void registerData(ParticleSet& P, WFBufferType& buf) = 0;
414 
415   /** For particle-by-particle move. Put the objects of this class
416    *  in the walker buffer or forward the memory cursor.
417    * @param P particle set
418    * @param buf Anonymous storage
419    * @param fromscratch request recomputing the precision critical
420    *        pieces of wavefunction from scratch
421    * @return log value of the wavefunction.
422    */
423   virtual LogValueType updateBuffer(ParticleSet& P, WFBufferType& buf, bool fromscratch = false) = 0;
424 
425   /** For particle-by-particle move. Copy data or attach memory
426    *  from a walker buffer to the objects of this class.
427    *  The log value, P.G and P.L contribution from the objects
428    *  of this class are also added.
429    * @param P particle set
430    * @param buf Anonymous storage
431    */
432   virtual void copyFromBuffer(ParticleSet& P, WFBufferType& buf) = 0;
433 
434   /** initialize a shared resource and hand it to a collection
435    */
createResourceWaveFunctionComponent436   virtual void createResource(ResourceCollection& collection) const {}
437 
438   /** acquire a shared resource from a collection
439    */
acquireResourceWaveFunctionComponent440   virtual void acquireResource(ResourceCollection& collection) {}
441 
442   /** return a shared resource to a collection
443    */
releaseResourceWaveFunctionComponent444   virtual void releaseResource(ResourceCollection& collection) {}
445 
446   /** make clone
447    * @param tqp target Quantum ParticleSet
448    * @param deepcopy if true, make a decopy
449    *
450    * If not true, return a proxy class
451    */
452   virtual WaveFunctionComponentPtr makeClone(ParticleSet& tqp) const;
453 
454   /** Return the Chiesa kinetic energy correction
455    */
456   virtual RealType KECorrection();
457 
458   /** Compute derivatives of the wavefunction with respect to the optimizable
459    *  parameters.
460    *  @param P particle set
461    *  @param optvars optimizable parameters
462    *  @param dlogpsi array of derivatives of the log of the wavefunction
463    *  @param dhpsioverpsi array of derivatives of the Laplacian of the wavefunction divided by the wavefunction.
464    *          Note that this does not use the Laplacian of the log of the wavefunction, as in evaluateLog.
465    *          Also the factor of -1/2 from the kinetic energy must be included here.  The 1/m
466    *          factor is applied in TrialWaveFunction.
467    */
468   virtual void evaluateDerivatives(ParticleSet& P,
469                                    const opt_variables_type& optvars,
470                                    std::vector<ValueType>& dlogpsi,
471                                    std::vector<ValueType>& dhpsioverpsi);
472 
473   /** Compute derivatives of rhe wavefunction with respect to the optimizable
474    *  parameters
475    *  @param P particle set
476    *  @param optvars optimizable parameters
477    *  @param dlogpsi array of derivatives of the log of the wavefunction
478    *  Note: this function differs from the evaluateDerivatives function in the way that it only computes
479    *        the derivative of the log of the wavefunction.
480   */
481   virtual void evaluateDerivativesWF(ParticleSet& P,
482                                      const opt_variables_type& optvars,
483                                      std::vector<ValueType>& dlogpsi);
484 
multiplyDerivsByOrbRWaveFunctionComponent485   virtual void multiplyDerivsByOrbR(std::vector<ValueType>& dlogpsi)
486   {
487     RealType myrat = std::real(LogToValue<PsiValueType>::convert(LogValue));
488     for (int j = 0; j < myVars.size(); j++)
489     {
490       int loc = myVars.where(j);
491       dlogpsi[loc] *= myrat;
492     }
493   }
494 
495   /** Calculates the derivatives of \f$ \grad(\textrm{log}(\psif)) \f$ with respect to
496       the optimizable parameters, and the dot product of this is then
497       performed with the passed-in G_in gradient vector. This object is then
498       returned as dgradlogpsi.
499    */
500 
evaluateGradDerivativesWaveFunctionComponent501   virtual void evaluateGradDerivatives(const ParticleSet::ParticleGradient_t& G_in, std::vector<ValueType>& dgradlogpsi)
502   {
503     APP_ABORT("Need specialization of WaveFunctionComponent::evaluateGradDerivatives in " + ClassName + " class.\n");
504   }
505 
finalizeOptimizationWaveFunctionComponent506   virtual void finalizeOptimization() {}
507 
508   /** evaluate the ratios of one virtual move with respect to all the particles
509    * @param P reference particleset
510    * @param ratios \f$ ratios[i]=\{{\bf R}\}\rightarrow {r_0,\cdots,r_i^p=pos,\cdots,r_{N-1}}\f$
511    */
512   virtual void evaluateRatiosAlltoOne(ParticleSet& P, std::vector<ValueType>& ratios);
513 
514   /** evaluate ratios to evaluate the non-local PP
515    * @param VP VirtualParticleSet
516    * @param ratios ratios with new positions VP.R[k] the VP.refPtcl
517    */
518   virtual void evaluateRatios(const VirtualParticleSet& VP, std::vector<ValueType>& ratios);
519 
520   /** evaluate ratios to evaluate the non-local PP multiple walkers
521    * @param wfc_list the list of WaveFunctionComponent references of the same component in a walker batch
522    * @param vp_list the list of VirtualParticleSet references in a walker batch
523    * @param ratios of all the virtual moves of all the walkers
524    */
525   virtual void mw_evaluateRatios(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list,
526                                  const RefVector<const VirtualParticleSet>& vp_list,
527                                  std::vector<std::vector<ValueType>>& ratios) const;
528 
529   /** evaluate ratios to evaluate the non-local PP
530    * @param VP VirtualParticleSet
531    * @param ratios ratios with new positions VP.R[k] the VP.refPtcl
532    * @param dratios \f$\partial_{\alpha}(\ln \Psi ({\bf R}^{\prime}) - \ln \Psi ({\bf R})) \f$
533    */
534   virtual void evaluateDerivRatios(VirtualParticleSet& VP,
535                                    const opt_variables_type& optvars,
536                                    std::vector<ValueType>& ratios,
537                                    Matrix<ValueType>& dratios);
538 
539   /////////////////////////////////////////////////////
540   // Functions for vectorized evaluation and updates //
541   /////////////////////////////////////////////////////
542 #ifdef QMC_CUDA
543   using CTS = CUDAGlobalTypes;
544 
freeGPUmemWaveFunctionComponent545   virtual void freeGPUmem() {}
546 
recomputeWaveFunctionComponent547   virtual void recompute(MCWalkerConfiguration& W, bool firstTime) {}
548 
reserveWaveFunctionComponent549   virtual void reserve(PointerPool<gpu::device_vector<CTS::ValueType>>& pool, int kblocksize) {}
550 
551   /** Evaluate the log of the WF for all walkers
552    *  @param walkers   vector of all walkers
553    *  @param logPsi    output vector of log(psi)
554    */
addLogWaveFunctionComponent555   virtual void addLog(MCWalkerConfiguration& W, std::vector<RealType>& logPsi)
556   {
557     APP_ABORT("Need specialization of WaveFunctionComponent::addLog for " + ClassName +
558               ".\n Required CUDA functionality not implemented. Contact developers.\n");
559   }
560 
561   /** Evaluate the wave-function ratio w.r.t. moving particle iat
562    *  for all walkers
563    *  @param walkers     vector of all walkers
564    *  @param iat         particle which is moving
565    *  @param psi_ratios  output vector with psi_new/psi_old
566    */
ratioWaveFunctionComponent567   virtual void ratio(MCWalkerConfiguration& W, int iat, std::vector<ValueType>& psi_ratios)
568   {
569     APP_ABORT("Need specialization of WaveFunctionComponent::ratio for " + ClassName +
570               ".\n Required CUDA functionality not implemented. Contact developers.\n");
571   }
572 
573   // Returns the WF ratio and gradient w.r.t. iat for each walker
574   // in the respective vectors
ratioWaveFunctionComponent575   virtual void ratio(MCWalkerConfiguration& W, int iat, std::vector<ValueType>& psi_ratios, std::vector<GradType>& grad)
576   {
577     APP_ABORT("Need specialization of WaveFunctionComponent::ratio for " + ClassName +
578               ".\n Required CUDA functionality not implemented. Contact developers.\n");
579   }
580 
ratioWaveFunctionComponent581   virtual void ratio(MCWalkerConfiguration& W,
582                      int iat,
583                      std::vector<ValueType>& psi_ratios,
584                      std::vector<GradType>& grad,
585                      std::vector<ValueType>& lapl)
586   {
587     APP_ABORT("Need specialization of WaveFunctionComponent::ratio for " + ClassName +
588               ".\n Required CUDA functionality not implemented. Contact developers.\n");
589   }
590 
calcRatioWaveFunctionComponent591   virtual void calcRatio(MCWalkerConfiguration& W,
592                          int iat,
593                          std::vector<ValueType>& psi_ratios,
594                          std::vector<GradType>& grad,
595                          std::vector<ValueType>& lapl)
596   {
597     APP_ABORT("Need specialization of WaveFunctionComponent::calcRatio for " + ClassName +
598               ".\n Required CUDA functionality not implemented. Contact developers.\n");
599   }
600 
addRatioWaveFunctionComponent601   virtual void addRatio(MCWalkerConfiguration& W,
602                         int iat,
603                         int k,
604                         std::vector<ValueType>& psi_ratios,
605                         std::vector<GradType>& grad,
606                         std::vector<ValueType>& lapl)
607   {
608     APP_ABORT("Need specialization of WaveFunctionComponent::addRatio for " + ClassName +
609               ".\n Required CUDA functionality not implemented. Contact developers.\n");
610   }
611 
ratioWaveFunctionComponent612   virtual void ratio(std::vector<Walker_t*>& walkers,
613                      std::vector<int>& iatList,
614                      std::vector<PosType>& rNew,
615                      std::vector<ValueType>& psi_ratios,
616                      std::vector<GradType>& grad,
617                      std::vector<ValueType>& lapl)
618   {
619     APP_ABORT("Need specialization of WaveFunctionComponent::ratio for " + ClassName +
620               ".\n Required CUDA functionality not implemented. Contact developers.\n");
621   }
622 
623 
addGradientWaveFunctionComponent624   virtual void addGradient(MCWalkerConfiguration& W, int iat, std::vector<GradType>& grad)
625   {
626     APP_ABORT("Need specialization of WaveFunctionComponent::addGradient for " + ClassName +
627               ".\n Required CUDA functionality not implemented. Contact developers.\n");
628   }
629 
calcGradientWaveFunctionComponent630   virtual void calcGradient(MCWalkerConfiguration& W, int iat, int k, std::vector<GradType>& grad)
631   {
632     APP_ABORT("Need specialization of WaveFunctionComponent::calcGradient for " + ClassName +
633               ".\n Required CUDA functionality not implemented. Contact developers.\n");
634   }
635 
gradLaplWaveFunctionComponent636   virtual void gradLapl(MCWalkerConfiguration& W, GradMatrix_t& grads, ValueMatrix_t& lapl)
637   {
638     APP_ABORT("Need specialization of WaveFunctionComponent::gradLapl for " + ClassName +
639               ".\n Required CUDA functionality not implemented. Contact developers.\n");
640   }
641 
det_lookaheadWaveFunctionComponent642   virtual void det_lookahead(MCWalkerConfiguration& W,
643                              std::vector<ValueType>& psi_ratios,
644                              std::vector<GradType>& grad,
645                              std::vector<ValueType>& lapl,
646                              int iat,
647                              int k,
648                              int kd,
649                              int nw)
650   {
651     APP_ABORT("Need specialization of WaveFunctionComponent::det_lookahead for " + ClassName +
652               ".\n Required CUDA functionality not implemented. Contact developers.\n");
653   }
654 
updateWaveFunctionComponent655   virtual void update(MCWalkerConfiguration* W, std::vector<Walker_t*>& walkers, int iat, std::vector<bool>* acc, int k)
656   {
657     APP_ABORT("Need specialization of WaveFunctionComponent::update for " + ClassName +
658               ".\n Required CUDA functionality not implemented. Contact developers.\n");
659   }
660 
updateWaveFunctionComponent661   virtual void update(const std::vector<Walker_t*>& walkers, const std::vector<int>& iatList)
662   {
663     APP_ABORT("Need specialization of WaveFunctionComponent::update for " + ClassName +
664               ".\n Required CUDA functionality not implemented. Contact developers.\n");
665   }
666 
667 
NLratiosWaveFunctionComponent668   virtual void NLratios(MCWalkerConfiguration& W,
669                         std::vector<NLjob>& jobList,
670                         std::vector<PosType>& quadPoints,
671                         std::vector<ValueType>& psi_ratios)
672   {
673     APP_ABORT("Need specialization of WaveFunctionComponent::NLRatios for " + ClassName +
674               ".\n Required CUDA functionality not implemented. Contact developers.\n");
675   }
676 
NLratiosWaveFunctionComponent677   virtual void NLratios(MCWalkerConfiguration& W,
678                         gpu::device_vector<CUDA_PRECISION*>& Rlist,
679                         gpu::device_vector<int*>& ElecList,
680                         gpu::device_vector<int>& NumCoreElecs,
681                         gpu::device_vector<CUDA_PRECISION*>& QuadPosList,
682                         gpu::device_vector<CUDA_PRECISION*>& RatioList,
683                         int numQuadPoints)
684   {
685     APP_ABORT("Need specialization of WaveFunctionComponent::NLRatios for " + ClassName +
686               ".\n Required CUDA functionality not implemented. Contact developers.\n");
687   }
688 
evaluateDerivativesWaveFunctionComponent689   virtual void evaluateDerivatives(MCWalkerConfiguration& W,
690                                    const opt_variables_type& optvars,
691                                    RealMatrix_t& dgrad_logpsi,
692                                    RealMatrix_t& dhpsi_over_psi)
693   {
694     APP_ABORT("Need specialization of WaveFunctionComponent::evaluateDerivatives for " + ClassName +
695               ".\n Required CUDA functionality not implemented. Contact developers.\n");
696   }
697 #endif
698 };
699 } // namespace qmcplusplus
700 #endif
701