Skip to content

Commit 5a19708

Browse files
committed
feature : fix efield and rename Dipole class to be Efield class
1 parent 51a2035 commit 5a19708

File tree

17 files changed

+183
-104
lines changed

17 files changed

+183
-104
lines changed

docs/input-main.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070

7171
[deepks_out_labels](#out-descriptor) | [deepks_descriptor_lmax](#lmax-descriptor) | [deepks_scf](#deepks-scf) | [deepks_model](#model-file)
7272

73+
- [Electric field and dipole correction](#Electric-field-and-dipole-correction)
74+
75+
[efield](#efield) | [dipole](#dipole) | [edir](#edir) | [emaxpos](#emaxpos) | [eopreg](#eopreg) | [eamp](#eamp)
76+
7377
[back to main page](../README.md)
7478

7579
## Structure of the file
@@ -910,6 +914,48 @@ Warning: this function is not robust enough for version 2.2.0. Please try these
910914
- **Description**: the path of the trained, traced NN model file (generated by deepks-kit). used when deepks_scf is set to 1.
911915
- **Default**: None
912916
917+
### Electric field and dipole correction
918+
919+
This part of variables are relevant to electric field and dipole correction
920+
921+
#### efield
922+
923+
- **Type**: Boolean
924+
- **Description**: If set to true, a saw-like potential simulating an electric field
925+
is added to the bare ionic potential.
926+
- **Default**: false
927+
928+
#### dipole
929+
930+
- **Type**: Boolean
931+
- **Description**: If dipole == true and efield == true, a dipole correction is also
932+
added to the bare ionic potential. If you want no electric field, parameter eamp should be zero. Must be used ONLY in a slab geometry for surface calculations, with the discontinuity FALLING IN THE EMPTY SPACE.
933+
- **Default**: false
934+
935+
#### edir
936+
937+
- **Type**: Integer
938+
- **Description**: The direction of the electric field or dipole correction is parallel to the reciprocal lattice vector, so the potential is constant in planes defined by FFT grid points, edir = 0, 1 or 2. Used only if efield == true.
939+
- **Default**: 2
940+
941+
#### emaxpos
942+
943+
- **Type**: Real
944+
- **Description**: Position of the maximum of the saw-like potential along crystal axis edir, within the unit cell, 0 < emaxpos < 1. Used only if efield == true.
945+
- **Default**: 0.5
946+
947+
#### eopreg
948+
949+
- **Type**: Real
950+
- **Description**: Zone in the unit cell where the saw-like potential decreases, 0 < eopreg < 1. Used only if efield == true.
951+
- **Default**: 0.1
952+
953+
#### eamp
954+
955+
- **Type**: Real
956+
- **Description**: Amplitude of the electric field, in ***Hartree*** a.u.; 1 a.u. = 51.4220632*10^10 V/m. Used only if efield == true. The saw-like potential increases with slope eamp in the region from (emaxpos+eopreg-1) to (emaxpos), then decreases until (emaxpos+eopreg), in units of the crystal vector edir. Important: the change of slope of this potential must be located in the empty region, or else unphysical forces will result.
957+
- **Default**: 0.0
958+
913959
### Exact Exchange
914960
915961
This part of variables are relevant when using hybrid functionals

source/Makefile.Objects

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ OBJS_SURCHEM=H_correction_pw.o\
243243
cal_vel.o\
244244
corrected_energy.o\
245245
minimize_cg.o\
246-
dipole.o\
246+
efield.o\
247247

248248
OBJS_XC=xc_funct_corr_gga.o \
249249
xc_funct_corr_lda.o \

source/input.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,15 @@ void Input::Default(void)
288288
lcao_dr = 0.01;
289289
lcao_rmax = 30; // (a.u.)
290290
//----------------------------------------------------------
291+
// efield and dipole correction Yu Liu add 2022-05-18
292+
//----------------------------------------------------------
293+
efield = false;
294+
dipole = false;
295+
edir = 2;
296+
emaxpos = 0.5;
297+
eopreg = 0.1;
298+
eamp = 0.0;
299+
//----------------------------------------------------------
291300
// vdw //jiyy add 2019-08-04
292301
//----------------------------------------------------------
293302
vdw_method = "none";
@@ -1155,6 +1164,34 @@ bool Input::Read(const std::string &fn)
11551164
read_value(ifs, mdp.md_damp);
11561165
}
11571166
//----------------------------------------------------------
1167+
// efield and dipole correction
1168+
// Yu Liu add 2022-05-18
1169+
//----------------------------------------------------------
1170+
else if (strcmp("efield", word) == 0)
1171+
{
1172+
read_value(ifs, efield);
1173+
}
1174+
else if (strcmp("dipole", word) == 0)
1175+
{
1176+
read_value(ifs, dipole);
1177+
}
1178+
else if (strcmp("edir", word) == 0)
1179+
{
1180+
read_value(ifs, edir);
1181+
}
1182+
else if (strcmp("emaxpos", word) == 0)
1183+
{
1184+
read_value(ifs, emaxpos);
1185+
}
1186+
else if (strcmp("eopreg", word) == 0)
1187+
{
1188+
read_value(ifs, eopreg);
1189+
}
1190+
else if (strcmp("eamp", word) == 0)
1191+
{
1192+
read_value(ifs, eamp);
1193+
}
1194+
//----------------------------------------------------------
11581195
// tddft
11591196
// Fuxiang He add 2016-10-26
11601197
//----------------------------------------------------------
@@ -1997,6 +2034,13 @@ void Input::Bcast()
19972034
Parallel_Common::bcast_double(mdp.msst_tscale);
19982035
Parallel_Common::bcast_double(mdp.md_tfreq);
19992036
Parallel_Common::bcast_double(mdp.md_damp);
2037+
// Yu Liu add 2022-05-18
2038+
Parallel_Common::bcast_bool(efield);
2039+
Parallel_Common::bcast_bool(dipole);
2040+
Parallel_Common::bcast_int(edir);
2041+
Parallel_Common::bcast_double(emaxpos);
2042+
Parallel_Common::bcast_double(eopreg);
2043+
Parallel_Common::bcast_double(eamp);
20002044
/* // Peize Lin add 2014-04-07
20012045
Parallel_Common::bcast_bool( vdwD2 );
20022046
Parallel_Common::bcast_double( vdwD2_scaling );

source/input.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,17 @@ class Input
255255
int md_msdstartTime; //choose which step that msd be calculated */
256256
MD_parameters mdp;
257257

258+
//==========================================================
259+
// efield and dipole correction
260+
// Yu Liu add 2022-05-18
261+
//==========================================================
262+
bool efield; // add electric field
263+
bool dipole; // dipole correction
264+
int edir; // the direction of the electric field or dipole correction
265+
double emaxpos; // position of the maximum of the saw-like potential along crystal axis edir
266+
double eopreg; // zone in the unit cell where the saw-like potential decreases
267+
double eamp; // amplitude of the electric field
268+
258269
//==========================================================
259270
// vdw
260271
// Peize Lin add 2014-03-31, jiyy update 2019-08-01

source/input_conv.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "src_lcao/local_orbital_charge.h"
2727
#endif
2828
#include "module_base/timer.h"
29+
#include "module_surchem/efield.h"
2930

3031
void Input_Conv::Convert(void)
3132
{
@@ -209,6 +210,16 @@ void Input_Conv::Convert(void)
209210
GlobalV::NPOL = 1;
210211
}
211212

213+
//----------------------------------------------------------
214+
// Yu Liu add 2022-05-18
215+
//----------------------------------------------------------
216+
GlobalV::EFIELD = INPUT.efield;
217+
GlobalV::DIPOLE = INPUT.dipole;
218+
Efield::edir = INPUT.edir;
219+
Efield::emaxpos = INPUT.emaxpos;
220+
Efield::eopreg = INPUT.eopreg;
221+
Efield::eamp = INPUT.eamp;
222+
212223
//----------------------------------------------------------
213224
// Fuxiang He add 2016-10-26
214225
//----------------------------------------------------------

source/module_esolver/esolver_ks_lcao.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "src_pw/symmetry_rho.h"
1515
#include "src_io/chi0_hilbert.h"
1616
#include "src_pw/threshold_elec.h"
17-
#include "module_surchem/dipole.h"
1817

1918
#ifdef __DEEPKS
2019
#include "../module_deepks/LCAO_deepks.h"
@@ -316,7 +315,6 @@ namespace ModuleESolver
316315
if (iter == 1)
317316
{
318317
GlobalC::CHR.set_new_e_iteration(true);
319-
Dipole::first = true;
320318
}
321319
else
322320
{

source/module_esolver/esolver_ks_pw.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "../src_io/chi0_hilbert.h"
2222
#include "../src_io/epsilon0_pwscf.h"
2323
#include "../src_io/epsilon0_vasp.h"
24-
#include "../module_surchem/dipole.h"
2524
//-----force-------------------
2625
#include "../src_pw/forces.h"
2726
//-----stress------------------
@@ -197,15 +196,8 @@ namespace ModuleESolver
197196
void ESolver_KS_PW::eachiterinit(const int istep, const int iter)
198197
{
199198
// mohan add 2010-07-16
200-
if (iter == 1)
201-
{
202-
GlobalC::CHR.set_new_e_iteration(true);
203-
Dipole::first = true;
204-
}
205-
else
206-
{
207-
GlobalC::CHR.set_new_e_iteration(false);
208-
}
199+
if (iter == 1) GlobalC::CHR.set_new_e_iteration(true);
200+
else GlobalC::CHR.set_new_e_iteration(false);
209201

210202
if (GlobalV::FINAL_SCF && iter == 1)
211203
{

source/module_surchem/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ add_library(
99
cal_vel.cpp
1010
corrected_energy.cpp
1111
minimize_cg.cpp
12-
dipole.cpp
12+
efield.cpp
1313
)

source/module_surchem/dipole.cpp renamed to source/module_surchem/efield.cpp

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,32 @@
1-
#include "dipole.h"
1+
#include "efield.h"
22
#include "../module_base/constants.h"
33
#include "../module_base/timer.h"
44
#include "../module_base/global_variable.h"
55
#include "../src_parallel/parallel_reduce.h"
66

7-
double Dipole::etotefield = 0.0;
8-
double Dipole::tot_dipole = 0.0;
9-
int Dipole::edir = 2;
10-
double Dipole::emaxpos = 0.5;
11-
double Dipole::eopreg = 0.1;
12-
double Dipole::eamp = 0.0;
13-
bool Dipole::first = true;
14-
double Dipole::bvec[3];
15-
double Dipole::bmod;
7+
double Efield::etotefield = 0.0;
8+
double Efield::tot_dipole = 0.0;
9+
int Efield::edir;
10+
double Efield::emaxpos;
11+
double Efield::eopreg;
12+
double Efield::eamp;
13+
double Efield::bvec[3];
14+
double Efield::bmod;
1615

17-
Dipole::Dipole(){}
16+
Efield::Efield(){}
1817

19-
Dipole::~Dipole(){}
18+
Efield::~Efield(){}
2019

2120
//=======================================================
2221
// calculate dipole potential in surface calculations
2322
//=======================================================
24-
ModuleBase::matrix Dipole::add_efield(const UnitCell &cell,
23+
ModuleBase::matrix Efield::add_efield(const UnitCell &cell,
2524
PW_Basis &pwb,
2625
const int &nspin,
2726
const double *const *const rho)
2827
{
29-
ModuleBase::TITLE("Dipole", "add_efield");
30-
ModuleBase::timer::tick("Dipole", "add_efield");
31-
32-
ModuleBase::matrix v(nspin, pwb.nrxx);
33-
34-
// efield only needs to be added on the first iteration, if dipfield
35-
// is not used. note that for relax calculations it has to be added
36-
// again on subsequent relax steps.
37-
if(!GlobalV::DIPOLE && !first)
38-
{
39-
return v;
40-
}
41-
first = false;
28+
ModuleBase::TITLE("Efield", "add_efield");
29+
ModuleBase::timer::tick("Efield", "add_efield");
4230

4331
double latvec; // latvec along the efield direction
4432
if(edir == 0)
@@ -64,7 +52,7 @@ ModuleBase::matrix Dipole::add_efield(const UnitCell &cell,
6452
}
6553
else
6654
{
67-
ModuleBase::WARNING_QUIT("Dipole::ion_dipole", "direction is wrong!");
55+
ModuleBase::WARNING_QUIT("Efield::add_efield", "direction is wrong!");
6856
}
6957
bmod = sqrt(pow(bvec[0],2) + pow(bvec[1],2) + pow(bvec[2],2));
7058

@@ -83,20 +71,22 @@ ModuleBase::matrix Dipole::add_efield(const UnitCell &cell,
8371
else
8472
{
8573
ion_dipole = cal_ion_dipole(cell, bmod);
86-
tot_dipole = ion_dipole - elec_dipole;
8774

8875
// energy correction
89-
etotefield = - ModuleBase::e2 * eamp * tot_dipole * cell.omega / ModuleBase::FOUR_PI;
76+
etotefield = - ModuleBase::e2 * eamp * ion_dipole * cell.omega / ModuleBase::FOUR_PI;
9077
}
9178

9279
const double length = (1.0 - eopreg) * latvec * cell.lat0;
9380
const double vamp = ModuleBase::e2 * (eamp - tot_dipole) * length;
9481

9582
GlobalV::ofs_running << "\n\n Adding external electric field: " << std::endl;
96-
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Computed dipole along edir", edir);
97-
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Elec. dipole (Ry a.u.)", elec_dipole);
98-
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Ion dipole (Ry a.u.)", ion_dipole);
99-
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Total dipole (Ry a.u.)", tot_dipole);
83+
if(GlobalV::DIPOLE)
84+
{
85+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Computed dipole along edir", edir);
86+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Elec. dipole (Ry a.u.)", elec_dipole);
87+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Ion dipole (Ry a.u.)", ion_dipole);
88+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Total dipole (Ry a.u.)", tot_dipole);
89+
}
10090
if( abs(eamp) > 0.0)
10191
{
10292
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Amplitute of Efield (Hartree)", eamp);
@@ -105,6 +95,7 @@ ModuleBase::matrix Dipole::add_efield(const UnitCell &cell,
10595
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Total length (Bohr)", length);
10696

10797
// dipole potential
98+
ModuleBase::matrix v(nspin, pwb.nrxx);
10899
const int nspin0 = (nspin == 2) ? 2 : 1;
109100

110101
for (int ir = 0; ir < pwb.nrxx; ++ir)
@@ -127,15 +118,15 @@ ModuleBase::matrix Dipole::add_efield(const UnitCell &cell,
127118

128119
double fac = ModuleBase::e2 * (eamp - tot_dipole) * cell.lat0 / bmod;
129120

130-
ModuleBase::timer::tick("Dipole", "add_efield");
121+
ModuleBase::timer::tick("Efield", "add_efield");
131122
return v * fac;
132123
}
133124

134125

135126
//=======================================================
136127
// calculate dipole density in surface calculations
137128
//=======================================================
138-
double Dipole::cal_ion_dipole(const UnitCell &cell, const double &bmod)
129+
double Efield::cal_ion_dipole(const UnitCell &cell, const double &bmod)
139130
{
140131
double ion_dipole = 0;
141132
for(int it=0; it<cell.ntype; ++it)
@@ -152,7 +143,7 @@ double Dipole::cal_ion_dipole(const UnitCell &cell, const double &bmod)
152143
return ion_dipole;
153144
}
154145

155-
double Dipole::cal_elec_dipole(const UnitCell &cell,
146+
double Efield::cal_elec_dipole(const UnitCell &cell,
156147
PW_Basis &pwb,
157148
const int &nspin,
158149
const double *const *const rho,
@@ -185,7 +176,7 @@ double Dipole::cal_elec_dipole(const UnitCell &cell,
185176
return elec_dipole;
186177
}
187178

188-
double Dipole::saw_function(const double &a, const double &b, const double &x)
179+
double Efield::saw_function(const double &a, const double &b, const double &x)
189180
{
190181
assert(x>=0);
191182
assert(x<=1);
@@ -206,7 +197,7 @@ double Dipole::saw_function(const double &a, const double &b, const double &x)
206197
}
207198
}
208199

209-
void Dipole::compute_force(const UnitCell &cell, ModuleBase::matrix &fdip)
200+
void Efield::compute_force(const UnitCell &cell, ModuleBase::matrix &fdip)
210201
{
211202
if(GlobalV::DIPOLE)
212203
{

0 commit comments

Comments
 (0)