Skip to content

Commit a356ede

Browse files
authored
Feature: Add a new parameter out_freq_td to control output frequency in RT-TDDFT (#6796)
* Refactor in a more elegant way * Refactor ctrl_output_td * Refactor ctrl_scf_lcao * Refactor ctrl_output_fp * Reformat ctrl_scf_lcao.h
1 parent bd19b48 commit a356ede

File tree

10 files changed

+470
-445
lines changed

10 files changed

+470
-445
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
- [cell\_factor](#cell_factor)
136136
- [Output Variables](#variables-related-to-output-information)
137137
- [out\_freq\_ion](#out_freq_ion)
138+
- [out\_freq\_td](#out_freq_td)
138139
- [out\_freq\_elec](#out_freq_elec)
139140
- [out\_chg](#out_chg)
140141
- [out\_pot](#out_pot)
@@ -535,7 +536,7 @@ These variables are used to control general system parameters.
535536
- ofdft: orbital-free density functional theory
536537
- tdofdft: time-dependent orbital-free density functional theory
537538
- sdft: [stochastic density functional theory](#electronic-structure-sdft)
538-
- tddft: real-time time-dependent density functional theory (TDDFT)
539+
- tddft: real-time time-dependent density functional theory (RT-TDDFT)
539540
- lj: Leonard Jones potential
540541
- dp: DeeP potential, see details in [md.md](../md.md#dpmd)
541542
- nep: Neuroevolution Potential, see details in [md.md](../md.md#nep)
@@ -1688,15 +1689,22 @@ These variables are used to control the output of properties.
16881689
### out_freq_ion
16891690

16901691
- **Type**: Integer
1691-
- **Description**: Control the interval to print information every few ion steps. These properties cover charge density, local potential, electrostatic potential, Hamiltonian matrix, overlap matrix, density matrix, Mulliken population analysis and so on.
1692+
- **Description**: Controls the output interval in **ionic steps**. When set to a positive integer $N$, information such as charge density, local potential, electrostatic potential, Hamiltonian matrix, overlap matrix, density matrix, and Mulliken population analysis is printed every $N$ ionic steps.
16921693
- **Default**: 0
1693-
- **Note**: The integer indicates to print information every 'out_freq_ion' ion steps.
1694+
- **Note**: In RT-TDDFT calculations, this parameter is inactive; output frequency is instead controlled by [`out_freq_td`](#out_freq_td)—see its description for details.
1695+
1696+
### out_freq_td
1697+
1698+
- **Type**: Integer
1699+
- **Description**: Controls the output interval in **completed electronic evolution steps** during RT-TDDFT calculations. When set to a positive integer $N$, detailed information (see [`out_freq_ion`](#out_freq_ion)) is printed every $N$ electron time-evolution steps (i.e., every $N$ `STEP OF ELECTRON EVOLVE`). For example, if you wish to output information once per ionic step, you should set `out_freq_td` equal to [`estep_per_md`](#estep_per_md), since one ionic step corresponds to [`estep_per_md`](#estep_per_md) electronic evolution steps.
1700+
- **Default**: 0
1701+
- **Note**: This parameter is **only active in RT-TDDFT mode** (`esolver_type = tddft`). It has no effect in ground-state calculations.
16941702

16951703
### out_freq_elec
16961704

16971705
- **Type**: Integer
1698-
- **Description**: Output the charge density (only binary format, controlled by [out_chg](#out_chg)), wavefunction (controlled by [out_wfc_pw](#out_wfc_pw)) per `out_freq_elec` electronic iterations. Note that they are always output when converged or reach the maximum iterations [scf_nmax](#scf_nmax).
1699-
- **Default**: [scf_nmax](#scf_nmax)
1706+
- **Description**: Output the charge density (only binary format, controlled by [`out_chg`](#out_chg)), wavefunction (controlled by [`out_wfc_pw`](#out_wfc_pw)) per `out_freq_elec` electronic iterations. Note that they are always output when converged or reach the maximum iterations [`scf_nmax`](#scf_nmax).
1707+
- **Default**: [`scf_nmax`](#scf_nmax)
17001708

17011709
### out_chg
17021710

source/source_esolver/esolver_ks_lcao_tddft.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ void ESolver_KS_LCAO_TDDFT<TR, Device>::runner(UnitCell& ucell, const int istep)
107107
{
108108
estep_max = PARAM.inp.estep_per_md + 1;
109109
}
110-
// reset laststep matrix and wfc, if any atom cross the boundary
110+
111+
// Reset laststep matrix and wfc, if any atom cross the boundary
112+
// Apply a phase correction to H, S, and psi to keep consistency when atoms cross periodic boundaries
111113
const size_t len_hs_ik = use_tensor && use_lapack ? PARAM.globalv.nlocal * PARAM.globalv.nlocal : this->pv.nloc;
112114
module_rt::reset_matrix_boundary(ucell,
113115
this->kv,
@@ -116,6 +118,7 @@ void ESolver_KS_LCAO_TDDFT<TR, Device>::runner(UnitCell& ucell, const int istep)
116118
this->Sk_laststep,
117119
this->psi_laststep,
118120
len_hs_ik);
121+
119122
for (int estep = 0; estep < estep_max; estep++)
120123
{
121124
// calculate total time step
Lines changed: 89 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
#include "source_io/ctrl_output_fp.h" // use ctrl_output_fp()
1+
#include "source_io/ctrl_output_fp.h" // use ctrl_output_fp()
2+
3+
#include "cube_io.h" // use write_vdata_palgrid
24
#include "source_estate/module_charge/symmetry_rho.h" // use Symmetry_rho
3-
#include "source_io/write_elecstat_pot.h" // use write_elecstat_pot
5+
#include "source_hamilt/module_xc/xc_functional.h" // use XC_Functional
6+
#include "source_io/write_elecstat_pot.h" // use write_elecstat_pot
47
#include "source_io/write_elf.h"
5-
#include "cube_io.h" // use write_vdata_palgrid
6-
#include "source_hamilt/module_xc/xc_functional.h" // use XC_Functional
78

89
#ifdef USE_LIBXC
910
#include "source_io/write_libxc_r.h"
@@ -12,14 +13,14 @@
1213
namespace ModuleIO
1314
{
1415

15-
void ctrl_output_fp(UnitCell& ucell,
16-
elecstate::ElecState* pelec,
17-
ModulePW::PW_Basis_Big* pw_big,
18-
ModulePW::PW_Basis* pw_rhod,
19-
Charge &chr,
20-
surchem &solvent,
21-
Parallel_Grid &para_grid,
22-
const int istep)
16+
void ctrl_output_fp(UnitCell& ucell,
17+
elecstate::ElecState* pelec,
18+
ModulePW::PW_Basis_Big* pw_big,
19+
ModulePW::PW_Basis* pw_rhod,
20+
Charge& chr,
21+
surchem& solvent,
22+
Parallel_Grid& para_grid,
23+
const int istep)
2324
{
2425
ModuleBase::TITLE("ModuleIO", "ctrl_output_fp");
2526
ModuleBase::timer::tick("ModuleIO", "ctrl_output_fp");
@@ -29,59 +30,64 @@ void ctrl_output_fp(UnitCell& ucell,
2930
const int nspin = PARAM.inp.nspin;
3031
const std::string global_out_dir = PARAM.globalv.global_out_dir;
3132

32-
33-
// print out the 'g' index when istep_in!=-1
33+
// print out the 'g' index when istep_in != -1
3434
int istep_in = -1;
35-
if (PARAM.inp.out_freq_ion>0) // default value of out_freq_ion is 0
35+
if (PARAM.inp.esolver_type != "tddft" && PARAM.inp.out_freq_ion > 0) // default value of out_freq_ion is 0
3636
{
3737
if (istep % PARAM.inp.out_freq_ion == 0)
3838
{
3939
istep_in = istep;
4040
}
4141
}
42+
else if (PARAM.inp.esolver_type == "tddft" && PARAM.inp.out_freq_td > 0) // default value of out_freq_td is 0
43+
{
44+
if (istep % PARAM.inp.out_freq_td == 0)
45+
{
46+
istep_in = istep;
47+
}
48+
}
4249

4350
std::string geom_block;
44-
if(istep_in==-1)
51+
if (istep_in == -1)
4552
{
4653
// do nothing
4754
}
48-
else if(istep_in>=0)
55+
else if (istep_in >= 0)
4956
{
5057
geom_block = "g" + std::to_string(istep + 1);
5158
}
5259

53-
5460
// 4) write charge density
5561
if (PARAM.inp.out_chg[0] > 0)
5662
{
5763
for (int is = 0; is < nspin; ++is)
5864
{
5965
pw_rhod->real2recip(chr.rho_save[is], chr.rhog_save[is]);
6066

61-
std::string fn =PARAM.globalv.global_out_dir + "chg";
67+
std::string fn = PARAM.globalv.global_out_dir + "chg";
6268

6369
std::string spin_block;
64-
if(nspin == 2 || nspin == 4)
70+
if (nspin == 2 || nspin == 4)
6571
{
66-
spin_block= "s" + std::to_string(is + 1);
72+
spin_block = "s" + std::to_string(is + 1);
6773
}
68-
else if(nspin == 1)
74+
else if (nspin == 1)
6975
{
7076
// do nothing
7177
}
7278

7379
fn += spin_block + geom_block + ".cube";
7480

7581
ModuleIO::write_vdata_palgrid(para_grid,
76-
chr.rho_save[is],
77-
is,
78-
nspin,
79-
istep_in,
80-
fn,
81-
pelec->eferm.get_efval(is),
82-
&(ucell),
83-
PARAM.inp.out_chg[1],
84-
1);
82+
chr.rho_save[is],
83+
is,
84+
nspin,
85+
istep_in,
86+
fn,
87+
pelec->eferm.get_efval(is),
88+
&(ucell),
89+
PARAM.inp.out_chg[1],
90+
1);
8591

8692
if (XC_Functional::get_ked_flag())
8793
{
@@ -90,13 +96,13 @@ void ctrl_output_fp(UnitCell& ucell,
9096
fn += spin_block + geom_block + ".cube";
9197

9298
ModuleIO::write_vdata_palgrid(para_grid,
93-
chr.kin_r_save[is],
94-
is,
95-
nspin,
96-
istep,
97-
fn,
98-
pelec->eferm.get_efval(is),
99-
&(ucell));
99+
chr.kin_r_save[is],
100+
is,
101+
nspin,
102+
istep,
103+
fn,
104+
pelec->eferm.get_efval(is),
105+
&(ucell));
100106
}
101107
}
102108
}
@@ -106,49 +112,49 @@ void ctrl_output_fp(UnitCell& ucell,
106112
{
107113
for (int is = 0; is < nspin; is++)
108114
{
109-
std::string fn =PARAM.globalv.global_out_dir + "pot";
115+
std::string fn = PARAM.globalv.global_out_dir + "pot";
110116

111117
std::string spin_block;
112-
if(nspin == 2 || nspin == 4)
118+
if (nspin == 2 || nspin == 4)
113119
{
114-
spin_block= "s" + std::to_string(is + 1);
120+
spin_block = "s" + std::to_string(is + 1);
115121
}
116-
else if(nspin == 1)
122+
else if (nspin == 1)
117123
{
118124
// do nothing
119125
}
120126

121127
fn += spin_block + geom_block + ".cube";
122128

123129
ModuleIO::write_vdata_palgrid(para_grid,
124-
pelec->pot->get_eff_v(is),
125-
is,
126-
nspin,
127-
istep_in,
128-
fn,
129-
0.0, // efermi
130-
&(ucell),
131-
3, // precision
132-
0); // out_fermi
130+
pelec->pot->get_eff_v(is),
131+
is,
132+
nspin,
133+
istep_in,
134+
fn,
135+
0.0, // efermi
136+
&(ucell),
137+
3, // precision
138+
0); // out_fermi
133139
}
134140
}
135141
else if (PARAM.inp.out_pot == 2)
136142
{
137-
std::string fn =PARAM.globalv.global_out_dir + "potes";
143+
std::string fn = PARAM.globalv.global_out_dir + "potes";
138144
fn += geom_block + ".cube";
139145

140146
ModuleIO::write_elecstat_pot(
141147
#ifdef __MPI
142-
pw_big->bz,
143-
pw_big->nbz,
148+
pw_big->bz,
149+
pw_big->nbz,
144150
#endif
145-
fn,
146-
istep,
147-
pw_rhod,
148-
&chr,
149-
&(ucell),
150-
pelec->pot->get_fixed_v(),
151-
solvent);
151+
fn,
152+
istep,
153+
pw_rhod,
154+
&chr,
155+
&(ucell),
156+
pelec->pot->get_fixed_v(),
157+
solvent);
152158
}
153159

154160
// 6) write ELF
@@ -161,40 +167,39 @@ void ctrl_output_fp(UnitCell& ucell,
161167
srho.begin(is, chr, pw_rhod, ucell.symm);
162168
}
163169

164-
std::string out_dir =PARAM.globalv.global_out_dir;
170+
std::string out_dir = PARAM.globalv.global_out_dir;
165171
ModuleIO::write_elf(
166172
#ifdef __MPI
167-
pw_big->bz,
168-
pw_big->nbz,
173+
pw_big->bz,
174+
pw_big->nbz,
169175
#endif
170-
out_dir,
171-
istep,
172-
nspin,
173-
chr.rho,
174-
chr.kin_r,
175-
pw_rhod,
176-
para_grid,
177-
&(ucell),
178-
PARAM.inp.out_elf[1]);
176+
out_dir,
177+
istep,
178+
nspin,
179+
chr.rho,
180+
chr.kin_r,
181+
pw_rhod,
182+
para_grid,
183+
&(ucell),
184+
PARAM.inp.out_elf[1]);
179185
}
180186

181187
#ifdef USE_LIBXC
182188
// 7) write xc(r)
183-
if(PARAM.inp.out_xc_r[0]>=0)
189+
if (PARAM.inp.out_xc_r[0] >= 0)
184190
{
185-
ModuleIO::write_libxc_r(
186-
PARAM.inp.out_xc_r[0],
187-
XC_Functional::get_func_id(),
188-
pw_rhod->nrxx, // number of real-space grid
189-
ucell.omega, // volume of cell
190-
ucell.tpiba,
191-
chr,
192-
*pw_big,
193-
*pw_rhod);
191+
ModuleIO::write_libxc_r(PARAM.inp.out_xc_r[0],
192+
XC_Functional::get_func_id(),
193+
pw_rhod->nrxx, // number of real-space grid
194+
ucell.omega, // volume of cell
195+
ucell.tpiba,
196+
chr,
197+
*pw_big,
198+
*pw_rhod);
194199
}
195200
#endif
196201

197202
ModuleBase::timer::tick("ModuleIO", "ctrl_output_fp");
198203
}
199204

200-
} // End ModuleIO
205+
} // namespace ModuleIO

source/source_io/ctrl_output_fp.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
#ifndef CTRL_OUTPUT_FP_H
2-
#define CTRL_OUTPUT_FP_H
1+
#ifndef CTRL_OUTPUT_FP_H
2+
#define CTRL_OUTPUT_FP_H
33

44
#include "source_estate/elecstate_lcao.h"
55

66
namespace ModuleIO
77
{
88

9-
void ctrl_output_fp(UnitCell& ucell,
10-
elecstate::ElecState* pelec,
11-
ModulePW::PW_Basis_Big* pw_big,
12-
ModulePW::PW_Basis* pw_rhod,
13-
Charge &chr,
14-
surchem &solvent,
15-
Parallel_Grid &para_grid,
16-
const int istep);
9+
void ctrl_output_fp(UnitCell& ucell,
10+
elecstate::ElecState* pelec,
11+
ModulePW::PW_Basis_Big* pw_big,
12+
ModulePW::PW_Basis* pw_rhod,
13+
Charge& chr,
14+
surchem& solvent,
15+
Parallel_Grid& para_grid,
16+
const int istep);
1717

1818
}
1919
#endif

source/source_io/ctrl_output_td.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ void ctrl_output_td(const UnitCell& ucell,
5959
}
6060

6161
// (3) Output file for restart
62-
if (PARAM.inp.out_freq_ion > 0) // default value of out_freq_ion is 0
62+
if (PARAM.inp.out_freq_td > 0) // default value of out_freq_td is 0
6363
{
64-
if (istep % PARAM.inp.out_freq_ion == 0)
64+
if (istep % PARAM.inp.out_freq_td == 0)
6565
{
6666
if (td_p != nullptr)
6767
{

0 commit comments

Comments
 (0)