29 template<
typename ST,
typename LT>
49 #pragma omp parallel for 50 for (
size_t ig = 0; ig <
NumGvecs; ig++)
53 gvec_shift = gvecs_in[ig + first] + HalfG * 0.5;
59 template<
typename YLM_ENGINE,
typename VVT>
65 Ylm.evaluateV(Ghat[0], Ghat[1], Ghat[2], YlmG.
data());
68 template<
typename VVT>
69 inline void calc_jlm_G(
const int lmax, ST& r,
const size_t ig, VVT& j_lm_G)
const 72 for (
size_t l = lmax; l > 0; l--)
73 for (
size_t lm = l * l; lm < (l + 1) * (l + 1); lm++)
74 j_lm_G[lm] = j_lm_G[l];
77 template<
typename PT,
typename VT>
78 inline void calc_phase_shift(
const PT& RSoA,
const size_t ig, VT& phase_shift_real, VT& phase_shift_imag)
const 80 const ST* restrict px = RSoA.data(0);
81 const ST* restrict py = RSoA.data(1);
82 const ST* restrict pz = RSoA.data(2);
83 ST* restrict v_r = phase_shift_real.data();
84 ST* restrict v_i = phase_shift_imag.data();
89 #pragma omp simd aligned(px, py, pz, v_r, v_i : QMC_SIMD_ALIGNMENT) 90 for (
size_t iat = 0; iat < RSoA.size(); iat++)
91 qmcplusplus::sincos(px[iat] * gv_x + py[iat] * gv_y + pz[iat] * gv_z, v_i + iat, v_r + iat);
98 std::complex<ST> val(0.0, 0.0);
99 for (
size_t ig = 0; ig <
NumGvecs; ig++)
109 template<
typename PT>
114 for (
size_t ig = 0; ig <
NumGvecs; ig++)
128 for (
size_t ig = 0; ig <
NumGvecs; ig++)
134 template<
typename SA>
138 template<
typename SA>
143 auto bspline = std::make_unique<SA>(my_name);
144 app_log() <<
" ClassName = " <<
bspline->getClassName() << std::endl;
146 initialize_hybridrep_atomic_centers(*
bspline);
147 bool foundspline = spline_reader_.createSplineDataSpaceLookforDumpFile(bandgroup, *
bspline);
148 typename SA::HYBRIDBASE& hybrid_center_orbs = *
bspline;
149 hybrid_center_orbs.resizeStorage(
bspline->myV.size());
154 const auto splinefile = getSplineDumpFileName(bandgroup);
155 h5f.
open(splinefile, H5F_ACC_RDONLY);
156 foundspline =
bspline->read_splines(h5f);
158 app_log() <<
" Successfully restored 3D B-spline coefficients from " << splinefile <<
". The reading time is " 159 << now.
elapsed() <<
" sec." << std::endl;
164 hybrid_center_orbs.flush_zero();
165 initialize_hybrid_pio_gather(spin, bandgroup, *
bspline);
167 if (saveSplineCoefs && myComm->rank() == 0)
170 const std::string splinefile(getSplineDumpFileName(bandgroup));
173 std::string classname =
bspline->getClassName();
174 h5f.
write(classname,
"class_name");
176 h5f.
write(sizeD,
"sizeof");
179 app_log() <<
" Stored spline coefficients in " << splinefile <<
" for potential reuse. The writing time is " 180 << now.
elapsed() <<
" sec." << std::endl;
187 app_log() <<
" Time to bcast the table = " << now.
elapsed() << std::endl;
192 template<
typename SA>
195 auto& mybuilder = spline_reader_.mybuilder;
198 std::string scheme_name(
"Consistent");
199 std::string s_function_name(
"LEKS2018");
200 a.
add(scheme_name,
"smoothing_scheme");
201 a.
add(s_function_name,
"smoothing_function");
202 a.
put(mybuilder->XMLRoot);
204 if (scheme_name ==
"Consistent")
205 bspline.smooth_scheme = SA::smoothing_schemes::CONSISTENT;
206 else if (scheme_name ==
"SmoothAll")
207 bspline.smooth_scheme = SA::smoothing_schemes::SMOOTHALL;
208 else if (scheme_name ==
"SmoothPartial")
209 bspline.smooth_scheme = SA::smoothing_schemes::SMOOTHPARTIAL;
211 APP_ABORT(
"initialize_hybridrep_atomic_centers wrong smoothing_scheme name! Only allows Consistent, SmoothAll or " 215 if (s_function_name ==
"LEKS2018")
217 else if (s_function_name ==
"coscos")
219 else if (s_function_name ==
"linear")
223 "initialize_hybridrep_atomic_centers wrong smoothing_function name! Only allows LEKS2018, coscos or linear.");
224 app_log() <<
"Hybrid orbital representation uses " << scheme_name <<
" smoothing scheme and " << s_function_name
225 <<
" smoothing function." << std::endl;
227 bspline.set_info(*(mybuilder->SourcePtcl), mybuilder->TargetPtcl, mybuilder->Super2Prim);
228 auto& centers =
bspline.AtomicCenters;
229 auto& ACInfo = mybuilder->AtomicCentersInfo;
231 if (centers.size() == 0)
234 app_log() <<
"Reading atomic center info for hybrid representation" << std::endl;
235 for (
int center_idx = 0; center_idx < ACInfo.Ncenters; center_idx++)
237 const int my_GroupID = ACInfo.GroupID[center_idx];
238 if (ACInfo.cutoff[center_idx] < 0)
240 app_error() <<
"Hybrid orbital representation needs parameter 'cutoff_radius' for atom " << center_idx
245 if (ACInfo.inner_cutoff[center_idx] < 0)
247 const double inner_cutoff = std::max(ACInfo.cutoff[center_idx] - 0.3, 0.0);
248 app_log() <<
"Hybrid orbital representation setting 'inner_cutoff' to " << inner_cutoff <<
" for group " 249 << my_GroupID <<
" as atom " << center_idx << std::endl;
251 for (
int id = 0;
id < ACInfo.Ncenters;
id++)
252 if (my_GroupID == ACInfo.GroupID[
id])
253 ACInfo.inner_cutoff[id] = inner_cutoff;
255 else if (ACInfo.inner_cutoff[center_idx] > ACInfo.cutoff[center_idx])
257 app_error() <<
"Hybrid orbital representation 'inner_cutoff' must be smaller than 'spline_radius' for atom " 258 << center_idx << std::endl;
262 if (ACInfo.cutoff[center_idx] > 0)
264 if (ACInfo.lmax[center_idx] < 0)
266 app_error() <<
"Hybrid orbital representation needs parameter 'lmax' for atom " << center_idx << std::endl;
270 if (ACInfo.spline_radius[center_idx] < 0 && ACInfo.spline_npoints[center_idx] < 0)
272 app_log() <<
"Parameters 'spline_radius' and 'spline_npoints' for group " << my_GroupID <<
" as atom " 273 << center_idx <<
" are not specified." << std::endl;
274 const double delta =
std::min(0.02, ACInfo.cutoff[center_idx] / 4.0);
275 const int n_grid_point =
std::ceil((ACInfo.cutoff[center_idx] + 1
e-4) / delta) + 3;
276 for (
int id = 0;
id < ACInfo.Ncenters;
id++)
277 if (my_GroupID == ACInfo.GroupID[
id])
279 ACInfo.spline_npoints[id] = n_grid_point;
280 ACInfo.spline_radius[id] = (n_grid_point - 1) * delta;
282 app_log() <<
" Based on default grid point distance " << delta << std::endl;
283 app_log() <<
" Setting 'spline_npoints' to " << ACInfo.spline_npoints[center_idx] << std::endl;
284 app_log() <<
" Setting 'spline_radius' to " << ACInfo.spline_radius[center_idx] << std::endl;
288 if (ACInfo.spline_radius[center_idx] < 0)
290 app_error() <<
"Hybrid orbital representation needs parameter 'spline_radius' for atom " << center_idx
295 if (ACInfo.spline_npoints[center_idx] < 0)
297 app_error() <<
"Hybrid orbital representation needs parameter 'spline_npoints' for atom " << center_idx
304 double max_allowed_cutoff = ACInfo.spline_radius[center_idx] -
305 2.0 * ACInfo.spline_radius[center_idx] / (ACInfo.spline_npoints[center_idx] - 1);
306 if (success && ACInfo.cutoff[center_idx] > max_allowed_cutoff)
308 app_error() <<
"Hybrid orbital representation requires cutoff_radius<=" << max_allowed_cutoff
309 <<
" calculated by spline_radius-2*spline_radius/(spline_npoints-1) for atom " << center_idx
317 ACInfo.spline_radius[center_idx] = 0.0;
318 ACInfo.spline_npoints[center_idx] = 0;
319 ACInfo.lmax[center_idx] = 0;
324 spline_reader_.myComm->barrier_and_abort(
325 "initialize_hybridrep_atomic_centers Failed to initialize atomic centers " 326 "in hybrid orbital representation!");
328 for (
int center_idx = 0; center_idx < ACInfo.Ncenters; center_idx++)
331 oneCenter.
set_info(ACInfo.ion_pos[center_idx], ACInfo.cutoff[center_idx], ACInfo.inner_cutoff[center_idx],
332 ACInfo.spline_radius[center_idx], ACInfo.non_overlapping_radius[center_idx],
333 ACInfo.spline_npoints[center_idx]);
334 centers.push_back(oneCenter);
339 template<
typename SA>
343 const std::complex<double>& rotate_phase,
346 auto& mybuilder = spline_reader_.mybuilder;
347 double rotate_phase_r = rotate_phase.real();
348 double rotate_phase_i = rotate_phase.imag();
350 band_group_comm.
bcast(rotate_phase_r);
351 band_group_comm.
bcast(rotate_phase_i);
353 const int Ngvecs = mybuilder->Gvecs[0].size();
354 const int Nprocs = band_group_comm.
size();
355 const int Ngvecgroups =
std::min(Ngvecs, Nprocs);
356 Communicate gvec_group_comm(band_group_comm, Ngvecgroups);
357 std::vector<int> gvec_groups(Ngvecgroups + 1, 0);
359 const int gvec_first = gvec_groups[gvec_group_comm.
getGroupID()];
360 const int gvec_last = gvec_groups[gvec_group_comm.
getGroupID() + 1];
367 std::vector<AtomicOrbitals<DataType>>& centers =
bspline.AtomicCenters;
368 app_log() <<
"Transforming band " << iorb <<
" on Rank 0" << std::endl;
370 std::vector<int> uniq_species;
371 for (
int center_idx = 0; center_idx < centers.size(); center_idx++)
373 auto& ACInfo = mybuilder->AtomicCentersInfo;
374 const int my_GroupID = ACInfo.GroupID[center_idx];
376 for (
size_t idx = 0; idx < uniq_species.size(); idx++)
377 if (my_GroupID == uniq_species[idx])
383 uniq_species.push_back(my_GroupID);
386 std::vector<std::vector<int>> group_list(uniq_species.size());
387 for (
int center_idx = 0; center_idx < centers.size(); center_idx++)
389 auto& ACInfo = mybuilder->AtomicCentersInfo;
390 const int my_GroupID = ACInfo.GroupID[center_idx];
391 for (
size_t idx = 0; idx < uniq_species.size(); idx++)
392 if (my_GroupID == uniq_species[idx])
394 group_list[idx].push_back(center_idx);
399 for (
int group_idx = 0; group_idx < group_list.size(); group_idx++)
401 const auto& mygroup = group_list[group_idx];
402 const double spline_radius = centers[mygroup[0]].getSplineRadius();
403 const int spline_npoints = centers[mygroup[0]].getSplineNpoints();
404 const int lmax = centers[mygroup[0]].getLmax();
405 const double delta = spline_radius /
static_cast<double>(spline_npoints - 1);
406 const int lm_tot = (lmax + 1) * (lmax + 1);
407 const size_t natoms = mygroup.size();
408 const int policy = lm_tot > natoms ? 0 : 1;
410 std::vector<std::complex<double>> i_power(lm_tot);
412 std::complex<double> i_temp(rotate_phase_r, rotate_phase_i);
413 for (
size_t l = 0; l <= lmax; l++)
415 for (
size_t lm = l * l; lm < (l + 1) * (l + 1); lm++)
416 i_power[lm] = i_temp;
417 i_temp *= std::complex<double>(0.0, 1.0);
420 std::vector<Matrix<double>> all_vals(natoms);
421 std::vector<std::vector<aligned_vector<double>>> vals_local(spline_npoints *
omp_get_max_threads());
423 for (
size_t idx = 0; idx < natoms; idx++)
425 all_vals[idx].resize(spline_npoints, lm_tot * 2);
427 myRSoA(idx) = centers[mygroup[idx]].getCenterPos();
435 for (
int ip = 0; ip < spline_npoints; ip++)
437 const size_t ip_idx = tid * spline_npoints + ip;
440 vals_local[ip_idx].resize(lm_tot * 2);
441 for (
size_t lm = 0; lm < lm_tot * 2; lm++)
443 auto& vals = vals_local[ip_idx][lm];
445 std::fill(vals.begin(), vals.end(), 0.0);
450 vals_local[ip_idx].resize(natoms * 2);
451 for (
size_t iat = 0; iat < natoms * 2; iat++)
453 auto& vals = vals_local[ip_idx][iat];
455 std::fill(vals.begin(), vals.end(), 0.0);
460 const size_t size_pw_tile = 32;
461 const size_t num_pw_tiles = (Gvecs.
NumGvecs + size_pw_tile - 1) / size_pw_tile;
463 std::vector<aligned_vector<double>> phase_shift_r(size_pw_tile);
464 std::vector<aligned_vector<double>> phase_shift_i(size_pw_tile);
465 std::vector<aligned_vector<double>> YlmG(size_pw_tile);
466 for (
size_t ig = 0; ig < size_pw_tile; ig++)
468 phase_shift_r[ig].resize(natoms);
469 phase_shift_i[ig].resize(natoms);
470 YlmG[ig].resize(lm_tot);
475 for (
size_t tile_id = 0; tile_id < num_pw_tiles; tile_id++)
477 const size_t ig_first = tile_id * size_pw_tile;
478 const size_t ig_last =
std::min((tile_id + 1) * size_pw_tile, Gvecs.
NumGvecs);
479 for (
size_t ig = ig_first; ig < ig_last; ig++)
481 const size_t ig_local = ig - ig_first;
483 Gvecs.
calc_phase_shift(myRSoA, ig, phase_shift_r[ig_local], phase_shift_i[ig_local]);
487 for (
int ip = 0; ip < spline_npoints; ip++)
489 double r = delta *
static_cast<double>(ip);
490 const size_t ip_idx = tid * spline_npoints + ip;
492 for (
size_t ig = ig_first; ig < ig_last; ig++)
494 const size_t ig_local = ig - ig_first;
497 for (
size_t lm = 0; lm < lm_tot; lm++)
498 j_lm_G[lm] *= YlmG[ig_local][lm];
500 const double cG_r = cG[ig + gvec_first].real();
501 const double cG_i = cG[ig + gvec_first].imag();
504 for (
size_t lm = 0; lm < lm_tot; lm++)
506 double* restrict vals_r = vals_local[ip_idx][lm * 2].data();
507 double* restrict vals_i = vals_local[ip_idx][lm * 2 + 1].data();
508 const double* restrict ps_r_ptr = phase_shift_r[ig_local].data();
509 const double* restrict ps_i_ptr = phase_shift_i[ig_local].data();
510 double cG_j_r = cG_r * j_lm_G[lm];
511 double cG_j_i = cG_i * j_lm_G[lm];
512 #pragma omp simd aligned(vals_r, vals_i, ps_r_ptr, ps_i_ptr : QMC_SIMD_ALIGNMENT) 513 for (
size_t idx = 0; idx < natoms; idx++)
515 const double ps_r = ps_r_ptr[idx];
516 const double ps_i = ps_i_ptr[idx];
517 vals_r[idx] += cG_j_r * ps_r - cG_j_i * ps_i;
518 vals_i[idx] += cG_j_i * ps_r + cG_j_r * ps_i;
524 for (
size_t idx = 0; idx < natoms; idx++)
526 double* restrict vals_r = vals_local[ip_idx][idx * 2].data();
527 double* restrict vals_i = vals_local[ip_idx][idx * 2 + 1].data();
528 const double* restrict j_lm_G_ptr = j_lm_G.data();
529 double cG_ps_r = cG_r * phase_shift_r[ig_local][idx] - cG_i * phase_shift_i[ig_local][idx];
530 double cG_ps_i = cG_i * phase_shift_r[ig_local][idx] + cG_r * phase_shift_i[ig_local][idx];
531 #pragma omp simd aligned(vals_r, vals_i, j_lm_G_ptr : QMC_SIMD_ALIGNMENT) 532 for (
size_t lm = 0; lm < lm_tot; lm++)
534 const double jlm = j_lm_G_ptr[lm];
535 vals_r[lm] += cG_ps_r * jlm;
536 vals_i[lm] += cG_ps_i * jlm;
544 #pragma omp for collapse(2) 545 for (
int ip = 0; ip < spline_npoints; ip++)
546 for (
size_t idx = 0; idx < natoms; idx++)
548 double* vals = all_vals[idx][ip];
549 for (
size_t tid = 0; tid < nt; tid++)
550 for (
size_t lm = 0; lm < lm_tot; lm++)
552 double vals_th_r, vals_th_i;
553 const size_t ip_idx = tid * spline_npoints + ip;
556 vals_th_r = vals_local[ip_idx][lm * 2][idx];
557 vals_th_i = vals_local[ip_idx][lm * 2 + 1][idx];
561 vals_th_r = vals_local[ip_idx][idx * 2][lm];
562 vals_th_i = vals_local[ip_idx][idx * 2 + 1][lm];
564 const double real_tmp = 4.0 * M_PI * i_power[lm].real();
565 const double imag_tmp = 4.0 * M_PI * i_power[lm].imag();
566 vals[lm] += vals_th_r * real_tmp - vals_th_i * imag_tmp;
567 vals[lm + lm_tot] += vals_th_i * real_tmp + vals_th_r * imag_tmp;
573 for (
size_t idx = 0; idx < natoms; idx++)
576 band_group_comm.
reduce_in_place(all_vals[idx].data(), all_vals[idx].size());
579 #pragma omp parallel for 580 for (
int lm = 0; lm < lm_tot; lm++)
582 auto& mycenter = centers[mygroup[idx]];
584 UBspline_1d_d* atomic_spline_r =
nullptr;
585 for (
size_t ip = 0; ip < spline_npoints; ip++)
586 splineData_r[ip] = all_vals[idx][ip][lm];
587 atomic_spline_r =
einspline::create(atomic_spline_r, 0.0, spline_radius, spline_npoints, splineData_r.data(),
588 ((lm == 0) || (lm > 3)));
591 mycenter.set_spline(atomic_spline_r, lm, iorb);
592 einspline::destroy(atomic_spline_r);
597 UBspline_1d_d* atomic_spline_i =
nullptr;
598 for (
size_t ip = 0; ip < spline_npoints; ip++)
599 splineData_i[ip] = all_vals[idx][ip][lm + lm_tot];
600 atomic_spline_i =
einspline::create(atomic_spline_i, 0.0, spline_radius, spline_npoints, splineData_i.data(),
601 ((lm == 0) || (lm > 3)));
602 mycenter.set_spline(atomic_spline_r, lm, iorb * 2);
603 mycenter.set_spline(atomic_spline_i, lm, iorb * 2 + 1);
604 einspline::destroy(atomic_spline_r);
605 einspline::destroy(atomic_spline_i);
612 template<
typename SA>
617 auto& mybuilder = spline_reader_.mybuilder;
620 const int Nprocs = myComm->size();
621 const int Nbandgroups =
std::min(Nbands, Nprocs);
623 std::vector<int> band_groups(Nbandgroups + 1, 0);
625 int iorb_first = band_groups[band_group_comm.
getGroupID()];
626 int iorb_last = band_groups[band_group_comm.
getGroupID() + 1];
628 app_log() <<
"Start transforming plane waves to 3D B-splines and atomic radial orbital 1D B-splines." << std::endl;
632 const std::vector<BandInfo>& cur_bands = bandgroup.
myBands;
634 h5f.open(mybuilder->H5FileName, H5F_ACC_RDONLY);
635 for (
int iorb = iorb_first; iorb < iorb_last; iorb++)
639 const auto& cur_band = cur_bands[
bspline.BandIndexMap[iorb]];
640 const int ti = cur_band.TwistIndex;
641 spline_reader_.readOneOrbitalCoefs(psi_g_path(ti, spin, cur_band.BandIndex), h5f, cG);
642 oneband.fft_spline(cG, mybuilder->Gvecs[0], mybuilder->primcell_kpoints[ti], rotate);
643 bspline.set_spline(&oneband.get_spline_r(), &oneband.get_spline_i(), cur_band.TwistIndex, iorb, 0);
645 band_group_comm.
bcast(cG);
646 create_atomic_centers_Gspace(cG, band_group_comm, iorb, oneband.getRotatePhase(),
bspline);
654 app_log() <<
" Time to gather the table = " << now.
elapsed() << std::endl;
658 #if defined(QMC_COMPLEX) 661 #if !defined(QMC_MIXED_PRECISION) 669 #if !defined(QMC_MIXED_PRECISION) double bspline(double x, const std::vector< double > &t, const std::vector< double > &c, int k)
a class that defines a supercell in D-dimensional Euclean space.
std::vector< T, aligned_allocator< T > > aligned_vector
void write(T &data, const std::string &aname)
write the data to the group aname and check status runtime error is issued on I/O error ...
bool open(const std::filesystem::path &fname, unsigned flags=H5F_ACC_RDWR)
open a file
helper functions for EinsplineSetBuilder
HybridRepSetReader(EinsplineSetBuilder *e)
std::complex< T > Ylm(int l, int m, const TinyVector< T, 3 > &r)
calculates Ylm param[in] l angular momentum param[in] m magnetic quantum number param[in] r position ...
void calc_Ylm_G(const size_t ig, YLM_ENGINE &Ylm, VVT &YlmG) const
bool put(xmlNodePtr cur)
assign attributes to the set
void close()
close all the open groups and file
std::ostream & app_error()
CrystalLattice< ParticleSet::Scalar_t, DIM > UnitCellType
SoA adaptor class for Vector<TinyVector<T,D> >
void calc_phase_shift(const PT &RSoA, const size_t ig, VT &phase_shift_real, VT &phase_shift_imag) const
void set_info(const PT &R, const VT &cutoff_in, const VT &cutoff_buffer_in, const VT &spline_radius_in, const VT &non_overlapping_radius_in, const int spline_npoints_in)
SoaSphericalTensor that evaluates the Real Spherical Harmonics.
Gvectors(const std::vector< TinyVector< int, 3 >> &gvecs_in, const LT &Lattice_in, const TinyVector< int, 3 > &HalfG, size_t first, size_t last)
int size() const
return the number of tasks
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
int getNumDistinctOrbitals() const
return the size of this band
Wrapping information on parallelism.
void evaluate_psi_r(const Vector< std::complex< double >> &cG, const PT &pos, ValueType &phi, ValueType &d2phi)
void calc_jlm_G(const int lmax, ST &r, const size_t ig, VVT &j_lm_G) const
SingleParticlePos k_cart(const SingleParticlePos &kin) const
conversion of a reciprocal-vector
omp_int_t omp_get_thread_num()
Each SplineC2X needs a reader derived from BsplineReader.
int getGroupID() const
return the group id
MakeReturn< UnaryNode< FnCeil, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t ceil(const Vector< T1, C1 > &l)
omp_int_t omp_get_max_threads()
typename SA::DataType DataType
void initialize_hybridrep_atomic_centers(SA &bspline) const
initialize basic parameters of atomic orbitals
class to handle a set of attributes of an xmlNode
std::complex< ST > ValueType
std::vector< PosType > gvecs_cart
void initialize_hybrid_pio_gather(const int spin, const BandInfoGroup &bandgroup, SA &bspline) const
transforming planewave orbitals to 3D B-spline orbitals and 1D B-spline radial orbitals in real space...
bool isGroupLeader()
return true if the current MPI rank is the group lead
double evaluate_KE(const Vector< std::complex< double >> &cG)
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
ValueType evaluate_psi_r(const Vector< std::complex< double >> &cG, const PT &pos)
omp_int_t omp_get_num_threads()
void create_atomic_centers_Gspace(const Vector< std::complex< double >> &cG, Communicate &band_group_comm, const int iorb, const std::complex< double > &rotate_phase, SA &bspline) const
initialize construct atomic orbital radial functions from plane waves
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
bool create(const std::filesystem::path &fname, unsigned flags=H5F_ACC_TRUNC)
create a file
void reduce_in_place(T *restrict, int n)
Communicate * getGroupLeaderComm()
void sincos(T a, T *restrict s, T *restrict c)
sincos function wrapper
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
General HybridRepSetReader to handle any unitcell.
std::unique_ptr< SPOSet > create_spline_set(const std::string &my_name, int spin, const BandInfoGroup &bandgroup) override
create the actual spline sets
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
derived from BsplineReader
std::vector< BandInfo > myBands
Bands that belong to this group.
void bessel_steed_array_cpu(const int lmax, const T x, T *jl)
Compute spherical bessel function from 0 to lmax.