Skip to content

Commit 9695fe3

Browse files
committed
Merge branch 'eband' of https://github.com/sunliang98/abacus-develop into eband
2 parents d7e9da3 + 10c613f commit 9695fe3

File tree

26 files changed

+371
-13
lines changed

26 files changed

+371
-13
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@
255255
- [of\_ml\_chi\_pnl](#of_ml_chi_pnl)
256256
- [of\_ml\_chi\_qnl](#of_ml_chi_qnl)
257257
- [of\_ml\_local\_test](#of_ml_local_test)
258+
- [TD-OFDFT: time dependent orbital free density functional theory](#tdofdft-time-dependent-orbital-free-density-functional-theory)
259+
- [of\_cd](#of_cd)
260+
- [of\_mcd\_alpha](#of_mcd_alpha)
258261
- [Electric Field and Dipole Correction](#electric-field-and-dipole-correction)
259262
- [efield\_flag](#efield_flag)
260263
- [dip\_cor\_flag](#dip_cor_flag)
@@ -527,6 +530,7 @@ These variables are used to control general system parameters.
527530
- **Description**: choose the energy solver.
528531
- ksdft: Kohn-Sham density functional theory
529532
- ofdft: orbital-free density functional theory
533+
- tdofdft: time-dependent orbital-free density functional theory
530534
- sdft: [stochastic density functional theory](#electronic-structure-sdft)
531535
- tddft: real-time time-dependent density functional theory (TDDFT)
532536
- lj: Leonard Jones potential
@@ -1072,7 +1076,20 @@ calculations.
10721076

10731077
- **Type**: String
10741078
- **Description**: In our package, the XC functional can either be set explicitly using the `dft_functional` keyword in `INPUT` file. If `dft_functional` is not specified, ABACUS will use the xc functional indicated in the pseudopotential file.
1075-
On the other hand, if dft_functional is specified, it will overwrite the functional from pseudopotentials and performs calculation with whichever functional the user prefers. We further offer two ways of supplying exchange-correlation functional. The first is using 'short-hand' names such as 'LDA', 'PBE', 'SCAN'. A complete list of 'short-hand' expressions can be found in [the source code](../../../source/source_hamilt/module_xc/xc_functional.cpp). The other way is only available when ***compiling with LIBXC***, and it allows for supplying exchange-correlation functionals as combinations of LIBXC keywords for functional components, joined by a plus sign, for example, dft_functional='LDA_X_1D_EXPONENTIAL+LDA_C_1D_CSC'. The list of LIBXC keywords can be found on its [website](https://libxc.gitlab.io/functionals/). In this way, **we support all the LDA,GGA and mGGA functionals provided by LIBXC**.
1079+
On the other hand, if dft_functional is specified, it will overwrite the functional from pseudopotentials and performs calculation with whichever functional the user prefers. We further offer two ways of supplying exchange-correlation functional. The first is using 'short-hand' names. A complete list of 'short-hand' expressions can be found in [the source code](../../../source/source_hamilt/module_xc/xc_functional.cpp). Supported density functionals are:
1080+
- LDA functionals
1081+
- LDA (equivalent with PZ and SLAPZNOGXNOGC), PWLDA
1082+
- GGA functionals
1083+
- PBE (equivalent with SLAPWPBXPBC), PBESOL, REVPBE, WC, BLYP, BP(referred to BP86), PW91, HCTH, OLYP, BLYP_LR
1084+
- meta-GGA functionals
1085+
- SCAN (require LIBXC)
1086+
- Hybrid functionals
1087+
- PBE0, HF
1088+
- If LIBXC is avaliale, additional short-hand names of hybrid functionals are supported: HSE(referred to HSE06), B3LYP, LC_PBE, LC_WPBE, LRC_WPBE, LRC_WPBEH, CAM_PBEH, WP22, CWP22, MULLER (equivalent with POWER)
1089+
- Hybrid meta-GGA functionals
1090+
- SCAN0 (require LIBXC)
1091+
1092+
The other way is only available when ***compiling with LIBXC***, and it allows for supplying exchange-correlation functionals as combinations of LIBXC keywords for functional components, joined by a plus sign, for example, dft_functional='LDA_X_1D_EXPONENTIAL+LDA_C_1D_CSC'. The list of LIBXC keywords can be found on its [website](https://libxc.gitlab.io/functionals/). In this way, **we support all the LDA,GGA and mGGA functionals provided by LIBXC**. Some popular functionals and their usage are: RPBE of [Hammer et al.](https://journals.aps.org/prb/abstract/10.1103/PhysRevB.59.7413), set `dft_functional` to 'GGA_X_RPBE+GGA_C_PBE', and [r$^{2}$SCAN](https://pubs.acs.org/doi/10.1021/acs.jpclett.0c02405), set `dft_functional` to 'MGGA_X_R2SCAN+MGGA_C_R2SCAN'.
10761093

10771094
Furthermore, the old INPUT parameter exx_hybrid_type for hybrid functionals has been absorbed into dft_functional. Options are `hf` (pure Hartree-Fock), `pbe0`(PBE0), `hse` (Note: in order to use HSE functional, LIBXC is required). Note also that HSE has been tested while PBE0 has NOT been fully tested yet, and the maximum CPU cores for running exx in parallel is $N(N+1)/2$, with N being the number of atoms.
10781095

@@ -2725,6 +2742,25 @@ Warning: this function is not robust enough for the current version. Please try
27252742

27262743
[back to top](#full-list-of-input-keywords)
27272744

2745+
## TDOFDFT: time dependent orbital free density functional theory
2746+
2747+
### of_cd
2748+
2749+
- **Type**: Boolean
2750+
- **Availability**: TDOFDFT
2751+
- **Type**: Boolean
2752+
- **Description**: Added the current dependent(CD) potential. (https://doi.org/10.1103/PhysRevB.98.144302)
2753+
- True: Added the CD potential.
2754+
- False: Not added the CD potential.
2755+
- **Default**: False
2756+
2757+
### of_mcd_alpha
2758+
2759+
- **Type**: Real
2760+
- **Availability**: TDOFDFT
2761+
- **Description**: The value of the parameter alpha in modified CD potential method. mCDPotenial=alpha*CDPotenial(proposed in paper PhysRevB.98.144302)
2762+
- **Default**: 1.0
2763+
27282764
## Electric field and dipole correction
27292765

27302766
These variables are relevant to electric field and dipole correction

source/source_cell/update_cell.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,13 @@ void periodic_boundary_adjustment(Atom* atoms,
496496
atom->taud[ia][ik] -= 1.0;
497497
}
498498
}
499-
if (atom->taud[ia].x < 0
500-
|| atom->taud[ia].y < 0
501-
|| atom->taud[ia].z < 0
502-
|| atom->taud[ia].x >= 1.0
503-
|| atom->taud[ia].y >= 1.0
504-
|| atom->taud[ia].z >= 1.0)
499+
const double eps = 1e-12;
500+
if (atom->taud[ia].x < -eps
501+
|| atom->taud[ia].y < -eps
502+
|| atom->taud[ia].z < -eps
503+
|| atom->taud[ia].x >= 1.0+eps
504+
|| atom->taud[ia].y >= 1.0+eps
505+
|| atom->taud[ia].z >= 1.0+eps)
505506
{
506507
GlobalV::ofs_warning << " atom type=" << it + 1 << " atom index=" << ia + 1 << std::endl;
507508
GlobalV::ofs_warning << " direct coordinate=" << atom->taud[ia].x << " "

source/source_io/module_parameter/input_parameter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,5 +686,10 @@ struct Input_para
686686
// src/gga_c_pbe.c
687687
std::vector<double> xc_corr_ext = {
688688
130, 0.06672455060314922, 0.031090690869654895034, 1.00000};
689+
690+
// ============== #Parameters (24.td-ofdft) ===========================
691+
bool of_cd = false; ///< add CD potential or not https://doi.org/10.1103/PhysRevB.98.144302
692+
double of_mCD_alpha = 1.0; /// parameter of modified CD Potential
693+
689694
};
690695
#endif

source/source_io/read_input.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ ReadInput::ReadInput(const int& rank)
101101
this->item_sdft();
102102
this->item_deepks();
103103
this->item_rt_tddft();
104+
this->item_tdofdft();
104105
this->item_lr_tddft();
105106
this->item_output();
106107
this->item_postprocess();

source/source_io/read_input.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class ReadInput
108108
// items for real time tddft
109109
void item_rt_tddft();
110110
// items for linear response tddft
111+
void item_tdofdft();
112+
// items for td-ofdft
111113
void item_lr_tddft();
112114
// items for output
113115
void item_output();

source/source_io/read_input_item_tddft.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,22 @@ void ReadInput::item_rt_tddft()
305305
}
306306

307307

308+
}
309+
void ReadInput::item_tdofdft()
310+
{
311+
// TD-OFDFT
312+
{
313+
Input_Item item("of_cd");
314+
item.annotation = "add CD Potential or not";
315+
read_sync_bool(input.of_cd);
316+
this->add_item(item);
317+
}
318+
{
319+
Input_Item item("of_mcd_alpha");
320+
item.annotation = "parameter of modified CD Potential";
321+
read_sync_double(input.of_mCD_alpha);
322+
this->add_item(item);
323+
}
308324
}
309325
void ReadInput::item_lr_tddft()
310326
{

source/source_io/test/read_input_ptest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ TEST_F(InputParaTest, ParaRead)
364364
EXPECT_EQ(param.inp.of_full_pw_dim, 0);
365365
EXPECT_FALSE(param.inp.of_read_kernel);
366366
EXPECT_EQ(param.inp.of_kernel_file, "WTkernel.txt");
367+
EXPECT_FALSE(param.inp.of_cd);
368+
EXPECT_DOUBLE_EQ(param.inp.of_mCD_alpha,1.0);
367369
EXPECT_DOUBLE_EQ(param.inp.of_xwm_kappa, 1.);
368370
EXPECT_DOUBLE_EQ(param.inp.of_xwm_rho_ref, 1.);
369371
EXPECT_EQ(param.inp.device, "cpu");

source/source_io/test/support/INPUT

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,7 @@ nsc_min 4 #Minimum number of spin-constrained iteration
387387
sc_scf_nmin 4 #Minimum number of outer scf loop before initializing lambda loop
388388
alpha_trial 0.02 #Initial trial step size for lambda in eV/uB^2
389389
sccut 4 #Maximal step size for lambda in eV/uB
390+
391+
#Parameters (23. Time-dependent orbital-free DFT)
392+
of_cd 0 #0: no CD potential; 1: add CD potential
393+
of_mCD_alpha 1.0 # parameter of modified CD potential

source/source_pw/module_ofdft/evolve_ofdft.cpp

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ void Evolve_OFDFT::cal_Hpsi(elecstate::ElecState* pelec,
2525
}
2626

2727
pelec->pot->update_from_charge(&chr, &ucell); // Hartree + XC + external
28-
this->cal_tf_potential(chr.rho,pw_rho ,pelec->pot->get_effective_v()); // TF potential
28+
this->cal_tf_potential(chr.rho, pw_rho, pelec->pot->get_effective_v()); // TF potential
29+
if (PARAM.inp.of_cd)
30+
{
31+
this->cal_CD_potential(psi_, pw_rho, pelec->pot->get_effective_v(), PARAM.inp.of_mCD_alpha); // CD potential
32+
}
2933

3034
#ifdef _OPENMP
3135
#pragma omp parallel for
@@ -72,6 +76,9 @@ void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>> pphi,
7276
ModulePW::PW_Basis* pw_rho,
7377
std::vector<std::complex<double>> Hpsi)
7478
{
79+
if (PARAM.inp.nspin <= 0) {
80+
ModuleBase::WARNING_QUIT("Evolve_OFDFT","nspin must be positive");
81+
}
7582
std::complex<double>** rLapPhi = new std::complex<double>*[PARAM.inp.nspin];
7683
#ifdef _OPENMP
7784
#pragma omp parallel for
@@ -118,13 +125,96 @@ void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>> pphi,
118125

119126
void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
120127
ModulePW::PW_Basis* pw_rho,
121-
ModuleBase::matrix& rpot)
128+
ModuleBase::matrix& rpot,
129+
double mCD_para)
122130
{
131+
std::complex<double> imag(0.0,1.0);
132+
133+
if (PARAM.inp.nspin <= 0) {
134+
ModuleBase::WARNING_QUIT("Evolve_OFDFT","nspin must be positive");
135+
}
136+
std::complex<double>** recipPhi = new std::complex<double>*[PARAM.inp.nspin];
137+
std::complex<double>** rPhi = new std::complex<double>*[PARAM.inp.nspin];
138+
#ifdef _OPENMP
139+
#pragma omp parallel for
140+
#endif
141+
for (int is = 0; is < PARAM.inp.nspin; ++is) {
142+
rPhi[is] = new std::complex<double>[pw_rho->nrxx];
143+
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
144+
{
145+
rPhi[is][ir]=psi_[is * pw_rho->nrxx + ir];
146+
}
147+
}
148+
149+
#ifdef _OPENMP
150+
#pragma omp parallel for
151+
#endif
123152
for (int is = 0; is < PARAM.inp.nspin; ++is)
124153
{
125-
//recipCurrent = new std::complex<double>[pw_rho->npw];
126-
//delete[] recipCurrent;
154+
std::complex<double> *recipCurrent_x=new std::complex<double>[pw_rho->npw];
155+
std::complex<double> *recipCurrent_y=new std::complex<double>[pw_rho->npw];
156+
std::complex<double> *recipCurrent_z=new std::complex<double>[pw_rho->npw];
157+
std::complex<double> *recipCDPotential=new std::complex<double>[pw_rho->npw];
158+
std::complex<double> *rCurrent_x=new std::complex<double>[pw_rho->nrxx];
159+
std::complex<double> *rCurrent_y=new std::complex<double>[pw_rho->nrxx];
160+
std::complex<double> *rCurrent_z=new std::complex<double>[pw_rho->nrxx];
161+
std::complex<double> *kF_r=new std::complex<double>[pw_rho->nrxx];
162+
std::complex<double> *rCDPotential=new std::complex<double>[pw_rho->nrxx];
163+
recipPhi[is] = new std::complex<double>[pw_rho->npw];
164+
165+
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
166+
{
167+
kF_r[ir]=std::pow(3*std::pow(ModuleBase::PI*std::abs(rPhi[is][ir]),2),1/3);
168+
}
169+
170+
pw_rho->real2recip(rPhi[is], recipPhi[is]);
171+
for (int ik = 0; ik < pw_rho->npw; ++ik)
172+
{
173+
recipCurrent_x[ik]=imag*pw_rho->gcar[ik].x*recipPhi[is][ik]* pw_rho->tpiba;
174+
recipCurrent_y[ik]=imag*pw_rho->gcar[ik].y*recipPhi[is][ik]* pw_rho->tpiba;
175+
recipCurrent_z[ik]=imag*pw_rho->gcar[ik].z*recipPhi[is][ik]* pw_rho->tpiba;
176+
}
177+
pw_rho->recip2real(recipCurrent_x,rCurrent_x);
178+
pw_rho->recip2real(recipCurrent_y,rCurrent_y);
179+
pw_rho->recip2real(recipCurrent_z,rCurrent_z);
180+
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
181+
{
182+
rCurrent_x[ir]=std::imag(rCurrent_x[ir]*std::conj(rPhi[is][ir]));
183+
rCurrent_y[ir]=std::imag(rCurrent_y[ir]*std::conj(rPhi[is][ir]));
184+
rCurrent_z[ir]=std::imag(rCurrent_z[ir]*std::conj(rPhi[is][ir]));
185+
}
186+
pw_rho->real2recip(rCurrent_x,recipCurrent_x);
187+
pw_rho->real2recip(rCurrent_y,recipCurrent_y);
188+
pw_rho->real2recip(rCurrent_z,recipCurrent_z);
189+
for (int ik = 0; ik < pw_rho->npw; ++ik)
190+
{
191+
recipCDPotential[ik]=recipCurrent_x[ik]*pw_rho->gcar[ik].x+recipCurrent_y[ik]*pw_rho->gcar[ik].y+recipCurrent_z[ik]*pw_rho->gcar[ik].z;
192+
recipCDPotential[ik]*=imag/pw_rho->gg[ik];
193+
}
194+
pw_rho->recip2real(recipCDPotential,rCDPotential);
195+
196+
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
197+
{
198+
rpot(0, ir) -= mCD_para*2.0*std::real(rCDPotential[ir])*std::pow(ModuleBase::PI,3) / (2.0*std::pow(std::real(kF_r[ir]),2));
199+
}
200+
delete[] recipCurrent_x;
201+
delete[] recipCurrent_y;
202+
delete[] recipCurrent_z;
203+
delete[] rCurrent_x;
204+
delete[] rCurrent_y;
205+
delete[] rCurrent_z;
127206
}
207+
208+
#ifdef _OPENMP
209+
#pragma omp parallel for
210+
#endif
211+
for (int is = 0; is < PARAM.inp.nspin; ++is)
212+
{
213+
delete[] recipPhi[is];
214+
delete[] rPhi[is];
215+
}
216+
delete[] recipPhi;
217+
delete[] rPhi;
128218
}
129219

130220
void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,

source/source_pw/module_ofdft/evolve_ofdft.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ class Evolve_OFDFT
4848
std::vector<std::complex<double>> Hpsi); // -1/2 \nabla^2 \phi
4949
void cal_CD_potential(std::vector<std::complex<double>> psi_,
5050
ModulePW::PW_Basis* pw_rho,
51-
ModuleBase::matrix& rpot);
51+
ModuleBase::matrix& rpot,
52+
double mCD_para);
5253

5354
};
5455
#endif

0 commit comments

Comments
 (0)