MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
direct.hpp
1#ifndef MPQC_CI_DIRECT_HPP
2#define MPQC_CI_DIRECT_HPP
3
4#include <util/misc/formio.h>
5
6#include "mpqc/ci/string.hpp"
7#include "mpqc/ci/vector.hpp"
8#include "mpqc/ci/sigma.hpp"
9#include "mpqc/ci/preconditioner.hpp"
10
11#include "mpqc/math/matrix.hpp"
12#include "mpqc/file.hpp"
13
14#include "mpqc/utility/profile.hpp"
15
16#define MPQC_CI_VERBOSE 0
17
18namespace mpqc {
19namespace ci {
20
23
26 const std::vector<mpqc::range> &local) {
27 timer t;
28 size_t count = 0;
29 BOOST_FOREACH (auto r, local) {
30 mpqc::Vector v(r.size());
31 F(r) >> v;
32 V(r) << v;
33 count += r.size();
34 }
35#if MPQC_CI_VERBOSE
36 printf("read took %f s, %f mb/s\n", (double)t, count*sizeof(double)/(t*(1<<20)));
37#endif
38 }
39
42 const std::vector<mpqc::range> &local) {
43 timer t;
44 size_t count = 0;
45 BOOST_FOREACH (auto r, local) {
46 mpqc::Vector v(r.size());
47 V(r) >> v;
48 F(r) << v;
49 count += r.size();
50 }
51#if MPQC_CI_VERBOSE
52 printf("write took %f s, %f mb/s\n", (double)t, count*sizeof(double)/(t*(1<<20)));
53#endif
54 }
55
60 template<class Type, class Index>
61 std::vector<double> direct(CI<Type,Index> &ci,
62 const mpqc::Vector &h,
63 const mpqc::Matrix &V) {
64
65 MPQC_PROFILE_REGISTER_THREAD;
66
67 mpqc::Matrix lambda;
68 mpqc::Vector a, r;
69 size_t R = ci.config.roots; // roots
70 size_t M = 1;
71
72 const auto &alpha = ci.alpha;
73 const auto &beta = ci.beta;
74
76 struct Iter {
77 double E, D;
78 size_t M;
80 mpqc::Vector lambda;
82 };
83 std::map<int, Iter> iters;
84 iters[-1].E = iters[-1].D = 0;
85
86 auto &comm = ci.comm;
87
88 ci::Vector C("ci.C", ci.subspace, comm, (ci.config.incore >= 1));
89 ci::Vector D("ci.D", ci.subspace, comm, (ci.config.incore >= 2));
90
91 comm.barrier();
92
93 std::vector<double> E;
94
95 for (size_t it = 0;; ++it) {
96
97 timer t;
98
99 // augment G
100 {
101 mpqc::Matrix g = G;
102 G.resize(M, M);
103 G.fill(0);
104 range m(0, M - 1);
105 G(m, m) = g(m, m);
106 }
107
108 {
109 // read local segments of b(it) to C
110 read(C, ci.vector.b[it], ci.local());
111 C.sync();
112
113 sigma(ci, h, V, C, D);
114 D.sync();
115
116 // write local segments of D to Hb(it)
117 write(D, ci.vector.Hb[it], ci.local());
118 D.sync();
119 }
120
121 // augment G matrix
122 {
123 MPQC_PROFILE_LINE;
124 mpqc::Vector g = mpqc::Vector::Zero(M);
125 BOOST_FOREACH (auto r, ci.local()) {
126 mpqc::Vector c(r.size());
127 mpqc::Vector s(r.size());
128 D(r) >> s;
129 for (int j = 0; j < M; ++j) {
130 ci.vector.b(r,j) >> c;
131 g(j) += c.dot(s);
132 }
133 }
134 comm.sum(g.data(), M);
135 G.row(it) = g;
136 G.col(it) = g;
137 //std::cout << "G = \n" << G << std::endl;
138 }
139
140 // solve G eigenvalue
141 mpqc::Vector lambda = symmetric(G).eigenvalues();
142 mpqc::Matrix a = symmetric(G).eigenvectors();
143
144 iters[it].M = M;
145 iters[it].G = G;
146 iters[it].lambda = lambda;
147 iters[it].a = a;
148
149 // std::cout << "lambda:\n" << lambda << std::endl;
150 // std::cout << "alpha:\n" << a << std::endl;
151
152 for (int k = 0; k < R; ++k) {
153
154 // update d part
155 for (auto r : ci.local()) {
156 MPQC_PROFILE_LINE;
157 mpqc::Vector v(r.size());
158 mpqc::Vector d(r.size());
159 d.fill(0);
160 for (int i = 0; i < M; ++i) {
161 ci.vector.b(r,i) >> v;
162 double r = -a(i,k)*lambda(k);
163 d += r*v;
164 }
165 for (int i = 0; i < M; ++i) {
166 ci.vector.Hb(r,i) >> v;
167 d += a(i,k)*v;
168 }
169 D(r) << d;
170 }
171 D.sync();
172
173 iters[it].E = lambda[0];
174 iters[it].D = norm(D, ci.local(), comm);
175
176 if (comm.rank() == 0) {
177 double dc = fabs(iters[it - 1].D - iters[it].D);
178 double de = fabs(iters[it - 1].E - iters[it].E);
180 << sc::indent
181 << sc::scprintf("CI iter. %3i, E=%15.12lf, "
182 "del.E=%4.2e, del.C=%4.2e\n",
183 (int)it,
184 lambda[0] + ci.config.e_ref + ci.config.e_core,
185 de, dc);
186 }
187
188 preconditioner(ci, h, V, lambda[0], D);
189
190 // orthonormalize
191 for (int i = 0; i < M; ++i) {
192 ci::Vector &b = C;
193 read(b, ci.vector.b[i], ci.local());
194 orthonormalize(b, D, ci.local(), ci.comm);
195 }
196 D.sync();
197
198 if (it+1 == ci.config.max) break;
199
200 write(D, ci.vector.b[it+1], ci.local());
201 D.sync();
202
203 }
204
205 MPQC_PROFILE_DUMP(std::cout);
206
207 sc::ExEnv::out0() << sc::indent << "Davidson iteration time: " << t << std::endl;
208
209 if (fabs(iters[it - 1].E - iters[it].E) < ci.config.convergence) {
210 E.push_back(iters[it].E);
211 break;
212 }
213
214 if (it+1 == ci.config.max) {
215 throw MPQC_EXCEPTION("CI failed to converge");
216 }
217
218 ++M;
219 }
220
221 return E;
222
223 }
224
226
227} // namespace ci
228} // namespace mpqc
229
230#endif /* MPQC_CI_DIRECT_HPP */
static std::ostream & out0()
Return an ostream that writes from node 0.
This class allows printf-like output to be sent to an ostream.
Definition formio.h:97
void write(ci::Vector &V, File::Dataspace< double > F, const std::vector< mpqc::range > &local)
write local segments of V to F
Definition direct.hpp:41
void sigma(const CI< Type, Index > &ci, const mpqc::Vector &h, const Matrix &V, ci::Vector &C, ci::Vector &S)
Computes sigma 1,2,3 contributions.
Definition sigma.hpp:30
void read(ci::Vector &V, File::Dataspace< double > F, const std::vector< mpqc::range > &local)
read local segments into V from F
Definition direct.hpp:25
double orthonormalize(ci::Vector &b, ci::Vector &D, const std::vector< mpqc::range > &local, const MPI::Comm &comm)
Schmidt orthogonalization d' = normalized(d - <d,b>*b)
Definition vector.hpp:180
std::vector< double > direct(CI< Type, Index > &ci, const mpqc::Vector &h, const mpqc::Matrix &V)
Direct Davidson.
Definition direct.hpp:61
double norm(ci::Vector &V, const std::vector< mpqc::range > &local, const MPI::Comm &comm)
Compute CI vector norm.
Definition vector.hpp:160
#define MPQC_EXCEPTION(...)
Constructs mpqc::Exception with file, line information and an optional printf-style format and argume...
Definition exception.hpp:51
Eigen::SelfAdjointEigenSolver< Matrix::EigenType > symmetric(const matrix< T > &a)
Computes (Eigen::SelfAdjointEigenSolver) eigensystem of a matrix.
Definition matrix.hpp:199
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37
A subset of File::Dataset.
Definition file.hpp:351
CI class template.
Definition ci.hpp:75
mpqc::ci::CI::IO vector
CI vectors b (aka C), Hb (aka sigma) file datasets.
ci::String::List< Index > beta
Beta string list.
Definition ci.hpp:82
const ci::Config config
CI configuration.
Definition ci.hpp:79
SubspaceGrid subspace
CI subspaces grid.
Definition ci.hpp:84
MPI::Comm comm
CI communicator.
Definition ci.hpp:86
ci::String::List< Index > alpha
Alpha string list.
Definition ci.hpp:81
double convergence
energy convergence criteria
Definition ci.hpp:33
size_t max
maximum number of iterations
Definition ci.hpp:29
size_t roots
number of roots to find
Definition ci.hpp:28
int incore
determines if arrays C+S (2), C (1), or none(0) will be in core
Definition ci.hpp:35
Block CI Vector, with 1-d (vector) and 2-d (matrix) access.
Definition vector.hpp:18
Matrix class derived from Eigen::Matrix with additional MPQC integration.
Definition matrix.hpp:23
Definition range.hpp:25
Definition timer.hpp:9
Vector class derived from Eigen::Matrix with additional MPQC integration.
Definition matrix.hpp:133

Generated at Wed Sep 25 2024 02:45:30 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.12.0.