📄 hsosv2lb.cc
字号:
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 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 = %14.10f", passe) << endl; ExEnv::out0() << indent << scprintf(" restart_orbital_v2lb = %d", ((pass+1) * ni)) << endl; } } // exit loop over i-batches (pass) // 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); // do this only if nsocc > 0 since gop1 will fail otherwise tim_enter("compute ecorr"); if (nsocc > 0) { tim_enter("global sum mo_int_do_so_vir"); msg_->sum(mo_int_do_so_vir,ndocc*nsocc*(nvir-nsocc),mo_int_tmp); tim_exit("global 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); 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)/2 << 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); ExEnv::out0().flush(); } 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); free(trans_int4_tmp); if (nsocc) free(socc_sum); if (nsocc) free(socc_sum_tmp); if (nsocc) free(mo_int_do_so_vir); if (nsocc) free(mo_int_tmp); free(evals_open); free(myshells); free(shellsize); free (myshellsizes); free (split_info); free(sorted_shells); free(nbf); free(proc); delete[] scf_vector; delete[] scf_vector_dat; }/////////////////////////////////////////////////////////////////// Function iquicksort performs a quick sort (larger -> smaller) // of the integer data in item by the integer indices in index;// data in item remain unchanged/////////////////////////////////////////////////////////////////static voidiquicksort(int *item,int *index,int n){ int i; if (n<=0) return; for (i=0; i<n; i++) { index[i] = i; } iqs(item,index,0,n-1); }static voidiqs(int *item,int *index,int left,int right){ register int i,j; int x,y; i=left; j=right; x=item[index[(left+right)/2]]; do { while(item[index[i]]>x && i<right) i++; while(x>item[index[j]] && j>left) j--; if (i<=j) { if (item[index[i]] != item[index[j]]) { y=index[i]; index[i]=index[j]; index[j]=y; } i++; j--; } } while(i<=j); if (left<j) iqs(item,index,left,j); if (i<right) iqs(item,index,i,right);}////////////////////////////////////////////////////////////////////// Function findprocminmax finds the processor with the most/fewest// basis functions and the corresponding number of basis functions////////////////////////////////////////////////////////////////////static voidfindprocminmax(int *nbf, int nproc, int *procmin, int *procmax, int *minbf, int *maxbf){ int i; *procmax = *procmin = 0; *maxbf = nbf[0]; *minbf = nbf[0]; for (i=1; i<nproc; i++) { if (nbf[i] > *maxbf) { *maxbf = nbf[i]; *procmax = i; } if (nbf[i] < *minbf) { *minbf = nbf[i]; *procmin = i; } }}/////////////////////////////////////////////////////////////////// Function findshellmax finds the largest shell on a processor/////////////////////////////////////////////////////////////////static voidfindshellmax(int *myshellsizes, int nRshell, int *shellmax, int *shellmaxindex){ int i; *shellmax = myshellsizes[0]; *shellmaxindex = 0; for (i=1; i<nRshell; i++) { if (myshellsizes[i] > *shellmax) { *shellmax = myshellsizes[i]; *shellmaxindex = i; } }}//////////////////////////////////////////////////////////////// Function expand_array expands the dimension of an array of// doubles by 1; // NB: THE ARRAY MUST HAVE BEEN ALLOCATED WITH MALLOC//////////////////////////////////////////////////////////////static void expandintarray(int *&a, int olddim){ int i; int *tmp; tmp = (int*) malloc((olddim+1)*sizeof(int)); for (i=0; i<olddim; i++) { tmp[i] = a[i]; } tmp[olddim] = 0; free(a); a = tmp;}////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ-CONDENSED"// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -