4
// Copyright (C) 2004 Edward Valeev
6
// Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
9
// This file is part of the SC Toolkit.
11
// The SC Toolkit is free software; you can redistribute it and/or modify
12
// it under the terms of the GNU Library General Public License as published by
13
// the Free Software Foundation; either version 2, or (at your option)
16
// The SC Toolkit is distributed in the hope that it will be useful,
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
// GNU Library General Public License for more details.
21
// You should have received a copy of the GNU Library General Public License
22
// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23
// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25
// The U.S. Government is granted a limited license as per AL 91-7.
29
#pragma implementation
32
#include <util/misc/formio.h>
33
#include <util/ref/ref.h>
34
#include <util/state/state_bin.h>
35
#include <math/scmat/local.h>
36
#include <chemistry/qc/mbptr12/vxb_eval_info.h>
37
#include <chemistry/qc/mbptr12/pairiter.h>
38
#include <chemistry/qc/mbptr12/r12int_eval.h>
44
#define NOT_INCLUDE_DIAGONAL_VXB_CONTIBUTIONS 0
46
inline int max(int a,int b) { return (a > b) ? a : b;}
51
static ClassDesc R12IntEval_cd(
52
typeid(R12IntEval),"R12IntEval",1,"virtual public SavableState",
55
R12IntEval::R12IntEval(const Ref<R12IntEvalInfo>& r12info, bool gbc, bool ebc,
56
LinearR12::ABSMethod abs_method,
57
LinearR12::StandardApproximation stdapprox, bool follow_ks_ebcfree) :
58
r12info_(r12info), gbc_(gbc), ebc_(ebc), abs_method_(abs_method),
59
stdapprox_(stdapprox), spinadapted_(false), include_mp1_(false),
60
follow_ks_ebcfree_(follow_ks_ebcfree), debug_(0), evaluated_(false)
62
int nocc_act = r12info_->nocc_act();
63
int nvir_act = r12info_->nvir_act();
64
dim_ij_aa_ = new SCDimension((nocc_act*(nocc_act-1))/2);
65
dim_ij_ab_ = new SCDimension(nocc_act*nocc_act);
66
dim_ij_s_ = new SCDimension((nocc_act*(nocc_act+1))/2);
67
dim_ij_t_ = dim_ij_aa_;
68
dim_ab_aa_ = new SCDimension((nvir_act*(nvir_act-1))/2);
69
dim_ab_ab_ = new SCDimension(nvir_act*nvir_act);
71
Ref<LocalSCMatrixKit> local_matrix_kit = new LocalSCMatrixKit();
72
Vaa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ij_aa_);
73
Vab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ij_ab_);
74
Xaa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ij_aa_);
75
Xab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ij_ab_);
76
Baa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ij_aa_);
77
Bab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ij_ab_);
79
Aaa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
80
Aab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
81
if (follow_ks_ebcfree_) {
82
Ac_aa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
83
Ac_ab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
85
T2aa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
86
T2ab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
87
Raa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
88
Rab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
90
emp2pair_aa_ = local_matrix_kit->vector(dim_ij_aa_);
91
emp2pair_ab_ = local_matrix_kit->vector(dim_ij_ab_);
97
R12IntEval::R12IntEval(StateIn& si) : SavableState(si)
99
int gbc; si.get(gbc); gbc_ = (bool) gbc;
100
int ebc; si.get(ebc); ebc_ = (bool) ebc;
101
int absmethod; si.get(absmethod); abs_method_ = (LinearR12::ABSMethod) absmethod;
102
int stdapprox; si.get(stdapprox); stdapprox_ = (LinearR12::StandardApproximation) stdapprox;
103
int follow_ks_ebcfree; si.get(follow_ks_ebcfree); follow_ks_ebcfree_ = static_cast<bool>(follow_ks_ebcfree);
105
r12info_ << SavableState::restore_state(si);
106
dim_ij_aa_ << SavableState::restore_state(si);
107
dim_ij_ab_ << SavableState::restore_state(si);
108
dim_ij_s_ << SavableState::restore_state(si);
109
dim_ij_t_ << SavableState::restore_state(si);
110
dim_ab_aa_ << SavableState::restore_state(si);
111
dim_ab_ab_ << SavableState::restore_state(si);
113
Ref<LocalSCMatrixKit> local_matrix_kit = new LocalSCMatrixKit();
114
Vaa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ij_aa_);
115
Vab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ij_ab_);
116
Xaa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ij_aa_);
117
Xab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ij_ab_);
118
Baa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ij_aa_);
119
Bab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ij_ab_);
121
Aaa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
122
Aab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
123
if (follow_ks_ebcfree_) {
124
Ac_aa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
125
Ac_ab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
127
T2aa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
128
T2ab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
129
Raa_ = local_matrix_kit->matrix(dim_ij_aa_,dim_ab_aa_);
130
Rab_ = local_matrix_kit->matrix(dim_ij_ab_,dim_ab_ab_);
132
emp2pair_aa_ = local_matrix_kit->vector(dim_ij_aa_);
133
emp2pair_ab_ = local_matrix_kit->vector(dim_ij_ab_);
151
emp2pair_aa_.restore(si);
152
emp2pair_ab_.restore(si);
156
for(int t=0; t<num_tforms; t++) {
157
std::string tform_name;
159
Ref<TwoBodyMOIntsTransform> tform;
160
tform << SavableState::restore_state(si);
161
tform_map_[tform_name] = tform;
164
int spinadapted; si.get(spinadapted); spinadapted_ = (bool) spinadapted;
165
int evaluated; si.get(evaluated); evaluated_ = (bool) evaluated;
171
R12IntEval::~R12IntEval()
183
R12IntEval::save_data_state(StateOut& so)
187
so.put((int)abs_method_);
188
so.put((int)stdapprox_);
189
so.put((int)follow_ks_ebcfree_);
191
SavableState::save_state(r12info_.pointer(),so);
192
SavableState::save_state(dim_ij_aa_.pointer(),so);
193
SavableState::save_state(dim_ij_ab_.pointer(),so);
194
SavableState::save_state(dim_ij_s_.pointer(),so);
195
SavableState::save_state(dim_ij_t_.pointer(),so);
196
SavableState::save_state(dim_ab_aa_.pointer(),so);
197
SavableState::save_state(dim_ab_ab_.pointer(),so);
215
emp2pair_aa_.save(so);
216
emp2pair_ab_.save(so);
218
int num_tforms = tform_map_.size();
220
TformMap::iterator first_tform = tform_map_.begin();
221
TformMap::iterator last_tform = tform_map_.end();
222
for(TformMap::iterator t=first_tform; t!=last_tform; t++) {
224
SavableState::save_state((*t).second.pointer(),so);
227
so.put((int)spinadapted_);
228
so.put((int)evaluated_);
233
R12IntEval::obsolete()
237
// make all transforms obsolete
238
TformMap::iterator first_tform = tform_map_.begin();
239
TformMap::iterator last_tform = tform_map_.end();
240
for(TformMap::iterator t=first_tform; t!=last_tform; t++) {
241
(*t).second->obsolete();
247
void R12IntEval::include_mp1(bool include_mp1) { include_mp1_ = include_mp1; };
248
void R12IntEval::set_debug(int debug) { if (debug >= 0) { debug_ = debug; r12info_->set_debug_level(debug_); }};
249
void R12IntEval::set_dynamic(bool dynamic) { r12info_->set_dynamic(dynamic); };
250
void R12IntEval::set_print_percent(double pp) { r12info_->set_print_percent(pp); };
251
void R12IntEval::set_memory(size_t nbytes) { r12info_->set_memory(nbytes); };
253
Ref<R12IntEvalInfo> R12IntEval::r12info() const { return r12info_; };
254
RefSCDimension R12IntEval::dim_oo_aa() const { return dim_ij_aa_; };
255
RefSCDimension R12IntEval::dim_oo_ab() const { return dim_ij_ab_; };
256
RefSCDimension R12IntEval::dim_oo_s() const { return dim_ij_s_; };
257
RefSCDimension R12IntEval::dim_oo_t() const { return dim_ij_t_; };
258
RefSCDimension R12IntEval::dim_vv_aa() const { return dim_ab_aa_; };
259
RefSCDimension R12IntEval::dim_vv_ab() const { return dim_ab_ab_; };
261
RefSCMatrix R12IntEval::V_aa()
267
RefSCMatrix R12IntEval::X_aa()
273
RefSymmSCMatrix R12IntEval::B_aa()
277
// Extract lower triangle of the matrix
278
Ref<SCMatrixKit> kit = Baa_.kit();
279
RefSymmSCMatrix Baa = kit->symmmatrix(Baa_.rowdim());
280
int naa = Baa_.nrow();
281
double* baa = new double[naa*naa];
283
const double* baa_ptr = baa;
284
for(int i=0; i<naa; i++, baa_ptr += i)
285
for(int j=i; j<naa; j++, baa_ptr++)
286
Baa.set_element(i,j,*baa_ptr);
292
RefSCMatrix R12IntEval::A_aa()
299
RefSCMatrix R12IntEval::Ac_aa()
301
if (ebc_ == false && follow_ks_ebcfree_) {
306
throw ProgrammingError("R12IntEval::Ac_aa() called although the object initialized with follow_ks_ebcfree set to false",__FILE__,__LINE__);
309
RefSCMatrix R12IntEval::T2_aa()
316
RefSCMatrix R12IntEval::V_ab()
322
RefSCMatrix R12IntEval::X_ab()
328
RefSymmSCMatrix R12IntEval::B_ab()
332
// Extract lower triangle of the matrix
333
Ref<SCMatrixKit> kit = Bab_.kit();
334
RefSymmSCMatrix Bab = kit->symmmatrix(Bab_.rowdim());
335
int nab = Bab_.nrow();
336
double* bab = new double[nab*nab];
338
const double* bab_ptr = bab;
339
for(int i=0; i<nab; i++, bab_ptr += i)
340
for(int j=i; j<nab; j++, bab_ptr++)
341
Bab.set_element(i,j,*bab_ptr);
347
RefSCMatrix R12IntEval::A_ab()
354
RefSCMatrix R12IntEval::Ac_ab()
356
if (ebc_ == false && follow_ks_ebcfree_) {
361
throw ProgrammingError("R12IntEval::Ac_ab() called although the object initialized with follow_ks_ebcfree set to false",__FILE__,__LINE__);
364
RefSCMatrix R12IntEval::T2_ab()
371
RefSCVector R12IntEval::emp2_aa()
377
RefSCVector R12IntEval::emp2_ab()
383
RefDiagSCMatrix R12IntEval::evals() const { return r12info_->obs_space()->evals(); };
386
R12IntEval::checkpoint_() const
388
int me = r12info_->msg()->me();
389
Wavefunction* wfn = r12info_->wfn();
391
if (me == 0 && wfn->if_to_checkpoint()) {
392
StateOutBin stateout(wfn->checkpoint_file());
393
SavableState::save_state(wfn,stateout);
394
ExEnv::out0() << indent << "Checkpointed the wave function" << endl;
399
R12IntEval::init_tforms_()
401
Ref<MOIntsTransformFactory> tfactory = r12info_->tfactory();
402
tfactory->set_ints_method((MOIntsTransformFactory::StoreMethod)r12info_->ints_method());
404
const std::string ipjq_name = "(ip|jq)";
405
Ref<TwoBodyMOIntsTransform> ipjq_tform = tform_map_[ipjq_name];
406
if (ipjq_tform.null()) {
407
tfactory->set_spaces(r12info_->act_occ_space(),r12info_->obs_space(),
408
r12info_->act_occ_space(),r12info_->obs_space());
409
ipjq_tform = tfactory->twobody_transform_13(ipjq_name);
410
tform_map_[ipjq_name] = ipjq_tform;
411
tform_map_[ipjq_name]->set_num_te_types(3);
414
const std::string iajb_name = "(ia|jb)";
415
Ref<TwoBodyMOIntsTransform> iajb_tform = tform_map_[iajb_name];
416
if (iajb_tform.null()) {
417
tfactory->set_spaces(r12info_->act_occ_space(),r12info_->act_vir_space(),
418
r12info_->act_occ_space(),r12info_->act_vir_space());
419
iajb_tform = tfactory->twobody_transform_13(iajb_name);
420
tform_map_[iajb_name] = iajb_tform;
421
tform_map_[iajb_name]->set_num_te_types(3);
424
const std::string imja_name = "(im|ja)";
425
Ref<TwoBodyMOIntsTransform> imja_tform = tform_map_[imja_name];
426
if (imja_tform.null()) {
427
tfactory->set_spaces(r12info_->act_occ_space(),r12info_->occ_space(),
428
r12info_->act_occ_space(),r12info_->act_vir_space());
429
imja_tform = tfactory->twobody_transform_13(imja_name);
430
tform_map_[imja_name] = imja_tform;
431
tform_map_[imja_name]->set_num_te_types(4);
434
const std::string imjn_name = "(im|jn)";
435
Ref<TwoBodyMOIntsTransform> imjn_tform = tform_map_[imjn_name];
436
if (imjn_tform.null()) {
437
tfactory->set_spaces(r12info_->act_occ_space(),r12info_->occ_space(),
438
r12info_->act_occ_space(),r12info_->occ_space());
439
imjn_tform = tfactory->twobody_transform_13(imjn_name);
440
tform_map_[imjn_name] = imjn_tform;
441
tform_map_[imjn_name]->set_num_te_types(3);
444
const std::string imjy_name = "(im|jy)";
445
Ref<TwoBodyMOIntsTransform> imjy_tform = tform_map_[imjy_name];
446
if (imjy_tform.null()) {
447
tfactory->set_spaces(r12info_->act_occ_space(),r12info_->occ_space(),
448
r12info_->act_occ_space(),r12info_->ribs_space());
449
imjy_tform = tfactory->twobody_transform_13(imjy_name);
450
tform_map_[imjy_name] = imjy_tform;
451
tform_map_[imjy_name]->set_num_te_types(4);
454
iajb_tform = tform_map_[iajb_name];
455
imjn_tform = tform_map_[imjn_name];
456
ipjq_tform = tform_map_[ipjq_name];
459
Ref<TwoBodyMOIntsTransform>
460
R12IntEval::get_tform_(const std::string& tform_name)
462
TformMap::const_iterator tform_iter = tform_map_.find(tform_name);
463
TwoBodyMOIntsTransform* tform = (*tform_iter).second.pointer();
465
std::string errmsg = "R12IntEval::get_tform_() -- transform " + tform_name + " is not known";
466
throw std::runtime_error(errmsg.c_str());
474
R12IntEval::init_intermeds_()
476
if (r12info_->msg()->me() == 0) {
477
#if NOT_INCLUDE_DIAGONAL_VXB_CONTIBUTIONS
498
if (follow_ks_ebcfree_) {
510
//r2_contrib_to_X_orig_();
511
#if !NOT_INCLUDE_DIAGONAL_VXB_CONTIBUTIONS
512
r2_contrib_to_X_new_();
515
emp2pair_aa_.assign(0.0);
516
emp2pair_ab_.assign(0.0);
519
/// Compute <space1 space1|r_{12}^2|space1 space2>
521
R12IntEval::compute_r2_(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2)
523
/*-----------------------------------------------------
524
Compute overlap, dipole, quadrupole moment integrals
525
-----------------------------------------------------*/
526
RefSCMatrix S_11, MX_11, MY_11, MZ_11, MXX_11, MYY_11, MZZ_11;
527
r12info_->compute_multipole_ints(space1, space1, MX_11, MY_11, MZ_11, MXX_11, MYY_11, MZZ_11);
528
r12info_->compute_overlap_ints(space1, space1, S_11);
530
RefSCMatrix S_12, MX_12, MY_12, MZ_12, MXX_12, MYY_12, MZZ_12;
531
if (space1 == space2) {
541
r12info_->compute_multipole_ints(space1, space2, MX_12, MY_12, MZ_12, MXX_12, MYY_12, MZZ_12);
542
r12info_->compute_overlap_ints(space1, space2, S_12);
545
ExEnv::out0() << indent << "Computed overlap and multipole moment integrals" << endl;
547
const int nproc = r12info_->msg()->n();
548
const int me = r12info_->msg()->me();
550
const int n1 = space1->rank();
551
const int n2 = space2->rank();
552
const int n12 = n1*n2;
553
const int n1112 = n1*n1*n12;
554
double* r2_array = new double[n1112];
555
memset(r2_array,0,n1112*sizeof(double));
558
double* ijkl_ptr = r2_array;
559
for(int i=0; i<n1; i++)
560
for(int j=0; j<n1; j++, ij++) {
562
int ij_proc = ij%nproc;
569
for(int k=0; k<n1; k++)
570
for(int l=0; l<n2; l++, kl++, ijkl_ptr++) {
572
double r1r1_ik = -1.0*(MXX_11->get_element(i,k) + MYY_11->get_element(i,k) + MZZ_11->get_element(i,k));
573
double r1r1_jl = -1.0*(MXX_12->get_element(j,l) + MYY_12->get_element(j,l) + MZZ_12->get_element(j,l));
574
double r1r2_ijkl = MX_11->get_element(i,k)*MX_12->get_element(j,l) +
575
MY_11->get_element(i,k)*MY_12->get_element(j,l) +
576
MZ_11->get_element(i,k)*MZ_12->get_element(j,l);
577
double S_ik = S_11.get_element(i,k);
578
double S_jl = S_12.get_element(j,l);
580
double R2_ijkl = r1r1_ik * S_jl + r1r1_jl * S_ik - 2.0*r1r2_ijkl;
585
r12info_->msg()->sum(r2_array,n1112);
587
MOPairIterFactory pair_factory;
588
RefSCDimension dim_ij = pair_factory.scdim_ab(space1,space1);
589
RefSCDimension dim_kl = pair_factory.scdim_ab(space1,space2);
591
Ref<LocalSCMatrixKit> local_matrix_kit = new LocalSCMatrixKit();
592
RefSCMatrix R2 = local_matrix_kit->matrix(dim_ij, dim_kl);
601
R12IntEval::r2_contrib_to_X_orig_()
603
/*---------------------------------------------------------------
604
Compute dipole and quadrupole moment integrals in act MO basis
605
---------------------------------------------------------------*/
606
RefSCMatrix MX, MY, MZ, MXX, MYY, MZZ;
607
r12info_->compute_multipole_ints(r12info_->act_occ_space(),r12info_->act_occ_space(),MX,MY,MZ,MXX,MYY,MZZ);
609
ExEnv::out0() << indent << "Computed multipole moment integrals" << endl;
611
const int nproc = r12info_->msg()->n();
612
const int me = r12info_->msg()->me();
614
SpatialMOPairIter_eq ij_iter(r12info_->act_occ_space());
615
SpatialMOPairIter_eq kl_iter(r12info_->act_occ_space());
617
for(kl_iter.start();int(kl_iter);kl_iter.next()) {
619
const int kl = kl_iter.ij();
620
int kl_proc = kl%nproc;
623
const int k = kl_iter.i();
624
const int l = kl_iter.j();
625
const int kl_aa = kl_iter.ij_aa();
626
const int kl_ab = kl_iter.ij_ab();
627
const int lk_ab = kl_iter.ij_ba();
629
for(ij_iter.start();int(ij_iter);ij_iter.next()) {
631
const int i = ij_iter.i();
632
const int j = ij_iter.j();
633
const int ij_aa = ij_iter.ij_aa();
634
const int ij_ab = ij_iter.ij_ab();
635
const int ji_ab = ij_iter.ij_ba();
637
/*----------------------------------
638
Compute (r12)^2 contribution to X
639
----------------------------------*/
640
double r1r1_ik = -1.0*(MXX->get_element(i,k) + MYY->get_element(i,k) + MZZ->get_element(i,k));
641
double r1r1_il = -1.0*(MXX->get_element(i,l) + MYY->get_element(i,l) + MZZ->get_element(i,l));
642
double r1r1_jk = -1.0*(MXX->get_element(j,k) + MYY->get_element(j,k) + MZZ->get_element(j,k));
643
double r1r1_jl = -1.0*(MXX->get_element(j,l) + MYY->get_element(j,l) + MZZ->get_element(j,l));
644
double r1r2_ijkl = MX->get_element(i,k)*MX->get_element(j,l) +
645
MY->get_element(i,k)*MY->get_element(j,l) +
646
MZ->get_element(i,k)*MZ->get_element(j,l);
647
double r1r2_ijlk = MX->get_element(i,l)*MX->get_element(j,k) +
648
MY->get_element(i,l)*MY->get_element(j,k) +
649
MZ->get_element(i,l)*MZ->get_element(j,k);
650
double delta_ik = (i==k ? 1.0 : 0.0);
651
double delta_il = (i==l ? 1.0 : 0.0);
652
double delta_jk = (j==k ? 1.0 : 0.0);
653
double delta_jl = (j==l ? 1.0 : 0.0);
655
double Xab_ijkl = r1r1_ik * delta_jl + r1r1_jl * delta_ik - 2.0*r1r2_ijkl;
656
Xab_.accumulate_element(ij_ab,kl_ab,Xab_ijkl);
658
if (ij_ab != ji_ab) {
659
double Xab_jikl = r1r1_jk * delta_il + r1r1_il * delta_jk - 2.0*r1r2_ijlk;
660
Xab_.accumulate_element(ji_ab,kl_ab,Xab_jikl);
663
if (kl_ab != lk_ab) {
664
double Xab_ijlk = r1r1_il * delta_jk + r1r1_jk * delta_il - 2.0*r1r2_ijlk;
665
Xab_.accumulate_element(ij_ab,lk_ab,Xab_ijlk);
668
if (ij_ab != ji_ab && kl_ab != lk_ab) {
669
double Xab_jilk = r1r1_ik * delta_jl + r1r1_jl * delta_ik - 2.0*r1r2_ijkl;
670
Xab_.accumulate_element(ji_ab,lk_ab,Xab_jilk);
673
if (ij_aa != -1 && kl_aa != -1) {
674
double Xaa_ijkl = r1r1_ik * delta_jl + r1r1_jl * delta_ik - 2.0*r1r2_ijkl -
675
r1r1_jk * delta_il - r1r1_il * delta_jk + 2.0*r1r2_ijlk;
676
Xaa_.accumulate_element(ij_aa,kl_aa,Xaa_ijkl);
684
R12IntEval::r2_contrib_to_X_new_()
686
unsigned int me = r12info_->msg()->me();
688
// compute r_{12}^2 operator in act.occ.pair/act.occ.pair basis
689
RefSCMatrix R2 = compute_r2_(r12info_->act_occ_space(),r12info_->act_occ_space());
695
SpatialMOPairIter_eq ij_iter(r12info_->act_occ_space());
696
SpatialMOPairIter_eq kl_iter(r12info_->act_occ_space());
698
for(kl_iter.start();int(kl_iter);kl_iter.next()) {
700
const int kl_aa = kl_iter.ij_aa();
703
const int kl_ab = kl_iter.ij_ab();
705
for(ij_iter.start();int(ij_iter);ij_iter.next()) {
707
const int ij_aa = ij_iter.ij_aa();
708
const int ij_ab = ij_iter.ij_ab();
709
const int ji_ab = ij_iter.ij_ba();
712
double Xaa_ijkl = R2.get_element(ij_ab,kl_ab) - R2.get_element(ji_ab,kl_ab);
713
Xaa_.accumulate_element(ij_aa,kl_aa,Xaa_ijkl);
721
R12IntEval::form_focc_space_()
723
// compute the Fock matrix between the complement and all occupieds and
724
// create the new Fock-weighted space
725
if (focc_space_.null()) {
726
Ref<MOIndexSpace> occ_space = r12info_->occ_space();
727
Ref<MOIndexSpace> ribs_space = r12info_->ribs_space();
729
RefSCMatrix F_ri_o = fock_(occ_space,ribs_space,occ_space);
731
F_ri_o.print("Fock matrix (RI-BS/occ.)");
732
focc_space_ = new MOIndexSpace("Fock-weighted occupied MOs sorted by energy",
733
occ_space, ribs_space->coefs()*F_ri_o, ribs_space->basis());
738
R12IntEval::form_factocc_space_()
740
// compute the Fock matrix between the complement and active occupieds and
741
// create the new Fock-weighted space
742
if (factocc_space_.null()) {
743
Ref<MOIndexSpace> occ_space = r12info_->occ_space();
744
Ref<MOIndexSpace> act_occ_space = r12info_->act_occ_space();
745
Ref<MOIndexSpace> ribs_space = r12info_->ribs_space();
747
RefSCMatrix F_ri_ao = fock_(occ_space,ribs_space,act_occ_space);
749
F_ri_ao.print("Fock matrix (RI-BS/act.occ.)");
750
factocc_space_ = new MOIndexSpace("Fock-weighted active occupied MOs sorted by energy",
751
act_occ_space, ribs_space->coefs()*F_ri_ao, ribs_space->basis());
756
R12IntEval::form_canonvir_space_()
758
// Create a complement space to all occupieds
759
// Fock operator is diagonal in this space
760
if (canonvir_space_.null()) {
762
if (r12info_->basis_vir()->equiv(r12info_->basis())) {
763
canonvir_space_ = r12info_->vir_space();
767
const Ref<MOIndexSpace> mo_space = r12info_->mo_space();
768
Ref<MOIndexSpace> vir_space = r12info_->vir_space_symblk();
769
RefSCMatrix F_vir = fock_(r12info_->occ_space(),vir_space,vir_space);
771
int nrow = vir_space->rank();
772
double* F_full = new double[nrow*nrow];
773
double* F_lowtri = new double [nrow*(nrow+1)/2];
774
F_vir->convert(F_full);
776
for(int row=0; row<nrow; row++) {
778
for(int col=0; col<=row; col++, rc++, ij++) {
779
F_lowtri[ij] = F_full[rc];
782
RefSymmSCMatrix F_vir_lt(F_vir.rowdim(),F_vir->kit());
783
F_vir_lt->assign(F_lowtri);
788
Ref<MOIndexSpace> canonvir_space_symblk = new MOIndexSpace("Virt. MOs symmetry-blocked",
789
vir_space, vir_space->coefs()*F_vir_lt.eigvecs(),
791
RefDiagSCMatrix F_vir_evals = F_vir_lt.eigvals();
792
canonvir_space_ = new MOIndexSpace("Virt. MOs sorted by energy",
793
canonvir_space_symblk->coefs(),
794
canonvir_space_symblk->basis(),
795
canonvir_space_symblk->integral(),
797
MOIndexSpace::energy);
802
R12IntEval::tasks_with_ints_(const Ref<R12IntsAcc> ints_acc, vector<int>& map_to_twi)
804
int nproc = r12info_->msg()->n();
806
// Compute the number of tasks that have full access to the integrals
807
// and split the work among them
808
int nproc_with_ints = 0;
809
for(int proc=0;proc<nproc;proc++)
810
if (ints_acc->has_access(proc)) nproc_with_ints++;
812
map_to_twi.resize(nproc);
814
for(int proc=0;proc<nproc;proc++)
815
if (ints_acc->has_access(proc)) {
816
map_to_twi[proc] = count;
820
map_to_twi[proc] = -1;
822
ExEnv::out0() << indent << "Computing intermediates on " << nproc_with_ints
823
<< " processors" << endl;
825
return nproc_with_ints;
830
R12IntEval::compute()
835
if (r12info_->basis_vir()->equiv(r12info_->basis())) {
836
obs_contrib_to_VXB_gebc_vbseqobs_();
838
Vaa_.print("Alpha-alpha V(OBS) contribution");
839
Vab_.print("Alpha-beta V(OBS) contribution");
840
Xaa_.print("Alpha-alpha X(OBS) contribution");
841
Xab_.print("Alpha-beta X(OBS) contribution");
842
Baa_.print("Alpha-alpha B(OBS) contribution");
843
Bab_.print("Alpha-beta B(OBS) contribution");
845
if (r12info_->basis() != r12info_->basis_ri())
846
abs1_contrib_to_VXB_gebc_();
848
Vaa_.print("Alpha-alpha V(OBS+ABS) contribution");
849
Vab_.print("Alpha-beta V(OBS+ABS) contribution");
850
Xaa_.print("Alpha-alpha X(OBS+ABS) contribution");
851
Xab_.print("Alpha-beta X(OBS+ABS) contribution");
852
Baa_.print("Alpha-alpha B(OBS+ABS) contribution");
853
Bab_.print("Alpha-beta B(OBS+ABS) contribution");
857
contrib_to_VXB_gebc_vbsneqobs_();
866
RefSCMatrix F = fock_(r12info_->occ_space(),r12info_->obs_space(),r12info_->obs_space());
867
F.print("Fock matrix in OBS");
868
r12info_->obs_space()->evals().print("OBS eigenvalues");
870
r12info_->ribs_space()->coefs().print("Orthonormal RI-BS");
872
r12info_->compute_overlap_ints(r12info_->ribs_space(),r12info_->ribs_space(),S_ri);
873
S_ri.print("Overlap in RI-BS");
874
RefSCMatrix F_ri = fock_(r12info_->occ_space(),r12info_->ribs_space(),r12info_->ribs_space());
875
F_ri.print("Fock matrix in RI-BS");
876
RefSymmSCMatrix F_ri_symm = F_ri.kit()->symmmatrix(F_ri.rowdim());
877
int nrow = F_ri.rowdim().n();
878
for(int r=0; r<nrow; r++)
879
for(int c=0; c<nrow; c++)
880
F_ri_symm.set_element(r,c,F_ri.get_element(r,c));
881
F_ri_symm.eigvals().print("Eigenvalues of the Fock matrix (RI-BS)");
883
RefSCMatrix F_obs_ri = fock_(r12info_->occ_space(),r12info_->obs_space(),r12info_->ribs_space());
884
F_obs_ri.print("Fock matrix in OBS/RI-BS");
889
// These functions assume that virtuals are expanded in the same basis
890
// as the occupied orbitals
891
if (!r12info_->basis_vir()->equiv(r12info_->basis()))
892
throw std::runtime_error("R12IntEval::compute() -- ebc=false is only supported when basis_vir == basis");
897
if (follow_ks_ebcfree_) {
898
compute_A_via_commutator_();
909
// These functions assume that virtuals are expanded in the same basis
910
// as the occupied orbitals
911
if (!r12info_->basis_vir()->equiv(r12info_->basis()))
912
throw std::runtime_error("R12IntEval::compute() -- gbc=false is only supported when basis_vir == basis");
916
Baa_.print("Alpha-alpha B(OBS+ABS+GBC1) contribution");
917
Bab_.print("Alpha-beta B(OBS+ABS+GBC1) contribution");
921
Baa_.print("Alpha-alpha B(OBS+ABS+GBC1+GBC2) contribution");
922
Bab_.print("Alpha-beta B(OBS+ABS+GBC1+GBC2) contribution");
926
// Distribute the final intermediates to every node
927
globally_sum_intermeds_(true);
933
R12IntEval::globally_sum_scmatrix_(RefSCMatrix& A, bool to_all_tasks, bool to_average)
935
Ref<MessageGrp> msg = r12info_->msg();
936
unsigned int ntasks = msg->n();
937
// If there's only one task then there's nothing to do
941
const int nelem = A.ncol() * A.nrow();
942
double *A_array = new double[nelem];
945
msg->sum(A_array,nelem,0,-1);
947
msg->sum(A_array,nelem,0,0);
950
A.scale(1.0/(double)ntasks);
951
if (!to_all_tasks && msg->me() != 0)
958
R12IntEval::globally_sum_scvector_(RefSCVector& A, bool to_all_tasks, bool to_average)
960
Ref<MessageGrp> msg = r12info_->msg();
961
unsigned int ntasks = msg->n();
962
// If there's only one task then there's nothing to do
966
const int nelem = A.dim().n();
967
double *A_array = new double[nelem];
970
msg->sum(A_array,nelem,0,-1);
972
msg->sum(A_array,nelem,0,0);
975
A.scale(1.0/(double)ntasks);
976
if (!to_all_tasks && msg->me() != 0)
983
R12IntEval::globally_sum_intermeds_(bool to_all_tasks)
985
globally_sum_scmatrix_(Vaa_,to_all_tasks);
986
globally_sum_scmatrix_(Vab_,to_all_tasks);
988
globally_sum_scmatrix_(Xaa_,to_all_tasks);
989
globally_sum_scmatrix_(Xab_,to_all_tasks);
991
globally_sum_scmatrix_(Baa_,to_all_tasks);
992
globally_sum_scmatrix_(Bab_,to_all_tasks);
995
globally_sum_scmatrix_(Aaa_,to_all_tasks);
996
globally_sum_scmatrix_(Aab_,to_all_tasks);
998
if (follow_ks_ebcfree_) {
999
globally_sum_scmatrix_(Ac_aa_,to_all_tasks);
1000
globally_sum_scmatrix_(Ac_ab_,to_all_tasks);
1003
globally_sum_scmatrix_(T2aa_,to_all_tasks);
1004
globally_sum_scmatrix_(T2ab_,to_all_tasks);
1006
globally_sum_scmatrix_(Raa_,to_all_tasks);
1007
globally_sum_scmatrix_(Rab_,to_all_tasks);
1010
globally_sum_scvector_(emp2pair_aa_,to_all_tasks);
1011
globally_sum_scvector_(emp2pair_ab_,to_all_tasks);
1014
ExEnv::out0() << indent << "Collected contributions to the intermediates from all tasks";
1016
ExEnv::out0() << " and distributed to every task" << endl;
1018
ExEnv::out0() << " on task 0" << endl;
1022
/////////////////////////////////////////////////////////////////////////////
1026
// c-file-style: "CLJ-CONDENSED"