Skip to content

Commit 6095b84

Browse files
mohanchenabacus_fixer
andauthored
Update write_dipole.cpp (#7349)
* change the output of step of electron evolve, starts from 1 * update dipole outputs * 改进 dipole_io 模块:优化性能和代码结构 1. 增强 write_dipole 函数: - 添加 ofs_running 参数,支持自定义输出流 - 移除未使用的头文件引用(charge.h, evolve_elec.h) - 统一电子偶极矩计算算法,移除 ifdef MPI 分支 - 预计算倒网格维度倒数,优化性能 - 添加除零保护检查 - 添加 OpenMP 并行化,使用 reduction 累加 - 提取公共打印函数 printDipoleMoment 2. 改进 prepare 函数: - 使用 switch 语句替代 if-else 链 - 移除中间变量,直接返回结果 3. 更新 dipole_io.h: - 添加 UnitCell 头文件引用 - 调整参数顺序,添加 ofs_running 在前 4. 添加详细注释: - 函数文档注释 - 物理公式说明 - 代码实现细节 5. 优化代码风格: - 使用小写常量名(small_value) - 优化变量作用域 - 改进错误处理 * delete uselss #ifdef __LCAO * Refactor: migrate write_dipole from ctrl_output_td to ctrl_output_fp This refactoring extends the dipole output functionality to all DFT solvers by moving it from the TDDFT-specific module to the common output module. Changes: 1. source/source_io/module_ctrl/ctrl_output_fp.cpp - Add include for dipole_io.h - Add dipole output functionality after out_xc_r section - Now supports out_dipole parameter for all FP-based solvers 2. source/source_io/module_ctrl/ctrl_output_td.cpp - Remove duplicate dipole output code (migrated to ctrl_output_fp) - Remove unnecessary dipole_io.h include - Renumber comments (1) for current, (3) for restart 3. source/source_io/module_dipole/write_dipole.cpp - Rename printDipoleMoment to print_dipole_moment (snake_case convention) Benefits: - OFDFT, KSDFT (PW/LCAO), SDFT, and TDDFT all gain dipole output capability - Single implementation point reduces maintenance burden - Consistent behavior across all solver types - Better code organization following the base class aggregation pattern * Cleanup: remove unused 'is' parameter from write_dipole The 'is' (spin channel index) parameter was not used in the write_dipole function: - Electron dipole moment uses rho_save (already selected by spin) - Ionic dipole moment uses ucell (spin-independent) - File naming is handled by the caller through 'fn' parameter Changes: 1. dipole_io.h - Remove 'is' parameter from function declaration 2. write_dipole.cpp - Remove 'is' parameter from function definition 3. ctrl_output_fp.cpp - Update function call to remove 'is' argument * update index.rst * add back #ifdef __LCAO * add output_dipole.md * add INPUT * fix --------- Co-authored-by: abacus_fixer <mohanchen@pku.eud.cn>
1 parent 8ff0a05 commit 6095b84

9 files changed

Lines changed: 280 additions & 112 deletions

File tree

docs/advanced/output_files/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ Detailed Introduction of the Output Files
77

88
output-specification
99
running_scf.log
10-
10+
output_dipole.md
11+
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Outputting Dipole Moment
2+
3+
ABACUS can output the dipole moment by adding the keyword `out_dipole` in the INPUT file:
4+
5+
```
6+
out_dipole 1
7+
```
8+
9+
## Supported Calculations
10+
11+
This feature is available for all types of DFT calculations that use charge density:
12+
13+
- **KSDFT** (Kohn-Sham DFT)
14+
- Plane wave (PW) basis
15+
- Linear combination of atomic orbitals (LCAO) basis
16+
- **SDFT** (Stochastic DFT)
17+
- **OFDFT** (Orbital-Free DFT)
18+
- **TDDFT** (Time-Dependent DFT)
19+
20+
## Input Parameters
21+
22+
| Parameter | Type | Description | Default |
23+
|-----------|------|-------------|---------|
24+
| `out_dipole` | Integer | Whether to output dipole moment | 0 |
25+
26+
- `out_dipole = 0`: Disable dipole output
27+
- `out_dipole = 1`: Enable dipole output
28+
29+
## Output Files
30+
31+
When `out_dipole` is set to 1, ABACUS will generate files named `dipole_s${spin}.txt` for each spin channel in the output directory.
32+
33+
For spin-polarized calculation (nspin=2):
34+
- `dipole_s1.txt`
35+
- `dipole_s2.txt`
36+
37+
For non-spin-polarized calculation (nspin=1):
38+
- `dipole_s1.txt`
39+
40+
## Output Format
41+
42+
The dipole output file contains one line for each ionic/electronic step:
43+
44+
```
45+
step_index dipole_x dipole_y dipole_z
46+
```
47+
48+
- `step_index`: The current step number (starts from 1)
49+
- `dipole_x, dipole_y, dipole_z`: The x, y, z components of the dipole moment
50+
51+
Example output:
52+
53+
```
54+
1 -0.00123456 0.00234567 -0.00345678
55+
2 -0.00123457 0.00234568 -0.00345679
56+
...
57+
```
58+
59+
## Additional Information
60+
61+
During the calculation, the dipole moment is also printed in the `running_*.log` file, including:
62+
- Electronic dipole moment
63+
- Ionic dipole moment
64+
- Total dipole moment
65+
- Total dipole moment norm
66+
67+
The dipole moment calculation includes both electronic and ionic contributions. The total dipole moment is the sum of electronic and ionic dipoles.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
INPUT_PARAMETERS
2+
#Parameters (1.General)
3+
suffix Si_nve
4+
calculation md
5+
nbands 20
6+
symmetry 0
7+
pseudo_dir ../../../tests/PP_ORB
8+
orbital_dir ../../../tests/PP_ORB
9+
10+
#Parameters (2.Iteration)
11+
ecutwfc 30
12+
scf_thr 1e-5
13+
scf_nmax 100
14+
15+
#Parameters (3.Basis)
16+
basis_type lcao
17+
ks_solver genelpa
18+
gamma_only 1
19+
20+
#Parameters (4.Smearing)
21+
smearing_method gaussian
22+
smearing_sigma 0.001
23+
24+
#Parameters (5.Mixing)
25+
mixing_type broyden
26+
mixing_beta 0.3
27+
chg_extrap second-order
28+
29+
#Parameters (6.MD)
30+
md_type nve
31+
md_nstep 10
32+
md_dt 1
33+
md_tfirst 300
34+
35+
out_dipole 1

examples/22_rt-tddft/01_H2_length_gauge/INPUT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ smearing_method gauss
2020

2121
#Parameters (5.MD Parameters)
2222
md_type nve
23-
md_nstep 1000
23+
md_nstep 5
2424
md_dt 0.005
2525
md_tfirst 0
2626

source/source_esolver/esolver_ks_lcao_tddft.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ template <typename TR, typename Device>
249249
void ESolver_KS_LCAO_TDDFT<TR, Device>::print_step()
250250
{
251251
std::cout << " -------------------------------------------" << std::endl;
252-
std::cout << " STEP OF ELECTRON EVOLVE : " << unsigned(totstep) << std::endl;
252+
std::cout << " STEP OF ELECTRON EVOLVE : " << unsigned(totstep)+1 << std::endl;
253253
std::cout << " -------------------------------------------" << std::endl;
254254
}
255255

source/source_io/module_ctrl/ctrl_output_fp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "ctrl_output_fp.h" // use ctrl_output_fp()
22

33
#include "../module_output/cube_io.h" // use write_vdata_palgrid
4+
#include "../module_dipole/dipole_io.h" // use write_dipole
45
#include "source_estate/module_charge/symmetry_rho.h" // use Symmetry_rho
56
#include "source_hamilt/module_xc/xc_functional.h" // use XC_Functional
67
#include "source_io/module_chgpot/write_elecstat_pot.h" // use write_elecstat_pot
@@ -198,6 +199,17 @@ void ctrl_output_fp(UnitCell& ucell,
198199
}
199200
#endif
200201

202+
// 8) write dipole moment
203+
if (PARAM.inp.out_dipole == 1)
204+
{
205+
for (int is = 0; is < nspin; ++is)
206+
{
207+
std::stringstream ss_dipole;
208+
ss_dipole << global_out_dir << "dipole_s" << is + 1 << ".txt";
209+
ModuleIO::write_dipole(ucell, chr.rho_save[is], pw_rhod, istep, ss_dipole.str(), GlobalV::ofs_running);
210+
}
211+
}
212+
201213
ModuleBase::timer::end("ModuleIO", "ctrl_output_fp");
202214
}
203215

source/source_io/module_ctrl/ctrl_output_td.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "ctrl_output_td.h"
22

33
#include "source_base/parallel_global.h"
4-
#include "source_io/module_dipole/dipole_io.h"
54
#include "source_io/module_parameter/parameter.h"
65
#include "source_io/module_current/td_current_io.h"
76

@@ -30,18 +29,7 @@ void ctrl_output_td(const UnitCell& ucell,
3029
ModuleBase::TITLE("ModuleIO", "ctrl_output_td");
3130

3231
#ifdef __LCAO
33-
// (1) Write dipole information
34-
for (int is = 0; is < PARAM.inp.nspin; ++is)
35-
{
36-
if (PARAM.inp.out_dipole == 1)
37-
{
38-
std::stringstream ss_dipole;
39-
ss_dipole << PARAM.globalv.global_out_dir << "dipole_s" << is + 1 << ".txt";
40-
ModuleIO::write_dipole(ucell, rho_save[is], rhopw, is, istep, ss_dipole.str());
41-
}
42-
}
43-
44-
// (2) Write current information
32+
// (1) Write current information
4533
const elecstate::ElecStateLCAO<std::complex<double>>* pelec_lcao
4634
= dynamic_cast<const elecstate::ElecStateLCAO<std::complex<double>>*>(pelec);
4735

@@ -65,7 +53,6 @@ void ctrl_output_td(const UnitCell& ucell,
6553
{
6654
ModuleIO::write_current(ucell, grid, istep, psi, pelec, kv, pv, orb, td_p->r_calculator, p_hamilt->getSR(), p_hamilt->getHR(), exx_nao);
6755
}
68-
6956
// (3) Output file for restart
7057
if (PARAM.inp.out_freq_td > 0) // default value of out_freq_td is 0
7158
{

source/source_io/module_dipole/dipole_io.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
#define DIPOLE_IO_H
33

44
#include "source_basis/module_pw/pw_basis.h"
5+
#include "source_cell/unitcell.h"
56

7+
#include <fstream>
68
#include <string>
79

810
namespace ModuleIO
911
{
1012
void write_dipole(const UnitCell& ucell,
1113
const double* rho_save,
1214
const ModulePW::PW_Basis* rhopw,
13-
const int& is,
1415
const int& istep,
1516
const std::string& fn,
17+
std::ofstream& ofs_running,
1618
const int& precision = 11);
1719

1820
double prepare(const UnitCell& cell, int& dir);

0 commit comments

Comments
 (0)