1
#include <libmoinfo/libmoinfo.h>
2
#include <liboptions/liboptions.h>
7
#include <libutil/libutil.h>
9
#include <libchkpt/chkpt.h>
13
namespace psi{ namespace psimrcc{
17
bool CCMRCC::build_diagonalize_Heff(int cycle, double time)
20
bool converged = false;
22
build_Heff_diagonal();
23
build_Heff_offdiagonal();
26
current_energy=diagonalize_Heff(moinfo->get_root(),moinfo->get_nrefs(),Heff,eigenvector,true);
27
old_energy=current_energy;
28
print_eigensystem(moinfo->get_nrefs(),Heff,eigenvector);
30
if((cycle>0) || (cycle==-1)){
31
// Compute the energy difference
32
old_energy=current_energy;
33
current_energy=diagonalize_Heff(moinfo->get_root(),moinfo->get_nrefs(),Heff,eigenvector,false);
35
if(options_get_bool("PRINT_HEFF"))
36
print_eigensystem(moinfo->get_nrefs(),Heff,eigenvector);
38
print_eigensystem(moinfo->get_nrefs(),Heff,eigenvector);
40
double delta_energy = current_energy-old_energy;
41
if(fabs(log10(fabs(delta_energy))) > options_get_int("CONVERGENCE"))
45
/// TODO fix this code which is temporarly not working
46
// if(options_get_int("DAMPING_FACTOR")>0){
47
// if(fabs(delta_energy) < moinfo->get_no_damp_convergence()){
48
// double damping_factor = moinfo->get_damping_factor();
49
// damping_factor *= 0.95;
50
// fprintf(outfile,"\n\t# Scaling damp factor to zero, damping_factor = %lf",moinfo->get_damping_factor());
51
// moinfo->set_damping_factor(damping_factor);
55
print_mrccsd_energy(cycle);
57
print_eigensystem(moinfo->get_nrefs(),Heff,eigenvector);
58
chkpt_wt_etot(current_energy);
63
void CCMRCC::build_Heff_diagonal()
65
// Compute the diagonal elements of the effective Hamiltonian
66
// using a simple UCCSD energy expression
67
blas->solve("Eaa{u} = t1[o][v]{u} . fock[o][v]{u}");
68
blas->solve("Ebb{u} = t1[O][V]{u} . fock[O][V]{u}");
70
blas->solve("Eaaaa{u} = 1/4 tau[oo][vv]{u} . <[oo]:[vv]>");
71
blas->solve("Eabab{u} = tau[oO][vV]{u} . <[oo]|[vv]>");
72
blas->solve("Ebbbb{u} = 1/4 tau[OO][VV]{u} . <[oo]:[vv]>");
74
blas->solve("ECCSD{u} = Eaa{u} + Ebb{u} + Eaaaa{u} + Eabab{u} + Ebbbb{u} + ERef{u}");
76
for(int n=0;n<moinfo->get_nrefs();n++)
77
Heff[n][n]=blas->get_scalar("ECCSD",moinfo->get_ref_number("a",n));
80
void CCMRCC::build_Heff_offdiagonal()
82
for(int i=0;i<moinfo->get_ref_size("a");i++){
83
int i_unique = moinfo->get_ref_number("a",i);
84
// Find the off_diagonal elements for reference i
85
// Loop over reference j (in a safe way)
86
for(int j=0;j<moinfo->get_ref_size("a");j++){
88
vector<pair<int,int> > alpha_internal_excitation = moinfo->get_alpha_internal_excitation(i,j);
89
vector<pair<int,int> > beta_internal_excitation = moinfo->get_beta_internal_excitation(i,j);
90
double sign_internal_excitation = moinfo->get_sign_internal_excitation(i,j);
94
// Set alpha-alpha single excitations
95
if((alpha_internal_excitation.size()==1)&&(beta_internal_excitation.size()==0))
96
element=sign_internal_excitation * blas->get_MatTmp("t1_eqns[o][v]",i_unique,none)->get_two_address_element(
97
alpha_internal_excitation[0].first,
98
alpha_internal_excitation[0].second);
100
// Set beta-beta single excitations
101
if((alpha_internal_excitation.size()==0)&&(beta_internal_excitation.size()==1))
102
element=sign_internal_excitation * blas->get_MatTmp("t1_eqns[O][V]",i_unique,none)->get_two_address_element(
103
beta_internal_excitation[0].first,
104
beta_internal_excitation[0].second);
106
// Set (alpha,alpha)->(alpha,alpha) double excitations
107
if((alpha_internal_excitation.size()==2)&&(beta_internal_excitation.size()==0))
108
element=sign_internal_excitation * blas->get_MatTmp("t2_eqns[oo][vv]",i_unique,none)->get_four_address_element(
109
alpha_internal_excitation[0].first,
110
alpha_internal_excitation[1].first,
111
alpha_internal_excitation[0].second,
112
alpha_internal_excitation[1].second);
114
// Set (alpha,beta)->(alpha,beta) double excitations
115
if((alpha_internal_excitation.size()==1)&&(beta_internal_excitation.size()==1))
116
element=sign_internal_excitation * blas->get_MatTmp("t2_eqns[oO][vV]",i_unique,none)->get_four_address_element(
117
alpha_internal_excitation[0].first,
118
beta_internal_excitation[0].first,
119
alpha_internal_excitation[0].second,
120
beta_internal_excitation[0].second);
122
// Set (beta,beta)->(beta,beta) double excitations
123
if((alpha_internal_excitation.size()==0)&&(beta_internal_excitation.size()==2))
124
element=sign_internal_excitation * blas->get_MatTmp("t2_eqns[OO][VV]",i_unique,none)->get_four_address_element(
125
beta_internal_excitation[0].first,
126
beta_internal_excitation[1].first,
127
beta_internal_excitation[0].second,
128
beta_internal_excitation[1].second);
130
// Set alpha-alpha single excitations
131
if((alpha_internal_excitation.size()==1)&&(beta_internal_excitation.size()==0))
132
element=sign_internal_excitation * blas->get_MatTmp("t1_eqns[O][V]",i_unique,none)->get_two_address_element(
133
alpha_internal_excitation[0].first,
134
alpha_internal_excitation[0].second);
136
// Set beta-beta single excitations
137
if((alpha_internal_excitation.size()==0)&&(beta_internal_excitation.size()==1))
138
element=sign_internal_excitation * blas->get_MatTmp("t1_eqns[o][v]",i_unique,none)->get_two_address_element(
139
beta_internal_excitation[0].first,
140
beta_internal_excitation[0].second);
142
// Set (alpha,alpha)->(alpha,alpha) double excitations
143
if((alpha_internal_excitation.size()==2)&&(beta_internal_excitation.size()==0))
144
element=sign_internal_excitation * blas->get_MatTmp("t2_eqns[OO][VV]",i_unique,none)->get_four_address_element(
145
alpha_internal_excitation[0].first,
146
alpha_internal_excitation[1].first,
147
alpha_internal_excitation[0].second,
148
alpha_internal_excitation[1].second);
150
// Set (alpha,beta)->(alpha,beta) double excitations
151
if((alpha_internal_excitation.size()==1)&&(beta_internal_excitation.size()==1))
152
element=sign_internal_excitation * blas->get_MatTmp("t2_eqns[oO][vV]",i_unique,none)->get_four_address_element(
153
beta_internal_excitation[0].first,
154
alpha_internal_excitation[0].first,
155
beta_internal_excitation[0].second,
156
alpha_internal_excitation[0].second);
158
// Set (beta,beta)->(beta,beta) double excitations
159
if((alpha_internal_excitation.size()==0)&&(beta_internal_excitation.size()==2))
160
element=sign_internal_excitation * blas->get_MatTmp("t2_eqns[oo][vv]",i_unique,none)->get_four_address_element(
161
beta_internal_excitation[0].first,
162
beta_internal_excitation[1].first,
163
beta_internal_excitation[0].second,
164
beta_internal_excitation[1].second);
172
}} /* End Namespaces */