Skip to content

Commit 91b3c82

Browse files
Chentao168ErjieWu
andauthored
Add more types bandgap of labels for deepks (#6226)
* add parameter of deepks_band_range * upload deepks_bandgap for 2\3\4 * Update read_atoms.cpp * Update LCAO_deepks_interface.cpp * Update read_input_item_deepks.cpp * Update input_parameter.h * Update LCAO_deepks_interface.cpp * add tests for deepks bandgap * update input --------- Co-authored-by: Erjie Wu <[email protected]>
1 parent 6c559be commit 91b3c82

File tree

36 files changed

+729
-8
lines changed

36 files changed

+729
-8
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
- [bessel\_descriptor\_smooth](#bessel_descriptor_smooth)
196196
- [bessel\_descriptor\_sigma](#bessel_descriptor_sigma)
197197
- [deepks\_bandgap](#deepks_bandgap)
198+
- [deepks\_bandgap\_range](#deepks_bandgap_range)
198199
- [deepks\_v\_delta](#deepks_v_delta)
199200
- [deepks\_out\_unittest](#deepks_out_unittest)
200201
- [OFDFT: orbital free density functional theory](#ofdft-orbital-free-density-functional-theory)
@@ -2145,10 +2146,24 @@ Warning: this function is not robust enough for the current version. Please try
21452146

21462147
### deepks_bandgap
21472148

2148-
- **Type**: Boolean
2149+
- **Type**: Int
21492150
- **Availability**: numerical atomic orbital basis and `deepks_scf` is true
21502151
- **Description**: include bandgap label for DeePKS training
2151-
- **Default**: False
2152+
- 0: Don't include bandgap label
2153+
- 1: Include HOMO and LOMO for bandgap label
2154+
- 2: Include multiple bandgap label (see [deepks\_bandgap\_range](#deepks_bandgap_range) for more details)
2155+
- 3: Include target bandgap label (see [deepks\_bandgap\_range](#deepks_bandgap_range) for more details)
2156+
- 4: For systems containing H atoms only, HOMO is defined as the max occupation expect H atoms and the bandgap label is the energy between (HOMO, HOMO + 1)
2157+
- **Default**: 0
2158+
2159+
### deepks_bandgap_range
2160+
2161+
- **Type**: Int*2
2162+
- **Availability**: numerical atomic orbital basis, `deepks_scf` is true, and `deepks_bandgap` is 2 or 3
2163+
- **Description**:
2164+
- `deepks_bandgap` is 2: Bandgap labels are energies between (LUMO + deepks_bandgap_range[0], HOMO), (LUMO + deepks_bandgap_range[0] + 1, HOMO), ..., (LUMO + deepks_bandgap_range[1], HOMO) except (HOMO, HOMO)
2165+
- `deepks_bandgap` is 3: Bandgap label is the energy between (LUMO + deepks_bandgap_range[0], LUMO + deepks_bandgap_range[1])
2166+
- **Default**: 0 0
21522167

21532168
### deepks_v_delta
21542169

source/module_cell/read_atoms.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ bool unitcell::read_atom_positions(UnitCell& ucell,
8080
ofs_warning << " Label from ATOMIC_SPECIES is " << ucell.atom_label[it] << std::endl;
8181
return false;
8282
}
83-
ModuleBase::GlobalFunc::OUT(ofs_running, "atom label",ucell.atoms[it].label);
83+
ModuleBase::GlobalFunc::OUT(ofs_running, "atom label", ucell.atoms[it].label);
8484

8585
bool set_element_mag_zero = false;
86-
ModuleBase::GlobalFunc::READ_VALUE(ifpos, ucell.magnet.start_mag[it] );
86+
ModuleBase::GlobalFunc::READ_VALUE(ifpos, ucell.magnet.start_mag[it]);
8787

8888
#ifndef __SYMMETRY
8989
//===========================================

source/module_hamilt_lcao/module_deepks/LCAO_deepks_interface.cpp

Lines changed: 263 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ void LCAO_Deepks_Interface<TK, TR>::out_deepks_labels(const double& etot,
204204
}
205205

206206
// Bandgap Part
207-
if (PARAM.inp.deepks_bandgap)
207+
if (PARAM.inp.deepks_bandgap == 1)
208208
{
209209
const int nocc = (PARAM.inp.nelec + 1) / 2;
210210
ModuleBase::matrix o_tot(nks, 1);
@@ -273,6 +273,268 @@ void LCAO_Deepks_Interface<TK, TR>::out_deepks_labels(const double& etot,
273273
} // end deepks_out_labels == 1
274274
} // end bandgap label
275275

276+
if (PARAM.inp.deepks_bandgap == 2)
277+
{
278+
const int nocc = (PARAM.inp.nelec + 1) / 2;
279+
const int range = PARAM.inp.deepks_band_range[1] - PARAM.inp.deepks_band_range[0];
280+
ModuleBase::matrix o_tot(nks, range);
281+
for (int iks = 0; iks < nks; ++iks)
282+
{
283+
// record band gap for each k point (including spin)
284+
for (int ib = 0; ib <= range; ++ib)
285+
{
286+
if (ib + PARAM.inp.deepks_band_range[0] < -1)
287+
{
288+
o_tot(iks, ib) = ekb(iks, nocc + ib + PARAM.inp.deepks_band_range[0]) - ekb(iks, nocc - 1);
289+
}
290+
if (ib + PARAM.inp.deepks_band_range[0] > -1)
291+
{
292+
o_tot(iks, ib - 1) = ekb(iks, nocc + ib + PARAM.inp.deepks_band_range[0]) - ekb(iks, nocc -1);
293+
}
294+
}
295+
}
296+
297+
const std::string file_otot
298+
= PARAM.globalv.global_out_dir
299+
+ (PARAM.inp.deepks_out_labels == 1 ? "deepks_otot.npy" : "deepks_orbital.npy");
300+
LCAO_deepks_io::save_matrix2npy(file_otot, o_tot, rank); // Unit: Hartree
301+
302+
if (PARAM.inp.deepks_out_labels == 1) // don't need these when deepks_out_labels == 2
303+
{
304+
if (PARAM.inp.deepks_scf)
305+
{
306+
std::vector<ModuleBase::matrix> wg_hl_range(range);
307+
std::vector<std::vector<TH>> dm_bandgap_range(range);
308+
309+
// Calculate O_delta
310+
for (int ir = 0; ir <= range; ++ir)
311+
{
312+
if (ir + PARAM.inp.deepks_band_range[0] < -1)
313+
{
314+
wg_hl_range[ir].create(nks, PARAM.inp.nbands);
315+
wg_hl_range[ir].zero_out();
316+
dm_bandgap_range[ir].resize(nks);
317+
for (int iks = 0; iks < nks; ++iks)
318+
{
319+
wg_hl_range[ir](iks, nocc - 1) = -1.0;
320+
wg_hl_range[ir](iks, nocc + ir + PARAM.inp.deepks_band_range[0]) = 1.0;
321+
}
322+
elecstate::cal_dm(ParaV, wg_hl_range[ir], psi, dm_bandgap_range[ir]);
323+
}
324+
if (ir + PARAM.inp.deepks_band_range[0] > -1)
325+
{
326+
wg_hl_range[ir - 1].create(nks, PARAM.inp.nbands);
327+
wg_hl_range[ir - 1].zero_out();
328+
dm_bandgap_range[ir - 1].resize(nks);
329+
for (int iks = 0; iks < nks; ++iks)
330+
{
331+
wg_hl_range[ir - 1](iks, nocc - 1) = -1.0;
332+
wg_hl_range[ir - 1](iks, nocc + ir + PARAM.inp.deepks_band_range[0]) = 1.0;
333+
}
334+
elecstate::cal_dm(ParaV, wg_hl_range[ir - 1], psi, dm_bandgap_range[ir - 1]);
335+
}
336+
}
337+
338+
ModuleBase::matrix o_delta(nks, range);
339+
torch::Tensor orbital_precalc_range;
340+
341+
for (int ir = 0; ir < range; ++ir)
342+
{
343+
torch::Tensor orbital_precalc_temp;
344+
ModuleBase::matrix o_delta_temp(nks, 1);
345+
DeePKS_domain::cal_orbital_precalc<TK, TH>(dm_bandgap_range[ir],
346+
lmaxd,
347+
inlmax,
348+
nat,
349+
nks,
350+
inl2l,
351+
kvec_d,
352+
phialpha,
353+
gevdm,
354+
inl_index,
355+
ucell,
356+
orb,
357+
*ParaV,
358+
GridD,
359+
orbital_precalc_temp);
360+
if (ir == 0)
361+
{
362+
orbital_precalc_range = orbital_precalc_temp;
363+
}
364+
else
365+
{
366+
orbital_precalc_range = torch::cat({orbital_precalc_range, orbital_precalc_temp}, 0);
367+
}
368+
369+
DeePKS_domain::cal_o_delta<TK, TH>(dm_bandgap_range[ir], *h_delta, o_delta_temp, *ParaV, nks, nspin);
370+
for (int iks = 0; iks < nks; ++iks)
371+
{
372+
o_delta(iks, ir) = o_delta_temp(iks, 0);
373+
}
374+
}
375+
376+
// save obase and orbital_precalc
377+
const std::string file_orbpre = PARAM.globalv.global_out_dir + "deepks_orbpre.npy";
378+
LCAO_deepks_io::save_tensor2npy<double>(file_orbpre, orbital_precalc_range, rank);
379+
380+
const std::string file_obase = PARAM.globalv.global_out_dir + "deepks_obase.npy";
381+
LCAO_deepks_io::save_matrix2npy(file_obase, o_tot - o_delta, rank); // Unit: Hartree
382+
} // end deepks_scf == 1
383+
else // deepks_scf == 0
384+
{
385+
const std::string file_obase = PARAM.globalv.global_out_dir + "deepks_obase.npy";
386+
LCAO_deepks_io::save_matrix2npy(file_obase, o_tot, rank); // no scf, o_tot=o_base
387+
} // end deepks_scf == 0
388+
} // end deepks_out_labels == 1
389+
} // end bandgap label
390+
391+
if (PARAM.inp.deepks_bandgap == 3)
392+
{
393+
const int nocc = (PARAM.inp.nelec + 1) / 2;
394+
ModuleBase::matrix o_tot(nks, 1);
395+
for (int iks = 0; iks < nks; ++iks)
396+
{
397+
// record band gap for each k point (including spin)
398+
o_tot(iks, 0) = ekb(iks, nocc + PARAM.inp.deepks_band_range[1]) - ekb(iks, nocc + PARAM.inp.deepks_band_range[0]);
399+
}
400+
401+
const std::string file_otot
402+
= PARAM.globalv.global_out_dir
403+
+ (PARAM.inp.deepks_out_labels == 1 ? "deepks_otot.npy" : "deepks_orbital.npy");
404+
LCAO_deepks_io::save_matrix2npy(file_otot, o_tot, rank); // Unit: Hartree
405+
406+
if (PARAM.inp.deepks_out_labels == 1) // don't need these when deepks_out_labels == 2
407+
{
408+
if (PARAM.inp.deepks_scf)
409+
{
410+
ModuleBase::matrix wg_hl;
411+
std::vector<TH> dm_bandgap;
412+
413+
// Calculate O_delta
414+
wg_hl.create(nks, PARAM.inp.nbands);
415+
dm_bandgap.resize(nks);
416+
wg_hl.zero_out();
417+
for (int iks = 0; iks < nks; ++iks)
418+
{
419+
wg_hl(iks, nocc + PARAM.inp.deepks_band_range[0]) = -1.0;
420+
wg_hl(iks, nocc + PARAM.inp.deepks_band_range[1]) = 1.0;
421+
}
422+
elecstate::cal_dm(ParaV, wg_hl, psi, dm_bandgap);
423+
424+
ModuleBase::matrix o_delta(nks, 1);
425+
426+
// calculate and save orbital_precalc: [nks,NAt,NDscrpt]
427+
torch::Tensor orbital_precalc;
428+
DeePKS_domain::cal_orbital_precalc<TK, TH>(dm_bandgap,
429+
lmaxd,
430+
inlmax,
431+
nat,
432+
nks,
433+
inl2l,
434+
kvec_d,
435+
phialpha,
436+
gevdm,
437+
inl_index,
438+
ucell,
439+
orb,
440+
*ParaV,
441+
GridD,
442+
orbital_precalc);
443+
DeePKS_domain::cal_o_delta<TK, TH>(dm_bandgap, *h_delta, o_delta, *ParaV, nks, nspin);
444+
445+
// save obase and orbital_precalc
446+
const std::string file_orbpre = PARAM.globalv.global_out_dir + "deepks_orbpre.npy";
447+
LCAO_deepks_io::save_tensor2npy<double>(file_orbpre, orbital_precalc, rank);
448+
449+
const std::string file_obase = PARAM.globalv.global_out_dir + "deepks_obase.npy";
450+
LCAO_deepks_io::save_matrix2npy(file_obase, o_tot - o_delta, rank); // Unit: Hartree
451+
} // end deepks_scf == 1
452+
else // deepks_scf == 0
453+
{
454+
const std::string file_obase = PARAM.globalv.global_out_dir + "deepks_obase.npy";
455+
LCAO_deepks_io::save_matrix2npy(file_obase, o_tot, rank); // no scf, o_tot=o_base
456+
} // end deepks_scf == 0
457+
} // end deepks_out_labels == 1
458+
} // end bandgap label
459+
460+
if (PARAM.inp.deepks_bandgap == 4)
461+
{
462+
int natom_H = 0;
463+
for(int it = 0; it < ucell.ntype; it++)
464+
{
465+
if(ucell.atoms[it].label == "H")
466+
{
467+
natom_H = ucell.atoms[it].na;
468+
break;
469+
}
470+
}
471+
const int nocc = (PARAM.inp.nelec - natom_H) / 2;
472+
ModuleBase::matrix o_tot(nks, 1);
473+
for (int iks = 0; iks < nks; ++iks)
474+
{
475+
// record band gap for each k point (including spin)
476+
o_tot(iks, 0) = ekb(iks, nocc) - ekb(iks, nocc - 1);
477+
}
478+
479+
const std::string file_otot
480+
= PARAM.globalv.global_out_dir
481+
+ (PARAM.inp.deepks_out_labels == 1 ? "deepks_otot.npy" : "deepks_orbital.npy");
482+
LCAO_deepks_io::save_matrix2npy(file_otot, o_tot, rank); // Unit: Hartree
483+
484+
if (PARAM.inp.deepks_out_labels == 1) // don't need these when deepks_out_labels == 2
485+
{
486+
if (PARAM.inp.deepks_scf)
487+
{
488+
ModuleBase::matrix wg_hl;
489+
std::vector<TH> dm_bandgap;
490+
491+
// Calculate O_delta
492+
wg_hl.create(nks, PARAM.inp.nbands);
493+
dm_bandgap.resize(nks);
494+
wg_hl.zero_out();
495+
for (int iks = 0; iks < nks; ++iks)
496+
{
497+
wg_hl(iks, nocc - 1) = -1.0;
498+
wg_hl(iks, nocc) = 1.0;
499+
}
500+
elecstate::cal_dm(ParaV, wg_hl, psi, dm_bandgap);
501+
502+
ModuleBase::matrix o_delta(nks, 1);
503+
504+
// calculate and save orbital_precalc: [nks,NAt,NDscrpt]
505+
torch::Tensor orbital_precalc;
506+
DeePKS_domain::cal_orbital_precalc<TK, TH>(dm_bandgap,
507+
lmaxd,
508+
inlmax,
509+
nat,
510+
nks,
511+
inl2l,
512+
kvec_d,
513+
phialpha,
514+
gevdm,
515+
inl_index,
516+
ucell,
517+
orb,
518+
*ParaV,
519+
GridD,
520+
orbital_precalc);
521+
DeePKS_domain::cal_o_delta<TK, TH>(dm_bandgap, *h_delta, o_delta, *ParaV, nks, nspin);
522+
523+
// save obase and orbital_precalc
524+
const std::string file_orbpre = PARAM.globalv.global_out_dir + "deepks_orbpre.npy";
525+
LCAO_deepks_io::save_tensor2npy<double>(file_orbpre, orbital_precalc, rank);
526+
527+
const std::string file_obase = PARAM.globalv.global_out_dir + "deepks_obase.npy";
528+
LCAO_deepks_io::save_matrix2npy(file_obase, o_tot - o_delta, rank); // Unit: Hartree
529+
} // end deepks_scf == 1
530+
else // deepks_scf == 0
531+
{
532+
const std::string file_obase = PARAM.globalv.global_out_dir + "deepks_obase.npy";
533+
LCAO_deepks_io::save_matrix2npy(file_obase, o_tot, rank); // no scf, o_tot=o_base
534+
} // end deepks_scf == 0
535+
} // end deepks_out_labels == 1
536+
} // end bandgap label
537+
276538
// not add deepks_out_labels = 2 for HR yet
277539
// H(R) matrix part, for HR, base will not be calculated since they are HContainer objects
278540
if (PARAM.inp.deepks_v_delta < 0)

source/module_io/read_input_item_deepks.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,17 @@ void ReadInput::item_deepks()
4747
{
4848
Input_Item item("deepks_bandgap");
4949
item.annotation = ">0 for bandgap label";
50-
read_sync_bool(input.deepks_bandgap);
50+
read_sync_int(input.deepks_bandgap);
51+
this->add_item(item);
52+
}
53+
{
54+
Input_Item item("deepks_band_range");
55+
item.annotation = "(int, int) range of bands for bandgap label";
56+
item.read_value = [](const Input_Item& item, Parameter& para) {
57+
para.input.deepks_band_range[0] = std::stod(item.str_values[0]);
58+
para.input.deepks_band_range[1] = std::stod(item.str_values[1]);
59+
};
60+
sync_intvec(input.deepks_band_range, 2, 0);
5161
this->add_item(item);
5262
}
5363
{
@@ -142,4 +152,4 @@ void ReadInput::item_deepks()
142152
this->add_item(item);
143153
}
144154
}
145-
} // namespace ModuleIO
155+
} // namespace ModuleIO

source/module_parameter/input_parameter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ struct Input_para
264264
///< descriptors for training, wenfei 2022-1-12
265265
bool deepks_scf = false; ///< (need libnpy and libtorch) if set to true, a trained model
266266
///< would be needed to calculate V_delta and F_delta
267-
bool deepks_bandgap = false; ///< for bandgap label. QO added 2021-12-15
267+
int deepks_bandgap = 0; ///< for bandgap label. QO added 2021-12-15
268+
std::vector<int> deepks_band_range = {0, 0}; ///< the range of bands to calculate bandgap
268269
int deepks_v_delta = 0; ///< for v_delta label. xuan added
269270
bool deepks_equiv = false; ///< whether to use equivariant version of DeePKS
270271
bool deepks_out_unittest = false; ///< if set to true, prints intermediate quantities that shall
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
INPUT_PARAMETERS
2+
suffix autotest
3+
calculation scf
4+
5+
ecutwfc 50
6+
scf_thr 1e-6
7+
scf_nmax 35
8+
pseudo_dir ../../PP_ORB
9+
orbital_dir ../../PP_ORB
10+
basis_type lcao
11+
dft_functional lda
12+
gamma_only 1
13+
mixing_type broyden
14+
mixing_beta 0.8
15+
smearing_method gaussian
16+
smearing_sigma 0.02
17+
18+
cal_force 0
19+
cal_stress 0
20+
deepks_scf 1
21+
deepks_model ../Model_ProjOrb/model_lda_pbe_18.ptg
22+
deepks_out_labels 1
23+
deepks_bandgap 2
24+
deepks_band_range -1 0
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
K_POINTS
2+
0
3+
Gamma
4+
1 1 1 0 0 0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test bandgap label (deepks_bandgap = 2) output for deepks_out_labels = 1, for gamma_only H2O molecule

0 commit comments

Comments
 (0)