1 //
2 // BAGEL - Brilliantly Advanced General Electronic Structure Library
3 // Filename: gradeval_base.h
4 // Copyright (C) 2012 Toru Shiozaki
5 //
6 // Author: Toru Shiozaki <shiozaki@northwestern.edu>
7 // Maintainer: Shiozaki group
8 //
9 // This file is part of the BAGEL package.
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 //
24 
25 #ifndef __SRC_GRAD_GRADEVAL_BASE_H
26 #define __SRC_GRAD_GRADEVAL_BASE_H
27 
28 #include <mutex>
29 #include <src/util/math/xyzfile.h>
30 #include <src/wfn/geometry.h>
31 
32 namespace bagel {
33 
34 // GradTask is a helper class of GradEval_base and declared as friend
35 class GradEval_base;
36 
37 #define GRADTASK_INCLUDE
38 #include <src/grad/gradtask.hpp>
39 #undef  GRADTASK_INCLUDE
40 
41 // base class for gradient evaluations
42 class GradEval_base {
43   protected:
44     std::shared_ptr<const Geometry> geom_;
45 
46     /// contract 1-electron gradient integrals with density matrix "d" and energy weighted density matrix (or equivalent) "w"
47     template<typename TaskType>
48     std::vector<std::shared_ptr<GradTask>> contract_grad1e(const std::shared_ptr<const Matrix> d, const std::shared_ptr<const Matrix> w);
49     /// same as above, but one can specify density matrices to each integral kernel
50     template<typename TaskType>
51     std::vector<std::shared_ptr<GradTask>> contract_grad1e(const std::shared_ptr<const Matrix> n, const std::shared_ptr<const Matrix> k, const std::shared_ptr<const Matrix> o);
52     /// contract 1-electron gradient integrals used for DKH
53     std::vector<std::shared_ptr<GradTask>> contract_graddkh1e(std::array<std::shared_ptr<const Matrix>, 4>);
54     /// contract small NAI gradient integrals with an array of densities
55     std::vector<std::shared_ptr<GradTask>> contract_gradsmall1e(std::array<std::shared_ptr<const Matrix>,6>);
56     /// contract finite-nucleus NAI gradient
57     std::vector<std::shared_ptr<GradTask>> contract_grad1e_fnai(const std::shared_ptr<const Matrix> n);
58     std::vector<std::shared_ptr<GradTask>> contract_grad1e_fnai(std::array<std::shared_ptr<const Matrix>,6> n,  const std::shared_ptr<const Geometry> geom = nullptr);
59 
60     /// contract 3-index 2-electron gradient integrals with density matrix "o".
61     std::vector<std::shared_ptr<GradTask>> contract_grad2e(const std::shared_ptr<const DFDist> o,               const std::shared_ptr<const Geometry> geom = nullptr);
62     std::vector<std::shared_ptr<GradTask>> contract_grad2e(const std::array<std::shared_ptr<const DFDist>,6> o, const std::shared_ptr<const Geometry> geom = nullptr);
63 
64     /// contract 2-index 2-electron gradient integrals with density matrix "o".
65     std::vector<std::shared_ptr<GradTask>> contract_grad2e_2index(const std::shared_ptr<const Matrix> o,        const std::shared_ptr<const Geometry> geom = nullptr);
66 
67     // the results will be stored in grad_
68     std::shared_ptr<GradFile> grad_;
69     std::vector<std::mutex> mutex_;
70 
71   public:
GradEval_base(const std::shared_ptr<const Geometry> g)72     GradEval_base(const std::shared_ptr<const Geometry> g) : geom_(g), grad_(std::make_shared<GradFile>(g->natom())), mutex_(g->natom()) { }
73 
74     /// compute gradient given density matrices
75     std::shared_ptr<GradFile> contract_gradient(const std::shared_ptr<const Matrix> d, const std::shared_ptr<const Matrix> w,
76                                                 const std::shared_ptr<const DFDist> o, const std::shared_ptr<const Matrix> o2,
77                                                 const std::shared_ptr<const Matrix> v = nullptr, const bool numerical = false,
78                                                 const std::shared_ptr<const Geometry> g2 = nullptr,
79                                                 const std::shared_ptr<const DFDist> g2o = nullptr,
80                                                 const std::shared_ptr<const Matrix> g2o2 = nullptr);
compute()81     virtual std::shared_ptr<GradFile> compute() { assert(false); return nullptr; }
82 
83     friend class GradTask1;
84     friend class GradTask1s;
85     friend class GradTask2;
86     friend class GradTask3;
87     friend class GradTask1r;
88     friend class GradTask1f;
89     friend class GradTask3r;
90     friend class GradTask1rf;
91     friend class GradTask1d;
92 };
93 
94 template<typename TBatch>
compute_os(std::shared_ptr<const Matrix> den)95 std::shared_ptr<GradFile> GradTask1::compute_os(std::shared_ptr<const Matrix> den) const {
96   const int dimb1 = shell_[0]->nbasis();
97   const int dimb0 = shell_[1]->nbasis();
98   std::shared_ptr<const Matrix> cden = den->get_submatrix(offset_[1], offset_[0], dimb1, dimb0);
99   TBatch batch(shell_);
100   batch.compute();
101   return batch.compute_gradient(cden, atomindex_[0], atomindex_[1], ge_->geom_->natom());
102 }
103 
104 template<typename TBatch>
compute_os(std::shared_ptr<const Matrix> den)105 std::shared_ptr<GradFile> GradTask1s::compute_os(std::shared_ptr<const Matrix> den) const {
106   const int dimb1 = shell_[0]->nbasis();
107   const int dimb0 = shell_[1]->nbasis();
108   std::shared_ptr<const Matrix> cden = den->get_submatrix(offset_[1], offset_[0], dimb1, dimb0);
109   TBatch batch(shell_);
110   batch.compute();
111   return batch.compute_gradient(cden, atomindex_[0], atomindex_[1], ge_->geom_->natom());
112 }
113 
114 template<typename TBatch>
compute_os(std::shared_ptr<const Matrix> den)115 std::shared_ptr<GradFile> GradTask1d::compute_os(std::shared_ptr<const Matrix> den) const {
116   const int dimb1 = shell_[0]->nbasis();
117   const int dimb0 = shell_[1]->nbasis();
118   std::shared_ptr<const Matrix> cden = den->get_submatrix(offset_[1], offset_[0], dimb1, dimb0);
119   TBatch batch(shell_);
120   batch.compute();
121   return batch.compute_gradient(cden, atomindex_[0], atomindex_[1], ge_->geom_->natom());
122 }
123 
124 
125 extern template
126 std::vector<std::shared_ptr<GradTask>> GradEval_base::contract_grad1e<GradTask1>(const std::shared_ptr<const Matrix> d, const std::shared_ptr<const Matrix> w);
127 extern template
128 std::vector<std::shared_ptr<GradTask>> GradEval_base::contract_grad1e<GradTask1s>(const std::shared_ptr<const Matrix> d, const std::shared_ptr<const Matrix> w);
129 extern template
130 std::vector<std::shared_ptr<GradTask>> GradEval_base::contract_grad1e<GradTask1>(const std::shared_ptr<const Matrix> n, const std::shared_ptr<const Matrix> k,
131                                                                                  const std::shared_ptr<const Matrix> o);
132 extern template
133 std::vector<std::shared_ptr<GradTask>> GradEval_base::contract_grad1e<GradTask1s>(const std::shared_ptr<const Matrix> n, const std::shared_ptr<const Matrix> k,
134                                                                                   const std::shared_ptr<const Matrix> o);
135 
136 }
137 
138 #endif
139