Skip to content

Commit f19f00c

Browse files
author
Zanthoxylum
committed
Refactor DFPT serial tests: derive pert/rho/phon/q0 fixtures from a shared DFPTSerialBase (cell/basis/data setup, Coulomb/NC atom builders, analytic dVloc reference)
1 parent 4f451c4 commit f19f00c

7 files changed

Lines changed: 318 additions & 447 deletions

File tree

source/source_pw/module_dfpt/test_serial/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ AddTest(
4141
# Shared ctor/dtor stubs for the cell/spepot/Plus_U link closures
4242
# (see test/dfpt_test_mocks.cpp).
4343
../test/dfpt_test_mocks.cpp
44+
# Shared serial-side cell/basis/data fixture.
45+
dfpt_serial_fixture.cpp
4446
)
4547

4648
AddTest(
@@ -56,6 +58,8 @@ AddTest(
5658
# Shared ctor/dtor stubs for the cell/spepot/Plus_U link closures
5759
# (see test/dfpt_test_mocks.cpp).
5860
../test/dfpt_test_mocks.cpp
61+
# Shared serial-side cell/basis/data fixture.
62+
dfpt_serial_fixture.cpp
5963
)
6064

6165
AddTest(
@@ -72,6 +76,8 @@ AddTest(
7276
# Shared ctor/dtor stubs for the cell/spepot/Plus_U link closures
7377
# (see test/dfpt_test_mocks.cpp).
7478
../test/dfpt_test_mocks.cpp
79+
# Shared serial-side cell/basis/data fixture.
80+
dfpt_serial_fixture.cpp
7581
)
7682

7783
AddTest(
@@ -88,4 +94,6 @@ AddTest(
8894
# Shared ctor/dtor stubs for the cell/spepot/Plus_U link closures
8995
# (see test/dfpt_test_mocks.cpp).
9096
../test/dfpt_test_mocks.cpp
97+
# Shared serial-side cell/basis/data fixture.
98+
dfpt_serial_fixture.cpp
9199
)

source/source_pw/module_dfpt/test_serial/dfpt_pert_serial_test.cpp

Lines changed: 3 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "source_base/vector3.h"
2828
#include "source_pw/module_pwdft/dftu_base.h"
2929
#include "source_psi/psi.h"
30+
#include "dfpt_serial_fixture.h"
3031

3132
// ctor/dtor stubs for the cell/spepot/stru_fac link closures live in the
3233
// shared test/dfpt_test_mocks.cpp compiled into every DFPT test binary.
@@ -53,162 +54,17 @@
5354
* - build_dv under with_u()/u_active()==false (pure-PW DFT+U safety).
5455
*/
5556

56-
class DFPTPertSerialTest : public testing::Test
57+
class DFPTPertSerialTest : public DFPTSerialBase
5758
{
5859
protected:
59-
const double lat0_ = 1.8897261254578281;
60-
const double ecutwfc_ = 2.5; // Ry
61-
// rho cutoff inflated to 9x ecutwfc so every Delta = G''-G' of the
62-
// convolution lies inside the rho ball and nothing aliases
63-
const double rho_mult_ = 9.0;
64-
65-
ModuleBase::Matrix3 latvec_;
66-
UnitCell ucell_;
67-
ModulePW::PW_Basis pw_rho_;
68-
ModulePW::PW_Basis_K pw_wfc_;
6960
Structure_Factor sf_;
7061
ModuleDFPT::DFPT_Pert pert_;
71-
ModuleCell::QList qlist_;
72-
ModuleDFPT::DFPT_PW_Data data_;
73-
74-
// q is generic; k = -q so k+q = 0: the k+q ball then stays inside the
75-
// ground-state G list (single-k limitation documented in DFPT_KQ_Basis)
76-
const ModuleBase::Vector3<double> q_d_{0.13, 0.0, 0.07};
77-
const ModuleBase::Vector3<double> k_d_{-0.13, 0.0, -0.07};
78-
ModuleBase::Vector3<double> q_cart_;
79-
const ModuleBase::Vector3<double> tau_{1.1, 2.3, 0.7}; // lat0 units
8062

8163
void SetUp() override
8264
{
83-
latvec_ = ModuleBase::Matrix3(10.0, 0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 10.0);
84-
ucell_.ntype = 1;
85-
ucell_.nat = 1;
86-
ucell_.atoms = new Atom[1];
87-
ucell_.atoms[0].na = 1;
88-
ucell_.atoms[0].tau.resize(1);
89-
ucell_.atoms[0].tau[0] = tau_;
90-
ucell_.latvec = latvec_;
91-
ucell_.GT = latvec_.Inverse();
92-
ucell_.G = ucell_.GT.Transpose();
93-
ucell_.lat0 = lat0_;
94-
ucell_.tpiba = ModuleBase::TWO_PI / lat0_;
95-
ucell_.tpiba2 = ucell_.tpiba * ucell_.tpiba;
96-
ucell_.omega = 1000.0 * lat0_ * lat0_ * lat0_;
97-
MakeCoulombAtom();
98-
99-
// shared-grid basis setup, mirroring setup_pwrho / setup_pwwfc
100-
pw_rho_.initgrids(lat0_, latvec_, rho_mult_ * ecutwfc_);
101-
pw_rho_.initparameters(false, rho_mult_ * ecutwfc_);
102-
pw_rho_.fft_bundle.initfftmode(0);
103-
pw_rho_.setuptransform();
104-
pw_rho_.collect_local_pw();
105-
106-
const ModuleBase::Vector3<double> klist[1] = {k_d_};
107-
pw_wfc_.initgrids(lat0_, latvec_, pw_rho_.nx, pw_rho_.ny, pw_rho_.nz);
108-
pw_wfc_.initparameters(false, ecutwfc_, 1, klist);
109-
pw_wfc_.fft_bundle.initfftmode(0);
110-
pw_wfc_.setuptransform();
111-
pw_wfc_.collect_local_pw();
112-
113-
qlist_.nkstot = 1;
114-
qlist_.kvec_d.push_back(q_d_);
115-
q_cart_ = q_d_ * ucell_.G;
116-
117-
data_.init(&qlist_, 1, 2, pw_wfc_.npwk_max, pw_rho_.nrxx, 1, 1, nullptr);
65+
DFPTSerialBase::SetUp();
11866
pert_.init(ucell_, &pw_rho_, &pw_wfc_, sf_);
11967
}
120-
121-
void TearDown() override
122-
{
123-
delete[] ucell_.atoms;
124-
ucell_.atoms = nullptr;
125-
}
126-
127-
void MakeCoulombAtom()
128-
{
129-
Atom& at = ucell_.atoms[0];
130-
at.label = "C";
131-
at.coulomb_potential = true;
132-
at.ncpp.zv = 4.0;
133-
at.ncpp.tvanp = false;
134-
at.ncpp.has_so = false;
135-
at.ncpp.nbeta = 0;
136-
at.ncpp.nh = 0;
137-
at.ncpp.msh = 0;
138-
at.ncpp.kkbeta = 0;
139-
}
140-
141-
void MakeNCAtom()
142-
{
143-
Atom& at = ucell_.atoms[0];
144-
at.label = "Si";
145-
at.coulomb_potential = false;
146-
pseudo& p = at.ncpp;
147-
p.zv = 4.0;
148-
p.tvanp = false;
149-
p.has_so = false;
150-
p.nbeta = 2;
151-
p.lll = {0, 1};
152-
p.nh = 4;
153-
p.msh = 121;
154-
p.kkbeta = 121;
155-
p.r.resize(121);
156-
p.rab.resize(121);
157-
p.vloc_at.assign(121, 0.0);
158-
const double dx = 0.025;
159-
for (int i = 0; i < 121; ++i)
160-
{
161-
p.r[i] = i * dx;
162-
p.rab[i] = dx;
163-
}
164-
p.betar.create(2, 121);
165-
for (int i = 0; i < 121; ++i)
166-
{
167-
const double r = p.r[i];
168-
p.betar(0, i) = std::exp(-std::pow(r - 1.0, 2) / (2.0 * 0.3 * 0.3));
169-
p.betar(1, i) = std::exp(-std::pow(r - 1.2, 2) / (2.0 * 0.35 * 0.35));
170-
}
171-
p.dion.create(2, 2);
172-
p.dion(0, 0) = 0.8;
173-
p.dion(0, 1) = 0.15;
174-
p.dion(1, 0) = -0.25;
175-
p.dion(1, 1) = 1.1;
176-
}
177-
178-
// key of an integer FFT triple (gcar * a is integral on the cubic cell)
179-
long long FKey(int ix, int iy, int iz) const
180-
{
181-
return (static_cast<long long>(ix + 64) * 128 + (iy + 64)) * 128 + (iz + 64);
182-
}
183-
long long GKey(const ModuleBase::Vector3<double>& g) const
184-
{
185-
const double a = 10.0;
186-
return FKey(static_cast<int>(std::llround(g.x * a)),
187-
static_cast<int>(std::llround(g.y * a)),
188-
static_cast<int>(std::llround(g.z * a)));
189-
}
190-
191-
// analytic Coulomb local potential (Ry) at |g|^2 in bohr^-2, mirroring
192-
// vl_pw.cpp::vloc_coulomb independently of DFPT_Pert::vloc_at_g
193-
double VlocCoulomb(double g2_bohr) const
194-
{
195-
return -ucell_.atoms[0].ncpp.zv * ModuleBase::e2 * ModuleBase::FOUR_PI / ucell_.omega / g2_bohr;
196-
}
197-
198-
// analytic dVloc/dtau_alpha coefficient at displacement vector w (1/lat0);
199-
// GS structure-factor convention (stru_fac.cpp): exp(-i 2pi (g.tau)) and
200-
// dV/dtau = -i (Delta+q)_alpha tpiba Vloc exp(-i 2pi (Delta+q).tau)
201-
std::complex<double> AnalyticDVloc(int dir, const ModuleBase::Vector3<double>& w) const
202-
{
203-
const double w2 = w * w;
204-
if (w2 < 1.0e-12)
205-
{
206-
return std::complex<double>(0.0, 0.0);
207-
}
208-
const double arg = -ModuleBase::TWO_PI * (w * tau_);
209-
return std::complex<double>(0.0, -1.0) * (ucell_.tpiba * w[dir]) * VlocCoulomb(w2 * ucell_.tpiba2)
210-
* std::complex<double>(std::cos(arg), std::sin(arg));
211-
}
21268
};
21369

21470
TEST_F(DFPTPertSerialTest, RhoGvecMatchesDistributedGcar)

source/source_pw/module_dfpt/test_serial/dfpt_phon_serial_test.cpp

Lines changed: 11 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "source_base/matrix3.h"
2828
#include "source_base/vector3.h"
2929
#include "source_psi/psi.h"
30+
#include "dfpt_serial_fixture.h"
3031

3132
// ctor/dtor stubs for the cell/spepot/stru_fac link closures live in the
3233
// shared test/dfpt_test_mocks.cpp compiled into every DFPT test binary.
@@ -55,148 +56,29 @@
5556
* - check_sum_rule at Gamma.
5657
*/
5758

58-
class DFPTPhonSerialTest : public testing::Test
59+
class DFPTPhonSerialTest : public DFPTSerialBase
5960
{
6061
protected:
61-
const double lat0_ = 1.8897261254578281;
62-
const double ecutwfc_ = 2.5;
63-
const double rho_mult_ = 9.0;
64-
// cubic cell in lat0 units
65-
const double a_ = 10.0;
66-
67-
ModuleBase::Matrix3 latvec_;
68-
UnitCell ucell_;
69-
ModulePW::PW_Basis pw_rho_;
70-
ModulePW::PW_Basis_K pw_wfc_;
7162
Structure_Factor sf_;
7263
ModuleDFPT::DFPT_Pert pert_;
7364
ModuleDFPT::DFPT_Phon phon_;
74-
ModuleCell::QList qlist_;
75-
ModuleDFPT::DFPT_PW_Data data_;
76-
77-
const ModuleBase::Vector3<double> q_d_{0.13, 0.0, 0.07};
78-
const ModuleBase::Vector3<double> k_d_{-0.13, 0.0, -0.07};
79-
ModuleBase::Vector3<double> q_cart_;
80-
const ModuleBase::Vector3<double> tau_{1.1, 2.3, 0.7};
8165

8266
void SetUp() override
8367
{
84-
latvec_ = ModuleBase::Matrix3(a_, 0.0, 0.0, 0.0, a_, 0.0, 0.0, 0.0, a_);
85-
ucell_.ntype = 1;
86-
ucell_.nat = 1;
87-
ucell_.atoms = new Atom[1];
88-
ucell_.atoms[0].na = 1;
89-
ucell_.atoms[0].tau.resize(1);
90-
ucell_.atoms[0].tau[0] = tau_;
91-
ucell_.latvec = latvec_;
92-
ucell_.GT = latvec_.Inverse();
93-
ucell_.G = ucell_.GT.Transpose();
94-
ucell_.lat0 = lat0_;
95-
ucell_.tpiba = ModuleBase::TWO_PI / lat0_;
96-
ucell_.tpiba2 = ucell_.tpiba * ucell_.tpiba;
97-
ucell_.omega = a_ * a_ * a_ * lat0_ * lat0_ * lat0_;
98-
ucell_.iat2it = new int[1];
99-
ucell_.iat2ia = new int[1];
100-
ucell_.iat2it[0] = 0;
101-
ucell_.iat2ia[0] = 0;
102-
MakeCoulombAtom();
103-
104-
SetupBases(k_d_, q_d_);
68+
DFPTSerialBase::SetUp();
69+
SetupPhon(k_d_, q_d_);
10570
}
10671

107-
// (re)initialize the bases and module wiring for a given (k, q) pair;
108-
// SetUp uses the default (k_d_, q_d_) fixture values
109-
void SetupBases(const ModuleBase::Vector3<double>& k_d,
110-
const ModuleBase::Vector3<double>& q_d)
111-
{
112-
pw_rho_.initgrids(lat0_, latvec_, rho_mult_ * ecutwfc_);
113-
pw_rho_.initparameters(false, rho_mult_ * ecutwfc_);
114-
pw_rho_.fft_bundle.initfftmode(0);
115-
pw_rho_.setuptransform();
116-
pw_rho_.collect_local_pw();
117-
118-
const ModuleBase::Vector3<double> klist[1] = {k_d};
119-
pw_wfc_.initgrids(lat0_, latvec_, pw_rho_.nx, pw_rho_.ny, pw_rho_.nz);
120-
pw_wfc_.initparameters(false, ecutwfc_, 1, klist);
121-
pw_wfc_.fft_bundle.initfftmode(0);
122-
pw_wfc_.setuptransform();
123-
pw_wfc_.collect_local_pw();
124-
125-
qlist_.nkstot = 1;
126-
qlist_.kvec_d.clear();
127-
qlist_.kvec_d.push_back(q_d);
128-
q_cart_ = q_d * ucell_.G;
129-
130-
data_.init(&qlist_, 1, 2, pw_wfc_.npwk_max, pw_rho_.nrxx, 1, 1, nullptr);
72+
// (re)initialize the bases and the pert/phon wiring for a given (k, q)
73+
// pair; SetUp uses the default fixture values
74+
void SetupPhon(const ModuleBase::Vector3<double>& k_d,
75+
const ModuleBase::Vector3<double>& q_d)
76+
{
77+
SetupBases(k_d, q_d, 2);
13178
pert_.init(ucell_, &pw_rho_, &pw_wfc_, sf_);
13279
phon_.init(ucell_, &pw_rho_, &pert_);
13380
}
13481

135-
void TearDown() override
136-
{
137-
delete[] ucell_.atoms;
138-
ucell_.atoms = nullptr;
139-
delete[] ucell_.iat2it;
140-
ucell_.iat2it = nullptr;
141-
delete[] ucell_.iat2ia;
142-
ucell_.iat2ia = nullptr;
143-
}
144-
145-
void MakeCoulombAtom()
146-
{
147-
Atom& at = ucell_.atoms[0];
148-
at.label = "C";
149-
at.coulomb_potential = true;
150-
at.ncpp.zv = 4.0;
151-
at.ncpp.tvanp = false;
152-
at.ncpp.has_so = false;
153-
at.ncpp.nbeta = 0;
154-
at.ncpp.nh = 0;
155-
at.ncpp.msh = 0;
156-
at.ncpp.kkbeta = 0;
157-
at.mass = 12.0;
158-
}
159-
160-
double VlocCoulomb(double g2_bohr) const
161-
{
162-
return -ucell_.atoms[0].ncpp.zv * ModuleBase::e2 * ModuleBase::FOUR_PI / ucell_.omega / g2_bohr;
163-
}
164-
165-
// reconfigure the cell as a two-atom Z=4/Z=2 crystal breaking all symmetry
166-
void MakeTwoAtomCell()
167-
{
168-
ucell_.ntype = 2;
169-
ucell_.nat = 2;
170-
delete[] ucell_.atoms;
171-
ucell_.atoms = new Atom[2];
172-
ucell_.atoms[0].na = 1;
173-
ucell_.atoms[1].na = 1;
174-
ucell_.atoms[0].tau.resize(1);
175-
ucell_.atoms[1].tau.resize(1);
176-
ucell_.atoms[0].tau[0] = ModuleBase::Vector3<double>(0.0, 0.0, 0.0);
177-
ucell_.atoms[1].tau[0] = ModuleBase::Vector3<double>(0.25, 0.31, 0.17);
178-
for (int it = 0; it < 2; ++it)
179-
{
180-
Atom& at = ucell_.atoms[it];
181-
at.label = (it == 0) ? "A" : "B";
182-
at.coulomb_potential = true;
183-
at.ncpp.zv = (it == 0) ? 4.0 : 2.0;
184-
at.ncpp.tvanp = false;
185-
at.ncpp.has_so = false;
186-
at.ncpp.nbeta = 0;
187-
at.ncpp.nh = 0;
188-
at.mass = (it == 0) ? 12.0 : 4.0;
189-
}
190-
delete[] ucell_.iat2it;
191-
delete[] ucell_.iat2ia;
192-
ucell_.iat2it = new int[2];
193-
ucell_.iat2ia = new int[2];
194-
ucell_.iat2it[0] = 0;
195-
ucell_.iat2ia[0] = 0;
196-
ucell_.iat2it[1] = 1;
197-
ucell_.iat2ia[1] = 0;
198-
}
199-
20082
// independent Ry/bohr^2/amu -> cm^-1 conversion used by diagonalize
20183
double RyBohr2AmuToCm1() const
20284
{
@@ -570,7 +452,7 @@ TEST_F(DFPTPhonSerialTest, AccumulateElectronD2CommensurateQ)
570452
// with kernel K_{da,db}(G) = -tpiba^2 G_da G_db Vloc(|G|^2) e^{-i2pi G.tau}
571453
const ModuleBase::Vector3<double> k_d(-0.5, 0.0, 0.0);
572454
const ModuleBase::Vector3<double> q_d(0.5, 0.0, 0.0);
573-
SetupBases(k_d, q_d);
455+
SetupPhon(k_d, q_d);
574456

575457
const int npwk = pw_wfc_.npwk[0];
576458
psi::Psi<std::complex<double>> psi(1, 2, npwk, npwk, true);

0 commit comments

Comments
 (0)