Skip to content

Commit 115a989

Browse files
authored
Feature: support segment split in kline mode in KPT file and out_band band output precision control, 8 as default (#3493)
* add precision control * correct serial version of nscf_band function * fix issue 3482 * update unit and integrated test * update document * correct unittest and make compatible with false and true
1 parent 22cfc0b commit 115a989

File tree

19 files changed

+140
-69
lines changed

19 files changed

+140
-69
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,8 +1494,8 @@ These variables are used to control the output of properties.
14941494

14951495
### out_band
14961496

1497-
- **Type**: Boolean
1498-
- **Description**: Whether to output the band structure (in eV). For more information, refer to the [band.md](../elec_properties/band.md)
1497+
- **Type**: Boolean Integer(optional)
1498+
- **Description**: Whether to output the band structure (in eV), optionally output precision can be set by a second parameter, default is 8. For more information, refer to the [band.md](../elec_properties/band.md)
14991499
- **Default**: False
15001500

15011501
### out_proj_band

source/module_cell/klist.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ bool K_Vectors::read_kpoints(const std::string &fn)
362362

363363
//recalculate nkstot.
364364
nkstot = 0;
365+
/* ISSUE#3482: to distinguish different kline segments */
366+
std::vector<int> kpt_segids;
367+
kl_segids.clear(); kl_segids.shrink_to_fit();
368+
int kpt_segid = 0;
365369
for(int iks=0; iks<nks_special; iks++)
366370
{
367371
ifk >> ksx[iks];
@@ -371,6 +375,9 @@ bool K_Vectors::read_kpoints(const std::string &fn)
371375
//std::cout << " nkl[" << iks << "]=" << nkl[iks] << std::endl;
372376
assert(nkl[iks] >= 0);
373377
nkstot += nkl[iks];
378+
/* ISSUE#3482: to distinguish different kline segments */
379+
if((nkl[iks] == 1)&&(iks!=(nks_special-1))) kpt_segid++;
380+
kpt_segids.push_back(kpt_segid);
374381
}
375382
assert( nkl[nks_special-1] == 1);
376383

@@ -389,6 +396,7 @@ bool K_Vectors::read_kpoints(const std::string &fn)
389396
kvec_c[count].x = ksx[iks-1] + is*dx;
390397
kvec_c[count].y = ksy[iks-1] + is*dy;
391398
kvec_c[count].z = ksz[iks-1] + is*dz;
399+
kl_segids.push_back(kpt_segids[iks-1]); /* ISSUE#3482: to distinguish different kline segments */
392400
++count;
393401
}
394402
}
@@ -397,15 +405,14 @@ bool K_Vectors::read_kpoints(const std::string &fn)
397405
kvec_c[count].x = ksx[nks_special-1];
398406
kvec_c[count].y = ksy[nks_special-1];
399407
kvec_c[count].z = ksz[nks_special-1];
408+
kl_segids.push_back(kpt_segids[nks_special-1]); /* ISSUE#3482: to distinguish different kline segments */
400409
++count;
401410

402411
//std::cout << " count = " << count << std::endl;
403-
assert (count == nkstot );
404-
405-
for(int ik=0; ik<nkstot; ik++)
406-
{
407-
wk[ik] = 1.0;
408-
}
412+
assert(count == nkstot);
413+
assert(kl_segids.size() == nkstot); /* ISSUE#3482: to distinguish different kline segments */
414+
415+
std::for_each(wk.begin(), wk.end(), [](double& d){d = 1.0;});
409416

410417
this->kc_done = true;
411418

@@ -439,15 +446,22 @@ bool K_Vectors::read_kpoints(const std::string &fn)
439446

