Skip to content

Commit 95f6450

Browse files
authored
Fix: Robust handling of bandgap boundary conditions in ElecState and add unit tests (deepmodeling#6917)
* add change * add numrial fast * add check for cal_bandgap Boundary * Revert "add change" This reverts commit 78444e9. * add back mlago * add back mlago format
1 parent c243e11 commit 95f6450

2 files changed

Lines changed: 73 additions & 2 deletions

File tree

source/source_estate/elecstate_energy.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,16 @@ void ElecState::cal_bandgap()
3737
}
3838
}
3939
}
40-
40+
// Assign fermi level to CBM if it's still infinity
41+
if(cbm == std::numeric_limits<double>::infinity())
42+
{
43+
cbm =this->eferm.ef;
44+
}
45+
// Assign fermi level to VBM if it's still negative infinity
46+
if(vbm ==-std::numeric_limits<double>::infinity())
47+
{
48+
vbm =this->eferm.ef;
49+
}
4150
#ifdef __MPI
4251
Parallel_Reduce::gather_max_double_all(GlobalV::NPROC, vbm);
4352
Parallel_Reduce::gather_min_double_all(GlobalV::NPROC, cbm);
@@ -92,6 +101,24 @@ void ElecState::cal_bandgap_updw()
92101
}
93102
}
94103
}
104+
// Assign fermi level to CBM if it's still infinity
105+
if (cbm_up == std::numeric_limits<double>::infinity())
106+
{
107+
cbm_up =this->eferm.ef_up;
108+
}
109+
if (cbm_dw == std::numeric_limits<double>::infinity())
110+
{
111+
cbm_dw =this->eferm.ef_dw;
112+
}
113+
// Assign fermi level to VBM if it's still negative infinity
114+
if(vbm_up ==-std::numeric_limits<double>::infinity())
115+
{
116+
vbm_up =this->eferm.ef_up;
117+
}
118+
if(vbm_dw ==-std::numeric_limits<double>::infinity())
119+
{
120+
vbm_dw =this->eferm.ef_dw;
121+
}
95122

96123
#ifdef __MPI
97124
Parallel_Reduce::gather_max_double_all(GlobalV::NPROC, vbm_up);

source/source_estate/test/elecstate_energy_test.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#include "gmock/gmock.h"
32
#include "gtest/gtest.h"
43
#define private public
@@ -242,3 +241,48 @@ TEST_F(ElecStateEnergyTest, CalBandgapUpDw)
242241
EXPECT_DOUBLE_EQ(elecstate->bandgap_up, 1.0);
243242
EXPECT_DOUBLE_EQ(elecstate->bandgap_dw, 0.5);
244243
}
244+
245+
TEST_F(ElecStateEnergyTest, CalBandgapBoundaryConditions)
246+
{
247+
K_Vectors* klist = new K_Vectors;
248+
klist->set_nks(1);
249+
elecstate->klist = klist;
250+
elecstate->ekb.create(1, 1);
251+
252+
// Case 1: Only VBM found (all bands below Fermi level)
253+
elecstate->ekb(0, 0) = -5.0;
254+
elecstate->eferm.ef = 0.0;
255+
elecstate->cal_bandgap();
256+
// Only VBM found, CBM is set to eferm.ef, so bandgap should be eferm.ef - vbm
257+
EXPECT_DOUBLE_EQ(elecstate->bandgap, 5.0);
258+
259+
// Case 2: Only CBM found (all bands above Fermi level)
260+
elecstate->ekb(0, 0) = 5.0;
261+
elecstate->eferm.ef = 0.0;
262+
elecstate->cal_bandgap();
263+
// Only CBM found, VBM is set to eferm.ef, so bandgap should be cbm - eferm.ef
264+
EXPECT_DOUBLE_EQ(elecstate->bandgap, 5.0);
265+
}
266+
267+
TEST_F(ElecStateEnergyTest, CalBandgapUpDwBoundaryConditions)
268+
{
269+
K_Vectors* klist = new K_Vectors;
270+
klist->set_nks(2);
271+
klist->isk.resize(2);
272+
klist->isk[0] = 0; // spin up
273+
klist->isk[1] = 1; // spin down
274+
elecstate->klist = klist;
275+
elecstate->ekb.create(2, 1); // 2 k-points, 1 band
276+
277+
// Spin UP: Only VBM (band < ef)
278+
elecstate->ekb(0, 0) = -5.0;
279+
elecstate->eferm.ef_up = 0.0;
280+
// Spin DW: Only CBM (band > ef)
281+
elecstate->ekb(1, 0) = 5.0;
282+
elecstate->eferm.ef_dw = 0.0;
283+
elecstate->cal_bandgap_updw();
284+
// up: Only VBM found, CBM is set to eferm.ef_up, so gap should be eferm.ef_up - vbm_up
285+
// dw: Only CBM found, VBM is set to eferm.ef_dw, so gap should be cbm_dw - eferm.ef_dw
286+
EXPECT_DOUBLE_EQ(elecstate->bandgap_up, 5.0);
287+
EXPECT_DOUBLE_EQ(elecstate->bandgap_dw, 5.0);
288+
}

0 commit comments

Comments
 (0)