📄 hsosv1.cc
字号:
for (a=0; a<a_number; a++) { iajb = &trans_int4_node[a*nvir]; c_rb = &scf_vector[r][nocc]; iajr = trans_int3[i*(i+1)/2 + i*i_offset + j + dim_ij*(a+a_number*r)]; for (b=0; b<nvir; b++) { *iajb++ += *c_rb++ * iajr; } } } tim_exit("4. quart. tr."); /* collect each node's part of fully transf. int. into trans_int4 */ tim_enter("collect"); msg_->collect(trans_int4_node,a_vector,trans_int4); tim_exit("collect"); /* we now have the fully transformed integrals (ia|jb) * * for one i, one j (j <= i_offset+i), and all a and b; * * compute contribution to the OPT1 and OPT2 correlation * * energies; use restriction b <= a to save flops */ tim_enter("compute ecorr"); for (a=0; a<nvir; a++) { for (b=0; b<=a; b++) { compute_index++; if (compute_index%nproc != me) continue; docc_index = ((i_offset+i) >= nsocc && (i_offset+i) < nocc) + (j >= nsocc && j < nocc); socc_index = ((i_offset+i)<nsocc)+(j<nsocc)+(a<nsocc)+(b<nsocc); vir_index = (a >= nsocc) + (b >= nsocc); if (socc_index >= 3) continue; /* skip to next b value */ delta_ijab = evals_open[i_offset+i] + evals_open[j] - evals_open[nocc+a] - evals_open[nocc+b]; /* determine integral type and compute energy contribution */ if (docc_index == 2 && vir_index == 2) { if (i_offset+i == j && a == b) { contrib1 = trans_int4[a*nvir + b]*trans_int4[a*nvir + b]; ecorr_opt2 += contrib1/delta_ijab; ecorr_opt1 += contrib1/delta_ijab; } else if (i_offset+i == j || a == b) { contrib1 = trans_int4[a*nvir + b]*trans_int4[a*nvir + b]; ecorr_opt2 += 2*contrib1/delta_ijab; ecorr_opt1 += 2*contrib1/delta_ijab; } else { contrib1 = trans_int4[a*nvir + b]; contrib2 = trans_int4[b*nvir + a]; ecorr_opt2 += 4*(contrib1*contrib1 + contrib2*contrib2 - contrib1*contrib2)/delta_ijab; ecorr_opt1 += 4*(contrib1*contrib1 + contrib2*contrib2 - contrib1*contrib2)/delta_ijab; } } else if (docc_index == 2 && socc_index == 2) { contrib1 = (trans_int4[a*nvir + b] - trans_int4[b*nvir + a])* (trans_int4[a*nvir + b] - trans_int4[b*nvir + a]); ecorr_opt2 += contrib1/ (delta_ijab - 0.5*(socc_sum[a]+socc_sum[b])); ecorr_opt1 += contrib1/delta_ijab; } else if (socc_index == 2 && vir_index == 2) { contrib1 = (trans_int4[a*nvir + b] - trans_int4[b*nvir + a])* (trans_int4[a*nvir + b] - trans_int4[b*nvir + a]); ecorr_opt2 += contrib1/ (delta_ijab - 0.5*(socc_sum[i_offset+i]+socc_sum[j])); ecorr_opt1 += contrib1/delta_ijab; } else if (docc_index == 2 && socc_index == 1 && vir_index == 1) { if (i_offset+i == j) { contrib1 = trans_int4[a*nvir + b]*trans_int4[a*nvir + b]; ecorr_opt2 += contrib1/(delta_ijab - 0.5*socc_sum[b]); ecorr_opt1 += contrib1/delta_ijab; } else { contrib1 = trans_int4[a*nvir + b]; contrib2 = trans_int4[b*nvir + a]; ecorr_opt2 += 2*(contrib1*contrib1 + contrib2*contrib2 - contrib1*contrib2)/(delta_ijab - 0.5*socc_sum[b]); ecorr_opt1 += 2*(contrib1*contrib1 + contrib2*contrib2 - contrib1*contrib2)/delta_ijab; } } else if (docc_index == 1 && socc_index == 2 && vir_index == 1) { contrib1 = trans_int4[b*nvir+a]*trans_int4[b*nvir+a]; if (j == b) { /* to compute the total energy contribution from an integral * * of the type (is1|s1a) (i=d.o., s1=s.o., a=unocc.), we need * * the (is|sa) integrals for all s=s.o.; these integrals are * * therefore stored here in the array mo_int_do_so_vir, and * * the energy contribution is computed after exiting the loop * * over i-batches (pass) */ mo_int_do_so_vir[a-nsocc + (nvir-nsocc)* (i_offset+i-nsocc + ndocc*b)] = trans_int4[b*nvir + a]; ecorr_opt2_contrib += 1.5*contrib1/delta_ijab; ecorr_opt1 += 1.5*contrib1/delta_ijab; ecorr_zapt2_contrib += contrib1/ (delta_ijab - 0.5*(socc_sum[j]+socc_sum[b])) + 0.5*contrib1/delta_ijab; } else { ecorr_opt2 += contrib1/ (delta_ijab - 0.5*(socc_sum[j] + socc_sum[b])); ecorr_opt1 += contrib1/delta_ijab; } } else if (docc_index == 1 && socc_index == 1 && vir_index == 2) { if (a == b) { contrib1 = trans_int4[a*nvir + b]*trans_int4[a*nvir + b]; ecorr_opt2 += contrib1/(delta_ijab - 0.5*socc_sum[j]); ecorr_opt1 += contrib1/delta_ijab; } else { contrib1 = trans_int4[a*nvir + b]; contrib2 = trans_int4[b*nvir + a]; ecorr_opt2 += 2*(contrib1*contrib1 + contrib2*contrib2 - contrib1*contrib2)/(delta_ijab - 0.5*socc_sum[j]); ecorr_opt1 += 2*(contrib1*contrib1 + contrib2*contrib2 - contrib1*contrib2)/delta_ijab; } } } /* exit b loop */ } /* exit a loop */ tim_exit("compute ecorr"); } /* exit j loop */ } /* exit i loop */ if (nsocc == 0 && npass > 1 && pass < npass - 1) { double passe = ecorr_opt2; msg_->sum(passe); ExEnv::out0() << indent << "Partial correlation energy for pass " << pass << ":" << endl; ExEnv::out0() << indent << scprintf(" restart_ecorr = %18.14f", passe) << endl; ExEnv::out0() << indent << scprintf(" restart_orbital_v1 = %d", ((pass+1) * ni)) << endl; } } /* exit loop over i-batches (pass) */ // don't need the AO integrals and threads anymore double aoint_computed = 0.0; for (i=0; i<thr_->nthread(); i++) { tbint[i] = 0; aoint_computed += e1thread[i]->aoint_computed(); delete e1thread[i]; } delete[] e1thread; delete[] tbint; /* compute contribution from excitations of the type is1 -> s1a where * * i=d.o., s1=s.o. and a=unocc; single excitations of the type i -> a, * * where i and a have the same spin, contribute to this term; * * (Brillouin's theorem not satisfied for ROHF wave functions); */ tim_enter("compute ecorr"); if (nsocc > 0) { tim_enter("sum mo_int_do_so_vir"); msg_->sum(mo_int_do_so_vir,ndocc*nsocc*(nvir-nsocc),mo_int_tmp); tim_exit("sum mo_int_do_so_vir"); } /* add extra contribution for triplet and higher spin multiplicities * * contribution = sum over s1 and s2<s1 of (is1|s1a)*(is2|s2a)/delta */ if (me == 0 && nsocc) { for (i=0; i<ndocc; i++) { for (a=0; a<nvir-nsocc; a++) { delta = evals_open[nsocc+i] - evals_open[nocc+nsocc+a]; for (s1=0; s1<nsocc; s1++) { for (s2=0; s2<s1; s2++) { contrib1 = mo_int_do_so_vir[a + (nvir-nsocc)*(i + ndocc*s1)]* mo_int_do_so_vir[a + (nvir-nsocc)*(i + ndocc*s2)]/delta; ecorr_opt2 += contrib1; ecorr_opt1 += contrib1; } } } /* exit a loop */ } /* exit i loop */ } tim_exit("compute ecorr"); ecorr_zapt2 = ecorr_opt2 + ecorr_zapt2_contrib; ecorr_opt2 += ecorr_opt2_contrib; msg_->sum(ecorr_opt1); msg_->sum(ecorr_opt2); msg_->sum(ecorr_zapt2); msg_->sum(aoint_computed); if (restart_orbital_v1_) { ecorr_opt1 += restart_ecorr_; ecorr_opt2 += restart_ecorr_; ecorr_zapt2 += restart_ecorr_; } escf = reference_->energy(); hf_energy_ = escf; if (me == 0) { eopt2 = escf + ecorr_opt2; eopt1 = escf + ecorr_opt1; ezapt2 = escf + ecorr_zapt2; /* print out various energies etc.*/ ExEnv::out0() << indent << "Number of shell quartets for which AO integrals would" << endl << indent << "have been computed without bounds checking: " << npass*nshell*nshell*(nshell+1)*(nshell+1)/4 << endl; ExEnv::out0() << indent << "Number of shell quartets for which AO integrals" << endl << indent << "were computed: " << aoint_computed << endl; ExEnv::out0() << indent << scprintf("ROHF energy [au]: %17.12lf\n", escf); ExEnv::out0() << indent << scprintf("OPT1 energy [au]: %17.12lf\n", eopt1); ExEnv::out0() << indent << scprintf("OPT2 second order correction [au]: %17.12lf\n", ecorr_opt2); ExEnv::out0() << indent << scprintf("OPT2 energy [au]: %17.12lf\n", eopt2); ExEnv::out0() << indent << scprintf("ZAPT2 correlation energy [au]: %17.12lf\n", ecorr_zapt2); ExEnv::out0() << indent << scprintf("ZAPT2 energy [au]: %17.12lf\n", ezapt2); } msg_->bcast(eopt1); msg_->bcast(eopt2); msg_->bcast(ezapt2); if (method_ && !strcmp(method_,"opt1")) { set_energy(eopt1); set_actual_value_accuracy(reference_->actual_value_accuracy() *ref_to_mp2_acc); } else if (method_ && !strcmp(method_,"opt2")) { set_energy(eopt2); set_actual_value_accuracy(reference_->actual_value_accuracy() *ref_to_mp2_acc); } else if (method_ && nsocc == 0 && !strcmp(method_,"mp")) { set_energy(ezapt2); set_actual_value_accuracy(reference_->actual_value_accuracy() *ref_to_mp2_acc); } else { if (!(!method_ || !strcmp(method_,"zapt"))) { ExEnv::out0() << indent << "MBPT2: bad method: " << method_ << ", using zapt" << endl; } set_energy(ezapt2); set_actual_value_accuracy(reference_->actual_value_accuracy() *ref_to_mp2_acc); } free(trans_int1); free(trans_int2); free(trans_int3); free(trans_int4_node); free(trans_int4); free(a_vector); if (nsocc) free(socc_sum); if (nsocc) free(mo_int_do_so_vir); if (nsocc) free(mo_int_tmp); free(evals_open); delete[] scf_vector; delete[] scf_vector_dat; }////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ-CONDENSED"// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -