1 #ifndef MPQC_CI_PRECONDITIONER_HPP
2 #define MPQC_CI_PRECONDITIONER_HPP
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"
11 #include "mpqc/utility/profile.hpp"
17 MPQC_CHECK(a.rows() == a.cols());
18 for (
size_t j = 0; j < a.cols(); ++j) {
20 for (
size_t i = 0; i < j; ++i) {
21 a(i,j) = scale*a(i,j);
22 a(j,i) = phase*a(i,j);
27 template<
class Type,
class Index>
28 void preconditioner(CI<Type, Index> &ci,
34 const auto &comm = ci.comm;
35 const auto &alpha = ci.alpha;
36 const auto &beta = ci.beta;
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);
44 std::unique_ptr<MPI::Task> task;
46 task.reset(
new MPI::Task(comm));
50 auto next = task->next(blocks.begin(), blocks.end());
51 if (next == blocks.end())
break;
53 auto Ia = A.at(next->alpha);
54 auto Ib = B.at(next->beta);
55 if (!ci.test(Ia,Ib))
continue;
59 for (
int a = 0; a < Ia.size(); ++a) {
60 aa(a) = diagonal(alpha[*Ia.begin() + a], h, V);
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;
77 if (ci.config.ms != 0) {
78 throw MPQC_EXCEPTION(
"Preconditioner not yet implemented for ci.ms != 0");
82 double scale = 1.0/sqrt(dd);
84 task.reset(
new MPI::Task(comm));
88 auto next = task->next(blocks.begin(), blocks.end());
89 if (next == blocks.end())
break;
91 auto Ia = A.at(next->alpha);
92 auto Ib = B.at(next->beta);
93 if (!ci.test(Ia,Ib))
continue;
95 if (next->alpha == next->beta) {
97 ci::symmetrize(aa, phase, scale);
101 if (next->alpha < next->beta) {
105 ba = phase*(ab.transpose());