440447
//recalculate nkstot.
441448
nkstot = 0;
449+
/* ISSUE#3482: to distinguish different kline segments */
450+
std::vector<int> kpt_segids;
451+
kl_segids.clear(); kl_segids.shrink_to_fit();
452+
int kpt_segid = 0;
442453
for(int iks=0; iks<nks_special; iks++)
443454
{
444455
ifk >> ksx[iks];
445456
ifk >> ksy[iks];
446457
ifk >> ksz[iks];
447-
ModuleBase::GlobalFunc::READ_VALUE( ifk, nkl[iks] );
458+
ModuleBase::GlobalFunc::READ_VALUE( ifk, nkl[iks] ); /* so ifk is ifstream for kpoint, then nkl is number of kpoints on line */
448459
//std::cout << " nkl[" << iks << "]=" << nkl[iks] << std::endl;
449460
assert(nkl[iks] >= 0);
450461
nkstot += nkl[iks];
462+
/* ISSUE#3482: to distinguish different kline segments */
463+
if((nkl[iks] == 1)&&(iks!=(nks_special-1))) kpt_segid++;
464+
kpt_segids.push_back(kpt_segid);
451465
}
452466
assert( nkl[nks_special-1] == 1);
453467

@@ -466,6 +480,7 @@ bool K_Vectors::read_kpoints(const std::string &fn)
466480
kvec_d[count].x = ksx[iks-1] + is*dx;
467481
kvec_d[count].y = ksy[iks-1] + is*dy;
468482
kvec_d[count].z = ksz[iks-1] + is*dz;
483+
kl_segids.push_back(kpt_segids[iks-1]); /* ISSUE#3482: to distinguish different kline segments */
469484
++count;
470485
}
471486
}
@@ -474,18 +489,16 @@ bool K_Vectors::read_kpoints(const std::string &fn)
474489
kvec_d[count].x = ksx[nks_special-1];
475490
kvec_d[count].y = ksy[nks_special-1];
476491
kvec_d[count].z = ksz[nks_special-1];
492+
kl_segids.push_back(kpt_segids[nks_special-1]); /* ISSUE#3482: to distinguish different kline segments */
477493
++count;
478494

479495
//std::cout << " count = " << count << std::endl;
480-
assert (count == nkstot );
496+
assert(count == nkstot );
497+
assert(kl_segids.size() == nkstot); /* ISSUE#3482: to distinguish different kline segments */
481498

482-
for(int ik=0; ik<nkstot; ik++)
483-
{
484-
wk[ik] = 1.0;
485-
}
499+
std::for_each(wk.begin(), wk.end(), [](double& d){d = 1.0;});
486500

487501
this->kd_done = true;
488-
489502
}
490503

491504
else
@@ -1122,6 +1135,9 @@ void K_Vectors::mpi_k(void)
11221135

11231136
Parallel_Common::bcast_int(nmp, 3);
11241137

1138+
kl_segids.resize(nkstot);
1139+
Parallel_Common::bcast_int(kl_segids.data(), nkstot);
1140+
11251141
Parallel_Common::bcast_double(koffset, 3);
11261142

11271143
this->nks = GlobalC::Pkpoints.nks_pool[GlobalV::MY_POOL];
@@ -1352,6 +1368,8 @@ void K_Vectors::mpi_k_after_vc(void)
13521368
Parallel_Common::bcast_int(nspin);
13531369
Parallel_Common::bcast_int(nkstot);
13541370
Parallel_Common::bcast_int(nmp, 3);
1371+
kl_segids.resize(nkstot);
1372+
Parallel_Common::bcast_int(kl_segids.data(), nkstot);
13551373
Parallel_Common::bcast_double(koffset, 3);
13561374

13571375
this->nks = GlobalC::Pkpoints.nks_pool[GlobalV::MY_POOL];

source/module_cell/klist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class K_Vectors
2929
int nkstot_full; /// number of k points in full k mesh
3030

3131
int nmp[3]; // Number of Monhorst-Pack
32+
std::vector<int> kl_segids; // index of kline segment
3233

3334
K_Vectors();
3435
~K_Vectors();

source/module_esolver/esolver_ks_lcao.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ namespace ModuleESolver
309309
GlobalV::ofs_running << " !FINAL_ETOT_IS " << this->pelec->f_en.etot * ModuleBase::Ry_to_eV << " eV" << std::endl;
310310
GlobalV::ofs_running << " --------------------------------------------\n\n" << std::endl;
311311

