From b35a13d64827c8cb7e30a25e62a5a83e0b770442 Mon Sep 17 00:00:00 2001 From: dyzheng <49852742+dyzheng@users.noreply.github.com> Date: Wed, 5 May 2021 21:08:55 +0800 Subject: [PATCH] fixed bug of ewald term in STRESS (#16) merge into deepmodeling * modify h_psi to make it able to calculate all bands in one time * add ORB_api in src_external * update ORB_api and modifies related files in ABACUS * 1. add OpenMP in PW_Basis::setup_structure_factor * fix a bug in schmit_orth which results from commit e647aa9 * update ORB files * delete usage of tools.h in ORB_gaunt_table * 1. delete unnecessary header files included in class Sph_Bessel_Recursive * add lat0 parameter in ORB_control::set_orb_tables subroutine to minimize global variables * modify ORB_table_beta.cpp and ORB_table_beta.h * set ntype as an input parameter * keep eliminating global variables in ORB files * keep eliminating global variables in ORB * add math_integral class * delete SimpsonIntegrals in Mathzone, use the one in src_global/math_integral.h instead * some files haven't be successfully submitted in reading descriptor * make Exx_Abfs::Lmax as an input for ORB module * fix a bug in h_psi for NSPIN!=4 * out lcao-line descriptor * add new input parameter read_file_dir * eliminate inclusion of global files in ORB* files * add __NORMAL option in complex to avoid linking to lapack in some cases * update matrix to make connecting to lapack unnecessary * update of ORB files * optimize src_lcao/LCAO_gen_fixedH.cpp * delete useless variable itia* in ORB_read * delete nkb variable in ORB_read, the variable has been defined in ppcell.nkb * add GRID_api in src_external * fixed bug in cell-relax, start refactor after_vc part * fix a segfault in src_lcao/LCAO_gen_fixedH.cpp * delte NEW_DM global variable, use INPUT.new_dm instead, this will be modified further in future * add some comments in ylm and ORB_gen_tables * fixed a bug in FORCE&&STRESS, but this part still puzzling * refactor some repete codes in Unitcell * update grid base * seems a bug in src_lcao/LCAO_gen_fixedH.cpp when multiple cores are parallel * 1. add BSSE for lcao 1.1 src_pw/pseudopot_upf.h 1.2 src_pw/pseudopot_upf.cpp 1.3 src_pw/atom_pseudo.h 1.4 src_io/read_atoms.cpp 1.5 src_io/read_pseudopot.cpp 1.6 src_pw/charge.cpp 2. refactor Charge::atomic_rho() 2.1 src_pw/charge.cpp * fixed nspin=2 bug * fix bugs in lcao-line descriptor * fix ORB_gen_tables conflicts * revert * fix a bug about no initialization of variable * DFT+U stress Fix bug of stress of DFT+U; Change fortran code lscc.f90 to C++ * Delete lscc.f * Revert "DFT+U" * fix a bug when the pseudopotential dir is incorrect * delete ucell.lmax in ORB* * set ORB parameters in ORB codes, not through global variables * 1. fix bug of flag_empty_element * 1. delete testing header file * fixed bug of relax * 1. add Matrix3::Zero() * 1. fix bug in Vdwd2::cal_stress() * DFT+U (#25) * DFT+U fix the problem of dftu_relax.h header file * DFT+U Fix bug in stress calculation; delete lscc.f * Update README * avoid using INPUT.descriptor * update soc class for non-local pseudopotential initial * 1. add bcast flag_empty_element in Atom::bcast_atom() * update reader of upf ONCV pseudopotential * eliminate INPUT.descriptor in ORB codes * cleanup some .h files * update formats in ORB * update ORB_gen_tables * delete Coefficient_D in ORB_nonlocal * keep cleaning ORB_nonlocal * keep cleaning ORB * add __OPENMP option for openmp codes * update ORB codes * add parameter in set_orb * keep on updating ORB * delete a useless variable in ORB_read * delte a useless function in ORB_read * add MY_RANK as an input parameter for ORB module * add two variables in set_orb * update ORB * update file pointers in ORB * add correct warning when the orbital files cannot be found * ready for reconstruction of nchi array for ORB module * update some formats in pdiag_double * extract common parts in 'Read_PAO' and 'Read_Descriptor' to function 'read_orb_file' * 1. fix bug of operator*(const double&, const Matrix3&) 2. delete default parameters in Matrix3() * 1. delete Matrix3::Reset() * Update README * reformat some pseudopotential codes * delete pseudo_us class * merge pseudo_atom and pseudo_h classes to pseudo_nc * update pseudo_nc * update ORB include files * change pseudopot_cell_vl and _vnl to more appropriate names, namely, VL_in_pw and VNL_in_pw, respectively * divide pseudopot_upf to two files * change read_pseudopot to read_cell_pseudopots * divide read_pseudopotentials to three formats: upf100 stands for version of upf, upf201 stands for upf.2.0.1, and vwr * add vdwd3 Co-authored-by: Han Wang Co-authored-by: qianrui Co-authored-by: mohan Co-authored-by: linpz Co-authored-by: maki49 <1579492865@qq.com> Co-authored-by: Yu Liu <77716030+YuLiu98@users.noreply.github.com> Co-authored-by: YuLiu Co-authored-by: 80610702-git Co-authored-by: Quxin <78459762+80610702-git@users.noreply.github.com> Co-authored-by: jiyuyang * Revert "update (#2)" (#4) This reverts commit 14b481f9fe9e4dfa0cde5faf95131418537da1ce. * fixed bug in stress-ewald Co-authored-by: Han Wang Co-authored-by: qianrui Co-authored-by: mohan Co-authored-by: linpz Co-authored-by: maki49 <1579492865@qq.com> Co-authored-by: Yu Liu <77716030+YuLiu98@users.noreply.github.com> Co-authored-by: YuLiu Co-authored-by: 80610702-git Co-authored-by: Quxin <78459762+80610702-git@users.noreply.github.com> Co-authored-by: jiyuyang --- ABACUS.develop/source/src_pw/stress.cpp | 1860 ----------------- ABACUS.develop/source/src_pw/stress.h | 137 -- .../source/src_pw/stress_func_ewa.cpp | 5 +- 3 files changed, 3 insertions(+), 1999 deletions(-) delete mode 100644 ABACUS.develop/source/src_pw/stress.cpp delete mode 100644 ABACUS.develop/source/src_pw/stress.h diff --git a/ABACUS.develop/source/src_pw/stress.cpp b/ABACUS.develop/source/src_pw/stress.cpp deleted file mode 100644 index 080066d194..0000000000 --- a/ABACUS.develop/source/src_pw/stress.cpp +++ /dev/null @@ -1,1860 +0,0 @@ -#include "stress.h" -#include "global.h" -#include "potential.h" -#include "xc_functional.h" -#include "xc_gga_pw.h" -#include "efield.h" -#include "myfunc.h" -#include "symmetry.h" -// new -#include "H_Ewald_pw.h" -#include "H_Hartree_pw.h" -#include "H_XC_pw.h" - -void Stress::cal_stress(void) -{ - TITLE("Stress","cal_stress"); - timer::tick("Stress","cal_stress",'E'); - - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - sigmatot[i][j] = 0.0; - sigmaxc[i][j] = 0.0; - sigmahar[i][j] = 0.0; - sigmakin[i][j] = 0.0; - sigmaloc[i][j] = 0.0; - sigmanlc[i][j] = 0.0; - sigmaewa[i][j] = 0.0; - sigmaxcc[i][j] = 0.0; - } - } - - //kinetic contribution - stres_knl(); - - if(Symmetry::symm_flag) - { - symm.stress_symmetry(sigmakin); - }//end symmetry - - //hartree contribution - stres_har(); - - //ewald contribution - stres_ewa(); - - //xc contribution: add gradient corrections(non diagonal) - for(int i=0;i<3;i++) - { - sigmaxc[i][i] = - (H_XC_pw::etxc - H_XC_pw::vtxc) / ucell.omega; - } - stres_gradcorr(); - - //local contribution - stres_loc(); - - //nlcc - stres_cc(); - - //nonlocal - stres_nl(); - - if(Symmetry::symm_flag) - { - symm.stress_symmetry(sigmanlc); - }//end symmetry - - for(int ipol=0;ipol<3;ipol++) - { - for(int jpol=0;jpol<3;jpol++) - { - sigmatot[ipol][jpol] = sigmakin[ipol][jpol] + sigmahar[ipol][jpol] + sigmanlc[ipol][jpol] - + sigmaxc[ipol][jpol] + sigmaxcc[ipol][jpol] + sigmaewa[ipol][jpol] - + sigmaloc[ipol][jpol]; - } - } - - if(Symmetry::symm_flag) - { - symm.stress_symmetry(sigmatot); - } - -/* cout<<"total stress:"<printstress_total(ry); - - if(TEST_STRESS) - { - ofs_running << "\n PARTS OF STRESS: " << endl; - ofs_running << setiosflags(ios::showpos); - ofs_running << setiosflags(ios::fixed) << setprecision(10) << endl; - this->print_stress("KINETIC STRESS",sigmakin,TEST_STRESS,ry); - this->print_stress("LOCAL STRESS",sigmaloc,TEST_STRESS,ry); - this->print_stress("HARTREE STRESS",sigmahar,TEST_STRESS,ry); - this->print_stress("NON-LOCAL STRESS",sigmanlc,TEST_STRESS,ry); - this->print_stress("XC STRESS",sigmaxc,TEST_STRESS,ry); - this->print_stress("EWALD STRESS",sigmaewa,TEST_STRESS,ry); - this->print_stress("NLCC STRESS",sigmaxcc,TEST_STRESS,ry); - this->print_stress("TOTAL STRESS",sigmatot,TEST_STRESS,ry); - } - return; - -} - - -void Stress::print_stress(const string &name, double f[][3], const bool screen, bool ry)const -{ - ofs_running << " --------------------------- " << name << " ----------------------------" << endl; - - - double fac = 1.0; - - if(!ry) - { - // fac = Ry_to_eV / 0.529177; - } - - cout << setprecision(8); - cout << setiosflags(ios::showpos); - - if(screen) - { - cout << " ------------------- " << name << " --------------------" << endl; - - } - - const double output_acc = 1.0e-8; - for (int i=0;i<3;i++) - { - ofs_running << setw(15)<< " "; - if( abs(f[i][0]) >output_acc) ofs_running << setw(15) << f[i][0]*fac; - else ofs_running << setw(15) << "0"; - if( abs(f[i][1]) >output_acc) ofs_running << setw(15) << f[i][1]*fac; - else ofs_running << setw(15) << "0"; - if( abs(f[i][2]) >output_acc) ofs_running << setw(15) << f[i][2]*fac; - else ofs_running << setw(15) << "0"; - ofs_running << endl; - - if(screen) - { - if( abs(f[i][0]) >output_acc) cout << setw(15) << f[i][0]*fac; - else cout << setw(15) << "0"; - if( abs(f[i][1]) >output_acc) cout << setw(15) << f[i][1]*fac; - else cout << setw(15) << "0"; - if( abs(f[i][2]) >output_acc) cout << setw(15) << f[i][2]*fac; - else cout << setw(15) << "0"; - cout << endl; - } - - - } - - cout << resetiosflags(ios::showpos); - - return; -} - -void Stress::printstress_total (bool ry) -{ -// zhengdy update 2016-10-08 - double unit_transform = 1; - - if(!ry) - { - unit_transform = RYDBERG_SI / pow(BOHR_RADIUS_SI,3) * 1.0e-8; - } - // cout.setf(ios::fixed); - - - //ofs_running << setiosflags(ios::right); - ofs_running << setprecision(8) << setiosflags(ios::showpos) << setiosflags(ios::fixed) << endl; - NEW_PART("TOTAL-STRESS (KBAR)");//Ryd/(a.u.)^3 - -// if(INPUT.stress_set == 1) - if(TEST_STRESS) - { - stringstream ss; - ss << global_out_dir << "STRESS.dat" ; - ofstream ofs( ss.str().c_str() ); - if(!ofs) - { - cout << "open STRESS.dat error !" <1){ -// iunigh.clear(); -// iunigh.seekg(0,ios::beg); -// }//go back to the beginning of file - - for(ik=0;ik1){ -// iunigk>>igk; -// get_buffer(evc,nwordwfc,iunwfc,ik); -// } - for(i=0;i0){ -// gk2=pow(gk[i].x,2)+pow(gk[i].y,2)+pow(gk[i].z,2); -// arg=pow((gk2-ecfixed)/q2sigma,2); -// kfac[i]=1+qcutz/q2sigma*tbsp*exp(-arg); -// } - } - - //kinetic contribution - - for(l=0;l<3;l++) - { - for(m=0;m *Porter = UFFT.porter; - - // Hartree potential VH(r) from n(r) - ZEROS( Porter, pw.nrxx ); - for(int is=0; is( CHR.rho[is][ir], 0.0 ); - } - } - //============================= - // bring rho (aux) to G space - //============================= - pw.FFT_chg.FFT3D(Porter, -1); - - complex *psic = new complex [pw.nrxx]; - double *psic0 = new double[pw.nrxx]; - ZEROS( psic0, pw.nrxx); - for(int is=0; is(psic0[ir], 0.0); - } - } - - pw.FFT_chg.FFT3D(psic, -1) ; - - - double charge; - if (pw.gstart == 1) - { - charge = ucell.omega * Porter[pw.ig2fftc[0]].real(); - } - - complex *vh_g = new complex[pw.ngmc]; - ZEROS(vh_g, pw.ngmc); - - double g[3]; - //test - // int i=pw.gstart; - // cout<< "gstart " <= 1.0e-12) //LiuXh 20180410 - { - const double fac = e2 * FOUR_PI / (ucell.tpiba2 * pw.gg [ig]); - - ehart += ( conj( Porter[j] ) * Porter[j] ).real() * fac; - // vh_g[ig] = fac * Porter[j]; - - shart= ( conj( Porter[j] ) * Porter[j] ).real()/(ucell.tpiba2 * pw.gg [ig]); - - g[0]=pw.gcar[ig].x; - g[1]=pw.gcar[ig].y; - g[2]=pw.gcar[ig].z; - //test - - //cout<<"g "< *Porter = UFFT.porter; - - ZEROS( Porter, pw.nrxx ); - for(int is=0; is(CHR.rho[is][ir], 0.0 ); - } - } - pw.FFT_chg.FFT3D(Porter, -1); - - if(INPUT.gamma_only==1) fact=2.0; - else fact=1.0; - - evloc=0.0; - double g[3]={0,0,0}; - - complex *vg = new complex[pw.ngmc]; - ZEROS( vg, pw.ngmc ); - for (int it=0; itzv, dvloc); - } - else{ - // normal case: dvloc contains dV_loc(G)/dG - dvloc_of_g ( atom->msh, atom->rab, atom->r, - atom->vloc_at, atom->zv, dvloc); - } - - for( ng = 0;ng< pw.ngmc;ng++) - { - const int j = pw.ig2fftc[ng]; - g[0]=pw.gcar[ng].x; - g[1]=pw.gcar[ng].y; - g[2]=pw.gcar[ng].z; - for (l = 0;l< 3;l++) - { - for (m = 0; m ) - ComplexMatrix dbecp( nkb, NBANDS); - ComplexMatrix becp( nkb, NBANDS); - - // vkb1: |Beta(nkb,npw)> - ComplexMatrix vkb1( nkb, wf.npwx ); - ComplexMatrix vkb0[3]; - for(int i=0;i<3;i++){ - vkb0[i].create(nkb, wf.npwx); - } - ComplexMatrix vkb2( nkb, wf.npwx ); - for (int ik = 0;ik < kv.nks;ik++) - { - for(int i=0;i<3;i++){ - vkb0[i].zero_out(); - } - vkb2.zero_out(); - - if (NSPIN==2) CURRENT_SPIN = kv.isk[ik]; - wf.npw = kv.ngk[ik]; - // generate vkb - if (ppcell.nkb > 0) - { - ppcell.getvnl(ik); - } - - // get becp according to wave functions and vkb - // important here ! becp must set zero!! - // vkb: Beta(nkb,npw) - // becp(nkb,nbnd): - becp.zero_out(); - for (int ib=0; ib qvec; - double qvec0[3]; - - for (int ipol = 0; ipol<3; ipol++) - { - for(int jpol = 0; jpol < ipol+1; jpol++) - { - dbecp.zero_out(); - vkb1.zero_out(); - for (int i = 0;i < nkb;i++) - { - - for (int ig=0; ig 1e-8) qm1 = 1.0 / qvec.norm(); - else qm1 = 0; - dbecp(i,ib) += -2.0 * wf.evc[ik](ib,ig) * conj(vkb2(i,ig)) * qvec0[ipol] * qvec0[jpol] * qm1 * ucell.tpiba; - }//end ig - }//end i - }//end ib - - - // don't need to reduce here, keep dbecp different in each processor, - // and at last sum up all the forces. - // Parallel_Reduce::reduce_complex_double_pool( dbecp.ptr, dbecp.ndata); - - // double *cf = new double[ucell.nat*3]; - // ZEROS(cf, ucell.nat); - for (int ib=0; ibprint(ofs_running, "nonlocal stress", stresnl); - timer::tick("Stress","stres_nl"); - return; -} - -void Stress::get_dvnl1( - ComplexMatrix &vkb, - const int ik, - const int ipol) -{ - if(test_pp) TITLE("Stress","get_dvnl1"); - // timer::tick("Stress","get_dvnl1"); - - const int lmaxkb = ppcell.lmaxkb; - if(lmaxkb < 0) - { - return; - } - - const int npw = kv.ngk[ik]; - const int nhm = ppcell.nhm; - int ig, ia, nb, ih; - matrix vkb1(nhm, npw); - vkb1.zero_out(); - double *vq = new double[npw]; - const int x1= (lmaxkb + 1)*(lmaxkb + 1); - - matrix dylm(x1, npw); - Vector3 *gk = new Vector3[npw]; - for (ig = 0;ig < npw;ig++) - { - gk[ig] = wf.get_1qvec_cartesian(ik, ig); - } - - dylmr2(x1, npw, gk, dylm, ipol); - - int jkb = 0; - for(int it = 0;it < ucell.ntype;it++) - { - if(test_pp>1) OUT("it",it); - // calculate beta in G-space using an interpolation table - const int nbeta = ucell.atoms[it].nbeta; - const int nh = ucell.atoms[it].nh; - - if(test_pp>1) OUT("nbeta",nbeta); - - for (nb = 0;nb < nbeta;nb++) - { - if(test_pp>1) OUT("ib",nb); - for (ig = 0;ig < npw;ig++) - { - const double gnorm = gk[ig].norm() * ucell.tpiba; - - // cout << "\n gk[ig] = " << gk[ig].x << " " << gk[ig].y << " " << gk[ig].z; - // cout << "\n gk.norm = " << gnorm; - - vq [ig] = Mathzone::Polynomial_Interpolation( - ppcell.tab, it, nb, NQX, DQ, gnorm ); - - } // enddo - - // add spherical harmonic part - for (ih = 0;ih < nh;ih++) - { - if (nb == ppcell.indv(it, ih)) - { - const int lm = static_cast( ppcell.nhtolm(it, ih) ); - for (ig = 0;ig < npw;ig++) - { - vkb1(ih, ig) = dylm(lm, ig) * vq [ig]; - } - - } - - } // end ih - - } // end nbeta - - // vkb1 contains all betas including angular part for type nt - // now add the structure factor and factor (-i)^l - for (ia=0; ia *sk = wf.get_sk(ik, it, ia); - for (ih = 0;ih < nh;ih++) - { - complex pref = pow( NEG_IMAG_UNIT, ppcell.nhtol(it, ih)); //? - for (ig = 0;ig < npw;ig++) - { - vkb(jkb, ig) = vkb1(ih, ig) * sk [ig] * pref; - } - ++jkb; - } // end ih - delete [] sk; - } // end ia - } // enddo - delete [] gk; - delete [] vq; - //timer::tick("Stress","get_dvnl1"); - return; -}//end get_dvnl1 - - -void Stress::get_dvnl2( - ComplexMatrix &vkb, - const int ik) -{ - if(test_pp) TITLE("Stress","get_dvnl2"); - timer::tick("Stress","get_dvnl2"); - - const int lmaxkb = ppcell.lmaxkb; - if(lmaxkb < 0) - { - return; - } - - const int npw = kv.ngk[ik]; - const int nhm = ppcell.nhm; - int ig, ia, nb, ih; - matrix vkb1(nhm, npw); - double *vq = new double[npw]; - const int x1= (lmaxkb + 1)*(lmaxkb + 1); - - matrix ylm(x1, npw); - Vector3 *gk = new Vector3[npw]; - for (ig = 0;ig < npw;ig++) - { - gk[ig] = wf.get_1qvec_cartesian(ik, ig); - } - Mathzone::Ylm_Real(x1, npw, gk, ylm); - - int jkb = 0; - for(int it = 0;it < ucell.ntype;it++) - { - if(test_pp>1) OUT("it",it); - // calculate beta in G-space using an interpolation table - const int nbeta = ucell.atoms[it].nbeta; - const int nh = ucell.atoms[it].nh; - - if(test_pp>1) OUT("nbeta",nbeta); - - for (nb = 0;nb < nbeta;nb++) - { - if(test_pp>1) OUT("ib",nb); - for (ig = 0;ig < npw;ig++) - { - const double gnorm = gk[ig].norm() * ucell.tpiba; - - // cout << "\n gk[ig] = " << gk[ig].x << " " << gk[ig].y << " " << gk[ig].z; - // cout << "\n gk.norm = " << gnorm; - vq [ig] = Polynomial_Interpolation_nl( - ppcell.tab, it, nb, DQ, gnorm ); - - } // enddo - - // add spherical harmonic part - for (ih = 0;ih < nh;ih++) - { - if (nb == ppcell.indv(it, ih)) - { - const int lm = static_cast( ppcell.nhtolm(it, ih) ); - for (ig = 0;ig < npw;ig++) - { - vkb1(ih, ig) = ylm(lm, ig) * vq [ig]; - } - } - } // end ih - } // end nbeta - - // vkb1 contains all betas including angular part for type nt - // now add the structure factor and factor (-i)^l - for (ia=0; ia *sk = wf.get_sk(ik, it, ia); - for (ih = 0;ih < nh;ih++) - { - complex pref = pow( NEG_IMAG_UNIT, ppcell.nhtol(it, ih)); //? - for (ig = 0;ig < npw;ig++) - { - vkb(jkb, ig) = vkb1(ih, ig) * sk [ig] * pref; - } - ++jkb; - } // end ih - delete [] sk; - - } // end ia - } // enddo - - delete [] gk; - delete [] vq; - timer::tick("Stress","get_dvnl2"); - - return; -} - - -double Stress::Polynomial_Interpolation_nl -( - const realArray &table, - const int &dim1, - const int &dim2, - const double &table_interval, - const double &x // input value -) -{ -// timer::tick("Mathzone","Poly_Interpo_2"); - assert(table_interval>0.0); - const double position = x / table_interval; - const int iq = static_cast(position); - - const double x0 = position - static_cast(iq); - const double x1 = 1.0 - x0; - const double x2 = 2.0 - x0; - const double x3 = 3.0 - x0; - const double y= - ( table(dim1, dim2, iq) * (-x2*x3-x1*x3-x1*x2) / 6.0 + - table(dim1, dim2, iq+1) * (+x2*x3-x0*x3-x0*x2) / 2.0 - - table(dim1, dim2, iq+2) * (+x1*x3-x0*x3-x0*x1) / 2.0 + - table(dim1, dim2, iq+3) * (+x1*x2-x0*x2-x0*x1) / 6.0 )/table_interval ; - -// timer::tick("Mathzone","Poly_Interpo_2"); - return y; -} - -void Stress::dylmr2 ( - const int nylm, - const int ngy, - Vector3 *gk, - matrix &dylm, - const int ipol){ - //----------------------------------------------------------------------- - // - // compute \partial Y_lm(G) \over \partial (G)_ipol - // using simple numerical derivation (SdG) - // The spherical harmonics are calculated in ylmr2 - // - //int nylm, ngy, ipol; - // number of spherical harmonics - // the number of g vectors to compute - // desired polarization - //double g (3, ngy), gg (ngy), dylm (ngy, nylm) - // the coordinates of g vectors - // the moduli of g vectors - // the spherical harmonics derivatives - // - int ig, lm; - // counter on g vectors - // counter on l,m component - - const double delta = 1e-6; - double *dg, *dgi; - - matrix ylmaux; - // dg is the finite increment for numerical derivation: - // dg = delta |G| = delta * sqrt(gg) - // dgi= 1 /(delta * sqrt(gg)) - // gx = g +/- dg - - - Vector3 *gx = new Vector3 [ngy]; - - - dg = new double [ngy]; - dgi = new double [ngy]; - - ylmaux.create (nylm, ngy); - - dylm.zero_out(); - ylmaux.zero_out(); - - for( ig = 0;ig< ngy;ig++){ - gx[ig] = gk[ig]; - } -//$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) - for( ig = 0;ig< ngy;ig++){ - dg [ig] = delta * gx[ig].norm() ; - if (gx[ig].norm2() > 1e-9) { - dgi [ig] = 1.0 / dg [ig]; - } - else{ - dgi [ig] = 0.0; - } - } -//$OMP END PARALLEL DO - -//$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) - for( ig = 0;ig< ngy;ig++){ - if(ipol==0) - gx [ig].x = gk[ ig].x + dg [ig]; - else if(ipol==1) - gx [ig].y = gk [ ig].y + dg [ig]; - else if(ipol==2) - gx [ig].z = gk [ ig].z + dg [ig]; - } -//$OMP END PARALLEL DO - - Mathzone::Ylm_Real(nylm, ngy, gx, dylm); -//$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) - for(ig = 0;ig< ngy;ig++){ - if(ipol==0) - gx [ig].x = gk [ ig].x - dg [ig]; - else if(ipol==1) - gx [ig].y = gk [ ig].y - dg [ig]; - else if(ipol==2) - gx [ig].z = gk [ ig].z - dg [ig]; - } -//$OMP END PARALLEL DO - - Mathzone::Ylm_Real(nylm, ngy, gx, ylmaux); - - -// zaxpy ( - 1.0, ylmaux, 1, dylm, 1); - for( lm = 0;lm< nylm;lm++){ - for(ig = 0;ig< ngy;ig++){ - dylm (lm,ig) = dylm(lm,ig) - ylmaux(lm,ig); - } - } - - - for( lm = 0;lm< nylm;lm++){ -//$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(ig) - for(ig = 0;ig< ngy;ig++){ - dylm (lm,ig) = dylm(lm,ig) * 0.5 * dgi [ig]; - } -//$OMP END PARALLEL DO - } - delete[] gx; - delete[] dg; - delete[] dgi; - - return; -} - - - - - -//main part -void Stress::stres_ewa(){ - int i,j,l,m; - double g[3]; - //the erfc function - - //tpiba2=pow(tpi/alat,2); -/* for(i=0;i<3;i++){ - for(j=0;j<3;j++){ - sigmaewa[i][j]=0; - } - }*/ - double charge=0; - for(int it=0; it < ucell.ntype; it++){ - for(int i=0; i1e-7); - - //G-space sum here - //Determine if this processor contains G=0 and set the constant term - double sdewald; - if(pw.gstart == 1) - { - sdewald = (TWO_PI) * e2 / 4.0 / alpha * pow(charge/ucell.omega,2); - } - else { - sdewald = 0.0; - } - //sdewald is the diagonal term - - double fact; - if (INPUT.gamma_only) fact=2.0; - else fact=1.0; - - double g2,g2a; - double arg; - complex rhostar; - double sewald; - for(int ng=pw.gstart;ng= 1.0e-12) //LiuXh 20180410 - { - g2 = pw.gg[ng]* ucell.tpiba2; - g2a = g2 /4.0/alpha; - rhostar=(0.0,0.0); - for(int it=0; it < ucell.ntype; it++){ - for(int i=0; i(ucell.atoms[it].zv * cos(arg),ucell.atoms[it].zv * sin(arg)); - } - } - rhostar /= ucell.omega; - sewald = fact* (TWO_PI) * e2 * exp(-g2a) / g2 * pow(abs(rhostar),2); - sdewald = sdewald - sewald; - g[0]=pw.gcar[ng].x; - g[1]=pw.gcar[ng].y; - g[2]=pw.gcar[ng].z; - for(l=0;l<3;l++){ - for(m=0;m *r; - double *r2; - r = new Vector3[mxr]; - r2 = new double[mxr]; - irr = new int[mxr]; - double rr; - Vector3 d_tau; - double r0[3]; - int rmax , nrm=0; - double fac; - if(pw.gstart==1){ - rmax = 4.0/sqrt(alpha)/ucell.lat0; - //with this choice terms up to ZiZj*erfc(5) are counted (erfc(5)=2*10^-1) - for(int it=0; it < ucell.ntype; it++){ - for(int i=0; i0); - const double fac = 1.0/ NSPIN; - - // doing FFT to get rho in G space: rhog1 - CHR.set_rhog(CHR.rho[0], CHR.rhog[0]); - if(NSPIN==2)//mohan fix bug 2012-05-28 - { - CHR.set_rhog(CHR.rho[1], CHR.rhog[1]); - } - CHR.set_rhog(CHR.rho_core, CHR.rhog_core); - - double* rhotmp1; - double* rhotmp2; - complex* rhogsum1; - complex* rhogsum2; - Vector3* gdr1; - Vector3* gdr2; - - rhotmp1 = new double[pw.nrxx]; - rhogsum1 = new complex[pw.ngmc]; - ZEROS(rhotmp1, pw.nrxx); - ZEROS(rhogsum1, pw.ngmc); - for(int ir=0; ir[pw.nrxx]; - ZEROS(gdr1, pw.nrxx); - - GGA_PW::grad_rho( rhogsum1 , gdr1 ); - - if(NSPIN==2) - { - rhotmp2 = new double[pw.nrxx]; - rhogsum2 = new complex[pw.ngmc]; - ZEROS(rhotmp2, pw.nrxx); - ZEROS(rhogsum2, pw.ngmc); - for(int ir=0; ir[pw.nrxx]; - ZEROS(gdr2, pw.nrxx); - - GGA_PW::grad_rho( rhogsum2 , gdr2 ); - } - - const double epsr = 1.0e-6; - const double epsg = 1.0e-10; - - double grho2a = 0.0; - double grho2b = 0.0; - double sx = 0.0; - double sc = 0.0; - double v1x = 0.0; - double v2x = 0.0; - double v1c = 0.0; - double v2c = 0.0; - double vtxcgc = 0.0; - double etxcgc = 0.0; - - if(NSPIN==1||NSPIN==4) - { - double segno; - for(int ir=0; ir epsr) - { - grho2a = gdr1[ir].norm2(); - if( grho2a > epsg ) - { - if( rhotmp1[ir] >= 0.0 ) segno = 1.0; - if( rhotmp1[ir] < 0.0 ) segno = -1.0; - - XC_Functional::gcxc( arho, grho2a, sx, sc, v1x, v2x, v1c, v2c); - double tt[3]; - tt[0] = gdr1[ir].x; - tt[1] = gdr1[ir].y; - tt[2] = gdr1[ir].z; - for(int l = 0;l< 3;l++){ - for(int m = 0;m< l+1;m++){ - sigma_gradcorr[l][m] += tt[l] * tt[m] * e2 * (v2x + v2c); - } - } - } - } - } - } - else if(NSPIN==2) - { - double v1cup = 0.0; - double v1cdw = 0.0; - double v2cup = 0.0; - double v2cdw = 0.0; - double v1xup = 0.0; - double v1xdw = 0.0; - double v2xup = 0.0; - double v2xdw = 0.0; - double v2cud = 0.0; - double v2c = 0.0; - for(int ir=0; ir epsr) - { - if(igcc_is_lyp) - { - WARNING_QUIT("stress","igcc_is_lyp is not available now."); - } - else - { - double zeta = ( rhotmp1[ir] - rhotmp2[ir] ) / rh; - double grh2 = (gdr1[ir]+gdr2[ir]).norm2(); - //XC_Functional::gcc_spin(rh, zeta, grh2, sc, v1cup, v1cdw, v2c); - gcc_spin(rh, zeta, grh2, sc, v1cup, v1cdw, v2c); - v2cup = v2c; - v2cdw = v2c; - v2cud = v2c; - } - } - else - { - sc = 0.0; - v1cup = 0.0; - v1cdw = 0.0; - v2c = 0.0; - v2cup = 0.0; - v2cdw = 0.0; - v2cud = 0.0; - } - double tt1[3],tt2[3]; - { - tt1[0] = gdr1[ir].x; - tt1[1] = gdr1[ir].y; - tt1[2] = gdr1[ir].z; - tt2[0] = gdr2[ir].x; - tt2[1] = gdr2[ir].y; - tt2[2] = gdr2[ir].z; - } - for(int l = 0;l< 3;l++){ - for(int m = 0;m< l+1;m++){ - // exchange - sigma_gradcorr [l][m] += tt1[l] * tt1[m] * e2 * v2xup + - tt2[l] * tt2[m] * e2 * v2xdw; - // correlation - sigma_gradcorr [l][m] += ( tt1[l] * tt1[m] * v2cup + - tt2[l] * tt2[m] * v2cdw + - (tt1[l] * tt2[m] + - tt2[l] * tt1[m] ) * v2cud ) * e2; - } - } - } - } - - for(int l = 0;l< 3;l++){ - for(int m = 0;m< l;m++){ - sigma_gradcorr[m][l] = sigma_gradcorr[l][m]; - } - } - for(int l = 0;l<3;l++){ - for(int m = 0;m<3;m++){ - Parallel_Reduce::reduce_double_pool( sigma_gradcorr[l][m] ); - } - } - p= &sigma_gradcorr[0][0]; - double* p1 = &sigmaxc[0][0]; - for(int i=0;i<9;i++){ - *p /= pw.ncxyz ; - *p1++ += *p++; - } - - delete[] rhotmp1; - delete[] rhogsum1; - delete[] gdr1; - if(NSPIN==2) - { - delete[] rhotmp2; - delete[] rhogsum2; - delete[] gdr2; - } - return; -} - - -void Stress::stres_cc() -{ - - int nt,ng,l,m,ir; - double fact; - complex sigmadiag; - double* rhocg; - double g[3]; - - - int judge=0; - for(nt=0;nt * psic = new complex [pw.nrxx]; - ZEROS(psic, pw.nrxx); - - if(NSPIN==1||NSPIN==4){ - for(ir=0;ir(vxc(0, ir), 0.0); - } - } - else { - for(ir=0;ir t = conj(psic[pw.ig2fftc[ng]] ) - * pw.strucFac (nt, ng) * rhocg [pw.ig2ngg[ng] ] * ucell.tpiba * - g [l] * g [m] / pw.gcar[ng].norm() * fact; - sigmaxcc [l][ m] += t.real(); - }//end m - }//end l - }//end ng - }//end if - }//end nt - for( l = 0;l< 3;l++){ - sigmaxcc [l][ l] += sigmadiag.real(); - } - //mp_sum( sigmaxcc, intra_bgrp_comm ); - for( l = 0;l< 3;l++){ - for (m = 0;m< 3;m++){ - Parallel_Reduce::reduce_double_pool( sigmaxcc[l][m] ); - } - } - - delete[] rhocg; - delete[] psic; - return; -} - - -void Stress::deriv_drhoc ( - const bool &numeric, - const int mesh, - const double *r, - const double *rab, - const double *rhoc, - double *drhocg) -{ - //int ngl, mesh; - // input: the number of g shell - // input: the number of radial mesh points - - // input: the number of G shells - // input: the radial mesh - // input: the derivative of the radial mesh - // input: the radial core charge - // output: fourier transform of d Rho_c/dG - // - // here the local variables - // - double gx = 0, rhocg1 = 0; - // the modulus of g for a given shell - // the fourier transform - double *aux; - // auxiliary memory for integration - - int ir, igl, igl0; - // counter on radial mesh points - // counter on g shells - // lower limit for loop on ngl - - // - // G=0 term - // - if (pw.ggs[0] < 1.0e-8){ - drhocg [0] = 0.0; - igl0 = 1; - } - else{ - igl0 = 0; - } - // - // G <> 0 term - // - aux= new double[ mesh]; - - for( igl = igl0;igl< pw.nggm;igl++){ - gx = sqrt(pw.ggs [igl] * ucell.tpiba2); - for( ir = 0;ir< mesh; ir++){ - aux [ir] = r [ir] * rhoc [ir] * (r [ir] * cos (gx * r [ir] ) / gx - sin (gx * r [ir] ) / pow(gx,2)); - }//ir - Mathzone::Simpson_Integral(mesh, aux, rab, rhocg1); - drhocg [igl] = FOUR_PI / ucell.omega * rhocg1; - }//igl - delete [] aux; - - return; -} - diff --git a/ABACUS.develop/source/src_pw/stress.h b/ABACUS.develop/source/src_pw/stress.h deleted file mode 100644 index c578da618b..0000000000 --- a/ABACUS.develop/source/src_pw/stress.h +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef STRESS_H -#define STRESS_H - -#include "tools.h" - -//------------------------------------------------------------------- -// mohan reconstruction note: 2021-02-07 -// the stress code needs reconstructions (by Daye Zheng) -// 1) add explanations for each function, each variable, for -// main procedures, make the code readable -// 2) divide the stress class into several files, each file -// deals with only one part of the stress, it is convenient for -// the next-step reconstruction, for example, we want to make -// pw as an external variable instead of a global variable -// 3) for PW and LCAO, keeps only one copy of the code, for example -// the ewald term needs only one copy, it will reduce the -// time to maintain both copies of stress codes. -// 4) remain openning interfaces for others to contribute stress -// codes, for example, molecular dynamics will have an ionic stress -// term, +U? exx? may have other stress terms. -// 5) delete useless comments and tests, if you have a useless code, -// please explicitly explain why you want to keep the test -// 6) the codes should be written as clear as possibel, -//------------------------------------------------------------------- - -//---------------------------------------------------------------- -// compute the stress terms in terms of the plane wave basis set -// the stress terms include: -// 1) the stress from the electron kinetic energy -// 2) the stress from the local pseudopotentials -// 3) the stress from the non-local pseudopotentials -// 4) the stress from the Hartree term -// 5) the stress from the non-linear core correction (if any) -// 6) the strees from the exchange-correlation functional term -// 7) the stress from the ewald term (ion-ion intraction under -// periodic boundary conditions). -// 8) the stress from ionic contributions (for molecular dynamics) -// 9) the stress from DFT+U -// 10) the stress from vdW -//---------------------------------------------------------------- -using namespace std; - -class Stress -{ - public: - - Stress(){}; - ~Stress(){}; - - void cal_stress(); - - void dvloc_of_g (const int& msh, - const double* rab, - const double* r, - const double* vloc_at, - const double& zp, - double* dvloc); - - void dvloc_coul (const double& zp, double* dvloc); - - void deriv_drhoc ( - const bool &numeric, - const int mesh, - const double *r, - const double *rab, - const double *rhoc, - double *drhocg); - - void print_stress(const string &name, double f[][3], const bool screen, bool ry)const; - - void printstress_total (bool ry); - - // total stress - double sigmatot[3][3]; - - private: - - void stres_knl(); - - void stres_har(); - - void stres_ewa(); - - void stres_loc(); - - void stres_cc(); - - void stres_gradcorr(); - - void stres_nl(); - - void dylmr2 ( - const int nylm, - const int ngy, - Vector3 *gk, - matrix &dylm, - const int ipol); - - double Polynomial_Interpolation_nl( - const realArray &table, - const int &dim1, - const int &dim2, - const double &table_interval, - const double &x); - - void get_dvnl2( - ComplexMatrix &vkb, - const int ik); - - void get_dvnl1( - ComplexMatrix &vkb, - const int ik, - const int ipol); - - // stress for exchange-correlation functional term - double sigmaxc[3][3]; - // stress for electron kinetic energy term - double sigmakin[3][3]; - // stress for hartree term - double sigmahar[3][3]; - // stress for local pseudopotential term - double sigmaloc[3][3]; - // stress for nonlocal pseudopotential term - double sigmanlc[3][3]; - // stress for Ewald term (ion-ion interaction) - double sigmaewa[3][3]; - // stress for non-linear core correction term - double sigmaxcc[3][3]; -}; - - - - - - - -#endif diff --git a/ABACUS.develop/source/src_pw/stress_func_ewa.cpp b/ABACUS.develop/source/src_pw/stress_func_ewa.cpp index 7c66d64fc2..09e7dd9bd5 100644 --- a/ABACUS.develop/source/src_pw/stress_func_ewa.cpp +++ b/ABACUS.develop/source/src_pw/stress_func_ewa.cpp @@ -95,7 +95,8 @@ void Stress_Func::stress_ewa(matrix& sigma, const bool is_pw) double rr; Vector3 d_tau; double r0[3]; - int rmax , nrm=0; + double rmax=0.0; + int nrm=0; double fac; if(pw.gstart==1) { @@ -116,7 +117,7 @@ void Stress_Func::stress_ewa(matrix& sigma, const bool is_pw) for(int nr=0 ; nr