source: ThirdParty/mpqc_open/src/lib/chemistry/qc/mbptr12/r12int_eval.cc

Candidate_v1.6.1
Last change on this file was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 31.3 KB
Line 
1//
2// r12int_eval.cc
3//
4// Copyright (C) 2004 Edward Valeev
5//
6// Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
7// Maintainer: EV
8//
9// This file is part of the SC Toolkit.
10//
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)
14// any later version.
15//
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.
20//
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.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#ifdef __GNUG__
29#pragma implementation
30#endif
31
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>
39
40using namespace std;
41using namespace sc;
42
43#define TEST_FOCK 0
44#define NOT_INCLUDE_DIAGONAL_VXB_CONTIBUTIONS 0
45
46inline int max(int a,int b) { return (a > b) ? a : b;}
47
48/*-----------------
49 R12IntEval
50 -----------------*/
51static ClassDesc R12IntEval_cd(
52 typeid(R12IntEval),"R12IntEval",1,"virtual public SavableState",
53 0, 0, 0);
54
55R12IntEval::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)
61{
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);
70
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_);
78 if (ebc_ == false) {
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_);
84 }
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_);
89 }
90 emp2pair_aa_ = local_matrix_kit->vector(dim_ij_aa_);
91 emp2pair_ab_ = local_matrix_kit->vector(dim_ij_ab_);
92
93 init_intermeds_();
94 init_tforms_();
95}
96
97R12IntEval::R12IntEval(StateIn& si) : SavableState(si)
98{
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);
104
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);
112
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_);
120 if (ebc_ == false) {
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_);
126 }
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_);
131 }
132 emp2pair_aa_ = local_matrix_kit->vector(dim_ij_aa_);
133 emp2pair_ab_ = local_matrix_kit->vector(dim_ij_ab_);
134
135 Vaa_.restore(si);
136 Vab_.restore(si);
137 Xaa_.restore(si);
138 Xab_.restore(si);
139 Baa_.restore(si);
140 Bab_.restore(si);
141 if (ebc_ == false) {
142 Aaa_.restore(si);
143 Aab_.restore(si);
144 Ac_aa_.restore(si);
145 Ac_ab_.restore(si);
146 T2aa_.restore(si);
147 T2ab_.restore(si);
148 Raa_.restore(si);
149 Rab_.restore(si);
150 }
151 emp2pair_aa_.restore(si);
152 emp2pair_ab_.restore(si);
153
154 int num_tforms;
155 si.get(num_tforms);
156 for(int t=0; t<num_tforms; t++) {
157 std::string tform_name;
158 si.get(tform_name);
159 Ref<TwoBodyMOIntsTransform> tform;
160 tform << SavableState::restore_state(si);
161 tform_map_[tform_name] = tform;
162 }
163
164 int spinadapted; si.get(spinadapted); spinadapted_ = (bool) spinadapted;
165 int evaluated; si.get(evaluated); evaluated_ = (bool) evaluated;
166 si.get(debug_);
167
168 init_tforms_();
169}
170
171R12IntEval::~R12IntEval()
172{
173 r12info_ = 0;
174 dim_ij_aa_ = 0;
175 dim_ij_ab_ = 0;
176 dim_ij_s_ = 0;
177 dim_ij_t_ = 0;
178 dim_ab_aa_ = 0;
179 dim_ab_ab_ = 0;
180}
181
182void
183R12IntEval::save_data_state(StateOut& so)
184{
185 so.put((int)gbc_);
186 so.put((int)ebc_);
187 so.put((int)abs_method_);
188 so.put((int)stdapprox_);
189 so.put((int)follow_ks_ebcfree_);
190
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);
198
199 Vaa_.save(so);
200 Vab_.save(so);
201 Xaa_.save(so);
202 Xab_.save(so);
203 Baa_.save(so);
204 Bab_.save(so);
205 if (ebc_ == false) {
206 Aaa_.save(so);
207 Aab_.save(so);
208 Ac_aa_.save(so);
209 Ac_ab_.save(so);
210 T2aa_.save(so);
211 T2ab_.save(so);
212 Raa_.save(so);
213 Rab_.save(so);
214 }
215 emp2pair_aa_.save(so);
216 emp2pair_ab_.save(so);
217
218 int num_tforms = tform_map_.size();
219 so.put(num_tforms);
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++) {
223 so.put((*t).first);
224 SavableState::save_state((*t).second.pointer(),so);
225 }
226
227 so.put((int)spinadapted_);
228 so.put((int)evaluated_);
229 so.put(debug_);
230}
231
232void
233R12IntEval::obsolete()
234{
235 evaluated_ = false;
236
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();
242 }
243
244 init_intermeds_();
245}
246
247void R12IntEval::include_mp1(bool include_mp1) { include_mp1_ = include_mp1; };
248void R12IntEval::set_debug(int debug) { if (debug >= 0) { debug_ = debug; r12info_->set_debug_level(debug_); }};
249void R12IntEval::set_dynamic(bool dynamic) { r12info_->set_dynamic(dynamic); };
250void R12IntEval::set_print_percent(double pp) { r12info_->set_print_percent(pp); };
251void R12IntEval::set_memory(size_t nbytes) { r12info_->set_memory(nbytes); };
252
253Ref<R12IntEvalInfo> R12IntEval::r12info() const { return r12info_; };
254RefSCDimension R12IntEval::dim_oo_aa() const { return dim_ij_aa_; };
255RefSCDimension R12IntEval::dim_oo_ab() const { return dim_ij_ab_; };
256RefSCDimension R12IntEval::dim_oo_s() const { return dim_ij_s_; };
257RefSCDimension R12IntEval::dim_oo_t() const { return dim_ij_t_; };
258RefSCDimension R12IntEval::dim_vv_aa() const { return dim_ab_aa_; };
259RefSCDimension R12IntEval::dim_vv_ab() const { return dim_ab_ab_; };
260
261RefSCMatrix R12IntEval::V_aa()
262{
263 compute();
264 return Vaa_;
265}
266
267RefSCMatrix R12IntEval::X_aa()
268{
269 compute();
270 return Xaa_;
271}
272
273RefSymmSCMatrix R12IntEval::B_aa()
274{
275 compute();
276
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];
282 Baa_.convert(baa);
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);
287 delete[] baa;
288
289 return Baa;
290}
291
292RefSCMatrix R12IntEval::A_aa()
293{
294 if (ebc_ == false)
295 compute();
296 return Aaa_;
297}
298
299RefSCMatrix R12IntEval::Ac_aa()
300{
301 if (ebc_ == false && follow_ks_ebcfree_) {
302 compute();
303 return Ac_aa_;
304 }
305 else
306 throw ProgrammingError("R12IntEval::Ac_aa() called although the object initialized with follow_ks_ebcfree set to false",__FILE__,__LINE__);
307}
308
309RefSCMatrix R12IntEval::T2_aa()
310{
311 if (ebc_ == false)
312 compute();
313 return T2aa_;
314}
315
316RefSCMatrix R12IntEval::V_ab()
317{
318 compute();
319 return Vab_;
320}
321
322RefSCMatrix R12IntEval::X_ab()
323{
324 compute();
325 return Xab_;
326}
327
328RefSymmSCMatrix R12IntEval::B_ab()
329{
330 compute();
331
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];
337 Bab_.convert(bab);
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);
342 delete[] bab;
343
344 return Bab;
345}
346
347RefSCMatrix R12IntEval::A_ab()
348{
349 if (ebc_ == false)
350 compute();
351 return Aab_;
352}
353
354RefSCMatrix R12IntEval::Ac_ab()
355{
356 if (ebc_ == false && follow_ks_ebcfree_) {
357 compute();
358 return Ac_ab_;
359 }
360 else
361 throw ProgrammingError("R12IntEval::Ac_ab() called although the object initialized with follow_ks_ebcfree set to false",__FILE__,__LINE__);
362}
363
364RefSCMatrix R12IntEval::T2_ab()
365{
366 if (ebc_ == false)
367 compute();
368 return T2ab_;
369}
370
371RefSCVector R12IntEval::emp2_aa()
372{
373 compute();
374 return emp2pair_aa_;
375}
376
377RefSCVector R12IntEval::emp2_ab()
378{
379 compute();
380 return emp2pair_ab_;
381}
382
383RefDiagSCMatrix R12IntEval::evals() const { return r12info_->obs_space()->evals(); };
384
385void
386R12IntEval::checkpoint_() const
387{
388 int me = r12info_->msg()->me();
389 Wavefunction* wfn = r12info_->wfn();
390
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;
395 }
396}
397
398void
399R12IntEval::init_tforms_()
400{
401 Ref<MOIntsTransformFactory> tfactory = r12info_->tfactory();
402 tfactory->set_ints_method((MOIntsTransformFactory::StoreMethod)r12info_->ints_method());
403
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);
412 }
413
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);
422 }
423
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);
432 }
433
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);
442 }
443
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);
452 }
453
454 iajb_tform = tform_map_[iajb_name];
455 imjn_tform = tform_map_[imjn_name];
456 ipjq_tform = tform_map_[ipjq_name];
457}
458
459Ref<TwoBodyMOIntsTransform>
460R12IntEval::get_tform_(const std::string& tform_name)
461{
462 TformMap::const_iterator tform_iter = tform_map_.find(tform_name);
463 TwoBodyMOIntsTransform* tform = (*tform_iter).second.pointer();
464 if (tform == NULL) {
465 std::string errmsg = "R12IntEval::get_tform_() -- transform " + tform_name + " is not known";
466 throw std::runtime_error(errmsg.c_str());
467 }
468 tform->compute();
469
470 return tform;
471}
472
473void
474R12IntEval::init_intermeds_()
475{
476 if (r12info_->msg()->me() == 0) {
477#if NOT_INCLUDE_DIAGONAL_VXB_CONTIBUTIONS
478 Vaa_->assign(0.0);
479 Vab_->assign(0.0);
480 Baa_->assign(0.0);
481 Bab_->assign(0.0);
482#else
483 Vaa_->unit();
484 Vab_->unit();
485 Baa_->unit();
486 Bab_->unit();
487#endif
488 }
489 else {
490 Vaa_.assign(0.0);
491 Vab_.assign(0.0);
492 Baa_.assign(0.0);
493 Bab_.assign(0.0);
494 }
495 if (ebc_ == false) {
496 Aaa_.assign(0.0);
497 Aab_.assign(0.0);
498 if (follow_ks_ebcfree_) {
499 Ac_aa_.assign(0.0);
500 Ac_ab_.assign(0.0);
501 }
502 T2aa_.assign(0.0);
503 T2ab_.assign(0.0);
504 Raa_.assign(0.0);
505 Rab_.assign(0.0);
506 }
507
508 Xaa_.assign(0.0);
509 Xab_.assign(0.0);
510 //r2_contrib_to_X_orig_();
511#if !NOT_INCLUDE_DIAGONAL_VXB_CONTIBUTIONS
512 r2_contrib_to_X_new_();
513#endif
514
515 emp2pair_aa_.assign(0.0);
516 emp2pair_ab_.assign(0.0);
517}
518
519/// Compute <space1 space1|r_{12}^2|space1 space2>
520RefSCMatrix
521R12IntEval::compute_r2_(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2)
522{
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);
529
530 RefSCMatrix S_12, MX_12, MY_12, MZ_12, MXX_12, MYY_12, MZZ_12;
531 if (space1 == space2) {
532 S_12 = S_11;
533 MX_12 = MX_11;
534 MY_12 = MY_11;
535 MZ_12 = MZ_11;
536 MXX_12 = MXX_11;
537 MYY_12 = MYY_11;
538 MZZ_12 = MZZ_11;
539 }
540 else {
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);
543 }
544 if (debug_)
545 ExEnv::out0() << indent << "Computed overlap and multipole moment integrals" << endl;
546
547 const int nproc = r12info_->msg()->n();
548 const int me = r12info_->msg()->me();
549
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));
556
557 int ij = 0;
558 double* ijkl_ptr = r2_array;
559 for(int i=0; i<n1; i++)
560 for(int j=0; j<n1; j++, ij++) {
561
562 int ij_proc = ij%nproc;
563 if (ij_proc != me) {
564 ijkl_ptr += n12;
565 continue;
566 }
567
568 int kl=0;
569 for(int k=0; k<n1; k++)
570 for(int l=0; l<n2; l++, kl++, ijkl_ptr++) {
571
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);
579
580 double R2_ijkl = r1r1_ik * S_jl + r1r1_jl * S_ik - 2.0*r1r2_ijkl;
581 *ijkl_ptr = R2_ijkl;
582 }
583 }
584
585 r12info_->msg()->sum(r2_array,n1112);
586
587 MOPairIterFactory pair_factory;
588 RefSCDimension dim_ij = pair_factory.scdim_ab(space1,space1);
589 RefSCDimension dim_kl = pair_factory.scdim_ab(space1,space2);
590
591 Ref<LocalSCMatrixKit> local_matrix_kit = new LocalSCMatrixKit();
592 RefSCMatrix R2 = local_matrix_kit->matrix(dim_ij, dim_kl);
593 R2.assign(r2_array);
594 delete[] r2_array;
595
596 return R2;
597}
598
599
600void
601R12IntEval::r2_contrib_to_X_orig_()
602{
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);
608 if (debug_)
609 ExEnv::out0() << indent << "Computed multipole moment integrals" << endl;
610
611 const int nproc = r12info_->msg()->n();
612 const int me = r12info_->msg()->me();
613
614 SpatialMOPairIter_eq ij_iter(r12info_->act_occ_space());
615 SpatialMOPairIter_eq kl_iter(r12info_->act_occ_space());
616
617 for(kl_iter.start();int(kl_iter);kl_iter.next()) {
618
619 const int kl = kl_iter.ij();
620 int kl_proc = kl%nproc;
621 if (kl_proc != me)
622 continue;
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();
628
629 for(ij_iter.start();int(ij_iter);ij_iter.next()) {
630
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();
636
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);
654
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);
657
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);
661 }
662
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);
666 }
667
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);
671 }
672
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);
677 }
678
679 }
680 }
681}
682
683void
684R12IntEval::r2_contrib_to_X_new_()
685{
686 unsigned int me = r12info_->msg()->me();
687
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());
690
691 if (me != 0)
692 return;
693 Xab_.accumulate(R2);
694
695 SpatialMOPairIter_eq ij_iter(r12info_->act_occ_space());
696 SpatialMOPairIter_eq kl_iter(r12info_->act_occ_space());
697
698 for(kl_iter.start();int(kl_iter);kl_iter.next()) {
699
700 const int kl_aa = kl_iter.ij_aa();
701 if (kl_aa == -1)
702 continue;
703 const int kl_ab = kl_iter.ij_ab();
704
705 for(ij_iter.start();int(ij_iter);ij_iter.next()) {
706
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();
710
711 if (ij_aa != -1) {
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);
714 }
715
716 }
717 }
718}
719
720void
721R12IntEval::form_focc_space_()
722{
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();
728
729 RefSCMatrix F_ri_o = fock_(occ_space,ribs_space,occ_space);
730 if (debug_ > 1)
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());
734 }
735}
736
737void
738R12IntEval::form_factocc_space_()
739{
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();
746
747 RefSCMatrix F_ri_ao = fock_(occ_space,ribs_space,act_occ_space);
748 if (debug_ > 1)
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());
752 }
753}
754
755void
756R12IntEval::form_canonvir_space_()
757{
758 // Create a complement space to all occupieds
759 // Fock operator is diagonal in this space
760 if (canonvir_space_.null()) {
761
762 if (r12info_->basis_vir()->equiv(r12info_->basis())) {
763 canonvir_space_ = r12info_->vir_space();
764 return;
765 }
766
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);
770
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);
775 int ij = 0;
776 for(int row=0; row<nrow; row++) {
777 int rc = row*nrow;
778 for(int col=0; col<=row; col++, rc++, ij++) {
779 F_lowtri[ij] = F_full[rc];
780 }
781 }
782 RefSymmSCMatrix F_vir_lt(F_vir.rowdim(),F_vir->kit());
783 F_vir_lt->assign(F_lowtri);
784 F_vir = 0;
785 delete[] F_full;
786 delete[] F_lowtri;
787
788 Ref<MOIndexSpace> canonvir_space_symblk = new MOIndexSpace("Virt. MOs symmetry-blocked",
789 vir_space, vir_space->coefs()*F_vir_lt.eigvecs(),
790 vir_space->basis());
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(),
796 F_vir_evals, 0, 0,
797 MOIndexSpace::energy);
798 }
799}
800
801const int
802R12IntEval::tasks_with_ints_(const Ref<R12IntsAcc> ints_acc, vector<int>& map_to_twi)
803{
804 int nproc = r12info_->msg()->n();
805
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++;
811
812 map_to_twi.resize(nproc);
813 int count = 0;
814 for(int proc=0;proc<nproc;proc++)
815 if (ints_acc->has_access(proc)) {
816 map_to_twi[proc] = count;
817 count++;
818 }
819 else
820 map_to_twi[proc] = -1;
821
822 ExEnv::out0() << indent << "Computing intermediates on " << nproc_with_ints
823 << " processors" << endl;
824
825 return nproc_with_ints;
826}
827
828
829void
830R12IntEval::compute()
831{
832 if (evaluated_)
833 return;
834
835 if (r12info_->basis_vir()->equiv(r12info_->basis())) {
836 obs_contrib_to_VXB_gebc_vbseqobs_();
837 if (debug_ > 1) {
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");
844 }
845 if (r12info_->basis() != r12info_->basis_ri())
846 abs1_contrib_to_VXB_gebc_();
847 if (debug_ > 1) {
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");
854 }
855 }
856 else {
857 contrib_to_VXB_gebc_vbsneqobs_();
858 compute_dualEmp2_();
859 if (include_mp1_)
860 compute_dualEmp1_();
861 }
862
863
864#if TEST_FOCK
865 if (!evaluated_) {
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");
869
870 r12info_->ribs_space()->coefs().print("Orthonormal RI-BS");
871 RefSCMatrix S_ri;
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)");
882
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");
885 }
886#endif
887
888 if (!ebc_) {
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");
893
894 compute_A_simple_();
895 Aaa_.scale(2.0);
896 Aab_.scale(2.0);
897 if (follow_ks_ebcfree_) {
898 compute_A_via_commutator_();
899 Ac_aa_.scale(2.0);
900 Ac_ab_.scale(2.0);
901 }
902 compute_T2_();
903 AT2_contrib_to_V_();
904 compute_R_();
905 AR_contrib_to_B_();
906 }
907
908 if (!gbc_) {
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");
913
914 compute_B_gbc_1_();
915 if (debug_ > 1) {
916 Baa_.print("Alpha-alpha B(OBS+ABS+GBC1) contribution");
917 Bab_.print("Alpha-beta B(OBS+ABS+GBC1) contribution");
918 }
919 compute_B_gbc_2_();
920 if (debug_ > 1) {
921 Baa_.print("Alpha-alpha B(OBS+ABS+GBC1+GBC2) contribution");
922 Bab_.print("Alpha-beta B(OBS+ABS+GBC1+GBC2) contribution");
923 }
924 }
925
926 // Distribute the final intermediates to every node
927 globally_sum_intermeds_(true);
928
929 evaluated_ = true;
930}
931
932void
933R12IntEval::globally_sum_scmatrix_(RefSCMatrix& A, bool to_all_tasks, bool to_average)
934{
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
938 if (ntasks == 1)
939 return;
940
941 const int nelem = A.ncol() * A.nrow();
942 double *A_array = new double[nelem];
943 A.convert(A_array);
944 if (to_all_tasks)
945 msg->sum(A_array,nelem,0,-1);
946 else
947 msg->sum(A_array,nelem,0,0);
948 A.assign(A_array);
949 if (to_average)
950 A.scale(1.0/(double)ntasks);
951 if (!to_all_tasks && msg->me() != 0)
952 A.assign(0.0);
953
954 delete[] A_array;
955}
956
957void
958R12IntEval::globally_sum_scvector_(RefSCVector& A, bool to_all_tasks, bool to_average)
959{
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
963 if (ntasks == 1)
964 return;
965
966 const int nelem = A.dim().n();
967 double *A_array = new double[nelem];
968 A.convert(A_array);
969 if (to_all_tasks)
970 msg->sum(A_array,nelem,0,-1);
971 else
972 msg->sum(A_array,nelem,0,0);
973 A.assign(A_array);
974 if (to_average)
975 A.scale(1.0/(double)ntasks);
976 if (!to_all_tasks && msg->me() != 0)
977 A.assign(0.0);
978
979 delete[] A_array;
980}
981
982void
983R12IntEval::globally_sum_intermeds_(bool to_all_tasks)
984{
985 globally_sum_scmatrix_(Vaa_,to_all_tasks);
986 globally_sum_scmatrix_(Vab_,to_all_tasks);
987
988 globally_sum_scmatrix_(Xaa_,to_all_tasks);
989 globally_sum_scmatrix_(Xab_,to_all_tasks);
990
991 globally_sum_scmatrix_(Baa_,to_all_tasks);
992 globally_sum_scmatrix_(Bab_,to_all_tasks);
993
994 if (ebc_ == false) {
995 globally_sum_scmatrix_(Aaa_,to_all_tasks);
996 globally_sum_scmatrix_(Aab_,to_all_tasks);
997
998 if (follow_ks_ebcfree_) {
999 globally_sum_scmatrix_(Ac_aa_,to_all_tasks);
1000 globally_sum_scmatrix_(Ac_ab_,to_all_tasks);
1001 }
1002
1003 globally_sum_scmatrix_(T2aa_,to_all_tasks);
1004 globally_sum_scmatrix_(T2ab_,to_all_tasks);
1005
1006 globally_sum_scmatrix_(Raa_,to_all_tasks);
1007 globally_sum_scmatrix_(Rab_,to_all_tasks);
1008 }
1009
1010 globally_sum_scvector_(emp2pair_aa_,to_all_tasks);
1011 globally_sum_scvector_(emp2pair_ab_,to_all_tasks);
1012
1013 if (debug_) {
1014 ExEnv::out0() << indent << "Collected contributions to the intermediates from all tasks";
1015 if (to_all_tasks)
1016 ExEnv::out0() << " and distributed to every task" << endl;
1017 else
1018 ExEnv::out0() << " on task 0" << endl;
1019 }
1020}
1021
1022/////////////////////////////////////////////////////////////////////////////
1023
1024// Local Variables:
1025// mode: c++
1026// c-file-style: "CLJ-CONDENSED"
1027// End:
Note: See TracBrowser for help on using the repository browser.