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