1 //
2 // BAGEL - Brilliantly Advanced General Electronic Structure Library
3 // Filename: matrix1earray.h
4 // Copyright (C) 2013 Toru Shiozaki
5 //
6 // Author: Shane Parker <shane.parker@u.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
26 #ifndef __SRC_MOLECULE_MATRIX1EARRAY_H
27 #define __SRC_MOLECULE_MATRIX1EARRAY_H
28
29 #include <src/mat1e/matrix1e.h>
30 #include <src/util/taskqueue.h>
31
32 namespace bagel {
33
34 template <int N, typename MatType>
35 class Matrix1eArrayTask;
36
37 // specialized matrix for N component 1e integrals
38 template <int N, typename MatType = Matrix>
39 class Matrix1eArray {
40 friend class Matrix1eArrayTask<N, MatType>;
41 protected:
42 std::array<std::shared_ptr<MatType>, N> matrices_;
43
44 virtual void init(std::shared_ptr<const Molecule>);
45 virtual void computebatch(const std::array<std::shared_ptr<const Shell>,2>&, const int, const int, std::shared_ptr<const Molecule>) = 0;
46
47 bool localized_;
48
49 public:
Matrix1eArray()50 Matrix1eArray() {}
51 Matrix1eArray(const std::shared_ptr<const Molecule>, const bool loc = false);
52 Matrix1eArray(const int n, const int m, const bool loc = false);
53 Matrix1eArray(const Matrix1eArray&);
~Matrix1eArray()54 virtual ~Matrix1eArray() { }
55
ax_plus_y(const double a,const Matrix1eArray<N,MatType> & o)56 void ax_plus_y(const double a, const Matrix1eArray<N, MatType>& o) {
57 std::transform(o.matrices_.begin(), o.matrices_.end(), matrices_.begin(), matrices_.begin(),
58 [&a](std::shared_ptr<MatType> p, std::shared_ptr<MatType> q) { q->ax_plus_y(a, p); return q; });
59 }
60
data(const int i)61 std::shared_ptr<MatType>& data(const int i) { return matrices_[i]; }
data(const int i)62 std::shared_ptr<const MatType> data(const int i) const { return matrices_[i]; }
63
64 MatType& operator[](const int i) { return *matrices_[i]; }
65 const MatType& operator[](const int i) const { return *matrices_[i]; }
66
Nblocks()67 constexpr static int Nblocks() { return N; }
68
fill_upper()69 void fill_upper() { for (auto& i : matrices_) i->fill_upper(); }
fill_upper_conjg()70 void fill_upper_conjg() { for (auto& i : matrices_) i->fill_upper_conjg(); }
71 template<typename DataType>
scale(const DataType a)72 void scale(const DataType a) { for (auto& i : matrices_) i->scale(a); }
73
74 virtual void print(const std::string name = "", const int len = 10) const;
75
localize()76 void localize() {
77 localized_ = true;
78 for (auto& i : matrices_) i->localize();
79 }
80
81 };
82
83 template <int N, typename MatType>
Matrix1eArray(const std::shared_ptr<const Molecule> mol,const bool loc)84 Matrix1eArray<N, MatType>::Matrix1eArray(const std::shared_ptr<const Molecule> mol, const bool loc) : localized_(loc) {
85 static_assert(N > 0, "Matrix1eArray should be constructed with N > 0");
86 for(int i = 0; i < N; ++i) {
87 matrices_[i] = std::make_shared<MatType>(mol->nbasis(), mol->nbasis(), loc);
88 }
89 }
90
91
92 template <int N, typename MatType>
Matrix1eArray(const int n,const int m,const bool loc)93 Matrix1eArray<N, MatType>::Matrix1eArray(const int n, const int m, const bool loc) : localized_(loc) {
94 static_assert(N > 0, "Matrix1eArray should be constructed with N > 0");
95 for(int i = 0; i < N; ++i) {
96 matrices_[i] = std::make_shared<MatType>(n, m, loc);
97 }
98 }
99
100
101 template <int N, typename MatType>
Matrix1eArray(const Matrix1eArray & o)102 Matrix1eArray<N, MatType>::Matrix1eArray(const Matrix1eArray& o) : localized_(o.localized_) {
103 for (int i = 0; i < N; ++i) {
104 *data(i) = *o.data(i);
105 }
106 }
107
108
109 template <int N, typename MatType>
print(const std::string name,const int len)110 void Matrix1eArray<N, MatType>::print(const std::string name, const int len) const {
111 int j = 0;
112 for (auto& i : matrices_) {
113 std::stringstream ss; ss << name << " " << j++;
114 i->print(ss.str(), len);
115 }
116 }
117
118 template <int N, typename MatType>
init(std::shared_ptr<const Molecule> mol)119 void Matrix1eArray<N, MatType>::init(std::shared_ptr<const Molecule> mol) {
120
121 // identical to Matrix1e::init()
122 // only lower half will be stored
123 const size_t nshell = accumulate(mol->atoms().begin(), mol->atoms().end(), 0, [](int r, std::shared_ptr<const Atom> p) { return r+p->nshell(); });
124 TaskQueue<Matrix1eArrayTask<N, MatType>> task(nshell*(nshell+1)/2);
125
126 size_t oa0 = 0;
127 int u = 0;
128 for (auto a0 = mol->atoms().begin(); a0 != mol->atoms().end(); ++a0) {
129 // iatom1 = iatom1;
130 size_t ob0 = oa0;
131 for (auto& b0 : (*a0)->shells()) {
132 size_t ob1 = oa0;
133 for (auto& b1 : (*a0)->shells()) {
134 if (u++ % mpi__->size() == mpi__->rank()) {
135 task.emplace_back(std::array<std::shared_ptr<const Shell>,2>{{b1, b0}}, ob0, ob1, mol, this);
136 }
137 ob1 += b1->nbasis();
138 }
139 ob0 += b0->nbasis();
140 }
141
142 auto oa1 = oa0 + (*a0)->nbasis();
143 for (auto a1 = a0+1; a1 != mol->atoms().end(); ++a1) {
144 size_t ob0 = oa0;
145 for (auto& b0 : (*a0)->shells()) {
146 size_t ob1 = oa1;
147 for (auto& b1 : (*a1)->shells()) {
148 if (u++ % mpi__->size() == mpi__->rank()) {
149 task.emplace_back(std::array<std::shared_ptr<const Shell>,2>{{b1, b0}}, ob0, ob1, mol, this);
150 }
151 ob1 += b1->nbasis();
152 }
153 ob0 += b0->nbasis();
154 }
155 oa1 += (*a1)->nbasis();
156 }
157 oa0 += (*a0)->nbasis();
158 }
159 task.compute();
160 for (auto& i : matrices_) i->allreduce();
161
162 }
163
164 template <int N, typename MatType = Matrix>
165 class Matrix1eArrayTask {
166 protected:
167 Matrix1eArray<N, MatType>* parent_;
168 size_t ob0, ob1;
169 std::array<std::shared_ptr<const Shell>,2> bas;
170 std::shared_ptr<const Molecule> mol;
171 public:
172 Matrix1eArrayTask<N, MatType>(std::array<std::shared_ptr<const Shell>,2> a, size_t b, size_t c, std::shared_ptr<const Molecule> m, Matrix1eArray<N, MatType>* d)
parent_(d)173 : parent_(d), ob0(b), ob1(c), bas(a), mol(m) { }
compute()174 void compute() const { parent_->computebatch(bas, ob0, ob1, mol); }
175 };
176
177 }
178
179 #endif
180