From 5d8b0c75a092f241e4ce379a67027ba9942a6323 Mon Sep 17 00:00:00 2001 From: mohan Date: Wed, 27 Mar 2024 10:51:50 +0800 Subject: [PATCH 01/46] update timer, add std --- source/module_base/timer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/module_base/timer.cpp b/source/module_base/timer.cpp index 48dbb0be8a4..5a40d000d2d 100644 --- a/source/module_base/timer.cpp +++ b/source/module_base/timer.cpp @@ -158,10 +158,14 @@ void timer::write_to_json(std::string file_name) auto double_to_string = [](double d) -> std::string { formatter::Fmt fmt(0, 15, ' ', false, false, false); - if(isinf(d)) + if(std::isinf(d)) + { return "Infinity"; + } else + { return fmt.format(d); + } }; // The output json file format is like this: From b5bcc7fa3dc038b0eff3a7516a84dc828550c579 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 12:10:42 +0800 Subject: [PATCH 02/46] update the format of esolver_fp.cpp --- source/module_esolver/esolver_fp.cpp | 449 ++++++++++-------- .../module_esolver/esolver_sdft_pw_tool.cpp | 0 2 files changed, 245 insertions(+), 204 deletions(-) mode change 100755 => 100644 source/module_esolver/esolver_sdft_pw_tool.cpp diff --git a/source/module_esolver/esolver_fp.cpp b/source/module_esolver/esolver_fp.cpp index 9c231acf946..566c97b877d 100644 --- a/source/module_esolver/esolver_fp.cpp +++ b/source/module_esolver/esolver_fp.cpp @@ -4,237 +4,278 @@ #include "module_hamilt_pw/hamilt_pwdft/global.h" #include "module_io/input.h" namespace ModuleESolver -{ ESolver_FP::ESolver_FP() - { - // pw_rho = new ModuleBase::PW_Basis(); +{ - pw_rho = new ModulePW::PW_Basis_Big(GlobalV::device_flag, GlobalV::precision_flag); +ESolver_FP::ESolver_FP() +{ + // pw_rho = new ModuleBase::PW_Basis(); + pw_rho = new ModulePW::PW_Basis_Big(GlobalV::device_flag, GlobalV::precision_flag); - if (GlobalV::double_grid) - { - pw_rhod = new ModulePW::PW_Basis_Big(GlobalV::device_flag, GlobalV::precision_flag); - } - else - { - pw_rhod = pw_rho; - } + if (GlobalV::double_grid) + { + pw_rhod = new ModulePW::PW_Basis_Big(GlobalV::device_flag, GlobalV::precision_flag); + } + else + { + pw_rhod = pw_rho; + } - //temporary, it will be removed - pw_big = static_cast(pw_rhod); - pw_big->setbxyz(INPUT.bx, INPUT.by, INPUT.bz); - sf.set(pw_rhod, INPUT.nbspline); + //temporary, it will be removed + pw_big = static_cast(pw_rhod); + pw_big->setbxyz(INPUT.bx, INPUT.by, INPUT.bz); + sf.set(pw_rhod, INPUT.nbspline); - GlobalC::ucell.symm.epsilon = GlobalC::ucell.symm.epsilon_input = INPUT.symmetry_prec; + GlobalC::ucell.symm.epsilon = GlobalC::ucell.symm.epsilon_input = INPUT.symmetry_prec; } - ESolver_FP::~ESolver_FP() - { - delete pw_rho; - if (GlobalV::double_grid) - { - delete pw_rhod; - } - delete this->pelec; - } - void ESolver_FP::Init(Input& inp, UnitCell& cell) - { - if(!GlobalV::use_paw) - { - cell.read_pseudo(GlobalV::ofs_running); - } + + +ESolver_FP::~ESolver_FP() +{ + delete pw_rho; + if (GlobalV::double_grid) + { + delete pw_rhod; + } + delete this->pelec; +} + + +void ESolver_FP::Init(Input& inp, UnitCell& cell) +{ + if(!GlobalV::use_paw) + { + cell.read_pseudo(GlobalV::ofs_running); + } #ifdef __MPI - this->pw_rho->initmpi(GlobalV::NPROC_IN_POOL, GlobalV::RANK_IN_POOL, POOL_WORLD); -#endif - if (this->classname == "ESolver_OF") - this->pw_rho->setfullpw(inp.of_full_pw, inp.of_full_pw_dim); - // Initalize the plane wave basis set - if (inp.nx * inp.ny * inp.nz == 0) - this->pw_rho->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, 4.0 * inp.ecutwfc); - else - this->pw_rho->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, inp.nx, inp.ny, inp.nz); - this->pw_rho->initparameters(false, 4.0 * inp.ecutwfc); - this->pw_rho->ft.fft_mode = inp.fft_mode; - this->pw_rho->setuptransform(); - this->pw_rho->collect_local_pw(); - this->pw_rho->collect_uniqgg(); - - if (GlobalV::double_grid) - { - ModulePW::PW_Basis_Sup* pw_rhod_sup = static_cast(pw_rhod); -#ifdef __MPI - this->pw_rhod->initmpi(GlobalV::NPROC_IN_POOL, GlobalV::RANK_IN_POOL, POOL_WORLD); + this->pw_rho->initmpi(GlobalV::NPROC_IN_POOL, GlobalV::RANK_IN_POOL, POOL_WORLD); #endif - if (this->classname == "ESolver_OF") - this->pw_rhod->setfullpw(inp.of_full_pw, inp.of_full_pw_dim); - if (inp.ndx * inp.ndy * inp.ndz == 0) - this->pw_rhod->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, inp.ecutrho); - else - this->pw_rhod->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, inp.ndx, inp.ndy, inp.ndz); - this->pw_rhod->initparameters(false, inp.ecutrho); - this->pw_rhod->ft.fft_mode = inp.fft_mode; - pw_rhod_sup->setuptransform(this->pw_rho); - this->pw_rhod->collect_local_pw(); - this->pw_rhod->collect_uniqgg(); - } - - this->print_rhofft(inp, GlobalV::ofs_running); + if (this->classname == "ESolver_OF") + { + this->pw_rho->setfullpw(inp.of_full_pw, inp.of_full_pw_dim); } - void ESolver_FP::init_after_vc(Input& inp, UnitCell& cell) + //! Initalize the plane wave basis set + if (inp.nx * inp.ny * inp.nz == 0) { - ModuleBase::TITLE("ESolver_FP", "init_after_vc"); + this->pw_rho->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, 4.0 * inp.ecutwfc); + } + else + { + this->pw_rho->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, inp.nx, inp.ny, inp.nz); + } + this->pw_rho->initparameters(false, 4.0 * inp.ecutwfc); + this->pw_rho->ft.fft_mode = inp.fft_mode; + this->pw_rho->setuptransform(); + this->pw_rho->collect_local_pw(); + this->pw_rho->collect_uniqgg(); - if (GlobalV::md_prec_level == 2) + if (GlobalV::double_grid) + { + ModulePW::PW_Basis_Sup* pw_rhod_sup = static_cast(pw_rhod); +#ifdef __MPI + this->pw_rhod->initmpi(GlobalV::NPROC_IN_POOL, GlobalV::RANK_IN_POOL, POOL_WORLD); +#endif + if (this->classname == "ESolver_OF") { - if (inp.nx * inp.ny * inp.nz == 0) - this->pw_rho->initgrids(cell.lat0, cell.latvec, 4.0 * inp.ecutwfc); - else - this->pw_rho->initgrids(cell.lat0, cell.latvec, inp.nx, inp.ny, inp.nz); - - this->pw_rho->initparameters(false, 4.0 * inp.ecutwfc); - this->pw_rho->setuptransform(); - this->pw_rho->collect_local_pw(); - this->pw_rho->collect_uniqgg(); - - if (GlobalV::double_grid) - { - ModulePW::PW_Basis_Sup* pw_rhod_sup = static_cast(pw_rhod); - if (inp.ndx * inp.ndy * inp.ndz == 0) - this->pw_rhod->initgrids(cell.lat0, cell.latvec, inp.ecutrho); - else - this->pw_rhod->initgrids(cell.lat0, cell.latvec, inp.ndx, inp.ndy, inp.ndz); - this->pw_rhod->initparameters(false, inp.ecutrho); - pw_rhod_sup->setuptransform(this->pw_rho); - this->pw_rhod->collect_local_pw(); - this->pw_rhod->collect_uniqgg(); - } + this->pw_rhod->setfullpw(inp.of_full_pw, inp.of_full_pw_dim); } - else + if (inp.ndx * inp.ndy * inp.ndz == 0) { - // only G-vector and K-vector are changed due to the change of lattice vector - // FFT grids do not change!! - pw_rho->initgrids(cell.lat0, cell.latvec, pw_rho->nx, pw_rho->ny, pw_rho->nz); - pw_rho->collect_local_pw(); - pw_rho->collect_uniqgg(); - - if (GlobalV::double_grid) - { - this->pw_rhod->initgrids(cell.lat0, cell.latvec, pw_rhod->nx, pw_rhod->ny, pw_rhod->nz); - this->pw_rhod->collect_local_pw(); - this->pw_rhod->collect_uniqgg(); - } - - GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, pw_rhod); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "LOCAL POTENTIAL"); + this->pw_rhod->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, inp.ecutrho); } - this->pelec->omega = GlobalC::ucell.omega; - - if(ModuleSymmetry::Symmetry::symm_flag == 1) + else { - cell.symm.analy_sys(cell.lat, cell.st, cell.atoms, GlobalV::ofs_running); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); + this->pw_rhod->initgrids(inp.ref_cell_factor * cell.lat0, cell.latvec, inp.ndx, inp.ndy, inp.ndz); } + this->pw_rhod->initparameters(false, inp.ecutrho); + this->pw_rhod->ft.fft_mode = inp.fft_mode; + pw_rhod_sup->setuptransform(this->pw_rho); + this->pw_rhod->collect_local_pw(); + this->pw_rhod->collect_uniqgg(); + } - kv.set_after_vc(cell.symm, GlobalV::global_kpoint_card, GlobalV::NSPIN, cell.G, cell.latvec); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); - } + this->print_rhofft(inp, GlobalV::ofs_running); +} - void ESolver_FP::print_rhofft(Input&inp, std::ofstream &ofs) - { - std::cout << " UNIFORM GRID DIM : " << pw_rho->nx << " * " << pw_rho->ny << " * " << pw_rho->nz - << std::endl; - std::cout << " UNIFORM GRID DIM(BIG) : " << pw_big->nbx << " * " << pw_big->nby << " * " << pw_big->nbz - << std::endl; - if (GlobalV::double_grid) - std::cout << " UNIFORM GRID DIM(DENSE) : " << pw_rhod->nx << " * " << pw_rhod->ny << " * " << pw_rhod->nz - << std::endl; - - ofs << "\n\n\n\n"; - ofs << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; - ofs << " | |" << std::endl; - ofs << " | Setup plane waves of charge/potential: |" << std::endl; - ofs << " | Use the energy cutoff and the lattice vectors to generate the |" << std::endl; - ofs << " | dimensions of FFT grid. The number of FFT grid on each processor |" << std::endl; - ofs << " | is 'nrxx'. The number of plane wave basis in reciprocal space is |" << std::endl; - ofs << " | different for charege/potential and wave functions. We also set |" << std::endl; - ofs << " | the 'sticks' for the parallel of FFT. The number of plane waves |" << std::endl; - ofs << " | is 'npw' in each processor. |" << std::endl; - ofs << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; - ofs << "\n\n\n\n"; - ofs << "\n SETUP THE PLANE WAVE BASIS" << std::endl; - double ecut = 4 * INPUT.ecutwfc; - if(inp.nx * inp.ny * inp.nz > 0) - { - ecut = this->pw_rho->gridecut_lat * this->pw_rho->tpiba2; - ofs << "use input fft dimensions for wave functions." << std::endl; - ofs << "calculate energy cutoff from nx, ny, nz:" << std::endl; - } - ModuleBase::GlobalFunc::OUT(ofs,"energy cutoff for charge/potential (unit:Ry)", ecut); - - ModuleBase::GlobalFunc::OUT(ofs,"fft grid for charge/potential", this->pw_rho->nx,this->pw_rho->ny,this->pw_rho->nz); - ModuleBase::GlobalFunc::OUT(ofs, "fft grid division", pw_big->bx, pw_big->by, pw_big->bz); - ModuleBase::GlobalFunc::OUT(ofs, "big fft grid for charge/potential", pw_big->nbx, pw_big->nby, pw_big->nbz); - ModuleBase::GlobalFunc::OUT(ofs, "nbxx", pw_big->nbxx); - ModuleBase::GlobalFunc::OUT(ofs, "nrxx", this->pw_rho->nrxx); - - ofs << "\n SETUP PLANE WAVES FOR CHARGE/POTENTIAL" << std::endl; - ModuleBase::GlobalFunc::OUT(ofs,"number of plane waves",this->pw_rho->npwtot); - ModuleBase::GlobalFunc::OUT(ofs,"number of sticks", this->pw_rho->nstot); - - ofs << "\n PARALLEL PW FOR CHARGE/POTENTIAL" << std::endl; - ofs <<" "<< std::setw(8) << "PROC"<< std::setw(15) << "COLUMNS(POT)"<< std::setw(15) << "PW" << std::endl; - for (int i = 0; i < GlobalV::NPROC_IN_POOL ; ++i) +void ESolver_FP::init_after_vc(Input& inp, UnitCell& cell) +{ + ModuleBase::TITLE("ESolver_FP", "init_after_vc"); + + if (GlobalV::md_prec_level == 2) + { + if (inp.nx * inp.ny * inp.nz == 0) { - ofs <<" "<pw_rho->nst_per[i] << std::setw(15) << this->pw_rho->npw_per[i] << std::endl; + this->pw_rho->initgrids(cell.lat0, cell.latvec, 4.0 * inp.ecutwfc); } - ofs << " --------------- sum -------------------" << std::endl; - ofs << " " << std::setw(8) << GlobalV::NPROC_IN_POOL << std::setw(15) << this->pw_rho->nstot << std::setw(15) << this->pw_rho->npwtot << std::endl; - - ModuleBase::GlobalFunc::OUT(ofs,"number of |g|", this->pw_rho->ngg); - ModuleBase::GlobalFunc::OUT(ofs,"max |g|", this->pw_rho->gg_uniq[ this->pw_rho->ngg-1]); - ModuleBase::GlobalFunc::OUT(ofs,"min |g|", this->pw_rho->gg_uniq[0]); - - if (GlobalV::double_grid) + else { - ofs << std::endl; - ofs << std::endl; - ofs << std::endl; - double ecut = INPUT.ecutrho; - if (inp.ndx * inp.ndy * inp.ndz > 0) + this->pw_rho->initgrids(cell.lat0, cell.latvec, inp.nx, inp.ny, inp.nz); + } + + this->pw_rho->initparameters(false, 4.0 * inp.ecutwfc); + this->pw_rho->setuptransform(); + this->pw_rho->collect_local_pw(); + this->pw_rho->collect_uniqgg(); + + if (GlobalV::double_grid) + { + ModulePW::PW_Basis_Sup* pw_rhod_sup = static_cast(pw_rhod); + if (inp.ndx * inp.ndy * inp.ndz == 0) { - ecut = this->pw_rhod->gridecut_lat * this->pw_rhod->tpiba2; - ofs << "use input fft dimensions for the dense part of charge density." << std::endl; - ofs << "calculate energy cutoff from ndx, ndy, ndz:" << std::endl; + this->pw_rhod->initgrids(cell.lat0, cell.latvec, inp.ecutrho); } - ModuleBase::GlobalFunc::OUT(ofs, "energy cutoff for dense charge/potential (unit:Ry)", ecut); - - ModuleBase::GlobalFunc::OUT(ofs, - "fft grid for dense charge/potential", - this->pw_rhod->nx, - this->pw_rhod->ny, - this->pw_rhod->nz); - ModuleBase::GlobalFunc::OUT(ofs, "nrxx", this->pw_rhod->nrxx); - - ofs << "\n SETUP PLANE WAVES FOR dense CHARGE/POTENTIAL" << std::endl; - ModuleBase::GlobalFunc::OUT(ofs, "number of plane waves", this->pw_rhod->npwtot); - ModuleBase::GlobalFunc::OUT(ofs, "number of sticks", this->pw_rhod->nstot); - - ofs << "\n PARALLEL PW FOR dense CHARGE/POTENTIAL" << std::endl; - ofs << " " << std::setw(8) << "PROC" << std::setw(15) << "COLUMNS(POT)" << std::setw(15) << "PW" - << std::endl; - for (int i = 0; i < GlobalV::NPROC_IN_POOL; ++i) + else { - ofs << " " << std::setw(8) << i + 1 << std::setw(15) << this->pw_rhod->nst_per[i] << std::setw(15) - << this->pw_rhod->npw_per[i] << std::endl; + this->pw_rhod->initgrids(cell.lat0, cell.latvec, inp.ndx, inp.ndy, inp.ndz); } - ofs << " --------------- sum -------------------" << std::endl; - ofs << " " << std::setw(8) << GlobalV::NPROC_IN_POOL << std::setw(15) << this->pw_rhod->nstot - << std::setw(15) << this->pw_rhod->npwtot << std::endl; + this->pw_rhod->initparameters(false, inp.ecutrho); + pw_rhod_sup->setuptransform(this->pw_rho); + this->pw_rhod->collect_local_pw(); + this->pw_rhod->collect_uniqgg(); + } + } + else + { + // only G-vector and K-vector are changed due to the change of lattice vector + // FFT grids do not change!! + pw_rho->initgrids(cell.lat0, cell.latvec, pw_rho->nx, pw_rho->ny, pw_rho->nz); + pw_rho->collect_local_pw(); + pw_rho->collect_uniqgg(); - ModuleBase::GlobalFunc::OUT(ofs, "number of |g|", this->pw_rhod->ngg); - ModuleBase::GlobalFunc::OUT(ofs, "max |g|", this->pw_rhod->gg_uniq[this->pw_rhod->ngg - 1]); - ModuleBase::GlobalFunc::OUT(ofs, "min |g|", this->pw_rhod->gg_uniq[0]); - } + if (GlobalV::double_grid) + { + this->pw_rhod->initgrids(cell.lat0, cell.latvec, pw_rhod->nx, pw_rhod->ny, pw_rhod->nz); + this->pw_rhod->collect_local_pw(); + this->pw_rhod->collect_uniqgg(); + } + + GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, pw_rhod); + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "LOCAL POTENTIAL"); + } + this->pelec->omega = GlobalC::ucell.omega; + + if(ModuleSymmetry::Symmetry::symm_flag == 1) + { + cell.symm.analy_sys(cell.lat, cell.st, cell.atoms, GlobalV::ofs_running); + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); + } + + kv.set_after_vc(cell.symm, GlobalV::global_kpoint_card, GlobalV::NSPIN, cell.G, cell.latvec); + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); +} + + +void ESolver_FP::print_rhofft(Input&inp, std::ofstream &ofs) +{ + std::cout << " UNIFORM GRID DIM : " << pw_rho->nx << " * " << pw_rho->ny << " * " << pw_rho->nz + << std::endl; + std::cout << " UNIFORM GRID DIM(BIG) : " << pw_big->nbx << " * " << pw_big->nby << " * " << pw_big->nbz + << std::endl; + if (GlobalV::double_grid) + { + std::cout << " UNIFORM GRID DIM(DENSE) : " << pw_rhod->nx << " * " << pw_rhod->ny << " * " << pw_rhod->nz + << std::endl; } -} \ No newline at end of file + + ofs << "\n\n\n\n"; + ofs << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; + ofs << " | |" << std::endl; + ofs << " | Setup plane waves of charge/potential: |" << std::endl; + ofs << " | Use the energy cutoff and the lattice vectors to generate the |" << std::endl; + ofs << " | dimensions of FFT grid. The number of FFT grid on each processor |" << std::endl; + ofs << " | is 'nrxx'. The number of plane wave basis in reciprocal space is |" << std::endl; + ofs << " | different for charege/potential and wave functions. We also set |" << std::endl; + ofs << " | the 'sticks' for the parallel of FFT. The number of plane waves |" << std::endl; + ofs << " | is 'npw' in each processor. |" << std::endl; + ofs << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; + ofs << "\n\n\n\n"; + ofs << "\n SETUP THE PLANE WAVE BASIS" << std::endl; + + double ecut = 4 * INPUT.ecutwfc; + if(inp.nx * inp.ny * inp.nz > 0) + { + ecut = this->pw_rho->gridecut_lat * this->pw_rho->tpiba2; + ofs << "use input fft dimensions for wave functions." << std::endl; + ofs << "calculate energy cutoff from nx, ny, nz:" << std::endl; + } + + ModuleBase::GlobalFunc::OUT(ofs,"energy cutoff for charge/potential (unit:Ry)", ecut); + + ModuleBase::GlobalFunc::OUT(ofs,"fft grid for charge/potential", this->pw_rho->nx,this->pw_rho->ny,this->pw_rho->nz); + ModuleBase::GlobalFunc::OUT(ofs, "fft grid division", pw_big->bx, pw_big->by, pw_big->bz); + ModuleBase::GlobalFunc::OUT(ofs, "big fft grid for charge/potential", pw_big->nbx, pw_big->nby, pw_big->nbz); + ModuleBase::GlobalFunc::OUT(ofs, "nbxx", pw_big->nbxx); + ModuleBase::GlobalFunc::OUT(ofs, "nrxx", this->pw_rho->nrxx); + + ofs << "\n SETUP PLANE WAVES FOR CHARGE/POTENTIAL" << std::endl; + ModuleBase::GlobalFunc::OUT(ofs,"number of plane waves",this->pw_rho->npwtot); + ModuleBase::GlobalFunc::OUT(ofs,"number of sticks", this->pw_rho->nstot); + + ofs << "\n PARALLEL PW FOR CHARGE/POTENTIAL" << std::endl; + ofs <<" "<< std::setw(8) << "PROC"<< std::setw(15) << "COLUMNS(POT)"<< std::setw(15) << "PW" << std::endl; + + for (int i = 0; i < GlobalV::NPROC_IN_POOL ; ++i) + { + ofs <<" "<pw_rho->nst_per[i] + << std::setw(15) << this->pw_rho->npw_per[i] << std::endl; + } + ofs << " --------------- sum -------------------" << std::endl; + ofs << " " << std::setw(8) + << GlobalV::NPROC_IN_POOL + << std::setw(15) << this->pw_rho->nstot + << std::setw(15) << this->pw_rho->npwtot << std::endl; + + ModuleBase::GlobalFunc::OUT(ofs,"number of |g|", this->pw_rho->ngg); + ModuleBase::GlobalFunc::OUT(ofs,"max |g|", this->pw_rho->gg_uniq[ this->pw_rho->ngg-1]); + ModuleBase::GlobalFunc::OUT(ofs,"min |g|", this->pw_rho->gg_uniq[0]); + + if (GlobalV::double_grid) + { + ofs << std::endl; + ofs << std::endl; + ofs << std::endl; + double ecut = INPUT.ecutrho; + if (inp.ndx * inp.ndy * inp.ndz > 0) + { + ecut = this->pw_rhod->gridecut_lat * this->pw_rhod->tpiba2; + ofs << "use input fft dimensions for the dense part of charge density." << std::endl; + ofs << "calculate energy cutoff from ndx, ndy, ndz:" << std::endl; + } + ModuleBase::GlobalFunc::OUT(ofs, "energy cutoff for dense charge/potential (unit:Ry)", ecut); + + ModuleBase::GlobalFunc::OUT(ofs, + "fft grid for dense charge/potential", + this->pw_rhod->nx, + this->pw_rhod->ny, + this->pw_rhod->nz); + + ModuleBase::GlobalFunc::OUT(ofs, "nrxx", this->pw_rhod->nrxx); + + ofs << "\n SETUP PLANE WAVES FOR dense CHARGE/POTENTIAL" << std::endl; + ModuleBase::GlobalFunc::OUT(ofs, "number of plane waves", this->pw_rhod->npwtot); + ModuleBase::GlobalFunc::OUT(ofs, "number of sticks", this->pw_rhod->nstot); + + ofs << "\n PARALLEL PW FOR dense CHARGE/POTENTIAL" << std::endl; + ofs << " " << std::setw(8) << "PROC" << std::setw(15) << "COLUMNS(POT)" << std::setw(15) << "PW" + << std::endl; + + for (int i = 0; i < GlobalV::NPROC_IN_POOL; ++i) + { + ofs << " " << std::setw(8) << i + 1 << std::setw(15) << this->pw_rhod->nst_per[i] << std::setw(15) + << this->pw_rhod->npw_per[i] << std::endl; + } + ofs << " --------------- sum -------------------" << std::endl; + ofs << " " << std::setw(8) << GlobalV::NPROC_IN_POOL << std::setw(15) << this->pw_rhod->nstot + << std::setw(15) << this->pw_rhod->npwtot << std::endl; + + ModuleBase::GlobalFunc::OUT(ofs, "number of |g|", this->pw_rhod->ngg); + ModuleBase::GlobalFunc::OUT(ofs, "max |g|", this->pw_rhod->gg_uniq[this->pw_rhod->ngg - 1]); + ModuleBase::GlobalFunc::OUT(ofs, "min |g|", this->pw_rhod->gg_uniq[0]); + } +} + +} //! end of namespace ModuleESolver diff --git a/source/module_esolver/esolver_sdft_pw_tool.cpp b/source/module_esolver/esolver_sdft_pw_tool.cpp old mode 100755 new mode 100644 From 3c69ace1cb10f84b0f0cb6837998faf6baa3152b Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 12:23:55 +0800 Subject: [PATCH 03/46] add description in esolver_fp.h --- source/module_esolver/esolver_fp.h | 34 +++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/source/module_esolver/esolver_fp.h b/source/module_esolver/esolver_fp.h index 21b0588ff2d..73c2a41a2d6 100644 --- a/source/module_esolver/esolver_fp.h +++ b/source/module_esolver/esolver_fp.h @@ -7,37 +7,61 @@ #include "module_cell/module_symmetry/symmetry.h" #include "module_elecstate/elecstate.h" #include "module_hamilt_pw/hamilt_pwdft/structure_factor.h" -// #include "hamilt.h" + +//! The First-Principles (FP) Energy Solver Class +/** + * This class represents components that needed in + * first-principles energy solver, such as the plane + * wave basis, the structure factors, and the k points. + * +*/ + namespace ModuleESolver { class ESolver_FP : public ESolver { public: + ModulePW::PW_Basis* pw_rho; + /** - * same as pw_rho for ncpp. + * @brief same as pw_rho for ncpp. Here 'd' stands for 'dense' * dense grid for for uspp, used for ultrasoft augmented charge density. * charge density and potential are defined on dense grids, * but effective potential needs to be interpolated on smooth grids in order to compute Veff|psi> */ ModulePW::PW_Basis* pw_rhod; ModulePW::PW_Basis_Big* pw_big; ///< [temp] pw_basis_big class + + //! Constructor ESolver_FP(); + + //! Deconstructor virtual ~ESolver_FP(); + + //! Initialize of the first-principels energy solver virtual void Init(Input& inp, UnitCell& cell) override; + virtual void init_after_vc(Input& inp, UnitCell& cell); // liuyu add 2023-03-09 - // Hamilt* phamilt; + //! Electronic states elecstate::ElecState* pelec = nullptr; + + //! Electorn charge density Charge chr; - //--------------temporary---------------------------- - // this is the interface of non-self-consistant calculation + + //! Non-Self-Consistant Filed (NSCF) calculations virtual void nscf(){}; + //! Structure factors Structure_Factor sf; + + //! K-point list K_Vectors kv; private: + + //! Print charge density using FFT void print_rhofft(Input& inp, std::ofstream &ofs); }; } From e1551cf96b4e71ba620f380ac210d01623d3928d Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 12:56:41 +0800 Subject: [PATCH 04/46] update a few esolver files --- source/module_esolver/esolver_fp.h | 4 +- source/module_esolver/esolver_ks.cpp | 1124 ++++++++++++++------------ source/module_esolver/esolver_ks.h | 191 +++-- 3 files changed, 696 insertions(+), 623 deletions(-) diff --git a/source/module_esolver/esolver_fp.h b/source/module_esolver/esolver_fp.h index 73c2a41a2d6..b05c400245e 100644 --- a/source/module_esolver/esolver_fp.h +++ b/source/module_esolver/esolver_fp.h @@ -53,10 +53,10 @@ namespace ModuleESolver //! Non-Self-Consistant Filed (NSCF) calculations virtual void nscf(){}; - //! Structure factors + //! Structure factors that used with plane-wave basis set Structure_Factor sf; - //! K-point list + //! K points in Brillouin zone K_Vectors kv; private: diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 89cb0ceb649..47ce415fe74 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -30,580 +30,630 @@ namespace ModuleESolver { - template - ESolver_KS::ESolver_KS() - { - classname = "ESolver_KS"; - basisname = "PLEASE ADD BASISNAME FOR CURRENT ESOLVER."; - scf_thr = GlobalV::SCF_THR; - drho = 0.0; - maxniter = GlobalV::SCF_NMAX; - niter = maxniter; - out_freq_elec = GlobalV::OUT_FREQ_ELEC; - - // pw_rho = new ModuleBase::PW_Basis(); - //temporary, it will be removed - pw_wfc = new ModulePW::PW_Basis_K_Big(GlobalV::device_flag, GlobalV::precision_flag); - ModulePW::PW_Basis_K_Big* tmp = static_cast(pw_wfc); - tmp->setbxyz(INPUT.bx,INPUT.by,INPUT.bz); - - ///---------------------------------------------------------- - /// charge mixing - ///---------------------------------------------------------- - p_chgmix = new Charge_Mixing(); - p_chgmix->set_rhopw(this->pw_rho, this->pw_rhod); - - ///---------------------------------------------------------- - /// wavefunc - ///---------------------------------------------------------- - this->wf.init_wfc = INPUT.init_wfc; - this->wf.mem_saver = INPUT.mem_saver; - this->wf.out_wfc_pw = INPUT.out_wfc_pw; - this->wf.out_wfc_r = INPUT.out_wfc_r; - } - - template - ESolver_KS::~ESolver_KS() - { - delete this->psi; - delete this->pw_wfc; - delete this->p_hamilt; - delete this->phsol; - delete this->p_chgmix; - } - - template - void ESolver_KS::Init(Input& inp, UnitCell& ucell) - { - ESolver_FP::Init(inp,ucell); - - //------------------Charge Mixing------------------ - p_chgmix->set_mixing(GlobalV::MIXING_MODE, - GlobalV::MIXING_BETA, - GlobalV::MIXING_NDIM, - GlobalV::MIXING_GG0, - GlobalV::MIXING_TAU, - GlobalV::MIXING_BETA_MAG, - GlobalV::MIXING_GG0_MAG, - GlobalV::MIXING_GG0_MIN, - GlobalV::MIXING_ANGLE, - GlobalV::MIXING_DMR); - +template +ESolver_KS::ESolver_KS() +{ + classname = "ESolver_KS"; + basisname = "PLEASE ADD BASISNAME FOR CURRENT ESOLVER."; + scf_thr = GlobalV::SCF_THR; + drho = 0.0; + maxniter = GlobalV::SCF_NMAX; + niter = maxniter; + out_freq_elec = GlobalV::OUT_FREQ_ELEC; + + // pw_rho = new ModuleBase::PW_Basis(); + //temporary, it will be removed + pw_wfc = new ModulePW::PW_Basis_K_Big(GlobalV::device_flag, GlobalV::precision_flag); + ModulePW::PW_Basis_K_Big* tmp = static_cast(pw_wfc); + tmp->setbxyz(INPUT.bx,INPUT.by,INPUT.bz); + + ///---------------------------------------------------------- + /// charge mixing + ///---------------------------------------------------------- + p_chgmix = new Charge_Mixing(); + p_chgmix->set_rhopw(this->pw_rho, this->pw_rhod); + + ///---------------------------------------------------------- + /// wavefunc + ///---------------------------------------------------------- + this->wf.init_wfc = INPUT.init_wfc; + this->wf.mem_saver = INPUT.mem_saver; + this->wf.out_wfc_pw = INPUT.out_wfc_pw; + this->wf.out_wfc_r = INPUT.out_wfc_r; +} + +template +ESolver_KS::~ESolver_KS() +{ + delete this->psi; + delete this->pw_wfc; + delete this->p_hamilt; + delete this->phsol; + delete this->p_chgmix; +} + +template +void ESolver_KS::Init(Input& inp, UnitCell& ucell) +{ + ESolver_FP::Init(inp,ucell); + + //------------------Charge Mixing------------------ + p_chgmix->set_mixing(GlobalV::MIXING_MODE, + GlobalV::MIXING_BETA, + GlobalV::MIXING_NDIM, + GlobalV::MIXING_GG0, + GlobalV::MIXING_TAU, + GlobalV::MIXING_BETA_MAG, + GlobalV::MIXING_GG0_MAG, + GlobalV::MIXING_GG0_MIN, + GlobalV::MIXING_ANGLE, + GlobalV::MIXING_DMR); + + /// PAW Section + #ifdef USE_PAW - if(GlobalV::use_paw) - { - int * atom_type; - double ** atom_coord; - std::vector filename_list; - - atom_type = new int [GlobalC::ucell.nat]; - atom_coord = new double * [GlobalC::ucell.nat]; - filename_list.resize(GlobalC::ucell.ntype); - - for(int ia = 0; ia < GlobalC::ucell.nat; ia ++) - { - atom_coord[ia] = new double [3]; - } - - int iat = 0; - for(int it = 0; it < GlobalC::ucell.ntype; it ++) - { - for(int ia = 0; ia < GlobalC::ucell.atoms[it].na; ia ++) - { - atom_type[iat] = it; - atom_coord[iat][0] = GlobalC::ucell.atoms[it].taud[ia].x; - atom_coord[iat][1] = GlobalC::ucell.atoms[it].taud[ia].y; - atom_coord[iat][2] = GlobalC::ucell.atoms[it].taud[ia].z; - iat ++; - } - } - - if(GlobalV::MY_RANK == 0) - { - std::ifstream ifa(GlobalV::stru_file.c_str(), std::ios::in); - if (!ifa) - { - ModuleBase::WARNING_QUIT("set_libpaw_files", "can not open stru file"); - } - - std::string line; - while(!ifa.eof()) - { - getline(ifa,line); - if (line.find("PAW_FILES") != std::string::npos) break; - } - - for(int it = 0; it < GlobalC::ucell.ntype; it++) - { - ifa >> filename_list[it]; - } - } + if(GlobalV::use_paw) + { + int * atom_type; + double ** atom_coord; + std::vector filename_list; + + atom_type = new int [GlobalC::ucell.nat]; + atom_coord = new double * [GlobalC::ucell.nat]; + filename_list.resize(GlobalC::ucell.ntype); + + for(int ia = 0; ia < GlobalC::ucell.nat; ia ++) + { + atom_coord[ia] = new double [3]; + } + + int iat = 0; + for(int it = 0; it < GlobalC::ucell.ntype; it ++) + { + for(int ia = 0; ia < GlobalC::ucell.atoms[it].na; ia ++) + { + atom_type[iat] = it; + atom_coord[iat][0] = GlobalC::ucell.atoms[it].taud[ia].x; + atom_coord[iat][1] = GlobalC::ucell.atoms[it].taud[ia].y; + atom_coord[iat][2] = GlobalC::ucell.atoms[it].taud[ia].z; + iat ++; + } + } + + if(GlobalV::MY_RANK == 0) + { + std::ifstream ifa(GlobalV::stru_file.c_str(), std::ios::in); + if (!ifa) + { + ModuleBase::WARNING_QUIT("set_libpaw_files", "can not open stru file"); + } + + std::string line; + while(!ifa.eof()) + { + getline(ifa,line); + if (line.find("PAW_FILES") != std::string::npos) break; + } + + for(int it = 0; it < GlobalC::ucell.ntype; it++) + { + ifa >> filename_list[it]; + } + } #ifdef __MPI - for(int it = 0; it < GlobalC::ucell.ntype; it++) - { - Parallel_Common::bcast_string(filename_list[it]); - } + for(int it = 0; it < GlobalC::ucell.ntype; it++) + { + Parallel_Common::bcast_string(filename_list[it]); + } #endif - - GlobalC::paw_cell.init_paw_cell(INPUT.ecutwfc, INPUT.cell_factor, - GlobalC::ucell.omega,GlobalC::ucell.nat,GlobalC::ucell.ntype, - atom_type,(const double **) atom_coord, - filename_list); - - for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) - { - delete [] atom_coord[iat]; - } - delete [] atom_coord; - delete [] atom_type; - } + + GlobalC::paw_cell.init_paw_cell(INPUT.ecutwfc, INPUT.cell_factor, + GlobalC::ucell.omega,GlobalC::ucell.nat,GlobalC::ucell.ntype, + atom_type,(const double **) atom_coord, + filename_list); + + for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) + { + delete [] atom_coord[iat]; + } + delete [] atom_coord; + delete [] atom_type; + } #endif - ucell.cal_nelec(GlobalV::nelec); - - /* it has been established that that - xc_func is same for all elements, therefore - only the first one if used*/ - if(GlobalV::use_paw) - { - XC_Functional::set_xc_type(GlobalV::DFT_FUNCTIONAL); - } - else - { - XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func); - } - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); - - // symmetry analysis should be performed every time the cell is changed - if (ModuleSymmetry::Symmetry::symm_flag == 1) - { - ucell.symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); - } - - // Setup the k points according to symmetry. - this->kv.set(ucell.symm, GlobalV::global_kpoint_card, GlobalV::NSPIN, ucell.G, ucell.latvec); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); - - // print information - // mohan add 2021-01-30 - Print_Info::setup_parameters(ucell, this->kv); - - //if(GlobalV::BASIS_TYPE=="pw" || GlobalV::CALCULATION=="get_wf") - //{ - //Envelope function is calculated as lcao_in_pw - //new plane wave basis + /// End PAW + + ucell.cal_nelec(GlobalV::nelec); + + /* it has been established that that + xc_func is same for all elements, therefore + only the first one if used*/ + if(GlobalV::use_paw) + { + XC_Functional::set_xc_type(GlobalV::DFT_FUNCTIONAL); + } + else + { + XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func); + } + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); + + // symmetry analysis should be performed every time the cell is changed + if (ModuleSymmetry::Symmetry::symm_flag == 1) + { + ucell.symm.analy_sys(ucell.lat, ucell.st, ucell.atoms, GlobalV::ofs_running); + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SYMMETRY"); + } + + // Setup the k points according to symmetry. + this->kv.set(ucell.symm, GlobalV::global_kpoint_card, GlobalV::NSPIN, ucell.G, ucell.latvec); + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT K-POINTS"); + + // print information + // mohan add 2021-01-30 + Print_Info::setup_parameters(ucell, this->kv); + + //if(GlobalV::BASIS_TYPE=="pw" || GlobalV::CALCULATION=="get_wf") + //{ + //Envelope function is calculated as lcao_in_pw + //new plane wave basis #ifdef __MPI - this->pw_wfc->initmpi(GlobalV::NPROC_IN_POOL, GlobalV::RANK_IN_POOL, POOL_WORLD); + this->pw_wfc->initmpi(GlobalV::NPROC_IN_POOL, GlobalV::RANK_IN_POOL, POOL_WORLD); #endif - this->pw_wfc->initgrids(inp.ref_cell_factor * ucell.lat0, - ucell.latvec, - this->pw_rho->nx, - this->pw_rho->ny, - this->pw_rho->nz); - this->pw_wfc->initparameters(false, inp.ecutwfc, this->kv.nks, this->kv.kvec_d.data()); + this->pw_wfc->initgrids(inp.ref_cell_factor * ucell.lat0, + ucell.latvec, + this->pw_rho->nx, + this->pw_rho->ny, + this->pw_rho->nz); + this->pw_wfc->initparameters(false, inp.ecutwfc, this->kv.nks, this->kv.kvec_d.data()); #ifdef __MPI - if (INPUT.pw_seed > 0) - MPI_Allreduce(MPI_IN_PLACE, &this->pw_wfc->ggecut, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - // qianrui add 2021-8-13 to make different kpar parameters can get the same results + if (INPUT.pw_seed > 0) + { + MPI_Allreduce(MPI_IN_PLACE, &this->pw_wfc->ggecut, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + } + // qianrui add 2021-8-13 to make different kpar parameters can get the same results #endif - this->pw_wfc->ft.fft_mode = inp.fft_mode; - this->pw_wfc->setuptransform(); - for (int ik = 0; ik < this->kv.nks; ++ik) - this->kv.ngk[ik] = this->pw_wfc->npwk[ik]; - this->pw_wfc->collect_local_pw(inp.erf_ecut, inp.erf_height, inp.erf_sigma); - this->print_wfcfft(inp, GlobalV::ofs_running); - //} - // initialize the real-space uniform grid for FFT and parallel - // distribution of plane waves - GlobalC::Pgrid.init(this->pw_rhod->nx, - this->pw_rhod->ny, - this->pw_rhod->nz, - this->pw_rhod->nplane, - this->pw_rhod->nrxx, - pw_big->nbz, - pw_big->bz); // mohan add 2010-07-22, update 2011-05-04 - - // Calculate Structure factor - this->sf.setup_structure_factor(&GlobalC::ucell, this->pw_rhod); - - // Initialize charge extrapolation - CE.Init_CE(GlobalC::ucell.nat); + this->pw_wfc->ft.fft_mode = inp.fft_mode; + this->pw_wfc->setuptransform(); + for (int ik = 0; ik < this->kv.nks; ++ik) + { + this->kv.ngk[ik] = this->pw_wfc->npwk[ik]; + } + + this->pw_wfc->collect_local_pw(inp.erf_ecut, inp.erf_height, inp.erf_sigma); + + this->print_wfcfft(inp, GlobalV::ofs_running); + + //! initialize the real-space uniform grid for FFT and parallel + //! distribution of plane waves + GlobalC::Pgrid.init(this->pw_rhod->nx, + this->pw_rhod->ny, + this->pw_rhod->nz, + this->pw_rhod->nplane, + this->pw_rhod->nrxx, + pw_big->nbz, + pw_big->bz); // mohan add 2010-07-22, update 2011-05-04 + + // Calculate Structure factor + this->sf.setup_structure_factor(&GlobalC::ucell, this->pw_rhod); + + // Initialize charge extrapolation + CE.Init_CE(GlobalC::ucell.nat); #ifdef USE_PAW - if(GlobalV::use_paw) - { - GlobalC::paw_cell.set_libpaw_ecut(INPUT.ecutwfc/2.0,INPUT.ecutwfc/2.0); //in Hartree - GlobalC::paw_cell.set_libpaw_fft(this->pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz, - this->pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz, - this->pw_wfc->startz,this->pw_wfc->numz); + if(GlobalV::use_paw) + { + GlobalC::paw_cell.set_libpaw_ecut(INPUT.ecutwfc/2.0,INPUT.ecutwfc/2.0); //in Hartree + GlobalC::paw_cell.set_libpaw_fft(this->pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz, + this->pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz, + this->pw_wfc->startz,this->pw_wfc->numz); #ifdef __MPI - if(GlobalV::RANK_IN_POOL == 0) GlobalC::paw_cell.prepare_paw(); + if(GlobalV::RANK_IN_POOL == 0) + { + GlobalC::paw_cell.prepare_paw(); + } #else - GlobalC::paw_cell.prepare_paw(); + GlobalC::paw_cell.prepare_paw(); #endif - GlobalC::paw_cell.set_sij(); + GlobalC::paw_cell.set_sij(); - GlobalC::paw_cell.set_eigts( - this->pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz, - this->sf.eigts1.c,this->sf.eigts2.c,this->sf.eigts3.c); + GlobalC::paw_cell.set_eigts( + this->pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz, + this->sf.eigts1.c,this->sf.eigts2.c,this->sf.eigts3.c); - std::vector> rhoijp; - std::vector> rhoijselect; - std::vector nrhoijsel; + std::vector> rhoijp; + std::vector> rhoijselect; + std::vector nrhoijsel; #ifdef __MPI - if(GlobalV::RANK_IN_POOL == 0) - { - GlobalC::paw_cell.get_rhoijp(rhoijp, rhoijselect, nrhoijsel); - - for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) - { - GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); - } - } + if(GlobalV::RANK_IN_POOL == 0) + { + GlobalC::paw_cell.get_rhoijp(rhoijp, rhoijselect, nrhoijsel); + + for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) + { + GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); + } + } #else - GlobalC::paw_cell.get_rhoijp(rhoijp, rhoijselect, nrhoijsel); + GlobalC::paw_cell.get_rhoijp(rhoijp, rhoijselect, nrhoijsel); - for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) - { - GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); - } + for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) + { + GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); + } #endif - } + } #endif - } - - template - void ESolver_KS::init_after_vc(Input& inp, UnitCell& ucell) - { - ModuleBase::TITLE("ESolver_KS", "init_after_vc"); - - ESolver_FP::init_after_vc(inp, ucell); - - if (GlobalV::md_prec_level == 2) - { - // initialize the real-space uniform grid for FFT and parallel - // distribution of plane waves - GlobalC::Pgrid.init(this->pw_rhod->nx, - this->pw_rhod->ny, - this->pw_rhod->nz, - this->pw_rhod->nplane, - this->pw_rhod->nrxx, - pw_big->nbz, - pw_big->bz); // mohan add 2010-07-22, update 2011-05-04 - - // Calculate Structure factor - this->sf.setup_structure_factor(&ucell, this->pw_rhod); - } - } - - template - void ESolver_KS::hamilt2density(const int istep, const int iter, const double ethr) - { - ModuleBase::timer::tick(this->classname, "hamilt2density"); - //Temporarily, before HSolver is constructed, it should be overrided by - //LCAO, PW, SDFT and TDDFT. - //After HSolver is constructed, LCAO, PW, SDFT should delete their own - //hamilt2density() and use: - //this->phsol->solve(this->phamilt, this->pes, this->wf, ETHR); - ModuleBase::timer::tick(this->classname, "hamilt2density"); - } - - template - void ESolver_KS::print_wfcfft(Input& inp, std::ofstream &ofs) - { - ofs << "\n\n\n\n"; - ofs << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; - ofs << " | |" << std::endl; - ofs << " | Setup plane waves of wave functions: |" << std::endl; - ofs << " | Use the energy cutoff and the lattice vectors to generate the |" << std::endl; - ofs << " | dimensions of FFT grid. The number of FFT grid on each processor |" << std::endl; - ofs << " | is 'nrxx'. The number of plane wave basis in reciprocal space is |" << std::endl; - ofs << " | different for charege/potential and wave functions. We also set |" << std::endl; - ofs << " | the 'sticks' for the parallel of FFT. The number of plane wave of |" << std::endl; - ofs << " | each k-point is 'npwk[ik]' in each processor |" << std::endl; - ofs << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; - ofs << "\n\n\n\n"; - ofs << "\n SETUP PLANE WAVES FOR WAVE FUNCTIONS" << std::endl; - double ecut = INPUT.ecutwfc; - if(std::abs(ecut-this->pw_wfc->gk_ecut * this->pw_wfc->tpiba2) > 1e-6) - { - ecut = this->pw_wfc->gk_ecut * this->pw_wfc->tpiba2; - ofs<<"Energy cutoff for wavefunc is incompatible with nx, ny, nz and it will be reduced!"<pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz); - ModuleBase::GlobalFunc::OUT(ofs,"number of plane waves",this->pw_wfc->npwtot); - ModuleBase::GlobalFunc::OUT(ofs,"number of sticks", this->pw_wfc->nstot); - - ofs << "\n PARALLEL PW FOR WAVE FUNCTIONS" << std::endl; - ofs <<" "<< std::setw(8) << "PROC"<< std::setw(15) << "COLUMNS(POT)"<< std::setw(15) << "PW" << std::endl; - for (int i = 0; i < GlobalV::NPROC_IN_POOL ; ++i) - { - ofs <<" "<pw_wfc->nst_per[i] << std::setw(15) << this->pw_wfc->npw_per[i] << std::endl; - } - ofs << " --------------- sum -------------------" << std::endl; - ofs << " " << std::setw(8) << GlobalV::NPROC_IN_POOL << std::setw(15) << this->pw_wfc->nstot << std::setw(15) << this->pw_wfc->npwtot << std::endl; - ModuleBase::GlobalFunc::DONE(ofs, "INIT PLANEWAVE"); - } - - template - void ESolver_KS::Run(const int istep, UnitCell& ucell) - { - if (!(GlobalV::CALCULATION == "scf" || GlobalV::CALCULATION == "md" - || GlobalV::CALCULATION == "relax" || GlobalV::CALCULATION == "cell-relax")) - { - this->othercalculation(istep); - } - else - { - ModuleBase::timer::tick(this->classname, "Run"); - - this->beforescf(istep); //Something else to do before the iter loop - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT SCF"); - if(this->maxniter > 0) this->printhead(); //print the headline on the screen. - - bool firstscf = true; - this->conv_elec = false; - this->niter = this->maxniter; - for (int iter = 1; iter <= this->maxniter; ++iter) - { - writehead(GlobalV::ofs_running, istep, iter); +} + +template +void ESolver_KS::init_after_vc(Input& inp, UnitCell& ucell) +{ + ModuleBase::TITLE("ESolver_KS", "init_after_vc"); + + ESolver_FP::init_after_vc(inp, ucell); + + if (GlobalV::md_prec_level == 2) + { + // initialize the real-space uniform grid for FFT and parallel + // distribution of plane waves + GlobalC::Pgrid.init(this->pw_rhod->nx, + this->pw_rhod->ny, + this->pw_rhod->nz, + this->pw_rhod->nplane, + this->pw_rhod->nrxx, + pw_big->nbz, + pw_big->bz); // mohan add 2010-07-22, update 2011-05-04 + + // Calculate Structure factor + this->sf.setup_structure_factor(&ucell, this->pw_rhod); + } +} + + +template +void ESolver_KS::hamilt2density(const int istep, const int iter, const double ethr) +{ + ModuleBase::timer::tick(this->classname, "hamilt2density"); + //Temporarily, before HSolver is constructed, it should be overrided by + //LCAO, PW, SDFT and TDDFT. + //After HSolver is constructed, LCAO, PW, SDFT should delete their own + //hamilt2density() and use: + //this->phsol->solve(this->phamilt, this->pes, this->wf, ETHR); + ModuleBase::timer::tick(this->classname, "hamilt2density"); +} + +template +void ESolver_KS::print_wfcfft(Input& inp, std::ofstream &ofs) +{ + ofs << "\n\n\n\n"; + ofs << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl; + ofs << " | |" << std::endl; + ofs << " | Setup plane waves of wave functions: |" << std::endl; + ofs << " | Use the energy cutoff and the lattice vectors to generate the |" << std::endl; + ofs << " | dimensions of FFT grid. The number of FFT grid on each processor |" << std::endl; + ofs << " | is 'nrxx'. The number of plane wave basis in reciprocal space is |" << std::endl; + ofs << " | different for charege/potential and wave functions. We also set |" << std::endl; + ofs << " | the 'sticks' for the parallel of FFT. The number of plane wave of |" << std::endl; + ofs << " | each k-point is 'npwk[ik]' in each processor |" << std::endl; + ofs << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; + ofs << "\n\n\n\n"; + ofs << "\n SETUP PLANE WAVES FOR WAVE FUNCTIONS" << std::endl; + double ecut = INPUT.ecutwfc; + if(std::abs(ecut-this->pw_wfc->gk_ecut * this->pw_wfc->tpiba2) > 1e-6) + { + ecut = this->pw_wfc->gk_ecut * this->pw_wfc->tpiba2; + ofs<<"Energy cutoff for wavefunc is incompatible with nx, ny, nz and it will be reduced!"<pw_wfc->nx,this->pw_wfc->ny,this->pw_wfc->nz); + ModuleBase::GlobalFunc::OUT(ofs,"number of plane waves",this->pw_wfc->npwtot); + ModuleBase::GlobalFunc::OUT(ofs,"number of sticks", this->pw_wfc->nstot); + + ofs << "\n PARALLEL PW FOR WAVE FUNCTIONS" << std::endl; + ofs <<" "<< std::setw(8) << "PROC"<< std::setw(15) << "COLUMNS(POT)"<< std::setw(15) << "PW" << std::endl; + for (int i = 0; i < GlobalV::NPROC_IN_POOL ; ++i) + { + ofs <<" "<pw_wfc->nst_per[i] + << std::setw(15) + << this->pw_wfc->npw_per[i] << std::endl; + } + ofs << " --------------- sum -------------------" << std::endl; + ofs << " " << std::setw(8) + << GlobalV::NPROC_IN_POOL + << std::setw(15) << this->pw_wfc->nstot + << std::setw(15) << this->pw_wfc->npwtot << std::endl; + ModuleBase::GlobalFunc::DONE(ofs, "INIT PLANEWAVE"); +} + +template +void ESolver_KS::Run(const int istep, UnitCell& ucell) +{ + if (!(GlobalV::CALCULATION == "scf" + || GlobalV::CALCULATION == "md" + || GlobalV::CALCULATION == "relax" + || GlobalV::CALCULATION == "cell-relax")) + { + this->othercalculation(istep); + } + else + { + ModuleBase::timer::tick(this->classname, "Run"); + + this->beforescf(istep); //Something else to do before the iter loop + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT SCF"); + if(this->maxniter > 0) + { + this->printhead(); //print the headline on the screen. + } + + bool firstscf = true; + this->conv_elec = false; + this->niter = this->maxniter; + for (int iter = 1; iter <= this->maxniter; ++iter) + { + writehead(GlobalV::ofs_running, istep, iter); #ifdef __MPI - auto iterstart = MPI_Wtime(); + auto iterstart = MPI_Wtime(); #else - auto iterstart = std::chrono::system_clock::now(); + auto iterstart = std::chrono::system_clock::now(); #endif - double diag_ethr = this->phsol->set_diagethr(istep, iter, drho); - eachiterinit(istep, iter); - this->hamilt2density(istep, iter, diag_ethr); - - // It may be changed when more clever parallel algorithm is put forward. - //When parallel algorithm for bands are adopted. Density will only be treated in the first group. - //(Different ranks should have abtained the same, but small differences always exist in practice.) - //Maybe in the future, density and wavefunctions should use different parallel algorithms, in which - //they do not occupy all processors, for example wavefunctions uses 20 processors while density uses 10. - if(GlobalV::MY_STOGROUP == 0) - { - // double drho = this->estate.caldr2(); - // EState should be used after it is constructed. - - drho = p_chgmix->get_drho(pelec->charge, GlobalV::nelec); - double hsolver_error = 0.0; - if (firstscf) - { - firstscf = false; - hsolver_error = this->phsol->cal_hsolerror(); - // The error of HSolver is larger than drho, so a more precise HSolver should be excuconv_elected. - if (hsolver_error > drho) - { - diag_ethr = this->phsol->reset_diagethr(GlobalV::ofs_running, hsolver_error, drho); - this->hamilt2density(istep, iter, diag_ethr); - drho = p_chgmix->get_drho(pelec->charge, GlobalV::nelec); - hsolver_error = this->phsol->cal_hsolerror(); - } - } - // mixing will restart at this->p_chgmix->mixing_restart steps - if (drho <= GlobalV::MIXING_RESTART && GlobalV::MIXING_RESTART > 0.0 && this->p_chgmix->mixing_restart > iter) - { - this->p_chgmix->mixing_restart = iter + 1; - } - // drho will be 0 at this->p_chgmix->mixing_restart step, which is not ground state - this->conv_elec = (drho < this->scf_thr && !(iter==this->p_chgmix->mixing_restart && GlobalV::MIXING_RESTART > 0.0)); - - // If drho < hsolver_error in the first iter or drho < scf_thr, we do not change rho. - if (drho < hsolver_error || this->conv_elec) - { - if (drho < hsolver_error) GlobalV::ofs_warning << " drho < hsolver_error, keep charge density unchanged." << std::endl; - } - else - { - //----------charge mixing--------------- - // mixing will restart after this->p_chgmix->mixing_restart steps - if (GlobalV::MIXING_RESTART > 0 && iter == this->p_chgmix->mixing_restart - 1) - { - // do not mix charge density - } - else - { - p_chgmix->mix_rho(pelec->charge); // update chr->rho by mixing - } - if (GlobalV::SCF_THR_TYPE == 2) pelec->charge->renormalize_rho(); // renormalize rho in R-space would induce a error in K-space - //----------charge mixing done----------- - } - } + double diag_ethr = this->phsol->set_diagethr(istep, iter, drho); + + eachiterinit(istep, iter); + + this->hamilt2density(istep, iter, diag_ethr); + + // It may be changed when more clever parallel algorithm is put forward. + //When parallel algorithm for bands are adopted. Density will only be treated in the first group. + //(Different ranks should have abtained the same, but small differences always exist in practice.) + //Maybe in the future, density and wavefunctions should use different parallel algorithms, in which + //they do not occupy all processors, for example wavefunctions uses 20 processors while density uses 10. + if(GlobalV::MY_STOGROUP == 0) + { + // double drho = this->estate.caldr2(); + // EState should be used after it is constructed. + + drho = p_chgmix->get_drho(pelec->charge, GlobalV::nelec); + double hsolver_error = 0.0; + if (firstscf) + { + firstscf = false; + hsolver_error = this->phsol->cal_hsolerror(); + // The error of HSolver is larger than drho, + // so a more precise HSolver should be excuconv_elected. + if (hsolver_error > drho) + { + diag_ethr = this->phsol->reset_diagethr(GlobalV::ofs_running, hsolver_error, drho); + this->hamilt2density(istep, iter, diag_ethr); + drho = p_chgmix->get_drho(pelec->charge, GlobalV::nelec); + hsolver_error = this->phsol->cal_hsolerror(); + } + } + // mixing will restart at this->p_chgmix->mixing_restart steps + if (drho <= GlobalV::MIXING_RESTART + && GlobalV::MIXING_RESTART > 0.0 + && this->p_chgmix->mixing_restart > iter) + { + this->p_chgmix->mixing_restart = iter + 1; + } + + // drho will be 0 at this->p_chgmix->mixing_restart step, which is not ground state + this->conv_elec = (drho < this->scf_thr + && !(iter==this->p_chgmix->mixing_restart + && GlobalV::MIXING_RESTART > 0.0)); + + // If drho < hsolver_error in the first iter or drho < scf_thr, we do not change rho. + if (drho < hsolver_error || this->conv_elec) + { + if (drho < hsolver_error) + { + GlobalV::ofs_warning << " drho < hsolver_error, keep charge density unchanged." << std::endl; + } + } + else + { + //----------charge mixing--------------- + // mixing will restart after this->p_chgmix->mixing_restart steps + if (GlobalV::MIXING_RESTART > 0 + && iter == this->p_chgmix->mixing_restart - 1) + { + // do not mix charge density + } + else + { + p_chgmix->mix_rho(pelec->charge); // update chr->rho by mixing + } + if (GlobalV::SCF_THR_TYPE == 2) + { + pelec->charge->renormalize_rho(); // renormalize rho in R-space would induce a error in K-space + } + //----------charge mixing done----------- + } + } #ifdef __MPI - MPI_Bcast(&drho, 1, MPI_DOUBLE , 0, PARAPW_WORLD); - MPI_Bcast(&this->conv_elec, 1, MPI_DOUBLE , 0, PARAPW_WORLD); - MPI_Bcast(pelec->charge->rho[0], this->pw_rhod->nrxx, MPI_DOUBLE, 0, PARAPW_WORLD); + MPI_Bcast(&drho, 1, MPI_DOUBLE , 0, PARAPW_WORLD); + MPI_Bcast(&this->conv_elec, 1, MPI_DOUBLE , 0, PARAPW_WORLD); + MPI_Bcast(pelec->charge->rho[0], this->pw_rhod->nrxx, MPI_DOUBLE, 0, PARAPW_WORLD); #endif - // Hamilt should be used after it is constructed. - // this->phamilt->update(conv_elec); - updatepot(istep, iter); - eachiterfinish(iter); + // Hamilt should be used after it is constructed. + // this->phamilt->update(conv_elec); + updatepot(istep, iter); + eachiterfinish(iter); #ifdef __MPI - double duration = (double)(MPI_Wtime() - iterstart); + double duration = (double)(MPI_Wtime() - iterstart); #else - double duration = (std::chrono::duration_cast(std::chrono::system_clock::now() - iterstart)).count() / static_cast(1e6); + double duration = (std::chrono::duration_cast(std::chrono::system_clock::now() - iterstart)).count() / static_cast(1e6); #endif - /* - SCF print: G1 -3.435545e+03 0.000000e+00 3.607e-01 2.862e-01 - */ - - double dkin = 0.0; // for meta-GGA - if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) - { - dkin = p_chgmix->get_dkin(pelec->charge, GlobalV::nelec); - } - printiter(iter, drho, dkin, duration, diag_ethr); - + /* + SCF print: G1 -3.435545e+03 0.000000e+00 3.607e-01 2.862e-01 + */ + + double dkin = 0.0; // for meta-GGA + if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) + { + dkin = p_chgmix->get_dkin(pelec->charge, GlobalV::nelec); + } + printiter(iter, drho, dkin, duration, diag_ethr); + #ifdef __RAPIDJSON - //add Json of scf mag - Json::add_output_scf_mag( - GlobalC::ucell.magnet.tot_magnetization, GlobalC::ucell.magnet.abs_magnetization, - this->pelec->f_en.etot * ModuleBase::Ry_to_eV, - this->pelec->f_en.etot_delta * ModuleBase::Ry_to_eV, - drho, - duration - ); + //add Json of scf mag + Json::add_output_scf_mag( + GlobalC::ucell.magnet.tot_magnetization, GlobalC::ucell.magnet.abs_magnetization, + this->pelec->f_en.etot * ModuleBase::Ry_to_eV, + this->pelec->f_en.etot_delta * ModuleBase::Ry_to_eV, + drho, + duration + ); #endif //__RAPIDJSON - - - if (this->conv_elec) - { - this->niter = iter; - bool stop = this->do_after_converge(iter); - if(stop) break; - } - // notice for restart - if (GlobalV::MIXING_RESTART > 0 && iter == this->p_chgmix->mixing_restart - 1 && iter != GlobalV::SCF_NMAX) - { - std::cout<<"SCF restart after this step!"<conv_elec) + { + this->niter = iter; + bool stop = this->do_after_converge(iter); + if(stop) break; + } + + // notice for restart + if (GlobalV::MIXING_RESTART > 0 + && iter == this->p_chgmix->mixing_restart - 1 + && iter != GlobalV::SCF_NMAX) + { + std::cout<<"SCF restart after this step!"<pelec->eferm.ef * ModuleBase::Ry_to_eV, - this->pelec->f_en.etot * ModuleBase::Ry_to_eV, - this->conv_elec - ); + //add Json of efermi energy converge + Json::add_output_efermi_energy_converge( + this->pelec->eferm.ef * ModuleBase::Ry_to_eV, + this->pelec->f_en.etot * ModuleBase::Ry_to_eV, + this->conv_elec + ); #endif //__RAPIDJSON - afterscf(istep); - ModuleBase::timer::tick(this->classname, "Run"); - } + afterscf(istep); + ModuleBase::timer::tick(this->classname, "Run"); + } #ifdef __RAPIDJSON - // add nkstot,nkstot_ibz to output json - int Jnkstot = this->pelec->klist->nkstot; - int Jnkstot_ibz = this->pelec->klist->nkstot_ibz; - Json::add_nkstot(Jnkstot,Jnkstot_ibz); + // add nkstot,nkstot_ibz to output json + int Jnkstot = this->pelec->klist->nkstot; + int Jnkstot_ibz = this->pelec->klist->nkstot_ibz; + Json::add_nkstot(Jnkstot,Jnkstot_ibz); #endif //__RAPIDJSON - return; - }; - - template - void ESolver_KS::printhead() - { - std::cout << " " << std::setw(7) << "ITER"; - if (GlobalV::NSPIN == 2) - { - std::cout << std::setw(10) << "TMAG"; - std::cout << std::setw(10) << "AMAG"; - } - std::cout << std::setw(15) << "ETOT(eV)"; - std::cout << std::setw(15) << "EDIFF(eV)"; - std::cout << std::setw(11) << "DRHO"; - if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) - { - std::cout << std::setw(11) << "DKIN"; - } - std::cout << std::setw(11) << "TIME(s)" << std::endl; - } - - template - void ESolver_KS::printiter(const int iter, const double drho, const double dkin, const double duration, const double ethr) - { + return; +}; + +template +void ESolver_KS::printhead() +{ + std::cout << " " << std::setw(7) << "ITER"; + if (GlobalV::NSPIN == 2) + { + std::cout << std::setw(10) << "TMAG"; + std::cout << std::setw(10) << "AMAG"; + } + std::cout << std::setw(15) << "ETOT(eV)"; + std::cout << std::setw(15) << "EDIFF(eV)"; + std::cout << std::setw(11) << "DRHO"; + if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) + { + std::cout << std::setw(11) << "DKIN"; + } + std::cout << std::setw(11) << "TIME(s)" << std::endl; +} + +template +void ESolver_KS::printiter( + const int iter, + const double drho, + const double dkin, + const double duration, + const double ethr) +{ this->pelec->print_etot(this->conv_elec, iter, drho, dkin, duration, INPUT.printe, ethr); - } - - template - void ESolver_KS::writehead(std::ofstream& ofs_running, const int istep, const int iter) - { - ofs_running - << "\n " - << this->basisname - << " ALGORITHM --------------- ION=" << std::setw(4) << istep + 1 - << " ELEC=" << std::setw(4) << iter - << "--------------------------------\n"; - } - - template - int ESolver_KS::getniter() - { - return this->niter; - } - - template - ModuleIO::Output_Rho ESolver_KS::create_Output_Rho(int is, int iter, const std::string& prefix) - { - int precision = 3; - std::string tag = "CHG"; - return ModuleIO::Output_Rho(this->pw_big, - this->pw_rhod, - is, - GlobalV::NSPIN, - pelec->charge->rho_save[is], - iter, - this->pelec->eferm.get_efval(is), - &(GlobalC::ucell), - GlobalV::global_out_dir, - precision, - tag, - prefix); - } - - template - ModuleIO::Output_Rho ESolver_KS::create_Output_Kin(int is, int iter, const std::string& prefix) - { - int precision = 11; - std::string tag = "TAU"; - return ModuleIO::Output_Rho(this->pw_big, - this->pw_rhod, - is, - GlobalV::NSPIN, - pelec->charge->kin_r_save[is], - iter, - this->pelec->eferm.get_efval(is), - &(GlobalC::ucell), - GlobalV::global_out_dir, - precision, - tag, - prefix); - } - - template - ModuleIO::Output_Potential ESolver_KS::create_Output_Potential(int iter, const std::string& prefix) - { - int precision = 3; - std::string tag = "POT"; - return ModuleIO::Output_Potential(this->pw_big, - this->pw_rhod, - GlobalV::NSPIN, - iter, - GlobalV::out_pot, - this->pelec->pot->get_effective_v(), - this->pelec->pot->get_fixed_v(), - &(GlobalC::ucell), - pelec->charge, - precision, - GlobalV::global_out_dir, - tag, - prefix); - } +} +template +void ESolver_KS::writehead(std::ofstream& ofs_running, const int istep, const int iter) +{ + ofs_running + << "\n " + << this->basisname + << " ALGORITHM --------------- ION=" << std::setw(4) << istep + 1 + << " ELEC=" << std::setw(4) << iter + << "--------------------------------\n"; +} + +template +int ESolver_KS::getniter() +{ + return this->niter; +} + + +template +ModuleIO::Output_Rho ESolver_KS::create_Output_Rho( + int is, + int iter, + const std::string& prefix) +{ + int precision = 3; + std::string tag = "CHG"; + return ModuleIO::Output_Rho(this->pw_big, + this->pw_rhod, + is, + GlobalV::NSPIN, + pelec->charge->rho_save[is], + iter, + this->pelec->eferm.get_efval(is), + &(GlobalC::ucell), + GlobalV::global_out_dir, + precision, + tag, + prefix); +} + +template +ModuleIO::Output_Rho ESolver_KS::create_Output_Kin(int is, int iter, const std::string& prefix) +{ + int precision = 11; + std::string tag = "TAU"; + return ModuleIO::Output_Rho(this->pw_big, + this->pw_rhod, + is, + GlobalV::NSPIN, + pelec->charge->kin_r_save[is], + iter, + this->pelec->eferm.get_efval(is), + &(GlobalC::ucell), + GlobalV::global_out_dir, + precision, + tag, + prefix); +} + + +template +ModuleIO::Output_Potential ESolver_KS::create_Output_Potential(int iter, const std::string& prefix) +{ + const int precision = 3; + std::string tag = "POT"; + return ModuleIO::Output_Potential(this->pw_big, + this->pw_rhod, + GlobalV::NSPIN, + iter, + GlobalV::out_pot, + this->pelec->pot->get_effective_v(), + this->pelec->pot->get_fixed_v(), + &(GlobalC::ucell), + pelec->charge, + precision, + GlobalV::global_out_dir, + tag, + prefix); +} template class ESolver_KS, psi::DEVICE_CPU>; @@ -615,4 +665,4 @@ template class ESolver_KS, psi::DEVICE_GPU>; #ifdef __LCAO template class ESolver_KS; #endif -} \ No newline at end of file +} diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index 3d9d80e69af..8432a432a9f 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -20,88 +20,111 @@ namespace ModuleESolver { - template - class ESolver_KS : public ESolver_FP - { - public: - ESolver_KS(); - virtual ~ESolver_KS(); - // HSolver* phsol; - double scf_thr; // scf threshold - double drho; // the difference between rho_in (before HSolver) and rho_out (After HSolver) - int maxniter; // maximum iter steps for scf - int niter; // iter steps actually used in scf - bool conv_elec; // If electron density is converged in scf. - int out_freq_elec;// frequency for output - virtual void Init(Input& inp, UnitCell& cell) override; - - virtual void init_after_vc(Input& inp, UnitCell& cell) override; // liuyu add 2023-03-09 - - virtual void Run(const int istep, UnitCell& cell) override; - - // calculate electron density from a specific Hamiltonian - virtual void hamilt2density(const int istep, const int iter, const double ethr); - - // calculate electron states from a specific Hamiltonian - virtual void hamilt2estates(const double ethr){}; - - // get current step of Ionic simulation - virtual int getniter() override; - - protected: - // Something to do before SCF iterations. - virtual void beforescf(int istep) {}; - // Something to do before hamilt2density function in each iter loop. - virtual void eachiterinit(const int istep, const int iter) {}; - // Something to do after hamilt2density function in each iter loop. - virtual void eachiterfinish(const int iter) {}; - // Something to do after SCF iterations when SCF is converged or comes to the max iter step. - virtual void afterscf(const int istep) {}; - // It should be replaced by a function in Hamilt Class - virtual void updatepot(const int istep, const int iter) {}; - // choose strategy when charge density convergence achieved - virtual bool do_after_converge(int& iter){return true;} - - //TOOLS: - protected: - // Print the headline on the screen: - // ITER ETOT(eV) EDIFF(eV) DRHO TIME(s) - void printhead(); - // Print inforamtion in each iter - // G1 -3.435545e+03 0.000000e+00 3.607e-01 2.862e-01 - // for metaGGA - // ITER ETOT(eV) EDIFF(eV) DRHO DKIN TIME(s) - // G1 -3.435545e+03 0.000000e+00 3.607e-01 3.522e-01 2.862e-01 - void printiter(const int iter, const double drho, const double dkin, const double duration, const double ethr); - // Write the headline in the running_log file - // "PW/LCAO" ALGORITHM --------------- ION= 1 ELEC= 1-------------------------------- - void writehead(std::ofstream& ofs_running, const int istep, const int iter); - - /// @brief create a new ModuleIO::Output_Rho object to output charge density - ModuleIO::Output_Rho create_Output_Rho(int is, int iter, const std::string& prefix="None"); - - /// @brief create a new ModuleIO::Output_Rho object to print kinetic energy density - ModuleIO::Output_Rho create_Output_Kin(int is, int iter, const std::string& prefix = "None"); - - /// @brief create a new ModuleIO::Output_Potential object to print potential - ModuleIO::Output_Potential create_Output_Potential(int iter, const std::string& prefix = "None"); - // TODO: control single precision at input files - - hsolver::HSolver* phsol = nullptr; - hamilt::Hamilt* p_hamilt = nullptr; - ModulePW::PW_Basis_K* pw_wfc = nullptr; - Charge_Mixing* p_chgmix = nullptr; - wavefunc wf; - Charge_Extra CE; - - // wavefunction coefficients - psi::Psi* psi = nullptr; - - protected: - std::string basisname; //PW or LCAO - protected: - void print_wfcfft(Input& inp, std::ofstream &ofs); - - }; -} +template +class ESolver_KS : public ESolver_FP +{ + public: + + //! Constructor + ESolver_KS(); + + //! Deconstructor + virtual ~ESolver_KS(); + + double scf_thr; // scf threshold + double drho; // the difference between rho_in (before HSolver) and rho_out (After HSolver) + int maxniter; // maximum iter steps for scf + int niter; // iter steps actually used in scf + bool conv_elec; // If electron density is converged in scf. + int out_freq_elec;// frequency for output + + virtual void Init(Input& inp, UnitCell& cell) override; + + virtual void init_after_vc(Input& inp, UnitCell& cell) override; // liuyu add 2023-03-09 + + virtual void Run(const int istep, UnitCell& cell) override; + + // calculate electron density from a specific Hamiltonian + virtual void hamilt2density(const int istep, const int iter, const double ethr); + + // calculate electron states from a specific Hamiltonian + virtual void hamilt2estates(const double ethr){}; + + // get current step of Ionic simulation + virtual int getniter() override; + + protected: + //! Something to do before SCF iterations. + virtual void beforescf(int istep) {}; + + //! Something to do before hamilt2density function in each iter loop. + virtual void eachiterinit(const int istep, const int iter) {}; + + //! Something to do after hamilt2density function in each iter loop. + virtual void eachiterfinish(const int iter) {}; + + //! Something to do after SCF iterations when SCF is converged or comes to the max iter step. + virtual void afterscf(const int istep) {}; + + //! It should be replaced by a function in Hamilt Class + virtual void updatepot(const int istep, const int iter) {}; + + //! choose strategy when charge density convergence achieved + virtual bool do_after_converge(int& iter){return true;} + + protected: + + // Print the headline on the screen: + // ITER ETOT(eV) EDIFF(eV) DRHO TIME(s) + void printhead(); + + // Print inforamtion in each iter + // G1 -3.435545e+03 0.000000e+00 3.607e-01 2.862e-01 + // for metaGGA + // ITER ETOT(eV) EDIFF(eV) DRHO DKIN TIME(s) + // G1 -3.435545e+03 0.000000e+00 3.607e-01 3.522e-01 2.862e-01 + void printiter(const int iter, const double drho, const double dkin, const double duration, const double ethr); + + + // Write the headline in the running_log file + // "PW/LCAO" ALGORITHM --------------- ION= 1 ELEC= 1-------------------------------- + void writehead(std::ofstream& ofs_running, const int istep, const int iter); + + /// @brief create a new ModuleIO::Output_Rho object to output charge density + ModuleIO::Output_Rho create_Output_Rho(int is, int iter, const std::string& prefix="None"); + + /// @brief create a new ModuleIO::Output_Rho object to print kinetic energy density + ModuleIO::Output_Rho create_Output_Kin(int is, int iter, const std::string& prefix = "None"); + + /// @brief create a new ModuleIO::Output_Potential object to print potential + ModuleIO::Output_Potential create_Output_Potential(int iter, const std::string& prefix = "None"); + + + // TODO: control single precision at input files + + //! Solve Hamitonian + hsolver::HSolver* phsol = nullptr; + + //! Hamiltonian + hamilt::Hamilt* p_hamilt = nullptr; + + ModulePW::PW_Basis_K* pw_wfc = nullptr; + + Charge_Mixing* p_chgmix = nullptr; + + wavefunc wf; + + Charge_Extra CE; + + // wavefunction coefficients + psi::Psi* psi = nullptr; + + protected: + + std::string basisname; //PW or LCAO + + void print_wfcfft(Input& inp, std::ofstream &ofs); +}; + +} // end of namespace #endif From f0a5c3b855f77ae0bb8ee577af9553d9e2ac0eaf Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 15:38:54 +0800 Subject: [PATCH 05/46] update esolver description for LCAO --- source/module_esolver/esolver_ks.cpp | 5 + source/module_esolver/esolver_ks.h | 1 - source/module_esolver/esolver_ks_lcao.cpp | 318 +++++++++++------- .../module_esolver/esolver_ks_lcao_elec.cpp | 4 +- source/module_esolver/esolver_ks_lcao_tddft.h | 2 +- 5 files changed, 204 insertions(+), 126 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 47ce415fe74..c0252444eed 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -656,12 +656,17 @@ ModuleIO::Output_Potential ESolver_KS::create_Output_Potential(int it } +//! This is for mixed-precision pw/LCAO basis sets. template class ESolver_KS, psi::DEVICE_CPU>; template class ESolver_KS, psi::DEVICE_CPU>; + +//! This is for GPU codes. #if ((defined __CUDA) || (defined __ROCM)) template class ESolver_KS, psi::DEVICE_GPU>; template class ESolver_KS, psi::DEVICE_GPU>; #endif + +//! This is for LCAO basis set. #ifdef __LCAO template class ESolver_KS; #endif diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index 8432a432a9f..9b2e898ce8d 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -99,7 +99,6 @@ class ESolver_KS : public ESolver_FP /// @brief create a new ModuleIO::Output_Potential object to print potential ModuleIO::Output_Potential create_Output_Potential(int iter, const std::string& prefix = "None"); - // TODO: control single precision at input files //! Solve Hamitonian diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index fc4d9d5619e..905ddea95a6 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -44,37 +44,41 @@ namespace ModuleESolver { - template - ESolver_KS_LCAO::ESolver_KS_LCAO() + + +template +ESolver_KS_LCAO::ESolver_KS_LCAO() { - this->classname = "ESolver_KS_LCAO"; - this->basisname = "LCAO"; + this->classname = "ESolver_KS_LCAO"; + this->basisname = "LCAO"; #ifdef __EXX - if (GlobalC::exx_info.info_ri.real_number) - { - this->exx_lri_double = std::make_shared>(GlobalC::exx_info.info_ri); - this->exd = std::make_shared>(this->exx_lri_double); - this->LM.Hexxd = &this->exd->get_Hexxs(); - } - else - { - this->exx_lri_complex = std::make_shared>>(GlobalC::exx_info.info_ri); - this->exc = std::make_shared>>(this->exx_lri_complex); - this->LM.Hexxc = &this->exc->get_Hexxs(); - } + if (GlobalC::exx_info.info_ri.real_number) + { + this->exx_lri_double = std::make_shared>(GlobalC::exx_info.info_ri); + this->exd = std::make_shared>(this->exx_lri_double); + this->LM.Hexxd = &this->exd->get_Hexxs(); + } + else + { + this->exx_lri_complex = std::make_shared>>(GlobalC::exx_info.info_ri); + this->exc = std::make_shared>>(this->exx_lri_complex); + this->LM.Hexxc = &this->exc->get_Hexxs(); + } #endif - } +} - template - ESolver_KS_LCAO::~ESolver_KS_LCAO() + +template +ESolver_KS_LCAO::~ESolver_KS_LCAO() { #ifndef USE_NEW_TWO_CENTER - this->orb_con.clear_after_ions(GlobalC::UOT, GlobalC::ORB, GlobalV::deepks_setorb, GlobalC::ucell.infoNL.nproj); + this->orb_con.clear_after_ions(GlobalC::UOT, GlobalC::ORB, GlobalV::deepks_setorb, GlobalC::ucell.infoNL.nproj); #endif } - template - void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) + +template +void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) { ModuleBase::TITLE("ESolver_KS_LCAO", "Init"); // if we are only calculating S, then there is no need @@ -104,6 +108,7 @@ namespace ModuleESolver // init ElecState // autoset nbands in ElecState, it should before basis_init (for Psi 2d divid) if (this->pelec == nullptr) + { this->pelec = new elecstate::ElecStateLCAO(&(this->chr), &(this->kv), this->kv.nks, @@ -112,6 +117,7 @@ namespace ModuleESolver &(this->LOWF), this->pw_rho, this->pw_big); + } //------------------init Basis_lcao---------------------- // Init Basis should be put outside of Ensolver. @@ -120,12 +126,13 @@ namespace ModuleESolver this->Init_Basis_lcao(this->orb_con, inp, ucell); //------------------init Basis_lcao---------------------- - // pass Hamilt-pointer to Operator + //! pass Hamilt-pointer to Operator this->UHM.genH.LM = this->UHM.LM = &this->LM; - // pass basis-pointer to EState and Psi + + //! pass basis-pointer to EState and Psi this->LOC.ParaV = this->LOWF.ParaV = this->LM.ParaV = &(this->orb_con.ParaV); - // init DensityMatrix + //! initialize DensityMatrix dynamic_cast*>(this->pelec)->init_DM(&this->kv, this->LM.ParaV, GlobalV::NSPIN); if (GlobalV::CALCULATION == "get_S") @@ -141,9 +148,9 @@ namespace ModuleESolver #ifdef __EXX // PLEASE simplify the Exx_Global interface - // mohan add 2021-03-25 - // Peize Lin 2016-12-03 - if (GlobalV::CALCULATION == "scf" || GlobalV::CALCULATION == "relax" || GlobalV::CALCULATION == "cell-relax" + if (GlobalV::CALCULATION == "scf" + || GlobalV::CALCULATION == "relax" + || GlobalV::CALCULATION == "cell-relax" || GlobalV::CALCULATION == "md") { if (GlobalC::exx_info.info_global.cal_exx) @@ -151,7 +158,9 @@ namespace ModuleESolver /* In the special "two-level" calculation case, first scf iteration only calculate the functional without exact exchange. but in "nscf" calculation, there is no need of "two-level" method. */ - if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "PBE0" || ucell.atoms[0].ncpp.xc_func == "HSE") + if (ucell.atoms[0].ncpp.xc_func == "HF" + || ucell.atoms[0].ncpp.xc_func == "PBE0" + || ucell.atoms[0].ncpp.xc_func == "HSE") { XC_Functional::set_xc_type("pbe"); } @@ -162,9 +171,13 @@ namespace ModuleESolver // GlobalC::exx_lcao.init(); if (GlobalC::exx_info.info_ri.real_number) + { this->exx_lri_double->init(MPI_COMM_WORLD, this->kv); + } else + { this->exx_lri_complex->init(MPI_COMM_WORLD, this->kv); + } } } #endif @@ -220,24 +233,24 @@ namespace ModuleESolver } } - template - void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) +template +void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) { - ESolver_KS::init_after_vc(inp, ucell); + ESolver_KS::init_after_vc(inp, ucell); if (GlobalV::md_prec_level == 2) - { - delete this->pelec; - this->pelec = new elecstate::ElecStateLCAO(&(this->chr), - &(this->kv), - this->kv.nks, - &(this->LOC), - &(this->UHM), - &(this->LOWF), - this->pw_rho, - this->pw_big); - dynamic_cast*>(this->pelec)->init_DM(&this->kv, this->LM.ParaV, GlobalV::NSPIN); - + { + delete this->pelec; + this->pelec = new elecstate::ElecStateLCAO(&(this->chr), + &(this->kv), + this->kv.nks, + &(this->LOC), + &(this->UHM), + &(this->LOWF), + this->pw_rho, + this->pw_big); + + dynamic_cast*>(this->pelec)->init_DM(&this->kv, this->LM.ParaV, GlobalV::NSPIN); GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, this->pw_rho); @@ -258,40 +271,47 @@ namespace ModuleESolver } } - template - double ESolver_KS_LCAO::cal_Energy() + +template +double ESolver_KS_LCAO::cal_Energy() { return this->pelec->f_en.etot; } - template - void ESolver_KS_LCAO::cal_Force(ModuleBase::matrix& force) + + +template +void ESolver_KS_LCAO::cal_Force(ModuleBase::matrix& force) { - Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); - FSL.getForceStress(GlobalV::CAL_FORCE, - GlobalV::CAL_STRESS, - GlobalV::TEST_FORCE, - GlobalV::TEST_STRESS, - this->LOC, - this->pelec, - this->psi, - this->UHM, - force, - this->scs, - this->sf, - this->kv, - this->pw_rho, + Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); + FSL.getForceStress(GlobalV::CAL_FORCE, + GlobalV::CAL_STRESS, + GlobalV::TEST_FORCE, + GlobalV::TEST_STRESS, + this->LOC, + this->pelec, + this->psi, + this->UHM, + force, + this->scs, + this->sf, + this->kv, + this->pw_rho, #ifdef __EXX - * this->exx_lri_double, - * this->exx_lri_complex, + * this->exx_lri_double, + * this->exx_lri_complex, #endif - & GlobalC::ucell.symm); - // delete RA after cal_Force - this->RA.delete_grid(); - this->have_force = true; + & GlobalC::ucell.symm); + + // delete RA after cal_Force + + this->RA.delete_grid(); + + this->have_force = true; } - template - void ESolver_KS_LCAO::cal_Stress(ModuleBase::matrix& stress) + +template +void ESolver_KS_LCAO::cal_Stress(ModuleBase::matrix& stress) { if (!this->have_force) { @@ -302,8 +322,9 @@ namespace ModuleESolver this->have_force = false; } - template - void ESolver_KS_LCAO::postprocess() + +template +void ESolver_KS_LCAO::postprocess() { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; GlobalV::ofs_running << std::setprecision(16); @@ -325,12 +346,14 @@ namespace ModuleESolver GlobalV::ofs_running << "\n\n\n\n"; } // qianrui modify 2020-10-18 - if (GlobalV::CALCULATION == "scf" || GlobalV::CALCULATION == "md" || GlobalV::CALCULATION == "relax") + if (GlobalV::CALCULATION == "scf" + || GlobalV::CALCULATION == "md" + || GlobalV::CALCULATION == "relax") { ModuleIO::write_istate_info(this->pelec->ekb, this->pelec->wg, this->kv, &(GlobalC::Pkpoints)); } - int nspin0 = (GlobalV::NSPIN == 2) ? 2 : 1; + const int nspin0 = (GlobalV::NSPIN == 2) ? 2 : 1; if (INPUT.out_band[0]) // pengfei 2014-10-13 { @@ -374,25 +397,26 @@ namespace ModuleESolver if (INPUT.out_dos) { - ModuleIO::out_dos_nao( - this->psi, - this->UHM, - this->pelec->ekb, - this->pelec->wg, - INPUT.dos_edelta_ev, - INPUT.dos_scale, - INPUT.dos_sigma, - *(this->pelec->klist), - GlobalC::Pkpoints, - GlobalC::ucell, - this->pelec->eferm, - GlobalV::NBANDS, - this->p_hamilt); - } + ModuleIO::out_dos_nao( + this->psi, + this->UHM, + this->pelec->ekb, + this->pelec->wg, + INPUT.dos_edelta_ev, + INPUT.dos_scale, + INPUT.dos_sigma, + *(this->pelec->klist), + GlobalC::Pkpoints, + GlobalC::ucell, + this->pelec->eferm, + GlobalV::NBANDS, + this->p_hamilt); + } } - template - void ESolver_KS_LCAO::Init_Basis_lcao(ORB_control& orb_con, Input& inp, UnitCell& ucell) + +template +void ESolver_KS_LCAO::Init_Basis_lcao(ORB_control& orb_con, Input& inp, UnitCell& ucell) { // autoset NB2D first if (GlobalV::NB2D == 0) @@ -490,8 +514,9 @@ namespace ModuleESolver } } - template - void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) + +template +void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) { if (iter == 1) { @@ -555,7 +580,9 @@ namespace ModuleESolver // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (GlobalV::NSPIN == 4) + { GlobalC::ucell.cal_ux(); + } this->pelec->pot->update_from_charge(this->pelec->charge, &GlobalC::ucell); this->pelec->f_en.descf = this->pelec->cal_delta_escf(); } @@ -564,9 +591,13 @@ namespace ModuleESolver #ifdef __EXX // calculate exact-exchange if (GlobalC::exx_info.info_ri.real_number) + { this->exd->exx_eachiterinit(*dynamic_cast*>(this->pelec)->get_DM(), iter); + } else + { this->exc->exx_eachiterinit(*dynamic_cast*>(this->pelec)->get_DM(), iter); + } #endif if (GlobalV::dft_plus_u) @@ -584,6 +615,7 @@ namespace ModuleESolver GlobalC::dftu.cal_slater_UJ(this->pelec->charge->rho, this->pw_rho->nrxx); // Calculate U and J if Yukawa potential is used } + #ifdef __DEEPKS // the density matrixes of DeePKS have been updated in each iter GlobalC::ld.set_hr_cal(true); @@ -613,8 +645,9 @@ namespace ModuleESolver } } - template - void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) + +template +void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) { // save input rho this->pelec->charge->save_rho_before_sum_band(); @@ -660,9 +693,13 @@ namespace ModuleESolver #ifdef __EXX if (GlobalC::exx_info.info_ri.real_number) + { this->exd->exx_hamilt2density(*this->pelec, *this->LOWF.ParaV, iter); + } else + { this->exc->exx_hamilt2density(*this->pelec, *this->LOWF.ParaV, iter); + } #endif // if DFT+U calculation is needed, this function will calculate @@ -674,7 +711,8 @@ namespace ModuleESolver { if (GlobalC::dftu.omc != 2) { - const std::vector>& tmp_dm = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); + const std::vector>& tmp_dm = + dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); this->dftu_cal_occup_m(iter, tmp_dm); } GlobalC::dftu.cal_energy_correction(istep); @@ -686,7 +724,8 @@ namespace ModuleESolver if (GlobalV::deepks_scf) { const Parallel_Orbitals* pv = this->LOWF.ParaV; - const std::vector>& dm = dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); + const std::vector>& dm = + dynamic_cast*>(this->pelec)->get_DM()->get_DMK_vector(); this->dpks_cal_e_delta_band(dm); } #endif @@ -717,8 +756,9 @@ namespace ModuleESolver this->pelec->f_en.deband = this->pelec->cal_delta_eband(); } - template - void ESolver_KS_LCAO::updatepot(const int istep, const int iter) + +template +void ESolver_KS_LCAO::updatepot(const int istep, const int iter) { // print Hamiltonian and Overlap matrix if (this->conv_elec) @@ -771,7 +811,9 @@ namespace ModuleESolver if (this->conv_elec) { if (elecstate::ElecStateLCAO::out_wfc_lcao) + { elecstate::ElecStateLCAO::out_wfc_flag = elecstate::ElecStateLCAO::out_wfc_lcao; + } for (int ik = 0; ik < this->kv.nks; ik++) { @@ -782,7 +824,9 @@ namespace ModuleESolver } } if (elecstate::ElecStateLCAO::out_wfc_lcao) + { elecstate::ElecStateLCAO::out_wfc_flag = 0; + } } // (9) Calculate new potential according to new Charge Density. @@ -796,7 +840,9 @@ namespace ModuleESolver if (!this->conv_elec) { if (GlobalV::NSPIN == 4) + { GlobalC::ucell.cal_ux(); + } this->pelec->pot->update_from_charge(this->pelec->charge, &GlobalC::ucell); this->pelec->f_en.descf = this->pelec->cal_delta_escf(); } @@ -806,8 +852,9 @@ namespace ModuleESolver } } - template - void ESolver_KS_LCAO::eachiterfinish(int iter) + +template +void ESolver_KS_LCAO::eachiterfinish(int iter) { // mix density matrix if (GlobalV::MIXING_RESTART > 0 && iter >= this->p_chgmix->mixing_restart && GlobalV::MIXING_DMR ) @@ -877,8 +924,9 @@ namespace ModuleESolver this->pelec->cal_energies(2); } - template - void ESolver_KS_LCAO::afterscf(const int istep) + +template +void ESolver_KS_LCAO::afterscf(const int istep) { // save charge difference into files for charge extrapolation if (GlobalV::CALCULATION != "scf") @@ -919,18 +967,24 @@ namespace ModuleESolver bool out_exc = true; // tmp, add parameter! if (GlobalV::out_mat_xc) + { ModuleIO::write_Vxc(GlobalV::NSPIN, GlobalV::NLOCAL, GlobalV::DRANK, *this->psi, GlobalC::ucell, this->sf, *this->pw_rho, *this->pw_rhod, GlobalC::ppcell.vloc, *this->pelec->charge, this->UHM, this->LM, this->LOC, this->kv, this->pelec->wg, GlobalC::GridD); + } #ifdef __EXX if (GlobalC::exx_info.info_global.cal_exx) // Peize Lin add if 2022.11.14 { const std::string file_name_exx = GlobalV::global_out_dir + "HexxR_" + std::to_string(GlobalV::MY_RANK); if (GlobalC::exx_info.info_ri.real_number) + { this->exd->write_Hexxs(file_name_exx); + } else + { this->exc->write_Hexxs(file_name_exx); + } } #endif @@ -1009,22 +1063,37 @@ namespace ModuleESolver } } - template - bool ESolver_KS_LCAO::do_after_converge(int& iter) + +template +bool ESolver_KS_LCAO::do_after_converge(int& iter) { #ifdef __EXX if (GlobalC::exx_info.info_ri.real_number) - return this->exd->exx_after_converge(*this->p_hamilt, this->LM, *dynamic_cast*>(this->pelec)->get_DM(), this->kv, iter); - else - return this->exc->exx_after_converge(*this->p_hamilt, this->LM, *dynamic_cast*>(this->pelec)->get_DM(), this->kv, iter); + { + return this->exd->exx_after_converge( + *this->p_hamilt, + this->LM, + *dynamic_cast*>(this->pelec)->get_DM(), + this->kv, + iter); + } + else + { + return this->exc->exx_after_converge(*this->p_hamilt, + this->LM, + *dynamic_cast*>(this->pelec)->get_DM(), + this->kv, + iter); + } #endif // __EXX return true; } - template - ModuleIO::Output_DM ESolver_KS_LCAO::create_Output_DM(int is, int iter) + +template +ModuleIO::Output_DM ESolver_KS_LCAO::create_Output_DM(int is, int iter) { - int precision = 3; + const int precision = 3; return ModuleIO::Output_DM(this->GridT, is, @@ -1038,16 +1107,18 @@ namespace ModuleESolver GlobalV::GAMMA_ONLY_LOCAL); } - template - ModuleIO::Output_DM1 ESolver_KS_LCAO::create_Output_DM1(int istep) + +template +ModuleIO::Output_DM1 ESolver_KS_LCAO::create_Output_DM1(int istep) { const elecstate::DensityMatrix,double>* DM = dynamic_cast>*>(this->pelec)->get_DM(); return ModuleIO::Output_DM1(GlobalV::NSPIN, istep, this->LOC, this->RA, this->kv, DM); } - template - ModuleIO::Output_Mat_Sparse ESolver_KS_LCAO::create_Output_Mat_Sparse(int istep) + +template +ModuleIO::Output_Mat_Sparse ESolver_KS_LCAO::create_Output_Mat_Sparse(int istep) { return ModuleIO::Output_Mat_Sparse(hsolver::HSolverLCAO::out_mat_hsR, hsolver::HSolverLCAO::out_mat_dh, @@ -1062,8 +1133,9 @@ namespace ModuleESolver this->p_hamilt); } - template - bool ESolver_KS_LCAO::md_skip_out(std::string calculation, int istep, int interval) + +template +bool ESolver_KS_LCAO::md_skip_out(std::string calculation, int istep, int interval) { if (calculation == "md") { @@ -1072,9 +1144,11 @@ namespace ModuleESolver return true; } } - return false; - } - template class ESolver_KS_LCAO; - template class ESolver_KS_LCAO, double>; - template class ESolver_KS_LCAO, std::complex>; + return false; +} + + +template class ESolver_KS_LCAO; +template class ESolver_KS_LCAO, double>; +template class ESolver_KS_LCAO, std::complex>; } // namespace ModuleESolver diff --git a/source/module_esolver/esolver_ks_lcao_elec.cpp b/source/module_esolver/esolver_ks_lcao_elec.cpp index 5c4fee6a4bc..46a377a6e4d 100644 --- a/source/module_esolver/esolver_ks_lcao_elec.cpp +++ b/source/module_esolver/esolver_ks_lcao_elec.cpp @@ -101,8 +101,8 @@ void ESolver_KS_LCAO::beforesolver(const int istep) // init psi if (this->psi == nullptr) { - int nsk; - int ncol; + int nsk=0; + int ncol=0; if (GlobalV::GAMMA_ONLY_LOCAL) { nsk = GlobalV::NSPIN; diff --git a/source/module_esolver/esolver_ks_lcao_tddft.h b/source/module_esolver/esolver_ks_lcao_tddft.h index 090e804b540..eaf785ae924 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.h +++ b/source/module_esolver/esolver_ks_lcao_tddft.h @@ -14,7 +14,7 @@ namespace ModuleESolver { - class ESolver_KS_LCAO_TDDFT : public ESolver_KS_LCAO, double> +class ESolver_KS_LCAO_TDDFT : public ESolver_KS_LCAO, double> { public: ESolver_KS_LCAO_TDDFT(); From 1c8ed86c072fa801af34cc79d250e1b300649838 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 19:42:12 +0800 Subject: [PATCH 06/46] update some formats of esolver codes --- .../module_esolver/esolver_ks_lcao_elec.cpp | 9 +- source/module_esolver/esolver_ks_pw.cpp | 113 ++++++++++++++---- source/module_io/write_proj_band_lcao.cpp | 4 + 3 files changed, 101 insertions(+), 25 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao_elec.cpp b/source/module_esolver/esolver_ks_lcao_elec.cpp index 46a377a6e4d..e16774c6f13 100644 --- a/source/module_esolver/esolver_ks_lcao_elec.cpp +++ b/source/module_esolver/esolver_ks_lcao_elec.cpp @@ -264,9 +264,12 @@ void ESolver_KS_LCAO::beforesolver(const int istep) //========================================================= // cal_ux should be called before init_scf because // the direction of ux is used in noncoline_rho - //========================================================= - if(GlobalV::NSPIN == 4 && GlobalV::DOMAG) GlobalC::ucell.cal_ux(); - ModuleBase::timer::tick("ESolver_KS_LCAO", "beforesolver"); + //========================================================= + if(GlobalV::NSPIN == 4 && GlobalV::DOMAG) + { + GlobalC::ucell.cal_ux(); + } + ModuleBase::timer::tick("ESolver_KS_LCAO", "beforesolver"); } template diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index 5ed1ac842b2..a22b57f4167 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -125,7 +125,9 @@ void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) // issue or pull request. if (this->psi != nullptr) + { delete this->psi; + } // allocate memory for std::complex datatype psi // New psi initializer in ABACUS, Developer's note: @@ -191,13 +193,16 @@ void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) } // --------------------------------------------------------------------------------- - this->kspw_psi = GlobalV::device_flag == "gpu" || GlobalV::precision_flag == "single" + this->kspw_psi = GlobalV::device_flag == "gpu" + || GlobalV::precision_flag == "single" ? new psi::Psi(this->psi[0]) : reinterpret_cast*>(this->psi); + if (GlobalV::precision_flag == "single") { ModuleBase::Memory::record("Psi_single", sizeof(T) * this->psi[0].size()); } + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT BASIS"); } @@ -225,8 +230,10 @@ void ESolver_KS_PW::Init(Input& inp, UnitCell& ucell) this->pw_big); } - // Inititlize the charge density. + //! Inititlize the charge density. this->pelec->charge->allocate(GlobalV::NSPIN); + + //! set the cell volume variable in pelec this->pelec->omega = GlobalC::ucell.omega; // Initialize the potential. @@ -276,7 +283,9 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) #endif this->pw_wfc->setuptransform(); for (int ik = 0; ik < this->kv.nks; ++ik) + { this->kv.ngk[ik] = this->pw_wfc->npwk[ik]; + } this->pw_wfc->collect_local_pw(inp.erf_ecut, inp.erf_height, inp.erf_sigma); delete this->phsol; @@ -317,7 +326,9 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) this->pw_wfc->nx, this->pw_wfc->ny, this->pw_wfc->nz); + this->pw_wfc->initparameters(false, INPUT.ecutwfc, this->kv.nks, this->kv.kvec_d.data()); + this->pw_wfc->collect_local_pw(inp.erf_ecut, inp.erf_height, inp.erf_sigma); if(GlobalV::psi_initializer) // new initialization method, used in KSDFT and LCAO_IN_PW calculation @@ -326,8 +337,12 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) // for nao, we recalculate the overlap matrix between flz and jlq // for atomic, we recalculate the overlap matrix between pswfc and jlq // for psig is not read-only, its value will be overwritten in initialize_psi(), dont need delete and reallocate - if((GlobalV::init_wfc.substr(0, 3) == "nao")||(GlobalV::init_wfc.substr(0, 6) == "atomic")) this->psi_init->tabulate(); - } + if((GlobalV::init_wfc.substr(0, 3) == "nao") + ||(GlobalV::init_wfc.substr(0, 6) == "atomic")) + { + this->psi_init->tabulate(); + } + } else // old initialization method, used in EXX calculation { this->wf.init_after_vc(this->kv.nks); // reallocate wanf2, the planewave expansion of lcao @@ -344,7 +359,10 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) this->pw_wfc->startz,this->pw_wfc->numz); #ifdef __MPI - if(GlobalV::RANK_IN_POOL == 0) GlobalC::paw_cell.prepare_paw(); + if(GlobalV::RANK_IN_POOL == 0) + { + GlobalC::paw_cell.prepare_paw(); + } #else GlobalC::paw_cell.prepare_paw(); #endif @@ -360,7 +378,11 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) { - GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); + GlobalC::paw_cell.set_rhoij(iat, + nrhoijsel[iat], + rhoijselect[iat].size(), + rhoijselect[iat].data(), + rhoijp[iat].data()); } } #else @@ -368,8 +390,12 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) { - GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); - } + GlobalC::paw_cell.set_rhoij(iat, + nrhoijsel[iat], + rhoijselect[iat].size(), + rhoijselect[iat].data(), + rhoijp[iat].data()); + } #endif } #endif @@ -424,14 +450,20 @@ void ESolver_KS_PW::beforescf(int istep) // calculate ewald energy if (!GlobalV::test_skip_ewald) { - this->pelec->f_en.ewald_energy = H_Ewald_pw::compute_ewald(GlobalC::ucell, this->pw_rhod, this->sf.strucFac); - } + this->pelec->f_en.ewald_energy = H_Ewald_pw::compute_ewald( + GlobalC::ucell, + this->pw_rhod, + this->sf.strucFac); + } //========================================================= // cal_ux should be called before init_scf because // the direction of ux is used in noncoline_rho //========================================================= - if(GlobalV::NSPIN == 4 && GlobalV::DOMAG) GlobalC::ucell.cal_ux(); + if(GlobalV::NSPIN == 4 && GlobalV::DOMAG) + { + GlobalC::ucell.cal_ux(); + } //========================================================= // calculate the total local pseudopotential in real space @@ -442,14 +474,18 @@ void ESolver_KS_PW::beforescf(int istep) Symmetry_rho srho; for (int is = 0; is < GlobalV::NSPIN; is++) { - srho.begin(is, *(this->pelec->charge), this->pw_rhod, GlobalC::Pgrid, GlobalC::ucell.symm); - } - + srho.begin(is, + *(this->pelec->charge), + this->pw_rhod, + GlobalC::Pgrid, + GlobalC::ucell.symm); + } // liuyu move here 2023-10-09 // D in uspp need vloc, thus behind init_scf() // calculate the effective coefficient matrix for non-local pseudopotential projectors ModuleBase::matrix veff = this->pelec->pot->get_effective_v(); + GlobalC::ppcell.cal_effective_D(veff, this->pw_rhod, GlobalC::ucell); // after init_rho (in pelec->init_scf), we have rho now. @@ -461,7 +497,11 @@ void ESolver_KS_PW::beforescf(int istep) // psi every time before scf. But for random wavefunction, we dont, because random wavefunction is not // related to atomic coordinates. // What the old strategy does is only to initialize for once... - if(((GlobalV::init_wfc == "random")&&(istep == 0))||(GlobalV::init_wfc != "random")) this->initialize_psi(); + if(((GlobalV::init_wfc == "random")&&(istep == 0)) + ||(GlobalV::init_wfc != "random")) + { + this->initialize_psi(); + } } } @@ -537,13 +577,42 @@ void ESolver_KS_PW::allocate_psi_init() // under restriction of C++11, std::unique_ptr can not be allocate via std::make_unique // use new instead, but will cause asymmetric allocation and deallocation, in literal aspect ModuleBase::timer::tick("ESolver_KS_PW", "allocate_psi_init"); - if((GlobalV::init_wfc.substr(0, 6) == "atomic")&&(GlobalC::ucell.natomwfc == 0)) this->psi_init = std::unique_ptr>(new psi_initializer_random()); - else if(GlobalV::init_wfc == "atomic") this->psi_init = std::unique_ptr>(new psi_initializer_atomic()); - else if(GlobalV::init_wfc == "random") this->psi_init = std::unique_ptr>(new psi_initializer_random()); - else if(GlobalV::init_wfc == "nao") this->psi_init = std::unique_ptr>(new psi_initializer_nao()); - else if(GlobalV::init_wfc == "atomic+random") this->psi_init = std::unique_ptr>(new psi_initializer_atomic_random()); - else if(GlobalV::init_wfc == "nao+random") this->psi_init = std::unique_ptr>(new psi_initializer_nao_random()); - else ModuleBase::WARNING_QUIT("ESolver_KS_PW::allocate_psi_init", "for new psi initializer, init_wfc type not supported"); + if((GlobalV::init_wfc.substr(0, 6) == "atomic")&&(GlobalC::ucell.natomwfc == 0)) + { + this->psi_init = std::unique_ptr>( + new psi_initializer_random()); + } + else if(GlobalV::init_wfc == "atomic") + { + this->psi_init = std::unique_ptr>( + new psi_initializer_atomic()); + } + else if(GlobalV::init_wfc == "random") + { + this->psi_init = std::unique_ptr>( + new psi_initializer_random()); + } + else if(GlobalV::init_wfc == "nao") + { + this->psi_init = std::unique_ptr>( + new psi_initializer_nao()); + } + else if(GlobalV::init_wfc == "atomic+random") + { + this->psi_init = std::unique_ptr>( + new psi_initializer_atomic_random()); + } + else if(GlobalV::init_wfc == "nao+random") + { + this->psi_init = std::unique_ptr>( + new psi_initializer_nao_random()); + } + else + { + ModuleBase::WARNING_QUIT("ESolver_KS_PW::allocate_psi_init", + "for new psi initializer, init_wfc type not supported"); + } + // function polymorphism is moved from constructor to function initialize. Two slightly different implementation are for MPI and serial case, respectively. #ifdef __MPI this->psi_init->initialize(&this->sf, this->pw_wfc, &GlobalC::ucell, &GlobalC::Pkpoints, 1, &GlobalC::ppcell, GlobalV::MY_RANK); diff --git a/source/module_io/write_proj_band_lcao.cpp b/source/module_io/write_proj_band_lcao.cpp index c77de39cc90..71b37de8e0d 100644 --- a/source/module_io/write_proj_band_lcao.cpp +++ b/source/module_io/write_proj_band_lcao.cpp @@ -285,9 +285,13 @@ void ModuleIO::write_proj_band_lcao( out << "" << std::endl; out << "" << GlobalV::NSPIN << "" << std::endl; if (GlobalV::NSPIN == 4) + { out << "" << std::setw(2) << GlobalV::NLOCAL / 2 << "" << std::endl; + } else + { out << "" << std::setw(2) << GlobalV::NLOCAL << "" << std::endl; + } out << "" << std::endl; for (int ik = 0; ik < nks; ik++) From ea0e2c45f71204f34efc72c5b986fc24ea1e4b31 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 21:35:14 +0800 Subject: [PATCH 07/46] update esolver_ks_pw.cpp formats --- source/module_esolver/esolver_ks_pw.cpp | 343 ++++++++++++++++-------- 1 file changed, 235 insertions(+), 108 deletions(-) diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index a22b57f4167..c69a8b424ea 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -635,22 +635,31 @@ void ESolver_KS_PW::initialize_psi() { for (int ik = 0; ik < this->pw_wfc->nks; ik++) { - // fix the wavefunction to initialize at given kpoint + //! Fix the wavefunction to initialize at given kpoint this->psi->fix_k(ik); - // update Hamiltonian from other kpoint to the given one + + //! Update Hamiltonian from other kpoint to the given one this->p_hamilt->updateHk(ik); - // project atomic orbitals on |k+G> planewave basis, where k is wavevector of kpoint - // and G is wavevector of the peroiodic part of the Bloch function + + //! Project atomic orbitals on |k+G> planewave basis, where k is wavevector of kpoint + //! and G is wavevector of the peroiodic part of the Bloch function this->psi_init->proj_ao_onkG(ik); - // psi_initializer manages memory of psig with shared pointer, - // its access to use is shared here via weak pointer - // therefore once the psi_initializer is destructed, psig will be destructed, too - // this way, we can avoid memory leak and undefined behavior + + //! psi_initializer manages memory of psig with shared pointer, + //! its access to use is shared here via weak pointer + //! therefore once the psi_initializer is destructed, psig will be destructed, too + //! this way, we can avoid memory leak and undefined behavior std::weak_ptr> psig = this->psi_init->share_psig(); - if(psig.expired()) ModuleBase::WARNING_QUIT("ESolver_KS_PW::initialize_psi", "psig lifetime is expired"); - // to use psig, we need to lock it to get a shared pointer version, - // then switch kpoint of psig to the given one + + if(psig.expired()) + { + ModuleBase::WARNING_QUIT("ESolver_KS_PW::initialize_psi", "psig lifetime is expired"); + } + + //! to use psig, we need to lock it to get a shared pointer version, + //! then switch kpoint of psig to the given one auto psig_ = psig.lock(); psig_->fix_k(ik); + std::vector etatom(psig_->get_nbands(), 0.0); // then adjust dimension from psig to psi @@ -664,14 +673,21 @@ void ESolver_KS_PW::initialize_psi() {// the following function is only run serially, to be improved hsolver::DiagoIterAssist::diagH_subspace_init( this->p_hamilt, - psig_->get_pointer(), psig_->get_nbands(), psig_->get_nbasis(), - *(this->kspw_psi), etatom.data() - ); + psig_->get_pointer(), + psig_->get_nbands(), + psig_->get_nbasis(), + *(this->kspw_psi), + etatom.data() + ); continue; } - else if ((GlobalV::KS_SOLVER == "lapack") && (GlobalV::BASIS_TYPE == "lcao_in_pw")) - { - if(ik == 0) GlobalV::ofs_running << " START WAVEFUNCTION: LCAO_IN_PW, psi initialization skipped " << std::endl; + else if ((GlobalV::KS_SOLVER == "lapack") + && (GlobalV::BASIS_TYPE == "lcao_in_pw")) + { + if(ik == 0) + { + GlobalV::ofs_running << " START WAVEFUNCTION: LCAO_IN_PW, psi initialization skipped " << std::endl; + } continue; } // else the case is davidson @@ -680,10 +696,12 @@ void ESolver_KS_PW::initialize_psi() { if (GlobalV::KS_SOLVER == "cg") { - hsolver::DiagoIterAssist::diagH_subspace( - this->p_hamilt, - *(psig_), *(this->kspw_psi), etatom.data() - ); + hsolver::DiagoIterAssist::diagH_subspace( + this->p_hamilt, + *(psig_), + *(this->kspw_psi), + etatom.data() + ); continue; } // else the case is davidson @@ -702,11 +720,13 @@ void ESolver_KS_PW::initialize_psi() ModuleBase::timer::tick("ESolver_KS_PW", "initialize_psi"); } + // Temporary, it should be replaced by hsolver later. template void ESolver_KS_PW::hamilt2density(const int istep, const int iter, const double ethr) { ModuleBase::timer::tick("ESolver_KS_PW", "hamilt2density"); + if (this->phsol != nullptr) { // reset energy @@ -731,8 +751,12 @@ void ESolver_KS_PW::hamilt2density(const int istep, const int iter, c // What the old strategy does is only to initialize for once... we also initialize only once here because // this can save a lot of time. But if cell and ion change significantly, re-initialization psi will be - // more efficient. Or an extrapolation strategy can be used. - if((istep == 0)&&(iter == 1)&&!(this->psi_init->initialized())) this->initialize_psi(); + // more efficient. Or an extrapolation strategy can be used. + if((istep == 0)&&(iter == 1) + &&!(this->psi_init->initialized())) + { + this->initialize_psi(); + } } if(GlobalV::BASIS_TYPE != "lcao_in_pw") { @@ -748,8 +772,13 @@ void ESolver_KS_PW::hamilt2density(const int istep, const int iter, c // multiple inheritance and polymorphism. But for now, we just do it in this way. // In the future, there will be a series of class ESolver_KS_LCAO_PW, HSolver_LCAO_PW and so on. std::weak_ptr> psig = this->psi_init->share_psig(); - if(psig.expired()) ModuleBase::WARNING_QUIT("ESolver_KS_PW::hamilt2density", "psig lifetime is expired"); - // from HSolverPW + + if(psig.expired()) + { + ModuleBase::WARNING_QUIT("ESolver_KS_PW::hamilt2density", "psig lifetime is expired"); + } + + // from HSolverPW this->phsol->solve(this->p_hamilt, // hamilt::Hamilt* pHamilt, this->kspw_psi[0], // psi::Psi& psi, this->pelec, // elecstate::ElecState* pelec, @@ -757,9 +786,15 @@ void ESolver_KS_PW::hamilt2density(const int istep, const int iter, c } if (GlobalV::out_bandgap) { - if (!GlobalV::TWO_EFERMI) this->pelec->cal_bandgap(); - else this->pelec->cal_bandgap_updw(); - } + if (!GlobalV::TWO_EFERMI) + { + this->pelec->cal_bandgap(); + } + else + { + this->pelec->cal_bandgap_updw(); + } + } } else { @@ -795,15 +830,18 @@ void ESolver_KS_PW::hamilt2density(const int istep, const int iter, c ModuleBase::timer::tick("ESolver_KS_PW", "hamilt2density"); } + // Temporary, it should be rewritten with Hamilt class. template void ESolver_KS_PW::updatepot(const int istep, const int iter) { if (!this->conv_elec) { - if (GlobalV::NSPIN == 4) - GlobalC::ucell.cal_ux(); - this->pelec->pot->update_from_charge(this->pelec->charge, &GlobalC::ucell); + if (GlobalV::NSPIN == 4) + { + GlobalC::ucell.cal_ux(); + } + this->pelec->pot->update_from_charge(this->pelec->charge, &GlobalC::ucell); this->pelec->f_en.descf = this->pelec->cal_delta_escf(); } else @@ -812,6 +850,7 @@ void ESolver_KS_PW::updatepot(const int istep, const int iter) } } + template void ESolver_KS_PW::eachiterfinish(const int iter) { @@ -859,6 +898,7 @@ void ESolver_KS_PW::eachiterfinish(const int iter) } } + template void ESolver_KS_PW::afterscf(const int istep) { @@ -896,6 +936,7 @@ void ESolver_KS_PW::afterscf(const int istep) } ModuleIO::output_convergence_after_scf(this->conv_elec, this->pelec->f_en.etot); + ModuleIO::output_efermi(this->conv_elec, this->pelec->eferm.ef); if (GlobalV::OUT_LEVEL != "m") @@ -964,12 +1005,14 @@ void ESolver_KS_PW::afterscf(const int istep) } } + template double ESolver_KS_PW::cal_Energy() { return this->pelec->f_en.etot; } + template void ESolver_KS_PW::cal_Force(ModuleBase::matrix& force) { @@ -982,9 +1025,19 @@ void ESolver_KS_PW::cal_Force(ModuleBase::matrix& force) ? new psi::Psi, Device>(this->kspw_psi[0]) : reinterpret_cast, Device>*>(this->kspw_psi); } - ff.cal_force(force, *this->pelec, this->pw_rhod, &GlobalC::ucell.symm, &this->sf, &this->kv, this->pw_wfc, this->__kspw_psi); + + //! Calculate forces + ff.cal_force(force, + *this->pelec, + this->pw_rhod, + &GlobalC::ucell.symm, + &this->sf, + &this->kv, + this->pw_wfc, + this->__kspw_psi); } + template void ESolver_KS_PW::cal_Stress(ModuleBase::matrix& stress) { @@ -993,24 +1046,24 @@ void ESolver_KS_PW::cal_Stress(ModuleBase::matrix& stress) this->__kspw_psi = nullptr; if (this->__kspw_psi == nullptr) { - this->__kspw_psi = GlobalV::precision_flag == "single" - ? new psi::Psi, Device>(this->kspw_psi[0]) - : reinterpret_cast, Device>*>(this->kspw_psi); - } - ss.cal_stress(stress, - GlobalC::ucell, - this->pw_rhod, - &GlobalC::ucell.symm, - &this->sf, - &this->kv, - this->pw_wfc, - this->psi, - this->__kspw_psi); - - // external stress - double unit_transform = 0.0; - unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; - double external_stress[3] = {GlobalV::PRESS1, GlobalV::PRESS2, GlobalV::PRESS3}; + this->__kspw_psi = GlobalV::precision_flag == "single" + ? new psi::Psi, Device>(this->kspw_psi[0]) + : reinterpret_cast, Device>*>(this->kspw_psi); + } + ss.cal_stress(stress, + GlobalC::ucell, + this->pw_rhod, + &GlobalC::ucell.symm, + &this->sf, + &this->kv, + this->pw_wfc, + this->psi, + this->__kspw_psi); + + // external stress + double unit_transform = 0.0; + unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; + double external_stress[3] = {GlobalV::PRESS1, GlobalV::PRESS2, GlobalV::PRESS3}; for (int i = 0; i < 3; i++) { stress(i, i) -= external_stress[i] / unit_transform; @@ -1018,8 +1071,9 @@ void ESolver_KS_PW::cal_Stress(ModuleBase::matrix& stress) GlobalV::PRESSURE = (stress(0, 0) + stress(1, 1) + stress(2, 2)) / 3; } + template -void ESolver_KS_PW::postprocess() +void ESolver_KS_PW::postprocess(void) { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; @@ -1036,17 +1090,21 @@ void ESolver_KS_PW::postprocess() GlobalV::ofs_running << " | DOS (density of states) and bands will be output here. |" << std::endl; GlobalV::ofs_running << " | If atomic orbitals are used, Mulliken charge analysis can be done. |" << std::endl; GlobalV::ofs_running << " | Also the .bxsf file containing fermi surface information can be |" << std::endl; - GlobalV::ofs_running << " | done here. |" << std::endl; - GlobalV::ofs_running << " | |" << std::endl; - GlobalV::ofs_running << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; - GlobalV::ofs_running << "\n\n\n\n"; - } - int nspin0 = 1; - if (GlobalV::NSPIN == 2) - nspin0 = 2; - // print occupation in istate.info - ModuleIO::write_istate_info(this->pelec->ekb, this->pelec->wg, this->kv, &(GlobalC::Pkpoints)); - // compute density of states + GlobalV::ofs_running << " | done here. |" << std::endl; + GlobalV::ofs_running << " | |" << std::endl; + GlobalV::ofs_running << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; + GlobalV::ofs_running << "\n\n\n\n"; + } + + int nspin0 = 1; + if (GlobalV::NSPIN == 2) + { + nspin0 = 2; + } + //! print occupation in istate.info + ModuleIO::write_istate_info(this->pelec->ekb, this->pelec->wg, this->kv, &(GlobalC::Pkpoints)); + + //! compute density of states if (INPUT.out_dos) { ModuleIO::write_dos_pw(this->pelec->ekb, @@ -1061,14 +1119,19 @@ void ESolver_KS_PW::postprocess() GlobalV::ofs_running << " Fermi energy is " << this->pelec->eferm.ef << " Rydberg" << std::endl; } else if (nspin0 == 2) - { - GlobalV::ofs_running << " Fermi energy (spin = 1) is " << this->pelec->eferm.ef_up << " Rydberg" - << std::endl; - GlobalV::ofs_running << " Fermi energy (spin = 2) is " << this->pelec->eferm.ef_dw << " Rydberg" - << std::endl; - } + { + GlobalV::ofs_running << " Fermi energy (spin = 1) is " + << this->pelec->eferm.ef_up + << " Rydberg" + << std::endl; + GlobalV::ofs_running << " Fermi energy (spin = 2) is " + << this->pelec->eferm.ef_dw + << " Rydberg" + << std::endl; + } } + if (INPUT.out_band[0]) // pengfei 2014-10-13 { int nks = 0; @@ -1097,6 +1160,7 @@ void ESolver_KS_PW::postprocess() } } + if (GlobalV::BASIS_TYPE == "pw" && winput::out_spillage) // xiaohui add 2013-09-01 { // std::cout << "\n Output Spillage Information : " << std::endl; @@ -1130,7 +1194,7 @@ void ESolver_KS_PW::postprocess() */ #endif - // output overlap + // ! Print out overlap before spillage optimization to generate atomic orbitals if (winput::out_spillage <= 2) { if(INPUT.bessel_nao_rcuts.size() == 1) @@ -1142,19 +1206,35 @@ void ESolver_KS_PW::postprocess() { for(int i = 0; i < INPUT.bessel_nao_rcuts.size(); i++) { - if(GlobalV::MY_RANK == 0) {std::cout << "update value: bessel_nao_rcut <- " << std::fixed << INPUT.bessel_nao_rcuts[i] << " a.u." << std::endl;} - INPUT.bessel_nao_rcut = INPUT.bessel_nao_rcuts[i]; + if(GlobalV::MY_RANK == 0) + { + std::cout << "update value: bessel_nao_rcut <- " + << std::fixed + << INPUT.bessel_nao_rcuts[i] + << " a.u." + << std::endl; + } + INPUT.bessel_nao_rcut = INPUT.bessel_nao_rcuts[i]; /* SEVERE BUG - the memory management of numerical_basis class is NOT SAFE, data cleaning before overwriting is absent. - instance created from present implementation of numerical_basis SHOULD NOT BE USED FOR MORE THAN ONE TIME. + the memory management of numerical_basis class is NOT SAFE, + data cleaning before overwriting is absent. + instance created from present implementation of numerical_basis + SHOULD NOT BE USED FOR MORE THAN ONE TIME. will cause data unexpected overwriting, file truncation and data loss. Will be refactored in the future. */ Numerical_Basis numerical_basis; numerical_basis.output_overlap(this->psi[0], this->sf, this->kv, this->pw_wfc); - std::string old_fname_header = winput::spillage_outdir + "/" + "orb_matrix."; - std::string new_fname_header = winput::spillage_outdir + "/" + "orb_matrix_rcut" + std::to_string(int(INPUT.bessel_nao_rcut)) + "deriv"; + std::string old_fname_header = winput::spillage_outdir + + "/" + + "orb_matrix."; + std::string new_fname_header = winput::spillage_outdir + + "/" + + "orb_matrix_rcut" + + std::to_string(int(INPUT.bessel_nao_rcut)) + + "deriv"; + for(int derivative_order = 0; derivative_order <= 1; derivative_order++) { // rename generated files @@ -1168,15 +1248,28 @@ void ESolver_KS_PW::postprocess() } } + //! Print out wave functions in real space if (this->wf.out_wfc_r == 1) // Peize Lin add 2021.11.21 { - ModuleIO::write_psi_r_1(this->psi[0], this->pw_wfc, "wfc_realspace", true, this->kv); + ModuleIO::write_psi_r_1( + this->psi[0], + this->pw_wfc, + "wfc_realspace", + true, + this->kv); } + //! Use Kubo-Greenwood method to compute conductivities if (INPUT.cal_cond) { - this->KG(INPUT.cond_smear, INPUT.cond_fwhm, INPUT.cond_wcut, INPUT.cond_dw, INPUT.cond_dt, this->pelec->wg); - } + this->KG( + INPUT.cond_smear, + INPUT.cond_fwhm, + INPUT.cond_wcut, + INPUT.cond_dw, + INPUT.cond_dt, + this->pelec->wg); + } } template @@ -1195,65 +1288,90 @@ void ESolver_KS_PW::hamilt2estates(const double ethr) } template -void ESolver_KS_PW::nscf() +void ESolver_KS_PW::nscf(void) { ModuleBase::TITLE("ESolver_KS_PW", "nscf"); ModuleBase::timer::tick("ESolver_KS_PW", "nscf"); this->beforescf(0); - //======================================== - // diagonalization of the KS hamiltonian - // ======================================= + + //! Setup the parameters for diagonalization double diag_ethr = GlobalV::PW_DIAG_THR; if (diag_ethr - 1e-2 > -1e-5) + { diag_ethr = std::max(1e-13, 0.1 * std::min(1e-2, GlobalV::SCF_THR / GlobalV::nelec)); + } GlobalV::ofs_running << " PW_DIAG_THR = " << diag_ethr << std::endl; + //! Diagonalize Hamiltonian this->hamilt2estates(diag_ethr); + + //! Calculate weights/Fermi energies this->pelec->calculate_weights(); + GlobalV::ofs_running << "\n End of Band Structure Calculation \n" << std::endl; + //! Print out band energies and weights for (int ik = 0; ik < this->kv.nks; ik++) { if (GlobalV::NSPIN == 2) { if (ik == 0) - GlobalV::ofs_running << " spin up :" << std::endl; - if (ik == (this->kv.nks / 2)) - GlobalV::ofs_running << " spin down :" << std::endl; + { + GlobalV::ofs_running << " spin up :" << std::endl; + } + if (ik == (this->kv.nks / 2)) + { + GlobalV::ofs_running << " spin down :" << std::endl; + } } - // out.printV3(GlobalV::ofs_running, this->kv.kvec_c[ik]); - GlobalV::ofs_running << " k-points" << ik + 1 << "(" << this->kv.nkstot << "): " << this->kv.kvec_c[ik].x << " " - << this->kv.kvec_c[ik].y << " " << this->kv.kvec_c[ik].z << std::endl; + GlobalV::ofs_running << " k-points" << ik + 1 + << "(" << this->kv.nkstot + << "): " << this->kv.kvec_c[ik].x + << " " + << this->kv.kvec_c[ik].y + << " " << this->kv.kvec_c[ik].z << std::endl; for (int ib = 0; ib < GlobalV::NBANDS; ib++) { - GlobalV::ofs_running << " spin" << this->kv.isk[ik] + 1 << "_final_band " << ib + 1 << " " - << this->pelec->ekb(ik, ib) * ModuleBase::Ry_to_eV << " " - << this->pelec->wg(ik, ib) * this->kv.nks << std::endl; - } + GlobalV::ofs_running << " spin" + << this->kv.isk[ik] + 1 + << "_final_band " + << ib + 1 << " " + << this->pelec->ekb(ik, ib) * ModuleBase::Ry_to_eV << " " + << this->pelec->wg(ik, ib) * this->kv.nks + << std::endl; + } GlobalV::ofs_running << std::endl; } + //! Print out band gaps if (GlobalV::out_bandgap) { if (!GlobalV::TWO_EFERMI) { this->pelec->cal_bandgap(); - GlobalV::ofs_running << " E_bandgap " << this->pelec->bandgap * ModuleBase::Ry_to_eV << " eV" << std::endl; - } + GlobalV::ofs_running << " E_bandgap " + << this->pelec->bandgap * ModuleBase::Ry_to_eV + << " eV" << std::endl; + } else { - this->pelec->cal_bandgap_updw(); - GlobalV::ofs_running << " E_bandgap_up " << this->pelec->bandgap_up * ModuleBase::Ry_to_eV << " eV" - << std::endl; - GlobalV::ofs_running << " E_bandgap_dw " << this->pelec->bandgap_dw * ModuleBase::Ry_to_eV << " eV" - << std::endl; - } + this->pelec->cal_bandgap_updw(); + GlobalV::ofs_running << " E_bandgap_up " + << this->pelec->bandgap_up * ModuleBase::Ry_to_eV + << " eV" + << std::endl; + GlobalV::ofs_running << " E_bandgap_dw " + << this->pelec->bandgap_dw * ModuleBase::Ry_to_eV + << " eV" + << std::endl; + } } + //! Calculate Wannier functions // add by jingan in 2018.11.7 if (INPUT.towannier90) { @@ -1267,18 +1385,27 @@ void ESolver_KS_PW::nscf() INPUT.wannier_spin ); - myWannier.calculate(this->pelec->ekb, this->pw_wfc, this->pw_big, this->kv, this->psi); - } + myWannier.calculate( + this->pelec->ekb, + this->pw_wfc, + this->pw_big, + this->kv, + this->psi); + } - //======================================================= - // Do a Berry phase polarization calculation if required - //======================================================= - if (berryphase::berry_phase_flag && ModuleSymmetry::Symmetry::symm_flag != 1) + //! Calculate Berry phase polarization + if (berryphase::berry_phase_flag + && ModuleSymmetry::Symmetry::symm_flag != 1) { berryphase bp; - bp.Macroscopic_polarization(this->pw_wfc->npwk_max, this->psi, this->pw_rho, this->pw_wfc, this->kv); - } + bp.Macroscopic_polarization( + this->pw_wfc->npwk_max, + this->psi, + this->pw_rho, + this->pw_wfc, + this->kv); + } ModuleBase::timer::tick("ESolver_KS_PW", "nscf"); return; From ae36b113695c3b4f19ab66010efc8df3c1757598 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 21:48:43 +0800 Subject: [PATCH 08/46] update formats of esolver_ks_pw.cpp and esolver_ks_pw.h --- source/module_esolver/esolver_ks_pw.cpp | 91 +++++++++++++++++-------- source/module_esolver/esolver_ks_pw.h | 45 ++++++++++-- 2 files changed, 101 insertions(+), 35 deletions(-) diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index c69a8b424ea..789972bd702 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -613,22 +613,38 @@ void ESolver_KS_PW::allocate_psi_init() "for new psi initializer, init_wfc type not supported"); } - // function polymorphism is moved from constructor to function initialize. Two slightly different implementation are for MPI and serial case, respectively. - #ifdef __MPI - this->psi_init->initialize(&this->sf, this->pw_wfc, &GlobalC::ucell, &GlobalC::Pkpoints, 1, &GlobalC::ppcell, GlobalV::MY_RANK); - #else - this->psi_init->initialize(&this->sf, this->pw_wfc, &GlobalC::ucell, 1, &GlobalC::ppcell); - #endif + //! function polymorphism is moved from constructor to function initialize. + //! Two slightly different implementation are for MPI and serial case, respectively. +#ifdef __MPI + this->psi_init->initialize( + &this->sf, + this->pw_wfc, + &GlobalC::ucell, + &GlobalC::Pkpoints, + 1, + &GlobalC::ppcell, + GlobalV::MY_RANK); +#else + this->psi_init->initialize( + &this->sf, + this->pw_wfc, + &GlobalC::ucell, + 1, + &GlobalC::ppcell); +#endif + // always new->initialize->tabulate->allocate->proj_ao_onkG this->psi_init->tabulate(); ModuleBase::timer::tick("ESolver_KS_PW", "allocate_psi_init"); + } -/* - Although ESolver_KS_PW supports template, but in this function it has no relationship with - heterogeneous calculation, so all templates function are specialized to double -*/ + + + +//! Although ESolver_KS_PW supports template, but in this function it has no relationship with +//! heterogeneous calculation, so all templates function are specialized to double template -void ESolver_KS_PW::initialize_psi() +void ESolver_KS_PW::initialize_psi(void) { ModuleBase::timer::tick("ESolver_KS_PW", "initialize_psi"); if (GlobalV::psi_initializer) @@ -657,8 +673,9 @@ void ESolver_KS_PW::initialize_psi() } //! to use psig, we need to lock it to get a shared pointer version, - //! then switch kpoint of psig to the given one - auto psig_ = psig.lock(); psig_->fix_k(ik); + //! then switch kpoint of psig to the given one + auto psig_ = psig.lock(); + psig_->fix_k(ik); std::vector etatom(psig_->get_nbands(), 0.0); @@ -666,11 +683,13 @@ void ESolver_KS_PW::initialize_psi() // either by matrix-multiplication or by copying-discarding if (this->psi_init->method() != "random") { + // lcao_in_pw and pw share the same esolver. In the future, we will have different esolver if ( ((GlobalV::KS_SOLVER == "cg")||(GlobalV::KS_SOLVER == "lapack")) - &&(GlobalV::BASIS_TYPE == "pw") // presently lcao_in_pw and pw share the same esolver. In the future, we will have different esolver + &&(GlobalV::BASIS_TYPE == "pw") ) - {// the following function is only run serially, to be improved + { + // the following function is only run serially, to be improved hsolver::DiagoIterAssist::diagH_subspace_init( this->p_hamilt, psig_->get_pointer(), @@ -686,7 +705,9 @@ void ESolver_KS_PW::initialize_psi() { if(ik == 0) { - GlobalV::ofs_running << " START WAVEFUNCTION: LCAO_IN_PW, psi initialization skipped " << std::endl; + GlobalV::ofs_running + << " START WAVEFUNCTION: LCAO_IN_PW, psi initialization skipped " + << std::endl; } continue; } @@ -706,7 +727,8 @@ void ESolver_KS_PW::initialize_psi() } // else the case is davidson } - // for davidson, we just copy the wavefunction (partially) + + // for the Davidson method, we just copy the wavefunction (partially) for (int iband = 0; iband < this->kspw_psi->get_nbands(); iband++) { for (int ibasis = 0; ibasis < this->kspw_psi->get_nbasis(); ibasis++) @@ -714,16 +736,21 @@ void ESolver_KS_PW::initialize_psi() (*(this->kspw_psi))(iband, ibasis) = (*psig_)(iband, ibasis); } } - } + }// end k-point loop + this->psi_init->set_initialized(true); - } + + } // end GlobalV::psi_initializer ModuleBase::timer::tick("ESolver_KS_PW", "initialize_psi"); } // Temporary, it should be replaced by hsolver later. template -void ESolver_KS_PW::hamilt2density(const int istep, const int iter, const double ethr) +void ESolver_KS_PW::hamilt2density( + const int istep, + const int iter, + const double ethr) { ModuleBase::timer::tick("ESolver_KS_PW", "hamilt2density"); @@ -806,27 +833,33 @@ void ESolver_KS_PW::hamilt2density(const int istep, const int iter, c this->pelec->set_exx(GlobalC::exx_lip.get_exx_energy()); // Peize Lin add 2019-03-09 #endif #endif + // calculate the delta_harris energy // according to new charge density. // mohan add 2009-01-23 this->pelec->cal_energies(1); + Symmetry_rho srho; for (int is = 0; is < GlobalV::NSPIN; is++) - { - srho.begin(is, *(this->pelec->charge), this->pw_rhod, GlobalC::Pgrid, GlobalC::ucell.symm); - } + { + srho.begin(is, + *(this->pelec->charge), + this->pw_rhod, + GlobalC::Pgrid, + GlobalC::ucell.symm); + } // compute magnetization, only for LSDA(spin==2) GlobalC::ucell.magnet.compute_magnetization(this->pelec->charge->nrxx, this->pelec->charge->nxyz, this->pelec->charge->rho, this->pelec->nelec_spin.data()); + // deband is calculated from "output" charge density calculated // in sum_band // need 'rho(out)' and 'vr (v_h(in) and v_xc(in))' - this->pelec->f_en.deband = this->pelec->cal_delta_eband(); - // if (LOCAL_BASIS) xiaohui modify 2013-09-02 + ModuleBase::timer::tick("ESolver_KS_PW", "hamilt2density"); } @@ -863,8 +896,8 @@ void ESolver_KS_PW::eachiterfinish(const int iter) GlobalC::ppcell.cal_effective_D(veff, this->pw_rhod, GlobalC::ucell); } - // print_eigenvalue(GlobalV::ofs_running); this->pelec->cal_energies(2); + // We output it for restarting the scf. bool print = false; if (this->out_freq_elec && iter % this->out_freq_elec == 0) @@ -928,8 +961,9 @@ void ESolver_KS_PW::afterscf(const int istep) } } - if (this->wf.out_wfc_pw == 1 || this->wf.out_wfc_pw == 2) - { + if (this->wf.out_wfc_pw == 1 + || this->wf.out_wfc_pw == 2) + { std::stringstream ssw; ssw << GlobalV::global_out_dir << "WAVEFUNC"; ModuleIO::write_wfc_pw(ssw.str(), this->psi[0], this->kv, this->pw_wfc); @@ -943,6 +977,7 @@ void ESolver_KS_PW::afterscf(const int istep) { this->pelec->print_eigenvalue(GlobalV::ofs_running); } + if (this->device == psi::GpuDevice) { castmem_2d_d2h_op()(this->psi[0].get_device(), diff --git a/source/module_esolver/esolver_ks_pw.h b/source/module_esolver/esolver_ks_pw.h index 5c9dff244f2..d08a24f552b 100644 --- a/source/module_esolver/esolver_ks_pw.h +++ b/source/module_esolver/esolver_ks_pw.h @@ -15,22 +15,35 @@ namespace ModuleESolver { - template - class ESolver_KS_PW : public ESolver_KS - { - private: - using Real = typename GetTypeReal::type; - public: +template +class ESolver_KS_PW : public ESolver_KS +{ + private: + + using Real = typename GetTypeReal::type; + + public: + ESolver_KS_PW(); + ~ESolver_KS_PW(); + void Init(Input& inp, UnitCell& cell) override; + void init_after_vc(Input& inp, UnitCell& cell) override; + double cal_Energy() override; + void cal_Force(ModuleBase::matrix& force) override; + void cal_Stress(ModuleBase::matrix& stress) override; + virtual void hamilt2density(const int istep, const int iter, const double ethr) override; + virtual void hamilt2estates(const double ethr) override; + virtual void nscf() override; + void postprocess() override; /** @@ -74,16 +87,23 @@ namespace ModuleESolver double* ct22); protected: + virtual void beforescf(const int istep) override; + virtual void eachiterinit(const int istep, const int iter) override; + virtual void updatepot(const int istep, const int iter) override; + virtual void eachiterfinish(const int iter) override; + virtual void afterscf(const int istep) override; + virtual void othercalculation(const int istep)override; //temporary, this will be removed in the future; //Init Global class void Init_GlobalC(Input& inp, UnitCell& cell); + /// @brief calculate conductivities from j-j correlation function void calcondw(const int nt, const double dt, @@ -94,13 +114,20 @@ namespace ModuleESolver double* ct11, double* ct12, double* ct22); + /// @brief allocate psi_init the new psi_initializer void allocate_psi_init(); + /// @brief initialize psi void initialize_psi(); + protected: - psi::Psi, psi::DEVICE_CPU>* psi = nullptr; //hide the psi in ESolver_KS for tmp use + + //! hide the psi in ESolver_KS for tmp use + psi::Psi, psi::DEVICE_CPU>* psi = nullptr; + private: + // psi_initializer* psi_init = nullptr; // change to use smart pointer to manage the memory, and avoid memory leak // while the std::make_unique() is not supported till C++14, @@ -108,9 +135,13 @@ namespace ModuleESolver std::unique_ptr> psi_init; Device * ctx = {}; + psi::AbacusDevice_t device = {}; + psi::Psi* kspw_psi = nullptr; + psi::Psi, Device>* __kspw_psi = nullptr; + using castmem_2d_d2h_op = psi::memory::cast_memory_op, T, psi::DEVICE_CPU, Device>; }; } // namespace ModuleESolver From 16b0f7622028c27831315cedace0271ce018568b Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 22:16:44 +0800 Subject: [PATCH 09/46] update esolver_ks_lcao_tddft.cpp formats --- .../module_esolver/esolver_ks_lcao_tddft.cpp | 246 +++++++++++------- tests/integrate/601_NO_TDDFT_CO/INPUT | 0 tests/integrate/601_NO_TDDFT_CO/KPT | 0 tests/integrate/601_NO_TDDFT_CO/STRU | 0 tests/integrate/601_NO_TDDFT_H2/INPUT | 0 tests/integrate/601_NO_TDDFT_H2/KPT | 0 tests/integrate/601_NO_TDDFT_H2/STRU | 0 7 files changed, 159 insertions(+), 87 deletions(-) mode change 100755 => 100644 tests/integrate/601_NO_TDDFT_CO/INPUT mode change 100755 => 100644 tests/integrate/601_NO_TDDFT_CO/KPT mode change 100755 => 100644 tests/integrate/601_NO_TDDFT_CO/STRU mode change 100755 => 100644 tests/integrate/601_NO_TDDFT_H2/INPUT mode change 100755 => 100644 tests/integrate/601_NO_TDDFT_H2/KPT mode change 100755 => 100644 tests/integrate/601_NO_TDDFT_H2/STRU diff --git a/source/module_esolver/esolver_ks_lcao_tddft.cpp b/source/module_esolver/esolver_ks_lcao_tddft.cpp index 48e9f6e28e8..ab2ad31acc4 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/module_esolver/esolver_ks_lcao_tddft.cpp @@ -38,6 +38,8 @@ ESolver_KS_LCAO_TDDFT::ESolver_KS_LCAO_TDDFT() classname = "ESolver_KS_LCAO_TDDFT"; basisname = "LCAO"; } + + ESolver_KS_LCAO_TDDFT::~ESolver_KS_LCAO_TDDFT() { // this->orb_con.clear_after_ions(GlobalC::UOT, GlobalC::ORB, GlobalV::deepks_setorb, GlobalC::ucell.infoNL.nproj); @@ -124,10 +126,14 @@ void ESolver_KS_LCAO_TDDFT::Init(Input& inp, UnitCell& ucell) &(sf), &(pelec->f_en.etxc), &(pelec->f_en.vtxc)); + this->pelec_td = dynamic_cast(this->pelec); } -void ESolver_KS_LCAO_TDDFT::hamilt2density(int istep, int iter, double ethr) +void ESolver_KS_LCAO_TDDFT::hamilt2density( + int istep, + int iter, + double ethr) { pelec->charge->save_rho_before_sum_band(); @@ -178,8 +184,12 @@ void ESolver_KS_LCAO_TDDFT::hamilt2density(int istep, int iter, double ethr) this->pelec->f_en.demet = 0.0; if (this->psi != nullptr) { - this->phsol->solve(this->p_hamilt, this->psi[0], this->pelec_td, GlobalV::KS_SOLVER); - } + this->phsol->solve( + this->p_hamilt, + this->psi[0], + this->pelec_td, + GlobalV::KS_SOLVER); + } } else { @@ -201,8 +211,13 @@ void ESolver_KS_LCAO_TDDFT::hamilt2density(int istep, int iter, double ethr) for (int ib = 0; ib < GlobalV::NBANDS; ib++) { std::setprecision(6); - GlobalV::ofs_running << ik + 1 << " " << ib + 1 << " " << this->pelec_td->wg(ik, ib) << std::endl; - } + GlobalV::ofs_running << ik + 1 + << " " + << ib + 1 + << " " + << this->pelec_td->wg(ik, ib) + << std::endl; + } } GlobalV::ofs_running << std::endl; GlobalV::ofs_running @@ -224,8 +239,12 @@ void ESolver_KS_LCAO_TDDFT::hamilt2density(int istep, int iter, double ethr) Symmetry_rho srho; for (int is = 0; is < GlobalV::NSPIN; is++) { - srho.begin(is, *(pelec->charge), pw_rho, GlobalC::Pgrid, GlobalC::ucell.symm); - } + srho.begin(is, + *(pelec->charge), + pw_rho, + GlobalC::Pgrid, + GlobalC::ucell.symm); + } } // (6) compute magnetization, only for spin==2 @@ -261,12 +280,29 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) this->p_hamilt->matrix(h_mat, s_mat); if (hsolver::HSolverLCAO>::out_mat_hs[0]) { - ModuleIO::save_mat(istep, h_mat.p, GlobalV::NLOCAL, bit, - hsolver::HSolverLCAO>::out_mat_hs[1], - 1, GlobalV::out_app_flag, "H", "data-" + std::to_string(ik), *this->LOWF.ParaV, GlobalV::DRANK); - ModuleIO::save_mat(istep, h_mat.p, GlobalV::NLOCAL, bit, - hsolver::HSolverLCAO>::out_mat_hs[1], - 1, GlobalV::out_app_flag, "S", "data-" + std::to_string(ik), *this->LOWF.ParaV, GlobalV::DRANK); + ModuleIO::save_mat(istep, + h_mat.p, + GlobalV::NLOCAL, + bit, + hsolver::HSolverLCAO>::out_mat_hs[1], + 1, + GlobalV::out_app_flag, + "H", + "data-" + std::to_string(ik), + *this->LOWF.ParaV, + GlobalV::DRANK); + + ModuleIO::save_mat(istep, + h_mat.p, + GlobalV::NLOCAL, + bit, + hsolver::HSolverLCAO>::out_mat_hs[1], + 1, + GlobalV::out_app_flag, + "S", + "data-" + std::to_string(ik), + *this->LOWF.ParaV, + GlobalV::DRANK); } } } @@ -293,9 +329,11 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) // Calculate new potential according to new Charge Density if (!this->conv_elec) { - if (GlobalV::NSPIN == 4) - GlobalC::ucell.cal_ux(); - this->pelec->pot->update_from_charge(this->pelec->charge, &GlobalC::ucell); + if (GlobalV::NSPIN == 4) + { + GlobalC::ucell.cal_ux(); + } + this->pelec->pot->update_from_charge(this->pelec->charge, &GlobalC::ucell); this->pelec->f_en.descf = this->pelec->cal_delta_escf(); } else @@ -306,17 +344,19 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) // store wfc and Hk laststep if (istep >= (wf.init_wfc == "file" ? 0 : 1) && this->conv_elec) { - if (this->psi_laststep == nullptr) + if (this->psi_laststep == nullptr) + { #ifdef __MPI - this->psi_laststep = new psi::Psi>(kv.nks, - this->LOWF.ParaV->ncol_bands, - this->LOWF.ParaV->nrow, - nullptr); + this->psi_laststep = new psi::Psi>(kv.nks, + this->LOWF.ParaV->ncol_bands, + this->LOWF.ParaV->nrow, + nullptr); #else - this->psi_laststep = new psi::Psi>(kv.nks, GlobalV::NBANDS, GlobalV::NLOCAL, nullptr); + this->psi_laststep = new psi::Psi>(kv.nks, GlobalV::NBANDS, GlobalV::NLOCAL, nullptr); #endif + } - if (td_htype == 1) + if (td_htype == 1) { if (this->Hk_laststep == nullptr) { @@ -343,8 +383,10 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) this->psi->fix_k(ik); this->psi_laststep->fix_k(ik); int size0 = psi->get_nbands() * psi->get_nbasis(); - for (int index = 0; index < size0; ++index) - psi_laststep[0].get_pointer()[index] = psi[0].get_pointer()[index]; + for (int index = 0; index < size0; ++index) + { + psi_laststep[0].get_pointer()[index] = psi[0].get_pointer()[index]; + } // store Hamiltonian if (td_htype == 1) @@ -358,8 +400,9 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) } // calculate energy density matrix for tddft - if (istep >= (wf.init_wfc == "file" ? 0 : 2) && module_tddft::Evolve_elec::td_edm == 0) - { + if (istep >= (wf.init_wfc == "file" ? 0 : 2) + && module_tddft::Evolve_elec::td_edm == 0) + { this->cal_edm_tddft(); } } @@ -374,6 +417,7 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) GlobalV::ofs_running << "ik iband Eii (eV)" << std::endl; GlobalV::ofs_running << std::setprecision(6); GlobalV::ofs_running << std::setiosflags(std::ios::showpoint); + for (int ik = 0; ik < kv.nks; ik++) { for (int ib = 0; ib < GlobalV::NBANDS; ib++) @@ -389,6 +433,7 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) } } + void ESolver_KS_LCAO_TDDFT::afterscf(const int istep) { for (int is = 0; is < GlobalV::NSPIN; is++) @@ -402,7 +447,8 @@ void ESolver_KS_LCAO_TDDFT::afterscf(const int istep) } if(module_tddft::Evolve_elec::out_current == 1) { - elecstate::DensityMatrix, double>* tmp_DM = dynamic_cast>*>(this->pelec)->get_DM(); + elecstate::DensityMatrix, double>* tmp_DM = + dynamic_cast>*>(this->pelec)->get_DM(); ModuleIO::write_current(istep, this->psi, pelec, @@ -415,48 +461,69 @@ void ESolver_KS_LCAO_TDDFT::afterscf(const int istep) } // use the original formula (Hamiltonian matrix) to calculate energy density matrix -void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() +void ESolver_KS_LCAO_TDDFT::cal_edm_tddft(void) { + // mohan add 2024-03-27 + const int nlocal = GlobalV::NLOCAL; + assert(nlocal>=0); + //this->LOC.edm_k_tddft.resize(kv.nks); dynamic_cast>*>(this->pelec)->get_DM()->EDMK.resize(kv.nks); for (int ik = 0; ik < kv.nks; ++ik) { - std::complex* tmp_dmk = dynamic_cast>*>(this->pelec)->get_DM()->get_DMK_pointer(ik); - ModuleBase::ComplexMatrix& tmp_edmk = dynamic_cast>*>(this->pelec)->get_DM()->EDMK[ik]; - const Parallel_Orbitals* tmp_pv = dynamic_cast>*>(this->pelec)->get_DM()->get_paraV_pointer(); + std::complex* tmp_dmk = + dynamic_cast>*>(this->pelec)->get_DM()->get_DMK_pointer(ik); + + ModuleBase::ComplexMatrix& tmp_edmk = + dynamic_cast>*>(this->pelec)->get_DM()->EDMK[ik]; + + const Parallel_Orbitals* tmp_pv = + dynamic_cast>*>(this->pelec)->get_DM()->get_paraV_pointer(); + #ifdef __MPI + + // mohan add 2024-03-27 + //! be careful, the type of nloc is 'long' + //! whether the long type is safe, needs more discussion + const long nloc = this->LOC.ParaV->nloc; + //this->LOC.edm_k_tddft[ik].create(this->LOC.ParaV->ncol, this->LOC.ParaV->nrow); tmp_edmk.create(this->LOC.ParaV->ncol, this->LOC.ParaV->nrow); - complex* Htmp = new complex[this->LOC.ParaV->nloc]; - complex* Sinv = new complex[this->LOC.ParaV->nloc]; - complex* tmp1 = new complex[this->LOC.ParaV->nloc]; - complex* tmp2 = new complex[this->LOC.ParaV->nloc]; - complex* tmp3 = new complex[this->LOC.ParaV->nloc]; - complex* tmp4 = new complex[this->LOC.ParaV->nloc]; - ModuleBase::GlobalFunc::ZEROS(Htmp, this->LOC.ParaV->nloc); - ModuleBase::GlobalFunc::ZEROS(Sinv, this->LOC.ParaV->nloc); - ModuleBase::GlobalFunc::ZEROS(tmp1, this->LOC.ParaV->nloc); - ModuleBase::GlobalFunc::ZEROS(tmp2, this->LOC.ParaV->nloc); - ModuleBase::GlobalFunc::ZEROS(tmp3, this->LOC.ParaV->nloc); - ModuleBase::GlobalFunc::ZEROS(tmp4, this->LOC.ParaV->nloc); + complex* Htmp = new complex[nloc]; + complex* Sinv = new complex[nloc]; + complex* tmp1 = new complex[nloc]; + complex* tmp2 = new complex[nloc]; + complex* tmp3 = new complex[nloc]; + complex* tmp4 = new complex[nloc]; + + ModuleBase::GlobalFunc::ZEROS(Htmp, nloc); + ModuleBase::GlobalFunc::ZEROS(Sinv, nloc); + ModuleBase::GlobalFunc::ZEROS(tmp1, nloc); + ModuleBase::GlobalFunc::ZEROS(tmp2, nloc); + ModuleBase::GlobalFunc::ZEROS(tmp3, nloc); + ModuleBase::GlobalFunc::ZEROS(tmp4, nloc); + const int inc = 1; int nrow = this->LOC.ParaV->nrow; int ncol = this->LOC.ParaV->ncol; - hamilt::MatrixBlock> h_mat, s_mat; + + hamilt::MatrixBlock> h_mat; + hamilt::MatrixBlock> s_mat; + p_hamilt->matrix(h_mat, s_mat); - zcopy_(&this->LOC.ParaV->nloc, h_mat.p, &inc, Htmp, &inc); - zcopy_(&this->LOC.ParaV->nloc, s_mat.p, &inc, Sinv, &inc); + zcopy_(&nloc, h_mat.p, &inc, Htmp, &inc); + zcopy_(&nloc, s_mat.p, &inc, Sinv, &inc); - int* ipiv = new int[this->LOC.ParaV->nloc]; + int* ipiv = new int[nloc]; int info; const int one_int = 1; - pzgetrf_(&GlobalV::NLOCAL, &GlobalV::NLOCAL, Sinv, &one_int, &one_int, this->LOC.ParaV->desc, ipiv, &info); + pzgetrf_(&nlocal, &nlocal, Sinv, &one_int, &one_int, this->LOC.ParaV->desc, ipiv, &info); int LWORK = -1, liWORK = -1; std::vector> WORK(1, 0); std::vector iWORK(1, 0); - pzgetri_(&GlobalV::NLOCAL, + pzgetri_(&nlocal, Sinv, &one_int, &one_int, @@ -473,7 +540,7 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() liWORK = iWORK[0]; iWORK.resize(liWORK, 0); - pzgetri_(&GlobalV::NLOCAL, + pzgetri_(&nlocal, Sinv, &one_int, &one_int, @@ -490,9 +557,9 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() const complex half_float = {0.5, 0.0}; pzgemm_(&N_char, &N_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, + &nlocal, + &nlocal, + &nlocal, &one_float, tmp_dmk, &one_int, @@ -510,9 +577,9 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() pzgemm_(&N_char, &N_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, + &nlocal, + &nlocal, + &nlocal, &one_float, tmp1, &one_int, @@ -530,9 +597,9 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() pzgemm_(&N_char, &N_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, + &nlocal, + &nlocal, + &nlocal, &one_float, Sinv, &one_int, @@ -550,9 +617,9 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() pzgemm_(&N_char, &N_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, + &nlocal, + &nlocal, + &nlocal, &one_float, tmp3, &one_int, @@ -569,8 +636,8 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() this->LOC.ParaV->desc); pzgeadd_(&N_char, - &GlobalV::NLOCAL, - &GlobalV::NLOCAL, + &nlocal, + &nlocal, &half_float, tmp2, &one_int, @@ -581,8 +648,8 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() &one_int, &one_int, this->LOC.ParaV->desc); - zcopy_(&this->LOC.ParaV->nloc, tmp4, &inc, tmp_edmk.c, &inc); - //zcopy_(&this->LOC.ParaV->nloc, tmp4, &inc, this->LOC.edm_k_tddft[ik].c, &inc); + zcopy_(&nloc, tmp4, &inc, tmp_edmk.c, &inc); + //zcopy_(&nloc, tmp4, &inc, this->LOC.edm_k_tddft[ik].c, &inc); delete[] Htmp; delete[] Sinv; delete[] tmp1; @@ -591,43 +658,48 @@ void ESolver_KS_LCAO_TDDFT::cal_edm_tddft() delete[] tmp4; delete[] ipiv; #else + // for serial version //this->LOC.edm_k_tddft[ik].create(this->LOC.ParaV->ncol, this->LOC.ParaV->nrow); tmp_edmk.create(this->LOC.ParaV->ncol, this->LOC.ParaV->nrow); - ModuleBase::ComplexMatrix Sinv(GlobalV::NLOCAL, GlobalV::NLOCAL); - ModuleBase::ComplexMatrix Htmp(GlobalV::NLOCAL, GlobalV::NLOCAL); - hamilt::MatrixBlock> h_mat, s_mat; + ModuleBase::ComplexMatrix Sinv(nlocal, nlocal); + ModuleBase::ComplexMatrix Htmp(nlocal, nlocal); + + hamilt::MatrixBlock> h_mat; + hamilt::MatrixBlock> s_mat; + p_hamilt->matrix(h_mat, s_mat); // cout<<"hmat "<* work = new std::complex[lwork]; + ModuleBase::GlobalFunc::ZEROS(work, lwork); - int LWORK = 3 * GlobalV::NLOCAL - 1; // tmp - std::complex* WORK = new std::complex[LWORK]; - ModuleBase::GlobalFunc::ZEROS(WORK, LWORK); - int IPIV[GlobalV::NLOCAL]; + int IPIV[nlocal]; - LapackConnector::zgetrf(GlobalV::NLOCAL, GlobalV::NLOCAL, Sinv, GlobalV::NLOCAL, IPIV, &INFO); - LapackConnector::zgetri(GlobalV::NLOCAL, Sinv, GlobalV::NLOCAL, IPIV, WORK, LWORK, &INFO); + LapackConnector::zgetrf(nlocal, nlocal, Sinv, nlocal, IPIV, &INFO); + LapackConnector::zgetri(nlocal, Sinv, nlocal, IPIV, work, lwork, &INFO); // I just use ModuleBase::ComplexMatrix temporarily, and will change it to complex* - ModuleBase::ComplexMatrix tmp_dmk_base(GlobalV::NLOCAL, GlobalV::NLOCAL); - for (int i = 0; i < GlobalV::NLOCAL; i++) + ModuleBase::ComplexMatrix tmp_dmk_base(nlocal, nlocal); + for (int i = 0; i < nlocal; i++) { - for (int j = 0; j < GlobalV::NLOCAL; j++) + for (int j = 0; j < nlocal; j++) { - tmp_dmk_base(i, j) = tmp_dmk[i * GlobalV::NLOCAL + j]; + tmp_dmk_base(i, j) = tmp_dmk[i * nlocal + j]; } } tmp_edmk = 0.5 * (Sinv * Htmp * tmp_dmk_base + tmp_dmk_base * Htmp * Sinv); - delete[] WORK; + delete[] work; #endif } return; } -} // namespace ModuleESolver \ No newline at end of file +} // namespace ModuleESolver diff --git a/tests/integrate/601_NO_TDDFT_CO/INPUT b/tests/integrate/601_NO_TDDFT_CO/INPUT old mode 100755 new mode 100644 diff --git a/tests/integrate/601_NO_TDDFT_CO/KPT b/tests/integrate/601_NO_TDDFT_CO/KPT old mode 100755 new mode 100644 diff --git a/tests/integrate/601_NO_TDDFT_CO/STRU b/tests/integrate/601_NO_TDDFT_CO/STRU old mode 100755 new mode 100644 diff --git a/tests/integrate/601_NO_TDDFT_H2/INPUT b/tests/integrate/601_NO_TDDFT_H2/INPUT old mode 100755 new mode 100644 diff --git a/tests/integrate/601_NO_TDDFT_H2/KPT b/tests/integrate/601_NO_TDDFT_H2/KPT old mode 100755 new mode 100644 diff --git a/tests/integrate/601_NO_TDDFT_H2/STRU b/tests/integrate/601_NO_TDDFT_H2/STRU old mode 100755 new mode 100644 From 1768c8889d5cb04d99ead0c2f03d9cea6f6df1db Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 22:25:00 +0800 Subject: [PATCH 10/46] update format of esolver_sdft_pw.cpp --- source/module_esolver/esolver_sdft_pw.cpp | 130 ++++++++++++++++++---- 1 file changed, 106 insertions(+), 24 deletions(-) diff --git a/source/module_esolver/esolver_sdft_pw.cpp b/source/module_esolver/esolver_sdft_pw.cpp index 8a05a7b2c84..2b4e16010e6 100644 --- a/source/module_esolver/esolver_sdft_pw.cpp +++ b/source/module_esolver/esolver_sdft_pw.cpp @@ -89,24 +89,34 @@ void ESolver_SDFT_PW::Init(Input& inp, UnitCell& ucell) Init_Sto_Orbitals_Ecut(this->stowf, inp.seed_sto, kv, *pw_wfc, inp.initsto_ecut); } } - else - Init_Com_Orbitals(this->stowf); + else + { + Init_Com_Orbitals(this->stowf); + } + size_t size = stowf.chi0->size(); + this->stowf.shchi = new psi::Psi>(kv.nks, stowf.nchip_max, wf.npwx, kv.ngk.data()); + ModuleBase::Memory::record("SDFT::shchi", size * sizeof(std::complex)); + if (GlobalV::NBANDS > 0) { this->stowf.chiortho = new psi::Psi>(kv.nks, stowf.nchip_max, wf.npwx, kv.ngk.data()); ModuleBase::Memory::record("SDFT::chiortho", size * sizeof(std::complex)); } + this->phsol = new hsolver::HSolverPW_SDFT(&kv, pw_wfc, &wf, this->stowf, inp.method_sto); } + void ESolver_SDFT_PW::beforescf(const int istep) { ESolver_KS_PW::beforescf(istep); - if (istep > 0 && INPUT.nbands_sto != 0 && INPUT.initsto_freq > 0 && istep % INPUT.initsto_freq == 0) - Update_Sto_Orbitals(this->stowf, INPUT.seed_sto); + if (istep > 0 && INPUT.nbands_sto != 0 && INPUT.initsto_freq > 0 && istep % INPUT.initsto_freq == 0) + { + Update_Sto_Orbitals(this->stowf, INPUT.seed_sto); + } } void ESolver_SDFT_PW::eachiterfinish(int iter) @@ -114,6 +124,8 @@ void ESolver_SDFT_PW::eachiterfinish(int iter) // this->pelec->print_eigenvalue(GlobalV::ofs_running); this->pelec->cal_energies(2); } + + void ESolver_SDFT_PW::afterscf(const int istep) { // save charge difference into files for charge extrapolation @@ -173,9 +185,21 @@ void ESolver_SDFT_PW::hamilt2density(int istep, int iter, double ethr) { hsolver::DiagoIterAssist>::need_subspace = true; } + hsolver::DiagoIterAssist>::PW_DIAG_THR = ethr; + hsolver::DiagoIterAssist>::PW_DIAG_NMAX = GlobalV::PW_DIAG_NMAX; - this->phsol->solve(this->p_hamilt, this->psi[0], this->pelec, pw_wfc, this->stowf, istep, iter, GlobalV::KS_SOLVER); + + this->phsol->solve( + this->p_hamilt, + this->psi[0], + this->pelec, + pw_wfc, + this->stowf, + istep, + iter, + GlobalV::KS_SOLVER); + if (GlobalV::MY_STOGROUP == 0) { Symmetry_rho srho; @@ -188,8 +212,10 @@ void ESolver_SDFT_PW::hamilt2density(int istep, int iter, double ethr) else { #ifdef __MPI - if (ModuleSymmetry::Symmetry::symm_flag == 1) - MPI_Barrier(MPI_COMM_WORLD); + if (ModuleSymmetry::Symmetry::symm_flag == 1) + { + MPI_Barrier(MPI_COMM_WORLD); + } #endif } } @@ -199,17 +225,41 @@ double ESolver_SDFT_PW::cal_Energy() return this->pelec->f_en.etot; } + void ESolver_SDFT_PW::cal_Force(ModuleBase::matrix& force) { Sto_Forces ff(GlobalC::ucell.nat); - ff.cal_stoforce(force, *this->pelec, pw_rho, &GlobalC::ucell.symm, &sf, &kv, pw_wfc, this->psi, this->stowf); + + ff.cal_stoforce(force, + *this->pelec, + pw_rho, + &GlobalC::ucell.symm, + &sf, + &kv, + pw_wfc, + this->psi, + this->stowf); } + + void ESolver_SDFT_PW::cal_Stress(ModuleBase::matrix& stress) { Sto_Stress_PW ss; - ss.cal_stress(stress, *this->pelec, pw_rho, &GlobalC::ucell.symm, &sf, &kv, pw_wfc, this->psi, this->stowf, pelec->charge); + ss.cal_stress( + stress, + *this->pelec, + pw_rho, + &GlobalC::ucell.symm, + &sf, + &kv, + pw_wfc, + this->psi, + this->stowf, + pelec->charge); } -void ESolver_SDFT_PW::postprocess() + + +void ESolver_SDFT_PW::postprocess(void) { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; @@ -219,9 +269,14 @@ void ESolver_SDFT_PW::postprocess() ModuleIO::write_istate_info(this->pelec->ekb, this->pelec->wg, kv, &(GlobalC::Pkpoints)); ((hsolver::HSolverPW_SDFT*)phsol)->stoiter.cleanchiallorder(); // release lots of memories + int nche_test = this->nche_sto; - if (INPUT.out_dos) - nche_test = std::max(nche_test, INPUT.dos_nche); + + if (INPUT.out_dos) + { + nche_test = std::max(nche_test, INPUT.dos_nche); + } + int cond_nche = 0; if (INPUT.cal_cond) { @@ -231,24 +286,41 @@ void ESolver_SDFT_PW::postprocess() { check_che(nche_test, INPUT.emin_sto, INPUT.emax_sto); } + if (INPUT.out_dos) { - double emax, emin; - if (INPUT.dos_setemax) - emax = INPUT.dos_emax_ev; - else - emax = ((hsolver::HSolverPW_SDFT*)phsol)->stoiter.stohchi.Emax * ModuleBase::Ry_to_eV; - if (INPUT.dos_setemin) - emin = INPUT.dos_emin_ev; - else - emin = ((hsolver::HSolverPW_SDFT*)phsol)->stoiter.stohchi.Emin * ModuleBase::Ry_to_eV; + double emax=0.0; + double emin=0.0; + if (INPUT.dos_setemax) + { + emax = INPUT.dos_emax_ev; + } + else + { + emax = ((hsolver::HSolverPW_SDFT*)phsol)->stoiter.stohchi.Emax * ModuleBase::Ry_to_eV; + } + if (INPUT.dos_setemin) + { + emin = INPUT.dos_emin_ev; + } + else + { + emin = ((hsolver::HSolverPW_SDFT*)phsol)->stoiter.stohchi.Emin * ModuleBase::Ry_to_eV; + } + if (!INPUT.dos_setemax && !INPUT.dos_setemin) { double delta = (emax - emin) * INPUT.dos_scale; emax = emax + delta / 2.0; emin = emin - delta / 2.0; } - this->caldos(INPUT.dos_nche, INPUT.dos_sigma, emin, emax, INPUT.dos_edelta_ev, INPUT.npart_sto); + this->caldos( + INPUT.dos_nche, + INPUT.dos_sigma, + emin, + emax, + INPUT.dos_edelta_ev, + INPUT.npart_sto); } // sKG cost memory, and it should be placed at the end of the program @@ -265,6 +337,7 @@ void ESolver_SDFT_PW::postprocess() } } + void ESolver_SDFT_PW::othercalculation(const int istep) { ModuleBase::TITLE("ESolver_SDFT_PW", "othercalculation"); @@ -282,18 +355,27 @@ void ESolver_SDFT_PW::othercalculation(const int istep) return; } -void ESolver_SDFT_PW::nscf() + +void ESolver_SDFT_PW::nscf(void) { ModuleBase::TITLE("ESolver_SDFT_PW", "nscf"); ModuleBase::timer::tick("ESolver_SDFT_PW", "nscf"); + const int istep = 0; + const int iter = 1; + const double diag_thr = std::max(std::min(1e-5, 0.1 * GlobalV::SCF_THR / std::max(1.0, GlobalV::nelec)), 1e-12); + std::cout << " DIGA_THR : " << diag_thr << std::endl; + this->beforescf(istep); + this->hamilt2density(istep, iter, diag_thr); + this->pelec->cal_energies(2); + ModuleBase::timer::tick("ESolver_SDFT_PW", "nscf"); return; } -} // namespace ModuleESolver \ No newline at end of file +} // namespace ModuleESolver From 6a606ed69a925a63905c6d82473eb9c1bf52ccb5 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 22:28:58 +0800 Subject: [PATCH 11/46] update the format of esolver_sdft_pw_tool.cpp --- .../module_esolver/esolver_sdft_pw_tool.cpp | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/source/module_esolver/esolver_sdft_pw_tool.cpp b/source/module_esolver/esolver_sdft_pw_tool.cpp index a9d7508c7ce..ef32bd5c123 100644 --- a/source/module_esolver/esolver_sdft_pw_tool.cpp +++ b/source/module_esolver/esolver_sdft_pw_tool.cpp @@ -13,6 +13,7 @@ #define TWOSQRT2LN2 2.354820045030949 // FWHM = 2sqrt(2ln2) * \sigma #define FACTOR 1.839939223835727e7 + namespace ModuleESolver { struct parallel_distribution @@ -66,6 +67,8 @@ struct info_gatherv int* displs = nullptr; }; #endif + + void convert_psi(const psi::Psi>& psi_in, psi::Psi>& psi_out) { psi_in.fix_k(0); @@ -77,6 +80,7 @@ void convert_psi(const psi::Psi>& psi_in, psi::Psi>* gatherchi(psi::Psi>& chi, psi::Psi>& chi_all, const int& npwx, @@ -105,6 +109,7 @@ psi::Psi>* gatherchi(psi::Psi>& chi, return p_chi; } + void ESolver_SDFT_PW::check_che(const int nche_in, const double try_emin, const double try_emax) { //------------------------------ @@ -649,7 +654,7 @@ void ESolver_SDFT_PW::sKG(const int nche_KG, double gamma = fwhmin / 2.0 / ModuleBase::Ry_to_eV; double dt = dt_in; // unit in a.u., 1 a.u. = 4.837771834548454e-17 s const double expfactor = 18.42; // exp(-18.42) = 1e-8 - int nt; // set nt empirically + int nt=0; // set nt empirically if(smear_type == 1) { nt = ceil(sqrt(2 * expfactor) / sigma / dt); @@ -813,8 +818,10 @@ void ESolver_SDFT_PW::sKG(const int nche_KG, //----------------------------------------------------------- // ks conductivity //----------------------------------------------------------- - if (GlobalV::MY_STOGROUP == 0 && allbands_ks > 0) - jjcorr_ks(ik, nt, dt, dEcut, this->pelec->wg, velop, ct11, ct12, ct22); + if (GlobalV::MY_STOGROUP == 0 && allbands_ks > 0) + { + jjcorr_ks(ik, nt, dt, dEcut, this->pelec->wg, velop, ct11, ct12, ct22); + } //----------------------------------------------------------- // sto conductivity @@ -897,7 +904,9 @@ void ESolver_SDFT_PW::sKG(const int nche_KG, npw, npwx, perbands_sto); + che.calcoef_real(&stoiter.stofunc, &Sto_Func::nroot_mfd); + che.calfinalvec_real(&stohchi, &Stochastic_hchi::hchi_norm, stopsi->get_pointer(), @@ -1173,12 +1182,16 @@ void ESolver_SDFT_PW::sKG(const int nche_KG, / 2.0); double tmp12 = static_cast( ModuleBase::GlobalFunc::ddot_real(num_per, j1l.data() + st_per, j2r.data() + st_per, false)); + double tmp21 = static_cast( ModuleBase::GlobalFunc::ddot_real(num_per, j2l.data() + st_per, j1r.data() + st_per, false)); + ct12[it] -= 0.5 * (tmp12 + tmp21) * kv.wk[ik] / 2.0; + ct22[it] += static_cast( ModuleBase::GlobalFunc::ddot_real(num_per, j2l.data() + st_per, j2r.data() + st_per, false) * kv.wk[ik] / 2.0); + ModuleBase::timer::tick(this->classname, "ddot_real"); } std::cout << std::endl; @@ -1303,8 +1316,11 @@ void ESolver_SDFT_PW::caldos(const int nche_dos, } } } - if (stoiter.method == 2) - delete[] allorderchi; + + if (stoiter.method == 2) + { + delete[] allorderchi; + } std::ofstream ofsdos; int ndos = int((emax - emin) / de) + 1; @@ -1413,7 +1429,5 @@ void ESolver_SDFT_PW::caldos(const int nche_dos, namespace GlobalTemp { - -const ModuleBase::matrix* veff; - -} \ No newline at end of file + const ModuleBase::matrix* veff; +} From cac11eae4ee0aa2b7f738641a921143c3f5efc7c Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 22:47:50 +0800 Subject: [PATCH 12/46] keep formating esolver_ks_pw.cpp --- source/module_esolver/esolver_ks_pw.cpp | 83 +++++++++++++++++-------- 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index 789972bd702..0395ff660da 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -108,7 +108,6 @@ ESolver_KS_PW::~ESolver_KS_PW() template void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) { - // --------------------------------------------------------------------------------- // GlobalC is a historically left-over namespace, it is used to store global classes, // including: // pseudopot_cell_vnl: pseudopotential in cell, V non-local @@ -159,20 +158,14 @@ void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) } // --------------------------------------------------------------------------------- - //======================= - // init pseudopotential - //======================= + //! init pseudopotential GlobalC::ppcell.init(GlobalC::ucell.ntype, &this->sf, this->pw_wfc); - //================================= - // initalize local pseudopotential - //================================= + //! initalize local pseudopotential GlobalC::ppcell.init_vloc(GlobalC::ppcell.vloc, this->pw_rhod); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "LOCAL POTENTIAL"); - //====================================== - // Initalize non local pseudopotential - //====================================== + //! Initalize non-local pseudopotential GlobalC::ppcell.init_vnl(GlobalC::ucell, this->pw_rhod); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "NON-LOCAL POTENTIAL"); @@ -193,11 +186,27 @@ void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) } // --------------------------------------------------------------------------------- + this->kspw_psi = GlobalV::device_flag == "gpu" || GlobalV::precision_flag == "single" ? new psi::Psi(this->psi[0]) : reinterpret_cast*>(this->psi); + // I would like to change the above sentence to the following, + // but I am not sure what the code is doing, so I leave it as a comment + // mohan by 2024-03-27 +/* + if (GlobalV::device_flag == "gpu" || GlobalV::precision_flag == "single") + { + // psi[0] means gamma_only? + this->kspw_psi = new psi::Psi(this->psi[0]); + } + else + { + this->kspw_psi = reinterpret_cast*>(this->psi); + } +*/ + if (GlobalV::precision_flag == "single") { ModuleBase::Memory::record("Psi_single", sizeof(T) * this->psi[0].size()); @@ -206,6 +215,7 @@ void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT BASIS"); } + template void ESolver_KS_PW::Init(Input& inp, UnitCell& ucell) { @@ -264,6 +274,7 @@ void ESolver_KS_PW::Init(Input& inp, UnitCell& ucell) } } + template void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) { @@ -274,18 +285,34 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) if (GlobalV::md_prec_level == 2) { - this->pw_wfc->initgrids(ucell.lat0, ucell.latvec, this->pw_rho->nx, this->pw_rho->ny, this->pw_rho->nz); - this->pw_wfc->initparameters(false, inp.ecutwfc, this->kv.nks, this->kv.kvec_d.data()); + this->pw_wfc->initgrids( + ucell.lat0, + ucell.latvec, + this->pw_rho->nx, + this->pw_rho->ny, + this->pw_rho->nz); + + this->pw_wfc->initparameters( + false, + inp.ecutwfc, + this->kv.nks, + this->kv.kvec_d.data()); + #ifdef __MPI - if (INPUT.pw_seed > 0) - MPI_Allreduce(MPI_IN_PLACE, &this->pw_wfc->ggecut, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - // qianrui add 2021-8-13 to make different kpar parameters can get the same results + if (INPUT.pw_seed > 0) + { + MPI_Allreduce(MPI_IN_PLACE, &this->pw_wfc->ggecut, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + } + // qianrui add 2021-8-13 to make different kpar parameters can get the same results #endif + this->pw_wfc->setuptransform(); + for (int ik = 0; ik < this->kv.nks; ++ik) { this->kv.ngk[ik] = this->pw_wfc->npwk[ik]; } + this->pw_wfc->collect_local_pw(inp.erf_ecut, inp.erf_height, inp.erf_sigma); delete this->phsol; @@ -302,9 +329,12 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) this->pw_big); this->pelec->charge->allocate(GlobalV::NSPIN); + + //! setup cell volume this->pelec->omega = GlobalC::ucell.omega; delete this->pelec->pot; + this->pelec->pot = new elecstate::Potential(this->pw_rhod, this->pw_rho, &GlobalC::ucell, @@ -432,10 +462,14 @@ void ESolver_KS_PW::beforescf(int istep) delete reinterpret_cast*>(this->p_hamilt); this->p_hamilt = nullptr; } + // allocate HamiltPW if (this->p_hamilt == nullptr) { - this->p_hamilt = new hamilt::HamiltPW(this->pelec->pot, this->pw_wfc, &this->kv); + this->p_hamilt = new hamilt::HamiltPW( + this->pelec->pot, + this->pw_wfc, + &this->kv); } //---------------------------------------------------------- @@ -456,21 +490,18 @@ void ESolver_KS_PW::beforescf(int istep) this->sf.strucFac); } - //========================================================= - // cal_ux should be called before init_scf because - // the direction of ux is used in noncoline_rho - //========================================================= + //! cal_ux should be called before init_scf because + //! the direction of ux is used in noncoline_rho if(GlobalV::NSPIN == 4 && GlobalV::DOMAG) { GlobalC::ucell.cal_ux(); } - //========================================================= - // calculate the total local pseudopotential in real space - //========================================================= + //! calculate the total local pseudopotential in real space this->pelec->init_scf(istep, this->sf.strucFac); - // Symmetry_rho should behind init_scf, because charge should be initialized first. - // liuyu comment: Symmetry_rho should be located between init_rho and v_of_rho? + + //! Symmetry_rho should behind init_scf, because charge should be initialized first. + //! liuyu comment: Symmetry_rho should be located between init_rho and v_of_rho? Symmetry_rho srho; for (int is = 0; is < GlobalV::NSPIN; is++) { @@ -505,6 +536,7 @@ void ESolver_KS_PW::beforescf(int istep) } } + template void ESolver_KS_PW::othercalculation(const int istep) { @@ -571,6 +603,7 @@ void ESolver_KS_PW::eachiterinit(const int istep, const int iter) } } + template void ESolver_KS_PW::allocate_psi_init() { From e191f6cd5d15610fe971288e194b6208343dfbf4 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 22:52:36 +0800 Subject: [PATCH 13/46] formating esolver_of_interface.cpp --- .../module_esolver/esolver_of_interface.cpp | 90 +++++++++++++------ 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/source/module_esolver/esolver_of_interface.cpp b/source/module_esolver/esolver_of_interface.cpp index 97ca0d471e7..090b01df2c3 100644 --- a/source/module_esolver/esolver_of_interface.cpp +++ b/source/module_esolver/esolver_of_interface.cpp @@ -11,23 +11,36 @@ namespace ModuleESolver */ void ESolver_OF::init_kedf(Input& inp) { + //! Thomas-Fermi (TF) KEDF, TF+ KEDF, and Want-Teter (WT) KEDF if (this->of_kinetic_ == "tf" || this->of_kinetic_ == "tf+" || this->of_kinetic_ == "wt") { - if (this->tf_ == nullptr) - this->tf_ = new KEDF_TF(); + if (this->tf_ == nullptr) + { + this->tf_ = new KEDF_TF(); + } this->tf_->set_para(this->pw_rho->nrxx, this->dV_, inp.of_tf_weight); } - if (this->of_kinetic_ == "vw" || this->of_kinetic_ == "tf+" || this->of_kinetic_ == "wt" - || this->of_kinetic_ == "lkt") + + //! vW, TF+, WT, and LKT KEDFs + if (this->of_kinetic_ == "vw" + || this->of_kinetic_ == "tf+" + || this->of_kinetic_ == "wt" + || this->of_kinetic_ == "lkt") { - if (this->vw_ == nullptr) - this->vw_ = new KEDF_vW(); + if (this->vw_ == nullptr) + { + this->vw_ = new KEDF_vW(); + } this->vw_->set_para(this->dV_, inp.of_vw_weight); } + + //! Wang-Teter KEDF if (this->of_kinetic_ == "wt") { - if (this->wt_ == nullptr) - this->wt_ = new KEDF_WT(); + if (this->wt_ == nullptr) + { + this->wt_ = new KEDF_WT(); + } this->wt_->set_para(this->dV_, inp.of_wt_alpha, inp.of_wt_beta, @@ -40,10 +53,14 @@ void ESolver_OF::init_kedf(Input& inp) inp.of_kernel_file, this->pw_rho); } + + //! LKT KEDF if (this->of_kinetic_ == "lkt") { - if (this->lkt_ == nullptr) - this->lkt_ = new KEDF_LKT(); + if (this->lkt_ == nullptr) + { + this->lkt_ = new KEDF_LKT(); + } this->lkt_->set_para(this->dV_, inp.of_lkt_a); } } @@ -80,8 +97,10 @@ void ESolver_OF::kinetic_potential(double** prho, double** pphi, ModuleBase::mat } } - if (this->of_kinetic_ == "vw" || this->of_kinetic_ == "tf+" || this->of_kinetic_ == "wt" - || this->of_kinetic_ == "lkt") + if (this->of_kinetic_ == "vw" + || this->of_kinetic_ == "tf+" + || this->of_kinetic_ == "wt" + || this->of_kinetic_ == "lkt") { this->vw_->vw_potential(pphi, this->pw_rho, rpot); } @@ -95,21 +114,28 @@ void ESolver_OF::kinetic_potential(double** prho, double** pphi, ModuleBase::mat */ double ESolver_OF::kinetic_energy() { - double kinetic_energy = 0.; + double kinetic_energy = 0.0; - if (this->of_kinetic_ == "tf" || this->of_kinetic_ == "tf+" || this->of_kinetic_ == "wt") + if (this->of_kinetic_ == "tf" + || this->of_kinetic_ == "tf+" + || this->of_kinetic_ == "wt") { kinetic_energy += this->tf_->tf_energy; } - if (this->of_kinetic_ == "vw" || this->of_kinetic_ == "tf+" || this->of_kinetic_ == "wt" - || this->of_kinetic_ == "lkt") + + if (this->of_kinetic_ == "vw" + || this->of_kinetic_ == "tf+" + || this->of_kinetic_ == "wt" + || this->of_kinetic_ == "lkt") { kinetic_energy += this->vw_->vw_energy; } + if (this->of_kinetic_ == "wt") { kinetic_energy += this->wt_->wt_energy; } + if (this->of_kinetic_ == "lkt") { kinetic_energy += this->lkt_->lkt_energy; @@ -139,17 +165,20 @@ void ESolver_OF::kinetic_stress(ModuleBase::matrix& kinetic_stress_) this->tf_->get_stress(this->pelec->omega); kinetic_stress_ += this->tf_->stress; } + if (this->of_kinetic_ == "vw" || this->of_kinetic_ == "tf+" || this->of_kinetic_ == "wt" || this->of_kinetic_ == "lkt") { this->vw_->get_stress(this->pphi_, this->pw_rho); kinetic_stress_ += this->vw_->stress; } + if (this->of_kinetic_ == "wt") { this->wt_->get_stress(pelec->charge->rho, this->pw_rho, GlobalV::of_vw_weight); kinetic_stress_ += this->wt_->stress; } + if (this->of_kinetic_ == "lkt") { this->lkt_->get_stress(pelec->charge->rho, this->pw_rho); @@ -163,21 +192,27 @@ void ESolver_OF::kinetic_stress(ModuleBase::matrix& kinetic_stress_) */ void ESolver_OF::init_opt() { - if (this->opt_dcsrch_ == nullptr) - this->opt_dcsrch_ = new ModuleBase::Opt_DCsrch(); + if (this->opt_dcsrch_ == nullptr) + { + this->opt_dcsrch_ = new ModuleBase::Opt_DCsrch(); + } if (this->of_method_ == "tn") { - if (this->opt_tn_ == nullptr) - this->opt_tn_ = new ModuleBase::Opt_TN(); + if (this->opt_tn_ == nullptr) + { + this->opt_tn_ = new ModuleBase::Opt_TN(); + } this->opt_tn_->allocate(this->pw_rho->nrxx); this->opt_tn_->set_para(this->dV_); } else if (this->of_method_ == "cg1" || this->of_method_ == "cg2") { - if (this->opt_cg_ == nullptr) - this->opt_cg_ = new ModuleBase::Opt_CG(); - this->opt_cg_->allocate(this->pw_rho->nrxx); + if (this->opt_cg_ == nullptr) + { + this->opt_cg_ = new ModuleBase::Opt_CG(); + } + this->opt_cg_->allocate(this->pw_rho->nrxx); this->opt_cg_->set_para(this->dV_); this->opt_dcsrch_->set_paras(1e-4, 1e-2); } @@ -242,9 +277,10 @@ void ESolver_OF::get_direction() */ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& ucell) { - double temp_energy = 0.; // energy of temp_phi and temp_rho - double kinetic_energy = 0.; // kinetic energy - double pseudopot_energy = 0.; // electron-ion interaction energy + double temp_energy = 0.0; // energy of temp_phi and temp_rho + double kinetic_energy = 0.0; // kinetic energy + double pseudopot_energy = 0.0; // electron-ion interaction energy + if (GlobalV::NSPIN == 1) { int numDC = 0; // iteration number of line search @@ -412,4 +448,4 @@ void ESolver_OF::get_step_length(double* dEdtheta, double** ptemp_phi, UnitCell& ModuleBase::WARNING_QUIT("esolver_of", "Sorry, SPIN4 case is not supported by OFDFT for now."); } } -} // namespace ModuleESolver \ No newline at end of file +} // namespace ModuleESolver From 8eddd5a452486527dd74e491cd214cc70c9c3ef7 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 23:00:01 +0800 Subject: [PATCH 14/46] change GlobalC::ucell to ucell in esolver_ks.cpp --- source/module_esolver/esolver_ks.cpp | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index c0252444eed..f0ec3d49c2e 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -98,24 +98,24 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) double ** atom_coord; std::vector filename_list; - atom_type = new int [GlobalC::ucell.nat]; - atom_coord = new double * [GlobalC::ucell.nat]; - filename_list.resize(GlobalC::ucell.ntype); + atom_type = new int [ucell.nat]; + atom_coord = new double * [ucell.nat]; + filename_list.resize(ucell.ntype); - for(int ia = 0; ia < GlobalC::ucell.nat; ia ++) + for(int ia = 0; ia < ucell.nat; ia ++) { atom_coord[ia] = new double [3]; } int iat = 0; - for(int it = 0; it < GlobalC::ucell.ntype; it ++) + for(int it = 0; it < ucell.ntype; it ++) { - for(int ia = 0; ia < GlobalC::ucell.atoms[it].na; ia ++) + for(int ia = 0; ia < ucell.atoms[it].na; ia ++) { atom_type[iat] = it; - atom_coord[iat][0] = GlobalC::ucell.atoms[it].taud[ia].x; - atom_coord[iat][1] = GlobalC::ucell.atoms[it].taud[ia].y; - atom_coord[iat][2] = GlobalC::ucell.atoms[it].taud[ia].z; + atom_coord[iat][0] = ucell.atoms[it].taud[ia].x; + atom_coord[iat][1] = ucell.atoms[it].taud[ia].y; + atom_coord[iat][2] = ucell.atoms[it].taud[ia].z; iat ++; } } @@ -135,24 +135,24 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) if (line.find("PAW_FILES") != std::string::npos) break; } - for(int it = 0; it < GlobalC::ucell.ntype; it++) + for(int it = 0; it < ucell.ntype; it++) { ifa >> filename_list[it]; } } #ifdef __MPI - for(int it = 0; it < GlobalC::ucell.ntype; it++) + for(int it = 0; it < ucell.ntype; it++) { Parallel_Common::bcast_string(filename_list[it]); } #endif GlobalC::paw_cell.init_paw_cell(INPUT.ecutwfc, INPUT.cell_factor, - GlobalC::ucell.omega,GlobalC::ucell.nat,GlobalC::ucell.ntype, + ucell.omega,ucell.nat,ucell.ntype, atom_type,(const double **) atom_coord, filename_list); - for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) + for(int iat = 0; iat < ucell.nat; iat ++) { delete [] atom_coord[iat]; } @@ -234,10 +234,10 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) pw_big->bz); // mohan add 2010-07-22, update 2011-05-04 // Calculate Structure factor - this->sf.setup_structure_factor(&GlobalC::ucell, this->pw_rhod); + this->sf.setup_structure_factor(&ucell, this->pw_rhod); // Initialize charge extrapolation - CE.Init_CE(GlobalC::ucell.nat); + CE.Init_CE(ucell.nat); #ifdef USE_PAW if(GlobalV::use_paw) @@ -268,7 +268,7 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) { GlobalC::paw_cell.get_rhoijp(rhoijp, rhoijselect, nrhoijsel); - for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) + for(int iat = 0; iat < ucell.nat; iat ++) { GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); } @@ -276,7 +276,7 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) #else GlobalC::paw_cell.get_rhoijp(rhoijp, rhoijselect, nrhoijsel); - for(int iat = 0; iat < GlobalC::ucell.nat; iat ++) + for(int iat = 0; iat < ucell.nat; iat ++) { GlobalC::paw_cell.set_rhoij(iat,nrhoijsel[iat],rhoijselect[iat].size(),rhoijselect[iat].data(),rhoijp[iat].data()); } From bcf4d54899103fd7e9377c91cfeae6ae69786733 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Wed, 27 Mar 2024 23:03:39 +0800 Subject: [PATCH 15/46] remove some GlobalC::ucell in esolver_sdft_pw.cpp --- source/module_esolver/esolver_sdft_pw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/module_esolver/esolver_sdft_pw.cpp b/source/module_esolver/esolver_sdft_pw.cpp index 2b4e16010e6..e41e8629b15 100644 --- a/source/module_esolver/esolver_sdft_pw.cpp +++ b/source/module_esolver/esolver_sdft_pw.cpp @@ -45,7 +45,7 @@ void ESolver_SDFT_PW::Init(Input& inp, UnitCell& ucell) this->pelec = new elecstate::ElecStatePW_SDFT(pw_wfc, &(chr), (K_Vectors*)(&(kv)), - &GlobalC::ucell, + &ucell, &(GlobalC::ppcell), this->pw_rhod, this->pw_rho, @@ -53,14 +53,14 @@ void ESolver_SDFT_PW::Init(Input& inp, UnitCell& ucell) // Inititlize the charge density. this->pelec->charge->allocate(GlobalV::NSPIN); - this->pelec->omega = GlobalC::ucell.omega; + this->pelec->omega = ucell.omega; // Initializee the potential. if (this->pelec->pot == nullptr) { this->pelec->pot = new elecstate::Potential(pw_rhod, pw_rho, - &GlobalC::ucell, + &ucell, &(GlobalC::ppcell.vloc), &(sf), &(this->pelec->f_en.etxc), From 1ca65747cbd89b0db27d6627ee1601370a13d347 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Thu, 28 Mar 2024 09:31:32 +0800 Subject: [PATCH 16/46] refactor the code before getting rid of RA in esolver_lcao --- source/module_esolver/esolver_ks_lcao.cpp | 29 ++++++---------- source/module_io/output_dm1.cpp | 29 ++++++++++------ source/module_io/output_dm1.h | 27 ++++++++++----- source/module_io/write_dm_sparse.cpp | 41 +++++++++++++++++------ source/module_io/write_dm_sparse.h | 3 ++ 5 files changed, 80 insertions(+), 49 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 905ddea95a6..73ff8336526 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -416,7 +416,10 @@ void ESolver_KS_LCAO::postprocess() template -void ESolver_KS_LCAO::Init_Basis_lcao(ORB_control& orb_con, Input& inp, UnitCell& ucell) +void ESolver_KS_LCAO::Init_Basis_lcao( + ORB_control& orb_con, + Input& inp, + UnitCell& ucell) { // autoset NB2D first if (GlobalV::NB2D == 0) @@ -457,22 +460,6 @@ void ESolver_KS_LCAO::Init_Basis_lcao(ORB_control& orb_con, Input& inp, two_center_bundle->build_orb_onsite(ucell.ntype, GlobalV::onsite_radius); // currently deepks only use one descriptor file, so cast bool to int is fine - //this->orb_con.read_orb_first(GlobalV::ofs_running, - // GlobalC::ORB, - // ucell.ntype, - // GlobalV::global_orbital_dir, - // ucell.orbital_fn, - // ucell.descriptor_file, - // ucell.lmax, - // inp.lcao_ecut, - // inp.lcao_dk, - // inp.lcao_dr, - // inp.lcao_rmax, - // GlobalV::deepks_setorb, - // inp.out_mat_r, - // GlobalV::CAL_FORCE, - // GlobalV::MY_RANK); - // TODO Due to the omnipresence of GlobalC::ORB, we still have to rely // on the old interface for now. two_center_bundle->to_LCAO_Orbitals(GlobalC::ORB, @@ -884,11 +871,17 @@ void ESolver_KS_LCAO::eachiterfinish(int iter) for (int ik = 0;ik < this->kv.nks;++ik) { ModuleBase::GlobalFunc::ZEROS(Hexxk_save.data(), Hexxk_save.size()); + hamilt::OperatorEXX> opexx_save(&this->LM, nullptr, &Hexxk_save, this->kv); + opexx_save.contributeHk(ik); + GlobalC::restart.save_disk("Hexx", ik, this->LOWF.ParaV->get_local_size(), Hexxk_save.data()); } - if (GlobalV::MY_RANK == 0)GlobalC::restart.save_disk("Eexx", 0, 1, &this->pelec->f_en.exx); + if (GlobalV::MY_RANK == 0) + { + GlobalC::restart.save_disk("Eexx", 0, 1, &this->pelec->f_en.exx); + } } #endif //----------------------------------- diff --git a/source/module_io/output_dm1.cpp b/source/module_io/output_dm1.cpp index 9087431bf25..21f78295e9c 100644 --- a/source/module_io/output_dm1.cpp +++ b/source/module_io/output_dm1.cpp @@ -5,32 +5,39 @@ namespace ModuleIO { -Output_DM1::Output_DM1(int nspin, int istep, Local_Orbital_Charge& LOC, Record_adj& RA, - K_Vectors& kv, const elecstate::DensityMatrix,double>* DM) - : _nspin(nspin), _istep(istep), _LOC(LOC), _RA(RA), _kv(kv), _DM(DM) +Output_DM1::Output_DM1( + int nspin, + int istep, + Local_Orbital_Charge& LOC, + Record_adj &RA, + K_Vectors& kv, + const elecstate::DensityMatrix,double>* DM) + : _nspin(nspin), _istep(istep), loc(LOC), _RA(RA), _kv(kv), _DM(DM) { } -void Output_DM1::write() +void Output_DM1::write(void) { double** dm2d; dm2d = new double*[_nspin]; for (int is = 0; is < _nspin; is++) { - dm2d[is] = new double[_LOC.ParaV->nnr]; - ModuleBase::GlobalFunc::ZEROS(dm2d[is], _LOC.ParaV->nnr); + dm2d[is] = new double[loc.ParaV->nnr]; + ModuleBase::GlobalFunc::ZEROS(dm2d[is], loc.ParaV->nnr); } + // get DMK from DM - _LOC.dm_k.resize(_kv.nks); + loc.dm_k.resize(_kv.nks); for (int ik = 0; ik < _kv.nks; ++ik) { - _LOC.set_dm_k(ik,_DM->get_DMK_pointer(ik)); + loc.set_dm_k(ik,_DM->get_DMK_pointer(ik)); } + // cal DMR in LOC - _LOC.cal_dm_R(_LOC.dm_k, _RA, dm2d, _kv); + loc.cal_dm_R(loc.dm_k, _RA, dm2d, _kv); for (int is = 0; is < _nspin; is++) { - write_dm1(is, _istep, dm2d, _LOC.ParaV, _LOC.DMR_sparse); + write_dm1(is, _istep, dm2d, loc.ParaV, loc.DMR_sparse); } for (int is = 0; is < _nspin; is++) @@ -40,4 +47,4 @@ void Output_DM1::write() delete[] dm2d; } -} // namespace ModuleIO \ No newline at end of file +} // namespace ModuleIO diff --git a/source/module_io/output_dm1.h b/source/module_io/output_dm1.h index fd0e39723fc..1e835077d81 100644 --- a/source/module_io/output_dm1.h +++ b/source/module_io/output_dm1.h @@ -14,18 +14,27 @@ namespace ModuleIO class Output_DM1 : public Output_Interface { public: - Output_DM1(int nspin, int istep, Local_Orbital_Charge& LOC, Record_adj& RA, K_Vectors& kv, const elecstate::DensityMatrix,double>* DM); - void write() override; + Output_DM1( + int nspin, + int istep, + Local_Orbital_Charge& LOC, + Record_adj& RA, + K_Vectors& kv, + const elecstate::DensityMatrix,double>* DM); + + void write() override; private: - int _nspin; - int _istep; - Local_Orbital_Charge& _LOC; - Record_adj& _RA; - K_Vectors& _kv; - const elecstate::DensityMatrix,double>* _DM; + + int _nspin; + int _istep; + Local_Orbital_Charge& loc; + Record_adj& _RA; + K_Vectors& _kv; + const elecstate::DensityMatrix,double>* _DM; + }; } // namespace ModuleIO -#endif \ No newline at end of file +#endif diff --git a/source/module_io/write_dm_sparse.cpp b/source/module_io/write_dm_sparse.cpp index f6851a9cf8a..a67f08167d2 100644 --- a/source/module_io/write_dm_sparse.cpp +++ b/source/module_io/write_dm_sparse.cpp @@ -6,8 +6,13 @@ #include "module_cell/module_neighbor/sltk_grid_driver.h" #include "module_hamilt_pw/hamilt_pwdft/global.h" -void ModuleIO::write_dm1(const int &is, const int &istep, double** dm2d, const Parallel_Orbitals* ParaV, - std::map, std::map>> &DMR_sparse) +void ModuleIO::write_dm1( + const int &is, + const int &istep, + double** dm2d, + const Parallel_Orbitals* ParaV, + std::map, + std::map>> &DMR_sparse) { ModuleBase::timer::tick("ModuleIO","write_dm"); ModuleBase::TITLE("ModuleIO","write_dm"); @@ -19,8 +24,11 @@ void ModuleIO::write_dm1(const int &is, const int &istep, double** dm2d, const P ModuleBase::timer::tick("ModuleIO","write_dm"); } -void ModuleIO::get_dm_sparse(const int &is, double** dm2d, const Parallel_Orbitals* ParaV, - std::map, std::map>> &DMR_sparse) +void ModuleIO::get_dm_sparse( + const int &is, + double** dm2d, + const Parallel_Orbitals* ParaV, + std::map, std::map>> &DMR_sparse) { ModuleBase::timer::tick("ModuleIO","get_dm_sparse"); ModuleBase::TITLE("ModuleIO","get_dm_sparse"); @@ -31,7 +39,7 @@ void ModuleIO::get_dm_sparse(const int &is, double** dm2d, const Parallel_Orbita ModuleBase::Vector3 dtau, tau1, tau2; ModuleBase::Vector3 dtau1, dtau2, tau0; - double temp_value_double; + double temp_value_double = 0.0; for(int T1 = 0; T1 < GlobalC::ucell.ntype; ++T1) { @@ -56,7 +64,10 @@ void ModuleIO::get_dm_sparse(const int &is, double** dm2d, const Parallel_Orbita bool adj = false; - if(distance < rcut) adj = true; + if(distance < rcut) + { + adj = true; + } else if(distance >= rcut) { for(int ad0 = 0; ad0 < GlobalC::GridD.getAdjacentNum()+1; ++ad0) @@ -85,21 +96,24 @@ void ModuleIO::get_dm_sparse(const int &is, double** dm2d, const Parallel_Orbita { const int start2 = GlobalC::ucell.itiaiw2iwt(T2,I2,0); - Abfs::Vector3_Order dR(GlobalC::GridD.getBox(ad).x, GlobalC::GridD.getBox(ad).y, GlobalC::GridD.getBox(ad).z); + Abfs::Vector3_Order dR( + GlobalC::GridD.getBox(ad).x, + GlobalC::GridD.getBox(ad).y, + GlobalC::GridD.getBox(ad).z); for(int ii=0; iinw; ii++) { const int iw1_all = start + ii; const int mu = ParaV->global2local_row(iw1_all); - if(mu<0)continue; + if(mu<0) continue; for(int jj=0; jjnw; jj++) { int iw2_all = start2 + jj; const int nu = ParaV->global2local_col(iw2_all); - if(nu<0)continue; + if(nu<0) continue; temp_value_double = dm2d[is][index]; if (std::abs(temp_value_double) > sparse_threshold) @@ -118,8 +132,12 @@ void ModuleIO::get_dm_sparse(const int &is, double** dm2d, const Parallel_Orbita ModuleBase::timer::tick("ModuleIO","get_dm_sparse"); } -void ModuleIO::write_dm_sparse(const int &is, const int &istep, const Parallel_Orbitals* ParaV, - std::map, std::map>> &DMR_sparse) + +void ModuleIO::write_dm_sparse( + const int &is, + const int &istep, + const Parallel_Orbitals* ParaV, + std::map, std::map>> &DMR_sparse) { ModuleBase::timer::tick("ModuleIO","write_dm_sparse"); ModuleBase::TITLE("ModuleIO","write_dm_sparse"); @@ -245,6 +263,7 @@ void ModuleIO::write_dm_sparse(const int &is, const int &istep, const Parallel_O ModuleBase::timer::tick("ModuleIO","write_dm_sparse"); } + void ModuleIO::destroy_dm_sparse(std::map, std::map>> &DMR_sparse) { std::map, std::map>> empty_DMR_sparse; diff --git a/source/module_io/write_dm_sparse.h b/source/module_io/write_dm_sparse.h index fae6d43ad95..0a5ad3e4984 100644 --- a/source/module_io/write_dm_sparse.h +++ b/source/module_io/write_dm_sparse.h @@ -10,10 +10,13 @@ namespace ModuleIO { void write_dm1(const int &is, const int &istep, double** dm2d, const Parallel_Orbitals* ParaV, std::map, std::map>> &DMR_sparse); + void get_dm_sparse(const int &is, double** dm2d, const Parallel_Orbitals* ParaV, std::map, std::map>> &DMR_sparse); + void write_dm_sparse(const int &is, const int &istep, const Parallel_Orbitals* ParaV, std::map, std::map>> &DMR_sparse); + void destroy_dm_sparse( std::map, std::map>> &DMR_sparse); } From 7987684b25717f8aa44ded5447ca279d3c630e28 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Thu, 28 Mar 2024 09:51:22 +0800 Subject: [PATCH 17/46] refactor before getting rid of LOWF --- source/module_esolver/esolver_ks_lcao.cpp | 16 +++- .../hamilt_lcaodft/local_orbital_charge.h | 26 ++++--- .../hamilt_lcaodft/local_orbital_wfc.cpp | 76 +++++++++++-------- .../hamilt_lcaodft/local_orbital_wfc.h | 33 +++++--- 4 files changed, 92 insertions(+), 59 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 73ff8336526..24543902ab0 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -511,7 +511,8 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) this->p_chgmix->mixing_restart = GlobalV::SCF_NMAX + 1; } // for mixing restart - if (iter == this->p_chgmix->mixing_restart && GlobalV::MIXING_RESTART > 0.0) + if (iter == this->p_chgmix->mixing_restart + && GlobalV::MIXING_RESTART > 0.0) { this->p_chgmix->init_mixing(); if (GlobalV::MIXING_DMR) // for mixing_dmr @@ -530,8 +531,9 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) // mohan move it outside 2011-01-13 // first need to calculate the weight according to // electrons number. - - if (istep == 0 && this->wf.init_wfc == "file" && this->LOWF.error == 0) + if (istep == 0 + && this->wf.init_wfc == "file" + && this->LOWF.error == 0) { if (iter == 1) { @@ -570,7 +572,11 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) { GlobalC::ucell.cal_ux(); } + + //! update the potentials by using new electron charge density this->pelec->pot->update_from_charge(this->pelec->charge, &GlobalC::ucell); + + //! compute the correction energy for metals this->pelec->f_en.descf = this->pelec->cal_delta_escf(); } } @@ -599,13 +605,15 @@ void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) dynamic_cast*>(this->pelec) ->get_DM(); } - GlobalC::dftu.cal_slater_UJ(this->pelec->charge->rho, this->pw_rho->nrxx); // Calculate U and J if Yukawa potential is used + // Calculate U and J if Yukawa potential is used + GlobalC::dftu.cal_slater_UJ(this->pelec->charge->rho, this->pw_rho->nrxx); } #ifdef __DEEPKS // the density matrixes of DeePKS have been updated in each iter GlobalC::ld.set_hr_cal(true); + // HR in HamiltLCAO should be recalculate if(GlobalV::deepks_scf) { diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h index 1ce3787ae3b..50049ee970c 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h @@ -13,6 +13,10 @@ #include "module_psi/psi.h" #include "module_elecstate/elecstate.h" #include "module_hamilt_lcao/hamilt_lcaodft/DM_gamma_2d_to_grid.h" + + +// try to get rid of this class, so please do not use it +// in new code anymoer, mohan 2024-03-28 class Local_Orbital_Charge { public: @@ -27,21 +31,24 @@ class Local_Orbital_Charge psi::Psi* psi, const K_Vectors& kv, const int& istep); + void allocate_dm_wfc(const Grid_Technique& gt, elecstate::ElecState* pelec, Local_Orbital_wfc& lowf, psi::Psi>* psi, const K_Vectors& kv, const int& istep); - //----------------- + // in DM_gamma.cpp - //----------------- - void allocate_gamma(const int& lgd, psi::Psi* psid, elecstate::ElecState* pelec, const int& nks, const int& istep); + void allocate_gamma(const int& lgd, + psi::Psi* psid, + elecstate::ElecState* pelec, + const int& nks, + const int& istep); + void cal_dk_gamma_from_2D_pub(void); - //----------------- // in DM_k.cpp - //----------------- void allocate_DM_k(const int& nks, const int& nnrg); // liaochen modify on 2010-3-23 @@ -53,9 +60,7 @@ class Local_Orbital_Charge static int out_dm; // output density matrix or not. static int out_dm1; - //----------------- // in dm_2d.cpp - //----------------- // dm stands for density matrix std::vector dm_gamma; // dm_gamma[is](iw1,iw2); std::vector dm_k; // dm_k[ik](iw1,iw2); @@ -72,13 +77,10 @@ class Local_Orbital_Charge double** dm2d, const K_Vectors& kv); //output, dm2d[NSPIN][LNNR] - //----------------- // wavefunctions' pointer - //----------------- Local_Orbital_wfc* LOWF; - //----------------- + // Parallel Variables' pointer - //----------------- const Parallel_Orbitals* ParaV; //temporary set it to public for ElecStateLCAO class, would be refactor later @@ -87,12 +89,14 @@ class Local_Orbital_Charge std::map, std::map>> DMR_sparse; void set_dm_k(int ik, std::complex* dm_k_in); // set dm_k from a pointer + void set_dm_gamma(int is, double* dm_gamma_in); // set dm_gamma from a pointer private: // whether the DM array has been allocated bool init_DM; + // whether the DM(R) array has been allocated bool init_DM_R; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.cpp index a242e20a770..cbf4ab56e7a 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.cpp @@ -40,7 +40,11 @@ void Local_Orbital_wfc::gamma_file(psi::Psi* psid, elecstate::ElecState* //allocate psi int ncol = this->ParaV->ncol_bands; - if (GlobalV::KS_SOLVER == "genelpa" || GlobalV::KS_SOLVER == "lapack_gvx" || GlobalV::KS_SOLVER == "scalapack_gvx" || GlobalV::KS_SOLVER == "cg_in_lcao" + + if (GlobalV::KS_SOLVER == "genelpa" + || GlobalV::KS_SOLVER == "lapack_gvx" + || GlobalV::KS_SOLVER == "scalapack_gvx" + || GlobalV::KS_SOLVER == "cg_in_lcao" #ifdef __CUSOLVER_LCAO || GlobalV::KS_SOLVER == "cusolver" #endif @@ -48,6 +52,7 @@ void Local_Orbital_wfc::gamma_file(psi::Psi* psid, elecstate::ElecState* { ncol = this->ParaV->ncol; } + if (psid == nullptr) { ModuleBase::WARNING_QUIT("gamma_file", "psid should be allocated first!"); @@ -125,10 +130,8 @@ void Local_Orbital_wfc::allocate_k(const int& lgd, } // allocate the second part. //if(lgd != 0) xiaohui modify 2015-02-04, fixed memory bug - //if(lgd != 0 && this->complex_flag == false) if(lgd != 0) { - //std::cout<<"lgd="<) * GlobalV::NBANDS*GlobalV::NLOCAL); - //ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"MemoryForWaveFunctions (MB)",mem); - //std::cout<<"wfc_k_grid["<complex_flag = true; } } @@ -152,7 +151,10 @@ void Local_Orbital_wfc::allocate_k(const int& lgd, } else if (INPUT.init_wfc == "file") { - if (istep > 0)return; + if (istep > 0) + { + return; + } std::cout << " Read in wave functions files: " << nkstot << std::endl; if (psi == nullptr) { @@ -201,6 +203,8 @@ void Local_Orbital_wfc::allocate_k(const int& lgd, return; } + + int Local_Orbital_wfc::globalIndex(int localindex, int nblk, int nprocs, int myproc) { int iblock, gIndex; @@ -229,9 +233,9 @@ void Local_Orbital_wfc::wfc_2d_to_grid(const int istep, const Parallel_Orbitals* pv = this->ParaV; const int inc = 1; - int myid; + int myid=0; MPI_Comm_rank(pv->comm_2D, &myid); - int info; + int info=0; //calculate maxnloc for bcasting 2d-wfc long maxnloc; // maximum number of elements in local matrix @@ -268,14 +272,18 @@ void Local_Orbital_wfc::wfc_2d_to_grid(const int istep, info=MPI_Bcast(naroc, 2, MPI_INT, src_rank, pv->comm_2D); info=MPI_Bcast(work, maxnloc, MPI_DOUBLE, src_rank, pv->comm_2D); - if (out_wfc_lcao) - info = this->set_wfc_grid(naroc, pv->nb, - pv->dim0, pv->dim1, iprow, ipcol, - work, wfc_grid, myid, ctot); - else - info = this->set_wfc_grid(naroc, pv->nb, - pv->dim0, pv->dim1, iprow, ipcol, - work, wfc_grid); + if (out_wfc_lcao) + { + info = this->set_wfc_grid(naroc, pv->nb, + pv->dim0, pv->dim1, iprow, ipcol, + work, wfc_grid, myid, ctot); + } + else + { + info = this->set_wfc_grid(naroc, pv->nb, + pv->dim0, pv->dim1, iprow, ipcol, + work, wfc_grid); + } }//loop ipcol }//loop iprow @@ -338,12 +346,12 @@ void Local_Orbital_wfc::wfc_2d_to_grid(const int istep, const Parallel_Orbitals* pv = this->ParaV; const int inc = 1; - int myid; + int myid=0; MPI_Comm_rank(pv->comm_2D, &myid); - int info; + int info=0; //calculate maxnloc for bcasting 2d-wfc - long maxnloc; // maximum number of elements in local matrix + long maxnloc=0; // maximum number of elements in local matrix info=MPI_Reduce(&pv->nloc_wfc, &maxnloc, 1, MPI_LONG, MPI_MAX, 0, pv->comm_2D); info=MPI_Bcast(&maxnloc, 1, MPI_LONG, 0, pv->comm_2D); std::complex *work=new std::complex[maxnloc]; // work/buffer matrix @@ -360,7 +368,7 @@ void Local_Orbital_wfc::wfc_2d_to_grid(const int istep, ModuleBase::Memory::record("LOWF::ctot", sizeof(std::complex) * GlobalV::NBANDS * GlobalV::NLOCAL); } - int naroc[2]; // maximum number of row or column + int naroc[2] = {0}; // maximum number of row or column for(int iprow=0; iprowdim0; ++iprow) { for(int ipcol=0; ipcoldim1; ++ipcol) @@ -377,15 +385,19 @@ void Local_Orbital_wfc::wfc_2d_to_grid(const int istep, info=MPI_Bcast(naroc, 2, MPI_INT, src_rank, pv->comm_2D); info = MPI_Bcast(work, maxnloc, MPI_DOUBLE_COMPLEX, src_rank, pv->comm_2D); - if (out_wfc_lcao) - info = this->set_wfc_grid(naroc, pv->nb, - pv->dim0, pv->dim1, iprow, ipcol, - work, wfc_grid, myid, ctot); - else - // mohan update 2021-02-12, delte BFIELD option - info = this->set_wfc_grid(naroc, pv->nb, - pv->dim0, pv->dim1, iprow, ipcol, - work, wfc_grid); + if (out_wfc_lcao) + { + info = this->set_wfc_grid(naroc, pv->nb, + pv->dim0, pv->dim1, iprow, ipcol, + work, wfc_grid, myid, ctot); + } + else + { + // mohan update 2021-02-12, delte BFIELD option + info = this->set_wfc_grid(naroc, pv->nb, + pv->dim0, pv->dim1, iprow, ipcol, + work, wfc_grid); + } }//loop ipcol }//loop iprow @@ -434,4 +446,4 @@ void Local_Orbital_wfc::wfc_2d_to_grid(const int istep, delete[] work; ModuleBase::timer::tick("Local_Orbital_wfc","wfc_2d_to_grid"); } -#endif \ No newline at end of file +#endif diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.h b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.h index c071d68ccfd..d994289029f 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.h @@ -81,7 +81,9 @@ class Local_Orbital_wfc #endif int error = 0; + private: + template int set_wfc_grid(int naroc[2], int nb, @@ -101,6 +103,7 @@ class Local_Orbital_wfc }; #ifdef __MPI +// the function should not be defined here!! mohan 2024-03-28 template int Local_Orbital_wfc::set_wfc_grid(int naroc[2], int nb, @@ -115,22 +118,28 @@ int Local_Orbital_wfc::set_wfc_grid(int naroc[2], { ModuleBase::TITLE(" Local_Orbital_wfc", "set_wfc_grid"); if (!wfc && !ctot) + { return 0; + } for (int j = 0; j < naroc[1]; ++j) { int igcol = globalIndex(j, nb, dim1, ipcol); - if (igcol >= GlobalV::NBANDS) - continue; - for (int i = 0; i < naroc[0]; ++i) - { - int igrow = globalIndex(i, nb, dim0, iprow); - int mu_local = this->gridt->trace_lo[igrow]; - if (wfc && mu_local >= 0) - { - wfc[igcol][mu_local] = work[j * naroc[0] + i]; - } - if (ctot && myid == 0) - ctot[igcol][igrow] = work[j * naroc[0] + i]; + if (igcol >= GlobalV::NBANDS) + { + continue; + } + for (int i = 0; i < naroc[0]; ++i) + { + int igrow = globalIndex(i, nb, dim0, iprow); + int mu_local = this->gridt->trace_lo[igrow]; + if (wfc && mu_local >= 0) + { + wfc[igcol][mu_local] = work[j * naroc[0] + i]; + } + if (ctot && myid == 0) + { + ctot[igcol][igrow] = work[j * naroc[0] + i]; + } } } return 0; From 186609fabad9de772eaad596157ddc4c98dc4260 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Thu, 28 Mar 2024 10:01:06 +0800 Subject: [PATCH 18/46] refactor before getting rid of LCAO_hamilt.h and LCAO_matrix.h --- source/module_esolver/esolver_ks_lcao.h | 13 +++ .../hamilt_lcaodft/LCAO_hamilt.h | 23 ++++- .../hamilt_lcaodft/LCAO_matrix.h | 83 +++++++++++++++---- 3 files changed, 104 insertions(+), 15 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index a6e2a20baad..579dd2244d2 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -45,12 +45,25 @@ namespace ModuleESolver virtual bool do_after_converge(int& iter) override; virtual void othercalculation(const int istep)override; + + // we will get rid of this class soon, don't use it, mohan 2024-03-28 ORB_control orb_con; //Basis_LCAO + + // we will get rid of this class soon, don't use it, mohan 2024-03-28 Record_adj RA; + + // we will get rid of this class soon, don't use it, mohan 2024-03-28 Local_Orbital_wfc LOWF; + + // we will get rid of this class soon, don't use it, mohan 2024-03-28 Local_Orbital_Charge LOC; + + // we will get rid of this class soon, don't use it, mohan 2024-03-28 LCAO_Hamilt UHM; + + // we will get rid of this class soon, don't use it, mohan 2024-03-28 LCAO_Matrix LM; + Grid_Technique GridT; std::unique_ptr two_center_bundle; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h index 53002629da8..90d23c4be30 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h @@ -18,25 +18,34 @@ class LCAO_Hamilt public: LCAO_Hamilt(); + ~LCAO_Hamilt(); void grid_prepare(const Grid_Technique& gt, const ModulePW::PW_Basis& rhopw, const ModulePW::PW_Basis_Big& bigpw); // jingan add 2021-6-4 void set_R_range_sparse(); + void calculate_HContainer_sparse_d(const int ¤t_spin, const double &sparse_threshold, const hamilt::HContainer& hR, std::map, std::map>>& target); + void calculate_HContainer_sparse_cd(const int ¤t_spin, const double &sparse_threshold, const hamilt::HContainer>& hR, std::map, std::map>>>& target); + void calculate_dSTN_R_sparse(const int ¤t_spin, const double &sparse_threshold); + void calculate_STN_R_sparse_for_S(const double &sparse_threshold); + void calculate_STN_R_sparse_for_T(const double &sparse_threshold); + void calculat_HR_dftu_sparse(const int ¤t_spin, const double &sparse_threshold); + void calculat_HR_dftu_soc_sparse(const int ¤t_spin, const double &sparse_threshold); + #ifdef __EXX template void calculate_HR_exx_sparse( const int ¤t_spin, @@ -44,13 +53,25 @@ class LCAO_Hamilt const int (&nmp)[3], const std::vector< std::map >, RI::Tensor > >>& Hexxs); #endif - void calculate_HSR_sparse(const int ¤t_spin, const double &sparse_threshold, const int (&nmp)[3], hamilt::Hamilt>* p_ham); + + void calculate_HSR_sparse( + const int ¤t_spin, + const double &sparse_threshold, + const int (&nmp)[3], + hamilt::Hamilt>* p_ham); + void calculate_SR_sparse(const double &sparse_threshold, hamilt::Hamilt>* p_ham); + void clear_zero_elements(const int ¤t_spin, const double &sparse_threshold); + void destroy_all_HSR_sparse(void); + void calculate_TR_sparse(const double &sparse_threshold); + void destroy_TR_sparse(void); + void calculate_dH_sparse(const int ¤t_spin, const double &sparse_threshold); + void destroy_dH_R_sparse(void); // used for gamma only algorithms. diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.h b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.h index 6f9d48faf6b..f395d051b8b 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.h @@ -192,41 +192,96 @@ class LCAO_Matrix double* DHloc_fixed_23; double* DHloc_fixed_33; - template - static void set_mat2d(const int& global_ir, const int& global_ic, const T& v, const Parallel_Orbitals& pv, T* mat); - void set_HSgamma(const int& iw1_all, const int& iw2_all, const double& v, double* HSloc); - void set_HSk(const int &iw1_all, const int &iw2_all, const std::complex &v, const char &dtype, const int spin = 0); - - void set_force (const int& iw1_all, const int& iw2_all, const double& vx, const double& vy, - const double& vz, const char &dtype); - void set_stress (const int& iw1_all, const int& iw2_all, const double& vx, const double& vy, - const double& vz, const char &dtype, const ModuleBase::Vector3 &dtau); - - void set_HR_tr(const int &Rx, const int &Ry, const int &Rz, const int &iw1_all, const int &iw2_all, const double &v); - void set_HR_tr_soc(const int &Rx, const int &Ry, const int &Rz, - const int &iw1_all, const int &iw2_all, const std::complex &v); //LiuXh add 2019-07-16 + template + static void set_mat2d( + const int& global_ir, + const int& global_ic, + const T& v, + const Parallel_Orbitals& pv, + T* mat); + + void set_HSgamma( + const int& iw1_all, + const int& iw2_all, + const double& v, + double* HSloc); + + void set_HSk( + const int &iw1_all, + const int &iw2_all, + const std::complex &v, + const char &dtype, + const int spin = 0); + + void set_force ( + const int& iw1_all, + const int& iw2_all, + const double& vx, + const double& vy, + const double& vz, + const char &dtype); + + void set_stress ( + const int& iw1_all, + const int& iw2_all, + const double& vx, + const double& vy, + const double& vz, + const char &dtype, + const ModuleBase::Vector3 &dtau); + + void set_HR_tr( + const int &Rx, + const int &Ry, + const int &Rz, + const int &iw1_all, + const int &iw2_all, + const double &v); + + void set_HR_tr_soc( + const int &Rx, + const int &Ry, + const int &Rz, + const int &iw1_all, + const int &iw2_all, + const std::complex &v); //LiuXh add 2019-07-16 void zeros_HSgamma(const char &mtype); + void zeros_HSk(const char &mtype); + void zeros_HSR(const char &mtype); void print_HSgamma(const char &mtype, std::ostream &os=std::cout); - void print_HSk(const char &mtype, const char &vtype = 'C', const double &accuracy = 1.0e-5, std::ostream &os=std::cout); + + void print_HSk( + const char &mtype, + const char &vtype = 'C', + const double &accuracy = 1.0e-5, + std::ostream &os=std::cout); + void update_Hloc(void); + void update_Hloc2(const int &ik); void allocate_HS_R(const int &nnr); void output_HSk(const char &mtype, std::string &fn); + //LiuXh add 2019-07-15 void allocate_Hloc_fixedR_tr(void); + void allocate_HR_tr(void); + void allocate_SlocR_tr(void); + void destroy_Hloc_fixedR_tr(void); // jingan add 2021-6-4, modify 2021-12-2 void destroy_HS_R_sparse(void); + void destroy_T_R_sparse(void); + void destroy_dH_R_sparse(void); }; From fc02fb84c318915681c602b709c1d9c01ee6eab9 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Thu, 28 Mar 2024 10:17:05 +0800 Subject: [PATCH 19/46] refactor wavefunc_in_pw --- .../hamilt_lcaodft/wavefunc_in_pw.cpp | 247 +----------------- .../hamilt_lcaodft/wavefunc_in_pw.h | 5 - 2 files changed, 6 insertions(+), 246 deletions(-) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/wavefunc_in_pw.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/wavefunc_in_pw.cpp index 1d0f480a321..7c7739dac99 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/wavefunc_in_pw.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/wavefunc_in_pw.cpp @@ -400,8 +400,10 @@ void Wavefunc_in_pw::produce_local_basis_in_pw(const int& ik, for(int m = 0;m<2*L+1;m++) { const int lm = L*L +m; - if (iwall + 2 * L + 1 > GlobalC::ucell.natomwfc) - ModuleBase::WARNING_QUIT("this->wf.atomic_wfc()", "error: too many wfcs"); + if (iwall + 2 * L + 1 > GlobalC::ucell.natomwfc) + { + ModuleBase::WARNING_QUIT("this->wf.atomic_wfc()", "error: too many wfcs"); + } for (int ig = 0; ig < npw; ig++) { aux[ig] = sk[ig] * ylm(lm,ig) * flq[ig]; @@ -430,7 +432,8 @@ void Wavefunc_in_pw::produce_local_basis_in_pw(const int& ik, } // end else GlobalC::ucell.atoms[it].has_so } // end for is_N } // end if GlobalV::NONCOLIN - else{//LSDA and nomagnet case + else + {//LSDA and nomagnet case for(int m=0; m<2*L+1; m++) { const int lm = L*L+m; @@ -455,241 +458,3 @@ void Wavefunc_in_pw::produce_local_basis_in_pw(const int& ik, delete[] gk; } -// void Wavefunc_in_pw::produce_local_basis_q_in_pw(const int &ik, -// ModuleBase::ComplexMatrix &psi, -// ModulePW::PW_Basis_K *wfc_basis, -// const ModuleBase::realArray &table_local, -// ModuleBase::Vector3 q) // pengfei 2016-11-23 -// { -// ModuleBase::TITLE("Wavefunc_in_pw","produce_local_basis_in_pw"); -// assert(ik>=0); -// const int npw = kv.ngk[ik]; -// const int total_lm = ( GlobalC::ucell.lmax + 1) * ( GlobalC::ucell.lmax + 1); -// ModuleBase::matrix ylm(total_lm, npw); -// std::complex *aux = new std::complex[npw]; -// double *chiaux = nullptr; - -// ModuleBase::Vector3 *gkq = new ModuleBase::Vector3[npw]; - -// for(int ig=0;iggetgpluskcar(ik, ig) + q; -// } - -// ModuleBase::YlmReal::Ylm_Real(total_lm, npw, gkq, ylm); - -// //int index = 0; -// double *flq = new double[npw]; -// int iwall=0; -// for (int it = 0;it < GlobalC::ucell.ntype;it++) -// { -// for (int ia = 0;ia < GlobalC::ucell.atoms[it].na;ia++) -// { -// std::complex *skq = GlobalC::sf.get_skq(ik, it, ia, wfc_basis, q); -// int ic=0; -// for(int L = 0; L < GlobalC::ucell.atoms[it].nwl+1; L++) -// { -// std::complex lphase = pow(ModuleBase::NEG_IMAG_UNIT, L); //mohan 2010-04-19 -// for(int N=0; N < GlobalC::ucell.atoms[it].l_nchi[L]; N++) -// { -// for(int ig=0; ig ((GlobalV::NQX-4) * GlobalV::DQ) ) -// { -// flq[ig] = 0.0; -// } -// else -// { -// flq[ig] = ModuleBase::PolyInt::Polynomial_Interpolation(table_local, it, ic, GlobalV::NQX, -// GlobalV::DQ, gkq[ig].norm() * GlobalC::ucell.tpiba ); -// } -// } - -// if(GlobalV::NSPIN==4) -// { -// Soc soc; -// soc.rot_ylm(GlobalC::ucell.atoms[it].nwl+1); -// for(int is_N = 0; is_N < 2; is_N++) -// { -// if(L==0&&is_N==1) continue; -// if(GlobalC::ucell.atoms[it].ncpp.has_so) -// { -// const double j = double(L+is_N) - 0.5; -// if ( !(GlobalV::DOMAG||GlobalV::DOMAG_Z)) -// {//atomic_wfc_so -// double fact[2]; -// for(int m=-L-1;m1e-8||fabs(fact[1])>1e-8) -// { -// for(int is=0;is<2;is++) -// { -// if(fabs(fact[is])>1e-8) -// { -// const int ind = GlobalC::ppcell.lmaxkb + soc.sph_ind(L,j,m,is); -// ModuleBase::GlobalFunc::ZEROS(aux, npw); -// for(int n1=0;n1<2*L+1;n1++){ -// const int lm = L*L +n1; -// if(std::abs(soc.rotylm(n1,ind))>1e-8) -// for(int ig=0; ignpwk_max*is ) = lphase * fact[is] * skq[ig] -// * aux[ig] -// * flq[ig]; -// } -// else -// for(int ig=0; ignpwk_max*is) = -// std::complex(0.0 , 0.0); -// }//is -// iwall++; -// }//if -// }//m -// }//if -// else -// {//atomic_wfc_so_mag - -// double alpha, gamma; -// std::complex fup,fdown; -// //int nc; -// //This routine creates two functions only in the case j=l+1/2 or exit in the other -// case if(fabs(j-L+0.5<1e-4)) continue; delete[] chiaux; chiaux = new double [npw]; -// //Find the functions j= l- 1/2 -// if(L==0) -// for(int ig=0;igGlobalC::ucell.natomwfc) -// ModuleBase::WARNING_QUIT("this->wf.atomic_wfc()","error: too many wfcs"); for(int ig = 0;ignpwk_max) = (cos(0.5 * gamma) - ModuleBase::IMAG_UNIT * -// sin(0.5*gamma)) -// * fdown; -// //second rotation with angle gamma around(OZ) -// fup = cos(0.5 * (alpha + ModuleBase::PI))*aux[ig]; -// fdown = ModuleBase::IMAG_UNIT * sin(0.5 * (alpha + ModuleBase::PI))*aux[ig]; -// psi(iwall+2*L+1,ig) = (cos(0.5*gamma) + -// ModuleBase::IMAG_UNIT*sin(0.5*gamma))*fup; psi(iwall+2*L+1,ig+ wfc_basis->npwk_max) -// = (cos(0.5*gamma) -// - ModuleBase::IMAG_UNIT*sin(0.5*gamma))*fdown; -// } -// iwall++; -// } -// iwall += 2*L +1; -// } -// } -// else -// {//atomic_wfc_nc -// double alpha, gamman; -// std::complex fup, fdown; -// //alpha = GlobalC::ucell.magnet.angle1_[it]; -// //gamman = -GlobalC::ucell.magnet.angle2_[it] + 0.5*ModuleBase::PI; -// alpha = GlobalC::ucell.atoms[it].angle1[ia]; -// gamman = -GlobalC::ucell.atoms[it].angle2[ia]+ 0.5*ModuleBase::PI; -// for(int m = 0;m<2*L+1;m++) -// { -// const int lm = L*L +m; -// // if(iwall+2*l+1>GlobalC::ucell.natomwfc) -// ModuleBase::WARNING_QUIT("this->wf.atomic_wfc()","error: too many wfcs"); for(int -// ig = 0;ignpwk_max) = (cos(0.5 * gamman) - ModuleBase::IMAG_UNIT * -// sin(0.5*gamman)) -// * fdown; -// //second rotation with angle gamma around(OZ) -// fup = cos(0.5 * (alpha + ModuleBase::PI)) * aux[ig]; -// fdown = ModuleBase::IMAG_UNIT * sin(0.5 * (alpha + ModuleBase::PI)) * aux[ig]; -// psi(iwall+2*L+1,ig) = (cos(0.5*gamman) + -// ModuleBase::IMAG_UNIT*sin(0.5*gamman))*fup; psi(iwall+2*L+1,ig+ wfc_basis->npwk_max) -// = (cos(0.5*gamman) -// - ModuleBase::IMAG_UNIT*sin(0.5*gamman))*fdown; -// } -// iwall++; -// } -// iwall += 2*L+1; -// } -// // iwall++; -// }//end is_N -// }//end if -// else{//LSDA and nomagnet case -// for(int m=0; m<2*L+1; m++) -// { -// const int lm = L*L+m; -// for(int ig=0; ig q); // pengfei 2016-11-23 } #endif From 7a8064f0e846e5428089adef6806b62cd34ba9b9 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Thu, 28 Mar 2024 10:28:59 +0800 Subject: [PATCH 20/46] refactor density matrix --- source/module_elecstate/elecstate_lcao.cpp | 16 ++-- .../module_dm/density_matrix.cpp | 89 ++++++++++--------- .../module_dm/density_matrix.h | 50 ++++++----- 3 files changed, 85 insertions(+), 70 deletions(-) diff --git a/source/module_elecstate/elecstate_lcao.cpp b/source/module_elecstate/elecstate_lcao.cpp index df9b3773760..6dd00a7f4f7 100644 --- a/source/module_elecstate/elecstate_lcao.cpp +++ b/source/module_elecstate/elecstate_lcao.cpp @@ -14,8 +14,10 @@ namespace elecstate template <> void ElecStateLCAO::print_psi(const psi::Psi& psi_in, const int istep) { - if (!ElecStateLCAO::out_wfc_lcao) - return; + if (!ElecStateLCAO::out_wfc_lcao) + { + return; + } // output but not do "2d-to-grid" conversion double** wfc_grid = nullptr; @@ -28,8 +30,11 @@ void ElecStateLCAO::print_psi(const psi::Psi& psi_in, const int template <> void ElecStateLCAO>::print_psi(const psi::Psi>& psi_in, const int istep) { - if (!ElecStateLCAO>::out_wfc_lcao && !ElecStateLCAO>::need_psi_grid) - return; + if (!ElecStateLCAO>::out_wfc_lcao + && !ElecStateLCAO>::need_psi_grid) + { + return; + } // output but not do "2d-to-grid" conversion std::complex** wfc_grid = nullptr; @@ -38,6 +43,7 @@ void ElecStateLCAO>::print_psi(const psi::Psilowf->wfc_k_grid[ik]; } + #ifdef __MPI this->lowf->wfc_2d_to_grid(istep, ElecStateLCAO>::out_wfc_flag, @@ -252,4 +258,4 @@ double ElecStateLCAO>::get_spin_constrain_energy() template class ElecStateLCAO; // Gamma_only case template class ElecStateLCAO>; // multi-k case -} // namespace elecstate \ No newline at end of file +} // namespace elecstate diff --git a/source/module_elecstate/module_dm/density_matrix.cpp b/source/module_elecstate/module_dm/density_matrix.cpp index 865245f905e..bdd1947d627 100644 --- a/source/module_elecstate/module_dm/density_matrix.cpp +++ b/source/module_elecstate/module_dm/density_matrix.cpp @@ -440,11 +440,11 @@ void DensityMatrix::cal_DMR_test() const int* r_index = tmp_ap.get_R_index(ir); hamilt::BaseMatrix* tmp_matrix = tmp_ap.find_matrix(r_index[0], r_index[1], r_index[2]); #ifdef __DEBUG - if (tmp_matrix == nullptr) - { - std::cout << "tmp_matrix is nullptr" << std::endl; - continue; - } + if (tmp_matrix == nullptr) + { + std::cout << "tmp_matrix is nullptr" << std::endl; + continue; + } #endif std::complex tmp_res; // loop over k-points @@ -515,44 +515,47 @@ void DensityMatrix, double>::cal_DMR() #endif // loop over k-points if(GlobalV::NSPIN !=4 ) - for (int ik = 0; ik < this->_nks; ++ik) - { - // cal k_phase - // if TK==std::complex, kphase is e^{ikR} - const ModuleBase::Vector3 dR(r_index[0], r_index[1], r_index[2]); - const double arg = (this->_kv->kvec_d[ik] * dR) * ModuleBase::TWO_PI; - double sinp, cosp; - ModuleBase::libm::sincos(arg, &sinp, &cosp); - std::complex kphase = std::complex(cosp, sinp); - // set DMR element - double* tmp_DMR_pointer = tmp_matrix->get_pointer(); - std::complex* tmp_DMK_pointer = this->_DMK[ik + ik_begin].data(); - double* DMK_real_pointer = nullptr; - double* DMK_imag_pointer = nullptr; - // jump DMK to fill DMR - // DMR is row-major, DMK is column-major - tmp_DMK_pointer += col_ap * this->_paraV->nrow + row_ap; - for (int mu = 0; mu < this->_paraV->get_row_size(iat1); ++mu) - { - DMK_real_pointer = (double*)tmp_DMK_pointer; - DMK_imag_pointer = DMK_real_pointer + 1; - BlasConnector::axpy(this->_paraV->get_col_size(iat2), - kphase.real(), - DMK_real_pointer, - ld_hk2, - tmp_DMR_pointer, - 1); - // "-" since i^2 = -1 - BlasConnector::axpy(this->_paraV->get_col_size(iat2), - -kphase.imag(), - DMK_imag_pointer, - ld_hk2, - tmp_DMR_pointer, - 1); - tmp_DMK_pointer += 1; - tmp_DMR_pointer += this->_paraV->get_col_size(iat2); - } - } + { + for (int ik = 0; ik < this->_nks; ++ik) + { + // cal k_phase + // if TK==std::complex, kphase is e^{ikR} + const ModuleBase::Vector3 dR(r_index[0], r_index[1], r_index[2]); + const double arg = (this->_kv->kvec_d[ik] * dR) * ModuleBase::TWO_PI; + double sinp, cosp; + ModuleBase::libm::sincos(arg, &sinp, &cosp); + std::complex kphase = std::complex(cosp, sinp); + // set DMR element + double* tmp_DMR_pointer = tmp_matrix->get_pointer(); + std::complex* tmp_DMK_pointer = this->_DMK[ik + ik_begin].data(); + double* DMK_real_pointer = nullptr; + double* DMK_imag_pointer = nullptr; + // jump DMK to fill DMR + // DMR is row-major, DMK is column-major + tmp_DMK_pointer += col_ap * this->_paraV->nrow + row_ap; + for (int mu = 0; mu < this->_paraV->get_row_size(iat1); ++mu) + { + DMK_real_pointer = (double*)tmp_DMK_pointer; + DMK_imag_pointer = DMK_real_pointer + 1; + BlasConnector::axpy(this->_paraV->get_col_size(iat2), + kphase.real(), + DMK_real_pointer, + ld_hk2, + tmp_DMR_pointer, + 1); + // "-" since i^2 = -1 + BlasConnector::axpy(this->_paraV->get_col_size(iat2), + -kphase.imag(), + DMK_imag_pointer, + ld_hk2, + tmp_DMR_pointer, + 1); + tmp_DMK_pointer += 1; + tmp_DMR_pointer += this->_paraV->get_col_size(iat2); + } + } + } + // treat DMR as pauli matrix when NSPIN=4 if(GlobalV::NSPIN==4) { diff --git a/source/module_elecstate/module_dm/density_matrix.h b/source/module_elecstate/module_dm/density_matrix.h index 519f798f5d4..1c758ae1395 100644 --- a/source/module_elecstate/module_dm/density_matrix.h +++ b/source/module_elecstate/module_dm/density_matrix.h @@ -15,28 +15,33 @@ namespace elecstate * = for Gamma-only calculation * = ,double> for multi-k calculation */ - template struct ShiftRealComplex - { - using type = void; - }; - template<> - struct ShiftRealComplex { - using type = std::complex; - }; - template<> - struct ShiftRealComplex> { - using type = double; - }; - - template - class DensityMatrix - { - using TRShift = typename ShiftRealComplex::type; - public: - /** - * @brief Destructor of class DensityMatrix - */ - ~DensityMatrix(); +template struct ShiftRealComplex +{ + using type = void; +}; + +template<> +struct ShiftRealComplex +{ + using type = std::complex; +}; + +template<> +struct ShiftRealComplex> +{ + using type = double; +}; + +template +class DensityMatrix +{ + using TRShift = typename ShiftRealComplex::type; + + public: + /** + * @brief Destructor of class DensityMatrix + */ + ~DensityMatrix(); /** * @brief Constructor of class DensityMatrix for multi-k calculation @@ -160,6 +165,7 @@ namespace elecstate * @brief get pointer of paraV */ const Parallel_Orbitals* get_paraV_pointer() const; + const K_Vectors* get_kv_pointer() const; /** From f95129d9c5337f2b8b0a5a71e7010029a7b03066 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Thu, 28 Mar 2024 10:31:37 +0800 Subject: [PATCH 21/46] refactor the format cal_dm_psi.cpp --- .../module_elecstate/module_dm/cal_dm_psi.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/source/module_elecstate/module_dm/cal_dm_psi.cpp b/source/module_elecstate/module_dm/cal_dm_psi.cpp index 4164294b759..58d58ea9596 100644 --- a/source/module_elecstate/module_dm/cal_dm_psi.cpp +++ b/source/module_elecstate/module_dm/cal_dm_psi.cpp @@ -44,8 +44,10 @@ void cal_dm_psi(const Parallel_Orbitals* ParaV, ModuleBase::WARNING_QUIT("ElecStateLCAO::cal_dm", "please check global2local_col!"); } } - if (ib_global >= wg.nc) - continue; + if (ib_global >= wg.nc) + { + continue; + } const double wg_local = wg(ik, ib_global); double* wg_wfc_pointer = &(wg_wfc(0, ib_local, 0)); BlasConnector::scal(nbasis_local, wg_local, wg_wfc_pointer, 1); @@ -107,9 +109,11 @@ void cal_dm_psi(const Parallel_Orbitals* ParaV, ModuleBase::WARNING_QUIT("ElecStateLCAO::cal_dm", "please check global2local_col!"); } } - if (ib_global >= wg.nc) - continue; - const double wg_local = wg(ik, ib_global); + if (ib_global >= wg.nc) + { + continue; + } + const double wg_local = wg(ik, ib_global); std::complex* wg_wfc_pointer = &(wg_wfc(0, ib_local, 0)); BlasConnector::scal(nbasis_local, wg_local, wg_wfc_pointer, 1); } @@ -233,7 +237,8 @@ void psiMulPsi(const psi::Psi>& psi1, const char N_char = 'N', T_char = 'T'; const int nlocal = psi1.get_nbasis(); const int nbands = psi1.get_nbands(); - const std::complex one_complex = {1.0, 0.0}, zero_complex = {0.0, 0.0}; + const std::complex one_complex = {1.0, 0.0}; + const std::complex zero_complex = {0.0, 0.0}; zgemm_(&N_char, &T_char, &nlocal, From 98234ae65366c83786476ae2222c225fe5faed4b Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sat, 30 Mar 2024 17:16:51 +0800 Subject: [PATCH 22/46] format forces.cpp --- .../module_hamilt_pw/hamilt_pwdft/forces.cpp | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/source/module_hamilt_pw/hamilt_pwdft/forces.cpp b/source/module_hamilt_pw/hamilt_pwdft/forces.cpp index e1a81d92174..7c2c15321f8 100644 --- a/source/module_hamilt_pw/hamilt_pwdft/forces.cpp +++ b/source/module_hamilt_pw/hamilt_pwdft/forces.cpp @@ -420,16 +420,22 @@ void Forces::cal_force(ModuleBase::matrix& force, { ModuleIO::print_force(GlobalV::ofs_running, GlobalC::ucell, "PAW FORCE (eV/Angstrom)", forcepaw, 0); } - if (GlobalV::EFIELD_FLAG) - ModuleIO::print_force(GlobalV::ofs_running, GlobalC::ucell, "EFIELD FORCE (eV/Angstrom)", force_e, 0); - if (GlobalV::GATE_FLAG) - ModuleIO::print_force(GlobalV::ofs_running, - GlobalC::ucell, - "GATEFIELD FORCE (eV/Angstrom)", - force_gate, - 0); - if (GlobalV::imp_sol) - ModuleIO::print_force(GlobalV::ofs_running, GlobalC::ucell, "IMP_SOL FORCE (eV/Angstrom)", forcesol, 0); + if (GlobalV::EFIELD_FLAG) + { + ModuleIO::print_force(GlobalV::ofs_running, GlobalC::ucell, "EFIELD FORCE (eV/Angstrom)", force_e, 0); + } + if (GlobalV::GATE_FLAG) + { + ModuleIO::print_force(GlobalV::ofs_running, + GlobalC::ucell, + "GATEFIELD FORCE (eV/Angstrom)", + force_gate, + 0); + } + if (GlobalV::imp_sol) + { + ModuleIO::print_force(GlobalV::ofs_running, GlobalC::ucell, "IMP_SOL FORCE (eV/Angstrom)", forcesol, 0); + } } ModuleIO::print_force(GlobalV::ofs_running, GlobalC::ucell, "TOTAL-FORCE (eV/Angstrom)", force, 0); @@ -1304,4 +1310,4 @@ void Forces::cal_force_scc(ModuleBase::matrix& forcescc, template class Forces; #if ((defined __CUDA) || (defined __ROCM)) template class Forces; -#endif \ No newline at end of file +#endif From 583214cacf0ab553bf27a05e4672f5c0a7b998a1 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sat, 30 Mar 2024 17:43:49 +0800 Subject: [PATCH 23/46] refactor esolver_of_tool.cpp --- source/module_esolver/esolver_of_tool.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/module_esolver/esolver_of_tool.cpp b/source/module_esolver/esolver_of_tool.cpp index 6eb398aaeb7..df44a329c81 100644 --- a/source/module_esolver/esolver_of_tool.cpp +++ b/source/module_esolver/esolver_of_tool.cpp @@ -291,6 +291,7 @@ void ESolver_OF::adjust_direction() */ void ESolver_OF::check_direction(double* dEdtheta, double** ptemp_phi, UnitCell& ucell) { + assert(GlobalV::NSPIN>0); double* temp_theta = new double[GlobalV::NSPIN]; ModuleBase::GlobalFunc::ZEROS(temp_theta, GlobalV::NSPIN); @@ -508,4 +509,4 @@ void ESolver_OF::print_info() context.center_title(); GlobalV::ofs_running << context.str() << std::endl; } -} // namespace ModuleESolver \ No newline at end of file +} // namespace ModuleESolver From 9505a9f0660b31438c3c01ea0026759655ab95d8 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 11:19:57 +0800 Subject: [PATCH 24/46] change member function beforescf in Esolver to before_scf --- source/module_esolver/esolver_ks.cpp | 2 +- source/module_esolver/esolver_ks.h | 2 +- source/module_esolver/esolver_ks_lcao.h | 3 ++- source/module_esolver/esolver_ks_lcao_elec.cpp | 8 ++++---- source/module_esolver/esolver_ks_pw.cpp | 12 +++++++----- source/module_esolver/esolver_ks_pw.h | 2 +- source/module_esolver/esolver_sdft_pw.cpp | 6 +++--- source/module_esolver/esolver_sdft_pw.h | 4 ++-- 8 files changed, 21 insertions(+), 18 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index f0ec3d49c2e..36f281ff2cf 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -381,7 +381,7 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) { ModuleBase::timer::tick(this->classname, "Run"); - this->beforescf(istep); //Something else to do before the iter loop + this->before_scf(istep); //Something else to do before the iter loop ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT SCF"); if(this->maxniter > 0) { diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index 9b2e898ce8d..fbdd29bd295 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -55,7 +55,7 @@ class ESolver_KS : public ESolver_FP protected: //! Something to do before SCF iterations. - virtual void beforescf(int istep) {}; + virtual void before_scf(int istep) {}; //! Something to do before hamilt2density function in each iter loop. virtual void eachiterinit(const int istep, const int iter) {}; diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index 579dd2244d2..aa18fc6de3e 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -16,6 +16,7 @@ #include "module_io/output_mat_sparse.h" #include "module_basis/module_nao/two_center_bundle.h" #include + namespace ModuleESolver { template @@ -36,7 +37,7 @@ namespace ModuleESolver void get_S(); protected: - virtual void beforescf(const int istep) override; + virtual void before_scf(const int istep) override; virtual void eachiterinit(const int istep, const int iter) override; virtual void hamilt2density(const int istep, const int iter, const double ethr) override; virtual void updatepot(const int istep, const int iter) override; diff --git a/source/module_esolver/esolver_ks_lcao_elec.cpp b/source/module_esolver/esolver_ks_lcao_elec.cpp index e16774c6f13..02ce26d2c01 100644 --- a/source/module_esolver/esolver_ks_lcao_elec.cpp +++ b/source/module_esolver/esolver_ks_lcao_elec.cpp @@ -273,10 +273,10 @@ void ESolver_KS_LCAO::beforesolver(const int istep) } template -void ESolver_KS_LCAO::beforescf(int istep) +void ESolver_KS_LCAO::before_scf(int istep) { - ModuleBase::TITLE("ESolver_KS_LCAO", "beforescf"); - ModuleBase::timer::tick("ESolver_KS_LCAO", "beforescf"); + ModuleBase::TITLE("ESolver_KS_LCAO", "before_scf"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "before_scf"); if (GlobalC::ucell.cell_parameter_updated) { @@ -335,7 +335,7 @@ void ESolver_KS_LCAO::beforescf(int istep) this->p_hamilt->non_first_scf = istep; - ModuleBase::timer::tick("ESolver_KS_LCAO", "beforescf"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "before_scf"); return; } diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index 0395ff660da..15b360d3acd 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -434,9 +434,9 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) } template -void ESolver_KS_PW::beforescf(int istep) +void ESolver_KS_PW::before_scf(int istep) { - ModuleBase::TITLE("ESolver_KS_PW", "beforescf"); + ModuleBase::TITLE("ESolver_KS_PW", "before_scf"); if (GlobalC::ucell.cell_parameter_updated) { @@ -523,7 +523,7 @@ void ESolver_KS_PW::beforescf(int istep) // before hamilt2density, we update Hk and initialize psi if(GlobalV::psi_initializer) { - // beforescf function will be called everytime before scf. However, once atomic coordinates changed, + // before_scf function will be called everytime before scf. However, once atomic coordinates changed, // structure factor will change, therefore all atomwise properties will change. So we need to reinitialize // psi every time before scf. But for random wavefunction, we dont, because random wavefunction is not // related to atomic coordinates. @@ -804,7 +804,7 @@ void ESolver_KS_PW::hamilt2density( // before hamilt2density, we update Hk and initialize psi if(GlobalV::psi_initializer) { - // beforescf function will be called everytime before scf. However, once atomic coordinates changed, + // before_scf function will be called everytime before scf. However, once atomic coordinates changed, // structure factor will change, therefore all atomwise properties will change. So we need to reinitialize // psi every time before scf. But for random wavefunction, we dont, because random wavefunction is not // related to atomic coordinates. @@ -1361,7 +1361,9 @@ void ESolver_KS_PW::nscf(void) ModuleBase::TITLE("ESolver_KS_PW", "nscf"); ModuleBase::timer::tick("ESolver_KS_PW", "nscf"); - this->beforescf(0); + // mohan add istep_tmp 2024-03-31 + const int istep_tmp = 0; + this->before_scf(istep_tmp); //! Setup the parameters for diagonalization double diag_ethr = GlobalV::PW_DIAG_THR; diff --git a/source/module_esolver/esolver_ks_pw.h b/source/module_esolver/esolver_ks_pw.h index d08a24f552b..284d5253126 100644 --- a/source/module_esolver/esolver_ks_pw.h +++ b/source/module_esolver/esolver_ks_pw.h @@ -88,7 +88,7 @@ class ESolver_KS_PW : public ESolver_KS protected: - virtual void beforescf(const int istep) override; + virtual void before_scf(const int istep) override; virtual void eachiterinit(const int istep, const int iter) override; diff --git a/source/module_esolver/esolver_sdft_pw.cpp b/source/module_esolver/esolver_sdft_pw.cpp index e41e8629b15..2826556ceaf 100644 --- a/source/module_esolver/esolver_sdft_pw.cpp +++ b/source/module_esolver/esolver_sdft_pw.cpp @@ -110,9 +110,9 @@ void ESolver_SDFT_PW::Init(Input& inp, UnitCell& ucell) } -void ESolver_SDFT_PW::beforescf(const int istep) +void ESolver_SDFT_PW::before_scf(const int istep) { - ESolver_KS_PW::beforescf(istep); + ESolver_KS_PW::before_scf(istep); if (istep > 0 && INPUT.nbands_sto != 0 && INPUT.initsto_freq > 0 && istep % INPUT.initsto_freq == 0) { Update_Sto_Orbitals(this->stowf, INPUT.seed_sto); @@ -369,7 +369,7 @@ void ESolver_SDFT_PW::nscf(void) std::cout << " DIGA_THR : " << diag_thr << std::endl; - this->beforescf(istep); + this->before_scf(istep); this->hamilt2density(istep, iter, diag_thr); diff --git a/source/module_esolver/esolver_sdft_pw.h b/source/module_esolver/esolver_sdft_pw.h index 6b3698b3c61..7bb3508e4bc 100644 --- a/source/module_esolver/esolver_sdft_pw.h +++ b/source/module_esolver/esolver_sdft_pw.h @@ -24,7 +24,7 @@ class ESolver_SDFT_PW : public ESolver_KS_PW> Stochastic_WF stowf; protected: - virtual void beforescf(const int istep) override; + virtual void before_scf(const int istep) override; // virtual void eachiterinit(int iter) override; virtual void hamilt2density(const int istep, const int iter, const double ethr) override; virtual void nscf() override; @@ -133,4 +133,4 @@ extern const ModuleBase::matrix* veff; } -#endif \ No newline at end of file +#endif From 313893ee45b875660b59d2de14f00547f9be8bd0 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 11:26:57 +0800 Subject: [PATCH 25/46] change afterscf to after_scf --- source/module_esolver/esolver_ks.cpp | 2 +- source/module_esolver/esolver_ks.h | 2 +- source/module_esolver/esolver_ks_lcao.cpp | 2 +- source/module_esolver/esolver_ks_lcao.h | 15 ++++++++++++++- source/module_esolver/esolver_ks_lcao_tddft.cpp | 4 ++-- source/module_esolver/esolver_ks_lcao_tddft.h | 6 +++++- source/module_esolver/esolver_ks_pw.cpp | 2 +- source/module_esolver/esolver_ks_pw.h | 2 +- source/module_esolver/esolver_sdft_pw.cpp | 2 +- source/module_esolver/esolver_sdft_pw.h | 14 +++++++++++++- 10 files changed, 40 insertions(+), 11 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 36f281ff2cf..eafaed9812d 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -532,7 +532,7 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) this->conv_elec ); #endif //__RAPIDJSON - afterscf(istep); + after_scf(istep); ModuleBase::timer::tick(this->classname, "Run"); } diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index fbdd29bd295..11d062b7112 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -64,7 +64,7 @@ class ESolver_KS : public ESolver_FP virtual void eachiterfinish(const int iter) {}; //! Something to do after SCF iterations when SCF is converged or comes to the max iter step. - virtual void afterscf(const int istep) {}; + virtual void after_scf(const int istep) {}; //! It should be replaced by a function in Hamilt Class virtual void updatepot(const int istep, const int iter) {}; diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 7ad792e1198..40c6814482f 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -929,7 +929,7 @@ void ESolver_KS_LCAO::eachiterfinish(int iter) template -void ESolver_KS_LCAO::afterscf(const int istep) +void ESolver_KS_LCAO::after_scf(const int istep) { // save charge difference into files for charge extrapolation if (GlobalV::CALCULATION != "scf") diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index aa18fc6de3e..0726a263b85 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -27,22 +27,35 @@ namespace ModuleESolver ~ESolver_KS_LCAO(); void Init(Input& inp, UnitCell& cell) override; + void init_after_vc(Input& inp, UnitCell& cell) override; double cal_Energy() override; + void cal_Force(ModuleBase::matrix& force) override; + void cal_Stress(ModuleBase::matrix& stress) override; + void postprocess() override; + void nscf() override; + void get_S(); protected: + virtual void before_scf(const int istep) override; + virtual void eachiterinit(const int istep, const int iter) override; + virtual void hamilt2density(const int istep, const int iter, const double ethr) override; + virtual void updatepot(const int istep, const int iter) override; + virtual void eachiterfinish(const int iter) override; - virtual void afterscf(const int istep) override; + + virtual void after_scf(const int istep) override; + virtual bool do_after_converge(int& iter) override; virtual void othercalculation(const int istep)override; diff --git a/source/module_esolver/esolver_ks_lcao_tddft.cpp b/source/module_esolver/esolver_ks_lcao_tddft.cpp index ab2ad31acc4..6b81ecb996b 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/module_esolver/esolver_ks_lcao_tddft.cpp @@ -434,7 +434,7 @@ void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) } -void ESolver_KS_LCAO_TDDFT::afterscf(const int istep) +void ESolver_KS_LCAO_TDDFT::after_scf(const int istep) { for (int is = 0; is < GlobalV::NSPIN; is++) { @@ -457,7 +457,7 @@ void ESolver_KS_LCAO_TDDFT::afterscf(const int istep) this->RA, this->UHM); } - ESolver_KS_LCAO, double>::afterscf(istep); + ESolver_KS_LCAO, double>::after_scf(istep); } // use the original formula (Hamiltonian matrix) to calculate energy density matrix diff --git a/source/module_esolver/esolver_ks_lcao_tddft.h b/source/module_esolver/esolver_ks_lcao_tddft.h index eaf785ae924..a9191eaa280 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.h +++ b/source/module_esolver/esolver_ks_lcao_tddft.h @@ -29,9 +29,13 @@ class ESolver_KS_LCAO_TDDFT : public ESolver_KS_LCAO, doubl int td_htype = 1; protected: + virtual void hamilt2density(const int istep, const int iter, const double ethr) override; + virtual void updatepot(const int istep, const int iter) override; - virtual void afterscf(const int istep) override; + + virtual void after_scf(const int istep) override; + void cal_edm_tddft(); }; diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index 15b360d3acd..bd1c3b4cf4c 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -966,7 +966,7 @@ void ESolver_KS_PW::eachiterfinish(const int iter) template -void ESolver_KS_PW::afterscf(const int istep) +void ESolver_KS_PW::after_scf(const int istep) { this->create_Output_Potential(istep).write(); diff --git a/source/module_esolver/esolver_ks_pw.h b/source/module_esolver/esolver_ks_pw.h index 284d5253126..84bf86aab1b 100644 --- a/source/module_esolver/esolver_ks_pw.h +++ b/source/module_esolver/esolver_ks_pw.h @@ -96,7 +96,7 @@ class ESolver_KS_PW : public ESolver_KS virtual void eachiterfinish(const int iter) override; - virtual void afterscf(const int istep) override; + virtual void after_scf(const int istep) override; virtual void othercalculation(const int istep)override; diff --git a/source/module_esolver/esolver_sdft_pw.cpp b/source/module_esolver/esolver_sdft_pw.cpp index 2826556ceaf..973c99e22ee 100644 --- a/source/module_esolver/esolver_sdft_pw.cpp +++ b/source/module_esolver/esolver_sdft_pw.cpp @@ -126,7 +126,7 @@ void ESolver_SDFT_PW::eachiterfinish(int iter) } -void ESolver_SDFT_PW::afterscf(const int istep) +void ESolver_SDFT_PW::after_scf(const int istep) { // save charge difference into files for charge extrapolation if (GlobalV::CALCULATION != "scf") diff --git a/source/module_esolver/esolver_sdft_pw.h b/source/module_esolver/esolver_sdft_pw.h index 7bb3508e4bc..3ed9a52e34a 100644 --- a/source/module_esolver/esolver_sdft_pw.h +++ b/source/module_esolver/esolver_sdft_pw.h @@ -15,22 +15,34 @@ class ESolver_SDFT_PW : public ESolver_KS_PW> public: ESolver_SDFT_PW(); ~ESolver_SDFT_PW(); + void Init(Input& inp, UnitCell& cell) override; + double cal_Energy() override; + void cal_Force(ModuleBase::matrix& force) override; + void cal_Stress(ModuleBase::matrix& stress) override; public: + Stochastic_WF stowf; protected: virtual void before_scf(const int istep) override; + // virtual void eachiterinit(int iter) override; + virtual void hamilt2density(const int istep, const int iter, const double ethr) override; + virtual void nscf() override; + virtual void othercalculation(const int istep) override; + virtual void eachiterfinish(const int iter) override; - virtual void afterscf(const int istep) override; + + virtual void after_scf(const int istep) override; + virtual void postprocess() override; public: From 7317a471bf60bad35f5173c84d47ea9ab1b8aad5 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 11:29:33 +0800 Subject: [PATCH 26/46] change updatepot to update_pot --- source/module_esolver/esolver_ks.cpp | 2 +- source/module_esolver/esolver_ks.h | 2 +- source/module_esolver/esolver_ks_lcao.cpp | 2 +- source/module_esolver/esolver_ks_lcao.h | 2 +- source/module_esolver/esolver_ks_lcao_tddft.cpp | 2 +- source/module_esolver/esolver_ks_lcao_tddft.h | 2 +- source/module_esolver/esolver_ks_pw.cpp | 2 +- source/module_esolver/esolver_ks_pw.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index eafaed9812d..893d9926adf 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -480,7 +480,7 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) // Hamilt should be used after it is constructed. // this->phamilt->update(conv_elec); - updatepot(istep, iter); + update_pot(istep, iter); eachiterfinish(iter); #ifdef __MPI double duration = (double)(MPI_Wtime() - iterstart); diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index 11d062b7112..e0f322527df 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -67,7 +67,7 @@ class ESolver_KS : public ESolver_FP virtual void after_scf(const int istep) {}; //! It should be replaced by a function in Hamilt Class - virtual void updatepot(const int istep, const int iter) {}; + virtual void update_pot(const int istep, const int iter) {}; //! choose strategy when charge density convergence achieved virtual bool do_after_converge(int& iter){return true;} diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 40c6814482f..4c73d8ce9c1 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -755,7 +755,7 @@ void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) template -void ESolver_KS_LCAO::updatepot(const int istep, const int iter) +void ESolver_KS_LCAO::update_pot(const int istep, const int iter) { // print Hamiltonian and Overlap matrix if (this->conv_elec) diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index 0726a263b85..b4df6f692a8 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -50,7 +50,7 @@ namespace ModuleESolver virtual void hamilt2density(const int istep, const int iter, const double ethr) override; - virtual void updatepot(const int istep, const int iter) override; + virtual void update_pot(const int istep, const int iter) override; virtual void eachiterfinish(const int iter) override; diff --git a/source/module_esolver/esolver_ks_lcao_tddft.cpp b/source/module_esolver/esolver_ks_lcao_tddft.cpp index 6b81ecb996b..fff72b1e7f4 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/module_esolver/esolver_ks_lcao_tddft.cpp @@ -257,7 +257,7 @@ void ESolver_KS_LCAO_TDDFT::hamilt2density( this->pelec->f_en.deband = this->pelec->cal_delta_eband(); } -void ESolver_KS_LCAO_TDDFT::updatepot(const int istep, const int iter) +void ESolver_KS_LCAO_TDDFT::update_pot(const int istep, const int iter) { // print Hamiltonian and Overlap matrix if (this->conv_elec) diff --git a/source/module_esolver/esolver_ks_lcao_tddft.h b/source/module_esolver/esolver_ks_lcao_tddft.h index a9191eaa280..73ecf1f7307 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.h +++ b/source/module_esolver/esolver_ks_lcao_tddft.h @@ -32,7 +32,7 @@ class ESolver_KS_LCAO_TDDFT : public ESolver_KS_LCAO, doubl virtual void hamilt2density(const int istep, const int iter, const double ethr) override; - virtual void updatepot(const int istep, const int iter) override; + virtual void update_pot(const int istep, const int iter) override; virtual void after_scf(const int istep) override; diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index bd1c3b4cf4c..94d64d99972 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -899,7 +899,7 @@ void ESolver_KS_PW::hamilt2density( // Temporary, it should be rewritten with Hamilt class. template -void ESolver_KS_PW::updatepot(const int istep, const int iter) +void ESolver_KS_PW::update_pot(const int istep, const int iter) { if (!this->conv_elec) { diff --git a/source/module_esolver/esolver_ks_pw.h b/source/module_esolver/esolver_ks_pw.h index 84bf86aab1b..80e240e09fe 100644 --- a/source/module_esolver/esolver_ks_pw.h +++ b/source/module_esolver/esolver_ks_pw.h @@ -92,7 +92,7 @@ class ESolver_KS_PW : public ESolver_KS virtual void eachiterinit(const int istep, const int iter) override; - virtual void updatepot(const int istep, const int iter) override; + virtual void update_pot(const int istep, const int iter) override; virtual void eachiterfinish(const int iter) override; From 730b4604b26904e66fecc6129edba373f989a543 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 11:35:49 +0800 Subject: [PATCH 27/46] change eachiterinit to iter_init, change eachiterfinish to iter_finish --- source/module_esolver/esolver_ks.cpp | 6 +++--- source/module_esolver/esolver_ks.h | 4 ++-- source/module_esolver/esolver_ks_lcao.cpp | 4 ++-- source/module_esolver/esolver_ks_lcao.h | 4 ++-- source/module_esolver/esolver_ks_pw.cpp | 4 ++-- source/module_esolver/esolver_ks_pw.h | 4 ++-- source/module_esolver/esolver_sdft_pw.cpp | 2 +- source/module_esolver/esolver_sdft_pw.h | 4 +--- 8 files changed, 15 insertions(+), 17 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 893d9926adf..0f677321a3f 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -401,7 +401,7 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) #endif double diag_ethr = this->phsol->set_diagethr(istep, iter, drho); - eachiterinit(istep, iter); + this->iter_init(istep, iter); this->hamilt2density(istep, iter, diag_ethr); @@ -480,8 +480,8 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) // Hamilt should be used after it is constructed. // this->phamilt->update(conv_elec); - update_pot(istep, iter); - eachiterfinish(iter); + this->update_pot(istep, iter); + this->iter_finish(iter); #ifdef __MPI double duration = (double)(MPI_Wtime() - iterstart); #else diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index e0f322527df..b8b9c5e7bfb 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -58,10 +58,10 @@ class ESolver_KS : public ESolver_FP virtual void before_scf(int istep) {}; //! Something to do before hamilt2density function in each iter loop. - virtual void eachiterinit(const int istep, const int iter) {}; + virtual void iter_init(const int istep, const int iter) {}; //! Something to do after hamilt2density function in each iter loop. - virtual void eachiterfinish(const int iter) {}; + virtual void iter_finish(const int iter) {}; //! Something to do after SCF iterations when SCF is converged or comes to the max iter step. virtual void after_scf(const int istep) {}; diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 4c73d8ce9c1..4519ce4689d 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -505,7 +505,7 @@ void ESolver_KS_LCAO::Init_Basis_lcao( template -void ESolver_KS_LCAO::eachiterinit(const int istep, const int iter) +void ESolver_KS_LCAO::iter_init(const int istep, const int iter) { if (iter == 1) { @@ -851,7 +851,7 @@ void ESolver_KS_LCAO::update_pot(const int istep, const int iter) template -void ESolver_KS_LCAO::eachiterfinish(int iter) +void ESolver_KS_LCAO::iter_finish(int iter) { // mix density matrix if (GlobalV::MIXING_RESTART > 0 && iter >= this->p_chgmix->mixing_restart && GlobalV::MIXING_DMR ) diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index b4df6f692a8..6eae49cb8b8 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -46,13 +46,13 @@ namespace ModuleESolver virtual void before_scf(const int istep) override; - virtual void eachiterinit(const int istep, const int iter) override; + virtual void iter_init(const int istep, const int iter) override; virtual void hamilt2density(const int istep, const int iter, const double ethr) override; virtual void update_pot(const int istep, const int iter) override; - virtual void eachiterfinish(const int iter) override; + virtual void iter_finish(const int iter) override; virtual void after_scf(const int istep) override; diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index 94d64d99972..b64e66e7f79 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -579,7 +579,7 @@ void ESolver_KS_PW::othercalculation(const int istep) } template -void ESolver_KS_PW::eachiterinit(const int istep, const int iter) +void ESolver_KS_PW::iter_init(const int istep, const int iter) { if (iter == 1) { @@ -918,7 +918,7 @@ void ESolver_KS_PW::update_pot(const int istep, const int iter) template -void ESolver_KS_PW::eachiterfinish(const int iter) +void ESolver_KS_PW::iter_finish(const int iter) { // liuyu 2023-10-24 // D in uspp need vloc, thus needs update when veff updated diff --git a/source/module_esolver/esolver_ks_pw.h b/source/module_esolver/esolver_ks_pw.h index 80e240e09fe..77c700fd0f0 100644 --- a/source/module_esolver/esolver_ks_pw.h +++ b/source/module_esolver/esolver_ks_pw.h @@ -90,11 +90,11 @@ class ESolver_KS_PW : public ESolver_KS virtual void before_scf(const int istep) override; - virtual void eachiterinit(const int istep, const int iter) override; + virtual void iter_init(const int istep, const int iter) override; virtual void update_pot(const int istep, const int iter) override; - virtual void eachiterfinish(const int iter) override; + virtual void iter_finish(const int iter) override; virtual void after_scf(const int istep) override; diff --git a/source/module_esolver/esolver_sdft_pw.cpp b/source/module_esolver/esolver_sdft_pw.cpp index 973c99e22ee..ed8410114f8 100644 --- a/source/module_esolver/esolver_sdft_pw.cpp +++ b/source/module_esolver/esolver_sdft_pw.cpp @@ -119,7 +119,7 @@ void ESolver_SDFT_PW::before_scf(const int istep) } } -void ESolver_SDFT_PW::eachiterfinish(int iter) +void ESolver_SDFT_PW::iter_finish(int iter) { // this->pelec->print_eigenvalue(GlobalV::ofs_running); this->pelec->cal_energies(2); diff --git a/source/module_esolver/esolver_sdft_pw.h b/source/module_esolver/esolver_sdft_pw.h index 3ed9a52e34a..ac1dc349b22 100644 --- a/source/module_esolver/esolver_sdft_pw.h +++ b/source/module_esolver/esolver_sdft_pw.h @@ -31,15 +31,13 @@ class ESolver_SDFT_PW : public ESolver_KS_PW> protected: virtual void before_scf(const int istep) override; - // virtual void eachiterinit(int iter) override; - virtual void hamilt2density(const int istep, const int iter, const double ethr) override; virtual void nscf() override; virtual void othercalculation(const int istep) override; - virtual void eachiterfinish(const int iter) override; + virtual void iter_finish(const int iter) override; virtual void after_scf(const int istep) override; From 31760e852445d81f8b9c86b946f4b3e26669e3ae Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 12:24:37 +0800 Subject: [PATCH 28/46] refactor esolvers, change member function names of most esolvers --- source/driver_run.cpp | 28 +- source/module_esolver/esolver.cpp | 287 ++++++++++-------- source/module_esolver/esolver.h | 31 +- source/module_esolver/esolver_dp.cpp | 12 +- source/module_esolver/esolver_dp.h | 12 +- source/module_esolver/esolver_fp.cpp | 2 +- source/module_esolver/esolver_fp.h | 2 +- source/module_esolver/esolver_ks.cpp | 56 ++-- source/module_esolver/esolver_ks.h | 25 +- source/module_esolver/esolver_ks_lcao.cpp | 21 +- source/module_esolver/esolver_ks_lcao.h | 15 +- .../module_esolver/esolver_ks_lcao_elec.cpp | 10 +- .../module_esolver/esolver_ks_lcao_tddft.cpp | 5 +- source/module_esolver/esolver_ks_lcao_tddft.h | 9 +- source/module_esolver/esolver_ks_pw.cpp | 37 ++- source/module_esolver/esolver_ks_pw.h | 12 +- source/module_esolver/esolver_lj.cpp | 12 +- source/module_esolver/esolver_lj.h | 20 +- source/module_esolver/esolver_of.cpp | 31 +- source/module_esolver/esolver_of.h | 19 +- source/module_esolver/esolver_sdft_pw.cpp | 23 +- source/module_esolver/esolver_sdft_pw.h | 12 +- source/module_md/md_func.cpp | 14 +- source/module_relax/relax_driver.cpp | 18 +- 24 files changed, 401 insertions(+), 312 deletions(-) diff --git a/source/driver_run.cpp b/source/driver_run.cpp index 5222be6aa55..de6cb18193d 100644 --- a/source/driver_run.cpp +++ b/source/driver_run.cpp @@ -19,16 +19,16 @@ * Esolver::Run takes in a configuration and provides force and stress, * the configuration-changing subroutine takes force and stress and updates the configuration */ -void Driver::driver_run() +void Driver::driver_run(void) { ModuleBase::TITLE("Driver", "driver_line"); ModuleBase::timer::tick("Driver", "driver_line"); - // 1. Determine type of Esolver + //! 1: initialize the ESolver ModuleESolver::ESolver *p_esolver = nullptr; ModuleESolver::init_esolver(p_esolver); - // 2. Setup cell and atom information + //! 2: setup cell and atom information #ifndef __LCAO if(GlobalV::BASIS_TYPE == "lcao_in_pw" || GlobalV::BASIS_TYPE == "lcao") { @@ -37,30 +37,29 @@ void Driver::driver_run() #endif GlobalC::ucell.setup_cell(GlobalV::stru_file, GlobalV::ofs_running); - // 3. For these two types of calculations + //! 3: for these two types of calculations // nothing else need to be initialized - if(GlobalV::CALCULATION == "test_neighbour" || GlobalV::CALCULATION == "test_memory") + if(GlobalV::CALCULATION == "test_neighbour" + || GlobalV::CALCULATION == "test_memory") { - p_esolver->Run(0, GlobalC::ucell); + p_esolver->run(0, GlobalC::ucell); ModuleBase::QUIT(); } - // 4. Initialize Esolver,and fill json-structure - p_esolver->Init(INPUT, GlobalC::ucell); + //! 4: initialize Esolver and fill json-structure + p_esolver->init(INPUT, GlobalC::ucell); #ifdef __RAPIDJSON Json::gen_stru_wrapper(&GlobalC::ucell); #endif - //------------------------------------------------------------ - // This part onward needs to be refactored. - //---------------------------MD/Relax------------------------- + //! 5: md or relax calculations if(GlobalV::CALCULATION == "md") { Run_MD::md_line(GlobalC::ucell, p_esolver, INPUT.mdp); } - else // scf; cell relaxation; nscf; etc + else //! scf; cell relaxation; nscf; etc { if (GlobalV::precision_flag == "single") { @@ -73,10 +72,9 @@ void Driver::driver_run() rl_driver.relax_driver(p_esolver); } } - //---------------------------MD/Relax------------------ - // 6. clean up esolver - p_esolver->postprocess(); + //! 6: clean up esolver + p_esolver->post_process(); ModuleESolver::clean_esolver(p_esolver); ModuleBase::timer::tick("Driver", "driver_line"); diff --git a/source/module_esolver/esolver.cpp b/source/module_esolver/esolver.cpp index 336ed32b1b4..fb366dfaf39 100644 --- a/source/module_esolver/esolver.cpp +++ b/source/module_esolver/esolver.cpp @@ -13,152 +13,173 @@ namespace ModuleESolver { - void ESolver::printname() - { - std::cout << classname << std::endl; - } - std::string determine_type() - { - std::string esolver_type = "none"; - if (GlobalV::BASIS_TYPE == "pw") - { - if(GlobalV::ESOLVER_TYPE == "sdft") - { - esolver_type = "sdft_pw"; - } - else if(GlobalV::ESOLVER_TYPE == "ofdft") - { - esolver_type = "ofdft"; - } - else if(GlobalV::ESOLVER_TYPE == "ksdft") - { - esolver_type = "ksdft_pw"; - } - } - else if (GlobalV::BASIS_TYPE == "lcao_in_pw") - { +void ESolver::printname(void) +{ + std::cout << classname << std::endl; +} + +std::string determine_type(void) +{ + std::string esolver_type = "none"; + if (GlobalV::BASIS_TYPE == "pw") + { + if(GlobalV::ESOLVER_TYPE == "sdft") + { + esolver_type = "sdft_pw"; + } + else if(GlobalV::ESOLVER_TYPE == "ofdft") + { + esolver_type = "ofdft"; + } + else if(GlobalV::ESOLVER_TYPE == "ksdft") + { + esolver_type = "ksdft_pw"; + } + } + else if (GlobalV::BASIS_TYPE == "lcao_in_pw") + { #ifdef __LCAO - if(GlobalV::ESOLVER_TYPE == "sdft") - { - esolver_type = "sdft_pw"; - } - else if(GlobalV::ESOLVER_TYPE == "ksdft") - { - esolver_type = "ksdft_pw"; - } + if(GlobalV::ESOLVER_TYPE == "sdft") + { + esolver_type = "sdft_pw"; + } + else if(GlobalV::ESOLVER_TYPE == "ksdft") + { + esolver_type = "ksdft_pw"; + } #else - ModuleBase::WARNING_QUIT("ESolver", "LCAO basis type must be compiled with __LCAO"); + ModuleBase::WARNING_QUIT("ESolver", "LCAO basis type must be compiled with __LCAO"); #endif - } - else if (GlobalV::BASIS_TYPE == "lcao") - { + } + else if (GlobalV::BASIS_TYPE == "lcao") + { #ifdef __LCAO - if(GlobalV::ESOLVER_TYPE == "tddft") - { - esolver_type = "ksdft_lcao_tddft"; - } - else if(GlobalV::ESOLVER_TYPE == "ksdft") - { - esolver_type = "ksdft_lcao"; - } + if(GlobalV::ESOLVER_TYPE == "tddft") + { + esolver_type = "ksdft_lcao_tddft"; + } + else if(GlobalV::ESOLVER_TYPE == "ksdft") + { + esolver_type = "ksdft_lcao"; + } #else - ModuleBase::WARNING_QUIT("ESolver", "LCAO basis type must be compiled with __LCAO"); + ModuleBase::WARNING_QUIT("ESolver", "LCAO basis type must be compiled with __LCAO"); #endif - } + } + + if(GlobalV::ESOLVER_TYPE == "lj") + { + esolver_type = "lj_pot"; + } + else if(GlobalV::ESOLVER_TYPE == "dp") + { + esolver_type = "dp_pot"; + } + else if(esolver_type == "none") + { + ModuleBase::WARNING_QUIT("ESolver", "No such esolver_type combined with basis_type"); + } + + GlobalV::ofs_running << " The esolver type has been set to : " << esolver_type << std::endl; + + auto device_info = GlobalV::device_flag; + + for (char &c : device_info) + { + if (std::islower(c)) + { + c = std::toupper(c); + } + } + if (GlobalV::MY_RANK == 0) + { + std::cout << " RUNNING WITH DEVICE : " << device_info << " / " + << psi::device::get_device_info(GlobalV::device_flag) << std::endl; + } - if(GlobalV::ESOLVER_TYPE == "lj") - { - esolver_type = "lj_pot"; - } - else if(GlobalV::ESOLVER_TYPE == "dp") - { - esolver_type = "dp_pot"; - } - else if(esolver_type == "none") - { - ModuleBase::WARNING_QUIT("ESolver", "No such esolver_type combined with basis_type"); - } + GlobalV::ofs_running << "\n RUNNING WITH DEVICE : " << device_info << " / " + << psi::device::get_device_info(GlobalV::device_flag) << std::endl; + + return esolver_type; +} - GlobalV::ofs_running << " The esolver type has been set to : " << esolver_type << std::endl; - auto device_info = GlobalV::device_flag; - for (char &c : device_info) { - if (std::islower(c)) { - c = std::toupper(c); - } - } - if (GlobalV::MY_RANK == 0) { - std::cout << " RUNNING WITH DEVICE : " << device_info << " / " - << psi::device::get_device_info(GlobalV::device_flag) << std::endl; - } - GlobalV::ofs_running << "\n RUNNING WITH DEVICE : " << device_info << " / " - << psi::device::get_device_info(GlobalV::device_flag) << std::endl; - return esolver_type; - } - //Some API to operate E_Solver - void init_esolver(ESolver*& p_esolver) - { - //determine type of esolver based on INPUT information - std::string esolver_type = determine_type(); +//Some API to operate E_Solver +void init_esolver(ESolver*& p_esolver) +{ + //determine type of esolver based on INPUT information + std::string esolver_type = determine_type(); - //initialize the corresponding Esolver child class - if (esolver_type == "ksdft_pw") - { - #if ((defined __CUDA) || (defined __ROCM)) - if (GlobalV::device_flag == "gpu") { - if (GlobalV::precision_flag == "single") { - p_esolver = new ESolver_KS_PW, psi::DEVICE_GPU>(); - } - else { - p_esolver = new ESolver_KS_PW, psi::DEVICE_GPU>(); - } - return; - } - #endif - if (GlobalV::precision_flag == "single") { - p_esolver = new ESolver_KS_PW, psi::DEVICE_CPU>(); - } - else { - p_esolver = new ESolver_KS_PW, psi::DEVICE_CPU>(); - } - } + //initialize the corresponding Esolver child class + if (esolver_type == "ksdft_pw") + { +#if ((defined __CUDA) || (defined __ROCM)) + if (GlobalV::device_flag == "gpu") + { + if (GlobalV::precision_flag == "single") + { + p_esolver = new ESolver_KS_PW, psi::DEVICE_GPU>(); + } + else + { + p_esolver = new ESolver_KS_PW, psi::DEVICE_GPU>(); + } + return; + } +#endif + if (GlobalV::precision_flag == "single") + { + p_esolver = new ESolver_KS_PW, psi::DEVICE_CPU>(); + } + else + { + p_esolver = new ESolver_KS_PW, psi::DEVICE_CPU>(); + } + } #ifdef __LCAO - else if (esolver_type == "ksdft_lcao") - { - if (GlobalV::GAMMA_ONLY_LOCAL) - p_esolver = new ESolver_KS_LCAO(); - else if (GlobalV::NSPIN < 4) - p_esolver = new ESolver_KS_LCAO, double>(); - else - p_esolver = new ESolver_KS_LCAO, std::complex>(); - } - else if (esolver_type == "ksdft_lcao_tddft") - { - p_esolver = new ESolver_KS_LCAO_TDDFT(); - } + else if (esolver_type == "ksdft_lcao") + { + if (GlobalV::GAMMA_ONLY_LOCAL) + { + p_esolver = new ESolver_KS_LCAO(); + } + else if (GlobalV::NSPIN < 4) + { + p_esolver = new ESolver_KS_LCAO, double>(); + } + else + { + p_esolver = new ESolver_KS_LCAO, std::complex>(); + } + } + else if (esolver_type == "ksdft_lcao_tddft") + { + p_esolver = new ESolver_KS_LCAO_TDDFT(); + } #endif - else if (esolver_type == "sdft_pw") - { - p_esolver = new ESolver_SDFT_PW(); - } - else if(esolver_type == "ofdft") - { - p_esolver = new ESolver_OF(); - } - else if (esolver_type == "lj_pot") - { - p_esolver = new ESolver_LJ(); - } - else if (esolver_type == "dp_pot") - { - p_esolver = new ESolver_DP(INPUT.mdp.pot_file); - } - } + else if (esolver_type == "sdft_pw") + { + p_esolver = new ESolver_SDFT_PW(); + } + else if(esolver_type == "ofdft") + { + p_esolver = new ESolver_OF(); + } + else if (esolver_type == "lj_pot") + { + p_esolver = new ESolver_LJ(); + } + else if (esolver_type == "dp_pot") + { + p_esolver = new ESolver_DP(INPUT.mdp.pot_file); + } +} + - void clean_esolver(ESolver*& pesolver) - { - delete pesolver; - } +void clean_esolver(ESolver*& pesolver) +{ + delete pesolver; +} } diff --git a/source/module_esolver/esolver.h b/source/module_esolver/esolver.h index 88345617cef..d55d483f46a 100644 --- a/source/module_esolver/esolver.h +++ b/source/module_esolver/esolver.h @@ -21,24 +21,27 @@ class ESolver { } - // virtual void Init(Input_EnSolver &inp, matrix &lattice_v)=0 - virtual void Init(Input& inp, UnitCell& cell) = 0; + //! initialize the energy solver by using input parameters and cell modules + virtual void init(Input& inp, UnitCell& cell) = 0; - // They shoud be add after atom class is refactored - // virtual void UpdateLatAtom(ModuleBase::matrix &lat_in, Atom &atom_in); - // virtual void UpdateLat(ModuleBase::matrix &lat_in); - // virtual void UpdateAtom(Atom &atom_in); + //! run energy solver + virtual void run(int istep, UnitCell& cell) = 0; - virtual void Run(int istep, UnitCell& cell) = 0; + //! deal with exx and other calculation than scf/md/relax: + //! such as nscf, get_wf and get_pchg + virtual void others(const int istep){}; - // Deal with exx and other calculation than scf/md/relax: - // such as nscf, get_wf and get_pchg - virtual void othercalculation(const int istep){}; + //! calculate total energy of a given system + virtual double cal_energy() = 0; - virtual double cal_Energy() = 0; - virtual void cal_Force(ModuleBase::matrix& force) = 0; - virtual void cal_Stress(ModuleBase::matrix& stress) = 0; - virtual void postprocess(){}; + //! calcualte forces for the atoms in the given cell + virtual void cal_force(ModuleBase::matrix& force) = 0; + + //! calcualte stress of given cell + virtual void cal_stress(ModuleBase::matrix& stress) = 0; + + //! perform post processing calculations + virtual void post_process(){}; // Print current classname. void printname(); diff --git a/source/module_esolver/esolver_dp.cpp b/source/module_esolver/esolver_dp.cpp index 8551ead5ff3..4406a38ef8c 100644 --- a/source/module_esolver/esolver_dp.cpp +++ b/source/module_esolver/esolver_dp.cpp @@ -25,7 +25,7 @@ namespace ModuleESolver { - void ESolver_DP::Init(Input& inp, UnitCell& ucell) + void ESolver_DP::init(Input& inp, UnitCell& ucell) { ucell_ = &ucell; dp_potential = 0; @@ -59,7 +59,7 @@ namespace ModuleESolver assert(ucell.nat == iat); } - void ESolver_DP::Run(const int istep, UnitCell& ucell) + void ESolver_DP::run(const int istep, UnitCell& ucell) { ModuleBase::TITLE("ESolver_DP", "Run"); ModuleBase::timer::tick("ESolver_DP", "Run"); @@ -122,18 +122,18 @@ namespace ModuleESolver ModuleBase::timer::tick("ESolver_DP", "Run"); } - double ESolver_DP::cal_Energy() + double ESolver_DP::cal_energy() { return dp_potential; } - void ESolver_DP::cal_Force(ModuleBase::matrix& force) + void ESolver_DP::cal_force(ModuleBase::matrix& force) { force = dp_force; ModuleIO::print_force(GlobalV::ofs_running, *ucell_, "TOTAL-FORCE (eV/Angstrom)", force, false); } - void ESolver_DP::cal_Stress(ModuleBase::matrix& stress) + void ESolver_DP::cal_stress(ModuleBase::matrix& stress) { stress = dp_virial; @@ -148,7 +148,7 @@ namespace ModuleESolver ModuleIO::print_stress("TOTAL-STRESS", stress, true, false); } - void ESolver_DP::postprocess() + void ESolver_DP::post_process(void) { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; GlobalV::ofs_running << std::setprecision(16); diff --git a/source/module_esolver/esolver_dp.h b/source/module_esolver/esolver_dp.h index 8e61661c382..54008eb0389 100644 --- a/source/module_esolver/esolver_dp.h +++ b/source/module_esolver/esolver_dp.h @@ -36,7 +36,7 @@ class ESolver_DP : public ESolver * @param inp input parameters * @param cell unitcell information */ - void Init(Input& inp, UnitCell& cell) override; + void init(Input& inp, UnitCell& cell) override; /** * @brief Run the DP solver for a given ion/md step and unit cell @@ -44,7 +44,7 @@ class ESolver_DP : public ESolver * @param istep the current ion/md step * @param cell unitcell information */ - void Run(const int istep, UnitCell& cell) override; + void run(const int istep, UnitCell& cell) override; /** * @brief get the total energy without ion kinetic energy @@ -52,28 +52,28 @@ class ESolver_DP : public ESolver * @param etot the computed energy * @return total energy without ion kinetic energy */ - double cal_Energy() override; + double cal_energy() override; /** * @brief get the computed atomic forces * * @param force the computed atomic forces */ - void cal_Force(ModuleBase::matrix& force) override; + void cal_force(ModuleBase::matrix& force) override; /** * @brief get the computed lattice virials * * @param stress the computed lattice virials */ - void cal_Stress(ModuleBase::matrix& stress) override; + void cal_stress(ModuleBase::matrix& stress) override; /** * @brief Prints the final total energy of the DP model to the output file * * This function prints the final total energy of the DP model in eV to the output file along with some formatting. */ - void postprocess() override; + void post_process() override; private: /** diff --git a/source/module_esolver/esolver_fp.cpp b/source/module_esolver/esolver_fp.cpp index 566c97b877d..076196941eb 100644 --- a/source/module_esolver/esolver_fp.cpp +++ b/source/module_esolver/esolver_fp.cpp @@ -40,7 +40,7 @@ ESolver_FP::~ESolver_FP() } -void ESolver_FP::Init(Input& inp, UnitCell& cell) +void ESolver_FP::init(Input& inp, UnitCell& cell) { if(!GlobalV::use_paw) { diff --git a/source/module_esolver/esolver_fp.h b/source/module_esolver/esolver_fp.h index b05c400245e..38e492d581b 100644 --- a/source/module_esolver/esolver_fp.h +++ b/source/module_esolver/esolver_fp.h @@ -40,7 +40,7 @@ namespace ModuleESolver virtual ~ESolver_FP(); //! Initialize of the first-principels energy solver - virtual void Init(Input& inp, UnitCell& cell) override; + virtual void init(Input& inp, UnitCell& cell) override; virtual void init_after_vc(Input& inp, UnitCell& cell); // liuyu add 2023-03-09 diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 0f677321a3f..419dc48ca3e 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -73,9 +73,9 @@ ESolver_KS::~ESolver_KS() } template -void ESolver_KS::Init(Input& inp, UnitCell& ucell) +void ESolver_KS::init(Input& inp, UnitCell& ucell) { - ESolver_FP::Init(inp,ucell); + ESolver_FP::init(inp,ucell); //------------------Charge Mixing------------------ p_chgmix->set_mixing(GlobalV::MIXING_MODE, @@ -94,12 +94,12 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) #ifdef USE_PAW if(GlobalV::use_paw) { - int * atom_type; - double ** atom_coord; + int * atom_type = nullptr; + double ** atom_coord = nullptr; std::vector filename_list; atom_type = new int [ucell.nat]; - atom_coord = new double * [ucell.nat]; + atom_coord = new double *[ucell.nat]; filename_list.resize(ucell.ntype); for(int ia = 0; ia < ucell.nat; ia ++) @@ -199,12 +199,14 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) #ifdef __MPI this->pw_wfc->initmpi(GlobalV::NPROC_IN_POOL, GlobalV::RANK_IN_POOL, POOL_WORLD); #endif + this->pw_wfc->initgrids(inp.ref_cell_factor * ucell.lat0, ucell.latvec, this->pw_rho->nx, this->pw_rho->ny, this->pw_rho->nz); this->pw_wfc->initparameters(false, inp.ecutwfc, this->kv.nks, this->kv.kvec_d.data()); + #ifdef __MPI if (INPUT.pw_seed > 0) { @@ -212,8 +214,11 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) } // qianrui add 2021-8-13 to make different kpar parameters can get the same results #endif + this->pw_wfc->ft.fft_mode = inp.fft_mode; + this->pw_wfc->setuptransform(); + for (int ik = 0; ik < this->kv.nks; ++ik) { this->kv.ngk[ik] = this->pw_wfc->npwk[ik]; @@ -285,6 +290,7 @@ void ESolver_KS::Init(Input& inp, UnitCell& ucell) #endif } + template void ESolver_KS::init_after_vc(Input& inp, UnitCell& ucell) { @@ -322,6 +328,7 @@ void ESolver_KS::hamilt2density(const int istep, const int iter, cons ModuleBase::timer::tick(this->classname, "hamilt2density"); } + template void ESolver_KS::print_wfcfft(Input& inp, std::ofstream &ofs) { @@ -352,6 +359,7 @@ void ESolver_KS::print_wfcfft(Input& inp, std::ofstream &ofs) ofs << "\n PARALLEL PW FOR WAVE FUNCTIONS" << std::endl; ofs <<" "<< std::setw(8) << "PROC"<< std::setw(15) << "COLUMNS(POT)"<< std::setw(15) << "PW" << std::endl; + for (int i = 0; i < GlobalV::NPROC_IN_POOL ; ++i) { ofs <<" "<::print_wfcfft(Input& inp, std::ofstream &ofs) << std::setw(15) << this->pw_wfc->npw_per[i] << std::endl; } + ofs << " --------------- sum -------------------" << std::endl; ofs << " " << std::setw(8) << GlobalV::NPROC_IN_POOL @@ -367,25 +376,26 @@ void ESolver_KS::print_wfcfft(Input& inp, std::ofstream &ofs) ModuleBase::GlobalFunc::DONE(ofs, "INIT PLANEWAVE"); } + template -void ESolver_KS::Run(const int istep, UnitCell& ucell) +void ESolver_KS::run(const int istep, UnitCell& ucell) { if (!(GlobalV::CALCULATION == "scf" || GlobalV::CALCULATION == "md" || GlobalV::CALCULATION == "relax" || GlobalV::CALCULATION == "cell-relax")) { - this->othercalculation(istep); + this->others(istep); } else { - ModuleBase::timer::tick(this->classname, "Run"); + ModuleBase::timer::tick(this->classname, "run"); this->before_scf(istep); //Something else to do before the iter loop ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT SCF"); if(this->maxniter > 0) { - this->printhead(); //print the headline on the screen. + this->print_head(); //print the headline on the screen. } bool firstscf = true; @@ -393,7 +403,7 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) this->niter = this->maxniter; for (int iter = 1; iter <= this->maxniter; ++iter) { - writehead(GlobalV::ofs_running, istep, iter); + this->write_head(GlobalV::ofs_running, istep, iter); #ifdef __MPI auto iterstart = MPI_Wtime(); #else @@ -485,7 +495,9 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) #ifdef __MPI double duration = (double)(MPI_Wtime() - iterstart); #else - double duration = (std::chrono::duration_cast(std::chrono::system_clock::now() - iterstart)).count() / static_cast(1e6); + double duration = + (std::chrono::duration_cast(std::chrono::system_clock::now() + - iterstart)).count() / static_cast(1e6); #endif /* SCF print: G1 -3.435545e+03 0.000000e+00 3.607e-01 2.862e-01 @@ -496,7 +508,7 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) { dkin = p_chgmix->get_dkin(pelec->charge, GlobalV::nelec); } - printiter(iter, drho, dkin, duration, diag_ethr); + this->print_iter(iter, drho, dkin, duration, diag_ethr); #ifdef __RAPIDJSON //add Json of scf mag @@ -533,7 +545,7 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) ); #endif //__RAPIDJSON after_scf(istep); - ModuleBase::timer::tick(this->classname, "Run"); + ModuleBase::timer::tick(this->classname, "run"); } #ifdef __RAPIDJSON @@ -545,27 +557,33 @@ void ESolver_KS::Run(const int istep, UnitCell& ucell) return; }; + template -void ESolver_KS::printhead() +void ESolver_KS::print_head(void) { std::cout << " " << std::setw(7) << "ITER"; + if (GlobalV::NSPIN == 2) { std::cout << std::setw(10) << "TMAG"; std::cout << std::setw(10) << "AMAG"; } + std::cout << std::setw(15) << "ETOT(eV)"; std::cout << std::setw(15) << "EDIFF(eV)"; std::cout << std::setw(11) << "DRHO"; + if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) { std::cout << std::setw(11) << "DKIN"; } + std::cout << std::setw(11) << "TIME(s)" << std::endl; } + template -void ESolver_KS::printiter( +void ESolver_KS::print_iter( const int iter, const double drho, const double dkin, @@ -575,8 +593,9 @@ void ESolver_KS::printiter( this->pelec->print_etot(this->conv_elec, iter, drho, dkin, duration, INPUT.printe, ethr); } + template -void ESolver_KS::writehead(std::ofstream& ofs_running, const int istep, const int iter) +void ESolver_KS::write_head(std::ofstream& ofs_running, const int istep, const int iter) { ofs_running << "\n " @@ -586,6 +605,7 @@ void ESolver_KS::writehead(std::ofstream& ofs_running, const int iste << "--------------------------------\n"; } + template int ESolver_KS::getniter() { @@ -599,7 +619,7 @@ ModuleIO::Output_Rho ESolver_KS::create_Output_Rho( int iter, const std::string& prefix) { - int precision = 3; + const int precision = 3; std::string tag = "CHG"; return ModuleIO::Output_Rho(this->pw_big, this->pw_rhod, @@ -618,7 +638,7 @@ ModuleIO::Output_Rho ESolver_KS::create_Output_Rho( template ModuleIO::Output_Rho ESolver_KS::create_Output_Kin(int is, int iter, const std::string& prefix) { - int precision = 11; + const int precision = 11; std::string tag = "TAU"; return ModuleIO::Output_Rho(this->pw_big, this->pw_rhod, diff --git a/source/module_esolver/esolver_ks.h b/source/module_esolver/esolver_ks.h index b8b9c5e7bfb..63f79a60d87 100644 --- a/source/module_esolver/esolver_ks.h +++ b/source/module_esolver/esolver_ks.h @@ -32,17 +32,22 @@ class ESolver_KS : public ESolver_FP virtual ~ESolver_KS(); double scf_thr; // scf threshold + double drho; // the difference between rho_in (before HSolver) and rho_out (After HSolver) + int maxniter; // maximum iter steps for scf + int niter; // iter steps actually used in scf + bool conv_elec; // If electron density is converged in scf. + int out_freq_elec;// frequency for output - virtual void Init(Input& inp, UnitCell& cell) override; + virtual void init(Input& inp, UnitCell& cell) override; virtual void init_after_vc(Input& inp, UnitCell& cell) override; // liuyu add 2023-03-09 - virtual void Run(const int istep, UnitCell& cell) override; + virtual void run(const int istep, UnitCell& cell) override; // calculate electron density from a specific Hamiltonian virtual void hamilt2density(const int istep, const int iter, const double ethr); @@ -76,19 +81,27 @@ class ESolver_KS : public ESolver_FP // Print the headline on the screen: // ITER ETOT(eV) EDIFF(eV) DRHO TIME(s) - void printhead(); + void print_head(); // Print inforamtion in each iter // G1 -3.435545e+03 0.000000e+00 3.607e-01 2.862e-01 // for metaGGA // ITER ETOT(eV) EDIFF(eV) DRHO DKIN TIME(s) // G1 -3.435545e+03 0.000000e+00 3.607e-01 3.522e-01 2.862e-01 - void printiter(const int iter, const double drho, const double dkin, const double duration, const double ethr); + void print_iter( + const int iter, + const double drho, + const double dkin, + const double duration, + const double ethr); // Write the headline in the running_log file // "PW/LCAO" ALGORITHM --------------- ION= 1 ELEC= 1-------------------------------- - void writehead(std::ofstream& ofs_running, const int istep, const int iter); + void write_head( + std::ofstream& ofs_running, + const int istep, + const int iter); /// @brief create a new ModuleIO::Output_Rho object to output charge density ModuleIO::Output_Rho create_Output_Rho(int is, int iter, const std::string& prefix="None"); @@ -99,8 +112,6 @@ class ESolver_KS : public ESolver_FP /// @brief create a new ModuleIO::Output_Potential object to print potential ModuleIO::Output_Potential create_Output_Potential(int iter, const std::string& prefix = "None"); - // TODO: control single precision at input files - //! Solve Hamitonian hsolver::HSolver* phsol = nullptr; diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 4519ce4689d..03433f9198b 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -68,8 +68,6 @@ ESolver_KS_LCAO::ESolver_KS_LCAO() } - - template ESolver_KS_LCAO::~ESolver_KS_LCAO() { @@ -80,9 +78,9 @@ ESolver_KS_LCAO::~ESolver_KS_LCAO() template -void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) +void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) { - ModuleBase::TITLE("ESolver_KS_LCAO", "Init"); + ModuleBase::TITLE("ESolver_KS_LCAO", "init"); // if we are only calculating S, then there is no need // to prepare for potentials and so on @@ -104,7 +102,7 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) } else { - ESolver_KS::Init(inp, ucell); + ESolver_KS::init(inp, ucell); } // end ifnot get_S // init ElecState @@ -235,6 +233,7 @@ void ESolver_KS_LCAO::Init(Input& inp, UnitCell& ucell) } } + template void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) { @@ -275,14 +274,14 @@ void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) template -double ESolver_KS_LCAO::cal_Energy() +double ESolver_KS_LCAO::cal_energy() { return this->pelec->f_en.etot; } template -void ESolver_KS_LCAO::cal_Force(ModuleBase::matrix& force) +void ESolver_KS_LCAO::cal_force(ModuleBase::matrix& force) { Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); FSL.getForceStress(GlobalV::CAL_FORCE, @@ -304,7 +303,7 @@ void ESolver_KS_LCAO::cal_Force(ModuleBase::matrix& force) #endif & GlobalC::ucell.symm); - // delete RA after cal_Force + // delete RA after cal_force this->RA.delete_grid(); @@ -313,12 +312,12 @@ void ESolver_KS_LCAO::cal_Force(ModuleBase::matrix& force) template -void ESolver_KS_LCAO::cal_Stress(ModuleBase::matrix& stress) +void ESolver_KS_LCAO::cal_stress(ModuleBase::matrix& stress) { if (!this->have_force) { ModuleBase::matrix fcs; - this->cal_Force(fcs); + this->cal_force(fcs); } stress = this->scs; // copy the stress this->have_force = false; @@ -326,7 +325,7 @@ void ESolver_KS_LCAO::cal_Stress(ModuleBase::matrix& stress) template -void ESolver_KS_LCAO::postprocess() +void ESolver_KS_LCAO::post_process(void) { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; GlobalV::ofs_running << std::setprecision(16); diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index 6eae49cb8b8..269bb2b3a1e 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -26,17 +26,17 @@ namespace ModuleESolver ESolver_KS_LCAO(); ~ESolver_KS_LCAO(); - void Init(Input& inp, UnitCell& cell) override; + void init(Input& inp, UnitCell& cell) override; void init_after_vc(Input& inp, UnitCell& cell) override; - double cal_Energy() override; + double cal_energy() override; - void cal_Force(ModuleBase::matrix& force) override; + void cal_force(ModuleBase::matrix& force) override; - void cal_Stress(ModuleBase::matrix& stress) override; + void cal_stress(ModuleBase::matrix& stress) override; - void postprocess() override; + void post_process() override; void nscf() override; @@ -58,7 +58,7 @@ namespace ModuleESolver virtual bool do_after_converge(int& iter) override; - virtual void othercalculation(const int istep)override; + virtual void others(const int istep)override; // we will get rid of this class soon, don't use it, mohan 2024-03-28 ORB_control orb_con; //Basis_LCAO @@ -124,8 +124,5 @@ namespace ModuleESolver #endif }; - - - } #endif diff --git a/source/module_esolver/esolver_ks_lcao_elec.cpp b/source/module_esolver/esolver_ks_lcao_elec.cpp index 02ce26d2c01..57a0bcd3eac 100644 --- a/source/module_esolver/esolver_ks_lcao_elec.cpp +++ b/source/module_esolver/esolver_ks_lcao_elec.cpp @@ -340,10 +340,10 @@ void ESolver_KS_LCAO::before_scf(int istep) } template -void ESolver_KS_LCAO::othercalculation(const int istep) +void ESolver_KS_LCAO::others(const int istep) { - ModuleBase::TITLE("ESolver_KS_LCAO", "othercalculation"); - ModuleBase::timer::tick("ESolver_KS_LCAO", "othercalculation"); + ModuleBase::TITLE("ESolver_KS_LCAO", "others"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "others"); if (GlobalV::CALCULATION == "get_S") { this->get_S(); @@ -440,10 +440,10 @@ void ESolver_KS_LCAO::othercalculation(const int istep) } else { - ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::othercalculation", "CALCULATION type not supported"); + ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::others", "CALCULATION type not supported"); } - ModuleBase::timer::tick("ESolver_KS_LCAO", "othercalculation"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "others"); return; } template <> diff --git a/source/module_esolver/esolver_ks_lcao_tddft.cpp b/source/module_esolver/esolver_ks_lcao_tddft.cpp index fff72b1e7f4..a4ff74d1501 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/module_esolver/esolver_ks_lcao_tddft.cpp @@ -62,9 +62,9 @@ ESolver_KS_LCAO_TDDFT::~ESolver_KS_LCAO_TDDFT() } } -void ESolver_KS_LCAO_TDDFT::Init(Input& inp, UnitCell& ucell) +void ESolver_KS_LCAO_TDDFT::init(Input& inp, UnitCell& ucell) { - ESolver_KS::Init(inp, ucell); + ESolver_KS::init(inp, ucell); // Initialize the FFT. // this function belongs to cell LOOP @@ -460,6 +460,7 @@ void ESolver_KS_LCAO_TDDFT::after_scf(const int istep) ESolver_KS_LCAO, double>::after_scf(istep); } + // use the original formula (Hamiltonian matrix) to calculate energy density matrix void ESolver_KS_LCAO_TDDFT::cal_edm_tddft(void) { diff --git a/source/module_esolver/esolver_ks_lcao_tddft.h b/source/module_esolver/esolver_ks_lcao_tddft.h index 73ecf1f7307..8e1f4a2c890 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.h +++ b/source/module_esolver/esolver_ks_lcao_tddft.h @@ -17,15 +17,22 @@ namespace ModuleESolver class ESolver_KS_LCAO_TDDFT : public ESolver_KS_LCAO, double> { public: + ESolver_KS_LCAO_TDDFT(); + ~ESolver_KS_LCAO_TDDFT(); - void Init(Input& inp, UnitCell& cell) override; + + void init(Input& inp, UnitCell& cell) override; psi::Psi>* psi_laststep = nullptr; + std::complex** Hk_laststep = nullptr; + std::complex** Sk_laststep = nullptr; + //same as pelec elecstate::ElecStateLCAO_TDDFT* pelec_td = nullptr; + int td_htype = 1; protected: diff --git a/source/module_esolver/esolver_ks_pw.cpp b/source/module_esolver/esolver_ks_pw.cpp index b64e66e7f79..8e1054f6b00 100644 --- a/source/module_esolver/esolver_ks_pw.cpp +++ b/source/module_esolver/esolver_ks_pw.cpp @@ -105,6 +105,8 @@ ESolver_KS_PW::~ESolver_KS_PW() } delete this->psi; } + + template void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) { @@ -217,9 +219,9 @@ void ESolver_KS_PW::Init_GlobalC(Input& inp, UnitCell& cell) template -void ESolver_KS_PW::Init(Input& inp, UnitCell& ucell) +void ESolver_KS_PW::init(Input& inp, UnitCell& ucell) { - ESolver_KS::Init(inp, ucell); + ESolver_KS::init(inp, ucell); // init HSolver if (this->phsol == nullptr) @@ -433,6 +435,7 @@ void ESolver_KS_PW::init_after_vc(Input& inp, UnitCell& ucell) ModuleBase::timer::tick("ESolver_KS_PW", "init_after_vc"); } + template void ESolver_KS_PW::before_scf(int istep) { @@ -538,10 +541,10 @@ void ESolver_KS_PW::before_scf(int istep) template -void ESolver_KS_PW::othercalculation(const int istep) +void ESolver_KS_PW::others(const int istep) { - ModuleBase::TITLE("ESolver_KS_PW", "othercalculation"); - ModuleBase::timer::tick("ESolver_KS_PW", "othercalculation"); + ModuleBase::TITLE("ESolver_KS_PW", "others"); + ModuleBase::timer::tick("ESolver_KS_PW", "others"); if (GlobalV::CALCULATION == "test_memory") { Cal_Test::test_memory(this->pw_rho, @@ -571,10 +574,10 @@ void ESolver_KS_PW::othercalculation(const int istep) } else { - ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::othercalculation", "CALCULATION type not supported"); + ModuleBase::WARNING_QUIT("ESolver_KS_PW::others", "CALCULATION type not supported"); } - ModuleBase::timer::tick("ESolver_KS_PW", "othercalculation"); + ModuleBase::timer::tick("ESolver_KS_PW", "others"); return; } @@ -1075,19 +1078,22 @@ void ESolver_KS_PW::after_scf(const int istep) template -double ESolver_KS_PW::cal_Energy() +double ESolver_KS_PW::cal_energy() { return this->pelec->f_en.etot; } template -void ESolver_KS_PW::cal_Force(ModuleBase::matrix& force) +void ESolver_KS_PW::cal_force(ModuleBase::matrix& force) { Forces ff(GlobalC::ucell.nat); - if (this->__kspw_psi != nullptr) - this->__kspw_psi = nullptr; - if (this->__kspw_psi == nullptr) + if (this->__kspw_psi != nullptr) + { + this->__kspw_psi = nullptr; + } + + if (this->__kspw_psi == nullptr) { this->__kspw_psi = GlobalV::precision_flag == "single" ? new psi::Psi, Device>(this->kspw_psi[0]) @@ -1107,11 +1113,14 @@ void ESolver_KS_PW::cal_Force(ModuleBase::matrix& force) template -void ESolver_KS_PW::cal_Stress(ModuleBase::matrix& stress) +void ESolver_KS_PW::cal_stress(ModuleBase::matrix& stress) { Stress_PW ss(this->pelec); if (this->__kspw_psi != nullptr) + { this->__kspw_psi = nullptr; + } + if (this->__kspw_psi == nullptr) { this->__kspw_psi = GlobalV::precision_flag == "single" @@ -1141,7 +1150,7 @@ void ESolver_KS_PW::cal_Stress(ModuleBase::matrix& stress) template -void ESolver_KS_PW::postprocess(void) +void ESolver_KS_PW::post_process(void) { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; diff --git a/source/module_esolver/esolver_ks_pw.h b/source/module_esolver/esolver_ks_pw.h index 77c700fd0f0..41aab7892ea 100644 --- a/source/module_esolver/esolver_ks_pw.h +++ b/source/module_esolver/esolver_ks_pw.h @@ -28,15 +28,15 @@ class ESolver_KS_PW : public ESolver_KS ~ESolver_KS_PW(); - void Init(Input& inp, UnitCell& cell) override; + void init(Input& inp, UnitCell& cell) override; void init_after_vc(Input& inp, UnitCell& cell) override; - double cal_Energy() override; + double cal_energy() override; - void cal_Force(ModuleBase::matrix& force) override; + void cal_force(ModuleBase::matrix& force) override; - void cal_Stress(ModuleBase::matrix& stress) override; + void cal_stress(ModuleBase::matrix& stress) override; virtual void hamilt2density(const int istep, const int iter, const double ethr) override; @@ -44,7 +44,7 @@ class ESolver_KS_PW : public ESolver_KS virtual void nscf() override; - void postprocess() override; + void post_process() override; /** * @brief calculate Onsager coefficients Lmn(\omega) and conductivities with Kubo-Greenwood formula @@ -98,7 +98,7 @@ class ESolver_KS_PW : public ESolver_KS virtual void after_scf(const int istep) override; - virtual void othercalculation(const int istep)override; + virtual void others(const int istep)override; //temporary, this will be removed in the future; //Init Global class diff --git a/source/module_esolver/esolver_lj.cpp b/source/module_esolver/esolver_lj.cpp index f48ff290d8f..0b5346a53f7 100644 --- a/source/module_esolver/esolver_lj.cpp +++ b/source/module_esolver/esolver_lj.cpp @@ -7,7 +7,7 @@ namespace ModuleESolver { - void ESolver_LJ::Init(Input& inp, UnitCell& ucell) + void ESolver_LJ::init(Input& inp, UnitCell& ucell) { ucell_ = &ucell; lj_potential = 0; @@ -24,7 +24,7 @@ namespace ModuleESolver lj_sigma *= ModuleBase::ANGSTROM_AU; } - void ESolver_LJ::Run(const int istep, UnitCell& ucell) + void ESolver_LJ::run(const int istep, UnitCell& ucell) { Grid_Driver grid_neigh(GlobalV::test_deconstructor, GlobalV::test_grid_driver, GlobalV::test_grid); atom_arrange::search( @@ -93,18 +93,18 @@ namespace ModuleESolver #endif } - double ESolver_LJ::cal_Energy() + double ESolver_LJ::cal_energy() { return lj_potential; } - void ESolver_LJ::cal_Force(ModuleBase::matrix& force) + void ESolver_LJ::cal_force(ModuleBase::matrix& force) { force = lj_force; ModuleIO::print_force(GlobalV::ofs_running, *ucell_, "TOTAL-FORCE (eV/Angstrom)", force, false); } - void ESolver_LJ::cal_Stress(ModuleBase::matrix& stress) + void ESolver_LJ::cal_stress(ModuleBase::matrix& stress) { stress = lj_virial; @@ -119,7 +119,7 @@ namespace ModuleESolver ModuleIO::print_stress("TOTAL-STRESS", stress, true, false); } - void ESolver_LJ::postprocess() + void ESolver_LJ::post_process(void) { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; GlobalV::ofs_running << std::setprecision(16); diff --git a/source/module_esolver/esolver_lj.h b/source/module_esolver/esolver_lj.h index 9d04243e1cc..6963e4b8547 100644 --- a/source/module_esolver/esolver_lj.h +++ b/source/module_esolver/esolver_lj.h @@ -14,17 +14,25 @@ namespace ModuleESolver classname = "ESolver_LJ"; } - void Init(Input& inp, UnitCell& cell) override; - void Run(const int istep, UnitCell& cell) override; - double cal_Energy() override; - void cal_Force(ModuleBase::matrix& force) override; - void cal_Stress(ModuleBase::matrix& stress) override; - void postprocess() override; + void init(Input& inp, UnitCell& cell) override; + + void run(const int istep, UnitCell& cell) override; + + double cal_energy() override; + + void cal_force(ModuleBase::matrix& force) override; + + void cal_stress(ModuleBase::matrix& stress) override; + + void post_process() override; private: + double LJ_energy(const double d); + ModuleBase::Vector3 LJ_force(const double d, const ModuleBase::Vector3 dr); + void LJ_virial(const ModuleBase::Vector3& force, const ModuleBase::Vector3& dtau); diff --git a/source/module_esolver/esolver_of.cpp b/source/module_esolver/esolver_of.cpp index 53e1224e44f..ccd6bc3b5b8 100644 --- a/source/module_esolver/esolver_of.cpp +++ b/source/module_esolver/esolver_of.cpp @@ -57,9 +57,9 @@ ESolver_OF::~ESolver_OF() delete this->opt_cg_mag_; } -void ESolver_OF::Init(Input& inp, UnitCell& ucell) +void ESolver_OF::init(Input& inp, UnitCell& ucell) { - ESolver_FP::Init(inp, ucell); + ESolver_FP::init(inp, ucell); // save necessary parameters this->of_kinetic_ = inp.of_kinetic; @@ -217,9 +217,9 @@ void ESolver_OF::init_after_vc(Input& inp, UnitCell& ucell) } } -void ESolver_OF::Run(int istep, UnitCell& ucell) +void ESolver_OF::run(int istep, UnitCell& ucell) { - ModuleBase::timer::tick("ESolver_OF", "Run"); + ModuleBase::timer::tick("ESolver_OF", "run"); // get Ewald energy, initial rho and phi if necessary this->before_opt(istep, ucell); this->iter_ = 0; @@ -232,11 +232,13 @@ void ESolver_OF::Run(int istep, UnitCell& ucell) // calculate the energy of new rho and phi this->energy_llast_ = this->energy_last_; this->energy_last_ = this->energy_current_; - this->energy_current_ = this->cal_Energy(); + this->energy_current_ = this->cal_energy(); // check if the job is done - if (this->check_exit()) - break; + if (this->check_exit()) + { + break; + } // find the optimization direction and step lenghth theta according to the potential this->optimize(ucell); @@ -249,7 +251,7 @@ void ESolver_OF::Run(int istep, UnitCell& ucell) this->after_opt(istep, ucell); - ModuleBase::timer::tick("ESolver_OF", "Run"); + ModuleBase::timer::tick("ESolver_OF", "run"); } /** @@ -334,7 +336,10 @@ void ESolver_OF::update_potential(UnitCell& ucell) { // (1) get dL/dphi if (GlobalV::NSPIN == 4) + { ucell.cal_ux(); + } + this->pelec->pot->update_from_charge(pelec->charge, &ucell); // Hartree + XC + external this->kinetic_potential(pelec->charge->rho, this->pphi_, @@ -582,7 +587,7 @@ void ESolver_OF::after_opt(const int istep, UnitCell& ucell) /** * @brief Output the FINAL_ETOT */ -void ESolver_OF::postprocess() +void ESolver_OF::post_process() { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; @@ -597,7 +602,7 @@ void ESolver_OF::postprocess() * * @return total energy */ -double ESolver_OF::cal_Energy() +double ESolver_OF::cal_energy() { this->pelec->cal_energies(2); double kinetic_energy = this->kinetic_energy(); // kinetic energy @@ -621,7 +626,7 @@ double ESolver_OF::cal_Energy() * * @param [out] force */ -void ESolver_OF::cal_Force(ModuleBase::matrix& force) +void ESolver_OF::cal_force(ModuleBase::matrix& force) { Forces ff(GlobalC::ucell.nat); ff.cal_force(force, *pelec, this->pw_rho, &GlobalC::ucell.symm, &sf); @@ -632,7 +637,7 @@ void ESolver_OF::cal_Force(ModuleBase::matrix& force) * * @param [out] stress */ -void ESolver_OF::cal_Stress(ModuleBase::matrix& stress) +void ESolver_OF::cal_stress(ModuleBase::matrix& stress) { ModuleBase::matrix kinetic_stress_; kinetic_stress_.create(3, 3); @@ -641,4 +646,4 @@ void ESolver_OF::cal_Stress(ModuleBase::matrix& stress) OF_Stress_PW ss(this->pelec, this->pw_rho); ss.cal_stress(stress, kinetic_stress_, GlobalC::ucell, &GlobalC::ucell.symm, &sf, &kv); } -} // namespace ModuleESolver \ No newline at end of file +} // namespace ModuleESolver diff --git a/source/module_esolver/esolver_of.h b/source/module_esolver/esolver_of.h index ab847321bee..42722b27b16 100644 --- a/source/module_esolver/esolver_of.h +++ b/source/module_esolver/esolver_of.h @@ -20,14 +20,19 @@ class ESolver_OF : public ESolver_FP ESolver_OF(); ~ESolver_OF(); - virtual void Init(Input& inp, UnitCell& ucell) override; + virtual void init(Input& inp, UnitCell& ucell) override; + virtual void init_after_vc(Input& inp, UnitCell& ucell) override; - virtual void Run(int istep, UnitCell& ucell) override; - virtual void postprocess() override; - virtual double cal_Energy() override; - virtual void cal_Force(ModuleBase::matrix& force) override; - virtual void cal_Stress(ModuleBase::matrix& stress) override; + virtual void run(int istep, UnitCell& ucell) override; + + virtual void post_process() override; + + virtual double cal_energy() override; + + virtual void cal_force(ModuleBase::matrix& force) override; + + virtual void cal_stress(ModuleBase::matrix& stress) override; virtual int getniter() override { @@ -135,4 +140,4 @@ class ESolver_OF : public ESolver_FP }; } // namespace ModuleESolver -#endif \ No newline at end of file +#endif diff --git a/source/module_esolver/esolver_sdft_pw.cpp b/source/module_esolver/esolver_sdft_pw.cpp index ed8410114f8..342c513014c 100644 --- a/source/module_esolver/esolver_sdft_pw.cpp +++ b/source/module_esolver/esolver_sdft_pw.cpp @@ -36,11 +36,12 @@ ESolver_SDFT_PW::~ESolver_SDFT_PW() { } -void ESolver_SDFT_PW::Init(Input& inp, UnitCell& ucell) +void ESolver_SDFT_PW::init(Input& inp, UnitCell& ucell) { this->nche_sto = inp.nche_sto; this->method_sto = inp.method_sto; - ESolver_KS::Init(inp, ucell); + + ESolver_KS::init(inp, ucell); this->pelec = new elecstate::ElecStatePW_SDFT(pw_wfc, &(chr), @@ -220,13 +221,13 @@ void ESolver_SDFT_PW::hamilt2density(int istep, int iter, double ethr) } } -double ESolver_SDFT_PW::cal_Energy() +double ESolver_SDFT_PW::cal_energy() { return this->pelec->f_en.etot; } -void ESolver_SDFT_PW::cal_Force(ModuleBase::matrix& force) +void ESolver_SDFT_PW::cal_force(ModuleBase::matrix& force) { Sto_Forces ff(GlobalC::ucell.nat); @@ -242,7 +243,7 @@ void ESolver_SDFT_PW::cal_Force(ModuleBase::matrix& force) } -void ESolver_SDFT_PW::cal_Stress(ModuleBase::matrix& stress) +void ESolver_SDFT_PW::cal_stress(ModuleBase::matrix& stress) { Sto_Stress_PW ss; ss.cal_stress( @@ -259,7 +260,7 @@ void ESolver_SDFT_PW::cal_Stress(ModuleBase::matrix& stress) } -void ESolver_SDFT_PW::postprocess(void) +void ESolver_SDFT_PW::post_process(void) { GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; @@ -338,10 +339,10 @@ void ESolver_SDFT_PW::postprocess(void) } -void ESolver_SDFT_PW::othercalculation(const int istep) +void ESolver_SDFT_PW::others(const int istep) { - ModuleBase::TITLE("ESolver_SDFT_PW", "othercalculation"); - ModuleBase::timer::tick("ESolver_SDFT_PW", "othercalculation"); + ModuleBase::TITLE("ESolver_SDFT_PW", "others"); + ModuleBase::timer::tick("ESolver_SDFT_PW", "others"); if (GlobalV::CALCULATION == "nscf") { @@ -349,9 +350,9 @@ void ESolver_SDFT_PW::othercalculation(const int istep) } else { - ModuleBase::WARNING_QUIT("ESolver_SDFT_PW::othercalculation", "CALCULATION type not supported"); + ModuleBase::WARNING_QUIT("ESolver_SDFT_PW::others", "CALCULATION type not supported"); } - ModuleBase::timer::tick("ESolver_SDFT_PW", "othercalculation"); + ModuleBase::timer::tick("ESolver_SDFT_PW", "others"); return; } diff --git a/source/module_esolver/esolver_sdft_pw.h b/source/module_esolver/esolver_sdft_pw.h index ac1dc349b22..cc9b2aa8b43 100644 --- a/source/module_esolver/esolver_sdft_pw.h +++ b/source/module_esolver/esolver_sdft_pw.h @@ -16,13 +16,13 @@ class ESolver_SDFT_PW : public ESolver_KS_PW> ESolver_SDFT_PW(); ~ESolver_SDFT_PW(); - void Init(Input& inp, UnitCell& cell) override; + void init(Input& inp, UnitCell& cell) override; - double cal_Energy() override; + double cal_energy() override; - void cal_Force(ModuleBase::matrix& force) override; + void cal_force(ModuleBase::matrix& force) override; - void cal_Stress(ModuleBase::matrix& stress) override; + void cal_stress(ModuleBase::matrix& stress) override; public: @@ -35,13 +35,13 @@ class ESolver_SDFT_PW : public ESolver_KS_PW> virtual void nscf() override; - virtual void othercalculation(const int istep) override; + virtual void others(const int istep) override; virtual void iter_finish(const int iter) override; virtual void after_scf(const int istep) override; - virtual void postprocess() override; + virtual void post_process() override; public: /** diff --git a/source/module_md/md_func.cpp b/source/module_md/md_func.cpp index b5e1d80b74a..05432471ce6 100644 --- a/source/module_md/md_func.cpp +++ b/source/module_md/md_func.cpp @@ -6,11 +6,11 @@ namespace MD_func { -double gaussrand() +double gaussrand(void) { static double V1, V2, S; static int phase = 0; - double X; + double X=0.0; if (phase == 0) { @@ -228,16 +228,16 @@ void force_virial(ModuleESolver::ESolver* p_esolver, ModuleBase::TITLE("MD_func", "force_virial"); ModuleBase::timer::tick("MD_func", "force_virial"); - p_esolver->Run(istep, unit_in); + p_esolver->run(istep, unit_in); - potential = p_esolver->cal_Energy(); + potential = p_esolver->cal_energy(); ModuleBase::matrix force_temp(unit_in.nat, 3); - p_esolver->cal_Force(force_temp); + p_esolver->cal_force(force_temp); if (cal_stress) { - p_esolver->cal_Stress(virial); + p_esolver->cal_stress(virial); } /// convert Rydberg to Hartree @@ -472,4 +472,4 @@ void current_md_info(const int& my_rank, const std::string& file_dir, int& md_st #endif } -} // namespace MD_func \ No newline at end of file +} // namespace MD_func diff --git a/source/module_relax/relax_driver.cpp b/source/module_relax/relax_driver.cpp index e9d8a092a2a..28f2485bc96 100644 --- a/source/module_relax/relax_driver.cpp +++ b/source/module_relax/relax_driver.cpp @@ -48,7 +48,7 @@ void Relax_Driver::relax_driver(ModuleESolver::ESolver *p_esolve #endif //__RAPIDJSON // mohan added eiter to count for the electron iteration number, 2021-01-28 - p_esolver->Run(istep - 1, GlobalC::ucell); + p_esolver->run(istep - 1, GlobalC::ucell); time_t eend = time(NULL); time_t fstart = time(NULL); @@ -62,17 +62,17 @@ void Relax_Driver::relax_driver(ModuleESolver::ESolver *p_esolve // but I'll use force and stress explicitly here for now // calculate the total energy - this->etot = p_esolver->cal_Energy(); + this->etot = p_esolver->cal_energy(); // calculate and gather all parts of total ionic forces if (GlobalV::CAL_FORCE) { - p_esolver->cal_Force(force); + p_esolver->cal_force(force); } // calculate and gather all parts of stress if (GlobalV::CAL_STRESS) { - p_esolver->cal_Stress(stress); + p_esolver->cal_stress(stress); } if (GlobalV::CALCULATION == "relax" || GlobalV::CALCULATION == "cell-relax") @@ -105,8 +105,12 @@ void Relax_Driver::relax_driver(ModuleESolver::ESolver *p_esolve GlobalC::ucell.print_cell_cif("STRU_NOW.cif"); } - ModuleESolver::ESolver_KS* p_esolver_ks = dynamic_cast*>(p_esolver); - if (p_esolver_ks && stop && p_esolver_ks->maxniter == p_esolver_ks->niter && !(p_esolver_ks->conv_elec)) + ModuleESolver::ESolver_KS* p_esolver_ks + = dynamic_cast*>(p_esolver); + if (p_esolver_ks + && stop + && p_esolver_ks->maxniter == p_esolver_ks->niter + && !(p_esolver_ks->conv_elec)) { std::cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl; std::cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" << std::endl; @@ -153,4 +157,4 @@ void Relax_Driver::relax_driver(ModuleESolver::ESolver *p_esolve } template class Relax_Driver; -template class Relax_Driver; \ No newline at end of file +template class Relax_Driver; From cccbb149846da6a7376b6319e15188fd89b49b06 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 12:37:21 +0800 Subject: [PATCH 29/46] reformat esolver.h --- source/module_esolver/esolver.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/module_esolver/esolver.h b/source/module_esolver/esolver.h index d55d483f46a..142efa2a4ab 100644 --- a/source/module_esolver/esolver.h +++ b/source/module_esolver/esolver.h @@ -9,8 +9,6 @@ namespace ModuleESolver { class ESolver { - // protected: - // ModuleBase::matrix lattice_v; public: ESolver() { @@ -62,7 +60,7 @@ class ESolver * * @return [out] std::string The type of ESolver */ -std::string determine_type(); +std::string determine_type(void); /** * @brief Determine and initialize an ESolver based on input information. From 270a39d1b4d972b4dd2d7bd2e9254a9f9159012c Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 14:26:03 +0800 Subject: [PATCH 30/46] update tests for esolvers --- .../module_esolver/test/esolver_dp_test.cpp | 30 +++++++++---------- source/module_md/test/fire_test.cpp | 4 +-- source/module_md/test/langevin_test.cpp | 4 +-- source/module_md/test/lj_pot_test.cpp | 4 +-- source/module_md/test/msst_test.cpp | 2 +- source/module_md/test/nhchain_test.cpp | 4 +-- source/module_md/test/verlet_test.cpp | 4 +-- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/source/module_esolver/test/esolver_dp_test.cpp b/source/module_esolver/test/esolver_dp_test.cpp index 8902c0e10a6..8f9fe878a2a 100644 --- a/source/module_esolver/test/esolver_dp_test.cpp +++ b/source/module_esolver/test/esolver_dp_test.cpp @@ -10,12 +10,12 @@ /** * - Tested Functions: - * - ESolver_DP::Init() - * - ESolver_DP::Run() - * - ESolver_DP::cal_Energy() - * - ESolver_DP::cal_Force() - * - ESolver_DP::cal_Stress() - * - ESolver_DP::postprocess() + * - ESolver_DP::init() + * - ESolver_DP::run() + * - ESolver_DP::cal_energy() + * - ESolver_DP::cal_force() + * - ESolver_DP::cal_stress() + * - ESolver_DP::post_process() * - ESolver_DP::type_map() */ namespace ModuleIO @@ -39,7 +39,7 @@ class ESolverDPTest : public ::testing::Test { // Initialize variables before each test esolver = new ModuleESolver::ESolver_DP("./support/case_1.pb"); - esolver->Init(inp, ucell); + esolver->init(inp, ucell); } void TearDown() override @@ -85,7 +85,7 @@ TEST_F(ESolverDPTest, InitCase2) esolver->dp_type[0] = 0; esolver->dp_type[1] = 0; esolver->dp_file = "./support/case_2.pb"; - esolver->Init(inp, ucell); + esolver->init(inp, ucell); // Check the initialized variables EXPECT_EQ(esolver->dp_type[0], 0); @@ -100,17 +100,17 @@ TEST_F(ESolverDPTest, RunWarningQuit) int istep = 0; testing::internal::CaptureStdout(); - EXPECT_EXIT(esolver->Run(istep, ucell), ::testing::ExitedWithCode(0), ""); + EXPECT_EXIT(esolver->run(istep, ucell), ::testing::ExitedWithCode(0), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("Please recompile with -D__DPMD")); } -// Test the cal_Energy() funciton +// Test the cal_energy() funciton TEST_F(ESolverDPTest, CalEnergy) { double etot = 0.0; esolver->dp_potential = 9.8; - etot = esolver->cal_Energy(); + etot = esolver->cal_energy(); // Check the results EXPECT_DOUBLE_EQ(etot, 9.8); @@ -128,7 +128,7 @@ TEST_F(ESolverDPTest, CalForce) } } - esolver->cal_Force(force); + esolver->cal_force(force); // Check the results for (int i = 0; i < ucell.nat; ++i) @@ -152,7 +152,7 @@ TEST_F(ESolverDPTest, CalStress) } } - esolver->cal_Stress(stress); + esolver->cal_stress(stress); // Check the results for (int i = 0; i < 3; ++i) @@ -171,7 +171,7 @@ TEST_F(ESolverDPTest, Postprocess) // Check the results GlobalV::ofs_running.open("log"); - esolver->postprocess(); + esolver->post_process(); GlobalV::ofs_running.close(); std::string expected_output = "\n\n --------------------------------------------\n !FINAL_ETOT_IS 133.3358404 eV\n " @@ -230,4 +230,4 @@ TEST_F(ESolverDPTest, TypeMapWarningQuit) EXPECT_EXIT(esolver->type_map(ucell), ::testing::ExitedWithCode(0), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("can not find the DP model")); -} \ No newline at end of file +} diff --git a/source/module_md/test/fire_test.cpp b/source/module_md/test/fire_test.cpp index c275ec20932..96a8e5612ef 100644 --- a/source/module_md/test/fire_test.cpp +++ b/source/module_md/test/fire_test.cpp @@ -46,7 +46,7 @@ class FIREtest : public testing::Test Setcell::parameters(); ModuleESolver::ESolver* p_esolver = new ModuleESolver::ESolver_LJ(); - p_esolver->Init(INPUT, ucell); + p_esolver->init(INPUT, ucell); mdrun = new FIRE(INPUT.mdp, ucell); mdrun->setup(p_esolver, GlobalV::global_readin_dir); @@ -208,4 +208,4 @@ TEST_F(FIREtest, PrintMD) EXPECT_THAT(output_str, testing::HasSubstr(" LARGEST GRAD (eV/A) : 0.049479926")); ifs.close(); remove("running.log"); -} \ No newline at end of file +} diff --git a/source/module_md/test/langevin_test.cpp b/source/module_md/test/langevin_test.cpp index 77bac815cec..8fc152c6519 100644 --- a/source/module_md/test/langevin_test.cpp +++ b/source/module_md/test/langevin_test.cpp @@ -46,7 +46,7 @@ class Langevin_test : public testing::Test Setcell::parameters(); ModuleESolver::ESolver* p_esolver = new ModuleESolver::ESolver_LJ(); - p_esolver->Init(INPUT, ucell); + p_esolver->init(INPUT, ucell); mdrun = new Langevin(INPUT.mdp, ucell); mdrun->setup(p_esolver, GlobalV::global_readin_dir); @@ -189,4 +189,4 @@ TEST_F(Langevin_test, print_md) " ------------------------------------------------------------------------------------------------")); ifs.close(); remove("running.log"); -} \ No newline at end of file +} diff --git a/source/module_md/test/lj_pot_test.cpp b/source/module_md/test/lj_pot_test.cpp index a6cbced392c..89a062a1b02 100644 --- a/source/module_md/test/lj_pot_test.cpp +++ b/source/module_md/test/lj_pot_test.cpp @@ -35,7 +35,7 @@ class LJ_pot_test : public testing::Test Setcell::parameters(); ModuleESolver::ESolver* p_esolver = new ModuleESolver::ESolver_LJ(); - p_esolver->Init(INPUT, ucell); + p_esolver->init(INPUT, ucell); MD_func::force_virial(p_esolver, 0, ucell, potential, force, true, stress); } @@ -77,4 +77,4 @@ TEST_F(LJ_pot_test, stress) EXPECT_NEAR(stress(2, 0), 0, doublethreshold); EXPECT_NEAR(stress(2, 1), -1.1858461261560206e-22, doublethreshold); EXPECT_NEAR(stress(2, 2), 6.4275429572682057e-07, doublethreshold); -} \ No newline at end of file +} diff --git a/source/module_md/test/msst_test.cpp b/source/module_md/test/msst_test.cpp index dcf33648730..a5d3ac97e46 100644 --- a/source/module_md/test/msst_test.cpp +++ b/source/module_md/test/msst_test.cpp @@ -46,7 +46,7 @@ class MSST_test : public testing::Test Setcell::parameters(); ModuleESolver::ESolver* p_esolver = new ModuleESolver::ESolver_LJ(); - p_esolver->Init(INPUT, ucell); + p_esolver->init(INPUT, ucell); mdrun = new MSST(INPUT.mdp, ucell); mdrun->setup(p_esolver, GlobalV::global_readin_dir); diff --git a/source/module_md/test/nhchain_test.cpp b/source/module_md/test/nhchain_test.cpp index 93ea37b8eb3..49ec2310816 100644 --- a/source/module_md/test/nhchain_test.cpp +++ b/source/module_md/test/nhchain_test.cpp @@ -46,7 +46,7 @@ class NHC_test : public testing::Test Setcell::parameters(); ModuleESolver::ESolver* p_esolver = new ModuleESolver::ESolver_LJ(); - p_esolver->Init(INPUT, ucell); + p_esolver->init(INPUT, ucell); INPUT.mdp.md_type = "npt"; INPUT.mdp.md_pmode = "tri"; @@ -237,4 +237,4 @@ TEST_F(NHC_test, print_md) " ------------------------------------------------------------------------------------------------")); ifs.close(); remove("running.log"); -} \ No newline at end of file +} diff --git a/source/module_md/test/verlet_test.cpp b/source/module_md/test/verlet_test.cpp index 9b2f138d207..8852743edc2 100644 --- a/source/module_md/test/verlet_test.cpp +++ b/source/module_md/test/verlet_test.cpp @@ -46,7 +46,7 @@ class Verlet_test : public testing::Test Setcell::parameters(); ModuleESolver::ESolver* p_esolver = new ModuleESolver::ESolver_LJ(); - p_esolver->Init(INPUT, ucell); + p_esolver->init(INPUT, ucell); mdrun = new Verlet(INPUT.mdp, ucell); mdrun->setup(p_esolver, GlobalV::global_readin_dir); @@ -330,4 +330,4 @@ TEST_F(Verlet_test, print_md) " ------------------------------------------------------------------------------------------------")); ifs.close(); remove("running.log"); -} \ No newline at end of file +} From bfc8ac747e64210bfde6ea0439a0b12e4f5510b1 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 14:56:53 +0800 Subject: [PATCH 31/46] add TITLE in esolver_ks_lcao --- source/module_esolver/esolver_ks_lcao.cpp | 17 ++++++++++++++--- source/module_esolver/esolver_ks_lcao.h | 2 +- source/module_esolver/esolver_ks_lcao_tddft.cpp | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 03433f9198b..f2a8e0d9d3b 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -21,7 +21,6 @@ #include "module_hamilt_pw/hamilt_pwdft/global.h" #include "module_io/print_info.h" #ifdef __EXX -// #include "module_rpa/rpa.h" #include "module_ri/RPA_LRI.h" #endif @@ -123,7 +122,7 @@ void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) // Init Basis should be put outside of Ensolver. // * reading the localized orbitals/projectors // * construct the interpolation tables. - this->Init_Basis_lcao(this->orb_con, inp, ucell); + this->init_basis_lcao(this->orb_con, inp, ucell); //------------------init Basis_lcao---------------------- //! pass Hamilt-pointer to Operator @@ -237,6 +236,8 @@ void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) template void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) { + ModuleBase::TITLE("ESolver_KS_LCAO", "init_after_vc"); + ESolver_KS::init_after_vc(inp, ucell); if (GlobalV::md_prec_level == 2) @@ -276,6 +277,8 @@ void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) template double ESolver_KS_LCAO::cal_energy() { + ModuleBase::TITLE("ESolver_KS_LCAO", "cal_energy"); + return this->pelec->f_en.etot; } @@ -283,6 +286,8 @@ double ESolver_KS_LCAO::cal_energy() template void ESolver_KS_LCAO::cal_force(ModuleBase::matrix& force) { + ModuleBase::TITLE("ESolver_KS_LCAO", "cal_force"); + Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); FSL.getForceStress(GlobalV::CAL_FORCE, GlobalV::CAL_STRESS, @@ -314,6 +319,8 @@ void ESolver_KS_LCAO::cal_force(ModuleBase::matrix& force) template void ESolver_KS_LCAO::cal_stress(ModuleBase::matrix& stress) { + ModuleBase::TITLE("ESolver_KS_LCAO", "cal_stress"); + if (!this->have_force) { ModuleBase::matrix fcs; @@ -327,6 +334,8 @@ void ESolver_KS_LCAO::cal_stress(ModuleBase::matrix& stress) template void ESolver_KS_LCAO::post_process(void) { + ModuleBase::TITLE("ESolver_KS_LCAO", "post_process"); + GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; GlobalV::ofs_running << std::setprecision(16); GlobalV::ofs_running << " !FINAL_ETOT_IS " << this->pelec->f_en.etot * ModuleBase::Ry_to_eV << " eV" << std::endl; @@ -417,7 +426,7 @@ void ESolver_KS_LCAO::post_process(void) template -void ESolver_KS_LCAO::Init_Basis_lcao( +void ESolver_KS_LCAO::init_basis_lcao( ORB_control& orb_con, Input& inp, UnitCell& ucell) @@ -506,6 +515,8 @@ void ESolver_KS_LCAO::Init_Basis_lcao( template void ESolver_KS_LCAO::iter_init(const int istep, const int iter) { + ModuleBase::TITLE("ESolver_KS_LCAO", "iter_init"); + if (iter == 1) { this->p_chgmix->init_mixing(); // init mixing diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index 269bb2b3a1e..abc8dbda6fb 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -89,7 +89,7 @@ namespace ModuleESolver ModuleBase::matrix scs; bool have_force = false; - void Init_Basis_lcao(ORB_control& orb_con, Input& inp, UnitCell& ucell); + void init_basis_lcao(ORB_control& orb_con, Input& inp, UnitCell& ucell); //--------------common for all calculation, not only scf------------- // set matrix and grid integral diff --git a/source/module_esolver/esolver_ks_lcao_tddft.cpp b/source/module_esolver/esolver_ks_lcao_tddft.cpp index a4ff74d1501..a9bd2e44313 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/module_esolver/esolver_ks_lcao_tddft.cpp @@ -90,7 +90,7 @@ void ESolver_KS_LCAO_TDDFT::init(Input& inp, UnitCell& ucell) // Init Basis should be put outside of Ensolver. // * reading the localized orbitals/projectors // * construct the interpolation tables. - this->Init_Basis_lcao(this->orb_con, inp, ucell); + this->init_basis_lcao(this->orb_con, inp, ucell); //------------------init Basis_lcao---------------------- //------------------init Hamilt_lcao---------------------- From 3e153888821d8436eacc961563cc80a0eadd9fd5 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 15:22:55 +0800 Subject: [PATCH 32/46] update esolver_ks_lcao --- source/module_esolver/esolver_ks_lcao.cpp | 41 ++++++++++++++++------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index f2a8e0d9d3b..2db9ee905dc 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -229,7 +229,8 @@ void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) if (GlobalV::ocp) { this->pelec->fixed_weights(GlobalV::ocp_kb); - } + } + return; } @@ -270,7 +271,8 @@ void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) &(this->pelec->f_en.etxc), &(this->pelec->f_en.vtxc)); } - } + } + return; } @@ -431,6 +433,8 @@ void ESolver_KS_LCAO::init_basis_lcao( Input& inp, UnitCell& ucell) { + ModuleBase::TITLE("ESolver_KS_LCAO", "init_basis_lcao"); + // autoset NB2D first if (GlobalV::NB2D == 0) { @@ -509,6 +513,8 @@ void ESolver_KS_LCAO::init_basis_lcao( this->orb_con.setup_2d_division(GlobalV::ofs_running, GlobalV::ofs_warning); this->orb_con.ParaV.set_atomic_trace(GlobalC::ucell.get_iat2iwt(), GlobalC::ucell.nat, GlobalV::NLOCAL); } + + return; } @@ -656,6 +662,8 @@ void ESolver_KS_LCAO::iter_init(const int istep, const int iter) template void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) { + ModuleBase::TITLE("ESolver_KS_LCAO", "hamilt2density"); + // save input rho this->pelec->charge->save_rho_before_sum_band(); // save density matrix for mixing @@ -767,6 +775,8 @@ void ESolver_KS_LCAO::hamilt2density(int istep, int iter, double ethr) template void ESolver_KS_LCAO::update_pot(const int istep, const int iter) { + ModuleBase::TITLE("ESolver_KS_LCAO", "update_pot"); + // print Hamiltonian and Overlap matrix if (this->conv_elec) { @@ -863,6 +873,8 @@ void ESolver_KS_LCAO::update_pot(const int istep, const int iter) template void ESolver_KS_LCAO::iter_finish(int iter) { + ModuleBase::TITLE("ESolver_KS_LCAO", "iter_finish"); + // mix density matrix if (GlobalV::MIXING_RESTART > 0 && iter >= this->p_chgmix->mixing_restart && GlobalV::MIXING_DMR ) { @@ -941,6 +953,8 @@ void ESolver_KS_LCAO::iter_finish(int iter) template void ESolver_KS_LCAO::after_scf(const int istep) { + ModuleBase::TITLE("ESolver_KS_LCAO", "after_scf"); + // save charge difference into files for charge extrapolation if (GlobalV::CALCULATION != "scf") { @@ -1063,6 +1077,7 @@ void ESolver_KS_LCAO::after_scf(const int istep) { RA.delete_grid(); } + if(GlobalV::qo_switch) { toQO tqo(GlobalV::qo_basis, GlobalV::qo_strategy, GlobalV::qo_thr, GlobalV::qo_screening_coeff); @@ -1138,17 +1153,17 @@ ModuleIO::Output_DM1 ESolver_KS_LCAO::create_Output_DM1(int istep) template ModuleIO::Output_Mat_Sparse ESolver_KS_LCAO::create_Output_Mat_Sparse(int istep) { - return ModuleIO::Output_Mat_Sparse(hsolver::HSolverLCAO::out_mat_hsR, - hsolver::HSolverLCAO::out_mat_dh, - hsolver::HSolverLCAO::out_mat_t, - INPUT.out_mat_r, - istep, - this->pelec->pot->get_effective_v(), - *this->LOWF.ParaV, - this->UHM, - this->LM, - this->kv, - this->p_hamilt); + return ModuleIO::Output_Mat_Sparse(hsolver::HSolverLCAO::out_mat_hsR, + hsolver::HSolverLCAO::out_mat_dh, + hsolver::HSolverLCAO::out_mat_t, + INPUT.out_mat_r, + istep, + this->pelec->pot->get_effective_v(), + *this->LOWF.ParaV, + this->UHM, + this->LM, + this->kv, + this->p_hamilt); } From 413e73fcd92294744b798cd6cf700dd11244a195 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 15:36:55 +0800 Subject: [PATCH 33/46] update esolver_lcao --- source/module_esolver/esolver_ks.cpp | 14 +++++++++----- source/module_esolver/esolver_ks_lcao.cpp | 7 +++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/module_esolver/esolver_ks.cpp b/source/module_esolver/esolver_ks.cpp index 419dc48ca3e..de479128f3a 100644 --- a/source/module_esolver/esolver_ks.cpp +++ b/source/module_esolver/esolver_ks.cpp @@ -392,7 +392,9 @@ void ESolver_KS::run(const int istep, UnitCell& ucell) ModuleBase::timer::tick(this->classname, "run"); this->before_scf(istep); //Something else to do before the iter loop + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "INIT SCF"); + if(this->maxniter > 0) { this->print_head(); //print the headline on the screen. @@ -499,9 +501,6 @@ void ESolver_KS::run(const int istep, UnitCell& ucell) (std::chrono::duration_cast(std::chrono::system_clock::now() - iterstart)).count() / static_cast(1e6); #endif - /* - SCF print: G1 -3.435545e+03 0.000000e+00 3.607e-01 2.862e-01 - */ double dkin = 0.0; // for meta-GGA if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) @@ -525,7 +524,10 @@ void ESolver_KS::run(const int istep, UnitCell& ucell) { this->niter = iter; bool stop = this->do_after_converge(iter); - if(stop) break; + if(stop) + { + break; + } } // notice for restart @@ -544,7 +546,9 @@ void ESolver_KS::run(const int istep, UnitCell& ucell) this->conv_elec ); #endif //__RAPIDJSON - after_scf(istep); + + this->after_scf(istep); + ModuleBase::timer::tick(this->classname, "run"); } diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 2db9ee905dc..dee44ab23b9 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -1040,6 +1040,7 @@ void ESolver_KS_LCAO::after_scf(const int istep) this->LOWF.ParaV, *(this->psi), dynamic_cast*>(this->pelec)->get_DM()); + ModuleBase::timer::tick("ESolver_KS_LCAO", "out_deepks_labels"); #endif @@ -1067,6 +1068,7 @@ void ESolver_KS_LCAO::after_scf(const int istep) } // qifeng add 2019/9/10, jiyy modify 2023/2/27, liuyu move here 2023-04-18 } + // spin constrain calculations, added by Tianqi Zhao. if (GlobalV::sc_mag_switch) { SpinConstrain& sc = SpinConstrain::getScInstance(); @@ -1078,6 +1080,7 @@ void ESolver_KS_LCAO::after_scf(const int istep) RA.delete_grid(); } + // quasi-orbitals, added by Yike Huang. if(GlobalV::qo_switch) { toQO tqo(GlobalV::qo_basis, GlobalV::qo_strategy, GlobalV::qo_thr, GlobalV::qo_screening_coeff); @@ -1095,6 +1098,8 @@ void ESolver_KS_LCAO::after_scf(const int istep) template bool ESolver_KS_LCAO::do_after_converge(int& iter) { + TITLE("ESolver_KS_LCAO","do_after_converge"); + #ifdef __EXX if (GlobalC::exx_info.info_ri.real_number) { @@ -1114,11 +1119,13 @@ bool ESolver_KS_LCAO::do_after_converge(int& iter) iter); } #endif // __EXX + if(GlobalV::dft_plus_u) { // use the converged occupation matrix for next MD/Relax SCF calculation GlobalC::dftu.initialed_locale = true; } + return true; } From 3f2006af5f2b02744efed66de69cf8fbd785903c Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 15:54:57 +0800 Subject: [PATCH 34/46] update timer::tick in esolver_lcao --- source/module_esolver/esolver_ks_lcao.cpp | 19 ++++++- .../hamilt_lcaodft/LCAO_hamilt.cpp | 56 ++++++++++++++----- 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index dee44ab23b9..c2176439f35 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -1,4 +1,5 @@ #include "esolver_ks_lcao.h" +#include "module_base/tool_title.h" #include "module_base/global_variable.h" #include "module_io/dos_nao.h" @@ -80,6 +81,8 @@ template void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) { ModuleBase::TITLE("ESolver_KS_LCAO", "init"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "init"); + // if we are only calculating S, then there is no need // to prepare for potentials and so on @@ -136,6 +139,7 @@ void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) if (GlobalV::CALCULATION == "get_S") { + ModuleBase::timer::tick("ESolver_KS_LCAO", "init"); return; } @@ -230,6 +234,8 @@ void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) { this->pelec->fixed_weights(GlobalV::ocp_kb); } + + ModuleBase::timer::tick("ESolver_KS_LCAO", "init"); return; } @@ -238,6 +244,7 @@ template void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) { ModuleBase::TITLE("ESolver_KS_LCAO", "init_after_vc"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "init_after_vc"); ESolver_KS::init_after_vc(inp, ucell); @@ -272,6 +279,8 @@ void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) &(this->pelec->f_en.vtxc)); } } + + ModuleBase::timer::tick("ESolver_KS_LCAO", "init_after_vc"); return; } @@ -289,6 +298,7 @@ template void ESolver_KS_LCAO::cal_force(ModuleBase::matrix& force) { ModuleBase::TITLE("ESolver_KS_LCAO", "cal_force"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "cal_force"); Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); FSL.getForceStress(GlobalV::CAL_FORCE, @@ -315,6 +325,8 @@ void ESolver_KS_LCAO::cal_force(ModuleBase::matrix& force) this->RA.delete_grid(); this->have_force = true; + + ModuleBase::timer::tick("ESolver_KS_LCAO", "cal_force"); } @@ -322,6 +334,7 @@ template void ESolver_KS_LCAO::cal_stress(ModuleBase::matrix& stress) { ModuleBase::TITLE("ESolver_KS_LCAO", "cal_stress"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "cal_stress"); if (!this->have_force) { @@ -330,6 +343,8 @@ void ESolver_KS_LCAO::cal_stress(ModuleBase::matrix& stress) } stress = this->scs; // copy the stress this->have_force = false; + + ModuleBase::timer::tick("ESolver_KS_LCAO", "cal_stress"); } @@ -337,6 +352,7 @@ template void ESolver_KS_LCAO::post_process(void) { ModuleBase::TITLE("ESolver_KS_LCAO", "post_process"); + ModuleBase::timer::tick("ESolver_KS_LCAO", "post_process"); GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl; GlobalV::ofs_running << std::setprecision(16); @@ -424,6 +440,7 @@ void ESolver_KS_LCAO::post_process(void) GlobalV::NBANDS, this->p_hamilt); } + ModuleBase::timer::tick("ESolver_KS_LCAO", "post_process"); } @@ -1098,7 +1115,7 @@ void ESolver_KS_LCAO::after_scf(const int istep) template bool ESolver_KS_LCAO::do_after_converge(int& iter) { - TITLE("ESolver_KS_LCAO","do_after_converge"); + ModuleBase::TITLE("ESolver_KS_LCAO","do_after_converge"); #ifdef __EXX if (GlobalC::exx_info.info_ri.real_number) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp index 4030ff5eef3..bcadc5f8090 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp @@ -188,7 +188,11 @@ void LCAO_Hamilt::calculate_STN_R_sparse_for_S(const double &sparse_threshold) } #include "module_hamilt_lcao/module_hcontainer/hcontainer.h" -void LCAO_Hamilt::calculate_HContainer_sparse_d(const int ¤t_spin, const double &sparse_threshold, const hamilt::HContainer& hR, std::map, std::map>>& target) +void LCAO_Hamilt::calculate_HContainer_sparse_d( + const int ¤t_spin, + const double &sparse_threshold, + const hamilt::HContainer& hR, + std::map, std::map>>& target) { ModuleBase::TITLE("LCAO_Hamilt","calculate_HContainer_sparse_d"); @@ -266,7 +270,11 @@ void LCAO_Hamilt::calculate_HContainer_sparse_cd(const int ¤t_spin, const return; } -void LCAO_Hamilt::calculate_HSR_sparse(const int ¤t_spin, const double &sparse_threshold, const int (&nmp)[3], hamilt::Hamilt>* p_ham) +void LCAO_Hamilt::calculate_HSR_sparse( + const int ¤t_spin, + const double &sparse_threshold, + const int (&nmp)[3], + hamilt::Hamilt>* p_ham) { ModuleBase::TITLE("LCAO_Hamilt","calculate_HSR_sparse"); @@ -275,15 +283,33 @@ void LCAO_Hamilt::calculate_HSR_sparse(const int ¤t_spin, const double &sp //calculate_STN_R_sparse(current_spin, sparse_threshold); if(GlobalV::NSPIN!=4) { - hamilt::HamiltLCAO, double>* p_ham_lcao = dynamic_cast, double>*>(p_ham); - this->calculate_HContainer_sparse_d(current_spin, sparse_threshold, *(p_ham_lcao->getHR()), this->LM->HR_sparse[current_spin]); - this->calculate_HContainer_sparse_d(current_spin, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_sparse); + hamilt::HamiltLCAO, double>* p_ham_lcao = + dynamic_cast, double>*>(p_ham); + + this->calculate_HContainer_sparse_d(current_spin, + sparse_threshold, + *(p_ham_lcao->getHR()), + this->LM->HR_sparse[current_spin]); + + this->calculate_HContainer_sparse_d(current_spin, + sparse_threshold, + *(p_ham_lcao->getSR()), + this->LM->SR_sparse); } else { - hamilt::HamiltLCAO, std::complex>* p_ham_lcao = dynamic_cast, std::complex>*>(p_ham); - this->calculate_HContainer_sparse_cd(current_spin, sparse_threshold, *(p_ham_lcao->getHR()), this->LM->HR_soc_sparse); - this->calculate_HContainer_sparse_cd(current_spin, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_soc_sparse); + hamilt::HamiltLCAO, std::complex>* p_ham_lcao = + dynamic_cast, std::complex>*>(p_ham); + + this->calculate_HContainer_sparse_cd(current_spin, + sparse_threshold, + *(p_ham_lcao->getHR()), + this->LM->HR_soc_sparse); + + this->calculate_HContainer_sparse_cd(current_spin, + sparse_threshold, + *(p_ham_lcao->getSR()), + this->LM->SR_soc_sparse); } // only old DFT+U method need to calculate extra contribution to HR @@ -303,11 +329,15 @@ void LCAO_Hamilt::calculate_HSR_sparse(const int ¤t_spin, const double &sp #ifdef __MPI if( GlobalC::exx_info.info_global.cal_exx ) { - if(GlobalC::exx_info.info_ri.real_number) - this->calculate_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxd); - else - this->calculate_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxc); - } + if(GlobalC::exx_info.info_ri.real_number) + { + this->calculate_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxd); + } + else + { + this->calculate_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxc); + } + } #endif // __MPI #endif // __EXX From 78c08cff731a3965eefeb02af9d0946ba16382ef Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 21:29:15 +0800 Subject: [PATCH 35/46] try to delete LCAO_Matrix in LCAO_Hamilt, and try to delete Parallel_Orbitals in Force_k --- source/module_esolver/esolver_ks_lcao.cpp | 8 +- source/module_esolver/esolver_ks_lcao.h | 4 +- .../hamilt_lcaodft/FORCE_STRESS.cpp | 40 +- .../hamilt_lcaodft/FORCE_STRESS.h | 12 +- .../hamilt_lcaodft/FORCE_gamma.cpp | 175 +++++--- .../hamilt_lcaodft/FORCE_gamma.h | 24 +- .../hamilt_lcaodft/FORCE_gamma_edm.cpp | 27 +- .../hamilt_lcaodft/FORCE_gamma_tvnl.cpp | 28 +- .../hamilt_lcaodft/FORCE_k.cpp | 418 ++++++++++-------- .../hamilt_lcaodft/FORCE_k.h | 71 +-- .../hamilt_lcaodft/LCAO_hamilt.cpp | 129 +++--- .../hamilt_lcaodft/LCAO_hamilt.h | 24 +- .../hamilt_lcaodft/record_adj.cpp | 1 - source/module_io/write_HS_R.cpp | 18 +- 14 files changed, 571 insertions(+), 408 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index c2176439f35..3379777f905 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -300,12 +300,16 @@ void ESolver_KS_LCAO::cal_force(ModuleBase::matrix& force) ModuleBase::TITLE("ESolver_KS_LCAO", "cal_force"); ModuleBase::timer::tick("ESolver_KS_LCAO", "cal_force"); - Force_Stress_LCAO FSL(this->RA, GlobalC::ucell.nat); - FSL.getForceStress(GlobalV::CAL_FORCE, + Force_Stress_LCAO fsl(this->RA, GlobalC::ucell.nat); + + fsl.getForceStress( + GlobalV::CAL_FORCE, GlobalV::CAL_STRESS, GlobalV::TEST_FORCE, GlobalV::TEST_STRESS, this->LOC, + this->orb_con.ParaV, + this->LM, this->pelec, this->psi, this->UHM, diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index abc8dbda6fb..49d95cdfe55 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -32,9 +32,9 @@ namespace ModuleESolver double cal_energy() override; - void cal_force(ModuleBase::matrix& force) override; + void cal_force(ModuleBase::matrix &force) override; - void cal_stress(ModuleBase::matrix& stress) override; + void cal_stress(ModuleBase::matrix &stress) override; void post_process() override; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp index 3608202ee8d..4fa805e78de 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp @@ -29,7 +29,9 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, const bool isstress, const bool istestf, const bool istests, - Local_Orbital_Charge& loc, + Local_Orbital_Charge &loc, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, const elecstate::ElecState* pelec, const psi::Psi* psi, LCAO_Hamilt& uhm, @@ -155,7 +157,9 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, #else svl_dphi, #endif - uhm, + uhm, + pv, + lm, kv); // implement vdw force or stress here // Peize Lin add 2014-04-04, update 2021-03-09 @@ -242,10 +246,12 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, tmp_dftu.cal_force_stress(isforce, isstress, force_dftu, stress_dftu); } } + if (!GlobalV::GAMMA_ONLY_LOCAL) { - this->flk.finish_k(); + this->flk.finish_k(lm); } + #ifdef __EXX // Force and Stress contribution from exx ModuleBase::matrix force_exx; @@ -712,7 +718,8 @@ void Force_Stress_LCAO::calForcePwPart(ModuleBase::matrix& fvl_dvl, // overlap, kinetic, nonlocal pseudopotential, Local potential terms in force and stress template<> -void Force_Stress_LCAO::calForceStressIntegralPart(const bool isGammaOnly, +void Force_Stress_LCAO::calForceStressIntegralPart( + const bool isGammaOnly, const bool isforce, const bool isstress, Local_Orbital_Charge& loc, @@ -731,9 +738,12 @@ void Force_Stress_LCAO::calForceStressIntegralPart(const bool isGammaOnl #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, + LCAO_Hamilt &uhm, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, const K_Vectors& kv) { + flk.ftable_gamma(isforce, isstress, psi, @@ -752,11 +762,15 @@ void Force_Stress_LCAO::calForceStressIntegralPart(const bool isGammaOnl #else svl_dphi, #endif - uhm); + uhm, + lm); return; } + + template<> -void Force_Stress_LCAO>::calForceStressIntegralPart(const bool isGammaOnly, +void Force_Stress_LCAO>::calForceStressIntegralPart( + const bool isGammaOnly, const bool isforce, const bool isstress, Local_Orbital_Charge& loc, @@ -775,7 +789,9 @@ void Force_Stress_LCAO>::calForceStressIntegralPart(const b #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, + LCAO_Hamilt &uhm, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, const K_Vectors& kv) { flk.ftable_k(isforce, @@ -797,8 +813,10 @@ void Force_Stress_LCAO>::calForceStressIntegralPart(const b #else svl_dphi, #endif - uhm, - kv); + uhm, + pv, + lm, + kv); return; } @@ -904,4 +922,4 @@ void Force_Stress_LCAO::forceSymmetry(ModuleBase::matrix& fcs, ModuleSymmetry } template class Force_Stress_LCAO; -template class Force_Stress_LCAO>; \ No newline at end of file +template class Force_Stress_LCAO>; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h index ccca8073ff6..8aaf0d4a387 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h @@ -30,8 +30,10 @@ class Force_Stress_LCAO const bool isstress, const bool istestf, const bool istests, - Local_Orbital_Charge& loc, - const elecstate::ElecState* pelec, + Local_Orbital_Charge& loc, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const elecstate::ElecState* pelec, const psi::Psi* psi, LCAO_Hamilt& uhm, ModuleBase::matrix& fcs, @@ -85,8 +87,10 @@ class Force_Stress_LCAO #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, - const K_Vectors& kv); + LCAO_Hamilt &uhm, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const K_Vectors& kv); void calStressPwPart(ModuleBase::matrix& sigmadvl, ModuleBase::matrix& sigmahar, diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp index 1db8883136d..2bc04ebd51b 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp @@ -38,7 +38,8 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm) + LCAO_Hamilt &uhm, + LCAO_Matrix &lm) { ModuleBase::TITLE("Force_LCAO_gamma", "ftable"); ModuleBase::timer::tick("Force_LCAO_gamma", "ftable_gamma"); @@ -53,15 +54,15 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, // allocate DSloc_x, DSloc_y, DSloc_z // allocate DHloc_fixed_x, DHloc_fixed_y, DHloc_fixed_z - this->allocate_gamma(*this->ParaV); + this->allocate_gamma(*this->ParaV, lm); // calculate the 'energy density matrix' here. - this->cal_foverlap(isforce, isstress, psid, pelec, foverlap, soverlap); + this->cal_foverlap(isforce, isstress, psid, pelec, lm, foverlap, soverlap); // sum up the density matrix with different spin // DM->sum_DMR_spin(); // - this->cal_ftvnl_dphi(DM, isforce, isstress, ftvnl_dphi, stvnl_dphi); + this->cal_ftvnl_dphi(DM, lm, isforce, isstress, ftvnl_dphi, stvnl_dphi); this->cal_fvnl_dbeta(DM, isforce, isstress, fvnl_dbeta, svnl_dbeta); this->cal_fvl_dphi(loc.DM, isforce, isstress, pelec->pot, fvl_dphi, svl_dphi); @@ -119,13 +120,15 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, // delete DSloc_x, DSloc_y, DSloc_z // delete DHloc_fixed_x, DHloc_fixed_y, DHloc_fixed_z - this->finish_ftable_gamma(); + this->finish_ftable_gamma(lm); ModuleBase::timer::tick("Force_LCAO_gamma", "ftable_gamma"); return; } -void Force_LCAO_gamma::allocate_gamma(const Parallel_Orbitals& pv) +void Force_LCAO_gamma::allocate_gamma( + const Parallel_Orbitals &pv, + LCAO_Matrix &lm) { ModuleBase::TITLE("Force_LCAO_gamma", "allocate_gamma"); ModuleBase::timer::tick("Force_LCAO_gamma", "allocate_gamma"); @@ -138,108 +141,134 @@ void Force_LCAO_gamma::allocate_gamma(const Parallel_Orbitals& pv) // liaochen add on 2010/7/12 // save the results in dense matrix by now. // pv.nloc: number of H elements in this proc. - this->UHM->LM->DSloc_x = new double[pv.nloc]; - this->UHM->LM->DSloc_y = new double[pv.nloc]; - this->UHM->LM->DSloc_z = new double[pv.nloc]; - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_x, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_y, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_z, pv.nloc); + lm.DSloc_x = new double[pv.nloc]; + lm.DSloc_y = new double[pv.nloc]; + lm.DSloc_z = new double[pv.nloc]; + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_x, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_y, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_z, pv.nloc); ModuleBase::Memory::record("Force::dS_GO", sizeof(double) * pv.nloc * 3); // allocate stress part in gamma_only-line, added by zhengdy-stress if (GlobalV::CAL_STRESS) { - this->UHM->LM->DSloc_11 = new double[pv.nloc]; - this->UHM->LM->DSloc_12 = new double[pv.nloc]; - this->UHM->LM->DSloc_13 = new double[pv.nloc]; - this->UHM->LM->DSloc_22 = new double[pv.nloc]; - this->UHM->LM->DSloc_23 = new double[pv.nloc]; - this->UHM->LM->DSloc_33 = new double[pv.nloc]; - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_11, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_12, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_13, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_22, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_23, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_33, pv.nloc); - this->UHM->LM->DHloc_fixed_11 = new double[pv.nloc]; - this->UHM->LM->DHloc_fixed_12 = new double[pv.nloc]; - this->UHM->LM->DHloc_fixed_13 = new double[pv.nloc]; - this->UHM->LM->DHloc_fixed_22 = new double[pv.nloc]; - this->UHM->LM->DHloc_fixed_23 = new double[pv.nloc]; - this->UHM->LM->DHloc_fixed_33 = new double[pv.nloc]; - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_11, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_12, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_13, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_22, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_23, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_33, pv.nloc); + lm.DSloc_11 = new double[pv.nloc]; + lm.DSloc_12 = new double[pv.nloc]; + lm.DSloc_13 = new double[pv.nloc]; + lm.DSloc_22 = new double[pv.nloc]; + lm.DSloc_23 = new double[pv.nloc]; + lm.DSloc_33 = new double[pv.nloc]; + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_11, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_12, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_13, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_22, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_23, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_33, pv.nloc); + lm.DHloc_fixed_11 = new double[pv.nloc]; + lm.DHloc_fixed_12 = new double[pv.nloc]; + lm.DHloc_fixed_13 = new double[pv.nloc]; + lm.DHloc_fixed_22 = new double[pv.nloc]; + lm.DHloc_fixed_23 = new double[pv.nloc]; + lm.DHloc_fixed_33 = new double[pv.nloc]; + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_11, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_12, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_13, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_22, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_23, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_33, pv.nloc); ModuleBase::Memory::record("Stress::dSH_GO", sizeof(double) * pv.nloc * 12); } // calculate dS in LCAO basis // ModuleBase::timer::tick("Force_LCAO_gamma","build_S_new"); - this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, this->UHM->LM->Sloc.data()); + this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, lm.Sloc.data()); // ModuleBase::timer::tick("Force_LCAO_gamma","build_S_new"); // calculate dT in LCAP // allocation dt // liaochen add on 2010/7/12 - this->UHM->LM->DHloc_fixed_x = new double[pv.nloc]; - this->UHM->LM->DHloc_fixed_y = new double[pv.nloc]; - this->UHM->LM->DHloc_fixed_z = new double[pv.nloc]; + lm.DHloc_fixed_x = new double[pv.nloc]; + lm.DHloc_fixed_y = new double[pv.nloc]; + lm.DHloc_fixed_z = new double[pv.nloc]; ModuleBase::Memory::record("Force::dTVNL", sizeof(double) * pv.nloc * 3); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_x, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_y, pv.nloc); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixed_z, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_x, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_y, pv.nloc); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixed_z, pv.nloc); // calculate dT // calculate T + VNL(P1) in LCAO basis // ModuleBase::timer::tick("Force_LCAO_gamma","build_T_new"); - this->UHM->genH.build_ST_new('T', cal_deri, GlobalC::ucell, this->UHM->LM->Hloc_fixed.data()); + this->UHM->genH.build_ST_new('T', cal_deri, GlobalC::ucell, lm.Hloc_fixed.data()); // ModuleBase::timer::tick("Force_LCAO_gamma","build_T_new"); - // test_gamma(this->UHM->LM->DHloc_fixed_x, "dHloc_fixed_x T part"); + // test_gamma(lm.DHloc_fixed_x, "dHloc_fixed_x T part"); // ModuleBase::timer::tick("Force_LCAO_gamma","build_Nonlocal_mu"); - this->UHM->genH.build_Nonlocal_mu_new(this->UHM->genH.LM->Hloc_fixed.data(), cal_deri); + this->UHM->genH.build_Nonlocal_mu_new(lm.Hloc_fixed.data(), cal_deri); // ModuleBase::timer::tick("Force_LCAO_gamma","build_Nonlocal_mu"); - // test_gamma(this->UHM->LM->DHloc_fixed_x, "dHloc_fixed_x Vnl part"); + // test_gamma(lm.DHloc_fixed_x, "dHloc_fixed_x Vnl part"); // calculate asynchronous S matrix to output for Hefei-NAMD if (INPUT.cal_syns) { cal_deri = false; - this->UHM->genH.LM->zeros_HSgamma('S'); - this->UHM->genH - .build_ST_new('S', cal_deri, GlobalC::ucell, this->UHM->genH.LM->Sloc.data(), INPUT.cal_syns, INPUT.dmax); + + lm.zeros_HSgamma('S'); + + this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, + + lm.Sloc.data(), INPUT.cal_syns, INPUT.dmax); + bool bit = false; // LiuXh, 2017-03-21 - ModuleIO::save_mat(0, this->UHM->genH.LM->Hloc.data(), GlobalV::NLOCAL, bit, GlobalV::out_ndigits, 0, GlobalV::out_app_flag, "H", "data-" + std::to_string(0), *this->ParaV, GlobalV::DRANK); - ModuleIO::save_mat(0, this->UHM->genH.LM->Sloc.data(), GlobalV::NLOCAL, bit, GlobalV::out_ndigits, 0, GlobalV::out_app_flag, "S", "data-" + std::to_string(0), *this->ParaV, GlobalV::DRANK); - } + + ModuleIO::save_mat(0, + lm.Hloc.data(), + GlobalV::NLOCAL, + bit, + GlobalV::out_ndigits, + 0, + GlobalV::out_app_flag, + "H", + "data-" + std::to_string(0), + *this->ParaV, + GlobalV::DRANK); + + ModuleIO::save_mat(0, + lm.Sloc.data(), + GlobalV::NLOCAL, + bit, + GlobalV::out_ndigits, + 0, + GlobalV::out_app_flag, + "S", + "data-" + std::to_string(0), + *this->ParaV, + GlobalV::DRANK); + } ModuleBase::timer::tick("Force_LCAO_gamma", "allocate_gamma"); return; } -void Force_LCAO_gamma::finish_ftable_gamma(void) +void Force_LCAO_gamma::finish_ftable_gamma(LCAO_Matrix &lm) { - delete[] this->UHM->LM->DSloc_x; - delete[] this->UHM->LM->DSloc_y; - delete[] this->UHM->LM->DSloc_z; - delete[] this->UHM->LM->DHloc_fixed_x; - delete[] this->UHM->LM->DHloc_fixed_y; - delete[] this->UHM->LM->DHloc_fixed_z; + delete[] lm.DSloc_x; + delete[] lm.DSloc_y; + delete[] lm.DSloc_z; + delete[] lm.DHloc_fixed_x; + delete[] lm.DHloc_fixed_y; + delete[] lm.DHloc_fixed_z; if (GlobalV::CAL_STRESS) // added by zhengdy-stress { - delete[] this->UHM->LM->DSloc_11; - delete[] this->UHM->LM->DSloc_12; - delete[] this->UHM->LM->DSloc_13; - delete[] this->UHM->LM->DHloc_fixed_11; - delete[] this->UHM->LM->DHloc_fixed_12; - delete[] this->UHM->LM->DHloc_fixed_13; - delete[] this->UHM->LM->DSloc_22; - delete[] this->UHM->LM->DSloc_23; - delete[] this->UHM->LM->DSloc_33; - delete[] this->UHM->LM->DHloc_fixed_22; - delete[] this->UHM->LM->DHloc_fixed_23; - delete[] this->UHM->LM->DHloc_fixed_33; + delete[] lm.DSloc_11; + delete[] lm.DSloc_12; + delete[] lm.DSloc_13; + delete[] lm.DHloc_fixed_11; + delete[] lm.DHloc_fixed_12; + delete[] lm.DHloc_fixed_13; + delete[] lm.DSloc_22; + delete[] lm.DSloc_23; + delete[] lm.DSloc_33; + delete[] lm.DHloc_fixed_22; + delete[] lm.DHloc_fixed_23; + delete[] lm.DHloc_fixed_33; } return; } @@ -282,4 +311,4 @@ void stress_fill(const double& lat0_, const double& omega_, ModuleBase::matrix& } } } -} // namespace StressTools \ No newline at end of file +} // namespace StressTools diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h index e9efd88b425..a3358382ee7 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h @@ -20,8 +20,11 @@ class Force_LCAO_gamma ~Force_LCAO_gamma(); private: + LCAO_Hamilt* UHM; + const Parallel_Orbitals* ParaV; + elecstate::Potential* pot; // orthonormal force + contribution from T and VNL @@ -43,12 +46,17 @@ class Force_LCAO_gamma #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm); + LCAO_Hamilt& uhm, + LCAO_Matrix& lm); + + // get the ds, dt, dvnl. - void allocate_gamma(const Parallel_Orbitals& pv); + void allocate_gamma( + const Parallel_Orbitals& pv, + LCAO_Matrix &lm); - void finish_ftable_gamma(void); + void finish_ftable_gamma(LCAO_Matrix &lm); void average_force(double* fm); @@ -61,15 +69,17 @@ class Force_LCAO_gamma void cal_foverlap(const bool isforce, const bool isstress, - const psi::Psi* psid, - const elecstate::ElecState* pelec, - ModuleBase::matrix& foverlap, - ModuleBase::matrix& soverlap); + const psi::Psi *psid, + const elecstate::ElecState *pelec, + LCAO_Matrix &lm, + ModuleBase::matrix &foverlap, + ModuleBase::matrix &soverlap); //------------------------------------------------------------- // forces related to kinetic and non-local pseudopotentials //-------------------------------------------------------------- void cal_ftvnl_dphi(const elecstate::DensityMatrix* DM, + LCAO_Matrix &lm, const bool isforce, const bool isstress, ModuleBase::matrix& ftvnl_dphi, diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_edm.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_edm.cpp index a69821c50ce..e719bc8537e 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_edm.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_edm.cpp @@ -11,10 +11,11 @@ void Force_LCAO_gamma::cal_foverlap( const bool isforce, const bool isstress, - const psi::Psi* psid, - const elecstate::ElecState* pelec, - ModuleBase::matrix& foverlap, - ModuleBase::matrix& soverlap) + const psi::Psi *psid, + const elecstate::ElecState *pelec, + LCAO_Matrix &lm, + ModuleBase::matrix &foverlap, + ModuleBase::matrix &soverlap) { ModuleBase::TITLE("Force_LCAO_gamma","cal_foverlap"); ModuleBase::timer::tick("Force_LCAO_gamma","cal_foverlap"); @@ -61,19 +62,19 @@ void Force_LCAO_gamma::cal_foverlap( if(isforce) { - foverlap(iat,0) += sum * this->UHM->LM->DSloc_x[index]; - foverlap(iat,1) += sum * this->UHM->LM->DSloc_y[index]; - foverlap(iat,2) += sum * this->UHM->LM->DSloc_z[index]; + foverlap(iat,0) += sum * lm.DSloc_x[index]; + foverlap(iat,1) += sum * lm.DSloc_y[index]; + foverlap(iat,2) += sum * lm.DSloc_z[index]; } if(isstress) { - soverlap(0,0) += sum/2.0 * this->UHM->LM->DSloc_11[index]; - soverlap(0,1) += sum/2.0 * this->UHM->LM->DSloc_12[index]; - soverlap(0,2) += sum/2.0 * this->UHM->LM->DSloc_13[index]; - soverlap(1,1) += sum/2.0 * this->UHM->LM->DSloc_22[index]; - soverlap(1,2) += sum/2.0 * this->UHM->LM->DSloc_23[index]; - soverlap(2,2) += sum/2.0 * this->UHM->LM->DSloc_33[index]; + soverlap(0,0) += sum/2.0 * lm.DSloc_11[index]; + soverlap(0,1) += sum/2.0 * lm.DSloc_12[index]; + soverlap(0,2) += sum/2.0 * lm.DSloc_13[index]; + soverlap(1,1) += sum/2.0 * lm.DSloc_22[index]; + soverlap(1,2) += sum/2.0 * lm.DSloc_23[index]; + soverlap(2,2) += sum/2.0 * lm.DSloc_33[index]; } } diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_tvnl.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_tvnl.cpp index 3759f5f9a7e..dd89912d1dd 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_tvnl.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_tvnl.cpp @@ -237,6 +237,7 @@ void Force_LCAO_gamma::cal_fvnl_dbeta( void Force_LCAO_gamma::cal_ftvnl_dphi( const elecstate::DensityMatrix* DM, + LCAO_Matrix &lm, const bool isforce, const bool isstress, ModuleBase::matrix& ftvnl_dphi, @@ -268,25 +269,26 @@ void Force_LCAO_gamma::cal_ftvnl_dphi( if(isforce) { - ftvnl_dphi(iat,0) += sum * this->UHM->LM->DHloc_fixed_x[index]; - ftvnl_dphi(iat,1) += sum * this->UHM->LM->DHloc_fixed_y[index]; - ftvnl_dphi(iat,2) += sum * this->UHM->LM->DHloc_fixed_z[index]; + ftvnl_dphi(iat,0) += sum * lm.DHloc_fixed_x[index]; + ftvnl_dphi(iat,1) += sum * lm.DHloc_fixed_y[index]; + ftvnl_dphi(iat,2) += sum * lm.DHloc_fixed_z[index]; } if(isstress) { - stvnl_dphi(0,0) += sum/2.0 * this->UHM->LM->DHloc_fixed_11[index]; - stvnl_dphi(0,1) += sum/2.0 * this->UHM->LM->DHloc_fixed_12[index]; - stvnl_dphi(0,2) += sum/2.0 * this->UHM->LM->DHloc_fixed_13[index]; - stvnl_dphi(1,1) += sum/2.0 * this->UHM->LM->DHloc_fixed_22[index]; - stvnl_dphi(1,2) += sum/2.0 * this->UHM->LM->DHloc_fixed_23[index]; - stvnl_dphi(2,2) += sum/2.0 * this->UHM->LM->DHloc_fixed_33[index]; + stvnl_dphi(0,0) += sum/2.0 * lm.DHloc_fixed_11[index]; + stvnl_dphi(0,1) += sum/2.0 * lm.DHloc_fixed_12[index]; + stvnl_dphi(0,2) += sum/2.0 * lm.DHloc_fixed_13[index]; + stvnl_dphi(1,1) += sum/2.0 * lm.DHloc_fixed_22[index]; + stvnl_dphi(1,2) += sum/2.0 * lm.DHloc_fixed_23[index]; + stvnl_dphi(2,2) += sum/2.0 * lm.DHloc_fixed_33[index]; } } } } - if(isstress){ - StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, stvnl_dphi); - } + if(isstress) + { + StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, stvnl_dphi); + } ModuleBase::timer::tick("Force_LCAO_gamma","cal_ftvnl_dphi"); return; -} \ No newline at end of file +} diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp index 918d4c53461..947d5bc5be8 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp @@ -50,7 +50,9 @@ void Force_LCAO_k::ftable_k(const bool isforce, #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, + LCAO_Hamilt &uhm, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, const K_Vectors& kv) { ModuleBase::TITLE("Force_LCAO_k", "ftable_k"); @@ -61,25 +63,22 @@ void Force_LCAO_k::ftable_k(const bool isforce, elecstate::DensityMatrix,double>* DM = dynamic_cast>*>(pelec)->get_DM(); - this->ParaV = DM->get_paraV_pointer(); - const Parallel_Orbitals* pv = this->ParaV; - //const Parallel_Orbitals* pv = loc.ParaV; - this->allocate_k(*this->ParaV, kv.nks, kv.kvec_d); + this->allocate_k(pv, lm, kv.nks, kv.kvec_d); // calculate the energy density matrix // and the force related to overlap matrix and energy density matrix. - this->cal_foverlap_k(isforce, isstress, ra, psi, loc, DM, foverlap, soverlap, pelec, kv.nks, kv); + this->cal_foverlap_k(isforce, isstress, ra, psi, loc, pv, lm, DM, foverlap, soverlap, pelec, kv.nks, kv); //DM->sum_DMR_spin(); - this->cal_ftvnl_dphi_k(DM, isforce, isstress, ra, ftvnl_dphi, stvnl_dphi); + this->cal_ftvnl_dphi_k(DM, pv, lm, isforce, isstress, ra, ftvnl_dphi, stvnl_dphi); // --------------------------------------- // doing on the real space grid. // --------------------------------------- - this->cal_fvl_dphi_k(isforce, isstress, pelec->pot, fvl_dphi, svl_dphi, loc.DM_R); + this->cal_fvl_dphi_k(isforce, isstress, lm, pelec->pot, fvl_dphi, svl_dphi, loc.DM_R); - this->cal_fvnl_dbeta_k(DM, isforce, isstress, fvnl_dbeta, svnl_dbeta); + this->cal_fvnl_dbeta_k(DM, isforce, isstress, pv, fvnl_dbeta, svnl_dbeta); #ifdef __DEEPKS if (GlobalV::deepks_scf) @@ -149,49 +148,58 @@ void Force_LCAO_k::ftable_k(const bool isforce, } void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, + LCAO_Matrix &lm, const int& nks, const std::vector>& kvec_d) { ModuleBase::TITLE("Force_LCAO_k", "allocate_k"); ModuleBase::timer::tick("Force_LCAO_k", "allocate_k"); - this->ParaV = &pv; const int nnr = pv.nnr; + + assert(nnr>=0); + //-------------------------------- // (1) allocate for dSx dSy & dSz //-------------------------------- - this->UHM->LM->DSloc_Rx = new double[nnr]; - this->UHM->LM->DSloc_Ry = new double[nnr]; - this->UHM->LM->DSloc_Rz = new double[nnr]; - const auto init_DSloc_Rxyz = [this, nnr](int num_threads, int thread_id) { - int beg, len; - ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, nnr, 1024, beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_Rx + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_Ry + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DSloc_Rz + beg, len); - }; + lm.DSloc_Rx = new double[nnr]; + lm.DSloc_Ry = new double[nnr]; + lm.DSloc_Rz = new double[nnr]; + + // mohan add lm on 2024-03-31 + const auto init_DSloc_Rxyz = [this, nnr, &lm](int num_threads, int thread_id) + { + int beg=0; + int len=0; + ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, nnr, 1024, beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_Rx + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_Ry + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.DSloc_Rz + beg, len); + }; + ModuleBase::OMP_PARALLEL(init_DSloc_Rxyz); ModuleBase::Memory::record("Force::dS_K", sizeof(double) * nnr * 3); if (GlobalV::CAL_STRESS) { - this->UHM->LM->DH_r = new double[3 * nnr]; - this->UHM->LM->stvnl11 = new double[nnr]; - this->UHM->LM->stvnl12 = new double[nnr]; - this->UHM->LM->stvnl13 = new double[nnr]; - this->UHM->LM->stvnl22 = new double[nnr]; - this->UHM->LM->stvnl23 = new double[nnr]; - this->UHM->LM->stvnl33 = new double[nnr]; - const auto init_DH_r_stvnl = [this, nnr](int num_threads, int thread_id) { + lm.DH_r = new double[3 * nnr]; + lm.stvnl11 = new double[nnr]; + lm.stvnl12 = new double[nnr]; + lm.stvnl13 = new double[nnr]; + lm.stvnl22 = new double[nnr]; + lm.stvnl23 = new double[nnr]; + lm.stvnl33 = new double[nnr]; + // mohan add lm on 2024-03-31 + const auto init_DH_r_stvnl = [this, nnr, &lm](int num_threads, int thread_id) { int beg, len; ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, nnr, 1024, beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DH_r + 3 * beg, 3 * len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->stvnl11 + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->stvnl12 + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->stvnl13 + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->stvnl22 + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->stvnl23 + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->stvnl33 + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.DH_r + 3 * beg, 3 * len); + ModuleBase::GlobalFunc::ZEROS(lm.stvnl11 + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.stvnl12 + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.stvnl13 + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.stvnl22 + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.stvnl23 + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.stvnl33 + beg, len); }; ModuleBase::OMP_PARALLEL(init_DH_r_stvnl); @@ -208,15 +216,17 @@ void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, //----------------------------------------- // (2) allocate for //----------------------------------------- - this->UHM->LM->DHloc_fixedR_x = new double[nnr]; - this->UHM->LM->DHloc_fixedR_y = new double[nnr]; - this->UHM->LM->DHloc_fixedR_z = new double[nnr]; - const auto init_DHloc_fixedR_xyz = [this, nnr](int num_threads, int thread_id) { + lm.DHloc_fixedR_x = new double[nnr]; + lm.DHloc_fixedR_y = new double[nnr]; + lm.DHloc_fixedR_z = new double[nnr]; + + // mohan add lm on 2024-03-31 + const auto init_DHloc_fixedR_xyz = [this, nnr, &lm](int num_threads, int thread_id) { int beg, len; ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, nnr, 1024, beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixedR_x + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixedR_y + beg, len); - ModuleBase::GlobalFunc::ZEROS(this->UHM->LM->DHloc_fixedR_z + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixedR_x + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixedR_y + beg, len); + ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixedR_z + beg, len); }; ModuleBase::OMP_PARALLEL(init_DHloc_fixedR_xyz); ModuleBase::Memory::record("Force::dTVNL", sizeof(double) * nnr * 3); @@ -224,27 +234,51 @@ void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, // calculate dT= in LCAO // calculate T + VNL(P1) in LCAO basis this->UHM->genH.build_ST_new('T', cal_deri, GlobalC::ucell, this->UHM->genH.LM->Hloc_fixedR.data()); - // test(this->UHM->LM->DHloc_fixedR_x,"this->UHM->LM->DHloc_fixedR_x T part"); // calculate dVnl= in LCAO this->UHM->genH.build_Nonlocal_mu_new(this->UHM->genH.LM->Hloc_fixed.data(), cal_deri); - // test(this->UHM->LM->DHloc_fixedR_x,"this->UHM->LM->DHloc_fixedR_x Vnl part"); // calculate asynchronous S matrix to output for Hefei-NAMD if (INPUT.cal_syns) { cal_deri = false; // this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, this->UHM->genH.LM->SlocR.data(), - // INPUT.cal_syns); - this->UHM->genH - .build_ST_new('S', cal_deri, GlobalC::ucell, this->UHM->genH.LM->SlocR.data(), INPUT.cal_syns, INPUT.dmax); + // INPUT.cal_syns); + this->UHM->genH.build_ST_new('S', + cal_deri, + GlobalC::ucell, + lm.SlocR.data(), + INPUT.cal_syns, + INPUT.dmax); + for (int ik = 0; ik < nks; ik++) { - this->UHM->genH.LM->zeros_HSk('S'); - this->UHM->genH.LM->folding_fixedH(ik, kvec_d, 1); + lm.zeros_HSk('S'); + lm.folding_fixedH(ik, kvec_d, 1); bool bit = false; // LiuXh, 2017-03-21 - ModuleIO::save_mat(0, this->UHM->genH.LM->Hloc2.data(), GlobalV::NLOCAL, bit, GlobalV::out_ndigits, 0, GlobalV::out_app_flag, "H", "data-" + std::to_string(ik), *this->ParaV, GlobalV::DRANK); - ModuleIO::save_mat(0, this->UHM->genH.LM->Sloc2.data(), GlobalV::NLOCAL, bit, GlobalV::out_ndigits, 0, GlobalV::out_app_flag, "S", "data-" + std::to_string(ik), *this->ParaV, GlobalV::DRANK); + ModuleIO::save_mat(0, + lm.Hloc2.data(), + GlobalV::NLOCAL, + bit, + GlobalV::out_ndigits, + 0, + GlobalV::out_app_flag, + "H", + "data-" + std::to_string(ik), + pv, + GlobalV::DRANK); + + ModuleIO::save_mat(0, + lm.Sloc2.data(), + GlobalV::NLOCAL, + bit, + GlobalV::out_ndigits, + 0, + GlobalV::out_app_flag, + "S", + "data-" + std::to_string(ik), + pv, + GlobalV::DRANK); } } @@ -252,23 +286,25 @@ void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, return; } -void Force_LCAO_k::finish_k(void) + +void Force_LCAO_k::finish_k(LCAO_Matrix &lm) { - delete[] this->UHM->LM->DSloc_Rx; - delete[] this->UHM->LM->DSloc_Ry; - delete[] this->UHM->LM->DSloc_Rz; - delete[] this->UHM->LM->DHloc_fixedR_x; - delete[] this->UHM->LM->DHloc_fixedR_y; - delete[] this->UHM->LM->DHloc_fixedR_z; + delete[] lm.DSloc_Rx; + delete[] lm.DSloc_Ry; + delete[] lm.DSloc_Rz; + delete[] lm.DHloc_fixedR_x; + delete[] lm.DHloc_fixedR_y; + delete[] lm.DHloc_fixedR_z; + if (GlobalV::CAL_STRESS) { - delete[] this->UHM->LM->DH_r; - delete[] this->UHM->LM->stvnl11; - delete[] this->UHM->LM->stvnl12; - delete[] this->UHM->LM->stvnl13; - delete[] this->UHM->LM->stvnl22; - delete[] this->UHM->LM->stvnl23; - delete[] this->UHM->LM->stvnl33; + delete[] lm.DH_r; + delete[] lm.stvnl11; + delete[] lm.stvnl12; + delete[] lm.stvnl13; + delete[] lm.stvnl22; + delete[] lm.stvnl23; + delete[] lm.stvnl33; } return; } @@ -276,23 +312,23 @@ void Force_LCAO_k::finish_k(void) #include "module_hamilt_lcao/hamilt_lcaodft/record_adj.h" void Force_LCAO_k::cal_foverlap_k(const bool isforce, const bool isstress, - Record_adj& ra, - const psi::Psi>* psi, - Local_Orbital_Charge& loc, - const elecstate::DensityMatrix, double>* DM, - ModuleBase::matrix& foverlap, - ModuleBase::matrix& soverlap, - const elecstate::ElecState* pelec, - const int& nks, - const K_Vectors& kv) + Record_adj &ra, + const psi::Psi> *psi, + Local_Orbital_Charge &loc, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const elecstate::DensityMatrix, double> *DM, + ModuleBase::matrix &foverlap, + ModuleBase::matrix &soverlap, + const elecstate::ElecState *pelec, + const int &nks, + const K_Vectors &kv) { ModuleBase::TITLE("Force_LCAO_k", "cal_foverlap_k"); ModuleBase::timer::tick("Force_LCAO_k", "cal_foverlap_k"); - const Parallel_Orbitals* pv = this->ParaV; - // construct a DensityMatrix object - elecstate::DensityMatrix, double> EDM(&kv,pv,GlobalV::NSPIN); + elecstate::DensityMatrix, double> EDM(&kv,&pv,GlobalV::NSPIN); //-------------------------------------------- // calculate the energy density matrix here. @@ -328,7 +364,7 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, } else { - //elecstate::cal_dm(loc.ParaV, wgEkb, psi[0], edm_k); + //elecstate::cal_dm(pv, wgEkb, psi[0], edm_k); // cal_dm_psi elecstate::cal_dm_psi(EDM.get_paraV_pointer(), wgEkb, psi[0], EDM); } @@ -348,16 +384,16 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, int total_irr = 0; #ifdef _OPENMP #pragma omp parallel - { - int num_threads = omp_get_num_threads(); - ModuleBase::matrix local_soverlap(3, 3); - int local_total_irr = 0; + { + int num_threads = omp_get_num_threads(); + ModuleBase::matrix local_soverlap(3, 3); + int local_total_irr = 0; #else - ModuleBase::matrix& local_soverlap = soverlap; - int& local_total_irr = total_irr; + ModuleBase::matrix& local_soverlap = soverlap; + int& local_total_irr = total_irr; #endif - ModuleBase::Vector3 tau1, dtau, tau2; + ModuleBase::Vector3 tau1, dtau, tau2; #ifdef _OPENMP #pragma omp for schedule(dynamic) @@ -370,8 +406,10 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, // get iat1 int iat1 = GlobalC::ucell.itia2iat(T1, I1); double* foverlap_iat; - if (isforce) - foverlap_iat = &foverlap(iat, 0); + if (isforce) + { + foverlap_iat = &foverlap(iat, 0); + } #ifdef _OPENMP // using local stack to avoid false sharing in multi-threaded case @@ -381,7 +419,7 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, foverlap_iat = foverlap_temp; } #endif - int irr = pv->nlocstart[iat]; + int irr = pv.nlocstart[iat]; const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); for (int cb = 0; cb < ra.na_each[iat]; ++cb) { @@ -399,13 +437,16 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, double Rz = ra.info[iat][cb][2]; // get BaseMatrix hamilt::BaseMatrix* tmp_matrix = EDM.get_DMR_pointer(1)->find_matrix(iat1, iat2, Rx, Ry, Rz); - if(tmp_matrix == nullptr) continue; - int row_ap = pv->atom_begin_row[iat1]; - int col_ap = pv->atom_begin_col[iat2]; + if(tmp_matrix == nullptr) + { + continue; + } + int row_ap = pv.atom_begin_row[iat1]; + int col_ap = pv.atom_begin_col[iat2]; // get DMR - for (int mu = 0; mu < pv->get_row_size(iat1); ++mu) + for (int mu = 0; mu < pv.get_row_size(iat1); ++mu) { - for (int nu = 0; nu < pv->get_col_size(iat2); ++nu) + for (int nu = 0; nu < pv.get_col_size(iat2); ++nu) { // here do not sum over spin due to EDM.sum_DMR_spin(); double edm2d1 = tmp_matrix->get_value(mu,nu); @@ -413,24 +454,28 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, if (isforce) { - foverlap_iat[0] -= edm2d2 * this->UHM->LM->DSloc_Rx[irr]; - foverlap_iat[1] -= edm2d2 * this->UHM->LM->DSloc_Ry[irr]; - foverlap_iat[2] -= edm2d2 * this->UHM->LM->DSloc_Rz[irr]; + foverlap_iat[0] -= edm2d2 * lm.DSloc_Rx[irr]; + foverlap_iat[1] -= edm2d2 * lm.DSloc_Ry[irr]; + foverlap_iat[2] -= edm2d2 * lm.DSloc_Rz[irr]; } if (isstress) { for (int ipol = 0; ipol < 3; ipol++) { - local_soverlap(0, ipol) += edm2d1 * this->UHM->LM->DSloc_Rx[irr] - * this->UHM->LM->DH_r[irr * 3 + ipol]; + local_soverlap(0, ipol) += edm2d1 * lm.DSloc_Rx[irr] + * lm.DH_r[irr * 3 + ipol]; if (ipol < 1) - continue; - local_soverlap(1, ipol) += edm2d1 * this->UHM->LM->DSloc_Ry[irr] - * this->UHM->LM->DH_r[irr * 3 + ipol]; - if (ipol < 2) - continue; - local_soverlap(2, ipol) += edm2d1 * this->UHM->LM->DSloc_Rz[irr] - * this->UHM->LM->DH_r[irr * 3 + ipol]; + { + continue; + } + local_soverlap(1, ipol) += edm2d1 * lm.DSloc_Ry[irr] + * lm.DH_r[irr * 3 + ipol]; + if (ipol < 2) + { + continue; + } + local_soverlap(2, ipol) += edm2d1 * lm.DSloc_Rz[irr] + * lm.DH_r[irr * 3 + ipol]; } } //} @@ -457,12 +502,16 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, for (int ipol = 0; ipol < 3; ipol++) { soverlap(0, ipol) += local_soverlap(0, ipol); - if (ipol < 1) - continue; - soverlap(1, ipol) += local_soverlap(1, ipol); - if (ipol < 2) - continue; - soverlap(2, ipol) += local_soverlap(2, ipol); + if (ipol < 1) + { + continue; + } + soverlap(1, ipol) += local_soverlap(1, ipol); + if (ipol < 2) + { + continue; + } + soverlap(2, ipol) += local_soverlap(2, ipol); } } } @@ -474,10 +523,10 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, soverlap); } - if (total_irr != pv->nnr) + if (total_irr != pv.nnr) { ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong irr", total_irr); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong LNNR.nnr", pv->nnr); + ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong LNNR.nnr", pv.nnr); ModuleBase::WARNING_QUIT("Force_LCAO_k::cal_foverlap_k", "irr!=LNNR.nnr"); } @@ -486,6 +535,8 @@ void Force_LCAO_k::cal_foverlap_k(const bool isforce, } void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrix, double>* DM, + const Parallel_Orbitals &pv, + LCAO_Matrix &lm, const bool isforce, const bool isstress, Record_adj& ra, @@ -496,7 +547,6 @@ void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrixParaV; // get the adjacent atom's information. // GlobalV::ofs_running << " calculate the ftvnl_dphi_k force" << std::endl; @@ -508,10 +558,10 @@ void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrixnlocstart[iat]; + int irr = pv.nlocstart[iat]; const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); double* ftvnl_dphi_iat; - if (isforce) - ftvnl_dphi_iat = &ftvnl_dphi(iat, 0); + if (isforce) + { + ftvnl_dphi_iat = &ftvnl_dphi(iat, 0); + } #ifdef _OPENMP // using local stack to avoid false sharing in multi-threaded case double ftvnl_dphi_temp[3] = {0.0, 0.0, 0.0}; @@ -544,7 +596,7 @@ void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrixget_row_size(iat1) <= 0 || pv->get_col_size(iat2) <= 0) + if (pv.get_row_size(iat1) <= 0 || pv.get_col_size(iat2) <= 0) { continue; } @@ -554,9 +606,9 @@ void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrixget_DMR_pointer(is+1)->find_matrix(iat1, iat2, Rx, Ry, Rz)); } //hamilt::BaseMatrix* tmp_matrix = DM->get_DMR_pointer(1)->find_matrix(iat1, iat2, Rx, Ry, Rz); - for (int mu = 0; mu < pv->get_row_size(iat1); ++mu) + for (int mu = 0; mu < pv.get_row_size(iat1); ++mu) { - for (int nu = 0; nu < pv->get_col_size(iat2); ++nu) + for (int nu = 0; nu < pv.get_col_size(iat2); ++nu) { // get value from DM double dm2d1 = 0.0; @@ -568,18 +620,18 @@ void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrixUHM->LM->DHloc_fixedR_x[irr]; - ftvnl_dphi_iat[1] += dm2d2 * this->UHM->LM->DHloc_fixedR_y[irr]; - ftvnl_dphi_iat[2] += dm2d2 * this->UHM->LM->DHloc_fixedR_z[irr]; + ftvnl_dphi_iat[0] += dm2d2 * lm.DHloc_fixedR_x[irr]; + ftvnl_dphi_iat[1] += dm2d2 * lm.DHloc_fixedR_y[irr]; + ftvnl_dphi_iat[2] += dm2d2 * lm.DHloc_fixedR_z[irr]; } if (isstress) { - local_stvnl_dphi(0, 0) -= dm2d1 * this->UHM->LM->stvnl11[irr]; - local_stvnl_dphi(0, 1) -= dm2d1 * this->UHM->LM->stvnl12[irr]; - local_stvnl_dphi(0, 2) -= dm2d1 * this->UHM->LM->stvnl13[irr]; - local_stvnl_dphi(1, 1) -= dm2d1 * this->UHM->LM->stvnl22[irr]; - local_stvnl_dphi(1, 2) -= dm2d1 * this->UHM->LM->stvnl23[irr]; - local_stvnl_dphi(2, 2) -= dm2d1 * this->UHM->LM->stvnl33[irr]; + local_stvnl_dphi(0, 0) -= dm2d1 * lm.stvnl11[irr]; + local_stvnl_dphi(0, 1) -= dm2d1 * lm.stvnl12[irr]; + local_stvnl_dphi(0, 2) -= dm2d1 * lm.stvnl13[irr]; + local_stvnl_dphi(1, 1) -= dm2d1 * lm.stvnl22[irr]; + local_stvnl_dphi(1, 2) -= dm2d1 * lm.stvnl23[irr]; + local_stvnl_dphi(2, 2) -= dm2d1 * lm.stvnl33[irr]; } //} ++local_total_irr; @@ -612,10 +664,7 @@ void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrixnnr); - - // test(this->UHM->LM->DSloc_Rx); - // test(dm2d[0],"dm2d"); + assert(total_irr == pv.nnr); if (isstress) { @@ -626,11 +675,17 @@ void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrixParaV; + // mohan remove 'const' for pv, 2024-03-31 if (GlobalV::NPROC != 1) + { return; + } + std::cout << "test!" << std::endl; int irr = 0; @@ -638,7 +693,9 @@ void Force_LCAO_k::test(double* mmm, const std::string& name) GlobalV::ofs_running << " Calculate the test in Force_LCAO_k" << std::endl; Record_adj RA; - RA.for_2d(*this->UHM->LM->ParaV, GlobalV::GAMMA_ONLY_LOCAL); + + // mohan update 2024-03-31 + RA.for_2d(pv, GlobalV::GAMMA_ONLY_LOCAL); double* test; test = new double[GlobalV::NLOCAL * GlobalV::NLOCAL]; @@ -664,8 +721,7 @@ void Force_LCAO_k::test(double* mmm, const std::string& name) for (int kk = 0; kk < atom2->nw; kk++) { const int iw2_all = start2 + kk; - assert(irr < pv->nnr); - // test[iw1_all*GlobalV::NLOCAL+iw2_all] += this->UHM->LM->DHloc_fixedR_x[irr]; + assert(irr < pv.nnr); test[iw1_all * GlobalV::NLOCAL + iw2_all] += mmm[irr]; ++irr; } @@ -699,13 +755,13 @@ typedef std::tuple key_tuple; // must consider three-center H matrix. void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrix, double>* DM, const bool isforce, - const bool isstress, - ModuleBase::matrix& fvnl_dbeta, + const bool isstress, + const Parallel_Orbitals &pv, + ModuleBase::matrix& fvnl_dbeta, ModuleBase::matrix& svnl_dbeta) { ModuleBase::TITLE("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); ModuleBase::timer::tick("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); - const Parallel_Orbitals* pv = this->ParaV; // Data structure for storing , for a detailed description // check out the same data structure in build_Nonlocal_mu_new @@ -757,10 +813,12 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrixglobal2local_row(iw1_all); - const int iw2_local = pv->global2local_col(iw1_all); - if (iw1_local < 0 && iw2_local < 0) - continue; + const int iw1_local = pv.global2local_row(iw1_all); + const int iw2_local = pv.global2local_col(iw1_all); + if (iw1_local < 0 && iw2_local < 0) + { + continue; + } const int iw1_0 = iw1 / GlobalV::NPOL; std::vector> nlm; #ifdef USE_NEW_TWO_CENTER @@ -846,7 +904,7 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrixParaV->nlocstart[iat1]; + int nnr = pv.nlocstart[iat1]; /* !!!!!!!!!!!!!!!! @@ -894,8 +952,10 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrixget_row_size(iat1) <= 0 || pv->get_col_size(iat2) <= 0) + if (pv.get_row_size(iat1) <= 0 || pv.get_col_size(iat2) <= 0) { continue; } @@ -984,17 +1044,21 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrixglobal2local_row(iw1_all); - if (mu < 0) - continue; + const int mu = pv.global2local_row(iw1_all); + if (mu < 0) + { + continue; + } for (int k = 0; k < atom2->nw * GlobalV::NPOL; k++) { const int k0 = k / GlobalV::NPOL; const int iw2_all = start2 + k; - const int nu = pv->global2local_col(iw2_all); - if (nu < 0) - continue; + const int nu = pv.global2local_col(iw2_all); + if (nu < 0) + { + continue; + } // const Atom* atom0 = &GlobalC::ucell.atoms[T0]; double nlm[3] = {0, 0, 0}; @@ -1093,9 +1157,11 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrixglobal2local_row(iw1_all); - if (mu < 0) - continue; + const int mu = pv.global2local_row(iw1_all); + if (mu < 0) + { + continue; + } // fix a serious bug: atom2[T2] -> atom2 // mohan 2010-12-20 @@ -1103,10 +1169,12 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrixglobal2local_col(iw2_all); - if (nu < 0) - continue; - total_nnr++; + const int nu = pv.global2local_col(iw2_all); + if (nu < 0) + { + continue; + } + total_nnr++; nnr++; } } @@ -1161,7 +1229,7 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrixnnr); + assert(total_nnr == pv.nnr); if (isstress) { @@ -1174,11 +1242,12 @@ void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrix void Force_LCAO_k::cal_fvl_dphi_k(const bool isforce, - const bool isstress, - const elecstate::Potential* pot_in, - ModuleBase::matrix& fvl_dphi, - ModuleBase::matrix& svl_dphi, - double** DM_R) + const bool isstress, + LCAO_Matrix &lm, + const elecstate::Potential* pot_in, + ModuleBase::matrix& fvl_dphi, + ModuleBase::matrix& svl_dphi, + double** DM_R) { ModuleBase::TITLE("Force_LCAO_k", "cal_fvl_dphi_k"); ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); @@ -1188,9 +1257,10 @@ void Force_LCAO_k::cal_fvl_dphi_k(const bool isforce, ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); return; } - assert(this->UHM->LM->DHloc_fixedR_x != NULL); - assert(this->UHM->LM->DHloc_fixedR_y != NULL); - assert(this->UHM->LM->DHloc_fixedR_z != NULL); + + assert(lm.DHloc_fixedR_x != NULL); + assert(lm.DHloc_fixedR_y != NULL); + assert(lm.DHloc_fixedR_z != NULL); int istep = 1; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h index 0deb189aa56..2d9b3bc2c30 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h @@ -12,16 +12,15 @@ class Force_LCAO_k : public Force_LCAO_gamma { -public: + public: template friend class Force_Stress_LCAO; Force_LCAO_k(); ~Force_LCAO_k(); - private: + private: LCAO_Hamilt* UHM; - const Parallel_Orbitals* ParaV; // orthonormal force + contribution from T and VNL void ftable_k(const bool isforce, @@ -43,53 +42,65 @@ class Force_LCAO_k : public Force_LCAO_gamma #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, - const K_Vectors& kv); + LCAO_Hamilt &uhm, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const K_Vectors &kv); // get the ds, dt, dvnl. void allocate_k(const Parallel_Orbitals& pv, + LCAO_Matrix &lm, const int& nks, const std::vector>& kvec_d); - void finish_k(void); + void finish_k(LCAO_Matrix &lm); // calculate the force due to < dphi | beta > < beta | phi > - void cal_ftvnl_dphi_k(const elecstate::DensityMatrix, double>* DM, - const bool isforce, - const bool isstress, - Record_adj& ra, - ModuleBase::matrix& ftvnl_dphi, - ModuleBase::matrix& stvnl_dphi); + void cal_ftvnl_dphi_k(const elecstate::DensityMatrix, double>* DM, + const Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const bool isforce, + const bool isstress, + Record_adj& ra, + ModuleBase::matrix& ftvnl_dphi, + ModuleBase::matrix& stvnl_dphi); // calculate the overlap force void cal_foverlap_k(const bool isforce, const bool isstress, - Record_adj& ra, - const psi::Psi>* psi, - Local_Orbital_Charge& loc, - const elecstate::DensityMatrix, double>* DM, - ModuleBase::matrix& foverlap, - ModuleBase::matrix& soverlap, - const elecstate::ElecState* pelec, - const int& nks, - const K_Vectors& kv); + Record_adj &ra, + const psi::Psi> *psi, + Local_Orbital_Charge &loc, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const elecstate::DensityMatrix, double> *DM, + ModuleBase::matrix &foverlap, + ModuleBase::matrix &soverlap, + const elecstate::ElecState *pelec, + const int &nks, + const K_Vectors &kv); // calculate the force due to < phi | Vlocal | dphi > - void cal_fvl_dphi_k(const bool isforce, - const bool isstress, - const elecstate::Potential* pot_in, - ModuleBase::matrix& fvl_dphi, - ModuleBase::matrix& svl_dphi, - double** DM_R); + void cal_fvl_dphi_k(const bool isforce, + const bool isstress, + LCAO_Matrix &lm, + const elecstate::Potential* pot_in, + ModuleBase::matrix& fvl_dphi, + ModuleBase::matrix& svl_dphi, + double** DM_R); // new method to calculate the force due to < phi | dbeta > < beta | phi > , developed by wenfei-li void cal_fvnl_dbeta_k(const elecstate::DensityMatrix, double>* DM, const bool isforce, - const bool isstress, - ModuleBase::matrix& fvnl_dbeta, + const bool isstress, + const Parallel_Orbitals &pv, + ModuleBase::matrix& fvnl_dbeta, ModuleBase::matrix& svnl_dbeta); - void test(double* mm, const std::string& name); + void test( + Parallel_Orbitals &pv, + double* mm, + const std::string& name); }; #endif diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp index bcadc5f8090..419f1726e71 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp @@ -31,7 +31,10 @@ LCAO_Hamilt::~LCAO_Hamilt() //-------------------------------------------- // prepare grid network for Gint(grid integral) //-------------------------------------------- -void LCAO_Hamilt::grid_prepare(const Grid_Technique& gt, const ModulePW::PW_Basis& rhopw, const ModulePW::PW_Basis_Big& bigpw) +void LCAO_Hamilt::grid_prepare( + const Grid_Technique& gt, + const ModulePW::PW_Basis& rhopw, + const ModulePW::PW_Basis_Big& bigpw) { ModuleBase::TITLE("LCAO_Hamilt","grid_prepare"); ModuleBase::timer::tick("LCAO_Hamilt","grid_prepare"); @@ -45,7 +48,7 @@ void LCAO_Hamilt::grid_prepare(const Grid_Technique& gt, const ModulePW::PW_Basi } else // multiple k-points { - // calculate the grid integration of 'Vl' matrix for l-points algorithms. + // cal the grid integration of 'Vl' matrix for l-points algorithms. this->GK.prep_grid(gt, bigpw.nbx, bigpw.nby, bigpw.nbzp, bigpw.nbzp_start, rhopw.nxyz, bigpw.bx, bigpw.by, bigpw.bz, bigpw.bxyz, bigpw.nbxx, rhopw.ny, rhopw.nplane, rhopw.startz_current); @@ -55,7 +58,7 @@ void LCAO_Hamilt::grid_prepare(const Grid_Technique& gt, const ModulePW::PW_Basi return; } -void LCAO_Hamilt::set_R_range_sparse() +void LCAO_Hamilt::set_R_range_sparse(void) { int R_minX = int(GlobalC::GridD.getD_minX()); int R_minY = int(GlobalC::GridD.getD_minY()); @@ -80,15 +83,15 @@ void LCAO_Hamilt::set_R_range_sparse() return; } -void LCAO_Hamilt::calculate_STN_R_sparse_for_S(const double &sparse_threshold) +void LCAO_Hamilt::cal_STN_R_sparse_for_S(const double &sparse_threshold) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_STN_R_sparse_for_S"); + ModuleBase::TITLE("LCAO_Hamilt","cal_STN_R_sparse_for_S"); int index = 0; ModuleBase::Vector3 dtau, tau1, tau2; ModuleBase::Vector3 dtau1, dtau2, tau0; - double temp_value_double; + double temp_value_double = 0.0; std::complex temp_value_complex; for(int T1 = 0; T1 < GlobalC::ucell.ntype; ++T1) @@ -188,13 +191,13 @@ void LCAO_Hamilt::calculate_STN_R_sparse_for_S(const double &sparse_threshold) } #include "module_hamilt_lcao/module_hcontainer/hcontainer.h" -void LCAO_Hamilt::calculate_HContainer_sparse_d( +void LCAO_Hamilt::cal_HContainer_sparse_d( const int ¤t_spin, const double &sparse_threshold, const hamilt::HContainer& hR, std::map, std::map>>& target) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_HContainer_sparse_d"); + ModuleBase::TITLE("LCAO_Hamilt","cal_HContainer_sparse_d"); const Parallel_Orbitals* paraV = this->LM->ParaV; auto row_indexes = paraV->get_indexes_row(); @@ -231,9 +234,14 @@ void LCAO_Hamilt::calculate_HContainer_sparse_d( return; } -void LCAO_Hamilt::calculate_HContainer_sparse_cd(const int ¤t_spin, const double &sparse_threshold, const hamilt::HContainer>& hR, std::map, std::map>>>& target) +void LCAO_Hamilt::cal_HContainer_sparse_cd( + const int ¤t_spin, + const double &sparse_threshold, + const hamilt::HContainer>& hR, + std::map, + std::map>>>& target) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_HContainer_sparse_cd"); + ModuleBase::TITLE("LCAO_Hamilt","cal_HContainer_sparse_cd"); const Parallel_Orbitals* paraV = this->LM->ParaV; auto row_indexes = paraV->get_indexes_row(); @@ -270,28 +278,28 @@ void LCAO_Hamilt::calculate_HContainer_sparse_cd(const int ¤t_spin, const return; } -void LCAO_Hamilt::calculate_HSR_sparse( +void LCAO_Hamilt::cal_HSR_sparse( const int ¤t_spin, const double &sparse_threshold, const int (&nmp)[3], hamilt::Hamilt>* p_ham) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_HSR_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_HSR_sparse"); set_R_range_sparse(); - //calculate_STN_R_sparse(current_spin, sparse_threshold); + //cal_STN_R_sparse(current_spin, sparse_threshold); if(GlobalV::NSPIN!=4) { hamilt::HamiltLCAO, double>* p_ham_lcao = dynamic_cast, double>*>(p_ham); - this->calculate_HContainer_sparse_d(current_spin, + this->cal_HContainer_sparse_d(current_spin, sparse_threshold, *(p_ham_lcao->getHR()), this->LM->HR_sparse[current_spin]); - this->calculate_HContainer_sparse_d(current_spin, + this->cal_HContainer_sparse_d(current_spin, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_sparse); @@ -301,27 +309,27 @@ void LCAO_Hamilt::calculate_HSR_sparse( hamilt::HamiltLCAO, std::complex>* p_ham_lcao = dynamic_cast, std::complex>*>(p_ham); - this->calculate_HContainer_sparse_cd(current_spin, + this->cal_HContainer_sparse_cd(current_spin, sparse_threshold, *(p_ham_lcao->getHR()), this->LM->HR_soc_sparse); - this->calculate_HContainer_sparse_cd(current_spin, + this->cal_HContainer_sparse_cd(current_spin, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_soc_sparse); } - // only old DFT+U method need to calculate extra contribution to HR + // only old DFT+U method need to cal extra contribution to HR if (GlobalV::dft_plus_u == 2) { if (GlobalV::NSPIN != 4) { - calculat_HR_dftu_sparse(current_spin, sparse_threshold); + cal_HR_dftu_sparse(current_spin, sparse_threshold); } else { - calculat_HR_dftu_soc_sparse(current_spin, sparse_threshold); + cal_HR_dftu_soc_sparse(current_spin, sparse_threshold); } } @@ -331,11 +339,11 @@ void LCAO_Hamilt::calculate_HSR_sparse( { if(GlobalC::exx_info.info_ri.real_number) { - this->calculate_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxd); + this->cal_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxd); } else { - this->calculate_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxc); + this->cal_HR_exx_sparse(current_spin, sparse_threshold, nmp, *this->LM->Hexxc); } } #endif // __MPI @@ -344,9 +352,9 @@ void LCAO_Hamilt::calculate_HSR_sparse( clear_zero_elements(current_spin, sparse_threshold); } -void LCAO_Hamilt::calculate_dH_sparse(const int ¤t_spin, const double &sparse_threshold) +void LCAO_Hamilt::cal_dH_sparse(const int ¤t_spin, const double &sparse_threshold) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_dH_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_dH_sparse"); set_R_range_sparse(); @@ -358,8 +366,8 @@ void LCAO_Hamilt::calculate_dH_sparse(const int ¤t_spin, const double &spa ModuleBase::GlobalFunc::ZEROS(this->LM->DHloc_fixedR_x, this->LM->ParaV->nloc); ModuleBase::GlobalFunc::ZEROS(this->LM->DHloc_fixedR_y, this->LM->ParaV->nloc); ModuleBase::GlobalFunc::ZEROS(this->LM->DHloc_fixedR_z, this->LM->ParaV->nloc); - // calculate dT= in LCAO - // calculate T + VNL(P1) in LCAO basis + // cal dT= in LCAO + // cal T + VNL(P1) in LCAO basis if(GlobalV::CAL_STRESS) { GlobalV::CAL_STRESS = false; @@ -372,7 +380,7 @@ void LCAO_Hamilt::calculate_dH_sparse(const int ¤t_spin, const double &spa } this->genH.build_Nonlocal_mu_new (this->LM->Hloc_fixed.data(), true); - calculate_dSTN_R_sparse(current_spin, sparse_threshold); + cal_dSTN_R_sparse(current_spin, sparse_threshold); delete[] this->LM->DHloc_fixedR_x; delete[] this->LM->DHloc_fixedR_y; @@ -381,9 +389,9 @@ void LCAO_Hamilt::calculate_dH_sparse(const int ¤t_spin, const double &spa GK.cal_dvlocal_R_sparseMatrix(current_spin, sparse_threshold, this->LM); } -void LCAO_Hamilt::calculate_STN_R_sparse_for_T(const double &sparse_threshold) +void LCAO_Hamilt::cal_STN_R_sparse_for_T(const double &sparse_threshold) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_STN_R_sparse_for_T"); + ModuleBase::TITLE("LCAO_Hamilt","cal_STN_R_sparse_for_T"); int index = 0; ModuleBase::Vector3 dtau, tau1, tau2; @@ -444,7 +452,10 @@ void LCAO_Hamilt::calculate_STN_R_sparse_for_T(const double &sparse_threshold) { const int start2 = GlobalC::ucell.itiaiw2iwt(T2,I2,0); - Abfs::Vector3_Order dR(GlobalC::GridD.getBox(ad).x, GlobalC::GridD.getBox(ad).y, GlobalC::GridD.getBox(ad).z); + Abfs::Vector3_Order dR( + GlobalC::GridD.getBox(ad).x, + GlobalC::GridD.getBox(ad).y, + GlobalC::GridD.getBox(ad).z); for(int ii=0; iinw*GlobalV::NPOL; ii++) { @@ -488,39 +499,43 @@ void LCAO_Hamilt::calculate_STN_R_sparse_for_T(const double &sparse_threshold) return; } -void LCAO_Hamilt::calculate_SR_sparse(const double &sparse_threshold, hamilt::Hamilt>* p_ham) +void LCAO_Hamilt::cal_SR_sparse(const double &sparse_threshold, hamilt::Hamilt>* p_ham) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_SR_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_SR_sparse"); set_R_range_sparse(); - //calculate_STN_R_sparse(current_spin, sparse_threshold); + //cal_STN_R_sparse(current_spin, sparse_threshold); if(GlobalV::NSPIN!=4) { - hamilt::HamiltLCAO, double>* p_ham_lcao = dynamic_cast, double>*>(p_ham); - this->calculate_HContainer_sparse_d(0, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_sparse); + hamilt::HamiltLCAO, double>* p_ham_lcao + = dynamic_cast, double>*>(p_ham); + this->cal_HContainer_sparse_d(0, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_sparse); } else { - hamilt::HamiltLCAO, std::complex>* p_ham_lcao = dynamic_cast, std::complex>*>(p_ham); - this->calculate_HContainer_sparse_cd(0, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_soc_sparse); + hamilt::HamiltLCAO, std::complex>* p_ham_lcao + = dynamic_cast, std::complex>*>(p_ham); + this->cal_HContainer_sparse_cd(0, sparse_threshold, *(p_ham_lcao->getSR()), this->LM->SR_soc_sparse); } } -void LCAO_Hamilt::calculate_TR_sparse(const double &sparse_threshold) +void LCAO_Hamilt::cal_TR_sparse(const double &sparse_threshold) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_TR_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_TR_sparse"); //need to rebuild T(R) this->LM->Hloc_fixedR.resize(this->LM->ParaV->nnr); this->LM->zeros_HSR('T'); this->genH.build_ST_new('T', 0, GlobalC::ucell, this->LM->Hloc_fixedR.data()); - set_R_range_sparse(); - calculate_STN_R_sparse_for_T(sparse_threshold); + this->set_R_range_sparse(); + this->cal_STN_R_sparse_for_T(sparse_threshold); + + return; } -void LCAO_Hamilt::calculat_HR_dftu_sparse(const int ¤t_spin, const double &sparse_threshold) +void LCAO_Hamilt::cal_HR_dftu_sparse(const int ¤t_spin, const double &sparse_threshold) { - ModuleBase::TITLE("LCAO_Hamilt","calculat_HR_dftu_sparse"); - ModuleBase::timer::tick("LCAO_Hamilt","calculat_HR_dftu_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_HR_dftu_sparse"); + ModuleBase::timer::tick("LCAO_Hamilt","cal_HR_dftu_sparse"); int total_R_num = this->LM->all_R_coor.size(); int *nonzero_num = new int[total_R_num]; @@ -544,9 +559,9 @@ void LCAO_Hamilt::calculat_HR_dftu_sparse(const int ¤t_spin, const double double *HR_tmp = new double[this->LM->ParaV->nloc]; double *SR_tmp = new double[this->LM->ParaV->nloc]; - int ir; - int ic; - int iic; + int ir=0; + int ic=0; + int iic=0; auto &temp_HR_sparse = this->LM->HR_sparse[current_spin]; count = 0; @@ -626,14 +641,14 @@ void LCAO_Hamilt::calculat_HR_dftu_sparse(const int ¤t_spin, const double HR_tmp = nullptr; SR_tmp = nullptr; - ModuleBase::timer::tick("LCAO_Hamilt","calculat_HR_dftu_sparse"); + ModuleBase::timer::tick("LCAO_Hamilt","cal_HR_dftu_sparse"); } -void LCAO_Hamilt::calculat_HR_dftu_soc_sparse(const int ¤t_spin, const double &sparse_threshold) +void LCAO_Hamilt::cal_HR_dftu_soc_sparse(const int ¤t_spin, const double &sparse_threshold) { - ModuleBase::TITLE("LCAO_Hamilt","calculat_HR_dftu_soc_sparse"); - ModuleBase::timer::tick("LCAO_Hamilt","calculat_HR_dftu_soc_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_HR_dftu_soc_sparse"); + ModuleBase::timer::tick("LCAO_Hamilt","cal_HR_dftu_soc_sparse"); int total_R_num = this->LM->all_R_coor.size(); int *nonzero_num = new int[total_R_num]; @@ -657,9 +672,9 @@ void LCAO_Hamilt::calculat_HR_dftu_soc_sparse(const int ¤t_spin, const dou std::complex *HR_soc_tmp = new std::complex[this->LM->ParaV->nloc]; std::complex *SR_soc_tmp = new std::complex[this->LM->ParaV->nloc]; - int ir; - int ic; - int iic; + int ir=0; + int ic=0; + int iic=0; count = 0; for (auto &R_coor : this->LM->all_R_coor) @@ -833,9 +848,9 @@ void LCAO_Hamilt::clear_zero_elements(const int ¤t_spin, const double &spa } } -void LCAO_Hamilt::calculate_dSTN_R_sparse(const int ¤t_spin, const double &sparse_threshold) +void LCAO_Hamilt::cal_dSTN_R_sparse(const int ¤t_spin, const double &sparse_threshold) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_dSTN_R_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_dSTN_R_sparse"); int index = 0; ModuleBase::Vector3 dtau, tau1, tau2; @@ -932,7 +947,7 @@ void LCAO_Hamilt::calculate_dSTN_R_sparse(const int ¤t_spin, const double } else { - ModuleBase::WARNING_QUIT("calculate_dSTN_R_sparse","soc not supported!"); + ModuleBase::WARNING_QUIT("cal_dSTN_R_sparse","soc not supported!"); } ++index; } diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h index 90d23c4be30..1422752c15d 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h @@ -26,51 +26,51 @@ class LCAO_Hamilt // jingan add 2021-6-4 void set_R_range_sparse(); - void calculate_HContainer_sparse_d(const int ¤t_spin, + void cal_HContainer_sparse_d(const int ¤t_spin, const double &sparse_threshold, const hamilt::HContainer& hR, std::map, std::map>>& target); - void calculate_HContainer_sparse_cd(const int ¤t_spin, + void cal_HContainer_sparse_cd(const int ¤t_spin, const double &sparse_threshold, const hamilt::HContainer>& hR, std::map, std::map>>>& target); - void calculate_dSTN_R_sparse(const int ¤t_spin, const double &sparse_threshold); + void cal_dSTN_R_sparse(const int ¤t_spin, const double &sparse_threshold); - void calculate_STN_R_sparse_for_S(const double &sparse_threshold); + void cal_STN_R_sparse_for_S(const double &sparse_threshold); - void calculate_STN_R_sparse_for_T(const double &sparse_threshold); + void cal_STN_R_sparse_for_T(const double &sparse_threshold); - void calculat_HR_dftu_sparse(const int ¤t_spin, const double &sparse_threshold); + void cal_HR_dftu_sparse(const int ¤t_spin, const double &sparse_threshold); - void calculat_HR_dftu_soc_sparse(const int ¤t_spin, const double &sparse_threshold); + void cal_HR_dftu_soc_sparse(const int ¤t_spin, const double &sparse_threshold); #ifdef __EXX - template void calculate_HR_exx_sparse( + template void cal_HR_exx_sparse( const int ¤t_spin, const double &sparse_threshold, const int (&nmp)[3], const std::vector< std::map >, RI::Tensor > >>& Hexxs); #endif - void calculate_HSR_sparse( + void cal_HSR_sparse( const int ¤t_spin, const double &sparse_threshold, const int (&nmp)[3], hamilt::Hamilt>* p_ham); - void calculate_SR_sparse(const double &sparse_threshold, hamilt::Hamilt>* p_ham); + void cal_SR_sparse(const double &sparse_threshold, hamilt::Hamilt>* p_ham); void clear_zero_elements(const int ¤t_spin, const double &sparse_threshold); void destroy_all_HSR_sparse(void); - void calculate_TR_sparse(const double &sparse_threshold); + void cal_TR_sparse(const double &sparse_threshold); void destroy_TR_sparse(void); - void calculate_dH_sparse(const int ¤t_spin, const double &sparse_threshold); + void cal_dH_sparse(const int ¤t_spin, const double &sparse_threshold); void destroy_dH_R_sparse(void); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/record_adj.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/record_adj.cpp index c648e25fa32..a5fa9a54e3e 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/record_adj.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/record_adj.cpp @@ -63,7 +63,6 @@ void Record_adj::for_2d(Parallel_Orbitals &pv, bool gamma_only) ModuleBase::GlobalFunc::ZEROS(na_each, na_proc); int iat = 0; -// std::cout << " in for_2d" << std::endl; for (int T1 = 0; T1 < GlobalC::ucell.ntype; ++T1) { diff --git a/source/module_io/write_HS_R.cpp b/source/module_io/write_HS_R.cpp index 2fbb56bbca3..81346621f78 100644 --- a/source/module_io/write_HS_R.cpp +++ b/source/module_io/write_HS_R.cpp @@ -23,13 +23,13 @@ void ModuleIO::output_HS_R(const int& istep, if(GlobalV::NSPIN==1||GlobalV::NSPIN==4) { // jingan add 2021-6-4, modify 2021-12-2 - UHM.calculate_HSR_sparse(0, sparse_threshold, kv.nmp, p_ham); + UHM.cal_HSR_sparse(0, sparse_threshold, kv.nmp, p_ham); } else if(GlobalV::NSPIN==2) { // save HR of current_spin first - UHM.calculate_HSR_sparse(GlobalV::CURRENT_SPIN, sparse_threshold, kv.nmp, p_ham); - // calculate HR of the other spin + UHM.cal_HSR_sparse(GlobalV::CURRENT_SPIN, sparse_threshold, kv.nmp, p_ham); + // cal HR of the other spin if(GlobalV::VL_IN_H) { int ik = 0; @@ -46,7 +46,7 @@ void ModuleIO::output_HS_R(const int& istep, p_ham->refresh(); p_ham->updateHk(ik); } - UHM.calculate_HSR_sparse(GlobalV::CURRENT_SPIN, sparse_threshold, kv.nmp, p_ham); + UHM.cal_HSR_sparse(GlobalV::CURRENT_SPIN, sparse_threshold, kv.nmp, p_ham); } ModuleIO::save_HSR_sparse(istep, *UHM.LM, sparse_threshold, binary, SR_filename, HR_filename_up, HR_filename_down); @@ -70,7 +70,7 @@ void ModuleIO::output_dH_R(const int& istep, UHM.GK.allocate_pvdpR(); if(GlobalV::NSPIN==1||GlobalV::NSPIN==4) { - UHM.calculate_dH_sparse(0, sparse_threshold); + UHM.cal_dH_sparse(0, sparse_threshold); } else if(GlobalV::NSPIN==2) { @@ -95,7 +95,7 @@ void ModuleIO::output_dH_R(const int& istep, } } - UHM.calculate_dH_sparse(GlobalV::CURRENT_SPIN, sparse_threshold); + UHM.cal_dH_sparse(GlobalV::CURRENT_SPIN, sparse_threshold); } } } @@ -119,7 +119,7 @@ void ModuleIO::output_S_R( ModuleBase::TITLE("ModuleIO","output_S_R"); ModuleBase::timer::tick("ModuleIO","output_S_R"); - UHM.calculate_SR_sparse(sparse_threshold, p_ham); + UHM.cal_SR_sparse(sparse_threshold, p_ham); ModuleIO::save_SR_sparse(*UHM.LM, sparse_threshold, binary, SR_filename); UHM.destroy_all_HSR_sparse(); @@ -148,10 +148,10 @@ void ModuleIO::output_T_R( sst << GlobalV::global_out_dir << TR_filename; } - UHM.calculate_TR_sparse(sparse_threshold); + UHM.cal_TR_sparse(sparse_threshold); ModuleIO::save_TR_sparse(istep, *UHM.LM, sparse_threshold, binary, sst.str().c_str()); UHM.destroy_TR_sparse(); ModuleBase::timer::tick("ModuleIO","output_T_R"); return; -} \ No newline at end of file +} From 76b23de9b4324547160ea710ef833bf83a1d6843 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Sun, 31 Mar 2024 22:07:44 +0800 Subject: [PATCH 36/46] fix the compiling issue with LCAO_hamilt.hpp --- .../hamilt_lcaodft/LCAO_hamilt.hpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.hpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.hpp index db8b32a13ab..57ed48c7e7f 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.hpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.hpp @@ -23,30 +23,35 @@ // Peize Lin add 2022.09.13 template -void LCAO_Hamilt::calculate_HR_exx_sparse( +void LCAO_Hamilt::cal_HR_exx_sparse( const int ¤t_spin, const double &sparse_threshold, const int (&nmp)[3], const std::vector< std::map>, RI::Tensor>>>& Hexxs) { - ModuleBase::TITLE("LCAO_Hamilt","calculate_HR_exx_sparse"); - ModuleBase::timer::tick("LCAO_Hamilt","calculate_HR_exx_sparse"); + ModuleBase::TITLE("LCAO_Hamilt","cal_HR_exx_sparse"); + ModuleBase::timer::tick("LCAO_Hamilt","cal_HR_exx_sparse"); const Tdata frac = GlobalC::exx_info.info_global.hybrid_alpha; std::map> atoms_pos; for(int iat=0; iat,3> latvec = {RI_Util::Vector3_to_array3(GlobalC::ucell.a1), RI_Util::Vector3_to_array3(GlobalC::ucell.a2), RI_Util::Vector3_to_array3(GlobalC::ucell.a3)}; + const std::array Rs_period = {nmp[0], nmp[1], nmp[2]}; RI::Cell_Nearest cell_nearest; cell_nearest.init(atoms_pos, latvec, Rs_period); const std::vector is_list = (GlobalV::NSPIN!=4) ? std::vector{current_spin} : std::vector{0,1,2,3}; + for(const int is : is_list) { int is0_b, is1_b; @@ -102,7 +107,7 @@ void LCAO_Hamilt::calculate_HR_exx_sparse( } } - ModuleBase::timer::tick("LCAO_Hamilt","calculate_HR_exx_sparse"); + ModuleBase::timer::tick("LCAO_Hamilt","cal_HR_exx_sparse"); } #endif From 4018fa2bc91c259f238eab088328b0a5391440f5 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 04:59:31 +0800 Subject: [PATCH 37/46] try to divide the FORCE_k.cpp into several small files --- .../hamilt_lcaodft/fvnl_dbeta_k.cpp | 489 ++++++++++++++++++ 1 file changed, 489 insertions(+) create mode 100644 source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp new file mode 100644 index 00000000000..6cfac40f2d7 --- /dev/null +++ b/source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp @@ -0,0 +1,489 @@ + +// must consider three-center H matrix. +void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrix, double>* DM, + const bool isforce, + const bool isstress, + const Parallel_Orbitals &pv, + ModuleBase::matrix& fvnl_dbeta, + ModuleBase::matrix& svnl_dbeta) +{ + ModuleBase::TITLE("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); + ModuleBase::timer::tick("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); + + // Data structure for storing , for a detailed description + // check out the same data structure in build_Nonlocal_mu_new + std::vector>>>> nlm_tot; + + nlm_tot.resize(GlobalC::ucell.nat); + +#ifdef _OPENMP +// use schedule(dynamic) for load balancing because adj_num is various +#pragma omp parallel for schedule(dynamic) +#endif + for (int iat = 0; iat < GlobalC::ucell.nat; iat++) + { + + const int it = GlobalC::ucell.iat2it[iat]; + const int ia = GlobalC::ucell.iat2ia[iat]; + + // Step 1 : generate + // type of atom; distance; atomic basis; projectors + + const double Rcut_Beta = GlobalC::ucell.infoNL.Beta[it].get_rcut_max(); + const ModuleBase::Vector3 tau = GlobalC::ucell.atoms[it].tau[ia]; + AdjacentAtomInfo adjs; + GlobalC::GridD.Find_atom(GlobalC::ucell, tau, it, ia, &adjs); + + nlm_tot[iat].clear(); + + for (int ad = 0; ad < adjs.adj_num + 1; ++ad) + { + const int T1 = adjs.ntype[ad]; + const int I1 = adjs.natom[ad]; + const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); + const double Rcut_AO1 = GlobalC::ORB.Phi[T1].getRcut(); + + const ModuleBase::Vector3& tau1 = adjs.adjacent_tau[ad]; + const Atom* atom1 = &GlobalC::ucell.atoms[T1]; + const int nw1_tot = atom1->nw * GlobalV::NPOL; + + const ModuleBase::Vector3 dtau = tau1 - tau; + const double dist1 = dtau.norm2() * pow(GlobalC::ucell.lat0, 2); + if (dist1 > pow(Rcut_Beta + Rcut_AO1, 2)) + { + continue; + } + + std::unordered_map>> nlm_cur; + nlm_cur.clear(); + + for (int iw1 = 0; iw1 < nw1_tot; ++iw1) + { + const int iw1_all = start1 + iw1; + const int iw1_local = pv.global2local_row(iw1_all); + const int iw2_local = pv.global2local_col(iw1_all); + if (iw1_local < 0 && iw2_local < 0) + { + continue; + } + const int iw1_0 = iw1 / GlobalV::NPOL; + std::vector> nlm; +#ifdef USE_NEW_TWO_CENTER + //================================================================= + // new two-center integral (temporary) + //================================================================= + int L1 = atom1->iw2l[ iw1_0 ]; + int N1 = atom1->iw2n[ iw1_0 ]; + int m1 = atom1->iw2m[ iw1_0 ]; + + // convert m (0,1,...2l) to M (-l, -l+1, ..., l-1, l) + int M1 = (m1 % 2 == 0) ? -m1/2 : (m1+1)/2; + + ModuleBase::Vector3 dtau = tau - tau1; + GlobalC::UOT.two_center_bundle->overlap_orb_beta->snap( + T1, L1, N1, M1, it, dtau * GlobalC::ucell.lat0, true, nlm); +#else + GlobalC::UOT.snap_psibeta_half(GlobalC::ORB, + GlobalC::ucell.infoNL, + nlm, + tau1, + T1, + atom1->iw2l[iw1_0], // L1 + atom1->iw2m[iw1_0], // m1 + atom1->iw2n[iw1_0], // N1 + tau, + it, + 1); // R0,T0 +#endif + nlm_cur.insert({iw1_all, nlm}); + } // end iw + const int iat1 = GlobalC::ucell.itia2iat(T1, I1); + const int rx1 = adjs.box[ad].x; + const int ry1 = adjs.box[ad].y; + const int rz1 = adjs.box[ad].z; + key_tuple key_1(iat1, rx1, ry1, rz1); + nlm_tot[iat][key_1] = nlm_cur; + } // end ad + } + + //======================================================= + // Step2: + // calculate sum_(L0,M0) beta + // and accumulate the value to Hloc_fixedR(i,j) + //======================================================= + int total_nnr = 0; +#ifdef _OPENMP +#pragma omp parallel reduction(+ : total_nnr) + { + ModuleBase::matrix local_svnl_dbeta(3, 3); + const int num_threads = omp_get_num_threads(); +#else + ModuleBase::matrix& local_svnl_dbeta = svnl_dbeta; +#endif + + ModuleBase::Vector3 tau1; + ModuleBase::Vector3 tau2; + ModuleBase::Vector3 dtau; + ModuleBase::Vector3 tau0; + ModuleBase::Vector3 dtau1; + ModuleBase::Vector3 dtau2; + + double rcut; + double distance; + + double rcut1; + double rcut2; + double distance1; + double distance2; + +#ifdef _OPENMP +// use schedule(dynamic) for load balancing because adj_num is various +#pragma omp for schedule(dynamic) +#endif + for (int iat1 = 0; iat1 < GlobalC::ucell.nat; iat1++) + { + const int T1 = GlobalC::ucell.iat2it[iat1]; + const Atom* atom1 = &GlobalC::ucell.atoms[T1]; + + { + const int I1 = GlobalC::ucell.iat2ia[iat1]; + tau1 = atom1->tau[I1]; + AdjacentAtomInfo adjs; + GlobalC::GridD.Find_atom(GlobalC::ucell, tau1, T1, I1, &adjs); + const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); + int nnr = pv.nlocstart[iat1]; + + /* + !!!!!!!!!!!!!!!! + This optimization is also improving the performance of single thread. + Making memory access more linearly in the core loop + */ + bool iat_recorded = false; + bool force_updated = false; + // record iat of adjs + std::vector adj_iat; + // record fvnl_dbeta diff of adjs + std::vector adj_fvnl_dbeta; + if (isforce) + { + adj_iat.resize(adjs.adj_num + 1); + adj_fvnl_dbeta.resize((adjs.adj_num + 1) * 3, 0.0); + } + + for (int ad2 = 0; ad2 < adjs.adj_num + 1; ++ad2) + { + const int T2 = adjs.ntype[ad2]; + const Atom* atom2 = &GlobalC::ucell.atoms[T2]; + + const int I2 = adjs.natom[ad2]; + const int iat2 = GlobalC::ucell.itia2iat(T2, I2); + const int start2 = GlobalC::ucell.itiaiw2iwt(T2, I2, 0); + tau2 = adjs.adjacent_tau[ad2]; + + const int rx2 = adjs.box[ad2].x; + const int ry2 = adjs.box[ad2].y; + const int rz2 = adjs.box[ad2].z; + + dtau = tau2 - tau1; + distance = dtau.norm2() * pow(GlobalC::ucell.lat0, 2); + // this rcut is in order to make nnr consistent + // with other matrix. + rcut = pow(GlobalC::ORB.Phi[T1].getRcut() + GlobalC::ORB.Phi[T2].getRcut(), 2); + + // check if this a adjacent atoms. + bool is_adj = false; + if (distance < rcut) + is_adj = true; + else if (distance >= rcut) + { + for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) + { + const int T0 = adjs.ntype[ad0]; + if (GlobalC::ucell.infoNL.nproj[T0] == 0) + { + continue; + } + const int I0 = adjs.natom[ad0]; + // const int iat0 = GlobalC::ucell.itia2iat(T0, I0); + // const int start0 = GlobalC::ucell.itiaiw2iwt(T0, I0, 0); + + tau0 = adjs.adjacent_tau[ad0]; + dtau1 = tau0 - tau1; + distance1 = dtau1.norm() * GlobalC::ucell.lat0; + rcut1 = GlobalC::ORB.Phi[T1].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(); + + dtau2 = tau0 - tau2; + distance2 = dtau2.norm() * GlobalC::ucell.lat0; + rcut2 = GlobalC::ORB.Phi[T2].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(); + + if (distance1 < rcut1 && distance2 < rcut2) + { + is_adj = true; + break; + } + } + } + + if (is_adj) + { + // basematrix and its data pointer + if (pv.get_row_size(iat1) <= 0 || pv.get_col_size(iat2) <= 0) + { + continue; + } + std::vector tmp_matrix_ptr; + for (int is = 0; is < GlobalV::NSPIN; ++is) + { + auto* tmp_base_matrix = DM->get_DMR_pointer(is+1)->find_matrix(iat1, iat2, rx2, ry2, rz2); + tmp_matrix_ptr.push_back(tmp_base_matrix->get_pointer()); + } + //hamilt::BaseMatrix* tmp_matrix = DM->get_DMR_pointer(1)->find_matrix(iat1, iat2, rx2, ry2, rz2); + //double* tmp_matrix_ptr = tmp_matrix->get_pointer(); + for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) + { + const int T0 = adjs.ntype[ad0]; + const int I0 = adjs.natom[ad0]; + const int iat = GlobalC::ucell.itia2iat(T0, I0); + if (!iat_recorded && isforce) + adj_iat[ad0] = iat; + + // mohan add 2010-12-19 + if (GlobalC::ucell.infoNL.nproj[T0] == 0) + continue; + + // const int I0 = GlobalC::GridD.getNatom(ad0); + // const int start0 = GlobalC::ucell.itiaiw2iwt(T0, I0, 0); + tau0 = adjs.adjacent_tau[ad0]; + + dtau1 = tau0 - tau1; + dtau2 = tau0 - tau2; + const double distance1 = dtau1.norm2() * pow(GlobalC::ucell.lat0, 2); + const double distance2 = dtau2.norm2() * pow(GlobalC::ucell.lat0, 2); + + // seems a bug here!! mohan 2011-06-17 + rcut1 = pow(GlobalC::ORB.Phi[T1].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(), + 2); + rcut2 = pow(GlobalC::ORB.Phi[T2].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(), + 2); + + double r0[3]; + double r1[3]; + r1[0] = (tau1.x - tau0.x); + r1[1] = (tau1.y - tau0.y); + r1[2] = (tau1.z - tau0.z); + r0[0] = (tau2.x - tau0.x); + r0[1] = (tau2.y - tau0.y); + r0[2] = (tau2.z - tau0.z); + + if (distance1 >= rcut1 || distance2 >= rcut2) + { + continue; + } + + const int rx0 = adjs.box[ad0].x; + const int ry0 = adjs.box[ad0].y; + const int rz0 = adjs.box[ad0].z; + key_tuple key1(iat1, -rx0, -ry0, -rz0); + key_tuple key2(iat2, rx2 - rx0, ry2 - ry0, rz2 - rz0); + + int nnr_inner = 0; + for (int j = 0; j < atom1->nw * GlobalV::NPOL; j++) + { + const int j0 = j / GlobalV::NPOL; // added by zhengdy-soc + const int iw1_all = start1 + j; + const int mu = pv.global2local_row(iw1_all); + if (mu < 0) + { + continue; + } + + for (int k = 0; k < atom2->nw * GlobalV::NPOL; k++) + { + const int k0 = k / GlobalV::NPOL; + const int iw2_all = start2 + k; + const int nu = pv.global2local_col(iw2_all); + if (nu < 0) + { + continue; + } + + // const Atom* atom0 = &GlobalC::ucell.atoms[T0]; + double nlm[3] = {0, 0, 0}; + std::vector nlm_1 = nlm_tot[iat][key2][iw2_all][0]; + std::vector> nlm_2; + nlm_2.resize(3); + for (int i = 0; i < 3; i++) + { + nlm_2[i] = nlm_tot[iat][key1][iw1_all][i + 1]; + } + + assert(nlm_1.size() == nlm_2[0].size()); + + const int nproj = GlobalC::ucell.infoNL.nproj[T0]; + int ib = 0; + for (int nb = 0; nb < nproj; nb++) + { + const int L0 = GlobalC::ucell.infoNL.Beta[T0].Proj[nb].getL(); + for (int m = 0; m < 2 * L0 + 1; m++) + { + for (int ir = 0; ir < 3; ir++) + { + nlm[ir] += nlm_2[ir][ib] * nlm_1[ib] + * GlobalC::ucell.atoms[T0].ncpp.dion(nb, nb); + } + ib += 1; + } + } + assert(ib == nlm_1.size()); + + double nlm1[3] = {0, 0, 0}; + if (isstress) + { + std::vector nlm_1 = nlm_tot[iat][key1][iw1_all][0]; + std::vector> nlm_2; + nlm_2.resize(3); + for (int i = 0; i < 3; i++) + { + nlm_2[i] = nlm_tot[iat][key2][iw2_all][i + 1]; + } + + assert(nlm_1.size() == nlm_2[0].size()); + + const int nproj = GlobalC::ucell.infoNL.nproj[T0]; + int ib = 0; + for (int nb = 0; nb < nproj; nb++) + { + const int L0 = GlobalC::ucell.infoNL.Beta[T0].Proj[nb].getL(); + for (int m = 0; m < 2 * L0 + 1; m++) + { + for (int ir = 0; ir < 3; ir++) + { + nlm1[ir] += nlm_2[ir][ib] * nlm_1[ib] + * GlobalC::ucell.atoms[T0].ncpp.dion(nb, nb); + } + ib += 1; + } + } + assert(ib == nlm_1.size()); + } + + /// only one projector for each atom force, but another projector for stress + force_updated = true; + // get DMR + double dm2d1 = 0.0; + for (int is = 0; is < GlobalV::NSPIN; ++is) + { + dm2d1 += tmp_matrix_ptr[is][nnr_inner]; + } + double dm2d2 = 2.0 * dm2d1; + // + for (int jpol = 0; jpol < 3; jpol++) + { + if (isforce) + { + adj_fvnl_dbeta[ad0 * 3 + jpol] -= dm2d2 * nlm[jpol]; + } + if (isstress) + { + for (int ipol = jpol; ipol < 3; ipol++) + { + local_svnl_dbeta(jpol, ipol) + += dm2d1 + * (nlm[jpol] * r1[ipol] + nlm1[jpol] * r0[ipol]); + } + } + } + //} + nnr_inner++; + } // k + } // j + } // ad0 + + // outer circle : accumulate nnr + for (int j = 0; j < atom1->nw * GlobalV::NPOL; j++) + { + const int j0 = j / GlobalV::NPOL; // added by zhengdy-soc + const int iw1_all = start1 + j; + const int mu = pv.global2local_row(iw1_all); + if (mu < 0) + { + continue; + } + + // fix a serious bug: atom2[T2] -> atom2 + // mohan 2010-12-20 + for (int k = 0; k < atom2->nw * GlobalV::NPOL; k++) + { + const int k0 = k / GlobalV::NPOL; + const int iw2_all = start2 + k; + const int nu = pv.global2local_col(iw2_all); + if (nu < 0) + { + continue; + } + total_nnr++; + nnr++; + } + } + iat_recorded = true; + } // is_adj + } // ad2 + + // sum the diff to fvnl_dbeta + if (force_updated && isforce) + { +#ifdef _OPENMP + if (num_threads > 1) + { + for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) + { +#pragma omp atomic + fvnl_dbeta(adj_iat[ad0], 0) += adj_fvnl_dbeta[ad0 * 3 + 0]; +#pragma omp atomic + fvnl_dbeta(adj_iat[ad0], 1) += adj_fvnl_dbeta[ad0 * 3 + 1]; +#pragma omp atomic + fvnl_dbeta(adj_iat[ad0], 2) += adj_fvnl_dbeta[ad0 * 3 + 2]; + } + } + else +#endif + { + for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) + { + fvnl_dbeta(adj_iat[ad0], 0) += adj_fvnl_dbeta[ad0 * 3 + 0]; + fvnl_dbeta(adj_iat[ad0], 1) += adj_fvnl_dbeta[ad0 * 3 + 1]; + fvnl_dbeta(adj_iat[ad0], 2) += adj_fvnl_dbeta[ad0 * 3 + 2]; + } + } + } + } // I1 + } // T1 + +#ifdef _OPENMP + if (isstress) + { +#pragma omp critical(cal_fvnl_dbeta_k_new_reduce) + { + for (int l = 0; l < 3; l++) + { + for (int m = 0; m < 3; m++) + { + svnl_dbeta(l, m) += local_svnl_dbeta(l, m); + } + } + } + } + } +#endif + + assert(total_nnr == pv.nnr); + + if (isstress) + { + StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, svnl_dbeta); + } + + ModuleBase::timer::tick("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); + return; +} + From 34add559f13c7306fd565bbf6348876095cae3e8 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 05:21:50 +0800 Subject: [PATCH 38/46] divide FORCE_k into foverlap_k.cpp ftvnl_dphi_k.cpp fvl_dphi_k.cpp fvnl_dbeta_k.cpp four files --- .../hamilt_lcaodft/CMakeLists.txt | 6 +- .../hamilt_lcaodft/FORCE_k.cpp | 923 ------------------ .../hamilt_lcaodft/foverlap_k.cpp | 250 +++++ .../hamilt_lcaodft/ftvnl_dphi_k.cpp | 165 ++++ .../hamilt_lcaodft/fvl_dphi_k.cpp | 95 ++ .../hamilt_lcaodft/fvnl_dbeta_k.cpp | 26 + 6 files changed, 541 insertions(+), 924 deletions(-) create mode 100644 source/module_hamilt_lcao/hamilt_lcaodft/foverlap_k.cpp create mode 100644 source/module_hamilt_lcao/hamilt_lcaodft/ftvnl_dphi_k.cpp create mode 100644 source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/CMakeLists.txt b/source/module_hamilt_lcao/hamilt_lcaodft/CMakeLists.txt index 10b1df34bde..3a6bcdd3fd6 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/CMakeLists.txt +++ b/source/module_hamilt_lcao/hamilt_lcaodft/CMakeLists.txt @@ -21,6 +21,10 @@ if(ENABLE_LCAO) FORCE_gamma_tvnl.cpp FORCE_gamma_vl.cpp FORCE_k.cpp + foverlap_k.cpp + ftvnl_dphi_k.cpp + fvl_dphi_k.cpp + fvnl_dbeta_k.cpp LCAO_gen_fixedH.cpp LCAO_hamilt.cpp LCAO_matrix.cpp @@ -48,4 +52,4 @@ if(ENABLE_LCAO) add_coverage(hamilt_lcao) endif() -endif() \ No newline at end of file +endif() diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp index 947d5bc5be8..a94cbd3d11a 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp @@ -309,371 +309,6 @@ void Force_LCAO_k::finish_k(LCAO_Matrix &lm) return; } -#include "module_hamilt_lcao/hamilt_lcaodft/record_adj.h" -void Force_LCAO_k::cal_foverlap_k(const bool isforce, - const bool isstress, - Record_adj &ra, - const psi::Psi> *psi, - Local_Orbital_Charge &loc, - Parallel_Orbitals &pv, - LCAO_Matrix &lm, - const elecstate::DensityMatrix, double> *DM, - ModuleBase::matrix &foverlap, - ModuleBase::matrix &soverlap, - const elecstate::ElecState *pelec, - const int &nks, - const K_Vectors &kv) -{ - ModuleBase::TITLE("Force_LCAO_k", "cal_foverlap_k"); - ModuleBase::timer::tick("Force_LCAO_k", "cal_foverlap_k"); - - // construct a DensityMatrix object - elecstate::DensityMatrix, double> EDM(&kv,&pv,GlobalV::NSPIN); - - //-------------------------------------------- - // calculate the energy density matrix here. - //-------------------------------------------- - ModuleBase::timer::tick("Force_LCAO_k", "cal_edm_2d"); - - ModuleBase::matrix wgEkb; - wgEkb.create(nks, GlobalV::NBANDS); - ModuleBase::Memory::record("Force::wgEkb", sizeof(double) * nks * GlobalV::NBANDS); -#ifdef _OPENMP -#pragma omp parallel for collapse(2) schedule(static, 1024) -#endif - for (int ik = 0; ik < nks; ik++) - { - for (int ib = 0; ib < GlobalV::NBANDS; ib++) - { - wgEkb(ik, ib) = pelec->wg(ik, ib) * pelec->ekb(ik, ib); - } - } - std::vector edm_k(nks); - - // use the original formula (Hamiltonian matrix) to calculate energy density matrix - if (DM->EDMK.size()) - { -#ifdef _OPENMP -#pragma omp parallel for schedule(static, 1024) -#endif - for (int ik = 0; ik < nks; ++ik) - { - //edm_k[ik] = loc.edm_k_tddft[ik]; - EDM.set_DMK_pointer(ik,DM->EDMK[ik].c); - } - } - else - { - //elecstate::cal_dm(pv, wgEkb, psi[0], edm_k); - // cal_dm_psi - elecstate::cal_dm_psi(EDM.get_paraV_pointer(), wgEkb, psi[0], EDM); - } - - //loc.cal_dm_R(edm_k, ra, edm2d, kv); - - // cal_dm_2d - EDM.init_DMR(ra,&GlobalC::ucell); - EDM.cal_DMR(); - EDM.sum_DMR_spin(); - // - ModuleBase::timer::tick("Force_LCAO_k", "cal_edm_2d"); - //-------------------------------------------- - // summation \sum_{i,j} E(i,j)*dS(i,j) - // BEGIN CALCULATION OF FORCE OF EACH ATOM - //-------------------------------------------- - int total_irr = 0; -#ifdef _OPENMP -#pragma omp parallel - { - int num_threads = omp_get_num_threads(); - ModuleBase::matrix local_soverlap(3, 3); - int local_total_irr = 0; -#else - ModuleBase::matrix& local_soverlap = soverlap; - int& local_total_irr = total_irr; -#endif - - ModuleBase::Vector3 tau1, dtau, tau2; - -#ifdef _OPENMP -#pragma omp for schedule(dynamic) -#endif - for (int iat = 0; iat < GlobalC::ucell.nat; iat++) - { - const int T1 = GlobalC::ucell.iat2it[iat]; - Atom* atom1 = &GlobalC::ucell.atoms[T1]; - const int I1 = GlobalC::ucell.iat2ia[iat]; - // get iat1 - int iat1 = GlobalC::ucell.itia2iat(T1, I1); - double* foverlap_iat; - if (isforce) - { - foverlap_iat = &foverlap(iat, 0); - } - -#ifdef _OPENMP - // using local stack to avoid false sharing in multi-threaded case - double foverlap_temp[3] = {0.0, 0.0, 0.0}; - if (num_threads > 1) - { - foverlap_iat = foverlap_temp; - } -#endif - int irr = pv.nlocstart[iat]; - const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); - for (int cb = 0; cb < ra.na_each[iat]; ++cb) - { - const int T2 = ra.info[iat][cb][3]; - const int I2 = ra.info[iat][cb][4]; - - const int start2 = GlobalC::ucell.itiaiw2iwt(T2, I2, 0); - - Atom* atom2 = &GlobalC::ucell.atoms[T2]; - - // get iat2 - int iat2 = GlobalC::ucell.itia2iat(T2, I2); - double Rx = ra.info[iat][cb][0]; - double Ry = ra.info[iat][cb][1]; - double Rz = ra.info[iat][cb][2]; - // get BaseMatrix - hamilt::BaseMatrix* tmp_matrix = EDM.get_DMR_pointer(1)->find_matrix(iat1, iat2, Rx, Ry, Rz); - if(tmp_matrix == nullptr) - { - continue; - } - int row_ap = pv.atom_begin_row[iat1]; - int col_ap = pv.atom_begin_col[iat2]; - // get DMR - for (int mu = 0; mu < pv.get_row_size(iat1); ++mu) - { - for (int nu = 0; nu < pv.get_col_size(iat2); ++nu) - { - // here do not sum over spin due to EDM.sum_DMR_spin(); - double edm2d1 = tmp_matrix->get_value(mu,nu); - double edm2d2 = 2.0 * edm2d1; - - if (isforce) - { - foverlap_iat[0] -= edm2d2 * lm.DSloc_Rx[irr]; - foverlap_iat[1] -= edm2d2 * lm.DSloc_Ry[irr]; - foverlap_iat[2] -= edm2d2 * lm.DSloc_Rz[irr]; - } - if (isstress) - { - for (int ipol = 0; ipol < 3; ipol++) - { - local_soverlap(0, ipol) += edm2d1 * lm.DSloc_Rx[irr] - * lm.DH_r[irr * 3 + ipol]; - if (ipol < 1) - { - continue; - } - local_soverlap(1, ipol) += edm2d1 * lm.DSloc_Ry[irr] - * lm.DH_r[irr * 3 + ipol]; - if (ipol < 2) - { - continue; - } - local_soverlap(2, ipol) += edm2d1 * lm.DSloc_Rz[irr] - * lm.DH_r[irr * 3 + ipol]; - } - } - //} - ++local_total_irr; - ++irr; - } // end kk - } // end jj - } // end cb -#ifdef _OPENMP - if (isforce && num_threads > 1) - { - foverlap(iat, 0) += foverlap_iat[0]; - foverlap(iat, 1) += foverlap_iat[1]; - foverlap(iat, 2) += foverlap_iat[2]; - } -#endif - } // end iat -#ifdef _OPENMP -#pragma omp critical(cal_foverlap_k_reduce) - { - total_irr += local_total_irr; - if (isstress) - { - for (int ipol = 0; ipol < 3; ipol++) - { - soverlap(0, ipol) += local_soverlap(0, ipol); - if (ipol < 1) - { - continue; - } - soverlap(1, ipol) += local_soverlap(1, ipol); - if (ipol < 2) - { - continue; - } - soverlap(2, ipol) += local_soverlap(2, ipol); - } - } - } - } -#endif - - if (isstress) - { - StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, soverlap); - } - - if (total_irr != pv.nnr) - { - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong irr", total_irr); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong LNNR.nnr", pv.nnr); - ModuleBase::WARNING_QUIT("Force_LCAO_k::cal_foverlap_k", "irr!=LNNR.nnr"); - } - - ModuleBase::timer::tick("Force_LCAO_k", "cal_foverlap_k"); - return; -} - -void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrix, double>* DM, - const Parallel_Orbitals &pv, - LCAO_Matrix &lm, - const bool isforce, - const bool isstress, - Record_adj& ra, - ModuleBase::matrix& ftvnl_dphi, - ModuleBase::matrix& stvnl_dphi) -{ - ModuleBase::TITLE("Force_LCAO_k", "cal_ftvnl_dphi_k"); - ModuleBase::timer::tick("Force_LCAO_k", "cal_ftvnl_dphi_k"); - - int total_irr = 0; - // get the adjacent atom's information. - - // GlobalV::ofs_running << " calculate the ftvnl_dphi_k force" << std::endl; -#ifdef _OPENMP -#pragma omp parallel - { - int num_threads = omp_get_num_threads(); - ModuleBase::matrix local_stvnl_dphi(3, 3); - int local_total_irr = 0; -#pragma omp for schedule(dynamic) -#else - ModuleBase::matrix& local_stvnl_dphi = stvnl_dphi; - int& local_total_irr = total_irr; -#endif - for (int iat = 0; iat < GlobalC::ucell.nat; iat++) - { - const int T1 = GlobalC::ucell.iat2it[iat]; - Atom* atom1 = &GlobalC::ucell.atoms[T1]; - const int I1 = GlobalC::ucell.iat2ia[iat]; - // get iat1 - int iat1 = GlobalC::ucell.itia2iat(T1, I1); - // - int irr = pv.nlocstart[iat]; - const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); - double* ftvnl_dphi_iat; - if (isforce) - { - ftvnl_dphi_iat = &ftvnl_dphi(iat, 0); - } -#ifdef _OPENMP - // using local stack to avoid false sharing in multi-threaded case - double ftvnl_dphi_temp[3] = {0.0, 0.0, 0.0}; - if (num_threads > 1) - { - ftvnl_dphi_iat = ftvnl_dphi_temp; - } -#endif - for (int cb = 0; cb < ra.na_each[iat]; ++cb) - { - const int T2 = ra.info[iat][cb][3]; - const int I2 = ra.info[iat][cb][4]; - const int start2 = GlobalC::ucell.itiaiw2iwt(T2, I2, 0); - Atom* atom2 = &GlobalC::ucell.atoms[T2]; - // get iat2 - int iat2 = GlobalC::ucell.itia2iat(T2, I2); - double Rx = ra.info[iat][cb][0]; - double Ry = ra.info[iat][cb][1]; - double Rz = ra.info[iat][cb][2]; - // get BaseMatrix - if (pv.get_row_size(iat1) <= 0 || pv.get_col_size(iat2) <= 0) - { - continue; - } - std::vector*> tmp_matrix; - for (int is = 0; is < GlobalV::NSPIN; ++is) - { - tmp_matrix.push_back(DM->get_DMR_pointer(is+1)->find_matrix(iat1, iat2, Rx, Ry, Rz)); - } - //hamilt::BaseMatrix* tmp_matrix = DM->get_DMR_pointer(1)->find_matrix(iat1, iat2, Rx, Ry, Rz); - for (int mu = 0; mu < pv.get_row_size(iat1); ++mu) - { - for (int nu = 0; nu < pv.get_col_size(iat2); ++nu) - { - // get value from DM - double dm2d1 = 0.0; - for (int is = 0; is < GlobalV::NSPIN; ++is) - { - dm2d1 += tmp_matrix[is]->get_value(mu, nu); - } - double dm2d2 = 2.0 * dm2d1; - // - if (isforce) - { - ftvnl_dphi_iat[0] += dm2d2 * lm.DHloc_fixedR_x[irr]; - ftvnl_dphi_iat[1] += dm2d2 * lm.DHloc_fixedR_y[irr]; - ftvnl_dphi_iat[2] += dm2d2 * lm.DHloc_fixedR_z[irr]; - } - if (isstress) - { - local_stvnl_dphi(0, 0) -= dm2d1 * lm.stvnl11[irr]; - local_stvnl_dphi(0, 1) -= dm2d1 * lm.stvnl12[irr]; - local_stvnl_dphi(0, 2) -= dm2d1 * lm.stvnl13[irr]; - local_stvnl_dphi(1, 1) -= dm2d1 * lm.stvnl22[irr]; - local_stvnl_dphi(1, 2) -= dm2d1 * lm.stvnl23[irr]; - local_stvnl_dphi(2, 2) -= dm2d1 * lm.stvnl33[irr]; - } - //} - ++local_total_irr; - ++irr; - } // end kk - } // end jj - } // end cb -#ifdef _OPENMP - if (isforce && num_threads > 1) - { - ftvnl_dphi(iat, 0) += ftvnl_dphi_iat[0]; - ftvnl_dphi(iat, 1) += ftvnl_dphi_iat[1]; - ftvnl_dphi(iat, 2) += ftvnl_dphi_iat[2]; - } -#endif - } // end iat -#ifdef _OPENMP -#pragma omp critical(cal_ftvnl_dphi_k_reduce) - { - total_irr += local_total_irr; - if (isstress) - { - stvnl_dphi(0, 0) += local_stvnl_dphi(0, 0); - stvnl_dphi(0, 1) += local_stvnl_dphi(0, 1); - stvnl_dphi(0, 2) += local_stvnl_dphi(0, 2); - stvnl_dphi(1, 1) += local_stvnl_dphi(1, 1); - stvnl_dphi(1, 2) += local_stvnl_dphi(1, 2); - stvnl_dphi(2, 2) += local_stvnl_dphi(2, 2); - } - } - } -#endif - assert(total_irr == pv.nnr); - - if (isstress) - { - StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, stvnl_dphi); - } - - ModuleBase::timer::tick("Force_LCAO_k", "cal_ftvnl_dphi_k"); - return; -} void Force_LCAO_k::test( Parallel_Orbitals &pv, @@ -750,563 +385,5 @@ void Force_LCAO_k::test( return; } -typedef std::tuple key_tuple; - -// must consider three-center H matrix. -void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrix, double>* DM, - const bool isforce, - const bool isstress, - const Parallel_Orbitals &pv, - ModuleBase::matrix& fvnl_dbeta, - ModuleBase::matrix& svnl_dbeta) -{ - ModuleBase::TITLE("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); - ModuleBase::timer::tick("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); - - // Data structure for storing , for a detailed description - // check out the same data structure in build_Nonlocal_mu_new - std::vector>>>> nlm_tot; - - nlm_tot.resize(GlobalC::ucell.nat); - -#ifdef _OPENMP -// use schedule(dynamic) for load balancing because adj_num is various -#pragma omp parallel for schedule(dynamic) -#endif - for (int iat = 0; iat < GlobalC::ucell.nat; iat++) - { - - const int it = GlobalC::ucell.iat2it[iat]; - const int ia = GlobalC::ucell.iat2ia[iat]; - - // Step 1 : generate - // type of atom; distance; atomic basis; projectors - - const double Rcut_Beta = GlobalC::ucell.infoNL.Beta[it].get_rcut_max(); - const ModuleBase::Vector3 tau = GlobalC::ucell.atoms[it].tau[ia]; - AdjacentAtomInfo adjs; - GlobalC::GridD.Find_atom(GlobalC::ucell, tau, it, ia, &adjs); - - nlm_tot[iat].clear(); - - for (int ad = 0; ad < adjs.adj_num + 1; ++ad) - { - const int T1 = adjs.ntype[ad]; - const int I1 = adjs.natom[ad]; - const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); - const double Rcut_AO1 = GlobalC::ORB.Phi[T1].getRcut(); - - const ModuleBase::Vector3& tau1 = adjs.adjacent_tau[ad]; - const Atom* atom1 = &GlobalC::ucell.atoms[T1]; - const int nw1_tot = atom1->nw * GlobalV::NPOL; - - const ModuleBase::Vector3 dtau = tau1 - tau; - const double dist1 = dtau.norm2() * pow(GlobalC::ucell.lat0, 2); - if (dist1 > pow(Rcut_Beta + Rcut_AO1, 2)) - { - continue; - } - - std::unordered_map>> nlm_cur; - nlm_cur.clear(); - - for (int iw1 = 0; iw1 < nw1_tot; ++iw1) - { - const int iw1_all = start1 + iw1; - const int iw1_local = pv.global2local_row(iw1_all); - const int iw2_local = pv.global2local_col(iw1_all); - if (iw1_local < 0 && iw2_local < 0) - { - continue; - } - const int iw1_0 = iw1 / GlobalV::NPOL; - std::vector> nlm; -#ifdef USE_NEW_TWO_CENTER - //================================================================= - // new two-center integral (temporary) - //================================================================= - int L1 = atom1->iw2l[ iw1_0 ]; - int N1 = atom1->iw2n[ iw1_0 ]; - int m1 = atom1->iw2m[ iw1_0 ]; - - // convert m (0,1,...2l) to M (-l, -l+1, ..., l-1, l) - int M1 = (m1 % 2 == 0) ? -m1/2 : (m1+1)/2; - - ModuleBase::Vector3 dtau = tau - tau1; - GlobalC::UOT.two_center_bundle->overlap_orb_beta->snap( - T1, L1, N1, M1, it, dtau * GlobalC::ucell.lat0, true, nlm); -#else - GlobalC::UOT.snap_psibeta_half(GlobalC::ORB, - GlobalC::ucell.infoNL, - nlm, - tau1, - T1, - atom1->iw2l[iw1_0], // L1 - atom1->iw2m[iw1_0], // m1 - atom1->iw2n[iw1_0], // N1 - tau, - it, - 1); // R0,T0 -#endif - nlm_cur.insert({iw1_all, nlm}); - } // end iw - const int iat1 = GlobalC::ucell.itia2iat(T1, I1); - const int rx1 = adjs.box[ad].x; - const int ry1 = adjs.box[ad].y; - const int rz1 = adjs.box[ad].z; - key_tuple key_1(iat1, rx1, ry1, rz1); - nlm_tot[iat][key_1] = nlm_cur; - } // end ad - } - - //======================================================= - // Step2: - // calculate sum_(L0,M0) beta - // and accumulate the value to Hloc_fixedR(i,j) - //======================================================= - int total_nnr = 0; -#ifdef _OPENMP -#pragma omp parallel reduction(+ : total_nnr) - { - ModuleBase::matrix local_svnl_dbeta(3, 3); - const int num_threads = omp_get_num_threads(); -#else - ModuleBase::matrix& local_svnl_dbeta = svnl_dbeta; -#endif - - ModuleBase::Vector3 tau1; - ModuleBase::Vector3 tau2; - ModuleBase::Vector3 dtau; - ModuleBase::Vector3 tau0; - ModuleBase::Vector3 dtau1; - ModuleBase::Vector3 dtau2; - - double rcut; - double distance; - - double rcut1; - double rcut2; - double distance1; - double distance2; - -#ifdef _OPENMP -// use schedule(dynamic) for load balancing because adj_num is various -#pragma omp for schedule(dynamic) -#endif - for (int iat1 = 0; iat1 < GlobalC::ucell.nat; iat1++) - { - const int T1 = GlobalC::ucell.iat2it[iat1]; - const Atom* atom1 = &GlobalC::ucell.atoms[T1]; - - { - const int I1 = GlobalC::ucell.iat2ia[iat1]; - tau1 = atom1->tau[I1]; - AdjacentAtomInfo adjs; - GlobalC::GridD.Find_atom(GlobalC::ucell, tau1, T1, I1, &adjs); - const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); - int nnr = pv.nlocstart[iat1]; - - /* - !!!!!!!!!!!!!!!! - This optimization is also improving the performance of single thread. - Making memory access more linearly in the core loop - */ - bool iat_recorded = false; - bool force_updated = false; - // record iat of adjs - std::vector adj_iat; - // record fvnl_dbeta diff of adjs - std::vector adj_fvnl_dbeta; - if (isforce) - { - adj_iat.resize(adjs.adj_num + 1); - adj_fvnl_dbeta.resize((adjs.adj_num + 1) * 3, 0.0); - } - - for (int ad2 = 0; ad2 < adjs.adj_num + 1; ++ad2) - { - const int T2 = adjs.ntype[ad2]; - const Atom* atom2 = &GlobalC::ucell.atoms[T2]; - - const int I2 = adjs.natom[ad2]; - const int iat2 = GlobalC::ucell.itia2iat(T2, I2); - const int start2 = GlobalC::ucell.itiaiw2iwt(T2, I2, 0); - tau2 = adjs.adjacent_tau[ad2]; - - const int rx2 = adjs.box[ad2].x; - const int ry2 = adjs.box[ad2].y; - const int rz2 = adjs.box[ad2].z; - - dtau = tau2 - tau1; - distance = dtau.norm2() * pow(GlobalC::ucell.lat0, 2); - // this rcut is in order to make nnr consistent - // with other matrix. - rcut = pow(GlobalC::ORB.Phi[T1].getRcut() + GlobalC::ORB.Phi[T2].getRcut(), 2); - - // check if this a adjacent atoms. - bool is_adj = false; - if (distance < rcut) - is_adj = true; - else if (distance >= rcut) - { - for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) - { - const int T0 = adjs.ntype[ad0]; - if (GlobalC::ucell.infoNL.nproj[T0] == 0) - { - continue; - } - const int I0 = adjs.natom[ad0]; - // const int iat0 = GlobalC::ucell.itia2iat(T0, I0); - // const int start0 = GlobalC::ucell.itiaiw2iwt(T0, I0, 0); - - tau0 = adjs.adjacent_tau[ad0]; - dtau1 = tau0 - tau1; - distance1 = dtau1.norm() * GlobalC::ucell.lat0; - rcut1 = GlobalC::ORB.Phi[T1].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(); - - dtau2 = tau0 - tau2; - distance2 = dtau2.norm() * GlobalC::ucell.lat0; - rcut2 = GlobalC::ORB.Phi[T2].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(); - - if (distance1 < rcut1 && distance2 < rcut2) - { - is_adj = true; - break; - } - } - } - - if (is_adj) - { - // basematrix and its data pointer - if (pv.get_row_size(iat1) <= 0 || pv.get_col_size(iat2) <= 0) - { - continue; - } - std::vector tmp_matrix_ptr; - for (int is = 0; is < GlobalV::NSPIN; ++is) - { - auto* tmp_base_matrix = DM->get_DMR_pointer(is+1)->find_matrix(iat1, iat2, rx2, ry2, rz2); - tmp_matrix_ptr.push_back(tmp_base_matrix->get_pointer()); - } - //hamilt::BaseMatrix* tmp_matrix = DM->get_DMR_pointer(1)->find_matrix(iat1, iat2, rx2, ry2, rz2); - //double* tmp_matrix_ptr = tmp_matrix->get_pointer(); - for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) - { - const int T0 = adjs.ntype[ad0]; - const int I0 = adjs.natom[ad0]; - const int iat = GlobalC::ucell.itia2iat(T0, I0); - if (!iat_recorded && isforce) - adj_iat[ad0] = iat; - - // mohan add 2010-12-19 - if (GlobalC::ucell.infoNL.nproj[T0] == 0) - continue; - - // const int I0 = GlobalC::GridD.getNatom(ad0); - // const int start0 = GlobalC::ucell.itiaiw2iwt(T0, I0, 0); - tau0 = adjs.adjacent_tau[ad0]; - - dtau1 = tau0 - tau1; - dtau2 = tau0 - tau2; - const double distance1 = dtau1.norm2() * pow(GlobalC::ucell.lat0, 2); - const double distance2 = dtau2.norm2() * pow(GlobalC::ucell.lat0, 2); - - // seems a bug here!! mohan 2011-06-17 - rcut1 = pow(GlobalC::ORB.Phi[T1].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(), - 2); - rcut2 = pow(GlobalC::ORB.Phi[T2].getRcut() + GlobalC::ucell.infoNL.Beta[T0].get_rcut_max(), - 2); - - double r0[3]; - double r1[3]; - r1[0] = (tau1.x - tau0.x); - r1[1] = (tau1.y - tau0.y); - r1[2] = (tau1.z - tau0.z); - r0[0] = (tau2.x - tau0.x); - r0[1] = (tau2.y - tau0.y); - r0[2] = (tau2.z - tau0.z); - - if (distance1 >= rcut1 || distance2 >= rcut2) - { - continue; - } - - const int rx0 = adjs.box[ad0].x; - const int ry0 = adjs.box[ad0].y; - const int rz0 = adjs.box[ad0].z; - key_tuple key1(iat1, -rx0, -ry0, -rz0); - key_tuple key2(iat2, rx2 - rx0, ry2 - ry0, rz2 - rz0); - - int nnr_inner = 0; - for (int j = 0; j < atom1->nw * GlobalV::NPOL; j++) - { - const int j0 = j / GlobalV::NPOL; // added by zhengdy-soc - const int iw1_all = start1 + j; - const int mu = pv.global2local_row(iw1_all); - if (mu < 0) - { - continue; - } - - for (int k = 0; k < atom2->nw * GlobalV::NPOL; k++) - { - const int k0 = k / GlobalV::NPOL; - const int iw2_all = start2 + k; - const int nu = pv.global2local_col(iw2_all); - if (nu < 0) - { - continue; - } - - // const Atom* atom0 = &GlobalC::ucell.atoms[T0]; - double nlm[3] = {0, 0, 0}; - std::vector nlm_1 = nlm_tot[iat][key2][iw2_all][0]; - std::vector> nlm_2; - nlm_2.resize(3); - for (int i = 0; i < 3; i++) - { - nlm_2[i] = nlm_tot[iat][key1][iw1_all][i + 1]; - } - - assert(nlm_1.size() == nlm_2[0].size()); - - const int nproj = GlobalC::ucell.infoNL.nproj[T0]; - int ib = 0; - for (int nb = 0; nb < nproj; nb++) - { - const int L0 = GlobalC::ucell.infoNL.Beta[T0].Proj[nb].getL(); - for (int m = 0; m < 2 * L0 + 1; m++) - { - for (int ir = 0; ir < 3; ir++) - { - nlm[ir] += nlm_2[ir][ib] * nlm_1[ib] - * GlobalC::ucell.atoms[T0].ncpp.dion(nb, nb); - } - ib += 1; - } - } - assert(ib == nlm_1.size()); - - double nlm1[3] = {0, 0, 0}; - if (isstress) - { - std::vector nlm_1 = nlm_tot[iat][key1][iw1_all][0]; - std::vector> nlm_2; - nlm_2.resize(3); - for (int i = 0; i < 3; i++) - { - nlm_2[i] = nlm_tot[iat][key2][iw2_all][i + 1]; - } - - assert(nlm_1.size() == nlm_2[0].size()); - - const int nproj = GlobalC::ucell.infoNL.nproj[T0]; - int ib = 0; - for (int nb = 0; nb < nproj; nb++) - { - const int L0 = GlobalC::ucell.infoNL.Beta[T0].Proj[nb].getL(); - for (int m = 0; m < 2 * L0 + 1; m++) - { - for (int ir = 0; ir < 3; ir++) - { - nlm1[ir] += nlm_2[ir][ib] * nlm_1[ib] - * GlobalC::ucell.atoms[T0].ncpp.dion(nb, nb); - } - ib += 1; - } - } - assert(ib == nlm_1.size()); - } - - /// only one projector for each atom force, but another projector for stress - force_updated = true; - // get DMR - double dm2d1 = 0.0; - for (int is = 0; is < GlobalV::NSPIN; ++is) - { - dm2d1 += tmp_matrix_ptr[is][nnr_inner]; - } - double dm2d2 = 2.0 * dm2d1; - // - for (int jpol = 0; jpol < 3; jpol++) - { - if (isforce) - { - adj_fvnl_dbeta[ad0 * 3 + jpol] -= dm2d2 * nlm[jpol]; - } - if (isstress) - { - for (int ipol = jpol; ipol < 3; ipol++) - { - local_svnl_dbeta(jpol, ipol) - += dm2d1 - * (nlm[jpol] * r1[ipol] + nlm1[jpol] * r0[ipol]); - } - } - } - //} - nnr_inner++; - } // k - } // j - } // ad0 - - // outer circle : accumulate nnr - for (int j = 0; j < atom1->nw * GlobalV::NPOL; j++) - { - const int j0 = j / GlobalV::NPOL; // added by zhengdy-soc - const int iw1_all = start1 + j; - const int mu = pv.global2local_row(iw1_all); - if (mu < 0) - { - continue; - } - - // fix a serious bug: atom2[T2] -> atom2 - // mohan 2010-12-20 - for (int k = 0; k < atom2->nw * GlobalV::NPOL; k++) - { - const int k0 = k / GlobalV::NPOL; - const int iw2_all = start2 + k; - const int nu = pv.global2local_col(iw2_all); - if (nu < 0) - { - continue; - } - total_nnr++; - nnr++; - } - } - iat_recorded = true; - } // is_adj - } // ad2 - - // sum the diff to fvnl_dbeta - if (force_updated && isforce) - { -#ifdef _OPENMP - if (num_threads > 1) - { - for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) - { -#pragma omp atomic - fvnl_dbeta(adj_iat[ad0], 0) += adj_fvnl_dbeta[ad0 * 3 + 0]; -#pragma omp atomic - fvnl_dbeta(adj_iat[ad0], 1) += adj_fvnl_dbeta[ad0 * 3 + 1]; -#pragma omp atomic - fvnl_dbeta(adj_iat[ad0], 2) += adj_fvnl_dbeta[ad0 * 3 + 2]; - } - } - else -#endif - { - for (int ad0 = 0; ad0 < adjs.adj_num + 1; ++ad0) - { - fvnl_dbeta(adj_iat[ad0], 0) += adj_fvnl_dbeta[ad0 * 3 + 0]; - fvnl_dbeta(adj_iat[ad0], 1) += adj_fvnl_dbeta[ad0 * 3 + 1]; - fvnl_dbeta(adj_iat[ad0], 2) += adj_fvnl_dbeta[ad0 * 3 + 2]; - } - } - } - } // I1 - } // T1 - -#ifdef _OPENMP - if (isstress) - { -#pragma omp critical(cal_fvnl_dbeta_k_new_reduce) - { - for (int l = 0; l < 3; l++) - { - for (int m = 0; m < 3; m++) - { - svnl_dbeta(l, m) += local_svnl_dbeta(l, m); - } - } - } - } - } -#endif - - assert(total_nnr == pv.nnr); - - if (isstress) - { - StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, svnl_dbeta); - } - - ModuleBase::timer::tick("Force_LCAO_k", "cal_fvnl_dbeta_k_new"); - return; -} - -// calculate the force due to < phi | Vlocal | dphi > -void Force_LCAO_k::cal_fvl_dphi_k(const bool isforce, - const bool isstress, - LCAO_Matrix &lm, - const elecstate::Potential* pot_in, - ModuleBase::matrix& fvl_dphi, - ModuleBase::matrix& svl_dphi, - double** DM_R) -{ - ModuleBase::TITLE("Force_LCAO_k", "cal_fvl_dphi_k"); - ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); - - if (!isforce && !isstress) - { - ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); - return; - } - - assert(lm.DHloc_fixedR_x != NULL); - assert(lm.DHloc_fixedR_y != NULL); - assert(lm.DHloc_fixedR_z != NULL); - - int istep = 1; - - for (int is = 0; is < GlobalV::NSPIN; ++is) - { - GlobalV::CURRENT_SPIN = is; - - const double* vr_eff1 = pot_in->get_effective_v(GlobalV::CURRENT_SPIN); - const double* vofk_eff1 = nullptr; - if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) - { - vofk_eff1 = pot_in->get_effective_vofk(GlobalV::CURRENT_SPIN); - } - - //-------------------------------- - // Grid integration here. - //-------------------------------- - // fvl_dphi can not be set to zero here if Vna is used - if (isstress || isforce) - { - if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) - { - Gint_inout inout(DM_R, - is, - vr_eff1, - vofk_eff1, - isforce, - isstress, - &fvl_dphi, - &svl_dphi, - Gint_Tools::job_type::force_meta); - this->UHM->GK.cal_gint(&inout); - } - else - { - Gint_inout inout(DM_R, is, vr_eff1, isforce, isstress, &fvl_dphi, &svl_dphi, Gint_Tools::job_type::force); - this->UHM->GK.cal_gint(&inout); - } - } - } - if (isstress) - { - StressTools::stress_fill(-1.0, GlobalC::ucell.omega, svl_dphi); - } - ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); - return; -} diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/foverlap_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/foverlap_k.cpp new file mode 100644 index 00000000000..0fcb9a9251f --- /dev/null +++ b/source/module_hamilt_lcao/hamilt_lcaodft/foverlap_k.cpp @@ -0,0 +1,250 @@ +#include "FORCE_k.h" + +#include +#include + +#include "module_base/memory.h" +#include "module_base/parallel_reduce.h" +#include "module_base/timer.h" +#include "module_base/tool_threading.h" +#include "module_cell/module_neighbor/sltk_grid_driver.h" +#include "module_elecstate/cal_dm.h" +#include "module_elecstate/module_dm/cal_dm_psi.h" +#include "module_elecstate/elecstate_lcao.h" +#include "module_hamilt_pw/hamilt_pwdft/global.h" +#include "module_io/write_HS.h" + +#ifdef __DEEPKS +#include "module_hamilt_lcao/module_deepks/LCAO_deepks.h" +#endif + +#ifdef _OPENMP +#include +#endif + +#include "module_hamilt_lcao/hamilt_lcaodft/record_adj.h" + + +void Force_LCAO_k::cal_foverlap_k(const bool isforce, + const bool isstress, + Record_adj &ra, + const psi::Psi> *psi, + Local_Orbital_Charge &loc, + Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const elecstate::DensityMatrix, double> *DM, + ModuleBase::matrix &foverlap, + ModuleBase::matrix &soverlap, + const elecstate::ElecState *pelec, + const int &nks, + const K_Vectors &kv) +{ + ModuleBase::TITLE("Force_LCAO_k", "cal_foverlap_k"); + ModuleBase::timer::tick("Force_LCAO_k", "cal_foverlap_k"); + + // construct a DensityMatrix object + elecstate::DensityMatrix, double> EDM(&kv,&pv,GlobalV::NSPIN); + + //-------------------------------------------- + // calculate the energy density matrix here. + //-------------------------------------------- + ModuleBase::timer::tick("Force_LCAO_k", "cal_edm_2d"); + + ModuleBase::matrix wgEkb; + wgEkb.create(nks, GlobalV::NBANDS); + ModuleBase::Memory::record("Force::wgEkb", sizeof(double) * nks * GlobalV::NBANDS); +#ifdef _OPENMP +#pragma omp parallel for collapse(2) schedule(static, 1024) +#endif + for (int ik = 0; ik < nks; ik++) + { + for (int ib = 0; ib < GlobalV::NBANDS; ib++) + { + wgEkb(ik, ib) = pelec->wg(ik, ib) * pelec->ekb(ik, ib); + } + } + std::vector edm_k(nks); + + // use the original formula (Hamiltonian matrix) to calculate energy density matrix + if (DM->EDMK.size()) + { +#ifdef _OPENMP +#pragma omp parallel for schedule(static, 1024) +#endif + for (int ik = 0; ik < nks; ++ik) + { + //edm_k[ik] = loc.edm_k_tddft[ik]; + EDM.set_DMK_pointer(ik,DM->EDMK[ik].c); + } + } + else + { + //elecstate::cal_dm(pv, wgEkb, psi[0], edm_k); + // cal_dm_psi + elecstate::cal_dm_psi(EDM.get_paraV_pointer(), wgEkb, psi[0], EDM); + } + + //loc.cal_dm_R(edm_k, ra, edm2d, kv); + + // cal_dm_2d + EDM.init_DMR(ra,&GlobalC::ucell); + EDM.cal_DMR(); + EDM.sum_DMR_spin(); + // + ModuleBase::timer::tick("Force_LCAO_k", "cal_edm_2d"); + //-------------------------------------------- + // summation \sum_{i,j} E(i,j)*dS(i,j) + // BEGIN CALCULATION OF FORCE OF EACH ATOM + //-------------------------------------------- + int total_irr = 0; +#ifdef _OPENMP +#pragma omp parallel + { + int num_threads = omp_get_num_threads(); + ModuleBase::matrix local_soverlap(3, 3); + int local_total_irr = 0; +#else + ModuleBase::matrix& local_soverlap = soverlap; + int& local_total_irr = total_irr; +#endif + + ModuleBase::Vector3 tau1, dtau, tau2; + +#ifdef _OPENMP +#pragma omp for schedule(dynamic) +#endif + for (int iat = 0; iat < GlobalC::ucell.nat; iat++) + { + const int T1 = GlobalC::ucell.iat2it[iat]; + Atom* atom1 = &GlobalC::ucell.atoms[T1]; + const int I1 = GlobalC::ucell.iat2ia[iat]; + // get iat1 + int iat1 = GlobalC::ucell.itia2iat(T1, I1); + double* foverlap_iat; + if (isforce) + { + foverlap_iat = &foverlap(iat, 0); + } + +#ifdef _OPENMP + // using local stack to avoid false sharing in multi-threaded case + double foverlap_temp[3] = {0.0, 0.0, 0.0}; + if (num_threads > 1) + { + foverlap_iat = foverlap_temp; + } +#endif + int irr = pv.nlocstart[iat]; + const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); + for (int cb = 0; cb < ra.na_each[iat]; ++cb) + { + const int T2 = ra.info[iat][cb][3]; + const int I2 = ra.info[iat][cb][4]; + + const int start2 = GlobalC::ucell.itiaiw2iwt(T2, I2, 0); + + Atom* atom2 = &GlobalC::ucell.atoms[T2]; + + // get iat2 + int iat2 = GlobalC::ucell.itia2iat(T2, I2); + double Rx = ra.info[iat][cb][0]; + double Ry = ra.info[iat][cb][1]; + double Rz = ra.info[iat][cb][2]; + // get BaseMatrix + hamilt::BaseMatrix* tmp_matrix = EDM.get_DMR_pointer(1)->find_matrix(iat1, iat2, Rx, Ry, Rz); + if(tmp_matrix == nullptr) + { + continue; + } + int row_ap = pv.atom_begin_row[iat1]; + int col_ap = pv.atom_begin_col[iat2]; + // get DMR + for (int mu = 0; mu < pv.get_row_size(iat1); ++mu) + { + for (int nu = 0; nu < pv.get_col_size(iat2); ++nu) + { + // here do not sum over spin due to EDM.sum_DMR_spin(); + double edm2d1 = tmp_matrix->get_value(mu,nu); + double edm2d2 = 2.0 * edm2d1; + + if (isforce) + { + foverlap_iat[0] -= edm2d2 * lm.DSloc_Rx[irr]; + foverlap_iat[1] -= edm2d2 * lm.DSloc_Ry[irr]; + foverlap_iat[2] -= edm2d2 * lm.DSloc_Rz[irr]; + } + if (isstress) + { + for (int ipol = 0; ipol < 3; ipol++) + { + local_soverlap(0, ipol) += edm2d1 * lm.DSloc_Rx[irr] + * lm.DH_r[irr * 3 + ipol]; + if (ipol < 1) + { + continue; + } + local_soverlap(1, ipol) += edm2d1 * lm.DSloc_Ry[irr] + * lm.DH_r[irr * 3 + ipol]; + if (ipol < 2) + { + continue; + } + local_soverlap(2, ipol) += edm2d1 * lm.DSloc_Rz[irr] + * lm.DH_r[irr * 3 + ipol]; + } + } + //} + ++local_total_irr; + ++irr; + } // end kk + } // end jj + } // end cb +#ifdef _OPENMP + if (isforce && num_threads > 1) + { + foverlap(iat, 0) += foverlap_iat[0]; + foverlap(iat, 1) += foverlap_iat[1]; + foverlap(iat, 2) += foverlap_iat[2]; + } +#endif + } // end iat +#ifdef _OPENMP +#pragma omp critical(cal_foverlap_k_reduce) + { + total_irr += local_total_irr; + if (isstress) + { + for (int ipol = 0; ipol < 3; ipol++) + { + soverlap(0, ipol) += local_soverlap(0, ipol); + if (ipol < 1) + { + continue; + } + soverlap(1, ipol) += local_soverlap(1, ipol); + if (ipol < 2) + { + continue; + } + soverlap(2, ipol) += local_soverlap(2, ipol); + } + } + } + } +#endif + + if (isstress) + { + StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, soverlap); + } + + if (total_irr != pv.nnr) + { + ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong irr", total_irr); + ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong LNNR.nnr", pv.nnr); + ModuleBase::WARNING_QUIT("Force_LCAO_k::cal_foverlap_k", "irr!=LNNR.nnr"); + } + + ModuleBase::timer::tick("Force_LCAO_k", "cal_foverlap_k"); + return; +} diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/ftvnl_dphi_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/ftvnl_dphi_k.cpp new file mode 100644 index 00000000000..ab95392b117 --- /dev/null +++ b/source/module_hamilt_lcao/hamilt_lcaodft/ftvnl_dphi_k.cpp @@ -0,0 +1,165 @@ +#include "FORCE_k.h" + +#include +#include + +#include "module_base/memory.h" +#include "module_base/parallel_reduce.h" +#include "module_base/timer.h" +#include "module_base/tool_threading.h" +#include "module_cell/module_neighbor/sltk_grid_driver.h" +#include "module_elecstate/cal_dm.h" +#include "module_elecstate/module_dm/cal_dm_psi.h" +#include "module_elecstate/elecstate_lcao.h" +#include "module_hamilt_pw/hamilt_pwdft/global.h" +#include "module_io/write_HS.h" + +#ifdef __DEEPKS +#include "module_hamilt_lcao/module_deepks/LCAO_deepks.h" +#endif + +#ifdef _OPENMP +#include +#endif + + +void Force_LCAO_k::cal_ftvnl_dphi_k(const elecstate::DensityMatrix, double>* DM, + const Parallel_Orbitals &pv, + LCAO_Matrix &lm, + const bool isforce, + const bool isstress, + Record_adj& ra, + ModuleBase::matrix& ftvnl_dphi, + ModuleBase::matrix& stvnl_dphi) +{ + ModuleBase::TITLE("Force_LCAO_k", "cal_ftvnl_dphi_k"); + ModuleBase::timer::tick("Force_LCAO_k", "cal_ftvnl_dphi_k"); + + int total_irr = 0; + // get the adjacent atom's information. + + // GlobalV::ofs_running << " calculate the ftvnl_dphi_k force" << std::endl; +#ifdef _OPENMP +#pragma omp parallel + { + int num_threads = omp_get_num_threads(); + ModuleBase::matrix local_stvnl_dphi(3, 3); + int local_total_irr = 0; +#pragma omp for schedule(dynamic) +#else + ModuleBase::matrix& local_stvnl_dphi = stvnl_dphi; + int& local_total_irr = total_irr; +#endif + for (int iat = 0; iat < GlobalC::ucell.nat; iat++) + { + const int T1 = GlobalC::ucell.iat2it[iat]; + Atom* atom1 = &GlobalC::ucell.atoms[T1]; + const int I1 = GlobalC::ucell.iat2ia[iat]; + // get iat1 + int iat1 = GlobalC::ucell.itia2iat(T1, I1); + // + int irr = pv.nlocstart[iat]; + const int start1 = GlobalC::ucell.itiaiw2iwt(T1, I1, 0); + double* ftvnl_dphi_iat; + if (isforce) + { + ftvnl_dphi_iat = &ftvnl_dphi(iat, 0); + } +#ifdef _OPENMP + // using local stack to avoid false sharing in multi-threaded case + double ftvnl_dphi_temp[3] = {0.0, 0.0, 0.0}; + if (num_threads > 1) + { + ftvnl_dphi_iat = ftvnl_dphi_temp; + } +#endif + for (int cb = 0; cb < ra.na_each[iat]; ++cb) + { + const int T2 = ra.info[iat][cb][3]; + const int I2 = ra.info[iat][cb][4]; + const int start2 = GlobalC::ucell.itiaiw2iwt(T2, I2, 0); + Atom* atom2 = &GlobalC::ucell.atoms[T2]; + // get iat2 + int iat2 = GlobalC::ucell.itia2iat(T2, I2); + double Rx = ra.info[iat][cb][0]; + double Ry = ra.info[iat][cb][1]; + double Rz = ra.info[iat][cb][2]; + // get BaseMatrix + if (pv.get_row_size(iat1) <= 0 || pv.get_col_size(iat2) <= 0) + { + continue; + } + std::vector*> tmp_matrix; + for (int is = 0; is < GlobalV::NSPIN; ++is) + { + tmp_matrix.push_back(DM->get_DMR_pointer(is+1)->find_matrix(iat1, iat2, Rx, Ry, Rz)); + } + //hamilt::BaseMatrix* tmp_matrix = DM->get_DMR_pointer(1)->find_matrix(iat1, iat2, Rx, Ry, Rz); + for (int mu = 0; mu < pv.get_row_size(iat1); ++mu) + { + for (int nu = 0; nu < pv.get_col_size(iat2); ++nu) + { + // get value from DM + double dm2d1 = 0.0; + for (int is = 0; is < GlobalV::NSPIN; ++is) + { + dm2d1 += tmp_matrix[is]->get_value(mu, nu); + } + double dm2d2 = 2.0 * dm2d1; + // + if (isforce) + { + ftvnl_dphi_iat[0] += dm2d2 * lm.DHloc_fixedR_x[irr]; + ftvnl_dphi_iat[1] += dm2d2 * lm.DHloc_fixedR_y[irr]; + ftvnl_dphi_iat[2] += dm2d2 * lm.DHloc_fixedR_z[irr]; + } + if (isstress) + { + local_stvnl_dphi(0, 0) -= dm2d1 * lm.stvnl11[irr]; + local_stvnl_dphi(0, 1) -= dm2d1 * lm.stvnl12[irr]; + local_stvnl_dphi(0, 2) -= dm2d1 * lm.stvnl13[irr]; + local_stvnl_dphi(1, 1) -= dm2d1 * lm.stvnl22[irr]; + local_stvnl_dphi(1, 2) -= dm2d1 * lm.stvnl23[irr]; + local_stvnl_dphi(2, 2) -= dm2d1 * lm.stvnl33[irr]; + } + //} + ++local_total_irr; + ++irr; + } // end kk + } // end jj + } // end cb +#ifdef _OPENMP + if (isforce && num_threads > 1) + { + ftvnl_dphi(iat, 0) += ftvnl_dphi_iat[0]; + ftvnl_dphi(iat, 1) += ftvnl_dphi_iat[1]; + ftvnl_dphi(iat, 2) += ftvnl_dphi_iat[2]; + } +#endif + } // end iat +#ifdef _OPENMP +#pragma omp critical(cal_ftvnl_dphi_k_reduce) + { + total_irr += local_total_irr; + if (isstress) + { + stvnl_dphi(0, 0) += local_stvnl_dphi(0, 0); + stvnl_dphi(0, 1) += local_stvnl_dphi(0, 1); + stvnl_dphi(0, 2) += local_stvnl_dphi(0, 2); + stvnl_dphi(1, 1) += local_stvnl_dphi(1, 1); + stvnl_dphi(1, 2) += local_stvnl_dphi(1, 2); + stvnl_dphi(2, 2) += local_stvnl_dphi(2, 2); + } + } + } +#endif + assert(total_irr == pv.nnr); + + if (isstress) + { + StressTools::stress_fill(GlobalC::ucell.lat0, GlobalC::ucell.omega, stvnl_dphi); + } + + ModuleBase::timer::tick("Force_LCAO_k", "cal_ftvnl_dphi_k"); + return; +} diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp new file mode 100644 index 00000000000..cc0ae1d1c20 --- /dev/null +++ b/source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp @@ -0,0 +1,95 @@ +#include "FORCE_k.h" + +#include +#include + +#include "module_base/memory.h" +#include "module_base/parallel_reduce.h" +#include "module_base/timer.h" +#include "module_base/tool_threading.h" +#include "module_cell/module_neighbor/sltk_grid_driver.h" +#include "module_elecstate/cal_dm.h" +#include "module_elecstate/module_dm/cal_dm_psi.h" +#include "module_elecstate/elecstate_lcao.h" +#include "module_hamilt_pw/hamilt_pwdft/global.h" +#include "module_io/write_HS.h" + +#ifdef __DEEPKS +#include "module_hamilt_lcao/module_deepks/LCAO_deepks.h" +#endif + +#ifdef _OPENMP +#include +#endif + + +// calculate the force due to < phi | Vlocal | dphi > +void Force_LCAO_k::cal_fvl_dphi_k(const bool isforce, + const bool isstress, + LCAO_Matrix &lm, + const elecstate::Potential* pot_in, + ModuleBase::matrix& fvl_dphi, + ModuleBase::matrix& svl_dphi, + double** DM_R) +{ + ModuleBase::TITLE("Force_LCAO_k", "cal_fvl_dphi_k"); + ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); + + if (!isforce && !isstress) + { + ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); + return; + } + + assert(lm.DHloc_fixedR_x != NULL); + assert(lm.DHloc_fixedR_y != NULL); + assert(lm.DHloc_fixedR_z != NULL); + + int istep = 1; + + for (int is = 0; is < GlobalV::NSPIN; ++is) + { + GlobalV::CURRENT_SPIN = is; + + const double* vr_eff1 = pot_in->get_effective_v(GlobalV::CURRENT_SPIN); + const double* vofk_eff1 = nullptr; + if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) + { + vofk_eff1 = pot_in->get_effective_vofk(GlobalV::CURRENT_SPIN); + } + + //-------------------------------- + // Grid integration here. + //-------------------------------- + // fvl_dphi can not be set to zero here if Vna is used + if (isstress || isforce) + { + if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) + { + Gint_inout inout(DM_R, + is, + vr_eff1, + vofk_eff1, + isforce, + isstress, + &fvl_dphi, + &svl_dphi, + Gint_Tools::job_type::force_meta); + this->UHM->GK.cal_gint(&inout); + } + else + { + Gint_inout inout(DM_R, is, vr_eff1, isforce, isstress, &fvl_dphi, &svl_dphi, Gint_Tools::job_type::force); + this->UHM->GK.cal_gint(&inout); + } + } + } + + if (isstress) + { + StressTools::stress_fill(-1.0, GlobalC::ucell.omega, svl_dphi); + } + + ModuleBase::timer::tick("Force_LCAO_k", "cal_fvl_dphi_k"); + return; +} diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp index 6cfac40f2d7..65e3ebb290e 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/fvnl_dbeta_k.cpp @@ -1,3 +1,29 @@ +#include "FORCE_k.h" + +#include +#include + +#include "module_base/memory.h" +#include "module_base/parallel_reduce.h" +#include "module_base/timer.h" +#include "module_base/tool_threading.h" +#include "module_cell/module_neighbor/sltk_grid_driver.h" +#include "module_elecstate/cal_dm.h" +#include "module_elecstate/module_dm/cal_dm_psi.h" +#include "module_elecstate/elecstate_lcao.h" +#include "module_hamilt_pw/hamilt_pwdft/global.h" +#include "module_io/write_HS.h" + +#ifdef __DEEPKS +#include "module_hamilt_lcao/module_deepks/LCAO_deepks.h" +#endif + +#ifdef _OPENMP +#include +#endif + + +typedef std::tuple key_tuple; // must consider three-center H matrix. void Force_LCAO_k::cal_fvnl_dbeta_k(const elecstate::DensityMatrix, double>* DM, From 0469d942b60a2ce665d3ec8010daa63424c8018c Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 05:37:08 +0800 Subject: [PATCH 39/46] get rid of UHM in FORCE_k.cpp --- .../hamilt_lcaodft/FORCE_k.cpp | 92 +++++++++++++------ .../hamilt_lcaodft/FORCE_k.h | 3 +- .../hamilt_lcaodft/fvl_dphi_k.cpp | 5 +- 3 files changed, 71 insertions(+), 29 deletions(-) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp index a94cbd3d11a..08dcd5ccbf5 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp @@ -58,27 +58,61 @@ void Force_LCAO_k::ftable_k(const bool isforce, ModuleBase::TITLE("Force_LCAO_k", "ftable_k"); ModuleBase::timer::tick("Force_LCAO_k", "ftable_k"); - this->UHM = &uhm; - elecstate::DensityMatrix,double>* DM = dynamic_cast>*>(pelec)->get_DM(); - this->allocate_k(pv, lm, kv.nks, kv.kvec_d); + this->allocate_k( + pv, + lm, + uhm.genH, + kv.nks, + kv.kvec_d); // calculate the energy density matrix // and the force related to overlap matrix and energy density matrix. - this->cal_foverlap_k(isforce, isstress, ra, psi, loc, pv, lm, DM, foverlap, soverlap, pelec, kv.nks, kv); - - //DM->sum_DMR_spin(); - - this->cal_ftvnl_dphi_k(DM, pv, lm, isforce, isstress, ra, ftvnl_dphi, stvnl_dphi); - - // --------------------------------------- - // doing on the real space grid. - // --------------------------------------- - this->cal_fvl_dphi_k(isforce, isstress, lm, pelec->pot, fvl_dphi, svl_dphi, loc.DM_R); - - this->cal_fvnl_dbeta_k(DM, isforce, isstress, pv, fvnl_dbeta, svnl_dbeta); + this->cal_foverlap_k( + isforce, + isstress, + ra, + psi, + loc, + pv, + lm, + DM, + foverlap, + soverlap, + pelec, + kv.nks, + kv); + + this->cal_ftvnl_dphi_k( + DM, + pv, + lm, + isforce, + isstress, + ra, + ftvnl_dphi, + stvnl_dphi); + + // doing on the real space grid. + this->cal_fvl_dphi_k( + isforce, + isstress, + lm, + uhm.GK, + pelec->pot, + fvl_dphi, + svl_dphi, + loc.DM_R); + + this->cal_fvnl_dbeta_k( + DM, + isforce, + isstress, + pv, + fvnl_dbeta, + svnl_dbeta); #ifdef __DEEPKS if (GlobalV::deepks_scf) @@ -149,6 +183,7 @@ void Force_LCAO_k::ftable_k(const bool isforce, void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, LCAO_Matrix &lm, + LCAO_gen_fixedH &gen_h, const int& nks, const std::vector>& kvec_d) { @@ -211,7 +246,7 @@ void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, // calculate dS = //----------------------------- bool cal_deri = true; - this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, this->UHM->genH.LM->SlocR.data()); + gen_h.build_ST_new('S', cal_deri, GlobalC::ucell, gen_h.LM->SlocR.data()); //----------------------------------------- // (2) allocate for @@ -222,7 +257,8 @@ void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, // mohan add lm on 2024-03-31 const auto init_DHloc_fixedR_xyz = [this, nnr, &lm](int num_threads, int thread_id) { - int beg, len; + int beg=0; + int len=0; ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, nnr, 1024, beg, len); ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixedR_x + beg, len); ModuleBase::GlobalFunc::ZEROS(lm.DHloc_fixedR_y + beg, len); @@ -233,18 +269,18 @@ void Force_LCAO_k::allocate_k(const Parallel_Orbitals& pv, // calculate dT= in LCAO // calculate T + VNL(P1) in LCAO basis - this->UHM->genH.build_ST_new('T', cal_deri, GlobalC::ucell, this->UHM->genH.LM->Hloc_fixedR.data()); + gen_h.build_ST_new('T', cal_deri, GlobalC::ucell, gen_h.LM->Hloc_fixedR.data()); // calculate dVnl= in LCAO - this->UHM->genH.build_Nonlocal_mu_new(this->UHM->genH.LM->Hloc_fixed.data(), cal_deri); + gen_h.build_Nonlocal_mu_new(gen_h.LM->Hloc_fixed.data(), cal_deri); // calculate asynchronous S matrix to output for Hefei-NAMD if (INPUT.cal_syns) { cal_deri = false; - // this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, this->UHM->genH.LM->SlocR.data(), + // gen_h.build_ST_new('S', cal_deri, GlobalC::ucell, gen_h.LM->SlocR.data(), // INPUT.cal_syns); - this->UHM->genH.build_ST_new('S', + gen_h.build_ST_new('S', cal_deri, GlobalC::ucell, lm.SlocR.data(), @@ -372,11 +408,15 @@ void Force_LCAO_k::test( { for (int j = 0; j < GlobalV::NLOCAL; j++) { - if (std::abs(test[i * GlobalV::NLOCAL + j]) > 1.0e-5) - std::cout << std::setw(12) << test[i * GlobalV::NLOCAL + j]; - else - std::cout << std::setw(12) << "0"; - } + if (std::abs(test[i * GlobalV::NLOCAL + j]) > 1.0e-5) + { + std::cout << std::setw(12) << test[i * GlobalV::NLOCAL + j]; + } + else + { + std::cout << std::setw(12) << "0"; + } + } std::cout << std::endl; } delete[] test; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h index 2d9b3bc2c30..9b449db151d 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h @@ -20,7 +20,6 @@ class Force_LCAO_k : public Force_LCAO_gamma ~Force_LCAO_k(); private: - LCAO_Hamilt* UHM; // orthonormal force + contribution from T and VNL void ftable_k(const bool isforce, @@ -50,6 +49,7 @@ class Force_LCAO_k : public Force_LCAO_gamma // get the ds, dt, dvnl. void allocate_k(const Parallel_Orbitals& pv, LCAO_Matrix &lm, + LCAO_gen_fixedH &gen_h, const int& nks, const std::vector>& kvec_d); @@ -84,6 +84,7 @@ class Force_LCAO_k : public Force_LCAO_gamma void cal_fvl_dphi_k(const bool isforce, const bool isstress, LCAO_Matrix &lm, + Gint_k &gint_k, const elecstate::Potential* pot_in, ModuleBase::matrix& fvl_dphi, ModuleBase::matrix& svl_dphi, diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp index cc0ae1d1c20..f6d267c511b 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/fvl_dphi_k.cpp @@ -27,6 +27,7 @@ void Force_LCAO_k::cal_fvl_dphi_k(const bool isforce, const bool isstress, LCAO_Matrix &lm, + Gint_k &gint_k, const elecstate::Potential* pot_in, ModuleBase::matrix& fvl_dphi, ModuleBase::matrix& svl_dphi, @@ -75,12 +76,12 @@ void Force_LCAO_k::cal_fvl_dphi_k(const bool isforce, &fvl_dphi, &svl_dphi, Gint_Tools::job_type::force_meta); - this->UHM->GK.cal_gint(&inout); + gint_k.cal_gint(&inout); } else { Gint_inout inout(DM_R, is, vr_eff1, isforce, isstress, &fvl_dphi, &svl_dphi, Gint_Tools::job_type::force); - this->UHM->GK.cal_gint(&inout); + gint_k.cal_gint(&inout); } } } From 2eac6337646dfd6ddab452a8dd4877623516c387 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 06:40:57 +0800 Subject: [PATCH 40/46] cannot compile, but I have modified some files in order to get rid of Gint_k and Gint_Gamma in UHM --- source/module_elecstate/elecstate_lcao.cpp | 12 ++++----- source/module_elecstate/elecstate_lcao.h | 20 ++++++++++----- .../module_elecstate/elecstate_lcao_tddft.cpp | 7 +++--- .../module_elecstate/elecstate_lcao_tddft.h | 8 +++--- source/module_esolver/esolver_ks_lcao.h | 10 ++++++++ .../hamilt_lcaodft/FORCE_STRESS.cpp | 25 +++++++++++++------ .../hamilt_lcaodft/FORCE_STRESS.h | 11 ++++++-- .../hamilt_lcaodft/FORCE_gamma.cpp | 15 +++++------ .../hamilt_lcaodft/FORCE_gamma.h | 10 +++++--- .../hamilt_lcaodft/FORCE_gamma_vl.cpp | 18 ++++++++++--- .../hamilt_lcaodft/FORCE_k.cpp | 3 ++- .../hamilt_lcaodft/FORCE_k.h | 2 ++ .../hamilt_lcaodft/LCAO_hamilt.cpp | 6 +++-- .../hamilt_lcaodft/LCAO_hamilt.h | 20 ++++++++------- 14 files changed, 111 insertions(+), 56 deletions(-) diff --git a/source/module_elecstate/elecstate_lcao.cpp b/source/module_elecstate/elecstate_lcao.cpp index 6dd00a7f4f7..a2c9d8df8d3 100644 --- a/source/module_elecstate/elecstate_lcao.cpp +++ b/source/module_elecstate/elecstate_lcao.cpp @@ -142,9 +142,9 @@ void ElecStateLCAO>::psiToRho(const psi::Psiuhm->GK.transfer_DM2DtoGrid(this->DM->get_DMR_vector()); // transfer DM2D to DM_grid in gint + this->gint_k->transfer_DM2DtoGrid(this->DM->get_DMR_vector()); // transfer DM2D to DM_grid in gint Gint_inout inout(this->loc->DM_R, this->charge->rho, Gint_Tools::job_type::rho); - this->uhm->GK.cal_gint(&inout); + this->gint_k->cal_gint(&inout); if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) { @@ -153,7 +153,7 @@ void ElecStateLCAO>::psiToRho(const psi::Psicharge->kin_r[is], this->charge->nrxx); } Gint_inout inout1(this->loc->DM_R, this->charge->kin_r, Gint_Tools::job_type::tau); - this->uhm->GK.cal_gint(&inout1); + this->gint_k->cal_gint(&inout1); } this->charge->renormalize_rho(); @@ -216,9 +216,9 @@ void ElecStateLCAO::psiToRho(const psi::Psi& psi) // calculate the charge density on real space grid. //------------------------------------------------------------ ModuleBase::GlobalFunc::NOTE("Calculate the charge on real space grid!"); - this->uhm->GG.transfer_DM2DtoGrid(this->DM->get_DMR_vector()); // transfer DM2D to DM_grid in gint + this->gint_gamma->transfer_DM2DtoGrid(this->DM->get_DMR_vector()); // transfer DM2D to DM_grid in gint Gint_inout inout(this->loc->DM, this->charge->rho, Gint_Tools::job_type::rho); - this->uhm->GG.cal_gint(&inout); + this->gint_gamma->cal_gint(&inout); if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) { for (int is = 0; is < GlobalV::NSPIN; is++) @@ -226,7 +226,7 @@ void ElecStateLCAO::psiToRho(const psi::Psi& psi) ModuleBase::GlobalFunc::ZEROS(this->charge->kin_r[is], this->charge->nrxx); } Gint_inout inout1(this->loc->DM, this->charge->kin_r, Gint_Tools::job_type::tau); - this->uhm->GG.cal_gint(&inout1); + this->gint_gamma->cal_gint(&inout1); } this->charge->renormalize_rho(); diff --git a/source/module_elecstate/elecstate_lcao.h b/source/module_elecstate/elecstate_lcao.h index c47e297b027..977e0a2fdb3 100644 --- a/source/module_elecstate/elecstate_lcao.h +++ b/source/module_elecstate/elecstate_lcao.h @@ -2,7 +2,8 @@ #define ELECSTATELCAO_H #include "elecstate.h" -#include "module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h" +#include "module_hamilt_lcao/module_gint/gint_gamma.h" +#include "module_hamilt_lcao/module_gint/gint_k.h" #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h" #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.h" #include "module_elecstate/module_dm/density_matrix.h" @@ -18,6 +19,8 @@ class ElecStateLCAO : public ElecState const K_Vectors* klist_in , int nks_in, Local_Orbital_Charge* loc_in , + Gint_Gamma* gint_gamma_in, //mohan add 2024-04-01 + Gint_k* gint_k_in, //mohan add 2024-04-01 LCAO_Hamilt* uhm_in , Local_Orbital_wfc* lowf_in , ModulePW::PW_Basis* rhopw_in , @@ -25,15 +28,18 @@ class ElecStateLCAO : public ElecState { init_ks(chg_in, klist_in, nks_in, rhopw_in, bigpw_in); this->loc = loc_in; - this->uhm = uhm_in; + this->gint_gamma = gint_gamma_in; // mohan add 2024-04-01 + this->gint_k = gint_k_in; // mohan add 2024-04-01 this->lowf = lowf_in; this->classname = "ElecStateLCAO"; } virtual ~ElecStateLCAO() { - if (this->DM != nullptr) - delete this->DM; + if (this->DM != nullptr) + { + delete this->DM; + } } // void init(Charge* chg_in):charge(chg_in){} override; @@ -69,7 +75,9 @@ class ElecStateLCAO : public ElecState // void rhoBandK(const psi::Psi>& psi); Local_Orbital_Charge* loc = nullptr; - LCAO_Hamilt* uhm = nullptr; + Gint_Gamma* gint_gamma = nullptr; // mohan add 2024-04-01 + Gint_k* gint_k = nullptr; // mohan add 2024-04-01 + //LCAO_Hamilt* uhm = nullptr; // mohan modify 2024-04-01 Local_Orbital_wfc* lowf = nullptr; DensityMatrix* DM = nullptr; @@ -86,4 +94,4 @@ bool ElecStateLCAO::need_psi_grid = 1; } // namespace elecstate -#endif \ No newline at end of file +#endif diff --git a/source/module_elecstate/elecstate_lcao_tddft.cpp b/source/module_elecstate/elecstate_lcao_tddft.cpp index 3d3539fd1a9..cc0e7133e4e 100644 --- a/source/module_elecstate/elecstate_lcao_tddft.cpp +++ b/source/module_elecstate/elecstate_lcao_tddft.cpp @@ -63,9 +63,9 @@ void ElecStateLCAO_TDDFT::psiToRho_td(const psi::Psi>& psi) //------------------------------------------------------------ ModuleBase::GlobalFunc::NOTE("Calculate the charge on real space grid!"); - this->uhm->GK.transfer_DM2DtoGrid(this->DM->get_DMR_vector()); // transfer DM2D to DM_grid in gint + this->gint_k->transfer_DM2DtoGrid(this->DM->get_DMR_vector()); // transfer DM2D to DM_grid in gint Gint_inout inout(this->loc->DM_R, this->charge->rho, Gint_Tools::job_type::rho); // rho calculation - this->uhm->GK.cal_gint(&inout); + this->gint_k->cal_gint(&inout); this->charge->renormalize_rho(); @@ -110,5 +110,4 @@ void ElecStateLCAO_TDDFT::calculate_weights_td() } - -} // namespace elecstate \ No newline at end of file +} // namespace elecstate diff --git a/source/module_elecstate/elecstate_lcao_tddft.h b/source/module_elecstate/elecstate_lcao_tddft.h index f84a2c5ec21..140759e9d47 100644 --- a/source/module_elecstate/elecstate_lcao_tddft.h +++ b/source/module_elecstate/elecstate_lcao_tddft.h @@ -3,7 +3,7 @@ #include "elecstate.h" #include "elecstate_lcao.h" -#include "module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h" +#include "module_hamilt_lcao/module_gint/gint_k.h" #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h" #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.h" @@ -16,14 +16,14 @@ class ElecStateLCAO_TDDFT : public ElecStateLCAO> const K_Vectors* klist_in , int nks_in, Local_Orbital_Charge* loc_in , - LCAO_Hamilt* uhm_in , + Gint_k* gint_k_in, //mohan add 2024-04-01 Local_Orbital_wfc* lowf_in , ModulePW::PW_Basis* rhopw_in , ModulePW::PW_Basis_Big* bigpw_in ) { init_ks(chg_in, klist_in, nks_in, rhopw_in, bigpw_in); this->loc = loc_in; - this->uhm = uhm_in; + this->gint_k = gint_k_in; this->lowf = lowf_in; this->classname = "ElecStateLCAO_TDDFT"; } @@ -33,4 +33,4 @@ class ElecStateLCAO_TDDFT : public ElecStateLCAO> } // namespace elecstate -#endif \ No newline at end of file +#endif diff --git a/source/module_esolver/esolver_ks_lcao.h b/source/module_esolver/esolver_ks_lcao.h index 49d95cdfe55..c8c81ab203d 100644 --- a/source/module_esolver/esolver_ks_lcao.h +++ b/source/module_esolver/esolver_ks_lcao.h @@ -6,6 +6,10 @@ #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h" #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_wfc.h" #include "module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h" +// for grid integration +#include "module_hamilt_lcao/module_gint/gint_gamma.h" +#include "module_hamilt_lcao/module_gint/gint_k.h" + #include "module_basis/module_ao/ORB_control.h" #ifdef __EXX #include "module_ri/Mix_DMk_2D.h" @@ -75,6 +79,12 @@ namespace ModuleESolver // we will get rid of this class soon, don't use it, mohan 2024-03-28 LCAO_Hamilt UHM; + // used for k-dependent grid integration. + Gint_k GK; + + // used for gamma only algorithms. + Gint_Gamma GG; + // we will get rid of this class soon, don't use it, mohan 2024-03-28 LCAO_Matrix LM; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp index 4fa805e78de..e6944bd2cc7 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp @@ -34,8 +34,10 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, LCAO_Matrix &lm, const elecstate::ElecState* pelec, const psi::Psi* psi, - LCAO_Hamilt& uhm, - ModuleBase::matrix& fcs, + LCAO_Hamilt& uhm, + Gint_Gamma &gint_gamma, // mohan add 2024-04-01 + Gint_k &gint_k, // mohan add 2024-04-01 + ModuleBase::matrix& fcs, ModuleBase::matrix& scs, const Structure_Factor& sf, const K_Vectors& kv, @@ -138,7 +140,7 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, //-------------------------------------------------------- // implement four terms which needs integration //-------------------------------------------------------- - this->calForceStressIntegralPart(GlobalV::GAMMA_ONLY_LOCAL, + this->integral_part(GlobalV::GAMMA_ONLY_LOCAL, isforce, isstress, loc, @@ -158,9 +160,12 @@ void Force_Stress_LCAO::getForceStress(const bool isforce, svl_dphi, #endif uhm, + gint_gamma, + gint_k, pv, lm, kv); + // implement vdw force or stress here // Peize Lin add 2014-04-04, update 2021-03-09 // jiyy add 2019-05-18, update 2021-05-02 @@ -718,7 +723,7 @@ void Force_Stress_LCAO::calForcePwPart(ModuleBase::matrix& fvl_dvl, // overlap, kinetic, nonlocal pseudopotential, Local potential terms in force and stress template<> -void Force_Stress_LCAO::calForceStressIntegralPart( +void Force_Stress_LCAO::integral_part( const bool isGammaOnly, const bool isforce, const bool isstress, @@ -738,7 +743,9 @@ void Force_Stress_LCAO::calForceStressIntegralPart( #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt &uhm, + LCAO_Hamilt &uhm, + Gint_Gamma &gint_gamma, // mohan add 2024-04-01 + Gint_k &gint_k, // mohan add 2024-04-01 Parallel_Orbitals &pv, LCAO_Matrix &lm, const K_Vectors& kv) @@ -763,13 +770,14 @@ void Force_Stress_LCAO::calForceStressIntegralPart( svl_dphi, #endif uhm, + gint_gamma, lm); return; } template<> -void Force_Stress_LCAO>::calForceStressIntegralPart( +void Force_Stress_LCAO>::integral_part( const bool isGammaOnly, const bool isforce, const bool isstress, @@ -790,9 +798,11 @@ void Force_Stress_LCAO>::calForceStressIntegralPart( ModuleBase::matrix& svl_dphi, #endif LCAO_Hamilt &uhm, + Gint_Gamma &gint_gamma, + Gint_k &gint_k, Parallel_Orbitals &pv, LCAO_Matrix &lm, - const K_Vectors& kv) + const K_Vectors& kv) { flk.ftable_k(isforce, isstress, @@ -814,6 +824,7 @@ void Force_Stress_LCAO>::calForceStressIntegralPart( svl_dphi, #endif uhm, + gint_k, pv, lm, kv); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h index 8aaf0d4a387..1604fd76cc8 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.h @@ -13,6 +13,8 @@ #ifdef __EXX #include "module_ri/Exx_LRI.h" #endif +#include "module_hamilt_lcao/module_gint/gint_gamma.h" +#include "module_hamilt_lcao/module_gint/gint_k.h" template class Force_Stress_LCAO @@ -35,7 +37,9 @@ class Force_Stress_LCAO LCAO_Matrix &lm, const elecstate::ElecState* pelec, const psi::Psi* psi, - LCAO_Hamilt& uhm, + LCAO_Hamilt& uhm, + Gint_Gamma &gint_gamma, // mohan add 2024-04-01 + Gint_k &gint_k, // mohan add 2024-04-01 ModuleBase::matrix& fcs, ModuleBase::matrix& scs, const Structure_Factor& sf, @@ -68,7 +72,8 @@ class Force_Stress_LCAO ModulePW::PW_Basis* rhopw, const Structure_Factor& sf); - void calForceStressIntegralPart(const bool isGammaOnly, + void integral_part( + const bool isGammaOnly, const bool isforce, const bool isstress, Local_Orbital_Charge& loc, @@ -88,6 +93,8 @@ class Force_Stress_LCAO ModuleBase::matrix& svl_dphi, #endif LCAO_Hamilt &uhm, + Gint_Gamma &gint_gamma, + Gint_k &gint_k, Parallel_Orbitals &pv, LCAO_Matrix &lm, const K_Vectors& kv); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp index 2bc04ebd51b..0b5835446b1 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp @@ -39,6 +39,7 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, ModuleBase::matrix& svl_dphi, #endif LCAO_Hamilt &uhm, + Gint_Gamma &gint_gamma, LCAO_Matrix &lm) { ModuleBase::TITLE("Force_LCAO_gamma", "ftable"); @@ -50,11 +51,10 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, this->ParaV = DM->get_paraV_pointer(); //const Parallel_Orbitals* pv = loc.ParaV; - this->UHM = &uhm; // allocate DSloc_x, DSloc_y, DSloc_z // allocate DHloc_fixed_x, DHloc_fixed_y, DHloc_fixed_z - this->allocate_gamma(*this->ParaV, lm); + this->allocate_gamma(*this->ParaV, uhm.genH, lm); // calculate the 'energy density matrix' here. this->cal_foverlap(isforce, isstress, psid, pelec, lm, foverlap, soverlap); @@ -65,7 +65,7 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, this->cal_ftvnl_dphi(DM, lm, isforce, isstress, ftvnl_dphi, stvnl_dphi); this->cal_fvnl_dbeta(DM, isforce, isstress, fvnl_dbeta, svnl_dbeta); - this->cal_fvl_dphi(loc.DM, isforce, isstress, pelec->pot, fvl_dphi, svl_dphi); + this->cal_fvl_dphi(loc.DM, isforce, isstress, pelec->pot, gint_gamma, fvl_dphi, svl_dphi); // caoyu add for DeePKS #ifdef __DEEPKS @@ -128,6 +128,7 @@ void Force_LCAO_gamma::ftable_gamma(const bool isforce, void Force_LCAO_gamma::allocate_gamma( const Parallel_Orbitals &pv, + LCAO_gen_fixedH &gen_h, LCAO_Matrix &lm) { ModuleBase::TITLE("Force_LCAO_gamma", "allocate_gamma"); @@ -179,7 +180,7 @@ void Force_LCAO_gamma::allocate_gamma( } // calculate dS in LCAO basis // ModuleBase::timer::tick("Force_LCAO_gamma","build_S_new"); - this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, lm.Sloc.data()); + gen_h.build_ST_new('S', cal_deri, GlobalC::ucell, lm.Sloc.data()); // ModuleBase::timer::tick("Force_LCAO_gamma","build_S_new"); // calculate dT in LCAP @@ -196,12 +197,12 @@ void Force_LCAO_gamma::allocate_gamma( // calculate dT // calculate T + VNL(P1) in LCAO basis // ModuleBase::timer::tick("Force_LCAO_gamma","build_T_new"); - this->UHM->genH.build_ST_new('T', cal_deri, GlobalC::ucell, lm.Hloc_fixed.data()); + gen_h.build_ST_new('T', cal_deri, GlobalC::ucell, lm.Hloc_fixed.data()); // ModuleBase::timer::tick("Force_LCAO_gamma","build_T_new"); // test_gamma(lm.DHloc_fixed_x, "dHloc_fixed_x T part"); // ModuleBase::timer::tick("Force_LCAO_gamma","build_Nonlocal_mu"); - this->UHM->genH.build_Nonlocal_mu_new(lm.Hloc_fixed.data(), cal_deri); + gen_h.build_Nonlocal_mu_new(lm.Hloc_fixed.data(), cal_deri); // ModuleBase::timer::tick("Force_LCAO_gamma","build_Nonlocal_mu"); // test_gamma(lm.DHloc_fixed_x, "dHloc_fixed_x Vnl part"); @@ -212,7 +213,7 @@ void Force_LCAO_gamma::allocate_gamma( lm.zeros_HSgamma('S'); - this->UHM->genH.build_ST_new('S', cal_deri, GlobalC::ucell, + gen_h.build_ST_new('S', cal_deri, GlobalC::ucell, lm.Sloc.data(), INPUT.cal_syns, INPUT.dmax); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h index a3358382ee7..c8fe00c040c 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.h @@ -9,6 +9,7 @@ #include "module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.h" #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h" #include "module_psi/psi.h" +#include "module_hamilt_lcao/module_gint/gint_gamma.h" class Force_LCAO_gamma { @@ -21,8 +22,6 @@ class Force_LCAO_gamma private: - LCAO_Hamilt* UHM; - const Parallel_Orbitals* ParaV; elecstate::Potential* pot; @@ -46,14 +45,16 @@ class Force_LCAO_gamma #else ModuleBase::matrix& svl_dphi, #endif - LCAO_Hamilt& uhm, - LCAO_Matrix& lm); + LCAO_Hamilt& uhm, + Gint_Gamma &gint_gamma, + LCAO_Matrix& lm); // get the ds, dt, dvnl. void allocate_gamma( const Parallel_Orbitals& pv, + LCAO_gen_fixedH &gen_h, LCAO_Matrix &lm); void finish_ftable_gamma(LCAO_Matrix &lm); @@ -98,6 +99,7 @@ class Force_LCAO_gamma const bool isforce, const bool isstress, const elecstate::Potential* pot_in, + Gint_Gamma &gint_gamma, // mohan add 2024-04-01 ModuleBase::matrix& fvl_dphi, ModuleBase::matrix& svl_dphi); }; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_vl.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_vl.cpp index 6e97123cd07..5ce367c5682 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_vl.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma_vl.cpp @@ -7,6 +7,7 @@ void Force_LCAO_gamma::cal_fvl_dphi( const bool isforce, const bool isstress, const elecstate::Potential* pot_in, + Gint_Gamma &gint_gamma, ModuleBase::matrix& fvl_dphi, ModuleBase::matrix& svl_dphi) { @@ -27,13 +28,22 @@ void Force_LCAO_gamma::cal_fvl_dphi( if(XC_Functional::get_func_type()==3 || XC_Functional::get_func_type()==5) { - Gint_inout inout(DM_in, is, vr_eff1, vofk_eff1, isforce, isstress, &fvl_dphi, &svl_dphi, Gint_Tools::job_type::force_meta); - this->UHM->GG.cal_gint(&inout); + Gint_inout inout(DM_in, + is, + vr_eff1, + vofk_eff1, + isforce, + isstress, + &fvl_dphi, + &svl_dphi, + Gint_Tools::job_type::force_meta); + + gint_gamma.cal_gint(&inout); } else { Gint_inout inout(DM_in, is, vr_eff1, isforce, isstress, &fvl_dphi, &svl_dphi, Gint_Tools::job_type::force); - this->UHM->GG.cal_gint(&inout); + gint_gamma.cal_gint(&inout); } } @@ -50,4 +60,4 @@ void Force_LCAO_gamma::cal_fvl_dphi( } } ModuleBase::timer::tick("Force_LCAO_gamma","cal_fvl_dphi"); -} \ No newline at end of file +} diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp index 08dcd5ccbf5..98fd9379793 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp @@ -51,6 +51,7 @@ void Force_LCAO_k::ftable_k(const bool isforce, ModuleBase::matrix& svl_dphi, #endif LCAO_Hamilt &uhm, + Gint_k &gint_k, Parallel_Orbitals &pv, LCAO_Matrix &lm, const K_Vectors& kv) @@ -100,7 +101,7 @@ void Force_LCAO_k::ftable_k(const bool isforce, isforce, isstress, lm, - uhm.GK, + gint_k, pelec->pot, fvl_dphi, svl_dphi, diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h index 9b449db151d..9fa60e2ad5e 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.h @@ -9,6 +9,7 @@ #include "module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h" #include "module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.h" #include "module_hamilt_lcao/hamilt_lcaodft/local_orbital_charge.h" +#include "module_hamilt_lcao/module_gint/gint_k.h" class Force_LCAO_k : public Force_LCAO_gamma { @@ -42,6 +43,7 @@ class Force_LCAO_k : public Force_LCAO_gamma ModuleBase::matrix& svl_dphi, #endif LCAO_Hamilt &uhm, + Gint_k &gint_k, Parallel_Orbitals &pv, LCAO_Matrix &lm, const K_Vectors &kv); diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp index 419f1726e71..870525928af 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp @@ -33,6 +33,8 @@ LCAO_Hamilt::~LCAO_Hamilt() //-------------------------------------------- void LCAO_Hamilt::grid_prepare( const Grid_Technique& gt, + Gint_Gamma &gint_gamma, + Gint_k &gint_k, const ModulePW::PW_Basis& rhopw, const ModulePW::PW_Basis_Big& bigpw) { @@ -41,7 +43,7 @@ void LCAO_Hamilt::grid_prepare( if(GlobalV::GAMMA_ONLY_LOCAL) { - this->GG.prep_grid(gt, bigpw.nbx, bigpw.nby, bigpw.nbzp, bigpw.nbzp_start, + gint_gamma.prep_grid(gt, bigpw.nbx, bigpw.nby, bigpw.nbzp, bigpw.nbzp_start, rhopw.nxyz, bigpw.bx, bigpw.by, bigpw.bz, bigpw.bxyz, bigpw.nbxx, rhopw.ny, rhopw.nplane, rhopw.startz_current); @@ -49,7 +51,7 @@ void LCAO_Hamilt::grid_prepare( else // multiple k-points { // cal the grid integration of 'Vl' matrix for l-points algorithms. - this->GK.prep_grid(gt, bigpw.nbx, bigpw.nby, bigpw.nbzp, bigpw.nbzp_start, + gint_k.prep_grid(gt, bigpw.nbx, bigpw.nby, bigpw.nbzp, bigpw.nbzp_start, rhopw.nxyz, bigpw.bx, bigpw.by, bigpw.bz, bigpw.bxyz, bigpw.nbxx, rhopw.ny, rhopw.nplane, rhopw.startz_current); } diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h index 1422752c15d..5d12d8ca9b3 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h @@ -4,10 +4,13 @@ #include "module_base/global_function.h" #include "module_base/global_variable.h" #include "LCAO_gen_fixedH.h" -#include "module_hamilt_lcao/module_gint/gint_gamma.h" -#include "module_hamilt_lcao/module_gint/gint_k.h" #include "module_hamilt_lcao/module_hcontainer/hcontainer.h" #include "module_hamilt_general/hamilt.h" +#include "module_hamilt_lcao/module_gint/grid_technique.h" + +#include "module_hamilt_lcao/module_gint/gint_gamma.h" +#include "module_hamilt_lcao/module_gint/gint_k.h" + #ifdef __EXX #include @@ -21,7 +24,12 @@ class LCAO_Hamilt ~LCAO_Hamilt(); - void grid_prepare(const Grid_Technique& gt, const ModulePW::PW_Basis& rhopw, const ModulePW::PW_Basis_Big& bigpw); + void grid_prepare( + const Grid_Technique& gt, + Gint_Gamma &gint_gamma, + Gint_k &gint_k, + const ModulePW::PW_Basis& rhopw, + const ModulePW::PW_Basis_Big& bigpw); // jingan add 2021-6-4 void set_R_range_sparse(); @@ -74,12 +82,6 @@ class LCAO_Hamilt void destroy_dH_R_sparse(void); - // used for gamma only algorithms. - Gint_Gamma GG; - - // used for k-dependent grid integration. - Gint_k GK; - // use overlap matrix to generate fixed Hamiltonian LCAO_gen_fixedH genH; From 21d4637bf10bbfcfb9523f47e85bf39a1afae80e Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 06:59:22 +0800 Subject: [PATCH 41/46] keep updating, cannot run --- .../hamilt_lcaodft/LCAO_hamilt.cpp | 7 +- .../hamilt_lcaodft/LCAO_hamilt.h | 5 +- source/module_io/write_HS_R.cpp | 13 ++- source/module_io/write_HS_R.h | 4 +- source/module_io/write_Vxc.hpp | 98 +++++++++++++++---- 5 files changed, 99 insertions(+), 28 deletions(-) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp index 870525928af..f23ca3bc9c9 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp @@ -354,7 +354,10 @@ void LCAO_Hamilt::cal_HSR_sparse( clear_zero_elements(current_spin, sparse_threshold); } -void LCAO_Hamilt::cal_dH_sparse(const int ¤t_spin, const double &sparse_threshold) +void LCAO_Hamilt::cal_dH_sparse( + const int ¤t_spin, + const double &sparse_threshold, + Gint_k &gint_k) { ModuleBase::TITLE("LCAO_Hamilt","cal_dH_sparse"); @@ -388,7 +391,7 @@ void LCAO_Hamilt::cal_dH_sparse(const int ¤t_spin, const double &sparse_th delete[] this->LM->DHloc_fixedR_y; delete[] this->LM->DHloc_fixedR_z; - GK.cal_dvlocal_R_sparseMatrix(current_spin, sparse_threshold, this->LM); + gint_k.cal_dvlocal_R_sparseMatrix(current_spin, sparse_threshold, this->LM); } void LCAO_Hamilt::cal_STN_R_sparse_for_T(const double &sparse_threshold) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h index 5d12d8ca9b3..1d8775a5e17 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h @@ -78,7 +78,10 @@ class LCAO_Hamilt void destroy_TR_sparse(void); - void cal_dH_sparse(const int ¤t_spin, const double &sparse_threshold); + void cal_dH_sparse( + const int ¤t_spin, + const double &sparse_threshold, + Gint_k &gint_k); // mohan add 2024-04-01 void destroy_dH_R_sparse(void); diff --git a/source/module_io/write_HS_R.cpp b/source/module_io/write_HS_R.cpp index 81346621f78..a7576a79c37 100644 --- a/source/module_io/write_HS_R.cpp +++ b/source/module_io/write_HS_R.cpp @@ -59,6 +59,8 @@ void ModuleIO::output_HS_R(const int& istep, void ModuleIO::output_dH_R(const int& istep, const ModuleBase::matrix& v_eff, LCAO_Hamilt& UHM, + Gint_k& gint_k, // mohan add 2024-04-01 + LCAO_Matrix &lm, // mohan add 2024-04-01 const K_Vectors& kv, const bool& binary, const double& sparse_threshold) @@ -66,8 +68,8 @@ void ModuleIO::output_dH_R(const int& istep, ModuleBase::TITLE("ModuleIO","output_dH_R"); ModuleBase::timer::tick("ModuleIO","output_dH_R"); - UHM.LM->Hloc_fixedR.resize(UHM.LM->ParaV->nnr); - UHM.GK.allocate_pvdpR(); + lm.Hloc_fixedR.resize(lm.ParaV->nnr); + gint_k.allocate_pvdpR(); if(GlobalV::NSPIN==1||GlobalV::NSPIN==4) { UHM.cal_dH_sparse(0, sparse_threshold); @@ -91,7 +93,7 @@ void ModuleIO::output_dH_R(const int& istep, if(GlobalV::VL_IN_H) { Gint_inout inout(vr_eff1, GlobalV::CURRENT_SPIN, Gint_Tools::job_type::dvlocal); - UHM.GK.cal_gint(&inout); + gint_k.cal_gint(&inout); } } @@ -100,10 +102,11 @@ void ModuleIO::output_dH_R(const int& istep, } } - ModuleIO::save_dH_sparse(istep, *UHM.LM, sparse_threshold, binary); + // mohan update 2024-04-01 + ModuleIO::save_dH_sparse(istep, lm, sparse_threshold, binary); UHM.destroy_dH_R_sparse(); - UHM.GK.destroy_pvdpR(); + gint_k.destroy_pvdpR(); ModuleBase::timer::tick("ModuleIO","output_HS_R"); return; diff --git a/source/module_io/write_HS_R.h b/source/module_io/write_HS_R.h index 5389af2f912..738af1d3a7d 100644 --- a/source/module_io/write_HS_R.h +++ b/source/module_io/write_HS_R.h @@ -23,7 +23,9 @@ namespace ModuleIO void output_dH_R( const int &istep, const ModuleBase::matrix& v_eff, - LCAO_Hamilt &UHM, + LCAO_Hamilt &UHM, + Gint_k& gint_k, // mohan add 2024-04-01 + LCAO_Matrix &lm, // mohan add 2024-04-01 const K_Vectors& kv, const bool& binary = false, const double& sparse_threshold = 1e-10); diff --git a/source/module_io/write_Vxc.hpp b/source/module_io/write_Vxc.hpp index baa24ceef3e..047cac96342 100644 --- a/source/module_io/write_Vxc.hpp +++ b/source/module_io/write_Vxc.hpp @@ -4,16 +4,21 @@ #include "module_base/scalapack_connector.h" #include "module_base/parallel_reduce.h" template struct TGint; + template <> struct TGint { using type = Gint_Gamma; }; + template <> struct TGint> { using type = Gint_k; }; + + namespace ModuleIO { + inline void gint_vl(Gint_Gamma& gg, Gint_inout& io, LCAO_Matrix& lm) { gg.cal_vlocal(&io, &lm, false); }; inline void gint_vl(Gint_k& gk, Gint_inout& io, LCAO_Matrix& lm, ModuleBase::matrix& wg) { gk.cal_gint(&io); }; @@ -21,7 +26,7 @@ namespace ModuleIO { std::ofstream ofs; #ifdef __MPI - int dsize; + int dsize=0; MPI_Comm_size(MPI_COMM_WORLD, &dsize); p2d.set_block_size(pv.nb); p2d.set_proc_dim(dsize); @@ -37,8 +42,14 @@ namespace ModuleIO #endif } - std::vector> cVc(std::complex* V, std::complex* c, int nbasis, int nbands, const Parallel_Orbitals& pv, const Parallel_2D& p2d) - { + std::vector> cVc( + std::complex* V, + std::complex* c, + int nbasis, + int nbands, + const Parallel_Orbitals& pv, + const Parallel_2D& p2d) + { std::vector> Vc(pv.nloc_wfc, 0.0); char transa = 'N'; char transb = 'N'; @@ -60,7 +71,13 @@ namespace ModuleIO return cVc; } - std::vector cVc(double* V, double* c, int nbasis, int nbands, const Parallel_Orbitals& pv, const Parallel_2D& p2d) + std::vector cVc( + double* V, + double* c, + int nbasis, + int nbands, + const Parallel_Orbitals& pv, + const Parallel_2D& p2d) { std::vector Vc(pv.nloc_wfc, 0.0); char transa = 'N'; @@ -87,13 +104,23 @@ namespace ModuleIO inline double get_real(const double& d) { return d; } template - double all_band_energy(const int ik, const std::vector& mat_mo, const Parallel_2D& p2d, const ModuleBase::matrix& wg) + double all_band_energy( + const int ik, + const std::vector& mat_mo, + const Parallel_2D& p2d, + const ModuleBase::matrix& wg) { double e = 0.0; for (int i = 0;i < p2d.get_row_size();++i) - for (int j = 0;j < p2d.get_col_size();++j) - if (p2d.local2global_row(i) == p2d.local2global_col(j)) - e += get_real(mat_mo[j * p2d.get_row_size() + i]) * wg(ik, p2d.local2global_row(i)); + { + for (int j = 0;j < p2d.get_col_size();++j) + { + if (p2d.local2global_row(i) == p2d.local2global_col(j)) + { + e += get_real(mat_mo[j * p2d.get_row_size() + i]) * wg(ik, p2d.local2global_row(i)); + } + } + } Parallel_Reduce::reduce_all(e); return e; } @@ -106,20 +133,33 @@ namespace ModuleIO { gint = &uhm.GG; } + template <> void set_gint_pointer>(LCAO_Hamilt& uhm, typename TGint>::type*& gint) { gint = &uhm.GK; } - /// @brief write the Vxc matrix in KS orbital representation, usefull for GW calculation /// including terms: local/semi-local XC, EXX, DFTU template - void write_Vxc(int nspin, int nbasis, int drank, const psi::Psi& psi, const UnitCell& ucell, Structure_Factor& sf, - const ModulePW::PW_Basis& rho_basis, const ModulePW::PW_Basis& rhod_basis, const ModuleBase::matrix& vloc, - const Charge& chg, LCAO_Hamilt& uhm, LCAO_Matrix& lm, Local_Orbital_Charge& loc, - const K_Vectors& kv, const ModuleBase::matrix& wg, Grid_Driver& gd) + void write_Vxc( + int nspin, + int nbasis, + int drank, + const psi::Psi& psi, + const UnitCell& ucell, + Structure_Factor& sf, + const ModulePW::PW_Basis& rho_basis, + const ModulePW::PW_Basis& rhod_basis, + const ModuleBase::matrix& vloc, + const Charge& chg, + LCAO_Hamilt& uhm, + LCAO_Matrix& lm, + Local_Orbital_Charge& loc, + const K_Vectors& kv, + const ModuleBase::matrix& wg, + Grid_Driver& gd) { ModuleBase::TITLE("ModuleIO", "write_Vxc"); const Parallel_Orbitals* pv = lm.ParaV; @@ -150,7 +190,18 @@ namespace ModuleIO std::vector>*> vxcs_op_ao(nspin0); for (int is = 0;is < nspin0;++is) { - vxcs_op_ao[is] = new hamilt::Veff>(gint, &loc, &lm, kv.kvec_d, potxc, &vxcs_R_ao[is], &vxc_k_ao, &ucell, &gd, pv); + vxcs_op_ao[is] = new hamilt::Veff>( + gint, + &loc, + &lm, + kv.kvec_d, + potxc, + &vxcs_R_ao[is], + &vxc_k_ao, + &ucell, + &gd, + pv); + GlobalV::CURRENT_SPIN = is; //caution: Veff::contributeHR depends on GlobalV::CURRENT_SPIN vxcs_op_ao[is]->contributeHR(); } @@ -177,7 +228,10 @@ namespace ModuleIO int is = GlobalV::CURRENT_SPIN = kv.isk[ik]; dynamic_cast*>(vxcs_op_ao[is])->contributeHk(ik); #ifdef __EXX - if (GlobalC::exx_info.info_global.cal_exx) vexx_op_ao.contributeHk(ik); + if (GlobalC::exx_info.info_global.cal_exx) + { + vexx_op_ao.contributeHk(ik); + } // ======test======= // ModuleBase::GlobalFunc::ZEROS(test_vexxonly_k_ao.data(), pv->nloc); // if (GlobalC::exx_info.info_global.cal_exx) test_vexxonly_op_ao.contributeHk(ik); @@ -185,8 +239,11 @@ namespace ModuleIO // exx_energy += all_band_energy(ik, test_vexxonly_k_mo, p2d, wg); // ======test======= #endif - if (GlobalV::dft_plus_u) vdftu_op_ao.contributeHk(ik); - std::vector vxc_k_mo = cVc(vxc_k_ao.data(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d); + if (GlobalV::dft_plus_u) + { + vdftu_op_ao.contributeHk(ik); + } + std::vector vxc_k_mo = cVc(vxc_k_ao.data(), &psi(ik, 0, 0), nbasis, nbands, *pv, p2d); // write ModuleIO::save_mat(-1, vxc_k_mo.data(), nbands, false/*binary*/, GlobalV::out_ndigits, true/*triangle*/, false/*append*/, @@ -204,6 +261,9 @@ namespace ModuleIO // std::cout << "exx_energy: " << 0.5 * exx_energy << std::endl; // ======test======= delete potxc; - for (int is = 0;is < nspin0;++is) delete vxcs_op_ao[is]; + for (int is = 0;is < nspin0;++is) + { + delete vxcs_op_ao[is]; + } } -} \ No newline at end of file +} From 3e018109fde1f284cf93bb13aa31f3efc4d5527e Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 07:48:09 +0800 Subject: [PATCH 42/46] update write_Vxc, cannot run yet --- source/module_esolver/esolver_ks_lcao.cpp | 25 ++++++-- source/module_io/write_Vxc.hpp | 77 +++++++++++++++++------ 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index 3379777f905..fde064b162f 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -665,7 +665,7 @@ void ESolver_KS_LCAO::iter_init(const int istep, const int iter) // update Gint_K if (!GlobalV::GAMMA_ONLY_LOCAL) { - this->UHM.GK.renew(); + this->GK.renew(); } // update real space Hamiltonian this->p_hamilt->refresh(); @@ -803,7 +803,7 @@ void ESolver_KS_LCAO::update_pot(const int istep, const int iter) { if (!GlobalV::GAMMA_ONLY_LOCAL && hsolver::HSolverLCAO::out_mat_hs[0]) { - this->UHM.GK.renew(true); + this->GK.renew(true); } for (int ik = 0; ik < this->kv.nks; ++ik) { @@ -1016,9 +1016,24 @@ void ESolver_KS_LCAO::after_scf(const int istep) bool out_exc = true; // tmp, add parameter! if (GlobalV::out_mat_xc) { - ModuleIO::write_Vxc(GlobalV::NSPIN, GlobalV::NLOCAL, GlobalV::DRANK, - *this->psi, GlobalC::ucell, this->sf, *this->pw_rho, *this->pw_rhod, GlobalC::ppcell.vloc, - *this->pelec->charge, this->UHM, this->LM, this->LOC, this->kv, this->pelec->wg, GlobalC::GridD); + ModuleIO::write_Vxc( + GlobalV::NSPIN, + GlobalV::NLOCAL, + GlobalV::DRANK, + *this->psi, + GlobalC::ucell, + this->sf, + *this->pw_rho, + *this->pw_rhod, + GlobalC::ppcell.vloc, + *this->pelec->charge, + this->GG, + this->GK, + this->LM, + this->LOC, + this->kv, + this->pelec->wg, + GlobalC::GridD); } #ifdef __EXX diff --git a/source/module_io/write_Vxc.hpp b/source/module_io/write_Vxc.hpp index 047cac96342..b9f5c435b96 100644 --- a/source/module_io/write_Vxc.hpp +++ b/source/module_io/write_Vxc.hpp @@ -3,6 +3,7 @@ #include "module_hamilt_lcao/hamilt_lcaodft/operator_lcao/op_dftu_lcao.h" #include "module_base/scalapack_connector.h" #include "module_base/parallel_reduce.h" + template struct TGint; template <> @@ -19,8 +20,22 @@ struct TGint> { namespace ModuleIO { - inline void gint_vl(Gint_Gamma& gg, Gint_inout& io, LCAO_Matrix& lm) { gg.cal_vlocal(&io, &lm, false); }; - inline void gint_vl(Gint_k& gk, Gint_inout& io, LCAO_Matrix& lm, ModuleBase::matrix& wg) { gk.cal_gint(&io); }; + inline void gint_vl( + Gint_Gamma& gg, + Gint_inout& io, + LCAO_Matrix& lm) + { + gg.cal_vlocal(&io, &lm, false); + }; + + inline void gint_vl( + Gint_k& gk, + Gint_inout& io, + LCAO_Matrix& lm, + ModuleBase::matrix& wg) + { + gk.cal_gint(&io); + }; void set_para2d_MO(const Parallel_Orbitals& pv, const int nbands, Parallel_2D& p2d) { @@ -57,16 +72,20 @@ namespace ModuleIO const std::complex beta(0.0, 0.0); #ifdef __MPI const int i1 = 1; - pzgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &i1, &i1, pv.desc, c, &i1, &i1, pv.desc_wfc, &beta, Vc.data(), &i1, &i1, pv.desc_wfc); + pzgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &i1, + &i1, pv.desc, c, &i1, &i1, pv.desc_wfc, &beta, Vc.data(), &i1, &i1, pv.desc_wfc); #else - zgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &nbasis, c, &nbasis, &beta, Vc.data(), &nbasis); + zgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &nbasis, + c, &nbasis, &beta, Vc.data(), &nbasis); #endif std::vector> cVc(p2d.nloc, 0.0); transa = 'C'; #ifdef __MPI - pzgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, &i1, &i1, pv.desc_wfc, Vc.data(), &i1, &i1, pv.desc_wfc, &beta, cVc.data(), &i1, &i1, p2d.desc); + pzgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, &i1, &i1, + pv.desc_wfc, Vc.data(), &i1, &i1, pv.desc_wfc, &beta, cVc.data(), &i1, &i1, p2d.desc); #else - zgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, &nbasis, Vc.data(), &nbasis, &beta, cVc.data(), &nbasis); + zgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, &nbasis, + Vc.data(), &nbasis, &beta, cVc.data(), &nbasis); #endif return cVc; } @@ -86,21 +105,26 @@ namespace ModuleIO const double beta = 0.0; #ifdef __MPI const int i1 = 1; - pdgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &i1, &i1, pv.desc, c, &i1, &i1, pv.desc_wfc, &beta, Vc.data(), &i1, &i1, pv.desc_wfc); + pdgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &i1, + &i1, pv.desc, c, &i1, &i1, pv.desc_wfc, &beta, Vc.data(), &i1, &i1, pv.desc_wfc); #else - dgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &nbasis, c, &nbasis, &beta, Vc.data(), &nbasis); + dgemm_(&transa, &transb, &nbasis, &nbands, &nbasis, &alpha, V, &nbasis, + c, &nbasis, &beta, Vc.data(), &nbasis); #endif std::vector cVc(p2d.nloc, 0.0); transa = 'T'; #ifdef __MPI - pdgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, &i1, &i1, pv.desc_wfc, Vc.data(), &i1, &i1, pv.desc_wfc, &beta, cVc.data(), &i1, &i1, p2d.desc); + pdgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, &i1, &i1, + pv.desc_wfc, Vc.data(), &i1, &i1, pv.desc_wfc, &beta, cVc.data(), &i1, &i1, p2d.desc); #else - dgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, &nbasis, Vc.data(), &nbasis, &beta, cVc.data(), &nbasis); + dgemm_(&transa, &transb, &nbands, &nbands, &nbasis, &alpha, c, + &nbasis, Vc.data(), &nbasis, &beta, cVc.data(), &nbasis); #endif return cVc; } inline double get_real(const std::complex& c) { return c.real(); } + inline double get_real(const double& d) { return d; } template @@ -125,19 +149,31 @@ namespace ModuleIO return e; } + // mohan update 2024-04-01 template - void set_gint_pointer(LCAO_Hamilt& uhm, typename TGint::type*& gint); + void set_gint_pointer( + Gint_Gamma &gint_gamma, + Gint_k &gint_k, + typename TGint::type*& gint); - template <> - void set_gint_pointer(LCAO_Hamilt& uhm, typename TGint::type*& gint) - { - gint = &uhm.GG; + // mohan update 2024-04-01 + template <> + void set_gint_pointer( + Gint_Gamma &gint_gamma, + Gint_k &gint_k, + typename TGint::type*& gint) + { + gint = &gint_gamma; } + // mohan update 2024-04-01 template <> - void set_gint_pointer>(LCAO_Hamilt& uhm, typename TGint>::type*& gint) + void set_gint_pointer>( + Gint_Gamma &gint_gamma, + Gint_k &gint_k, + typename TGint>::type*& gint) { - gint = &uhm.GK; + gint = &gint_k; } /// @brief write the Vxc matrix in KS orbital representation, usefull for GW calculation @@ -154,7 +190,8 @@ namespace ModuleIO const ModulePW::PW_Basis& rhod_basis, const ModuleBase::matrix& vloc, const Charge& chg, - LCAO_Hamilt& uhm, + Gint_Gamma &gint_gamma, // mohan add 2024-04-01 + Gint_k &gint_k, // mohan add 2024-04-01 LCAO_Matrix& lm, Local_Orbital_Charge& loc, const K_Vectors& kv, @@ -186,7 +223,9 @@ namespace ModuleIO // 3. allocate operators and contribute HR // op (corresponding to hR) typename TGint::type* gint = nullptr; - set_gint_pointer(uhm, gint); + + set_gint_pointer(gint_gamma, gint_k, gint); + std::vector>*> vxcs_op_ao(nspin0); for (int is = 0;is < nspin0;++is) { From be3b80ab98e05645be8650d6ce842bdc0da83bcf Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 10:17:44 +0800 Subject: [PATCH 43/46] keep updating gint_gamma and gint_k --- source/module_elecstate/elecstate_lcao.cpp | 4 ++ source/module_esolver/esolver_ks_lcao.cpp | 13 ++++++- .../module_esolver/esolver_ks_lcao_elec.cpp | 25 ++++++++----- .../module_esolver/esolver_ks_lcao_tddft.cpp | 6 +-- source/module_io/output_mat_sparse.cpp | 37 +++++++++++++------ source/module_io/output_mat_sparse.h | 6 ++- source/module_io/write_HS_R.cpp | 6 ++- 7 files changed, 68 insertions(+), 29 deletions(-) diff --git a/source/module_elecstate/elecstate_lcao.cpp b/source/module_elecstate/elecstate_lcao.cpp index a2c9d8df8d3..a70153fe687 100644 --- a/source/module_elecstate/elecstate_lcao.cpp +++ b/source/module_elecstate/elecstate_lcao.cpp @@ -216,9 +216,13 @@ void ElecStateLCAO::psiToRho(const psi::Psi& psi) // calculate the charge density on real space grid. //------------------------------------------------------------ ModuleBase::GlobalFunc::NOTE("Calculate the charge on real space grid!"); + this->gint_gamma->transfer_DM2DtoGrid(this->DM->get_DMR_vector()); // transfer DM2D to DM_grid in gint + Gint_inout inout(this->loc->DM, this->charge->rho, Gint_Tools::job_type::rho); + this->gint_gamma->cal_gint(&inout); + if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) { for (int is = 0; is < GlobalV::NSPIN; is++) diff --git a/source/module_esolver/esolver_ks_lcao.cpp b/source/module_esolver/esolver_ks_lcao.cpp index fde064b162f..d5c7a9ae0e1 100644 --- a/source/module_esolver/esolver_ks_lcao.cpp +++ b/source/module_esolver/esolver_ks_lcao.cpp @@ -111,10 +111,13 @@ void ESolver_KS_LCAO::init(Input& inp, UnitCell& ucell) // autoset nbands in ElecState, it should before basis_init (for Psi 2d divid) if (this->pelec == nullptr) { - this->pelec = new elecstate::ElecStateLCAO(&(this->chr), + this->pelec = new elecstate::ElecStateLCAO( + &(this->chr), &(this->kv), this->kv.nks, &(this->LOC), + &(this->GG), // mohan add 2024-04-01 + &(this->GK), // mohan add 2024-04-01 &(this->UHM), &(this->LOWF), this->pw_rho, @@ -255,6 +258,8 @@ void ESolver_KS_LCAO::init_after_vc(Input& inp, UnitCell& ucell) &(this->kv), this->kv.nks, &(this->LOC), + &(this->GG), // mohan add 2024-04-01 + &(this->GK), // mohan add 2024-04-01 &(this->UHM), &(this->LOWF), this->pw_rho, @@ -313,6 +318,8 @@ void ESolver_KS_LCAO::cal_force(ModuleBase::matrix& force) this->pelec, this->psi, this->UHM, + this->GG, // mohan add 2024-04-01 + this->GK, // mohan add 2024-04-01 force, this->scs, this->sf, @@ -1196,7 +1203,8 @@ ModuleIO::Output_DM1 ESolver_KS_LCAO::create_Output_DM1(int istep) template ModuleIO::Output_Mat_Sparse ESolver_KS_LCAO::create_Output_Mat_Sparse(int istep) { - return ModuleIO::Output_Mat_Sparse(hsolver::HSolverLCAO::out_mat_hsR, + return ModuleIO::Output_Mat_Sparse( + hsolver::HSolverLCAO::out_mat_hsR, hsolver::HSolverLCAO::out_mat_dh, hsolver::HSolverLCAO::out_mat_t, INPUT.out_mat_r, @@ -1204,6 +1212,7 @@ ModuleIO::Output_Mat_Sparse ESolver_KS_LCAO::create_Output_Mat_Spars this->pelec->pot->get_effective_v(), *this->LOWF.ParaV, this->UHM, + this->GK, // mohan add 2024-04-01 this->LM, this->kv, this->p_hamilt); diff --git a/source/module_esolver/esolver_ks_lcao_elec.cpp b/source/module_esolver/esolver_ks_lcao_elec.cpp index 57a0bcd3eac..290feed8b30 100644 --- a/source/module_esolver/esolver_ks_lcao_elec.cpp +++ b/source/module_esolver/esolver_ks_lcao_elec.cpp @@ -126,7 +126,12 @@ void ESolver_KS_LCAO::beforesolver(const int istep) } // prepare grid in Gint - this->UHM.grid_prepare(this->GridT, *this->pw_rho, *this->pw_big); + this->UHM.grid_prepare( + this->GridT, + this->GG, + this->GK, + *this->pw_rho, + *this->pw_big); // init Hamiltonian if (this->p_hamilt != nullptr) @@ -137,8 +142,8 @@ void ESolver_KS_LCAO::beforesolver(const int istep) if (this->p_hamilt == nullptr) { elecstate::DensityMatrix* DM = dynamic_cast*>(this->pelec)->get_DM(); - this->p_hamilt = new hamilt::HamiltLCAO(GlobalV::GAMMA_ONLY_LOCAL ? &(this->UHM.GG) : nullptr, - GlobalV::GAMMA_ONLY_LOCAL ? nullptr : &(this->UHM.GK), + this->p_hamilt = new hamilt::HamiltLCAO(GlobalV::GAMMA_ONLY_LOCAL ? &(this->GG) : nullptr, + GlobalV::GAMMA_ONLY_LOCAL ? nullptr : &(this->GK), &(this->UHM.genH), &(this->LM), &(this->LOC), @@ -194,7 +199,7 @@ void ESolver_KS_LCAO::beforesolver(const int istep) if (GlobalV::GAMMA_ONLY_LOCAL) { Gint_inout inout(this->LOC.DM, this->pelec->charge->rho, Gint_Tools::job_type::rho); - this->UHM.GG.cal_gint(&inout); + this->GG.cal_gint(&inout); if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) { for (int is = 0; is < GlobalV::NSPIN; is++) @@ -202,13 +207,13 @@ void ESolver_KS_LCAO::beforesolver(const int istep) ModuleBase::GlobalFunc::ZEROS(this->pelec->charge->kin_r[0], this->pw_rho->nrxx); } Gint_inout inout1(this->LOC.DM, this->pelec->charge->kin_r, Gint_Tools::job_type::tau); - this->UHM.GG.cal_gint(&inout1); + this->GG.cal_gint(&inout1); } } else { Gint_inout inout(this->LOC.DM_R, this->pelec->charge->rho, Gint_Tools::job_type::rho); - this->UHM.GK.cal_gint(&inout); + this->GK.cal_gint(&inout); if (XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) { for (int is = 0; is < GlobalV::NSPIN; is++) @@ -216,7 +221,7 @@ void ESolver_KS_LCAO::beforesolver(const int istep) ModuleBase::GlobalFunc::ZEROS(this->pelec->charge->kin_r[0], this->pw_rho->nrxx); } Gint_inout inout1(this->LOC.DM_R, this->pelec->charge->kin_r, Gint_Tools::job_type::tau); - this->UHM.GK.cal_gint(&inout1); + this->GK.cal_gint(&inout1); } } @@ -389,7 +394,7 @@ void ESolver_KS_LCAO::others(const int istep) else if (GlobalV::CALCULATION == "get_pchg") { IState_Charge ISC(this->psi, this->LOC); - ISC.begin(this->UHM.GG, + ISC.begin(this->GG, this->pelec, this->pw_rho, this->pw_big, @@ -411,7 +416,7 @@ void ESolver_KS_LCAO::others(const int istep) this->pw_wfc, this->pw_big, this->LOWF, - this->UHM.GG, + this->GG, INPUT.out_wfc_pw, this->wf.out_wfc_r, this->kv, @@ -427,7 +432,7 @@ void ESolver_KS_LCAO::others(const int istep) this->pw_wfc, this->pw_big, this->LOWF, - this->UHM.GK, + this->GK, INPUT.out_wfc_pw, this->wf.out_wfc_r, this->kv, diff --git a/source/module_esolver/esolver_ks_lcao_tddft.cpp b/source/module_esolver/esolver_ks_lcao_tddft.cpp index a9bd2e44313..182242eb6a3 100644 --- a/source/module_esolver/esolver_ks_lcao_tddft.cpp +++ b/source/module_esolver/esolver_ks_lcao_tddft.cpp @@ -79,8 +79,8 @@ void ESolver_KS_LCAO_TDDFT::init(Input& inp, UnitCell& ucell) this->pelec = new elecstate::ElecStateLCAO_TDDFT(&(this->chr), &(kv), kv.nks, - &(this->LOC), - &(this->UHM), + &(this->LOC), + &(this->GK), // mohan add 2024-04-01 &(this->LOWF), this->pw_rho, pw_big); @@ -264,7 +264,7 @@ void ESolver_KS_LCAO_TDDFT::update_pot(const int istep, const int iter) { if (!GlobalV::GAMMA_ONLY_LOCAL) { - this->UHM.GK.renew(true); + this->GK.renew(true); } for (int ik = 0; ik < kv.nks; ++ik) { diff --git a/source/module_io/output_mat_sparse.cpp b/source/module_io/output_mat_sparse.cpp index 693528a43ee..0c82f71a350 100644 --- a/source/module_io/output_mat_sparse.cpp +++ b/source/module_io/output_mat_sparse.cpp @@ -7,7 +7,8 @@ namespace ModuleIO { template - Output_Mat_Sparse::Output_Mat_Sparse(int out_mat_hsR, + Output_Mat_Sparse::Output_Mat_Sparse( + int out_mat_hsR, int out_mat_dh, int out_mat_t, int out_mat_r, @@ -15,6 +16,7 @@ namespace ModuleIO const ModuleBase::matrix& v_eff, const Parallel_Orbitals& pv, LCAO_Hamilt& UHM, + Gint_k& gint_k, // mohan add 2024-04-01 LCAO_Matrix& LM, const K_Vectors& kv, hamilt::Hamilt* p_ham) @@ -26,15 +28,21 @@ namespace ModuleIO _v_eff(v_eff), _pv(pv), _UHM(UHM), + _gint_k(gint_k), // mohan add 2024-04-01 _LM(LM), _kv(kv), _p_ham(p_ham) { - } - template<> - void Output_Mat_Sparse::write() {} - template<> - void Output_Mat_Sparse>::write() +} + +template<> +void Output_Mat_Sparse::write(void) +{ +} + + +template<> +void Output_Mat_Sparse>::write(void) { if (_out_mat_hsR) { @@ -48,8 +56,14 @@ namespace ModuleIO if (_out_mat_dh) { - output_dH_R(_istep, this->_v_eff, this->_UHM, _kv); // LiuXh add 2019-07-15 - } + output_dH_R( + _istep, + this->_v_eff, + this->_UHM, + this->_gint_k, // mohan add 2024-04-01 + this->_LM, + _kv); // LiuXh add 2019-07-15 + } // add by jingan for out r_R matrix 2019.8.14 if (_out_mat_r) @@ -67,6 +81,7 @@ namespace ModuleIO } } - template class Output_Mat_Sparse; - template class Output_Mat_Sparse>; -} // namespace ModuleIO \ No newline at end of file +template class Output_Mat_Sparse; +template class Output_Mat_Sparse>; + +} // namespace ModuleIO diff --git a/source/module_io/output_mat_sparse.h b/source/module_io/output_mat_sparse.h index 4d5bcde5c26..8012b108bca 100644 --- a/source/module_io/output_mat_sparse.h +++ b/source/module_io/output_mat_sparse.h @@ -4,6 +4,7 @@ #include "module_basis/module_ao/parallel_orbitals.h" #include "module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h" #include "module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.h" +#include "module_hamilt_lcao/module_gint/gint_k.h" #include "module_hsolver/hsolver_lcao.h" #include "output_interface.h" @@ -22,9 +23,11 @@ namespace ModuleIO const ModuleBase::matrix& v_eff, const Parallel_Orbitals& pv, LCAO_Hamilt& UHM, + Gint_k &gint_k, // mohan add 2024-04-01 LCAO_Matrix& LM, const K_Vectors& kv, hamilt::Hamilt* p_ham); + void write() override; private: @@ -36,10 +39,11 @@ namespace ModuleIO const ModuleBase::matrix& _v_eff; const Parallel_Orbitals& _pv; LCAO_Hamilt& _UHM; + Gint_k& _gint_k; // mohan add 2024-04-01 LCAO_Matrix& _LM; const K_Vectors& _kv; hamilt::Hamilt* _p_ham; }; } // namespace ModuleIO -#endif // OUTPUT_MAT_SPARSE_H \ No newline at end of file +#endif // OUTPUT_MAT_SPARSE_H diff --git a/source/module_io/write_HS_R.cpp b/source/module_io/write_HS_R.cpp index a7576a79c37..76bf11c7cae 100644 --- a/source/module_io/write_HS_R.cpp +++ b/source/module_io/write_HS_R.cpp @@ -72,7 +72,9 @@ void ModuleIO::output_dH_R(const int& istep, gint_k.allocate_pvdpR(); if(GlobalV::NSPIN==1||GlobalV::NSPIN==4) { - UHM.cal_dH_sparse(0, sparse_threshold); + // mohan add 2024-04-01 + assert(GlobalV::CURRENT_SPIN==0); + UHM.cal_dH_sparse(GlobalV::CURRENT_SPIN, sparse_threshold, gint_k); } else if(GlobalV::NSPIN==2) { @@ -97,7 +99,7 @@ void ModuleIO::output_dH_R(const int& istep, } } - UHM.cal_dH_sparse(GlobalV::CURRENT_SPIN, sparse_threshold); + UHM.cal_dH_sparse(GlobalV::CURRENT_SPIN, sparse_threshold, gint_k); } } } From 37066e53187070b0a448dac72e617d8ed4fdff58 Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 10:32:02 +0800 Subject: [PATCH 44/46] update LCAO_matrix.cpp --- .../hamilt_lcaodft/LCAO_matrix.cpp | 158 +++++++++--------- 1 file changed, 83 insertions(+), 75 deletions(-) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.cpp index b394ccd032f..38bf7b138f3 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_matrix.cpp @@ -45,11 +45,13 @@ void LCAO_Matrix::divide_HS_in_frag(const bool isGamma, Parallel_Orbitals &pv, c { na[it] = GlobalC::ucell.atoms[it].na; } + GlobalC::ld.init(GlobalC::ORB, GlobalC::ucell.nat, GlobalC::ucell.ntype, pv, na); + if(GlobalV::deepks_scf) { if(isGamma) @@ -72,7 +74,11 @@ void LCAO_Matrix::allocate_HS_gamma(const long &nloc) ModuleBase::TITLE("LCAO_Matrix","allocate_HS_gamma"); ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"nloc",nloc); - if(nloc==0) return; //mohan fix bug 2012-05-25 + + if(nloc==0) + { + return; + } // because we initilize in the constructor function // with dimension '1', so here we reconstruct these @@ -95,7 +101,11 @@ void LCAO_Matrix::allocate_HS_k(const long &nloc) ModuleBase::TITLE("LCAO_Matrix","allocate_HS_k"); ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"nloc",nloc); - if(nloc==0) return; //mohan fix bug 2012-05-25 + + if(nloc==0) + { + return; //mohan fix bug 2012-05-25 + } // because we initilize in the constructor function // with dimension '1', so here we reconstruct these @@ -116,19 +126,33 @@ void LCAO_Matrix::allocate_HS_R(const int &nnR) if(GlobalV::NSPIN!=4) { this->SlocR.resize(nnR); - if(GlobalV::CALCULATION!="get_S") this->Hloc_fixedR.resize(nnR); + if(GlobalV::CALCULATION!="get_S") + { + this->Hloc_fixedR.resize(nnR); + } ModuleBase::GlobalFunc::ZEROS(SlocR.data(), nnR); - if(GlobalV::CALCULATION!="get_S") ModuleBase::GlobalFunc::ZEROS(Hloc_fixedR.data(), nnR); + + if(GlobalV::CALCULATION!="get_S") + { + ModuleBase::GlobalFunc::ZEROS(Hloc_fixedR.data(), nnR); + } } else { this->SlocR_soc.resize(nnR); - if(GlobalV::CALCULATION!="get_S") this->Hloc_fixedR_soc.resize(nnR); + if(GlobalV::CALCULATION!="get_S") + { + this->Hloc_fixedR_soc.resize(nnR); + } ModuleBase::GlobalFunc::ZEROS(SlocR_soc.data(), nnR); - if(GlobalV::CALCULATION!="get_S") ModuleBase::GlobalFunc::ZEROS(Hloc_fixedR_soc.data(), nnR); - + + if(GlobalV::CALCULATION!="get_S") + { + ModuleBase::GlobalFunc::ZEROS(Hloc_fixedR_soc.data(), nnR); + } + } return; @@ -139,16 +163,26 @@ void LCAO_Matrix::set_HSgamma(const int& iw1_all, const int& iw2_all, const doub LCAO_Matrix::set_mat2d(iw1_all, iw2_all, v, *this->ParaV, HSloc); return; } + + void LCAO_Matrix::set_HSk(const int& iw1_all, const int& iw2_all, const std::complex& v, const char& dtype, const int spin) { - if (dtype=='S')//overlap Hamiltonian. - LCAO_Matrix::set_mat2d>(iw1_all, iw2_all, v, *this->ParaV, this->Sloc2.data()); - else if (dtype=='T' || dtype=='N')// kinetic and nonlocal Hamiltonian. - LCAO_Matrix::set_mat2d>(iw1_all, iw2_all, v, *this->ParaV, this->Hloc_fixed2.data()); - else if (dtype=='L') // Local potential Hamiltonian. - LCAO_Matrix::set_mat2d>(iw1_all, iw2_all, v, *this->ParaV, this->Hloc2.data()); - else - ModuleBase::WARNING_QUIT("LCAO_Matrix", "set_HSk"); + if (dtype=='S')//overlap Hamiltonian. + { + LCAO_Matrix::set_mat2d>(iw1_all, iw2_all, v, *this->ParaV, this->Sloc2.data()); + } + else if (dtype=='T' || dtype=='N')// kinetic and nonlocal Hamiltonian. + { + LCAO_Matrix::set_mat2d>(iw1_all, iw2_all, v, *this->ParaV, this->Hloc_fixed2.data()); + } + else if (dtype=='L') // Local potential Hamiltonian. + { + LCAO_Matrix::set_mat2d>(iw1_all, iw2_all, v, *this->ParaV, this->Hloc2.data()); + } + else + { + ModuleBase::WARNING_QUIT("LCAO_Matrix", "set_HSk"); + } return; } @@ -267,17 +301,38 @@ void LCAO_Matrix::zeros_HSgamma(const char &mtype) long long beg, len; if (mtype=='S') { - ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, (long long)this->Sloc.size(), (long long)512, beg, len); - ModuleBase::GlobalFunc::ZEROS(this->Sloc.data() + beg, len); + ModuleBase::BLOCK_TASK_DIST_1D( + num_threads, + thread_id, + (long long)this->Sloc.size(), + (long long)512, + beg, + len); + + ModuleBase::GlobalFunc::ZEROS(this->Sloc.data() + beg, len); } else if (mtype=='T') { - ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, (long long)this->Hloc_fixed.size(), (long long)512, beg, len); + ModuleBase::BLOCK_TASK_DIST_1D( + num_threads, + thread_id, + (long long)this->Hloc_fixed.size(), + (long long)512, + beg, + len); + ModuleBase::GlobalFunc::ZEROS(this->Hloc_fixed.data() + beg, len); } else if (mtype=='H') { - ModuleBase::BLOCK_TASK_DIST_1D(num_threads, thread_id, (long long)this->Hloc.size(), (long long)512, beg, len); + ModuleBase::BLOCK_TASK_DIST_1D( + num_threads, + thread_id, + (long long)this->Hloc.size(), + (long long)512, + beg, + len); + ModuleBase::GlobalFunc::ZEROS(this->Hloc.data() + beg, len); } }; @@ -404,12 +459,10 @@ void LCAO_Matrix::print_HSk(const char &mtype, const char &vtype, const double & if( std::abs(v) > accuracy ) { - // os << std::setw(15) << v; os << v << "\t"; } else { - // os << std::setw(15) << "0"; os << "0" << "\t"; } } @@ -556,9 +609,6 @@ void LCAO_Matrix::allocate_Hloc_fixedR_tr(void) { ModuleBase::TITLE("LCAO_Matrix","allocate_Hloc_fixedR_tr"); - //int R_x = 10; - //int R_y = 10; - //int R_z = 10; int R_x = GlobalC::GridD.getCellX(); int R_y = GlobalC::GridD.getCellY(); int R_z = GlobalC::GridD.getCellZ(); @@ -566,26 +616,16 @@ void LCAO_Matrix::allocate_Hloc_fixedR_tr(void) if(GlobalV::NSPIN!=4) { Hloc_fixedR_tr = new double***[R_x]; - //HR_tr = new double***[R_x]; - //SlocR_tr = new double***[R_x]; for(int ix=0; ixParaV->nloc]; - //HR_tr[ix][iy][iz] = new double[this->ParaV->nloc]; - //SlocR_tr[ix][iy][iz] = new double[this->ParaV->nloc]; ModuleBase::GlobalFunc::ZEROS(Hloc_fixedR_tr[ix][iy][iz], this->ParaV->nloc); - //ModuleBase::GlobalFunc::ZEROS(HR_tr[ix][iy][iz], this->ParaV->nloc); - //ModuleBase::GlobalFunc::ZEROS(SlocR_tr[ix][iy][iz], this->ParaV->nloc); } } } @@ -593,36 +633,20 @@ void LCAO_Matrix::allocate_Hloc_fixedR_tr(void) else { Hloc_fixedR_tr_soc = new std::complex***[R_x]; - //HR_tr = new double***[R_x]; - //SlocR_tr = new double***[R_x]; for(int ix=0; ix**[R_y]; - //HR_tr[ix] = new double**[R_y]; - //SlocR_tr[ix] = new double**[R_y]; for(int iy=0; iy*[R_z]; - //HR_tr[ix][iy] = new double*[R_z]; - //SlocR_tr[ix][iy] = new double*[R_z]; for(int iz=0; iz[this->ParaV->nloc]; - //HR_tr[ix][iy][iz] = new double[this->ParaV->nloc]; - //SlocR_tr[ix][iy][iz] = new double[this->ParaV->nloc]; ModuleBase::GlobalFunc::ZEROS(Hloc_fixedR_tr_soc[ix][iy][iz], this->ParaV->nloc); - //ModuleBase::GlobalFunc::ZEROS(HR_tr[ix][iy][iz], this->ParaV->nloc); - //ModuleBase::GlobalFunc::ZEROS(SlocR_tr[ix][iy][iz], this->ParaV->nloc); } } } } -//std::cout<<"R_x: "<ParaV->nloc: "<ParaV->nloc< &v) +void LCAO_Matrix::set_HR_tr_soc( + const int &Rx, + const int &Ry, + const int &Rz, + const int &iw1_all, + const int &iw2_all, + const std::complex &v) { const int ir = this->ParaV->global2local_row(iw1_all); const int ic = this->ParaV->global2local_col(iw2_all); -//std::cout<<"ir: "<ParaV->nrow+ir; -//std::cout<<"index: "<ParaV->ncol+ic; -//std::cout<<"index: "<ParaV->nloc: "<ParaV->nloc<ParaV->nloc); -//std::cout<<"Rx: "< Date: Mon, 1 Apr 2024 10:39:34 +0800 Subject: [PATCH 45/46] divide force files, and update Makefile.Objects --- source/Makefile.Objects | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/Makefile.Objects b/source/Makefile.Objects index e03f39948e4..45903f3a733 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -496,6 +496,10 @@ OBJS_LCAO=DM_gamma.o\ FORCE_gamma_tvnl.o\ FORCE_gamma_vl.o\ FORCE_k.o\ + foverlap_k.o\ + ftvnl_dphi_k.o\ + fvl_dphi_k.o\ + fvnl_dbeta_k.o\ LCAO_gen_fixedH.o\ LCAO_hamilt.o\ LCAO_matrix.o\ From a2e25b37c088292ce72dc9ff20753dbc77b000ef Mon Sep 17 00:00:00 2001 From: mohanchen Date: Mon, 1 Apr 2024 19:08:11 +0800 Subject: [PATCH 46/46] update LCAO_hamilt.cpp --- .../hamilt_lcaodft/LCAO_hamilt.cpp | 77 ++++++++++++------- .../hamilt_lcaodft/LCAO_hamilt.h | 11 ++- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp index f23ca3bc9c9..b1881849f48 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.cpp @@ -60,7 +60,7 @@ void LCAO_Hamilt::grid_prepare( return; } -void LCAO_Hamilt::set_R_range_sparse(void) +void LCAO_Hamilt::set_R_range_sparse(LCAO_Matrix &lm) { int R_minX = int(GlobalC::GridD.getD_minX()); int R_minY = int(GlobalC::GridD.getD_minY()); @@ -77,7 +77,7 @@ void LCAO_Hamilt::set_R_range_sparse(void) for(int iz = 0; iz < R_z; iz++) { Abfs::Vector3_Order temp_R(ix+R_minX, iy+R_minY, iz+R_minZ); - this->LM->all_R_coor.insert(temp_R); + lm.all_R_coor.insert(temp_R); } } } @@ -85,7 +85,13 @@ void LCAO_Hamilt::set_R_range_sparse(void) return; } -void LCAO_Hamilt::cal_STN_R_sparse_for_S(const double &sparse_threshold) +void LCAO_Hamilt::cal_STN_R_sparse_for_S( + const Parallel_Orbitals pv, + std::vector &slocR, + std::vector> &slocR_soc, + std::map, std::map>> &SR_sparse, + std::map, std::map>>> &SR_soc_sparse, + const double &sparse_threshold) { ModuleBase::TITLE("LCAO_Hamilt","cal_STN_R_sparse_for_S"); @@ -93,8 +99,8 @@ void LCAO_Hamilt::cal_STN_R_sparse_for_S(const double &sparse_threshold) ModuleBase::Vector3 dtau, tau1, tau2; ModuleBase::Vector3 dtau1, dtau2, tau0; - double temp_value_double = 0.0; - std::complex temp_value_complex; + double tmp=0.0; + std::complex tmpc=complex(0.0,0.0); for(int T1 = 0; T1 < GlobalC::ucell.ntype; ++T1) { @@ -119,7 +125,10 @@ void LCAO_Hamilt::cal_STN_R_sparse_for_S(const double &sparse_threshold) bool adj = false; - if(distance < rcut) adj = true; + if(distance < rcut) + { + adj = true; + } else if(distance >= rcut) { for(int ad0 = 0; ad0 < GlobalC::GridD.getAdjacentNum()+1; ++ad0) @@ -148,36 +157,45 @@ void LCAO_Hamilt::cal_STN_R_sparse_for_S(const double &sparse_threshold) { const int start2 = GlobalC::ucell.itiaiw2iwt(T2,I2,0); - Abfs::Vector3_Order dR(GlobalC::GridD.getBox(ad).x, GlobalC::GridD.getBox(ad).y, GlobalC::GridD.getBox(ad).z); + Abfs::Vector3_Order dR( + GlobalC::GridD.getBox(ad).x, + GlobalC::GridD.getBox(ad).y, + GlobalC::GridD.getBox(ad).z); for(int ii=0; iinw*GlobalV::NPOL; ii++) { const int iw1_all = start + ii; - const int mu = this->LM->ParaV->global2local_row(iw1_all); + const int mu = pv.global2local_row(iw1_all); - if(mu<0)continue; + if(mu<0) + { + continue; + } for(int jj=0; jjnw*GlobalV::NPOL; jj++) { int iw2_all = start2 + jj; - const int nu = this->LM->ParaV->global2local_col(iw2_all); + const int nu = pv.global2local_col(iw2_all); - if(nu<0)continue; + if(nu<0) + { + continue; + } if(GlobalV::NSPIN!=4) { - temp_value_double = this->LM->SlocR[index]; - if (std::abs(temp_value_double) > sparse_threshold) + tmp = slocR[index]; + if (std::abs(tmp) > sparse_threshold) { - this->LM->SR_sparse[dR][iw1_all][iw2_all] = temp_value_double; + SR_sparse[dR][iw1_all][iw2_all] = tmp; } } else { - temp_value_complex = this->LM->SlocR_soc[index]; - if(std::abs(temp_value_complex) > sparse_threshold) + tmpc = slocR_soc[index]; + if(std::abs(tmpc) > sparse_threshold) { - this->LM->SR_soc_sparse[dR][iw1_all][iw2_all] = temp_value_complex; + SR_soc_sparse[dR][iw1_all][iw2_all] = tmpc; } } @@ -288,7 +306,7 @@ void LCAO_Hamilt::cal_HSR_sparse( { ModuleBase::TITLE("LCAO_Hamilt","cal_HSR_sparse"); - set_R_range_sparse(); + set_R_range_sparse(*this->LM); //cal_STN_R_sparse(current_spin, sparse_threshold); if(GlobalV::NSPIN!=4) @@ -361,7 +379,7 @@ void LCAO_Hamilt::cal_dH_sparse( { ModuleBase::TITLE("LCAO_Hamilt","cal_dH_sparse"); - set_R_range_sparse(); + set_R_range_sparse(*this->LM); const int nnr = this->LM->ParaV->nnr; this->LM->DHloc_fixedR_x = new double[nnr]; @@ -394,6 +412,7 @@ void LCAO_Hamilt::cal_dH_sparse( gint_k.cal_dvlocal_R_sparseMatrix(current_spin, sparse_threshold, this->LM); } + void LCAO_Hamilt::cal_STN_R_sparse_for_T(const double &sparse_threshold) { ModuleBase::TITLE("LCAO_Hamilt","cal_STN_R_sparse_for_T"); @@ -402,8 +421,8 @@ void LCAO_Hamilt::cal_STN_R_sparse_for_T(const double &sparse_threshold) ModuleBase::Vector3 dtau, tau1, tau2; ModuleBase::Vector3 dtau1, dtau2, tau0; - double temp_value_double; - std::complex temp_value_complex; + double tmp=0.0; + std::complex tmpc=complex(0.0,0.0); for(int T1 = 0; T1 < GlobalC::ucell.ntype; ++T1) { @@ -478,18 +497,18 @@ void LCAO_Hamilt::cal_STN_R_sparse_for_T(const double &sparse_threshold) if(GlobalV::NSPIN!=4) { - temp_value_double = this->LM->Hloc_fixedR[index]; - if (std::abs(temp_value_double) > sparse_threshold) + tmp = this->LM->Hloc_fixedR[index]; + if (std::abs(tmp) > sparse_threshold) { - this->LM->TR_sparse[dR][iw1_all][iw2_all] = temp_value_double; + this->LM->TR_sparse[dR][iw1_all][iw2_all] = tmp; } } else { - temp_value_complex = this->LM->Hloc_fixedR_soc[index]; - if(std::abs(temp_value_complex) > sparse_threshold) + tmpc = this->LM->Hloc_fixedR_soc[index]; + if(std::abs(tmpc) > sparse_threshold) { - this->LM->TR_soc_sparse[dR][iw1_all][iw2_all] = temp_value_complex; + this->LM->TR_soc_sparse[dR][iw1_all][iw2_all] = tmpc; } } @@ -507,7 +526,7 @@ void LCAO_Hamilt::cal_STN_R_sparse_for_T(const double &sparse_threshold) void LCAO_Hamilt::cal_SR_sparse(const double &sparse_threshold, hamilt::Hamilt>* p_ham) { ModuleBase::TITLE("LCAO_Hamilt","cal_SR_sparse"); - set_R_range_sparse(); + set_R_range_sparse(*this->LM); //cal_STN_R_sparse(current_spin, sparse_threshold); if(GlobalV::NSPIN!=4) { @@ -531,7 +550,7 @@ void LCAO_Hamilt::cal_TR_sparse(const double &sparse_threshold) this->LM->Hloc_fixedR.resize(this->LM->ParaV->nnr); this->LM->zeros_HSR('T'); this->genH.build_ST_new('T', 0, GlobalC::ucell, this->LM->Hloc_fixedR.data()); - this->set_R_range_sparse(); + this->set_R_range_sparse(*this->LM); this->cal_STN_R_sparse_for_T(sparse_threshold); return; diff --git a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h index 1d8775a5e17..b57ebf43e7b 100644 --- a/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h +++ b/source/module_hamilt_lcao/hamilt_lcaodft/LCAO_hamilt.h @@ -32,7 +32,7 @@ class LCAO_Hamilt const ModulePW::PW_Basis_Big& bigpw); // jingan add 2021-6-4 - void set_R_range_sparse(); + void set_R_range_sparse(LCAO_Matrix &lm); void cal_HContainer_sparse_d(const int ¤t_spin, const double &sparse_threshold, @@ -46,7 +46,14 @@ class LCAO_Hamilt void cal_dSTN_R_sparse(const int ¤t_spin, const double &sparse_threshold); - void cal_STN_R_sparse_for_S(const double &sparse_threshold); + // mohan update 2024-04-01 + void cal_STN_R_sparse_for_S( + const Parallel_Orbitals pv, + std::vector &slocR, + std::vector> &slocR_soc, + std::map, std::map>> &SR_sparse, + std::map, std::map>>> &SR_soc_sparse, + const double &sparse_threshold); void cal_STN_R_sparse_for_T(const double &sparse_threshold);