MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
preconditioner.hpp
1#ifndef MPQC_CI_PRECONDITIONER_HPP
2#define MPQC_CI_PRECONDITIONER_HPP
3
4#include "mpqc/ci/hamiltonian.hpp"
5#include "mpqc/ci/vector.hpp"
6#include "mpqc/math/matrix.hpp"
7#include <boost/foreach.hpp>
8#include "mpqc/mpi.hpp"
9#include "mpqc/mpi/task.hpp"
10
11#include "mpqc/utility/profile.hpp"
12
13namespace mpqc {
14namespace ci {
15
16 void symmetrize(mpqc::Matrix &a, double phase, double scale) {
17 MPQC_CHECK(a.rows() == a.cols());
18 for (size_t j = 0; j < a.cols(); ++j) {
19 a(j,j) *= scale;
20 for (size_t i = 0; i < j; ++i) {
21 a(i,j) = scale*a(i,j); // + a(j,i));
22 a(j,i) = phase*a(i,j);
23 }
24 }
25 }
26
27 template<class Type, class Index>
28 void preconditioner(CI<Type, Index> &ci,
29 const mpqc::Vector &h, const mpqc::Matrix &V,
30 double lambda, ci::Vector &D) {
31
32 MPQC_PROFILE_LINE;
33
34 const auto &comm = ci.comm;
35 const auto &alpha = ci.alpha;
36 const auto &beta = ci.beta;
37
38 double dd = 0;
39
40 const std::vector< Subspace<Alpha> > &A = ci.subspace.alpha();
41 const std::vector< Subspace<Beta> > &B = ci.subspace.beta();
42 const auto &blocks = ci::blocks(A, B);
43
44 std::unique_ptr<MPI::Task> task;
45
46 task.reset(new MPI::Task(comm));
47#pragma omp parallel
48 while (true) {
49
50 auto next = task->next(blocks.begin(), blocks.end());
51 if (next == blocks.end()) break;
52
53 auto Ia = A.at(next->alpha);
54 auto Ib = B.at(next->beta);
55 if (!ci.test(Ia,Ib)) continue;
56
57 mpqc::Matrix d = D(Ia,Ib);
58 mpqc::Vector aa(Ia.size());
59 for (int a = 0; a < Ia.size(); ++a) {
60 aa(a) = diagonal(alpha[*Ia.begin() + a], h, V);
61 }
62 for (int j = 0; j < Ib.size(); ++j) {
63 const String &bj = beta[*Ib.begin() + j];
64 double bb = diagonal(bj, h, V);
65 for (int a = 0; a < Ia.size(); ++a) {
66 double q = diagonal2(alpha[*Ia.begin() + a], bj, V);
67 q = (lambda - (q + aa(a) + bb));
68 d(a,j) = (fabs(q) > 1.0e-4) ? d(a,j)/q : 0;
69 }
70 }
71 D(Ia,Ib) = d;
72 dd += dot(d, d);
73 }
74 comm.sum(dd);
75 D.sync();
76
77 if (ci.config.ms != 0) {
78 throw MPQC_EXCEPTION("Preconditioner not yet implemented for ci.ms != 0");
79 }
80
81 double phase = 1.0;
82 double scale = 1.0/sqrt(dd);
83
84 task.reset(new MPI::Task(comm));
85#pragma omp parallel
86 while (true) {
87
88 auto next = task->next(blocks.begin(), blocks.end());
89 if (next == blocks.end()) break;
90
91 auto Ia = A.at(next->alpha);
92 auto Ib = B.at(next->beta);
93 if (!ci.test(Ia,Ib)) continue;
94
95 if (next->alpha == next->beta) {
96 Matrix aa = D(Ia,Ib);
97 ci::symmetrize(aa, phase, scale);
98 D(Ia,Ib) = aa;
99 }
100
101 if (next->alpha < next->beta) {
102 Matrix ab = D(Ia,Ib);
103 Matrix ba = D(Ib,Ia);
104 ab *= scale;
105 ba = phase*(ab.transpose());
106 D(Ia,Ib) = ab;
107 D(Ib,Ia) = ba;
108 }
109
110 }
111 D.sync();
112
113 }
114
115} // namespace ci
116} // namespace mpqc
117
118
119#endif /* MPQC_CI_PRECONDITIONER_HPP */
#define MPQC_EXCEPTION(...)
Constructs mpqc::Exception with file, line information and an optional printf-style format and argume...
Definition exception.hpp:51
matrix< double > Matrix
Convience double matrix type.
Definition matrix.hpp:170
T dot(const matrix< T > &a, const matrix< T > &b)
element-wise dot product of two matrices
Definition matrix.hpp:186
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37
void symmetrize(const Ref< GPetiteList2 > &plist2, const Ref< Integral > &integral, const RefSymmSCMatrix &skel, const RefSymmSCMatrix &sym)
Uses plist2 to convert the "skeleton" matrix into the full matrix. Only applicable when the two basis...
Matrix class derived from Eigen::Matrix with additional MPQC integration.
Definition matrix.hpp:23
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.