312-
if (INPUT.out_dos != 0 || INPUT.out_band != 0 || INPUT.out_proj_band != 0)
312+
if (INPUT.out_dos != 0 || INPUT.out_band[0] != 0 || INPUT.out_proj_band != 0)
313313
{
314314
GlobalV::ofs_running << "\n\n\n\n";
315315
GlobalV::ofs_running << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
@@ -331,7 +331,7 @@ namespace ModuleESolver
331331

332332
int nspin0 = (GlobalV::NSPIN == 2) ? 2 : 1;
333333

334-
if (INPUT.out_band) // pengfei 2014-10-13
334+
if (INPUT.out_band[0]) // pengfei 2014-10-13
335335
{
336336
int nks = 0;
337337
if (nspin0 == 1)
@@ -348,7 +348,15 @@ namespace ModuleESolver
348348
std::stringstream ss2;
349349
ss2 << GlobalV::global_out_dir << "BANDS_" << is + 1 << ".dat";
350350
GlobalV::ofs_running << "\n Output bands in file: " << ss2.str() << std::endl;
351-
ModuleIO::nscf_band(is, ss2.str(), nks, GlobalV::NBANDS, 0.0, this->pelec->ekb, this->kv, &(GlobalC::Pkpoints));
351+
ModuleIO::nscf_band(is,
352+
ss2.str(),
353+
nks,
354+
GlobalV::NBANDS,
355+
0.0,
356+
INPUT.out_band[1],
357+
this->pelec->ekb,
358+
this->kv,
359+
&(GlobalC::Pkpoints));
352360
}
353361
} // out_band
354362

source/module_esolver/esolver_ks_pw.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ void ESolver_KS_PW<T, Device>::postprocess()
959959
GlobalV::ofs_running << " !FINAL_ETOT_IS " << this->pelec->f_en.etot * ModuleBase::Ry_to_eV << " eV" << std::endl;
960960
GlobalV::ofs_running << " --------------------------------------------\n\n" << std::endl;
961961

962-
if (INPUT.out_dos != 0 || INPUT.out_band != 0)
962+
if (INPUT.out_dos != 0 || INPUT.out_band[0] != 0)
963963
{
964964
GlobalV::ofs_running << "\n\n\n\n";
965965
GlobalV::ofs_running << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << std::endl;
@@ -1001,7 +1001,7 @@ void ESolver_KS_PW<T, Device>::postprocess()
10011001
}
10021002
}
10031003

1004-
if (INPUT.out_band) // pengfei 2014-10-13
1004+
if (INPUT.out_band[0]) // pengfei 2014-10-13
10051005
{
10061006
int nks = 0;
10071007
if (nspin0 == 1)
@@ -1022,6 +1022,7 @@ void ESolver_KS_PW<T, Device>::postprocess()
10221022
nks,
10231023
GlobalV::NBANDS,
10241024
0.0,
1025+
INPUT.out_band[1],
10251026
this->pelec->ekb,
10261027
this->kv,
10271028
&(GlobalC::Pkpoints));

