Skip to content

Commit 5bbbec5

Browse files
authored
Merge pull request #5389 from PDoakORNL/kcontainer_working_precision
kcontainer now encapsulated and provides k elements at working prec
2 parents 1b3a0ea + 55c4f1c commit 5bbbec5

41 files changed

Lines changed: 500 additions & 289 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Particle/LongRange/EwaldHandler2D.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,18 @@ void EwaldHandler2D::fillFk(const KContainer& KList)
3434
const mRealType kalpha = 1.0 / (2.0*alpha);
3535
mRealType kmag, uk;
3636

37-
Fk.resize(KList.kpts_cart.size());
38-
MaxKshell = KList.kshell.size() - 1;
37+
Fk.resize(KList.getKptsCartWorking().size());
38+
const auto& kshell = KList.getKShell();
39+
MaxKshell = kshell.size() - 1;
3940
Fk_symm.resize(MaxKshell);
4041

42+
const auto& ksq = KList.getKSQWorking();
4143
for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
4244
{
43-
kmag = std::sqrt(KList.ksq[ki]);
45+
kmag = std::sqrt(ksq[ki]);
4446
uk = knorm * erfc(kalpha*kmag)/kmag;
4547
Fk_symm[ks] = uk;
46-
while (ki < KList.kshell[ks + 1] && ki < Fk.size())
48+
while (ki < kshell[ks + 1] && ki < Fk.size())
4749
Fk[ki++] = uk;
4850
}
4951
}

src/Particle/LongRange/EwaldHandler3D.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,24 @@ EwaldHandler3D::EwaldHandler3D(const EwaldHandler3D& aLR, ParticleSet& ref)
5353

5454
void EwaldHandler3D::fillFk(const KContainer& KList)
5555
{
56-
Fk.resize(KList.kpts_cart.size());
57-
Fkg.resize(KList.kpts_cart.size());
58-
const std::vector<int>& kshell(KList.kshell);
56+
const auto& kpts_cart = KList.getKptsCartWorking();
57+
Fk.resize(kpts_cart.size());
58+
Fkg.resize(kpts_cart.size());
59+
const std::vector<int>& kshell(KList.getKShell());
5960

6061
MaxKshell = kshell.size() - 1;
6162

6263
Fk_symm.resize(MaxKshell);
6364
kMag.resize(MaxKshell);
6465
mRealType kgauss = 1.0 / (4 * Sigma * Sigma);
6566
mRealType knorm = 4 * M_PI / Volume;
67+
const auto ksq = KList.getKSQWorking();
6668
for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
6769
{
68-
mRealType t2e = KList.ksq[ki] * kgauss;
69-
mRealType uk = knorm * std::exp(-t2e) / KList.ksq[ki];
70+
mRealType t2e = ksq[ki] * kgauss;
71+
mRealType uk = knorm * std::exp(-t2e) / ksq[ki];
7072
Fk_symm[ks] = uk;
71-
while (ki < KList.kshell[ks + 1] && ki < Fk.size())
73+
while (ki < kshell[ks + 1] && ki < Fk.size())
7274
Fk[ki++] = uk;
7375
}
7476

src/Particle/LongRange/EwaldHandler3D.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,26 @@ class EwaldHandler3D : public LRHandlerBase
103103

104104
void fillYkgstrain(const KContainer& KList)
105105
{
106-
Fkgstrain.resize(KList.kpts_cart.size());
107-
const std::vector<int>& kshell(KList.kshell);
106+
Fkgstrain.resize(KList.getKptsCartWorking().size());
107+
const std::vector<int>& kshell(KList.getKShell());
108108
MaxKshell = kshell.size() - 1;
109+
const auto& ksq = KList.getKSQWorking();
109110
for (int ks = 0, ki = 0; ks < MaxKshell; ks++)
110111
{
111-
mRealType uk = evalYkgstrain(std::sqrt(KList.ksq[ki]));
112-
while (ki < KList.kshell[ks + 1] && ki < Fkgstrain.size())
112+
mRealType uk = evalYkgstrain(std::sqrt(ksq[ki]));
113+
while (ki < kshell[ks + 1] && ki < Fkgstrain.size())
113114
Fkgstrain[ki++] = uk;
114115
}
115116
}
116117

117118
void filldFk_dk(const KContainer& KList)
118119
{
119-
dFk_dstrain.resize(KList.kpts_cart.size());
120-
120+
const auto& kpts_cart = KList.getKptsCartWorking();
121+
dFk_dstrain.resize(kpts_cart.size());
122+
const auto& ksq = KList.getKSQWorking();
121123
for (int ki = 0; ki < dFk_dstrain.size(); ki++)
122124
{
123-
dFk_dstrain[ki] = evaluateLR_dstrain(KList.kpts_cart[ki], std::sqrt(KList.ksq[ki]));
125+
dFk_dstrain[ki] = evaluateLR_dstrain(kpts_cart[ki], std::sqrt(ksq[ki]));
124126
}
125127
}
126128

src/Particle/LongRange/EwaldHandlerQuasi2D.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,19 @@ void EwaldHandlerQuasi2D::fillFk(const KContainer& KList)
3535
{
3636
const mRealType knorm = M_PI / area;
3737
mRealType kmag, uk;
38-
39-
Fk.resize(KList.kpts_cart.size());
40-
MaxKshell = KList.kshell.size() - 1;
38+
const auto& kpts_cart = KList.getKptsCartWorking();
39+
Fk.resize(kpts_cart.size());
40+
MaxKshell = KList.getKShell().size() - 1;
4141
Fk_symm.resize(MaxKshell);
4242

4343
kmags.resize(MaxKshell);
4444
for (int ks = 0, ki = 0; ks < Fk_symm.size(); ks++)
4545
{
46-
kmag = std::sqrt(KList.ksq[ki]);
46+
kmag = std::sqrt(KList.getKSQWorking()[ki]);
4747
kmags[ks] = kmag; // store k magnitutes
4848
uk = knorm/kmag;
4949
Fk_symm[ks] = uk;
50-
while (ki < KList.kshell[ks + 1] && ki < Fk.size())
50+
while (ki < KList.getKShell()[ks + 1] && ki < Fk.size())
5151
Fk[ki++] = uk;
5252
}
5353
}

src/Particle/LongRange/KContainer.cpp

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
// This file is distributed under the University of Illinois/NCSA Open Source License.
33
// See LICENSE file in top directory for details.
44
//
5-
// Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
5+
// Copyright (c) 2025 QMCPACK developers.
66
//
77
// File developed by: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
88
// Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
99
// Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10+
// Peter W. Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
1011
//
1112
// File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
1213
//////////////////////////////////////////////////////////////////////////////////////
@@ -21,11 +22,41 @@
2122

2223
namespace qmcplusplus
2324
{
24-
void KContainer::updateKLists(const ParticleLayout& lattice,
25-
RealType kc,
26-
unsigned ndim,
27-
const PosType& twist,
28-
bool useSphere)
25+
26+
template<typename REAL>
27+
const std::vector<typename KContainerT<REAL>::AppPosition>& KContainerT<
28+
REAL>::getKptsCartWorking() const
29+
{
30+
// This is an `if constexpr` so it should not cost a branch at runtime.
31+
if constexpr (std::is_same_v<decltype(kpts_cart_), decltype(kpts_cart_working_)>)
32+
return kpts_cart_;
33+
else
34+
return kpts_cart_working_;
35+
}
36+
37+
template<typename REAL>
38+
const std::vector<REAL>& KContainerT<REAL>::getKSQWorking() const
39+
{
40+
// This is an `if constexpr` so it should not cost a branch at runtime.
41+
if constexpr (std::is_same<decltype(ksq_), decltype(ksq_working_)>::value)
42+
return ksq_;
43+
else
44+
return ksq_working_;
45+
}
46+
47+
template<typename REAL>
48+
int KContainerT<REAL>::getMinusK(int k) const
49+
{
50+
assert(k < minusk.size());
51+
return minusk[k];
52+
}
53+
54+
template<typename REAL>
55+
void KContainerT<REAL>::updateKLists(const Lattice& lattice,
56+
FullPrecReal kc,
57+
unsigned ndim,
58+
const Position& twist,
59+
bool useSphere)
2960
{
3061
kcutoff = kc;
3162
if (kcutoff <= 0.0)
@@ -37,11 +68,12 @@ void KContainer::updateKLists(const ParticleLayout& lattice,
3768

3869
app_log() << " KContainer initialised with cutoff " << kcutoff << std::endl;
3970
app_log() << " # of K-shell = " << kshell.size() << std::endl;
40-
app_log() << " # of K points = " << kpts.size() << std::endl;
71+
app_log() << " # of K points = " << kpts_.size() << std::endl;
4172
app_log() << std::endl;
4273
}
4374

44-
void KContainer::findApproxMMax(const ParticleLayout& lattice, unsigned ndim)
75+
template<typename REAL>
76+
void KContainerT<REAL>::findApproxMMax(const Lattice& lattice, unsigned ndim)
4577
{
4678
//Estimate the size of the parallelpiped that encompasses a sphere of kcutoff.
4779
//mmax is stored as integer translations of the reciprocal cell vectors.
@@ -102,19 +134,22 @@ void KContainer::findApproxMMax(const ParticleLayout& lattice, unsigned ndim)
102134
mmax[1] = 0;
103135
}
104136

105-
void KContainer::BuildKLists(const ParticleLayout& lattice, const PosType& twist, bool useSphere)
137+
template<typename REAL>
138+
void KContainerT<REAL>::BuildKLists(const Lattice& lattice,
139+
const Position& twist,
140+
bool useSphere)
106141
{
107142
TinyVector<int, DIM + 1> TempActualMax;
108143
TinyVector<int, DIM> kvec;
109-
TinyVector<RealType, DIM> kvec_cart;
110-
RealType modk2;
144+
TinyVector<FullPrecReal, DIM> kvec_cart;
145+
FullPrecReal modk2;
111146
std::vector<TinyVector<int, DIM>> kpts_tmp;
112-
std::vector<PosType> kpts_cart_tmp;
113-
std::vector<RealType> ksq_tmp;
147+
std::vector<PositionFull> kpts_cart_tmp;
148+
std::vector<FullPrecReal> ksq_tmp;
114149
// reserve the space for memory efficiency
115150
if (useSphere)
116151
{
117-
const RealType kcut2 = kcutoff * kcutoff;
152+
const FullPrecReal kcut2 = kcutoff * kcutoff;
118153
//Loop over guesses for valid k-points.
119154
for (int i = -mmax[0]; i <= mmax[0]; i++)
120155
{
@@ -208,10 +243,10 @@ void KContainer::BuildKLists(const ParticleLayout& lattice, const PosType& twist
208243
}
209244
}
210245
std::map<int64_t, std::vector<int>*>::iterator it(kpts_sorted.begin());
211-
kpts.resize(numk);
212-
kpts_cart.resize(numk);
246+
kpts_.resize(numk);
247+
kpts_cart_.resize(numk);
213248
kpts_cart_soa_.resize(numk);
214-
ksq.resize(numk);
249+
ksq_.resize(numk);
215250
kshell.resize(kpts_sorted.size() + 1, 0);
216251
int ok = 0, ish = 0;
217252
while (it != kpts_sorted.end())
@@ -220,10 +255,10 @@ void KContainer::BuildKLists(const ParticleLayout& lattice, const PosType& twist
220255
while (vit != (*it).second->end())
221256
{
222257
int ik = (*vit);
223-
kpts[ok] = kpts_tmp[ik];
224-
kpts_cart[ok] = kpts_cart_tmp[ik];
258+
kpts_[ok] = kpts_tmp[ik];
259+
kpts_cart_[ok] = kpts_cart_tmp[ik];
225260
kpts_cart_soa_(ok) = kpts_cart_tmp[ik];
226-
ksq[ok] = ksq_tmp[ik];
261+
ksq_[ok] = ksq_tmp[ik];
227262
++vit;
228263
++ok;
229264
}
@@ -232,6 +267,13 @@ void KContainer::BuildKLists(const ParticleLayout& lattice, const PosType& twist
232267
++ish;
233268
}
234269
kpts_cart_soa_.updateTo();
270+
if constexpr (!std::is_same<Real, FullPrecReal>::value)
271+
{
272+
// This copy implicity does the precision reduction.
273+
// the working vectors are not used or initialized for full precision builds.
274+
std::copy(kpts_cart_.begin(), kpts_cart_.end(), std::back_inserter(kpts_cart_working_));
275+
std::copy(ksq_.begin(), ksq_.end(), std::back_inserter(ksq_working_));
276+
}
235277
it = kpts_sorted.begin();
236278
std::map<int64_t, std::vector<int>*>::iterator e_it(kpts_sorted.end());
237279
while (it != e_it)
@@ -262,13 +304,19 @@ void KContainer::BuildKLists(const ParticleLayout& lattice, const PosType& twist
262304
std::map<int64_t, int> hashToIndex;
263305
for (int ki = 0; ki < numk; ki++)
264306
{
265-
hashToIndex[getHashOfVec(kpts[ki], numk)] = ki;
307+
hashToIndex[getHashOfVec(kpts_[ki], numk)] = ki;
266308
}
267309
// Use the map to find the index of -k from the index of k
268310
for (int ki = 0; ki < numk; ki++)
269311
{
270-
minusk[ki] = hashToIndex[getHashOfVec(-1 * kpts[ki], numk)];
312+
minusk[ki] = hashToIndex[getHashOfVec(-1 * kpts_[ki], numk)];
271313
}
272314
}
273315

316+
#ifdef MIXED_PRECISION
317+
template class KContainerT<float>;
318+
template class KContainerT<double>;
319+
#else
320+
template class KContainerT<double>;
321+
#endif
274322
} // namespace qmcplusplus

0 commit comments

Comments
 (0)