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: Bryan Clark, bclark@Princeton.edu, Princeton University 8 // Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign 9 // Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory 10 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign 11 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign 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 DiracDeterminant.h 20 * @brief Declaration of DiracDeterminant with a S(ingle)P(article)O(rbital)Set 21 */ 22 #ifndef QMCPLUSPLUS_DIRACDETERMINANT_H 23 #define QMCPLUSPLUS_DIRACDETERMINANT_H 24 25 #include "QMCWaveFunctions/Fermion/DiracDeterminantBase.h" 26 #include "QMCWaveFunctions/Fermion/DelayedUpdate.h" 27 #if defined(ENABLE_CUDA) 28 #include "QMCWaveFunctions/Fermion/DelayedUpdateCUDA.h" 29 #endif 30 31 namespace qmcplusplus 32 { 33 template<typename DU_TYPE = DelayedUpdate<QMCTraits::ValueType, QMCTraits::QTFull::ValueType>> 34 class DiracDeterminant : public DiracDeterminantBase 35 { 36 protected: 37 int ndelay; 38 39 public: 40 using ValueVector_t = SPOSet::ValueVector_t; 41 using ValueMatrix_t = SPOSet::ValueMatrix_t; 42 using GradVector_t = SPOSet::GradVector_t; 43 using GradMatrix_t = SPOSet::GradMatrix_t; 44 using HessMatrix_t = SPOSet::HessMatrix_t; 45 using HessVector_t = SPOSet::HessVector_t; 46 using HessType = SPOSet::HessType; 47 48 using mValueType = QMCTraits::QTFull::ValueType; 49 using mGradType = TinyVector<mValueType, DIM>; 50 51 /** constructor 52 *@param spos the single-particle orbital set 53 *@param first index of the first particle 54 */ 55 DiracDeterminant(std::shared_ptr<SPOSet>&& spos, int first = 0); 56 57 // copy constructor and assign operator disabled 58 DiracDeterminant(const DiracDeterminant& s) = delete; 59 DiracDeterminant& operator=(const DiracDeterminant& s) = delete; 60 61 /** set the index of the first particle in the determinant and reset the size of the determinant 62 *@param first index of first particle 63 *@param nel number of particles in the determinant 64 */ 65 void set(int first, int nel, int delay = 1) override final; 66 67 void evaluateDerivatives(ParticleSet& P, 68 const opt_variables_type& active, 69 std::vector<ValueType>& dlogpsi, 70 std::vector<ValueType>& dhpsioverpsi) override; 71 72 ///reset the size: with the number of particles and number of orbtials 73 void resize(int nel, int morb); 74 75 void registerData(ParticleSet& P, WFBufferType& buf) override; 76 77 void updateAfterSweep(const ParticleSet& P, ParticleSet::ParticleGradient_t& G, ParticleSet::ParticleLaplacian_t& L); 78 79 LogValueType updateBuffer(ParticleSet& P, WFBufferType& buf, bool fromscratch = false) override; 80 81 void copyFromBuffer(ParticleSet& P, WFBufferType& buf) override; 82 83 /** return the ratio only for the iat-th partcle move 84 * @param P current configuration 85 * @param iat the particle thas is being moved 86 */ 87 PsiValueType ratio(ParticleSet& P, int iat) override; 88 89 //Ye: TODO, good performance needs batched SPO evaluation. 90 //void mw_calcRatio(const std::vector<WaveFunctionComponent*>& wfc_list, 91 // const std::vector<ParticleSet*>& p_list, 92 // int iat, 93 // std::vector<PsiValueType>& ratios) override; 94 95 /** compute multiple ratios for a particle move 96 */ 97 void evaluateRatios(const VirtualParticleSet& VP, std::vector<ValueType>& ratios) override; 98 99 void mw_evaluateRatios(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list, 100 const RefVector<const VirtualParticleSet>& vp_list, 101 std::vector<std::vector<ValueType>>& ratios) const override; 102 103 PsiValueType ratioGrad(ParticleSet& P, int iat, GradType& grad_iat) override; 104 105 PsiValueType ratioGradWithSpin(ParticleSet& P, int iat, GradType& grad_iat, ComplexType& spingrad) override final; 106 107 void mw_ratioGrad(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list, 108 const RefVectorWithLeader<ParticleSet>& p_list, 109 int iat, 110 std::vector<PsiValueType>& ratios, 111 std::vector<GradType>& grad_new) const override; 112 113 GradType evalGrad(ParticleSet& P, int iat) override; 114 115 GradType evalGradWithSpin(ParticleSet& P, int iat, ComplexType& spingrad) override final; 116 117 GradType evalGradSource(ParticleSet& P, ParticleSet& source, int iat) override; 118 119 GradType evalGradSource(ParticleSet& P, 120 ParticleSet& source, 121 int iat, 122 TinyVector<ParticleSet::ParticleGradient_t, OHMMS_DIM>& grad_grad, 123 TinyVector<ParticleSet::ParticleLaplacian_t, OHMMS_DIM>& lapl_grad) override; 124 125 /** move was accepted, update the real container 126 */ 127 void acceptMove(ParticleSet& P, int iat, bool safe_to_delay = false) override; 128 129 void mw_accept_rejectMove(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list, 130 const RefVectorWithLeader<ParticleSet>& p_list, 131 int iat, 132 const std::vector<bool>& isAccepted, 133 bool safe_to_delay = false) const override 134 { 135 for (int iw = 0; iw < wfc_list.size(); iw++) 136 if (isAccepted[iw]) 137 wfc_list[iw].acceptMove(p_list[iw], iat, safe_to_delay); 138 else 139 wfc_list[iw].restore(iat); 140 } 141 142 void completeUpdates() override; 143 mw_completeUpdates(const RefVectorWithLeader<WaveFunctionComponent> & wfc_list)144 void mw_completeUpdates(const RefVectorWithLeader<WaveFunctionComponent>& wfc_list) const override 145 { 146 for (int iw = 0; iw < wfc_list.size(); iw++) 147 wfc_list[iw].completeUpdates(); 148 } 149 150 /** move was rejected. copy the real container to the temporary to move on 151 */ 152 void restore(int iat) override; 153 154 ///evaluate log of a determinant for a particle set 155 LogValueType evaluateLog(const ParticleSet& P, 156 ParticleSet::ParticleGradient_t& G, 157 ParticleSet::ParticleLaplacian_t& L) override; 158 159 //Ye: TODO, good performance needs batched SPO evaluation. 160 //void mw_evaluateLog(const std::vector<WaveFunctionComponent*>& wfc_list, 161 // const std::vector<ParticleSet*>& p_list, 162 // const std::vector<ParticleSet::ParticleGradient_t*>& G_list, 163 // const std::vector<ParticleSet::ParticleLaplacian_t*>& L_list) override; 164 165 void recompute(const ParticleSet& P) override; 166 167 LogValueType evaluateGL(const ParticleSet& P, 168 ParticleSet::ParticleGradient_t& G, 169 ParticleSet::ParticleLaplacian_t& L, 170 bool fromscratch) override; 171 172 void evaluateHessian(ParticleSet& P, HessVector_t& grad_grad_psi) override; 173 174 void createResource(ResourceCollection& collection) const override; 175 void acquireResource(ResourceCollection& collection) override; 176 void releaseResource(ResourceCollection& collection) override; 177 178 /** cloning function 179 * @param tqp target particleset 180 * @param spo spo set 181 * 182 * This interface is exposed only to SlaterDet and its derived classes 183 * can overwrite to clone itself correctly. 184 */ 185 DiracDeterminant* makeCopy(std::shared_ptr<SPOSet>&& spo) const override; 186 187 void evaluateRatiosAlltoOne(ParticleSet& P, std::vector<ValueType>& ratios) override; 188 189 #ifndef NDEBUG 190 /// return for testing getPsiMinv()191 ValueMatrix_t& getPsiMinv() override { return psiM; } 192 #else getPsiMinv()193 ValueMatrix_t& getPsiMinv() { return psiM; } 194 #endif 195 196 /// psiM(j,i) \f$= \psi_j({\bf r}_i)\f$ 197 ValueMatrix_t psiM_temp; 198 199 /// inverse transpose of psiM(j,i) \f$= \psi_j({\bf r}_i)\f$ 200 ValueMatrix_t psiM; 201 202 /// temporary container for testing 203 ValueMatrix_t psiMinv; 204 205 /// dpsiM(i,j) \f$= \nabla_i \psi_j({\bf r}_i)\f$ 206 GradMatrix_t dpsiM; 207 208 /// d2psiM(i,j) \f$= \nabla_i^2 \psi_j({\bf r}_i)\f$ 209 ValueMatrix_t d2psiM; 210 211 /// Used for force computations 212 GradMatrix_t grad_source_psiM, grad_lapl_source_psiM; 213 HessMatrix_t grad_grad_source_psiM; 214 215 GradMatrix_t phi_alpha_Minv, grad_phi_Minv; 216 ValueMatrix_t lapl_phi_Minv; 217 HessMatrix_t grad_phi_alpha_Minv; 218 219 /// value of single-particle orbital for particle-by-particle update 220 ValueVector_t psiV; 221 ValueVector_t dspin_psiV; 222 GradVector_t dpsiV; 223 ValueVector_t d2psiV; 224 225 /// delayed update engine 226 DU_TYPE updateEng; 227 228 /// the row of up-to-date inverse matrix 229 ValueVector_t invRow; 230 231 /** row id correspond to the up-to-date invRow. [0 norb), invRow is ready; -1, invRow is not valid. 232 * This id is set after calling getInvRow indicating invRow has been prepared for the invRow_id row 233 * ratioGrad checks if invRow_id is consistent. If not, invRow needs to be recomputed. 234 * acceptMove and completeUpdates mark invRow invalid by setting invRow_id to -1 235 */ 236 int invRow_id; 237 238 PsiValueType curRatio; 239 ValueType* FirstAddressOfdV; 240 ValueType* LastAddressOfdV; 241 242 private: 243 /// invert psiM or its copies 244 void invertPsiM(const ValueMatrix_t& logdetT, ValueMatrix_t& invMat); 245 246 /// Resize all temporary arrays required for force computation. 247 void resizeScratchObjectsForIonDerivs(); 248 249 /// internal function computing ratio and gradients after computing the SPOs, used by ratioGrad. 250 PsiValueType ratioGrad_compute(int iat, GradType& grad_iat); 251 }; 252 253 extern template class DiracDeterminant<>; 254 #if defined(ENABLE_CUDA) 255 extern template class DiracDeterminant<DelayedUpdateCUDA<QMCTraits::ValueType, QMCTraits::QTFull::ValueType>>; 256 #endif 257 258 } // namespace qmcplusplus 259 #endif 260