source/module_io/input.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ void Input::Default(void)
336336
out_wfc_pw = 0;
337337
out_wfc_r = 0;
338338
out_dos = 0;
339-
out_band = 0;
339+
out_band = {0, 8};
340340
out_proj_band = 0;
341341
out_mat_hs = {0, 8};
342342
out_mat_xc = 0;
@@ -1378,13 +1378,13 @@ bool Input::Read(const std::string& fn)
13781378
}
13791379
else if (strcmp("out_band", word) == 0)
13801380
{
1381-
read_bool(ifs, out_band);
1381+
read_value2stdvector(ifs, out_band);
1382+
if(out_band.size() == 1) out_band.push_back(8);
13821383
}
13831384
else if (strcmp("out_proj_band", word) == 0)
13841385
{
13851386
read_bool(ifs, out_proj_band);
13861387
}
1387-
13881388
else if (strcmp("out_mat_hs", word) == 0)
13891389
{
13901390
read_value2stdvector(ifs, out_mat_hs);
@@ -2826,7 +2826,7 @@ void Input::Default_2(void) // jiyy add 2019-08-04
28262826
this->relax_nmax = 1;
28272827
out_stru = 0;
28282828
out_dos = 0;
2829-
out_band = 0;
2829+
out_band[0] = 0;
28302830
out_proj_band = 0;
28312831
cal_force = 0;
28322832
init_wfc = "file";
@@ -2843,7 +2843,7 @@ void Input::Default_2(void) // jiyy add 2019-08-04
28432843
this->relax_nmax = 1;
28442844
out_stru = 0;
28452845
out_dos = 0;
2846-
out_band = 0;
2846+
out_band[0] = 0;
28472847
out_proj_band = 0;
28482848
cal_force = 0;
28492849
init_wfc = "file";
@@ -3325,7 +3325,8 @@ void Input::Bcast()
33253325
Parallel_Common::bcast_int(out_wfc_pw);
33263326
Parallel_Common::bcast_bool(out_wfc_r);
33273327
Parallel_Common::bcast_int(out_dos);
3328-
Parallel_Common::bcast_bool(out_band);
3328+
if(GlobalV::MY_RANK != 0) out_band.resize(2); /* If this line is absent, will cause segmentation fault in io_input_test_para */
3329+
Parallel_Common::bcast_int(out_band.data(), 2);
33293330
Parallel_Common::bcast_bool(out_proj_band);
33303331
if(GlobalV::MY_RANK != 0) out_mat_hs.resize(2); /* If this line is absent, will cause segmentation fault in io_input_test_para */
33313332
Parallel_Common::bcast_int(out_mat_hs.data(), 2);

source/module_io/input.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ class Input
263263
int out_wfc_pw; // 0: no; 1: txt; 2: dat
264264
bool out_wfc_r; // 0: no; 1: yes
265265
int out_dos; // dos calculation. mohan add 20090909
266-
bool out_band; // band calculation pengfei 2014-10-13
266+
std::vector<int> out_band; // band calculation pengfei 2014-10-13
267267
bool out_proj_band; // projected band structure calculation jiyy add 2022-05-11
268268
std::vector<int> out_mat_hs; // output H matrix and S matrix in local basis.
269269
bool out_mat_xc; // output exchange-correlation matrix in KS-orbital representation.
@@ -667,7 +667,15 @@ class Input
667667
template <typename T>
668668
typename std::enable_if<std::is_same<T, double>::value, T>::type cast_string(const std::string& str) { return std::stod(str); }
669669
template <typename T>
670-
typename std::enable_if<std::is_same<T, int>::value, T>::type cast_string(const std::string& str) { return std::stoi(str); }
670+
typename std::enable_if<std::is_same<T, int>::value, T>::type cast_string(const std::string& str)
671+
{
672+
if (str == "true" || str == "1")
673+
return 1;
674+
else if (str == "false" || str == "0")
675+
return 0;
676+
else
677+
return std::stoi(str);
678+
}
671679
template <typename T>
672680
typename std::enable_if<std::is_same<T, bool>::value, T>::type cast_string(const std::string& str) { return (str == "true" || str == "1"); }
673681
template <typename T>

source/module_io/nscf_band.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#include "module_base/global_variable.h"
44
#include "module_base/timer.h"
55
#include "module_base/tool_title.h"
6+
#include "module_base/formatter_physfmt.h"
67

78
void ModuleIO::nscf_band(
89
const int &is,
910
const std::string &out_band_dir,
1011
const int &nks,
1112
const int &nband,
1213
const double &fermie,
14+
const int &precision,
1315
const ModuleBase::matrix& ekb,
1416
const K_Vectors& kv,
1517
const Parallel_Kpoints* Pkpoints)
@@ -33,23 +35,28 @@ void ModuleIO::nscf_band(
3335
if (ik>0)
3436
{
3537
auto delta=kv.kvec_c[ik]-kv.kvec_c[ik-1];
36-
klength[ik] = klength[ik-1] + delta.norm();
38+
klength[ik] = klength[ik-1];
39+
klength[ik] += (kv.kl_segids[ik] == kv.kl_segids[ik-1]) ? delta.norm() : 0.0;
3740
}
41+
/* first find if present kpoint in present pool */
3842
if ( GlobalV::MY_POOL == Pkpoints->whichpool[ik] )
3943
{
44+
/* then get the local kpoint index, which starts definitly from 0 */
4045
const int ik_now = ik - Pkpoints->startk_pool[GlobalV::MY_POOL];
46+
/* if present kpoint corresponds the spin of the present one */
4147
if( kv.isk[ik_now+is*nks] == is )
4248
{
4349
if ( GlobalV::RANK_IN_POOL == 0)
4450
{
45-
std::ofstream ofs(out_band_dir.c_str(),std::ios::app);
46-
ofs << std::setprecision(8);
47-
//start from 1
48-
ofs << ik+1;
49-
ofs << " " << klength[ik] << " ";
51+
formatter::PhysicalFmt physfmt; // create a physical formatter temporarily
52+
std::ofstream ofs(out_band_dir.c_str(), std::ios::app);
53+
physfmt.adjust_formatter_flexible(4, 0, false); // for integer
54+
ofs << physfmt.get_p_formatter()->format(ik+1);
55+
physfmt.adjust_formatter_flexible(precision, 4.0/double(precision), false); // for decimal
56+
ofs << physfmt.get_p_formatter()->format(klength[ik]);
5057
for(int ib = 0; ib < nband; ib++)
5158
{
52-
ofs << " " << (ekb(ik_now+is*nks, ib)-fermie) * ModuleBase::Ry_to_eV;
59+
ofs << physfmt.get_p_formatter()->format((ekb(ik_now+is*nks, ib)-fermie) * ModuleBase::Ry_to_eV);
5360
}
5461
ofs << std::endl;
5562
ofs.close();
@@ -83,18 +90,30 @@ void ModuleIO::nscf_band(
8390
#else
8491
// std::cout<<"\n nband = "<<nband<<std::endl;
8592
// std::cout<<out_band_dir<<std::endl;
86-
93+
formatter::PhysicalFmt physfmt; // create a physical formatter temporarily
94+
std::vector<double> klength;
95+
klength.resize(nks);
96+
klength[0] = 0.0;
8797
std::ofstream ofs(out_band_dir.c_str());
8898
for(int ik=0;ik<nks;ik++)
8999
{
100+
if (ik>0)
101+
{
102+
auto delta=kv.kvec_c[ik]-kv.kvec_c[ik-1];
103+
klength[ik] = klength[ik-1];
104+
klength[ik] += (kv.kl_segids[ik] == kv.kl_segids[ik-1]) ? delta.norm() : 0.0;
105+
}
90106
if( kv.isk[ik] == is)
91107
{
92-
ofs<<std::setw(12)<<ik + 1;
108+
physfmt.adjust_formatter_flexible(4, 0, false); // for integer
109+
ofs << physfmt.get_p_formatter()->format(ik+1);
110+
physfmt.adjust_formatter_flexible(precision, 4.0/double(precision), false); // for decimal
111+
ofs << physfmt.get_p_formatter()->format(klength[ik]); // add klength, in accordance with the MPI version
93112
for(int ibnd = 0; ibnd < nband; ibnd++)
94113
{
95-
ofs <<std::setw(15) << (ekb(ik, ibnd)-fermie) * ModuleBase::Ry_to_eV;
114+
ofs << physfmt.get_p_formatter()->format((ekb(ik, ibnd)-fermie) * ModuleBase::Ry_to_eV);
96115
}
97-
ofs<<std::endl;
116+
ofs << std::endl;
98117
}
99118
}
100119
ofs.close();

source/module_io/nscf_band.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace ModuleIO
1212
const int &nks,
1313
const int &nband,
1414
const double &fermie,
15+
const int &precision,
1516
const ModuleBase::matrix &ekb,
1617
const K_Vectors& kv,
1718
const Parallel_Kpoints* Pkpoints);

source/module_io/parameter_pool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ bool input_parameters_set(std::map<std::string, InputParameter> input_parameters
917917
}
918918
else if (input_parameters.count("out_band") != 0)
919919
{
920-
INPUT.out_band = *static_cast<bool*>(input_parameters["out_band"].get());
920+
INPUT.out_band = *static_cast<std::vector<int>*>(input_parameters["out_band"].get());
921921
}
922922
else if (input_parameters.count("out_proj_band") != 0)
923923
{

0 commit comments

Comments
 (0)