Skip to content

Commit b930866

Browse files
authored
Feature: ldos in pw basis set (#6100)
* add input parameters for ldos * Feature: ldos in pw basis set * Refactor: after_all_runners * Fix: complie bug * Refactor: cal_ldos in pw
1 parent 0ec12d9 commit b930866

23 files changed

+234
-158
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
- [out\_wfc\_r](#out_wfc_r)
141141
- [out\_wfc\_lcao](#out_wfc_lcao)
142142
- [out\_dos](#out_dos)
143+
- [out\_ldos](#out_ldos)
143144
- [out\_band](#out_band)
144145
- [out\_proj\_band](#out_proj_band)
145146
- [out\_stru](#out_stru)
@@ -175,6 +176,7 @@
175176
- [dos\_emin\_ev](#dos_emin_ev)
176177
- [dos\_emax\_ev](#dos_emax_ev)
177178
- [dos\_nche](#dos_nche)
179+
- [stm\_bias](#stm_bias)
178180
- [NAOs](#naos)
179181
- [bessel\_nao\_ecut](#bessel_nao_ecut)
180182
- [bessel\_nao\_tolerence](#bessel_nao_tolerence)
@@ -1707,6 +1709,12 @@ These variables are used to control the output of properties.
17071709
- lcao-only: output the density of states (DOS) and the projected density of states (PDOS)
17081710
- **Default**: 0
17091711

1712+
### out_ldos
1713+
1714+
- **Type**: Boolean
1715+
- **Description**: Whether to output the local density of states for given bias in cube file format, which is controlled by [stm_bias](#stm_bias).
1716+
- **Default**: False
1717+
17101718
### out_band
17111719

17121720
- **Type**: Boolean \[Integer\](optional)
@@ -1963,9 +1971,16 @@ These variables are used to control the calculation of DOS. [Detailed introducti
19631971
### dos_nche
19641972

19651973
- **Type**: Integer
1966-
The order of Chebyshev expansions when using Stochastic Density Functional Theory (SDFT) to calculate DOS.
1974+
- **Description**: The order of Chebyshev expansions when using Stochastic Density Functional Theory (SDFT) to calculate DOS.
19671975
- **Default**: 100
19681976

1977+
### stm_bias
1978+
1979+
- **Type**: Real
1980+
- **Description**: The bias voltage used to calculate local density of states to simulate scanning tunneling microscope, see details in [out_ldos](#out_ldos).
1981+
- **Default**: 1.0
1982+
- **Unit**: V
1983+
19691984
[back to top](#full-list-of-input-keywords)
19701985

19711986
## NAOs

source/Makefile.Objects

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ OBJS_IO=input_conv.o\
497497
write_dos_pw.o\
498498
nscf_band.o\
499499
cal_dos.o\
500+
cal_ldos.o\
500501
cif_io.o\
501502
dos_nao.o\
502503
numerical_descriptor.o\

source/module_elecstate/elecstate_pw.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ class ElecStatePW : public ElecState
4646
T** rhog = nullptr; // [Device] [spin][nrxx] rhog
4747
Real** kin_r = nullptr; // [Device] [spin][nrxx] kin_r
4848

49+
ModulePW::PW_Basis_K* basis = nullptr;
50+
4951
protected:
5052

5153
ModulePW::PW_Basis* rhopw_smooth = nullptr;
5254

53-
ModulePW::PW_Basis_K* basis = nullptr;
54-
5555
UnitCell* ucell = nullptr;
5656

5757
const pseudopot_cell_vnl* ppcell = nullptr;

source/module_elecstate/fp_energy.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,22 @@ void fenergy::print_all() const
9696
std::cout << " total= " << etot << std::endl;
9797
}
9898

99-
/// @brief get the reference of fermi of a specific spin
99+
/// @brief set efermi of a specific spin
100100
/// @param is SPIN
101-
/// @return a reference of fermi(is)
102-
double& efermi::get_ef(const int& is)
101+
/// @param ef_in fermi(is)
102+
void efermi::set_efval(const int& is, const double& ef_in)
103103
{
104104
if (!two_efermi)
105105
{
106-
return this->ef;
106+
this->ef = ef_in;
107107
}
108108
else if (is == 0)
109109
{
110-
return this->ef_up;
110+
this->ef_up = ef_in;
111111
}
112112
else if (is == 1)
113113
{
114-
return this->ef_dw;
114+
this->ef_dw = ef_in;
115115
}
116116
else
117117
{

source/module_elecstate/fp_energy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct efermi
6464
double ef_up = 0.0; ///< spin up Fermi energy
6565
double ef_dw = 0.0; ///< spin down Fermi energy
6666
bool two_efermi = false; ///<
67-
double& get_ef(const int& is);
67+
void set_efval(const int& is, const double& ef_in);
6868
double get_efval(const int& is) const;
6969
std::vector<double> get_all_ef() const;
7070
};

source/module_elecstate/test/elecstate_fp_energy_test.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* - fenergy::calculate_harris()
1515
* - fenergy::clear_all()
1616
* - fenergy::print_all()
17-
* - efermi::get_ef()
17+
* - efermi::set_efval()
1818
* - efermi::get_efval()
1919
*/
2020
class fenergy : public ::testing::Test
@@ -61,19 +61,18 @@ TEST_F(fenergy, print_all)
6161
TEST_F(fenergy, eferm_get_ef)
6262
{
6363
eferm.two_efermi = false;
64-
double& tmp_ef = eferm.get_ef(0);
65-
tmp_ef = 0.7;
64+
eferm.set_efval(0, 0.7);
6665
EXPECT_EQ(eferm.ef, 0.7);
66+
eferm.set_efval(2, 0.77);
67+
EXPECT_EQ(eferm.ef, 0.77);
6768
eferm.two_efermi = true;
68-
double& tmp_efup = eferm.get_ef(0);
69-
tmp_efup = 1.0;
70-
EXPECT_EQ(eferm.ef_up, 1.0);
71-
double& tmp_efdw = eferm.get_ef(1);
72-
tmp_efdw = -1.0;
69+
eferm.set_efval(0, 0.6);
70+
EXPECT_EQ(eferm.ef_up, 0.6);
71+
eferm.set_efval(1, -1.0);
7372
EXPECT_EQ(eferm.ef_dw, -1.0);
7473

7574
testing::internal::CaptureStdout();
76-
EXPECT_EXIT(double& tmpp = eferm.get_ef(2);, ::testing::ExitedWithCode(1), "");
75+
EXPECT_EXIT(eferm.set_efval(3, 1.0);, ::testing::ExitedWithCode(1), "");
7776
std::string output = testing::internal::GetCapturedStdout();
7877
EXPECT_THAT(output, testing::HasSubstr("Please check NSPIN when TWO_EFERMI is true"));
7978
}

source/module_esolver/esolver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ESolver
2626
virtual void runner(UnitCell& cell, const int istep) = 0;
2727

2828
//! perform post processing calculations
29-
virtual void after_all_runners(UnitCell& ucell){};
29+
virtual void after_all_runners(UnitCell& ucell) = 0;
3030

3131
//! deal with exx and other calculation than scf/md/relax/cell-relax:
3232
//! such as nscf, get_wf and get_pchg

source/module_esolver/esolver_fp.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,4 +408,12 @@ void ESolver_FP::iter_finish(UnitCell& ucell, const int istep, int& iter, bool&
408408
}
409409
}
410410

411+
void ESolver_FP::after_all_runners(UnitCell& ucell)
412+
{
413+
GlobalV::ofs_running << "\n\n --------------------------------------------" << std::endl;
414+
GlobalV::ofs_running << std::setprecision(16);
415+
GlobalV::ofs_running << " !FINAL_ETOT_IS " << this->pelec->f_en.etot * ModuleBase::Ry_to_eV << " eV" << std::endl;
416+
GlobalV::ofs_running << " --------------------------------------------\n\n" << std::endl;
417+
}
418+
411419
} // namespace ModuleESolver

source/module_esolver/esolver_fp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class ESolver_FP: public ESolver
4949
//! Initialize of the first-principels energy solver
5050
virtual void before_all_runners(UnitCell& ucell, const Input_para& inp) override;
5151

52+
virtual void after_all_runners(UnitCell& ucell) override;
53+
5254
protected:
5355
//! Something to do before SCF iterations.
5456
virtual void before_scf(UnitCell& ucell, const int istep);

source/module_esolver/esolver_ks.cpp

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
#include "module_base/timer.h"
44
#include "module_cell/cal_atoms_info.h"
5+
#include "module_elecstate/elecstate_print.h"
56
#include "module_hamilt_general/module_xc/xc_functional.h"
7+
#include "module_hsolver/hsolver.h"
68
#include "module_io/cube_io.h"
79
#include "module_io/json_output/init_info.h"
810
#include "module_io/json_output/output_info.h"
11+
#include "module_io/nscf_band.h"
912
#include "module_io/output_log.h"
1013
#include "module_io/print_info.h"
1114
#include "module_io/write_istate_info.h"
1215
#include "module_parameter/parameter.h"
13-
#include "module_elecstate/elecstate_print.h"
14-
#include "module_hsolver/hsolver.h"
1516

1617
#include <ctime>
1718
#include <iostream>
@@ -724,6 +725,69 @@ void ESolver_KS<T, Device>::after_scf(UnitCell& ucell, const int istep, const bo
724725
}
725726
}
726727

728+
template <typename T, typename Device>
729+
void ESolver_KS<T, Device>::after_all_runners(UnitCell& ucell)
730+
{
731+
ESolver_FP::after_all_runners(ucell);
732+
733+
// 1) write information
734+
if (PARAM.inp.out_dos != 0 || PARAM.inp.out_band[0] != 0 || PARAM.inp.out_proj_band != 0)
735+
{
736+
GlobalV::ofs_running << "\n\n\n\n";
737+
GlobalV::ofs_running << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
738+
">>>>>>>>>>>>>>>>>>>>>>>>>"
739+
<< std::endl;
740+
GlobalV::ofs_running << " | "
741+
" |"
742+
<< std::endl;
743+
GlobalV::ofs_running << " | Post-processing of data: "
744+
" |"
745+
<< std::endl;
746+
GlobalV::ofs_running << " | DOS (density of states) and bands will be "
747+
"output here. |"
748+
<< std::endl;
749+
GlobalV::ofs_running << " | If atomic orbitals are used, Mulliken "
750+
"charge analysis can be done. |"
751+
<< std::endl;
752+
GlobalV::ofs_running << " | Also the .bxsf file containing fermi "
753+
"surface information can be |"
754+
<< std::endl;
755+
GlobalV::ofs_running << " | done here. "
756+
" |"
757+
<< std::endl;
758+
GlobalV::ofs_running << " | "
759+
" |"
760+
<< std::endl;
761+
GlobalV::ofs_running << " <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
762+
"<<<<<<<<<<<<<<<<<<<<<<<<<"
763+
<< std::endl;
764+
GlobalV::ofs_running << "\n\n\n\n";
765+
}
766+
767+
// 2) write information
768+
ModuleIO::write_istate_info(this->pelec->ekb, this->pelec->wg, this->kv);
769+
770+
const int nspin0 = (PARAM.inp.nspin == 2) ? 2 : 1;
771+
772+
// 3) print out band information
773+
if (PARAM.inp.out_band[0])
774+
{
775+
for (int is = 0; is < nspin0; is++)
776+
{
777+
std::stringstream ss2;
778+
ss2 << PARAM.globalv.global_out_dir << "BANDS_" << is + 1 << ".dat";
779+
GlobalV::ofs_running << "\n Output bands in file: " << ss2.str() << std::endl;
780+
ModuleIO::nscf_band(is,
781+
ss2.str(),
782+
PARAM.inp.nbands,
783+
0.0,
784+
PARAM.inp.out_band[1],
785+
this->pelec->ekb,
786+
this->kv);
787+
}
788+
}
789+
}
790+
727791
//------------------------------------------------------------------------------
728792
//! the 16th-20th functions of ESolver_KS
729793
//! mohan add 2024-05-12

0 commit comments

Comments
 (0)