From be86dee514f37583e594ad3d32a5d689197f8694 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Feb 2022 14:49:27 +0800 Subject: [PATCH 01/36] xc refactor : move relevant files to module_xc --- CMakeLists.txt | 2 +- source/CMakeLists.txt | 1 + source/Makefile | 1 + source/module_xc/CMakeLists.txt | 14 ++++++++++++++ source/{src_pw => module_xc}/H_XC_pw.cpp | 0 source/{src_pw => module_xc}/H_XC_pw.h | 0 source/{src_pw => module_xc}/exx_global.h | 2 +- source/{src_pw => module_xc}/potential_libxc.cpp | 2 +- source/{src_pw => module_xc}/potential_libxc.h | 0 .../{src_pw => module_xc}/potential_libxc_meta.cpp | 2 +- source/{src_pw => module_xc}/xc_functional.cpp | 3 +-- source/{src_pw => module_xc}/xc_functional.h | 0 source/{src_pw => module_xc}/xc_gga_pw.cpp | 2 +- source/{src_pw => module_xc}/xc_gga_pw.h | 0 source/{src_pw => module_xc}/xc_type.cpp | 2 +- source/{src_pw => module_xc}/xc_type.h | 0 source/src_io/eximport.cpp | 2 +- source/src_io/print_info.h | 2 +- source/src_lcao/FORCE_STRESS.cpp | 4 ++-- source/src_lcao/exx_lip.h | 2 +- source/src_pw/CMakeLists.txt | 6 ------ source/src_pw/energy.cpp | 2 +- source/src_pw/forces.cpp | 4 ++-- source/src_pw/global.h | 4 ++-- source/src_pw/potential.cpp | 8 ++++---- source/src_pw/stress_func_cc.cpp | 2 +- source/src_pw/stress_func_gga.cpp | 4 ++-- source/src_pw/stress_func_mgga.cpp | 5 ++--- source/src_pw/stress_pw.cpp | 2 +- source/src_ri/exx_lcao.h | 4 ++-- 30 files changed, 45 insertions(+), 37 deletions(-) create mode 100644 source/module_xc/CMakeLists.txt rename source/{src_pw => module_xc}/H_XC_pw.cpp (100%) rename source/{src_pw => module_xc}/H_XC_pw.h (100%) rename source/{src_pw => module_xc}/exx_global.h (96%) rename source/{src_pw => module_xc}/potential_libxc.cpp (99%) rename source/{src_pw => module_xc}/potential_libxc.h (100%) rename source/{src_pw => module_xc}/potential_libxc_meta.cpp (99%) rename source/{src_pw => module_xc}/xc_functional.cpp (99%) rename source/{src_pw => module_xc}/xc_functional.h (100%) rename source/{src_pw => module_xc}/xc_gga_pw.cpp (99%) rename source/{src_pw => module_xc}/xc_gga_pw.h (100%) rename source/{src_pw => module_xc}/xc_type.cpp (99%) rename source/{src_pw => module_xc}/xc_type.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d4415a82d4..c67d764f63f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,7 +260,6 @@ target_link_libraries(${ABACUS_BIN_NAME} cell symmetry md - symmetry neighbor orb io @@ -272,6 +271,7 @@ target_link_libraries(${ABACUS_BIN_NAME} pw ri driver + xc -lm ) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index e65955d5989..7c668353f68 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -5,6 +5,7 @@ add_subdirectory(module_neighbor) add_subdirectory(module_orbital) add_subdirectory(module_md) add_subdirectory(module_deepks) +add_subdirectory(module_xc) add_subdirectory(src_io) add_subdirectory(src_ions) add_subdirectory(src_lcao) diff --git a/source/Makefile b/source/Makefile index d7dcf8e6bee..f2b4fbf019a 100644 --- a/source/Makefile +++ b/source/Makefile @@ -15,6 +15,7 @@ VPATH=./src_global\ :./module_base\ :./module_md\ :./module_deepks\ +:./module_xc\ :./src_pw\ :./src_lcao\ :./src_ions\ diff --git a/source/module_xc/CMakeLists.txt b/source/module_xc/CMakeLists.txt new file mode 100644 index 00000000000..9711308e986 --- /dev/null +++ b/source/module_xc/CMakeLists.txt @@ -0,0 +1,14 @@ +list(APPEND objects + H_XC_pw.cpp + potential_libxc.cpp + potential_libxc_meta.cpp + xc_functional.cpp + xc_gga_pw.cpp + xc_type.cpp + ) + +add_library( + xc + OBJECT + ${objects} +) diff --git a/source/src_pw/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp similarity index 100% rename from source/src_pw/H_XC_pw.cpp rename to source/module_xc/H_XC_pw.cpp diff --git a/source/src_pw/H_XC_pw.h b/source/module_xc/H_XC_pw.h similarity index 100% rename from source/src_pw/H_XC_pw.h rename to source/module_xc/H_XC_pw.h diff --git a/source/src_pw/exx_global.h b/source/module_xc/exx_global.h similarity index 96% rename from source/src_pw/exx_global.h rename to source/module_xc/exx_global.h index 337b02becc0..316df6f4268 100644 --- a/source/src_pw/exx_global.h +++ b/source/module_xc/exx_global.h @@ -1,7 +1,7 @@ #ifndef EXX_GLOBAL_H #define EXX_GLOBAL_H -#include "xc_type.h" +#include "../module_xc/xc_type.h" struct Exx_Global { diff --git a/source/src_pw/potential_libxc.cpp b/source/module_xc/potential_libxc.cpp similarity index 99% rename from source/src_pw/potential_libxc.cpp rename to source/module_xc/potential_libxc.cpp index 5a8aac1fced..96b4fe6fee1 100644 --- a/source/src_pw/potential_libxc.cpp +++ b/source/module_xc/potential_libxc.cpp @@ -7,7 +7,7 @@ #ifdef USE_LIBXC #include "potential_libxc.h" -#include "global.h" +#include "../src_pw/global.h" #include "../module_base/global_function.h" #include "../module_base/global_variable.h" #include "module_base/timer.h" diff --git a/source/src_pw/potential_libxc.h b/source/module_xc/potential_libxc.h similarity index 100% rename from source/src_pw/potential_libxc.h rename to source/module_xc/potential_libxc.h diff --git a/source/src_pw/potential_libxc_meta.cpp b/source/module_xc/potential_libxc_meta.cpp similarity index 99% rename from source/src_pw/potential_libxc_meta.cpp rename to source/module_xc/potential_libxc_meta.cpp index ee02ae2537d..a0ec724e80e 100644 --- a/source/src_pw/potential_libxc_meta.cpp +++ b/source/module_xc/potential_libxc_meta.cpp @@ -7,7 +7,7 @@ #ifdef USE_LIBXC #include "potential_libxc.h" -#include "global.h" +#include "../src_pw/global.h" #include "../module_base/global_function.h" #include "../module_base/global_variable.h" #include "module_base/timer.h" diff --git a/source/src_pw/xc_functional.cpp b/source/module_xc/xc_functional.cpp similarity index 99% rename from source/src_pw/xc_functional.cpp rename to source/module_xc/xc_functional.cpp index c353c568b55..0429d71e8b1 100644 --- a/source/src_pw/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -1,7 +1,6 @@ #include "xc_functional.h" #include "xc_type.h" -#include "global.h" -#include "myfunc.h" +#include "../src_pw/global.h" #include "../module_base/global_function.h" #include diff --git a/source/src_pw/xc_functional.h b/source/module_xc/xc_functional.h similarity index 100% rename from source/src_pw/xc_functional.h rename to source/module_xc/xc_functional.h diff --git a/source/src_pw/xc_gga_pw.cpp b/source/module_xc/xc_gga_pw.cpp similarity index 99% rename from source/src_pw/xc_gga_pw.cpp rename to source/module_xc/xc_gga_pw.cpp index 535504f2eb2..41cd98ed5f5 100644 --- a/source/src_pw/xc_gga_pw.cpp +++ b/source/module_xc/xc_gga_pw.cpp @@ -1,5 +1,5 @@ #include "xc_gga_pw.h" -#include "global.h" +#include "../src_pw/global.h" #include "xc_functional.h" // from gradcorr.f90 diff --git a/source/src_pw/xc_gga_pw.h b/source/module_xc/xc_gga_pw.h similarity index 100% rename from source/src_pw/xc_gga_pw.h rename to source/module_xc/xc_gga_pw.h diff --git a/source/src_pw/xc_type.cpp b/source/module_xc/xc_type.cpp similarity index 99% rename from source/src_pw/xc_type.cpp rename to source/module_xc/xc_type.cpp index 288bdde6bee..44c65a7c13d 100644 --- a/source/src_pw/xc_type.cpp +++ b/source/module_xc/xc_type.cpp @@ -1,6 +1,6 @@ #include "xc_type.h" #include "../module_base/global_function.h" -#include "global.h" +#include "../src_pw/global.h" #include "exx_global.h" xcfunc::xcfunc() diff --git a/source/src_pw/xc_type.h b/source/module_xc/xc_type.h similarity index 100% rename from source/src_pw/xc_type.h rename to source/module_xc/xc_type.h diff --git a/source/src_io/eximport.cpp b/source/src_io/eximport.cpp index ac193dae2e6..a263f81df47 100644 --- a/source/src_io/eximport.cpp +++ b/source/src_io/eximport.cpp @@ -701,7 +701,7 @@ void eximport::in_evc(std::ifstream &in) //=========== #include "../src_pw/H_Ewald_pw.h" #include "../src_pw/H_Hartree_pw.h" -#include "../src_pw/H_XC_pw.h" +#include "../module_xc/H_XC_pw.h" void eximport::out_energy(std::ofstream &out_data) { //std::cout << "\n ==> out_energy" << std::endl; diff --git a/source/src_io/print_info.h b/source/src_io/print_info.h index aa0b1b53a38..3ac5a37db21 100644 --- a/source/src_io/print_info.h +++ b/source/src_io/print_info.h @@ -8,7 +8,7 @@ #include "../module_base/timer.h" #include "../module_cell/unitcell_pseudo.h" #include "../src_pw/klist.h" -#include "../src_pw/xc_type.h" +#include "../module_xc/xc_type.h" class Print_Info { diff --git a/source/src_lcao/FORCE_STRESS.cpp b/source/src_lcao/FORCE_STRESS.cpp index cfd90c6a929..80c4e9acae8 100644 --- a/source/src_lcao/FORCE_STRESS.cpp +++ b/source/src_lcao/FORCE_STRESS.cpp @@ -1,9 +1,9 @@ #include "FORCE_STRESS.h" #include "../src_pw/global.h" -#include "../src_pw/potential_libxc.h" +#include "../module_xc/potential_libxc.h" #include "./dftu.h" //Quxin add for DFT+U on 20201029 // new -#include "../src_pw/H_XC_pw.h" +#include "../module_xc/H_XC_pw.h" #include "../src_pw/vdwd2.h" #include "../src_pw/vdwd3.h" #include "../module_base/timer.h" diff --git a/source/src_lcao/exx_lip.h b/source/src_lcao/exx_lip.h index a1ceefd25a8..d11f0e4fe23 100644 --- a/source/src_lcao/exx_lip.h +++ b/source/src_lcao/exx_lip.h @@ -8,7 +8,7 @@ #include "../module_base/complexmatrix.h" #include "../module_base/vector3.h" #include "../src_pw/hamilt.h" -#include "../src_pw/exx_global.h" +#include "../module_xc/exx_global.h" class K_Vectors; class wavefunc; diff --git a/source/src_pw/CMakeLists.txt b/source/src_pw/CMakeLists.txt index 556fcd54901..67a647f2eee 100644 --- a/source/src_pw/CMakeLists.txt +++ b/source/src_pw/CMakeLists.txt @@ -1,7 +1,6 @@ list(APPEND objects H_Ewald_pw.cpp H_Hartree_pw.cpp - H_XC_pw.cpp VL_in_pw.cpp VNL_in_pw.cpp charge.cpp @@ -19,8 +18,6 @@ list(APPEND objects magnetism.cpp occupy.cpp potential.cpp - potential_libxc.cpp - potential_libxc_meta.cpp pw_basis.cpp bspline_sf.cpp pw_complement.cpp @@ -51,9 +48,6 @@ list(APPEND objects wf_atomic.cpp wf_igk.cpp xc_3.cpp - xc_functional.cpp - xc_gga_pw.cpp - xc_type.cpp run_md_pw.cpp) if(USE_CUDA) list(APPEND objects diff --git a/source/src_pw/energy.cpp b/source/src_pw/energy.cpp index 6353abdb4bf..89ce329e8e2 100644 --- a/source/src_pw/energy.cpp +++ b/source/src_pw/energy.cpp @@ -16,7 +16,7 @@ //new #include "H_Ewald_pw.h" #include "H_Hartree_pw.h" -#include "H_XC_pw.h" +#include "../module_xc/H_XC_pw.h" #ifdef __DEEPKS #include "../src_lcao/../module_deepks/LCAO_deepks.h" #endif diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index b9039090420..143a0e6a286 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -4,9 +4,9 @@ #include "vdwd3.h" #include "../module_symmetry/symmetry.h" // new -#include "H_XC_pw.h" +#include "../module_xc/H_XC_pw.h" #include "../module_base/math_integral.h" -#include "potential_libxc.h" +#include "../module_xc/potential_libxc.h" #include "../src_parallel/parallel_reduce.h" #include "../module_base/timer.h" diff --git a/source/src_pw/global.h b/source/src_pw/global.h index 24efee2d863..8ebce487698 100644 --- a/source/src_pw/global.h +++ b/source/src_pw/global.h @@ -11,7 +11,7 @@ #include "VNL_in_pw.h" #include "charge_broyden.h" #include "energy.h" -#include "exx_global.h" +#include "../module_xc/exx_global.h" #include "hamilt.h" #include "klist.h" #include "magnetism.h" @@ -23,7 +23,7 @@ #include "vdwd3.h" #include "vdwd3_parameters.h" #include "wavefunc.h" -#include "xc_type.h" +#include "../module_xc/xc_type.h" #ifdef __CUDA namespace CudaCheck diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index 1424d100fed..d59089e2cae 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -3,14 +3,14 @@ #include "../module_base/memory.h" #include "global.h" #include "potential.h" -#include "xc_functional.h" -#include "xc_gga_pw.h" +#include "../module_xc/xc_functional.h" +#include "../module_xc/xc_gga_pw.h" #include "efield.h" #include "math.h" -#include "potential_libxc.h" +#include "../module_xc/potential_libxc.h" // new #include "H_Hartree_pw.h" -#include "H_XC_pw.h" +#include "../module_xc/H_XC_pw.h" #ifdef __LCAO #include "../src_lcao/ELEC_evolve.h" #endif diff --git a/source/src_pw/stress_func_cc.cpp b/source/src_pw/stress_func_cc.cpp index 70f143ff298..b5150e4b829 100644 --- a/source/src_pw/stress_func_cc.cpp +++ b/source/src_pw/stress_func_cc.cpp @@ -1,5 +1,5 @@ #include "./stress_func.h" -#include "./H_XC_pw.h" +#include "../module_xc/H_XC_pw.h" #include "../module_base/math_integral.h" #include "../module_base/timer.h" diff --git a/source/src_pw/stress_func_gga.cpp b/source/src_pw/stress_func_gga.cpp index 02dcf61d14f..81155b419aa 100644 --- a/source/src_pw/stress_func_gga.cpp +++ b/source/src_pw/stress_func_gga.cpp @@ -1,6 +1,6 @@ #include "./stress_func.h" -#include "./xc_functional.h" -#include "./xc_gga_pw.h" +#include "../module_xc/xc_functional.h" +#include "../module_xc/xc_gga_pw.h" #include "../module_base/timer.h" //calculate the GGA stress correction in PW and LCAO diff --git a/source/src_pw/stress_func_mgga.cpp b/source/src_pw/stress_func_mgga.cpp index 54ae75ab9aa..763a1939480 100644 --- a/source/src_pw/stress_func_mgga.cpp +++ b/source/src_pw/stress_func_mgga.cpp @@ -1,7 +1,6 @@ #include "./stress_func.h" -#include "./xc_functional.h" -#include "./myfunc.h" -#include "./xc_gga_pw.h" +#include "../module_xc/xc_functional.h" +#include "../module_xc/xc_gga_pw.h" #include "../module_base/timer.h" //calculate the mGGA stress correction in PW and LCAO diff --git a/source/src_pw/stress_pw.cpp b/source/src_pw/stress_pw.cpp index 3735bf3d6b0..885a1d948f8 100644 --- a/source/src_pw/stress_pw.cpp +++ b/source/src_pw/stress_pw.cpp @@ -1,5 +1,5 @@ #include "./stress_pw.h" -#include "./H_XC_pw.h" +#include "../module_xc/H_XC_pw.h" #include "vdwd2.h" #include "vdwd3.h" #include "../module_base/timer.h" diff --git a/source/src_ri/exx_lcao.h b/source/src_ri/exx_lcao.h index 9705dc282cd..a9c5a19c281 100644 --- a/source/src_ri/exx_lcao.h +++ b/source/src_ri/exx_lcao.h @@ -10,8 +10,8 @@ #include "exx_abfs-screen-schwarz.h" #include "exx_abfs-screen-cauchy.h" #include "../module_base/element_basis_index.h" -#include "../src_pw/xc_type.h" -#include "../src_pw/exx_global.h" +#include "../module_xc/xc_type.h" +#include "../module_xc/exx_global.h" #if EXX_DM==1 #include "exx_abfs-parallel-communicate-dm.h" From 3538d6ba3ddac23c79b99fb85674954f4023dbcf Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Feb 2022 17:58:40 +0800 Subject: [PATCH 02/36] xc refactor : replace keywords for components dft[4] by a single keyword xc_func --- source/module_cell/atom_pseudo.cpp | 2 +- source/module_cell/pseudo_nc.cpp | 7 +- source/module_cell/pseudo_nc.h | 2 +- source/module_cell/read_cell_pseudopots.cpp | 23 +- source/module_cell/read_pp.h | 2 +- source/module_cell/read_pp_blps.cpp | 8 +- source/module_cell/read_pp_upf100.cpp | 33 +- source/module_cell/read_pp_upf201.cpp | 770 +------------------- source/module_cell/read_pp_vwr.cpp | 5 +- source/module_cell/unitcell_pseudo.cpp | 30 +- source/module_xc/xc_type.cpp | 112 +-- source/module_xc/xc_type.h | 2 +- source/run_lcao.cpp | 2 +- source/run_pw.cpp | 2 +- source/src_io/print_info.cpp | 10 - 15 files changed, 58 insertions(+), 952 deletions(-) diff --git a/source/module_cell/atom_pseudo.cpp b/source/module_cell/atom_pseudo.cpp index 2002d71a04e..268e83e3ac6 100644 --- a/source/module_cell/atom_pseudo.cpp +++ b/source/module_cell/atom_pseudo.cpp @@ -197,7 +197,7 @@ void Atom_pseudo::bcast_atom_pseudo2(void) //std::string Parallel_Common::bcast_string( psd ); Parallel_Common::bcast_string( pp_type ); - Parallel_Common::bcast_string( dft, 4 ); + Parallel_Common::bcast_string( xc_func ); if(GlobalV::MY_RANK!=0) { diff --git a/source/module_cell/pseudo_nc.cpp b/source/module_cell/pseudo_nc.cpp index bbc5e8270e2..e34d5535d67 100644 --- a/source/module_cell/pseudo_nc.cpp +++ b/source/module_cell/pseudo_nc.cpp @@ -125,10 +125,7 @@ void pseudo_nc::set_pseudo_h(const Pseudopot_upf &upf) this->tvanp = upf.tvanp;// if USPP this->nlcc = upf.nlcc;// Non linear core corrections( bool ?) - for(int i=0; i<4; i++) - { - this->dft[i] = upf.dft[i]; - } + this->xc_func = upf.xc_func; this->zv = upf.zp; this->etotps = upf.etotps; @@ -377,7 +374,7 @@ void pseudo_nc::print_pseudo_h(std::ofstream &ofs) ofs << "\n pp_type " << pp_type; ofs << "\n tvanp " << tvanp; ofs << "\n nlcc " << nlcc; - ofs << "\n dft " << dft; + ofs << "\n dft " << xc_func; ofs << "\n zv " << zv; ofs << "\n etotps " << etotps; ofs << "\n ecutwfc " << ecutwfc; diff --git a/source/module_cell/pseudo_nc.h b/source/module_cell/pseudo_nc.h index 29fa0d81af0..e6d9b280e77 100644 --- a/source/module_cell/pseudo_nc.h +++ b/source/module_cell/pseudo_nc.h @@ -22,7 +22,7 @@ class pseudo_nc std::string pp_type; // Pseudo type ( NC or US ) bool tvanp; // .true. if Ultrasoft bool nlcc; // Non linear core corrections(bool) - std::string dft[4]; // Exch-Corr type + std::string xc_func; // Exch-Corr type int zv; // z valence double etotps; // total energy double ecutwfc; // suggested cut-off for wfc diff --git a/source/module_cell/read_cell_pseudopots.cpp b/source/module_cell/read_cell_pseudopots.cpp index 1861c99398f..ac0f176df16 100644 --- a/source/module_cell/read_cell_pseudopots.cpp +++ b/source/module_cell/read_cell_pseudopots.cpp @@ -82,10 +82,7 @@ void UnitCell_pseudo::read_cell_pseudopots(const std::string &pp_dir, std::ofstr log << "\n Read in pseudopotential file is " << pseudo_fn[i] << std::endl; ModuleBase::GlobalFunc::OUT(log,"pseudopotential type",atoms[i].pp_type); - ModuleBase::GlobalFunc::OUT(log,"functional Ex", atoms[i].dft[0]); - ModuleBase::GlobalFunc::OUT(log,"functional Ec", atoms[i].dft[1]); - ModuleBase::GlobalFunc::OUT(log,"functional GCEx", atoms[i].dft[2]); - ModuleBase::GlobalFunc::OUT(log,"functional GCEc", atoms[i].dft[3]); + ModuleBase::GlobalFunc::OUT(log,"exchange-correlation functional", atoms[i].xc_func); ModuleBase::GlobalFunc::OUT(log,"nonlocal core correction", atoms[i].nlcc); // ModuleBase::GlobalFunc::OUT(log,"spin orbital",atoms[i].has_so); ModuleBase::GlobalFunc::OUT(log,"valence electrons", atoms[i].zv); @@ -100,20 +97,16 @@ void UnitCell_pseudo::read_cell_pseudopots(const std::string &pp_dir, std::ofstr } if(upf.functional_error == 1) { - std::cout << "In Pseudopot_upf::read_pseudo_header : input xc functional does not match that in pseudopot file" << std::endl; + std::cout << "In Pseudopot_upf::read_pseudo_header : dft_functional from INPUT does not match that in pseudopot file" << std::endl; std::cout << "Please make sure this is what you need" << std::endl; - atoms[i].dft[0] = GlobalV::DFT_FUNCTIONAL; - transform(atoms[i].dft[0].begin(), atoms[i].dft[0].end(), atoms[i].dft[0].begin(), (::toupper)); - atoms[i].dft[1].clear(); - atoms[i].dft[2].clear(); - atoms[i].dft[3].clear(); + atoms[i].xc_func = GlobalV::DFT_FUNCTIONAL; + transform(atoms[i].xc_func.begin(), atoms[i].xc_func.end(), atoms[i].xc_func.begin(), (::toupper)); if(GlobalV::MY_RANK==0) { - log << "\n XC functional updated to : " << std::endl; - ModuleBase::GlobalFunc::OUT(log,"functional Ex", atoms[i].dft[0]); - ModuleBase::GlobalFunc::OUT(log,"functional Ec", atoms[i].dft[1]); - ModuleBase::GlobalFunc::OUT(log,"functional GCEx", atoms[i].dft[2]); - ModuleBase::GlobalFunc::OUT(log,"functional GCEc", atoms[i].dft[3]); + log << "\n In Pseudopot_upf::read_pseudo_header : dft_functional from INPUT does not match that in pseudopot file" << std::endl; + log << " Please make sure this is what you need" << std::endl; + log << " XC functional updated to : " << std::endl; + ModuleBase::GlobalFunc::OUT(log,"exchange-correlation functional", atoms[i].xc_func); } } diff --git a/source/module_cell/read_pp.h b/source/module_cell/read_pp.h index 9d400cc9ce6..658c03865b0 100644 --- a/source/module_cell/read_pp.h +++ b/source/module_cell/read_pp.h @@ -32,7 +32,7 @@ class Pseudopot_upf std::string pp_type; // header_3 // Pseudo type ( NC or US ) bool tvanp; // header_4 // .true. if Ultrasoft bool nlcc; // header_5 // Non linear core corrections - std::string dft[4]; // header_6 // Exch-Corr type + std::string xc_func; // header_6 // Exch-Corr type int zp; // header_7 // z valence double etotps; // header_8 // total energy double ecutwfc; // header_9 // suggested cut-off for wfc diff --git a/source/module_cell/read_pp_blps.cpp b/source/module_cell/read_pp_blps.cpp index 16a3bf34d0b..249da34976a 100644 --- a/source/module_cell/read_pp_blps.cpp +++ b/source/module_cell/read_pp_blps.cpp @@ -40,16 +40,12 @@ int Pseudopot_upf::read_pseudo_blps(std::ifstream &ifs) if(pspxc == 2) { - this->dft[0] = "LDA"; - this->dft[1] = "LDA"; + this->xc_func = "LDA"; } else if (pspxc == 11) { - this->dft[0] = "GGA"; - this->dft[1] = "GGA"; + this->xc_func = "GGA"; } - this->dft[2] = "NOGX"; - this->dft[3] = "NOGC"; ifs.ignore(300, '\n'); ifs.ignore(300, '\n'); diff --git a/source/module_cell/read_pp_upf100.cpp b/source/module_cell/read_pp_upf100.cpp index 6e4317f07cf..08b02f2e7b2 100644 --- a/source/module_cell/read_pp_upf100.cpp +++ b/source/module_cell/read_pp_upf100.cpp @@ -168,50 +168,33 @@ void Pseudopot_upf::read_pseudo_header(std::ifstream &ifs) } // mohan modify 2009-12-15 - ifs >> dft[0] >> dft[1] >> dft[2] >> dft[3]; - - //dft[i](i=0-3) gives the four components of xc functional: - //local X, local C, semilocal X, semilocal C - //dft_tot is the name of the combination - std::string dft_tot; - ModuleBase::GlobalFunc::READ_VALUE(ifs, dft_tot); + std::string junk; + ifs >> junk >> junk >> junk >> junk; + ModuleBase::GlobalFunc::READ_VALUE(ifs, xc_func); // dft functional enforced to modify // mohan add 2010-07-15 if(GlobalV::DFT_FUNCTIONAL!="none") { - /*xiaohui modify 2015-03-24 - dft[0] = GlobalV::DFT_FUNCTIONAL; - dft[1] = GlobalV::DFT_FUNCTIONAL; - dft[2] = GlobalV::DFT_FUNCTIONAL; - dft[3] = GlobalV::DFT_FUNCTIONAL; - xiaohui modify 2015-03-24*/ - //xiaohui add 2015-03-23 std::string dft_functional; - if(dft[1] == "PZ") + if(xc_func == "PZ") { dft_functional = "lda"; } - else if(dft[1] == "PBE") + else if(xc_func == "PBE") { dft_functional = "pbe"; } - else if(dft[1] == "SCAN") + else if(xc_func == "SCAN") { dft_functional = "scan"; } - if(dft_tot != GlobalV::DFT_FUNCTIONAL) + if(xc_func != GlobalV::DFT_FUNCTIONAL) { functional_error = 1; - - std::cout << " dft_functional readin is: " << GlobalV::DFT_FUNCTIONAL << std::endl; - std::cout << " dft_functional in pseudopot file is: " << dft_tot << std::endl; - GlobalV::ofs_warning << " dft_functional readin is: " << GlobalV::DFT_FUNCTIONAL << std::endl; - GlobalV::ofs_warning << " dft_functional in pseudopot file is: " << dft_tot << std::endl; - //ModuleBase::WARNING_QUIT("Pseudopot_upf::read_pseudo_header","input xc functional does not match that in pseudopot file"); } } @@ -460,7 +443,7 @@ void Pseudopot_upf::print_pseudo_upf(std::ofstream &ofs) ofs << " pp_type: " << pp_type << std::endl; ofs << " tvanp: " << tvanp << std::endl; ofs << " nlcc: " << nlcc << std::endl; - ofs << " dft: " << dft[0] << " " << dft[1] << " " << dft[2] << " " << dft[3] << std::endl; + ofs << " dft: " << xc_func << std::endl; ofs << " zp: " << zp << std::endl; ofs << " etotps: " << etotps << std::endl; ofs << " ecutwfc: " << ecutwfc << std::endl; diff --git a/source/module_cell/read_pp_upf201.cpp b/source/module_cell/read_pp_upf201.cpp index 774e8f161fa..d2813baa6e5 100644 --- a/source/module_cell/read_pp_upf201.cpp +++ b/source/module_cell/read_pp_upf201.cpp @@ -68,11 +68,7 @@ int Pseudopot_upf::read_pseudo_upf201(std::ifstream &ifs) nlcc = false; } else if(name[ip]=="functional"){ - std::stringstream wdsstream(val[ip]); - for( int idft = 0; idft < 4; idft++ ) - { - getline(wdsstream,dft[idft],'-'); - } + xc_func = val[ip]; } else if(name[ip]=="z_valence"){ zp = atoi(val[ip].c_str()); @@ -394,776 +390,18 @@ int Pseudopot_upf::read_pseudo_upf201(std::ifstream &ifs) if(GlobalV::DFT_FUNCTIONAL!="none") { - if(dft[0] != GlobalV::DFT_FUNCTIONAL) + if(xc_func != GlobalV::DFT_FUNCTIONAL) { functional_error = 1; std::cout << " dft_functional readin is: " << GlobalV::DFT_FUNCTIONAL << std::endl; - std::cout << " dft_functional in pseudopot file is: " << dft[0] << std::endl; + std::cout << " dft_functional in pseudopot file is: " << xc_func << std::endl; GlobalV::ofs_warning << " dft_functional readin is: " << GlobalV::DFT_FUNCTIONAL << std::endl; - GlobalV::ofs_warning << " dft_functional in pseudopot file is: " << dft[0] << std::endl; + GlobalV::ofs_warning << " dft_functional in pseudopot file is: " << xc_func << std::endl; } } return 0; - //qianrui remove it 2020-5-10 - /*while (ifs.good()) - { - ifs >> dummy; - // We start from PP_Header - if(dummy=="psd,'"'); - getline(wdsstream,this->psd,'"'); - - ifs >> word; // pseudo_type - if(word == "pseudo_type=\"") - { - ifs >> word; - get_char(word); - this->pp_type = word.substr(0,Number[0]); - } - else - { - get_char(word); - this->pp_type = word.substr(Number[0]+1,(Number[1]-Number[0]-1)); - } - - if(pp_type!="NC") - { - ModuleBase::WARNING_QUIT("Pseudopot_upf::read_pseudo_header","unknown pseudo type"); - } - - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // relativistic - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // is_ultrasoft - if ( word.find("\"T\"") < word.length() ) // zws add 20160108 - { - std::cout << "\n WARNING: ULTRASOFT PSEUDOPOTENTIAL IS NOT SUPPORTED !!! \n" << std::endl; - } - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // is_paw - if ( word.find("\"T\"") < word.length() ) - { - std::cout << "\n WARNING: PAW PSEUDOPOTENTIAL IS NOT SUPPORTED !!! \n" << std::endl; - } - - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // is_coulomb - ifs >> word; // has_so - std::string so; - - if(word == "has_so=\"") - { - ifs >> word; - get_char(word); - so = word.substr(0,Number[0]); - } - else - { - get_char(word); - so = word.substr(Number[0]+1,(Number[1]-Number[0]-1)); - } - - if (so == "T") - { - this->has_so = true; - } - else - { - this->has_so = false; - } - - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // has_wfc - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // has_gipaw - - std::string nlc; - //char p[13] = "paw_as_gipaw"; - ifs >> word; // paw_as_gipaw? - //std::cout << "word.substr(0,30) = " << word.substr(0,30) << "."<< std::endl; - if( word.substr(0,13) == "paw_as_gipaw" ) - { - ONCVPSP = 0; - ifs >> word; // core_correction - if(word == "core_correction=\"") - { - ifs >> word; - get_char(word); - nlc = word.substr(0,Number[0]); - } - else - { - get_char(word); - nlc = word.substr(Number[0]+1,(Number[1]-Number[0]-1)); - } - - } - else - { - ONCVPSP = 1; // Generated using ONCVPSP code by D. R. Hamann, SG15 DOJO - if(word == "core_correction=\"") - { - ifs >> word; - get_char(word); - nlc = word.substr(0,Number[0]); - } - else - { - get_char(word); - nlc = word.substr(Number[0]+1,(Number[1]-Number[0]-1)); - } - } - - //std::cout << "nlc = " << nlc << std::endl; - - if (nlc == "T") - { - this->nlcc = true; - } - else - { - this->nlcc = false; - } - - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // functional - //std::cout << "word = " << word << std::endl; - // this->dft[0]="SLA"; - // this->dft[1]="PZ"; - // this->dft[2]="NOGX"; - // this->dft[3]="NOGC"; - - std::string funcstr; //{zws 01-06-16 - wdsstream.str(""); - wdsstream.clear(); - wdsstream << word; - for ( int idft = 0; idft < 2; idft++) - { - getline(wdsstream,funcstr,'"'); - } - wdsstream.str(""); - wdsstream.clear(); - wdsstream << funcstr; - - for( int idft = 0; idft < 4; idft++ ) - { - getline(wdsstream,dft[idft],'-'); - } - - do - { - getline(ifs, word); - //std::cout << "word = " << word << std::endl; - word.erase(0,word.find_first_not_of(" ") ); - word.erase(word.find_last_not_of(" ")+1 ); - //word = trim(word); - //std::cout << "trim(word) = " << word << std::endl; - get_char(word); - //std::cout << " Number = " << Number[0] << ", " << Number[1] << std::endl; - //std::cout << word.substr(0,Number[0]) << "__" << word.substr(Number[0]+1, Number[1]-Number[0]-1) << std::endl; - dummy = word.substr(0,Number[0]) ; - //std::cout << " dummy = " << dummy << std::endl; - if( dummy == "z_valence=" ) - { - this->zp = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - else if ( dummy == "total_psenergy=" ) - { - this->etotps = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - else if ( dummy == "rho_cutoff=" ) - { - } - else if ( dummy == "wfc_cutoff=" ) - { - } - else if ( dummy == "l_max=" ) - { - this->lmax = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - else if ( dummy == "mesh_size=" ) - { - this->mesh = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - else if ( dummy == "number_of_wfc=" ) - { - this->nwfc = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - else if ( dummy == "number_of_proj=" ) - { - this->nbeta = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - //break; - - }while( word.substr(word.length()-1, 1) !=">" ); - //std::cout << "word.substr(word.length()-1, 1)=" << word.substr(word.length()-1, 1) << std::endl; - //exit(0); - - - //ifs >> word; // zp - ////std::cout << "word = " << word << std::endl; - //{ - // if(word == "z_valence=\"") - // { - // ifs >> word; - // get_char(word); - // this->zp = atoi(word.substr(0,Number[0]).c_str()); - // } - // else - // { - // get_char(word); - // this->zp = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - // } - // //std::cout << "zp = " << this->zp << std::endl; - //} - - //ifs >> word; // total_psenergy - //{ - // if(word == "total_psenergy=\"") - // { - // ifs >> word; - // get_char(word); - // this->etotps = atof(word.substr(0,Number[0]).c_str()); - // } - // else - // { - // get_char(word); - // this->etotps = atof(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - // } - // //std::cout << "etotps = " << this->etotps << std::endl; - //} - ////std::cout << " word (total_psenergy) = " << word << std::endl; - - - //if(ONCVPSP == 0) //zws modify 20160108 - //{ - // ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // wfc_cutoff - // //std::cout << "word = " << word << std::endl; - //} - //ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // rho_cutoff - //std::cout << "word (cutoff) = " << word << std::endl; - - - //ifs >> word; // lmax - ////std::cout << "word (lmax) = " << word << std::endl; - //{ - // if(word == "l_max=\"") - // { - // ifs >> word; - // get_char(word); - // this->lmax = atoi(word.substr(0,Number[0]).c_str()); - // } - // else - // { - // get_char(word); - // this->lmax = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - // } - - //} - - ////std::cout << "lmax = " << this->lmax << std::endl; - - //if(ONCVPSP == 0) - //{ - // ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // l_max_rho - //} - - //ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // l_local - - //ifs >> word; // mesh_size - ////std::cout << "word (mesh) = " << word << std::endl; - //{ - // if(word == "mesh_size=\"") - // { - // ifs >> word; - // get_char(word); - // this->mesh = atoi(word.substr(0,Number[0]).c_str()); - // } - // else - // { - // get_char(word); - // this->mesh = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - // } - // //std::cout << "mesh = " << this->mesh << std::endl; - //} - - - - //ifs >> word; // number_of_wfc - ////std::cout << "word = " << word << std::endl; - //{ - // if(word == "number_of_wfc=\"") - // { - // ifs >> word; - // get_char(word); - // this->nwfc = atoi(word.substr(0,Number[0]).c_str()); - - // } - // else - // { - // get_char(word); - // this->nwfc = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - // } - // //std::cout << "nwfc = " << this->nwfc << std::endl; - //} - // - //ifs >> word; // number_of_proj - ////std::cout << "word = " << word << std::endl; - //{ - // if(word == "number_of_proj=\"") - // { - // ifs >> word; - // get_char(word); - // this->nbeta = atoi(word.substr(0,Number[0]).c_str()); - - // } - // else - // { - // get_char(word); - // this->nbeta = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - // } - // //std::cout << "nbeta = " << this->nbeta << std::endl; - //} - - - // READ Mesh - if(ONCVPSP == 0) - { - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, ""); - } - - assert(mesh>0); - if(ONCVPSP == 0) - { - ifs >> word; // dx - ifs >> word; // mesh - ifs >> word; // xmin - ifs >> word; // rmax - ifs >> word; // zmesh - } - - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, "> rmesh0; - // if ( abs(rmesh0) < 1.0e-15 ) - // { - // mesh -= 1; - // nmeshdel += 1; - // } - // std::cout << " mesh =" << mesh << std::endl; - // if (mesh%2 == 0) - // { - // mesh -= 1; - // nmeshdel += 1; - // } //}zws add 20160108 - // std::cout << " nmeshdel =" << nmeshdel << std::endl; - - - delete[] r; - delete[] rab; - this->r = new double[mesh]; - this->rab = new double[mesh]; - ModuleBase::GlobalFunc::ZEROS(r,mesh); - ModuleBase::GlobalFunc::ZEROS(rab,mesh); - - - // if (nmeshdel == 0) //{zws add160108 delete160328 - // { - // this->r[0] = rmesh0; - // for (ir = 1;ir < mesh;ir++) - // { - // ifs >> this->r[ir]; - // } - // } - // else - // { - // for ( int idel=0; idel < nmeshdel-1; idel++) - // { - // std::cout << "skip " << nmeshdel << "grid point(s) in PP mesh" << std::endl; - // double tmpdel; - // ifs >> tmpdel; - // } - // for (ir = 0;ir < mesh;ir++) - // { - // ifs >> this->r[ir]; - // } - // } //}zws 20160108 - for (ir = 0;ir < mesh;ir++) - { - ifs >> this->r[ir]; - } - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, "> tmpdel; - // } //}zws add 20160108 - for (ir = 0;ir < mesh;ir++) - { - ifs >> this->rab[ir]; - } - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - // READ NLCC - if (this->nlcc) - { - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, "0); - delete[] rho_atc; - this->rho_atc = new double[mesh]; - ModuleBase::GlobalFunc::ZEROS(rho_atc, mesh); - - for (ir = 0;ir < mesh;ir++) - { - ifs >> this->rho_atc[ir]; - } - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - } - - // READ VLOCAL - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, "0); - delete[] vloc; - this->vloc = new double[mesh]; - ModuleBase::GlobalFunc::ZEROS(vloc, mesh); - - for (ir = 0;ir < mesh;ir++) - { - ifs >> this->vloc[ir]; - } - - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - // READ NONLOCAL - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, ""); - - delete[] kkbeta; - delete[] lll; - this->kkbeta = new int[nbeta]; - this->lll = new int[nbeta]; - this->beta.create(nbeta , mesh); - this->dion.create(nbeta , nbeta); - - for(i=0;i> word; //number - ifs >> word; //type - if(word == "type=\"") - { - ifs >> word; - } - ifs >> word; //size - if(word == "size=\"") - { - ifs >> word; - } - - ifs >> word; //columns - if(word == "columns=\"") - { - ifs >> word; - } - - ifs >> word; //index - { - if(word == "index=\"") - { - ifs >> word; - get_char(word); - //idum = atoi(word.substr(0,Number[0]).c_str()); - } - else - { - get_char(word); - //idum = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - //std::cout << "idum = " << idum << std::endl; - } - - if(ONCVPSP == 0) - { - ifs >> word; //label - } - - ifs >> word; //angular_momentum - if(word == "angular_momentum=\"") - { - ifs >> word; - get_char(word); - this->lll[i] = atoi(word.substr(0,Number[0]).c_str()); - - } - else - { - get_char(word); - this->lll[i] = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - - ifs >> word; //cutoff_radius_index - if(word == "cutoff_radius_index=\"") - { - ifs >> word; - get_char(word); - this->kkbeta[i] = atoi(word.substr(0,Number[0]).c_str()); - - } - else - { - get_char(word); - this->kkbeta[i] = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - //std::cout << "kkbeta[i] = " << this->kkbeta[i] << std::endl; - - if(ONCVPSP ==0) - { - ifs >> word; //cutoff_radius - ifs >> word; //ultrasoft_cutoff_radius - } - else - { - ModuleBase::GlobalFunc::READ_VALUE(ifs, word); // cutoff_radius - } - - for (ir=0;ir> this->beta(i, ir); - - } - - ifs >> word; //number - - } - - // READ DIJ - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, "nd = nbeta * nbeta; - for(i=0;i> dion(i,j); - if ( i != j && dion(i,j) != 0.0 ) - { - std::cout << " error: for i != j, Dij of Pseudopotential must be 0.0 " << std::endl; - exit(1); - } - } - } - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - // READ PSWFC - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, ""); - - delete[] els; - delete[] lchi; - delete[] oc; - this->els = new std::string[nwfc]; - this->lchi = new int[nwfc]; - this->oc = new double[nwfc]; - ModuleBase::GlobalFunc::ZEROS(lchi, nwfc); // angular momentum of each orbital - ModuleBase::GlobalFunc::ZEROS(oc, nwfc);//occupation of each orbital - - this->chi.create(this->nwfc, this->mesh); - for (i=0;i> word; // number - ifs >> word; // type - ifs >> word; // size - { - if(word == "size=\"") - { - ifs >> word; - word = "\"" + word ; - } - } - ifs >> word; // columns - ifs >> word; // index - ifs >> word; // occupation - { - if(word == "occupation=\"") - { - ifs >> word; - word = "\"" + word ; - } - get_char(word); - oc[i] = atof(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - - ifs >> word; // pseudo_energy - if(word == "pseudo_energy=\"") - { - ifs >> word; - word = "\"" + word ; - } - get_char(word); - - ifs >> word; // label - if(word == "label=\"") - { - ifs >> word; - word = "\"" + word ; - } - get_char(word); - els[i] = word.substr(Number[0]+1,(Number[1]-Number[0]-1)); - - ifs >> word; // l - if(word == "l=\"") - { - ifs >> word; - word = "\"" + word ; - } - get_char(word); - lchi[i] = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - //std::cout << " lchi[i] = " << lchi[i] << std::endl; - - ifs >> word; // > - if ( word != ">" ) - { - std::cout << " error: bad end while reading CHI" << i << " of PSWFC" << std::endl; - exit(1); - } - - for (ir = 0;ir < mesh;ir++) - { - ifs >> this->chi(i, ir); - } - ifs >> word; // number - } - - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - // READ RHOATOM - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, "rho_at = new double[mesh]; - ModuleBase::GlobalFunc::ZEROS(rho_at, mesh); - - for (ir = 0;ir < mesh;ir++) - { - ifs >> this->rho_at[ir]; - } - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - - ModuleBase::GlobalFunc::SCAN_BEGIN(ifs, ""); - //added by zhengdy-soc - delete[] this->jchi; - delete[] this->jjj; - delete[] this->nn; - this->jchi = new double [nwfc]; - this->jjj = new double [nbeta]; - this->nn = new int [nwfc]; - ModuleBase::GlobalFunc::ZEROS(jchi,nwfc); - ModuleBase::GlobalFunc::ZEROS(jjj,nbeta); - ModuleBase::GlobalFunc::ZEROS(nn,nwfc); - - for(int round=0;round<2;round++) - { - ifs>>word; - if(word==">word; //RELBETA - ifs>>word; //index - ifs>>word; //lll - get_char(word); - this->lll[nb] = atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - ifs>>word; //jjj - get_char(word); - this->jjj[nb] = atof(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - } - } - else if(word==">word; //RELWFC - ifs>>word; //index - ifs>>word; //els - get_char(word); - this->els[nw]= word.substr(Number[0]+1,(Number[1]-Number[0]-1)); - ifs>>word; //nn - get_char(word); - this->nn[nw]= atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - ifs>>word; //lchi - get_char(word); - this->lchi[nw]= atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - ifs>>word; //jchi - get_char(word); - this->jchi[nw]= atof(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - ifs>>word; //oc - get_char(word); - this->oc[nw]= atof(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - - } - } - else - { - for(int nw = 0;nw>word;//RELWFC - ifs>>word; //index - ifs>>word; //lchi - get_char(word); - this->lchi[nw]= atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - ifs>>word; //jchi - get_char(word); - this->jchi[nw]= atof(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - ifs>>word; - get_char(word); - this->nn[nw]= atoi(word.substr(Number[0]+1,(Number[1]-Number[0]-1)).c_str()); - - } - } - } - else if(round==0) - { - this->has_so = 0; - // std::cout<<"ignore SPIN_ORB part!"<"); - - if (mesh%2 == 0) - { - mesh -= 1; - } - - ModuleBase::GlobalFunc::SCAN_END(ifs, ""); - break; - } - } - return 0;*/ } void Pseudopot_upf:: getnameval(std::ifstream& ifs,int &n, std::string * name, std::string *val) { diff --git a/source/module_cell/read_pp_vwr.cpp b/source/module_cell/read_pp_vwr.cpp index b54d16d54d5..94249bd9b96 100644 --- a/source/module_cell/read_pp_vwr.cpp +++ b/source/module_cell/read_pp_vwr.cpp @@ -23,10 +23,7 @@ int Pseudopot_upf::read_pseudo_vwr(std::ifstream &ifs) // -------------------------------------- // (1) read in data // -------------------------------------- - this->dft[0]="SLA"; - this->dft[1]="PZ"; - this->dft[2]="NOGX"; - this->dft[3]="NOGC"; + this->xc_func="PZ"; this->pp_type="NC"; this->tvanp=false; GlobalV::ofs_running << " Always use PZ-LDA by now." << std::endl; diff --git a/source/module_cell/unitcell_pseudo.cpp b/source/module_cell/unitcell_pseudo.cpp index fa8474512e5..6c683b81f75 100644 --- a/source/module_cell/unitcell_pseudo.cpp +++ b/source/module_cell/unitcell_pseudo.cpp @@ -271,32 +271,18 @@ void UnitCell_pseudo::setup_cell( for(int it=0; itcal_natomwfc(log); diff --git a/source/module_xc/xc_type.cpp b/source/module_xc/xc_type.cpp index 44c65a7c13d..706480cb880 100644 --- a/source/module_xc/xc_type.cpp +++ b/source/module_xc/xc_type.cpp @@ -20,87 +20,37 @@ const std::string gradc[10] = { "NOGC", "P86", "GGC", "BLYP", "PBC", "HCTH", "ME // from function.f90 //----------------------------------------------------------------------- -void xcfunc::which_dft(const std::string *dft) +void xcfunc::which_dft(const std::string xc_func) { //----------------------------------------------------------------------- // translates a std::string containing the exchange-correlation name // into internal indices iexch, icorr, igcx, igcc - const int nxc = 10; // number of exchange functional - const int ncc = 12; // number of correlation functional - const int ngcx = 14; // number of gradient correction for exchange functional - const int ngcc = 10; // number of gradient correction for correlation functional - - //int l=0; - int i=0; int notset = -1; - // (1) exchange this->iexch = notset; - - for (i = 0;i < nxc;i++) - { - if (exc[i] == dft[0]) - { - set_dft_value(iexch, i); - } - } - - // (2) correlation this->icorr = notset; - - for (i = 0;i < ncc;i++) - { - if (corr[i] == dft[1]) - { - set_dft_value(icorr, i); - } - } - - // (3) gradient correction, exchange this->igcx = notset; - for (i = 0;i < ngcx;i++) - { - if (gradx[i] == dft[2]) - { - set_dft_value(igcx, i); - } - } - - // (4) gradient correction, correlation this->igcc = notset; - for (i = 0;i < ngcc;i++) - { - if (gradc[i] == dft[3]) - { - set_dft_value(igcc, i); - } - } - + //======================= Second Part =============================== // special case : BLYP => B88 for gradient correction on exchange - static int itype = 0; - ++itype; - std::stringstream ss; - ss << " ELEMENT " << itype << " FUNCTIONAL : "; -// std::cout << ss.str() << dft[0] << " " << dft[1] << " " << dft[2] << " " << dft[3] << std::endl; - - if( match_one( dft, "PBE0")) + if( xc_func == "PBE0") { set_dft_value(iexch,6); set_dft_value(icorr,4); set_dft_value(igcx,8); set_dft_value(igcc,4); } - if( match_one( dft, "LDA")) + if( xc_func == "LDA" || xc_func == "PZ") { set_dft_value(iexch,1); set_dft_value(icorr,1); set_dft_value(igcx,0); set_dft_value(igcc,0); } - else if ( match_one(dft, "PBE") ) + else if ( xc_func == "PBE" ) { // special case : PBE set_dft_value(iexch, 1); @@ -108,7 +58,7 @@ void xcfunc::which_dft(const std::string *dft) set_dft_value(igcx, 3); set_dft_value(igcc, 4); } - else if( match_one( dft, "revPBE" ) ) + else if( xc_func == "revPBE" ) { // special case : revPBE set_dft_value(iexch,1); @@ -116,34 +66,36 @@ void xcfunc::which_dft(const std::string *dft) set_dft_value(igcx, 4); set_dft_value(igcc, 4); } - else if ( match_one(dft, "PBEsol") ) + else if ( xc_func == "PBEsol") { set_dft_value(iexch, 1); set_dft_value(icorr, 4); set_dft_value(igcx, 10); set_dft_value(igcc, 8); } - else if ( match_one(dft, "WC") ) + else if ( xc_func == "WC") { set_dft_value(iexch, 1); set_dft_value(icorr, 4); set_dft_value(igcx, 11); set_dft_value(igcc, 4); } - else if ( match_one( dft, "BLYP") ) + else if ( xc_func == "BLYP") { set_dft_value(iexch, 1); set_dft_value(icorr, 3); set_dft_value(igcx, 1); set_dft_value(igcc, 3); } - else if ( match_one(dft, "BP") ) + else if ( xc_func == "BP") { // special case : BP = B88 + P86 + set_dft_value(iexch, 0); + set_dft_value(icorr, 0); set_dft_value(igcx, 1); set_dft_value(igcc, 1); } - else if ( match_one(dft, "PW91") ) + else if ( xc_func == "PW91") { // special case : PW91 = GGX + GGC set_dft_value(iexch, 1); @@ -151,18 +103,15 @@ void xcfunc::which_dft(const std::string *dft) set_dft_value(igcx, 2); set_dft_value(igcc, 2); } - else if ( match_one(dft, "HCTH") ) + else if ( xc_func == "HCTH") { // special case : HCTH already contains LDA exchange and correlation set_dft_value(iexch, 0); set_dft_value(icorr, 0); + set_dft_value(igcx, 5); + set_dft_value(igcc, 5); } - else if ( match_one(dft, "OPTX") ) - { - // special case : OPTX already contains LDA exchange - set_dft_value(iexch, 0); - } - else if (match_one(dft, "OLYP") ) + else if ( xc_func == "OLYP") { // special case : OLYP = OPTX + LYP set_dft_value(iexch, 0); @@ -170,7 +119,7 @@ void xcfunc::which_dft(const std::string *dft) set_dft_value(igcx, 6); set_dft_value(igcc, 3); } - else if ( match_one(dft, "SCAN") ) + else if ( xc_func == "SCAN") { // special case : SCAN already contains LDA exchange and correlation set_dft_value(iexch, 0); @@ -206,18 +155,6 @@ void xcfunc::which_dft(const std::string *dft) set_dft_value(igcc, 0); } -// std::cout << "\n iexch = " << iexch; -// std::cout << "\n icorr = " << icorr; -// std::cout << "\n igcx = " << igcx; -// std::cout << "\n igcc = " << igcc << std::endl; - - //std::cout << "\n corr = " << exc[icorr]; - //std::cout << " corr = " << corr[icorr]; - //std::cout << " gradx = " << gradx[igcx]; - //std::cout << " gradc = " << gradc[igcc] << std::endl; - //'-'//corr (icorr) //'-'//gradx (igcx) //'-'//gradc (igcc) - // WRITE( stdout,'(a)') dftout - copy_to_now(); hybrid_first(); @@ -232,7 +169,7 @@ void xcfunc::set_dft_value(int &m,const int i) if (m != notset && m != i) { - std::cerr << "\n set_dft_value, two conflicting matching values,"; // 1); + std::cerr << "\n set_dft_value, two conflicting matching values,"; } m = i; return; @@ -250,7 +187,6 @@ void xcfunc::printdft(std::ofstream &ofs) << " -> " << gradc[igcc]; } - void xcfunc::ostreamdft(std::ostream &ofs) // zws add 20150108 { if ( iexch == 1 && icorr == 1 && igcx == 0 && igcc == 0 ) @@ -270,16 +206,6 @@ void xcfunc::ostreamdft(std::ostream &ofs) // zws add 20150108 } } - -bool xcfunc::match_one(const std::string* dft, const std::string &name)const -{ - for(int i=0; i<4; i++) - { - if(dft[i]==name) return 1; // match one of the four std::string. - } - return 0; // no one match -} - // Peize Lin add 2016-12-03 void xcfunc::copy_to_now() { diff --git a/source/module_xc/xc_type.h b/source/module_xc/xc_type.h index 4fd10f5955b..2d6082c7167 100644 --- a/source/module_xc/xc_type.h +++ b/source/module_xc/xc_type.h @@ -120,7 +120,7 @@ class xcfunc ~xcfunc(); // there are four values of dft. - void which_dft(const std::string *dft); + void which_dft(const std::string xc_func); void printdft(std::ofstream &ofs); void ostreamdft(std::ostream &ofs); // zws add 20150108 private: diff --git a/source/run_lcao.cpp b/source/run_lcao.cpp index dad53cf0cde..5410274a729 100644 --- a/source/run_lcao.cpp +++ b/source/run_lcao.cpp @@ -60,7 +60,7 @@ void Run_lcao::lcao_line(void) // I warn the user again for each type. for(int it=0; it Date: Wed, 9 Feb 2022 21:14:26 +0800 Subject: [PATCH 03/36] xc refactor : rearranged potential_libxc.cpp not finished yet, but working --- source/module_xc/potential_libxc.cpp | 667 ++++++++++++++------------- source/module_xc/potential_libxc.h | 3 + source/src_pw/forces.cpp | 2 +- source/src_pw/potential.cpp | 2 +- 4 files changed, 347 insertions(+), 327 deletions(-) diff --git a/source/module_xc/potential_libxc.cpp b/source/module_xc/potential_libxc.cpp index 96b4fe6fee1..5ac0fc11874 100644 --- a/source/module_xc/potential_libxc.cpp +++ b/source/module_xc/potential_libxc.cpp @@ -23,6 +23,9 @@ // [etxc, vtxc, v] = Potential_Libxc::v_xc(...) std::tuple Potential_Libxc::v_xc( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell const double * const * const rho_in, const double * const rho_core_in) { @@ -31,7 +34,7 @@ std::tuple Potential_Libxc::v_xc( double etxc = 0.0; double vtxc = 0.0; - ModuleBase::matrix v(GlobalV::NSPIN,GlobalC::pw.nrxx); + ModuleBase::matrix v(GlobalV::NSPIN,nrxx); if(GlobalV::VXC_IN_H == 0 ) { @@ -44,258 +47,49 @@ std::tuple Potential_Libxc::v_xc( // use can check on website, for example: // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ //---------------------------------------------------------- - std::vector funcs = init_func(); - - // the type of rho_sigma_gdr is automatically set to 'tuple' - // [rho, sigma, gdr] = cal_input( funcs, rho_in ); - const auto rho_sigma_gdr = cal_input( funcs, rho_in, rho_core_in ); - const std::vector &rho = std::get<0>(rho_sigma_gdr); - const std::vector &sigma = std::get<1>(rho_sigma_gdr); - - for( xc_func_type &func : funcs ) - { - // jiyy add for threshold - constexpr double rho_threshold = 1E-6; - constexpr double grho_threshold = 1E-10; - xc_func_set_dens_threshold(&func, rho_threshold); - // sgn for threshold mask - const std::vector sgn = [&]() -> std::vector - { - std::vector sgn( GlobalC::pw.nrxx * nspin0(), 1.0); - if(nspin0()==2 && func.info->family != XC_FAMILY_LDA && func.info->kind==XC_CORRELATION) - { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - if ( rho[ir*2] exc ( GlobalC::pw.nrxx ); - std::vector vrho ( GlobalC::pw.nrxx * nspin0() ); - std::vector vsigma( GlobalC::pw.nrxx * ((1==nspin0())?1:3) ); - - // cal etxc from rho, exc - auto process_exc = [&]() - { - for( size_t is=0; is!=nspin0(); ++is ) - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; - }; - - // cal vtx, v from rho_in, vrho - auto process_vrho = [&]() - { - if(nspin0()==1 || GlobalV::NSPIN==2) - { - for( size_t is=0; is!=nspin0(); ++is ) - { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - const double v_tmp = ModuleBase::e2 * vrho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; - v(is,ir) += v_tmp; - vtxc += v_tmp * rho_in[is][ir]; - } - } - } - else // may need updates for SOC - { - constexpr double vanishing_charge = 1.0e-12; - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - std::vector v_tmp(4); - v_tmp[0] = ModuleBase::e2 * (0.5 * (vrho[ir*2] + vrho[ir*2+1])); - const double vs = 0.5 * (vrho[ir*2] - vrho[ir*2+1]); - const double amag = sqrt( pow(rho_in[1][ir],2) - + pow(rho_in[2][ir],2) - + pow(rho_in[3][ir],2) ); - - if(amag>vanishing_charge) - { - for(int ipol=1; ipol<4; ++ipol) - { - v_tmp[ipol] = ModuleBase::e2 * vs * rho_in[ipol][ir] / amag; - } - } - for(int ipol=0; ipol<4; ++ipol) - { - v(ipol, ir) += v_tmp[ipol]; - vtxc += v_tmp[ipol] * rho_in[ipol][ir]; - } - } - } - - }; - - // cal vtxc, v from rho_in, rho, gdr, vsigma - auto process_vsigma = [&]() - { - const std::vector>> &gdr = std::get<2>(rho_sigma_gdr); - - std::vector>> h( nspin0(), std::vector>(GlobalC::pw.nrxx) ); - if( 1==nspin0() ) - { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - h[0][ir] = ModuleBase::e2 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; - } - } - else - { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - h[0][ir] = ModuleBase::e2 * (gdr[0][ir] * vsigma[ir*3 ] * 2.0 * sgn[ir*2 ] - + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); - h[1][ir] = ModuleBase::e2 * (gdr[1][ir] * vsigma[ir*3+2] * 2.0 * sgn[ir*2+1] - + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); - } - } - - // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] - std::vector> dh(nspin0(), std::vector(GlobalC::pw.nrxx)); - for( size_t is=0; is!=nspin0(); ++is ) - GGA_PW::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); - - for( size_t is=0; is!=nspin0(); ++is ) - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - vtxc -= dh[is][ir] * rho[ir*nspin0()+is]; - - if(nspin0()==1 || GlobalV::NSPIN==2) - { - for( size_t is=0; is!=nspin0(); ++is ) - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - v(is,ir) -= dh[is][ir]; - } - else // may need updates for SOC - { - constexpr double vanishing_charge = 1.0e-12; - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - v(0,ir) -= 0.5 * (dh[0][ir] + dh[1][ir]); - const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); - const double neg = (GlobalC::ucell.magnet.lsign_ - && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0]+rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1]+rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) - ? -1 : 1; - if(amag > vanishing_charge) - { - for(int i=1;i<4;i++) - v(i,ir) -= neg * 0.5 * (dh[0][ir]-dh[1][ir]) * rho_in[i][ir] / amag; - } - } - } - }; - - //------------------------------------------------------------------ - // "func.info->family" includes LDA, GGA, Hybrid functional (HYB). - //------------------------------------------------------------------ - switch( func.info->family ) - { - case XC_FAMILY_LDA: - // call Libxc function: xc_lda_exc_vxc - xc_lda_exc_vxc( &func, GlobalC::pw.nrxx, rho.data(), - exc.data(), vrho.data() ); - process_exc(); - process_vrho(); - break; - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - // call Libxc function: xc_gga_exc_vxc - xc_gga_exc_vxc( &func, GlobalC::pw.nrxx, rho.data(), sigma.data(), - exc.data(), vrho.data(), vsigma.data() ); - process_exc(); - process_vrho(); - process_vsigma(); - break; - default: - throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(func.info->family) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - break; - } - // Libxc function: Deallocate memory - xc_func_end(&func); - } - - //------------------------------------------------- - // for MPI, reduce the exchange-correlation energy - //------------------------------------------------- - Parallel_Reduce::reduce_double_pool( etxc ); - Parallel_Reduce::reduce_double_pool( vtxc ); - - etxc *= GlobalC::ucell.omega / GlobalC::pw.ncxyz; - vtxc *= GlobalC::ucell.omega / GlobalC::pw.ncxyz; - - ModuleBase::timer::tick("Potential_Libxc","v_xc"); - return std::make_tuple( etxc, vtxc, std::move(v) ); -} - - -//---------------------------------------------------------------------------- -// for adding new xc functionals, only this function needs to be updated -// now we use iexch, igcx, icorr, igcc in xcf to characterize XC functionals -//---------------------------------------------------------------------------- -std::vector Potential_Libxc::init_func() -{ - // 'funcs' is the return value - std::vector funcs; + xc_func_type x_func; + xc_func_type c_func; const int xc_polarized = (1==nspin0()) ? XC_UNPOLARIZED : XC_POLARIZED; - - //------------------------------------------- - // define a function named 'add_func', which - // will be called in the following codes - //------------------------------------------- - auto add_func = [&]( const int function ) - { - funcs.push_back({}); - // 'xc_func_init' is defined in Libxc - xc_func_init( &funcs.back(), function, xc_polarized ); - }; - //-------------------------------------- - // for the exchange energy + // determine exchange functional //-------------------------------------- if( 6==GlobalC::xcf.iexch_now && 8==GlobalC::xcf.igcx_now && 4==GlobalC::xcf.icorr_now && 4==GlobalC::xcf.igcc_now ) // GGA functional { - add_func( XC_HYB_GGA_XC_PBEH ); + xc_func_init( &x_func, XC_HYB_GGA_XC_PBEH, xc_polarized ); double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, GlobalC::exx_global.info.hse_omega, GlobalC::exx_global.info.hse_omega }; - xc_func_set_ext_params(&funcs.back(), parameter_hse); - return funcs; + xc_func_set_ext_params( &x_func, parameter_hse); } else if( 9==GlobalC::xcf.iexch_now && 12==GlobalC::xcf.igcx_now && 4==GlobalC::xcf.icorr_now && 4==GlobalC::xcf.igcc_now ) // HSE06 hybrid functional { - add_func( XC_HYB_GGA_XC_HSE06 ); + xc_func_init( &x_func, XC_HYB_GGA_XC_HSE06, xc_polarized ); double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, GlobalC::exx_global.info.hse_omega, GlobalC::exx_global.info.hse_omega }; - xc_func_set_ext_params(&funcs.back(), parameter_hse); - return funcs; + xc_func_set_ext_params(&x_func, parameter_hse); } if( 1==GlobalC::xcf.iexch_now && 0==GlobalC::xcf.igcx_now ) // LDA functional { - add_func( XC_LDA_X ); + xc_func_init( &x_func, XC_LDA_X, xc_polarized ); } else if( 1==GlobalC::xcf.iexch_now && 3==GlobalC::xcf.igcx_now ) // GGA functional { - add_func( XC_GGA_X_PBE ); + xc_func_init( &x_func, XC_GGA_X_PBE, xc_polarized ); } else if(GlobalC::xcf.igcx_now == 13 ) //SCAN_X { - add_func(263); + xc_func_init( &x_func, 263, xc_polarized ); } else { @@ -304,19 +98,19 @@ std::vector Potential_Libxc::init_func() } //-------------------------------------- - // for the correlation energy part + // determine correlation functional //-------------------------------------- if( 1==GlobalC::xcf.icorr_now && 0==GlobalC::xcf.igcc_now ) { - add_func( XC_LDA_C_PZ ); + xc_func_init( &c_func, XC_LDA_C_PZ, xc_polarized ); } else if( 4==GlobalC::xcf.icorr_now && 4==GlobalC::xcf.igcc_now ) { - add_func( XC_GGA_C_PBE ); + xc_func_init( &c_func, XC_GGA_C_PBE, xc_polarized ); } else if (GlobalC::xcf.igcc_now == 9) { - add_func( 267 ); + xc_func_init( &c_func, 267, xc_polarized ); } else { @@ -324,140 +118,363 @@ std::vector Potential_Libxc::init_func() +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); } - return funcs; -} + bool is_gga = false; + switch( x_func.info->family ) + { + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + is_gga = true; + break; + } + switch( c_func.info->family ) + { + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + is_gga = true; + break; + } + // converting rho + std::vector rho; + rho.resize(GlobalC::pw.nrxx*nspin0()); + if(nspin0()==1 || GlobalV::NSPIN==2) + { + for( int is=0; is!=nspin0(); ++is ) + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + rho[ir*nspin0()+is] = rho_in[is][ir] + 1.0/nspin0()*rho_core_in[ir]; + } + else // may need updates for SOC + { + if(GlobalC::xcf.igcx||GlobalC::xcf.igcc) + { + GlobalC::ucell.cal_ux(); + } + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); + const double neg = (GlobalC::ucell.magnet.lsign_ && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0] + +rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1] + +rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) + ? -1 : 1; + rho[ir*2] = 0.5 * (rho_in[0][ir] + neg * amag) + 0.5 * rho_core_in[ir]; + rho[ir*2+1] = 0.5 * (rho_in[0][ir] - neg * amag) + 0.5 * rho_core_in[ir]; + } + } + std::vector>> gdr; + std::vector sigma; + if(is_gga) + { + // calculating grho + gdr.resize( nspin0() ); + for( int is=0; is!=nspin0(); ++is ) + { + std::vector rhor(GlobalC::pw.nrxx); + for(int ir=0; ir> rhog(GlobalC::pw.ngmc); + GlobalC::CHR.set_rhog(rhor.data(), rhog.data()); + + //------------------------------------------- + // compute the gradient of charge density and + // store the gradient in gdr[is] + //------------------------------------------- + gdr[is].resize(GlobalC::pw.nrxx); + GGA_PW::grad_rho(rhog.data(), gdr[is].data()); + } -// [rho, sigma, gdr] = Potential_Libxc::cal_input(...) -std::tuple< std::vector, - std::vector, - std::vector>> > -Potential_Libxc::cal_input( - const std::vector &funcs, - const double * const * const rho_in, - const double * const rho_core_in ) -{ - // ..., ↑_{i},↓_{i}, ↑_{i+1},↓_{i+1}, ... - std::vector rho; - bool finished_rho = false; + // converting grho + sigma.resize( nrxx * ((1==nspin0())?1:3) ); + + if( 1==nspin0() ) + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + sigma[ir] = gdr[0][ir]*gdr[0][ir]; + } + } + else + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + sigma[ir*3] = gdr[0][ir]*gdr[0][ir]; + sigma[ir*3+1] = gdr[0][ir]*gdr[1][ir]; + sigma[ir*3+2] = gdr[1][ir]*gdr[1][ir]; + } + } + } + + // jiyy add for threshold + constexpr double rho_threshold = 1E-10; + xc_func_set_dens_threshold(&x_func, rho_threshold); + // sgn for threshold mask + std::vector sgn( nrxx * nspin0(), 1.0); + + for( int ir=0; ir!= nrxx * nspin0(); ++ir ) + { + if ( rho[ir] exc ( nrxx ); + std::vector vrho ( nrxx * nspin0() ); + std::vector vsigma( nrxx * ((1==nspin0())?1:3) ); + + switch( x_func.info->family ) + { + case XC_FAMILY_LDA: + // call Libxc function: xc_lda_exc_vxc + xc_lda_exc_vxc( &x_func, nrxx, rho.data(), + exc.data(), vrho.data() ); + break; + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + // call Libxc function: xc_gga_exc_vxc + xc_gga_exc_vxc( &x_func, nrxx, rho.data(), sigma.data(), + exc.data(), vrho.data(), vsigma.data() ); + break; + default: + throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(x_func.info->family) + +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + break; + } + for( int is=0; is!=nspin0(); ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; + } + } - // here we assume rho_core equally exists in different spins, may need double check - auto cal_rho = [&]() + if(nspin0()==1 || GlobalV::NSPIN==2) { - if(!finished_rho) + for( int is=0; is!=nspin0(); ++is ) { - rho.resize(GlobalC::pw.nrxx*nspin0()); - if(nspin0()==1 || GlobalV::NSPIN==2) + for( int ir=0; ir!= nrxx; ++ir ) { - for( size_t is=0; is!=nspin0(); ++is ) - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - rho[ir*nspin0()+is] = rho_in[is][ir] + 1.0/nspin0()*rho_core_in[ir]; + const double v_tmp = ModuleBase::e2 * vrho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; + v(is,ir) += v_tmp; + vtxc += v_tmp * rho_in[is][ir]; } - else // may need updates for SOC + } + } + else // may need updates for SOC + { + constexpr double vanishing_charge = 1.0e-12; + for( int ir=0; ir!= nrxx; ++ir ) + { + std::vector v_tmp(4); + v_tmp[0] = ModuleBase::e2 * (0.5 * (vrho[ir*2] + vrho[ir*2+1])); + const double vs = 0.5 * (vrho[ir*2] - vrho[ir*2+1]); + const double amag = sqrt( pow(rho_in[1][ir],2) + + pow(rho_in[2][ir],2) + + pow(rho_in[3][ir],2) ); + + if(amag>vanishing_charge) { - if(GlobalC::xcf.igcx||GlobalC::xcf.igcc) + for(int ipol=1; ipol<4; ++ipol) { - GlobalC::ucell.cal_ux(); + v_tmp[ipol] = ModuleBase::e2 * vs * rho_in[ipol][ir] / amag; } - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + } + for(int ipol=0; ipol<4; ++ipol) + { + v(ipol, ir) += v_tmp[ipol]; + vtxc += v_tmp[ipol] * rho_in[ipol][ir]; + } + } + } + + if(x_func.info->family == XC_FAMILY_GGA || x_func.info->family == XC_FAMILY_HYB_GGA) + { + std::vector>> h( nspin0(), std::vector>(nrxx) ); + if( 1==nspin0() ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = ModuleBase::e2 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; + } + } + else + { + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = ModuleBase::e2 * (gdr[0][ir] * vsigma[ir*3 ] * 2.0 * sgn[ir*2 ] + + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + h[1][ir] = ModuleBase::e2 * (gdr[1][ir] * vsigma[ir*3+2] * 2.0 * sgn[ir*2+1] + + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + } + } + + // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] + std::vector> dh(nspin0(), std::vector( nrxx)); + for( int is=0; is!=nspin0(); ++is ) + GGA_PW::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); + + for( int is=0; is!=nspin0(); ++is ) + for( int ir=0; ir!= nrxx; ++ir ) + vtxc -= dh[is][ir] * rho[ir*nspin0()+is]; + + if(nspin0()==1 || GlobalV::NSPIN==2) + { + for( int is=0; is!=nspin0(); ++is ) + for( int ir=0; ir!= nrxx; ++ir ) + v(is,ir) -= dh[is][ir]; + } + else // may need updates for SOC + { + constexpr double vanishing_charge = 1.0e-12; + for( int ir=0; ir!= nrxx; ++ir ) + { + v(0,ir) -= 0.5 * (dh[0][ir] + dh[1][ir]); + const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); + const double neg = (GlobalC::ucell.magnet.lsign_ + && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0]+rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1]+rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) + ? -1 : 1; + if(amag > vanishing_charge) { - const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); - const double neg = (GlobalC::ucell.magnet.lsign_ && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0] - +rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1] - +rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) - ? -1 : 1; - rho[ir*2] = 0.5 * (rho_in[0][ir] + neg * amag) + 0.5 * rho_core_in[ir]; - rho[ir*2+1] = 0.5 * (rho_in[0][ir] - neg * amag) + 0.5 * rho_core_in[ir]; + for(int i=1;i<4;i++) + v(i,ir) -= neg * 0.5 * (dh[0][ir]-dh[1][ir]) * rho_in[i][ir] / amag; } } } - finished_rho = true; - }; - - // [...,↑_{i},↑_{i+1},...], [...,↓_{i},↓_{i+1},...] - std::vector>> gdr; - bool finished_gdr = false; - auto cal_gdr = [&]() + } + + switch( c_func.info->family ) { - if(!finished_gdr) + case XC_FAMILY_LDA: + // call Libxc function: xc_lda_exc_vxc + xc_lda_exc_vxc( &c_func, nrxx, rho.data(), + exc.data(), vrho.data() ); + break; + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + // call Libxc function: xc_gga_exc_vxc + xc_gga_exc_vxc( &c_func, nrxx, rho.data(), sigma.data(), + exc.data(), vrho.data(), vsigma.data() ); + break; + default: + throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(c_func.info->family) + +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + break; + } + for( int is=0; is!=nspin0(); ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) { - gdr.resize( nspin0() ); - for( size_t is=0; is!=nspin0(); ++is ) + etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; + } + } + + if(nspin0()==1 || GlobalV::NSPIN==2) + { + for( int is=0; is!=nspin0(); ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) { - std::vector rhor(GlobalC::pw.nrxx); - for(int ir=0; ir> rhog(GlobalC::pw.ngmc); - GlobalC::CHR.set_rhog(rhor.data(), rhog.data()); - - //------------------------------------------- - // compute the gradient of charge density and - // store the gradient in gdr[is] - //------------------------------------------- - gdr[is].resize(GlobalC::pw.nrxx); - GGA_PW::grad_rho(rhog.data(), gdr[is].data()); + const double v_tmp = ModuleBase::e2 * vrho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; + v(is,ir) += v_tmp; + vtxc += v_tmp * rho_in[is][ir]; } } - finished_gdr = true; - }; - - // ..., ↑↑_{i},↑↓_{i},↓↓_{i}, ↑↑_{i+1},↑↓_{i+1},↓↓_{i+1}, ... - std::vector sigma; - bool finished_sigma = false; - auto cal_sigma = [&]() + } + else // may need updates for SOC { - if(!finished_sigma) + constexpr double vanishing_charge = 1.0e-12; + for( int ir=0; ir!= nrxx; ++ir ) { - sigma.resize( GlobalC::pw.nrxx * ((1==nspin0())?1:3) ); - - if( 1==nspin0() ) + std::vector v_tmp(4); + v_tmp[0] = ModuleBase::e2 * (0.5 * (vrho[ir*2] + vrho[ir*2+1])); + const double vs = 0.5 * (vrho[ir*2] - vrho[ir*2+1]); + const double amag = sqrt( pow(rho_in[1][ir],2) + + pow(rho_in[2][ir],2) + + pow(rho_in[3][ir],2) ); + + if(amag>vanishing_charge) { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for(int ipol=1; ipol<4; ++ipol) { - sigma[ir] = gdr[0][ir]*gdr[0][ir]; + v_tmp[ipol] = ModuleBase::e2 * vs * rho_in[ipol][ir] / amag; } } - else + for(int ipol=0; ipol<4; ++ipol) { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - sigma[ir*3] = gdr[0][ir]*gdr[0][ir]; - sigma[ir*3+1] = gdr[0][ir]*gdr[1][ir]; - sigma[ir*3+2] = gdr[1][ir]*gdr[1][ir]; - } + v(ipol, ir) += v_tmp[ipol]; + vtxc += v_tmp[ipol] * rho_in[ipol][ir]; } } - finished_sigma = true; - }; + } - for( const xc_func_type &func : funcs ) - { - switch( func.info->family ) + if(c_func.info->family == XC_FAMILY_GGA || c_func.info->family == XC_FAMILY_HYB_GGA) + { + std::vector>> h( nspin0(), std::vector>(nrxx) ); + if( 1==nspin0() ) { - case XC_FAMILY_LDA: - cal_rho(); - break; - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - case XC_FAMILY_MGGA: - cal_rho(); - cal_gdr(); - cal_sigma(); - break; - default: - throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(func.info->family) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - break; + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = ModuleBase::e2 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; + } + } + else + { + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = ModuleBase::e2 * (gdr[0][ir] * vsigma[ir*3 ] * 2.0 * sgn[ir*2 ] + + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + h[1][ir] = ModuleBase::e2 * (gdr[1][ir] * vsigma[ir*3+2] * 2.0 * sgn[ir*2+1] + + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + } + } + + // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] + std::vector> dh(nspin0(), std::vector( nrxx)); + for( int is=0; is!=nspin0(); ++is ) + GGA_PW::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); + + for( int is=0; is!=nspin0(); ++is ) + for( int ir=0; ir!= nrxx; ++ir ) + vtxc -= dh[is][ir] * rho[ir*nspin0()+is]; + + if(nspin0()==1 || GlobalV::NSPIN==2) + { + for( int is=0; is!=nspin0(); ++is ) + for( int ir=0; ir!= nrxx; ++ir ) + v(is,ir) -= dh[is][ir]; + } + else // may need updates for SOC + { + constexpr double vanishing_charge = 1.0e-12; + for( int ir=0; ir!= nrxx; ++ir ) + { + v(0,ir) -= 0.5 * (dh[0][ir] + dh[1][ir]); + const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); + const double neg = (GlobalC::ucell.magnet.lsign_ + && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0]+rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1]+rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) + ? -1 : 1; + if(amag > vanishing_charge) + { + for(int i=1;i<4;i++) + v(i,ir) -= neg * 0.5 * (dh[0][ir]-dh[1][ir]) * rho_in[i][ir] / amag; + } + } } } - - return std::make_tuple( std::move(rho), std::move(sigma), std::move(gdr) ); + + //------------------------------------------------- + // for MPI, reduce the exchange-correlation energy + //------------------------------------------------- + Parallel_Reduce::reduce_double_pool( etxc ); + Parallel_Reduce::reduce_double_pool( vtxc ); + + etxc *= omega / ncxyz; + vtxc *= omega / ncxyz; + + ModuleBase::timer::tick("Potential_Libxc","v_xc"); + return std::make_tuple( etxc, vtxc, std::move(v) ); } #endif //ifdef USE_LIBXC diff --git a/source/module_xc/potential_libxc.h b/source/module_xc/potential_libxc.h index fc5c05c7934..d98d99fa842 100644 --- a/source/module_xc/potential_libxc.h +++ b/source/module_xc/potential_libxc.h @@ -27,6 +27,9 @@ class Potential_Libxc //------------------------------------------------ // [etxc, vtxc, v] = v_xc(...) static std::tuple v_xc( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell const double * const * const rho_in, const double * const rho_core_in); diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index 143a0e6a286..97708256c17 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -571,7 +571,7 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) } else { - const auto etxc_vtxc_v = Potential_Libxc::v_xc(GlobalC::CHR.rho, GlobalC::CHR.rho_core); + const auto etxc_vtxc_v = Potential_Libxc::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index d59089e2cae..acafb3e10be 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -338,7 +338,7 @@ ModuleBase::matrix Potential::v_of_rho( } else { - const std::tuple etxc_vtxc_v = Potential_Libxc::v_xc(rho_in, GlobalC::CHR.rho_core); + const std::tuple etxc_vtxc_v = Potential_Libxc::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); From 5d8b45f651f011a4c12234e7346948ec24492295 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Feb 2022 21:59:18 +0800 Subject: [PATCH 04/36] xc refactor : move etxc and vtxc to energy class --- source/module_xc/H_XC_pw.cpp | 42 +++++++++++++++----------------- source/module_xc/H_XC_pw.h | 40 ------------------------------ source/module_xc/xc_functional.h | 10 ++++++++ source/src_io/eximport.cpp | 3 +-- source/src_lcao/FORCE_STRESS.cpp | 3 +-- source/src_pw/energy.cpp | 7 +++--- source/src_pw/energy.h | 2 ++ source/src_pw/forces.cpp | 18 +++++++------- source/src_pw/potential.cpp | 15 ++++++------ source/src_pw/stress_func_cc.cpp | 8 +++--- source/src_pw/stress_pw.cpp | 3 +-- 11 files changed, 57 insertions(+), 94 deletions(-) delete mode 100644 source/module_xc/H_XC_pw.h diff --git a/source/module_xc/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp index 8b814f73935..5b84ee71b71 100644 --- a/source/module_xc/H_XC_pw.cpp +++ b/source/module_xc/H_XC_pw.cpp @@ -1,14 +1,10 @@ -#include "H_XC_pw.h" #include "xc_functional.h" #include "xc_gga_pw.h" #include "../src_parallel/parallel_reduce.h" #include "../module_base/timer.h" -double H_XC_pw::etxc; -double H_XC_pw::vtxc; - -// [etxc, vtxc, v] = H_XC_pw::v_xc(...) -std::tuple H_XC_pw::v_xc +// [etxc, vtxc, v] = XC_Functional::v_xc(...) +std::tuple XC_Functional::v_xc ( const int &nrxx, // number of real-space grid const int &ncxyz, // total number of charge grid @@ -26,14 +22,14 @@ std::tuple H_XC_pw::v_xc } #endif //Exchange-Correlation potential Vxc(r) from n(r) - double et_xc = 0.0; - double vt_xc = 0.0; + double etxc = 0.0; + double vtxc = 0.0; ModuleBase::matrix v(GlobalV::NSPIN, nrxx); if(GlobalV::VXC_IN_H == 0) { ModuleBase::timer::tick("H_XC_pw","v_xc"); - return std::make_tuple(et_xc, vt_xc, std::move(v)); + return std::make_tuple(etxc, vtxc, std::move(v)); } // the square of the e charge // in Rydeberg unit, so * 2.0. @@ -65,9 +61,9 @@ std::tuple H_XC_pw::v_xc XC_Functional::xc(arhox, ex, ec, vx[0], vc[0]); v(0,ir) = e2 * (vx[0] + vc[0]); // consider the total charge density - et_xc += e2 * (ex + ec) * rhox; + etxc += e2 * (ex + ec) * rhox; // only consider rho_in - vt_xc += v(0, ir) * rho_in[0][ir]; + vtxc += v(0, ir) * rho_in[0][ir]; } // endif } //enddo } @@ -111,9 +107,9 @@ std::tuple H_XC_pw::v_xc v(is, ir) = e2 * (vx[is] + vc[is]); } - et_xc += e2 * (ex + ec) * rhox; + etxc += e2 * (ex + ec) * rhox; - vt_xc += v(0, ir) * rho_in[0][ir] + v(1, ir) * rho_in[1][ir]; + vtxc += v(0, ir) * rho_in[0][ir] + v(1, ir) * rho_in[1][ir]; } } @@ -143,10 +139,10 @@ std::tuple H_XC_pw::v_xc XC_Functional::xc_spin( arhox, zeta, ex, ec, vx[0], vx[1], vc[0], vc[1] ); - et_xc += e2 * ( ex + ec ) * rhox; + etxc += e2 * ( ex + ec ) * rhox; v(0, ir) = e2*( 0.5 * ( vx[0] + vc[0] + vx[1] + vc[1] ) ); - vt_xc += v(0,ir) * rho_in[0][ir]; + vtxc += v(0,ir) * rho_in[0][ir]; double vs = 0.5 * ( vx[0] + vc[0] - vx[1] - vc[1] ); if ( amag > vanishing_charge ) @@ -154,7 +150,7 @@ std::tuple H_XC_pw::v_xc for(int ipol = 1;ipol< 4;ipol++) { v(ipol, ir) = e2 * vs * rho_in[ipol][ir] / amag; - vt_xc += v(ipol,ir) * rho_in[ipol][ir]; + vtxc += v(ipol,ir) * rho_in[ipol][ir]; }//end do }//end if }//end if @@ -164,16 +160,16 @@ std::tuple H_XC_pw::v_xc // add gradient corrections (if any) // mohan modify 2009-12-15 - GGA_PW::gradcorr(et_xc, vt_xc, v); + GGA_PW::gradcorr(etxc, vtxc, v); - // parallel code : collect vt_xc,et_xc + // parallel code : collect vtxc,etxc // mohan add 2008-06-01 - Parallel_Reduce::reduce_double_pool( et_xc ); - Parallel_Reduce::reduce_double_pool( vt_xc ); + Parallel_Reduce::reduce_double_pool( etxc ); + Parallel_Reduce::reduce_double_pool( vtxc ); - et_xc *= omega / ncxyz; - vt_xc *= omega / ncxyz; + etxc *= omega / ncxyz; + vtxc *= omega / ncxyz; ModuleBase::timer::tick("H_XC_pw","v_xc"); - return std::make_tuple(et_xc, vt_xc, std::move(v)); + return std::make_tuple(etxc, vtxc, std::move(v)); } diff --git a/source/module_xc/H_XC_pw.h b/source/module_xc/H_XC_pw.h deleted file mode 100644 index 8cda7a09059..00000000000 --- a/source/module_xc/H_XC_pw.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef H_XC_PW_H -#define H_XC_PW_H - -#include "../module_base/global_function.h" -#include "../module_base/global_variable.h" -#include "../module_base/matrix.h" - -class H_XC_pw -{ - public: - - friend class Stress_Func; - friend class Stress_PW; - friend class Forces; - friend class Force_Stress_LCAO; - friend class Potential; - friend class energy; - friend class eximport; - - H_XC_pw(); - ~H_XC_pw(); - - private: - - // the Hartree energy - static double etxc; - static double vtxc; - - // compute the exchange-correlation energy - // [etxc, vtxc, v] = v_xc(...) - static std::tuple v_xc( - const int &nrxx, // number of real-space grid - const int &ncxyz, // total number of charge grid - const double &omega, // volume of cell - const double*const*const rho_in, - const double*const rho_core); // core charge density - -}; - -#endif //Exchange-correlation energy diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 7f61f050780..f4ebd77f29e 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -12,6 +12,7 @@ #include "../module_base/global_function.h" #include "../module_base/global_variable.h" #include "../module_base/vector3.h" +#include "../module_base/matrix.h" class XC_Functional { public: @@ -19,6 +20,15 @@ class XC_Functional XC_Functional(); ~XC_Functional(); + // compute the exchange-correlation energy + // [etxc, vtxc, v] = v_xc(...) + static std::tuple v_xc( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell + const double*const*const rho_in, + const double*const rho_core); // core charge density + // LDA static void xc(const double &rho, double &ex, double &ec, double &vx, double &vc); diff --git a/source/src_io/eximport.cpp b/source/src_io/eximport.cpp index a263f81df47..cbff6ea81d1 100644 --- a/source/src_io/eximport.cpp +++ b/source/src_io/eximport.cpp @@ -701,7 +701,6 @@ void eximport::in_evc(std::ifstream &in) //=========== #include "../src_pw/H_Ewald_pw.h" #include "../src_pw/H_Hartree_pw.h" -#include "../module_xc/H_XC_pw.h" void eximport::out_energy(std::ofstream &out_data) { //std::cout << "\n ==> out_energy" << std::endl; @@ -711,7 +710,7 @@ void eximport::out_energy(std::ofstream &out_data) out_data << std::setw(20) << GlobalC::en.eband << std::endl; //6.4 out_data << std::setw(20) << GlobalC::en.eband + GlobalC::en.deband << std::endl; //6.5 out_data << std::setw(20) << H_Hartree_pw::hartree_energy << std::endl; - out_data << std::setw(20) << H_XC_pw::etxc - GlobalC::en.etxcc << std::endl; //6.7 + out_data << std::setw(20) << GlobalC::en.etxc - GlobalC::en.etxcc << std::endl; //6.7 out_data << std::setw(20) << H_Ewald_pw::ewald_energy << std::endl; //6.8 } diff --git a/source/src_lcao/FORCE_STRESS.cpp b/source/src_lcao/FORCE_STRESS.cpp index 80c4e9acae8..8c5b30fc6a9 100644 --- a/source/src_lcao/FORCE_STRESS.cpp +++ b/source/src_lcao/FORCE_STRESS.cpp @@ -3,7 +3,6 @@ #include "../module_xc/potential_libxc.h" #include "./dftu.h" //Quxin add for DFT+U on 20201029 // new -#include "../module_xc/H_XC_pw.h" #include "../src_pw/vdwd2.h" #include "../src_pw/vdwd3.h" #include "../module_base/timer.h" @@ -814,7 +813,7 @@ void Force_Stress_LCAO::calStressPwPart( //-------------------------------------------------------- for(int i=0;i<3;i++) { - sigmaxc(i,i) = -(H_XC_pw::etxc) / GlobalC::ucell.omega; + sigmaxc(i,i) = -(GlobalC::en.etxc) / GlobalC::ucell.omega; } //Exchange-correlation for PBE sc_pw.stress_gga(sigmaxc); diff --git a/source/src_pw/energy.cpp b/source/src_pw/energy.cpp index 89ce329e8e2..4d67ef8fe0e 100644 --- a/source/src_pw/energy.cpp +++ b/source/src_pw/energy.cpp @@ -16,7 +16,6 @@ //new #include "H_Ewald_pw.h" #include "H_Hartree_pw.h" -#include "../module_xc/H_XC_pw.h" #ifdef __DEEPKS #include "../src_lcao/../module_deepks/LCAO_deepks.h" #endif @@ -55,7 +54,7 @@ void energy::calculate_harris(const int &flag) else if(flag==2) { this->etot_harris = eband + deband_harris - + (H_XC_pw::etxc - etxcc) + + (etxc - etxcc) + H_Ewald_pw::ewald_energy + H_Hartree_pw::hartree_energy + demet @@ -93,7 +92,7 @@ void energy::calculate_etot(void) ModuleBase::TITLE("energy","calculate_etot"); //std::cout << "\n demet in etot = " << demet << std::endl; this->etot = eband + deband - + (H_XC_pw::etxc - etxcc) + + (etxc - etxcc) + H_Ewald_pw::ewald_energy + H_Hartree_pw::hartree_energy + demet @@ -171,7 +170,7 @@ void energy::print_etot( this->print_format("E_band", eband); this->print_format("E_one_elec", eband + deband); this->print_format("E_Hartree", H_Hartree_pw::hartree_energy); - this->print_format("E_xc", H_XC_pw::etxc - etxcc); + this->print_format("E_xc", etxc - etxcc); this->print_format("E_Ewald", H_Ewald_pw::ewald_energy); this->print_format("E_demet", demet); //mohan add 2011-12-02 this->print_format("E_descf", descf); diff --git a/source/src_pw/energy.h b/source/src_pw/energy.h index 4c63f6b07bf..41c68721dde 100644 --- a/source/src_pw/energy.h +++ b/source/src_pw/energy.h @@ -47,6 +47,8 @@ class energy double descf; double etxcc; // the nlcc exchange and correlation + double etxc; + double vtxc; double exx; // the exact exchange energy. double evdw; // the vdw energy // Peize Lin add 2021.03.09 diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index 97708256c17..9af4afeccbd 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -4,7 +4,7 @@ #include "vdwd3.h" #include "../module_symmetry/symmetry.h" // new -#include "../module_xc/H_XC_pw.h" +#include "../module_xc/xc_functional.h" #include "../module_base/math_integral.h" #include "../module_xc/potential_libxc.h" #include "../src_parallel/parallel_reduce.h" @@ -565,21 +565,21 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) if(GlobalV::DFT_META) { const auto etxc_vtxc_v = Potential_Libxc::v_xc_meta(GlobalC::CHR.rho, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); - H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); - H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); - v = std::get<2>(etxc_vtxc_v); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); + GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); + v = std::get<2>(etxc_vtxc_v); } else { const auto etxc_vtxc_v = Potential_Libxc::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); - H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); - H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); + GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); } #else - const auto etxc_vtxc_v = H_XC_pw::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); - H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); // may delete? - H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); // may delete? + const auto etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); + GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); #endif diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index acafb3e10be..adb00d10bb5 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -10,7 +10,6 @@ #include "../module_xc/potential_libxc.h" // new #include "H_Hartree_pw.h" -#include "../module_xc/H_XC_pw.h" #ifdef __LCAO #include "../src_lcao/ELEC_evolve.h" #endif @@ -331,23 +330,23 @@ ModuleBase::matrix Potential::v_of_rho( if(GlobalV::DFT_META) { const std::tuple etxc_vtxc_v = Potential_Libxc::v_xc_meta(rho_in, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); - H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); - H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); + GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); vofk = std::get<3>(etxc_vtxc_v); } else { const std::tuple etxc_vtxc_v = Potential_Libxc::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); - H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); - H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); + GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); } #else - const std::tuple etxc_vtxc_v = H_XC_pw::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); + const std::tuple etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); - H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); - H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); + GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); #endif diff --git a/source/src_pw/stress_func_cc.cpp b/source/src_pw/stress_func_cc.cpp index b5150e4b829..9e4b6e005bf 100644 --- a/source/src_pw/stress_func_cc.cpp +++ b/source/src_pw/stress_func_cc.cpp @@ -1,5 +1,5 @@ #include "./stress_func.h" -#include "../module_xc/H_XC_pw.h" +#include "../module_xc/xc_functional.h" #include "../module_base/math_integral.h" #include "../module_base/timer.h" @@ -35,9 +35,9 @@ void Stress_Func::stress_cc(ModuleBase::matrix& sigma, const bool is_pw) } //recalculate the exchange-correlation potential - const auto etxc_vtxc_v = H_XC_pw::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); - H_XC_pw::etxc = std::get<0>(etxc_vtxc_v); // may delete? - H_XC_pw::vtxc = std::get<1>(etxc_vtxc_v); // may delete? + const auto etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); // may delete? + GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); // may delete? const ModuleBase::matrix vxc = std::get<2>(etxc_vtxc_v); std::complex * psic = new std::complex [GlobalC::pw.nrxx]; diff --git a/source/src_pw/stress_pw.cpp b/source/src_pw/stress_pw.cpp index 885a1d948f8..702748a2a58 100644 --- a/source/src_pw/stress_pw.cpp +++ b/source/src_pw/stress_pw.cpp @@ -1,5 +1,4 @@ #include "./stress_pw.h" -#include "../module_xc/H_XC_pw.h" #include "vdwd2.h" #include "vdwd3.h" #include "../module_base/timer.h" @@ -64,7 +63,7 @@ void Stress_PW::cal_stress(ModuleBase::matrix& sigmatot) //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) / GlobalC::ucell.omega; + sigmaxc(i,i) = - (GlobalC::en.etxc - GlobalC::en.vtxc) / GlobalC::ucell.omega; } stress_gga(sigmaxc); if(GlobalV::DFT_META) stress_mgga(sigmaxc); From b37eb9917e4e6abba4f7b71e28d336651145268b Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Thu, 10 Feb 2022 23:01:51 +0800 Subject: [PATCH 05/36] xc refactor : replace (except for hybrid functionals) class xc_func by two ID's identifying the type of exchange and correlation functional which is consistent with LIBXC --- source/input.cpp | 21 +- source/input.h | 2 - source/input_conv.cpp | 42 +- source/module_base/global_variable.cpp | 2 +- source/module_base/tool_title.cpp | 6 +- source/module_cell/read_cell_pseudopots.cpp | 2 +- source/module_cell/read_pp_upf100.cpp | 23 +- source/module_cell/read_pp_upf201.cpp | 2 +- source/module_deepks/LCAO_deepks.h | 1 + source/module_xc/H_XC_pw.cpp | 29 +- source/module_xc/exx_global.h | 19 - source/module_xc/potential_libxc.cpp | 424 ++++------ source/module_xc/potential_libxc.h | 49 -- source/module_xc/potential_libxc_meta.cpp | 18 +- source/module_xc/xc_functional.cpp | 851 +++++++++----------- source/module_xc/xc_functional.h | 93 ++- source/module_xc/xc_gga_pw.cpp | 94 +-- source/module_xc/xc_gga_pw.h | 24 - source/module_xc/xc_type.cpp | 203 ----- source/run_lcao.cpp | 27 +- source/run_pw.cpp | 10 +- source/src_io/print_info.cpp | 24 +- source/src_io/print_info.h | 3 +- source/src_io/write_input.cpp | 2 +- source/src_ions/ions.cpp | 4 +- source/src_lcao/ELEC_scf.cpp | 3 +- source/src_lcao/LOOP_elec.cpp | 3 - source/src_pw/forces.cpp | 4 +- source/src_pw/global.h | 2 +- source/src_pw/potential.cpp | 5 +- source/src_pw/run_md_pw.cpp | 2 - source/src_pw/stress_func_gga.cpp | 42 +- source/src_pw/stress_func_mgga.cpp | 3 +- 33 files changed, 684 insertions(+), 1355 deletions(-) delete mode 100644 source/module_xc/xc_gga_pw.h diff --git a/source/input.cpp b/source/input.cpp index 919e973740e..99c9df1a93b 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -355,7 +355,7 @@ void Input::Default(void) //---------------------------------------------------------- // exx //Peize Lin add 2018-06-20 //---------------------------------------------------------- - exx_hybrid_type = "no"; + dft_functional = "default"; exx_hybrid_alpha = 0.25; exx_hse_omega = 0.11; @@ -1490,9 +1490,9 @@ bool Input::Read(const std::string &fn) // exx // Peize Lin add 2018-06-20 //---------------------------------------------------------- - else if (strcmp("exx_hybrid_type", word) == 0) + else if (strcmp("dft_functional", word) == 0) { - read_value(ifs, exx_hybrid_type); + read_value(ifs, dft_functional); } else if (strcmp("exx_hybrid_alpha", word) == 0) { @@ -2258,7 +2258,7 @@ void Input::Bcast() Parallel_Common::bcast_double( eps_degauss ); // Peize Lin add 2018-06-20 - Parallel_Common::bcast_string( exx_hybrid_type ); + Parallel_Common::bcast_string( dft_functional ); Parallel_Common::bcast_double( exx_hybrid_alpha ); Parallel_Common::bcast_double( exx_hse_omega ); Parallel_Common::bcast_bool( exx_separate_loop ); @@ -2862,16 +2862,7 @@ void Input::Check(void) } } - if(exx_hybrid_type!="no" && - exx_hybrid_type!="hf" && - exx_hybrid_type!="pbe0" && - exx_hybrid_type!="hse" && - exx_hybrid_type!="opt_orb") - { - ModuleBase::WARNING_QUIT("INPUT","exx_hybrid_type must be no or hf or pbe0 or hse or opt_orb"); - } - - if(exx_hybrid_type=="hf" || exx_hybrid_type=="pbe0" || exx_hybrid_type=="hse") + if(dft_functional=="hf" || dft_functional=="pbe0" || dft_functional=="hse") { if(exx_hybrid_alpha<0 || exx_hybrid_alpha>1) { @@ -2893,7 +2884,7 @@ void Input::Check(void) ModuleBase::WARNING_QUIT("INPUT","exx_distribute_type must be htime or kmeans2 or kmeans1"); } } - if(exx_hybrid_type=="opt_orb") + if(dft_functional=="opt_orb") { if(exx_opt_orb_lmax<0) { diff --git a/source/input.h b/source/input.h index acd6f778f30..19ad262fecb 100644 --- a/source/input.h +++ b/source/input.h @@ -360,8 +360,6 @@ class Input // exx // Peize Lin add 2018-06-20 //========================================================== - std::string exx_hybrid_type; // "no", "hf", "pbe0", "hse" - double exx_hybrid_alpha; double exx_hse_omega; diff --git a/source/input_conv.cpp b/source/input_conv.cpp index 648d451ad43..e8a6e8d663c 100644 --- a/source/input_conv.cpp +++ b/source/input_conv.cpp @@ -419,7 +419,7 @@ void Input_Conv::Convert(void) const std::string command0 = "test -d " + GlobalC::restart.folder + " || mkdir " + GlobalC::restart.folder; if (GlobalV::MY_RANK == 0) system(command0.c_str()); - if (INPUT.exx_hybrid_type == "no") + if (INPUT.dft_functional == "no") { GlobalC::restart.info_save.save_charge = true; } @@ -432,7 +432,7 @@ void Input_Conv::Convert(void) if (INPUT.restart_load) { GlobalC::restart.folder = GlobalV::global_out_dir + "restart/"; - if (INPUT.exx_hybrid_type == "no") + if (INPUT.dft_functional == "hf" || INPUT.dft_functional == "pbe0" || INPUT.dft_functional == "hse" || INPUT.dft_functional == "opt_orb") { GlobalC::restart.info_load.load_charge = true; } @@ -447,28 +447,30 @@ void Input_Conv::Convert(void) // about exx, Peize Lin add 2018-06-20 //---------------------------------------------------------- #ifdef __LCAO - if (INPUT.exx_hybrid_type == "no") + + if (INPUT.dft_functional == "hf") { - GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::No; + GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::HF; + } + else if (INPUT.dft_functional == "pbe0") + { + GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::PBE0; + } + else if (INPUT.dft_functional == "hse") + { + GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::HSE; + } + else if (INPUT.dft_functional == "opt_orb") + { + GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::Generate_Matrix; } else { - if (INPUT.exx_hybrid_type == "hf") - { - GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::HF; - } - else if (INPUT.exx_hybrid_type == "pbe0") - { - GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::PBE0; - } - else if (INPUT.exx_hybrid_type == "hse") - { - GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::HSE; - } - else if (INPUT.exx_hybrid_type == "opt_orb") - { - GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::Generate_Matrix; - } + GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::No; + } + + if(GlobalC::exx_global.info.hybrid_type != Exx_Global::Hybrid_Type::No) + { GlobalC::exx_global.info.hybrid_alpha = INPUT.exx_hybrid_alpha; GlobalC::exx_global.info.hse_omega = INPUT.exx_hse_omega; GlobalC::exx_global.info.separate_loop = INPUT.exx_separate_loop; diff --git a/source/module_base/global_variable.cpp b/source/module_base/global_variable.cpp index f1bb46a1604..82d4ec9a19d 100644 --- a/source/module_base/global_variable.cpp +++ b/source/module_base/global_variable.cpp @@ -29,7 +29,7 @@ std::string CALCULATION = "scf"; int EFIELD = 0; // 5: add electric field int DIPOLE = 0; // 7: add dipole field -std::string DFT_FUNCTIONAL = "none"; +std::string DFT_FUNCTIONAL = "default"; bool DFT_META = 0; int NSPIN = 1; // LDA bool TWO_EFERMI = 0; // two fermi energy, exist only magnetization is fixed. diff --git a/source/module_base/tool_title.cpp b/source/module_base/tool_title.cpp index 5a82ccc3d86..08360abf208 100644 --- a/source/module_base/tool_title.cpp +++ b/source/module_base/tool_title.cpp @@ -13,7 +13,7 @@ namespace ModuleBase //========================================================== void TITLE(const std::string &class_function_name) { - return;//no output + //return;//no output #ifdef __NORMAL std::cout<<" ==> "< "< "<zp); diff --git a/source/module_cell/read_pp_upf201.cpp b/source/module_cell/read_pp_upf201.cpp index d2813baa6e5..11da94dc7fe 100644 --- a/source/module_cell/read_pp_upf201.cpp +++ b/source/module_cell/read_pp_upf201.cpp @@ -388,7 +388,7 @@ int Pseudopot_upf::read_pseudo_upf201(std::ifstream &ifs) delete []name; delete []val; - if(GlobalV::DFT_FUNCTIONAL!="none") + if(GlobalV::DFT_FUNCTIONAL!="default") { if(xc_func != GlobalV::DFT_FUNCTIONAL) { diff --git a/source/module_deepks/LCAO_deepks.h b/source/module_deepks/LCAO_deepks.h index f1f6edc6db7..2e90971ccac 100644 --- a/source/module_deepks/LCAO_deepks.h +++ b/source/module_deepks/LCAO_deepks.h @@ -19,6 +19,7 @@ #include "../src_pw/global.h" #include "../src_io/winput.h" #include "../module_base/matrix.h" +#include "../module_base/timer.h" /// /// The LCAO_Deepks contains subroutines for implementation of the DeePKS method in atomic basis. diff --git a/source/module_xc/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp index 5b84ee71b71..6b968fcf3b4 100644 --- a/source/module_xc/H_XC_pw.cpp +++ b/source/module_xc/H_XC_pw.cpp @@ -1,5 +1,4 @@ #include "xc_functional.h" -#include "xc_gga_pw.h" #include "../src_parallel/parallel_reduce.h" #include "../module_base/timer.h" @@ -38,10 +37,8 @@ std::tuple XC_Functional::v_xc double rhox = 0.0; double arhox = 0.0; double zeta = 0.0; - double ex = 0.0; - double ec = 0.0; - double vx[2]; - double vc[2]; + double exc = 0.0; + double vxc[2]; int ir, is; int neg [3]; @@ -58,10 +55,10 @@ std::tuple XC_Functional::v_xc arhox = abs(rhox); if (arhox > vanishing_charge) { - XC_Functional::xc(arhox, ex, ec, vx[0], vc[0]); - v(0,ir) = e2 * (vx[0] + vc[0]); + XC_Functional::xc(arhox, exc, vxc[0]); + v(0,ir) = e2 * vxc[0]; // consider the total charge density - etxc += e2 * (ex + ec) * rhox; + etxc += e2 * exc * rhox; // only consider rho_in vtxc += v(0, ir) * rho_in[0][ir]; } // endif @@ -100,14 +97,14 @@ std::tuple XC_Functional::v_xc } // call - XC_Functional::xc_spin(arhox, zeta, ex, ec, vx[0], vx[1], vc[0], vc[1]); + XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); for (is = 0;is < GlobalV::NSPIN;is++) { - v(is, ir) = e2 * (vx[is] + vc[is]); + v(is, ir) = e2 * vxc[is]; } - etxc += e2 * (ex + ec) * rhox; + etxc += e2 * exc * rhox; vtxc += v(0, ir) * rho_in[0][ir] + v(1, ir) * rho_in[1][ir]; } @@ -137,14 +134,14 @@ std::tuple XC_Functional::v_xc zeta = (zeta > 0.0) ? 1.0 : (-1.0); }//end if - XC_Functional::xc_spin( arhox, zeta, ex, ec, vx[0], vx[1], vc[0], vc[1] ); + XC_Functional::xc_spin( arhox, zeta, exc, vxc[0], vxc[1]); - etxc += e2 * ( ex + ec ) * rhox; + etxc += e2 * exc * rhox; - v(0, ir) = e2*( 0.5 * ( vx[0] + vc[0] + vx[1] + vc[1] ) ); + v(0, ir) = e2*( 0.5 * ( vxc[0] + vxc[1]) ); vtxc += v(0,ir) * rho_in[0][ir]; - double vs = 0.5 * ( vx[0] + vc[0] - vx[1] - vc[1] ); + double vs = 0.5 * ( vxc[0] - vxc[1] ); if ( amag > vanishing_charge ) { for(int ipol = 1;ipol< 4;ipol++) @@ -160,7 +157,7 @@ std::tuple XC_Functional::v_xc // add gradient corrections (if any) // mohan modify 2009-12-15 - GGA_PW::gradcorr(etxc, vtxc, v); + gradcorr(etxc, vtxc, v); // parallel code : collect vtxc,etxc // mohan add 2008-06-01 diff --git a/source/module_xc/exx_global.h b/source/module_xc/exx_global.h index 316df6f4268..d02d9804cd4 100644 --- a/source/module_xc/exx_global.h +++ b/source/module_xc/exx_global.h @@ -15,25 +15,6 @@ struct Exx_Global bool separate_loop = true; size_t hybrid_step = 1; - - void set_xcfunc( xcfunc &xcf ) const - { - switch( hybrid_type ) - { - case Exx_Global::Hybrid_Type::HF: - xcf.iexch_now=5; xcf.igcx_now=0; - xcf.icorr_now=0; xcf.igcc_now=0; - break; - case Exx_Global::Hybrid_Type::PBE0: - xcf.iexch_now=6; xcf.igcx_now=8; - break; - case Exx_Global::Hybrid_Type::HSE: - xcf.iexch_now=9; xcf.igcx_now=12; - break; - default: - throw std::invalid_argument(ModuleBase::GlobalFunc::TO_STRING(__FILE__)+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - } }; Exx_Info info; }; diff --git a/source/module_xc/potential_libxc.cpp b/source/module_xc/potential_libxc.cpp index 5ac0fc11874..0985bce4489 100644 --- a/source/module_xc/potential_libxc.cpp +++ b/source/module_xc/potential_libxc.cpp @@ -12,7 +12,8 @@ #include "../module_base/global_variable.h" #include "module_base/timer.h" #include "src_parallel/parallel_reduce.h" -#include "xc_gga_pw.h" +#include "xc_functional.h" + #ifdef __LCAO #include "../src_lcao/global_fp.h" #endif @@ -22,7 +23,7 @@ //XC_FAMILY_LDA, XC_FAMILY_GGA, XC_FAMILY_HYB_GGA, XC_CORRELATION: internal flags used in LIBXC, denote the types of functional associated with a certain functional ID, definition can be found in xc.h from LIBXC // [etxc, vtxc, v] = Potential_Libxc::v_xc(...) -std::tuple Potential_Libxc::v_xc( +std::tuple XC_Functional::v_xc_libxc( const int &nrxx, // number of real-space grid const int &ncxyz, // total number of charge grid const double &omega, // volume of cell @@ -47,91 +48,18 @@ std::tuple Potential_Libxc::v_xc( // use can check on website, for example: // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ //---------------------------------------------------------- - xc_func_type x_func; - xc_func_type c_func; - - const int xc_polarized = (1==nspin0()) ? XC_UNPOLARIZED : XC_POLARIZED; - //-------------------------------------- - // determine exchange functional - //-------------------------------------- - if( 6==GlobalC::xcf.iexch_now && - 8==GlobalC::xcf.igcx_now && - 4==GlobalC::xcf.icorr_now && - 4==GlobalC::xcf.igcc_now ) // GGA functional - { - xc_func_init( &x_func, XC_HYB_GGA_XC_PBEH, xc_polarized ); - double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, - GlobalC::exx_global.info.hse_omega, - GlobalC::exx_global.info.hse_omega }; - xc_func_set_ext_params( &x_func, parameter_hse); - } - else if( 9==GlobalC::xcf.iexch_now && - 12==GlobalC::xcf.igcx_now && - 4==GlobalC::xcf.icorr_now && - 4==GlobalC::xcf.igcc_now ) // HSE06 hybrid functional - { - xc_func_init( &x_func, XC_HYB_GGA_XC_HSE06, xc_polarized ); - double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, - GlobalC::exx_global.info.hse_omega, - GlobalC::exx_global.info.hse_omega }; - xc_func_set_ext_params(&x_func, parameter_hse); - } - - if( 1==GlobalC::xcf.iexch_now && - 0==GlobalC::xcf.igcx_now ) // LDA functional - { - xc_func_init( &x_func, XC_LDA_X, xc_polarized ); - } - else if( 1==GlobalC::xcf.iexch_now && - 3==GlobalC::xcf.igcx_now ) // GGA functional - { - xc_func_init( &x_func, XC_GGA_X_PBE, xc_polarized ); - } - else if(GlobalC::xcf.igcx_now == 13 ) //SCAN_X - { - xc_func_init( &x_func, 263, xc_polarized ); - } - else - { - throw std::domain_error("iexch="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.iexch_now)+", igcx="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.igcx_now) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - - //-------------------------------------- - // determine correlation functional - //-------------------------------------- - if( 1==GlobalC::xcf.icorr_now && 0==GlobalC::xcf.igcc_now ) - { - xc_func_init( &c_func, XC_LDA_C_PZ, xc_polarized ); - } - else if( 4==GlobalC::xcf.icorr_now && 4==GlobalC::xcf.igcc_now ) - { - xc_func_init( &c_func, XC_GGA_C_PBE, xc_polarized ); - } - else if (GlobalC::xcf.igcc_now == 9) - { - xc_func_init( &c_func, 267, xc_polarized ); - } - else - { - throw std::domain_error("icorr="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.icorr_now)+", igcc="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.igcc_now) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } + std::vector funcs = init_func(); bool is_gga = false; - switch( x_func.info->family ) - { - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - is_gga = true; - break; - } - switch( c_func.info->family ) + for( xc_func_type &func : funcs ) { - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - is_gga = true; - break; + switch( func.info->family ) + { + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + is_gga = true; + break; + } } // converting rho @@ -145,7 +73,7 @@ std::tuple Potential_Libxc::v_xc( } else // may need updates for SOC { - if(GlobalC::xcf.igcx||GlobalC::xcf.igcc) + if(func_type == 2) { GlobalC::ucell.cal_ux(); } @@ -185,7 +113,7 @@ std::tuple Potential_Libxc::v_xc( // store the gradient in gdr[is] //------------------------------------------- gdr[is].resize(GlobalC::pw.nrxx); - GGA_PW::grad_rho(rhog.data(), gdr[is].data()); + XC_Functional::grad_rho(rhog.data(), gdr[is].data()); } // converting grho @@ -211,7 +139,6 @@ std::tuple Potential_Libxc::v_xc( // jiyy add for threshold constexpr double rho_threshold = 1E-10; - xc_func_set_dens_threshold(&x_func, rho_threshold); // sgn for threshold mask std::vector sgn( nrxx * nspin0(), 1.0); @@ -224,241 +151,126 @@ std::tuple Potential_Libxc::v_xc( std::vector vrho ( nrxx * nspin0() ); std::vector vsigma( nrxx * ((1==nspin0())?1:3) ); - switch( x_func.info->family ) - { - case XC_FAMILY_LDA: - // call Libxc function: xc_lda_exc_vxc - xc_lda_exc_vxc( &x_func, nrxx, rho.data(), - exc.data(), vrho.data() ); - break; - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - // call Libxc function: xc_gga_exc_vxc - xc_gga_exc_vxc( &x_func, nrxx, rho.data(), sigma.data(), - exc.data(), vrho.data(), vsigma.data() ); - break; - default: - throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(x_func.info->family) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - break; - } - for( int is=0; is!=nspin0(); ++is ) + for( xc_func_type &func : funcs ) { - for( int ir=0; ir!= nrxx; ++ir ) + xc_func_set_dens_threshold(&func, rho_threshold); + switch( func.info->family ) { - etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; + case XC_FAMILY_LDA: + // call Libxc function: xc_lda_exc_vxc + xc_lda_exc_vxc( &func, nrxx, rho.data(), + exc.data(), vrho.data() ); + break; + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + // call Libxc function: xc_gga_exc_vxc + xc_gga_exc_vxc( &func, nrxx, rho.data(), sigma.data(), + exc.data(), vrho.data(), vsigma.data() ); + break; + default: + throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(func.info->family) + +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + break; } - } - if(nspin0()==1 || GlobalV::NSPIN==2) - { for( int is=0; is!=nspin0(); ++is ) { for( int ir=0; ir!= nrxx; ++ir ) { - const double v_tmp = ModuleBase::e2 * vrho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; - v(is,ir) += v_tmp; - vtxc += v_tmp * rho_in[is][ir]; + etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; } } - } - else // may need updates for SOC - { - constexpr double vanishing_charge = 1.0e-12; - for( int ir=0; ir!= nrxx; ++ir ) - { - std::vector v_tmp(4); - v_tmp[0] = ModuleBase::e2 * (0.5 * (vrho[ir*2] + vrho[ir*2+1])); - const double vs = 0.5 * (vrho[ir*2] - vrho[ir*2+1]); - const double amag = sqrt( pow(rho_in[1][ir],2) - + pow(rho_in[2][ir],2) - + pow(rho_in[3][ir],2) ); - - if(amag>vanishing_charge) - { - for(int ipol=1; ipol<4; ++ipol) - { - v_tmp[ipol] = ModuleBase::e2 * vs * rho_in[ipol][ir] / amag; - } - } - for(int ipol=0; ipol<4; ++ipol) - { - v(ipol, ir) += v_tmp[ipol]; - vtxc += v_tmp[ipol] * rho_in[ipol][ir]; - } - } - } - - if(x_func.info->family == XC_FAMILY_GGA || x_func.info->family == XC_FAMILY_HYB_GGA) - { - std::vector>> h( nspin0(), std::vector>(nrxx) ); - if( 1==nspin0() ) - { - for( int ir=0; ir!= nrxx; ++ir ) - { - h[0][ir] = ModuleBase::e2 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; - } - } - else - { - for( int ir=0; ir!= nrxx; ++ir ) - { - h[0][ir] = ModuleBase::e2 * (gdr[0][ir] * vsigma[ir*3 ] * 2.0 * sgn[ir*2 ] - + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); - h[1][ir] = ModuleBase::e2 * (gdr[1][ir] * vsigma[ir*3+2] * 2.0 * sgn[ir*2+1] - + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); - } - } - - // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] - std::vector> dh(nspin0(), std::vector( nrxx)); - for( int is=0; is!=nspin0(); ++is ) - GGA_PW::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); - - for( int is=0; is!=nspin0(); ++is ) - for( int ir=0; ir!= nrxx; ++ir ) - vtxc -= dh[is][ir] * rho[ir*nspin0()+is]; if(nspin0()==1 || GlobalV::NSPIN==2) { for( int is=0; is!=nspin0(); ++is ) + { for( int ir=0; ir!= nrxx; ++ir ) - v(is,ir) -= dh[is][ir]; + { + const double v_tmp = ModuleBase::e2 * vrho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; + v(is,ir) += v_tmp; + vtxc += v_tmp * rho_in[is][ir]; + } + } } else // may need updates for SOC { constexpr double vanishing_charge = 1.0e-12; for( int ir=0; ir!= nrxx; ++ir ) { - v(0,ir) -= 0.5 * (dh[0][ir] + dh[1][ir]); - const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); - const double neg = (GlobalC::ucell.magnet.lsign_ - && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0]+rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1]+rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) - ? -1 : 1; - if(amag > vanishing_charge) + std::vector v_tmp(4); + v_tmp[0] = ModuleBase::e2 * (0.5 * (vrho[ir*2] + vrho[ir*2+1])); + const double vs = 0.5 * (vrho[ir*2] - vrho[ir*2+1]); + const double amag = sqrt( pow(rho_in[1][ir],2) + + pow(rho_in[2][ir],2) + + pow(rho_in[3][ir],2) ); + + if(amag>vanishing_charge) { - for(int i=1;i<4;i++) - v(i,ir) -= neg * 0.5 * (dh[0][ir]-dh[1][ir]) * rho_in[i][ir] / amag; + for(int ipol=1; ipol<4; ++ipol) + { + v_tmp[ipol] = ModuleBase::e2 * vs * rho_in[ipol][ir] / amag; + } } - } - } - } - - switch( c_func.info->family ) - { - case XC_FAMILY_LDA: - // call Libxc function: xc_lda_exc_vxc - xc_lda_exc_vxc( &c_func, nrxx, rho.data(), - exc.data(), vrho.data() ); - break; - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - // call Libxc function: xc_gga_exc_vxc - xc_gga_exc_vxc( &c_func, nrxx, rho.data(), sigma.data(), - exc.data(), vrho.data(), vsigma.data() ); - break; - default: - throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(c_func.info->family) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - break; - } - for( int is=0; is!=nspin0(); ++is ) - { - for( int ir=0; ir!= nrxx; ++ir ) - { - etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; - } - } - - if(nspin0()==1 || GlobalV::NSPIN==2) - { - for( int is=0; is!=nspin0(); ++is ) - { - for( int ir=0; ir!= nrxx; ++ir ) - { - const double v_tmp = ModuleBase::e2 * vrho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; - v(is,ir) += v_tmp; - vtxc += v_tmp * rho_in[is][ir]; - } - } - } - else // may need updates for SOC - { - constexpr double vanishing_charge = 1.0e-12; - for( int ir=0; ir!= nrxx; ++ir ) - { - std::vector v_tmp(4); - v_tmp[0] = ModuleBase::e2 * (0.5 * (vrho[ir*2] + vrho[ir*2+1])); - const double vs = 0.5 * (vrho[ir*2] - vrho[ir*2+1]); - const double amag = sqrt( pow(rho_in[1][ir],2) - + pow(rho_in[2][ir],2) - + pow(rho_in[3][ir],2) ); - - if(amag>vanishing_charge) - { - for(int ipol=1; ipol<4; ++ipol) + for(int ipol=0; ipol<4; ++ipol) { - v_tmp[ipol] = ModuleBase::e2 * vs * rho_in[ipol][ir] / amag; + v(ipol, ir) += v_tmp[ipol]; + vtxc += v_tmp[ipol] * rho_in[ipol][ir]; } } - for(int ipol=0; ipol<4; ++ipol) - { - v(ipol, ir) += v_tmp[ipol]; - vtxc += v_tmp[ipol] * rho_in[ipol][ir]; - } } - } - if(c_func.info->family == XC_FAMILY_GGA || c_func.info->family == XC_FAMILY_HYB_GGA) - { - std::vector>> h( nspin0(), std::vector>(nrxx) ); - if( 1==nspin0() ) - { - for( int ir=0; ir!= nrxx; ++ir ) + if(func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) + { + std::vector>> h( nspin0(), std::vector>(nrxx) ); + if( 1==nspin0() ) { - h[0][ir] = ModuleBase::e2 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = ModuleBase::e2 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; + } } - } - else - { - for( int ir=0; ir!= nrxx; ++ir ) + else { - h[0][ir] = ModuleBase::e2 * (gdr[0][ir] * vsigma[ir*3 ] * 2.0 * sgn[ir*2 ] - + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); - h[1][ir] = ModuleBase::e2 * (gdr[1][ir] * vsigma[ir*3+2] * 2.0 * sgn[ir*2+1] - + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = ModuleBase::e2 * (gdr[0][ir] * vsigma[ir*3 ] * 2.0 * sgn[ir*2 ] + + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + h[1][ir] = ModuleBase::e2 * (gdr[1][ir] * vsigma[ir*3+2] * 2.0 * sgn[ir*2+1] + + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + } } - } - // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] - std::vector> dh(nspin0(), std::vector( nrxx)); - for( int is=0; is!=nspin0(); ++is ) - GGA_PW::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); - - for( int is=0; is!=nspin0(); ++is ) - for( int ir=0; ir!= nrxx; ++ir ) - vtxc -= dh[is][ir] * rho[ir*nspin0()+is]; + // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] + std::vector> dh(nspin0(), std::vector( nrxx)); + for( int is=0; is!=nspin0(); ++is ) + XC_Functional::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); - if(nspin0()==1 || GlobalV::NSPIN==2) - { for( int is=0; is!=nspin0(); ++is ) for( int ir=0; ir!= nrxx; ++ir ) - v(is,ir) -= dh[is][ir]; - } - else // may need updates for SOC - { - constexpr double vanishing_charge = 1.0e-12; - for( int ir=0; ir!= nrxx; ++ir ) + vtxc -= dh[is][ir] * rho[ir*nspin0()+is]; + + if(nspin0()==1 || GlobalV::NSPIN==2) + { + for( int is=0; is!=nspin0(); ++is ) + for( int ir=0; ir!= nrxx; ++ir ) + v(is,ir) -= dh[is][ir]; + } + else // may need updates for SOC { - v(0,ir) -= 0.5 * (dh[0][ir] + dh[1][ir]); - const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); - const double neg = (GlobalC::ucell.magnet.lsign_ - && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0]+rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1]+rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) - ? -1 : 1; - if(amag > vanishing_charge) + constexpr double vanishing_charge = 1.0e-12; + for( int ir=0; ir!= nrxx; ++ir ) { - for(int i=1;i<4;i++) - v(i,ir) -= neg * 0.5 * (dh[0][ir]-dh[1][ir]) * rho_in[i][ir] / amag; + v(0,ir) -= 0.5 * (dh[0][ir] + dh[1][ir]); + const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); + const double neg = (GlobalC::ucell.magnet.lsign_ + && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0]+rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1]+rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) + ? -1 : 1; + if(amag > vanishing_charge) + { + for(int i=1;i<4;i++) + v(i,ir) -= neg * 0.5 * (dh[0][ir]-dh[1][ir]) * rho_in[i][ir] / amag; + } } } } @@ -477,4 +289,48 @@ std::tuple Potential_Libxc::v_xc( return std::make_tuple( etxc, vtxc, std::move(v) ); } +std::vector XC_Functional::init_func() +{ + // 'funcs' is the return value + std::vector funcs; + const int xc_polarized = (1==nspin0()) ? XC_UNPOLARIZED : XC_POLARIZED; + + //------------------------------------------- + // define a function named 'add_func', which + // initialize a functional according to its ID + //------------------------------------------- + auto add_func = [&]( const int func_id ) + { + funcs.push_back({}); + // 'xc_func_init' is defined in Libxc + xc_func_init( &funcs.back(), func_id, xc_polarized ); + }; + + for(int id : func_id) + { + if( id == 406 ) // PBE0 + { + add_func( XC_HYB_GGA_XC_PBEH ); + double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, + GlobalC::exx_global.info.hse_omega, + GlobalC::exx_global.info.hse_omega }; + xc_func_set_ext_params(&funcs.back(), parameter_hse); + } + else if( id == 428 ) // HSE06 hybrid functional + { + add_func( XC_HYB_GGA_XC_HSE06 ); + double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, + GlobalC::exx_global.info.hse_omega, + GlobalC::exx_global.info.hse_omega }; + xc_func_set_ext_params(&funcs.back(), parameter_hse); + } + else + { + add_func( id ); + } + } + return funcs; +} + + #endif //ifdef USE_LIBXC diff --git a/source/module_xc/potential_libxc.h b/source/module_xc/potential_libxc.h index d98d99fa842..0d4092cdc8b 100644 --- a/source/module_xc/potential_libxc.h +++ b/source/module_xc/potential_libxc.h @@ -19,56 +19,7 @@ class Potential_Libxc { - public: - //------------------------------------------------ - // evaluate the exchange-correlation (XC) energy - // by using the input charge density rho_in and rho_core_in - //------------------------------------------------ - // [etxc, vtxc, v] = v_xc(...) - static std::tuple v_xc( - const int &nrxx, // number of real-space grid - const int &ncxyz, // total number of charge grid - const double &omega, // volume of cell - const double * const * const rho_in, - const double * const rho_core_in); - - static std::tuple v_xc_meta( - const double * const * const rho_in, - const double * const rho_core_in, - const double * const * const kin_r_in); - - private: - - //------------------------------------------- - // return the type of XC functional by - // calling init_func() - //------------------------------------------- - static std::vector init_func(); - - //------------------------------------------------ - // evaluate three quantities: rho, sigma, and gdr - // according to the input types of XC functionals - //------------------------------------------------ - // [rho, sigma, gdr] = cal_input(...) - static std::tuple< - std::vector, - std::vector, - std::vector>> > - cal_input( - const std::vector &funcs, - const double * const * const rho_in, - const double * const rho_core_in ); - - //---------------------------- - // decide the value of spin - //---------------------------- - static int nspin0() // may need updates from SOC - { - if (GlobalV::NSPIN==1 || (GlobalV::NSPIN==4 && (!GlobalV::DOMAG && !GlobalV::DOMAG_Z))) return 1; - else if(GlobalV::NSPIN==2 || (GlobalV::NSPIN==4 && ( GlobalV::DOMAG || GlobalV::DOMAG_Z))) return 2; - else throw std::runtime_error(ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } }; #endif diff --git a/source/module_xc/potential_libxc_meta.cpp b/source/module_xc/potential_libxc_meta.cpp index a0ec724e80e..a9167331082 100644 --- a/source/module_xc/potential_libxc_meta.cpp +++ b/source/module_xc/potential_libxc_meta.cpp @@ -12,7 +12,6 @@ #include "../module_base/global_variable.h" #include "module_base/timer.h" #include "src_parallel/parallel_reduce.h" -#include "xc_gga_pw.h" #include "./xc_functional.h" #ifdef __LCAO #include "../src_lcao/global_fp.h" @@ -32,7 +31,7 @@ using namespace std; //XC_POLARIZED, XC_UNPOLARIZED: internal flags used in LIBXC, denote the polarized(nspin=1) or unpolarized(nspin=2) calculations, definition can be found in xc.h from LIBXC // [etxc, vtxc, v, vofk] = Potential_Libxc::v_xc(...) -tuple Potential_Libxc::v_xc_meta( +tuple XC_Functional::v_xc_meta( const double * const * const rho_in, const double * const rho_core_in, const double * const * const kin_r_in) @@ -64,26 +63,23 @@ tuple Potential_Libxc::v_xc const int xc_polarized = (GlobalV::NSPIN ? XC_UNPOLARIZED : XC_POLARIZED); //exchange - if(GlobalC::xcf.igcx_now == 13) + if( func_id[0] == 263) { xc_func_init(&x_func, 263 ,xc_polarized); } else { - throw domain_error("iexch="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.iexch_now)+", igcx="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.igcx_now) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); } //correlation - if(GlobalC::xcf.igcc_now == 9) + if( func_id[1] == 267) { xc_func_init(&c_func, 267 ,xc_polarized); } else { - throw domain_error("icorr="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.icorr_now)+", igcc="+ModuleBase::GlobalFunc::TO_STRING(GlobalC::xcf.igcc_now) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - + throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); } //rho,grho,tau @@ -119,7 +115,7 @@ tuple Potential_Libxc::v_xc vector> rhog(GlobalC::pw.ngmc); GlobalC::CHR.set_rhog(rho[is].data(), rhog.data()); - GGA_PW::grad_rho(rhog.data(), grho[is].data()); + XC_Functional::grad_rho(rhog.data(), grho[is].data()); } //kin_r : from double** to vector @@ -277,7 +273,7 @@ tuple Potential_Libxc::v_xc for(int is=0;is @@ -8,218 +7,238 @@ XC_Functional::XC_Functional(){} XC_Functional::~XC_Functional(){} -void XC_Functional::xc(const double &rho, double &ex, double &ec, double &vx, double &vc) +std::vector XC_Functional::func_id(1); +int XC_Functional::func_type = 0; + +int XC_Functional::get_func_type() { - double small = 1.e-10; - double third = 1.0 / 3.0; - double pi34 = 0.6203504908994e0 ; // pi34=(3/4pi)^(1/3) - double rs; + return func_type; +} - if(rho <= small) +// The setting values of functional id +// according to the index in LIBXC +// for detail, refer to https://www.tddft.org/programs/libxc/functionals/ +void XC_Functional::set_xc_type(const std::string xc_func_in) +{ + std::cout << "xc_func_in : "<< xc_func_in << std::endl; + func_id.clear(); + std::string xc_func = xc_func_in; + std::transform(xc_func.begin(), xc_func.end(), xc_func.begin(), (::toupper)); + if( xc_func == "LDA" || xc_func == "PZ" || xc_func == "SLAPZNOGXNOGC") //SLA+PZ { - ex = ec = vx = vc = 0.00; - return; + // I should use XC_LDA_X and XC_LDA_C_PZ here, + // but since we are not compiling with libxc as default, + // I chose to set it manually instead. + // Same for the rest. + func_id.push_back(1); + func_id.push_back(9); + func_type = 1; + } + else if ( xc_func == "PBE" || xc_func == "SLAPWPBXPBC") //PBX+PBC + { + func_id.push_back(101); + func_id.push_back(130); + func_type = 2; + } + else if( xc_func == "revPBE" ) //rPBX+PBC + { + func_id.push_back(117); + func_id.push_back(130); + func_type = 2; } - else + else if ( xc_func == "PBEsol") //PBXsol+PBCsol { - rs = pi34 / std::pow(rho, third); + func_id.push_back(116); + func_id.push_back(133); + func_type = 2; + } + else if ( xc_func == "WC") //WC+PBC + { + func_id.push_back(118); + func_id.push_back(130); + func_type = 2; + } + else if ( xc_func == "BLYP") //B88+BLYP + { + func_id.push_back(106); + func_id.push_back(131); + } + else if ( xc_func == "BP") //B88+P86 + { + func_id.push_back(106); + func_id.push_back(132); + func_type = 2; + } + else if ( xc_func == "PW91") //PW91_X+PW91_C + { + func_id.push_back(109); + func_id.push_back(134); + func_type = 2; + } + else if ( xc_func == "HCTH") //HCTH_X+HCTH_C + { + func_id.push_back(34); + func_id.push_back(97); + func_type = 2; + } + else if ( xc_func == "OLYP") //OPTX+BLYP + { + func_id.push_back(110); + func_id.push_back(131); + func_type = 2; + } + else if ( xc_func == "SCAN") + { + func_id.push_back(263); + func_id.push_back(267); + GlobalV::DFT_META = 1; + } + else if( xc_func == "PBE0") + { + func_id.push_back(406); + func_type = 4; } + else if( xc_func == "HF" || xc_func == "OPT_ORB" || xc_func == "NONE") + { + // not doing anything + } + else if( xc_func == "HSE") + { + func_id.push_back(428); + func_type = 4; + } + else + { + std::cout << "functional name not recognized!" << std::endl; + } - // Exchange: - // "nox" none iexch=0 - // "sla" Slater (alpha=2/3) iexch=1 (default) - // "sl1" Slater (alpha=1.0) iexch=2 - // "rxc" Relativistic Slater iexch=3 - // "oep" Optimized Effective Potential iexch=4 - // "hf" Hartree-Fock iexch=5 - // "pb0x" PBE0 (Slater*0.75+HF*0.25) iexch=6 - // "b3lp" B3LYP(Slater*0.80+HF*0.20) iexch=7 - // "kzk" Finite-size corrections iexch=8 - // "hsex" HSE06 iexch=9 - - // Correlation: - // "noc" none icorr=0 - // "pz" Perdew-Zunger icorr=1 (default) - // "vwn" Vosko-Wilk-Nusair icorr=2 - // "lyp" Lee-Yang-Parr icorr=3 - // "pw" Perdew-Wang icorr=4 - // "wig" Wigner icorr=5 - // "hl" Hedin-Lunqvist icorr=6 - // "obz" Ortiz-Ballone form for PZ icorr=7 - // "obw" Ortiz-Ballone form for PW icorr=8 - // "gl" Gunnarson-Lunqvist icorr=9 - // "b3lp" B3LYP (same as "vwn") icorr=10 - // "kzk" Finite-size corrections icorr=11 - - // Gradient Correction on Exchange: - // "nogx" none igcx =0 (default) - // "b88" Becke88 (beta=0.0042) igcx =1 - // "ggx" Perdew-Wang 91 igcx =2 - // "pbx" Perdew-Burke-Ernzenhof exch igcx =3 - // "rpb" revised PBE by Zhang-Yang igcx =4 - // "hcth" Cambridge exch, Handy et al igcx =5 - // "optx" Handy's exchange functional igcx =6 - // "meta" TPSS meta-gga igcx =7 - // "pb0x" PBE0 (PBE exchange*0.75) igcx =8 - // "b3lp" B3LYP (Becke88*0.72) igcx =9 - // "psx" PBEsol exchange igcx =10 - // "wcx" Wu-Cohen igcx =11 - // "hsex" HSE06 igcx =12 - // "scan" SCAN igcx =13 - - // Gradient Correction on Correlation: - // "nogc" none igcc =0 (default) - // "p86" Perdew86 igcc =1 - // "ggc" Perdew-Wang 91 corr. igcc =2 - // "blyp" Lee-Yang-Parr igcc =3 - // "pbc" Perdew-Burke-Ernzenhof corr igcc =4 - // "hcth" Cambridge corr, Handy et al igcc =5 - // "meta" TPSS meta-gga igcc =6 - // "b3lp" B3LYP (Lee-Yang-Parr*0.81) igcc =7 - // "psc" PBEsol corr igcc =8 - // "scan" SCAN igcx =9 - - // Special cases (dft_shortname): - // "bp" = "b88+p86" = Becke-Perdew grad.corr. - // "pw91" = "pw +ggx+ggc" = PW91 (aka GGA) - // "blyp" = "sla+b88+lyp+blyp" = BLYP - // "pbe" = "sla+pw+pbx+pbc" = PBE - // "revpbe"= "sla+pw+rpb+pbc" = revPBE (Zhang-Yang) - // "pbesol"= "sla+pw+psx+psc" = PBEsol - // "hcth" = "nox+noc+hcth+hcth" = HCTH/120 - // "olyp" = "nox+lyp+optx+blyp"!!! UNTESTED !!! - // "tpss" = "sla+pw+meta+meta" = TPSS Meta-GGA - // "wc" = "sla+pw+wcx+pbc" = Wu-Cohen - // "pbe0" = "pb0x+pw+pb0x+pbc" = PBE0 - // "b3lyp" = "b3lp+vwn+b3lp+b3lp"= B3LYP - // "hse" = "hsex+pw+hsex+pbc" = HSE - - // References: - // pz J.P.Perdew and A.Zunger, PRB 23, 5048 (1981) - // vwn S.H.Vosko, L.Wilk, M.Nusair, Can.J.Phys. 58,1200(1980) - // wig E.P.Wigner, Trans. Faraday Soc. 34, 67 (1938) - // hl L.Hedin and B.I.Lundqvist, J. Phys. C4, 2064 (1971) - // gl O.Gunnarsson and B.I.Lundqvist, PRB 13, 4274 (1976) - // pw J.P.Perdew and Y.Wang, PRB 45, 13244 (1992) - // obpz G.Ortiz and P.Ballone, PRB 50, 1391 (1994) - // obpw as above - // b88 A.D.Becke, PRA 38, 3098 (1988) - // p86 J.P.Perdew, PRB 33, 8822 (1986) - // pbe J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996) - // pw91 J.P.Perdew and Y. Wang, PRB 46, 6671 (1992) - // blyp C.Lee, W.Yang, R.G.Parr, PRB 37, 785 (1988) - // hcth Handy et al, JCP 109, 6264 (1998) - // olyp Handy et al, JCP 116, 5411 (2002) - // revPBE Zhang and Yang, PRL 80, 890 (1998) - // meta J.Tao, J.P.Perdew, V.N.Staroverov, G.E. Scuseria,PRL 91, 146401 (2003) - // kzk H.Kwee, S. Zhang, H. Krakauer, PRL 100, 126404 (2008) - // pbe0 J.P.Perdew, M. Ernzerhof, K.Burke, JCP 105, 9982 (1996) - // b3lyp P.J. Stephens,F.J. Devlin,C.F. Chabalowski,M.J. Frisch J.Phys.Chem 98, 11623 (1994) - // pbesol J.P. Perdew et al., PRL 100, 136406 (2008) - // wc Z. Wu and R. E. Cohen, PRB 73, 235116 (2006) - // hse Paier J, Marsman M, Hummer K, et al, JPC 124(15): 154709 (2006) - //std::cout << " " << GlobalC::xcf.iexch_now << " " << GlobalC::xcf.icorr_now << " " << GlobalC::xcf.igcx_now << " " << GlobalC::xcf.igcc_now << std::endl; - - switch(GlobalC::xcf.iexch_now) + if (func_id[0] == 110) { - case 1: - XC_Functional::slater(rs, ex, vx);break; - case 2: - XC_Functional::slater1(rs, ex, vx);break; - case 3: - XC_Functional::slater_rxc(rs, ex, vx);break; - case 6: - XC_Functional::slater(rs, ex, vx); - ex = 0.75 * ex; - vx = 0.75 * vx; - break; - case 9: - throw std::domain_error("HSE unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - break; - default: - ex = vx = 0.0; + std::cerr << "\n OPTX untested please test,"; } +} + +void XC_Functional::xc(const double &rho, double &exc, double &vxc) +{ + double small = 1.e-10; + double third = 1.0 / 3.0; + double pi34 = 0.6203504908994e0 ; // pi34=(3/4pi)^(1/3) + double rs; + double e,v; + + exc = vxc = 0.00; - switch(GlobalC::xcf.icorr_now) + if(rho <= small) + { + + return; + } + else { - case 1: - XC_Functional::pz(rs, 0, ec, vc);break; - case 2: - XC_Functional::vwn(rs, ec, vc);break; - case 3: - XC_Functional::lyp(rs, ec, vc);break; - case 4: - // mohan note: 0 is correct! - XC_Functional::pw(rs, 0, ec, vc);break; - case 5: - XC_Functional::wigner(rs, ec, vc);break; - case 6: - XC_Functional::hl(rs, ec, vc);break; - case 7: - XC_Functional::pz(rs, 1, ec, vc);break; - case 8: - XC_Functional::pw(rs, 1, ec, vc);break; - case 9: - XC_Functional::gl(rs, ec, vc);break; - default: - ex = vc = 0.0; + rs = pi34 / std::pow(rho, third); } + for(int id : func_id) + { + switch( id ) + { + // Exchange functionals containing slater exchange + case 1: case 101: case 117: case 116: case 118: case 106: case 109: + // SLA PBX rPBX PBXsol WC B88 PW91_X + XC_Functional::slater(rs, e, v);break; + + // Exchange functionals containing attenuated slater exchange + case 406: + // PBE0 + XC_Functional::slater(rs, e, v); + e *= 0.75; v*= 0.75; + break; + + // Correlation functionals containing PW correlation + case 130: case 133: + // PBC PBCsol + XC_Functional::pw(rs, 0, e, v);break; + + // Correlation functionals containing PZ correlation + case 9: case 132: + // PZ P86 + XC_Functional::pz(rs, 0, e, v);break; + + // Correlation functionals containing LYP correlation + case 131: + // BLYP + XC_Functional::lyp(rs, e, v);break; + + // Functionals that are realized only using LIBXC + case 428: case 263: case 267: + // HSE SCAN_X SCAN_C + throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + + default: + e = v = 0.0; + } + exc += e; + vxc += v; + } return; } void XC_Functional::xc_spin(const double &rho, const double &zeta, - double &ex, double &ec, - double &vxup, double &vxdw, - double &vcup, double &vcdw) + double &exc, double &vxcup, double &vxcdw) { static const double small = 1.e-10; + double e, vup, vdw; + exc = vxcup = vxcdw = 0.0; + if (rho <= small) { - ex = ec = vxup = vxdw = vcup = vcdw = 0.0; return; } static const double third = 1.0 / 3.0; static const double pi34 = 0.62035049089940; - const double rs = pi34 / pow(rho, third);//wigner_sitz_radius; -// std::cout << " GlobalC::xcf.iexch_now=" << GlobalC::xcf.iexch_now << std::endl; -// std::cout << " GlobalC::xcf.icorr_now=" << GlobalC::xcf.icorr_now << std::endl; - - switch(GlobalC::xcf.iexch_now) - { - case 1: - XC_Functional::slater_spin(rho, zeta, ex, vxup, vxdw); break; - case 2: - XC_Functional::slater1_spin(rho, zeta, ex, vxup, vxdw); break; - case 3: - XC_Functional::slater_rxc_spin(rho, zeta, ex, vxup, vxdw); break; - case 6: - XC_Functional::slater_spin(rho, zeta, ex, vxup, vxdw); - ex = 0.75 * ex; - vxup = 0.75 * vxup; - vxdw = 0.75 * vxdw; - break; - case 9: - throw std::domain_error("HSE unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); break; - default: - ex = vxup = vxdw =0.0; - } + for(int id : func_id) + { + switch( id ) + { + // Exchange functionals containing slater exchange + case 1: case 101: case 117: case 116: case 118: case 106: case 109: + // SLA PBX rPBX PBXsol WC B88 PW91_X + XC_Functional::slater_spin(rho, zeta, e, vup, vdw); break; + + // Exchange functionals containing attenuated slater exchange + case 406: + // PBE0 + XC_Functional::slater_spin(rho, zeta, e, vup, vdw); + e *= 0.75; vup *= 0.75; vdw *=0.75; + break; + + // Correlation functionals containing PZ correlation + case 9: case 132: + XC_Functional::pz_spin(rs, zeta, e, vup, vdw); break; + + // Correlation functionals containing PW correlationtests/integrate/101_PW_OU_pseudopot + case 130: case 133: + // PBC PBCsol + XC_Functional::pw_spin(rs, zeta, e, vup, vdw); break; + + // Correlation functionals that already contains LDA components + // so sets to 0 here + case 34: case 97: case 110: + //HCTH_X HTCH_C OPTX + e = vup = vdw =0.0; + + // Cases that are only realized in LIBXC + default: + throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); break; - switch(GlobalC::xcf.icorr_now) - { - case 0: - ec = vcup = vcdw = 0.0; break; - case 1: - XC_Functional::pz_spin(rs, zeta, ec, vcup, vcdw); break; - case 4: //mohan fix bug 2012-05-28, case 2 to 4. - XC_Functional::pw_spin(rs, zeta, ec, vcup, vcdw); break; - default: - ModuleBase::WARNING_QUIT("XC_Functional::xc_spin", "xcf.icorr_now wrong!"); + } + exc += e; + vxcup += vup; + vxcdw += vdw; } - return; } @@ -967,32 +986,29 @@ void XC_Functional::tau_xc(const double &rho, const double &grho, const double & const int xc_polarized = XC_UNPOLARIZED; //exchange - if (GlobalC::xcf.igcx_now == 13) - { - xc_func_init(&x_func, 263 ,xc_polarized); - xc_mgga_exc_vxc(&x_func,1,&rho,&grho,&lapl_rho,&atau,&sx,&v1x,&v2x,&vlapl_rho,&v3x); - xc_func_end(&x_func); - sx = sx * rho; - v2x = v2x * 2.0; - } - else - { - ModuleBase::WARNING_QUIT("tau_xc","functional not implemented yet"); - } + for(int id : XC_Functional::func_id) + { + switch( id ) + { + case 263: + xc_func_init(&x_func, 263 ,xc_polarized); + xc_mgga_exc_vxc(&x_func,1,&rho,&grho,&lapl_rho,&atau,&sx,&v1x,&v2x,&vlapl_rho,&v3x); + xc_func_end(&x_func); + sx = sx * rho; + v2x = v2x * 2.0; + break; + case 267: + xc_func_init(&c_func, 267 ,xc_polarized); + xc_mgga_exc_vxc(&c_func,1,&rho,&grho,&lapl_rho,&atau,&sc,&v1c,&v2c,&vlapl_rho,&v3c); + xc_func_end(&c_func); + sc = sc * rho; + v2c = v2c * 2.0; + break; + default: + throw std::domain_error( "functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + } + } -//correlation - if(GlobalC::xcf.igcc_now == 9) - { - xc_func_init(&c_func, 267 ,xc_polarized); - xc_mgga_exc_vxc(&c_func,1,&rho,&grho,&lapl_rho,&atau,&sc,&v1c,&v2c,&vlapl_rho,&v3c); - xc_func_end(&c_func); - sc = sc * rho; - v2c = v2c * 2.0; - } - else - { - ModuleBase::WARNING_QUIT("tau_xc","functional not implemented yet"); - } return; } @@ -1021,7 +1037,7 @@ void XC_Functional::tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out tau[0]=mgga_spin_in.tauup; tau[1]=mgga_spin_in.taudw; //exchange - if (GlobalC::xcf.igcx_now == 13) + if (func_id[0]==263) { xc_func_init(&x_func, 263 ,xc_polarized); xc_mgga_exc_vxc(&x_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sx,v1x.data(),v2x.data(),vlapl_rho.data(),v3x.data()); @@ -1033,7 +1049,7 @@ void XC_Functional::tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out } //correlation - if(GlobalC::xcf.igcc_now == 9) + if(func_id[1]==267) { xc_func_init(&c_func, 267 ,xc_polarized); xc_mgga_exc_vxc(&c_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sc,v1c.data(),mgga_spin_out.v2c.data(),vlapl_rho.data(),v3c.data()); @@ -1066,8 +1082,8 @@ void XC_Functional::tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out } #endif -void XC_Functional::gcxc(const double &rho, const double &grho, double &sx, double &sc, - double &v1x, double &v2x, double &v1c, double &v2c) +void XC_Functional::gcxc(const double &rho, const double &grho, double &sxc, + double &v1xc, double &v2xc) { //----------------------------------------------------------------------- // gradient corrections for exchange and correlation - Hartree a.u. @@ -1091,121 +1107,57 @@ void XC_Functional::gcxc(const double &rho, const double &grho, double &sx, doub // USE kinds // implicit none // real rho, grho, sx, sc, v1x, v2x, v1c, v2c; - double small = 1.e-10; //parameter: + double small = 1.e-10; + double s,v1,v2; + sxc = v1xc = v2xc = 0.0; - // exchange if (rho <= small) { - sx = 0.00; - v1x = 0.00; - v2x = 0.00; - } - else if (GlobalC::xcf.igcx_now == 1) - { - XC_Functional::becke88(rho, grho, sx, v1x, v2x); - } - else if (GlobalC::xcf.igcx_now == 2) - { - XC_Functional::ggax(rho, grho, sx, v1x, v2x); - } - else if (GlobalC::xcf.igcx_now == 3) - { - //mohan modify 2009-12-15 - // 0 stands for PBE, 1 stands for revised PBE - XC_Functional::pbex(rho, grho, 0, sx, v1x, v2x); - } - else if (GlobalC::xcf.igcx_now == 4) - { - // revised PBE. - XC_Functional::pbex(rho, grho, 1, sx, v1x, v2x); - } - else if (GlobalC::xcf.igcx_now == 5 && GlobalC::xcf.igcc_now == 5) - { - XC_Functional::hcth(rho, grho, sx, v1x, v2x); - } - else if (GlobalC::xcf.igcx_now == 6) - { - XC_Functional::optx(rho, grho, sx, v1x, v2x); + return; } - else if (GlobalC::xcf.igcx_now == 8) - { - XC_Functional::pbex (rho, grho, 0, sx, v1x, v2x); - sx *= 0.75; - v1x *= 0.75; - v2x *= 0.75; - } - else if (GlobalC::xcf.igcx_now == 10) - { - // PBESOL - XC_Functional::pbex(rho, grho, 2, sx, v1x, v2x); - } - else if (GlobalC::xcf.igcx_now == 11) - { - // wu cohen - XC_Functional::wcx (rho, grho, sx, v1x, v2x); - } - else if (GlobalC::xcf.igcx_now == 12) - { - // HSE - throw std::domain_error("HSE unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - else if (GlobalC::xcf.igcx_now == 13) - { - //SCAN - cout << "to use SCAN, please link LIBXC" << endl; - throw domain_error("Check "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - else - { - sx = 0.00; - v1x = 0.00; - v2x = 0.00; - } // endif - - //std::cout << "\n igcx = " << GlobalC::xcf.igcx_now; - //std::cout << "\n igcc = " << GlobalC::xcf.igcc_now << std::endl; - // correlation - if (rho <= small) - { - sc = 0.00; - v1c = 0.00; - v2c = 0.00; - } - else if (GlobalC::xcf.igcc_now == 1) - { - XC_Functional::perdew86(rho, grho, sc, v1c, v2c); - } - else if (GlobalC::xcf.igcc_now == 2) - { - XC_Functional::ggac(rho, grho, sc, v1c, v2c); - } - else if (GlobalC::xcf.igcc_now == 3) - { - XC_Functional::glyp(rho, grho, sc, v1c, v2c); - } - else if (GlobalC::xcf.igcc_now == 4) + for(int id : func_id) { - XC_Functional::pbec(rho, grho, 0, sc, v1c, v2c); + switch( id ) + { + case 106: //B88 + XC_Functional::becke88(rho, grho, s, v1, v2);break; + case 109: //PW91_X + XC_Functional::ggax(rho, grho, s, v1, v2);break; + case 101: //PBX + XC_Functional::pbex(rho, grho, 0, s, v1, v2);break; + case 117: //revised PBX + XC_Functional::pbex(rho, grho, 1, s, v1, v2);break; + case 34: //HCTH_X + XC_Functional::hcth(rho, grho, s, v1, v2);break; //XC together + case 97: //HCTH_C + s = 0.0; v1 = 0.0; v2 = 0.0;break; + case 110: //OPTX + XC_Functional::optx(rho, grho, s, v1, v2);break; + case 406: //PBE0 + XC_Functional::pbex(rho, grho, 0, s, v1, v2); + s *= 0.75; v1 *= 0.75; v2 *= 0.75;break; + case 116: //PBXsol + XC_Functional::pbex(rho, grho, 2, s, v1, v2);break; + case 118: //Wu-Cohen + XC_Functional::wcx (rho, grho, s, v1, v2);break; + case 132: //P86 + XC_Functional::perdew86(rho, grho, s, v1, v2);break; + case 134: //PW91_C + XC_Functional::ggac(rho, grho, s, v1, v2);break; + case 130: //PBC + XC_Functional::pbec(rho, grho, 0, s, v1, v2);break; + case 133: //PBCsol + XC_Functional::pbec(rho, grho, 1, s, v1, v2);break; + case 131: //BLYP + XC_Functional::glyp(rho, grho, s, v1, v2); break; + default: //SCAN_X,SCAN_C,HSE, and so on + throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + } + sxc += s; + v1xc += v1; + v2xc += v2; } - else if (GlobalC::xcf.igcc_now == 8) - { - // PBESOL - XC_Functional::pbec(rho, grho, 1, sc, v1c, v2c); - } - else if (GlobalC::xcf.igcc_now == 9) - { - //SCAN - cout << "to use SCAN, please link LIBXC" << endl; - throw domain_error("Check "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - else - { - // note that if igcc == 5 the hcth functional is called above - sc = 0.00; - v1c = 0.00; - v2c = 0.00; - } // endif return; } @@ -1576,140 +1528,84 @@ void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double // exchange double rho = rhoup + rhodw; - //std::cout << " GlobalC::xcf.igcx_now=" << GlobalC::xcf.igcx_now << std::endl; + sx = 0.00; + v1xup = 0.00; v2xup = 0.00; + v1xdw = 0.00; v2xdw = 0.00; - if (rho <= small || GlobalC::xcf.igcx_now == 0) - { - sx = 0.00; - v1xup = 0.00; - v2xup = 0.00; - v1xdw = 0.00; - v2xdw = 0.00; - } - else if (GlobalC::xcf.igcx_now == 1) + if (rho <= small) { - if (rhoup > small && sqrt(fabs(grhoup2)) > small) - { - XC_Functional::becke88_spin(rhoup, grhoup2, sxup, v1xup, v2xup); - } - else - { - sxup = 0.0; - v1xup = 0.0; - v2xup = 0.0; - } // endif - - if (rhodw > small && sqrt(fabs(grhodw2)) > small) - { - XC_Functional::becke88_spin(rhodw, grhodw2, sxdw, v1xdw, v2xdw); - } - else - { - sxdw = 0.0; - v1xdw = 0.0; - v2xdw = 0.0; - } //endif - - sx = sxup + sxdw; + return; } - else if (GlobalC::xcf.igcx_now == 2) - { - if (rhoup > small && sqrt(abs(grhoup2)) > small) - { - throw std::runtime_error("sxup, v1xup, v2xup uninitialized in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - else - { - sxup = 0.0; - v1xup = 0.0; - v2xup = 0.0; - } //endif - if (rhodw > small && sqrt(abs(grhodw2)) > small) + // not the correct way to do things, will change later + // should put exchange and correlation together + // like the others + //for(int id : func_id) + //{ + int id = func_id[0]; + switch( id ) { - throw std::runtime_error("sxdw, v1xdw, v2xdw uninitialized in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + case 106: //B88 + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::becke88_spin(rhoup, grhoup2, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::becke88_spin(rhodw, grhodw2, sxdw, v1xdw, v2xdw); + } + break; + case 101: //PBX + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 0, sxdw, v1xdw, v2xdw); + } + break; + case 117: //revised PBX + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 1, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 1, sxdw, v1xdw, v2xdw); + } + break; + case 406: //PBE0 + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); + sxup *= 0.75; v1xup *= 0.75; v2xup *= 0.75; + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 0, sxdw, v1xdw, v2xdw); + sxdw *= 0.75; v1xdw *= 0.75; v2xdw *= 0.75; + } + break; + case 116: //PBXsol + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 2, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 2, sxdw, v1xdw, v2xdw); + } + break; + default: + sxup = 0.0; sxdw = 0.0; + v1xup = 0.0; v2xup = 0.0; + v1xdw = 0.0; v2xdw = 0.0; } - else - { - sxdw = 0.0; - v1xdw = 0.0; - v2xdw = 0.0; - } //endif - sx = 0.50 * (sxup + sxdw); - v2xup = 2.0 * v2xup; - - v2xdw = 2.0 * v2xdw; - } - // igcx=3: PBE - // igcx=4: revised PBE - // igcx=8: PBE0 - // igcx=10: PBEsol - else if (GlobalC::xcf.igcx_now == 3 || GlobalC::xcf.igcx_now == 4 || GlobalC::xcf.igcx_now==8 || GlobalC::xcf.igcx_now == 10) - { - if (GlobalC::xcf.igcx_now == 4)//mohan fix bug 2012-05-28 - { - iflag = 1; //minus 1 in C++ - } - else if(GlobalC::xcf.igcx_now == 10) - { - iflag = 2; - } - else - { - iflag = 0; - } - - if (rhoup > small && sqrt(fabs(grhoup2)) > small) - { - XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, iflag, sxup, v1xup, v2xup); - } - else - { - sxup = 0.0; - v1xup = 0.0; - v2xup = 0.0; - } - - if (GlobalC::xcf.igcx_now == 8) // Peize Lin add 2017-10-23 - { - sxup *= 0.75; - v1xup *= 0.75; - v2xup *= 0.75; - } - - if (rhodw > small && sqrt(fabs(grhodw2)) > small) - { - XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, iflag, sxdw, v1xdw, v2xdw); - } - else - { - sxdw = 0.0; - v1xdw = 0.0; - v2xdw = 0.0; - } - - if (GlobalC::xcf.igcx_now == 8) // Peize Lin add 2017-10-23 - { - sxdw *= 0.75; - v1xdw *= 0.75; - v2xdw *= 0.75; - } - - sx = 0.5 * (sxup + sxdw); - v2xup = 2.0 * v2xup; - v2xdw = 2.0 * v2xdw; - } - // igcx=12: HSE - else if (GlobalC::xcf.igcx_now == 12) - { - throw std::domain_error( "HSE unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - else - { - std::cout << "\n gcx_spin, not implemented, igcx_now"; - } //endif + v2xdw = 2.0 * v2xdw; + //} return; } //end subroutine gcx_spin @@ -1743,12 +1639,11 @@ void XC_Functional::gcc_spin(double rho, double &zeta, double grho, double &sc, double x; - if (abs(zeta) - 1.0 > small) + sc = 0.00; + v1cup = 0.00; v1cdw = 0.00; + v2c = 0.00; + if (abs(zeta) - 1.0 > small || rho <= small || sqrt(abs(grho)) <= small) { - sc = 0.00; - v1cup = 0.00; - v1cdw = 0.00; - v2c = 0.00; return; } else @@ -1766,45 +1661,21 @@ void XC_Functional::gcc_spin(double rho, double &zeta, double grho, double &sc, } } //endif - -// std::cout << "GlobalC::xcf.igcc_now=" << GlobalC::xcf.igcc_now << std::endl; - - if (GlobalC::xcf.igcc_now == 0 || rho <= small || sqrt(abs(grho)) <= small) - { - sc = 0.00; - v1cup = 0.00; - v1cdw = 0.00; - v2c = 0.00; - } - else if (GlobalC::xcf.igcc_now == 1) - { - XC_Functional::perdew86_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c); - } - else if (GlobalC::xcf.igcc_now == 2) - { - XC_Functional::ggac_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c); - } - else if (GlobalC::xcf.igcc_now == 3 || GlobalC::xcf.igcc_now > 4) - { - std::cout << "\n lsda_functionals, not implemented, igcc_now = " - << GlobalC::xcf.igcc_now; - } - else if (GlobalC::xcf.igcc_now == 4) - { - XC_Functional::pbec_spin(rho, zeta, grho, 1, sc, v1cup, v1cdw, v2c); - } - else if (GlobalC::xcf.igcc_now == 8)//mohan add 2012-05-28 - { - XC_Functional::pbec_spin(rho, zeta, grho, 2, sc, v1cup, v1cdw, v2c); - } - else - { - sc = 0.00; - v1cup = 0.00; - v1cdw = 0.00; - v2c = 0.00; - } //endif - + //for(int id : func_id) + //{ + int id = func_id[1]; + switch( id ) + { + case 132: //P86 + XC_Functional::perdew86_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; + case 134: //PW91_C + XC_Functional::ggac_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; + case 130: //PBC + XC_Functional::pbec_spin(rho, zeta, grho, 1, sc, v1cup, v1cdw, v2c);break; + case 133: //PBCsol + XC_Functional::pbec_spin(rho, zeta, grho, 2, sc, v1cup, v1cdw, v2c);break; + } + //} return; } //end subroutine gcc_spin diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index f4ebd77f29e..423ddd34948 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -17,6 +17,9 @@ class XC_Functional { public: + friend class Run_lcao; + friend class Run_pw; + XC_Functional(); ~XC_Functional(); @@ -29,26 +32,23 @@ class XC_Functional const double*const*const rho_in, const double*const rho_core); // core charge density - // LDA - static void xc(const double &rho, double &ex, double &ec, double &vx, double &vc); - - // LSDA - static void xc_spin(const double &rho, const double &zeta, - double &ex, double &ec, - double &vxup, double &vxdw, - double &vcup, double &vcdw); - - // GGA - static void gcxc(const double &rho, const double &grho, double &sx, double &sc, - double &v1x, double &v2x, double &v1c, double &v2c); - - // spin polarized GGA - static void gcx_spin(double rhoup, double rhodw, double grhoup2, double grhodw2, - double &sx, double &v1xup, double &v1xdw, double &v2xup, - double &v2xdw); - static void gcc_spin(double rho, double &zeta, double grho, double &sc, - double &v1cup, double &v1cdw, double &v2c); - + //------------------------------------------------ + // evaluate the exchange-correlation (XC) energy + // by using the input charge density rho_in and rho_core_in + //------------------------------------------------ + // [etxc, vtxc, v] = v_xc(...) + static std::tuple v_xc_libxc( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell + const double * const * const rho_in, + const double * const rho_core_in); + + static std::tuple v_xc_meta( + const double * const * const rho_in, + const double * const rho_core_in, + const double * const * const kin_r_in); + #ifdef USE_LIBXC struct Mgga_spin_in { @@ -69,22 +69,46 @@ class XC_Functional double v3cup, v3cdw;//vc: mgga part }; + // GGA + static void gcxc(const double &rho, const double &grho, + double &sxc, double &v1xc, double &v2xc); + + // spin polarized GGA + static void gcx_spin(double rhoup, double rhodw, double grhoup2, double grhodw2, + double &sx, double &v1xup, double &v1xdw, double &v2xup, + double &v2xdw); + static void gcc_spin(double rho, double &zeta, double grho, double &sc, + double &v1cup, double &v1cdw, double &v2c); + + static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v); + static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); + static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); + static void grad_dot( const ModuleBase::Vector3 *h, double *dh); + static void noncolin_rho(double *rhoout1,double *rhoout2,double *seg); + // mGGA static void tau_xc(const double &rho, const double &grho, const double &atau, double &sx, double &sc, double &v1x, double &v2x, double &v3x, double &v1c, double &v2c, double &v3c); static void tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out &mgga_spin_out); + #endif - // PBEx, PBEc - static void pbex(const double &rho, const double &grho, const int &iflag, - double &sx, double &v1x, double &v2x); + static int get_func_type(); - static void pbec(const double &rho, const double &grho, const int &flag, - double &sc, double &v1c, double &v2c); + private: + static std::vector func_id; // id of exchange functional + static int func_type; //0:none, 1:lda, 2:gga, 3:mgga, 4:hybrid + static void set_xc_type(const std::string xc_func_in); + static std::vector init_func(); - private: + // LDA + static void xc(const double &rho, double &exc, double &vxc); + + // LSDA + static void xc_spin(const double &rho, const double &zeta, + double &exc, double &vxcup, double &vxcdw); // For LDA exchange energy static void slater(const double &rs, double &ex, double &vx); @@ -116,6 +140,13 @@ class XC_Functional static void pw_spin( const double &rs, const double &zeta, double &ec, double &vcup, double &vcdw); + // PBEx, PBEc + static void pbex(const double &rho, const double &grho, const int &iflag, + double &sx, double &v1x, double &v2x); + + static void pbec(const double &rho, const double &grho, const int &flag, + double &sc, double &v1c, double &v2c); + // some GGA functionals static void hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x); static void pwcorr(const double r, const double c[], double &g, double &dg); @@ -144,6 +175,16 @@ class XC_Functional double &v1cup, double &v1cdw, double &v2c); static void pbec_spin(double rho, double zeta, double grho, const int &flag, double &sc, double &v1cup, double &v1cdw, double &v2c); + + //---------------------------- + // decide the value of spin + //---------------------------- + static int nspin0() // may need updates from SOC + { + if (GlobalV::NSPIN==1 || (GlobalV::NSPIN==4 && (!GlobalV::DOMAG && !GlobalV::DOMAG_Z))) return 1; + else if(GlobalV::NSPIN==2 || (GlobalV::NSPIN==4 && ( GlobalV::DOMAG || GlobalV::DOMAG_Z))) return 2; + else throw std::runtime_error(ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + } }; #endif //XC_FUNCTION_H diff --git a/source/module_xc/xc_gga_pw.cpp b/source/module_xc/xc_gga_pw.cpp index 41cd98ed5f5..6f6d63ee3d6 100644 --- a/source/module_xc/xc_gga_pw.cpp +++ b/source/module_xc/xc_gga_pw.cpp @@ -1,31 +1,20 @@ -#include "xc_gga_pw.h" #include "../src_pw/global.h" #include "xc_functional.h" // from gradcorr.f90 -void GGA_PW::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) +void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) { - ModuleBase::TITLE("GGA_PW","gradcorr"); + ModuleBase::TITLE("XC_Functional","gradcorr"); - if (GlobalC::xcf.igcx_now == 0 && GlobalC::xcf.igcc_now == 0) - { - return; - } + if(func_type == 0 || func_type == 1) return; // none or LDA functional bool igcc_is_lyp = false; - if( GlobalC::xcf.igcc_now == 3 || GlobalC::xcf.igcc_now == 7) - { - igcc_is_lyp = true; - } + if( func_id[1] == 131) igcc_is_lyp = true; int nspin0 = GlobalV::NSPIN; if(GlobalV::NSPIN==4) nspin0 =1; if(GlobalV::NSPIN==4&&(GlobalV::DOMAG||GlobalV::DOMAG_Z)) nspin0 = 2; - if(GlobalV::NSPIN==4) - { - //if(GlobalC::xcf.igcx != 0 || GlobalC::xcf.igcc != 0) GlobalC::ucell.magnet.cal_ux(GlobalC::ucell.ntype); - if(GlobalC::xcf.igcx != 0 || GlobalC::xcf.igcc != 0) GlobalC::ucell.cal_ux(); - } + if(GlobalV::NSPIN==4) GlobalC::ucell.cal_ux(); assert(nspin0>0); const double fac = 1.0/ nspin0; @@ -64,7 +53,7 @@ void GGA_PW::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) gdr1 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; h1 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; - GGA_PW::grad_rho( rhogsum1 , gdr1 ); + XC_Functional::grad_rho( rhogsum1 , gdr1 ); // for spin polarized case; // calculate the gradient of (rho_core+rho) in reciprocal space. @@ -80,7 +69,7 @@ void GGA_PW::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) gdr2 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; h2 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; - GGA_PW::grad_rho( rhogsum2 , gdr2 ); + XC_Functional::grad_rho( rhogsum2 , gdr2 ); } if(GlobalV::NSPIN == 4&&(GlobalV::DOMAG||GlobalV::DOMAG_Z)) @@ -122,51 +111,19 @@ void GGA_PW::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) gdr2 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; h2 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; - GGA_PW::grad_rho( rhogsum1 , gdr1 ); - GGA_PW::grad_rho( rhogsum2 , gdr2 ); + XC_Functional::grad_rho( rhogsum1 , gdr1 ); + XC_Functional::grad_rho( rhogsum2 , gdr2 ); } - - // for test - /* - double sum[6]={0,0,0,0,0,0}; - for(int ir=0; 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); - + XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); // first term of the gradient correction: // D(rho*Exc)/D(rho) - v(0, ir) += ModuleBase::e2 * ( v1x + v1c ); + v(0, ir) += ModuleBase::e2 * v1xc; // h contains // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] = ModuleBase::e2 * ( v2x + v2c ) * gdr1[ir]; + h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; - vtxcgc += ModuleBase::e2*( v1x + v1c ) * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); - etxcgc += ModuleBase::e2*( sx + sc ) * segno; + vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); + etxcgc += ModuleBase::e2* sxc * segno; } } // end arho > epsr } @@ -213,6 +169,8 @@ void GGA_PW::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) double v2xdw = 0.0; double v2cud = 0.0; double v2c = 0.0; + double sx = 0.0; + double sc = 0.0; for(int ir=0; ir *rhog, const int ik, std::complex **grad, const int npw ) +void XC_Functional::grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ) { double *kplusg; kplusg = new double[npw]; @@ -386,7 +344,7 @@ void GGA_PW::grad_wfc( const std::complex *rhog, const int ik, std::comp return; } -void GGA_PW::grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ) +void XC_Functional::grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ) { std::complex *gdrtmpg = new std::complex[GlobalC::pw.ngmc]; ModuleBase::GlobalFunc::ZEROS(gdrtmpg, GlobalC::pw.ngmc); @@ -432,7 +390,7 @@ void GGA_PW::grad_rho( const std::complex *rhog, ModuleBase::Vector3 *h, double *dh) +void XC_Functional::grad_dot(const ModuleBase::Vector3 *h, double *dh) { std::complex *aux = new std::complex[GlobalC::pw.nrxx]; std::complex *gaux = new std::complex[GlobalC::pw.ngmc]; @@ -475,7 +433,7 @@ void GGA_PW::grad_dot(const ModuleBase::Vector3 *h, double *dh) return; } -void GGA_PW::noncolin_rho(double *rhoout1,double *rhoout2, double *neg) +void XC_Functional::noncolin_rho(double *rhoout1,double *rhoout2, double *neg) { //this function diagonalizes the spin density matrix and gives as output the //spin up and spin down components of the charge. diff --git a/source/module_xc/xc_gga_pw.h b/source/module_xc/xc_gga_pw.h deleted file mode 100644 index 47a343deb9f..00000000000 --- a/source/module_xc/xc_gga_pw.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef GGA_PW_H -#define GGA_PW_H - -#include "../module_base/global_function.h" -#include "../module_base/global_variable.h" -#include "../module_base/matrix.h" -#include "../module_base/vector3.h" -#include "../src_parallel/parallel_global.h" - -//========================================================== -// Calculate the charge gradient using plane wave basis. -// UPDATE : Peize Lin change all double** to ModuleBase::Vector3* 2017-12-20 -//========================================================== - -namespace GGA_PW -{ - void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v); - void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); - void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); - void grad_dot( const ModuleBase::Vector3 *h, double *dh); - void noncolin_rho(double *rhoout1,double *rhoout2,double *seg); -} - -#endif diff --git a/source/module_xc/xc_type.cpp b/source/module_xc/xc_type.cpp index 706480cb880..d0732de4b36 100644 --- a/source/module_xc/xc_type.cpp +++ b/source/module_xc/xc_type.cpp @@ -11,209 +11,6 @@ xcfunc::~xcfunc() { } -// mohan update 2009-12-15 -const std::string exc[10] = { "NOX", "SLA", "SL1", "RXC", "OEP", "HF", "PB0X", "B3LP", "KZK", "HSEX"}; -const std::string corr[12] = { "NOC", "PZ", "VWN", "LYP", "PW", "WIG", "HL", "OBZ", - "OBW", "GL", "B3LP", "KZK"}; -const std::string gradx[14] = { "NOGX", "B88", "GGX", "PBX", "RPB", "HCTH", "OPTX", "META", "PB0X", "B3LP", "PSX", "WC", "HSEX", "SCAN"}; -const std::string gradc[10] = { "NOGC", "P86", "GGC", "BLYP", "PBC", "HCTH", "META", "B3LP", "PSC", "SCAN"}; - -// from function.f90 -//----------------------------------------------------------------------- -void xcfunc::which_dft(const std::string xc_func) -{ - //----------------------------------------------------------------------- - // translates a std::string containing the exchange-correlation name - // into internal indices iexch, icorr, igcx, igcc - - int notset = -1; - - this->iexch = notset; - this->icorr = notset; - this->igcx = notset; - this->igcc = notset; - - //======================= Second Part =============================== - // special case : BLYP => B88 for gradient correction on exchange - - if( xc_func == "PBE0") - { - set_dft_value(iexch,6); - set_dft_value(icorr,4); - set_dft_value(igcx,8); - set_dft_value(igcc,4); - } - if( xc_func == "LDA" || xc_func == "PZ") - { - set_dft_value(iexch,1); - set_dft_value(icorr,1); - set_dft_value(igcx,0); - set_dft_value(igcc,0); - } - else if ( xc_func == "PBE" ) - { - // special case : PBE - set_dft_value(iexch, 1); - set_dft_value(icorr, 4); - set_dft_value(igcx, 3); - set_dft_value(igcc, 4); - } - else if( xc_func == "revPBE" ) - { - // special case : revPBE - set_dft_value(iexch,1); - set_dft_value(icorr,4); - set_dft_value(igcx, 4); - set_dft_value(igcc, 4); - } - else if ( xc_func == "PBEsol") - { - set_dft_value(iexch, 1); - set_dft_value(icorr, 4); - set_dft_value(igcx, 10); - set_dft_value(igcc, 8); - } - else if ( xc_func == "WC") - { - set_dft_value(iexch, 1); - set_dft_value(icorr, 4); - set_dft_value(igcx, 11); - set_dft_value(igcc, 4); - } - else if ( xc_func == "BLYP") - { - set_dft_value(iexch, 1); - set_dft_value(icorr, 3); - set_dft_value(igcx, 1); - set_dft_value(igcc, 3); - } - else if ( xc_func == "BP") - { - // special case : BP = B88 + P86 - set_dft_value(iexch, 0); - set_dft_value(icorr, 0); - set_dft_value(igcx, 1); - set_dft_value(igcc, 1); - } - else if ( xc_func == "PW91") - { - // special case : PW91 = GGX + GGC - set_dft_value(iexch, 1); - set_dft_value(icorr, 4); - set_dft_value(igcx, 2); - set_dft_value(igcc, 2); - } - else if ( xc_func == "HCTH") - { - // special case : HCTH already contains LDA exchange and correlation - set_dft_value(iexch, 0); - set_dft_value(icorr, 0); - set_dft_value(igcx, 5); - set_dft_value(igcc, 5); - } - else if ( xc_func == "OLYP") - { - // special case : OLYP = OPTX + LYP - set_dft_value(iexch, 0); - set_dft_value(icorr, 3); - set_dft_value(igcx, 6); - set_dft_value(igcc, 3); - } - else if ( xc_func == "SCAN") - { - // special case : SCAN already contains LDA exchange and correlation - set_dft_value(iexch, 0); - set_dft_value(icorr, 0); - set_dft_value(igcx, 13); - set_dft_value(igcc, 9); - GlobalV::DFT_META = 1; - } - - if (igcx == 6) - { - std::cerr << "\n which_dft,OPTX untested please test,"; //-igcx); - } - - if (iexch == notset) - { - // Default value: Slater exchange - set_dft_value(iexch, 1); - } - if (icorr == notset) - { - // Default value: Perdew-Zunger correlation - set_dft_value(icorr, 1); - } - if (igcx == notset) - { - // Default value: no gradient correction on exchange - set_dft_value(igcx, 0); - } - if (igcc == notset) - { - // Default value: no gradient correction on correlation - set_dft_value(igcc, 0); - } - - copy_to_now(); - - hybrid_first(); - - return; -} // end subroutine which_dft - -//----------------------------------------------------------------------- -void xcfunc::set_dft_value(int &m,const int i) -{ - int notset = - 1; - - if (m != notset && m != i) - { - std::cerr << "\n set_dft_value, two conflicting matching values,"; - } - m = i; - return; -} // end subroutine set_dft_value - -void xcfunc::printdft(std::ofstream &ofs) -{ - ofs << "\n iexch = " << iexch - << " -> " << exc [iexch]; - ofs << "\n icorr = " << icorr - << " -> " << corr[icorr]; - ofs << "\n igcx = " << igcx - << " -> " << gradx[igcx]; - ofs << "\n igcc = " << igcc - << " -> " << gradc[igcc]; -} - -void xcfunc::ostreamdft(std::ostream &ofs) // zws add 20150108 -{ - if ( iexch == 1 && icorr == 1 && igcx == 0 && igcc == 0 ) - { - ofs << "PZ-LDA"; - } - else if (iexch == 1 && icorr == 4 && igcx == 3 && igcc == 4 ) - { - ofs << "PBE"; - } - else - { - ofs << exc [iexch] ; - ofs << " " << corr[icorr] ; - ofs << " " << gradx[igcx] ; - ofs << " " << gradc[igcc] ; - } -} - -// Peize Lin add 2016-12-03 -void xcfunc::copy_to_now() -{ - iexch_now = iexch; - icorr_now = icorr; - igcx_now = igcx ; - igcc_now = igcc ; -} // Peize Lin add 2016-12-03 void xcfunc::hybrid_first() diff --git a/source/run_lcao.cpp b/source/run_lcao.cpp index 5410274a729..72fbca1c48e 100644 --- a/source/run_lcao.cpp +++ b/source/run_lcao.cpp @@ -53,15 +53,10 @@ void Run_lcao::lcao_line(void) // Yu Liu add 2021-07-03 GlobalC::CHR.cal_nelec(); - // mohan add 2010-09-06 - // Yu Liu move here 2021-06-27 - // because the number of element type - // will easily be ignored, so here - // I warn the user again for each type. - for(int it=0; it(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); } else { - const auto etxc_vtxc_v = Potential_Libxc::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); + const auto etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); diff --git a/source/src_pw/global.h b/source/src_pw/global.h index 8ebce487698..e1c0a145560 100644 --- a/source/src_pw/global.h +++ b/source/src_pw/global.h @@ -23,7 +23,7 @@ #include "vdwd3.h" #include "vdwd3_parameters.h" #include "wavefunc.h" -#include "../module_xc/xc_type.h" +#include "../module_xc/xc_functional.h" #ifdef __CUDA namespace CudaCheck diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index adb00d10bb5..ad9937a69d7 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -4,7 +4,6 @@ #include "global.h" #include "potential.h" #include "../module_xc/xc_functional.h" -#include "../module_xc/xc_gga_pw.h" #include "efield.h" #include "math.h" #include "../module_xc/potential_libxc.h" @@ -329,7 +328,7 @@ ModuleBase::matrix Potential::v_of_rho( #ifdef USE_LIBXC if(GlobalV::DFT_META) { - const std::tuple etxc_vtxc_v = Potential_Libxc::v_xc_meta(rho_in, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); + const std::tuple etxc_vtxc_v = XC_Functional::v_xc_meta(rho_in, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); @@ -337,7 +336,7 @@ ModuleBase::matrix Potential::v_of_rho( } else { - const std::tuple etxc_vtxc_v = Potential_Libxc::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); + const std::tuple etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); diff --git a/source/src_pw/run_md_pw.cpp b/source/src_pw/run_md_pw.cpp index 753bfd20850..66c829480d3 100644 --- a/source/src_pw/run_md_pw.cpp +++ b/source/src_pw/run_md_pw.cpp @@ -303,7 +303,6 @@ void Run_MD_PW::md_force_virial( eiter += elec.iter; if (elec.iter == 1 || hybrid_step == GlobalC::exx_global.info.hybrid_step - 1) // exx converge break; - GlobalC::exx_global.info.set_xcfunc(GlobalC::xcf); GlobalC::exx_lip.cal_exx(); } } @@ -311,7 +310,6 @@ void Run_MD_PW::md_force_virial( { elec.self_consistent(istep); eiter += elec.iter; - GlobalC::exx_global.info.set_xcfunc(GlobalC::xcf); elec.self_consistent(istep); eiter += elec.iter; } diff --git a/source/src_pw/stress_func_gga.cpp b/source/src_pw/stress_func_gga.cpp index 81155b419aa..9a193352971 100644 --- a/source/src_pw/stress_func_gga.cpp +++ b/source/src_pw/stress_func_gga.cpp @@ -1,6 +1,5 @@ #include "./stress_func.h" #include "../module_xc/xc_functional.h" -#include "../module_xc/xc_gga_pw.h" #include "../module_base/timer.h" //calculate the GGA stress correction in PW and LCAO @@ -8,21 +7,18 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) { ModuleBase::timer::tick("Stress_Func","stress_gga"); - if (GlobalC::xcf.igcx == 0 && GlobalC::xcf.igcc == 0) + int func_type = XC_Functional::get_func_type(); + if (func_type == 0 || func_type == 1) { ModuleBase::timer::tick("Stress_Func","stress_gga"); return; - } + } + double sigma_gradcorr[3][3]; double* p= &sigma_gradcorr[0][0]; for(int i=0;i<9;i++) *p++ = 0; - bool igcc_is_lyp = false; - if( GlobalC::xcf.igcc == 3 || GlobalC::xcf.igcc == 7) - { - igcc_is_lyp = true; - } const int nspin_in = GlobalV::NSPIN; assert(nspin_in>0); const double fac = 1.0/ nspin_in; @@ -51,7 +47,7 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) gdr1 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; ModuleBase::GlobalFunc::ZEROS(gdr1, GlobalC::pw.nrxx); - GGA_PW::grad_rho( rhogsum1 , gdr1 ); + XC_Functional::grad_rho( rhogsum1 , gdr1 ); if(nspin_in==2) { @@ -71,7 +67,7 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) gdr2 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; ModuleBase::GlobalFunc::ZEROS(gdr2, GlobalC::pw.nrxx); - GGA_PW::grad_rho( rhogsum2 , gdr2 ); + XC_Functional::grad_rho( rhogsum2 , gdr2 ); } const double epsr = 1.0e-6; @@ -88,6 +84,9 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) double v1c = 0.0; double v2c = 0.0; double v3c = 0.0; + double sxc = 0.0; + double v1xc = 0.0; + double v2xc = 0.0; if(nspin_in==1||nspin_in==4) { @@ -111,7 +110,7 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) } else { - XC_Functional::gcxc( arho, grho2a, sx, sc, v1x, v2x, v1c, v2c); + XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); } double tt[3]; tt[0] = gdr1[ir].x; @@ -121,7 +120,7 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) { for(int m = 0;m< l+1;m++) { - sigma_gradcorr[l][m] += tt[l] * tt[m] * ModuleBase::e2 * (v2x + v2c); + sigma_gradcorr[l][m] += tt[l] * tt[m] * ModuleBase::e2 * v2xc; } } } @@ -154,19 +153,12 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) if(rh > epsr) { - if(igcc_is_lyp) - { - ModuleBase::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); - v2cup = v2c; - v2cdw = v2c; - v2cud = v2c; - } + 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); + v2cup = v2c; + v2cdw = v2c; + v2cud = v2c; } else { diff --git a/source/src_pw/stress_func_mgga.cpp b/source/src_pw/stress_func_mgga.cpp index 763a1939480..c299f9df896 100644 --- a/source/src_pw/stress_func_mgga.cpp +++ b/source/src_pw/stress_func_mgga.cpp @@ -1,6 +1,5 @@ #include "./stress_func.h" #include "../module_xc/xc_functional.h" -#include "../module_xc/xc_gga_pw.h" #include "../module_base/timer.h" //calculate the mGGA stress correction in PW and LCAO @@ -48,7 +47,7 @@ void Stress_Func::stress_mgga(ModuleBase::matrix& sigma) { psi[ig]=GlobalC::wf.evc[ik](ibnd,ig); } - GGA_PW::grad_wfc(psi, ik, gradwfc, npw); + XC_Functional::grad_wfc(psi, ik, gradwfc, npw); int ipol = 0; for (int ix = 0; ix < 3; ix++) From 5d4a5f79fd4ace42c7362ddd87590e29a072edde Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Sun, 13 Feb 2022 18:38:55 +0800 Subject: [PATCH 06/36] xc refactor : fix hybrid functional --- source/Makefile.Objects | 3 +- source/input_conv.cpp | 6 +- source/module_xc/CMakeLists.txt | 1 - source/module_xc/exx_global.h | 4 +- source/module_xc/potential_libxc.cpp | 28 ++++-- source/module_xc/xc_functional.cpp | 2 +- source/module_xc/xc_functional.h | 5 + source/module_xc/xc_type.cpp | 37 -------- source/module_xc/xc_type.h | 133 --------------------------- source/run_lcao.cpp | 23 ++++- source/run_pw.cpp | 11 ++- source/src_ions/ions.cpp | 51 +--------- source/src_lcao/ELEC_scf.cpp | 17 ++-- source/src_lcao/LCAO_hamilt.cpp | 47 ++++++---- source/src_lcao/LOOP_elec.cpp | 17 ++-- source/src_pw/electrons.cpp | 17 ++-- source/src_pw/electrons.cu | 17 ++-- source/src_pw/electrons_hip.cpp | 10 +- source/src_pw/energy.cpp | 9 +- source/src_pw/forces.cpp | 2 +- source/src_pw/global.cpp | 1 - source/src_pw/global.h | 1 - source/src_pw/hamilt_pw.cpp | 20 ++-- source/src_pw/hamilt_pw.cu | 20 ++-- source/src_pw/hamilt_pw_hip.cpp | 20 ++-- source/src_pw/potential.cpp | 2 +- source/src_pw/run_md_pw.cpp | 2 + source/src_ri/exx_lcao.h | 1 - 28 files changed, 161 insertions(+), 346 deletions(-) delete mode 100644 source/module_xc/xc_type.cpp delete mode 100644 source/module_xc/xc_type.h diff --git a/source/Makefile.Objects b/source/Makefile.Objects index 4e8b0d48d23..6fbf44f3a8e 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -19,8 +19,7 @@ input_conv.o\ run_pw.o\ run_lcao.o\ -OBJS_PW=xc_type.o \ -xc_functional.o\ +OBJS_PW=xc_functional.o\ xc_3.o \ vdwd2.o\ vdwd2_parameters.o\ diff --git a/source/input_conv.cpp b/source/input_conv.cpp index e8a6e8d663c..63c2073c7b9 100644 --- a/source/input_conv.cpp +++ b/source/input_conv.cpp @@ -419,14 +419,14 @@ void Input_Conv::Convert(void) const std::string command0 = "test -d " + GlobalC::restart.folder + " || mkdir " + GlobalC::restart.folder; if (GlobalV::MY_RANK == 0) system(command0.c_str()); - if (INPUT.dft_functional == "no") + if (INPUT.dft_functional == "hf" || INPUT.dft_functional == "pbe0" || INPUT.dft_functional == "hse" || INPUT.dft_functional == "opt_orb") { GlobalC::restart.info_save.save_charge = true; + GlobalC::restart.info_save.save_H = true; } else { GlobalC::restart.info_save.save_charge = true; - GlobalC::restart.info_save.save_H = true; } } if (INPUT.restart_load) @@ -468,7 +468,7 @@ void Input_Conv::Convert(void) { GlobalC::exx_global.info.hybrid_type = Exx_Global::Hybrid_Type::No; } - + if(GlobalC::exx_global.info.hybrid_type != Exx_Global::Hybrid_Type::No) { GlobalC::exx_global.info.hybrid_alpha = INPUT.exx_hybrid_alpha; diff --git a/source/module_xc/CMakeLists.txt b/source/module_xc/CMakeLists.txt index 9711308e986..4c520cff52d 100644 --- a/source/module_xc/CMakeLists.txt +++ b/source/module_xc/CMakeLists.txt @@ -4,7 +4,6 @@ list(APPEND objects potential_libxc_meta.cpp xc_functional.cpp xc_gga_pw.cpp - xc_type.cpp ) add_library( diff --git a/source/module_xc/exx_global.h b/source/module_xc/exx_global.h index d02d9804cd4..292fa7818fd 100644 --- a/source/module_xc/exx_global.h +++ b/source/module_xc/exx_global.h @@ -1,7 +1,7 @@ #ifndef EXX_GLOBAL_H #define EXX_GLOBAL_H -#include "../module_xc/xc_type.h" +#include "xc_functional.h" struct Exx_Global { @@ -15,7 +15,7 @@ struct Exx_Global bool separate_loop = true; size_t hybrid_step = 1; - }; + }; Exx_Info info; }; diff --git a/source/module_xc/potential_libxc.cpp b/source/module_xc/potential_libxc.cpp index 0985bce4489..3d9f739c38f 100644 --- a/source/module_xc/potential_libxc.cpp +++ b/source/module_xc/potential_libxc.cpp @@ -137,22 +137,30 @@ std::tuple XC_Functional::v_xc_libxc( } } - // jiyy add for threshold - constexpr double rho_threshold = 1E-10; - // sgn for threshold mask - std::vector sgn( nrxx * nspin0(), 1.0); - - for( int ir=0; ir!= nrxx * nspin0(); ++ir ) - { - if ( rho[ir] exc ( nrxx ); std::vector vrho ( nrxx * nspin0() ); std::vector vsigma( nrxx * ((1==nspin0())?1:3) ); for( xc_func_type &func : funcs ) { + + // jiyy add for threshold + const double rho_threshold = 1E-6; + const double grho_threshold = 1E-10; + // sgn for threshold mask + std::vector sgn( nrxx * nspin0(), 1.0); + + if(nspin0()==2 && func.info->family != XC_FAMILY_LDA && func.info->kind==XC_CORRELATION) + { + for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + if ( rho[ir*2]family ) { diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index 1d6ab0adb43..89574a664f4 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -20,7 +20,6 @@ int XC_Functional::get_func_type() // for detail, refer to https://www.tddft.org/programs/libxc/functionals/ void XC_Functional::set_xc_type(const std::string xc_func_in) { - std::cout << "xc_func_in : "<< xc_func_in << std::endl; func_id.clear(); std::string xc_func = xc_func_in; std::transform(xc_func.begin(), xc_func.end(), xc_func.begin(), (::toupper)); @@ -101,6 +100,7 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) else if( xc_func == "HF" || xc_func == "OPT_ORB" || xc_func == "NONE") { // not doing anything + if(xc_func == "HF") func_type = 4; } else if( xc_func == "HSE") { diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 423ddd34948..8bdc6b58d43 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -13,12 +13,17 @@ #include "../module_base/global_variable.h" #include "../module_base/vector3.h" #include "../module_base/matrix.h" +#include "exx_global.h" class XC_Functional { public: friend class Run_lcao; friend class Run_pw; + friend class Ions; + friend class ELEC_scf; + friend class LOOP_elec; + friend class Run_MD_PW; XC_Functional(); ~XC_Functional(); diff --git a/source/module_xc/xc_type.cpp b/source/module_xc/xc_type.cpp deleted file mode 100644 index d0732de4b36..00000000000 --- a/source/module_xc/xc_type.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "xc_type.h" -#include "../module_base/global_function.h" -#include "../src_pw/global.h" -#include "exx_global.h" - -xcfunc::xcfunc() -{ -} - -xcfunc::~xcfunc() -{ -} - - -// Peize Lin add 2016-12-03 -void xcfunc::hybrid_first() -{ -#ifdef __LCAO - // may do something - ModuleBase::WARNING("functional","file "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)+" may error "); - if(Exx_Global::Hybrid_Type::HF==GlobalC::exx_global.info.hybrid_type) - { - iexch_now = 1; - igcx_now = 3; - } - else if(Exx_Global::Hybrid_Type::PBE0==GlobalC::exx_global.info.hybrid_type) - { - iexch_now = 1; - igcx_now = 3; - } - else if(Exx_Global::Hybrid_Type::HSE==GlobalC::exx_global.info.hybrid_type) - { - iexch_now = 1; - igcx_now = 3; - } -#endif -} diff --git a/source/module_xc/xc_type.h b/source/module_xc/xc_type.h deleted file mode 100644 index 2d6082c7167..00000000000 --- a/source/module_xc/xc_type.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef FUNCTIONAL_H -#define FUNCTIONAL_H - -#include "../module_base/global_function.h" -#include "../module_base/global_variable.h" -class xcfunc -{ - - public: - - // dft is the exchange-correlation functional, described by - // any nonconflicting combination of the following keywords - // (case-insensitive): - - // Exchange: "nox" none iexch=0 - // "sla" Slater (alpha=2/3) iexch=1 (default) - // "sl1" Slater (alpha=1.0) iexch=2 - // "rxc" Relativistic Slater iexch=3 - // "oep" Optimized Effective Potential iexch=4 - // "hf" Hartree-Fock iexch=5 - // "pb0x" PBE0 iexch=6 - // "b3lpx" B3LYP iexch=7 - // "kzk" Finite-size corrections iexch=8 - // "hsex" HSE06 iexch=9 - // - // Correlation: "noc" none icorr=0 - // "pz" Perdew-Zunger icorr=1 (default) - // "vwn" Vosko-Wilk-Nusair icorr=2 - // "lyp" Lee-Yang-Parr icorr=3 - // "pw" Perdew-Wang icorr=4 - // "wig" Wigner icorr=5 - // "hl" Hedin-Lunqvist icorr=6 - // "obz" Ortiz-Ballone form for PZ icorr=7 - // "obw" Ortiz-Ballone form for PW icorr=8 - // "gl" Gunnarson-Lunqvist icorr=9 - // - // Gradient Correction on Exchange: - // "nogx" none igcx =0 (default) - // "b88" Becke88 (beta=0.0042) igcx =1 - // "ggx" Perdew-Wang 91 igcx =2 - // "pbx" Perdew-Burke-Ernzenhof exch igcx =3 - // "rpb" revised PBE by Zhang-Yang igcx =4 - // "hcth" Cambridge exch, Handy et al igcx =5 - // "optx" Handy's exchange functional igcx =6 - // "meta" meta-gga igcx =7 - // "pb0x" PBE0 igcx =8 - // "b3lp" B3LYP igcx =9 - // "psx" PBEsol exchange igcx =10 - // "wcx" Wu-Cohen igcx =11 - // "hsex" HSE06 igcx =12 - // - // Gradient Correction on Correlation: - // "nogc" none igcc =0 (default) - // "p86" Perdew86 igcc =1 - // "ggc" Perdew-Wang 91 corr. igcc =2 - // "blyp" Lee-Yang-Parr igcc =3 - // "pbc" Perdew-Burke-Ernzenhof corr igcc =4 - // "hcth" Cambridge corr, Handy et al igcc =5 - // "meta" meta-gga igcc =6 - // - // Special cases: - // "bp" = "b88+p86" = Becke-Perdew grad.corr. - // "pw91" = "pw +ggx+ggc" = PW91 (aka GGA) - // "blyp" = "sla+b88+lyp+blyp" = BLYP - // "pbe" = "sla+pw+pbx+pbc" = PBE - // "revpbe"= "sla+pw+rpb+pbc" = revPBE (Zhang-Yang) - // "pbesol"= "sla+pw+psx+psc" = PBEsol - // "hcth" = "nox+noc+hcth+hcth" = HCTH/120 - // "olyp" = "nox+lyp+optx+blyp"!!! UNTESTED !!! - // "tpss" = "sla+pw+meta+meta" = TPSS Meta-GGA - // "wc" = "sla+pw+wcx+pbc" = Wu-Cohen - // "pbe0" = "pb0x+pw+pb0x+pbc" = PBE0 - // "b3lyp" = "b3lp+vwn+b3lp+b3lp"= B3LYP - // "hse" = "hsex+pw+hsex+pbc" = HSE - - - // References: - // pz J.P.Perdew and A.Zunger, PRB 23, 5048 (1981) - // vwn S.H.Vosko, L.Wilk, M.Nusair, Can.J.Phys. 58,1200(1980) - // wig E.P.Wigner, Trans. Faraday Soc. 34, 67 (1938) - // hl L.Hedin and B.I.Lundqvist, J. Phys. C4, 2064 (1971) - // gl O.Gunnarsson and B.I.Lundqvist, PRB 13, 4274 (1976) - // pw J.P.Perdew and Y.Wang, PRB 45, 13244 (1992) - // obpz G.Ortiz and P.Ballone, PRB 50, 1391 (1994) - // obpw as above - // b88 A.D.Becke, PRA 38, 3098 (1988) - // p86 J.P.Perdew, PRB 33, 8822 (1986) - // pbe J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996) - // pw91 J.P.Perdew and Y. Wang, PRB 46, 6671 (1992) - // blyp C.Lee, W.Yang, R.G.Parr, PRB 37, 785 (1988) - // hcth Handy et al, JCP 109, 6264 (1998) - // olyp Handy et al, JCP 116, 5411 (2002) - // revPBE Zhang and Yang, PRL 80, 890 (1998) - // meta J.Tao, J.P.Perdew, V.N.Staroverov, G.E. Scuseria,PRL 91, 146401 (2003) - // kzk H.Kwee, S. Zhang, H. Krakauer, PRL 100, 126404 (2008) - // pbe0 J.P.Perdew, M. Ernzerhof, K.Burke, JCP 105, 9982 (1996) - // b3lyp P.J. Stephens,F.J. Devlin,C.F. Chabalowski,M.J. Frisch J.Phys.Chem 98, 11623 (1994) - // pbesol J.P. Perdew et al., PRL 100, 136406 (2008) - // wc Z. Wu and R. E. Cohen, PRB 73, 235116 (2006) - // hse Paier J, Marsman M, Hummer K, et al, JPC 124(15): 154709 (2006) - - int iexch; - int icorr; - int igcx; - int igcc; - // internal indices for exchange-correlation - // iexch: type of exchange - // icorr: type of correlation - // igcx: type of gradient correction on exchange - // igcc: type of gradient correction on correlations - // see comments above and routine "which_dft" below - - // Peize Lin add 2016-12-03 - int iexch_now; - int icorr_now; - int igcx_now; - int igcc_now; - - xcfunc(); - ~xcfunc(); - - // there are four values of dft. - void which_dft(const std::string xc_func); - void printdft(std::ofstream &ofs); - void ostreamdft(std::ostream &ofs); // zws add 20150108 -private: - void set_dft_value(int &m,const int i); - bool match_one(const std::string* dft, const std::string &name)const; - void copy_to_now(); // Peize Lin add 2016-12-03 - void hybrid_first(); // Peize Lin add 2016-12-03 -}; - -#endif //FUNCTION_H diff --git a/source/run_lcao.cpp b/source/run_lcao.cpp index 72fbca1c48e..8d268ff9fb2 100644 --- a/source/run_lcao.cpp +++ b/source/run_lcao.cpp @@ -56,7 +56,14 @@ void Run_lcao::lcao_line(void) // it has been established that that // xc_func is same for all elements, therefore // only the first one if used - XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); + if(GlobalC::ucell.atoms[0].xc_func=="HSE" || GlobalC::ucell.atoms[0].xc_func=="PBE0") + { + XC_Functional::set_xc_type("pbe"); + } + else + { + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); + } //GlobalC::ucell.setup_cell( GlobalV::global_pseudo_dir , GlobalV::global_atom_card , GlobalV::ofs_running, GlobalV::NLOCAL, GlobalV::NBANDS); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); @@ -74,7 +81,7 @@ void Run_lcao::lcao_line(void) // print information // mohan add 2021-01-30 - Print_Info::setup_parameters(GlobalC::ucell, GlobalC::kv, GlobalC::xcf); + Print_Info::setup_parameters(GlobalC::ucell, GlobalC::kv); // * reading the localized orbitals/projectors // * construct the interpolation tables. @@ -146,6 +153,18 @@ void Run_lcao::lcao_line(void) GlobalC::pot.allocate(GlobalC::pw.nrxx); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running,"INIT POTENTIAL"); + if(GlobalV::CALCULATION=="nscf") + { + switch(GlobalC::exx_global.info.hybrid_type) + { + case Exx_Global::Hybrid_Type::HF: + case Exx_Global::Hybrid_Type::PBE0: + case Exx_Global::Hybrid_Type::HSE: + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); + break; + } + } + #ifdef __DEEPKS //wenfei 2021-12-19 //if we are performing DeePKS calculations, we need to load a model diff --git a/source/run_pw.cpp b/source/run_pw.cpp index 5df8493e30f..c801235320d 100644 --- a/source/run_pw.cpp +++ b/source/run_pw.cpp @@ -34,7 +34,14 @@ void Run_pw::plane_wave_line(void) // Yu Liu add 2021-07-03 GlobalC::CHR.cal_nelec(); - XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); + if(GlobalC::ucell.atoms[0].xc_func=="HSE"||GlobalC::ucell.atoms[0].xc_func=="PBE0") + { + XC_Functional::set_xc_type("pbe"); + } + else + { + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); + } ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); @@ -51,7 +58,7 @@ void Run_pw::plane_wave_line(void) // print information // mohan add 2021-01-30 - Print_Info::setup_parameters(GlobalC::ucell, GlobalC::kv, GlobalC::xcf); + Print_Info::setup_parameters(GlobalC::ucell, GlobalC::kv); // Initalize the plane wave basis set GlobalC::pw.gen_pw(GlobalV::ofs_running, GlobalC::ucell, GlobalC::kv); diff --git a/source/src_ions/ions.cpp b/source/src_ions/ions.cpp index 3213a5c6492..92e5d848cc1 100644 --- a/source/src_ions/ions.cpp +++ b/source/src_ions/ions.cpp @@ -56,53 +56,6 @@ void Ions::opt_ions_pw(void) if(GlobalV::OUT_LEVEL=="ie") { Print_Info::print_screen(stress_step, force_step, istep); -/* std::cout << " -------------------------------------------" << std::endl; - if(GlobalV::CALCULATION=="relax") //pengfei 2014-10-13 - { - std::cout << " STEP OF ION RELAXATION : " << istep << std::endl; - } - else if(GlobalV::CALCULATION=="cell-relax") - { - std::cout << " RELAX CELL : " << stress_step << std::endl; - std::cout << " RELAX IONS : " << force_step << " (in total: " << istep << ")" << std::endl; - } - else if(GlobalV::CALCULATION=="scf") //add 4 lines 2015-09-06, xiaohui - { - std::cout << " SELF-CONSISTENT : " << std::endl; - } - else if(GlobalV::CALCULATION=="nscf") //add 4 lines 2015-09-06, xiaohui - { - std::cout << " NONSELF-CONSISTENT : " << std::endl; - } - else if(GlobalV::CALCULATION=="md") - { - std::cout << " STEP OF MOLECULAR DYNAMICS : " << istep << std::endl; - } - std::cout << " -------------------------------------------" << std::endl; - - GlobalV::ofs_running << " -------------------------------------------" << std::endl; - if(GlobalV::CALCULATION=="relax") - { - GlobalV::ofs_running << " STEP OF ION RELAXATION : " << istep << std::endl; - } - else if(GlobalV::CALCULATION=="cell-relax") - { - GlobalV::ofs_running << " RELAX CELL : " << stress_step << std::endl; - GlobalV::ofs_running << " RELAX IONS : " << force_step << " (in total: " << istep << ")" << std::endl; - } - else if(GlobalV::CALCULATION=="md") - { - GlobalV::ofs_running << " STEP OF MOLECULAR DYNAMICS : " << istep << std::endl; - } - else if(GlobalV::CALCULATION=="scf") - { - GlobalV::ofs_running << " SELF-CONSISTENT" << std::endl; - } - else if(GlobalV::CALCULATION=="nscf") - { - GlobalV::ofs_running << " NONSELF-CONSISTENT" << std::endl; - } - GlobalV::ofs_running << " -------------------------------------------" << std::endl;*/ } //---------------------------------------------------------- @@ -157,7 +110,8 @@ void Ions::opt_ions_pw(void) elec.self_consistent(istep-1); eiter += elec.iter; if( elec.iter==1 || hybrid_step==GlobalC::exx_global.info.hybrid_step-1 ) // exx converge - break; + break; + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); GlobalC::exx_lip.cal_exx(); } } @@ -165,6 +119,7 @@ void Ions::opt_ions_pw(void) { elec.self_consistent(istep-1); eiter += elec.iter; + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); elec.self_consistent(istep-1); eiter += elec.iter; } diff --git a/source/src_lcao/ELEC_scf.cpp b/source/src_lcao/ELEC_scf.cpp index fab6d1fdc70..a9708d4f99e 100644 --- a/source/src_lcao/ELEC_scf.cpp +++ b/source/src_lcao/ELEC_scf.cpp @@ -220,14 +220,12 @@ void ELEC_scf::scf(const int &istep) } // calculate exact-exchange - if(XC_Functional::get_func_type()==4) // Peize Lin add 2018-10-30 + if(XC_Functional::get_func_type()==4) { - case 5: case 6: case 9: - if( !GlobalC::exx_global.info.separate_loop ) - { - GlobalC::exx_lcao.cal_exx_elec(); - } - break; + if( !GlobalC::exx_global.info.separate_loop ) + { + GlobalC::exx_lcao.cal_exx_elec(); + } } if(INPUT.dft_plus_u) @@ -315,12 +313,11 @@ void ELEC_scf::scf(const int &istep) GlobalC::en.set_exx(); // Peize Lin add 2020.04.04 - if(Exx_Global::Hybrid_Type::HF==GlobalC::exx_lcao.info.hybrid_type - || Exx_Global::Hybrid_Type::PBE0==GlobalC::exx_lcao.info.hybrid_type - || Exx_Global::Hybrid_Type::HSE==GlobalC::exx_lcao.info.hybrid_type) + if(XC_Functional::get_func_type()==4) { if(GlobalC::restart.info_load.load_H && GlobalC::restart.info_load.load_H_finish && !GlobalC::restart.info_load.restart_exx) { + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); GlobalC::exx_lcao.cal_exx_elec(); GlobalC::restart.info_load.restart_exx = true; } diff --git a/source/src_lcao/LCAO_hamilt.cpp b/source/src_lcao/LCAO_hamilt.cpp index 7f0e7666256..7d7a2e2d6d7 100644 --- a/source/src_lcao/LCAO_hamilt.cpp +++ b/source/src_lcao/LCAO_hamilt.cpp @@ -5,6 +5,7 @@ #include "global_fp.h" // mohan add 2021-01-30 #include "dftu.h" #include "../src_parallel/parallel_reduce.h" +#include "../module_xc/xc_functional.h" #ifdef __DEEPKS #include "../module_deepks/LCAO_deepks.h" //caoyu add 2021-07-26 #endif @@ -89,17 +90,20 @@ void LCAO_Hamilt::calculate_Hgamma( const int &ik ) // Peize Lin add ik 2016- this->GG.cal_vlocal(GlobalC::pot.vr_eff1); // Peize Lin add 2016-12-03 - if( 5==GlobalC::xcf.iexch_now && 0==GlobalC::xcf.igcx_now ) // HF + if(XC_Functional::get_func_type()==4) { - GlobalC::exx_lcao.add_Hexx(ik,1); - } - else if( 6==GlobalC::xcf.iexch_now && 8==GlobalC::xcf.igcx_now ) // PBE0 - { - GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); - } - else if( 9==GlobalC::xcf.iexch_now && 12==GlobalC::xcf.igcx_now ) // HSE - { - GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); + if( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type ) //HF + { + GlobalC::exx_lcao.add_Hexx(ik,1); + } + else if( Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type ) // PBE0 + { + GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); + } + else if( Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type ) // HSE + { + GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); + } } } @@ -244,17 +248,20 @@ void LCAO_Hamilt::calculate_Hk(const int &ik) } // Peize Lin add 2016-12-03 - if( 5==GlobalC::xcf.iexch_now && 0==GlobalC::xcf.igcx_now ) // HF + if(XC_Functional::get_func_type()==4) { - GlobalC::exx_lcao.add_Hexx(ik,1); - } - else if( 6==GlobalC::xcf.iexch_now && 8==GlobalC::xcf.igcx_now ) // PBE0 - { - GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); - } - else if( 9==GlobalC::xcf.iexch_now && 12==GlobalC::xcf.igcx_now ) // HSE - { - GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); + if( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type ) // HF + { + GlobalC::exx_lcao.add_Hexx(ik,1); + } + else if( Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type ) // PBE0 + { + GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); + } + else if( Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type ) // HSE + { + GlobalC::exx_lcao.add_Hexx(ik,GlobalC::exx_global.info.hybrid_alpha); + } } } diff --git a/source/src_lcao/LOOP_elec.cpp b/source/src_lcao/LOOP_elec.cpp index 9b70285952a..7c4ba06f3c9 100644 --- a/source/src_lcao/LOOP_elec.cpp +++ b/source/src_lcao/LOOP_elec.cpp @@ -180,18 +180,11 @@ void LOOP_elec::solver(const int &istep) || GlobalV::CALCULATION=="relax" || GlobalV::CALCULATION=="cell-relax") //pengfei 2014-10-13 { //Peize Lin add 2016-12-03 - switch(GlobalC::exx_lcao.info.hybrid_type) + if( Exx_Global::Hybrid_Type::HF==GlobalC::exx_lcao.info.hybrid_type + || Exx_Global::Hybrid_Type::PBE0==GlobalC::exx_lcao.info.hybrid_type + || Exx_Global::Hybrid_Type::HSE==GlobalC::exx_lcao.info.hybrid_type ) { - case Exx_Global::Hybrid_Type::HF: - case Exx_Global::Hybrid_Type::PBE0: - case Exx_Global::Hybrid_Type::HSE: - GlobalC::exx_lcao.cal_exx_ions(); - break; - case Exx_Global::Hybrid_Type::No: - case Exx_Global::Hybrid_Type::Generate_Matrix: - break; - default: - throw std::invalid_argument(ModuleBase::GlobalFunc::TO_STRING(__FILE__)+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + GlobalC::exx_lcao.cal_exx_ions(); } // No exx @@ -213,6 +206,7 @@ void LOOP_elec::solver(const int &istep) { for( size_t hybrid_step=0; hybrid_step!=GlobalC::exx_global.info.hybrid_step; ++hybrid_step ) { + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); GlobalC::exx_lcao.cal_exx_elec(); ELEC_scf es; @@ -225,6 +219,7 @@ void LOOP_elec::solver(const int &istep) } else { + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); ELEC_scf es; es.scf(istep-1); diff --git a/source/src_pw/electrons.cpp b/source/src_pw/electrons.cpp index 244d0c305cf..4706989ea7b 100644 --- a/source/src_pw/electrons.cpp +++ b/source/src_pw/electrons.cpp @@ -185,14 +185,15 @@ void Electrons::self_consistent(const int &istep) // calculate exact-exchange #ifdef __LCAO - switch(GlobalC::xcf.iexch_now) // Peize Lin add 2019-03-09 - { - case 5: case 6: case 9: - if( !GlobalC::exx_global.info.separate_loop ) - { - GlobalC::exx_lip.cal_exx(); - } - break; + if( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type ) + { + if( !GlobalC::exx_global.info.separate_loop ) + { + GlobalC::exx_lip.cal_exx(); + } + break; } #endif //(2) save change density as previous charge, diff --git a/source/src_pw/electrons.cu b/source/src_pw/electrons.cu index ef4497995dc..7679e8570f1 100644 --- a/source/src_pw/electrons.cu +++ b/source/src_pw/electrons.cu @@ -218,14 +218,15 @@ void Electrons::self_consistent(const int &istep) // calculate exact-exchange #ifdef __LCAO - switch(GlobalC::xcf.iexch_now) // Peize Lin add 2019-03-09 - { - case 5: case 6: case 9: - if( !GlobalC::exx_global.info.separate_loop ) - { - GlobalC::exx_lip.cal_exx(); - } - break; + if( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type ) + { + if( !GlobalC::exx_global.info.separate_loop ) + { + GlobalC::exx_lip.cal_exx(); + } + break; } #endif //(2) save change density as previous charge, diff --git a/source/src_pw/electrons_hip.cpp b/source/src_pw/electrons_hip.cpp index 1f3d03d6386..b4438c27646 100644 --- a/source/src_pw/electrons_hip.cpp +++ b/source/src_pw/electrons_hip.cpp @@ -198,9 +198,6 @@ void Electrons::self_consistent(const int &istep) if (GlobalV::FINAL_SCF && iter == 1) { init_mixstep_final_scf(); - // GlobalC::CHR.irstep=0; - // GlobalC::CHR.idstep=0; - // GlobalC::CHR.totstep=0; } // mohan move harris functional to here, 2012-06-05 @@ -211,11 +208,10 @@ void Electrons::self_consistent(const int &istep) // calculate exact-exchange #ifdef __LCAO - switch (GlobalC::xcf.iexch_now) // Peize Lin add 2019-03-09 + if( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type ) { - case 5: - case 6: - case 9: if (!GlobalC::exx_global.info.separate_loop) { GlobalC::exx_lip.cal_exx(); diff --git a/source/src_pw/energy.cpp b/source/src_pw/energy.cpp index 4d67ef8fe0e..c5fc9d81e39 100644 --- a/source/src_pw/energy.cpp +++ b/source/src_pw/energy.cpp @@ -548,15 +548,12 @@ void energy::set_exx() throw std::invalid_argument(ModuleBase::GlobalFunc::TO_STRING(__FILE__)+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); } }; - if( 5==GlobalC::xcf.iexch_now && 0==GlobalC::xcf.igcx_now ) // HF + if( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type ) // HF { this->exx = exx_energy(); } - else if( 6==GlobalC::xcf.iexch_now && 8==GlobalC::xcf.igcx_now ) // PBE0 - { - this->exx = GlobalC::exx_global.info.hybrid_alpha * exx_energy(); - } - else if( 9==GlobalC::xcf.iexch_now && 12==GlobalC::xcf.igcx_now ) // HSE + else if( Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type ) // PBE0 or HSE { this->exx = GlobalC::exx_global.info.hybrid_alpha * exx_energy(); } diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index 3fc6a13c4c9..112d2bc9cb8 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -571,7 +571,7 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) } else { - const auto etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); + const auto etxc_vtxc_v = XC_Functional::v_xc_libxc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); diff --git a/source/src_pw/global.cpp b/source/src_pw/global.cpp index 392aeb0dd4e..8785744d51e 100644 --- a/source/src_pw/global.cpp +++ b/source/src_pw/global.cpp @@ -17,7 +17,6 @@ Exx_Lip exx_lip(exx_global.info); #endif pseudopot_cell_vnl ppcell; UnitCell_pseudo ucell; -xcfunc xcf; Charge_Broyden CHR; Potential pot; ModuleSymmetry::Symmetry symm; diff --git a/source/src_pw/global.h b/source/src_pw/global.h index e1c0a145560..a17b13eedc6 100644 --- a/source/src_pw/global.h +++ b/source/src_pw/global.h @@ -328,7 +328,6 @@ extern pseudopot_cell_vnl ppcell; namespace GlobalC { extern UnitCell_pseudo ucell; -extern xcfunc xcf; extern Charge_Broyden CHR; extern Potential pot; extern ModuleSymmetry::Symmetry symm; diff --git a/source/src_pw/hamilt_pw.cpp b/source/src_pw/hamilt_pw.cpp index 534db55e292..a106ee3a0a6 100644 --- a/source/src_pw/hamilt_pw.cpp +++ b/source/src_pw/hamilt_pw.cpp @@ -171,17 +171,17 @@ void Hamilt_PW::diagH_subspace( } } }; - if( 5==GlobalC::xcf.iexch_now && 0==GlobalC::xcf.igcx_now ) // HF + if(XC_Functional::get_func_type()==4) { - add_Hexx(1); - } - else if( 6==GlobalC::xcf.iexch_now && 8==GlobalC::xcf.igcx_now ) // PBE0 - { - add_Hexx(GlobalC::exx_global.info.hybrid_alpha); - } - else if( 9==GlobalC::xcf.iexch_now && 12==GlobalC::xcf.igcx_now ) // HSE - { - add_Hexx(GlobalC::exx_global.info.hybrid_alpha); + if ( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type ) // HF + { + add_Hexx(1); + } + else if (Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type) // PBE0 or HSE + { + add_Hexx(GlobalC::exx_global.info.hybrid_alpha); + } } } #endif diff --git a/source/src_pw/hamilt_pw.cu b/source/src_pw/hamilt_pw.cu index 7ef18d93d43..12019b27eb2 100644 --- a/source/src_pw/hamilt_pw.cu +++ b/source/src_pw/hamilt_pw.cu @@ -303,17 +303,17 @@ void Hamilt_PW::diagH_subspace( } } }; - if( 5==GlobalC::xcf.iexch_now && 0==GlobalC::xcf.igcx_now ) // HF + if(XC_Functional::get_func_type()==4) { - add_Hexx(1); - } - else if( 6==GlobalC::xcf.iexch_now && 8==GlobalC::xcf.igcx_now ) // PBE0 - { - add_Hexx(GlobalC::exx_global.info.hybrid_alpha); - } - else if( 9==GlobalC::xcf.iexch_now && 12==GlobalC::xcf.igcx_now ) // HSE - { - add_Hexx(GlobalC::exx_global.info.hybrid_alpha); + if ( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type ) // HF + { + add_Hexx(1); + } + else if (Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type) // PBE0 or HSE + { + add_Hexx(GlobalC::exx_global.info.hybrid_alpha); + } } } #endif diff --git a/source/src_pw/hamilt_pw_hip.cpp b/source/src_pw/hamilt_pw_hip.cpp index 1a5aef9af55..97f29b2e7e8 100644 --- a/source/src_pw/hamilt_pw_hip.cpp +++ b/source/src_pw/hamilt_pw_hip.cpp @@ -318,17 +318,17 @@ void Hamilt_PW::diagH_subspace(const int ik, } } }; - if (5 == GlobalC::xcf.iexch_now && 0 == GlobalC::xcf.igcx_now) // HF + if(XC_Functional::get_func_type()==4) { - add_Hexx(1); - } - else if (6 == GlobalC::xcf.iexch_now && 8 == GlobalC::xcf.igcx_now) // PBE0 - { - add_Hexx(GlobalC::exx_global.info.hybrid_alpha); - } - else if (9 == GlobalC::xcf.iexch_now && 12 == GlobalC::xcf.igcx_now) // HSE - { - add_Hexx(GlobalC::exx_global.info.hybrid_alpha); + if ( Exx_Global::Hybrid_Type::HF == GlobalC::exx_lcao.info.hybrid_type ) // HF + { + add_Hexx(1); + } + else if (Exx_Global::Hybrid_Type::PBE0 == GlobalC::exx_lcao.info.hybrid_type || + Exx_Global::Hybrid_Type::HSE == GlobalC::exx_lcao.info.hybrid_type) // PBE0 or HSE + { + add_Hexx(GlobalC::exx_global.info.hybrid_alpha); + } } } #endif diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index ad9937a69d7..abedd7a6f35 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -336,7 +336,7 @@ ModuleBase::matrix Potential::v_of_rho( } else { - const std::tuple etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); + const std::tuple etxc_vtxc_v = XC_Functional::v_xc_libxc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); diff --git a/source/src_pw/run_md_pw.cpp b/source/src_pw/run_md_pw.cpp index 66c829480d3..c96f96ed2e8 100644 --- a/source/src_pw/run_md_pw.cpp +++ b/source/src_pw/run_md_pw.cpp @@ -303,6 +303,7 @@ void Run_MD_PW::md_force_virial( eiter += elec.iter; if (elec.iter == 1 || hybrid_step == GlobalC::exx_global.info.hybrid_step - 1) // exx converge break; + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); GlobalC::exx_lip.cal_exx(); } } @@ -310,6 +311,7 @@ void Run_MD_PW::md_force_virial( { elec.self_consistent(istep); eiter += elec.iter; + XC_Functional::set_xc_type(GlobalC::ucell.atoms[0].xc_func); elec.self_consistent(istep); eiter += elec.iter; } diff --git a/source/src_ri/exx_lcao.h b/source/src_ri/exx_lcao.h index a9c5a19c281..ae6cf857e42 100644 --- a/source/src_ri/exx_lcao.h +++ b/source/src_ri/exx_lcao.h @@ -10,7 +10,6 @@ #include "exx_abfs-screen-schwarz.h" #include "exx_abfs-screen-cauchy.h" #include "../module_base/element_basis_index.h" -#include "../module_xc/xc_type.h" #include "../module_xc/exx_global.h" #if EXX_DM==1 From 1030dfe374050908417b904ada33de0119482d4f Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Mon, 14 Feb 2022 23:01:26 +0800 Subject: [PATCH 07/36] xc refactor : make v_xc common interface to LDA functionals (using or not using libxc) --- source/module_xc/H_XC_pw.cpp | 47 ++++--- source/module_xc/potential_libxc.cpp | 20 +-- source/module_xc/xc_functional.cpp | 176 ++++++++++++++++++--------- source/module_xc/xc_functional.h | 7 +- source/src_pw/forces.cpp | 2 +- source/src_pw/potential.cpp | 2 +- 6 files changed, 155 insertions(+), 99 deletions(-) diff --git a/source/module_xc/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp index 6b968fcf3b4..a51287861cf 100644 --- a/source/module_xc/H_XC_pw.cpp +++ b/source/module_xc/H_XC_pw.cpp @@ -25,11 +25,6 @@ std::tuple XC_Functional::v_xc double vtxc = 0.0; ModuleBase::matrix v(GlobalV::NSPIN, nrxx); - if(GlobalV::VXC_IN_H == 0) - { - ModuleBase::timer::tick("H_XC_pw","v_xc"); - return std::make_tuple(etxc, vtxc, std::move(v)); - } // the square of the e charge // in Rydeberg unit, so * 2.0. double e2 = 2.0; @@ -41,7 +36,6 @@ std::tuple XC_Functional::v_xc double vxc[2]; int ir, is; - int neg [3]; double vanishing_charge = 1.0e-10; @@ -55,7 +49,16 @@ std::tuple XC_Functional::v_xc arhox = abs(rhox); if (arhox > vanishing_charge) { - XC_Functional::xc(arhox, exc, vxc[0]); + if(use_libxc) + { + std::cout << "xc_libxc" << std::endl; + XC_Functional::xc_libxc(arhox, exc, vxc[0]); + } + else + { + std::cout << "xc" << std::endl; + XC_Functional::xc(arhox, exc, vxc[0]); + } v(0,ir) = e2 * vxc[0]; // consider the total charge density etxc += e2 * exc * rhox; @@ -67,10 +70,6 @@ std::tuple XC_Functional::v_xc else if(GlobalV::NSPIN ==2) { // spin-polarized case - neg [0] = 0; - neg [1] = 0; - neg [2] = 0; - for (ir = 0;ir < nrxx;ir++) { rhox = rho_in[0][ir] + rho_in[1][ir] + rho_core[ir]; //HLX(05-29-06): bug fixed @@ -82,30 +81,31 @@ std::tuple XC_Functional::v_xc if (abs(zeta) > 1.0) { - ++neg[2]; zeta = (zeta > 0.0) ? 1.0 : (-1.0); } - if (rho_in[0][ir] < 0.0) + // call + if(use_libxc) { - ++neg[0]; + std::cout << "xc_libxc" << std::endl; + double rhoup = arhox * (1.0+zeta) / 2.0; + double rhodw = arhox * (1.0-zeta) / 2.0; + XC_Functional::xc_spin(rhoup, rhodw, exc, vxc[0], vxc[1]); } - - if (rho_in[1][ir] < 0.0) + else { - ++neg[1]; + std::cout << "xc" << std::endl; + double rhoup = arhox * (1.0+zeta) / 2.0; + double rhodw = arhox * (1.0-zeta) / 2.0; + XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); } - // call - XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); - for (is = 0;is < GlobalV::NSPIN;is++) { v(is, ir) = e2 * vxc[is]; } etxc += e2 * exc * rhox; - vtxc += v(0, ir) * rho_in[0][ir] + v(1, ir) * rho_in[1][ir]; } } @@ -119,8 +119,6 @@ std::tuple XC_Functional::v_xc rhox = rho_in[0][ir] + rho_core[ir]; - if ( rho_in[0][ir] < 0.0 ) neg[0] -= rho_in[0][ir]; - arhox = abs( rhox ); if ( arhox > vanishing_charge ) @@ -129,11 +127,8 @@ std::tuple XC_Functional::v_xc if ( abs( zeta ) > 1.0 ) { - neg[1] += 1.0 / omega; - zeta = (zeta > 0.0) ? 1.0 : (-1.0); }//end if - XC_Functional::xc_spin( arhox, zeta, exc, vxc[0], vxc[1]); etxc += e2 * exc * rhox; diff --git a/source/module_xc/potential_libxc.cpp b/source/module_xc/potential_libxc.cpp index 3d9f739c38f..514f546abde 100644 --- a/source/module_xc/potential_libxc.cpp +++ b/source/module_xc/potential_libxc.cpp @@ -48,7 +48,8 @@ std::tuple XC_Functional::v_xc_libxc( // use can check on website, for example: // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ //---------------------------------------------------------- - std::vector funcs = init_func(); + const int xc_polarized = (1==nspin0()) ? XC_UNPOLARIZED : XC_POLARIZED; + std::vector funcs = init_func(xc_polarized); bool is_gga = false; for( xc_func_type &func : funcs ) @@ -152,13 +153,13 @@ std::tuple XC_Functional::v_xc_libxc( if(nspin0()==2 && func.info->family != XC_FAMILY_LDA && func.info->kind==XC_CORRELATION) { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - if ( rho[ir*2] XC_Functional::v_xc_libxc( return std::make_tuple( etxc, vtxc, std::move(v) ); } -std::vector XC_Functional::init_func() +std::vector XC_Functional::init_func(const int xc_polarized) { // 'funcs' is the return value std::vector funcs; - const int xc_polarized = (1==nspin0()) ? XC_UNPOLARIZED : XC_POLARIZED; //------------------------------------------- // define a function named 'add_func', which diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index 89574a664f4..c1e20359d2d 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -2,6 +2,7 @@ #include "../src_pw/global.h" #include "../module_base/global_function.h" #include +#include XC_Functional::XC_Functional(){} @@ -9,14 +10,14 @@ XC_Functional::~XC_Functional(){} std::vector XC_Functional::func_id(1); int XC_Functional::func_type = 0; +bool XC_Functional::use_libxc = true; int XC_Functional::get_func_type() { return func_type; } -// The setting values of functional id -// according to the index in LIBXC +// The setting values of functional id according to the index in LIBXC // for detail, refer to https://www.tddft.org/programs/libxc/functionals/ void XC_Functional::set_xc_type(const std::string xc_func_in) { @@ -29,72 +30,84 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) // but since we are not compiling with libxc as default, // I chose to set it manually instead. // Same for the rest. - func_id.push_back(1); - func_id.push_back(9); + func_id.push_back(XC_LDA_X); + func_id.push_back(XC_LDA_C_PZ); func_type = 1; + use_libxc = false; } else if ( xc_func == "PBE" || xc_func == "SLAPWPBXPBC") //PBX+PBC { - func_id.push_back(101); - func_id.push_back(130); + func_id.push_back(XC_GGA_X_PBE); + func_id.push_back(XC_GGA_C_PBE); func_type = 2; + use_libxc = false; } else if( xc_func == "revPBE" ) //rPBX+PBC { - func_id.push_back(117); - func_id.push_back(130); + func_id.push_back(XC_GGA_X_RPBE); + func_id.push_back(XC_GGA_C_PBE); func_type = 2; + use_libxc = false; } else if ( xc_func == "PBEsol") //PBXsol+PBCsol { - func_id.push_back(116); - func_id.push_back(133); + func_id.push_back(XC_GGA_X_PBE_SOL); + func_id.push_back(XC_GGA_C_PBE_SOL); func_type = 2; + use_libxc = false; } else if ( xc_func == "WC") //WC+PBC { - func_id.push_back(118); - func_id.push_back(130); + func_id.push_back(XC_GGA_X_WC); + func_id.push_back(XC_GGA_C_PBE); func_type = 2; + use_libxc = false; } - else if ( xc_func == "BLYP") //B88+BLYP + else if ( xc_func == "BLYP") //B88+LYP { - func_id.push_back(106); - func_id.push_back(131); + func_id.push_back(XC_GGA_X_B88); + func_id.push_back(XC_GGA_C_LYP); + func_type = 2; + use_libxc = false; } else if ( xc_func == "BP") //B88+P86 { - func_id.push_back(106); - func_id.push_back(132); + func_id.push_back(XC_GGA_X_B88); + func_id.push_back(XC_GGA_C_P86); func_type = 2; + use_libxc = false; } else if ( xc_func == "PW91") //PW91_X+PW91_C { - func_id.push_back(109); - func_id.push_back(134); + func_id.push_back(XC_GGA_X_PW91); + func_id.push_back(XC_GGA_C_PW91); func_type = 2; + use_libxc = false; } else if ( xc_func == "HCTH") //HCTH_X+HCTH_C { - func_id.push_back(34); - func_id.push_back(97); + func_id.push_back(XC_GGA_X_HCTH_A); + func_id.push_back(XC_GGA_C_HCTH_A); func_type = 2; + use_libxc = false; } - else if ( xc_func == "OLYP") //OPTX+BLYP + else if ( xc_func == "OLYP") //OPTX+LYP { - func_id.push_back(110); - func_id.push_back(131); + func_id.push_back(XC_GGA_X_OPTX); + func_id.push_back(XC_GGA_C_LYP); func_type = 2; + use_libxc = false; } else if ( xc_func == "SCAN") { - func_id.push_back(263); - func_id.push_back(267); + func_id.push_back(XC_MGGA_X_SCAN); + func_id.push_back(XC_MGGA_C_SCAN); + func_type = 3; GlobalV::DFT_META = 1; } else if( xc_func == "PBE0") { - func_id.push_back(406); + func_id.push_back(XC_HYB_GGA_XC_PBEH); func_type = 4; } else if( xc_func == "HF" || xc_func == "OPT_ORB" || xc_func == "NONE") @@ -104,7 +117,7 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) } else if( xc_func == "HSE") { - func_id.push_back(428); + func_id.push_back(XC_HYB_GGA_XC_HSE06); func_type = 4; } else @@ -118,9 +131,30 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) } } +void XC_Functional::xc_libxc(const double &rho, double &exc, double &vxc) +{ + + double e,v; + exc = vxc = 0.00; + + std::vector funcs = init_func(XC_UNPOLARIZED); + + for(xc_func_type &func : funcs) + { + if( func.info->family == XC_FAMILY_LDA) + { + // call Libxc function: xc_lda_exc_vxc + xc_lda_exc_vxc( &func, 1, &rho, &e, &v); + } + exc += e; + vxc += v; + } + return; +} + void XC_Functional::xc(const double &rho, double &exc, double &vxc) { - double small = 1.e-10; + double third = 1.0 / 3.0; double pi34 = 0.6203504908994e0 ; // pi34=(3/4pi)^(1/3) double rs; @@ -128,50 +162,43 @@ void XC_Functional::xc(const double &rho, double &exc, double &vxc) exc = vxc = 0.00; - if(rho <= small) - { - - return; - } - else - { - rs = pi34 / std::pow(rho, third); - } + rs = pi34 / std::pow(rho, third); for(int id : func_id) { switch( id ) { // Exchange functionals containing slater exchange - case 1: case 101: case 117: case 116: case 118: case 106: case 109: - // SLA PBX rPBX PBXsol WC B88 PW91_X + case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: case XC_GGA_X_PBE_SOL: + case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: + // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X XC_Functional::slater(rs, e, v);break; // Exchange functionals containing attenuated slater exchange - case 406: + case XC_HYB_GGA_XC_PBEH: // PBE0 XC_Functional::slater(rs, e, v); e *= 0.75; v*= 0.75; break; // Correlation functionals containing PW correlation - case 130: case 133: - // PBC PBCsol + case XC_GGA_C_PBE: case XC_GGA_C_PBE_SOL: + // PBC,PBCsol XC_Functional::pw(rs, 0, e, v);break; // Correlation functionals containing PZ correlation - case 9: case 132: - // PZ P86 + case XC_LDA_C_PZ: case XC_GGA_C_P86: + // PZ,P86 XC_Functional::pz(rs, 0, e, v);break; // Correlation functionals containing LYP correlation - case 131: + case XC_GGA_C_LYP: // BLYP XC_Functional::lyp(rs, e, v);break; // Functionals that are realized only using LIBXC - case 428: case 263: case 267: - // HSE SCAN_X SCAN_C + case XC_HYB_GGA_XC_HSE06: case XC_MGGA_X_SCAN: case XC_MGGA_C_SCAN: + // HSE,SCAN_X,SCAN_C throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); default: @@ -183,6 +210,38 @@ void XC_Functional::xc(const double &rho, double &exc, double &vxc) return; } +void XC_Functional::xc_spin_libxc(const double &rhoup, const double &rhodw, + double &exc, double &vxcup, double &vxcdw) +{ + + double e, vup, vdw; + double *rho_ud, *vxc_ud; + exc = vxcup = vxcdw = 0.0; + + rho_ud = new double[2]; + vxc_ud = new double[2]; + rho_ud[0] = rhoup; + rho_ud[1] = rhodw; + + std::vector funcs = init_func(XC_POLARIZED); + + for(xc_func_type &func : funcs) + { + if( func.info->family == XC_FAMILY_LDA) + { + // call Libxc function: xc_lda_exc_vxc + xc_lda_exc_vxc( &func, 1, rho_ud, &e, vxc_ud); + } + exc += e; + vxcup += vxc_ud[0]; + vxcdw += vxc_ud[1]; + } + + + delete[] rho_ud; + delete[] vxc_ud; +} + void XC_Functional::xc_spin(const double &rho, const double &zeta, double &exc, double &vxcup, double &vxcdw) { @@ -190,11 +249,6 @@ void XC_Functional::xc_spin(const double &rho, const double &zeta, double e, vup, vdw; exc = vxcup = vxcdw = 0.0; - if (rho <= small) - { - return; - } - static const double third = 1.0 / 3.0; static const double pi34 = 0.62035049089940; const double rs = pi34 / pow(rho, third);//wigner_sitz_radius; @@ -204,29 +258,31 @@ void XC_Functional::xc_spin(const double &rho, const double &zeta, switch( id ) { // Exchange functionals containing slater exchange - case 1: case 101: case 117: case 116: case 118: case 106: case 109: - // SLA PBX rPBX PBXsol WC B88 PW91_X + case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: case XC_GGA_X_PBE_SOL: + case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: + // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X XC_Functional::slater_spin(rho, zeta, e, vup, vdw); break; // Exchange functionals containing attenuated slater exchange - case 406: + case XC_HYB_GGA_XC_PBEH: // PBE0 XC_Functional::slater_spin(rho, zeta, e, vup, vdw); e *= 0.75; vup *= 0.75; vdw *=0.75; break; // Correlation functionals containing PZ correlation - case 9: case 132: + case XC_LDA_C_PZ: case XC_GGA_C_P86: + // PZ,P86 XC_Functional::pz_spin(rs, zeta, e, vup, vdw); break; // Correlation functionals containing PW correlationtests/integrate/101_PW_OU_pseudopot - case 130: case 133: - // PBC PBCsol + case XC_GGA_C_PBE: case XC_GGA_C_PBE_SOL: + // PBC,PBCsol XC_Functional::pw_spin(rs, zeta, e, vup, vdw); break; // Correlation functionals that already contains LDA components // so sets to 0 here - case 34: case 97: case 110: + case XC_GGA_X_HCTH_A: case XC_GGA_C_HCTH_A: case XC_GGA_X_OPTX: //HCTH_X HTCH_C OPTX e = vup = vdw =0.0; diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 8bdc6b58d43..07dd1ecf06d 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -104,16 +104,21 @@ class XC_Functional static std::vector func_id; // id of exchange functional static int func_type; //0:none, 1:lda, 2:gga, 3:mgga, 4:hybrid + static bool use_libxc; static void set_xc_type(const std::string xc_func_in); - static std::vector init_func(); + static std::vector init_func(const int xc_polarized); // LDA static void xc(const double &rho, double &exc, double &vxc); + static void xc_libxc(const double &rho, double &exc, double &vxc); + // LSDA static void xc_spin(const double &rho, const double &zeta, double &exc, double &vxcup, double &vxcdw); + static void xc_spin_libxc(const double &rhoup, const double &rhodw, + double &exc, double &vxcup, double &vxcdw); // For LDA exchange energy static void slater(const double &rs, double &ex, double &vx); diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index 112d2bc9cb8..3fc6a13c4c9 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -571,7 +571,7 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) } else { - const auto etxc_vtxc_v = XC_Functional::v_xc_libxc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); + const auto etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index abedd7a6f35..ad9937a69d7 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -336,7 +336,7 @@ ModuleBase::matrix Potential::v_of_rho( } else { - const std::tuple etxc_vtxc_v = XC_Functional::v_xc_libxc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); + const std::tuple etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); From 10db92d9f3f6b7c50329bc03f9c943887c048dda Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Mon, 14 Feb 2022 23:01:55 +0800 Subject: [PATCH 08/36] xc refactor : make compiling with libxc as default --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c67d764f63f..28e82c1e11a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ project(ABACUS ) option(ENABLE_DEEPKS "Enable DeePKS functionality" OFF) -option(ENABLE_LIBXC "Enable LibXC functionality" OFF) +option(ENABLE_LIBXC "Enable LibXC functionality" ON) option(USE_CUDA "Enable support to CUDA." OFF) option(USE_ROCM "Enable support to ROCm." OFF) option(USE_OPENMP " Enable OpenMP in abacus." ON) From b52318d67c09c8635740da716f7a1dabcacf0fe4 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Tue, 15 Feb 2022 22:32:05 +0800 Subject: [PATCH 09/36] xc refactor : allow libxc for nspin = 4 --- source/module_xc/H_XC_pw.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/source/module_xc/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp index a51287861cf..3d37ea47183 100644 --- a/source/module_xc/H_XC_pw.cpp +++ b/source/module_xc/H_XC_pw.cpp @@ -90,7 +90,7 @@ std::tuple XC_Functional::v_xc std::cout << "xc_libxc" << std::endl; double rhoup = arhox * (1.0+zeta) / 2.0; double rhodw = arhox * (1.0-zeta) / 2.0; - XC_Functional::xc_spin(rhoup, rhodw, exc, vxc[0], vxc[1]); + XC_Functional::xc_spin_libxc(rhoup, rhodw, exc, vxc[0], vxc[1]); } else { @@ -129,8 +129,22 @@ std::tuple XC_Functional::v_xc { zeta = (zeta > 0.0) ? 1.0 : (-1.0); }//end if - XC_Functional::xc_spin( arhox, zeta, exc, vxc[0], vxc[1]); - + + if(use_libxc) + { + std::cout << "xc_libxc" << std::endl; + double rhoup = arhox * (1.0+zeta) / 2.0; + double rhodw = arhox * (1.0-zeta) / 2.0; + XC_Functional::xc_spin_libxc(rhoup, rhodw, exc, vxc[0], vxc[1]); + } + else + { + std::cout << "xc" << std::endl; + double rhoup = arhox * (1.0+zeta) / 2.0; + double rhodw = arhox * (1.0-zeta) / 2.0; + XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); + } + etxc += e2 * exc * rhox; v(0, ir) = e2*( 0.5 * ( vxc[0] + vxc[1]) ); From ec96646d760d46e76629e43e6b3e5ab020bd8239 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Thu, 17 Feb 2022 16:48:03 +0800 Subject: [PATCH 10/36] xc refactor : 1. add PWLDA functional 2. modify some parameters in pbex and pbec 3. add interface gcxc_libxc --- source/module_xc/H_XC_pw.cpp | 6 ----- source/module_xc/xc_functional.cpp | 43 +++++++++++++++++++++++++----- source/module_xc/xc_functional.h | 3 +++ source/module_xc/xc_gga_pw.cpp | 42 ++++++++++++++++++----------- 4 files changed, 67 insertions(+), 27 deletions(-) diff --git a/source/module_xc/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp index 3d37ea47183..a05f3a1f2ce 100644 --- a/source/module_xc/H_XC_pw.cpp +++ b/source/module_xc/H_XC_pw.cpp @@ -51,12 +51,10 @@ std::tuple XC_Functional::v_xc { if(use_libxc) { - std::cout << "xc_libxc" << std::endl; XC_Functional::xc_libxc(arhox, exc, vxc[0]); } else { - std::cout << "xc" << std::endl; XC_Functional::xc(arhox, exc, vxc[0]); } v(0,ir) = e2 * vxc[0]; @@ -87,14 +85,12 @@ std::tuple XC_Functional::v_xc // call if(use_libxc) { - std::cout << "xc_libxc" << std::endl; double rhoup = arhox * (1.0+zeta) / 2.0; double rhodw = arhox * (1.0-zeta) / 2.0; XC_Functional::xc_spin_libxc(rhoup, rhodw, exc, vxc[0], vxc[1]); } else { - std::cout << "xc" << std::endl; double rhoup = arhox * (1.0+zeta) / 2.0; double rhodw = arhox * (1.0-zeta) / 2.0; XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); @@ -132,14 +128,12 @@ std::tuple XC_Functional::v_xc if(use_libxc) { - std::cout << "xc_libxc" << std::endl; double rhoup = arhox * (1.0+zeta) / 2.0; double rhodw = arhox * (1.0-zeta) / 2.0; XC_Functional::xc_spin_libxc(rhoup, rhodw, exc, vxc[0], vxc[1]); } else { - std::cout << "xc" << std::endl; double rhoup = arhox * (1.0+zeta) / 2.0; double rhodw = arhox * (1.0-zeta) / 2.0; XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index c1e20359d2d..e8a9b28e347 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -34,7 +34,14 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) func_id.push_back(XC_LDA_C_PZ); func_type = 1; use_libxc = false; - } + } + else if (xc_func == "PWLDA") + { + func_id.push_back(XC_LDA_X); + func_id.push_back(XC_LDA_C_PW); + func_type = 1; + //use_libxc = false; + } else if ( xc_func == "PBE" || xc_func == "SLAPWPBXPBC") //PBX+PBC { func_id.push_back(XC_GGA_X_PBE); @@ -182,7 +189,7 @@ void XC_Functional::xc(const double &rho, double &exc, double &vxc) break; // Correlation functionals containing PW correlation - case XC_GGA_C_PBE: case XC_GGA_C_PBE_SOL: + case XC_GGA_C_PBE: case XC_GGA_C_PBE_SOL: case XC_GGA_C_PW91: case XC_LDA_C_PW: // PBC,PBCsol XC_Functional::pw(rs, 0, e, v);break; @@ -805,12 +812,13 @@ double &sx, double &v1x, double &v2x) // numerical coefficients (NB: c2=(3 pi^2)^(1/3) ) const double third = 1.0 / 3.0; - const double c1 = 0.750 / ModuleBase::PI; + const double pi = 3.14159265358979323846; + const double c1 = 0.750 / pi; const double c2 = 3.0936677262801360; const double c5 = 4.0 * third; // parameters of the functional double k[3] = { 0.8040, 1.24500, 0.8040 }; - const double mu[3] = {0.2195149727645171, 0.2195149727645171, 0.12345679012345679012} ;//modified by zhengdy, to ensure the same parameters with another dft code. + const double mu[3] = {0.2195149727645171, 0.2195149727645171, 0.12345679012345679} ;//modified by zhengdy, to ensure the same parameters with another dft code. const double agrho = sqrt(grho); const double kf = c2 * pow(rho, third); @@ -987,8 +995,8 @@ void XC_Functional::pbec(const double &rho, const double &grho, const int &iflag // PBE correlation (without LDA part) // iflag=0: J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996). // iflag=1: J.P.Perdew et al., PRL 100, 136406 (2008). - const double ga = 0.0310910; - const double be[2] = {0.0667250, 0.046}; + const double ga = 0.0310906908696548950; + const double be[2] = {0.06672455060314922, 0.046}; const double third = 1.0 / 3.0; const double pi34 = 0.62035049089940; @@ -1218,6 +1226,29 @@ void XC_Functional::gcxc(const double &rho, const double &grho, double &sxc, return; } +void XC_Functional::gcxc_libxc(const double &rho, const double &grho, double &sxc, + double &v1xc, double &v2xc) +{ + + double s,v1,v2; + sxc = v1xc = v2xc = 0.0; + + std::vector funcs = init_func(XC_UNPOLARIZED); + + for(xc_func_type &func : funcs) + { + if( func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) + { + // call Libxc function: xc_gga_exc_vxc + xc_gga_exc_vxc( &func, 1, &rho, &grho, &s, &v1, &v2); + } + sxc += s; + v1xc += v1; + v2xc += v2; + } + return; +} + void XC_Functional::optx(const double rho, const double grho, double &sx, double &v1x, double &v2x) { // OPTX, Handy et al. JCP 116, p. 5411 (2002) and refs. therein diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 07dd1ecf06d..26af2e814aa 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -78,6 +78,9 @@ class XC_Functional static void gcxc(const double &rho, const double &grho, double &sxc, double &v1xc, double &v2xc); + static void gcxc_libxc(const double &rho, const double &grho, + double &sxc, double &v1xc, double &v2xc); + // spin polarized GGA static void gcx_spin(double rhoup, double rhodw, double grhoup2, double grhodw2, double &sx, double &v1xup, double &v1xdw, double &v2xup, diff --git a/source/module_xc/xc_gga_pw.cpp b/source/module_xc/xc_gga_pw.cpp index 6f6d63ee3d6..90e3b4574c3 100644 --- a/source/module_xc/xc_gga_pw.cpp +++ b/source/module_xc/xc_gga_pw.cpp @@ -9,7 +9,7 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) if(func_type == 0 || func_type == 1) return; // none or LDA functional bool igcc_is_lyp = false; - if( func_id[1] == 131) igcc_is_lyp = true; + if( func_id[1] == XC_GGA_C_LYP) igcc_is_lyp = true; int nspin0 = GlobalV::NSPIN; if(GlobalV::NSPIN==4) nspin0 =1; @@ -134,26 +134,38 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) { const double arho = std::abs( rhotmp1[ir] ); h1[ir].x = h1[ir].y = h1[ir].z = 0.0; + if(arho > epsr) { grho2a = gdr1[ir].norm2(); - if( grho2a > epsg ) - { + //if( grho2a > epsg ) + //{ if( rhotmp1[ir] >= 0.0 ) segno = 1.0; if( rhotmp1[ir] < 0.0 ) segno = -1.0; - XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); - // first term of the gradient correction: - // D(rho*Exc)/D(rho) - v(0, ir) += ModuleBase::e2 * v1xc; - - // h contains - // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; - - vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); - etxcgc += ModuleBase::e2* sxc * segno; - } + if(use_libxc) + { + XC_Functional::gcxc_libxc( arho, grho2a, sxc, v1xc, v2xc ); + v(0,ir) = ModuleBase::e2 * v1xc; + h1[ir] = ModuleBase::e2 * 2.0 * v2xc * gdr1[ir]; + etxcgc += ModuleBase::e2* sxc * arho * segno; + vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); + } + else + { + XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); + // first term of the gradient correction: + // D(rho*Exc)/D(rho) + v(0, ir) += ModuleBase::e2 * v1xc; + + // h contains + // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; + + vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); + etxcgc += ModuleBase::e2* sxc * segno; + } + //} } // end arho > epsr } }// end nspin0 == 1 From 18b1d7c5fc5fcf37009f157f071d6dbc2eecdae5 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 18 Feb 2022 14:15:30 +0800 Subject: [PATCH 11/36] xc refactor : adds gcxc_spin --- source/module_xc/xc_functional.cpp | 56 +++++++++- source/module_xc/xc_functional.h | 4 + source/module_xc/xc_gga_pw.cpp | 170 ++++++++++++++++------------- 3 files changed, 151 insertions(+), 79 deletions(-) diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index e8a9b28e347..8e3c0718bdb 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -40,7 +40,7 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) func_id.push_back(XC_LDA_X); func_id.push_back(XC_LDA_C_PW); func_type = 1; - //use_libxc = false; + use_libxc = false; } else if ( xc_func == "PBE" || xc_func == "SLAPWPBXPBC") //PBX+PBC { @@ -1585,6 +1585,60 @@ void XC_Functional::glyp(const double &rho, const double &grho, double &sc, doub return; } // end subroutine glyp +void XC_Functional::gcxc_spin_libxc(double rhoup, double rhodw, + ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, + double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud) +{ + std::vector funcs = init_func(XC_POLARIZED); + double *rho, *grho, *v1xc, *v2xc, *sgn, s; + sxc = v1xcup = v1xcdw = 0.0; + v2xcup = v2xcdw = v2xcud = 0.0; + rho = new double[2]; + grho= new double[3]; + v1xc= new double[2]; + v2xc= new double[3]; + sgn = new double[2]; + + rho[0] = rhoup; + rho[1] = rhodw; + grho[0] = gdr1.norm2(); + grho[1] = gdr1 * gdr2; + grho[2] = gdr2.norm2(); + + const double rho_threshold = 1E-6; + const double grho_threshold = 1E-10; + + for(xc_func_type &func : funcs) + { + if( func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) + { + sgn[0] = sgn[1] = 1.0; + // call Libxc function: xc_gga_exc_vxc + xc_gga_exc_vxc( &func, 1, rho, grho, &s, v1xc, v2xc); + if(func.info->kind==XC_CORRELATION) + { + if ( rho[0] gdr1, ModuleBase::Vector3 gdr2, + double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud); + static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v); static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); diff --git a/source/module_xc/xc_gga_pw.cpp b/source/module_xc/xc_gga_pw.cpp index 90e3b4574c3..4a2da097024 100644 --- a/source/module_xc/xc_gga_pw.cpp +++ b/source/module_xc/xc_gga_pw.cpp @@ -138,102 +138,116 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) if(arho > epsr) { grho2a = gdr1[ir].norm2(); - //if( grho2a > epsg ) - //{ - if( rhotmp1[ir] >= 0.0 ) segno = 1.0; - if( rhotmp1[ir] < 0.0 ) segno = -1.0; + + if( rhotmp1[ir] >= 0.0 ) segno = 1.0; + if( rhotmp1[ir] < 0.0 ) segno = -1.0; + + if(use_libxc) + { + XC_Functional::gcxc_libxc( arho, grho2a, sxc, v1xc, v2xc ); + v(0,ir) += ModuleBase::e2 * v1xc; + h1[ir] = ModuleBase::e2 * 2.0 * v2xc * gdr1[ir]; + etxcgc += ModuleBase::e2* sxc * arho * segno; + vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); + } + else + { + XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); + // first term of the gradient correction: + // D(rho*Exc)/D(rho) + v(0, ir) += ModuleBase::e2 * v1xc; - if(use_libxc) - { - XC_Functional::gcxc_libxc( arho, grho2a, sxc, v1xc, v2xc ); - v(0,ir) = ModuleBase::e2 * v1xc; - h1[ir] = ModuleBase::e2 * 2.0 * v2xc * gdr1[ir]; - etxcgc += ModuleBase::e2* sxc * arho * segno; - vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); - } - else - { - XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); - // first term of the gradient correction: - // D(rho*Exc)/D(rho) - v(0, ir) += ModuleBase::e2 * v1xc; - - // h contains - // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; - - vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); - etxcgc += ModuleBase::e2* sxc * segno; - } - //} + // h contains + // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; + + vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); + etxcgc += ModuleBase::e2* sxc * segno; + } } // end arho > epsr } }// end nspin0 == 1 else // spin polarized case { - 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; - double sx = 0.0; - double sc = 0.0; for(int ir=0; ir epsr) + // h contains D(rho*Exc)/D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] += ModuleBase::e2 * ( v2xcup * gdr1[ir] + v2xcud * gdr2[ir] ); + h2[ir] += ModuleBase::e2 * ( v2xcdw * gdr2[ir] + v2xcud * gdr1[ir] ); + + vtxcgc = vtxcgc + ModuleBase::e2 * v1xcup * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] * fac ); + vtxcgc = vtxcgc + ModuleBase::e2 * v1xcdw * ( rhotmp2[ir] - GlobalC::CHR.rho_core[ir] * fac ); + etxcgc = etxcgc + ModuleBase::e2 * sxc; + } + else { - if(igcc_is_lyp) + 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; + double sx = 0.0; + double sc = 0.0; + double rh = rhotmp1[ir] + rhotmp2[ir]; + grho2a = gdr1[ir].norm2(); + grho2b = gdr2[ir].norm2(); + XC_Functional::gcx_spin(rhotmp1[ir], rhotmp2[ir], grho2a, grho2b, + sx, v1xup, v1xdw, v2xup, v2xdw); + + if(rh > epsr) { - ModuleBase::WARNING_QUIT("XC_Functional","igcc_is_lyp is not available now."); + if(igcc_is_lyp) + { + ModuleBase::WARNING_QUIT("XC_Functional","igcc_is_lyp is not available now."); + } + else + { + double zeta = ( rhotmp1[ir] - rhotmp2[ir] ) / rh; + if(GlobalV::NSPIN==4&&(GlobalV::DOMAG||GlobalV::DOMAG_Z)) zeta = fabs(zeta) * neg[ir]; + const double grh2 = (gdr1[ir]+gdr2[ir]).norm2(); + XC_Functional::gcc_spin(rh, zeta, grh2, sc, v1cup, v1cdw, v2c); + v2cup = v2c; + v2cdw = v2c; + v2cud = v2c; + } } else { - double zeta = ( rhotmp1[ir] - rhotmp2[ir] ) / rh; - if(GlobalV::NSPIN==4&&(GlobalV::DOMAG||GlobalV::DOMAG_Z)) zeta = fabs(zeta) * neg[ir]; - const double grh2 = (gdr1[ir]+gdr2[ir]).norm2(); - XC_Functional::gcc_spin(rh, zeta, grh2, sc, v1cup, v1cdw, v2c); - v2cup = v2c; - v2cdw = v2c; - v2cud = v2c; + sc = 0.0; + v1cup = 0.0; + v1cdw = 0.0; + v2c = 0.0; + v2cup = 0.0; + v2cdw = 0.0; + v2cud = 0.0; } - } - else - { - sc = 0.0; - v1cup = 0.0; - v1cdw = 0.0; - v2c = 0.0; - v2cup = 0.0; - v2cdw = 0.0; - v2cud = 0.0; - } - - // first term of the gradient correction : D(rho*Exc)/D(rho) - v(0,ir) = v(0,ir) + ModuleBase::e2 * ( v1xup + v1cup ); - v(1,ir) = v(1,ir) + ModuleBase::e2 * ( v1xdw + v1cdw ); -// continue; //mohan tmp - - // h contains D(rho*Exc)/D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] = ModuleBase::e2 * ( ( v2xup + v2cup ) * gdr1[ir] + v2cud * gdr2[ir] ); - h2[ir] = ModuleBase::e2 * ( ( v2xdw + v2cdw ) * gdr2[ir] + v2cud * gdr1[ir] ); - - vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xup + v1cup ) * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] * fac ); - vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xdw + v1cdw ) * ( rhotmp2[ir] - GlobalC::CHR.rho_core[ir] * fac ); - etxcgc = etxcgc + ModuleBase::e2 * ( sx + sc ); + // first term of the gradient correction : D(rho*Exc)/D(rho) + v(0,ir) = v(0,ir) + ModuleBase::e2 * ( v1xup + v1cup ); + v(1,ir) = v(1,ir) + ModuleBase::e2 * ( v1xdw + v1cdw ); + // h contains D(rho*Exc)/D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] = ModuleBase::e2 * ( ( v2xup + v2cup ) * gdr1[ir] + v2cud * gdr2[ir] ); + h2[ir] = ModuleBase::e2 * ( ( v2xdw + v2cdw ) * gdr2[ir] + v2cud * gdr1[ir] ); + vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xup + v1cup ) * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] * fac ); + vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xdw + v1cdw ) * ( rhotmp2[ir] - GlobalC::CHR.rho_core[ir] * fac ); + etxcgc = etxcgc + ModuleBase::e2 * ( sx + sc ); + } }// end ir } From 07e31c2597f4ab3741493ce68fb3b4c081b4e263 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 18 Feb 2022 16:40:45 +0800 Subject: [PATCH 12/36] xc refactor : 1. add xc_funcs.h for compiling without libxc 2. removed some no longer used subroutines --- source/Makefile.Objects | 1 - source/input_conv.cpp | 10 - source/module_base/global_variable.cpp | 1 - source/module_base/global_variable.h | 1 - source/module_xc/CMakeLists.txt | 1 - source/module_xc/H_XC_pw.cpp | 2 +- source/module_xc/potential_libxc.cpp | 344 ---------------------- source/module_xc/potential_libxc.h | 27 -- source/module_xc/potential_libxc_meta.cpp | 6 - source/module_xc/xc_funcs.h | 21 ++ source/module_xc/xc_functional.cpp | 74 ++++- source/module_xc/xc_functional.h | 59 ++-- source/src_lcao/FORCE_STRESS.cpp | 1 - source/src_pw/charge.cpp | 36 +-- source/src_pw/energy.cpp | 8 +- source/src_pw/forces.cpp | 12 +- source/src_pw/hamilt_pw.cpp | 2 +- source/src_pw/hamilt_pw.cu | 2 +- source/src_pw/hamilt_pw_hip.cpp | 2 +- source/src_pw/potential.cpp | 19 +- source/src_pw/stress_func_gga.cpp | 7 +- source/src_pw/stress_pw.cpp | 2 +- source/src_pw/symmetry_rho.cpp | 5 +- 23 files changed, 153 insertions(+), 490 deletions(-) delete mode 100644 source/module_xc/potential_libxc.cpp delete mode 100644 source/module_xc/potential_libxc.h create mode 100644 source/module_xc/xc_funcs.h diff --git a/source/Makefile.Objects b/source/Makefile.Objects index 6fbf44f3a8e..357487b8059 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -264,7 +264,6 @@ write_HS.o\ write_HS_R.o\ write_dm.o\ write_wfc_realspace.o\ -potential_libxc.o \ potential_libxc_meta.o \ efield.o \ magnetism.o\ diff --git a/source/input_conv.cpp b/source/input_conv.cpp index 63c2073c7b9..28dd0ee4955 100644 --- a/source/input_conv.cpp +++ b/source/input_conv.cpp @@ -571,16 +571,6 @@ void Input_Conv::Convert(void) // mohan add 2021-02-16 berryphase::berry_phase_flag = INPUT.berry_phase; - // wenfei 2021-7-28 - if (GlobalV::DFT_FUNCTIONAL == "scan") - { - if (GlobalV::BASIS_TYPE != "pw") - { - ModuleBase::WARNING_QUIT("Input_conv", "add metaGGA for pw first"); - } - GlobalV::DFT_META = 1; - } - ModuleBase::timer::tick("Input_Conv", "Convert"); //----------------------------------------------- // caoyu add for DeePKS diff --git a/source/module_base/global_variable.cpp b/source/module_base/global_variable.cpp index 82d4ec9a19d..8e65c45334c 100644 --- a/source/module_base/global_variable.cpp +++ b/source/module_base/global_variable.cpp @@ -30,7 +30,6 @@ int EFIELD = 0; // 5: add electric field int DIPOLE = 0; // 7: add dipole field std::string DFT_FUNCTIONAL = "default"; -bool DFT_META = 0; int NSPIN = 1; // LDA bool TWO_EFERMI = 0; // two fermi energy, exist only magnetization is fixed. int CURRENT_SPIN = 0; diff --git a/source/module_base/global_variable.h b/source/module_base/global_variable.h index 9c68ae56893..a25019f892a 100644 --- a/source/module_base/global_variable.h +++ b/source/module_base/global_variable.h @@ -31,7 +31,6 @@ extern int DIPOLE; // 7 add dipole correction extern std::string DFT_FUNCTIONAL; // 6.5 change the DFT functional from input file. -extern bool DFT_META; // whether is meta-GGA extern int NSPIN; // 7 extern bool TWO_EFERMI; // 7.5 mohan add 2011-04-03, two fermi energy, exist if magnetization is fixed. extern int CURRENT_SPIN; // 8 diff --git a/source/module_xc/CMakeLists.txt b/source/module_xc/CMakeLists.txt index 4c520cff52d..aea1a0da78e 100644 --- a/source/module_xc/CMakeLists.txt +++ b/source/module_xc/CMakeLists.txt @@ -1,6 +1,5 @@ list(APPEND objects H_XC_pw.cpp - potential_libxc.cpp potential_libxc_meta.cpp xc_functional.cpp xc_gga_pw.cpp diff --git a/source/module_xc/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp index a05f3a1f2ce..bbe337758f0 100644 --- a/source/module_xc/H_XC_pw.cpp +++ b/source/module_xc/H_XC_pw.cpp @@ -15,7 +15,7 @@ std::tuple XC_Functional::v_xc ModuleBase::timer::tick("H_XC_pw","v_xc"); #ifndef USE_LIBXC - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { ModuleBase::WARNING_QUIT("Potential::v_of_rho","to use metaGGA, please link LIBXC"); } diff --git a/source/module_xc/potential_libxc.cpp b/source/module_xc/potential_libxc.cpp deleted file mode 100644 index 514f546abde..00000000000 --- a/source/module_xc/potential_libxc.cpp +++ /dev/null @@ -1,344 +0,0 @@ -//========================================================== -// AUTHOR : Peize Lin -// DATE : 2017-09-14 -// UPDATE : 2021-02-28 -//========================================================== - -#ifdef USE_LIBXC - -#include "potential_libxc.h" -#include "../src_pw/global.h" -#include "../module_base/global_function.h" -#include "../module_base/global_variable.h" -#include "module_base/timer.h" -#include "src_parallel/parallel_reduce.h" -#include "xc_functional.h" - -#ifdef __LCAO -#include "../src_lcao/global_fp.h" -#endif - -//the interfacd to libxc xc_lda_exc_vxc and xc_gga_exc_vxc -//XC_POLARIZED, XC_UNPOLARIZED: internal flags used in LIBXC, denote the polarized(nspin=1) or unpolarized(nspin=2) calculations, definition can be found in xc.h from LIBXC -//XC_FAMILY_LDA, XC_FAMILY_GGA, XC_FAMILY_HYB_GGA, XC_CORRELATION: internal flags used in LIBXC, denote the types of functional associated with a certain functional ID, definition can be found in xc.h from LIBXC - -// [etxc, vtxc, v] = Potential_Libxc::v_xc(...) -std::tuple XC_Functional::v_xc_libxc( - const int &nrxx, // number of real-space grid - const int &ncxyz, // total number of charge grid - const double &omega, // volume of cell - const double * const * const rho_in, - const double * const rho_core_in) -{ - ModuleBase::TITLE("Potential_Libxc","v_xc"); - ModuleBase::timer::tick("Potential_Libxc","v_xc"); - - double etxc = 0.0; - double vtxc = 0.0; - ModuleBase::matrix v(GlobalV::NSPIN,nrxx); - - if(GlobalV::VXC_IN_H == 0 ) - { - ModuleBase::timer::tick("Potential_Libxc","v_xc"); - return std::make_tuple( etxc, vtxc, std::move(v) ); - } - //---------------------------------------------------------- - // xc_func_type is defined in Libxc package - // to understand the usage of xc_func_type, - // use can check on website, for example: - // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ - //---------------------------------------------------------- - const int xc_polarized = (1==nspin0()) ? XC_UNPOLARIZED : XC_POLARIZED; - std::vector funcs = init_func(xc_polarized); - - bool is_gga = false; - for( xc_func_type &func : funcs ) - { - switch( func.info->family ) - { - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - is_gga = true; - break; - } - } - - // converting rho - std::vector rho; - rho.resize(GlobalC::pw.nrxx*nspin0()); - if(nspin0()==1 || GlobalV::NSPIN==2) - { - for( int is=0; is!=nspin0(); ++is ) - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - rho[ir*nspin0()+is] = rho_in[is][ir] + 1.0/nspin0()*rho_core_in[ir]; - } - else // may need updates for SOC - { - if(func_type == 2) - { - GlobalC::ucell.cal_ux(); - } - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); - const double neg = (GlobalC::ucell.magnet.lsign_ && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0] - +rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1] - +rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) - ? -1 : 1; - rho[ir*2] = 0.5 * (rho_in[0][ir] + neg * amag) + 0.5 * rho_core_in[ir]; - rho[ir*2+1] = 0.5 * (rho_in[0][ir] - neg * amag) + 0.5 * rho_core_in[ir]; - } - } - - std::vector>> gdr; - std::vector sigma; - if(is_gga) - { - // calculating grho - gdr.resize( nspin0() ); - for( int is=0; is!=nspin0(); ++is ) - { - std::vector rhor(GlobalC::pw.nrxx); - for(int ir=0; ir> rhog(GlobalC::pw.ngmc); - GlobalC::CHR.set_rhog(rhor.data(), rhog.data()); - - //------------------------------------------- - // compute the gradient of charge density and - // store the gradient in gdr[is] - //------------------------------------------- - gdr[is].resize(GlobalC::pw.nrxx); - XC_Functional::grad_rho(rhog.data(), gdr[is].data()); - } - - // converting grho - sigma.resize( nrxx * ((1==nspin0())?1:3) ); - - if( 1==nspin0() ) - { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - sigma[ir] = gdr[0][ir]*gdr[0][ir]; - } - } - else - { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - sigma[ir*3] = gdr[0][ir]*gdr[0][ir]; - sigma[ir*3+1] = gdr[0][ir]*gdr[1][ir]; - sigma[ir*3+2] = gdr[1][ir]*gdr[1][ir]; - } - } - } - - std::vector exc ( nrxx ); - std::vector vrho ( nrxx * nspin0() ); - std::vector vsigma( nrxx * ((1==nspin0())?1:3) ); - - for( xc_func_type &func : funcs ) - { - - // jiyy add for threshold - const double rho_threshold = 1E-6; - const double grho_threshold = 1E-10; - // sgn for threshold mask - std::vector sgn( nrxx * nspin0(), 1.0); - - if(nspin0()==2 && func.info->family != XC_FAMILY_LDA && func.info->kind==XC_CORRELATION) - { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - if ( rho[ir*2]family ) - { - case XC_FAMILY_LDA: - // call Libxc function: xc_lda_exc_vxc - xc_lda_exc_vxc( &func, nrxx, rho.data(), - exc.data(), vrho.data() ); - break; - case XC_FAMILY_GGA: - case XC_FAMILY_HYB_GGA: - // call Libxc function: xc_gga_exc_vxc - xc_gga_exc_vxc( &func, nrxx, rho.data(), sigma.data(), - exc.data(), vrho.data(), vsigma.data() ); - break; - default: - throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(func.info->family) - +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - break; - } - - for( int is=0; is!=nspin0(); ++is ) - { - for( int ir=0; ir!= nrxx; ++ir ) - { - etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; - } - } - - if(nspin0()==1 || GlobalV::NSPIN==2) - { - for( int is=0; is!=nspin0(); ++is ) - { - for( int ir=0; ir!= nrxx; ++ir ) - { - const double v_tmp = ModuleBase::e2 * vrho[ir*nspin0()+is] * sgn[ir*nspin0()+is]; - v(is,ir) += v_tmp; - vtxc += v_tmp * rho_in[is][ir]; - } - } - } - else // may need updates for SOC - { - constexpr double vanishing_charge = 1.0e-12; - for( int ir=0; ir!= nrxx; ++ir ) - { - std::vector v_tmp(4); - v_tmp[0] = ModuleBase::e2 * (0.5 * (vrho[ir*2] + vrho[ir*2+1])); - const double vs = 0.5 * (vrho[ir*2] - vrho[ir*2+1]); - const double amag = sqrt( pow(rho_in[1][ir],2) - + pow(rho_in[2][ir],2) - + pow(rho_in[3][ir],2) ); - - if(amag>vanishing_charge) - { - for(int ipol=1; ipol<4; ++ipol) - { - v_tmp[ipol] = ModuleBase::e2 * vs * rho_in[ipol][ir] / amag; - } - } - for(int ipol=0; ipol<4; ++ipol) - { - v(ipol, ir) += v_tmp[ipol]; - vtxc += v_tmp[ipol] * rho_in[ipol][ir]; - } - } - } - - if(func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) - { - std::vector>> h( nspin0(), std::vector>(nrxx) ); - if( 1==nspin0() ) - { - for( int ir=0; ir!= nrxx; ++ir ) - { - h[0][ir] = ModuleBase::e2 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; - } - } - else - { - for( int ir=0; ir!= nrxx; ++ir ) - { - h[0][ir] = ModuleBase::e2 * (gdr[0][ir] * vsigma[ir*3 ] * 2.0 * sgn[ir*2 ] - + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); - h[1][ir] = ModuleBase::e2 * (gdr[1][ir] * vsigma[ir*3+2] * 2.0 * sgn[ir*2+1] - + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); - } - } - - // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] - std::vector> dh(nspin0(), std::vector( nrxx)); - for( int is=0; is!=nspin0(); ++is ) - XC_Functional::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); - - for( int is=0; is!=nspin0(); ++is ) - for( int ir=0; ir!= nrxx; ++ir ) - vtxc -= dh[is][ir] * rho[ir*nspin0()+is]; - - if(nspin0()==1 || GlobalV::NSPIN==2) - { - for( int is=0; is!=nspin0(); ++is ) - for( int ir=0; ir!= nrxx; ++ir ) - v(is,ir) -= dh[is][ir]; - } - else // may need updates for SOC - { - constexpr double vanishing_charge = 1.0e-12; - for( int ir=0; ir!= nrxx; ++ir ) - { - v(0,ir) -= 0.5 * (dh[0][ir] + dh[1][ir]); - const double amag = sqrt( pow(rho_in[1][ir],2) + pow(rho_in[2][ir],2) + pow(rho_in[3][ir],2) ); - const double neg = (GlobalC::ucell.magnet.lsign_ - && rho_in[1][ir]*GlobalC::ucell.magnet.ux_[0]+rho_in[2][ir]*GlobalC::ucell.magnet.ux_[1]+rho_in[3][ir]*GlobalC::ucell.magnet.ux_[2]<=0) - ? -1 : 1; - if(amag > vanishing_charge) - { - for(int i=1;i<4;i++) - v(i,ir) -= neg * 0.5 * (dh[0][ir]-dh[1][ir]) * rho_in[i][ir] / amag; - } - } - } - } - } - - //------------------------------------------------- - // for MPI, reduce the exchange-correlation energy - //------------------------------------------------- - Parallel_Reduce::reduce_double_pool( etxc ); - Parallel_Reduce::reduce_double_pool( vtxc ); - - etxc *= omega / ncxyz; - vtxc *= omega / ncxyz; - - ModuleBase::timer::tick("Potential_Libxc","v_xc"); - return std::make_tuple( etxc, vtxc, std::move(v) ); -} - -std::vector XC_Functional::init_func(const int xc_polarized) -{ - // 'funcs' is the return value - std::vector funcs; - - //------------------------------------------- - // define a function named 'add_func', which - // initialize a functional according to its ID - //------------------------------------------- - auto add_func = [&]( const int func_id ) - { - funcs.push_back({}); - // 'xc_func_init' is defined in Libxc - xc_func_init( &funcs.back(), func_id, xc_polarized ); - }; - - for(int id : func_id) - { - if( id == 406 ) // PBE0 - { - add_func( XC_HYB_GGA_XC_PBEH ); - double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, - GlobalC::exx_global.info.hse_omega, - GlobalC::exx_global.info.hse_omega }; - xc_func_set_ext_params(&funcs.back(), parameter_hse); - } - else if( id == 428 ) // HSE06 hybrid functional - { - add_func( XC_HYB_GGA_XC_HSE06 ); - double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, - GlobalC::exx_global.info.hse_omega, - GlobalC::exx_global.info.hse_omega }; - xc_func_set_ext_params(&funcs.back(), parameter_hse); - } - else - { - add_func( id ); - } - } - return funcs; -} - - -#endif //ifdef USE_LIBXC diff --git a/source/module_xc/potential_libxc.h b/source/module_xc/potential_libxc.h deleted file mode 100644 index 0d4092cdc8b..00000000000 --- a/source/module_xc/potential_libxc.h +++ /dev/null @@ -1,27 +0,0 @@ -//========================================================== -// AUTHOR : Peize Lin -// DATE : 2017-09-14 -// UPDATE : 2021-02-28 -//========================================================== - -#ifdef USE_LIBXC - -#ifndef POTENTIAL_LIBXC_H -#define POTENTIAL_LIBXC_H - -#include "../module_base/matrix.h" -#include "../module_base/vector3.h" -#include "../module_base/global_variable.h" -#include "../module_base/global_function.h" -#include -#include -#include - -class Potential_Libxc -{ - -}; - -#endif - -#endif // ifdef USE_LIBXC diff --git a/source/module_xc/potential_libxc_meta.cpp b/source/module_xc/potential_libxc_meta.cpp index a9167331082..6136210ca66 100644 --- a/source/module_xc/potential_libxc_meta.cpp +++ b/source/module_xc/potential_libxc_meta.cpp @@ -6,7 +6,6 @@ #ifdef USE_LIBXC -#include "potential_libxc.h" #include "../src_pw/global.h" #include "../module_base/global_function.h" #include "../module_base/global_variable.h" @@ -92,9 +91,6 @@ tuple XC_Functional::v_xc_m vector>> h; vector> kedtaur; - //ifstream ifs_rho("rho"); - //ifstream ifs_tau("tau"); - //rho : from double** to vector rho.resize(GlobalV::NSPIN); for( int is=0; is!=GlobalV::NSPIN; ++is ) @@ -103,7 +99,6 @@ tuple XC_Functional::v_xc_m for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) { rho[is][ir] = rho_in[is][ir] + (1.0/GlobalV::NSPIN)*rho_core_in[ir]; - //ifs_rho >> rho[is][ir]; } } @@ -128,7 +123,6 @@ tuple XC_Functional::v_xc_m for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) { kin_r[is][ir] = kin_r_in[is][ir]; - //ifs_tau >> kin_r[is][ir]; } } } diff --git a/source/module_xc/xc_funcs.h b/source/module_xc/xc_funcs.h new file mode 100644 index 00000000000..a365583f8e0 --- /dev/null +++ b/source/module_xc/xc_funcs.h @@ -0,0 +1,21 @@ +#define XC_LDA_X 1 /*Exchange */ +#define XC_LDA_C_PZ 9 /*Perdew & Zunger */ +#define XC_LDA_C_PW 12 /*Perdew & Wang */ +#define XC_HYB_GGA_XC_PBEH 406 /*aka PBE0 or PBE1PBE */ +#define XC_HYB_GGA_XC_HSE06 428 /* the 2006 version of the screened hybrid HSE */ +#define XC_GGA_X_HCTH_A 34 /*HCTH-A */ +#define XC_GGA_C_HCTH_A 97 /*HCTH-A */ +#define XC_GGA_X_PBE 101 /*Perdew, Burke & Ernzerhof exchange */ +#define XC_GGA_X_B88 106 /*Becke 88 */ +#define XC_GGA_X_PW91 109 /*Perdew & Wang 91 */ +#define XC_GGA_X_OPTX 110 /*Handy & Cohen OPTX 01 */ +#define XC_GGA_X_PBE_SOL 116 /* Perdew, Burke & Ernzerhof exchange (solids) */ +#define XC_GGA_X_RPBE 117 /*Hammer, Hansen & Norskov (PBE-like) */ +#define XC_GGA_X_WC 118 /*Wu & Cohen */ +#define XC_GGA_C_PBE 130 /*Perdew, Burke & Ernzerhof correlation */ +#define XC_GGA_C_LYP 131 /*Lee, Yang & Parr */ +#define XC_GGA_C_P86 132 /*Perdew 86 */ +#define XC_GGA_C_PBE_SOL 133 /* Perdew, Burke & Ernzerhof correlation SOL */ +#define XC_GGA_C_PW91 134 /*Perdew & Wang 91 */ +#define XC_MGGA_X_SCAN 263 /*SCAN exchange of Sun, Ruzsinszky, and Perdew */ +#define XC_MGGA_C_SCAN 267 /*SCAN correlation */ \ No newline at end of file diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index 8e3c0718bdb..6a004513413 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -110,12 +110,12 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) func_id.push_back(XC_MGGA_X_SCAN); func_id.push_back(XC_MGGA_C_SCAN); func_type = 3; - GlobalV::DFT_META = 1; } else if( xc_func == "PBE0") { func_id.push_back(XC_HYB_GGA_XC_PBEH); func_type = 4; + use_libxc = false; } else if( xc_func == "HF" || xc_func == "OPT_ORB" || xc_func == "NONE") { @@ -132,15 +132,25 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) std::cout << "functional name not recognized!" << std::endl; } - if (func_id[0] == 110) + if (func_id[0] == XC_GGA_X_OPTX) { std::cerr << "\n OPTX untested please test,"; } + + if(func_type ==3 && GlobalV::BASIS_TYPE != "pw") + { + ModuleBase::WARNING_QUIT("set_xc_type","mGGA not realized for LCAO yet"); + } + +#ifndef USE_LIBXC + use_libxc = false; +#endif + } void XC_Functional::xc_libxc(const double &rho, double &exc, double &vxc) { - +#ifdef USE_LIBXC double e,v; exc = vxc = 0.00; @@ -157,8 +167,10 @@ void XC_Functional::xc_libxc(const double &rho, double &exc, double &vxc) vxc += v; } return; +#endif } + void XC_Functional::xc(const double &rho, double &exc, double &vxc) { @@ -220,7 +232,7 @@ void XC_Functional::xc(const double &rho, double &exc, double &vxc) void XC_Functional::xc_spin_libxc(const double &rhoup, const double &rhodw, double &exc, double &vxcup, double &vxcdw) { - +#ifdef USE_LIBXC double e, vup, vdw; double *rho_ud, *vxc_ud; exc = vxcup = vxcdw = 0.0; @@ -247,6 +259,7 @@ void XC_Functional::xc_spin_libxc(const double &rhoup, const double &rhodw, delete[] rho_ud; delete[] vxc_ud; +#endif } void XC_Functional::xc_spin(const double &rho, const double &zeta, @@ -1229,7 +1242,7 @@ void XC_Functional::gcxc(const double &rho, const double &grho, double &sxc, void XC_Functional::gcxc_libxc(const double &rho, const double &grho, double &sxc, double &v1xc, double &v2xc) { - +#ifdef USE_LIBXC double s,v1,v2; sxc = v1xc = v2xc = 0.0; @@ -1247,6 +1260,7 @@ void XC_Functional::gcxc_libxc(const double &rho, const double &grho, double &sx v2xc += v2; } return; +#endif } void XC_Functional::optx(const double rho, const double grho, double &sx, double &v1x, double &v2x) @@ -1589,6 +1603,7 @@ void XC_Functional::gcxc_spin_libxc(double rhoup, double rhodw, ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud) { +#ifdef USE_LIBXC std::vector funcs = init_func(XC_POLARIZED); double *rho, *grho, *v1xc, *v2xc, *sgn, s; sxc = v1xcup = v1xcdw = 0.0; @@ -1637,7 +1652,8 @@ void XC_Functional::gcxc_spin_libxc(double rhoup, double rhodw, delete[] sgn; return; -} +#endif +} //----------------------------------------------------------------------- void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double grhodw2, @@ -2083,4 +2099,48 @@ void XC_Functional::pbec_spin(double rho, double zeta, double grho, const int &i v1cdw = h0 + dh0dw + dh0zdw; v2c = ddh0; return; -} // end subroutine pbec_spin \ No newline at end of file +} // end subroutine pbec_spin + +#ifdef USE_LIBXC +std::vector XC_Functional::init_func(const int xc_polarized) +{ + // 'funcs' is the return value + std::vector funcs; + + //------------------------------------------- + // define a function named 'add_func', which + // initialize a functional according to its ID + //------------------------------------------- + auto add_func = [&]( const int func_id ) + { + funcs.push_back({}); + // 'xc_func_init' is defined in Libxc + xc_func_init( &funcs.back(), func_id, xc_polarized ); + }; + + for(int id : func_id) + { + if( id == 406 ) // PBE0 + { + add_func( XC_HYB_GGA_XC_PBEH ); + double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, + GlobalC::exx_global.info.hse_omega, + GlobalC::exx_global.info.hse_omega }; + xc_func_set_ext_params(&funcs.back(), parameter_hse); + } + else if( id == 428 ) // HSE06 hybrid functional + { + add_func( XC_HYB_GGA_XC_HSE06 ); + double parameter_hse[3] = { GlobalC::exx_global.info.hybrid_alpha, + GlobalC::exx_global.info.hse_omega, + GlobalC::exx_global.info.hse_omega }; + xc_func_set_ext_params(&funcs.back(), parameter_hse); + } + else + { + add_func( id ); + } + } + return funcs; +} +#endif \ No newline at end of file diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 58e22c2599a..d8c49182596 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -7,6 +7,8 @@ #ifdef USE_LIBXC #include +#else +#include "xc_funcs.h" #endif // ifdef USE_LIBXC #include "../module_base/global_function.h" @@ -37,43 +39,11 @@ class XC_Functional const double*const*const rho_in, const double*const rho_core); // core charge density - //------------------------------------------------ - // evaluate the exchange-correlation (XC) energy - // by using the input charge density rho_in and rho_core_in - //------------------------------------------------ - // [etxc, vtxc, v] = v_xc(...) - static std::tuple v_xc_libxc( - const int &nrxx, // number of real-space grid - const int &ncxyz, // total number of charge grid - const double &omega, // volume of cell - const double * const * const rho_in, - const double * const rho_core_in); - static std::tuple v_xc_meta( const double * const * const rho_in, const double * const rho_core_in, const double * const * const kin_r_in); - -#ifdef USE_LIBXC - struct Mgga_spin_in - { - double rhoup, rhodw;//electron densities - ModuleBase::Vector3 grhoup, grhodw;//gradient of electron densities - double tauup, taudw;//kinetic energy densities - }; - struct Mgga_spin_out - { - double ex, ec;//xc energy densities - double v1xup, v1xdw;//vx: lda part - double v2xup, v2xdw;//vx: gga part - double v3xup, v3xdw;//vx: mgga part - double v1cup, v1cdw;//vc: lda part - ModuleBase::Vector3 v2cup, v2cdw; - std::vector v2c;//vc: gga part, two different formats - double v3cup, v3cdw;//vc: mgga part - }; - // GGA static void gcxc(const double &rho, const double &grho, double &sxc, double &v1xc, double &v2xc); @@ -99,11 +69,29 @@ class XC_Functional static void noncolin_rho(double *rhoout1,double *rhoout2,double *seg); // mGGA +#ifdef USE_LIBXC + struct Mgga_spin_in + { + double rhoup, rhodw;//electron densities + ModuleBase::Vector3 grhoup, grhodw;//gradient of electron densities + double tauup, taudw;//kinetic energy densities + }; + + struct Mgga_spin_out + { + double ex, ec;//xc energy densities + double v1xup, v1xdw;//vx: lda part + double v2xup, v2xdw;//vx: gga part + double v3xup, v3xdw;//vx: mgga part + double v1cup, v1cdw;//vc: lda part + ModuleBase::Vector3 v2cup, v2cdw; + std::vector v2c;//vc: gga part, two different formats + double v3cup, v3cdw;//vc: mgga part + }; static void tau_xc(const double &rho, const double &grho, const double &atau, double &sx, double &sc, double &v1x, double &v2x, double &v3x, double &v1c, double &v2c, double &v3c); static void tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out &mgga_spin_out); - -#endif +#endif static int get_func_type(); @@ -114,8 +102,9 @@ class XC_Functional static bool use_libxc; static void set_xc_type(const std::string xc_func_in); +#ifdef USE_LIBXC static std::vector init_func(const int xc_polarized); - +#endif // LDA static void xc(const double &rho, double &exc, double &vxc); static void xc_libxc(const double &rho, double &exc, double &vxc); diff --git a/source/src_lcao/FORCE_STRESS.cpp b/source/src_lcao/FORCE_STRESS.cpp index 8c5b30fc6a9..5fb3f0028e4 100644 --- a/source/src_lcao/FORCE_STRESS.cpp +++ b/source/src_lcao/FORCE_STRESS.cpp @@ -1,6 +1,5 @@ #include "FORCE_STRESS.h" #include "../src_pw/global.h" -#include "../module_xc/potential_libxc.h" #include "./dftu.h" //Quxin add for DFT+U on 20201029 // new #include "../src_pw/vdwd2.h" diff --git a/source/src_pw/charge.cpp b/source/src_pw/charge.cpp index 665e151f2c9..4b152ff6d48 100644 --- a/source/src_pw/charge.cpp +++ b/source/src_pw/charge.cpp @@ -47,7 +47,7 @@ Charge::~Charge() delete[] rhog[i]; delete[] rho_save[i]; delete[] rhog_save[i]; - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { delete[] kin_r[i]; delete[] kin_r_save[i]; @@ -59,7 +59,7 @@ Charge::~Charge() delete[] rhog_save; delete[] rho_core; delete[] rhog_core; - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { delete[] kin_r; delete[] kin_r_save; @@ -90,7 +90,7 @@ void Charge::allocate(const int &nspin_in, const int &nrxx_in, const int &ngmc_i rhog = new std::complex*[nspin]; rho_save = new double*[nspin]; rhog_save = new std::complex*[nspin]; - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { kin_r = new double*[nspin]; kin_r_save = new double*[nspin]; @@ -106,7 +106,7 @@ void Charge::allocate(const int &nspin_in, const int &nrxx_in, const int &ngmc_i ModuleBase::GlobalFunc::ZEROS(rhog[is], ngmc); ModuleBase::GlobalFunc::ZEROS(rho_save[is], nrxx); ModuleBase::GlobalFunc::ZEROS(rhog_save[is], ngmc); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { kin_r[is] = new double[nrxx]; ModuleBase::GlobalFunc::ZEROS(kin_r[is], nrxx); @@ -511,7 +511,7 @@ void Charge::atomic_rho(const int spin_number_need, double** rho_in)const // Pe rho_in[is][ir] = rho_in[is][ir] / ne_tot * nelec; //wenfei 2021-7-29 : initial tau = 3/5 rho^2/3, Thomas-Fermi - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { const double pi = 3.141592653589790; double fact = (3.0/5.0)*pow(3.0*pi*pi,2.0/3.0); @@ -725,7 +725,7 @@ void Charge::sum_band(void) for(int is=0; isrho[is][ir] / static_cast(GlobalV::NPROC_IN_POOL); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { tau_tmp[ir] = this->kin_r[is][ir] / static_cast(GlobalV::NPROC_IN_POOL); } } MPI_Allgatherv(rho_tmp, GlobalC::pw.nrxx, MPI_DOUBLE, rho_tot, rec, dis, MPI_DOUBLE, POOL_WORLD); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { MPI_Allgatherv(tau_tmp, GlobalC::pw.nrxx, MPI_DOUBLE, tau_tot, rec, dis, MPI_DOUBLE, POOL_WORLD); } @@ -1005,7 +1005,7 @@ void Charge::rho_mpi(void) // this is the most complicated part !! //================================================================= ModuleBase::GlobalFunc::ZEROS(rho_tot_aux, GlobalC::pw.ncxyz); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { ModuleBase::GlobalFunc::ZEROS(tau_tot_aux, GlobalC::pw.ncxyz); } @@ -1048,7 +1048,7 @@ void Charge::rho_mpi(void) // ------------------------------------------------- rho_tot_aux[GlobalC::pw.ncz*ir + start_z[ip] + iz] = rho_tot[num_z[ip]*ir + start_z[ip]*ncxy + iz]; - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { tau_tot_aux[GlobalC::pw.ncz*ir + start_z[ip] + iz] = tau_tot[num_z[ip]*ir + start_z[ip]*ncxy + iz]; @@ -1062,14 +1062,14 @@ void Charge::rho_mpi(void) if(GlobalV::CALCULATION=="scf-sto" || GlobalV::CALCULATION=="relax-sto" || GlobalV::CALCULATION=="md-sto") //qinarui add it temporarily. { MPI_Allreduce(rho_tot_aux,rho_tot,GlobalC::pw.ncxyz,MPI_DOUBLE,MPI_SUM,POOL_WORLD); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { MPI_Allreduce(tau_tot_aux,tau_tot,GlobalC::pw.ncxyz,MPI_DOUBLE,MPI_SUM,POOL_WORLD); } } else MPI_Allreduce(rho_tot_aux,rho_tot,GlobalC::pw.ncxyz,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { MPI_Allreduce(tau_tot_aux,tau_tot,GlobalC::pw.ncxyz,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); } @@ -1082,7 +1082,7 @@ void Charge::rho_mpi(void) for (iz=0;izrho[is][num_z[GlobalV::RANK_IN_POOL]*ir+iz] = rho_tot[GlobalC::pw.ncz*ir + start_z[GlobalV::RANK_IN_POOL] + iz ]; - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { this->kin_r[is][num_z[GlobalV::RANK_IN_POOL]*ir+iz] = tau_tot[GlobalC::pw.ncz*ir + start_z[GlobalV::RANK_IN_POOL] + iz ]; } @@ -1093,7 +1093,7 @@ void Charge::rho_mpi(void) delete[] rho_tot; delete[] rho_tmp; - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { delete[] tau_tot_aux; delete[] tau_tot; @@ -1115,7 +1115,7 @@ void Charge::save_rho_before_sum_band(void) for(int is=0; isdescf -= ( GlobalC::CHR.rho[0][ir] - GlobalC::CHR.rho_save[0][ir] ) * GlobalC::pot.vr(0, ir); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { this->descf -= ( GlobalC::CHR.kin_r[0][ir] - GlobalC::CHR.kin_r_save[0][ir] ) * GlobalC::pot.vofk(0, ir); } @@ -455,7 +455,7 @@ void energy::delta_escf(void) for (int ir=0; irdescf -= ( GlobalC::CHR.rho[1][ir] - GlobalC::CHR.rho_save[1][ir] ) * GlobalC::pot.vr(1, ir); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { this->descf -= ( GlobalC::CHR.kin_r[1][ir] - GlobalC::CHR.kin_r_save[1][ir] ) * GlobalC::pot.vofk(1, ir); } diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index 3fc6a13c4c9..f605f8d350d 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -6,7 +6,6 @@ // new #include "../module_xc/xc_functional.h" #include "../module_base/math_integral.h" -#include "../module_xc/potential_libxc.h" #include "../src_parallel/parallel_reduce.h" #include "../module_base/timer.h" @@ -561,13 +560,14 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) ModuleBase::matrix v(GlobalV::NSPIN,GlobalC::pw.nrxx); - #ifdef USE_LIBXC - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { +#ifdef USE_LIBXC const auto etxc_vtxc_v = XC_Functional::v_xc_meta(GlobalC::CHR.rho, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); +#endif } else { @@ -576,12 +576,6 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); } - #else - const auto etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); - GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); - GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); - v = std::get<2>(etxc_vtxc_v); - #endif const ModuleBase::matrix vxc = v; std::complex * psiv = new std::complex [GlobalC::pw.nrxx]; diff --git a/source/src_pw/hamilt_pw.cpp b/source/src_pw/hamilt_pw.cpp index a106ee3a0a6..1c4fc7de607 100644 --- a/source/src_pw/hamilt_pw.cpp +++ b/source/src_pw/hamilt_pw.cpp @@ -532,7 +532,7 @@ void Hamilt_PW::h_psi(const std::complex *psi_in, std::complex * // (4) the metaGGA part //------------------------------------ ModuleBase::timer::tick("Hamilt_PW","meta"); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { tmhpsi = hpsi; tmpsi_in = psi_in; diff --git a/source/src_pw/hamilt_pw.cu b/source/src_pw/hamilt_pw.cu index 12019b27eb2..e6565aa4fa3 100644 --- a/source/src_pw/hamilt_pw.cu +++ b/source/src_pw/hamilt_pw.cu @@ -1288,7 +1288,7 @@ void Hamilt_PW::h_psi(const std::complex *psi_in, std::complex * // (4) the metaGGA part //------------------------------------ // timer::tick("Hamilt_PW","meta"); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { tmhpsi = hpsi; tmpsi_in = psi_in; diff --git a/source/src_pw/hamilt_pw_hip.cpp b/source/src_pw/hamilt_pw_hip.cpp index 97f29b2e7e8..8e408df552c 100644 --- a/source/src_pw/hamilt_pw_hip.cpp +++ b/source/src_pw/hamilt_pw_hip.cpp @@ -1578,7 +1578,7 @@ void Hamilt_PW::h_psi(const std::complex *psi_in, std::complex * // (4) the metaGGA part //------------------------------------ // timer::tick("Hamilt_PW","meta"); - if (GlobalV::DFT_META) + if (XC_Functional::get_func_type() == 3) { tmhpsi = hpsi; tmpsi_in = psi_in; diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index ad9937a69d7..a14b8049a4c 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -6,7 +6,6 @@ #include "../module_xc/xc_functional.h" #include "efield.h" #include "math.h" -#include "../module_xc/potential_libxc.h" // new #include "H_Hartree_pw.h" #ifdef __LCAO @@ -44,7 +43,7 @@ void Potential::allocate(const int nrxx) ModuleBase::Memory::record("Potential","vr",GlobalV::NSPIN*nrxx,"double"); ModuleBase::Memory::record("Potential","vr_eff",GlobalV::NSPIN*nrxx,"double"); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { this->vofk.create(GlobalV::NSPIN,nrxx); ModuleBase::Memory::record("Potential","vofk",GlobalV::NSPIN*nrxx,"double"); @@ -82,7 +81,7 @@ void Potential::init_pot( // the vltot should and must be zero here. ModuleBase::GlobalFunc::ZEROS(this->vltot, GlobalC::pw.nrxx); - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { this->vofk.zero_out(); } @@ -325,14 +324,15 @@ ModuleBase::matrix Potential::v_of_rho( // calculate the exchange-correlation potential //---------------------------------------------------------- - #ifdef USE_LIBXC - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { +#ifdef USE_LIBXC const std::tuple etxc_vtxc_v = XC_Functional::v_xc_meta(rho_in, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); - vofk = std::get<3>(etxc_vtxc_v); + vofk = std::get<3>(etxc_vtxc_v); +#endif } else { @@ -341,13 +341,6 @@ ModuleBase::matrix Potential::v_of_rho( GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); } - #else - const std::tuple etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core); - - GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); - GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); - v += std::get<2>(etxc_vtxc_v); - #endif //---------------------------------------------------------- // calculate the Hartree potential diff --git a/source/src_pw/stress_func_gga.cpp b/source/src_pw/stress_func_gga.cpp index 9a193352971..137df6225d5 100644 --- a/source/src_pw/stress_func_gga.cpp +++ b/source/src_pw/stress_func_gga.cpp @@ -90,7 +90,6 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) if(nspin_in==1||nspin_in==4) { - //double segno; for(int ir=0; ir epsg ) { - //if( rhotmp1[ir] >= 0.0 ) segno = 1.0; - //if( rhotmp1[ir] < 0.0 ) segno = -1.0; - if(GlobalV::DFT_META) + if(XC_Functional::get_func_type() == 3) { #ifdef USE_LIBXC atau = GlobalC::CHR.kin_r[0][ir]/2.0; @@ -141,7 +138,7 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) double v2c = 0.0; for(int ir=0; ir Date: Fri, 25 Feb 2022 16:53:33 +0800 Subject: [PATCH 13/36] xc refactor : split realization of functionals into 5 separate files --- source/module_xc/CMakeLists.txt | 5 + source/module_xc/xc_funct_corr_gga.cpp | 435 ++++++++ source/module_xc/xc_funct_corr_lda.cpp | 359 +++++++ source/module_xc/xc_funct_exch_gga.cpp | 283 +++++ source/module_xc/xc_funct_exch_lda.cpp | 148 +++ source/module_xc/xc_funct_hcth.cpp | 147 +++ source/module_xc/xc_functional.cpp | 1346 +----------------------- 7 files changed, 1382 insertions(+), 1341 deletions(-) create mode 100644 source/module_xc/xc_funct_corr_gga.cpp create mode 100644 source/module_xc/xc_funct_corr_lda.cpp create mode 100644 source/module_xc/xc_funct_exch_gga.cpp create mode 100644 source/module_xc/xc_funct_exch_lda.cpp create mode 100644 source/module_xc/xc_funct_hcth.cpp diff --git a/source/module_xc/CMakeLists.txt b/source/module_xc/CMakeLists.txt index aea1a0da78e..93e38d0f6f3 100644 --- a/source/module_xc/CMakeLists.txt +++ b/source/module_xc/CMakeLists.txt @@ -3,6 +3,11 @@ list(APPEND objects potential_libxc_meta.cpp xc_functional.cpp xc_gga_pw.cpp + xc_funct_exch_lda.cpp + xc_funct_corr_lda.cpp + xc_funct_exch_gga.cpp + xc_funct_corr_gga.cpp + xc_funct_hcth.cpp ) add_library( diff --git a/source/module_xc/xc_funct_corr_gga.cpp b/source/module_xc/xc_funct_corr_gga.cpp new file mode 100644 index 00000000000..b46f762753d --- /dev/null +++ b/source/module_xc/xc_funct_corr_gga.cpp @@ -0,0 +1,435 @@ +// This file contains realizations of gradient correction to correlation part +// Spin unpolarized ones: +// 1. perdew86 : P86 +// 2. ggac : PW91 +// 3. pbec +// 4. glyp +// And some of their spin polarized counterparts: +// 1. perdew86_spin +// 2. ggac_spin +// 3. pbec_spin + +#include "xc_functional.h" + +void XC_Functional::perdew86(const double rho, const double grho, double &sc, double &v1c, double &v2c) +{ + // Perdew gradient correction on correlation: PRB 33, 8822 (1986) + + // USE kinds + // implicit none + // real(kind=DP) :: rho, grho, sc, v1c, v2c + double p1, p2, p3, p4, pc1, pc2, pci; + // parameter : + p1 = 0.0232660; + p2 = 7.389e-6; + p3 = 8.7230; + p4 = 0.4720; + // parameter : + pc1 = 0.0016670; + pc2 = 0.0025680; + pci = pc1 + pc2; + double third, pi34; + // parameter : + third = 1.0 / 3.0; + pi34 = 0.62035049089940; // pi34=(3/4pi)^(1/3) + double rho13, rho43, rs, rs2, rs3, cna, cnb, cn, drs; + double dcna, dcnb, dcn, phi, ephi; + + rho13 = pow(rho, third); + rho43 = pow(rho13, 4); + rs = pi34 / rho13; + rs2 = rs * rs; + rs3 = rs * rs2; + cna = pc2 + p1 * rs + p2 * rs2; + cnb = 1.0 + p3 * rs + p4 * rs2 + 1.e4 * p2 * rs3; + cn = pc1 + cna / cnb; + drs = - third * pi34 / rho43; + dcna = (p1 + 2.0 * p2 * rs) * drs; + dcnb = (p3 + 2.0 * p4 * rs + 3.e4 * p2 * rs2) * drs; + dcn = dcna / cnb - cna / (cnb * cnb) * dcnb; + phi = 0.1920 * pci / cn * sqrt(grho) * pow(rho, (- 7.0 / 6.0)); + // SdG: in the original paper 1.745*0.11=0.19195 is used + ephi = exp(- phi); + sc = grho / rho43 * cn * ephi; + v1c = sc * ((1.0 + phi) * dcn / cn - ((4.0 / 3.0) - (7.0 / + 6.0) * phi) / rho); + v2c = cn * ephi / rho43 * (2.0 - phi); + + return; +} //end subroutine perdew86 + +void XC_Functional::ggac(const double &rho,const double &grho, double &sc, double &v1c, double &v2c) +{ + // Perdew-Wang GGA (PW91) correlation part + double al, pa, pb, pc, pd, cx, cxc0, cc0; + // parameter : + al = 0.090; + pa = 0.0232660; + pb = 7.389e-6; + pc = 8.7230; + pd = 0.4720; + // parameter : + cx = -0.0016670; + cxc0 = 0.0025680; + cc0 = - cx + cxc0; + double third, pi34, nu, be, xkf, xks; + // parameter : + third = 1.0 / 3.0; + pi34 = 0.62035049089940; + // parameter : + nu = 15.7559203494831440; + be = nu * cc0; + // parameter : + xkf = 1.9191582926775130; + xks = 1.1283791670955130; + // pi34=(3/4pi)^(1/3), nu=(16/pi)*(3 pi^2)^(1/3) + // xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) + double kf, ks, rs, rs2, rs3, ec, vc, t, expe, af, bf, y, xy, + qy, s1; + double h0, dh0, ddh0, ee, cn, dcn, cna, dcna, cnb, dcnb, h1, + dh1, ddh1; + + rs = pi34 / pow(rho, third); + rs2 = rs * rs; + rs3 = rs * rs2; + + // call function: pw + XC_Functional::pw(rs, 0, ec, vc); + kf = xkf / rs; + ks = xks * sqrt(kf); + t = sqrt(grho) / (2.0 * ks * rho); + expe = exp(- 2.0 * al * ec / (be * be)); + af = 2.0 * al / be * (1.0 / (expe - 1.0)); + bf = expe * (vc - ec); + y = af * t * t; + xy = (1.0 + y) / (1.0 + y + y * y); + + double x; + x = 1.0 + y + y * y; + qy = y * y * (2.0 + y) / (x * x); + s1 = 1.0 + 2.0 * al / be * t * t * xy; + h0 = be * be / (2.0 * al) * log(s1); + dh0 = be * t * t / s1 * (- 7.0 / 3.0 * xy - qy * (af * bf / + be - 7.0 / 3.0)); + ddh0 = be / (2.0 * ks * ks * rho) * (xy - qy) / s1; + + x = ks / kf * t; + ee = - 100.0 * (x * x); + cna = cxc0 + pa * rs + pb * rs2; + dcna = pa * rs + 2.0 * pb * rs2; + cnb = 1.0 + pc * rs + pd * rs2 + 1.e4 * pb * rs3; + dcnb = pc * rs + 2.0 * pd * rs2 + 3.e4 * pb * rs3; + cn = cna / cnb - cx; + dcn = dcna / cnb - cna * dcnb / (cnb * cnb); + h1 = nu * (cn - cc0 - 3.0 / 7.0 * cx) * t * t * exp(ee); + dh1 = - third * (h1 * (7.0 + 8.0 * ee) + nu * t * t * exp(ee) + * dcn); + ddh1 = 2.0 * h1 * (1.0 + ee) * rho / grho; + sc = rho * (h0 + h1); + v1c = h0 + h1 + dh0 + dh1; + v2c = ddh0 + ddh1; + + return; +} //end subroutine ggac + +void XC_Functional::pbec(const double &rho, const double &grho, const int &iflag, double &sc, double &v1c, double &v2c) +{ + // PBE correlation (without LDA part) + // iflag=0: J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996). + // iflag=1: J.P.Perdew et al., PRL 100, 136406 (2008). + const double ga = 0.0310906908696548950; + const double be[2] = {0.06672455060314922, 0.046}; + + const double third = 1.0 / 3.0; + const double pi34 = 0.62035049089940; + const double xkf = 1.9191582926775130; + const double xks = 1.1283791670955130; + + // pi34=(3/4pi)^(1/3), xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) + double ec, vc; + + const double rs = pi34 / pow(rho, third); + + XC_Functional::pw(rs, 0, ec, vc); + + const double kf = xkf / rs; + const double ks = xks * sqrt(kf); + const double t = sqrt(grho) / (2.0 * ks * rho); + const double expe = exp(- ec / ga); + const double af = be[iflag] / ga * (1.0 / (expe - 1.0)); + const double bf = expe * (vc - ec); + const double y = af * t * t; + const double xy = (1.0 + y) / (1.0 + y + y * y); + + const double x = 1.0 + y + y * y; + const double qy = y * y * (2.0 + y) / (x * x); + const double s1 = 1.0 + be[iflag] / ga * t * t * xy; + const double h0 = ga * log(s1); + const double dh0 = be[iflag] * t * t / s1 * (- 7.0 / 3.0 * xy - qy * (af * bf /be[iflag] - 7.0 / 3.0)); + const double ddh0 = be[iflag] / (2.0 * ks * ks * rho) * (xy - qy) / s1; + + sc = rho * h0; + v1c = h0 + dh0; + v2c = ddh0; + + return; +} + +void XC_Functional::glyp(const double &rho, const double &grho, double &sc, double &v1c, double &v2c) +{ + //----------------------------------------------------------------------- + // Lee Yang Parr: gradient correction part + + double a, b, c, d; + a = 0.049180; + b = 0.1320; + c = 0.25330; + d = 0.3490; + double rhom13, rhom43, rhom53, om, xl, ff, dom, dxl; + + rhom13 = pow(rho, (- 1.0 / 3.0)); + om = exp(- c * rhom13) / (1.0 + d * rhom13); + xl = 1.0 + (7.0 / 3.0) * (c * rhom13 + d * rhom13 / (1.0 + d * + rhom13)); + ff = a * b * grho / 24.0; + rhom53 = pow(rhom13, 5); + sc = ff * rhom53 * om * xl; + dom = - om * (c + d + c * d * rhom13) / (1.0 + d * rhom13); + + double x; + x = 1.0 + d * rhom13; + dxl = (7.0 / 3.0) * (c + d + 2.0 * c * d * rhom13 + c * d * d * + rhom13 * rhom13) / (x * x); + rhom43 = pow(rhom13, 4); + v1c = - ff * rhom43 / 3.0 * (5.0 * rhom43 * om * xl + rhom53 * + dom * xl + rhom53 * om * dxl); + v2c = 2.0 * sc / grho; + + return; +} // end subroutine glyp + +//----------------------------------------------------------------------- +void XC_Functional::perdew86_spin(double rho, double zeta, double grho, double &sc, + double &v1cup, double &v1cdw, double &v2c) +{ + //------------------------------------------------------------------- + // Perdew gradient correction on correlation: PRB 33, 8822 (1986) + // spin-polarized case + + // USE kinds + // implicit none + // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c + double p1, p2, p3, p4, pc1, pc2, pci; + // parameter : + p1 = 0.0232660; + p2 = 7.389e-6; + p3 = 8.7230; + p4 = 0.4720; + // parameter : + pc1 = 0.0016670; + pc2 = 0.0025680; + pci = pc1 + pc2; + double third, pi34; + // parameter : + third = 1.0 / 3.0; + pi34 = 0.62035049089940; + // pi34=(3/4pi)^(1/3) + + double rho13, rho43, rs, rs2, rs3, cna, cnb, cn, drs; + double dcna, dcnb, dcn, phi, ephi, dd, ddd; + + rho13 = pow(rho, third); + rho43 = pow(rho13, 4); + rs = pi34 / rho13; + rs2 = rs * rs; + rs3 = rs * rs2; + cna = pc2 + p1 * rs + p2 * rs2; + cnb = 1.0 + p3 * rs + p4 * rs2 + 1.e4 * p2 * rs3; + cn = pc1 + cna / cnb; + drs = - third * pi34 / rho43; + dcna = (p1 + 2.0 * p2 * rs) * drs; + dcnb = (p3 + 2.0 * p4 * rs + 3.e4 * p2 * rs2) * drs; + dcn = dcna / cnb - cna / (cnb * cnb) * dcnb; + phi = 0.1920 * pci / cn * sqrt(grho) * pow(rho, (- 7.0 / 6.0)); + //SdG: in the original paper 1.745*0.11=0.19195 is used + dd = pow((2.0) , third) * sqrt(pow(((1.0 + zeta) * 0.50) , (5.0 / + 3.0)) + pow(((1.0 - zeta) * 0.50) , (5.0 / 3.0))); + ddd = pow((2.0) , (- 4.0 / 3.0)) * 5.0 * (pow(((1.0 + zeta) + * 0.50) , (2.0 / 3.0)) - pow(((1.0 - zeta) * 0.50) , (2.0 / + 3.0))) / (3.0 * dd); + ephi = exp(- phi); + sc = grho / rho43 * cn * ephi / dd; + v1cup = sc * ((1.0 + phi) * dcn / cn - ((4.0 / 3.0) - + (7.0 / 6.0) * phi) / rho) - sc * ddd / dd * (1.0 - zeta) + / rho; + v1cdw = sc * ((1.0 + phi) * dcn / cn - ((4.0 / 3.0) - + (7.0 / 6.0) * phi) / rho) + sc * ddd / dd * (1.0 + zeta) + / rho; + v2c = cn * ephi / rho43 * (2.0 - phi) / dd; + + return; +} //end subroutine perdew86_spin + +//----------------------------------------------------------------------- +void XC_Functional::ggac_spin(double rho, double zeta, double grho, double &sc, + double &v1cup, double &v1cdw, double &v2c) +{ + //------------------------------------------------------------------- + // Perdew-Wang GGA (PW91) correlation part - spin-polarized + + // USE kinds + // implicit none + // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c + double al, pa, pb, pc, pd, cx, cxc0, cc0; + // parameter : + al = 0.090; + pa = 0.0232660; + pb = 7.389e-6; + pc = 8.7230; + pd = 0.4720; + // parameter : + cx = - 0.0016670; + cxc0 = 0.0025680; + cc0 = - cx + cxc0; + + double third, pi34, nu, be, xkf, xks; + // parameter : + third = 1.0 / 3.0; + pi34 = 0.6203504908994e0l; + // parameter : + nu = 15.7559203494831440; + be = nu * cc0; + // parameter : + xkf = 1.9191582926775130; + xks = 1.1283791670955130; + // pi34=(3/4pi)^(1/3), nu=(16/pi)*(3 pi^2)^(1/3) + // xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) + double kf, ks, rs, rs2, rs3, ec, vcup, vcdw, t, expe, af, y, + xy, qy, s1, h0, ddh0, ee, cn, dcn, cna, dcna, cnb, dcnb, h1, dh1, + ddh1, fz, fz2, fz3, fz4, dfz, bfup, dh0up, dh0zup, //bfdw, dh0dw, + dh0zdw, dh1zup, dh1zdw; + + rs = pi34 / pow(rho, third); + rs2 = rs * rs; + rs3 = rs * rs2; + XC_Functional::pw_spin(rs, zeta, ec, vcup, vcdw); + kf = xkf / rs; + ks = xks * sqrt(kf); + fz = 0.50 * (pow((1.0 + zeta) , (2.0 / 3.0)) + pow((1.0 - zeta) , ( + 2.0 / 3.0))); + fz2 = fz * fz; + fz3 = fz2 * fz; + fz4 = fz3 * fz; + dfz = (pow((1.0 + zeta) , (- 1.0 / 3.0)) - pow((1.0 - zeta) , (- + 1.0 / 3.0))) / 3.0; + t = sqrt(grho) / (2.0 * fz * ks * rho); + expe = exp(- 2.0 * al * ec / (fz3 * be * be)); + af = 2.0 * al / be * (1.0 / (expe - 1.0)); + bfup = expe * (vcup - ec) / fz3; + //bfdw = expe * (vcdw - ec) / fz3; + y = af * t * t; + xy = (1.0 + y) / (1.0 + y + y * y); + qy = y * y * (2.0 + y) / (1.0 + y + y * y) ; //**2; + qy *= qy; + s1 = 1.0 + 2.0 * al / be * t * t * xy; + h0 = fz3 * be * be / (2.0 * al) * log(s1); + dh0up = be * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * + (af * bfup / be - 7.0 / 3.0)); + //dh0dw = be * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * + // (af * bfdw / be - 7.0 / 3.0)); + dh0zup = (3.0 * h0 / fz - be * t * t * fz2 / s1 * (2.0 * xy - + qy * (3.0 * af * expe * ec / fz3 / be + 2.0))) * dfz * (1.0 - + zeta); + dh0zdw = - (3.0 * h0 / fz - be * t * t * fz3 / s1 * (2.0 * xy - + qy * (3.0 * af * expe * ec / fz3 / be + 2.0))) * dfz * (1.0 + + zeta); + ddh0 = be * fz / (2.0 * ks * ks * rho) * (xy - qy) / s1; + ee = - 100.0 * fz4 * (ks / kf * t); // **2; + ee *= ee; + cna = cxc0 + pa * rs + pb * rs2; + dcna = pa * rs + 2.0 * pb * rs2; + cnb = 1.0 + pc * rs + pd * rs2 + 1.e4 * pb * rs3; + dcnb = pc * rs + 2.0 * pd * rs2 + 3.e4 * pb * rs3; + cn = cna / cnb - cx; + dcn = dcna / cnb - cna * dcnb / (cnb * cnb); + h1 = nu * (cn - cc0 - 3.0 / 7.0 * cx) * fz3 * t * t * exp(ee); + dh1 = - third * (h1 * (7.0 + 8.0 * ee) + fz3 * nu * t * t * exp + (ee) * dcn); + ddh1 = 2.0 * h1 * (1.0 + ee) * rho / grho; + dh1zup = (1.0 - zeta) * dfz * h1 * (1.0 + 2.0 * ee / fz); + dh1zdw = - (1.0 + zeta) * dfz * h1 * (1.0 + 2.0 * ee / fz); + sc = rho * (h0 + h1); + v1cup = h0 + h1 + dh0up + dh1 + dh0zup + dh1zup; + v1cdw = h0 + h1 + dh0up + dh1 + dh0zdw + dh1zdw; + v2c = ddh0 + ddh1; + return; +} // end subroutine ggac_spin + +//--------------------------------------------------------------- +void XC_Functional::pbec_spin(double rho, double zeta, double grho, const int &iflag, double &sc, + double &v1cup, double &v1cdw, double &v2c) +{ + //----------------------------------------------------------- + + // PBE correlation (without LDA part) - spin-polarized + // J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996). + + // USE kinds + // implicit none + // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c + double ga, be[3];//mohan add + // parameter : + ga = 0.0310910; + be[1] = 0.06672455060314922;//zhengdy add 2019-09-12, ensure same parameter with another dft code. + be[2] = 0.0460000;//mohan add 2012-05-28 + double third, pi34, xkf, xks; + // parameter : + third = 1.0 / 3.0; + pi34 = 0.62035049089940; + // parameter : + xkf = 1.9191582926775130; + xks = 1.1283791670955130; + // pi34=(3/4pi)^(1/3), xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) + double kf, ks, rs, ec, vcup, vcdw, t, expe, af, y, xy, qy, + s1, h0, ddh0; + double fz, fz2, fz3, dfz, bfup, bfdw, dh0up, dh0dw, dh0zup, dh0zdw; // fz4 + + rs = pi34 / pow(rho, third); + XC_Functional::pw_spin(rs, zeta, ec, vcup, vcdw); //mohan fix bug 2012-05-28 + kf = xkf / rs; + ks = xks * sqrt(kf); + fz = 0.50 * (pow((1.0 + zeta) , (2.0 / 3.0)) + pow((1.0 - zeta) , ( + 2.0 / 3.0))); + fz2 = fz * fz; + fz3 = fz2 * fz; + //fz4 = fz3 * fz; + dfz = (pow((1.0 + zeta) , (- 1.0 / 3.0)) - pow((1.0 - zeta) , (- + 1.0 / 3.0))) / 3.0; + t = sqrt(grho) / (2.0 * fz * ks * rho); + expe = exp(- ec / (fz3 * ga)); + af = be[iflag] / ga * (1.0 / (expe - 1.0)); + bfup = expe * (vcup - ec) / fz3; + bfdw = expe * (vcdw - ec) / fz3; + y = af * t * t; + xy = (1.0 + y) / (1.0 + y + y * y); + qy = y * y * (2.0 + y) / pow( (1.0 + y + y * y),2 ); +// qy *= qy; //bug + s1 = 1.0 + be[iflag] / ga * t * t * xy; + h0 = fz3 * ga * log(s1); + dh0up = be[iflag] * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * + (af * bfup / be[iflag] - 7.0 / 3.0)); + dh0dw = be[iflag] * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * + (af * bfdw / be[iflag] - 7.0 / 3.0)); + dh0zup = (3.0 * h0 / fz - be[iflag] * t * t * fz2 / s1 * (2.0 * xy - + qy * (3.0 * af * expe * ec / fz3 / be[iflag] + 2.0))) * dfz * (1.0 - + zeta); + dh0zdw = - (3.0 * h0 / fz - be[iflag] * t * t * fz2 / s1 * (2.0 * xy - + qy * (3.0 * af * expe * ec / fz3 / be[iflag] + 2.0))) * dfz * (1.0 + + zeta); + ddh0 = be[iflag] * fz / (2.0 * ks * ks * rho) * (xy - qy) / s1; + sc = rho * h0; + v1cup = h0 + dh0up + dh0zup; + v1cdw = h0 + dh0dw + dh0zdw; + v2c = ddh0; + return; +} // end subroutine pbec_spin \ No newline at end of file diff --git a/source/module_xc/xc_funct_corr_lda.cpp b/source/module_xc/xc_funct_corr_lda.cpp new file mode 100644 index 00000000000..4a749320b85 --- /dev/null +++ b/source/module_xc/xc_funct_corr_lda.cpp @@ -0,0 +1,359 @@ +// This file contains realization of LDA correlation functionals +// Spin unpolarized ones: +// 1. pw : Perdew-Wang LDA correlation +// 2. pz : Perdew-Zunger LDA correlation +// 3. lyp : Lee-Yang-Parr correlation +// 4. vwn : Vosko-Wilk-Nusair LDA correlation +// 5. wigner : Wigner +// 6. hl : Hedin-Lunqvist +// 7. gl : Gunnarson-Lunqvist +// And some of their spin polarized counterparts: +// 1. pw_spin +// 2. pz_spin, which calls pz_polarized + +#include "xc_functional.h" + +void XC_Functional::pw(const double &rs, const int &iflag, double &ec, double &vc) +{ + const double a = 0.0310910; + const double b1 = 7.59570; + const double b2 = 3.58760; + const double c0 = a; + const double c1 = 0.0466440; + const double c2 = 0.006640; + const double c3 = 0.010430; + const double d0 = 0.43350; + const double d1 = 1.44080; + double lnrs, rs12, rs32, rs2, om, dom, olog; + double a1[2] = { 0.213700, 0.0264810 }; + double b3[2] = { 1.63820, -0.466470 }; + double b4[2] = { 0.492940, 0.133540 }; + + // high- and low-density formulae implemented but not used in PW case + // (reason: inconsistencies in PBE/PW91 functionals) + + if (rs < 1 && iflag == 1) + { + // high density formula + lnrs = log(rs); + ec = c0 * lnrs - c1 + c2 * rs * lnrs - c3 * rs; + vc = c0 * lnrs - (c1 + c0 / 3.0) + 2.0 / 3.0 * c2 * rs * + lnrs - (2.0 * c3 + c2) / 3.0 * rs; + } + else if (rs > 100.0 && iflag == 1) + { + // low density formula + ec = - d0 / rs + d1 / pow(rs, 1.50); + vc = - 4.0 / 3.0 * d0 / rs + 1.50 * d1 / pow(rs, 1.50); + } + else + { + // interpolation formula + rs12 = sqrt(rs); + rs32 = rs * rs12; + rs2 = rs * rs; + om = 2.0 * a * (b1 * rs12 + b2 * rs + b3 [iflag] * rs32 + b4 [ + iflag] * rs2); + dom = 2.0 * a * (0.50 * b1 * rs12 + b2 * rs + 1.50 * b3 [ + iflag] * rs32 + 2.0 * b4 [iflag] * rs2); + olog = log(1.0 + 1.0 / om); + ec = - 2.0 * a * (1.0 + a1 [iflag] * rs) * olog; + vc = - 2.0 * a * (1.0 + 2.0 / 3.0 * a1 [iflag] * rs) + * olog - 2.0 / 3.0 * a * (1.0 + a1 [iflag] * rs) * dom / + (om * (om + 1.0)); + } + return; +} + +//LDA parameterization form Monte Carlo data +//iflag=0: J.P. Perdew and A. Zunger, PRB 23, 5048 (1981) +//iflag=1: G. Ortiz and P. Ballone, PRB 50, 1391 (1994) +void XC_Functional::pz(const double &rs, const int &iflag, double &ec, double &vc) +{ +// ModuleBase::TITLE("XC_Functional","pz"); + const double a[2] = {0.0311, 0.031091}; + const double b[2] = { -0.048, -0.046644 }; + const double c[2] = { 0.0020, 0.00419 }; + const double d[2] = { -0.0116, -0.00983 }; + const double gc[2] = { -0.1423, -0.103756}; + const double b1[2] = { 1.0529, 0.56371 }; + const double b2[2] = { 0.3334, 0.27358 }; + + if (rs < 1.0) + { + // high density formula + const double lnrs = log(rs); + ec = a [iflag] * lnrs + b [iflag] + c [iflag] * rs * lnrs + d [iflag] * rs; + vc = a [iflag] * lnrs + (b [iflag] - a [iflag] / 3.0) + 2.0 / + 3.0 * c [iflag] * rs * lnrs + (2.0 * d [iflag] - c [iflag]) + / 3.0 * rs; + } + else + { + // interpolation formula + const double rs12 = sqrt(rs); + const double ox = 1.0 + b1 [iflag] * rs12 + b2 [iflag] * rs; + const double dox = 1.0 + 7.0 / 6.0 * b1 [iflag] * rs12 + 4.0 / 3.0 * + b2 [iflag] * rs; + ec = gc [iflag] / ox; + vc = ec * dox / ox; + } + return; +} + +// C. Lee, W. Yang, and R.G. Parr, PRB 37, 785 (1988) +// LDA part only +void XC_Functional::lyp(const double &rs, double &ec, double &vc) +{ + const double a = 0.04918e0; + const double b = 0.1320 * 2.87123400018819108e0; + // pi43 = (4pi/3)^(1/3) + const double pi43 = 1.61199195401647e0; + const double c = 0.2533e0 * pi43; + const double d = 0.349e0 * pi43; + double ecrs, ox; + + ecrs = b * exp(- c * rs); + ox = 1.0 / (1.0 + d * rs); + ec = - a * ox * (1.0 + ecrs); + vc = ec - rs / 3.0 * a * ox * (d * ox + ecrs * (d * ox + c)); + + return; +} + +// S.H. Vosko, L. Wilk, and M. Nusair, Can. J. Phys. 58, 1200 (1980) +void XC_Functional::vwn(const double &rs, double &ec, double &vc) +{ + const double a = 0.0310907; + const double b = 3.72744; + const double c = 12.9352; + const double x0 = -0.10498; + double q, f1, f2, f3, rs12, fx, qx, tx, tt; + + q = sqrt(4.0 * c - b * b); + f1 = 2.0 * b / q; + f2 = b * x0 / (x0 * x0 + b * x0 + c); + f3 = 2.0 * (2.0 * x0 + b) / q; + rs12 = sqrt(rs); + fx = rs + b * rs12 + c; + qx = atan(q / (2.0 * rs12 + b)); + + double x; + x = (rs12 - x0); + ec = a * (log(rs / fx) + f1 * qx - f2 * (log((x * x) / + fx) + f3 * qx)); + tx = 2.0 * rs12 + b; + tt = tx * tx + q * q; + + vc = ec - rs12 * a / 6.0 * (2.0 / rs12 - tx / fx - 4.0 * b / + tt - f2 * (2.0 / (rs12 - x0) - tx / fx - 4.0 * (2.0 * x0 + b)/ tt)); + + return; +} + +void XC_Functional::wigner( const double &rs, double &ec, double &vc) +{ + const double pi34 = 0.6203504908994e0; + // pi34=(3/4pi)^(1/3), rho13=rho^(1/3) + + double rho13 = pi34 / rs; + double x = 1.0 + 12.570 * rho13; + vc = - rho13 * ((0.9436560 + 8.89630 * rho13) / (x * x)); + ec = - 0.7380 * rho13 * (0.9590 / (1.0 + 12.570 * rho13)); + return; +} + +// L. Hedin and B.I. Lundqvist, J. Phys. C 4, 2064 (1971) +void XC_Functional::hl( const double &rs, double &ec, double &vc) +{ + double a, x; + a = log(1.00 + 21.0 / rs); + x = rs / 21.00; + ec = a + (pow(x, 3) * a - x * x) + x / 2.0 - 1.00 / 3.00; + ec = - 0.02250 * ec; + vc = - 0.02250 * a; + return; +} + +// O. Gunnarsson and B. I. Lundqvist, PRB 13, 4274 (1976) +void XC_Functional::gl( const double &rs, double &ec, double &vc) +{ + const double c = 0.0333; + const double r = 11.4; + // c=0.0203, r=15.9 for the paramagnetic case + double x = rs / r; + vc = - c * log(1.0 + 1.0 / x); + ec = - c * ((1.0 + pow(x, 3)) * log(1.0 + 1.0 / x) - 1.00 / + 3.00 + x * (0.50 - x)); + return; +} + +// J.P. Perdew and Y. Wang, PRB 45, 13244 (1992) +void XC_Functional::pw_spin( const double &rs, const double &zeta, + double &ec, double &vcup, double &vcdw) +{ + const double a = 0.0310910; + const double a1 = 0.213700; + const double b1 = 7.59570; + const double b2 = 3.58760; + const double b3 = 1.63820; + const double b4 = 0.492940; + //const double c0 = a; + //const double c1 = 0.0466440; + //const double c2 = 0.006640; + //const double c3 = 0.010430; + //const double d0 = 0.43350; + //const double d1 = 1.44080; + // polarized parameters + const double ap = 0.0155450; + const double a1p = 0.205480; + const double b1p = 14.11890; + const double b2p = 6.19770; + const double b3p = 3.36620; + const double b4p = 0.625170; + //const double c0p = ap; + //const double c1p = 0.0255990; + //const double c2p = 0.003190; + //const double c3p = 0.003840; + //const double d0p = 0.32870; + //const double d1p = 1.76970; + // antiferro + const double aa = 0.0168870; + const double a1a = 0.111250; + const double b1a = 10.3570; + const double b2a = 3.62310; + const double b3a = 0.880260; + const double b4a = 0.496710; + //const double c0a = aa; + //const double c1a = 0.0354750; + //const double c2a = 0.001880; + //const double c3a = 0.005210; + //const double d0a = 0.22400; + //const double d1a = 0.39690; + + const double fz0 = 1.7099210; + double rs12, rs32, rs2, zeta2, zeta3, zeta4, fz, dfz; + double om, dom, olog, epwc, vpwc; + double omp, domp, ologp, epwcp, vpwcp; + double oma, doma, ologa, alpha, vpwca; + + // if(rs.lt.0.5d0) then + // high density formula (not implemented) + // + // else if(rs.gt.100.d0) then + // low density formula (not implemented) + // + // else + // interpolation formula + zeta2 = zeta * zeta; + zeta3 = zeta2 * zeta; + zeta4 = zeta3 * zeta; + rs12 = sqrt(rs); + rs32 = rs * rs12; + rs2 = rs * rs; + // unpolarised + om = 2.0 * a * (b1 * rs12 + b2 * rs + b3 * rs32 + b4 * rs2); + dom = 2.0 * a * (0.50 * b1 * rs12 + b2 * rs + 1.50 * b3 * rs32 + + 2.0 * b4 * rs2); + olog = log(1.0 + 1.00 / om); + epwc = - 2.0 * a * (1.0 + a1 * rs) * olog; + vpwc = - 2.0 * a * (1.0 + 2.0 / 3.0 * a1 * rs) * olog - 2.0 / + 3.0 * a * (1.0 + a1 * rs) * dom / (om * (om + 1.0)); + // polarized + omp = 2.0 * ap * (b1p * rs12 + b2p * rs + b3p * rs32 + b4p * rs2); + domp = 2.0 * ap * (0.50 * b1p * rs12 + b2p * rs + 1.50 * b3p * + rs32 + 2.0 * b4p * rs2); + ologp = log(1.0 + 1.00 / omp); + epwcp = - 2.0 * ap * (1.0 + a1p * rs) * ologp; + vpwcp = - 2.0 * ap * (1.0 + 2.0 / 3.0 * a1p * rs) * ologp - + 2.0 / 3.0 * ap * (1.0 + a1p * rs) * domp / (omp * (omp + 1.0)); + // antiferro + oma = 2.0 * aa * (b1a * rs12 + b2a * rs + b3a * rs32 + b4a * rs2); + doma = 2.0 * aa * (0.50 * b1a * rs12 + b2a * rs + 1.50 * b3a * + rs32 + 2.0 * b4a * rs2); + ologa = log(1.0 + 1.00 / oma); + alpha = 2.0 * aa * (1.0 + a1a * rs) * ologa; + vpwca = + 2.0 * aa * (1.0 + 2.0 / 3.0 * a1a * rs) * ologa + + 2.0 / 3.0 * aa * (1.0 + a1a * rs) * doma / (oma * (oma + 1.0)); + + fz = (pow((1.0 + zeta) , (4.0 / 3.0)) + pow((1.0 - zeta) , (4.0 / + 3.0)) - 2.0) / (pow(2.0, (4.0 / 3.0)) - 2.0); + dfz = (pow((1.0 + zeta) , (1.0 / 3.0)) - pow((1.0 - zeta) , (1.0 / + 3.0))) * 4.0 / (3.0 * (pow(2.0 , (4.0 / 3.0)) - 2.0)); + + ec = epwc + alpha * fz * (1.0 - zeta4) / fz0 + (epwcp - epwc) + * fz * zeta4; + + vcup = vpwc + vpwca * fz * (1.0 - zeta4) / fz0 + + (vpwcp - vpwc) * fz * zeta4 + + (alpha / fz0 * (dfz * (1.0 - zeta4) - 4.0 * fz * zeta3) + + (epwcp - epwc) * (dfz * zeta4 + 4.0 * fz * zeta3)) * (1.0 - zeta); + + vcdw = vpwc + vpwca * fz * (1.0 - zeta4) / fz0 + + (vpwcp - vpwc) * fz * zeta4 + - (alpha / fz0 * (dfz * (1.0 - zeta4) - 4.0 * fz * zeta3) + + (epwcp - epwc) * (dfz * zeta4 + 4.0 * fz * zeta3)) * (1.0 + zeta); + return; +} + +// J.P. Perdew and Y. Wang, PRB 45, 13244 (1992) +void XC_Functional::pz_spin( const double &rs, const double &zeta, + double &ec, double &vcup, double &vcdw) +{ +// ModuleBase::TITLE("XC_Functional","pz_spin"); + double ecu, vcu, ecp, vcp ; + static const double p43 = 4.00 / 3.0; + static const double third = 1.0 / 3.0; + + // unpolarized part (Perdew-Zunger formula) + XC_Functional::pz(rs, 0, ecu, vcu); + + // polarization contribution + XC_Functional::pz_polarized(rs, ecp, vcp); + + double fz = (pow((1.00 + zeta) , p43) + pow((1.0 - zeta) , p43) - 2.0) / + (pow(2.0 , p43) - 2.0); + double dfz = p43 * (pow((1.00 + zeta) , third) - pow((1.0 - zeta) , third)) + / (pow(2.0, p43) - 2.0); + + //correlation energy + ec = ecu + fz * (ecp - ecu); + + // spin up correlation potential + vcup = vcu + fz * (vcp - vcu) + (ecp - ecu) * dfz * (1.0 - zeta); + // spin down correlation potential + vcdw = vcu + fz * (vcp - vcu) + (ecp - ecu) * dfz * (- 1.0 - zeta); + + return; +} + +// J.P. Perdew and A. Zunger, PRB 23, 5048 (1981) +void XC_Functional::pz_polarized( const double &rs, double &ec, double &vc) +{ +// ModuleBase::TITLE("XC_Functional","pz_polarized"); + static const double a = 0.015550; + static const double b = -0.02690; + static const double c = 0.00070; + static const double d = -0.00480; + static const double gc = -0.08430; + static const double b1 = 1.39810; + static const double b2 = 0.26110; + + if (rs < 1.00) + { + double lnrs = log(rs); + ec = a * lnrs + b + c * rs * lnrs + d * rs; + vc = a * lnrs + (b - a / 3.0) + 2.0 / 3.0 * c * rs * lnrs + + (2.0 * d - c) / 3.0 * rs; + } + else + { + // interpolation formula + double rs12 = sqrt(rs); + double ox = 1.0 + b1 * rs12 + b2 * rs; + double dox = 1.0 + 7.0 / 6.0 * b1 * rs12 + 4.0 / 3.0 * b2 * rs; + ec = gc / ox; + vc = ec * dox / ox; + } + return; +} \ No newline at end of file diff --git a/source/module_xc/xc_funct_exch_gga.cpp b/source/module_xc/xc_funct_exch_gga.cpp new file mode 100644 index 00000000000..4045707085a --- /dev/null +++ b/source/module_xc/xc_funct_exch_gga.cpp @@ -0,0 +1,283 @@ +// This file contains realizations of gradient correction to exchange part +// Spin unpolarized ones: +// 1. becke88 : Becke88 exchange +// 2. ggax : PW91 exchange +// 3. pbex : PBE exchange (and revPBE) +// 4. optx : OPTX, Handy et al. +// 5. wcx : Wu-Cohen exchange +// And some of their spin polarized counterparts: +// 1. becke88_spin + +#include "xc_functional.h" + +void XC_Functional::becke88(const double &rho, const double &grho, double &sx, double &v1x, double &v2x) +{ + //----------------------------------------------------------------------- + // Becke exchange: A.D. Becke, PRA 38, 3098 (1988) + // only gradient-corrected part, no Slater term included + // + double beta, third, two13; + beta = 0.00420; + third = 1.0 / 3.0; + two13 = 1.2599210498948730; + double rho13, rho43, xs, xs2, sa2b8, shm1, dd, dd2, ee; + + rho13 = pow(rho, third); + rho43 = pow(rho13, 4); + xs = two13 * sqrt(grho) / rho43; + xs2 = xs * xs; + sa2b8 = sqrt(1.00 + xs2); + shm1 = log(xs + sa2b8); + dd = 1.00 + 6.00 * beta * xs * shm1; + dd2 = dd * dd; + ee = 6.00 * beta * xs2 / sa2b8 - 1.0; + sx = two13 * grho / rho43 * (- beta / dd); + v1x = - (4.0 / 3.0) / two13 * xs2 * beta * rho13 * ee / dd2; + v2x = two13 * beta * (ee - dd) / (rho43 * dd2); + + return; +} // end subroutine becke88 + +void XC_Functional::ggax(const double &rho, const double &grho, double &sx, double &v1x, double &v2x) +{ + //----------------------------------------------------------------------- + // Perdew-Wang GGA (PW91), exchange part: + // J.P. Perdew et al.,PRB 46, 6671 (1992) + const double f1 = 0.196450; + const double f2 = 7.79560; + const double f3 = 0.27430; + const double f4 = 0.15080; + const double f5 = 0.0040; + const double fp1 = -0.0192920212964260; + const double fp2 = 0.1616204596739950; + // fp1 = -3/(16 pi)*(3 pi^2)^(-1/3) + double rhom43, s, s2, s3, s4, exps, as, sa2b8, shm1, bs, das, + dbs, dls; + + rhom43 = pow(rho, (- 4.0 / 3.0)); + s = fp2 * sqrt(grho) * rhom43; + s2 = s * s; + s3 = s2 * s; + s4 = s2 * s2; + exps = f4 * exp(- 100.0 * s2); + as = f3 - exps - f5 * s2; + sa2b8 = sqrt(1.00 + f2 * f2 * s2); + shm1 = log(f2 * s + sa2b8); + bs = 1.0 + f1 * s * shm1 + f5 * s4; + das = (200.0 * exps - 2.0 * f5) * s; + dbs = f1 * (shm1 + f2 * s / sa2b8) + 4.0 * f5 * s3; + dls = (das / as - dbs / bs); + + sx = fp1 * grho * rhom43 * as / bs; + v1x = - 4.0 / 3.0 * sx / rho * (1.0 + s * dls); + v2x = fp1 * rhom43 * as / bs * (2.0 + s * dls); + + return; +} //end subroutine ggax + +void XC_Functional::pbex(const double &rho, const double &grho, const int &iflag, +double &sx, double &v1x, double &v2x) +{ + // PBE exchange (without Slater exchange): + // iflag=0 J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996) + // iflag=1 "revised' PBE: Y. Zhang et al., PRL 80, 890 (1998) + + // input: charge and squared gradient + // output: energy + // output: potential + // (3*pi2*|rho|)^(1/3) + // |grho| + // |grho|/(2*kf*|rho|) + // s^2 + // n*ds/dn + // n*ds/d(gn) + // exchange energy LDA part + // exchange energy gradient part + + // numerical coefficients (NB: c2=(3 pi^2)^(1/3) ) + const double third = 1.0 / 3.0; + const double pi = 3.14159265358979323846; + const double c1 = 0.750 / pi; + const double c2 = 3.0936677262801360; + const double c5 = 4.0 * third; + // parameters of the functional + double k[3] = { 0.8040, 1.24500, 0.8040 }; + const double mu[3] = {0.2195149727645171, 0.2195149727645171, 0.12345679012345679} ;//modified by zhengdy, to ensure the same parameters with another dft code. + + const double agrho = sqrt(grho); + const double kf = c2 * pow(rho, third); + const double dsg = 0.50 / kf; + const double s1 = agrho * dsg / rho; + const double s2 = s1 * s1; + const double ds = - c5 * s1; + + // Energy + const double f1 = s2 * mu[iflag] / k [iflag]; + const double f2 = 1.0 + f1; + const double f3 = k [iflag] / f2; + const double fx = k [iflag] - f3; + const double exunif = - c1 * kf; + sx = exunif * fx; + + // Potential + const double dxunif = exunif * third; + const double dfx1 = f2 * f2; + const double dfx = 2.0 * mu[iflag] * s1 / dfx1; + + v1x = sx + dxunif * fx + exunif * dfx * ds; + v2x = exunif * dfx * dsg / agrho; + sx = sx * rho; + + return; +} + +void XC_Functional::optx(const double rho, const double grho, double &sx, double &v1x, double &v2x) +{ + // OPTX, Handy et al. JCP 116, p. 5411 (2002) and refs. therein + // Present release: Mauro Boero, Tsukuba, 10/9/2002 + //-------------------------------------------------------------------------- + // rhoa = rhob = 0.5 * rho in LDA implementation + // grho is the SQUARE of the gradient of rho// --> gr=sqrt(grho) + // sx : total exchange correlation energy at point r + // v1x : d(sx)/drho + // v2x : 1/gr*d(sx)/d(gr) + //-------------------------------------------------------------------------- + // use kinds, only: DP + // implicit none + // real(kind=DP) :: rho, grho, sx, v1x, v2x + + // parameter : + double small = 1.e-30; + double smal2 = 1.e-10; + //.......coefficients and exponents.................... + // parameter : + double o43 = 4.00 / 3.00, + two13 = 1.2599210498948730, + two53 = 3.1748021039363990, + gam = 0.0060, + a1cx = 0.97845711702844210, + a2 = 1.431690; + double gr, rho43, xa, gamx2, uden, uu; + //.......OPTX in compact form.......................... + + if (rho <= small) + { + sx = 0.00; + v1x = 0.00; + v2x = 0.00; + } + else + { + gr = (grho > smal2) ? grho : smal2; //max() + rho43 = pow(rho, o43); + xa = two13 * sqrt(gr) / rho43; + gamx2 = gam * xa * xa; + uden = 1.e+00 / (1.e+00 + gamx2); + uu = a2 * gamx2 * gamx2 * uden * uden; + uden = rho43 * uu * uden; + sx = -rho43 * (a1cx + uu) / two13; + v1x = o43 * (sx + two53 * uden) / rho; + v2x = -two53 * uden / gr; + } //endif + + return; +} // end subroutine optx + +void XC_Functional::wcx(const double &rho,const double &grho, double &sx, double &v1x, double &v2x) +{ + double kf, agrho, s1, s2, es2, ds, dsg, exunif, fx; + // (3*pi2*|rho|)^(1/3) + // |grho| + // |grho|/(2*kf*|rho|) + // s^2 + // n*ds/dn + // n*ds/d(gn) + // exchange energy LDA part + // exchange energy gradient part + double dxunif, dfx, f1, f2, f3, dfx1, x1, x2, x3, dxds1, dxds2, dxds3; + // numerical coefficients (NB: c2=(3 pi^2)^(1/3) ) + double third, c1, c2, c5, teneightyone; // c6 + const double pi = 3.14159265358979323846; + + third = 1.0/3.0; + c1 = 0.75/pi; + c2 = 3.093667726280136; + c5 = 4.0 * third; + teneightyone = 0.123456790123; + // parameters of the functional + double k, mu, cwc; + k = 0.804; + mu = 0.2195149727645171; + cwc = 0.00793746933516; + // + agrho = sqrt (grho); + kf = c2 * pow(rho,third); + dsg = 0.5 / kf; + s1 = agrho * dsg / rho; + s2 = s1 * s1; + es2 = exp(-s2); + ds = - c5 * s1; + // + // Energy + // + // x = 10/81 s^2 + (mu - 10/81) s^2 e^-s^2 + ln (1 + c s^4) + x1 = teneightyone * s2; + x2 = (mu - teneightyone) * s2 * es2; + x3 = log(1.0 + cwc * s2 * s2); + f1 = (x1 + x2 + x3) / k; + f2 = 1.0 + f1; + f3 = k / f2; + fx = k - f3; + exunif = - c1 * kf; + sx = exunif * fx; + // + // Potential + // + dxunif = exunif * third; + dfx1 = f2 * f2; + dxds1 = teneightyone; + dxds2 = (mu - teneightyone) * es2 * (1.0 - s2); + dxds3 = 2.0 * cwc * s2 / (1.0 + cwc * s2 *s2); + dfx = 2.0 * s1 * (dxds1 + dxds2 + dxds3) / dfx1; + v1x = sx + dxunif * fx + exunif * dfx * ds; + v2x = exunif * dfx * dsg / agrho; + + sx = sx * rho; + return; +} + +void XC_Functional::becke88_spin(double rho, double grho, double &sx, double &v1x, double &v2x) +{ + //------------------------------------------------------------------- + // Becke exchange: A.D. Becke, PRA 38, 3098 (1988) - Spin polarized case + + // USE kinds + // implicit none + // real(kind=DP) :: rho, grho, sx, v1x, v2x + // input: charge + // input: gradient + // output: the up and down energies + // output: first part of the potential + // output: the second part of the potential + + double beta, third; + // parameter : + beta = 0.00420; + third = 1.0 / 3.0; + double rho13, rho43, xs, xs2, sa2b8, shm1, dd, dd2, ee; + + rho13 = pow(rho, third); + rho43 = pow(rho13, 4); + xs = sqrt(grho) / rho43; + xs2 = xs * xs; + sa2b8 = sqrt(1.00 + xs2); + shm1 = log(xs + sa2b8); + dd = 1.00 + 6.00 * beta * xs * shm1; + dd2 = dd * dd; + ee = 6.00 * beta * xs2 / sa2b8 - 1.0; + sx = grho / rho43 * (- beta / dd); + v1x = - (4.0 / 3.0) * xs2 * beta * rho13 * ee / dd2; + v2x = beta * (ee - dd) / (rho43 * dd2); + + return; +} //end subroutine becke88_spin diff --git a/source/module_xc/xc_funct_exch_lda.cpp b/source/module_xc/xc_funct_exch_lda.cpp new file mode 100644 index 00000000000..14f32c5a47b --- /dev/null +++ b/source/module_xc/xc_funct_exch_lda.cpp @@ -0,0 +1,148 @@ +// This file contains realization of LDA exchange functionals +// Spin unpolarized ones: +// 1. slater: ordinary Slater exchange with alpha=2/3 +// 2. slater1: Slater exchange with alpha=1 +// 3. slater_rxc : Slater exchange with alpha=2/3 and Relativistic exchange +// And their spin polarized counterparts: +// 1. slater_spin +// 2. slater1_spin +// 3. slater_rxc_spin + +#include "xc_functional.h" + +//Slater exchange with alpha=2/3 +void XC_Functional::slater(const double &rs, double &ex, double &vx) +{ + // f = -9/8*(3/2pi)^(2/3) + const double f = -0.687247939924714e0; + const double alpha = 2.00 / 3.00; + ex = f * alpha / rs; + vx = 4.0 / 3.0 * f * alpha / rs; + return; +} + +//Slater exchange with alpha=1, corresponding to -1.374/r_s Ry +//used to recover old results +void XC_Functional::slater1(const double &rs, double &ex, double &vx) +{ + const double f = -0.687247939924714e0; + const double alpha = 1.0; + ex = f * alpha / rs; + vx = 4.0 / 3.0 * f * alpha / rs; + return; +} + +// Slater exchange with alpha=2/3 and Relativistic exchange +void XC_Functional::slater_rxc(const double &rs, double &ex, double &vx) +{ + static const double pi = 3.14159265358979; + const double trd = 1.0 / 3.0; + //const double ftrd = 4.0 / 3.0; + //const double tftm = pow(2.0, ftrd) - 2.0; + const double a0 = pow((4.0 / (9.0 * pi)), trd); + // X-alpha parameter: + const double alp = 2 * trd; + + double vxp = -3 * alp / (2 * pi * a0 * rs); + double exp = 3 * vxp / 4; + const double beta = 0.014 / rs; + const double sb = sqrt(1 + beta * beta); + const double alb = log(beta + sb); + vxp = vxp * (-0.5 + 1.5 * alb / (beta * sb)); + double x = (beta * sb - alb) / (beta * beta); + exp = exp * (1.0 - 1.5 * x * x); + vx = vxp; + ex = exp; + return; +} + +// Slater exchange with alpha=2/3, spin-polarized case +void XC_Functional::slater_spin( const double &rho, const double &zeta, + double &ex, double &vxup, double &vxdw) +{ + const double f = - 1.107838149573033610; + const double alpha = 2.00 / 3.00; + // f = -9/8*(3/pi)^(1/3) + const double third = 1.0 / 3.0; + const double p43 = 4.0 / 3.0; + + double rho13 = pow(((1.0 + zeta) * rho) , third); + double exup = f * alpha * rho13; + vxup = p43 * f * alpha * rho13; + rho13 = pow(((1.0 - zeta) * rho) , third); + double exdw = f * alpha * rho13; + vxdw = p43 * f * alpha * rho13; + ex = 0.50 * ((1.0 + zeta) * exup + (1.0 - zeta) * exdw); + + return; +} + +// Slater exchange with alpha=2/3, spin-polarized case +void XC_Functional::slater1_spin( const double &rho, const double &zeta, double &ex, double &vxup, double &vxdw) +{ + const double f = - 1.107838149573033610; + const double alpha = 1.00; + const double third = 1.0 / 3.0; + const double p43 = 4.0 / 3.0; + // f = -9/8*(3/pi)^(1/3) + + double rho13 = pow(((1.0 + zeta) * rho) , third); + double exup = f * alpha * rho13; + vxup = p43 * f * alpha * rho13; + rho13 = pow(((1.0 - zeta) * rho) , third); + double exdw = f * alpha * rho13; + vxdw = p43 * f * alpha * rho13; + ex = 0.50 * ((1.0 + zeta) * exup + (1.0 - zeta) * exdw); + + return; +} // end subroutine slater1_spin + +// Slater exchange with alpha=2/3, relativistic exchange case +void XC_Functional::slater_rxc_spin( const double &rho, const double &z, + double &ex, double &vxup, double &vxdw) +{ + if (rho <= 0.0) + { + ex = vxup = vxdw = 0.0; + return; + } + + const double pi = 3.141592653589790; + + const double trd = 1.0 / 3.0; + const double ftrd = 4.0 / 3.0; + double tftm = pow(2.0, ftrd) - 2; + double a0 = pow((4 / (9 * pi)), trd); + + double alp = 2 * trd; + + double fz = (pow((1 + z), ftrd) + pow((1 - z), ftrd) - 2) / tftm; + double fzp = ftrd * (pow((1 + z), trd) - pow((1 - z), trd)) / tftm; + + double rs = pow((3 / (4 * pi * rho)), trd); + double vxp = -3 * alp / (2 * pi * a0 * rs); + double exp = 3 * vxp / 4; + + double beta = 0.014 / rs; + double sb = sqrt(1 + beta * beta); + double alb = log(beta + sb); + vxp = vxp * (-0.5 + 1.5 * alb / (beta * sb)); + exp = exp * (1.0- 1.5*( (beta*sb-alb) / (beta*beta) ) + * 1.5*( (beta*sb-alb) / (beta*beta) )); + + double x = (beta * sb - alb) / (beta * beta); + + exp = exp * (1.0 - 1.5 * x * x); + + double vxf = pow(2.0, trd) * vxp; + + double exf = pow(2.0, trd) * exp; + + vxup = vxp + fz * (vxf - vxp) + (1 - z) * fzp * (exf - exp); + + vxdw = vxp + fz * (vxf - vxp) - (1 + z) * fzp * (exf - exp); + + ex = exp + fz * (exf - exp); + + return; +} diff --git a/source/module_xc/xc_funct_hcth.cpp b/source/module_xc/xc_funct_hcth.cpp new file mode 100644 index 00000000000..37c92418f82 --- /dev/null +++ b/source/module_xc/xc_funct_hcth.cpp @@ -0,0 +1,147 @@ +// This file contains realizations of the HCTH GGA functional + +#include "xc_functional.h" + +void XC_Functional::hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x) +{ + // =============================================================== + // HCTH/120, JCP 109, p. 6264 (1998) + // Parameters set-up after N.L. Doltsisnis & M. Sprik (1999) + // Present release: Mauro Boero, Tsukuba, 11/05/2004 + //-------------------------------------------------------------------------- + // rhoa = rhob = 0.5 * rho + // grho is the SQUARE of the gradient of rho// --> gr=sqrt(grho) + // sx : total exchange correlation energy at point r + // v1x : d(sx)/drho (eq. dfdra = dfdrb in original) + // v2x : 1/gr*d(sx)/d(gr) (eq. 0.5 * dfdza = 0.5 * dfdzb in original) + //-------------------------------------------------------------------------- + // USE kinds + // implicit none + // real(kind=DP) :: rho, grho, sx, v1x, v2x + + // parameter : + const double pi = 3.14159265358979323846; + double o3 = 1.00 / 3.00; + double o34 = 4.00 / 3.00; + double fr83 = 8.0 / 3.0; + //double cg0[6], cg1[6], caa[6], cab[6], cx[6]; + double cg0[7], cg1[7], caa[7], cab[7], cx[7]; //mohan modify 2007-10-13 + double r3q2, r3pi, gr, rho_o3, rho_o34, xa, xa2, ra, rab, + dra_drho, drab_drho, g, dg, era1, dera1_dra, erab0, derab0_drab, + ex, dex_drho, uaa, uab, ux, ffaa, ffab, dffaa_drho, dffab_drho, + denaa, denab, denx, f83rho, bygr, gaa, gab, gx, taa, tab, txx, + dgaa_drho, dgab_drho, dgx_drho, dgaa_dgr, dgab_dgr, dgx_dgr; + + r3q2 = std::pow(2.0, (-o3)); + r3pi = std::pow((3.0 / pi), o3); + //.....coefficients for pwf correlation...................................... + cg0[1] = 0.0310910; + cg0[2] = 0.2137000; + cg0[3] = 7.5957000; + cg0[4] = 3.5876000; + cg0[5] = 1.6382000; + cg0[6] = 0.4929400; + + cg1[1] = 0.0155450; + cg1[2] = 0.2054800; + cg1[3] = 14.1189000; + cg1[4] = 6.1977000; + cg1[5] = 3.3662000; + cg1[6] = 0.6251700; + //......hcth-19-4..................................... + caa[1] = 0.489508e+00; + caa[2] = -0.260699e+00; + caa[3] = 0.432917e+00; + caa[4] = -0.199247e+01; + caa[5] = 0.248531e+01; + caa[6] = 0.200000e+00; + + cab[1] = 0.514730e+00; + cab[2] = 0.692982e+01; + cab[3] = -0.247073e+02; + cab[4] = 0.231098e+02; + cab[5] = -0.113234e+02; + cab[6] = 0.006000e+00; + + cx[1] = 0.109163e+01; + cx[2] = -0.747215e+00; + cx[3] = 0.507833e+01; + cx[4] = -0.410746e+01; + cx[5] = 0.117173e+01; + cx[6] = 0.004000e+00; + //........................................................................... + gr = sqrt(grho); + rho_o3 = pow(rho, (o3)); + rho_o34 = pow(rho, (o34)); + xa = 1.259921050 * gr / rho_o34; + xa2 = xa * xa; + ra = 0.7815926420 / rho_o3; + rab = r3q2 * ra; + dra_drho = -0.2605308810 / rho_o34; + drab_drho = r3q2 * dra_drho; + XC_Functional::pwcorr(ra, cg1, g, dg); + era1 = g; + dera1_dra = dg; + XC_Functional::pwcorr(rab, cg0, g, dg); + erab0 = g; + derab0_drab = dg; + ex = -0.750 * r3pi * rho_o34; + dex_drho = -r3pi * rho_o3; + uaa = caa[6] * xa2; + uaa = uaa / (1.00 + uaa); + uab = cab[6] * xa2; + uab = uab / (1.00 + uab); + ux = cx[6] * xa2; + ux = ux / (1.00 + ux); + ffaa = rho * era1; + ffab = rho * erab0 - ffaa; + dffaa_drho = era1 + rho * dera1_dra * dra_drho; + dffab_drho = erab0 + rho * derab0_drab * drab_drho - dffaa_drho; + // mb-> i-loop removed + denaa = 1.0 / (1.00 + caa[6] * xa2); + denab = 1.0 / (1.00 + cab[6] * xa2); + denx = 1.0 / (1.00 + cx[6] * xa2); + f83rho = fr83 / rho; + bygr = 2.00 / gr; + gaa = caa[1] + uaa * (caa[2] + uaa * (caa[3] + uaa * (caa[4] + uaa * caa[5]))); + gab = cab[1] + uab * (cab[2] + uab * (cab[3] + uab * (cab[4] + uab * cab[5]))); + gx = cx[1] + ux * (cx[2] + ux * (cx[3] + ux * (cx[4] + ux * cx[5]))); + taa = denaa * uaa * (caa[2] + uaa * (2.0 * caa[3] + uaa + * (3.0 * caa[4] + uaa * 4.0 * caa[5]))); + tab = denab * uab * (cab[2] + uab * (2.0 * cab[3] + uab + * (3.0 * cab[4] + uab * 4.0 * cab[5]))); + txx = denx * ux * (cx[2] + ux * (2.0 * cx[3] + ux + * (3.0 * cx[4] + ux * 4.0 * cx[5]))); + dgaa_drho = -f83rho * taa; + dgab_drho = -f83rho * tab; + dgx_drho = -f83rho * txx; + dgaa_dgr = bygr * taa; + dgab_dgr = bygr * tab; + dgx_dgr = bygr * txx; + // mb + sx = ex * gx + ffaa * gaa + ffab * gab; + v1x = dex_drho * gx + ex * dgx_drho + + dffaa_drho * gaa + ffaa * dgaa_drho + + dffab_drho * gab + ffab * dgab_drho; + v2x = (ex * dgx_dgr + ffaa * dgaa_dgr + ffab * dgab_dgr) / gr; + return; +} //end subroutine hcth + +void XC_Functional::pwcorr(const double r, const double c[], double &g, double &dg) +{ + // USE kinds + // implicit none + // real(kind=DP) :: r, g, dg, c(6) + double r12, r32, r2, rb, drb, sb; + + r12 = sqrt(r); + r32 = r * r12; + r2 = r * r; + rb = c[3] * r12 + c[4] * r + c[5] * r32 + c[6] * r2; //c[i] i=0--5; + sb = 1.00 + 1.00 / (2.00 * c[1] * rb); + g = -2.00 * c[1] * (1.00 + c[2] * r) * log(sb); + drb = c[3] / (2.00 * r12) + c[4] + 1.50 * c[5] * r12 + 2.00 * c[6] * r; + dg = (1.00 + c[2] * r) * drb / (rb * rb * sb) - 2.00 * c[1] * c[2] * log(sb); + + return; +} //end subroutine pwcorr \ No newline at end of file diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index 6a004513413..c7a19119ad7 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -56,13 +56,6 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) func_type = 2; use_libxc = false; } - else if ( xc_func == "PBEsol") //PBXsol+PBCsol - { - func_id.push_back(XC_GGA_X_PBE_SOL); - func_id.push_back(XC_GGA_C_PBE_SOL); - func_type = 2; - use_libxc = false; - } else if ( xc_func == "WC") //WC+PBC { func_id.push_back(XC_GGA_X_WC); @@ -188,7 +181,7 @@ void XC_Functional::xc(const double &rho, double &exc, double &vxc) switch( id ) { // Exchange functionals containing slater exchange - case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: case XC_GGA_X_PBE_SOL: + case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X XC_Functional::slater(rs, e, v);break; @@ -201,8 +194,8 @@ void XC_Functional::xc(const double &rho, double &exc, double &vxc) break; // Correlation functionals containing PW correlation - case XC_GGA_C_PBE: case XC_GGA_C_PBE_SOL: case XC_GGA_C_PW91: case XC_LDA_C_PW: - // PBC,PBCsol + case XC_GGA_C_PBE: case XC_GGA_C_PW91: case XC_LDA_C_PW: + // PBC,PW91,PWLDA XC_Functional::pw(rs, 0, e, v);break; // Correlation functionals containing PZ correlation @@ -278,7 +271,7 @@ void XC_Functional::xc_spin(const double &rho, const double &zeta, switch( id ) { // Exchange functionals containing slater exchange - case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: case XC_GGA_X_PBE_SOL: + case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X XC_Functional::slater_spin(rho, zeta, e, vup, vdw); break; @@ -296,7 +289,7 @@ void XC_Functional::xc_spin(const double &rho, const double &zeta, XC_Functional::pz_spin(rs, zeta, e, vup, vdw); break; // Correlation functionals containing PW correlationtests/integrate/101_PW_OU_pseudopot - case XC_GGA_C_PBE: case XC_GGA_C_PBE_SOL: + case XC_GGA_C_PBE: // PBC,PBCsol XC_Functional::pw_spin(rs, zeta, e, vup, vdw); break; @@ -318,734 +311,6 @@ void XC_Functional::xc_spin(const double &rho, const double &zeta, return; } -//Slater exchange with alpha=2/3 -void XC_Functional::slater(const double &rs, double &ex, double &vx) -{ - // f = -9/8*(3/2pi)^(2/3) - const double f = -0.687247939924714e0; - const double alpha = 2.00 / 3.00; - ex = f * alpha / rs; - vx = 4.0 / 3.0 * f * alpha / rs; - return; -} - -// Slater exchange with alpha=2/3, spin-polarized case -void XC_Functional::slater_spin( const double &rho, const double &zeta, - double &ex, double &vxup, double &vxdw) -{ - const double f = - 1.107838149573033610; - const double alpha = 2.00 / 3.00; - // f = -9/8*(3/pi)^(1/3) - const double third = 1.0 / 3.0; - const double p43 = 4.0 / 3.0; - - double rho13 = pow(((1.0 + zeta) * rho) , third); - double exup = f * alpha * rho13; - vxup = p43 * f * alpha * rho13; - rho13 = pow(((1.0 - zeta) * rho) , third); - double exdw = f * alpha * rho13; - vxdw = p43 * f * alpha * rho13; - ex = 0.50 * ((1.0 + zeta) * exup + (1.0 - zeta) * exdw); - - return; -} - - -//Slater exchange with alpha=1, corresponding to -1.374/r_s Ry -//used to recover old results -void XC_Functional::slater1(const double &rs, double &ex, double &vx) -{ - const double f = -0.687247939924714e0; - const double alpha = 1.0; - ex = f * alpha / rs; - vx = 4.0 / 3.0 * f * alpha / rs; - return; -} - - -// Slater exchange with alpha=2/3, spin-polarized case -void XC_Functional::slater1_spin( const double &rho, const double &zeta, double &ex, double &vxup, double &vxdw) -{ - const double f = - 1.107838149573033610; - const double alpha = 1.00; - const double third = 1.0 / 3.0; - const double p43 = 4.0 / 3.0; - // f = -9/8*(3/pi)^(1/3) - - double rho13 = pow(((1.0 + zeta) * rho) , third); - double exup = f * alpha * rho13; - vxup = p43 * f * alpha * rho13; - rho13 = pow(((1.0 - zeta) * rho) , third); - double exdw = f * alpha * rho13; - vxdw = p43 * f * alpha * rho13; - ex = 0.50 * ((1.0 + zeta) * exup + (1.0 - zeta) * exdw); - - return; -} // end subroutine slater1_spin - - -// Slater exchange with alpha=2/3 and Relativistic exchange -void XC_Functional::slater_rxc(const double &rs, double &ex, double &vx) -{ - static const double pi = 3.14159265358979; - const double trd = 1.0 / 3.0; - //const double ftrd = 4.0 / 3.0; - //const double tftm = pow(2.0, ftrd) - 2.0; - const double a0 = pow((4.0 / (9.0 * pi)), trd); - // X-alpha parameter: - const double alp = 2 * trd; - - double vxp = -3 * alp / (2 * pi * a0 * rs); - double exp = 3 * vxp / 4; - const double beta = 0.014 / rs; - const double sb = sqrt(1 + beta * beta); - const double alb = log(beta + sb); - vxp = vxp * (-0.5 + 1.5 * alb / (beta * sb)); - double x = (beta * sb - alb) / (beta * beta); - exp = exp * (1.0 - 1.5 * x * x); - vx = vxp; - ex = exp; - return; -} - -// Slater exchange with alpha=2/3, relativistic exchange case -void XC_Functional::slater_rxc_spin( const double &rho, const double &z, - double &ex, double &vxup, double &vxdw) -{ - if (rho <= 0.0) - { - ex = vxup = vxdw = 0.0; - return; - } - - const double pi = 3.141592653589790; - - const double trd = 1.0 / 3.0; - const double ftrd = 4.0 / 3.0; - double tftm = pow(2.0, ftrd) - 2; - double a0 = pow((4 / (9 * pi)), trd); - - double alp = 2 * trd; - - double fz = (pow((1 + z), ftrd) + pow((1 - z), ftrd) - 2) / tftm; - double fzp = ftrd * (pow((1 + z), trd) - pow((1 - z), trd)) / tftm; - - double rs = pow((3 / (4 * pi * rho)), trd); - double vxp = -3 * alp / (2 * pi * a0 * rs); - double exp = 3 * vxp / 4; - - double beta = 0.014 / rs; - double sb = sqrt(1 + beta * beta); - double alb = log(beta + sb); - vxp = vxp * (-0.5 + 1.5 * alb / (beta * sb)); - exp = exp * (1.0- 1.5*( (beta*sb-alb) / (beta*beta) ) - * 1.5*( (beta*sb-alb) / (beta*beta) )); - - double x = (beta * sb - alb) / (beta * beta); - - exp = exp * (1.0 - 1.5 * x * x); - - double vxf = pow(2.0, trd) * vxp; - - double exf = pow(2.0, trd) * exp; - - vxup = vxp + fz * (vxf - vxp) + (1 - z) * fzp * (exf - exp); - - vxdw = vxp + fz * (vxf - vxp) - (1 + z) * fzp * (exf - exp); - - ex = exp + fz * (exf - exp); - - return; -} - -//LDA parameterization form Monte Carlo data -//iflag=0: J.P. Perdew and A. Zunger, PRB 23, 5048 (1981) -//iflag=1: G. Ortiz and P. Ballone, PRB 50, 1391 (1994) -void XC_Functional::pz(const double &rs, const int &iflag, double &ec, double &vc) -{ -// ModuleBase::TITLE("XC_Functional","pz"); - const double a[2] = {0.0311, 0.031091}; - const double b[2] = { -0.048, -0.046644 }; - const double c[2] = { 0.0020, 0.00419 }; - const double d[2] = { -0.0116, -0.00983 }; - const double gc[2] = { -0.1423, -0.103756}; - const double b1[2] = { 1.0529, 0.56371 }; - const double b2[2] = { 0.3334, 0.27358 }; - - if (rs < 1.0) - { - // high density formula - const double lnrs = log(rs); - ec = a [iflag] * lnrs + b [iflag] + c [iflag] * rs * lnrs + d [iflag] * rs; - vc = a [iflag] * lnrs + (b [iflag] - a [iflag] / 3.0) + 2.0 / - 3.0 * c [iflag] * rs * lnrs + (2.0 * d [iflag] - c [iflag]) - / 3.0 * rs; - } - else - { - // interpolation formula - const double rs12 = sqrt(rs); - const double ox = 1.0 + b1 [iflag] * rs12 + b2 [iflag] * rs; - const double dox = 1.0 + 7.0 / 6.0 * b1 [iflag] * rs12 + 4.0 / 3.0 * - b2 [iflag] * rs; - ec = gc [iflag] / ox; - vc = ec * dox / ox; - } - return; -} - -// J.P. Perdew and Y. Wang, PRB 45, 13244 (1992) -void XC_Functional::pz_spin( const double &rs, const double &zeta, - double &ec, double &vcup, double &vcdw) -{ -// ModuleBase::TITLE("XC_Functional","pz_spin"); - double ecu, vcu, ecp, vcp ; - static const double p43 = 4.00 / 3.0; - static const double third = 1.0 / 3.0; - - // unpolarized part (Perdew-Zunger formula) - XC_Functional::pz(rs, 0, ecu, vcu); - - // polarization contribution - XC_Functional::pz_polarized(rs, ecp, vcp); - - double fz = (pow((1.00 + zeta) , p43) + pow((1.0 - zeta) , p43) - 2.0) / - (pow(2.0 , p43) - 2.0); - double dfz = p43 * (pow((1.00 + zeta) , third) - pow((1.0 - zeta) , third)) - / (pow(2.0, p43) - 2.0); - - //correlation energy - ec = ecu + fz * (ecp - ecu); - - // spin up correlation potential - vcup = vcu + fz * (vcp - vcu) + (ecp - ecu) * dfz * (1.0 - zeta); - // spin down correlation potential - vcdw = vcu + fz * (vcp - vcu) + (ecp - ecu) * dfz * (- 1.0 - zeta); - - return; -} - -// J.P. Perdew and A. Zunger, PRB 23, 5048 (1981) -void XC_Functional::pz_polarized( const double &rs, double &ec, double &vc) -{ -// ModuleBase::TITLE("XC_Functional","pz_polarized"); - static const double a = 0.015550; - static const double b = -0.02690; - static const double c = 0.00070; - static const double d = -0.00480; - static const double gc = -0.08430; - static const double b1 = 1.39810; - static const double b2 = 0.26110; - - if (rs < 1.00) - { - double lnrs = log(rs); - ec = a * lnrs + b + c * rs * lnrs + d * rs; - vc = a * lnrs + (b - a / 3.0) + 2.0 / 3.0 * c * rs * lnrs + - (2.0 * d - c) / 3.0 * rs; - } - else - { - // interpolation formula - double rs12 = sqrt(rs); - double ox = 1.0 + b1 * rs12 + b2 * rs; - double dox = 1.0 + 7.0 / 6.0 * b1 * rs12 + 4.0 / 3.0 * b2 * rs; - ec = gc / ox; - vc = ec * dox / ox; - } - return; -} - -// S.H. Vosko, L. Wilk, and M. Nusair, Can. J. Phys. 58, 1200 (1980) -void XC_Functional::vwn(const double &rs, double &ec, double &vc) -{ - const double a = 0.0310907; - const double b = 3.72744; - const double c = 12.9352; - const double x0 = -0.10498; - double q, f1, f2, f3, rs12, fx, qx, tx, tt; - - q = sqrt(4.0 * c - b * b); - f1 = 2.0 * b / q; - f2 = b * x0 / (x0 * x0 + b * x0 + c); - f3 = 2.0 * (2.0 * x0 + b) / q; - rs12 = sqrt(rs); - fx = rs + b * rs12 + c; - qx = atan(q / (2.0 * rs12 + b)); - - double x; - x = (rs12 - x0); - ec = a * (log(rs / fx) + f1 * qx - f2 * (log((x * x) / - fx) + f3 * qx)); - tx = 2.0 * rs12 + b; - tt = tx * tx + q * q; - - vc = ec - rs12 * a / 6.0 * (2.0 / rs12 - tx / fx - 4.0 * b / - tt - f2 * (2.0 / (rs12 - x0) - tx / fx - 4.0 * (2.0 * x0 + b)/ tt)); - - return; -} - -// C. Lee, W. Yang, and R.G. Parr, PRB 37, 785 (1988) -// LDA part only -void XC_Functional::lyp(const double &rs, double &ec, double &vc) -{ - const double a = 0.04918e0; - const double b = 0.1320 * 2.87123400018819108e0; - // pi43 = (4pi/3)^(1/3) - const double pi43 = 1.61199195401647e0; - const double c = 0.2533e0 * pi43; - const double d = 0.349e0 * pi43; - double ecrs, ox; - - ecrs = b * exp(- c * rs); - ox = 1.0 / (1.0 + d * rs); - ec = - a * ox * (1.0 + ecrs); - vc = ec - rs / 3.0 * a * ox * (d * ox + ecrs * (d * ox + c)); - - return; -} - -void XC_Functional::pw(const double &rs, const int &iflag, double &ec, double &vc) -{ - const double a = 0.0310910; - const double b1 = 7.59570; - const double b2 = 3.58760; - const double c0 = a; - const double c1 = 0.0466440; - const double c2 = 0.006640; - const double c3 = 0.010430; - const double d0 = 0.43350; - const double d1 = 1.44080; - double lnrs, rs12, rs32, rs2, om, dom, olog; - double a1[2] = { 0.213700, 0.0264810 }; - double b3[2] = { 1.63820, -0.466470 }; - double b4[2] = { 0.492940, 0.133540 }; - - // high- and low-density formulae implemented but not used in PW case - // (reason: inconsistencies in PBE/PW91 functionals) - - if (rs < 1 && iflag == 1) - { - // high density formula - lnrs = log(rs); - ec = c0 * lnrs - c1 + c2 * rs * lnrs - c3 * rs; - vc = c0 * lnrs - (c1 + c0 / 3.0) + 2.0 / 3.0 * c2 * rs * - lnrs - (2.0 * c3 + c2) / 3.0 * rs; - } - else if (rs > 100.0 && iflag == 1) - { - // low density formula - ec = - d0 / rs + d1 / pow(rs, 1.50); - vc = - 4.0 / 3.0 * d0 / rs + 1.50 * d1 / pow(rs, 1.50); - } - else - { - // interpolation formula - rs12 = sqrt(rs); - rs32 = rs * rs12; - rs2 = rs * rs; - om = 2.0 * a * (b1 * rs12 + b2 * rs + b3 [iflag] * rs32 + b4 [ - iflag] * rs2); - dom = 2.0 * a * (0.50 * b1 * rs12 + b2 * rs + 1.50 * b3 [ - iflag] * rs32 + 2.0 * b4 [iflag] * rs2); - olog = log(1.0 + 1.0 / om); - ec = - 2.0 * a * (1.0 + a1 [iflag] * rs) * olog; - vc = - 2.0 * a * (1.0 + 2.0 / 3.0 * a1 [iflag] * rs) - * olog - 2.0 / 3.0 * a * (1.0 + a1 [iflag] * rs) * dom / - (om * (om + 1.0)); - } - return; -} - -// J.P. Perdew and Y. Wang, PRB 45, 13244 (1992) -void XC_Functional::pw_spin( const double &rs, const double &zeta, - double &ec, double &vcup, double &vcdw) -{ - const double a = 0.0310910; - const double a1 = 0.213700; - const double b1 = 7.59570; - const double b2 = 3.58760; - const double b3 = 1.63820; - const double b4 = 0.492940; - //const double c0 = a; - //const double c1 = 0.0466440; - //const double c2 = 0.006640; - //const double c3 = 0.010430; - //const double d0 = 0.43350; - //const double d1 = 1.44080; - // polarized parameters - const double ap = 0.0155450; - const double a1p = 0.205480; - const double b1p = 14.11890; - const double b2p = 6.19770; - const double b3p = 3.36620; - const double b4p = 0.625170; - //const double c0p = ap; - //const double c1p = 0.0255990; - //const double c2p = 0.003190; - //const double c3p = 0.003840; - //const double d0p = 0.32870; - //const double d1p = 1.76970; - // antiferro - const double aa = 0.0168870; - const double a1a = 0.111250; - const double b1a = 10.3570; - const double b2a = 3.62310; - const double b3a = 0.880260; - const double b4a = 0.496710; - //const double c0a = aa; - //const double c1a = 0.0354750; - //const double c2a = 0.001880; - //const double c3a = 0.005210; - //const double d0a = 0.22400; - //const double d1a = 0.39690; - - const double fz0 = 1.7099210; - double rs12, rs32, rs2, zeta2, zeta3, zeta4, fz, dfz; - double om, dom, olog, epwc, vpwc; - double omp, domp, ologp, epwcp, vpwcp; - double oma, doma, ologa, alpha, vpwca; - - // if(rs.lt.0.5d0) then - // high density formula (not implemented) - // - // else if(rs.gt.100.d0) then - // low density formula (not implemented) - // - // else - // interpolation formula - zeta2 = zeta * zeta; - zeta3 = zeta2 * zeta; - zeta4 = zeta3 * zeta; - rs12 = sqrt(rs); - rs32 = rs * rs12; - rs2 = rs * rs; - // unpolarised - om = 2.0 * a * (b1 * rs12 + b2 * rs + b3 * rs32 + b4 * rs2); - dom = 2.0 * a * (0.50 * b1 * rs12 + b2 * rs + 1.50 * b3 * rs32 - + 2.0 * b4 * rs2); - olog = log(1.0 + 1.00 / om); - epwc = - 2.0 * a * (1.0 + a1 * rs) * olog; - vpwc = - 2.0 * a * (1.0 + 2.0 / 3.0 * a1 * rs) * olog - 2.0 / - 3.0 * a * (1.0 + a1 * rs) * dom / (om * (om + 1.0)); - // polarized - omp = 2.0 * ap * (b1p * rs12 + b2p * rs + b3p * rs32 + b4p * rs2); - domp = 2.0 * ap * (0.50 * b1p * rs12 + b2p * rs + 1.50 * b3p * - rs32 + 2.0 * b4p * rs2); - ologp = log(1.0 + 1.00 / omp); - epwcp = - 2.0 * ap * (1.0 + a1p * rs) * ologp; - vpwcp = - 2.0 * ap * (1.0 + 2.0 / 3.0 * a1p * rs) * ologp - - 2.0 / 3.0 * ap * (1.0 + a1p * rs) * domp / (omp * (omp + 1.0)); - // antiferro - oma = 2.0 * aa * (b1a * rs12 + b2a * rs + b3a * rs32 + b4a * rs2); - doma = 2.0 * aa * (0.50 * b1a * rs12 + b2a * rs + 1.50 * b3a * - rs32 + 2.0 * b4a * rs2); - ologa = log(1.0 + 1.00 / oma); - alpha = 2.0 * aa * (1.0 + a1a * rs) * ologa; - vpwca = + 2.0 * aa * (1.0 + 2.0 / 3.0 * a1a * rs) * ologa + - 2.0 / 3.0 * aa * (1.0 + a1a * rs) * doma / (oma * (oma + 1.0)); - - fz = (pow((1.0 + zeta) , (4.0 / 3.0)) + pow((1.0 - zeta) , (4.0 / - 3.0)) - 2.0) / (pow(2.0, (4.0 / 3.0)) - 2.0); - dfz = (pow((1.0 + zeta) , (1.0 / 3.0)) - pow((1.0 - zeta) , (1.0 / - 3.0))) * 4.0 / (3.0 * (pow(2.0 , (4.0 / 3.0)) - 2.0)); - - ec = epwc + alpha * fz * (1.0 - zeta4) / fz0 + (epwcp - epwc) - * fz * zeta4; - - vcup = vpwc + vpwca * fz * (1.0 - zeta4) / fz0 - + (vpwcp - vpwc) * fz * zeta4 - + (alpha / fz0 * (dfz * (1.0 - zeta4) - 4.0 * fz * zeta3) - + (epwcp - epwc) * (dfz * zeta4 + 4.0 * fz * zeta3)) * (1.0 - zeta); - - vcdw = vpwc + vpwca * fz * (1.0 - zeta4) / fz0 - + (vpwcp - vpwc) * fz * zeta4 - - (alpha / fz0 * (dfz * (1.0 - zeta4) - 4.0 * fz * zeta3) - + (epwcp - epwc) * (dfz * zeta4 + 4.0 * fz * zeta3)) * (1.0 + zeta); - return; -} - -void XC_Functional::wigner( const double &rs, double &ec, double &vc) -{ - const double pi34 = 0.6203504908994e0; - // pi34=(3/4pi)^(1/3), rho13=rho^(1/3) - - double rho13 = pi34 / rs; - double x = 1.0 + 12.570 * rho13; - vc = - rho13 * ((0.9436560 + 8.89630 * rho13) / (x * x)); - ec = - 0.7380 * rho13 * (0.9590 / (1.0 + 12.570 * rho13)); - return; -} - -// L. Hedin and B.I. Lundqvist, J. Phys. C 4, 2064 (1971) -void XC_Functional::hl( const double &rs, double &ec, double &vc) -{ - double a, x; - a = log(1.00 + 21.0 / rs); - x = rs / 21.00; - ec = a + (pow(x, 3) * a - x * x) + x / 2.0 - 1.00 / 3.00; - ec = - 0.02250 * ec; - vc = - 0.02250 * a; - return; -} - -// O. Gunnarsson and B. I. Lundqvist, PRB 13, 4274 (1976) -void XC_Functional::gl( const double &rs, double &ec, double &vc) -{ - const double c = 0.0333; - const double r = 11.4; - // c=0.0203, r=15.9 for the paramagnetic case - double x = rs / r; - vc = - c * log(1.0 + 1.0 / x); - ec = - c * ((1.0 + pow(x, 3)) * log(1.0 + 1.0 / x) - 1.00 / - 3.00 + x * (0.50 - x)); - return; -} - - -void XC_Functional::pbex(const double &rho, const double &grho, const int &iflag, -double &sx, double &v1x, double &v2x) -{ - // PBE exchange (without Slater exchange): - // iflag=0 J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996) - // iflag=1 "revised' PBE: Y. Zhang et al., PRL 80, 890 (1998) - - // input: charge and squared gradient - // output: energy - // output: potential - // (3*pi2*|rho|)^(1/3) - // |grho| - // |grho|/(2*kf*|rho|) - // s^2 - // n*ds/dn - // n*ds/d(gn) - // exchange energy LDA part - // exchange energy gradient part - - // numerical coefficients (NB: c2=(3 pi^2)^(1/3) ) - const double third = 1.0 / 3.0; - const double pi = 3.14159265358979323846; - const double c1 = 0.750 / pi; - const double c2 = 3.0936677262801360; - const double c5 = 4.0 * third; - // parameters of the functional - double k[3] = { 0.8040, 1.24500, 0.8040 }; - const double mu[3] = {0.2195149727645171, 0.2195149727645171, 0.12345679012345679} ;//modified by zhengdy, to ensure the same parameters with another dft code. - - const double agrho = sqrt(grho); - const double kf = c2 * pow(rho, third); - const double dsg = 0.50 / kf; - const double s1 = agrho * dsg / rho; - const double s2 = s1 * s1; - const double ds = - c5 * s1; - - // Energy - const double f1 = s2 * mu[iflag] / k [iflag]; - const double f2 = 1.0 + f1; - const double f3 = k [iflag] / f2; - const double fx = k [iflag] - f3; - const double exunif = - c1 * kf; - sx = exunif * fx; - - // Potential - const double dxunif = exunif * third; - const double dfx1 = f2 * f2; - const double dfx = 2.0 * mu[iflag] * s1 / dfx1; - - v1x = sx + dxunif * fx + exunif * dfx * ds; - v2x = exunif * dfx * dsg / agrho; - sx = sx * rho; - - return; -} - -void XC_Functional::pwcorr(const double r, const double c[], double &g, double &dg) -{ - // USE kinds - // implicit none - // real(kind=DP) :: r, g, dg, c(6) - double r12, r32, r2, rb, drb, sb; - - r12 = sqrt(r); - r32 = r * r12; - r2 = r * r; - rb = c[3] * r12 + c[4] * r + c[5] * r32 + c[6] * r2; //c[i] i=0--5; - sb = 1.00 + 1.00 / (2.00 * c[1] * rb); - g = -2.00 * c[1] * (1.00 + c[2] * r) * log(sb); - drb = c[3] / (2.00 * r12) + c[4] + 1.50 * c[5] * r12 + 2.00 * c[6] * r; - dg = (1.00 + c[2] * r) * drb / (rb * rb * sb) - 2.00 * c[1] * c[2] * log(sb); - - return; -} //end subroutine pwcorr - -void XC_Functional::hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x) -{ - // =============================================================== - // HCTH/120, JCP 109, p. 6264 (1998) - // Parameters set-up after N.L. Doltsisnis & M. Sprik (1999) - // Present release: Mauro Boero, Tsukuba, 11/05/2004 - //-------------------------------------------------------------------------- - // rhoa = rhob = 0.5 * rho - // grho is the SQUARE of the gradient of rho// --> gr=sqrt(grho) - // sx : total exchange correlation energy at point r - // v1x : d(sx)/drho (eq. dfdra = dfdrb in original) - // v2x : 1/gr*d(sx)/d(gr) (eq. 0.5 * dfdza = 0.5 * dfdzb in original) - //-------------------------------------------------------------------------- - // USE kinds - // implicit none - // real(kind=DP) :: rho, grho, sx, v1x, v2x - - // parameter : - double o3 = 1.00 / 3.00; - double o34 = 4.00 / 3.00; - double fr83 = 8.0 / 3.0; - //double cg0[6], cg1[6], caa[6], cab[6], cx[6]; - double cg0[7], cg1[7], caa[7], cab[7], cx[7]; //mohan modify 2007-10-13 - double r3q2, r3pi, gr, rho_o3, rho_o34, xa, xa2, ra, rab, - dra_drho, drab_drho, g, dg, era1, dera1_dra, erab0, derab0_drab, - ex, dex_drho, uaa, uab, ux, ffaa, ffab, dffaa_drho, dffab_drho, - denaa, denab, denx, f83rho, bygr, gaa, gab, gx, taa, tab, txx, - dgaa_drho, dgab_drho, dgx_drho, dgaa_dgr, dgab_dgr, dgx_dgr; - - r3q2 = std::pow(2.0, (-o3)); - r3pi = std::pow((3.0 / ModuleBase::PI), o3); - //.....coefficients for pwf correlation...................................... - cg0[1] = 0.0310910; - cg0[2] = 0.2137000; - cg0[3] = 7.5957000; - cg0[4] = 3.5876000; - cg0[5] = 1.6382000; - cg0[6] = 0.4929400; - - cg1[1] = 0.0155450; - cg1[2] = 0.2054800; - cg1[3] = 14.1189000; - cg1[4] = 6.1977000; - cg1[5] = 3.3662000; - cg1[6] = 0.6251700; - //......hcth-19-4..................................... - caa[1] = 0.489508e+00; - caa[2] = -0.260699e+00; - caa[3] = 0.432917e+00; - caa[4] = -0.199247e+01; - caa[5] = 0.248531e+01; - caa[6] = 0.200000e+00; - - cab[1] = 0.514730e+00; - cab[2] = 0.692982e+01; - cab[3] = -0.247073e+02; - cab[4] = 0.231098e+02; - cab[5] = -0.113234e+02; - cab[6] = 0.006000e+00; - - cx[1] = 0.109163e+01; - cx[2] = -0.747215e+00; - cx[3] = 0.507833e+01; - cx[4] = -0.410746e+01; - cx[5] = 0.117173e+01; - cx[6] = 0.004000e+00; - //........................................................................... - gr = sqrt(grho); - rho_o3 = pow(rho, (o3)); - rho_o34 = pow(rho, (o34)); - xa = 1.259921050 * gr / rho_o34; - xa2 = xa * xa; - ra = 0.7815926420 / rho_o3; - rab = r3q2 * ra; - dra_drho = -0.2605308810 / rho_o34; - drab_drho = r3q2 * dra_drho; - XC_Functional::pwcorr(ra, cg1, g, dg); - era1 = g; - dera1_dra = dg; - XC_Functional::pwcorr(rab, cg0, g, dg); - erab0 = g; - derab0_drab = dg; - ex = -0.750 * r3pi * rho_o34; - dex_drho = -r3pi * rho_o3; - uaa = caa[6] * xa2; - uaa = uaa / (1.00 + uaa); - uab = cab[6] * xa2; - uab = uab / (1.00 + uab); - ux = cx[6] * xa2; - ux = ux / (1.00 + ux); - ffaa = rho * era1; - ffab = rho * erab0 - ffaa; - dffaa_drho = era1 + rho * dera1_dra * dra_drho; - dffab_drho = erab0 + rho * derab0_drab * drab_drho - dffaa_drho; - // mb-> i-loop removed - denaa = 1.0 / (1.00 + caa[6] * xa2); - denab = 1.0 / (1.00 + cab[6] * xa2); - denx = 1.0 / (1.00 + cx[6] * xa2); - f83rho = fr83 / rho; - bygr = 2.00 / gr; - gaa = caa[1] + uaa * (caa[2] + uaa * (caa[3] + uaa * (caa[4] + uaa * caa[5]))); - gab = cab[1] + uab * (cab[2] + uab * (cab[3] + uab * (cab[4] + uab * cab[5]))); - gx = cx[1] + ux * (cx[2] + ux * (cx[3] + ux * (cx[4] + ux * cx[5]))); - taa = denaa * uaa * (caa[2] + uaa * (2.0 * caa[3] + uaa - * (3.0 * caa[4] + uaa * 4.0 * caa[5]))); - tab = denab * uab * (cab[2] + uab * (2.0 * cab[3] + uab - * (3.0 * cab[4] + uab * 4.0 * cab[5]))); - txx = denx * ux * (cx[2] + ux * (2.0 * cx[3] + ux - * (3.0 * cx[4] + ux * 4.0 * cx[5]))); - dgaa_drho = -f83rho * taa; - dgab_drho = -f83rho * tab; - dgx_drho = -f83rho * txx; - dgaa_dgr = bygr * taa; - dgab_dgr = bygr * tab; - dgx_dgr = bygr * txx; - // mb - sx = ex * gx + ffaa * gaa + ffab * gab; - v1x = dex_drho * gx + ex * dgx_drho - + dffaa_drho * gaa + ffaa * dgaa_drho - + dffab_drho * gab + ffab * dgab_drho; - v2x = (ex * dgx_dgr + ffaa * dgaa_dgr + ffab * dgab_dgr) / gr; - return; -} //end subroutine hcth - -void XC_Functional::pbec(const double &rho, const double &grho, const int &iflag, double &sc, double &v1c, double &v2c) -{ - // PBE correlation (without LDA part) - // iflag=0: J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996). - // iflag=1: J.P.Perdew et al., PRL 100, 136406 (2008). - const double ga = 0.0310906908696548950; - const double be[2] = {0.06672455060314922, 0.046}; - - const double third = 1.0 / 3.0; - const double pi34 = 0.62035049089940; - const double xkf = 1.9191582926775130; - const double xks = 1.1283791670955130; - - // pi34=(3/4pi)^(1/3), xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) - double ec, vc; - - const double rs = pi34 / pow(rho, third); - - XC_Functional::pw(rs, 0, ec, vc); - - const double kf = xkf / rs; - const double ks = xks * sqrt(kf); - const double t = sqrt(grho) / (2.0 * ks * rho); - const double expe = exp(- ec / ga); - const double af = be[iflag] / ga * (1.0 / (expe - 1.0)); - const double bf = expe * (vc - ec); - const double y = af * t * t; - const double xy = (1.0 + y) / (1.0 + y + y * y); - - const double x = 1.0 + y + y * y; - const double qy = y * y * (2.0 + y) / (x * x); - const double s1 = 1.0 + be[iflag] / ga * t * t * xy; - const double h0 = ga * log(s1); - const double dh0 = be[iflag] * t * t / s1 * (- 7.0 / 3.0 * xy - qy * (af * bf /be[iflag] - 7.0 / 3.0)); - const double ddh0 = be[iflag] / (2.0 * ks * ks * rho) * (xy - qy) / s1; - - sc = rho * h0; - v1c = h0 + dh0; - v2c = ddh0; - - return; -} - //tau_xc and tau_xc_spin: interface for calling xc_mgga_exc_vxc from LIBXC //XC_POLARIZED, XC_UNPOLARIZED: internal flags used in LIBXC, denote the polarized(nspin=1) or unpolarized(nspin=2) calculations, definition can be found in xc.h from LIBXC #ifdef USE_LIBXC @@ -1263,342 +528,6 @@ void XC_Functional::gcxc_libxc(const double &rho, const double &grho, double &sx #endif } -void XC_Functional::optx(const double rho, const double grho, double &sx, double &v1x, double &v2x) -{ - // OPTX, Handy et al. JCP 116, p. 5411 (2002) and refs. therein - // Present release: Mauro Boero, Tsukuba, 10/9/2002 - //-------------------------------------------------------------------------- - // rhoa = rhob = 0.5 * rho in LDA implementation - // grho is the SQUARE of the gradient of rho// --> gr=sqrt(grho) - // sx : total exchange correlation energy at point r - // v1x : d(sx)/drho - // v2x : 1/gr*d(sx)/d(gr) - //-------------------------------------------------------------------------- - // use kinds, only: DP - // implicit none - // real(kind=DP) :: rho, grho, sx, v1x, v2x - - // parameter : - double small = 1.e-30; - double smal2 = 1.e-10; - //.......coefficients and exponents.................... - // parameter : - double o43 = 4.00 / 3.00, - two13 = 1.2599210498948730, - two53 = 3.1748021039363990, - gam = 0.0060, - a1cx = 0.97845711702844210, - a2 = 1.431690; - double gr, rho43, xa, gamx2, uden, uu; - //.......OPTX in compact form.......................... - - if (rho <= small) - { - sx = 0.00; - v1x = 0.00; - v2x = 0.00; - } - else - { - gr = (grho > smal2) ? grho : smal2; //max() - rho43 = pow(rho, o43); - xa = two13 * sqrt(gr) / rho43; - gamx2 = gam * xa * xa; - uden = 1.e+00 / (1.e+00 + gamx2); - uu = a2 * gamx2 * gamx2 * uden * uden; - uden = rho43 * uu * uden; - sx = -rho43 * (a1cx + uu) / two13; - v1x = o43 * (sx + two53 * uden) / rho; - v2x = -two53 * uden / gr; - } //endif - - return; -} // end subroutine optx - -void XC_Functional::perdew86(const double rho, const double grho, double &sc, double &v1c, double &v2c) -{ - // Perdew gradient correction on correlation: PRB 33, 8822 (1986) - - // USE kinds - // implicit none - // real(kind=DP) :: rho, grho, sc, v1c, v2c - double p1, p2, p3, p4, pc1, pc2, pci; - // parameter : - p1 = 0.0232660; - p2 = 7.389e-6; - p3 = 8.7230; - p4 = 0.4720; - // parameter : - pc1 = 0.0016670; - pc2 = 0.0025680; - pci = pc1 + pc2; - double third, pi34; - // parameter : - third = 1.0 / 3.0; - pi34 = 0.62035049089940; // pi34=(3/4pi)^(1/3) - double rho13, rho43, rs, rs2, rs3, cna, cnb, cn, drs; - double dcna, dcnb, dcn, phi, ephi; - - rho13 = pow(rho, third); - rho43 = pow(rho13, 4); - rs = pi34 / rho13; - rs2 = rs * rs; - rs3 = rs * rs2; - cna = pc2 + p1 * rs + p2 * rs2; - cnb = 1.0 + p3 * rs + p4 * rs2 + 1.e4 * p2 * rs3; - cn = pc1 + cna / cnb; - drs = - third * pi34 / rho43; - dcna = (p1 + 2.0 * p2 * rs) * drs; - dcnb = (p3 + 2.0 * p4 * rs + 3.e4 * p2 * rs2) * drs; - dcn = dcna / cnb - cna / (cnb * cnb) * dcnb; - phi = 0.1920 * pci / cn * sqrt(grho) * pow(rho, (- 7.0 / 6.0)); - // SdG: in the original paper 1.745*0.11=0.19195 is used - ephi = exp(- phi); - sc = grho / rho43 * cn * ephi; - v1c = sc * ((1.0 + phi) * dcn / cn - ((4.0 / 3.0) - (7.0 / - 6.0) * phi) / rho); - v2c = cn * ephi / rho43 * (2.0 - phi); - - return; -} //end subroutine perdew86 - -void XC_Functional::ggax(const double &rho, const double &grho, double &sx, double &v1x, double &v2x) -{ - //----------------------------------------------------------------------- - // Perdew-Wang GGA (PW91), exchange part: - // J.P. Perdew et al.,PRB 46, 6671 (1992) - const double f1 = 0.196450; - const double f2 = 7.79560; - const double f3 = 0.27430; - const double f4 = 0.15080; - const double f5 = 0.0040; - const double fp1 = -0.0192920212964260; - const double fp2 = 0.1616204596739950; - // fp1 = -3/(16 pi)*(3 pi^2)^(-1/3) - double rhom43, s, s2, s3, s4, exps, as, sa2b8, shm1, bs, das, - dbs, dls; - - rhom43 = pow(rho, (- 4.0 / 3.0)); - s = fp2 * sqrt(grho) * rhom43; - s2 = s * s; - s3 = s2 * s; - s4 = s2 * s2; - exps = f4 * exp(- 100.0 * s2); - as = f3 - exps - f5 * s2; - sa2b8 = sqrt(1.00 + f2 * f2 * s2); - shm1 = log(f2 * s + sa2b8); - bs = 1.0 + f1 * s * shm1 + f5 * s4; - das = (200.0 * exps - 2.0 * f5) * s; - dbs = f1 * (shm1 + f2 * s / sa2b8) + 4.0 * f5 * s3; - dls = (das / as - dbs / bs); - - sx = fp1 * grho * rhom43 * as / bs; - v1x = - 4.0 / 3.0 * sx / rho * (1.0 + s * dls); - v2x = fp1 * rhom43 * as / bs * (2.0 + s * dls); - - return; -} //end subroutine ggax - - - -void XC_Functional::ggac(const double &rho,const double &grho, double &sc, double &v1c, double &v2c) -{ - // Perdew-Wang GGA (PW91) correlation part - double al, pa, pb, pc, pd, cx, cxc0, cc0; - // parameter : - al = 0.090; - pa = 0.0232660; - pb = 7.389e-6; - pc = 8.7230; - pd = 0.4720; - // parameter : - cx = -0.0016670; - cxc0 = 0.0025680; - cc0 = - cx + cxc0; - double third, pi34, nu, be, xkf, xks; - // parameter : - third = 1.0 / 3.0; - pi34 = 0.62035049089940; - // parameter : - nu = 15.7559203494831440; - be = nu * cc0; - // parameter : - xkf = 1.9191582926775130; - xks = 1.1283791670955130; - // pi34=(3/4pi)^(1/3), nu=(16/pi)*(3 pi^2)^(1/3) - // xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) - double kf, ks, rs, rs2, rs3, ec, vc, t, expe, af, bf, y, xy, - qy, s1; - double h0, dh0, ddh0, ee, cn, dcn, cna, dcna, cnb, dcnb, h1, - dh1, ddh1; - - rs = pi34 / pow(rho, third); - rs2 = rs * rs; - rs3 = rs * rs2; - - // call function: pw - XC_Functional::pw(rs, 0, ec, vc); - kf = xkf / rs; - ks = xks * sqrt(kf); - t = sqrt(grho) / (2.0 * ks * rho); - expe = exp(- 2.0 * al * ec / (be * be)); - af = 2.0 * al / be * (1.0 / (expe - 1.0)); - bf = expe * (vc - ec); - y = af * t * t; - xy = (1.0 + y) / (1.0 + y + y * y); - - double x; - x = 1.0 + y + y * y; - qy = y * y * (2.0 + y) / (x * x); - s1 = 1.0 + 2.0 * al / be * t * t * xy; - h0 = be * be / (2.0 * al) * log(s1); - dh0 = be * t * t / s1 * (- 7.0 / 3.0 * xy - qy * (af * bf / - be - 7.0 / 3.0)); - ddh0 = be / (2.0 * ks * ks * rho) * (xy - qy) / s1; - - x = ks / kf * t; - ee = - 100.0 * (x * x); - cna = cxc0 + pa * rs + pb * rs2; - dcna = pa * rs + 2.0 * pb * rs2; - cnb = 1.0 + pc * rs + pd * rs2 + 1.e4 * pb * rs3; - dcnb = pc * rs + 2.0 * pd * rs2 + 3.e4 * pb * rs3; - cn = cna / cnb - cx; - dcn = dcna / cnb - cna * dcnb / (cnb * cnb); - h1 = nu * (cn - cc0 - 3.0 / 7.0 * cx) * t * t * exp(ee); - dh1 = - third * (h1 * (7.0 + 8.0 * ee) + nu * t * t * exp(ee) - * dcn); - ddh1 = 2.0 * h1 * (1.0 + ee) * rho / grho; - sc = rho * (h0 + h1); - v1c = h0 + h1 + dh0 + dh1; - v2c = ddh0 + ddh1; - - return; -} //end subroutine ggac - -void XC_Functional::wcx(const double &rho,const double &grho, double &sx, double &v1x, double &v2x) -{ - double kf, agrho, s1, s2, es2, ds, dsg, exunif, fx; - // (3*pi2*|rho|)^(1/3) - // |grho| - // |grho|/(2*kf*|rho|) - // s^2 - // n*ds/dn - // n*ds/d(gn) - // exchange energy LDA part - // exchange energy gradient part - double dxunif, dfx, f1, f2, f3, dfx1, x1, x2, x3, dxds1, dxds2, dxds3; - // numerical coefficients (NB: c2=(3 pi^2)^(1/3) ) - double third, c1, c2, c5, teneightyone; // c6 - - third = 1.0/3.0; - c1 = 0.75/ModuleBase::PI; - c2 = 3.093667726280136; - c5 = 4.0 * third; - teneightyone = 0.123456790123; - // parameters of the functional - double k, mu, cwc; - k = 0.804; - mu = 0.2195149727645171; - cwc = 0.00793746933516; - // - agrho = sqrt (grho); - kf = c2 * pow(rho,third); - dsg = 0.5 / kf; - s1 = agrho * dsg / rho; - s2 = s1 * s1; - es2 = exp(-s2); - ds = - c5 * s1; - // - // Energy - // - // x = 10/81 s^2 + (mu - 10/81) s^2 e^-s^2 + ln (1 + c s^4) - x1 = teneightyone * s2; - x2 = (mu - teneightyone) * s2 * es2; - x3 = log(1.0 + cwc * s2 * s2); - f1 = (x1 + x2 + x3) / k; - f2 = 1.0 + f1; - f3 = k / f2; - fx = k - f3; - exunif = - c1 * kf; - sx = exunif * fx; - // - // Potential - // - dxunif = exunif * third; - dfx1 = f2 * f2; - dxds1 = teneightyone; - dxds2 = (mu - teneightyone) * es2 * (1.0 - s2); - dxds3 = 2.0 * cwc * s2 / (1.0 + cwc * s2 *s2); - dfx = 2.0 * s1 * (dxds1 + dxds2 + dxds3) / dfx1; - v1x = sx + dxunif * fx + exunif * dfx * ds; - v2x = exunif * dfx * dsg / agrho; - - sx = sx * rho; - return; -} - -void XC_Functional::becke88(const double &rho, const double &grho, double &sx, double &v1x, double &v2x) -{ - //----------------------------------------------------------------------- - // Becke exchange: A.D. Becke, PRA 38, 3098 (1988) - // only gradient-corrected part, no Slater term included - // - double beta, third, two13; - beta = 0.00420; - third = 1.0 / 3.0; - two13 = 1.2599210498948730; - double rho13, rho43, xs, xs2, sa2b8, shm1, dd, dd2, ee; - - rho13 = pow(rho, third); - rho43 = pow(rho13, 4); - xs = two13 * sqrt(grho) / rho43; - xs2 = xs * xs; - sa2b8 = sqrt(1.00 + xs2); - shm1 = log(xs + sa2b8); - dd = 1.00 + 6.00 * beta * xs * shm1; - dd2 = dd * dd; - ee = 6.00 * beta * xs2 / sa2b8 - 1.0; - sx = two13 * grho / rho43 * (- beta / dd); - v1x = - (4.0 / 3.0) / two13 * xs2 * beta * rho13 * ee / dd2; - v2x = two13 * beta * (ee - dd) / (rho43 * dd2); - - return; -} // end subroutine becke88 - - -void XC_Functional::glyp(const double &rho, const double &grho, double &sc, double &v1c, double &v2c) -{ - //----------------------------------------------------------------------- - // Lee Yang Parr: gradient correction part - - double a, b, c, d; - a = 0.049180; - b = 0.1320; - c = 0.25330; - d = 0.3490; - double rhom13, rhom43, rhom53, om, xl, ff, dom, dxl; - - rhom13 = pow(rho, (- 1.0 / 3.0)); - om = exp(- c * rhom13) / (1.0 + d * rhom13); - xl = 1.0 + (7.0 / 3.0) * (c * rhom13 + d * rhom13 / (1.0 + d * - rhom13)); - ff = a * b * grho / 24.0; - rhom53 = pow(rhom13, 5); - sc = ff * rhom53 * om * xl; - dom = - om * (c + d + c * d * rhom13) / (1.0 + d * rhom13); - - double x; - x = 1.0 + d * rhom13; - dxl = (7.0 / 3.0) * (c + d + 2.0 * c * d * rhom13 + c * d * d * - rhom13 * rhom13) / (x * x); - rhom43 = pow(rhom13, 4); - v1c = - ff * rhom43 / 3.0 * (5.0 * rhom43 * om * xl + rhom53 * - dom * xl + rhom53 * om * dxl); - v2c = 2.0 * sc / grho; - - return; -} // end subroutine glyp - void XC_Functional::gcxc_spin_libxc(double rhoup, double rhodw, ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud) @@ -1836,271 +765,6 @@ void XC_Functional::gcc_spin(double rho, double &zeta, double grho, double &sc, return; } //end subroutine gcc_spin -void XC_Functional::becke88_spin(double rho, double grho, double &sx, double &v1x, double &v2x) -{ - //------------------------------------------------------------------- - // Becke exchange: A.D. Becke, PRA 38, 3098 (1988) - Spin polarized case - - // USE kinds - // implicit none - // real(kind=DP) :: rho, grho, sx, v1x, v2x - // input: charge - // input: gradient - // output: the up and down energies - // output: first part of the potential - // output: the second part of the potential - - double beta, third; - // parameter : - beta = 0.00420; - third = 1.0 / 3.0; - double rho13, rho43, xs, xs2, sa2b8, shm1, dd, dd2, ee; - - rho13 = pow(rho, third); - rho43 = pow(rho13, 4); - xs = sqrt(grho) / rho43; - xs2 = xs * xs; - sa2b8 = sqrt(1.00 + xs2); - shm1 = log(xs + sa2b8); - dd = 1.00 + 6.00 * beta * xs * shm1; - dd2 = dd * dd; - ee = 6.00 * beta * xs2 / sa2b8 - 1.0; - sx = grho / rho43 * (- beta / dd); - v1x = - (4.0 / 3.0) * xs2 * beta * rho13 * ee / dd2; - v2x = beta * (ee - dd) / (rho43 * dd2); - - return; -} //end subroutine becke88_spin - -// -//----------------------------------------------------------------------- -void XC_Functional::perdew86_spin(double rho, double zeta, double grho, double &sc, - double &v1cup, double &v1cdw, double &v2c) -{ - //------------------------------------------------------------------- - // Perdew gradient correction on correlation: PRB 33, 8822 (1986) - // spin-polarized case - - // USE kinds - // implicit none - // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c - double p1, p2, p3, p4, pc1, pc2, pci; - // parameter : - p1 = 0.0232660; - p2 = 7.389e-6; - p3 = 8.7230; - p4 = 0.4720; - // parameter : - pc1 = 0.0016670; - pc2 = 0.0025680; - pci = pc1 + pc2; - double third, pi34; - // parameter : - third = 1.0 / 3.0; - pi34 = 0.62035049089940; - // pi34=(3/4pi)^(1/3) - - double rho13, rho43, rs, rs2, rs3, cna, cnb, cn, drs; - double dcna, dcnb, dcn, phi, ephi, dd, ddd; - - rho13 = pow(rho, third); - rho43 = pow(rho13, 4); - rs = pi34 / rho13; - rs2 = rs * rs; - rs3 = rs * rs2; - cna = pc2 + p1 * rs + p2 * rs2; - cnb = 1.0 + p3 * rs + p4 * rs2 + 1.e4 * p2 * rs3; - cn = pc1 + cna / cnb; - drs = - third * pi34 / rho43; - dcna = (p1 + 2.0 * p2 * rs) * drs; - dcnb = (p3 + 2.0 * p4 * rs + 3.e4 * p2 * rs2) * drs; - dcn = dcna / cnb - cna / (cnb * cnb) * dcnb; - phi = 0.1920 * pci / cn * sqrt(grho) * pow(rho, (- 7.0 / 6.0)); - //SdG: in the original paper 1.745*0.11=0.19195 is used - dd = pow((2.0) , third) * sqrt(pow(((1.0 + zeta) * 0.50) , (5.0 / - 3.0)) + pow(((1.0 - zeta) * 0.50) , (5.0 / 3.0))); - ddd = pow((2.0) , (- 4.0 / 3.0)) * 5.0 * (pow(((1.0 + zeta) - * 0.50) , (2.0 / 3.0)) - pow(((1.0 - zeta) * 0.50) , (2.0 / - 3.0))) / (3.0 * dd); - ephi = exp(- phi); - sc = grho / rho43 * cn * ephi / dd; - v1cup = sc * ((1.0 + phi) * dcn / cn - ((4.0 / 3.0) - - (7.0 / 6.0) * phi) / rho) - sc * ddd / dd * (1.0 - zeta) - / rho; - v1cdw = sc * ((1.0 + phi) * dcn / cn - ((4.0 / 3.0) - - (7.0 / 6.0) * phi) / rho) + sc * ddd / dd * (1.0 + zeta) - / rho; - v2c = cn * ephi / rho43 * (2.0 - phi) / dd; - - return; -} //end subroutine perdew86_spin - -// -//----------------------------------------------------------------------- -void XC_Functional::ggac_spin(double rho, double zeta, double grho, double &sc, - double &v1cup, double &v1cdw, double &v2c) -{ - //------------------------------------------------------------------- - // Perdew-Wang GGA (PW91) correlation part - spin-polarized - - // USE kinds - // implicit none - // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c - double al, pa, pb, pc, pd, cx, cxc0, cc0; - // parameter : - al = 0.090; - pa = 0.0232660; - pb = 7.389e-6; - pc = 8.7230; - pd = 0.4720; - // parameter : - cx = - 0.0016670; - cxc0 = 0.0025680; - cc0 = - cx + cxc0; - - double third, pi34, nu, be, xkf, xks; - // parameter : - third = 1.0 / 3.0; - pi34 = 0.6203504908994e0l; - // parameter : - nu = 15.7559203494831440; - be = nu * cc0; - // parameter : - xkf = 1.9191582926775130; - xks = 1.1283791670955130; - // pi34=(3/4pi)^(1/3), nu=(16/pi)*(3 pi^2)^(1/3) - // xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) - double kf, ks, rs, rs2, rs3, ec, vcup, vcdw, t, expe, af, y, - xy, qy, s1, h0, ddh0, ee, cn, dcn, cna, dcna, cnb, dcnb, h1, dh1, - ddh1, fz, fz2, fz3, fz4, dfz, bfup, dh0up, dh0zup, //bfdw, dh0dw, - dh0zdw, dh1zup, dh1zdw; - - rs = pi34 / pow(rho, third); - rs2 = rs * rs; - rs3 = rs * rs2; - XC_Functional::pw_spin(rs, zeta, ec, vcup, vcdw); - kf = xkf / rs; - ks = xks * sqrt(kf); - fz = 0.50 * (pow((1.0 + zeta) , (2.0 / 3.0)) + pow((1.0 - zeta) , ( - 2.0 / 3.0))); - fz2 = fz * fz; - fz3 = fz2 * fz; - fz4 = fz3 * fz; - dfz = (pow((1.0 + zeta) , (- 1.0 / 3.0)) - pow((1.0 - zeta) , (- - 1.0 / 3.0))) / 3.0; - t = sqrt(grho) / (2.0 * fz * ks * rho); - expe = exp(- 2.0 * al * ec / (fz3 * be * be)); - af = 2.0 * al / be * (1.0 / (expe - 1.0)); - bfup = expe * (vcup - ec) / fz3; - //bfdw = expe * (vcdw - ec) / fz3; - y = af * t * t; - xy = (1.0 + y) / (1.0 + y + y * y); - qy = y * y * (2.0 + y) / (1.0 + y + y * y) ; //**2; - qy *= qy; - s1 = 1.0 + 2.0 * al / be * t * t * xy; - h0 = fz3 * be * be / (2.0 * al) * log(s1); - dh0up = be * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * - (af * bfup / be - 7.0 / 3.0)); - //dh0dw = be * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * - // (af * bfdw / be - 7.0 / 3.0)); - dh0zup = (3.0 * h0 / fz - be * t * t * fz2 / s1 * (2.0 * xy - - qy * (3.0 * af * expe * ec / fz3 / be + 2.0))) * dfz * (1.0 - - zeta); - dh0zdw = - (3.0 * h0 / fz - be * t * t * fz3 / s1 * (2.0 * xy - - qy * (3.0 * af * expe * ec / fz3 / be + 2.0))) * dfz * (1.0 + - zeta); - ddh0 = be * fz / (2.0 * ks * ks * rho) * (xy - qy) / s1; - ee = - 100.0 * fz4 * (ks / kf * t); // **2; - ee *= ee; - cna = cxc0 + pa * rs + pb * rs2; - dcna = pa * rs + 2.0 * pb * rs2; - cnb = 1.0 + pc * rs + pd * rs2 + 1.e4 * pb * rs3; - dcnb = pc * rs + 2.0 * pd * rs2 + 3.e4 * pb * rs3; - cn = cna / cnb - cx; - dcn = dcna / cnb - cna * dcnb / (cnb * cnb); - h1 = nu * (cn - cc0 - 3.0 / 7.0 * cx) * fz3 * t * t * exp(ee); - dh1 = - third * (h1 * (7.0 + 8.0 * ee) + fz3 * nu * t * t * exp - (ee) * dcn); - ddh1 = 2.0 * h1 * (1.0 + ee) * rho / grho; - dh1zup = (1.0 - zeta) * dfz * h1 * (1.0 + 2.0 * ee / fz); - dh1zdw = - (1.0 + zeta) * dfz * h1 * (1.0 + 2.0 * ee / fz); - sc = rho * (h0 + h1); - v1cup = h0 + h1 + dh0up + dh1 + dh0zup + dh1zup; - v1cdw = h0 + h1 + dh0up + dh1 + dh0zdw + dh1zdw; - v2c = ddh0 + ddh1; - return; -} // end subroutine ggac_spin - -// -//--------------------------------------------------------------- -void XC_Functional::pbec_spin(double rho, double zeta, double grho, const int &iflag, double &sc, - double &v1cup, double &v1cdw, double &v2c) -{ - //----------------------------------------------------------- - - // PBE correlation (without LDA part) - spin-polarized - // J.P.Perdew, K.Burke, M.Ernzerhof, PRL 77, 3865 (1996). - - // USE kinds - // implicit none - // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c - double ga, be[3];//mohan add - // parameter : - ga = 0.0310910; - be[1] = 0.06672455060314922;//zhengdy add 2019-09-12, ensure same parameter with another dft code. - be[2] = 0.0460000;//mohan add 2012-05-28 - double third, pi34, xkf, xks; - // parameter : - third = 1.0 / 3.0; - pi34 = 0.62035049089940; - // parameter : - xkf = 1.9191582926775130; - xks = 1.1283791670955130; - // pi34=(3/4pi)^(1/3), xkf=(9 pi/4)^(1/3), xks= sqrt(4/pi) - double kf, ks, rs, ec, vcup, vcdw, t, expe, af, y, xy, qy, - s1, h0, ddh0; - double fz, fz2, fz3, dfz, bfup, bfdw, dh0up, dh0dw, dh0zup, dh0zdw; // fz4 - - rs = pi34 / pow(rho, third); - XC_Functional::pw_spin(rs, zeta, ec, vcup, vcdw); //mohan fix bug 2012-05-28 - kf = xkf / rs; - ks = xks * sqrt(kf); - fz = 0.50 * (pow((1.0 + zeta) , (2.0 / 3.0)) + pow((1.0 - zeta) , ( - 2.0 / 3.0))); - fz2 = fz * fz; - fz3 = fz2 * fz; - //fz4 = fz3 * fz; - dfz = (pow((1.0 + zeta) , (- 1.0 / 3.0)) - pow((1.0 - zeta) , (- - 1.0 / 3.0))) / 3.0; - t = sqrt(grho) / (2.0 * fz * ks * rho); - expe = exp(- ec / (fz3 * ga)); - af = be[iflag] / ga * (1.0 / (expe - 1.0)); - bfup = expe * (vcup - ec) / fz3; - bfdw = expe * (vcdw - ec) / fz3; - y = af * t * t; - xy = (1.0 + y) / (1.0 + y + y * y); - qy = y * y * (2.0 + y) / pow( (1.0 + y + y * y),2 ); -// qy *= qy; //bug - s1 = 1.0 + be[iflag] / ga * t * t * xy; - h0 = fz3 * ga * log(s1); - dh0up = be[iflag] * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * - (af * bfup / be[iflag] - 7.0 / 3.0)); - dh0dw = be[iflag] * t * t * fz3 / s1 * (- 7.0 / 3.0 * xy - qy * - (af * bfdw / be[iflag] - 7.0 / 3.0)); - dh0zup = (3.0 * h0 / fz - be[iflag] * t * t * fz2 / s1 * (2.0 * xy - - qy * (3.0 * af * expe * ec / fz3 / be[iflag] + 2.0))) * dfz * (1.0 - - zeta); - dh0zdw = - (3.0 * h0 / fz - be[iflag] * t * t * fz2 / s1 * (2.0 * xy - - qy * (3.0 * af * expe * ec / fz3 / be[iflag] + 2.0))) * dfz * (1.0 + - zeta); - ddh0 = be[iflag] * fz / (2.0 * ks * ks * rho) * (xy - qy) / s1; - sc = rho * h0; - v1cup = h0 + dh0up + dh0zup; - v1cdw = h0 + dh0dw + dh0zdw; - v2c = ddh0; - return; -} // end subroutine pbec_spin - #ifdef USE_LIBXC std::vector XC_Functional::init_func(const int xc_polarized) { From 73962a7957d1cbcac8310c3292d28b4e233c0b3a Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Thu, 3 Mar 2022 15:45:32 +0800 Subject: [PATCH 14/36] xc refactor : 1. remove input variable vxc_in_h since it is equivalent to setting dft_functional = "none" 2. switch back to v_xc_libxc since it is faster to calculate vxc on entire grid, not loop over points 3. move v_xc, v_xc_libxc and v_xc_meta to xc_functional_vxc.cpp --- source/input.cpp | 6 - source/input.h | 2 +- source/input_conv.cpp | 1 - source/module_base/global_variable.cpp | 1 - source/module_base/global_variable.h | 1 - source/module_xc/CMakeLists.txt | 3 +- source/module_xc/H_XC_pw.cpp | 175 ------ source/module_xc/potential_libxc_meta.cpp | 302 ---------- source/module_xc/xc_functional.cpp | 79 ++- source/module_xc/xc_functional.h | 16 +- source/module_xc/xc_functional_vxc.cpp | 666 ++++++++++++++++++++++ source/module_xc/xc_gga_pw.cpp | 33 +- source/src_io/write_input.cpp | 1 - source/src_pw/forces.cpp | 12 +- source/src_pw/potential.cpp | 4 +- 15 files changed, 735 insertions(+), 567 deletions(-) delete mode 100644 source/module_xc/H_XC_pw.cpp delete mode 100644 source/module_xc/potential_libxc_meta.cpp create mode 100644 source/module_xc/xc_functional_vxc.cpp diff --git a/source/input.cpp b/source/input.cpp index 99c9df1a93b..fe053292b8a 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -214,7 +214,6 @@ void Input::Default(void) vl_in_h = 1; vnl_in_h = 1; vh_in_h = 1; - vxc_in_h = 1; vion_in_h = 1; test_force = 0; test_stress = 0; @@ -892,10 +891,6 @@ bool Input::Read(const std::string &fn) { read_value(ifs, vh_in_h); } - else if (strcmp("vxc_in_h", word) == 0) - { - read_value(ifs, vxc_in_h); - } else if (strcmp("vion_in_h", word) == 0) { read_value(ifs, vion_in_h); @@ -2059,7 +2054,6 @@ void Input::Bcast() Parallel_Common::bcast_int( vl_in_h ); Parallel_Common::bcast_int( vnl_in_h ); Parallel_Common::bcast_int( vh_in_h ); - Parallel_Common::bcast_int( vxc_in_h ); Parallel_Common::bcast_int( vion_in_h ); Parallel_Common::bcast_int( test_force ); diff --git a/source/input.h b/source/input.h index 19ad262fecb..871cfa968c5 100644 --- a/source/input.h +++ b/source/input.h @@ -92,6 +92,7 @@ class Input // electrons / spin //========================================================== std::string dft_functional; // input DFT functional. + bool use_libxc; // whether to use LIBXC int nspin; // LDA ; LSDA ; non-linear spin double nelec; // total number of electrons int lmaxmax; @@ -166,7 +167,6 @@ class Input int vnl_in_h; // calculate the vnl or not. int vh_in_h; // calculate the hartree potential or not - int vxc_in_h; // calculate the xc potential or not int vion_in_h; // calculate the local ionic potential or not //only relevant when vl_in_h = 1 diff --git a/source/input_conv.cpp b/source/input_conv.cpp index 28dd0ee4955..ffce1ac432b 100644 --- a/source/input_conv.cpp +++ b/source/input_conv.cpp @@ -153,7 +153,6 @@ void Input_Conv::Convert(void) GlobalV::VL_IN_H = INPUT.vl_in_h; GlobalV::VNL_IN_H = INPUT.vnl_in_h; GlobalV::VH_IN_H = INPUT.vh_in_h; - GlobalV::VXC_IN_H = INPUT.vxc_in_h; GlobalV::VION_IN_H = INPUT.vion_in_h; GlobalV::TEST_FORCE = INPUT.test_force; GlobalV::TEST_STRESS = INPUT.test_stress; diff --git a/source/module_base/global_variable.cpp b/source/module_base/global_variable.cpp index 8e65c45334c..1b9a816fb1c 100644 --- a/source/module_base/global_variable.cpp +++ b/source/module_base/global_variable.cpp @@ -75,7 +75,6 @@ int T_IN_H = 1; // mohan add 2010-11-28 int VL_IN_H = 1; int VNL_IN_H = 1; int VH_IN_H = 1; -int VXC_IN_H = 1; int VION_IN_H = 1; int ZEEMAN_IN_H = 1; double STRESS_THR = 1.0e-2; //LiuXh add 20180515 diff --git a/source/module_base/global_variable.h b/source/module_base/global_variable.h index a25019f892a..a6a6a3022f7 100644 --- a/source/module_base/global_variable.h +++ b/source/module_base/global_variable.h @@ -88,7 +88,6 @@ extern int T_IN_H; // 23, calculate T in H or not. extern int VL_IN_H; // 24, calculate Vl in H or not. extern int VNL_IN_H; // 25, calculate Vnl in H or not. extern int VH_IN_H; // 26, calculate Vh in H or not. -extern int VXC_IN_H; // 27, calculate Vxc in H or not. extern int VION_IN_H; // 28, calculate Vion_loc in H or not. extern double STRESS_THR; //LiuXh add 20180515 diff --git a/source/module_xc/CMakeLists.txt b/source/module_xc/CMakeLists.txt index 93e38d0f6f3..2c01c8ec83a 100644 --- a/source/module_xc/CMakeLists.txt +++ b/source/module_xc/CMakeLists.txt @@ -1,7 +1,6 @@ list(APPEND objects - H_XC_pw.cpp - potential_libxc_meta.cpp xc_functional.cpp + xc_functional_vxc.cpp xc_gga_pw.cpp xc_funct_exch_lda.cpp xc_funct_corr_lda.cpp diff --git a/source/module_xc/H_XC_pw.cpp b/source/module_xc/H_XC_pw.cpp deleted file mode 100644 index bbe337758f0..00000000000 --- a/source/module_xc/H_XC_pw.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "xc_functional.h" -#include "../src_parallel/parallel_reduce.h" -#include "../module_base/timer.h" - -// [etxc, vtxc, v] = XC_Functional::v_xc(...) -std::tuple XC_Functional::v_xc -( - const int &nrxx, // number of real-space grid - const int &ncxyz, // total number of charge grid - const double &omega, // volume of cell - const double*const*const rho_in, - const double*const rho_core) // core charge density -{ - ModuleBase::TITLE("H_XC_pw","v_xc"); - ModuleBase::timer::tick("H_XC_pw","v_xc"); - - #ifndef USE_LIBXC - if(XC_Functional::get_func_type() == 3) - { - ModuleBase::WARNING_QUIT("Potential::v_of_rho","to use metaGGA, please link LIBXC"); - } - #endif - //Exchange-Correlation potential Vxc(r) from n(r) - double etxc = 0.0; - double vtxc = 0.0; - ModuleBase::matrix v(GlobalV::NSPIN, nrxx); - - // the square of the e charge - // in Rydeberg unit, so * 2.0. - double e2 = 2.0; - - double rhox = 0.0; - double arhox = 0.0; - double zeta = 0.0; - double exc = 0.0; - double vxc[2]; - - int ir, is; - - double vanishing_charge = 1.0e-10; - - if (GlobalV::NSPIN == 1 || ( GlobalV::NSPIN ==4 && !GlobalV::DOMAG && !GlobalV::DOMAG_Z)) - { - // spin-unpolarized case - for (int ir = 0;ir < nrxx;ir++) - { - // total electron charge density - rhox = rho_in[0][ir] + rho_core[ir]; - arhox = abs(rhox); - if (arhox > vanishing_charge) - { - if(use_libxc) - { - XC_Functional::xc_libxc(arhox, exc, vxc[0]); - } - else - { - XC_Functional::xc(arhox, exc, vxc[0]); - } - v(0,ir) = e2 * vxc[0]; - // consider the total charge density - etxc += e2 * exc * rhox; - // only consider rho_in - vtxc += v(0, ir) * rho_in[0][ir]; - } // endif - } //enddo - } - else if(GlobalV::NSPIN ==2) - { - // spin-polarized case - for (ir = 0;ir < nrxx;ir++) - { - rhox = rho_in[0][ir] + rho_in[1][ir] + rho_core[ir]; //HLX(05-29-06): bug fixed - arhox = abs(rhox); - - if (arhox > vanishing_charge) - { - zeta = (rho_in[0][ir] - rho_in[1][ir]) / arhox; //HLX(05-29-06): bug fixed - - if (abs(zeta) > 1.0) - { - zeta = (zeta > 0.0) ? 1.0 : (-1.0); - } - - // call - if(use_libxc) - { - double rhoup = arhox * (1.0+zeta) / 2.0; - double rhodw = arhox * (1.0-zeta) / 2.0; - XC_Functional::xc_spin_libxc(rhoup, rhodw, exc, vxc[0], vxc[1]); - } - else - { - double rhoup = arhox * (1.0+zeta) / 2.0; - double rhodw = arhox * (1.0-zeta) / 2.0; - XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); - } - - for (is = 0;is < GlobalV::NSPIN;is++) - { - v(is, ir) = e2 * vxc[is]; - } - - etxc += e2 * exc * rhox; - vtxc += v(0, ir) * rho_in[0][ir] + v(1, ir) * rho_in[1][ir]; - } - } - - } - else if(GlobalV::NSPIN == 4)//noncollinear case added by zhengdy - { - for( ir = 0;ir vanishing_charge ) - { - zeta = amag / arhox; - - if ( abs( zeta ) > 1.0 ) - { - zeta = (zeta > 0.0) ? 1.0 : (-1.0); - }//end if - - if(use_libxc) - { - double rhoup = arhox * (1.0+zeta) / 2.0; - double rhodw = arhox * (1.0-zeta) / 2.0; - XC_Functional::xc_spin_libxc(rhoup, rhodw, exc, vxc[0], vxc[1]); - } - else - { - double rhoup = arhox * (1.0+zeta) / 2.0; - double rhodw = arhox * (1.0-zeta) / 2.0; - XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); - } - - etxc += e2 * exc * rhox; - - v(0, ir) = e2*( 0.5 * ( vxc[0] + vxc[1]) ); - vtxc += v(0,ir) * rho_in[0][ir]; - - double vs = 0.5 * ( vxc[0] - vxc[1] ); - if ( amag > vanishing_charge ) - { - for(int ipol = 1;ipol< 4;ipol++) - { - v(ipol, ir) = e2 * vs * rho_in[ipol][ir] / amag; - vtxc += v(ipol,ir) * rho_in[ipol][ir]; - }//end do - }//end if - }//end if - }//end do - }//end if - // energy terms, local-density contributions - - // add gradient corrections (if any) - // mohan modify 2009-12-15 - gradcorr(etxc, vtxc, v); - - // parallel code : collect vtxc,etxc - // mohan add 2008-06-01 - Parallel_Reduce::reduce_double_pool( etxc ); - Parallel_Reduce::reduce_double_pool( vtxc ); - - etxc *= omega / ncxyz; - vtxc *= omega / ncxyz; - - ModuleBase::timer::tick("H_XC_pw","v_xc"); - return std::make_tuple(etxc, vtxc, std::move(v)); -} diff --git a/source/module_xc/potential_libxc_meta.cpp b/source/module_xc/potential_libxc_meta.cpp deleted file mode 100644 index 6136210ca66..00000000000 --- a/source/module_xc/potential_libxc_meta.cpp +++ /dev/null @@ -1,302 +0,0 @@ -//========================================================== -// AUTHOR : Wenfei Li -// DATE : 2021-07-30 -// UPDATE : -//========================================================== - -#ifdef USE_LIBXC - -#include "../src_pw/global.h" -#include "../module_base/global_function.h" -#include "../module_base/global_variable.h" -#include "module_base/timer.h" -#include "src_parallel/parallel_reduce.h" -#include "./xc_functional.h" -#ifdef __LCAO -#include "../src_lcao/global_fp.h" -#endif - -using namespace std; - -//the interface to libxc xc_mgga_exc_vxc(xc_func,n,rho,grho,laplrho,tau,e,v1,v2,v3,v4) -//xc_func : LIBXC data type, contains information on xc functional -//n: size of array, nspin*nnr -//rho,grho,laplrho: electron density, its gradient and laplacian -//tau(kin_r): kinetic energy density -//e: energy density -//v1-v4: derivative of energy density w.r.t rho, gradient, laplacian and tau -//v1 and v2 are combined to give v; v4 goes into vofk - -//XC_POLARIZED, XC_UNPOLARIZED: internal flags used in LIBXC, denote the polarized(nspin=1) or unpolarized(nspin=2) calculations, definition can be found in xc.h from LIBXC - -// [etxc, vtxc, v, vofk] = Potential_Libxc::v_xc(...) -tuple XC_Functional::v_xc_meta( - const double * const * const rho_in, - const double * const rho_core_in, - const double * const * const kin_r_in) -{ - ModuleBase::TITLE("Potential_Libxc","v_xc"); - ModuleBase::timer::tick("Potential_Libxc","v_xc"); - - //output of the subroutine - double etxc = 0.0; - double vtxc = 0.0; - ModuleBase::matrix v(GlobalV::NSPIN,GlobalC::pw.nrxx); - ModuleBase::matrix vofk(GlobalV::NSPIN,GlobalC::pw.nrxx); - - if(GlobalV::VXC_IN_H == 0 ) - { - ModuleBase::timer::tick("Potential_Libxc","v_xc_meta"); - return std::make_tuple( etxc, vtxc, move(v), move(vofk) ); - } - //---------------------------------------------------------- - // xc_func_type is defined in Libxc package - // to understand the usage of xc_func_type, - // use can check on website, for example: - // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ - //---------------------------------------------------------- - - //initialize X and C functionals - xc_func_type x_func; - xc_func_type c_func; - const int xc_polarized = (GlobalV::NSPIN ? XC_UNPOLARIZED : XC_POLARIZED); - - //exchange - if( func_id[0] == 263) - { - xc_func_init(&x_func, 263 ,xc_polarized); - } - else - { - throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - - //correlation - if( func_id[1] == 267) - { - xc_func_init(&c_func, 267 ,xc_polarized); - } - else - { - throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - - //rho,grho,tau - vector> rho; - vector>> grho; - vector> kin_r; - - //dExc/d rho,grho,tau - vector> vrho; - vector>> h; - vector> kedtaur; - - //rho : from double** to vector - rho.resize(GlobalV::NSPIN); - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - rho[is].resize(GlobalC::pw.nrxx); - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - rho[is][ir] = rho_in[is][ir] + (1.0/GlobalV::NSPIN)*rho_core_in[ir]; - } - } - - //grho : calculate gradient - grho.resize(GlobalV::NSPIN); - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - grho[is].resize(GlobalC::pw.nrxx); - - vector> rhog(GlobalC::pw.ngmc); - GlobalC::CHR.set_rhog(rho[is].data(), rhog.data()); - XC_Functional::grad_rho(rhog.data(), grho[is].data()); - } - - //kin_r : from double** to vector - kin_r.resize(GlobalV::NSPIN); - if(GlobalV::NSPIN==1 || GlobalV::NSPIN==2) - { - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - kin_r[is].resize(GlobalC::pw.nrxx); - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - kin_r[is][ir] = kin_r_in[is][ir]; - } - } - } - - if(GlobalV::NSPIN==1) - { - vrho.resize(GlobalV::NSPIN); - h.resize(GlobalV::NSPIN); - kedtaur.resize(GlobalV::NSPIN); - - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - vrho[is].resize(GlobalC::pw.nrxx); - h[is].resize(GlobalC::pw.nrxx); - kedtaur[is].resize(GlobalC::pw.nrxx); - - double arho, grho2, atau, lapl; - double ex, ec, v1x, v2x, v3x, v1c, v2c, v3c, vlapl; - const double rho_th = 1e-8; - const double grho_th = 1e-12; - const double tau_th = 1e-8; - - - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - arho = abs(rho_in[is][ir]); - grho2 = grho[0][ir]*grho[0][ir]; - atau = kin_r[is][ir] / ModuleBase::e2; - lapl = grho2;//dummy argument, not used - - if(arho > rho_th && grho2 > grho_th && abs(atau) > tau_th) - { - xc_mgga_exc_vxc(&x_func,1,&arho,&grho2,&lapl,&atau,&ex,&v1x,&v2x,&vlapl,&v3x); - xc_mgga_exc_vxc(&c_func,1,&arho,&grho2,&lapl,&atau,&ec,&v1c,&v2c,&vlapl,&v3c); - ex = ex * rho[is][ir]; - ec = ec * rho[is][ir]; - v2x = v2x * ModuleBase::e2; - v2c = v2c * ModuleBase::e2; - - vrho[is][ir] = (v1x + v1c) * ModuleBase::e2; - h[is][ir] = (v2x + v2c) * ModuleBase::e2 * grho[is][ir]; - kedtaur[is][ir] = v3x + v3c; - - etxc += (ex + ec) * ModuleBase::e2; - vtxc += (v1x + v1c) * ModuleBase::e2 * arho; - } - else - { - vrho[is][ir] = 0.0; - h[is][ir] = 0.0; - kedtaur[is][ir] = 0.0; - } - }//loop over grid points - }//loop over spin - }//nspin=1 - else if(GlobalV::NSPIN==2) - { - vrho.resize(GlobalV::NSPIN); - h.resize(GlobalV::NSPIN); - kedtaur.resize(GlobalV::NSPIN); - - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - vrho[is].resize(GlobalC::pw.nrxx); - h[is].resize(GlobalC::pw.nrxx); - kedtaur[is].resize(GlobalC::pw.nrxx); - } - - double rh, ggrho2, atau; - double rhoup, rhodw, tauup, taudw; - double ex, v1xup, v1xdw, v2xup, v2xdw, v3xup, v3xdw; - double ec, v1cup, v1cdw, v3cup, v3cdw; - ModuleBase::Vector3 grhoup,grhodw,v2cup,v2cdw; - - XC_Functional::Mgga_spin_in mgga_spin_in; - XC_Functional::Mgga_spin_out mgga_spin_out; - - - const double rho_th = 1e-8; - const double grho_th = 1e-12; - const double tau_th = 1e-8; - - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) - { - - auto set_input_tau_spin = [&]() - { - mgga_spin_in.rhoup = rho_in[0][ir]; - mgga_spin_in.rhodw = rho_in[1][ir]; - rh = rho_in[0][ir] + rho_in[1][ir]; - - mgga_spin_in.grhoup = grho[0][ir]; - mgga_spin_in.grhodw = grho[1][ir]; - ggrho2 = (grho[0][ir]*grho[0][ir] + grho[1][ir]*grho[1][ir]) * 4.0; - - mgga_spin_in.tauup = kin_r[0][ir] / ModuleBase::e2; - mgga_spin_in.taudw = kin_r[1][ir] / ModuleBase::e2; - atau = (kin_r[0][ir]+kin_r[1][ir])/ ModuleBase::e2; - }; - - auto set_output_tau_spin = [&]() - { - vrho[0][ir] = (mgga_spin_out.v1xup+mgga_spin_out.v1cup) * ModuleBase::e2; - vrho[1][ir] = (mgga_spin_out.v1xdw+mgga_spin_out.v1cdw) * ModuleBase::e2; - - h[0][ir] = (mgga_spin_out.v2xup*grhoup+mgga_spin_out.v2cup)*ModuleBase::e2; - h[1][ir] = (mgga_spin_out.v2xdw*grhodw+mgga_spin_out.v2cdw)*ModuleBase::e2; - - kedtaur[0][ir] = mgga_spin_out.v3xup+mgga_spin_out.v3cup; - kedtaur[1][ir] = mgga_spin_out.v3xdw+mgga_spin_out.v3cdw; - - etxc += (mgga_spin_out.ex+mgga_spin_out.ec) * ModuleBase::e2; - vtxc += (mgga_spin_out.v1xup+mgga_spin_out.v1xdw+mgga_spin_out.v1cup+mgga_spin_out.v1cdw) * ModuleBase::e2 * rh; - }; - - if (rh > rho_th && ggrho2 > grho_th && abs(atau) > tau_th) - { - set_input_tau_spin(); - XC_Functional::tau_xc_spin(mgga_spin_in, mgga_spin_out); - set_output_tau_spin(); - } - else - { - vrho[0][ir] = 0.0; - vrho[1][ir] = 0.0; - - h[0][ir]=0.0; - h[1][ir]=0.0; - - kedtaur[0][ir] = 0.0; - kedtaur[1][ir] = 0.0; - } - }//end loop grid points - }//nspin=2 - else - { - ModuleBase::WARNING_QUIT("potential_libxc_meta","meta-GGA for nspin=1,2 first"); - } - - vector dh; - dh.resize(GlobalC::pw.nrxx); - - for(int is=0;is funcs = init_func(XC_UNPOLARIZED); +void XC_Functional::set_xc_type_libxc(std::string xc_func_in) +{ - for(xc_func_type &func : funcs) + // determine the type (lda/gga/mgga) + func_type = 1; + if(xc_func_in.find("GGA") != std::string::npos) func_type = 2; + if(xc_func_in.find("MGGA") != std::string::npos) func_type = 3; + if(xc_func_in.find("HYB") != std::string::npos) func_type =4; + + // determine the id + int pos = 0; + std::string delimiter = "+"; + std::string token; + while ((pos = xc_func_in.find(delimiter)) != std::string::npos) { - if( func.info->family == XC_FAMILY_LDA) - { - // call Libxc function: xc_lda_exc_vxc - xc_lda_exc_vxc( &func, 1, &rho, &e, &v); - } - exc += e; - vxc += v; + token = xc_func_in.substr(0, pos); + int id = xc_functional_get_number(token.c_str()); + std::cout << "func,id" << token << " " << id << std::endl; + if (id == -1) ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc","functional name not recognized!"); + func_id.push_back(id); + xc_func_in.erase(0, pos + delimiter.length()); } - return; -#endif -} + int id = xc_functional_get_number(xc_func_in.c_str()); + std::cout << "func,id" << xc_func_in << " " << id << std::endl; + if (id == -1) ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc","functional name not recognized!"); + func_id.push_back(id); +} +#endif void XC_Functional::xc(const double &rho, double &exc, double &vxc) { @@ -504,30 +521,6 @@ void XC_Functional::gcxc(const double &rho, const double &grho, double &sxc, return; } -void XC_Functional::gcxc_libxc(const double &rho, const double &grho, double &sxc, - double &v1xc, double &v2xc) -{ -#ifdef USE_LIBXC - double s,v1,v2; - sxc = v1xc = v2xc = 0.0; - - std::vector funcs = init_func(XC_UNPOLARIZED); - - for(xc_func_type &func : funcs) - { - if( func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) - { - // call Libxc function: xc_gga_exc_vxc - xc_gga_exc_vxc( &func, 1, &rho, &grho, &s, &v1, &v2); - } - sxc += s; - v1xc += v1; - v2xc += v2; - } - return; -#endif -} - void XC_Functional::gcxc_spin_libxc(double rhoup, double rhodw, ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud) diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index d8c49182596..e2e97bd1cb5 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -39,7 +39,17 @@ class XC_Functional const double*const*const rho_in, const double*const rho_core); // core charge density + static std::tuple v_xc_libxc( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell + const double*const*const rho_in, + const double*const rho_core); // core charge density + static std::tuple v_xc_meta( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell const double * const * const rho_in, const double * const rho_core_in, const double * const * const kin_r_in); @@ -48,9 +58,6 @@ class XC_Functional static void gcxc(const double &rho, const double &grho, double &sxc, double &v1xc, double &v2xc); - static void gcxc_libxc(const double &rho, const double &grho, - double &sxc, double &v1xc, double &v2xc); - // spin polarized GGA static void gcx_spin(double rhoup, double rhodw, double grhoup2, double grhodw2, double &sx, double &v1xup, double &v1xdw, double &v2xup, @@ -103,12 +110,11 @@ class XC_Functional static void set_xc_type(const std::string xc_func_in); #ifdef USE_LIBXC + static void set_xc_type_libxc(const std::string xc_func_in); static std::vector init_func(const int xc_polarized); #endif // LDA static void xc(const double &rho, double &exc, double &vxc); - static void xc_libxc(const double &rho, double &exc, double &vxc); - // LSDA static void xc_spin(const double &rho, const double &zeta, diff --git a/source/module_xc/xc_functional_vxc.cpp b/source/module_xc/xc_functional_vxc.cpp new file mode 100644 index 00000000000..b25104ad35f --- /dev/null +++ b/source/module_xc/xc_functional_vxc.cpp @@ -0,0 +1,666 @@ +// This file contains interface to xc_functional class: +// 1. v_xc : which takes rho as input, and v_xc as output +// 2. v_xc_libxc : which does the same thing as v_xc, but calling libxc +// NOTE : it is only used for nspin = 1 and 2, the nspin = 4 case is treated in v_xc +// 3. v_xc_meta : which takes rho and tau as input, and v_xc as output + +#include "xc_functional.h" +#include "../src_parallel/parallel_reduce.h" +#include "../module_base/timer.h" +#include "./xc_functional.h" +#include "../src_pw/global.h" + +// [etxc, vtxc, v] = XC_Functional::v_xc(...) +std::tuple XC_Functional::v_xc( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell + const double*const*const rho_in, + const double*const rho_core) // core charge density +{ + ModuleBase::TITLE("XC_Functional","v_xc"); + ModuleBase::timer::tick("XC_Functional","v_xc"); + +#ifndef USE_LIBXC + if(func_type == 3) + { + ModuleBase::WARNING_QUIT("Potential::v_of_rho","to use metaGGA, please link LIBXC"); + } +#endif + + if((GlobalV::NSPIN == 1 || GlobalV::NSPIN == 2) && use_libxc) + { + return v_xc_libxc(nrxx, ncxyz, omega, rho_in, rho_core); + } + + //Exchange-Correlation potential Vxc(r) from n(r) + double etxc = 0.0; + double vtxc = 0.0; + ModuleBase::matrix v(GlobalV::NSPIN, nrxx); + + // the square of the e charge + // in Rydeberg unit, so * 2.0. + double e2 = 2.0; + + double rhox = 0.0; + double arhox = 0.0; + double zeta = 0.0; + double exc = 0.0; + double vxc[2]; + + int ir, is; + + double vanishing_charge = 1.0e-10; + + if( (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 2) && use_libxc) + { + return v_xc_libxc(nrxx, ncxyz, omega, rho_in, rho_core); + } + + if (GlobalV::NSPIN == 1 || ( GlobalV::NSPIN ==4 && !GlobalV::DOMAG && !GlobalV::DOMAG_Z)) + { + // spin-unpolarized case + for (int ir = 0;ir < nrxx;ir++) + { + // total electron charge density + rhox = rho_in[0][ir] + rho_core[ir]; + arhox = abs(rhox); + if (arhox > vanishing_charge) + { + XC_Functional::xc(arhox, exc, vxc[0]); + v(0,ir) = e2 * vxc[0]; + // consider the total charge density + etxc += e2 * exc * rhox; + // only consider rho_in + vtxc += v(0, ir) * rho_in[0][ir]; + } // endif + } //enddo + } + else if(GlobalV::NSPIN ==2) + { + // spin-polarized case + for (ir = 0;ir < nrxx;ir++) + { + rhox = rho_in[0][ir] + rho_in[1][ir] + rho_core[ir]; //HLX(05-29-06): bug fixed + arhox = abs(rhox); + + if (arhox > vanishing_charge) + { + zeta = (rho_in[0][ir] - rho_in[1][ir]) / arhox; //HLX(05-29-06): bug fixed + + if (abs(zeta) > 1.0) + { + zeta = (zeta > 0.0) ? 1.0 : (-1.0); + } + + double rhoup = arhox * (1.0+zeta) / 2.0; + double rhodw = arhox * (1.0-zeta) / 2.0; + XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); + + for (is = 0;is < GlobalV::NSPIN;is++) + { + v(is, ir) = e2 * vxc[is]; + } + + etxc += e2 * exc * rhox; + vtxc += v(0, ir) * rho_in[0][ir] + v(1, ir) * rho_in[1][ir]; + } + } + } + else if(GlobalV::NSPIN == 4)//noncollinear case added by zhengdy + { + for( ir = 0;ir vanishing_charge ) + { + zeta = amag / arhox; + + if ( abs( zeta ) > 1.0 ) + { + zeta = (zeta > 0.0) ? 1.0 : (-1.0); + }//end if + + if(use_libxc) + { + double rhoup = arhox * (1.0+zeta) / 2.0; + double rhodw = arhox * (1.0-zeta) / 2.0; + XC_Functional::xc_spin_libxc(rhoup, rhodw, exc, vxc[0], vxc[1]); + } + else + { + double rhoup = arhox * (1.0+zeta) / 2.0; + double rhodw = arhox * (1.0-zeta) / 2.0; + XC_Functional::xc_spin(arhox, zeta, exc, vxc[0], vxc[1]); + } + + etxc += e2 * exc * rhox; + + v(0, ir) = e2*( 0.5 * ( vxc[0] + vxc[1]) ); + vtxc += v(0,ir) * rho_in[0][ir]; + + double vs = 0.5 * ( vxc[0] - vxc[1] ); + if ( amag > vanishing_charge ) + { + for(int ipol = 1;ipol< 4;ipol++) + { + v(ipol, ir) = e2 * vs * rho_in[ipol][ir] / amag; + vtxc += v(ipol,ir) * rho_in[ipol][ir]; + }//end do + }//end if + }//end if + }//end do + }//end if + // energy terms, local-density contributions + + // add gradient corrections (if any) + // mohan modify 2009-12-15 + gradcorr(etxc, vtxc, v); + + // parallel code : collect vtxc,etxc + // mohan add 2008-06-01 + Parallel_Reduce::reduce_double_pool( etxc ); + Parallel_Reduce::reduce_double_pool( vtxc ); + + etxc *= omega / ncxyz; + vtxc *= omega / ncxyz; + + ModuleBase::timer::tick("XC_Functional","v_xc"); + return std::make_tuple(etxc, vtxc, std::move(v)); +} + +#ifdef USE_LIBXC + +std::tuple XC_Functional::v_xc_libxc( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell + const double * const * const rho_in, + const double * const rho_core_in) +{ + ModuleBase::TITLE("XC_Functional","v_xc"); + ModuleBase::timer::tick("XC_Functional","v_xc"); + + const int nspin = GlobalV::NSPIN; + + double etxc = 0.0; + double vtxc = 0.0; + ModuleBase::matrix v(nspin,nrxx); + + //---------------------------------------------------------- + // xc_func_type is defined in Libxc package + // to understand the usage of xc_func_type, + // use can check on website, for example: + // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ + //---------------------------------------------------------- + + std::vector funcs = init_func( ( (1==nspin) ? XC_UNPOLARIZED:XC_POLARIZED ) ); + + bool is_gga = false; + for( xc_func_type &func : funcs ) + { + switch( func.info->family ) + { + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + is_gga = true; + break; + } + } + + // converting rho + std::vector rho; + rho.resize(GlobalC::pw.nrxx*nspin); + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + rho[ir*nspin+is] = rho_in[is][ir] + 1.0/nspin*rho_core_in[ir]; + } + } + + std::vector>> gdr; + std::vector sigma; + if(is_gga) + { + // calculating grho + gdr.resize( nspin ); + for( int is=0; is!=nspin; ++is ) + { + std::vector rhor(GlobalC::pw.nrxx); + for(int ir=0; ir> rhog(GlobalC::pw.ngmc); + GlobalC::CHR.set_rhog(rhor.data(), rhog.data()); + + //------------------------------------------- + // compute the gradient of charge density and + // store the gradient in gdr[is] + //------------------------------------------- + gdr[is].resize(GlobalC::pw.nrxx); + XC_Functional::grad_rho(rhog.data(), gdr[is].data()); + } + + // converting grho + sigma.resize( nrxx * ((1==nspin)?1:3) ); + + if( 1==nspin ) + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + sigma[ir] = gdr[0][ir]*gdr[0][ir]; + } + } + else + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + sigma[ir*3] = gdr[0][ir]*gdr[0][ir]; + sigma[ir*3+1] = gdr[0][ir]*gdr[1][ir]; + sigma[ir*3+2] = gdr[1][ir]*gdr[1][ir]; + } + } + } + + std::vector exc ( nrxx ); + std::vector vrho ( nrxx * nspin ); + std::vector vsigma( nrxx * ((1==nspin)?1:3) ); + + for( xc_func_type &func : funcs ) + { + + // jiyy add for threshold + const double rho_threshold = 1E-6; + const double grho_threshold = 1E-10; + // sgn for threshold mask + std::vector sgn( nrxx * nspin, 1.0); + + // in the case of GGA correlation for polarized case, + // a cutoff for grho is required to ensure that libxc gives reasonable results + if(nspin==2 && func.info->family != XC_FAMILY_LDA && func.info->kind==XC_CORRELATION) + { + for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + if ( rho[ir*2]family ) + { + case XC_FAMILY_LDA: + // call Libxc function: xc_lda_exc_vxc + xc_lda_exc_vxc( &func, nrxx, rho.data(), + exc.data(), vrho.data() ); + break; + case XC_FAMILY_GGA: + case XC_FAMILY_HYB_GGA: + // call Libxc function: xc_gga_exc_vxc + xc_gga_exc_vxc( &func, nrxx, rho.data(), sigma.data(), + exc.data(), vrho.data(), vsigma.data() ); + break; + default: + throw std::domain_error("func.info->family ="+ModuleBase::GlobalFunc::TO_STRING(func.info->family) + +" unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + break; + } + + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin+is] * sgn[ir*nspin+is]; + } + } + + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + const double v_tmp = ModuleBase::e2 * vrho[ir*nspin+is] * sgn[ir*nspin+is]; + v(is,ir) += v_tmp; + vtxc += v_tmp * rho_in[is][ir]; + } + } + + if(func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) + { + std::vector>> h( nspin, std::vector>(nrxx) ); + if( 1==nspin ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = 2.0 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; + } + } + else + { + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = 2.0 * (gdr[0][ir] * vsigma[ir*3 ] * sgn[ir*2 ] * 2.0 + + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + h[1][ir] = 2.0 * (gdr[1][ir] * vsigma[ir*3+2] * sgn[ir*2+1] * 2.0 + + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + } + } + + // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] + std::vector> dh(nspin, std::vector( nrxx)); + for( int is=0; is!=nspin; ++is ) + { + XC_Functional::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); + } + + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + vtxc -= dh[is][ir] * rho[ir*nspin+is]; + v(is,ir) -= dh[is][ir]; + } + } + } + } + + //------------------------------------------------- + // for MPI, reduce the exchange-correlation energy + //------------------------------------------------- + Parallel_Reduce::reduce_double_pool( etxc ); + Parallel_Reduce::reduce_double_pool( vtxc ); + + etxc *= omega / ncxyz; + vtxc *= omega / ncxyz; + + ModuleBase::timer::tick("XC_Functional","v_xc"); + return std::make_tuple( etxc, vtxc, std::move(v) ); +} + +//the interface to libxc xc_mgga_exc_vxc(xc_func,n,rho,grho,laplrho,tau,e,v1,v2,v3,v4) +//xc_func : LIBXC data type, contains information on xc functional +//n: size of array, nspin*nnr +//rho,grho,laplrho: electron density, its gradient and laplacian +//tau(kin_r): kinetic energy density +//e: energy density +//v1-v4: derivative of energy density w.r.t rho, gradient, laplacian and tau +//v1 and v2 are combined to give v; v4 goes into vofk + +//XC_POLARIZED, XC_UNPOLARIZED: internal flags used in LIBXC, denote the polarized(nspin=1) or unpolarized(nspin=2) calculations, definition can be found in xc.h from LIBXC + +// [etxc, vtxc, v, vofk] = XC_Functional::v_xc(...) +tuple XC_Functional::v_xc_meta( + const int &nrxx, // number of real-space grid + const int &ncxyz, // total number of charge grid + const double &omega, // volume of cell + const double * const * const rho_in, + const double * const rho_core_in, + const double * const * const kin_r_in) +{ + ModuleBase::TITLE("XC_Functional","v_xc"); + ModuleBase::timer::tick("XC_Functional","v_xc"); + + double e2 = 2.0; + + //output of the subroutine + double etxc = 0.0; + double vtxc = 0.0; + ModuleBase::matrix v(GlobalV::NSPIN,nrxx); + ModuleBase::matrix vofk(GlobalV::NSPIN,nrxx); + + //---------------------------------------------------------- + // xc_func_type is defined in Libxc package + // to understand the usage of xc_func_type, + // use can check on website, for example: + // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ + //---------------------------------------------------------- + + //initialize X and C functionals + xc_func_type x_func; + xc_func_type c_func; + const int xc_polarized = (GlobalV::NSPIN ? XC_UNPOLARIZED : XC_POLARIZED); + + //exchange + if( func_id[0] == 263) + { + xc_func_init(&x_func, 263 ,xc_polarized); + } + else + { + throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + } + + //correlation + if( func_id[1] == 267) + { + xc_func_init(&c_func, 267 ,xc_polarized); + } + else + { + throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + } + + //rho,grho,tau + vector> rho; + vector>> grho; + vector> kin_r; + + //dExc/d rho,grho,tau + vector> vrho; + vector>> h; + vector> kedtaur; + + //rho : from double** to vector + rho.resize(GlobalV::NSPIN); + for( int is=0; is!=GlobalV::NSPIN; ++is ) + { + rho[is].resize(nrxx); + for( int ir=0; ir!=nrxx; ++ir ) + { + rho[is][ir] = rho_in[is][ir] + (1.0/GlobalV::NSPIN)*rho_core_in[ir]; + } + } + + //grho : calculate gradient + grho.resize(GlobalV::NSPIN); + for( int is=0; is!=GlobalV::NSPIN; ++is ) + { + grho[is].resize(nrxx); + + vector> rhog(GlobalC::pw.ngmc); + GlobalC::CHR.set_rhog(rho[is].data(), rhog.data()); + XC_Functional::grad_rho(rhog.data(), grho[is].data()); + } + + //kin_r : from double** to vector + kin_r.resize(GlobalV::NSPIN); + if(GlobalV::NSPIN==1 || GlobalV::NSPIN==2) + { + for( int is=0; is!=GlobalV::NSPIN; ++is ) + { + kin_r[is].resize(nrxx); + for( int ir=0; ir!=nrxx; ++ir ) + { + kin_r[is][ir] = kin_r_in[is][ir]; + } + } + } + + if(GlobalV::NSPIN==1) + { + vrho.resize(GlobalV::NSPIN); + h.resize(GlobalV::NSPIN); + kedtaur.resize(GlobalV::NSPIN); + + for( int is=0; is!=GlobalV::NSPIN; ++is ) + { + vrho[is].resize(nrxx); + h[is].resize(nrxx); + kedtaur[is].resize(nrxx); + + double arho, grho2, atau, lapl; + double ex, ec, v1x, v2x, v3x, v1c, v2c, v3c, vlapl; + const double rho_th = 1e-8; + const double grho_th = 1e-12; + const double tau_th = 1e-8; + + + for( int ir=0; ir!=nrxx; ++ir ) + { + arho = abs(rho_in[is][ir]); + grho2 = grho[0][ir]*grho[0][ir]; + atau = kin_r[is][ir] / e2; + lapl = grho2;//dummy argument, not used + + if(arho > rho_th && grho2 > grho_th && abs(atau) > tau_th) + { + xc_mgga_exc_vxc(&x_func,1,&arho,&grho2,&lapl,&atau,&ex,&v1x,&v2x,&vlapl,&v3x); + xc_mgga_exc_vxc(&c_func,1,&arho,&grho2,&lapl,&atau,&ec,&v1c,&v2c,&vlapl,&v3c); + ex = ex * rho[is][ir]; + ec = ec * rho[is][ir]; + v2x = v2x * e2; + v2c = v2c * e2; + + vrho[is][ir] = (v1x + v1c) * e2; + h[is][ir] = (v2x + v2c) * e2 * grho[is][ir]; + kedtaur[is][ir] = v3x + v3c; + + etxc += (ex + ec) * e2; + vtxc += (v1x + v1c) * e2 * arho; + } + else + { + vrho[is][ir] = 0.0; + h[is][ir] = 0.0; + kedtaur[is][ir] = 0.0; + } + }//loop over grid points + }//loop over spin + }//nspin=1 + else if(GlobalV::NSPIN==2) + { + vrho.resize(GlobalV::NSPIN); + h.resize(GlobalV::NSPIN); + kedtaur.resize(GlobalV::NSPIN); + + for( int is=0; is!=GlobalV::NSPIN; ++is ) + { + vrho[is].resize(nrxx); + h[is].resize(nrxx); + kedtaur[is].resize(nrxx); + } + + double rh, ggrho2, atau; + double rhoup, rhodw, tauup, taudw; + double ex, v1xup, v1xdw, v2xup, v2xdw, v3xup, v3xdw; + double ec, v1cup, v1cdw, v3cup, v3cdw; + ModuleBase::Vector3 grhoup,grhodw,v2cup,v2cdw; + + XC_Functional::Mgga_spin_in mgga_spin_in; + XC_Functional::Mgga_spin_out mgga_spin_out; + + + const double rho_th = 1e-8; + const double grho_th = 1e-12; + const double tau_th = 1e-8; + + for( int ir=0; ir!=nrxx; ++ir ) + { + + auto set_input_tau_spin = [&]() + { + mgga_spin_in.rhoup = rho_in[0][ir]; + mgga_spin_in.rhodw = rho_in[1][ir]; + rh = rho_in[0][ir] + rho_in[1][ir]; + + mgga_spin_in.grhoup = grho[0][ir]; + mgga_spin_in.grhodw = grho[1][ir]; + ggrho2 = (grho[0][ir]*grho[0][ir] + grho[1][ir]*grho[1][ir]) * 4.0; + + mgga_spin_in.tauup = kin_r[0][ir] / e2; + mgga_spin_in.taudw = kin_r[1][ir] / e2; + atau = (kin_r[0][ir]+kin_r[1][ir])/ e2; + }; + + auto set_output_tau_spin = [&]() + { + vrho[0][ir] = (mgga_spin_out.v1xup+mgga_spin_out.v1cup) * e2; + vrho[1][ir] = (mgga_spin_out.v1xdw+mgga_spin_out.v1cdw) * e2; + + h[0][ir] = (mgga_spin_out.v2xup*grhoup+mgga_spin_out.v2cup)*e2; + h[1][ir] = (mgga_spin_out.v2xdw*grhodw+mgga_spin_out.v2cdw)*e2; + + kedtaur[0][ir] = mgga_spin_out.v3xup+mgga_spin_out.v3cup; + kedtaur[1][ir] = mgga_spin_out.v3xdw+mgga_spin_out.v3cdw; + + etxc += (mgga_spin_out.ex+mgga_spin_out.ec) * e2; + vtxc += (mgga_spin_out.v1xup+mgga_spin_out.v1xdw+mgga_spin_out.v1cup+mgga_spin_out.v1cdw) * e2 * rh; + }; + + if (rh > rho_th && ggrho2 > grho_th && abs(atau) > tau_th) + { + set_input_tau_spin(); + XC_Functional::tau_xc_spin(mgga_spin_in, mgga_spin_out); + set_output_tau_spin(); + } + else + { + vrho[0][ir] = 0.0; + vrho[1][ir] = 0.0; + + h[0][ir]=0.0; + h[1][ir]=0.0; + + kedtaur[0][ir] = 0.0; + kedtaur[1][ir] = 0.0; + } + }//end loop grid points + }//nspin=2 + else + { + ModuleBase::WARNING_QUIT("v_xc_meta","meta-GGA has not been implemented for nspin = 4 yet"); + } + + vector dh; + dh.resize(nrxx); + + for(int is=0;is= 0.0 ) segno = 1.0; if( rhotmp1[ir] < 0.0 ) segno = -1.0; - if(use_libxc) - { - XC_Functional::gcxc_libxc( arho, grho2a, sxc, v1xc, v2xc ); - v(0,ir) += ModuleBase::e2 * v1xc; - h1[ir] = ModuleBase::e2 * 2.0 * v2xc * gdr1[ir]; - etxcgc += ModuleBase::e2* sxc * arho * segno; - vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); - } - else - { - XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); - // first term of the gradient correction: - // D(rho*Exc)/D(rho) - v(0, ir) += ModuleBase::e2 * v1xc; - - // h contains - // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; - - vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); - etxcgc += ModuleBase::e2* sxc * segno; - } + XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); + // first term of the gradient correction: + // D(rho*Exc)/D(rho) + v(0, ir) += ModuleBase::e2 * v1xc; + + // h contains + // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; + + vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); + etxcgc += ModuleBase::e2* sxc * segno; } // end arho > epsr } }// end nspin0 == 1 diff --git a/source/src_io/write_input.cpp b/source/src_io/write_input.cpp index 7fffb914368..0590a78de0e 100644 --- a/source/src_io/write_input.cpp +++ b/source/src_io/write_input.cpp @@ -195,7 +195,6 @@ void Input::Print(const std::string &fn)const ModuleBase::GlobalFunc::OUTP(ofs,"vl_in_h", vl_in_h,"calculate the local potential or not"); ModuleBase::GlobalFunc::OUTP(ofs,"vnl_in_h", vnl_in_h,"calculate the nonlocal potential or not"); ModuleBase::GlobalFunc::OUTP(ofs,"vh_in_h", vh_in_h,"calculate the hartree potential or not"); - ModuleBase::GlobalFunc::OUTP(ofs,"vxc_in_h", vxc_in_h,"calculate the xc potential or not"); ModuleBase::GlobalFunc::OUTP(ofs,"vion_in_h", vion_in_h,"calculate the local ionic potential or not"); ModuleBase::GlobalFunc::OUTP(ofs,"test_force", test_force, "test the force"); ModuleBase::GlobalFunc::OUTP(ofs,"test_stress", test_stress, "test the force"); diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index f605f8d350d..8f0c290383a 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -562,16 +562,20 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) if(XC_Functional::get_func_type() == 3) { -#ifdef USE_LIBXC - const auto etxc_vtxc_v = XC_Functional::v_xc_meta(GlobalC::CHR.rho, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); + const auto etxc_vtxc_v = XC_Functional::v_xc_meta( + GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, + GlobalC::CHR.rho, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); -#endif } else { - const auto etxc_vtxc_v = XC_Functional::v_xc(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core); + const auto etxc_vtxc_v = XC_Functional::v_xc( + GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, + GlobalC::CHR.rho, GlobalC::CHR.rho_core); + GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index a14b8049a4c..acba9fb8f50 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -326,13 +326,11 @@ ModuleBase::matrix Potential::v_of_rho( if(XC_Functional::get_func_type() == 3) { -#ifdef USE_LIBXC - const std::tuple etxc_vtxc_v = XC_Functional::v_xc_meta(rho_in, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); + const std::tuple etxc_vtxc_v = XC_Functional::v_xc_meta(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); vofk = std::get<3>(etxc_vtxc_v); -#endif } else { From 77e32c3d2b17328436478caaa55d40ab5154eb39 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Thu, 3 Mar 2022 17:34:43 +0800 Subject: [PATCH 15/36] xc_refactor : fix a bug --- source/module_xc/xc_functional.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index 43ef654b2ca..61c12fc296f 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -135,7 +135,7 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) std::cerr << "\n OPTX untested please test,"; } - if(func_type == 2 && GlobalV::BASIS_TYPE != "pw") + if(func_type == 3 && GlobalV::BASIS_TYPE != "pw") { ModuleBase::WARNING_QUIT("set_xc_type","mGGA not realized for LCAO yet"); } From 37a1e77a36f5a6b4bd1377935d0552cf42f3707b Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 4 Mar 2022 11:57:31 +0800 Subject: [PATCH 16/36] xc refactor : use gradcorr in stress calculation instead of gcxc --- source/module_xc/xc_functional.h | 2 +- source/module_xc/xc_functional_vxc.cpp | 6 +- source/module_xc/xc_gga_pw.cpp | 274 ++++++++++++++++--------- source/src_pw/stress_func_gga.cpp | 207 ++----------------- 4 files changed, 200 insertions(+), 289 deletions(-) diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index e2e97bd1cb5..351a7076f0d 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -69,7 +69,7 @@ class XC_Functional ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud); - static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v); + static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, std::vector &stress_gga, const bool is_stress = 0); static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); static void grad_dot( const ModuleBase::Vector3 *h, double *dh); diff --git a/source/module_xc/xc_functional_vxc.cpp b/source/module_xc/xc_functional_vxc.cpp index b25104ad35f..1592263e785 100644 --- a/source/module_xc/xc_functional_vxc.cpp +++ b/source/module_xc/xc_functional_vxc.cpp @@ -160,7 +160,11 @@ std::tuple XC_Functional::v_xc( // add gradient corrections (if any) // mohan modify 2009-12-15 - gradcorr(etxc, vtxc, v); + + // the dummy variable dum contains gradient correction to stress + // which is not used here + std::vector dum; + gradcorr(etxc, vtxc, v, dum); // parallel code : collect vtxc,etxc // mohan add 2008-06-01 diff --git a/source/module_xc/xc_gga_pw.cpp b/source/module_xc/xc_gga_pw.cpp index 15729525391..5ab0363967e 100644 --- a/source/module_xc/xc_gga_pw.cpp +++ b/source/module_xc/xc_gga_pw.cpp @@ -2,7 +2,7 @@ #include "xc_functional.h" // from gradcorr.f90 -void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) +void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, std::vector &stress_gga, const bool is_stress) { ModuleBase::TITLE("XC_Functional","gradcorr"); @@ -19,6 +19,15 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) assert(nspin0>0); const double fac = 1.0/ nspin0; + if(is_stress) + { + stress_gga.resize(9); + for(int i=0;i<9;i++) + { + stress_gga[i] = 0.0; + } + } + // doing FFT to get rho in G space: rhog1 GlobalC::CHR.set_rhog(GlobalC::CHR.rho[0], GlobalC::CHR.rhog[0]); if(GlobalV::NSPIN==2)//mohan fix bug 2012-05-28 @@ -51,7 +60,7 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) for(int ig=0; ig[GlobalC::pw.nrxx]; - h1 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; + if(!is_stress) h1 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; XC_Functional::grad_rho( rhogsum1 , gdr1 ); @@ -67,7 +76,7 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) for(int ig=0; ig[GlobalC::pw.nrxx]; - h2 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; + if(!is_stress) h2 = new ModuleBase::Vector3[GlobalC::pw.nrxx]; XC_Functional::grad_rho( rhogsum2 , gdr2 ); } @@ -80,17 +89,19 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) ModuleBase::GlobalFunc::ZEROS(rhotmp2, GlobalC::pw.nrxx); neg = new double [GlobalC::pw.nrxx]; ModuleBase::GlobalFunc::ZEROS(neg, GlobalC::pw.nrxx); - vsave = new double* [GlobalV::NSPIN]; - for(int is = 0;is[GlobalC::pw.ngmc]; @@ -133,7 +144,7 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) for(int ir=0; ir epsr) { @@ -143,16 +154,34 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) if( rhotmp1[ir] < 0.0 ) segno = -1.0; XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); - // first term of the gradient correction: - // D(rho*Exc)/D(rho) - v(0, ir) += ModuleBase::e2 * v1xc; - - // h contains - // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; - - vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); - etxcgc += ModuleBase::e2* sxc * segno; + if(is_stress) + { + 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++) + { + int ind = l*3 + m; + stress_gga[ind] += tt[l] * tt[m] * ModuleBase::e2 * v2xc; + } + } + } + else + { + // first term of the gradient correction: + // D(rho*Exc)/D(rho) + v(0, ir) += ModuleBase::e2 * v1xc; + + // h contains + // D(rho*Exc) / D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] = ModuleBase::e2 * v2xc * gdr1[ir]; + + vtxcgc += ModuleBase::e2* v1xc * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] ); + etxcgc += ModuleBase::e2* sxc * segno; + } } // end arho > epsr } }// end nspin0 == 1 @@ -165,17 +194,43 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) double sxc, v1xcup, v1xcdw, v2xcup, v2xcdw, v2xcud; XC_Functional::gcxc_spin_libxc(rhotmp1[ir], rhotmp2[ir], gdr1[ir], gdr2[ir], sxc, v1xcup, v1xcdw, v2xcup, v2xcdw, v2xcud); - // first term of the gradient correction : D(rho*Exc)/D(rho) - v(0,ir) += ModuleBase::e2 * v1xcup; - v(1,ir) += ModuleBase::e2 * v1xcdw; - - // h contains D(rho*Exc)/D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] += ModuleBase::e2 * ( v2xcup * gdr1[ir] + v2xcud * gdr2[ir] ); - h2[ir] += ModuleBase::e2 * ( v2xcdw * gdr2[ir] + v2xcud * gdr1[ir] ); + if(is_stress) + { + 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++) + { + int ind = l*3 + m; + stress_gga [ind] += ( tt1[l] * tt1[m] * v2xcup + + tt2[l] * tt2[m] * v2xcdw + + (tt1[l] * tt2[m] + + tt2[l] * tt1[m] ) * v2xcud ) * ModuleBase::e2; + } + } + } + else + { + // first term of the gradient correction : D(rho*Exc)/D(rho) + v(0,ir) += ModuleBase::e2 * v1xcup; + v(1,ir) += ModuleBase::e2 * v1xcdw; + + // h contains D(rho*Exc)/D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] += ModuleBase::e2 * ( v2xcup * gdr1[ir] + v2xcud * gdr2[ir] ); + h2[ir] += ModuleBase::e2 * ( v2xcdw * gdr2[ir] + v2xcud * gdr1[ir] ); - vtxcgc = vtxcgc + ModuleBase::e2 * v1xcup * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] * fac ); - vtxcgc = vtxcgc + ModuleBase::e2 * v1xcdw * ( rhotmp2[ir] - GlobalC::CHR.rho_core[ir] * fac ); - etxcgc = etxcgc + ModuleBase::e2 * sxc; + vtxcgc = vtxcgc + ModuleBase::e2 * v1xcup * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] * fac ); + vtxcgc = vtxcgc + ModuleBase::e2 * v1xcdw * ( rhotmp2[ir] - GlobalC::CHR.rho_core[ir] * fac ); + etxcgc = etxcgc + ModuleBase::e2 * sxc; + } } else { @@ -225,17 +280,47 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) v2cud = 0.0; } - // first term of the gradient correction : D(rho*Exc)/D(rho) - v(0,ir) = v(0,ir) + ModuleBase::e2 * ( v1xup + v1cup ); - v(1,ir) = v(1,ir) + ModuleBase::e2 * ( v1xdw + v1cdw ); - - // h contains D(rho*Exc)/D(|grad rho|) * (grad rho) / |grad rho| - h1[ir] = ModuleBase::e2 * ( ( v2xup + v2cup ) * gdr1[ir] + v2cud * gdr2[ir] ); - h2[ir] = ModuleBase::e2 * ( ( v2xdw + v2cdw ) * gdr2[ir] + v2cud * gdr1[ir] ); + if(is_stress) + { + 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++) + { + int ind = l*3 + m; + // exchange + stress_gga [ind] += tt1[l] * tt1[m] * ModuleBase::e2 * v2xup + + tt2[l] * tt2[m] * ModuleBase::e2 * v2xdw; + // correlation + stress_gga [ind] += ( tt1[l] * tt1[m] * v2cup + + tt2[l] * tt2[m] * v2cdw + + (tt1[l] * tt2[m] + + tt2[l] * tt1[m] ) * v2cud ) * ModuleBase::e2; + } + } + } + else + { + // first term of the gradient correction : D(rho*Exc)/D(rho) + v(0,ir) = v(0,ir) + ModuleBase::e2 * ( v1xup + v1cup ); + v(1,ir) = v(1,ir) + ModuleBase::e2 * ( v1xdw + v1cdw ); + + // h contains D(rho*Exc)/D(|grad rho|) * (grad rho) / |grad rho| + h1[ir] = ModuleBase::e2 * ( ( v2xup + v2cup ) * gdr1[ir] + v2cud * gdr2[ir] ); + h2[ir] = ModuleBase::e2 * ( ( v2xdw + v2cdw ) * gdr2[ir] + v2cud * gdr1[ir] ); - vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xup + v1cup ) * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] * fac ); - vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xdw + v1cdw ) * ( rhotmp2[ir] - GlobalC::CHR.rho_core[ir] * fac ); - etxcgc = etxcgc + ModuleBase::e2 * ( sx + sc ); + vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xup + v1cup ) * ( rhotmp1[ir] - GlobalC::CHR.rho_core[ir] * fac ); + vtxcgc = vtxcgc + ModuleBase::e2 * ( v1xdw + v1cdw ) * ( rhotmp2[ir] - GlobalC::CHR.rho_core[ir] * fac ); + etxcgc = etxcgc + ModuleBase::e2 * ( sx + sc ); + } } }// end ir @@ -244,86 +329,91 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v) //std::cout << "\n vtxcgc=" << vtxcgc; //std::cout << "\n etxcgc=" << etxcgc << std::endl; - for(int ir=0; ir1e-12) + for(int ir=0;ir1e-12) + { + for(int i=1;i<4;i++) + v(i,ir)+= neg[ir] * 0.5 *(vgg[0][ir]-vgg[1][ir])*GlobalC::CHR.rho[i][ir]/amag; + } } } } - // deacllocate delete[] rhotmp1; delete[] rhogsum1; delete[] gdr1; - delete[] h1; + if(!is_stress) delete[] h1; if(GlobalV::NSPIN==2) { delete[] rhotmp2; delete[] rhogsum2; delete[] gdr2; - delete[] h2; + if(!is_stress) delete[] h2; } if(GlobalV::NSPIN == 4 && (GlobalV::DOMAG||GlobalV::DOMAG_Z)) { delete[] neg; - for(int i=0; i0); - const double fac = 1.0/ nspin_in; - - // doing FFT to get rho in G space: rhog1 - GlobalC::CHR.set_rhog(GlobalC::CHR.rho[0], GlobalC::CHR.rhog[0]); - if(nspin_in==2)//mohan fix bug 2012-05-28 - { - GlobalC::CHR.set_rhog(GlobalC::CHR.rho[1], GlobalC::CHR.rhog[1]); - } - GlobalC::CHR.set_rhog(GlobalC::CHR.rho_core, GlobalC::CHR.rhog_core); - - double* rhotmp1; - double* rhotmp2; - std::complex* rhogsum1; - std::complex* rhogsum2; - ModuleBase::Vector3* gdr1; - ModuleBase::Vector3* gdr2; - - rhotmp1 = new double[GlobalC::pw.nrxx]; - rhogsum1 = new std::complex[GlobalC::pw.ngmc]; - ModuleBase::GlobalFunc::ZEROS(rhotmp1, GlobalC::pw.nrxx); - ModuleBase::GlobalFunc::ZEROS(rhogsum1, GlobalC::pw.ngmc); - for(int ir=0; ir[GlobalC::pw.nrxx]; - ModuleBase::GlobalFunc::ZEROS(gdr1, GlobalC::pw.nrxx); - - XC_Functional::grad_rho( rhogsum1 , gdr1 ); - - if(nspin_in==2) - { - rhotmp2 = new double[GlobalC::pw.nrxx]; - rhogsum2 = new std::complex[GlobalC::pw.ngmc]; - ModuleBase::GlobalFunc::ZEROS(rhotmp2, GlobalC::pw.nrxx); - ModuleBase::GlobalFunc::ZEROS(rhogsum2, GlobalC::pw.ngmc); - for(int ir=0; ir[GlobalC::pw.nrxx]; - ModuleBase::GlobalFunc::ZEROS(gdr2, GlobalC::pw.nrxx); - - XC_Functional::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 atau = 0.0; - double sx = 0.0; - double sc = 0.0; - double v1x = 0.0; - double v2x = 0.0; - double v3x = 0.0; - double v1c = 0.0; - double v2c = 0.0; - double v3c = 0.0; - double sxc = 0.0; - double v1xc = 0.0; - double v2xc = 0.0; - - if(nspin_in==1||nspin_in==4) - { - for(int ir=0; ir epsr) - { - grho2a = gdr1[ir].norm2(); - if( grho2a > epsg ) - { - if(XC_Functional::get_func_type() == 3) - { -#ifdef USE_LIBXC - atau = GlobalC::CHR.kin_r[0][ir]/2.0; - XC_Functional::tau_xc( arho, grho2a, atau, sx, sc, v1x, v2x, v3x, v1c, v2c, v3c); -#endif - } - else - { - XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); - } - 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] * ModuleBase::e2 * v2xc; - } - } - } - } - } - } - else if(nspin_in==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) - { - 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); - 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] * ModuleBase::e2 * v2xup + - tt2[l] * tt2[m] * ModuleBase::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 ) * ModuleBase::e2; - } - } - } - } + std::vector stress_gga; + double dum1, dum2; + ModuleBase::matrix dum3; + // call gradcorr to evaluate gradient correction to stress + // the first three terms are etxc, vtxc and v, which + // is not used here, so dummy variables are used. + XC_Functional::gradcorr(dum1, dum2, dum3, stress_gga, 1); for(int l = 0;l< 3;l++) { - for(int m = 0;m< l;m++) + for(int m = 0;m< l+1;m++) { + int ind = l*3 + m; + sigma_gradcorr[l][m] = stress_gga [ind]; sigma_gradcorr[m][l] = sigma_gradcorr[l][m]; } } + for(int l = 0;l<3;l++) { for(int m = 0;m<3;m++) @@ -207,14 +40,7 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) 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 /= GlobalC::pw.ncxyz ; - *p1++ += *p++; - }*/ - + for(int i=0;i<3;i++) { for(int j=0;j<3;j++) @@ -223,15 +49,6 @@ void Stress_Func::stress_gga(ModuleBase::matrix& sigma) } } - delete[] rhotmp1; - delete[] rhogsum1; - delete[] gdr1; - if(nspin_in==2) - { - delete[] rhotmp2; - delete[] rhogsum2; - delete[] gdr2; - } ModuleBase::timer::tick("Stress_Func","stress_gga"); return; } From 0812edcf5a0bf42f9147f7594f6d47565321ba2a Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 4 Mar 2022 14:56:20 +0800 Subject: [PATCH 17/36] xc refactor : move subroutines around; add comment --- source/module_xc/CMakeLists.txt | 5 +- source/module_xc/xc_functional.cpp | 579 ------------------ source/module_xc/xc_functional.h | 168 ++++- ..._gga_pw.cpp => xc_functional_gradcorr.cpp} | 0 .../module_xc/xc_functional_wrapper_gcxc.cpp | 330 ++++++++++ .../module_xc/xc_functional_wrapper_tauxc.cpp | 119 ++++ source/module_xc/xc_functional_wrapper_xc.cpp | 158 +++++ 7 files changed, 745 insertions(+), 614 deletions(-) rename source/module_xc/{xc_gga_pw.cpp => xc_functional_gradcorr.cpp} (100%) create mode 100644 source/module_xc/xc_functional_wrapper_gcxc.cpp create mode 100644 source/module_xc/xc_functional_wrapper_tauxc.cpp create mode 100644 source/module_xc/xc_functional_wrapper_xc.cpp diff --git a/source/module_xc/CMakeLists.txt b/source/module_xc/CMakeLists.txt index 2c01c8ec83a..b240d1e791b 100644 --- a/source/module_xc/CMakeLists.txt +++ b/source/module_xc/CMakeLists.txt @@ -1,7 +1,10 @@ list(APPEND objects xc_functional.cpp xc_functional_vxc.cpp - xc_gga_pw.cpp + xc_functional_gradcorr.cpp + xc_functional_wrapper_xc.cpp + xc_functional_wrapper_gcxc.cpp + xc_functional_wrapper_tauxc.cpp xc_funct_exch_lda.cpp xc_funct_corr_lda.cpp xc_funct_exch_gga.cpp diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index 61c12fc296f..aa660a8e3d9 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -1,8 +1,6 @@ #include "xc_functional.h" #include "../src_pw/global.h" #include "../module_base/global_function.h" -#include -#include XC_Functional::XC_Functional(){} @@ -181,583 +179,6 @@ void XC_Functional::set_xc_type_libxc(std::string xc_func_in) } #endif -void XC_Functional::xc(const double &rho, double &exc, double &vxc) -{ - - double third = 1.0 / 3.0; - double pi34 = 0.6203504908994e0 ; // pi34=(3/4pi)^(1/3) - double rs; - double e,v; - - exc = vxc = 0.00; - - rs = pi34 / std::pow(rho, third); - - for(int id : func_id) - { - switch( id ) - { - // Exchange functionals containing slater exchange - case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: - case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: - // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X - XC_Functional::slater(rs, e, v);break; - - // Exchange functionals containing attenuated slater exchange - case XC_HYB_GGA_XC_PBEH: - // PBE0 - XC_Functional::slater(rs, e, v); - e *= 0.75; v*= 0.75; - break; - - // Correlation functionals containing PW correlation - case XC_GGA_C_PBE: case XC_GGA_C_PW91: case XC_LDA_C_PW: - // PBC,PW91,PWLDA - XC_Functional::pw(rs, 0, e, v);break; - - // Correlation functionals containing PZ correlation - case XC_LDA_C_PZ: case XC_GGA_C_P86: - // PZ,P86 - XC_Functional::pz(rs, 0, e, v);break; - - // Correlation functionals containing LYP correlation - case XC_GGA_C_LYP: - // BLYP - XC_Functional::lyp(rs, e, v);break; - - // Functionals that are realized only using LIBXC - case XC_HYB_GGA_XC_HSE06: case XC_MGGA_X_SCAN: case XC_MGGA_C_SCAN: - // HSE,SCAN_X,SCAN_C - throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - - default: - e = v = 0.0; - } - exc += e; - vxc += v; - } - return; -} - -void XC_Functional::xc_spin_libxc(const double &rhoup, const double &rhodw, - double &exc, double &vxcup, double &vxcdw) -{ -#ifdef USE_LIBXC - double e, vup, vdw; - double *rho_ud, *vxc_ud; - exc = vxcup = vxcdw = 0.0; - - rho_ud = new double[2]; - vxc_ud = new double[2]; - rho_ud[0] = rhoup; - rho_ud[1] = rhodw; - - std::vector funcs = init_func(XC_POLARIZED); - - for(xc_func_type &func : funcs) - { - if( func.info->family == XC_FAMILY_LDA) - { - // call Libxc function: xc_lda_exc_vxc - xc_lda_exc_vxc( &func, 1, rho_ud, &e, vxc_ud); - } - exc += e; - vxcup += vxc_ud[0]; - vxcdw += vxc_ud[1]; - } - - - delete[] rho_ud; - delete[] vxc_ud; -#endif -} - -void XC_Functional::xc_spin(const double &rho, const double &zeta, - double &exc, double &vxcup, double &vxcdw) -{ - static const double small = 1.e-10; - double e, vup, vdw; - exc = vxcup = vxcdw = 0.0; - - static const double third = 1.0 / 3.0; - static const double pi34 = 0.62035049089940; - const double rs = pi34 / pow(rho, third);//wigner_sitz_radius; - - for(int id : func_id) - { - switch( id ) - { - // Exchange functionals containing slater exchange - case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: - case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: - // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X - XC_Functional::slater_spin(rho, zeta, e, vup, vdw); break; - - // Exchange functionals containing attenuated slater exchange - case XC_HYB_GGA_XC_PBEH: - // PBE0 - XC_Functional::slater_spin(rho, zeta, e, vup, vdw); - e *= 0.75; vup *= 0.75; vdw *=0.75; - break; - - // Correlation functionals containing PZ correlation - case XC_LDA_C_PZ: case XC_GGA_C_P86: - // PZ,P86 - XC_Functional::pz_spin(rs, zeta, e, vup, vdw); break; - - // Correlation functionals containing PW correlationtests/integrate/101_PW_OU_pseudopot - case XC_GGA_C_PBE: - // PBC,PBCsol - XC_Functional::pw_spin(rs, zeta, e, vup, vdw); break; - - // Correlation functionals that already contains LDA components - // so sets to 0 here - case XC_GGA_X_HCTH_A: case XC_GGA_C_HCTH_A: case XC_GGA_X_OPTX: - //HCTH_X HTCH_C OPTX - e = vup = vdw =0.0; - - // Cases that are only realized in LIBXC - default: - throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); break; - - } - exc += e; - vxcup += vup; - vxcdw += vdw; - } - return; -} - -//tau_xc and tau_xc_spin: interface for calling xc_mgga_exc_vxc from LIBXC -//XC_POLARIZED, XC_UNPOLARIZED: internal flags used in LIBXC, denote the polarized(nspin=1) or unpolarized(nspin=2) calculations, definition can be found in xc.h from LIBXC -#ifdef USE_LIBXC -void XC_Functional::tau_xc(const double &rho, const double &grho, const double &atau, double &sx, double &sc, - double &v1x, double &v2x, double &v3x, double &v1c, double &v2c, double &v3c) -{ - - double lapl_rho, vlapl_rho; - int func_id; - lapl_rho = grho; - -//initialize X and C functionals - xc_func_type x_func; - xc_func_type c_func; - const int xc_polarized = XC_UNPOLARIZED; - -//exchange - for(int id : XC_Functional::func_id) - { - switch( id ) - { - case 263: - xc_func_init(&x_func, 263 ,xc_polarized); - xc_mgga_exc_vxc(&x_func,1,&rho,&grho,&lapl_rho,&atau,&sx,&v1x,&v2x,&vlapl_rho,&v3x); - xc_func_end(&x_func); - sx = sx * rho; - v2x = v2x * 2.0; - break; - case 267: - xc_func_init(&c_func, 267 ,xc_polarized); - xc_mgga_exc_vxc(&c_func,1,&rho,&grho,&lapl_rho,&atau,&sc,&v1c,&v2c,&vlapl_rho,&v3c); - xc_func_end(&c_func); - sc = sc * rho; - v2c = v2c * 2.0; - break; - default: - throw std::domain_error( "functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - } - - return; -} - -void XC_Functional::tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out &mgga_spin_out) -{ -//initialize X and C functionals - xc_func_type x_func; - xc_func_type c_func; - const int xc_polarized = XC_POLARIZED; - - std::vector rho, grho2, tau; //density, gradient and kinetic energy density - std::vector v1x, v2x, v3x; //exchange potentials - std::vector v1c, v3c; //correlation potentials; v2c is in output - std::vector lapl_rho, vlapl_rho; //dummy variables, not used - double sx, sc; - - rho.resize(2); grho2.resize(3); tau.resize(2); - v1x.resize(2); v2x.resize(3); v3x.resize(2); - v1c.resize(3); mgga_spin_out.v2c.resize(3); v3c.resize(2); - lapl_rho.resize(6); vlapl_rho.resize(6); - - rho[0]=mgga_spin_in.rhoup; rho[1]=mgga_spin_in.rhodw; - grho2[0]=mgga_spin_in.grhoup*mgga_spin_in.grhoup; - grho2[1]=mgga_spin_in.grhoup*mgga_spin_in.grhodw; - grho2[2]=mgga_spin_in.grhodw*mgga_spin_in.grhodw; - tau[0]=mgga_spin_in.tauup; tau[1]=mgga_spin_in.taudw; - -//exchange - if (func_id[0]==263) - { - xc_func_init(&x_func, 263 ,xc_polarized); - xc_mgga_exc_vxc(&x_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sx,v1x.data(),v2x.data(),vlapl_rho.data(),v3x.data()); - xc_func_end(&x_func); - } - else - { - ModuleBase::WARNING_QUIT("tau_xc_spin","functional not implemented yet"); - } - -//correlation - if(func_id[1]==267) - { - xc_func_init(&c_func, 267 ,xc_polarized); - xc_mgga_exc_vxc(&c_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sc,v1c.data(),mgga_spin_out.v2c.data(),vlapl_rho.data(),v3c.data()); - xc_func_end(&c_func); - } - else - { - ModuleBase::WARNING_QUIT("tau_xc_spin","functional not implemented yet"); - } - - mgga_spin_out.ex = sx * (rho[0]+rho[1]); - mgga_spin_out.v1xup = v1x[0]; - mgga_spin_out.v2xup = v2x[0] * 2.0; - mgga_spin_out.v3xup = v3x[0]; - mgga_spin_out.v1xdw = v1x[1]; - mgga_spin_out.v2xdw = v2x[2] * 2.0; - mgga_spin_out.v3xdw = v3x[1]; - - mgga_spin_out.ec = sc * (rho[0]+rho[1]); - mgga_spin_out.v1cup = v1c[0]; - mgga_spin_out.v3cup = v3c[0]; - mgga_spin_out.v1cdw = v1c[1]; - mgga_spin_out.v3cdw = v3c[1]; - - mgga_spin_out.v2cup = mgga_spin_out.v2c[0]*mgga_spin_in.grhoup*2.0 - + mgga_spin_out.v2c[1]*mgga_spin_in.grhodw; - mgga_spin_out.v2cdw = mgga_spin_out.v2c[2]*mgga_spin_in.grhodw*2.0 - + mgga_spin_out.v2c[1]*mgga_spin_in.grhoup; - return; -} -#endif - -void XC_Functional::gcxc(const double &rho, const double &grho, double &sxc, - double &v1xc, double &v2xc) -{ - //----------------------------------------------------------------------- - // gradient corrections for exchange and correlation - Hartree a.u. - // exchange : Becke88 - // GGA (Generalized Gradient Approximation), PW91 - // PBE - // revPBE - // correlation: Perdew86 - // GGA (PW91) - // Lee-Yang-Parr - // PBE - // - // input: rho, grho=|\nabla rho|^2 - // definition: E_x = \int E_x(rho,grho) dr - // output: sx = E_x(rho,grho) - // v1x= D(E_x)/D(rho) - // v2x= D(E_x)/D( D rho/D r_alpha ) / |\nabla rho| - // sc, v1c, v2c as above for correlation - // - // use funct - // USE kinds - // implicit none - // real rho, grho, sx, sc, v1x, v2x, v1c, v2c; - double small = 1.e-10; - double s,v1,v2; - sxc = v1xc = v2xc = 0.0; - - if (rho <= small) - { - return; - } - - for(int id : func_id) - { - switch( id ) - { - case 106: //B88 - XC_Functional::becke88(rho, grho, s, v1, v2);break; - case 109: //PW91_X - XC_Functional::ggax(rho, grho, s, v1, v2);break; - case 101: //PBX - XC_Functional::pbex(rho, grho, 0, s, v1, v2);break; - case 117: //revised PBX - XC_Functional::pbex(rho, grho, 1, s, v1, v2);break; - case 34: //HCTH_X - XC_Functional::hcth(rho, grho, s, v1, v2);break; //XC together - case 97: //HCTH_C - s = 0.0; v1 = 0.0; v2 = 0.0;break; - case 110: //OPTX - XC_Functional::optx(rho, grho, s, v1, v2);break; - case 406: //PBE0 - XC_Functional::pbex(rho, grho, 0, s, v1, v2); - s *= 0.75; v1 *= 0.75; v2 *= 0.75;break; - case 116: //PBXsol - XC_Functional::pbex(rho, grho, 2, s, v1, v2);break; - case 118: //Wu-Cohen - XC_Functional::wcx (rho, grho, s, v1, v2);break; - case 132: //P86 - XC_Functional::perdew86(rho, grho, s, v1, v2);break; - case 134: //PW91_C - XC_Functional::ggac(rho, grho, s, v1, v2);break; - case 130: //PBC - XC_Functional::pbec(rho, grho, 0, s, v1, v2);break; - case 133: //PBCsol - XC_Functional::pbec(rho, grho, 1, s, v1, v2);break; - case 131: //BLYP - XC_Functional::glyp(rho, grho, s, v1, v2); break; - default: //SCAN_X,SCAN_C,HSE, and so on - throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - sxc += s; - v1xc += v1; - v2xc += v2; - } - - return; -} - -void XC_Functional::gcxc_spin_libxc(double rhoup, double rhodw, - ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, - double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud) -{ -#ifdef USE_LIBXC - std::vector funcs = init_func(XC_POLARIZED); - double *rho, *grho, *v1xc, *v2xc, *sgn, s; - sxc = v1xcup = v1xcdw = 0.0; - v2xcup = v2xcdw = v2xcud = 0.0; - rho = new double[2]; - grho= new double[3]; - v1xc= new double[2]; - v2xc= new double[3]; - sgn = new double[2]; - - rho[0] = rhoup; - rho[1] = rhodw; - grho[0] = gdr1.norm2(); - grho[1] = gdr1 * gdr2; - grho[2] = gdr2.norm2(); - - const double rho_threshold = 1E-6; - const double grho_threshold = 1E-10; - - for(xc_func_type &func : funcs) - { - if( func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) - { - sgn[0] = sgn[1] = 1.0; - // call Libxc function: xc_gga_exc_vxc - xc_gga_exc_vxc( &func, 1, rho, grho, &s, v1xc, v2xc); - if(func.info->kind==XC_CORRELATION) - { - if ( rho[0] small && sqrt(fabs(grhoup2)) > small) - { - XC_Functional::becke88_spin(rhoup, grhoup2, sxup, v1xup, v2xup); - } - if (rhodw > small && sqrt(fabs(grhodw2)) > small) - { - XC_Functional::becke88_spin(rhodw, grhodw2, sxdw, v1xdw, v2xdw); - } - break; - case 101: //PBX - if (rhoup > small && sqrt(fabs(grhoup2)) > small) - { - XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); - } - if (rhodw > small && sqrt(fabs(grhodw2)) > small) - { - XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 0, sxdw, v1xdw, v2xdw); - } - break; - case 117: //revised PBX - if (rhoup > small && sqrt(fabs(grhoup2)) > small) - { - XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 1, sxup, v1xup, v2xup); - } - if (rhodw > small && sqrt(fabs(grhodw2)) > small) - { - XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 1, sxdw, v1xdw, v2xdw); - } - break; - case 406: //PBE0 - if (rhoup > small && sqrt(fabs(grhoup2)) > small) - { - XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); - sxup *= 0.75; v1xup *= 0.75; v2xup *= 0.75; - } - if (rhodw > small && sqrt(fabs(grhodw2)) > small) - { - XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 0, sxdw, v1xdw, v2xdw); - sxdw *= 0.75; v1xdw *= 0.75; v2xdw *= 0.75; - } - break; - case 116: //PBXsol - if (rhoup > small && sqrt(fabs(grhoup2)) > small) - { - XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 2, sxup, v1xup, v2xup); - } - if (rhodw > small && sqrt(fabs(grhodw2)) > small) - { - XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 2, sxdw, v1xdw, v2xdw); - } - break; - default: - sxup = 0.0; sxdw = 0.0; - v1xup = 0.0; v2xup = 0.0; - v1xdw = 0.0; v2xdw = 0.0; - } - sx = 0.50 * (sxup + sxdw); - v2xup = 2.0 * v2xup; - v2xdw = 2.0 * v2xdw; - //} - - return; -} //end subroutine gcx_spin - -// -//----------------------------------------------------------------------- -void XC_Functional::gcc_spin(double rho, double &zeta, double grho, double &sc, - double &v1cup, double &v1cdw, double &v2c) -{ - //------------------------------------------------------------------- - // gradient corrections for correlations - Hartree a.u. - // Implemented: Perdew86, GGA (PW91), PBE - - // use funct - // USE kinds - // implicit none - - // dummy arguments - - // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c - // the total charge - // the magnetization - // the gradient of the charge squared - // exchange and correlation energies - // derivatives of correlation wr. rho - // derivatives of correlation wr. grho - - // parameter : - double small = 1.0e-10; - double epsr = 1.0e-6; - - double x; - - sc = 0.00; - v1cup = 0.00; v1cdw = 0.00; - v2c = 0.00; - if (abs(zeta) - 1.0 > small || rho <= small || sqrt(abs(grho)) <= small) - { - return; - } - else - { - // ... ( - 1.0 + epsr ) < zeta < ( 1.0 - epsr ) - // zeta = SIGN( MIN( ABS( zeta ), ( 1.D0 - epsr ) ) , zeta ) - x = std::min(abs(zeta), (1.0 - epsr)); - if(zeta>0) - { - zeta = x; - } - else - { - zeta = -x; - } - } //endif - - //for(int id : func_id) - //{ - int id = func_id[1]; - switch( id ) - { - case 132: //P86 - XC_Functional::perdew86_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; - case 134: //PW91_C - XC_Functional::ggac_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; - case 130: //PBC - XC_Functional::pbec_spin(rho, zeta, grho, 1, sc, v1cup, v1cdw, v2c);break; - case 133: //PBCsol - XC_Functional::pbec_spin(rho, zeta, grho, 2, sc, v1cup, v1cdw, v2c);break; - } - //} - return; -} //end subroutine gcc_spin - #ifdef USE_LIBXC std::vector XC_Functional::init_func(const int xc_polarized) { diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 351a7076f0d..ae7170801de 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -30,6 +30,23 @@ class XC_Functional XC_Functional(); ~XC_Functional(); +//------------------- +// subroutines, grouped according to the file they are in: +//------------------- + +//------------------- +// xc_functional_vxc.cpp +//------------------- + +// This file contains interface to the xc_functional class +// it includes 3 subroutines: +// 1. v_xc : which takes rho as input, and [etxc, vtxc, v_xc] as output +// 2. v_xc_libxc : which does the same thing as v_xc, but calling libxc +// NOTE : it is only used for nspin = 1 and 2, the nspin = 4 case is treated in v_xc +// 3. v_xc_meta : which takes rho and tau as input, and v_xc as output + + public: + // compute the exchange-correlation energy // [etxc, vtxc, v] = v_xc(...) static std::tuple v_xc( @@ -39,6 +56,7 @@ class XC_Functional const double*const*const rho_in, const double*const rho_core); // core charge density + // using libxc static std::tuple v_xc_libxc( const int &nrxx, // number of real-space grid const int &ncxyz, // total number of charge grid @@ -46,6 +64,7 @@ class XC_Functional const double*const*const rho_in, const double*const rho_core); // core charge density + // for mGGA functional static std::tuple v_xc_meta( const int &nrxx, // number of real-space grid const int &ncxyz, // total number of charge grid @@ -54,6 +73,90 @@ class XC_Functional const double * const rho_core_in, const double * const * const kin_r_in); +//------------------- +// xc_functional.cpp +//------------------- + +// This file contains subroutines for setting the functional +// it includes 4 subroutines: +// 1. get_func_type : which returns the type of functional (func_type): +// 0 = none; 1 = lda; 2 = gga; 3 = mgga; 4 = hybrid +// 2. set_xc_type : sets the value of: +// func_id, which is the LIBXC id of functional +// func_type, which is as specified in get_func_type +// use_libxc, whether to use LIBXC. The rule is to NOT use it for functionals that we already have. +// 3. set_xc_type_libxc : sets functional type, which allows combination of LIBXC keyword connected by "+" +// for example, "XC_LDA_X+XC_LDA_C_PZ" +// 4. init_func : which converts func_id into corresponding xc_func_type vector + + public: + + static int get_func_type(); + + private: + + static void set_xc_type(const std::string xc_func_in); +#ifdef USE_LIBXC + static void set_xc_type_libxc(const std::string xc_func_in); + static std::vector init_func(const int xc_polarized); +#endif + + static std::vector func_id; // libxc id of functional + static int func_type; //0:none, 1:lda, 2:gga, 3:mgga, 4:hybrid + static bool use_libxc; + +//------------------- +// xc_functional_wrapper_xc.cpp +//------------------- + +// This file contains wrapper for the LDA functionals +// it includes 3 subroutines: +// 1. xc, which is the wrapper of LDA part +// (i.e. LDA functional and LDA part of GGA functional) +// 2. xc_spin, which is the spin polarized counterpart of xc +// 3. xc_spin_libxc, which is the wrapper for LDA functional, spin polarized + +// NOTE : In our own realization of GGA functional, the LDA part +// and gradient correction are calculated separately. +// The LDA part is provided in xc, while the gradient correction is +// provided in gradcorr through gcxc/gcx_spin+gcc_spin. +// While in LIBXC, the entire GGA functional is provided. +// As a result, xc/xc_spin and xc_spin_libxc are different for GGA, +// the former gives nonzero result, while the latter returns 0. +// Furthermore, the reason for not having xc_libxc is that something like +// xc_libxc which evaluates functional for individual grid points +// is not efficient. For nspin = 1 and 2, v_xc_libxc evaluates potential +// on the entire grid. I'm having xc_spin_libxc because v_xc_libxc +// does not support nspin = 4. + + public : + + // LDA + static void xc(const double &rho, double &exc, double &vxc); + + // LSDA + static void xc_spin(const double &rho, const double &zeta, + double &exc, double &vxcup, double &vxcdw); + static void xc_spin_libxc(const double &rhoup, const double &rhodw, + double &exc, double &vxcup, double &vxcdw); + +//------------------- +// xc_functional_wrapper_gcxc.cpp +//------------------- + +// This file contains wrapper for the GGA functionals +// it includes 4 subroutines: +// 1. gcxc, which is the wrapper for gradient correction part +// 2. gcx_spin, spin polarized, exchange only +// 3. gcc_spin, spin polarized, correlation only +// 4. gcxc_spin_libxc, the entire GGA functional, LIBXC + +// The difference between our realization (gcxc/gcx_spin/gcc_spin) and +// LIBXC, and the reason for not having gcxc_libxc is explained +// in the NOTE in the comment for xc_functional_wrapper_wc.cpp part + + public: + // GGA static void gcxc(const double &rho, const double &grho, double &sxc, double &v1xc, double &v2xc); @@ -69,14 +172,20 @@ class XC_Functional ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud); - static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, std::vector &stress_gga, const bool is_stress = 0); - static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); - static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); - static void grad_dot( const ModuleBase::Vector3 *h, double *dh); - static void noncolin_rho(double *rhoout1,double *rhoout2,double *seg); +//------------------- +// xc_functional_wrapper_tauxc.cpp +//------------------- + +// This file contains wrapper for the mGGA functionals +// it includes 2 subroutines: +// 1. tau_xc +// 2. tau_xc_spin + +// NOTE : mGGA is realized through LIBXC - // mGGA #ifdef USE_LIBXC + public: + struct Mgga_spin_in { double rhoup, rhodw;//electron densities @@ -94,33 +203,34 @@ class XC_Functional ModuleBase::Vector3 v2cup, v2cdw; std::vector v2c;//vc: gga part, two different formats double v3cup, v3cdw;//vc: mgga part - }; + }; + + // mGGA static void tau_xc(const double &rho, const double &grho, const double &atau, double &sx, double &sc, double &v1x, double &v2x, double &v3x, double &v1c, double &v2c, double &v3c); static void tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out &mgga_spin_out); #endif - static int get_func_type(); +//------------------- +// xc_functional_gradcorr.cpp +//------------------- - private: +// This file contains subroutines realted to gradient calculations +// it contains 5 subroutines: +// 1. gradcorr, which calculates gradient correction +// 2. grad_wfc, which calculates gradient of wavefunction +// - static std::vector func_id; // id of exchange functional - static int func_type; //0:none, 1:lda, 2:gga, 3:mgga, 4:hybrid - static bool use_libxc; + public: - static void set_xc_type(const std::string xc_func_in); -#ifdef USE_LIBXC - static void set_xc_type_libxc(const std::string xc_func_in); - static std::vector init_func(const int xc_polarized); -#endif - // LDA - static void xc(const double &rho, double &exc, double &vxc); + static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, std::vector &stress_gga, const bool is_stress = 0); + static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); - // LSDA - static void xc_spin(const double &rho, const double &zeta, - double &exc, double &vxcup, double &vxcdw); - static void xc_spin_libxc(const double &rhoup, const double &rhodw, - double &exc, double &vxcup, double &vxcdw); + private: + + static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); + static void grad_dot( const ModuleBase::Vector3 *h, double *dh); + static void noncolin_rho(double *rhoout1,double *rhoout2,double *seg); // For LDA exchange energy static void slater(const double &rs, double &ex, double &vx); @@ -187,16 +297,6 @@ class XC_Functional double &v1cup, double &v1cdw, double &v2c); static void pbec_spin(double rho, double zeta, double grho, const int &flag, double &sc, double &v1cup, double &v1cdw, double &v2c); - - //---------------------------- - // decide the value of spin - //---------------------------- - static int nspin0() // may need updates from SOC - { - if (GlobalV::NSPIN==1 || (GlobalV::NSPIN==4 && (!GlobalV::DOMAG && !GlobalV::DOMAG_Z))) return 1; - else if(GlobalV::NSPIN==2 || (GlobalV::NSPIN==4 && ( GlobalV::DOMAG || GlobalV::DOMAG_Z))) return 2; - else throw std::runtime_error(ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } }; #endif //XC_FUNCTION_H diff --git a/source/module_xc/xc_gga_pw.cpp b/source/module_xc/xc_functional_gradcorr.cpp similarity index 100% rename from source/module_xc/xc_gga_pw.cpp rename to source/module_xc/xc_functional_gradcorr.cpp diff --git a/source/module_xc/xc_functional_wrapper_gcxc.cpp b/source/module_xc/xc_functional_wrapper_gcxc.cpp new file mode 100644 index 00000000000..d69f327fc67 --- /dev/null +++ b/source/module_xc/xc_functional_wrapper_gcxc.cpp @@ -0,0 +1,330 @@ +// This file contains wrapper for the GGA functionals +// it includes 4 subroutines: +// 1. gcxc, which is the wrapper for gradient correction part +// 2. gcx_spin, spin polarized, exchange only +// 3. gcc_spin, spin polarized, correlation only +// 4. gcxc_spin_libxc, the entire GGA functional, LIBXC + +#include "xc_functional.h" +#include +#include "../src_pw/global.h" +#include "../module_base/global_function.h" + +void XC_Functional::gcxc(const double &rho, const double &grho, double &sxc, + double &v1xc, double &v2xc) +{ + //----------------------------------------------------------------------- + // gradient corrections for exchange and correlation - Hartree a.u. + // exchange : Becke88 + // GGA (Generalized Gradient Approximation), PW91 + // PBE + // revPBE + // correlation: Perdew86 + // GGA (PW91) + // Lee-Yang-Parr + // PBE + // + // input: rho, grho=|\nabla rho|^2 + // definition: E_x = \int E_x(rho,grho) dr + // output: sx = E_x(rho,grho) + // v1x= D(E_x)/D(rho) + // v2x= D(E_x)/D( D rho/D r_alpha ) / |\nabla rho| + // sc, v1c, v2c as above for correlation + // + // use funct + // USE kinds + // implicit none + // real rho, grho, sx, sc, v1x, v2x, v1c, v2c; + double small = 1.e-10; + double s,v1,v2; + sxc = v1xc = v2xc = 0.0; + + if (rho <= small) + { + return; + } + + for(int id : func_id) + { + switch( id ) + { + case 106: //B88 + XC_Functional::becke88(rho, grho, s, v1, v2);break; + case 109: //PW91_X + XC_Functional::ggax(rho, grho, s, v1, v2);break; + case 101: //PBX + XC_Functional::pbex(rho, grho, 0, s, v1, v2);break; + case 117: //revised PBX + XC_Functional::pbex(rho, grho, 1, s, v1, v2);break; + case 34: //HCTH_X + XC_Functional::hcth(rho, grho, s, v1, v2);break; //XC together + case 97: //HCTH_C + s = 0.0; v1 = 0.0; v2 = 0.0;break; + case 110: //OPTX + XC_Functional::optx(rho, grho, s, v1, v2);break; + case 406: //PBE0 + XC_Functional::pbex(rho, grho, 0, s, v1, v2); + s *= 0.75; v1 *= 0.75; v2 *= 0.75;break; + case 116: //PBXsol + XC_Functional::pbex(rho, grho, 2, s, v1, v2);break; + case 118: //Wu-Cohen + XC_Functional::wcx (rho, grho, s, v1, v2);break; + case 132: //P86 + XC_Functional::perdew86(rho, grho, s, v1, v2);break; + case 134: //PW91_C + XC_Functional::ggac(rho, grho, s, v1, v2);break; + case 130: //PBC + XC_Functional::pbec(rho, grho, 0, s, v1, v2);break; + case 133: //PBCsol + XC_Functional::pbec(rho, grho, 1, s, v1, v2);break; + case 131: //BLYP + XC_Functional::glyp(rho, grho, s, v1, v2); break; + default: //SCAN_X,SCAN_C,HSE, and so on + throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + } + sxc += s; + v1xc += v1; + v2xc += v2; + } + + return; +} + +//----------------------------------------------------------------------- +void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double grhodw2, + double &sx, double &v1xup, double &v1xdw, double &v2xup, double &v2xdw) +{ + //-------------------------------------------------------------------- + // gradient corrections for exchange - Hartree a.u. + // Implemented: Becke88, GGA (PW91), PBE, revPBE + // + // use funct + // USE kinds + // implicit none + + // dummy arguments + + // real rhoup, rhodw, grhoup2, grhodw2, sx, v1xup, v1xdw, + // v2xup, v2xdw; + // up and down charge + // up and down gradient of the charge + // exchange and correlation energies + // derivatives of exchange wr. rho + // derivatives of exchange wr. grho + + // parameter : + double small = 1.e-10; + double sxup, sxdw; + int iflag; + + // exchange + double rho = rhoup + rhodw; + + sx = 0.00; + v1xup = 0.00; v2xup = 0.00; + v1xdw = 0.00; v2xdw = 0.00; + + if (rho <= small) + { + return; + } + + // not the correct way to do things, will change later + // should put exchange and correlation together + // like the others + //for(int id : func_id) + //{ + int id = func_id[0]; + switch( id ) + { + case 106: //B88 + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::becke88_spin(rhoup, grhoup2, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::becke88_spin(rhodw, grhodw2, sxdw, v1xdw, v2xdw); + } + break; + case 101: //PBX + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 0, sxdw, v1xdw, v2xdw); + } + break; + case 117: //revised PBX + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 1, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 1, sxdw, v1xdw, v2xdw); + } + break; + case 406: //PBE0 + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); + sxup *= 0.75; v1xup *= 0.75; v2xup *= 0.75; + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 0, sxdw, v1xdw, v2xdw); + sxdw *= 0.75; v1xdw *= 0.75; v2xdw *= 0.75; + } + break; + case 116: //PBXsol + if (rhoup > small && sqrt(fabs(grhoup2)) > small) + { + XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 2, sxup, v1xup, v2xup); + } + if (rhodw > small && sqrt(fabs(grhodw2)) > small) + { + XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 2, sxdw, v1xdw, v2xdw); + } + break; + default: + sxup = 0.0; sxdw = 0.0; + v1xup = 0.0; v2xup = 0.0; + v1xdw = 0.0; v2xdw = 0.0; + } + sx = 0.50 * (sxup + sxdw); + v2xup = 2.0 * v2xup; + v2xdw = 2.0 * v2xdw; + //} + + return; +} //end subroutine gcx_spin + +// +//----------------------------------------------------------------------- +void XC_Functional::gcc_spin(double rho, double &zeta, double grho, double &sc, + double &v1cup, double &v1cdw, double &v2c) +{ + //------------------------------------------------------------------- + // gradient corrections for correlations - Hartree a.u. + // Implemented: Perdew86, GGA (PW91), PBE + + // use funct + // USE kinds + // implicit none + + // dummy arguments + + // real(kind=DP) :: rho, zeta, grho, sc, v1cup, v1cdw, v2c + // the total charge + // the magnetization + // the gradient of the charge squared + // exchange and correlation energies + // derivatives of correlation wr. rho + // derivatives of correlation wr. grho + + // parameter : + double small = 1.0e-10; + double epsr = 1.0e-6; + + double x; + + sc = 0.00; + v1cup = 0.00; v1cdw = 0.00; + v2c = 0.00; + if (abs(zeta) - 1.0 > small || rho <= small || sqrt(abs(grho)) <= small) + { + return; + } + else + { + // ... ( - 1.0 + epsr ) < zeta < ( 1.0 - epsr ) + // zeta = SIGN( MIN( ABS( zeta ), ( 1.D0 - epsr ) ) , zeta ) + x = std::min(abs(zeta), (1.0 - epsr)); + if(zeta>0) + { + zeta = x; + } + else + { + zeta = -x; + } + } //endif + + //for(int id : func_id) + //{ + int id = func_id[1]; + switch( id ) + { + case 132: //P86 + XC_Functional::perdew86_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; + case 134: //PW91_C + XC_Functional::ggac_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; + case 130: //PBC + XC_Functional::pbec_spin(rho, zeta, grho, 1, sc, v1cup, v1cdw, v2c);break; + case 133: //PBCsol + XC_Functional::pbec_spin(rho, zeta, grho, 2, sc, v1cup, v1cdw, v2c);break; + } + //} + return; +} //end subroutine gcc_spin + +void XC_Functional::gcxc_spin_libxc(double rhoup, double rhodw, + ModuleBase::Vector3 gdr1, ModuleBase::Vector3 gdr2, + double &sxc, double &v1xcup, double &v1xcdw, double &v2xcup, double &v2xcdw, double &v2xcud) +{ +#ifdef USE_LIBXC + std::vector funcs = init_func(XC_POLARIZED); + double *rho, *grho, *v1xc, *v2xc, *sgn, s; + sxc = v1xcup = v1xcdw = 0.0; + v2xcup = v2xcdw = v2xcud = 0.0; + rho = new double[2]; + grho= new double[3]; + v1xc= new double[2]; + v2xc= new double[3]; + sgn = new double[2]; + + rho[0] = rhoup; + rho[1] = rhodw; + grho[0] = gdr1.norm2(); + grho[1] = gdr1 * gdr2; + grho[2] = gdr2.norm2(); + + const double rho_threshold = 1E-6; + const double grho_threshold = 1E-10; + + for(xc_func_type &func : funcs) + { + if( func.info->family == XC_FAMILY_GGA || func.info->family == XC_FAMILY_HYB_GGA) + { + sgn[0] = sgn[1] = 1.0; + // call Libxc function: xc_gga_exc_vxc + xc_gga_exc_vxc( &func, 1, rho, grho, &s, v1xc, v2xc); + if(func.info->kind==XC_CORRELATION) + { + if ( rho[0] rho, grho2, tau; //density, gradient and kinetic energy density + std::vector v1x, v2x, v3x; //exchange potentials + std::vector v1c, v3c; //correlation potentials; v2c is in output + std::vector lapl_rho, vlapl_rho; //dummy variables, not used + double sx, sc; + + rho.resize(2); grho2.resize(3); tau.resize(2); + v1x.resize(2); v2x.resize(3); v3x.resize(2); + v1c.resize(3); mgga_spin_out.v2c.resize(3); v3c.resize(2); + lapl_rho.resize(6); vlapl_rho.resize(6); + + rho[0]=mgga_spin_in.rhoup; rho[1]=mgga_spin_in.rhodw; + grho2[0]=mgga_spin_in.grhoup*mgga_spin_in.grhoup; + grho2[1]=mgga_spin_in.grhoup*mgga_spin_in.grhodw; + grho2[2]=mgga_spin_in.grhodw*mgga_spin_in.grhodw; + tau[0]=mgga_spin_in.tauup; tau[1]=mgga_spin_in.taudw; + +//exchange + if (func_id[0]==263) + { + xc_func_init(&x_func, 263 ,xc_polarized); + xc_mgga_exc_vxc(&x_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sx,v1x.data(),v2x.data(),vlapl_rho.data(),v3x.data()); + xc_func_end(&x_func); + } + else + { + ModuleBase::WARNING_QUIT("tau_xc_spin","functional not implemented yet"); + } + +//correlation + if(func_id[1]==267) + { + xc_func_init(&c_func, 267 ,xc_polarized); + xc_mgga_exc_vxc(&c_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sc,v1c.data(),mgga_spin_out.v2c.data(),vlapl_rho.data(),v3c.data()); + xc_func_end(&c_func); + } + else + { + ModuleBase::WARNING_QUIT("tau_xc_spin","functional not implemented yet"); + } + + mgga_spin_out.ex = sx * (rho[0]+rho[1]); + mgga_spin_out.v1xup = v1x[0]; + mgga_spin_out.v2xup = v2x[0] * 2.0; + mgga_spin_out.v3xup = v3x[0]; + mgga_spin_out.v1xdw = v1x[1]; + mgga_spin_out.v2xdw = v2x[2] * 2.0; + mgga_spin_out.v3xdw = v3x[1]; + + mgga_spin_out.ec = sc * (rho[0]+rho[1]); + mgga_spin_out.v1cup = v1c[0]; + mgga_spin_out.v3cup = v3c[0]; + mgga_spin_out.v1cdw = v1c[1]; + mgga_spin_out.v3cdw = v3c[1]; + + mgga_spin_out.v2cup = mgga_spin_out.v2c[0]*mgga_spin_in.grhoup*2.0 + + mgga_spin_out.v2c[1]*mgga_spin_in.grhodw; + mgga_spin_out.v2cdw = mgga_spin_out.v2c[2]*mgga_spin_in.grhodw*2.0 + + mgga_spin_out.v2c[1]*mgga_spin_in.grhoup; + return; +} +#endif \ No newline at end of file diff --git a/source/module_xc/xc_functional_wrapper_xc.cpp b/source/module_xc/xc_functional_wrapper_xc.cpp new file mode 100644 index 00000000000..a7f2b736f88 --- /dev/null +++ b/source/module_xc/xc_functional_wrapper_xc.cpp @@ -0,0 +1,158 @@ +// This file contains wrapper for the LDA functionals +// it includes 3 subroutines: +// 1. xc, which is the wrapper of LDA part +// (i.e. LDA functional and LDA part of GGA functional) +// 2. xc_spin, which is the spin polarized counterpart of xc +// 3. xc_spin_libxc, which is the wrapper for LDA functional, spin polarized + +#include "xc_functional.h" +#include + +void XC_Functional::xc(const double &rho, double &exc, double &vxc) +{ + + double third = 1.0 / 3.0; + double pi34 = 0.6203504908994e0 ; // pi34=(3/4pi)^(1/3) + double rs; + double e,v; + + exc = vxc = 0.00; + + rs = pi34 / std::pow(rho, third); + + for(int id : func_id) + { + switch( id ) + { + // Exchange functionals containing slater exchange + case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: + case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: + // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X + XC_Functional::slater(rs, e, v);break; + + // Exchange functionals containing attenuated slater exchange + case XC_HYB_GGA_XC_PBEH: + // PBE0 + XC_Functional::slater(rs, e, v); + e *= 0.75; v*= 0.75; + break; + + // Correlation functionals containing PW correlation + case XC_GGA_C_PBE: case XC_GGA_C_PW91: case XC_LDA_C_PW: + // PBC,PW91,PWLDA + XC_Functional::pw(rs, 0, e, v);break; + + // Correlation functionals containing PZ correlation + case XC_LDA_C_PZ: case XC_GGA_C_P86: + // PZ,P86 + XC_Functional::pz(rs, 0, e, v);break; + + // Correlation functionals containing LYP correlation + case XC_GGA_C_LYP: + // BLYP + XC_Functional::lyp(rs, e, v);break; + + // Functionals that are realized only using LIBXC + case XC_HYB_GGA_XC_HSE06: case XC_MGGA_X_SCAN: case XC_MGGA_C_SCAN: + // HSE,SCAN_X,SCAN_C + throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); + + default: + e = v = 0.0; + } + exc += e; + vxc += v; + } + return; +} + +void XC_Functional::xc_spin(const double &rho, const double &zeta, + double &exc, double &vxcup, double &vxcdw) +{ + static const double small = 1.e-10; + double e, vup, vdw; + exc = vxcup = vxcdw = 0.0; + + static const double third = 1.0 / 3.0; + static const double pi34 = 0.62035049089940; + const double rs = pi34 / pow(rho, third);//wigner_sitz_radius; + + for(int id : func_id) + { + switch( id ) + { + // Exchange functionals containing slater exchange + case XC_LDA_X: case XC_GGA_X_PBE: case XC_GGA_X_RPBE: + case XC_GGA_X_WC: case XC_GGA_X_B88: case XC_GGA_X_PW91: + // SLA,PBX,rPBX,PBXsol,WC,B88,PW91_X + XC_Functional::slater_spin(rho, zeta, e, vup, vdw); break; + + // Exchange functionals containing attenuated slater exchange + case XC_HYB_GGA_XC_PBEH: + // PBE0 + XC_Functional::slater_spin(rho, zeta, e, vup, vdw); + e *= 0.75; vup *= 0.75; vdw *=0.75; + break; + + // Correlation functionals containing PZ correlation + case XC_LDA_C_PZ: case XC_GGA_C_P86: + // PZ,P86 + XC_Functional::pz_spin(rs, zeta, e, vup, vdw); break; + + // Correlation functionals containing PW correlationtests/integrate/101_PW_OU_pseudopot + case XC_GGA_C_PBE: + // PBC,PBCsol + XC_Functional::pw_spin(rs, zeta, e, vup, vdw); break; + + // Correlation functionals that already contains LDA components + // so sets to 0 here + case XC_GGA_X_HCTH_A: case XC_GGA_C_HCTH_A: case XC_GGA_X_OPTX: + //HCTH_X HTCH_C OPTX + e = vup = vdw =0.0; + + // Cases that are only realized in LIBXC + default: + throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); break; + + } + exc += e; + vxcup += vup; + vxcdw += vdw; + } + return; +} + +void XC_Functional::xc_spin_libxc(const double &rhoup, const double &rhodw, + double &exc, double &vxcup, double &vxcdw) +{ +#ifdef USE_LIBXC + double e, vup, vdw; + double *rho_ud, *vxc_ud; + exc = vxcup = vxcdw = 0.0; + + rho_ud = new double[2]; + vxc_ud = new double[2]; + rho_ud[0] = rhoup; + rho_ud[1] = rhodw; + + std::vector funcs = init_func(XC_POLARIZED); + + for(xc_func_type &func : funcs) + { + if( func.info->family == XC_FAMILY_LDA) + { + // call Libxc function: xc_lda_exc_vxc + xc_lda_exc_vxc( &func, 1, rho_ud, &e, vxc_ud); + } + exc += e; + vxcup += vxc_ud[0]; + vxcdw += vxc_ud[1]; + } + + + delete[] rho_ud; + delete[] vxc_ud; +#else + ModuleBase::WARNING_QUIT("xc_spin_libxc","compile with LIBXC to use this subroutine"); +#endif +} \ No newline at end of file From 6435e983a90847214e4714e71b4c2a4b5758cbbd Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 4 Mar 2022 15:10:45 +0800 Subject: [PATCH 18/36] xc refactor : fix bug in mgga stress --- source/module_xc/xc_functional.cpp | 4 ++++ source/module_xc/xc_functional_gradcorr.cpp | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index aa660a8e3d9..18dd9acfe30 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -141,6 +141,10 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) { ModuleBase::WARNING_QUIT("set_xc_type","hybrid functional not realized for planewave yet"); } + if(func_type == 3 && GlobalV::STRESS == 1 && GlobalV::NSPIN!=1) + { + ModuleBase::WARNING_QUIT("set_xc_type","mgga stress not implemented for polarized case yet"); + } #ifndef USE_LIBXC use_libxc = false; diff --git a/source/module_xc/xc_functional_gradcorr.cpp b/source/module_xc/xc_functional_gradcorr.cpp index 5ab0363967e..fd60d65d2e2 100644 --- a/source/module_xc/xc_functional_gradcorr.cpp +++ b/source/module_xc/xc_functional_gradcorr.cpp @@ -152,8 +152,19 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, if( rhotmp1[ir] >= 0.0 ) segno = 1.0; if( rhotmp1[ir] < 0.0 ) segno = -1.0; - - XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); + if(func_type == 3 && is_stress) //the gradcorr part to stress of mGGA + { +#ifdef USE_LIBXC + double sx, sc, v1x, v2x, v3x, v1c, v2c, v3c; + double atau = GlobalC::CHR.kin_r[0][ir]/2.0; + XC_Functional::tau_xc( arho, grho2a, atau, sx, sc, v1x, v2x, v3x, v1c, v2c, v3c); + v2xc = v2x + v2c; +#endif + } + else + { + XC_Functional::gcxc( arho, grho2a, sxc, v1xc, v2xc); + } if(is_stress) { double tt[3]; From 1db8d67ef97af1011bae0b48550e7e8bca9cc3ca Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 4 Mar 2022 15:27:24 +0800 Subject: [PATCH 19/36] xc refactor : further rearrange files and add comments --- source/module_xc/xc_functional.h | 130 +++++++++++++++----- source/module_xc/xc_functional_gradcorr.cpp | 10 ++ 2 files changed, 110 insertions(+), 30 deletions(-) diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index ae7170801de..0c731d3f492 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -219,7 +219,11 @@ class XC_Functional // it contains 5 subroutines: // 1. gradcorr, which calculates gradient correction // 2. grad_wfc, which calculates gradient of wavefunction -// +// it is used in stress_func_mgga.cpp +// 3. grad_rho, which calculates gradient of density +// 4. grad_dot, which calculates divergence of something +// 5. noncolin_rho, which diagonalizes the spin density matrix +// and gives the spin up and spin down components of the charge. public: @@ -227,11 +231,27 @@ class XC_Functional static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); private: - + static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); static void grad_dot( const ModuleBase::Vector3 *h, double *dh); static void noncolin_rho(double *rhoout1,double *rhoout2,double *seg); +//------------------- +// xc_funct_exch_lda.cpp +//------------------- + +// This file contains realization of LDA exchange functionals +// Spin unpolarized ones: +// 1. slater: ordinary Slater exchange with alpha=2/3 +// 2. slater1: Slater exchange with alpha=1 +// 3. slater_rxc : Slater exchange with alpha=2/3 and Relativistic exchange +// And their spin polarized counterparts: +// 1. slater_spin +// 2. slater1_spin +// 3. slater_rxc_spin + + private: + // For LDA exchange energy static void slater(const double &rs, double &ex, double &vx); static void slater1(const double &rs, double &ex, double &vx); @@ -245,58 +265,108 @@ class XC_Functional static void slater_rxc_spin( const double &rho, const double &z, double &ex, double &vxup, double &vxdw); +//------------------- +// xc_funct_corr_lda.cpp +//------------------- + +// This file contains realization of LDA correlation functionals +// Spin unpolarized ones: +// 1. pw : Perdew-Wang LDA correlation +// 2. pz : Perdew-Zunger LDA correlation +// 3. lyp : Lee-Yang-Parr correlation +// 4. vwn : Vosko-Wilk-Nusair LDA correlation +// 5. wigner : Wigner +// 6. hl : Hedin-Lunqvist +// 7. gl : Gunnarson-Lunqvist +// And some of their spin polarized counterparts: +// 1. pw_spin +// 2. pz_spin, which calls pz_polarized + + private: + // For LDA correlation energy - static void pz(const double &rs, const int &iflag, double &ec, double &vc); - static void vwn(const double &rs, double &ec, double &vc); static void pw(const double &rs, const int &iflag, double &ec, double &vc); + static void pz(const double &rs, const int &iflag, double &ec, double &vc); static void lyp(const double &rs, double &ec, double &vc); + static void vwn(const double &rs, double &ec, double &vc); static void wigner(const double &rs, double &ec, double &vc); static void hl(const double &rs, double &ec, double &vc); static void gl(const double &rs, double &ec, double &vc); // For LSDA correlation energy - // pz and pz_polarized should be put together + static void pw_spin( const double &rs, const double &zeta, + double &ec, double &vcup, double &vcdw); static void pz_spin( const double &rs, const double &zeta, double &ec, double &vcup, double &vcdw); static void pz_polarized( const double &rs, double &ec, double &vc); - static void pw_spin( const double &rs, const double &zeta, - double &ec, double &vcup, double &vcdw); - // PBEx, PBEc +//------------------- +// xc_funct_exch_gga.cpp +//------------------- + +// This file contains realizations of gradient correction to exchange part +// Spin unpolarized ones: +// 1. becke88 : Becke88 exchange +// 2. ggax : PW91 exchange +// 3. pbex : PBE exchange (and revPBE) +// 4. optx : OPTX, Handy et al. +// 5. wcx : Wu-Cohen exchange +// And some of their spin polarized counterparts: +// 1. becke88_spin + + private: + + static void becke88(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); + static void ggax(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); static void pbex(const double &rho, const double &grho, const int &iflag, double &sx, double &v1x, double &v2x); + static void optx(const double rho, const double grho, double &sx, double &v1x, double &v2x); + static void wcx(const double &rho,const double &grho, double &sx, double &v1x, double &v2x); - static void pbec(const double &rho, const double &grho, const int &flag, - double &sc, double &v1c, double &v2c); + static void becke88_spin(double rho, double grho, double &sx, double &v1x, + double &v2x); - // some GGA functionals - static void hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x); - static void pwcorr(const double r, const double c[], double &g, double &dg); - static void optx(const double rho, const double grho, double &sx, double &v1x, double &v2x); +//------------------- +// xc_funct_corr_gga.cpp +//------------------- + +// This file contains realizations of gradient correction to correlation part +// Spin unpolarized ones: +// 1. perdew86 : P86 +// 2. ggac : PW91 +// 3. pbec +// 4. glyp +// And some of their spin polarized counterparts: +// 1. perdew86_spin +// 2. ggac_spin +// 3. pbec_spin + + private: - // For PW86 correlation functional static void perdew86(const double rho, const double grho, double &sc, double &v1c, double &v2c); - - // For PW91 - static void ggax(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); static void ggac(const double &rho,const double &grho, double &sc, double &v1c, double &v2c); - - // For Wu-Cohen - static void wcx(const double &rho,const double &grho, double &sx, double &v1x, double &v2x); - - // For BLYP - static void becke88(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); + static void pbec(const double &rho, const double &grho, const int &flag, + double &sc, double &v1c, double &v2c); static void glyp(const double &rho, const double &grho, double &sc, double &v1c, double &v2c); - // spin-polarized GGA - static void becke88_spin(double rho, double grho, double &sx, double &v1x, - double &v2x); static void perdew86_spin(double rho, double zeta, double grho, double &sc, - double &v1cup, double &v1cdw, double &v2c); + double &v1cup, double &v1cdw, double &v2c); static void ggac_spin(double rho, double zeta, double grho, double &sc, - double &v1cup, double &v1cdw, double &v2c); + double &v1cup, double &v1cdw, double &v2c); static void pbec_spin(double rho, double zeta, double grho, const int &flag, double &sc, - double &v1cup, double &v1cdw, double &v2c); + double &v1cup, double &v1cdw, double &v2c); + +//------------------- +// xc_funct_hcth.cpp +//------------------- +// This file contains realizations of the HCTH GGA functional +// hcth calls pwcorr + + private: + + static void hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x); + static void pwcorr(const double r, const double c[], double &g, double &dg); + }; #endif //XC_FUNCTION_H diff --git a/source/module_xc/xc_functional_gradcorr.cpp b/source/module_xc/xc_functional_gradcorr.cpp index fd60d65d2e2..2b28e863247 100644 --- a/source/module_xc/xc_functional_gradcorr.cpp +++ b/source/module_xc/xc_functional_gradcorr.cpp @@ -1,3 +1,13 @@ +// This file contains subroutines realted to gradient calculations +// it contains 5 subroutines: +// 1. gradcorr, which calculates gradient correction +// 2. grad_wfc, which calculates gradient of wavefunction +// it is used in stress_func_mgga.cpp +// 3. grad_rho, which calculates gradient of density +// 4. grad_dot, which calculates divergence of something +// 5. noncolin_rho, which diagonalizes the spin density matrix +// and gives the spin up and spin down components of the charge. + #include "../src_pw/global.h" #include "xc_functional.h" From c44d64919ec8f85e788af980b556dc4673238502 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 4 Mar 2022 16:44:03 +0800 Subject: [PATCH 20/36] xc refactor : 1. replace id numbers by LIBXC keywords 2. modify v_xc_meta and tau_xc, so that all mGGA in LIBXC can be used also fixed bugs in mGGA realization --- source/module_xc/xc_funcs.h | 6 +- source/module_xc/xc_functional.cpp | 4 + source/module_xc/xc_functional.h | 29 +- source/module_xc/xc_functional_gradcorr.cpp | 5 +- source/module_xc/xc_functional_vxc.cpp | 383 ++++++++---------- .../module_xc/xc_functional_wrapper_gcxc.cpp | 65 +-- .../module_xc/xc_functional_wrapper_tauxc.cpp | 114 +----- 7 files changed, 236 insertions(+), 370 deletions(-) diff --git a/source/module_xc/xc_funcs.h b/source/module_xc/xc_funcs.h index a365583f8e0..9e16f914f3f 100644 --- a/source/module_xc/xc_funcs.h +++ b/source/module_xc/xc_funcs.h @@ -1,8 +1,8 @@ +// This file is a list of functionals that we have realized #define XC_LDA_X 1 /*Exchange */ #define XC_LDA_C_PZ 9 /*Perdew & Zunger */ #define XC_LDA_C_PW 12 /*Perdew & Wang */ #define XC_HYB_GGA_XC_PBEH 406 /*aka PBE0 or PBE1PBE */ -#define XC_HYB_GGA_XC_HSE06 428 /* the 2006 version of the screened hybrid HSE */ #define XC_GGA_X_HCTH_A 34 /*HCTH-A */ #define XC_GGA_C_HCTH_A 97 /*HCTH-A */ #define XC_GGA_X_PBE 101 /*Perdew, Burke & Ernzerhof exchange */ @@ -16,6 +16,4 @@ #define XC_GGA_C_LYP 131 /*Lee, Yang & Parr */ #define XC_GGA_C_P86 132 /*Perdew 86 */ #define XC_GGA_C_PBE_SOL 133 /* Perdew, Burke & Ernzerhof correlation SOL */ -#define XC_GGA_C_PW91 134 /*Perdew & Wang 91 */ -#define XC_MGGA_X_SCAN 263 /*SCAN exchange of Sun, Ruzsinszky, and Perdew */ -#define XC_MGGA_C_SCAN 267 /*SCAN correlation */ \ No newline at end of file +#define XC_GGA_C_PW91 134 /*Perdew & Wang 91 */ \ No newline at end of file diff --git a/source/module_xc/xc_functional.cpp b/source/module_xc/xc_functional.cpp index 18dd9acfe30..5410d4c3a5c 100644 --- a/source/module_xc/xc_functional.cpp +++ b/source/module_xc/xc_functional.cpp @@ -147,6 +147,10 @@ void XC_Functional::set_xc_type(const std::string xc_func_in) } #ifndef USE_LIBXC + if(xc_func == "SCAN" || xc_func == "HSE") + { + ModuleBase::WARNING_QUIT("set_xc_type","to use SCAN or HSE, LIBXC is required"); + } use_libxc = false; #endif diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 0c731d3f492..ae991dc3a97 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -177,38 +177,17 @@ class XC_Functional //------------------- // This file contains wrapper for the mGGA functionals -// it includes 2 subroutines: +// it includes 1 subroutine: // 1. tau_xc -// 2. tau_xc_spin // NOTE : mGGA is realized through LIBXC #ifdef USE_LIBXC public: - - struct Mgga_spin_in - { - double rhoup, rhodw;//electron densities - ModuleBase::Vector3 grhoup, grhodw;//gradient of electron densities - double tauup, taudw;//kinetic energy densities - }; - - struct Mgga_spin_out - { - double ex, ec;//xc energy densities - double v1xup, v1xdw;//vx: lda part - double v2xup, v2xdw;//vx: gga part - double v3xup, v3xdw;//vx: mgga part - double v1cup, v1cdw;//vc: lda part - ModuleBase::Vector3 v2cup, v2cdw; - std::vector v2c;//vc: gga part, two different formats - double v3cup, v3cdw;//vc: mgga part - }; // mGGA - static void tau_xc(const double &rho, const double &grho, const double &atau, double &sx, double &sc, - double &v1x, double &v2x, double &v3x, double &v1c, double &v2c, double &v3c); - static void tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out &mgga_spin_out); + static void tau_xc(const double &rho, const double &grho, const double &atau, double &sxc, + double &v1xc, double &v2xc, double &v3xc); #endif //------------------- @@ -363,7 +342,7 @@ class XC_Functional // hcth calls pwcorr private: - + static void hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x); static void pwcorr(const double r, const double c[], double &g, double &dg); diff --git a/source/module_xc/xc_functional_gradcorr.cpp b/source/module_xc/xc_functional_gradcorr.cpp index 2b28e863247..3ad3cd415c1 100644 --- a/source/module_xc/xc_functional_gradcorr.cpp +++ b/source/module_xc/xc_functional_gradcorr.cpp @@ -165,10 +165,9 @@ void XC_Functional::gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, if(func_type == 3 && is_stress) //the gradcorr part to stress of mGGA { #ifdef USE_LIBXC - double sx, sc, v1x, v2x, v3x, v1c, v2c, v3c; + double v3xc; double atau = GlobalC::CHR.kin_r[0][ir]/2.0; - XC_Functional::tau_xc( arho, grho2a, atau, sx, sc, v1x, v2x, v3x, v1c, v2c, v3c); - v2xc = v2x + v2c; + XC_Functional::tau_xc( arho, grho2a, atau, sxc, v1xc, v2xc, v3xc); #endif } else diff --git a/source/module_xc/xc_functional_vxc.cpp b/source/module_xc/xc_functional_vxc.cpp index 1592263e785..04aa9a3958c 100644 --- a/source/module_xc/xc_functional_vxc.cpp +++ b/source/module_xc/xc_functional_vxc.cpp @@ -283,7 +283,6 @@ std::tuple XC_Functional::v_xc_libxc( for( xc_func_type &func : funcs ) { - // jiyy add for threshold const double rho_threshold = 1E-6; const double grho_threshold = 1E-10; @@ -416,6 +415,11 @@ tuple XC_Functional::v_xc_m ModuleBase::TITLE("XC_Functional","v_xc"); ModuleBase::timer::tick("XC_Functional","v_xc"); + if(GlobalV::NSPIN==4) + { + ModuleBase::WARNING_QUIT("v_xc_meta","meta-GGA has not been implemented for nspin = 4 yet"); + } + double e2 = 2.0; //output of the subroutine @@ -430,227 +434,182 @@ tuple XC_Functional::v_xc_m // use can check on website, for example: // https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/ //---------------------------------------------------------- + + const int nspin = GlobalV::NSPIN; + std::vector funcs = init_func( ( (1==nspin) ? XC_UNPOLARIZED:XC_POLARIZED ) ); - //initialize X and C functionals - xc_func_type x_func; - xc_func_type c_func; - const int xc_polarized = (GlobalV::NSPIN ? XC_UNPOLARIZED : XC_POLARIZED); + // converting rho + std::vector rho; + rho.resize(GlobalC::pw.nrxx*nspin); + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + rho[ir*nspin+is] = rho_in[is][ir] + 1.0/nspin*rho_core_in[ir]; + } + } - //exchange - if( func_id[0] == 263) - { - xc_func_init(&x_func, 263 ,xc_polarized); - } - else - { - throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } + std::vector>> gdr; + std::vector sigma; - //correlation - if( func_id[1] == 267) - { - xc_func_init(&c_func, 267 ,xc_polarized); - } + // calculating grho + gdr.resize( nspin ); + for( int is=0; is!=nspin; ++is ) + { + std::vector rhor(GlobalC::pw.nrxx); + for(int ir=0; ir> rhog(GlobalC::pw.ngmc); + GlobalC::CHR.set_rhog(rhor.data(), rhog.data()); + + //------------------------------------------- + // compute the gradient of charge density and + // store the gradient in gdr[is] + //------------------------------------------- + gdr[is].resize(GlobalC::pw.nrxx); + XC_Functional::grad_rho(rhog.data(), gdr[is].data()); + } + + // converting grho + sigma.resize( nrxx * ((1==nspin)?1:3) ); + + if( 1==nspin ) + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + sigma[ir] = gdr[0][ir]*gdr[0][ir]; + } + } else - { - throw domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } - - //rho,grho,tau - vector> rho; - vector>> grho; - vector> kin_r; - - //dExc/d rho,grho,tau - vector> vrho; - vector>> h; - vector> kedtaur; - - //rho : from double** to vector - rho.resize(GlobalV::NSPIN); - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - rho[is].resize(nrxx); - for( int ir=0; ir!=nrxx; ++ir ) - { - rho[is][ir] = rho_in[is][ir] + (1.0/GlobalV::NSPIN)*rho_core_in[ir]; - } - } + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + sigma[ir*3] = gdr[0][ir]*gdr[0][ir]; + sigma[ir*3+1] = gdr[0][ir]*gdr[1][ir]; + sigma[ir*3+2] = gdr[1][ir]*gdr[1][ir]; + } + } - //grho : calculate gradient - grho.resize(GlobalV::NSPIN); - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - grho[is].resize(nrxx); - - vector> rhog(GlobalC::pw.ngmc); - GlobalC::CHR.set_rhog(rho[is].data(), rhog.data()); - XC_Functional::grad_rho(rhog.data(), grho[is].data()); - } - - //kin_r : from double** to vector - kin_r.resize(GlobalV::NSPIN); - if(GlobalV::NSPIN==1 || GlobalV::NSPIN==2) - { - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - kin_r[is].resize(nrxx); - for( int ir=0; ir!=nrxx; ++ir ) - { - kin_r[is][ir] = kin_r_in[is][ir]; - } - } - } + //converting kin_r + std::vector kin_r; + kin_r.resize(GlobalC::pw.nrxx*nspin); + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + kin_r[ir*nspin+is] = kin_r_in[is][ir] / 2.0; + } + } - if(GlobalV::NSPIN==1) - { - vrho.resize(GlobalV::NSPIN); - h.resize(GlobalV::NSPIN); - kedtaur.resize(GlobalV::NSPIN); - - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - vrho[is].resize(nrxx); - h[is].resize(nrxx); - kedtaur[is].resize(nrxx); - - double arho, grho2, atau, lapl; - double ex, ec, v1x, v2x, v3x, v1c, v2c, v3c, vlapl; - const double rho_th = 1e-8; - const double grho_th = 1e-12; - const double tau_th = 1e-8; - - - for( int ir=0; ir!=nrxx; ++ir ) - { - arho = abs(rho_in[is][ir]); - grho2 = grho[0][ir]*grho[0][ir]; - atau = kin_r[is][ir] / e2; - lapl = grho2;//dummy argument, not used - - if(arho > rho_th && grho2 > grho_th && abs(atau) > tau_th) - { - xc_mgga_exc_vxc(&x_func,1,&arho,&grho2,&lapl,&atau,&ex,&v1x,&v2x,&vlapl,&v3x); - xc_mgga_exc_vxc(&c_func,1,&arho,&grho2,&lapl,&atau,&ec,&v1c,&v2c,&vlapl,&v3c); - ex = ex * rho[is][ir]; - ec = ec * rho[is][ir]; - v2x = v2x * e2; - v2c = v2c * e2; - - vrho[is][ir] = (v1x + v1c) * e2; - h[is][ir] = (v2x + v2c) * e2 * grho[is][ir]; - kedtaur[is][ir] = v3x + v3c; - - etxc += (ex + ec) * e2; - vtxc += (v1x + v1c) * e2 * arho; - } - else - { - vrho[is][ir] = 0.0; - h[is][ir] = 0.0; - kedtaur[is][ir] = 0.0; - } - }//loop over grid points - }//loop over spin - }//nspin=1 - else if(GlobalV::NSPIN==2) - { - vrho.resize(GlobalV::NSPIN); - h.resize(GlobalV::NSPIN); - kedtaur.resize(GlobalV::NSPIN); - - for( int is=0; is!=GlobalV::NSPIN; ++is ) - { - vrho[is].resize(nrxx); - h[is].resize(nrxx); - kedtaur[is].resize(nrxx); - } - - double rh, ggrho2, atau; - double rhoup, rhodw, tauup, taudw; - double ex, v1xup, v1xdw, v2xup, v2xdw, v3xup, v3xdw; - double ec, v1cup, v1cdw, v3cup, v3cdw; - ModuleBase::Vector3 grhoup,grhodw,v2cup,v2cdw; - - XC_Functional::Mgga_spin_in mgga_spin_in; - XC_Functional::Mgga_spin_out mgga_spin_out; + std::vector exc ( nrxx ); + std::vector vrho ( nrxx * nspin ); + std::vector vsigma ( nrxx * ((1==nspin)?1:3) ); + std::vector vtau ( nrxx * nspin ); + std::vector vlapl ( nrxx * nspin ); - - const double rho_th = 1e-8; - const double grho_th = 1e-12; - const double tau_th = 1e-8; - - for( int ir=0; ir!=nrxx; ++ir ) - { - - auto set_input_tau_spin = [&]() - { - mgga_spin_in.rhoup = rho_in[0][ir]; - mgga_spin_in.rhodw = rho_in[1][ir]; - rh = rho_in[0][ir] + rho_in[1][ir]; - - mgga_spin_in.grhoup = grho[0][ir]; - mgga_spin_in.grhodw = grho[1][ir]; - ggrho2 = (grho[0][ir]*grho[0][ir] + grho[1][ir]*grho[1][ir]) * 4.0; - - mgga_spin_in.tauup = kin_r[0][ir] / e2; - mgga_spin_in.taudw = kin_r[1][ir] / e2; - atau = (kin_r[0][ir]+kin_r[1][ir])/ e2; - }; - - auto set_output_tau_spin = [&]() - { - vrho[0][ir] = (mgga_spin_out.v1xup+mgga_spin_out.v1cup) * e2; - vrho[1][ir] = (mgga_spin_out.v1xdw+mgga_spin_out.v1cdw) * e2; - - h[0][ir] = (mgga_spin_out.v2xup*grhoup+mgga_spin_out.v2cup)*e2; - h[1][ir] = (mgga_spin_out.v2xdw*grhodw+mgga_spin_out.v2cdw)*e2; - - kedtaur[0][ir] = mgga_spin_out.v3xup+mgga_spin_out.v3cup; - kedtaur[1][ir] = mgga_spin_out.v3xdw+mgga_spin_out.v3cdw; - - etxc += (mgga_spin_out.ex+mgga_spin_out.ec) * e2; - vtxc += (mgga_spin_out.v1xup+mgga_spin_out.v1xdw+mgga_spin_out.v1cup+mgga_spin_out.v1cdw) * e2 * rh; - }; - - if (rh > rho_th && ggrho2 > grho_th && abs(atau) > tau_th) - { - set_input_tau_spin(); - XC_Functional::tau_xc_spin(mgga_spin_in, mgga_spin_out); - set_output_tau_spin(); - } - else - { - vrho[0][ir] = 0.0; - vrho[1][ir] = 0.0; - - h[0][ir]=0.0; - h[1][ir]=0.0; - - kedtaur[0][ir] = 0.0; - kedtaur[1][ir] = 0.0; - } - }//end loop grid points - }//nspin=2 - else - { - ModuleBase::WARNING_QUIT("v_xc_meta","meta-GGA has not been implemented for nspin = 4 yet"); - } + const double rho_th = 1e-8; + const double grho_th = 1e-12; + const double tau_th = 1e-8; + // sgn for threshold mask + std::vector sgn( nrxx * nspin, 1.0); - vector dh; - dh.resize(nrxx); + if(nspin == 1) + { + for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + { + if ( rho[ir]family == XC_FAMILY_MGGA); + xc_mgga_exc_vxc(&func, nrxx, rho.data(), sigma.data(), sigma.data(), + kin_r.data(), exc.data(), vrho.data(), vsigma.data(), vlapl.data(), vtau.data()); - v(is,ir) = vrho[is][ir]; - vofk(is,ir) = kedtaur[is][ir]; - } + //process etxc + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + etxc += ModuleBase::e2 * exc[ir] * rho[ir*nspin+is] * sgn[ir*nspin+is]; + } + } + + //process vtxc + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + const double v_tmp = ModuleBase::e2 * vrho[ir*nspin+is] * sgn[ir*nspin+is]; + v(is,ir) += v_tmp; + vtxc += v_tmp * rho_in[is][ir]; + } + } + + //process vsigma + std::vector>> h( nspin, std::vector>(nrxx) ); + if( 1==nspin ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = 2.0 * gdr[0][ir] * vsigma[ir] * 2.0 * sgn[ir]; + } + } + else + { + for( int ir=0; ir!= nrxx; ++ir ) + { + h[0][ir] = 2.0 * (gdr[0][ir] * vsigma[ir*3 ] * sgn[ir*2 ] * 2.0 + + gdr[1][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + h[1][ir] = 2.0 * (gdr[1][ir] * vsigma[ir*3+2] * sgn[ir*2+1] * 2.0 + + gdr[0][ir] * vsigma[ir*3+1] * sgn[ir*2] * sgn[ir*2+1]); + } + } + + // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] + std::vector> dh(nspin, std::vector( nrxx)); + for( int is=0; is!=nspin; ++is ) + { + XC_Functional::grad_dot( ModuleBase::GlobalFunc::VECTOR_TO_PTR(h[is]), ModuleBase::GlobalFunc::VECTOR_TO_PTR(dh[is]) ); + } + + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + vtxc -= dh[is][ir] * rho[ir*nspin+is]; + v(is,ir) -= dh[is][ir]; + } + } + + //process vtau + for( int is=0; is!=nspin; ++is ) + { + for( int ir=0; ir!= nrxx; ++ir ) + { + vofk(is,ir) += vtau[ir*nspin+is] * sgn[ir*nspin+is]; + } + } } //------------------------------------------------- diff --git a/source/module_xc/xc_functional_wrapper_gcxc.cpp b/source/module_xc/xc_functional_wrapper_gcxc.cpp index d69f327fc67..14c7cb5a509 100644 --- a/source/module_xc/xc_functional_wrapper_gcxc.cpp +++ b/source/module_xc/xc_functional_wrapper_gcxc.cpp @@ -48,37 +48,43 @@ void XC_Functional::gcxc(const double &rho, const double &grho, double &sxc, { switch( id ) { - case 106: //B88 + case XC_GGA_X_B88: //B88 XC_Functional::becke88(rho, grho, s, v1, v2);break; - case 109: //PW91_X + case XC_GGA_X_PW91: //PW91_X XC_Functional::ggax(rho, grho, s, v1, v2);break; - case 101: //PBX + case XC_GGA_X_PBE: //PBX XC_Functional::pbex(rho, grho, 0, s, v1, v2);break; - case 117: //revised PBX + case XC_GGA_X_RPBE: //revised PBX XC_Functional::pbex(rho, grho, 1, s, v1, v2);break; - case 34: //HCTH_X + case XC_GGA_X_HCTH_A: //HCTH_X XC_Functional::hcth(rho, grho, s, v1, v2);break; //XC together - case 97: //HCTH_C + case XC_GGA_C_HCTH_A: //HCTH_C s = 0.0; v1 = 0.0; v2 = 0.0;break; - case 110: //OPTX + case XC_GGA_X_OPTX: //OPTX XC_Functional::optx(rho, grho, s, v1, v2);break; - case 406: //PBE0 - XC_Functional::pbex(rho, grho, 0, s, v1, v2); - s *= 0.75; v1 *= 0.75; v2 *= 0.75;break; - case 116: //PBXsol + case XC_GGA_X_PBE_SOL: //PBXsol XC_Functional::pbex(rho, grho, 2, s, v1, v2);break; - case 118: //Wu-Cohen + case XC_GGA_X_WC: //Wu-Cohen XC_Functional::wcx (rho, grho, s, v1, v2);break; - case 132: //P86 + case XC_GGA_C_P86: //P86 XC_Functional::perdew86(rho, grho, s, v1, v2);break; - case 134: //PW91_C + case XC_GGA_C_PW91: //PW91_C XC_Functional::ggac(rho, grho, s, v1, v2);break; - case 130: //PBC + case XC_GGA_C_PBE: //PBC XC_Functional::pbec(rho, grho, 0, s, v1, v2);break; - case 133: //PBCsol + case XC_GGA_C_PBE_SOL: //PBCsol XC_Functional::pbec(rho, grho, 1, s, v1, v2);break; - case 131: //BLYP + case XC_GGA_C_LYP: //BLYP XC_Functional::glyp(rho, grho, s, v1, v2); break; + case XC_HYB_GGA_XC_PBEH: //PBE0 + double sx, v1x, v2x, sc, v1c, v2c; + XC_Functional::pbex(rho, grho, 0, sx, v1x, v2x); + sx *= 0.75; v1x *= 0.75; v2x *= 0.75; + XC_Functional::pbec(rho, grho, 0, sc, v1c, v2c); + s = sx + sc; + v1 = v1x + v1c; + v2 = v2x + v2c; + break; default: //SCAN_X,SCAN_C,HSE, and so on throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); } @@ -137,7 +143,7 @@ void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double int id = func_id[0]; switch( id ) { - case 106: //B88 + case XC_GGA_X_B88: //B88 if (rhoup > small && sqrt(fabs(grhoup2)) > small) { XC_Functional::becke88_spin(rhoup, grhoup2, sxup, v1xup, v2xup); @@ -147,7 +153,7 @@ void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double XC_Functional::becke88_spin(rhodw, grhodw2, sxdw, v1xdw, v2xdw); } break; - case 101: //PBX + case XC_GGA_X_PBE: //PBX if (rhoup > small && sqrt(fabs(grhoup2)) > small) { XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); @@ -157,7 +163,7 @@ void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 0, sxdw, v1xdw, v2xdw); } break; - case 117: //revised PBX + case XC_GGA_X_RPBE: //revised PBX if (rhoup > small && sqrt(fabs(grhoup2)) > small) { XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 1, sxup, v1xup, v2xup); @@ -167,7 +173,7 @@ void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double XC_Functional::pbex(2.0 * rhodw, 4.0 * grhodw2, 1, sxdw, v1xdw, v2xdw); } break; - case 406: //PBE0 + case XC_HYB_GGA_XC_PBEH: //PBE0 if (rhoup > small && sqrt(fabs(grhoup2)) > small) { XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 0, sxup, v1xup, v2xup); @@ -179,7 +185,7 @@ void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double sxdw *= 0.75; v1xdw *= 0.75; v2xdw *= 0.75; } break; - case 116: //PBXsol + case XC_GGA_X_PBE_SOL: //PBXsol if (rhoup > small && sqrt(fabs(grhoup2)) > small) { XC_Functional::pbex(2.0 * rhoup, 4.0 * grhoup2, 2, sxup, v1xup, v2xup); @@ -253,20 +259,27 @@ void XC_Functional::gcc_spin(double rho, double &zeta, double grho, double &sc, } } //endif + if(func_id[0]==XC_HYB_GGA_XC_PBEH) + { + XC_Functional::pbec_spin(rho, zeta, grho, 1, sc, v1cup, v1cdw, v2c); + return; + } + //for(int id : func_id) //{ int id = func_id[1]; switch( id ) { - case 132: //P86 + case XC_GGA_C_P86: //P86 XC_Functional::perdew86_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; - case 134: //PW91_C + case XC_GGA_C_PW91: //PW91_C XC_Functional::ggac_spin(rho, zeta, grho, sc, v1cup, v1cdw, v2c);break; - case 130: //PBC + case XC_GGA_C_PBE: //PBC XC_Functional::pbec_spin(rho, zeta, grho, 1, sc, v1cup, v1cdw, v2c);break; - case 133: //PBCsol + case XC_GGA_C_PBE_SOL: //PBCsol XC_Functional::pbec_spin(rho, zeta, grho, 2, sc, v1cup, v1cdw, v2c);break; } + //} return; } //end subroutine gcc_spin diff --git a/source/module_xc/xc_functional_wrapper_tauxc.cpp b/source/module_xc/xc_functional_wrapper_tauxc.cpp index d2775dc6975..b5ed2651196 100644 --- a/source/module_xc/xc_functional_wrapper_tauxc.cpp +++ b/source/module_xc/xc_functional_wrapper_tauxc.cpp @@ -1,119 +1,33 @@ // This file contains wrapper for the mGGA functionals -// it includes 2 subroutines: +// it includes 1 subroutine: // 1. tau_xc -// 2. tau_xc_spin #include "xc_functional.h" //tau_xc and tau_xc_spin: interface for calling xc_mgga_exc_vxc from LIBXC //XC_POLARIZED, XC_UNPOLARIZED: internal flags used in LIBXC, denote the polarized(nspin=1) or unpolarized(nspin=2) calculations, definition can be found in xc.h from LIBXC #ifdef USE_LIBXC -void XC_Functional::tau_xc(const double &rho, const double &grho, const double &atau, double &sx, double &sc, - double &v1x, double &v2x, double &v3x, double &v1c, double &v2c, double &v3c) +void XC_Functional::tau_xc(const double &rho, const double &grho, const double &atau, double &sxc, + double &v1xc, double &v2xc, double &v3xc) { - + double s, v1, v2, v3; double lapl_rho, vlapl_rho; - int func_id; lapl_rho = grho; - -//initialize X and C functionals - xc_func_type x_func; - xc_func_type c_func; - const int xc_polarized = XC_UNPOLARIZED; + std::vector funcs = init_func(XC_UNPOLARIZED); + + sxc = 0.0; v1xc = 0.0; v2xc = 0.0; v3xc = 0.0; -//exchange - for(int id : XC_Functional::func_id) + for(xc_func_type &func : funcs) { - switch( id ) - { - case 263: - xc_func_init(&x_func, 263 ,xc_polarized); - xc_mgga_exc_vxc(&x_func,1,&rho,&grho,&lapl_rho,&atau,&sx,&v1x,&v2x,&vlapl_rho,&v3x); - xc_func_end(&x_func); - sx = sx * rho; - v2x = v2x * 2.0; - break; - case 267: - xc_func_init(&c_func, 267 ,xc_polarized); - xc_mgga_exc_vxc(&c_func,1,&rho,&grho,&lapl_rho,&atau,&sc,&v1c,&v2c,&vlapl_rho,&v3c); - xc_func_end(&c_func); - sc = sc * rho; - v2c = v2c * 2.0; - break; - default: - throw std::domain_error( "functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - } + xc_mgga_exc_vxc(&func,1,&rho,&grho,&lapl_rho,&atau,&s,&v1,&v2,&vlapl_rho,&v3); + xc_func_end(&func); + sxc += s * rho; + v2xc += v2 * 2.0; + v1xc += v1; + v3xc += v3; } return; } -void XC_Functional::tau_xc_spin(const Mgga_spin_in &mgga_spin_in, Mgga_spin_out &mgga_spin_out) -{ -//initialize X and C functionals - xc_func_type x_func; - xc_func_type c_func; - const int xc_polarized = XC_POLARIZED; - - std::vector rho, grho2, tau; //density, gradient and kinetic energy density - std::vector v1x, v2x, v3x; //exchange potentials - std::vector v1c, v3c; //correlation potentials; v2c is in output - std::vector lapl_rho, vlapl_rho; //dummy variables, not used - double sx, sc; - - rho.resize(2); grho2.resize(3); tau.resize(2); - v1x.resize(2); v2x.resize(3); v3x.resize(2); - v1c.resize(3); mgga_spin_out.v2c.resize(3); v3c.resize(2); - lapl_rho.resize(6); vlapl_rho.resize(6); - - rho[0]=mgga_spin_in.rhoup; rho[1]=mgga_spin_in.rhodw; - grho2[0]=mgga_spin_in.grhoup*mgga_spin_in.grhoup; - grho2[1]=mgga_spin_in.grhoup*mgga_spin_in.grhodw; - grho2[2]=mgga_spin_in.grhodw*mgga_spin_in.grhodw; - tau[0]=mgga_spin_in.tauup; tau[1]=mgga_spin_in.taudw; - -//exchange - if (func_id[0]==263) - { - xc_func_init(&x_func, 263 ,xc_polarized); - xc_mgga_exc_vxc(&x_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sx,v1x.data(),v2x.data(),vlapl_rho.data(),v3x.data()); - xc_func_end(&x_func); - } - else - { - ModuleBase::WARNING_QUIT("tau_xc_spin","functional not implemented yet"); - } - -//correlation - if(func_id[1]==267) - { - xc_func_init(&c_func, 267 ,xc_polarized); - xc_mgga_exc_vxc(&c_func,1,rho.data(),grho2.data(),lapl_rho.data(),tau.data(),&sc,v1c.data(),mgga_spin_out.v2c.data(),vlapl_rho.data(),v3c.data()); - xc_func_end(&c_func); - } - else - { - ModuleBase::WARNING_QUIT("tau_xc_spin","functional not implemented yet"); - } - - mgga_spin_out.ex = sx * (rho[0]+rho[1]); - mgga_spin_out.v1xup = v1x[0]; - mgga_spin_out.v2xup = v2x[0] * 2.0; - mgga_spin_out.v3xup = v3x[0]; - mgga_spin_out.v1xdw = v1x[1]; - mgga_spin_out.v2xdw = v2x[2] * 2.0; - mgga_spin_out.v3xdw = v3x[1]; - - mgga_spin_out.ec = sc * (rho[0]+rho[1]); - mgga_spin_out.v1cup = v1c[0]; - mgga_spin_out.v3cup = v3c[0]; - mgga_spin_out.v1cdw = v1c[1]; - mgga_spin_out.v3cdw = v3c[1]; - - mgga_spin_out.v2cup = mgga_spin_out.v2c[0]*mgga_spin_in.grhoup*2.0 - + mgga_spin_out.v2c[1]*mgga_spin_in.grhodw; - mgga_spin_out.v2cdw = mgga_spin_out.v2c[2]*mgga_spin_in.grhodw*2.0 - + mgga_spin_out.v2c[1]*mgga_spin_in.grhoup; - return; -} #endif \ No newline at end of file From 55463c3a287f3159c10727f0933602039a4bb6cb Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 4 Mar 2022 16:52:10 +0800 Subject: [PATCH 21/36] xc refactor : fix bug in compiling without USE_LIBXC --- source/module_base/tool_title.cpp | 6 +++--- source/module_xc/xc_functional.cpp | 4 ++++ source/module_xc/xc_functional_vxc.cpp | 18 +++++------------- source/module_xc/xc_functional_wrapper_xc.cpp | 7 +------ source/src_pw/forces.cpp | 4 ++++ source/src_pw/potential.cpp | 4 ++++ 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/source/module_base/tool_title.cpp b/source/module_base/tool_title.cpp index 08360abf208..5a82ccc3d86 100644 --- a/source/module_base/tool_title.cpp +++ b/source/module_base/tool_title.cpp @@ -13,7 +13,7 @@ namespace ModuleBase //========================================================== void TITLE(const std::string &class_function_name) { - //return;//no output + return;//no output #ifdef __NORMAL std::cout<<" ==> "< "< "< XC_Functional::v_xc( ModuleBase::TITLE("XC_Functional","v_xc"); ModuleBase::timer::tick("XC_Functional","v_xc"); -#ifndef USE_LIBXC - if(func_type == 3) - { - ModuleBase::WARNING_QUIT("Potential::v_of_rho","to use metaGGA, please link LIBXC"); - } -#endif - - if((GlobalV::NSPIN == 1 || GlobalV::NSPIN == 2) && use_libxc) + if( (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 2) && use_libxc) { +#ifdef USE_LIBXC return v_xc_libxc(nrxx, ncxyz, omega, rho_in, rho_core); +#else + ModuleBase::WARNING_QUIT("v_xc","compile with LIBXC"); +#endif } //Exchange-Correlation potential Vxc(r) from n(r) @@ -52,11 +49,6 @@ std::tuple XC_Functional::v_xc( double vanishing_charge = 1.0e-10; - if( (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 2) && use_libxc) - { - return v_xc_libxc(nrxx, ncxyz, omega, rho_in, rho_core); - } - if (GlobalV::NSPIN == 1 || ( GlobalV::NSPIN ==4 && !GlobalV::DOMAG && !GlobalV::DOMAG_Z)) { // spin-unpolarized case diff --git a/source/module_xc/xc_functional_wrapper_xc.cpp b/source/module_xc/xc_functional_wrapper_xc.cpp index a7f2b736f88..c9e3ef9bd11 100644 --- a/source/module_xc/xc_functional_wrapper_xc.cpp +++ b/source/module_xc/xc_functional_wrapper_xc.cpp @@ -51,12 +51,7 @@ void XC_Functional::xc(const double &rho, double &exc, double &vxc) case XC_GGA_C_LYP: // BLYP XC_Functional::lyp(rs, e, v);break; - - // Functionals that are realized only using LIBXC - case XC_HYB_GGA_XC_HSE06: case XC_MGGA_X_SCAN: case XC_MGGA_C_SCAN: - // HSE,SCAN_X,SCAN_C - throw std::domain_error("functional unfinished in "+ModuleBase::GlobalFunc::TO_STRING(__FILE__)+" line "+ModuleBase::GlobalFunc::TO_STRING(__LINE__)); - + default: e = v = 0.0; } diff --git a/source/src_pw/forces.cpp b/source/src_pw/forces.cpp index 8f0c290383a..b1be301d858 100644 --- a/source/src_pw/forces.cpp +++ b/source/src_pw/forces.cpp @@ -562,6 +562,7 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) if(XC_Functional::get_func_type() == 3) { +#ifdef USE_LIBXC const auto etxc_vtxc_v = XC_Functional::v_xc_meta( GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, GlobalC::CHR.rho, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); @@ -569,6 +570,9 @@ void Forces::cal_force_cc(ModuleBase::matrix& forcecc) GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v = std::get<2>(etxc_vtxc_v); +#else + ModuleBase::WARNING_QUIT("cal_force_cc","to use mGGA, compile with LIBXC"); +#endif } else { diff --git a/source/src_pw/potential.cpp b/source/src_pw/potential.cpp index acba9fb8f50..dc9c3bd5f6e 100644 --- a/source/src_pw/potential.cpp +++ b/source/src_pw/potential.cpp @@ -326,11 +326,15 @@ ModuleBase::matrix Potential::v_of_rho( if(XC_Functional::get_func_type() == 3) { +#ifdef USE_LIBXC const std::tuple etxc_vtxc_v = XC_Functional::v_xc_meta(GlobalC::pw.nrxx, GlobalC::pw.ncxyz, GlobalC::ucell.omega, rho_in, GlobalC::CHR.rho_core, GlobalC::CHR.kin_r); GlobalC::en.etxc = std::get<0>(etxc_vtxc_v); GlobalC::en.vtxc = std::get<1>(etxc_vtxc_v); v += std::get<2>(etxc_vtxc_v); vofk = std::get<3>(etxc_vtxc_v); +#else + ModuleBase::WARNING_QUIT("v_of_rho","to use mGGA, compile with LIBXC"); +#endif } else { From fc65c766a6100dcfa06b5c1f782dfbf876b5ac0b Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Fri, 4 Mar 2022 17:05:57 +0800 Subject: [PATCH 22/36] xc refactor : set default back to libxc off --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28e82c1e11a..c67d764f63f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ project(ABACUS ) option(ENABLE_DEEPKS "Enable DeePKS functionality" OFF) -option(ENABLE_LIBXC "Enable LibXC functionality" ON) +option(ENABLE_LIBXC "Enable LibXC functionality" OFF) option(USE_CUDA "Enable support to CUDA." OFF) option(USE_ROCM "Enable support to ROCm." OFF) option(USE_OPENMP " Enable OpenMP in abacus." ON) From b2e409a9c238492291374adb7325e7c0d5fb535f Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Mon, 7 Mar 2022 15:16:26 +0800 Subject: [PATCH 23/36] xc refactor : fix bug in gradcorr --- source/module_xc/xc_functional_wrapper_gcxc.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/module_xc/xc_functional_wrapper_gcxc.cpp b/source/module_xc/xc_functional_wrapper_gcxc.cpp index 14c7cb5a509..0bb0b148f4f 100644 --- a/source/module_xc/xc_functional_wrapper_gcxc.cpp +++ b/source/module_xc/xc_functional_wrapper_gcxc.cpp @@ -129,6 +129,7 @@ void XC_Functional::gcx_spin(double rhoup, double rhodw, double grhoup2, double sx = 0.00; v1xup = 0.00; v2xup = 0.00; v1xdw = 0.00; v2xdw = 0.00; + sxup = 0.00; sxdw = 0.00; if (rho <= small) { From ea19c70ad46578d657c1de6efc0c63d62711a7b3 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Mon, 7 Mar 2022 15:44:39 +0800 Subject: [PATCH 24/36] xc refactor : update result.ref --- tests/integrate/101_PW_15_f_pseudopots/result.ref | 6 +++--- tests/integrate/101_PW_15_pseudopots/result.ref | 6 +++--- tests/integrate/101_PW_OU_pseudopots/result.ref | 4 ++-- tests/integrate/101_PW_VW_pseudopots/result.ref | 4 ++-- tests/integrate/101_PW_blps_pseudopots/result.ref | 6 +++--- tests/integrate/101_PW_upf201_Al_pseudopots/result.ref | 6 +++--- tests/integrate/101_PW_upf201_pseudopots/result.ref | 4 ++-- tests/integrate/102_PW_DA_davidson/result.ref | 4 ++-- tests/integrate/103_PW_15_CF_CS_S1_smallg/result.ref | 10 +++++----- tests/integrate/103_PW_15_CF_CS_S2_smallg/result.ref | 10 +++++----- tests/integrate/103_PW_15_CS_CF/result.ref | 10 +++++----- tests/integrate/103_PW_15_CS_CF_bspline/result.ref | 10 +++++----- tests/integrate/103_PW_CF_CS_S1_smallg/result.ref | 4 ++-- tests/integrate/103_PW_CF_CS_S2_smallg/result.ref | 4 ++-- tests/integrate/103_PW_OU_CS_CF/result.ref | 10 +++++----- tests/integrate/104_PW_AF_magnetic/result.ref | 6 +++--- tests/integrate/104_PW_FM_magnetic/result.ref | 6 +++--- tests/integrate/104_PW_NC_magnetic/result.ref | 6 +++--- tests/integrate/105_PW_FD_smearing/result.ref | 6 +++--- tests/integrate/105_PW_FX_smearing/result.ref | 4 ++-- tests/integrate/105_PW_GA_smearing/result.ref | 6 +++--- tests/integrate/105_PW_M2_smearing/result.ref | 6 +++--- tests/integrate/105_PW_MP_smearing/result.ref | 6 +++--- tests/integrate/105_PW_MV_smearing/result.ref | 6 +++--- tests/integrate/106_PW_BD_chargemixing/result.ref | 6 +++--- tests/integrate/106_PW_KK_chargemixing/result.ref | 6 +++--- tests/integrate/106_PW_PK_chargemixing/result.ref | 6 +++--- tests/integrate/106_PW_PL_chargemixing/result.ref | 6 +++--- tests/integrate/106_PW_PU_chargemixing/result.ref | 6 +++--- tests/integrate/107_PW_OB_outputbands/result.ref | 2 +- tests/integrate/107_PW_OD_outputdos/result.ref | 2 +- tests/integrate/108_PW_RE/result.ref | 8 ++++---- tests/integrate/108_PW_RE_MB/result.ref | 8 ++++---- tests/integrate/108_PW_RE_MG/result.ref | 6 +++--- tests/integrate/109_PW_CR/result.ref | 8 ++++---- tests/integrate/110_PW_SY_symmetry/result.ref | 4 ++-- tests/integrate/111_PW_S2_elec_add/result.ref | 10 +++++----- tests/integrate/111_PW_S2_elec_minus/result.ref | 6 +++--- tests/integrate/111_PW_elec_add/result.ref | 10 +++++----- tests/integrate/111_PW_elec_minus/result.ref | 8 ++++---- tests/integrate/114_PW_BD_15/result.ref | 6 +++--- tests/integrate/120_PW_KP_MD_FIRE/result.ref | 8 ++++---- tests/integrate/120_PW_KP_MD_NVE/result.ref | 8 ++++---- tests/integrate/120_PW_KP_MD_NVT/result.ref | 8 ++++---- tests/integrate/127_PW_15_PK_AF/result.ref | 6 +++--- tests/integrate/133_PW_DJ_PK/result.ref | 6 +++--- tests/integrate/135_PW_15_PK/result.ref | 6 +++--- tests/integrate/140_PW_15_SO/result.ref | 6 +++--- tests/integrate/140_PW_15_SO_average/result.ref | 6 +++--- tests/integrate/150_PW_15_CR_VDW3/result.ref | 10 +++++----- tests/integrate/170_PW_MD_1O/result.ref | 8 ++++---- tests/integrate/170_PW_MD_2O/result.ref | 8 ++++---- tests/integrate/201_NO_15_f_pseudopots/result.ref | 6 +++--- tests/integrate/201_NO_15_pseudopots/result.ref | 6 +++--- tests/integrate/201_NO_KP_15_CF_CS_Si/result.ref | 10 +++++----- tests/integrate/201_NO_KP_DJ_CF_CS_GaAs/result.ref | 10 +++++----- tests/integrate/201_NO_KP_DJ_Si/result.ref | 6 +++--- tests/integrate/201_NO_OU_pseudopots/result.ref | 4 ++-- tests/integrate/201_NO_upf201_pseudopots/result.ref | 4 ++-- tests/integrate/202_NO_KP_HP_hpseps/result.ref | 6 +++--- tests/integrate/203_NO_CF_CS_S1_smallg/result.ref | 10 +++++----- tests/integrate/203_NO_CF_CS_S2_smallg/result.ref | 4 ++-- tests/integrate/203_NO_bspline/result.ref | 10 +++++----- tests/integrate/204_NO_KP_AFM/result.ref | 6 +++--- tests/integrate/204_NO_KP_FM/result.ref | 4 ++-- tests/integrate/204_NO_KP_NC/result.ref | 4 ++-- tests/integrate/204_NO_NC_magnetic/result.ref | 6 +++--- tests/integrate/205_NO_FD_smearing/result.ref | 6 +++--- tests/integrate/205_NO_FX_smearing/result.ref | 4 ++-- tests/integrate/205_NO_GA_smearing/result.ref | 6 +++--- tests/integrate/205_NO_M2_smearing/result.ref | 6 +++--- tests/integrate/205_NO_MV_smearing/result.ref | 6 +++--- tests/integrate/206_NO_PK_chargemixing/result.ref | 6 +++--- tests/integrate/206_NO_PL_chargemixing/result.ref | 6 +++--- tests/integrate/206_NO_PU_chargemixing/result.ref | 6 +++--- tests/integrate/207_NO_KP_OB/result.ref | 4 ++-- tests/integrate/207_NO_KP_OD/result.ref | 2 +- tests/integrate/208_NO_KP_CF_RE/result.ref | 10 +++++----- tests/integrate/208_NO_KP_CS_CR/result.ref | 8 ++++---- tests/integrate/208_NO_KP_RE_MB/result.ref | 8 ++++---- tests/integrate/211_NO_S2_elec_add/result.ref | 4 ++-- tests/integrate/211_NO_S2_elec_minus/result.ref | 4 ++-- tests/integrate/211_NO_elec_add/result.ref | 8 ++++---- tests/integrate/211_NO_elec_minus/result.ref | 8 ++++---- tests/integrate/220_NO_KP_MD_FIRE/result.ref | 8 ++++---- tests/integrate/220_NO_KP_MD_NVE/result.ref | 8 ++++---- tests/integrate/220_NO_KP_MD_NVT/result.ref | 8 ++++---- tests/integrate/240_NO_KP_15_SO/result.ref | 6 +++--- tests/integrate/250_NO_KP_CR_VDW2/result.ref | 10 +++++----- tests/integrate/250_NO_KP_CR_VDW3/result.ref | 10 +++++----- tests/integrate/260_NO_15_PK_PU_AF/result.ref | 6 +++--- tests/integrate/270_NO_MD_1O/result.ref | 10 +++++----- tests/integrate/270_NO_MD_2O/result.ref | 10 +++++----- tests/integrate/301_NO_GO_15_CF_CS/result.ref | 10 +++++----- tests/integrate/301_NO_GO_DJ_Si/result.ref | 6 +++--- tests/integrate/304_NO_GO_AF/result.ref | 6 +++--- tests/integrate/304_NO_GO_FM/result.ref | 4 ++-- tests/integrate/307_NO_GO_OH/result.ref | 8 ++++---- tests/integrate/308_NO_GO_CF_RE/result.ref | 10 +++++----- tests/integrate/308_NO_GO_CS_CR/result.ref | 8 ++++---- tests/integrate/308_NO_GO_RE_MB/result.ref | 6 +++--- tests/integrate/311_NO_GO_S2_elec_minus/result.ref | 4 ++-- tests/integrate/311_NO_GO_elec_minus/result.ref | 8 ++++---- tests/integrate/320_NO_GO_MD_FIRE/result.ref | 8 ++++---- tests/integrate/320_NO_GO_MD_NVE/result.ref | 8 ++++---- tests/integrate/320_NO_GO_MD_NVT/result.ref | 8 ++++---- tests/integrate/345_NO_GO_BS/result.ref | 6 +++--- tests/integrate/401_NP_KP_sp/result.ref | 4 ++-- tests/integrate/401_NP_KP_spd/result.ref | 4 ++-- tests/integrate/601_NO_TDDFT_N2_occ/result.ref | 10 +++++----- tests/integrate/601_NO_TDDFT_N2_vel/result.ref | 10 +++++----- tests/integrate/801_PW_LT_sc/result.ref | 4 ++-- tests/integrate/802_PW_LT_fcc/result.ref | 4 ++-- tests/integrate/803_PW_LT_bcc/result.ref | 4 ++-- tests/integrate/804_PW_LT_hexagonal/result.ref | 4 ++-- tests/integrate/805_PW_LT_trigonal/result.ref | 4 ++-- tests/integrate/806_PW_LT_st/result.ref | 4 ++-- tests/integrate/807_PW_LT_bct/result.ref | 4 ++-- tests/integrate/808_PW_LT_so/result.ref | 4 ++-- tests/integrate/809_PW_LT_baco/result.ref | 4 ++-- tests/integrate/810_PW_LT_fco/result.ref | 4 ++-- tests/integrate/811_PW_LT_bco/result.ref | 4 ++-- tests/integrate/812_PW_LT_sm/result.ref | 4 ++-- tests/integrate/813_PW_LT_bacm/result.ref | 4 ++-- tests/integrate/814_PW_LT_triclinic/result.ref | 4 ++-- tests/integrate/815_NO_LT_sc/result.ref | 10 +++++----- tests/integrate/816_NO_LT_fcc/result.ref | 10 +++++----- tests/integrate/817_NO_LT_bcc/result.ref | 10 +++++----- tests/integrate/818_NO_LT_hexagonal/result.ref | 10 +++++----- tests/integrate/819_NO_LT_trigonal/result.ref | 10 +++++----- tests/integrate/820_NO_LT_st/result.ref | 10 +++++----- tests/integrate/821_NO_LT_bct/result.ref | 10 +++++----- tests/integrate/822_NO_LT_so/result.ref | 10 +++++----- tests/integrate/823_NO_LT_baco/result.ref | 10 +++++----- tests/integrate/824_NO_LT_fco/result.ref | 10 +++++----- tests/integrate/825_NO_LT_bco/result.ref | 10 +++++----- tests/integrate/826_NO_LT_sm/result.ref | 10 +++++----- tests/integrate/827_NO_LT_bacm/result.ref | 10 +++++----- tests/integrate/828_NO_LT_triclinic/result.ref | 10 +++++----- tests/integrate/829_NO_GO_LT_sc/result.ref | 10 +++++----- tests/integrate/830_NO_GO_LT_fcc/result.ref | 10 +++++----- tests/integrate/831_NO_GO_LT_bcc/result.ref | 8 ++++---- tests/integrate/832_NO_GO_LT_hexagonal/result.ref | 10 +++++----- tests/integrate/833_NO_GO_LT_trigonal/result.ref | 10 +++++----- tests/integrate/834_NO_GO_LT_st/result.ref | 10 +++++----- tests/integrate/835_NO_GO_LT_bct/result.ref | 10 +++++----- tests/integrate/836_NO_GO_LT_so/result.ref | 10 +++++----- tests/integrate/837_NO_GO_LT_baco/result.ref | 10 +++++----- tests/integrate/838_NO_GO_LT_fco/result.ref | 10 +++++----- tests/integrate/839_NO_GO_LT_bco/result.ref | 10 +++++----- tests/integrate/840_NO_GO_LT_sm/result.ref | 10 +++++----- tests/integrate/841_NO_GO_LT_bacm/result.ref | 10 +++++----- tests/integrate/842_NO_GO_LT_triclinic/result.ref | 10 +++++----- 153 files changed, 537 insertions(+), 537 deletions(-) diff --git a/tests/integrate/101_PW_15_f_pseudopots/result.ref b/tests/integrate/101_PW_15_f_pseudopots/result.ref index 38d9eeffec9..1b50d5c200f 100644 --- a/tests/integrate/101_PW_15_f_pseudopots/result.ref +++ b/tests/integrate/101_PW_15_f_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -3436.7453962201643662 -etotperatomref -3436.7453962202 -totaltimeref 0.29 +etotref -3436.7456195855502301 +etotperatomref -3436.7456195856 +totaltimeref 0.25569 diff --git a/tests/integrate/101_PW_15_pseudopots/result.ref b/tests/integrate/101_PW_15_pseudopots/result.ref index 53cfb8040b2..472be26df96 100644 --- a/tests/integrate/101_PW_15_pseudopots/result.ref +++ b/tests/integrate/101_PW_15_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -197.1405472976090607 -etotperatomref -98.5702736488 -totaltimeref 0.26 +etotref -197.1405644352684021 +etotperatomref -98.5702822176 +totaltimeref 0.24789 diff --git a/tests/integrate/101_PW_OU_pseudopots/result.ref b/tests/integrate/101_PW_OU_pseudopots/result.ref index 0ec5494fb2e..70393e0da2e 100644 --- a/tests/integrate/101_PW_OU_pseudopots/result.ref +++ b/tests/integrate/101_PW_OU_pseudopots/result.ref @@ -1,4 +1,4 @@ -etotref -212.9807623143877890 +etotref -212.9807623143886133 etotperatomref -106.4903811572 totalforceref 1.933998 -totaltimeref 0.34 +totaltimeref 0.24916 diff --git a/tests/integrate/101_PW_VW_pseudopots/result.ref b/tests/integrate/101_PW_VW_pseudopots/result.ref index 8f633f339ef..1026de1fd57 100644 --- a/tests/integrate/101_PW_VW_pseudopots/result.ref +++ b/tests/integrate/101_PW_VW_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -212.5017494788815497 +etotref -212.5017494788708632 etotperatomref -106.2508747394 -totaltimeref 0.25 +totaltimeref 0.21773 diff --git a/tests/integrate/101_PW_blps_pseudopots/result.ref b/tests/integrate/101_PW_blps_pseudopots/result.ref index b947111302f..6160c260e94 100644 --- a/tests/integrate/101_PW_blps_pseudopots/result.ref +++ b/tests/integrate/101_PW_blps_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -215.916802098472 -etotperatomref -107.958401049236 -totaltimeref 0.27 +etotref -215.9168025844694228 +etotperatomref -107.9584012922 +totaltimeref 0.18493 diff --git a/tests/integrate/101_PW_upf201_Al_pseudopots/result.ref b/tests/integrate/101_PW_upf201_Al_pseudopots/result.ref index b8cfbb764be..8321191faad 100644 --- a/tests/integrate/101_PW_upf201_Al_pseudopots/result.ref +++ b/tests/integrate/101_PW_upf201_Al_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -57.6687669261561098 -etotperatomref -57.6687669261561098 -totaltimeref 0.31724 +etotref -57.6687669261572680 +etotperatomref -57.6687669262 +totaltimeref 0.17453 diff --git a/tests/integrate/101_PW_upf201_pseudopots/result.ref b/tests/integrate/101_PW_upf201_pseudopots/result.ref index 93d82cd26d6..66105dcdd6b 100644 --- a/tests/integrate/101_PW_upf201_pseudopots/result.ref +++ b/tests/integrate/101_PW_upf201_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -261.1123684809314227 +etotref -261.1123684809232941 etotperatomref -130.5561842405 -totaltimeref 0.26 +totaltimeref 0.22726 diff --git a/tests/integrate/102_PW_DA_davidson/result.ref b/tests/integrate/102_PW_DA_davidson/result.ref index 3358d983056..5c5aba2ade3 100644 --- a/tests/integrate/102_PW_DA_davidson/result.ref +++ b/tests/integrate/102_PW_DA_davidson/result.ref @@ -1,3 +1,3 @@ -etotref -198.2238296207262067 +etotref -198.2238296207181065 etotperatomref -99.1119148104 -totaltimeref 0.22 +totaltimeref 0.25621 diff --git a/tests/integrate/103_PW_15_CF_CS_S1_smallg/result.ref b/tests/integrate/103_PW_15_CF_CS_S1_smallg/result.ref index d6da55bc2fd..2b640e9b1a9 100644 --- a/tests/integrate/103_PW_15_CF_CS_S1_smallg/result.ref +++ b/tests/integrate/103_PW_15_CF_CS_S1_smallg/result.ref @@ -1,5 +1,5 @@ -etotref -418.5390058330596048 -etotperatomref -139.5130019444 -totalforceref 775.141538 -totalstressref 2013.754655 -totaltimeref +8.12 +etotref -418.5390773892457332 +etotperatomref -139.5130257964 +totalforceref 775.141654 +totalstressref 2013.748121 +totaltimeref +3.68440 diff --git a/tests/integrate/103_PW_15_CF_CS_S2_smallg/result.ref b/tests/integrate/103_PW_15_CF_CS_S2_smallg/result.ref index 75228ea4133..59d83f4bd22 100644 --- a/tests/integrate/103_PW_15_CF_CS_S2_smallg/result.ref +++ b/tests/integrate/103_PW_15_CF_CS_S2_smallg/result.ref @@ -1,5 +1,5 @@ -etotref -418.5390721674327210 -etotperatomref -139.5130240558 -totalforceref 775.141667 -totalstressref 2013.747331 -totaltimeref +19.75 +etotref -418.5390721671562346 +etotperatomref -139.5130240557 +totalforceref 775.141668 +totalstressref 2013.747332 +totaltimeref +7.10204 diff --git a/tests/integrate/103_PW_15_CS_CF/result.ref b/tests/integrate/103_PW_15_CS_CF/result.ref index 50a1bbd8ca7..d634cbbe207 100644 --- a/tests/integrate/103_PW_15_CS_CF/result.ref +++ b/tests/integrate/103_PW_15_CS_CF/result.ref @@ -1,5 +1,5 @@ -etotref -4206.8776891314882960 -etotperatomref -2103.4388445657 -totalforceref 8.103662 -totalstressref 81776.138881 -totaltimeref +4.82 +etotref -4206.8778432613398763 +etotperatomref -2103.4389216307 +totalforceref 8.104034 +totalstressref 81776.142539 +totaltimeref +1.86203 diff --git a/tests/integrate/103_PW_15_CS_CF_bspline/result.ref b/tests/integrate/103_PW_15_CS_CF_bspline/result.ref index f60239bc285..6f15bd4c0a7 100644 --- a/tests/integrate/103_PW_15_CS_CF_bspline/result.ref +++ b/tests/integrate/103_PW_15_CS_CF_bspline/result.ref @@ -1,5 +1,5 @@ -etotref -4200.2531246755934262 -etotperatomref -2100.1265623378 -totalforceref 10.586356 -totalstressref 82981.349200 -totaltimeref +1.22 +etotref -4200.2532789945444165 +etotperatomref -2100.1266394973 +totalforceref 10.586354 +totalstressref 82981.350483 +totaltimeref +0.63892 diff --git a/tests/integrate/103_PW_CF_CS_S1_smallg/result.ref b/tests/integrate/103_PW_CF_CS_S1_smallg/result.ref index abf9500572e..e6a62eecd7e 100644 --- a/tests/integrate/103_PW_CF_CS_S1_smallg/result.ref +++ b/tests/integrate/103_PW_CF_CS_S1_smallg/result.ref @@ -1,5 +1,5 @@ -etotref -376.5302709544227469 +etotref -376.5302709544188815 etotperatomref -125.5100903181 totalforceref 987.469575 totalstressref 2048.625481 -totaltimeref +0.33 +totaltimeref +0.31761 diff --git a/tests/integrate/103_PW_CF_CS_S2_smallg/result.ref b/tests/integrate/103_PW_CF_CS_S2_smallg/result.ref index c0e8c0afd13..d79bb2f9f91 100644 --- a/tests/integrate/103_PW_CF_CS_S2_smallg/result.ref +++ b/tests/integrate/103_PW_CF_CS_S2_smallg/result.ref @@ -1,5 +1,5 @@ -etotref -376.5302709544327513 +etotref -376.5302709544168351 etotperatomref -125.5100903181 totalforceref 987.469575 totalstressref 2048.625481 -totaltimeref +0.87 +totaltimeref +0.47069 diff --git a/tests/integrate/103_PW_OU_CS_CF/result.ref b/tests/integrate/103_PW_OU_CS_CF/result.ref index 103862f12d4..7520a3223d6 100644 --- a/tests/integrate/103_PW_OU_CS_CF/result.ref +++ b/tests/integrate/103_PW_OU_CS_CF/result.ref @@ -1,5 +1,5 @@ -etotref -1687.3372452650710329 -etotperatomref -843.6686226325 -totalforceref 4.988096 -totalstressref 34076.541861 -totaltimeref +3.55 +etotref -1687.3372942267640155 +etotperatomref -843.6686471134 +totalforceref 4.988094 +totalstressref 34076.542345 +totaltimeref +1.38619 diff --git a/tests/integrate/104_PW_AF_magnetic/result.ref b/tests/integrate/104_PW_AF_magnetic/result.ref index 9ecc58addd0..5ade0ee2a6c 100644 --- a/tests/integrate/104_PW_AF_magnetic/result.ref +++ b/tests/integrate/104_PW_AF_magnetic/result.ref @@ -1,3 +1,3 @@ -etotref -5866.1747281854204630 -etotperatomref -2933.0873640927 -totaltimeref 1.37072 +etotref -5866.1747281848238345 +etotperatomref -2933.0873640924 +totaltimeref 0.74354 diff --git a/tests/integrate/104_PW_FM_magnetic/result.ref b/tests/integrate/104_PW_FM_magnetic/result.ref index ff309c5245c..faae05b0d34 100644 --- a/tests/integrate/104_PW_FM_magnetic/result.ref +++ b/tests/integrate/104_PW_FM_magnetic/result.ref @@ -1,3 +1,3 @@ -etotref -5866.1972974975478792 -etotperatomref -2933.0986487488 -totaltimeref 1.55426 +etotref -5866.1972974991922456 +etotperatomref -2933.0986487496 +totaltimeref 0.76669 diff --git a/tests/integrate/104_PW_NC_magnetic/result.ref b/tests/integrate/104_PW_NC_magnetic/result.ref index 6cbf3836f1f..d847209685a 100644 --- a/tests/integrate/104_PW_NC_magnetic/result.ref +++ b/tests/integrate/104_PW_NC_magnetic/result.ref @@ -1,3 +1,3 @@ -etotref -5866.1747312893548951 -etotperatomref -2933.0873656447 -totaltimeref 4.63381 +etotref -5866.1747283849499581 +etotperatomref -2933.0873641925 +totaltimeref 0.94562 diff --git a/tests/integrate/105_PW_FD_smearing/result.ref b/tests/integrate/105_PW_FD_smearing/result.ref index c96232dce7a..83867ef1ac6 100644 --- a/tests/integrate/105_PW_FD_smearing/result.ref +++ b/tests/integrate/105_PW_FD_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -9154.9242645437152532 -etotperatomref -1830.9848529087 -totaltimeref 5.19841 +etotref -9154.9244085567152069 +etotperatomref -1830.9848817113 +totaltimeref 1.24371 diff --git a/tests/integrate/105_PW_FX_smearing/result.ref b/tests/integrate/105_PW_FX_smearing/result.ref index 0bf9c86abb7..4800748118f 100644 --- a/tests/integrate/105_PW_FX_smearing/result.ref +++ b/tests/integrate/105_PW_FX_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -212.9934339557436260 +etotref -212.9934339557329395 etotperatomref -106.4967169779 -totaltimeref 0.27 +totaltimeref 0.22022 diff --git a/tests/integrate/105_PW_GA_smearing/result.ref b/tests/integrate/105_PW_GA_smearing/result.ref index c0202b57c06..b15fdadc019 100644 --- a/tests/integrate/105_PW_GA_smearing/result.ref +++ b/tests/integrate/105_PW_GA_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -9154.8888662199788087 -etotperatomref -1830.9777732440 -totaltimeref 5.20976 +etotref -9154.8890102701607248 +etotperatomref -1830.9778020540 +totaltimeref 1.31082 diff --git a/tests/integrate/105_PW_M2_smearing/result.ref b/tests/integrate/105_PW_M2_smearing/result.ref index 1fc24219c72..56c7e9012a6 100644 --- a/tests/integrate/105_PW_M2_smearing/result.ref +++ b/tests/integrate/105_PW_M2_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -1824.7600498986896582 -etotperatomref -1824.7600498987 -totaltimeref 0.41 +etotref -1824.7600798575761019 +etotperatomref -1824.7600798576 +totaltimeref 0.27968 diff --git a/tests/integrate/105_PW_MP_smearing/result.ref b/tests/integrate/105_PW_MP_smearing/result.ref index b02c78bd227..2ab1be0b466 100644 --- a/tests/integrate/105_PW_MP_smearing/result.ref +++ b/tests/integrate/105_PW_MP_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -3076.7955256078603270 -etotperatomref -3076.7955256079 -totaltimeref 1.39 +etotref -3076.7954958501354668 +etotperatomref -3076.7954958501 +totaltimeref 0.56465 diff --git a/tests/integrate/105_PW_MV_smearing/result.ref b/tests/integrate/105_PW_MV_smearing/result.ref index 7873da24758..a40c046d0b1 100644 --- a/tests/integrate/105_PW_MV_smearing/result.ref +++ b/tests/integrate/105_PW_MV_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -712.6316015880270243 -etotperatomref -356.3158007940 -totaltimeref 0.25 +etotref -712.6316223439622490 +etotperatomref -356.3158111720 +totaltimeref 0.27920 diff --git a/tests/integrate/106_PW_BD_chargemixing/result.ref b/tests/integrate/106_PW_BD_chargemixing/result.ref index ebeea134094..db19d752bc6 100644 --- a/tests/integrate/106_PW_BD_chargemixing/result.ref +++ b/tests/integrate/106_PW_BD_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1827.0057414526656885 -etotperatomref -1827.0057414527 -totaltimeref 0.28 +etotref -1827.0057723554482436 +etotperatomref -1827.0057723554 +totaltimeref 0.25269 diff --git a/tests/integrate/106_PW_KK_chargemixing/result.ref b/tests/integrate/106_PW_KK_chargemixing/result.ref index fc861e6f77d..2259c6dbb85 100644 --- a/tests/integrate/106_PW_KK_chargemixing/result.ref +++ b/tests/integrate/106_PW_KK_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1827.0057414436446379 -etotperatomref -1827.0057414436 -totaltimeref 0.34 +etotref -1827.0057723380321022 +etotperatomref -1827.0057723380 +totaltimeref 0.27387 diff --git a/tests/integrate/106_PW_PK_chargemixing/result.ref b/tests/integrate/106_PW_PK_chargemixing/result.ref index d93110db5c5..15aa2652685 100644 --- a/tests/integrate/106_PW_PK_chargemixing/result.ref +++ b/tests/integrate/106_PW_PK_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1827.0057414552159116 -etotperatomref -1827.0057414552 -totaltimeref 0.28 +etotref -1827.0057723387865281 +etotperatomref -1827.0057723388 +totaltimeref 0.24384 diff --git a/tests/integrate/106_PW_PL_chargemixing/result.ref b/tests/integrate/106_PW_PL_chargemixing/result.ref index 11d186768ec..7934aabf697 100644 --- a/tests/integrate/106_PW_PL_chargemixing/result.ref +++ b/tests/integrate/106_PW_PL_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1827.0057414351458647 -etotperatomref -1827.0057414351 -totaltimeref 0.28 +etotref -1827.0057723217482817 +etotperatomref -1827.0057723217 +totaltimeref 0.23232 diff --git a/tests/integrate/106_PW_PU_chargemixing/result.ref b/tests/integrate/106_PW_PU_chargemixing/result.ref index 2067a9b1026..833bc8298aa 100644 --- a/tests/integrate/106_PW_PU_chargemixing/result.ref +++ b/tests/integrate/106_PW_PU_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1827.0057414576297106 -etotperatomref -1827.0057414576 -totaltimeref 0.28 +etotref -1827.0057723529146188 +etotperatomref -1827.0057723529 +totaltimeref 0.22591 diff --git a/tests/integrate/107_PW_OB_outputbands/result.ref b/tests/integrate/107_PW_OB_outputbands/result.ref index a56cd97316f..18fb3e119a7 100644 --- a/tests/integrate/107_PW_OB_outputbands/result.ref +++ b/tests/integrate/107_PW_OB_outputbands/result.ref @@ -1,2 +1,2 @@ totalbandref 243.274815 -totaltimeref 0.15756 +totaltimeref diff --git a/tests/integrate/107_PW_OD_outputdos/result.ref b/tests/integrate/107_PW_OD_outputdos/result.ref index 168065ab4d0..aaadab5a107 100644 --- a/tests/integrate/107_PW_OD_outputdos/result.ref +++ b/tests/integrate/107_PW_OD_outputdos/result.ref @@ -1,2 +1,2 @@ totaldosref 1190.44 -totaltimeref +totaltimeref 0.12700 diff --git a/tests/integrate/108_PW_RE/result.ref b/tests/integrate/108_PW_RE/result.ref index 8c419b1c602..b079432e723 100644 --- a/tests/integrate/108_PW_RE/result.ref +++ b/tests/integrate/108_PW_RE/result.ref @@ -1,5 +1,5 @@ -etotref -211.5049218009923493 -etotperatomref -105.7524609005 +etotref -211.5049348072273858 +etotperatomref -105.7524674036 totalforceref 5.333244 -totalstressref 831.312220 -totaltimeref +1.24 +totalstressref 831.312161 +totaltimeref +0.82470 diff --git a/tests/integrate/108_PW_RE_MB/result.ref b/tests/integrate/108_PW_RE_MB/result.ref index 16027423727..7970b551a2f 100644 --- a/tests/integrate/108_PW_RE_MB/result.ref +++ b/tests/integrate/108_PW_RE_MB/result.ref @@ -1,4 +1,4 @@ -etotref -211.6198448450466572 -etotperatomref -105.8099224225 -totalforceref 6.582492 -totaltimeref 0.80 +etotref -211.6198578547672184 +etotperatomref -105.8099289274 +totalforceref 6.582534 +totaltimeref 0.67360 diff --git a/tests/integrate/108_PW_RE_MG/result.ref b/tests/integrate/108_PW_RE_MG/result.ref index 2bb66a0f25d..e60db73a6db 100644 --- a/tests/integrate/108_PW_RE_MG/result.ref +++ b/tests/integrate/108_PW_RE_MG/result.ref @@ -1,4 +1,4 @@ -etotref -210.7981017049479817 -etotperatomref -105.3990508525 +etotref -210.7981143004323030 +etotperatomref -105.3990571502 totalforceref 25.502706 -totaltimeref 0.74 +totaltimeref 0.63231 diff --git a/tests/integrate/109_PW_CR/result.ref b/tests/integrate/109_PW_CR/result.ref index 874e1a6d07c..ceb4f770b79 100644 --- a/tests/integrate/109_PW_CR/result.ref +++ b/tests/integrate/109_PW_CR/result.ref @@ -1,5 +1,5 @@ -etotref -211.8220593792583486 -etotperatomref -105.9110296896 +etotref -211.8220727419407581 +etotperatomref -105.9110363710 totalforceref 0.000046 -totalstressref 348.864350 -totaltimeref +1.14 +totalstressref 348.864353 +totaltimeref +0.72742 diff --git a/tests/integrate/110_PW_SY_symmetry/result.ref b/tests/integrate/110_PW_SY_symmetry/result.ref index 1d9c41a5f89..b8000e89bb1 100644 --- a/tests/integrate/110_PW_SY_symmetry/result.ref +++ b/tests/integrate/110_PW_SY_symmetry/result.ref @@ -1,3 +1,3 @@ -etotref -212.9934339557430576 +etotref -212.9934339557327689 etotperatomref -106.4967169779 -totaltimeref 0.40 +totaltimeref 0.24934 diff --git a/tests/integrate/111_PW_S2_elec_add/result.ref b/tests/integrate/111_PW_S2_elec_add/result.ref index 2980f71d779..447a252374b 100644 --- a/tests/integrate/111_PW_S2_elec_add/result.ref +++ b/tests/integrate/111_PW_S2_elec_add/result.ref @@ -1,5 +1,5 @@ -etotref -204.0827544455076463 -etotperatomref -102.0413772228 -totalforceref 6.751564 -totalstressref 2327.687165 -totaltimeref +1.82 +etotref -204.0827544486539580 +etotperatomref -102.0413772243 +totalforceref 6.751560 +totalstressref 2327.687370 +totaltimeref +0.80810 diff --git a/tests/integrate/111_PW_S2_elec_minus/result.ref b/tests/integrate/111_PW_S2_elec_minus/result.ref index 6700abea58b..3a1853e4b30 100644 --- a/tests/integrate/111_PW_S2_elec_minus/result.ref +++ b/tests/integrate/111_PW_S2_elec_minus/result.ref @@ -1,5 +1,5 @@ -etotref -1828.3296270481016563 +etotref -1828.3296270480752810 etotperatomref -1828.3296270481 totalforceref 0.000000 -totalstressref 19914.866886 -totaltimeref +0.89 +totalstressref 19914.866883 +totaltimeref +0.51252 diff --git a/tests/integrate/111_PW_elec_add/result.ref b/tests/integrate/111_PW_elec_add/result.ref index aa841895457..832de452fe7 100644 --- a/tests/integrate/111_PW_elec_add/result.ref +++ b/tests/integrate/111_PW_elec_add/result.ref @@ -1,5 +1,5 @@ -etotref -204.0633481856775120 -etotperatomref -102.0316740928 -totalforceref 6.753302 -totalstressref 2329.029686 -totaltimeref +0.84 +etotref -204.0633597012220548 +etotperatomref -102.0316798506 +totalforceref 6.753298 +totalstressref 2329.029731 +totaltimeref +0.40422 diff --git a/tests/integrate/111_PW_elec_minus/result.ref b/tests/integrate/111_PW_elec_minus/result.ref index d7d4ae35618..2651e72ec55 100644 --- a/tests/integrate/111_PW_elec_minus/result.ref +++ b/tests/integrate/111_PW_elec_minus/result.ref @@ -1,5 +1,5 @@ -etotref -1828.3296084466703633 -etotperatomref -1828.3296084467 +etotref -1828.3296385252835989 +etotperatomref -1828.3296385253 totalforceref 0.000000 -totalstressref 19914.868440 -totaltimeref +0.49 +totalstressref 19914.868692 +totaltimeref +0.30942 diff --git a/tests/integrate/114_PW_BD_15/result.ref b/tests/integrate/114_PW_BD_15/result.ref index 0b267bc370f..690ac36267f 100644 --- a/tests/integrate/114_PW_BD_15/result.ref +++ b/tests/integrate/114_PW_BD_15/result.ref @@ -1,3 +1,3 @@ -etotref -197.1405472912967127 -etotperatomref -98.5702736456 -totaltimeref 0.23 +etotref -197.1405644233169028 +etotperatomref -98.5702822117 +totaltimeref 0.26700 diff --git a/tests/integrate/120_PW_KP_MD_FIRE/result.ref b/tests/integrate/120_PW_KP_MD_FIRE/result.ref index 8bf20e168d6..4c2f598cff3 100644 --- a/tests/integrate/120_PW_KP_MD_FIRE/result.ref +++ b/tests/integrate/120_PW_KP_MD_FIRE/result.ref @@ -1,5 +1,5 @@ -etotref -211.7811062943954710 -etotperatomref -105.8905531472 +etotref -211.7811196630946426 +etotperatomref -105.8905598315 totalforceref 2.488928 -totalstressref 438.340529 -totaltimeref +1.28463 +totalstressref 438.340492 +totaltimeref +0.75608 diff --git a/tests/integrate/120_PW_KP_MD_NVE/result.ref b/tests/integrate/120_PW_KP_MD_NVE/result.ref index 34ca9d5f18f..ae16715ba6e 100644 --- a/tests/integrate/120_PW_KP_MD_NVE/result.ref +++ b/tests/integrate/120_PW_KP_MD_NVE/result.ref @@ -1,5 +1,5 @@ -etotref -211.7811062943954710 -etotperatomref -105.8905531472 +etotref -211.7811196630946426 +etotperatomref -105.8905598315 totalforceref 2.488928 -totalstressref 438.340529 -totaltimeref +1.29656 +totalstressref 438.340492 +totaltimeref +0.81354 diff --git a/tests/integrate/120_PW_KP_MD_NVT/result.ref b/tests/integrate/120_PW_KP_MD_NVT/result.ref index 8ea7562f6d9..4c00a0ceabd 100644 --- a/tests/integrate/120_PW_KP_MD_NVT/result.ref +++ b/tests/integrate/120_PW_KP_MD_NVT/result.ref @@ -1,5 +1,5 @@ -etotref -211.7844155910110260 -etotperatomref -105.8922077955 +etotref -211.7844289597302634 +etotperatomref -105.8922144799 totalforceref 2.079832 -totalstressref 427.615154 -totaltimeref +1.24968 +totalstressref 427.615125 +totaltimeref +0.74218 diff --git a/tests/integrate/127_PW_15_PK_AF/result.ref b/tests/integrate/127_PW_15_PK_AF/result.ref index 2f1f2834a49..128b978a555 100644 --- a/tests/integrate/127_PW_15_PK_AF/result.ref +++ b/tests/integrate/127_PW_15_PK_AF/result.ref @@ -1,3 +1,3 @@ -etotref -6141.0777738435708670 -etotperatomref -3070.5388869218 -totaltimeref 7.22 +etotref -6141.0777479102325742 +etotperatomref -3070.5388739551 +totaltimeref 3.13644 diff --git a/tests/integrate/133_PW_DJ_PK/result.ref b/tests/integrate/133_PW_DJ_PK/result.ref index ab5305f3129..2f837823592 100644 --- a/tests/integrate/133_PW_DJ_PK/result.ref +++ b/tests/integrate/133_PW_DJ_PK/result.ref @@ -1,3 +1,3 @@ -etotref -227.6339162609414473 -etotperatomref -113.8169581305 -totaltimeref 0.62 +etotref -227.6339320360473550 +etotperatomref -113.8169660180 +totaltimeref 0.35054 diff --git a/tests/integrate/135_PW_15_PK/result.ref b/tests/integrate/135_PW_15_PK/result.ref index 2e785759f64..e937e680e70 100644 --- a/tests/integrate/135_PW_15_PK/result.ref +++ b/tests/integrate/135_PW_15_PK/result.ref @@ -1,3 +1,3 @@ -etotref -1685.2868782152668246 -etotperatomref -842.6434391076 -totaltimeref 3.37 +etotref -1685.2869270036885609 +etotperatomref -842.6434635018 +totaltimeref 1.28405 diff --git a/tests/integrate/140_PW_15_SO/result.ref b/tests/integrate/140_PW_15_SO/result.ref index 92c05dd5bee..d8d16b4a41c 100644 --- a/tests/integrate/140_PW_15_SO/result.ref +++ b/tests/integrate/140_PW_15_SO/result.ref @@ -1,3 +1,3 @@ -etotref -1940.2366850458683984 -etotperatomref -970.1183425229 -totaltimeref 8.20 +etotref -1940.2366850760481611 +etotperatomref -970.1183425380 +totaltimeref 5.99897 diff --git a/tests/integrate/140_PW_15_SO_average/result.ref b/tests/integrate/140_PW_15_SO_average/result.ref index 886b24e2cf9..5f63c834527 100644 --- a/tests/integrate/140_PW_15_SO_average/result.ref +++ b/tests/integrate/140_PW_15_SO_average/result.ref @@ -1,3 +1,3 @@ -etotref -1940.4439491538623770 -etotperatomref -970.2219745769 -totaltimeref 1.95 +etotref -1940.4440038756742979 +etotperatomref -970.2220019378 +totaltimeref 1.03912 diff --git a/tests/integrate/150_PW_15_CR_VDW3/result.ref b/tests/integrate/150_PW_15_CR_VDW3/result.ref index 1b069a218fb..22db6733a42 100644 --- a/tests/integrate/150_PW_15_CR_VDW3/result.ref +++ b/tests/integrate/150_PW_15_CR_VDW3/result.ref @@ -1,5 +1,5 @@ -etotref -4009.5593316581530416 -etotperatomref -2004.7796658291 -totalforceref 0.853042 -totalstressref 5110.564941 -totaltimeref +4.07016 +etotref -4009.5594572099025754 +etotperatomref -2004.7797286050 +totalforceref 0.853012 +totalstressref 5110.563901 +totaltimeref +1.11389 diff --git a/tests/integrate/170_PW_MD_1O/result.ref b/tests/integrate/170_PW_MD_1O/result.ref index b2077de7965..7dc97352449 100644 --- a/tests/integrate/170_PW_MD_1O/result.ref +++ b/tests/integrate/170_PW_MD_1O/result.ref @@ -1,5 +1,5 @@ -etotref -211.7989630494656978 -etotperatomref -105.8994815247 +etotref -211.7989764183330408 +etotperatomref -105.8994882092 totalforceref 0.673690 -totalstressref 387.297998 -totaltimeref +1.84794 +totalstressref 387.297991 +totaltimeref +1.30228 diff --git a/tests/integrate/170_PW_MD_2O/result.ref b/tests/integrate/170_PW_MD_2O/result.ref index 94ca660d4e8..39624414a5f 100644 --- a/tests/integrate/170_PW_MD_2O/result.ref +++ b/tests/integrate/170_PW_MD_2O/result.ref @@ -1,5 +1,5 @@ -etotref -211.7989629812969099 -etotperatomref -105.8994814906 +etotref -211.7989763501604443 +etotperatomref -105.8994881751 totalforceref 0.674650 -totalstressref 387.345111 -totaltimeref +1.77587 +totalstressref 387.345104 +totaltimeref +1.21653 diff --git a/tests/integrate/201_NO_15_f_pseudopots/result.ref b/tests/integrate/201_NO_15_f_pseudopots/result.ref index f6de79033ce..fe15bec664d 100644 --- a/tests/integrate/201_NO_15_f_pseudopots/result.ref +++ b/tests/integrate/201_NO_15_f_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -3454.453537915334 -etotperatomref -3454.4535379153 -totaltimeref 7.0 +etotref -3454.453765718245 +etotperatomref -3454.4537657182 +totaltimeref 3.2230 diff --git a/tests/integrate/201_NO_15_pseudopots/result.ref b/tests/integrate/201_NO_15_pseudopots/result.ref index 231f29df46d..aedd0f08ef3 100644 --- a/tests/integrate/201_NO_15_pseudopots/result.ref +++ b/tests/integrate/201_NO_15_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -197.1510816936913 -etotperatomref -98.5755408468 -totaltimeref 4.1 +etotref -197.1510992866178 +etotperatomref -98.5755496433 +totaltimeref 1.1672 diff --git a/tests/integrate/201_NO_KP_15_CF_CS_Si/result.ref b/tests/integrate/201_NO_KP_15_CF_CS_Si/result.ref index d0902838ce9..36302af33fb 100644 --- a/tests/integrate/201_NO_KP_15_CF_CS_Si/result.ref +++ b/tests/integrate/201_NO_KP_15_CF_CS_Si/result.ref @@ -1,5 +1,5 @@ -etotref -205.3081974346920049 -etotperatomref -102.6540987173 -totalforceref 0.466584 -totalstressref 44.477311 -totaltimeref +4.05399 +etotref -205.3082152722922160 +etotperatomref -102.6541076361 +totalforceref 0.466590 +totalstressref 44.477814 +totaltimeref +2.16892 diff --git a/tests/integrate/201_NO_KP_DJ_CF_CS_GaAs/result.ref b/tests/integrate/201_NO_KP_DJ_CF_CS_GaAs/result.ref index c16f7403ae3..a1d8dd51b3d 100644 --- a/tests/integrate/201_NO_KP_DJ_CF_CS_GaAs/result.ref +++ b/tests/integrate/201_NO_KP_DJ_CF_CS_GaAs/result.ref @@ -1,5 +1,5 @@ -etotref -5063.7351132862058876 -etotperatomref -2531.8675566431 -totalforceref 120.480162 -totalstressref 45245.325202 -totaltimeref +44.504 +etotref -5063.7353000386819986 +etotperatomref -2531.8676500193 +totalforceref 120.480264 +totalstressref 45245.345839 +totaltimeref +3.06899 diff --git a/tests/integrate/201_NO_KP_DJ_Si/result.ref b/tests/integrate/201_NO_KP_DJ_Si/result.ref index 523ac5bbff9..d7376738bc8 100644 --- a/tests/integrate/201_NO_KP_DJ_Si/result.ref +++ b/tests/integrate/201_NO_KP_DJ_Si/result.ref @@ -1,3 +1,3 @@ -etotref -227.6006682333153 -etotperatomref -113.8003341167 -totaltimeref 3.37 +etotref -227.6006842377674 +etotperatomref -113.8003421189 +totaltimeref 0.81281 diff --git a/tests/integrate/201_NO_OU_pseudopots/result.ref b/tests/integrate/201_NO_OU_pseudopots/result.ref index 1147994f93d..f8eea99bc5d 100644 --- a/tests/integrate/201_NO_OU_pseudopots/result.ref +++ b/tests/integrate/201_NO_OU_pseudopots/result.ref @@ -1,4 +1,4 @@ -etotref -212.7076086748528 +etotref -212.7076086748538 etotperatomref -106.3538043374 totalforceref 2.022356 -totaltimeref 8.1 +totaltimeref 2.6051 diff --git a/tests/integrate/201_NO_upf201_pseudopots/result.ref b/tests/integrate/201_NO_upf201_pseudopots/result.ref index e2a747fb925..205c069226f 100644 --- a/tests/integrate/201_NO_upf201_pseudopots/result.ref +++ b/tests/integrate/201_NO_upf201_pseudopots/result.ref @@ -1,3 +1,3 @@ -etotref -260.9627868869136 +etotref -260.9627868869030 etotperatomref -130.4813934435 -totaltimeref 3.1 +totaltimeref 0.97637 diff --git a/tests/integrate/202_NO_KP_HP_hpseps/result.ref b/tests/integrate/202_NO_KP_HP_hpseps/result.ref index 6f514cc73bf..aa946dcd683 100644 --- a/tests/integrate/202_NO_KP_HP_hpseps/result.ref +++ b/tests/integrate/202_NO_KP_HP_hpseps/result.ref @@ -1,3 +1,3 @@ -etotref -197.1510816945242 -etotperatomref -98.5755408473 -totaltimeref 11.0 +etotref -197.1510992874946 +etotperatomref -98.5755496437 +totaltimeref 1.2083 diff --git a/tests/integrate/203_NO_CF_CS_S1_smallg/result.ref b/tests/integrate/203_NO_CF_CS_S1_smallg/result.ref index 32abd3d9fb5..0706cf73ced 100644 --- a/tests/integrate/203_NO_CF_CS_S1_smallg/result.ref +++ b/tests/integrate/203_NO_CF_CS_S1_smallg/result.ref @@ -1,5 +1,5 @@ -etotref -414.5973891123759358 -etotperatomref -138.1991297041 -totalforceref 809.898290 -totalstressref 2099.709007 -totaltimeref +16.73 +etotref -414.5974464473484886 +etotperatomref -138.1991488158 +totalforceref 809.898120 +totalstressref 2099.707694 +totaltimeref +5.15441 diff --git a/tests/integrate/203_NO_CF_CS_S2_smallg/result.ref b/tests/integrate/203_NO_CF_CS_S2_smallg/result.ref index cd98850ff80..b54a2885215 100644 --- a/tests/integrate/203_NO_CF_CS_S2_smallg/result.ref +++ b/tests/integrate/203_NO_CF_CS_S2_smallg/result.ref @@ -1,5 +1,5 @@ -etotref -414.5974371061202532 +etotref -414.5974371058629231 etotperatomref -138.1991457020 totalforceref 809.898130 totalstressref 2099.705596 -totaltimeref +29.85 +totaltimeref +8.67422 diff --git a/tests/integrate/203_NO_bspline/result.ref b/tests/integrate/203_NO_bspline/result.ref index 98fe80d1571..988570a9cdb 100644 --- a/tests/integrate/203_NO_bspline/result.ref +++ b/tests/integrate/203_NO_bspline/result.ref @@ -1,5 +1,5 @@ -etotref -5064.4144637077706648 -etotperatomref -2532.2072318539 -totalforceref 122.897460 -totalstressref 45625.040475 -totaltimeref +4.70767 +etotref -5064.4146528213323109 +etotperatomref -2532.2073264107 +totalforceref 122.897568 +totalstressref 45625.062810 +totaltimeref +2.86132 diff --git a/tests/integrate/204_NO_KP_AFM/result.ref b/tests/integrate/204_NO_KP_AFM/result.ref index fe61f6b94ea..764b9ec8b16 100644 --- a/tests/integrate/204_NO_KP_AFM/result.ref +++ b/tests/integrate/204_NO_KP_AFM/result.ref @@ -1,3 +1,3 @@ -etotref -211.5641445539016 -etotperatomref -105.7820722770 -totaltimeref 26.2 +etotref -211.5641445538902 +etotperatomref -105.7820722769 +totaltimeref 3.5836 diff --git a/tests/integrate/204_NO_KP_FM/result.ref b/tests/integrate/204_NO_KP_FM/result.ref index 885fd3028d1..b4e0fcb2ad2 100644 --- a/tests/integrate/204_NO_KP_FM/result.ref +++ b/tests/integrate/204_NO_KP_FM/result.ref @@ -1,3 +1,3 @@ -etotref -211.5641445538930 +etotref -211.5641445538928 etotperatomref -105.7820722769 -totaltimeref 5.75 +totaltimeref 2.0856 diff --git a/tests/integrate/204_NO_KP_NC/result.ref b/tests/integrate/204_NO_KP_NC/result.ref index d50df729ae5..13998be4c06 100644 --- a/tests/integrate/204_NO_KP_NC/result.ref +++ b/tests/integrate/204_NO_KP_NC/result.ref @@ -1,3 +1,3 @@ -etotref -319.8942103569556 +etotref -319.8942103569877 etotperatomref -159.9471051785 -totaltimeref 93. +totaltimeref 4.2802 diff --git a/tests/integrate/204_NO_NC_magnetic/result.ref b/tests/integrate/204_NO_NC_magnetic/result.ref index 639674069c8..3f6618a6173 100644 --- a/tests/integrate/204_NO_NC_magnetic/result.ref +++ b/tests/integrate/204_NO_NC_magnetic/result.ref @@ -1,3 +1,3 @@ -etotref -4870.339224795774 -etotperatomref -2435.1696123979 -totaltimeref 30. +etotref -4870.339224795971 +etotperatomref -2435.1696123980 +totaltimeref 10.468 diff --git a/tests/integrate/205_NO_FD_smearing/result.ref b/tests/integrate/205_NO_FD_smearing/result.ref index 8e849b84274..47cff3c9c65 100644 --- a/tests/integrate/205_NO_FD_smearing/result.ref +++ b/tests/integrate/205_NO_FD_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -10009.76524485243 -etotperatomref -2001.9530489705 -totaltimeref 23. +etotref -10009.76543319645 +etotperatomref -2001.9530866393 +totaltimeref 8.8819 diff --git a/tests/integrate/205_NO_FX_smearing/result.ref b/tests/integrate/205_NO_FX_smearing/result.ref index 8e8958aba6a..0238266fcef 100644 --- a/tests/integrate/205_NO_FX_smearing/result.ref +++ b/tests/integrate/205_NO_FX_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -211.5641445540704 +etotref -211.5641445540600 etotperatomref -105.7820722770 -totaltimeref 8.0 +totaltimeref 1.9489 diff --git a/tests/integrate/205_NO_GA_smearing/result.ref b/tests/integrate/205_NO_GA_smearing/result.ref index fbc638a0557..50d537be007 100644 --- a/tests/integrate/205_NO_GA_smearing/result.ref +++ b/tests/integrate/205_NO_GA_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -10009.77436343623 -etotperatomref -2001.9548726872 -totaltimeref 29. +etotref -10009.77455075878 +etotperatomref -2001.9549101518 +totaltimeref 10.922 diff --git a/tests/integrate/205_NO_M2_smearing/result.ref b/tests/integrate/205_NO_M2_smearing/result.ref index 443803d36b7..e9ab1eefc89 100644 --- a/tests/integrate/205_NO_M2_smearing/result.ref +++ b/tests/integrate/205_NO_M2_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -1992.111518766470 -etotperatomref -1992.1115187665 -totaltimeref 3.9 +etotref -1992.111551430742 +etotperatomref -1992.1115514307 +totaltimeref 1.5432 diff --git a/tests/integrate/205_NO_MV_smearing/result.ref b/tests/integrate/205_NO_MV_smearing/result.ref index f5152641139..9f1f3c5d927 100644 --- a/tests/integrate/205_NO_MV_smearing/result.ref +++ b/tests/integrate/205_NO_MV_smearing/result.ref @@ -1,3 +1,3 @@ -etotref -712.6090015780574 -etotperatomref -356.3045007890 -totaltimeref 23. +etotref -712.6090200722382 +etotperatomref -356.3045100361 +totaltimeref 5.0360 diff --git a/tests/integrate/206_NO_PK_chargemixing/result.ref b/tests/integrate/206_NO_PK_chargemixing/result.ref index 6ecdca8cc7a..1be67127df3 100644 --- a/tests/integrate/206_NO_PK_chargemixing/result.ref +++ b/tests/integrate/206_NO_PK_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1996.646951093111 -etotperatomref -1996.6469510931 -totaltimeref 1.5 +etotref -1996.646984922930 +etotperatomref -1996.6469849229 +totaltimeref 1.2422 diff --git a/tests/integrate/206_NO_PL_chargemixing/result.ref b/tests/integrate/206_NO_PL_chargemixing/result.ref index 0dce49c6983..5ea24955c79 100644 --- a/tests/integrate/206_NO_PL_chargemixing/result.ref +++ b/tests/integrate/206_NO_PL_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1996.646951137597 -etotperatomref -1996.6469511376 -totaltimeref 1.8 +etotref -1996.646984966179 +etotperatomref -1996.6469849662 +totaltimeref 1.3643 diff --git a/tests/integrate/206_NO_PU_chargemixing/result.ref b/tests/integrate/206_NO_PU_chargemixing/result.ref index baaf07fa1ff..4a376d81756 100644 --- a/tests/integrate/206_NO_PU_chargemixing/result.ref +++ b/tests/integrate/206_NO_PU_chargemixing/result.ref @@ -1,3 +1,3 @@ -etotref -1996.646950963574 -etotperatomref -1996.6469509636 -totaltimeref 1.3 +etotref -1996.646984765413 +etotperatomref -1996.6469847654 +totaltimeref 1.1889 diff --git a/tests/integrate/207_NO_KP_OB/result.ref b/tests/integrate/207_NO_KP_OB/result.ref index 0b8c716d030..3e974781df9 100644 --- a/tests/integrate/207_NO_KP_OB/result.ref +++ b/tests/integrate/207_NO_KP_OB/result.ref @@ -1,2 +1,2 @@ -totalbandref 248.427957 -totaltimeref 0.7965 +totalbandref 248.427925 +totaltimeref 0.56678 diff --git a/tests/integrate/207_NO_KP_OD/result.ref b/tests/integrate/207_NO_KP_OD/result.ref index 815da8aa65a..57d274bd3c4 100644 --- a/tests/integrate/207_NO_KP_OD/result.ref +++ b/tests/integrate/207_NO_KP_OD/result.ref @@ -1,2 +1,2 @@ totaldosref 1189.53 -totaltimeref +totaltimeref 1.0555 diff --git a/tests/integrate/208_NO_KP_CF_RE/result.ref b/tests/integrate/208_NO_KP_CF_RE/result.ref index b431b6ff712..86e3ebf932b 100644 --- a/tests/integrate/208_NO_KP_CF_RE/result.ref +++ b/tests/integrate/208_NO_KP_CF_RE/result.ref @@ -1,5 +1,5 @@ -etotref -211.3956779571906850 -etotperatomref -105.6978389786 -totalforceref 5.243618 -totalstressref 828.586147 -totaltimeref +20.69 +etotref -211.3956909660457484 +etotperatomref -105.6978454830 +totalforceref 5.243616 +totalstressref 828.586131 +totaltimeref +6.18246 diff --git a/tests/integrate/208_NO_KP_CS_CR/result.ref b/tests/integrate/208_NO_KP_CS_CR/result.ref index e639929f8b4..14c96da4231 100644 --- a/tests/integrate/208_NO_KP_CS_CR/result.ref +++ b/tests/integrate/208_NO_KP_CS_CR/result.ref @@ -1,5 +1,5 @@ -etotref -211.7271041349103200 -etotperatomref -105.8635520675 +etotref -211.7271174862360681 +etotperatomref -105.8635587431 totalforceref 0.000000 -totalstressref 340.584504 -totaltimeref 17.94 +totalstressref 340.584552 +totaltimeref 5.68937 diff --git a/tests/integrate/208_NO_KP_RE_MB/result.ref b/tests/integrate/208_NO_KP_RE_MB/result.ref index d59db6f02c0..a4cca61ce0f 100644 --- a/tests/integrate/208_NO_KP_RE_MB/result.ref +++ b/tests/integrate/208_NO_KP_RE_MB/result.ref @@ -1,4 +1,4 @@ -etotref -211.5071577448803 -etotperatomref -105.7535788724 -totalforceref 9.367974 -totaltimeref 18. +etotref -211.5071709850189 +etotperatomref -105.7535854925 +totalforceref 9.368004 +totaltimeref 4.4505 diff --git a/tests/integrate/211_NO_S2_elec_add/result.ref b/tests/integrate/211_NO_S2_elec_add/result.ref index ca0ff421750..ce2038c1ac3 100644 --- a/tests/integrate/211_NO_S2_elec_add/result.ref +++ b/tests/integrate/211_NO_S2_elec_add/result.ref @@ -1,5 +1,5 @@ -etotref -203.7508692128968448 +etotref -203.7508692128964469 etotperatomref -101.8754346064 totalforceref 6.700716 totalstressref 2239.343289 -totaltimeref +22.96783 +totaltimeref +12.75249 diff --git a/tests/integrate/211_NO_S2_elec_minus/result.ref b/tests/integrate/211_NO_S2_elec_minus/result.ref index 634fde25218..c094244ec0c 100644 --- a/tests/integrate/211_NO_S2_elec_minus/result.ref +++ b/tests/integrate/211_NO_S2_elec_minus/result.ref @@ -1,5 +1,5 @@ -etotref -2000.1549671674031288 +etotref -2000.1549671673908506 etotperatomref -2000.1549671674 totalforceref 0.000000 totalstressref 18696.588786 -totaltimeref +8.33 +totaltimeref +4.19012 diff --git a/tests/integrate/211_NO_elec_add/result.ref b/tests/integrate/211_NO_elec_add/result.ref index 36c71a6030b..acfbbd3db12 100644 --- a/tests/integrate/211_NO_elec_add/result.ref +++ b/tests/integrate/211_NO_elec_add/result.ref @@ -1,5 +1,5 @@ -etotref -203.7347412681091896 -etotperatomref -101.8673706341 +etotref -203.7347533462346973 +etotperatomref -101.8673766731 totalforceref 6.692754 -totalstressref 2240.896715 -totaltimeref +9.45359 +totalstressref 2240.896743 +totaltimeref +4.24912 diff --git a/tests/integrate/211_NO_elec_minus/result.ref b/tests/integrate/211_NO_elec_minus/result.ref index 2c43cf48fe2..edc96f2abf9 100644 --- a/tests/integrate/211_NO_elec_minus/result.ref +++ b/tests/integrate/211_NO_elec_minus/result.ref @@ -1,5 +1,5 @@ -etotref -2000.1549502104608109 -etotperatomref -2000.1549502105 +etotref -2000.1549807269748271 +etotperatomref -2000.1549807270 totalforceref 0.000000 -totalstressref 18696.588249 -totaltimeref +4.67 +totalstressref 18696.589485 +totaltimeref +2.63822 diff --git a/tests/integrate/220_NO_KP_MD_FIRE/result.ref b/tests/integrate/220_NO_KP_MD_FIRE/result.ref index a273904cbf1..c27f739534c 100644 --- a/tests/integrate/220_NO_KP_MD_FIRE/result.ref +++ b/tests/integrate/220_NO_KP_MD_FIRE/result.ref @@ -1,5 +1,5 @@ -etotref -211.6917087337825194 -etotperatomref -105.8458543669 +etotref -211.6917220832963267 +etotperatomref -105.8458610416 totalforceref 2.540704 -totalstressref 430.408877 -totaltimeref +15.02597 +totalstressref 430.408893 +totaltimeref +5.95029 diff --git a/tests/integrate/220_NO_KP_MD_NVE/result.ref b/tests/integrate/220_NO_KP_MD_NVE/result.ref index 5a3f378562f..bba32bf1b23 100644 --- a/tests/integrate/220_NO_KP_MD_NVE/result.ref +++ b/tests/integrate/220_NO_KP_MD_NVE/result.ref @@ -1,5 +1,5 @@ -etotref -211.6917087337825478 -etotperatomref -105.8458543669 +etotref -211.6917220832963551 +etotperatomref -105.8458610416 totalforceref 2.540704 -totalstressref 430.408877 -totaltimeref +15.10083 +totalstressref 430.408893 +totaltimeref +5.98608 diff --git a/tests/integrate/220_NO_KP_MD_NVT/result.ref b/tests/integrate/220_NO_KP_MD_NVT/result.ref index 343612bc0cd..1607b44a1e6 100644 --- a/tests/integrate/220_NO_KP_MD_NVT/result.ref +++ b/tests/integrate/220_NO_KP_MD_NVT/result.ref @@ -1,5 +1,5 @@ -etotref -211.6896371629715361 -etotperatomref -105.8448185815 +etotref -211.6896505124639134 +etotperatomref -105.8448252562 totalforceref 2.520046 -totalstressref 430.230780 -totaltimeref +14.96286 +totalstressref 430.230796 +totaltimeref +5.96808 diff --git a/tests/integrate/240_NO_KP_15_SO/result.ref b/tests/integrate/240_NO_KP_15_SO/result.ref index b654ff5c5a8..8852cef8f3c 100644 --- a/tests/integrate/240_NO_KP_15_SO/result.ref +++ b/tests/integrate/240_NO_KP_15_SO/result.ref @@ -1,3 +1,3 @@ -etotref -1870.568879522331 -etotperatomref -935.2844397612 -totaltimeref 93.7 +etotref -1870.568879523197 +etotperatomref -935.2844397616 +totaltimeref 16.038 diff --git a/tests/integrate/250_NO_KP_CR_VDW2/result.ref b/tests/integrate/250_NO_KP_CR_VDW2/result.ref index 6a2db99286d..891e4e6643d 100644 --- a/tests/integrate/250_NO_KP_CR_VDW2/result.ref +++ b/tests/integrate/250_NO_KP_CR_VDW2/result.ref @@ -1,5 +1,5 @@ -etotref -4262.5689526352498433 -etotperatomref -2131.2844763176 -totalforceref 0.320060 -totalstressref 409.978858 -totaltimeref +13.674 +etotref -4262.5690495251501488 +etotperatomref -2131.2845247626 +totalforceref 0.320062 +totalstressref 409.978937 +totaltimeref +5.08769 diff --git a/tests/integrate/250_NO_KP_CR_VDW3/result.ref b/tests/integrate/250_NO_KP_CR_VDW3/result.ref index e1a94e9e43c..89753801cd0 100644 --- a/tests/integrate/250_NO_KP_CR_VDW3/result.ref +++ b/tests/integrate/250_NO_KP_CR_VDW3/result.ref @@ -1,5 +1,5 @@ -etotref -4262.4810780157322370 -etotperatomref -2131.2405390079 -totalforceref 0.216574 -totalstressref 410.384422 -totaltimeref +13.745 +etotref -4262.4811749056207191 +etotperatomref -2131.2405874528 +totalforceref 0.216576 +totalstressref 410.384501 +totaltimeref +5.14938 diff --git a/tests/integrate/260_NO_15_PK_PU_AF/result.ref b/tests/integrate/260_NO_15_PK_PU_AF/result.ref index d9220f04504..cec0c198c3e 100644 --- a/tests/integrate/260_NO_15_PK_PU_AF/result.ref +++ b/tests/integrate/260_NO_15_PK_PU_AF/result.ref @@ -1,3 +1,3 @@ -etotref -7250.8489104633490570 -etotperatomref -1812.7122276158 -totaltimeref 7.70 +etotref -7250.8489104634099931 +etotperatomref -1812.7122276159 +totaltimeref 7.13240 diff --git a/tests/integrate/270_NO_MD_1O/result.ref b/tests/integrate/270_NO_MD_1O/result.ref index c256ec34c05..72f59b75c02 100644 --- a/tests/integrate/270_NO_MD_1O/result.ref +++ b/tests/integrate/270_NO_MD_1O/result.ref @@ -1,5 +1,5 @@ -etotref -211.5879819647362581 -etotperatomref -105.7939909824 -totalforceref 1.954338 -totalstressref 595.790527 -totaltimeref +28.48229 +etotref -211.5879950285990105 +etotperatomref -105.7939975143 +totalforceref 1.954348 +totalstressref 595.790314 +totaltimeref +10.44480 diff --git a/tests/integrate/270_NO_MD_2O/result.ref b/tests/integrate/270_NO_MD_2O/result.ref index d2ecd2475de..8f56e5cf123 100644 --- a/tests/integrate/270_NO_MD_2O/result.ref +++ b/tests/integrate/270_NO_MD_2O/result.ref @@ -1,5 +1,5 @@ -etotref -211.5879819668092239 -etotperatomref -105.7939909834 -totalforceref 1.954310 -totalstressref 595.789121 -totaltimeref +28.42436 +etotref -211.5879950307886190 +etotperatomref -105.7939975154 +totalforceref 1.954320 +totalstressref 595.788906 +totaltimeref +10.38425 diff --git a/tests/integrate/301_NO_GO_15_CF_CS/result.ref b/tests/integrate/301_NO_GO_15_CF_CS/result.ref index c822b12665b..55055625d5c 100644 --- a/tests/integrate/301_NO_GO_15_CF_CS/result.ref +++ b/tests/integrate/301_NO_GO_15_CF_CS/result.ref @@ -1,5 +1,5 @@ -etotref -204.6209535379965700 -etotperatomref -102.3104767690 -totalforceref 0.940712 -totalstressref 14.921960 -totaltimeref +2.561 +etotref -204.6209739505270022 +etotperatomref -102.3104869753 +totalforceref 0.940673 +totalstressref 14.921643 +totaltimeref +1.98814 diff --git a/tests/integrate/301_NO_GO_DJ_Si/result.ref b/tests/integrate/301_NO_GO_DJ_Si/result.ref index 1f4456885b1..16e47750bc8 100644 --- a/tests/integrate/301_NO_GO_DJ_Si/result.ref +++ b/tests/integrate/301_NO_GO_DJ_Si/result.ref @@ -1,3 +1,3 @@ -etotref -212.6400385776964 -etotperatomref -106.3200192888 -totaltimeref 0.96 +etotref -212.6400579517150 +etotperatomref -106.3200289759 +totaltimeref 0.67486 diff --git a/tests/integrate/304_NO_GO_AF/result.ref b/tests/integrate/304_NO_GO_AF/result.ref index 5c0ad583f82..ad513b75751 100644 --- a/tests/integrate/304_NO_GO_AF/result.ref +++ b/tests/integrate/304_NO_GO_AF/result.ref @@ -1,3 +1,3 @@ -etotref -6372.520190337425 -etotperatomref -3186.2600951687 -totaltimeref 11. +etotref -6372.520190335342 +etotperatomref -3186.2600951677 +totaltimeref 8.5271 diff --git a/tests/integrate/304_NO_GO_FM/result.ref b/tests/integrate/304_NO_GO_FM/result.ref index a66411d61c6..1928d4fb798 100644 --- a/tests/integrate/304_NO_GO_FM/result.ref +++ b/tests/integrate/304_NO_GO_FM/result.ref @@ -1,3 +1,3 @@ -etotref -196.0555462724182 +etotref -196.0555462724091 etotperatomref -98.0277731362 -totaltimeref 2.9 +totaltimeref 2.3325 diff --git a/tests/integrate/307_NO_GO_OH/result.ref b/tests/integrate/307_NO_GO_OH/result.ref index d407185c8c4..f0fe302927e 100644 --- a/tests/integrate/307_NO_GO_OH/result.ref +++ b/tests/integrate/307_NO_GO_OH/result.ref @@ -1,5 +1,5 @@ -etotref -204.5955633520227 -etotperatomref -102.2977816760 -totalHmatrix 41.193711 +etotref -204.5955834372641 +etotperatomref -102.2977917186 +totalHmatrix 41.193697 totalSmatrix 55.710272 -totaltimeref 4.06 +totaltimeref 1.2788 diff --git a/tests/integrate/308_NO_GO_CF_RE/result.ref b/tests/integrate/308_NO_GO_CF_RE/result.ref index 7cc1d8b1daa..7c77cf1ee6a 100644 --- a/tests/integrate/308_NO_GO_CF_RE/result.ref +++ b/tests/integrate/308_NO_GO_CF_RE/result.ref @@ -1,5 +1,5 @@ -etotref -196.2055558690879593 -etotperatomref -98.1027779345 -totalforceref 12.659378 -totalstressref 1635.171044 -totaltimeref +25.63 +etotref -196.2055731590284893 +etotperatomref -98.1027865795 +totalforceref 12.659410 +totalstressref 1635.170957 +totaltimeref +5.70917 diff --git a/tests/integrate/308_NO_GO_CS_CR/result.ref b/tests/integrate/308_NO_GO_CS_CR/result.ref index d0483925ff0..8fb49a5f209 100644 --- a/tests/integrate/308_NO_GO_CS_CR/result.ref +++ b/tests/integrate/308_NO_GO_CS_CR/result.ref @@ -1,5 +1,5 @@ -etotref -197.2114105448994508 -etotperatomref -98.6057052724 +etotref -197.2114281075652684 +etotperatomref -98.6057140538 totalforceref 0.000000 -totalstressref 1346.082405 -totaltimeref 16.15 +totalstressref 1346.081721 +totaltimeref 4.13670 diff --git a/tests/integrate/308_NO_GO_RE_MB/result.ref b/tests/integrate/308_NO_GO_RE_MB/result.ref index e5c809cc239..55839d29a27 100644 --- a/tests/integrate/308_NO_GO_RE_MB/result.ref +++ b/tests/integrate/308_NO_GO_RE_MB/result.ref @@ -1,4 +1,4 @@ -etotref -196.8393715139518 -etotperatomref -98.4196857570 +etotref -196.8393891024064 +etotperatomref -98.4196945512 totalforceref 15.849018 -totaltimeref 12. +totaltimeref 2.7860 diff --git a/tests/integrate/311_NO_GO_S2_elec_minus/result.ref b/tests/integrate/311_NO_GO_S2_elec_minus/result.ref index cda6990d747..76fb0392dde 100644 --- a/tests/integrate/311_NO_GO_S2_elec_minus/result.ref +++ b/tests/integrate/311_NO_GO_S2_elec_minus/result.ref @@ -1,5 +1,5 @@ -etotref -2008.0132185520162693 +etotref -2008.0132185520028543 etotperatomref -2008.0132185520 totalforceref 0.000000 totalstressref 68013.735078 -totaltimeref +6.33 +totaltimeref +3.58458 diff --git a/tests/integrate/311_NO_GO_elec_minus/result.ref b/tests/integrate/311_NO_GO_elec_minus/result.ref index 0e9df388d16..ec4450f6b75 100644 --- a/tests/integrate/311_NO_GO_elec_minus/result.ref +++ b/tests/integrate/311_NO_GO_elec_minus/result.ref @@ -1,5 +1,5 @@ -etotref -2008.0132019248164852 -etotperatomref -2008.0132019248 +etotref -2008.0132317935131141 +etotperatomref -2008.0132317935 totalforceref 0.000000 -totalstressref 27593.617671 -totaltimeref +3.83 +totalstressref 27593.618205 +totaltimeref +2.35581 diff --git a/tests/integrate/320_NO_GO_MD_FIRE/result.ref b/tests/integrate/320_NO_GO_MD_FIRE/result.ref index 828d6da68c1..ff7e4e22959 100644 --- a/tests/integrate/320_NO_GO_MD_FIRE/result.ref +++ b/tests/integrate/320_NO_GO_MD_FIRE/result.ref @@ -1,5 +1,5 @@ -etotref -197.1251149938644005 -etotperatomref -98.5625574969 +etotref -197.1251325896094784 +etotperatomref -98.5625662948 totalforceref 3.367520 -totalstressref 1429.252759 -totaltimeref +11.67397 +totalstressref 1429.252035 +totaltimeref +4.57898 diff --git a/tests/integrate/320_NO_GO_MD_NVE/result.ref b/tests/integrate/320_NO_GO_MD_NVE/result.ref index 6e3c7ecb194..cd9e582e5db 100644 --- a/tests/integrate/320_NO_GO_MD_NVE/result.ref +++ b/tests/integrate/320_NO_GO_MD_NVE/result.ref @@ -1,5 +1,5 @@ -etotref -197.1251149936946092 -etotperatomref -98.5625574968 +etotref -197.1251325894408239 +etotperatomref -98.5625662947 totalforceref 3.367518 -totalstressref 1429.252753 -totaltimeref +11.28376 +totalstressref 1429.252031 +totaltimeref +4.21575 diff --git a/tests/integrate/320_NO_GO_MD_NVT/result.ref b/tests/integrate/320_NO_GO_MD_NVT/result.ref index 62761b3f071..9413fc3af27 100644 --- a/tests/integrate/320_NO_GO_MD_NVT/result.ref +++ b/tests/integrate/320_NO_GO_MD_NVT/result.ref @@ -1,5 +1,5 @@ -etotref -197.1221860098347065 -etotperatomref -98.5610930049 +etotref -197.1222036054724356 +etotperatomref -98.5611018027 totalforceref 3.383774 -totalstressref 1439.895279 -totaltimeref +11.24960 +totalstressref 1439.894549 +totaltimeref +4.18915 diff --git a/tests/integrate/345_NO_GO_BS/result.ref b/tests/integrate/345_NO_GO_BS/result.ref index d546a6c3604..7a586369180 100644 --- a/tests/integrate/345_NO_GO_BS/result.ref +++ b/tests/integrate/345_NO_GO_BS/result.ref @@ -1,3 +1,3 @@ -etotref -268.9734688431619 -etotperatomref -134.4867344216 -totaltimeref 6.16 +etotref -268.9734688430915 +etotperatomref -134.4867344215 +totaltimeref 2.9478 diff --git a/tests/integrate/401_NP_KP_sp/result.ref b/tests/integrate/401_NP_KP_sp/result.ref index 6662079fc5f..89daa65dae4 100644 --- a/tests/integrate/401_NP_KP_sp/result.ref +++ b/tests/integrate/401_NP_KP_sp/result.ref @@ -1,3 +1,3 @@ -etotref -712.4253421792514018 -etotperatomref -356.2126710896 +etotref -712.4253628200150388 +etotperatomref -356.2126814100 totaltimeref diff --git a/tests/integrate/401_NP_KP_spd/result.ref b/tests/integrate/401_NP_KP_spd/result.ref index 700b639adbc..341e593e8a7 100644 --- a/tests/integrate/401_NP_KP_spd/result.ref +++ b/tests/integrate/401_NP_KP_spd/result.ref @@ -1,3 +1,3 @@ -etotref -211.3196938362545154 -etotperatomref -105.6598469181 +etotref -211.3197071622673775 +etotperatomref -105.6598535811 totaltimeref diff --git a/tests/integrate/601_NO_TDDFT_N2_occ/result.ref b/tests/integrate/601_NO_TDDFT_N2_occ/result.ref index 52fdc2c62ca..e3495a16f6f 100644 --- a/tests/integrate/601_NO_TDDFT_N2_occ/result.ref +++ b/tests/integrate/601_NO_TDDFT_N2_occ/result.ref @@ -1,5 +1,5 @@ -etotref -523.5882423360066014 -etotperatomref -261.7941211680 -totalforceref 3.515526 -totalstressref 6.265292 -totaltimeref 12.79 +etotref -523.5881896081084506 +etotperatomref -261.7940948041 +totalforceref 3.516478 +totalstressref 6.266327 +totaltimeref +5.50632 diff --git a/tests/integrate/601_NO_TDDFT_N2_vel/result.ref b/tests/integrate/601_NO_TDDFT_N2_vel/result.ref index e0dccd770c4..4a283e6e0a2 100644 --- a/tests/integrate/601_NO_TDDFT_N2_vel/result.ref +++ b/tests/integrate/601_NO_TDDFT_N2_vel/result.ref @@ -1,5 +1,5 @@ -etotref -540.9176878626068401 -etotperatomref -270.4588439313 -totalforceref 0.493932 -totalstressref 0.882329 -totaltimeref +9.24536 +etotref -540.9177189250765423 +etotperatomref -270.4588594625 +totalforceref 0.494072 +totalstressref 0.882047 +totaltimeref +6.21010 diff --git a/tests/integrate/801_PW_LT_sc/result.ref b/tests/integrate/801_PW_LT_sc/result.ref index fd8c04e26c7..6d2ad246cec 100644 --- a/tests/integrate/801_PW_LT_sc/result.ref +++ b/tests/integrate/801_PW_LT_sc/result.ref @@ -1,5 +1,5 @@ -etotref -30.3983392986650216 +etotref -30.3983392986648404 etotperatomref -15.1991696493 totalforceref 6.695464 totalstressref 32.286157 -totaltimeref +0.36 +totaltimeref +0.24673 diff --git a/tests/integrate/802_PW_LT_fcc/result.ref b/tests/integrate/802_PW_LT_fcc/result.ref index b831eee9993..587248d51f9 100644 --- a/tests/integrate/802_PW_LT_fcc/result.ref +++ b/tests/integrate/802_PW_LT_fcc/result.ref @@ -1,5 +1,5 @@ -etotref -31.6719740726273464 +etotref -31.6719740726272114 etotperatomref -15.8359870363 totalforceref 10.852550 totalstressref 298.152013 -totaltimeref +0.17 +totaltimeref +0.15546 diff --git a/tests/integrate/803_PW_LT_bcc/result.ref b/tests/integrate/803_PW_LT_bcc/result.ref index c36fe107287..79e02115a0f 100644 --- a/tests/integrate/803_PW_LT_bcc/result.ref +++ b/tests/integrate/803_PW_LT_bcc/result.ref @@ -1,5 +1,5 @@ -etotref -30.6144125396525304 +etotref -30.6144125396524203 etotperatomref -15.3072062698 totalforceref 7.577368 totalstressref 84.028843 -totaltimeref +0.37974 +totaltimeref +0.21685 diff --git a/tests/integrate/804_PW_LT_hexagonal/result.ref b/tests/integrate/804_PW_LT_hexagonal/result.ref index 360223db008..d570ae33435 100644 --- a/tests/integrate/804_PW_LT_hexagonal/result.ref +++ b/tests/integrate/804_PW_LT_hexagonal/result.ref @@ -1,5 +1,5 @@ -etotref -30.3807460311799993 +etotref -30.3807460311779920 etotperatomref -15.1903730156 totalforceref 6.625358 totalstressref 20.693987 -totaltimeref +0.57 +totaltimeref +0.42600 diff --git a/tests/integrate/805_PW_LT_trigonal/result.ref b/tests/integrate/805_PW_LT_trigonal/result.ref index 6424e3951cc..b6330dfcef5 100644 --- a/tests/integrate/805_PW_LT_trigonal/result.ref +++ b/tests/integrate/805_PW_LT_trigonal/result.ref @@ -1,5 +1,5 @@ -etotref -30.4287469281880369 +etotref -30.4287469281882998 etotperatomref -15.2143734641 totalforceref 6.858422 totalstressref 49.777651 -totaltimeref +0.31 +totaltimeref +0.26364 diff --git a/tests/integrate/806_PW_LT_st/result.ref b/tests/integrate/806_PW_LT_st/result.ref index c94653870bf..c7a1cbe212a 100644 --- a/tests/integrate/806_PW_LT_st/result.ref +++ b/tests/integrate/806_PW_LT_st/result.ref @@ -1,5 +1,5 @@ -etotref -30.3802655024176858 +etotref -30.3802655024150248 etotperatomref -15.1901327512 totalforceref 6.561610 totalstressref 16.939346 -totaltimeref +0.61 +totaltimeref +0.42663 diff --git a/tests/integrate/807_PW_LT_bct/result.ref b/tests/integrate/807_PW_LT_bct/result.ref index 8b3c840e7f1..6a2e5598abb 100644 --- a/tests/integrate/807_PW_LT_bct/result.ref +++ b/tests/integrate/807_PW_LT_bct/result.ref @@ -1,5 +1,5 @@ -etotref -30.3907901446287596 +etotref -30.3907901446301310 etotperatomref -15.1953950723 totalforceref 6.596246 totalstressref 33.627531 -totaltimeref +0.61 +totaltimeref +0.43827 diff --git a/tests/integrate/808_PW_LT_so/result.ref b/tests/integrate/808_PW_LT_so/result.ref index b3c5fb5cbfb..1d5b770d41a 100644 --- a/tests/integrate/808_PW_LT_so/result.ref +++ b/tests/integrate/808_PW_LT_so/result.ref @@ -1,5 +1,5 @@ -etotref -30.3676532353235693 +etotref -30.3676532353208763 etotperatomref -15.1838266177 totalforceref 6.504546 totalstressref 10.681511 -totaltimeref +1.24 +totaltimeref +0.76676 diff --git a/tests/integrate/809_PW_LT_baco/result.ref b/tests/integrate/809_PW_LT_baco/result.ref index 78b233f51e6..769add54f07 100644 --- a/tests/integrate/809_PW_LT_baco/result.ref +++ b/tests/integrate/809_PW_LT_baco/result.ref @@ -1,5 +1,5 @@ -etotref -30.4370645449027002 +etotref -30.4370645449019328 etotperatomref -15.2185322725 totalforceref 6.794566 totalstressref 26.221358 -totaltimeref +0.52 +totaltimeref +0.38578 diff --git a/tests/integrate/810_PW_LT_fco/result.ref b/tests/integrate/810_PW_LT_fco/result.ref index a545332d25b..fd0430c6cd2 100644 --- a/tests/integrate/810_PW_LT_fco/result.ref +++ b/tests/integrate/810_PW_LT_fco/result.ref @@ -1,5 +1,5 @@ -etotref -30.4494090165064968 +etotref -30.4494090165070510 etotperatomref -15.2247045083 totalforceref 6.839970 totalstressref 51.247689 -totaltimeref +0.39 +totaltimeref +0.34958 diff --git a/tests/integrate/811_PW_LT_bco/result.ref b/tests/integrate/811_PW_LT_bco/result.ref index 9913bfe311a..2624ad8ac0e 100644 --- a/tests/integrate/811_PW_LT_bco/result.ref +++ b/tests/integrate/811_PW_LT_bco/result.ref @@ -1,5 +1,5 @@ -etotref -30.3664499596154371 +etotref -30.3664499596163608 etotperatomref -15.1832249798 totalforceref 6.543724 totalstressref 21.508902 -totaltimeref +0.82 +totaltimeref +0.55089 diff --git a/tests/integrate/812_PW_LT_sm/result.ref b/tests/integrate/812_PW_LT_sm/result.ref index ef735f18ee6..e4282558efd 100644 --- a/tests/integrate/812_PW_LT_sm/result.ref +++ b/tests/integrate/812_PW_LT_sm/result.ref @@ -1,5 +1,5 @@ -etotref -30.3616252432714582 +etotref -30.3616252432671239 etotperatomref -15.1808126216 totalforceref 6.473100 totalstressref 10.809968 -totaltimeref +1.16 +totaltimeref +0.68489 diff --git a/tests/integrate/813_PW_LT_bacm/result.ref b/tests/integrate/813_PW_LT_bacm/result.ref index e528659a795..fc9cf191fbc 100644 --- a/tests/integrate/813_PW_LT_bacm/result.ref +++ b/tests/integrate/813_PW_LT_bacm/result.ref @@ -1,5 +1,5 @@ -etotref -30.3728393148398226 +etotref -30.3728393148387354 etotperatomref -15.1864196574 totalforceref 6.536096 totalstressref 21.198862 -totaltimeref +0.68 +totaltimeref +0.48486 diff --git a/tests/integrate/814_PW_LT_triclinic/result.ref b/tests/integrate/814_PW_LT_triclinic/result.ref index 88584a28e40..e50372e5d53 100644 --- a/tests/integrate/814_PW_LT_triclinic/result.ref +++ b/tests/integrate/814_PW_LT_triclinic/result.ref @@ -1,5 +1,5 @@ -etotref -30.3684358881013239 +etotref -30.3684358881004428 etotperatomref -15.1842179441 totalforceref 6.491772 totalstressref 11.478933 -totaltimeref +1.25 +totaltimeref +0.69886 diff --git a/tests/integrate/815_NO_LT_sc/result.ref b/tests/integrate/815_NO_LT_sc/result.ref index a835157fc2c..334742386ac 100644 --- a/tests/integrate/815_NO_LT_sc/result.ref +++ b/tests/integrate/815_NO_LT_sc/result.ref @@ -1,5 +1,5 @@ -etotref -31.6980620269583468 -etotperatomref -15.8490310135 -totalforceref 4.598170 -totalstressref 17.504887 -totaltimeref +0.87 +etotref -31.6980734632370016 +etotperatomref -15.8490367316 +totalforceref 4.598132 +totalstressref 17.505313 +totaltimeref +0.47309 diff --git a/tests/integrate/816_NO_LT_fcc/result.ref b/tests/integrate/816_NO_LT_fcc/result.ref index ac18cad2b7e..dc71bc307b0 100644 --- a/tests/integrate/816_NO_LT_fcc/result.ref +++ b/tests/integrate/816_NO_LT_fcc/result.ref @@ -1,5 +1,5 @@ -etotref -31.7043304392143952 -etotperatomref -15.8521652196 -totalforceref 4.560704 -totalstressref 71.803745 -totaltimeref +1.51 +etotref -31.7043366423150275 +etotperatomref -15.8521683212 +totalforceref 4.560702 +totalstressref 71.803678 +totaltimeref +0.59327 diff --git a/tests/integrate/817_NO_LT_bcc/result.ref b/tests/integrate/817_NO_LT_bcc/result.ref index 2175cc3f58b..feb3815b6f1 100644 --- a/tests/integrate/817_NO_LT_bcc/result.ref +++ b/tests/integrate/817_NO_LT_bcc/result.ref @@ -1,5 +1,5 @@ -etotref -31.7016469231926052 -etotperatomref -15.8508234616 -totalforceref 4.620847 -totalstressref 35.456846 -totaltimeref +1.24 +etotref -31.7016530135837726 +etotperatomref -15.8508265068 +totalforceref 4.620854 +totalstressref 35.456577 +totaltimeref +0.57672 diff --git a/tests/integrate/818_NO_LT_hexagonal/result.ref b/tests/integrate/818_NO_LT_hexagonal/result.ref index 796d548f0f9..0c103a961ba 100644 --- a/tests/integrate/818_NO_LT_hexagonal/result.ref +++ b/tests/integrate/818_NO_LT_hexagonal/result.ref @@ -1,5 +1,5 @@ -etotref -31.6979224725823840 -etotperatomref -15.8489612363 -totalforceref 4.597525 -totalstressref 10.129793 -totaltimeref +1.17 +etotref -31.6979340228234641 +etotperatomref -15.8489670114 +totalforceref 4.597526 +totalstressref 10.128228 +totaltimeref +0.65398 diff --git a/tests/integrate/819_NO_LT_trigonal/result.ref b/tests/integrate/819_NO_LT_trigonal/result.ref index df7fdc05f77..7ceed710b1d 100644 --- a/tests/integrate/819_NO_LT_trigonal/result.ref +++ b/tests/integrate/819_NO_LT_trigonal/result.ref @@ -1,5 +1,5 @@ -etotref -31.6985737392898130 -etotperatomref -15.8492868696 -totalforceref 4.603940 -totalstressref 24.787973 -totaltimeref +1.07 +etotref -31.6985831856819900 +etotperatomref -15.8492915928 +totalforceref 4.603874 +totalstressref 24.786739 +totaltimeref +0.49242 diff --git a/tests/integrate/820_NO_LT_st/result.ref b/tests/integrate/820_NO_LT_st/result.ref index 91386a2b877..f088b8fc27d 100644 --- a/tests/integrate/820_NO_LT_st/result.ref +++ b/tests/integrate/820_NO_LT_st/result.ref @@ -1,5 +1,5 @@ -etotref -31.6979491579475763 -etotperatomref -15.8489745790 -totalforceref 4.597222 -totalstressref 8.756871 -totaltimeref +1.09 +etotref -31.6979657348295198 +etotperatomref -15.8489828674 +totalforceref 4.597174 +totalstressref 8.756044 +totaltimeref +0.58991 diff --git a/tests/integrate/821_NO_LT_bct/result.ref b/tests/integrate/821_NO_LT_bct/result.ref index facb4e84dfe..e23181028da 100644 --- a/tests/integrate/821_NO_LT_bct/result.ref +++ b/tests/integrate/821_NO_LT_bct/result.ref @@ -1,5 +1,5 @@ -etotref -31.6979108005133767 -etotperatomref -15.8489554003 -totalforceref 4.598698 -totalstressref 17.518301 -totaltimeref +1.42 +etotref -31.6979234103855703 +etotperatomref -15.8489617052 +totalforceref 4.598700 +totalstressref 17.518819 +totaltimeref +0.60302 diff --git a/tests/integrate/822_NO_LT_so/result.ref b/tests/integrate/822_NO_LT_so/result.ref index 23d173c1767..46256d725c3 100644 --- a/tests/integrate/822_NO_LT_so/result.ref +++ b/tests/integrate/822_NO_LT_so/result.ref @@ -1,5 +1,5 @@ -etotref -31.6979246820960441 -etotperatomref -15.8489623410 -totalforceref 4.597128 -totalstressref 5.834882 -totaltimeref +1.23 +etotref -31.6979449573878753 +etotperatomref -15.8489724787 +totalforceref 4.597054 +totalstressref 5.835200 +totaltimeref +0.73846 diff --git a/tests/integrate/823_NO_LT_baco/result.ref b/tests/integrate/823_NO_LT_baco/result.ref index 1277737be3e..bd743a0d21b 100644 --- a/tests/integrate/823_NO_LT_baco/result.ref +++ b/tests/integrate/823_NO_LT_baco/result.ref @@ -1,5 +1,5 @@ -etotref -31.6985145802630299 -etotperatomref -15.8492572901 -totalforceref 4.599956 -totalstressref 11.733960 -totaltimeref +1.18 +etotref -31.6985254890549371 +etotperatomref -15.8492627445 +totalforceref 4.599964 +totalstressref 11.733485 +totaltimeref +0.63762 diff --git a/tests/integrate/824_NO_LT_fco/result.ref b/tests/integrate/824_NO_LT_fco/result.ref index cde21cc2ab2..d9ec28639aa 100644 --- a/tests/integrate/824_NO_LT_fco/result.ref +++ b/tests/integrate/824_NO_LT_fco/result.ref @@ -1,5 +1,5 @@ -etotref -31.6985927198734103 -etotperatomref -15.8492963599 -totalforceref 4.601774 -totalstressref 23.454864 -totaltimeref +1.29 +etotref -31.6986021284898776 +etotperatomref -15.8493010642 +totalforceref 4.601777 +totalstressref 23.454810 +totaltimeref +0.61690 diff --git a/tests/integrate/825_NO_LT_bco/result.ref b/tests/integrate/825_NO_LT_bco/result.ref index ee00083922c..ec6862b7069 100644 --- a/tests/integrate/825_NO_LT_bco/result.ref +++ b/tests/integrate/825_NO_LT_bco/result.ref @@ -1,5 +1,5 @@ -etotref -31.6978730352591498 -etotperatomref -15.8489365176 -totalforceref 4.598248 -totalstressref 11.673929 -totaltimeref +1.76 +etotref -31.6978884540436212 +etotperatomref -15.8489442270 +totalforceref 4.598300 +totalstressref 11.673818 +totaltimeref +0.87324 diff --git a/tests/integrate/826_NO_LT_sm/result.ref b/tests/integrate/826_NO_LT_sm/result.ref index 91ab7589282..a3c13369090 100644 --- a/tests/integrate/826_NO_LT_sm/result.ref +++ b/tests/integrate/826_NO_LT_sm/result.ref @@ -1,5 +1,5 @@ -etotref -31.6979367329958350 -etotperatomref -15.8489683665 -totalforceref 4.597066 -totalstressref 5.862562 -totaltimeref +1.53 +etotref -31.6979562273071416 +etotperatomref -15.8489781137 +totalforceref 4.597110 +totalstressref 5.862189 +totaltimeref +0.79228 diff --git a/tests/integrate/827_NO_LT_bacm/result.ref b/tests/integrate/827_NO_LT_bacm/result.ref index 4908836042f..2f00cff26f7 100644 --- a/tests/integrate/827_NO_LT_bacm/result.ref +++ b/tests/integrate/827_NO_LT_bacm/result.ref @@ -1,5 +1,5 @@ -etotref -31.6979068788851599 -etotperatomref -15.8489534394 -totalforceref 4.598074 -totalstressref 11.723501 -totaltimeref +1.31 +etotref -31.6979218930886937 +etotperatomref -15.8489609465 +totalforceref 4.598124 +totalstressref 11.723478 +totaltimeref +0.69656 diff --git a/tests/integrate/828_NO_LT_triclinic/result.ref b/tests/integrate/828_NO_LT_triclinic/result.ref index 7a3685d6f80..bba24d879de 100644 --- a/tests/integrate/828_NO_LT_triclinic/result.ref +++ b/tests/integrate/828_NO_LT_triclinic/result.ref @@ -1,5 +1,5 @@ -etotref -31.6978574713854933 -etotperatomref -15.8489287357 -totalforceref 4.597302 -totalstressref 6.250979 -totaltimeref +1.65 +etotref -31.6978772010451770 +etotperatomref -15.8489386005 +totalforceref 4.597320 +totalstressref 6.251313 +totaltimeref +0.95089 diff --git a/tests/integrate/829_NO_GO_LT_sc/result.ref b/tests/integrate/829_NO_GO_LT_sc/result.ref index 5dca006cdc4..0b59b7d3ae6 100644 --- a/tests/integrate/829_NO_GO_LT_sc/result.ref +++ b/tests/integrate/829_NO_GO_LT_sc/result.ref @@ -1,5 +1,5 @@ -etotref -31.7426355141714609 -etotperatomref -15.8713177571 -totalforceref 4.798248 -totalstressref 19.542307 -totaltimeref +0.84 +etotref -31.7426443504057829 +etotperatomref -15.8713221752 +totalforceref 4.798154 +totalstressref 19.542719 +totaltimeref +0.51595 diff --git a/tests/integrate/830_NO_GO_LT_fcc/result.ref b/tests/integrate/830_NO_GO_LT_fcc/result.ref index a2492c0bb1f..f1ac0759f2c 100644 --- a/tests/integrate/830_NO_GO_LT_fcc/result.ref +++ b/tests/integrate/830_NO_GO_LT_fcc/result.ref @@ -1,5 +1,5 @@ -etotref -32.8385728167959954 -etotperatomref -16.4192864084 -totalforceref 8.363264 -totalstressref 224.774177 -totaltimeref +1.22 +etotref -32.8385790451128798 +etotperatomref -16.4192895226 +totalforceref 8.363262 +totalstressref 224.774165 +totaltimeref +0.66081 diff --git a/tests/integrate/831_NO_GO_LT_bcc/result.ref b/tests/integrate/831_NO_GO_LT_bcc/result.ref index afaaf75d41f..34123278284 100644 --- a/tests/integrate/831_NO_GO_LT_bcc/result.ref +++ b/tests/integrate/831_NO_GO_LT_bcc/result.ref @@ -1,5 +1,5 @@ -etotref -31.9214415865240539 -etotperatomref -15.9607207933 +etotref -31.9214476562338909 +etotperatomref -15.9607238281 totalforceref 5.718350 -totalstressref 58.472104 -totaltimeref +1.55 +totalstressref 58.472117 +totaltimeref +0.67582 diff --git a/tests/integrate/832_NO_GO_LT_hexagonal/result.ref b/tests/integrate/832_NO_GO_LT_hexagonal/result.ref index 7e277997e3f..0c7c6fad316 100644 --- a/tests/integrate/832_NO_GO_LT_hexagonal/result.ref +++ b/tests/integrate/832_NO_GO_LT_hexagonal/result.ref @@ -1,5 +1,5 @@ -etotref -31.7375974883562790 -etotperatomref -15.8687987442 -totalforceref 4.764698 -totalstressref 12.623524 -totaltimeref +1.04 +etotref -31.7376079686760484 +etotperatomref -15.8688039843 +totalforceref 4.764758 +totalstressref 12.623606 +totaltimeref +0.67608 diff --git a/tests/integrate/833_NO_GO_LT_trigonal/result.ref b/tests/integrate/833_NO_GO_LT_trigonal/result.ref index 1bf2fe2c03e..534f4ef67e2 100644 --- a/tests/integrate/833_NO_GO_LT_trigonal/result.ref +++ b/tests/integrate/833_NO_GO_LT_trigonal/result.ref @@ -1,5 +1,5 @@ -etotref -31.7870421684308901 -etotperatomref -15.8935210842 -totalforceref 5.086940 -totalstressref 30.929588 -totaltimeref +0.94 +etotref -31.7870486902803755 +etotperatomref -15.8935243451 +totalforceref 5.086910 +totalstressref 30.929804 +totaltimeref +0.51335 diff --git a/tests/integrate/834_NO_GO_LT_st/result.ref b/tests/integrate/834_NO_GO_LT_st/result.ref index 696bff3395e..4cf42f4b1ab 100644 --- a/tests/integrate/834_NO_GO_LT_st/result.ref +++ b/tests/integrate/834_NO_GO_LT_st/result.ref @@ -1,5 +1,5 @@ -etotref -31.7243216038652918 -etotperatomref -15.8621608019 -totalforceref 4.707980 -totalstressref 10.192678 -totaltimeref +1.02 +etotref -31.7243385223599965 +etotperatomref -15.8621692612 +totalforceref 4.707976 +totalstressref 10.191810 +totaltimeref +0.63650 diff --git a/tests/integrate/835_NO_GO_LT_bct/result.ref b/tests/integrate/835_NO_GO_LT_bct/result.ref index db7cc9e887a..318001e4d8a 100644 --- a/tests/integrate/835_NO_GO_LT_bct/result.ref +++ b/tests/integrate/835_NO_GO_LT_bct/result.ref @@ -1,5 +1,5 @@ -etotref -31.7329701808600539 -etotperatomref -15.8664850904 -totalforceref 4.739560 -totalstressref 20.554906 -totaltimeref +1.27 +etotref -31.7329825704881969 +etotperatomref -15.8664912852 +totalforceref 4.739544 +totalstressref 20.555555 +totaltimeref +0.62692 diff --git a/tests/integrate/836_NO_GO_LT_so/result.ref b/tests/integrate/836_NO_GO_LT_so/result.ref index 648576043f3..dd1e62ca030 100644 --- a/tests/integrate/836_NO_GO_LT_so/result.ref +++ b/tests/integrate/836_NO_GO_LT_so/result.ref @@ -1,5 +1,5 @@ -etotref -31.7110787373379850 -etotperatomref -15.8555393687 -totalforceref 4.652448 -totalstressref 6.313733 -totaltimeref +1.26 +etotref -31.7110989292136374 +etotperatomref -15.8555494646 +totalforceref 4.652411 +totalstressref 6.314338 +totaltimeref +0.80023 diff --git a/tests/integrate/837_NO_GO_LT_baco/result.ref b/tests/integrate/837_NO_GO_LT_baco/result.ref index 55ff8e44f12..cb5dd1ed6b0 100644 --- a/tests/integrate/837_NO_GO_LT_baco/result.ref +++ b/tests/integrate/837_NO_GO_LT_baco/result.ref @@ -1,5 +1,5 @@ -etotref -31.7664974595636096 -etotperatomref -15.8832487298 -totalforceref 4.895260 -totalstressref 19.047258 -totaltimeref +1.05 +etotref -31.7665074976884441 +etotperatomref -15.8832537488 +totalforceref 4.895300 +totalstressref 19.046983 +totaltimeref +0.66316 diff --git a/tests/integrate/838_NO_GO_LT_fco/result.ref b/tests/integrate/838_NO_GO_LT_fco/result.ref index 6a80e887393..b0f1f5cdf7b 100644 --- a/tests/integrate/838_NO_GO_LT_fco/result.ref +++ b/tests/integrate/838_NO_GO_LT_fco/result.ref @@ -1,5 +1,5 @@ -etotref -31.7828168516261940 -etotperatomref -15.8914084258 -totalforceref 5.004438 -totalstressref 38.047744 -totaltimeref +1.14 +etotref -31.7828255573664293 +etotperatomref -15.8914127787 +totalforceref 5.004468 +totalstressref 38.048057 +totaltimeref +0.65935 diff --git a/tests/integrate/839_NO_GO_LT_bco/result.ref b/tests/integrate/839_NO_GO_LT_bco/result.ref index 83c8fdb33cb..1aedab46d30 100644 --- a/tests/integrate/839_NO_GO_LT_bco/result.ref +++ b/tests/integrate/839_NO_GO_LT_bco/result.ref @@ -1,5 +1,5 @@ -etotref -31.7110422206770330 -etotperatomref -15.8555211103 -totalforceref 4.653604 -totalstressref 12.631563 -totaltimeref +1.59 +etotref -31.7110579526487051 +etotperatomref -15.8555289763 +totalforceref 4.653690 +totalstressref 12.631471 +totaltimeref +0.86727 diff --git a/tests/integrate/840_NO_GO_LT_sm/result.ref b/tests/integrate/840_NO_GO_LT_sm/result.ref index a339616ed6b..69bbd9fee0c 100644 --- a/tests/integrate/840_NO_GO_LT_sm/result.ref +++ b/tests/integrate/840_NO_GO_LT_sm/result.ref @@ -1,5 +1,5 @@ -etotref -31.7111052800755431 -etotperatomref -15.8555526400 -totalforceref 4.652426 -totalstressref 6.343160 -totaltimeref +1.48 +etotref -31.7111243017135322 +etotperatomref -15.8555621509 +totalforceref 4.652444 +totalstressref 6.342909 +totaltimeref +0.87571 diff --git a/tests/integrate/841_NO_GO_LT_bacm/result.ref b/tests/integrate/841_NO_GO_LT_bacm/result.ref index 7e22ff1d212..7a34e2f4671 100644 --- a/tests/integrate/841_NO_GO_LT_bacm/result.ref +++ b/tests/integrate/841_NO_GO_LT_bacm/result.ref @@ -1,5 +1,5 @@ -etotref -31.7242379677732913 -etotperatomref -15.8621189839 -totalforceref 4.722658 -totalstressref 12.767337 -totaltimeref +1.23 +etotref -31.7242517939058111 +etotperatomref -15.8621258970 +totalforceref 4.722718 +totalstressref 12.767521 +totaltimeref +0.70748 diff --git a/tests/integrate/842_NO_GO_LT_triclinic/result.ref b/tests/integrate/842_NO_GO_LT_triclinic/result.ref index c07479d36ed..caafe6bf1e5 100644 --- a/tests/integrate/842_NO_GO_LT_triclinic/result.ref +++ b/tests/integrate/842_NO_GO_LT_triclinic/result.ref @@ -1,5 +1,5 @@ -etotref -31.7110287102751158 -etotperatomref -15.8555143551 -totalforceref 4.652756 -totalstressref 6.764644 -totaltimeref +1.59 +etotref -31.7110480507035852 +etotperatomref -15.8555240254 +totalforceref 4.652782 +totalstressref 6.765039 +totaltimeref +0.92562 From d151f2589ce478990b4e84ef933108db0195efdb Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Mon, 7 Mar 2022 20:35:39 +0800 Subject: [PATCH 25/36] change xc, gcxc, tau_xc to private --- source/module_xc/xc_functional.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index ae991dc3a97..cd0e67cb7ea 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -129,7 +129,7 @@ class XC_Functional // on the entire grid. I'm having xc_spin_libxc because v_xc_libxc // does not support nspin = 4. - public : + private : // LDA static void xc(const double &rho, double &exc, double &vxc); @@ -155,7 +155,7 @@ class XC_Functional // LIBXC, and the reason for not having gcxc_libxc is explained // in the NOTE in the comment for xc_functional_wrapper_wc.cpp part - public: + private: // GGA static void gcxc(const double &rho, const double &grho, @@ -183,7 +183,7 @@ class XC_Functional // NOTE : mGGA is realized through LIBXC #ifdef USE_LIBXC - public: + private: // mGGA static void tau_xc(const double &rho, const double &grho, const double &atau, double &sxc, From bc9d749b41cafec73698c7690e9e19faffd634bb Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Mon, 7 Mar 2022 20:44:59 +0800 Subject: [PATCH 26/36] xc refactor : modify default value for dft_functional in input.cpp --- source/input.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/input.cpp b/source/input.cpp index fe053292b8a..cfa7d55af77 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -144,7 +144,7 @@ void Input::Default(void) //---------------------------------------------------------- // electrons / spin //---------------------------------------------------------- - dft_functional = "none"; + dft_functional = "default"; nspin = 1; nelec = 0.0; lmaxmax = 2; @@ -354,7 +354,6 @@ void Input::Default(void) //---------------------------------------------------------- // exx //Peize Lin add 2018-06-20 //---------------------------------------------------------- - dft_functional = "default"; exx_hybrid_alpha = 0.25; exx_hse_omega = 0.11; From cb0cecd389335aefb706c1c390f9b085d869a488 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Mon, 7 Mar 2022 20:53:45 +0800 Subject: [PATCH 27/36] xc refactor : in read_pp, modify the way to check if xc functional from input and pp is consistent --- source/module_cell/read_pp_upf100.cpp | 4 +++- source/module_cell/read_pp_upf201.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source/module_cell/read_pp_upf100.cpp b/source/module_cell/read_pp_upf100.cpp index 33c121d1c0c..a116bcd2244 100644 --- a/source/module_cell/read_pp_upf100.cpp +++ b/source/module_cell/read_pp_upf100.cpp @@ -174,7 +174,9 @@ void Pseudopot_upf::read_pseudo_header(std::ifstream &ifs) // dft functional enforced to modify // mohan add 2010-07-15 - if(GlobalV::DFT_FUNCTIONAL!="default" && xc_func != GlobalV::DFT_FUNCTIONAL) + string xc_func1 = GlobalV::DFT_FUNCTIONAL; + transform(xc_func1.begin(), xc_func1.end(), xc_func1.begin(), (::toupper)); + if(GlobalV::DFT_FUNCTIONAL!="default" && xc_func1 != xc_func) { functional_error = 1; } diff --git a/source/module_cell/read_pp_upf201.cpp b/source/module_cell/read_pp_upf201.cpp index 11da94dc7fe..7c6c0a85d2f 100644 --- a/source/module_cell/read_pp_upf201.cpp +++ b/source/module_cell/read_pp_upf201.cpp @@ -390,7 +390,9 @@ int Pseudopot_upf::read_pseudo_upf201(std::ifstream &ifs) if(GlobalV::DFT_FUNCTIONAL!="default") { - if(xc_func != GlobalV::DFT_FUNCTIONAL) + string xc_func1 = GlobalV::DFT_FUNCTIONAL; + transform(xc_func1.begin(), xc_func1.end(), xc_func1.begin(), (::toupper)); + if(xc_func1 != xc_func) { functional_error = 1; From a3a4986722db3bec7c3d90226720ef978c8377f0 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Tue, 8 Mar 2022 20:19:44 +0800 Subject: [PATCH 28/36] xc refactor : add ifdef __MPI for parallel reduce --- source/module_xc/xc_functional_vxc.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/module_xc/xc_functional_vxc.cpp b/source/module_xc/xc_functional_vxc.cpp index 70b1aceb1fe..34f8163c193 100644 --- a/source/module_xc/xc_functional_vxc.cpp +++ b/source/module_xc/xc_functional_vxc.cpp @@ -160,9 +160,10 @@ std::tuple XC_Functional::v_xc( // parallel code : collect vtxc,etxc // mohan add 2008-06-01 +#ifdef __MPI Parallel_Reduce::reduce_double_pool( etxc ); Parallel_Reduce::reduce_double_pool( vtxc ); - +#endif etxc *= omega / ncxyz; vtxc *= omega / ncxyz; @@ -374,8 +375,10 @@ std::tuple XC_Functional::v_xc_libxc( //------------------------------------------------- // for MPI, reduce the exchange-correlation energy //------------------------------------------------- +#ifdef __MPI Parallel_Reduce::reduce_double_pool( etxc ); Parallel_Reduce::reduce_double_pool( vtxc ); +#endif etxc *= omega / ncxyz; vtxc *= omega / ncxyz; @@ -607,8 +610,10 @@ tuple XC_Functional::v_xc_m //------------------------------------------------- // for MPI, reduce the exchange-correlation energy //------------------------------------------------- +#ifdef __MPI Parallel_Reduce::reduce_double_pool( etxc ); Parallel_Reduce::reduce_double_pool( vtxc ); +#endif etxc *= omega / ncxyz; vtxc *= omega / ncxyz; From 840e0604b25f8aba18238d57e0f1f0bd43776276 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Tue, 8 Mar 2022 20:20:48 +0800 Subject: [PATCH 29/36] xc refactor : start to add unit test --- source/module_xc/CMakeLists.txt | 4 ++++ source/module_xc/test/CMakeLists.txt | 6 ++++++ source/module_xc/test/test_xc_pbe.cpp | 30 +++++++++++++++++++++++++++ source/module_xc/xc_functional.h | 1 + 4 files changed, 41 insertions(+) create mode 100644 source/module_xc/test/CMakeLists.txt create mode 100644 source/module_xc/test/test_xc_pbe.cpp diff --git a/source/module_xc/CMakeLists.txt b/source/module_xc/CMakeLists.txt index b240d1e791b..e74c40c0016 100644 --- a/source/module_xc/CMakeLists.txt +++ b/source/module_xc/CMakeLists.txt @@ -17,3 +17,7 @@ add_library( OBJECT ${objects} ) + +IF (BUILD_TESTING) + add_subdirectory(test) +endif() \ No newline at end of file diff --git a/source/module_xc/test/CMakeLists.txt b/source/module_xc/test/CMakeLists.txt new file mode 100644 index 00000000000..091d76deb7b --- /dev/null +++ b/source/module_xc/test/CMakeLists.txt @@ -0,0 +1,6 @@ +remove_definitions(-DUSE_LIBXC) + +AddTest( + TARGET XCTest_PBE + SOURCES test_xc_pbe.cpp ../xc_functional.cpp +) diff --git a/source/module_xc/test/test_xc_pbe.cpp b/source/module_xc/test/test_xc_pbe.cpp new file mode 100644 index 00000000000..f6846e7b5f9 --- /dev/null +++ b/source/module_xc/test/test_xc_pbe.cpp @@ -0,0 +1,30 @@ +#include "../xc_functional.h" +#include "gtest/gtest.h" + +//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. +namespace ModuleBase +{ + void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} +} + +namespace GlobalV +{ + std::string BASIS_TYPE = ""; + bool STRESS = 0; + int NSPIN = 1; +} + +class XCTest_PBE : public testing::Test +{ + protected: + void SetUp() + { + XC_Functional::set_xc_type("PBE"); + std::cout << XC_Functional::get_func_type() << std::endl; + } +}; + +TEST_F(XCTest_PBE, set_xc_type) +{ + EXPECT_EQ(XC_Functional::get_func_type(),2); +} \ No newline at end of file diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index cd0e67cb7ea..15b199b562f 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -26,6 +26,7 @@ class XC_Functional friend class ELEC_scf; friend class LOOP_elec; friend class Run_MD_PW; + friend class XCTest_PBE; XC_Functional(); ~XC_Functional(); From 99fee676be8f0c1b7678832fa34de69e90c3c324 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Tue, 8 Mar 2022 20:59:17 +0800 Subject: [PATCH 30/36] xc refactor : add 5 data points to XCTest_PBE --- source/module_xc/test/CMakeLists.txt | 2 +- source/module_xc/test/test_xc_pbe.cpp | 32 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/source/module_xc/test/CMakeLists.txt b/source/module_xc/test/CMakeLists.txt index 091d76deb7b..9dbf63ac90f 100644 --- a/source/module_xc/test/CMakeLists.txt +++ b/source/module_xc/test/CMakeLists.txt @@ -2,5 +2,5 @@ remove_definitions(-DUSE_LIBXC) AddTest( TARGET XCTest_PBE - SOURCES test_xc_pbe.cpp ../xc_functional.cpp + SOURCES test_xc_pbe.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp ) diff --git a/source/module_xc/test/test_xc_pbe.cpp b/source/module_xc/test/test_xc_pbe.cpp index f6846e7b5f9..7f27ffebc02 100644 --- a/source/module_xc/test/test_xc_pbe.cpp +++ b/source/module_xc/test/test_xc_pbe.cpp @@ -17,14 +17,44 @@ namespace GlobalV class XCTest_PBE : public testing::Test { protected: + std::vector e_lda, v_lda; + std::vector e_gga, v1_gga, v2_gga; + void SetUp() { XC_Functional::set_xc_type("PBE"); - std::cout << XC_Functional::get_func_type() << std::endl; + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + std::vector grho = {0.81E-11, 0.17E+01, 0.36E+02, 0.87E-01, 0.55E+00}; + + for(int i=0;i<5;i++) + { + double e,v,v1,v2; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + XC_Functional::gcxc(rho[i],grho[i],e,v1,v2); + e_gga.push_back(e); + v1_gga.push_back(v1); + v2_gga.push_back(v2); + } } }; TEST_F(XCTest_PBE, set_xc_type) { EXPECT_EQ(XC_Functional::get_func_type(),2); + std::vector e_lda_ref = {-0.9570906378,-0.9570906378,-0.9200171474,-0.3808291731,-9.124862983}; + std::vector v_lda_ref = {-1.259358955 , -1.259358955, -1.210234884,-0.4975768336,-12.12952188}; + std::vector e_gga_ref = {0.0 , -0.000103750,-0.0328708695,-0.0032277985,0.0 }; + std::vector v1_gga_ref = {0.0 ,0.00021536874,0.04931694948,0.05374316118,0.0 }; + std::vector v2_gga_ref = {0.0 ,-0.0002386176,-0.0025842562,-0.0825164089,0.0 }; + + for (int i = 0;i<5;++i) + { + EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); + EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); + EXPECT_NEAR(e_gga[i],e_gga_ref[i],1.0e-8); + EXPECT_NEAR(v1_gga[i],v1_gga_ref[i],1.0e-8); + EXPECT_NEAR(v2_gga[i],v2_gga_ref[i],1.0e-8); + } } \ No newline at end of file From 99d5a4627ccab42f7a672ac0e2e2e4c93a424744 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Tue, 8 Mar 2022 21:30:49 +0800 Subject: [PATCH 31/36] xc refactor : add tests for pwlda and pz --- source/module_xc/test/CMakeLists.txt | 10 ++++++ source/module_xc/test/test_xc_pwlda.cpp | 48 +++++++++++++++++++++++++ source/module_xc/test/test_xc_pz.cpp | 48 +++++++++++++++++++++++++ source/module_xc/xc_functional.h | 2 ++ 4 files changed, 108 insertions(+) create mode 100644 source/module_xc/test/test_xc_pwlda.cpp create mode 100644 source/module_xc/test/test_xc_pz.cpp diff --git a/source/module_xc/test/CMakeLists.txt b/source/module_xc/test/CMakeLists.txt index 9dbf63ac90f..6b6b5369d32 100644 --- a/source/module_xc/test/CMakeLists.txt +++ b/source/module_xc/test/CMakeLists.txt @@ -4,3 +4,13 @@ AddTest( TARGET XCTest_PBE SOURCES test_xc_pbe.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp ) + +AddTest( + TARGET XCTest_PZ + SOURCES test_xc_pz.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp +) + +AddTest( + TARGET XCTest_PWLDA + SOURCES test_xc_pwlda.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp +) \ No newline at end of file diff --git a/source/module_xc/test/test_xc_pwlda.cpp b/source/module_xc/test/test_xc_pwlda.cpp new file mode 100644 index 00000000000..b9a71052ab8 --- /dev/null +++ b/source/module_xc/test/test_xc_pwlda.cpp @@ -0,0 +1,48 @@ +#include "../xc_functional.h" +#include "gtest/gtest.h" + +//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. +namespace ModuleBase +{ + void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} +} + +namespace GlobalV +{ + std::string BASIS_TYPE = ""; + bool STRESS = 0; + int NSPIN = 1; +} + +class XCTest_PWLDA : public testing::Test +{ + protected: + std::vector e_lda, v_lda; + + void SetUp() + { + XC_Functional::set_xc_type("PWLDA"); + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + + for(int i=0;i<5;i++) + { + double e,v; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + } + } +}; + +TEST_F(XCTest_PWLDA, set_xc_type) +{ + EXPECT_EQ(XC_Functional::get_func_type(),1); + std::vector e_lda_ref = {-0.9570906378,-0.9570906378,-0.9200171474,-0.3808291731,-9.124862983}; + std::vector v_lda_ref = {-1.259358955 , -1.259358955, -1.210234884,-0.4975768336,-12.12952188}; + + for (int i = 0;i<5;++i) + { + EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); + EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); + } +} \ No newline at end of file diff --git a/source/module_xc/test/test_xc_pz.cpp b/source/module_xc/test/test_xc_pz.cpp new file mode 100644 index 00000000000..2a363c15157 --- /dev/null +++ b/source/module_xc/test/test_xc_pz.cpp @@ -0,0 +1,48 @@ +#include "../xc_functional.h" +#include "gtest/gtest.h" + +//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. +namespace ModuleBase +{ + void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} +} + +namespace GlobalV +{ + std::string BASIS_TYPE = ""; + bool STRESS = 0; + int NSPIN = 1; +} + +class XCTest_PZ : public testing::Test +{ + protected: + std::vector e_lda, v_lda; + + void SetUp() + { + XC_Functional::set_xc_type("PZ"); + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + + for(int i=0;i<5;i++) + { + double e,v; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + } + } +}; + +TEST_F(XCTest_PZ, set_xc_type) +{ + EXPECT_EQ(XC_Functional::get_func_type(),1); + std::vector e_lda_ref = {-0.9565173576,-0.9565173576,-0.9194417358,-0.38104767571,-9.125575429}; + std::vector v_lda_ref = {-1.2588131365,-1.2588131365,-1.2096658201,-0.49757720968,-12.13038680}; + + for (int i = 0;i<5;++i) + { + EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); + EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); + } +} \ No newline at end of file diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 15b199b562f..5b85143f1c1 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -27,6 +27,8 @@ class XC_Functional friend class LOOP_elec; friend class Run_MD_PW; friend class XCTest_PBE; + friend class XCTest_PZ; + friend class XCTest_PWLDA; XC_Functional(); ~XC_Functional(); From 4d7d2c9a54fc3299b7e481d21a661b3b5c7da346 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Mar 2022 14:41:10 +0800 Subject: [PATCH 32/36] xc refactor : add another test for BP --- source/module_xc/test/CMakeLists.txt | 5 +++ source/module_xc/test/test_xc_bp.cpp | 59 ++++++++++++++++++++++++++++ source/module_xc/xc_functional.h | 1 + 3 files changed, 65 insertions(+) create mode 100644 source/module_xc/test/test_xc_bp.cpp diff --git a/source/module_xc/test/CMakeLists.txt b/source/module_xc/test/CMakeLists.txt index 6b6b5369d32..18688447fd6 100644 --- a/source/module_xc/test/CMakeLists.txt +++ b/source/module_xc/test/CMakeLists.txt @@ -13,4 +13,9 @@ AddTest( AddTest( TARGET XCTest_PWLDA SOURCES test_xc_pwlda.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp +) + +AddTest( + TARGET XCTest_BP + SOURCES test_xc_bp.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp ) \ No newline at end of file diff --git a/source/module_xc/test/test_xc_bp.cpp b/source/module_xc/test/test_xc_bp.cpp new file mode 100644 index 00000000000..56be85b114e --- /dev/null +++ b/source/module_xc/test/test_xc_bp.cpp @@ -0,0 +1,59 @@ +#include "../xc_functional.h" +#include "gtest/gtest.h" + +//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. +namespace ModuleBase +{ + void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} +} + +namespace GlobalV +{ + std::string BASIS_TYPE = ""; + bool STRESS = 0; + int NSPIN = 1; +} + +class XCTest_BP : public testing::Test +{ + protected: + std::vector e_lda, v_lda; + std::vector e_gga, v1_gga, v2_gga; + + void SetUp() + { + XC_Functional::set_xc_type("BP"); + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + std::vector grho = {0.81E-11, 0.17E+01, 0.36E+02, 0.87E-01, 0.55E+00}; + + for(int i=0;i<5;i++) + { + double e,v,v1,v2; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + XC_Functional::gcxc(rho[i],grho[i],e,v1,v2); + e_gga.push_back(e); + v1_gga.push_back(v1); + v2_gga.push_back(v2); + } + } +}; + +TEST_F(XCTest_BP, set_xc_type) +{ + EXPECT_EQ(XC_Functional::get_func_type(),2); + std::vector e_lda_ref = {-0.9565173576,-0.9565173576,-0.9194417358,-0.38104767571,-9.125575429}; + std::vector v_lda_ref = {-1.2588131365,-1.2588131365,-1.2096658201,-0.49757720968,-12.13038680}; + std::vector e_gga_ref = {0.0 ,-0.0012525632,-0.0457062154,-0.0035030371,0.0 }; + std::vector v1_gga_ref = {0.0 ,0.00118557755,0.04272756138,0.04137909619,0.0 }; + std::vector v2_gga_ref = {-0.0010246353,-0.0016488916,-0.0027047176,-0.0753933855,0.0 }; + for (int i = 0;i<5;++i) + { + EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); + EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); + EXPECT_NEAR(e_gga[i],e_gga_ref[i],1.0e-7); + EXPECT_NEAR(v1_gga[i],v1_gga_ref[i],1.0e-7); + EXPECT_NEAR(v2_gga[i],v2_gga_ref[i],1.0e-7); + } +} \ No newline at end of file diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 5b85143f1c1..800ad447916 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -29,6 +29,7 @@ class XC_Functional friend class XCTest_PBE; friend class XCTest_PZ; friend class XCTest_PWLDA; + friend class XCTest_BP; XC_Functional(); ~XC_Functional(); From 0cb9e721867be088f15070e5511f96f7d9a15453 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Mar 2022 14:57:33 +0800 Subject: [PATCH 33/36] xc refactor : move set_xc_type to static public --- source/module_xc/xc_functional.h | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 800ad447916..076f08b81a6 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -20,17 +20,6 @@ class XC_Functional { public: - friend class Run_lcao; - friend class Run_pw; - friend class Ions; - friend class ELEC_scf; - friend class LOOP_elec; - friend class Run_MD_PW; - friend class XCTest_PBE; - friend class XCTest_PZ; - friend class XCTest_PWLDA; - friend class XCTest_BP; - XC_Functional(); ~XC_Functional(); @@ -96,15 +85,16 @@ class XC_Functional public: static int get_func_type(); + static void set_xc_type(const std::string xc_func_in); +#ifdef USE_LIBXC + static void set_xc_type_libxc(const std::string xc_func_in); +#endif private: - static void set_xc_type(const std::string xc_func_in); #ifdef USE_LIBXC - static void set_xc_type_libxc(const std::string xc_func_in); static std::vector init_func(const int xc_polarized); #endif - static std::vector func_id; // libxc id of functional static int func_type; //0:none, 1:lda, 2:gga, 3:mgga, 4:hybrid static bool use_libxc; From 72b09a101b053f04ec14fb545596321d62369a15 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Mar 2022 15:07:05 +0800 Subject: [PATCH 34/36] xc refactor : move all subroutines to public --- source/module_xc/xc_functional.h | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index 076f08b81a6..fee25245bb2 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -88,13 +88,11 @@ class XC_Functional static void set_xc_type(const std::string xc_func_in); #ifdef USE_LIBXC static void set_xc_type_libxc(const std::string xc_func_in); + static std::vector init_func(const int xc_polarized); #endif private: -#ifdef USE_LIBXC - static std::vector init_func(const int xc_polarized); -#endif static std::vector func_id; // libxc id of functional static int func_type; //0:none, 1:lda, 2:gga, 3:mgga, 4:hybrid static bool use_libxc; @@ -123,7 +121,7 @@ class XC_Functional // on the entire grid. I'm having xc_spin_libxc because v_xc_libxc // does not support nspin = 4. - private : + public: // LDA static void xc(const double &rho, double &exc, double &vxc); @@ -149,7 +147,7 @@ class XC_Functional // LIBXC, and the reason for not having gcxc_libxc is explained // in the NOTE in the comment for xc_functional_wrapper_wc.cpp part - private: + public: // GGA static void gcxc(const double &rho, const double &grho, @@ -177,7 +175,7 @@ class XC_Functional // NOTE : mGGA is realized through LIBXC #ifdef USE_LIBXC - private: + public: // mGGA static void tau_xc(const double &rho, const double &grho, const double &atau, double &sxc, @@ -202,9 +200,6 @@ class XC_Functional static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, std::vector &stress_gga, const bool is_stress = 0); static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); - - private: - static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); static void grad_dot( const ModuleBase::Vector3 *h, double *dh); static void noncolin_rho(double *rhoout1,double *rhoout2,double *seg); @@ -223,7 +218,7 @@ class XC_Functional // 2. slater1_spin // 3. slater_rxc_spin - private: + public: // For LDA exchange energy static void slater(const double &rs, double &ex, double &vx); @@ -255,7 +250,7 @@ class XC_Functional // 1. pw_spin // 2. pz_spin, which calls pz_polarized - private: + public: // For LDA correlation energy static void pw(const double &rs, const int &iflag, double &ec, double &vc); @@ -287,7 +282,7 @@ class XC_Functional // And some of their spin polarized counterparts: // 1. becke88_spin - private: + public: static void becke88(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); static void ggax(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); @@ -314,7 +309,7 @@ class XC_Functional // 2. ggac_spin // 3. pbec_spin - private: + public: static void perdew86(const double rho, const double grho, double &sc, double &v1c, double &v2c); static void ggac(const double &rho,const double &grho, double &sc, double &v1c, double &v2c); @@ -335,7 +330,7 @@ class XC_Functional // This file contains realizations of the HCTH GGA functional // hcth calls pwcorr - private: + public: static void hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x); static void pwcorr(const double r, const double c[], double &g, double &dg); From d5667e1215c528ee2010cd1bd2460ce1de9cfcc4 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Mar 2022 15:56:04 +0800 Subject: [PATCH 35/36] xc refactor : replace globalc::pw.nrxx in v_xc by nrxx (input variable) --- source/module_xc/xc_functional_vxc.cpp | 42 +++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/source/module_xc/xc_functional_vxc.cpp b/source/module_xc/xc_functional_vxc.cpp index 34f8163c193..8c7884ac290 100644 --- a/source/module_xc/xc_functional_vxc.cpp +++ b/source/module_xc/xc_functional_vxc.cpp @@ -212,10 +212,10 @@ std::tuple XC_Functional::v_xc_libxc( // converting rho std::vector rho; - rho.resize(GlobalC::pw.nrxx*nspin); + rho.resize(nrxx*nspin); for( int is=0; is!=nspin; ++is ) { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( int ir=0; ir!=nrxx; ++ir ) { rho[ir*nspin+is] = rho_in[is][ir] + 1.0/nspin*rho_core_in[ir]; } @@ -229,8 +229,8 @@ std::tuple XC_Functional::v_xc_libxc( gdr.resize( nspin ); for( int is=0; is!=nspin; ++is ) { - std::vector rhor(GlobalC::pw.nrxx); - for(int ir=0; ir rhor(nrxx); + for(int ir=0; ir XC_Functional::v_xc_libxc( // compute the gradient of charge density and // store the gradient in gdr[is] //------------------------------------------- - gdr[is].resize(GlobalC::pw.nrxx); + gdr[is].resize(nrxx); XC_Functional::grad_rho(rhog.data(), gdr[is].data()); } @@ -254,14 +254,14 @@ std::tuple XC_Functional::v_xc_libxc( if( 1==nspin ) { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( int ir=0; ir!=nrxx; ++ir ) { sigma[ir] = gdr[0][ir]*gdr[0][ir]; } } else { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( int ir=0; ir!=nrxx; ++ir ) { sigma[ir*3] = gdr[0][ir]*gdr[0][ir]; sigma[ir*3+1] = gdr[0][ir]*gdr[1][ir]; @@ -286,7 +286,7 @@ std::tuple XC_Functional::v_xc_libxc( // a cutoff for grho is required to ensure that libxc gives reasonable results if(nspin==2 && func.info->family != XC_FAMILY_LDA && func.info->kind==XC_CORRELATION) { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( size_t ir=0; ir!=nrxx; ++ir ) { if ( rho[ir*2] XC_Functional::v_xc_libxc( } } - // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] + // define two dimensional array dh [ nspin, nrxx ] std::vector> dh(nspin, std::vector( nrxx)); for( int is=0; is!=nspin; ++is ) { @@ -435,10 +435,10 @@ tuple XC_Functional::v_xc_m // converting rho std::vector rho; - rho.resize(GlobalC::pw.nrxx*nspin); + rho.resize(nrxx*nspin); for( int is=0; is!=nspin; ++is ) { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( int ir=0; ir!=nrxx; ++ir ) { rho[ir*nspin+is] = rho_in[is][ir] + 1.0/nspin*rho_core_in[ir]; } @@ -451,8 +451,8 @@ tuple XC_Functional::v_xc_m gdr.resize( nspin ); for( int is=0; is!=nspin; ++is ) { - std::vector rhor(GlobalC::pw.nrxx); - for(int ir=0; ir rhor(nrxx); + for(int ir=0; ir XC_Functional::v_xc_m // compute the gradient of charge density and // store the gradient in gdr[is] //------------------------------------------- - gdr[is].resize(GlobalC::pw.nrxx); + gdr[is].resize(nrxx); XC_Functional::grad_rho(rhog.data(), gdr[is].data()); } @@ -476,14 +476,14 @@ tuple XC_Functional::v_xc_m if( 1==nspin ) { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( int ir=0; ir!=nrxx; ++ir ) { sigma[ir] = gdr[0][ir]*gdr[0][ir]; } } else { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( int ir=0; ir!=nrxx; ++ir ) { sigma[ir*3] = gdr[0][ir]*gdr[0][ir]; sigma[ir*3+1] = gdr[0][ir]*gdr[1][ir]; @@ -493,10 +493,10 @@ tuple XC_Functional::v_xc_m //converting kin_r std::vector kin_r; - kin_r.resize(GlobalC::pw.nrxx*nspin); + kin_r.resize(nrxx*nspin); for( int is=0; is!=nspin; ++is ) { - for( int ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( int ir=0; ir!=nrxx; ++ir ) { kin_r[ir*nspin+is] = kin_r_in[is][ir] / 2.0; } @@ -516,7 +516,7 @@ tuple XC_Functional::v_xc_m if(nspin == 1) { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( size_t ir=0; ir!=nrxx; ++ir ) { if ( rho[ir] XC_Functional::v_xc_m } else { - for( size_t ir=0; ir!=GlobalC::pw.nrxx; ++ir ) + for( size_t ir=0; ir!=nrxx; ++ir ) { if ( rho[ir*2] XC_Functional::v_xc_m } } - // define two dimensional array dh [ nspin, GlobalC::pw.nrxx ] + // define two dimensional array dh [ nspin, nrxx ] std::vector> dh(nspin, std::vector( nrxx)); for( int is=0; is!=nspin; ++is ) { From 3df0264ea4bd5399e8a9ee3dafb5c4490227a934 Mon Sep 17 00:00:00 2001 From: wenfei-li Date: Wed, 9 Mar 2022 16:36:16 +0800 Subject: [PATCH 36/36] xc refactor : 1. put all tests in one file 2. remove some unnecessary public: in header --- source/module_xc/test/CMakeLists.txt | 17 +-- source/module_xc/test/test_xc.cpp | 157 ++++++++++++++++++++++++ source/module_xc/test/test_xc_bp.cpp | 59 --------- source/module_xc/test/test_xc_pbe.cpp | 60 --------- source/module_xc/test/test_xc_pwlda.cpp | 48 -------- source/module_xc/test/test_xc_pz.cpp | 48 -------- source/module_xc/xc_functional.h | 20 --- 7 files changed, 158 insertions(+), 251 deletions(-) create mode 100644 source/module_xc/test/test_xc.cpp delete mode 100644 source/module_xc/test/test_xc_bp.cpp delete mode 100644 source/module_xc/test/test_xc_pbe.cpp delete mode 100644 source/module_xc/test/test_xc_pwlda.cpp delete mode 100644 source/module_xc/test/test_xc_pz.cpp diff --git a/source/module_xc/test/CMakeLists.txt b/source/module_xc/test/CMakeLists.txt index 18688447fd6..4117bebfffe 100644 --- a/source/module_xc/test/CMakeLists.txt +++ b/source/module_xc/test/CMakeLists.txt @@ -2,20 +2,5 @@ remove_definitions(-DUSE_LIBXC) AddTest( TARGET XCTest_PBE - SOURCES test_xc_pbe.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp + SOURCES test_xc.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp ) - -AddTest( - TARGET XCTest_PZ - SOURCES test_xc_pz.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp -) - -AddTest( - TARGET XCTest_PWLDA - SOURCES test_xc_pwlda.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp -) - -AddTest( - TARGET XCTest_BP - SOURCES test_xc_bp.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp -) \ No newline at end of file diff --git a/source/module_xc/test/test_xc.cpp b/source/module_xc/test/test_xc.cpp new file mode 100644 index 00000000000..1ad02575334 --- /dev/null +++ b/source/module_xc/test/test_xc.cpp @@ -0,0 +1,157 @@ +#include "../xc_functional.h" +#include "gtest/gtest.h" + +//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. +namespace ModuleBase +{ + void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} +} + +namespace GlobalV +{ + std::string BASIS_TYPE = ""; + bool STRESS = 0; + int NSPIN = 1; +} + +class XCTest_PBE : public testing::Test +{ + protected: + std::vector e_lda, v_lda; + std::vector e_gga, v1_gga, v2_gga; + + void SetUp() + { + XC_Functional::set_xc_type("PBE"); + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + std::vector grho = {0.81E-11, 0.17E+01, 0.36E+02, 0.87E-01, 0.55E+00}; + + for(int i=0;i<5;i++) + { + double e,v,v1,v2; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + XC_Functional::gcxc(rho[i],grho[i],e,v1,v2); + e_gga.push_back(e); + v1_gga.push_back(v1); + v2_gga.push_back(v2); + } + } +}; + +TEST_F(XCTest_PBE, set_xc_type) +{ + EXPECT_EQ(XC_Functional::get_func_type(),2); + std::vector e_lda_ref = {-0.9570906378,-0.9570906378,-0.9200171474,-0.3808291731,-9.124862983}; + std::vector v_lda_ref = {-1.259358955 , -1.259358955, -1.210234884,-0.4975768336,-12.12952188}; + std::vector e_gga_ref = {0.0 , -0.000103750,-0.0328708695,-0.0032277985,0.0 }; + std::vector v1_gga_ref = {0.0 ,0.00021536874,0.04931694948,0.05374316118,0.0 }; + std::vector v2_gga_ref = {0.0 ,-0.0002386176,-0.0025842562,-0.0825164089,0.0 }; + + for (int i = 0;i<5;++i) + { + EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); + EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); + EXPECT_NEAR(e_gga[i],e_gga_ref[i],1.0e-8); + EXPECT_NEAR(v1_gga[i],v1_gga_ref[i],1.0e-8); + EXPECT_NEAR(v2_gga[i],v2_gga_ref[i],1.0e-8); + } +} + +class XCTest_BP : public testing::Test +{ + protected: + std::vector e_lda, v_lda; + std::vector e_gga, v1_gga, v2_gga; + + void SetUp() + { + XC_Functional::set_xc_type("BP"); + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + std::vector grho = {0.81E-11, 0.17E+01, 0.36E+02, 0.87E-01, 0.55E+00}; + + for(int i=0;i<5;i++) + { + double e,v,v1,v2; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + XC_Functional::gcxc(rho[i],grho[i],e,v1,v2); + e_gga.push_back(e); + v1_gga.push_back(v1); + v2_gga.push_back(v2); + } + } +}; + +TEST_F(XCTest_BP, set_xc_type) +{ + EXPECT_EQ(XC_Functional::get_func_type(),2); + std::vector e_lda_ref = {-0.9565173576,-0.9565173576,-0.9194417358,-0.38104767571,-9.125575429}; + std::vector v_lda_ref = {-1.2588131365,-1.2588131365,-1.2096658201,-0.49757720968,-12.13038680}; + std::vector e_gga_ref = {0.0 ,-0.0012525632,-0.0457062154,-0.0035030371,0.0 }; + std::vector v1_gga_ref = {0.0 ,0.00118557755,0.04272756138,0.04137909619,0.0 }; + std::vector v2_gga_ref = {-0.0010246353,-0.0016488916,-0.0027047176,-0.0753933855,0.0 }; + for (int i = 0;i<5;++i) + { + EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); + EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); + EXPECT_NEAR(e_gga[i],e_gga_ref[i],1.0e-7); + EXPECT_NEAR(v1_gga[i],v1_gga_ref[i],1.0e-7); + EXPECT_NEAR(v2_gga[i],v2_gga_ref[i],1.0e-7); + } +} + +class XCTest_PWLDA : public testing::Test +{ + protected: + std::vector e_lda, v_lda; + + void SetUp() + { + XC_Functional::set_xc_type("PWLDA"); + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + + for(int i=0;i<5;i++) + { + double e,v; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + } + } +}; + +TEST_F(XCTest_PWLDA, set_xc_type) +{ + EXPECT_EQ(XC_Functional::get_func_type(),1); + std::vector e_lda_ref = {-0.9570906378,-0.9570906378,-0.9200171474,-0.3808291731,-9.124862983}; + std::vector v_lda_ref = {-1.259358955 , -1.259358955, -1.210234884,-0.4975768336,-12.12952188}; + + for (int i = 0;i<5;++i) + { + EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); + EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); + } +} + +class XCTest_PZ : public testing::Test +{ + protected: + std::vector e_lda, v_lda; + + void SetUp() + { + XC_Functional::set_xc_type("PZ"); + std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; + + for(int i=0;i<5;i++) + { + double e,v; + XC_Functional::xc(rho[i],e,v); + e_lda.push_back(e); + v_lda.push_back(v); + } + } +}; \ No newline at end of file diff --git a/source/module_xc/test/test_xc_bp.cpp b/source/module_xc/test/test_xc_bp.cpp deleted file mode 100644 index 56be85b114e..00000000000 --- a/source/module_xc/test/test_xc_bp.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "../xc_functional.h" -#include "gtest/gtest.h" - -//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. -namespace ModuleBase -{ - void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} -} - -namespace GlobalV -{ - std::string BASIS_TYPE = ""; - bool STRESS = 0; - int NSPIN = 1; -} - -class XCTest_BP : public testing::Test -{ - protected: - std::vector e_lda, v_lda; - std::vector e_gga, v1_gga, v2_gga; - - void SetUp() - { - XC_Functional::set_xc_type("BP"); - std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; - std::vector grho = {0.81E-11, 0.17E+01, 0.36E+02, 0.87E-01, 0.55E+00}; - - for(int i=0;i<5;i++) - { - double e,v,v1,v2; - XC_Functional::xc(rho[i],e,v); - e_lda.push_back(e); - v_lda.push_back(v); - XC_Functional::gcxc(rho[i],grho[i],e,v1,v2); - e_gga.push_back(e); - v1_gga.push_back(v1); - v2_gga.push_back(v2); - } - } -}; - -TEST_F(XCTest_BP, set_xc_type) -{ - EXPECT_EQ(XC_Functional::get_func_type(),2); - std::vector e_lda_ref = {-0.9565173576,-0.9565173576,-0.9194417358,-0.38104767571,-9.125575429}; - std::vector v_lda_ref = {-1.2588131365,-1.2588131365,-1.2096658201,-0.49757720968,-12.13038680}; - std::vector e_gga_ref = {0.0 ,-0.0012525632,-0.0457062154,-0.0035030371,0.0 }; - std::vector v1_gga_ref = {0.0 ,0.00118557755,0.04272756138,0.04137909619,0.0 }; - std::vector v2_gga_ref = {-0.0010246353,-0.0016488916,-0.0027047176,-0.0753933855,0.0 }; - for (int i = 0;i<5;++i) - { - EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); - EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); - EXPECT_NEAR(e_gga[i],e_gga_ref[i],1.0e-7); - EXPECT_NEAR(v1_gga[i],v1_gga_ref[i],1.0e-7); - EXPECT_NEAR(v2_gga[i],v2_gga_ref[i],1.0e-7); - } -} \ No newline at end of file diff --git a/source/module_xc/test/test_xc_pbe.cpp b/source/module_xc/test/test_xc_pbe.cpp deleted file mode 100644 index 7f27ffebc02..00000000000 --- a/source/module_xc/test/test_xc_pbe.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "../xc_functional.h" -#include "gtest/gtest.h" - -//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. -namespace ModuleBase -{ - void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} -} - -namespace GlobalV -{ - std::string BASIS_TYPE = ""; - bool STRESS = 0; - int NSPIN = 1; -} - -class XCTest_PBE : public testing::Test -{ - protected: - std::vector e_lda, v_lda; - std::vector e_gga, v1_gga, v2_gga; - - void SetUp() - { - XC_Functional::set_xc_type("PBE"); - std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; - std::vector grho = {0.81E-11, 0.17E+01, 0.36E+02, 0.87E-01, 0.55E+00}; - - for(int i=0;i<5;i++) - { - double e,v,v1,v2; - XC_Functional::xc(rho[i],e,v); - e_lda.push_back(e); - v_lda.push_back(v); - XC_Functional::gcxc(rho[i],grho[i],e,v1,v2); - e_gga.push_back(e); - v1_gga.push_back(v1); - v2_gga.push_back(v2); - } - } -}; - -TEST_F(XCTest_PBE, set_xc_type) -{ - EXPECT_EQ(XC_Functional::get_func_type(),2); - std::vector e_lda_ref = {-0.9570906378,-0.9570906378,-0.9200171474,-0.3808291731,-9.124862983}; - std::vector v_lda_ref = {-1.259358955 , -1.259358955, -1.210234884,-0.4975768336,-12.12952188}; - std::vector e_gga_ref = {0.0 , -0.000103750,-0.0328708695,-0.0032277985,0.0 }; - std::vector v1_gga_ref = {0.0 ,0.00021536874,0.04931694948,0.05374316118,0.0 }; - std::vector v2_gga_ref = {0.0 ,-0.0002386176,-0.0025842562,-0.0825164089,0.0 }; - - for (int i = 0;i<5;++i) - { - EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); - EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); - EXPECT_NEAR(e_gga[i],e_gga_ref[i],1.0e-8); - EXPECT_NEAR(v1_gga[i],v1_gga_ref[i],1.0e-8); - EXPECT_NEAR(v2_gga[i],v2_gga_ref[i],1.0e-8); - } -} \ No newline at end of file diff --git a/source/module_xc/test/test_xc_pwlda.cpp b/source/module_xc/test/test_xc_pwlda.cpp deleted file mode 100644 index b9a71052ab8..00000000000 --- a/source/module_xc/test/test_xc_pwlda.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "../xc_functional.h" -#include "gtest/gtest.h" - -//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. -namespace ModuleBase -{ - void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} -} - -namespace GlobalV -{ - std::string BASIS_TYPE = ""; - bool STRESS = 0; - int NSPIN = 1; -} - -class XCTest_PWLDA : public testing::Test -{ - protected: - std::vector e_lda, v_lda; - - void SetUp() - { - XC_Functional::set_xc_type("PWLDA"); - std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; - - for(int i=0;i<5;i++) - { - double e,v; - XC_Functional::xc(rho[i],e,v); - e_lda.push_back(e); - v_lda.push_back(v); - } - } -}; - -TEST_F(XCTest_PWLDA, set_xc_type) -{ - EXPECT_EQ(XC_Functional::get_func_type(),1); - std::vector e_lda_ref = {-0.9570906378,-0.9570906378,-0.9200171474,-0.3808291731,-9.124862983}; - std::vector v_lda_ref = {-1.259358955 , -1.259358955, -1.210234884,-0.4975768336,-12.12952188}; - - for (int i = 0;i<5;++i) - { - EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); - EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); - } -} \ No newline at end of file diff --git a/source/module_xc/test/test_xc_pz.cpp b/source/module_xc/test/test_xc_pz.cpp deleted file mode 100644 index 2a363c15157..00000000000 --- a/source/module_xc/test/test_xc_pz.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "../xc_functional.h" -#include "gtest/gtest.h" - -//a mock function of WARNING_QUIT, to avoid the uncorrected call by matrix.cpp at line 37. -namespace ModuleBase -{ - void WARNING_QUIT(const std::string &file,const std::string &description) {return ;} -} - -namespace GlobalV -{ - std::string BASIS_TYPE = ""; - bool STRESS = 0; - int NSPIN = 1; -} - -class XCTest_PZ : public testing::Test -{ - protected: - std::vector e_lda, v_lda; - - void SetUp() - { - XC_Functional::set_xc_type("PZ"); - std::vector rho = {0.17E+01, 0.17E+01, 0.15E+01, 0.88E-01, 0.18E+04}; - - for(int i=0;i<5;i++) - { - double e,v; - XC_Functional::xc(rho[i],e,v); - e_lda.push_back(e); - v_lda.push_back(v); - } - } -}; - -TEST_F(XCTest_PZ, set_xc_type) -{ - EXPECT_EQ(XC_Functional::get_func_type(),1); - std::vector e_lda_ref = {-0.9565173576,-0.9565173576,-0.9194417358,-0.38104767571,-9.125575429}; - std::vector v_lda_ref = {-1.2588131365,-1.2588131365,-1.2096658201,-0.49757720968,-12.13038680}; - - for (int i = 0;i<5;++i) - { - EXPECT_NEAR(e_lda[i],e_lda_ref[i],1.0e-8); - EXPECT_NEAR(v_lda[i],v_lda_ref[i],1.0e-8); - } -} \ No newline at end of file diff --git a/source/module_xc/xc_functional.h b/source/module_xc/xc_functional.h index fee25245bb2..2baaeff954d 100644 --- a/source/module_xc/xc_functional.h +++ b/source/module_xc/xc_functional.h @@ -38,8 +38,6 @@ class XC_Functional // NOTE : it is only used for nspin = 1 and 2, the nspin = 4 case is treated in v_xc // 3. v_xc_meta : which takes rho and tau as input, and v_xc as output - public: - // compute the exchange-correlation energy // [etxc, vtxc, v] = v_xc(...) static std::tuple v_xc( @@ -82,8 +80,6 @@ class XC_Functional // for example, "XC_LDA_X+XC_LDA_C_PZ" // 4. init_func : which converts func_id into corresponding xc_func_type vector - public: - static int get_func_type(); static void set_xc_type(const std::string xc_func_in); #ifdef USE_LIBXC @@ -147,8 +143,6 @@ class XC_Functional // LIBXC, and the reason for not having gcxc_libxc is explained // in the NOTE in the comment for xc_functional_wrapper_wc.cpp part - public: - // GGA static void gcxc(const double &rho, const double &grho, double &sxc, double &v1xc, double &v2xc); @@ -175,8 +169,6 @@ class XC_Functional // NOTE : mGGA is realized through LIBXC #ifdef USE_LIBXC - public: - // mGGA static void tau_xc(const double &rho, const double &grho, const double &atau, double &sxc, double &v1xc, double &v2xc, double &v3xc); @@ -196,8 +188,6 @@ class XC_Functional // 5. noncolin_rho, which diagonalizes the spin density matrix // and gives the spin up and spin down components of the charge. - public: - static void gradcorr(double &etxc, double &vtxc, ModuleBase::matrix &v, std::vector &stress_gga, const bool is_stress = 0); static void grad_wfc( const std::complex *rhog, const int ik, std::complex **grad, const int npw ); static void grad_rho( const std::complex *rhog, ModuleBase::Vector3 *gdr ); @@ -218,8 +208,6 @@ class XC_Functional // 2. slater1_spin // 3. slater_rxc_spin - public: - // For LDA exchange energy static void slater(const double &rs, double &ex, double &vx); static void slater1(const double &rs, double &ex, double &vx); @@ -250,8 +238,6 @@ class XC_Functional // 1. pw_spin // 2. pz_spin, which calls pz_polarized - public: - // For LDA correlation energy static void pw(const double &rs, const int &iflag, double &ec, double &vc); static void pz(const double &rs, const int &iflag, double &ec, double &vc); @@ -282,8 +268,6 @@ class XC_Functional // And some of their spin polarized counterparts: // 1. becke88_spin - public: - static void becke88(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); static void ggax(const double &rho, const double &grho, double &sx, double &v1x, double &v2x); static void pbex(const double &rho, const double &grho, const int &iflag, @@ -309,8 +293,6 @@ class XC_Functional // 2. ggac_spin // 3. pbec_spin - public: - static void perdew86(const double rho, const double grho, double &sc, double &v1c, double &v2c); static void ggac(const double &rho,const double &grho, double &sc, double &v1c, double &v2c); static void pbec(const double &rho, const double &grho, const int &flag, @@ -330,8 +312,6 @@ class XC_Functional // This file contains realizations of the HCTH GGA functional // hcth calls pwcorr - public: - static void hcth(const double rho, const double grho, double &sx, double &v1x, double &v2x); static void pwcorr(const double r, const double c[], double &g, double &dg);