1 //////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source
3 // License.  See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by:
8 // Miguel A. Morales, moralessilva2@llnl.gov
9 //    Lawrence Livermore National Laboratory
10 //
11 // File created by:
12 // Miguel A. Morales, moralessilva2@llnl.gov
13 //    Lawrence Livermore National Laboratory
14 ////////////////////////////////////////////////////////////////////////////////
15 
16 #ifndef QMCPLUSPLUS_AFQMC_WAVEFUNCTION_HPP
17 #define QMCPLUSPLUS_AFQMC_WAVEFUNCTION_HPP
18 
19 #include <fstream>
20 
21 #include "AFQMC/config.h"
22 #include "boost/variant.hpp"
23 
24 #include "AFQMC/SlaterDeterminantOperations/SlaterDetOperations.hpp"
25 #include "AFQMC/Wavefunctions/NOMSD.hpp"
26 #include "AFQMC/Wavefunctions/PHMSD.hpp"
27 
28 namespace qmcplusplus
29 {
30 namespace afqmc
31 {
32 namespace dummy
33 {
34 /*
35  * Empty class to avoid need for default constructed Wavefunctions.
36  * Throws is any visitor is called.
37  */
38 class dummy_wavefunction
39 {
40 private:
41   std::vector<ComplexType> ci;
42   std::vector<PsiT_Matrix> orbs;
43 
44 public:
dummy_wavefunction()45   dummy_wavefunction(){};
46 
size_of_G_for_vbias() const47   int size_of_G_for_vbias() const
48   {
49     throw std::runtime_error("calling visitor on dummy_wavefunction object");
50     return 0;
51   }
local_number_of_cholesky_vectors() const52   int local_number_of_cholesky_vectors() const
53   {
54     throw std::runtime_error("calling visitor on dummy_wavefunction object");
55     return 0;
56   }
global_number_of_cholesky_vectors() const57   int global_number_of_cholesky_vectors() const
58   {
59     throw std::runtime_error("calling visitor on dummy_wavefunction object");
60     return 0;
61   }
global_origin_cholesky_vector() const62   int global_origin_cholesky_vector() const
63   {
64     throw std::runtime_error("calling visitor on dummy_wavefunction object");
65     return 0;
66   }
number_of_references_for_back_propagation() const67   int number_of_references_for_back_propagation() const
68   {
69     throw std::runtime_error("calling visitor on dummy_wavefunction object");
70     return 0;
71   }
distribution_over_cholesky_vectors() const72   bool distribution_over_cholesky_vectors() const
73   {
74     throw std::runtime_error("calling visitor on dummy_wavefunction object");
75     return false;
76   }
77 
getWalkerType() const78   WALKER_TYPES getWalkerType() const { return UNDEFINED_WALKER_TYPE; }
79 
transposed_G_for_vbias() const80   bool transposed_G_for_vbias() const
81   {
82     throw std::runtime_error("calling visitor on dummy_wavefunction object");
83     return false;
84   }
85 
transposed_G_for_E() const86   bool transposed_G_for_E() const
87   {
88     throw std::runtime_error("calling visitor on dummy_wavefunction object");
89     return false;
90   }
91 
transposed_vHS() const92   bool transposed_vHS() const
93   {
94     throw std::runtime_error("calling visitor on dummy_wavefunction object");
95     return false;
96   }
97 
98   template<class Vec>
vMF(Vec && v)99   void vMF(Vec&& v)
100   {
101     throw std::runtime_error("calling visitor on dummy_wavefunction object");
102   }
103 
104   template<class MatG, class MatA>
vbias(const MatG & G,MatA && v,double a=1.0)105   void vbias(const MatG& G, MatA&& v, double a = 1.0)
106   {
107     throw std::runtime_error("calling visitor on dummy_wavefunction object");
108   }
109 
110   template<class MatX, class MatA>
vHS(MatX && X,MatA && v,double a=1.0)111   void vHS(MatX&& X, MatA&& v, double a = 1.0)
112   {
113     throw std::runtime_error("calling visitor on dummy_wavefunction object");
114   }
115 
116   template<class WSet>
Energy(WSet & wset)117   void Energy(WSet& wset)
118   {
119     throw std::runtime_error("calling visitor on dummy_wavefunction object");
120   }
121 
122   template<class WlkSet, class Mat, class TVec>
Energy(const WlkSet & wset,Mat && E,TVec && Ov)123   void Energy(const WlkSet& wset, Mat&& E, TVec&& Ov)
124   {
125     throw std::runtime_error("calling visitor on dummy_wavefunction object");
126   }
127 
128   template<class WlkSet, class MatG>
MixedDensityMatrix(const WlkSet & wset,MatG && G,bool compact=true,bool transpose=false)129   void MixedDensityMatrix(const WlkSet& wset, MatG&& G, bool compact = true, bool transpose = false)
130   {
131     throw std::runtime_error("calling visitor on dummy_wavefunction object");
132   }
133 
134   template<class WlkSet, class MatG, class TVec>
MixedDensityMatrix(const WlkSet & wset,MatG && G,TVec && Ov,bool compact=true,bool transpose=false)135   void MixedDensityMatrix(const WlkSet& wset, MatG&& G, TVec&& Ov, bool compact = true, bool transpose = false)
136   {
137     throw std::runtime_error("calling visitor on dummy_wavefunction object");
138   }
139 
140   template<class WlkSet, class MatG, class CVec1, class CVec2, class Mat1, class Mat2>
WalkerAveragedDensityMatrix(const WlkSet & wset,CVec1 & wgt,MatG & G,CVec2 & denom,Mat1 && Ovlp,Mat2 && DMsum,bool free_projection=false,boost::multi::array_ref<ComplexType,3> * Refs=nullptr,boost::multi::array<ComplexType,2> * detR=nullptr)141   void WalkerAveragedDensityMatrix(const WlkSet& wset,
142                                    CVec1& wgt,
143                                    MatG& G,
144                                    CVec2& denom,
145                                    Mat1&& Ovlp,
146                                    Mat2&& DMsum,
147                                    bool free_projection                          = false,
148                                    boost::multi::array_ref<ComplexType, 3>* Refs = nullptr,
149                                    boost::multi::array<ComplexType, 2>* detR     = nullptr)
150   {
151     throw std::runtime_error("calling visitor on dummy_wavefunction object");
152   }
153 
154   template<class WlkSet, class MatG>
MixedDensityMatrix_for_vbias(const WlkSet & wset,MatG && G)155   void MixedDensityMatrix_for_vbias(const WlkSet& wset, MatG&& G)
156   {
157     throw std::runtime_error("calling visitor on dummy_wavefunction object");
158   }
159 
160   template<class... Args>
DensityMatrix(Args &&...args)161   void DensityMatrix(Args&&... args)
162   {
163     throw std::runtime_error("calling visitor on dummy_wavefunction object");
164   }
165 
166   template<class WlkSet, class TVec>
Overlap(const WlkSet & wset,TVec && Ov)167   void Overlap(const WlkSet& wset, TVec&& Ov)
168   {
169     throw std::runtime_error("calling visitor on dummy_wavefunction object");
170   }
171 
172   template<class WlkSet>
Overlap(WlkSet & wset)173   void Overlap(WlkSet& wset)
174   {
175     throw std::runtime_error("calling visitor on dummy_wavefunction object");
176   }
177 
178   template<class WlkSet>
Orthogonalize(WlkSet & wset,bool impSamp)179   void Orthogonalize(WlkSet& wset, bool impSamp)
180   {
181     throw std::runtime_error("calling visitor on dummy_wavefunction object");
182   }
183 
getReferenceWeight(int i)184   ComplexType getReferenceWeight(int i)
185   {
186     throw std::runtime_error("calling visitor on dummy_wavefunction object");
187     return ComplexType(0.0, 0.0);
188   }
189 
190   template<class Mat>
getReferencesForBackPropagation(Mat && A)191   void getReferencesForBackPropagation(Mat&& A)
192   {
193     throw std::runtime_error("calling visitor on dummy_wavefunction object");
194   }
195 
196   SlaterDetOperations SDet;
getSlaterDetOperations()197   SlaterDetOperations* getSlaterDetOperations() { return std::addressof(SDet); }
198 
199   HamiltonianOperations HOps;
getHamiltonianOperations()200   HamiltonianOperations* getHamiltonianOperations() { return std::addressof(HOps); }
201 };
202 } // namespace dummy
203 
204 class Wavefunction : public boost::variant<dummy::dummy_wavefunction,
205                                            NOMSD<devcsr_Matrix>,
206                                            NOMSD<ComplexMatrix<node_allocator<ComplexType>>>,
207                                            PHMSD>
208 {
209 public:
Wavefunction()210   Wavefunction() { APP_ABORT(" Error: Reached default constructor of Wavefunction. \n"); }
Wavefunction(NOMSD<devcsr_Matrix> && other)211   explicit Wavefunction(NOMSD<devcsr_Matrix>&& other) : variant(std::move(other)) {}
212   explicit Wavefunction(NOMSD<devcsr_Matrix> const& other) = delete;
213 
Wavefunction(NOMSD<ComplexMatrix<node_allocator<ComplexType>>> && other)214   explicit Wavefunction(NOMSD<ComplexMatrix<node_allocator<ComplexType>>>&& other) : variant(std::move(other)) {}
215   explicit Wavefunction(NOMSD<ComplexMatrix<node_allocator<ComplexType>>> const& other) = delete;
216 
Wavefunction(PHMSD && other)217   explicit Wavefunction(PHMSD&& other) : variant(std::move(other)) {}
218   explicit Wavefunction(PHMSD const& other) = delete;
219 
220   Wavefunction(Wavefunction const& other) = delete;
221   Wavefunction(Wavefunction&& other)      = default;
222 
223   Wavefunction& operator=(Wavefunction const& other) = delete;
224   Wavefunction& operator=(Wavefunction&& other) = default;
225 
size_of_G_for_vbias() const226   int size_of_G_for_vbias() const
227   {
228     return boost::apply_visitor([&](auto&& a) { return a.size_of_G_for_vbias(); }, *this);
229   }
230 
local_number_of_cholesky_vectors() const231   int local_number_of_cholesky_vectors() const
232   {
233     return boost::apply_visitor([&](auto&& a) { return a.local_number_of_cholesky_vectors(); }, *this);
234   }
235 
global_number_of_cholesky_vectors() const236   int global_number_of_cholesky_vectors() const
237   {
238     return boost::apply_visitor([&](auto&& a) { return a.global_number_of_cholesky_vectors(); }, *this);
239   }
240 
global_origin_cholesky_vector() const241   int global_origin_cholesky_vector() const
242   {
243     return boost::apply_visitor([&](auto&& a) { return a.global_origin_cholesky_vector(); }, *this);
244   }
245 
number_of_references_for_back_propagation() const246   int number_of_references_for_back_propagation() const
247   {
248     return boost::apply_visitor([&](auto&& a) { return a.number_of_references_for_back_propagation(); }, *this);
249   }
250 
distribution_over_cholesky_vectors() const251   bool distribution_over_cholesky_vectors() const
252   {
253     return boost::apply_visitor([&](auto&& a) { return a.distribution_over_cholesky_vectors(); }, *this);
254   }
255 
transposed_G_for_vbias() const256   bool transposed_G_for_vbias() const
257   {
258     return boost::apply_visitor([&](auto&& a) { return a.transposed_G_for_vbias(); }, *this);
259   }
260 
transposed_G_for_E() const261   bool transposed_G_for_E() const
262   {
263     return boost::apply_visitor([&](auto&& a) { return a.transposed_G_for_E(); }, *this);
264   }
265 
transposed_vHS() const266   bool transposed_vHS() const
267   {
268     return boost::apply_visitor([&](auto&& a) { return a.transposed_vHS(); }, *this);
269   }
270 
getWalkerType() const271   WALKER_TYPES getWalkerType() const
272   {
273     return boost::apply_visitor([&](auto&& a) { return a.getWalkerType(); }, *this);
274   }
275 
276   template<class... Args>
vMF(Args &&...args)277   void vMF(Args&&... args)
278   {
279     boost::apply_visitor([&](auto&& a) { a.vMF(std::forward<Args>(args)...); }, *this);
280   }
281 
282   template<class... Args>
vbias(Args &&...args)283   void vbias(Args&&... args)
284   {
285     boost::apply_visitor([&](auto&& a) { a.vbias(std::forward<Args>(args)...); }, *this);
286   }
287 
288   template<class... Args>
vHS(Args &&...args)289   void vHS(Args&&... args)
290   {
291     boost::apply_visitor([&](auto&& a) { a.vHS(std::forward<Args>(args)...); }, *this);
292   }
293 
294   template<class... Args>
Energy(Args &&...args)295   void Energy(Args&&... args)
296   {
297     boost::apply_visitor([&](auto&& a) { a.Energy(std::forward<Args>(args)...); }, *this);
298   }
299 
300   template<class... Args>
DensityMatrix(Args &&...args)301   void DensityMatrix(Args&&... args)
302   {
303     boost::apply_visitor([&](auto&& a) { a.DensityMatrix(std::forward<Args>(args)...); }, *this);
304   }
305 
306   template<class... Args>
MixedDensityMatrix(Args &&...args)307   void MixedDensityMatrix(Args&&... args)
308   {
309     boost::apply_visitor([&](auto&& a) { a.MixedDensityMatrix(std::forward<Args>(args)...); }, *this);
310   }
311 
312   template<class... Args>
MixedDensityMatrix_for_vbias(Args &&...args)313   void MixedDensityMatrix_for_vbias(Args&&... args)
314   {
315     boost::apply_visitor([&](auto&& a) { a.MixedDensityMatrix_for_vbias(std::forward<Args>(args)...); }, *this);
316   }
317 
318   template<class... Args>
Overlap(Args &&...args)319   void Overlap(Args&&... args)
320   {
321     boost::apply_visitor([&](auto&& a) { a.Overlap(std::forward<Args>(args)...); }, *this);
322   }
323 
324   template<class... Args>
Orthogonalize(Args &&...args)325   void Orthogonalize(Args&&... args)
326   {
327     boost::apply_visitor([&](auto&& a) { a.Orthogonalize(std::forward<Args>(args)...); }, *this);
328   }
329 
330   template<class... Args>
getReferenceWeight(Args &&...args)331   ComplexType getReferenceWeight(Args&&... args)
332   {
333     return boost::apply_visitor([&](auto&& a) { return a.getReferenceWeight(std::forward<Args>(args)...); }, *this);
334   }
335 
336   template<class... Args>
getReferencesForBackPropagation(Args &&...args)337   void getReferencesForBackPropagation(Args&&... args)
338   {
339     boost::apply_visitor([&](auto&& a) { a.getReferencesForBackPropagation(std::forward<Args>(args)...); }, *this);
340   }
341 
342   template<class... Args>
WalkerAveragedDensityMatrix(Args &&...args)343   void WalkerAveragedDensityMatrix(Args&&... args)
344   {
345     boost::apply_visitor([&](auto&& a) { a.WalkerAveragedDensityMatrix(std::forward<Args>(args)...); }, *this);
346   }
347 
getSlaterDetOperations()348   SlaterDetOperations* getSlaterDetOperations()
349   {
350     return boost::apply_visitor([&](auto&& a) { return a.getSlaterDetOperations(); }, *this);
351   }
352 
getHamiltonianOperations()353   HamiltonianOperations* getHamiltonianOperations()
354   {
355     return boost::apply_visitor([&](auto&& a) { return a.getHamiltonianOperations(); }, *this);
356   }
357 };
358 
359 } // namespace afqmc
360 
361 } // namespace qmcplusplus
362 
363 #endif
364