// // compute_amps.cc // // Copyright (C) 2004 Edward Valeev // // Author: Edward Valeev // Maintainer: EV // // This file is part of the SC Toolkit. // // The SC Toolkit is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // The SC Toolkit is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with the SC Toolkit; see the file COPYING.LIB. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // The U.S. Government is granted a limited license as per AL 91-7. // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace sc; void R12IntEval::compute_T2_vbsneqobs_() { Ref iajb_tform = get_tform_("(ia|jb)"); Ref ijab_acc = iajb_tform->ints_acc(); if (!ijab_acc->is_committed()) iajb_tform->compute(); if (!ijab_acc->is_active()) ijab_acc->activate(); tim_enter("mp2 t2 amplitudes"); Ref msg = r12info_->msg(); int me = msg->me(); int nproc = msg->n(); ExEnv::out0() << endl << indent << "Entered MP2 T2 amplitude evaluator" << endl; ExEnv::out0() << incindent; Ref act_occ_space = r12info_->act_occ_space(); Ref act_vir_space = r12info_->act_vir_space(); const int nactvir = act_vir_space->rank(); RefDiagSCMatrix act_occ_evals = act_occ_space->evals(); RefDiagSCMatrix act_vir_evals = act_vir_space->evals(); SpatialMOPairIter_eq ij_iter(act_occ_space); SpatialMOPairIter_eq ab_iter(act_vir_space); int naa = ij_iter.nij_aa(); // Number of alpha-alpha pairs (i > j) int nab = ij_iter.nij_ab(); // Number of alpha-beta pairs if (debug_) { ExEnv::out0() << indent << "naa = " << naa << endl; ExEnv::out0() << indent << "nab = " << nab << endl; } // Compute the number of tasks that have full access to the integrals // and split the work among them vector proc_with_ints; int nproc_with_ints = tasks_with_ints_(ijab_acc,proc_with_ints); ////////////////////////////////////////////////////////////// // // Evaluation of the MP2 T2 amplitudes proceeds as follows: // // loop over batches of ij, // load (ijxy)=(ix|jy) into memory // // loop over xy, 0<=xretrieve_pair_block(i,j,R12IntsAcc::eri); tim_exit("MO ints retrieve"); if (debug_) ExEnv::outn() << indent << "task " << me << ": obtained ij blocks" << endl; // Compute MP2 energies double T2_aa_ijab = 0.0; double T2_ab_ijab = 0.0; for(ab_iter.start();int(ab_iter);ab_iter.next()) { const int a = ab_iter.i(); const int b = ab_iter.j(); const int ab_aa = ab_iter.ij_aa(); const int ab_ab = ab_iter.ij_ab(); const int ba_ab = ab_iter.ij_ba(); const int ab_offset = a*nactvir + b; const int ba_offset = b*nactvir + a; const double oo_delta_ijab = -1.0/(-act_occ_evals(i)-act_occ_evals(j)+act_vir_evals(a)+act_vir_evals(b)); const double eri_iajb = ijxy_buf_eri[ab_offset]; const double eri_ibja = ijxy_buf_eri[ba_offset]; const double T2_ab_ijab = eri_iajb * oo_delta_ijab; const double T2_ab_ijba = eri_ibja * oo_delta_ijab; T2ab_.set_element(ij_ab,ab_ab,T2_ab_ijab); T2ab_.set_element(ji_ab,ba_ab,T2_ab_ijab); T2ab_.set_element(ji_ab,ab_ab,T2_ab_ijba); T2ab_.set_element(ij_ab,ba_ab,T2_ab_ijba); if (ij_aa != -1 && ab_aa != -1) { const double T2_aa_ijab = (eri_iajb - eri_ibja) * oo_delta_ijab; T2aa_.set_element(ij_aa,ab_aa,T2_aa_ijab); } } ijab_acc->release_pair_block(i,j,R12IntsAcc::eri); } globally_sum_scmatrix_(T2aa_); globally_sum_scmatrix_(T2ab_); ExEnv::out0() << decindent; ExEnv::out0() << indent << "Exited MP2 T2 amplitude evaluator" << endl; tim_exit("mp2 t2 amplitudes"); } void R12IntEval::compute_R_vbsneqobs_(const Ref& ipjq_tform, RefSCMatrix& Raa, RefSCMatrix& Rab) { Ref ijpq_acc = ipjq_tform->ints_acc(); if (!ijpq_acc->is_committed()) ipjq_tform->compute(); if (!ijpq_acc->is_active()) ijpq_acc->activate(); tim_enter("R intermediate"); Ref msg = r12info_->msg(); int me = msg->me(); int nproc = msg->n(); ExEnv::out0() << endl << indent << "Entered R intermediate evaluator" << endl; ExEnv::out0() << incindent; Ref act_occ_space = r12info_->act_occ_space(); Ref space2 = ipjq_tform->space2(); Ref space4 = ipjq_tform->space4(); const int rank2 = space2->rank(); const int rank4 = space4->rank(); MOPairIterFactory PIFactory; Ref ij_iter = PIFactory.mopairiter(act_occ_space,act_occ_space); Ref pq_iter = PIFactory.mopairiter(space2,space4); int nij_aa = ij_iter->nij_aa(); // Number of alpha-alpha pairs (i > j) int nij_ab = ij_iter->nij_ab(); // Number of alpha-beta pairs if (debug_) { ExEnv::out0() << indent << "nij_aa = " << nij_aa << endl; ExEnv::out0() << indent << "nij_ab = " << nij_ab << endl; } // Compute the number of tasks that have full access to the integrals // and split the work among them vector proc_with_ints; int nproc_with_ints = tasks_with_ints_(ijpq_acc,proc_with_ints); for(ij_iter->start();int(*ij_iter.pointer());ij_iter->next()) { const int ij = ij_iter->ij(); // Figure out if this task will handle this ij int ij_proc = ij%nproc_with_ints; if (ij_proc != proc_with_ints[me]) continue; const int i = ij_iter->i(); const int j = ij_iter->j(); const int ij_aa = ij_iter->ij_aa(); const int ij_ab = ij_iter->ij_ab(); const int ji_ab = ij_iter->ij_ba(); if (debug_) ExEnv::outn() << indent << "task " << me << ": working on (i,j) = " << i << "," << j << " " << endl; // Get (|1/r12|) integrals tim_enter("MO ints retrieve"); double *ijxy_buf_r12 = ijpq_acc->retrieve_pair_block(i,j,R12IntsAcc::r12); double *jixy_buf_r12 = ijpq_acc->retrieve_pair_block(j,i,R12IntsAcc::r12); tim_exit("MO ints retrieve"); if (debug_) ExEnv::outn() << indent << "task " << me << ": obtained ij blocks" << endl; for(pq_iter->start();int(*pq_iter.pointer());pq_iter->next()) { const int p = pq_iter->i(); const int q = pq_iter->j(); const int pq_aa = pq_iter->ij_aa(); const int pq_ab = pq_iter->ij_ab(); const int pq_ba = pq_iter->ij_ba(); const int pq_offset = p*rank4 + q; const double r12_ipjq = ijxy_buf_r12[pq_offset]; const double r12_jpiq = jixy_buf_r12[pq_offset]; Rab.set_element(ij_ab,pq_ab,r12_ipjq); Rab.set_element(ji_ab,pq_ba,r12_ipjq); Rab.set_element(ij_ab,pq_ba,r12_jpiq); Rab.set_element(ji_ab,pq_ab,r12_jpiq); if (ij_aa != -1 && pq_aa != -1) { const double R_aa_ijpq = (r12_ipjq - r12_jpiq); Raa.set_element(ij_aa,pq_aa,R_aa_ijpq); } } ijpq_acc->release_pair_block(i,j,R12IntsAcc::r12); ijpq_acc->release_pair_block(j,i,R12IntsAcc::r12); } globally_sum_scmatrix_(Raa); globally_sum_scmatrix_(Rab); ExEnv::out0() << decindent; ExEnv::out0() << indent << "Exited R intermediate evaluator" << endl; tim_exit("R intermediate"); } void R12IntEval::compute_amps_() { if (Amps_.nonnull()) return; Ref act_vir_space = r12info_->act_vir_space(); Ref occ_space = r12info_->occ_space(); Ref ribs_space = r12info_->ribs_space(); MOPairIterFactory PIFactory; RefSCDimension ij_aa = dim_ij_aa_; RefSCDimension ij_ab = dim_ij_ab_; RefSCDimension vv_aa = PIFactory.scdim_aa(act_vir_space,act_vir_space); RefSCDimension vv_ab = PIFactory.scdim_ab(act_vir_space,act_vir_space); RefSCDimension oo_aa = PIFactory.scdim_aa(occ_space,occ_space); RefSCDimension oo_ab = PIFactory.scdim_ab(occ_space,occ_space); RefSCDimension ov_aa = PIFactory.scdim_aa(occ_space,act_vir_space); RefSCDimension ov_ab = PIFactory.scdim_ab(occ_space,act_vir_space); RefSCDimension ox_aa = PIFactory.scdim_aa(occ_space,ribs_space); RefSCDimension ox_ab = PIFactory.scdim_ab(occ_space,ribs_space); Ref kit = new LocalSCMatrixKit(); RefSCMatrix T2_aa = kit->matrix(ij_aa,vv_aa); RefSCMatrix T2_ab = kit->matrix(ij_ab,vv_ab); RefSCMatrix Rvv_aa = kit->matrix(ij_aa,vv_aa); RefSCMatrix Rvv_ab = kit->matrix(ij_ab,vv_ab); RefSCMatrix Roo_aa = kit->matrix(ij_aa,oo_aa); RefSCMatrix Roo_ab = kit->matrix(ij_ab,oo_ab); RefSCMatrix Rvo_aa = kit->matrix(ij_aa,ov_aa); RefSCMatrix Rvo_ab = kit->matrix(ij_ab,ov_ab); RefSCMatrix Rxo_aa = kit->matrix(ij_aa,ox_aa); RefSCMatrix Rxo_ab = kit->matrix(ij_ab,ox_ab); compute_T2_vbsneqobs_(); compute_R_vbsneqobs_(get_tform_("(ia|jb)"),Rvv_aa,Rvv_ab); compute_R_vbsneqobs_(get_tform_("(im|jn)"),Roo_aa,Roo_ab); compute_R_vbsneqobs_(get_tform_("(im|ja)"),Rvo_aa,Rvo_ab); compute_R_vbsneqobs_(get_tform_("(im|jy)"),Rxo_aa,Rxo_ab); Amps_ = new R12Amplitudes(T2_aa, T2_ab, Rvv_aa, Rvv_ab, Roo_aa, Roo_ab, Rvo_aa, Rvo_ab, Rxo_aa, Rxo_ab); } Ref R12IntEval::amps() { if (Amps_.null()) compute_amps_(); return Amps_; } //////////////////////////////////////////////////////////////////////////// // Local Variables: // mode: c++ // c-file-style: "CLJ-CONDENSED" // End: