MPQC  3.0.0-alpha
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 
18 namespace mpqc {
19 namespace 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 
75  mpqc::Matrix G;
76  struct Iter {
77  double E, D;
78  size_t M;
79  mpqc::Matrix G;
80  mpqc::Vector lambda;
81  mpqc::Matrix a;
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 */
mpqc::orthonormalize
void orthonormalize(matrix< T > &d, const matrix< T > &b)
orthormalize matrix d wrt to normalized matrix b d = normalize(d - (<d|b>*b))
Definition: matrix.hpp:224
mpqc::ci::sigma
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
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37
mpqc::ci::CI::alpha
ci::String::List< Index > alpha
Alpha string list.
Definition: ci.hpp:81
mpqc::timer
Definition: timer.hpp:9
mpqc::range
Definition: range.hpp:23
mpqc::ci::CI::config
const ci::Config config
CI configuration.
Definition: ci.hpp:79
mpqc::matrix
Matrix class derived from Eigen::Matrix with additional MPQC integration.
Definition: matrix.hpp:21
mpqc::ci::Vector
Block CI Vector, with 1-d (vector) and 2-d (matrix) access.
Definition: vector.hpp:18
mpqc::ci::CI::beta
ci::String::List< Index > beta
Beta string list.
Definition: ci.hpp:82
MPQC_EXCEPTION
#define MPQC_EXCEPTION(...)
Definition: exception.hpp:51
mpqc::File::Dataspace
A subset of File::Dataset.
Definition: file.hpp:208
mpqc::ci::CI::subspace
SubspaceGrid subspace
CI subspaces grid.
Definition: ci.hpp:84
mpqc::norm
T norm(const matrix< T > &a)
Matrix norm.
Definition: matrix.hpp:209
mpqc::ci::CI
CI class template.
Definition: ci.hpp:71
mpqc::ci::write
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
mpqc::File::Dataspace::size
size_t size() const
Number of elements in the set.
Definition: file.hpp:356
mpqc::ci::CI::comm
MPI::Comm comm
CI communicator.
Definition: ci.hpp:86
mpqc::ci::CI::vector
mpqc::ci::CI::IO vector
CI vectors b (aka C), Hb (aka sigma) file datasets.
mpqc::ci::read
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
sc::ExEnv::out0
static std::ostream & out0()
Return an ostream that writes from node 0.
mpqc::vector
Vector class derived from Eigen::Matrix with additional MPQC integration.
Definition: matrix.hpp:133
mpqc::ci::direct
std::vector< double > direct(CI< Type, Index > &ci, const mpqc::Vector &h, const mpqc::Matrix &V)
Direct Davidson.
Definition: direct.hpp:61
sc::scprintf
This class allows printf-like output to be sent to an ostream.
Definition: formio.h:97
mpqc::symmetric
Eigen::SelfAdjointEigenSolver< Matrix::EigenType > symmetric(const matrix< T > &a)
Computes (Eigen::SelfAdjointEigenSolver) eigensystem of a matrix.
Definition: matrix.hpp:199

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.