QMCPACK
HybridRepSetReader< SA > Class Template Reference

General HybridRepSetReader to handle any unitcell. More...

+ Inheritance diagram for HybridRepSetReader< SA >:
+ Collaboration diagram for HybridRepSetReader< SA >:

Public Member Functions

 HybridRepSetReader (EinsplineSetBuilder *e)
 
std::unique_ptr< SPOSetcreate_spline_set (const std::string &my_name, int spin, const BandInfoGroup &bandgroup) override
 create the actual spline sets More...
 
void initialize_hybridrep_atomic_centers (SA &bspline) const
 initialize basic parameters of atomic orbitals More...
 
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 More...
 
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. More...
 
- Public Member Functions inherited from BsplineReader
 BsplineReader (EinsplineSetBuilder *e)
 
virtual ~BsplineReader ()
 
std::string getSplineDumpFileName (const BandInfoGroup &bandgroup) const
 
template<typename GT , typename BCT >
bool set_grid (const TinyVector< int, 3 > &halfg, GT *xyz_grid, BCT *xyz_bc) const
 read gvectors and set the mesh, and prepare for einspline More...
 
template<typename SPE >
void check_twists (SPE &bspline, const BandInfoGroup &bandgroup) const
 initialize twist-related data for N orbitals More...
 
std::string psi_g_path (int ti, int spin, int ib) const
 return the path name in hdf5 More...
 
std::string psi_r_path (int ti, int spin, int ib) const
 return the path name in hdf5 More...
 
void setCommon (xmlNodePtr cur)
 setting common parameters More...
 
std::unique_ptr< SPOSetcreate_spline_set (int spin, xmlNodePtr cur, SPOSetInputInfo &input_info)
 create the spline after one of the kind is created More...
 
std::unique_ptr< SPOSetcreate_spline_set (int spin, xmlNodePtr cur)
 create the spline set More...
 
void setCheckNorm (bool new_checknorm)
 Set the checkNorm variable. More...
 
void setRotate (bool new_rotate)
 Set the orbital rotation flag. More...
 
void initialize_spo2band (int spin, const std::vector< BandInfo > &bigspace, SPOSetInfo &sposet, std::vector< int > &band2spo)
 build index tables to map a state to band with k-point folidng More...
 

Private Types

using SplineReader = SplineSetReader< typename SA::SplineBase >
 
using DataType = typename SA::DataType
 

Private Attributes

SplineReader spline_reader_
 

Additional Inherited Members

- Public Attributes inherited from BsplineReader
EinsplineSetBuildermybuilder
 pointer to the EinsplineSetBuilder More...
 
CommunicatemyComm
 communicator More...
 
bool checkNorm
 mesh size check the norm of orbitals More...
 
bool saveSplineCoefs
 save spline coefficients to storage More...
 
bool rotate
 apply orbital rotations More...
 
std::vector< std::vector< int > > spo2band
 map from spo index to band index More...
 

Detailed Description

template<typename SA>
class qmcplusplus::HybridRepSetReader< SA >

General HybridRepSetReader to handle any unitcell.

Definition at line 30 of file HybridRepCenterOrbitals.h.

Member Typedef Documentation

◆ DataType

using DataType = typename SA::DataType
private

Definition at line 47 of file HybridRepSetReader.h.

◆ SplineReader

using SplineReader = SplineSetReader<typename SA::SplineBase>
private

Definition at line 46 of file HybridRepSetReader.h.

Constructor & Destructor Documentation

◆ HybridRepSetReader()

Member Function Documentation

◆ create_atomic_centers_Gspace()

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
inline

initialize construct atomic orbital radial functions from plane waves

Definition at line 340 of file HybridRepSetReader.cpp.

References qmcplusplus::app_log(), Communicate::bcast(), bspline(), Gvectors< ST, LT >::calc_jlm_G(), Gvectors< ST, LT >::calc_phase_shift(), Gvectors< ST, LT >::calc_Ylm_G(), qmcplusplus::create(), FairDivideLow(), Communicate::getGroupID(), Communicate::isGroupLeader(), omptarget::min(), Gvectors< ST, LT >::NumGvecs, omp_get_max_threads(), omp_get_num_threads(), omp_get_thread_num(), Communicate::reduce_in_place(), Communicate::size(), and qmcplusplus::Ylm().

345 {
347  double rotate_phase_r = rotate_phase.real();
348  double rotate_phase_i = rotate_phase.imag();
349 
350  band_group_comm.bcast(rotate_phase_r);
351  band_group_comm.bcast(rotate_phase_i);
352  //distribute G-vectors over processor groups
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);
358  FairDivideLow(Ngvecs, Ngvecgroups, gvec_groups);
359  const int gvec_first = gvec_groups[gvec_group_comm.getGroupID()];
360  const int gvec_last = gvec_groups[gvec_group_comm.getGroupID() + 1];
361 
362  // prepare Gvecs Ylm(G)
363  using UnitCellType = typename EinsplineSetBuilder::UnitCellType;
364  Gvectors<double, UnitCellType> Gvecs(mybuilder->Gvecs[0], mybuilder->PrimCell, bspline.HalfG, gvec_first, gvec_last);
365  // if(band_group_comm.isGroupLeader()) std::cout << "print band=" << iorb << " KE=" << Gvecs.evaluate_KE(cG) << std::endl;
366 
367  std::vector<AtomicOrbitals<DataType>>& centers = bspline.AtomicCenters;
368  app_log() << "Transforming band " << iorb << " on Rank 0" << std::endl;
369  // collect atomic centers by group
370  std::vector<int> uniq_species;
371  for (int center_idx = 0; center_idx < centers.size(); center_idx++)
372  {
373  auto& ACInfo = mybuilder->AtomicCentersInfo;
374  const int my_GroupID = ACInfo.GroupID[center_idx];
375  int found_idx = -1;
376  for (size_t idx = 0; idx < uniq_species.size(); idx++)
377  if (my_GroupID == uniq_species[idx])
378  {
379  found_idx = idx;
380  break;
381  }
382  if (found_idx < 0)
383  uniq_species.push_back(my_GroupID);
384  }
385  // construct group list
386  std::vector<std::vector<int>> group_list(uniq_species.size());
387  for (int center_idx = 0; center_idx < centers.size(); center_idx++)
388  {
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])
393  {
394  group_list[idx].push_back(center_idx);
395  break;
396  }
397  }
398 
399  for (int group_idx = 0; group_idx < group_list.size(); group_idx++)
400  {
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;
409 
410  std::vector<std::complex<double>> i_power(lm_tot);
411  // rotate phase is introduced here.
412  std::complex<double> i_temp(rotate_phase_r, rotate_phase_i);
413  for (size_t l = 0; l <= lmax; l++)
414  {
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);
418  }
419 
420  std::vector<Matrix<double>> all_vals(natoms);
421  std::vector<std::vector<aligned_vector<double>>> vals_local(spline_npoints * omp_get_max_threads());
422  VectorSoaContainer<double, 3> myRSoA(natoms);
423  for (size_t idx = 0; idx < natoms; idx++)
424  {
425  all_vals[idx].resize(spline_npoints, lm_tot * 2);
426  all_vals[idx] = 0.0;
427  myRSoA(idx) = centers[mygroup[idx]].getCenterPos();
428  }
429 
430 #pragma omp parallel
431  {
432  const size_t tid = omp_get_thread_num();
433  const size_t nt = omp_get_num_threads();
434 
435  for (int ip = 0; ip < spline_npoints; ip++)
436  {
437  const size_t ip_idx = tid * spline_npoints + ip;
438  if (policy == 1)
439  {
440  vals_local[ip_idx].resize(lm_tot * 2);
441  for (size_t lm = 0; lm < lm_tot * 2; lm++)
442  {
443  auto& vals = vals_local[ip_idx][lm];
444  vals.resize(natoms);
445  std::fill(vals.begin(), vals.end(), 0.0);
446  }
447  }
448  else
449  {
450  vals_local[ip_idx].resize(natoms * 2);
451  for (size_t iat = 0; iat < natoms * 2; iat++)
452  {
453  auto& vals = vals_local[ip_idx][iat];
454  vals.resize(lm_tot);
455  std::fill(vals.begin(), vals.end(), 0.0);
456  }
457  }
458  }
459 
460  const size_t size_pw_tile = 32;
461  const size_t num_pw_tiles = (Gvecs.NumGvecs + size_pw_tile - 1) / size_pw_tile;
462  aligned_vector<double> j_lm_G(lm_tot, 0.0);
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++)
467  {
468  phase_shift_r[ig].resize(natoms);
469  phase_shift_i[ig].resize(natoms);
470  YlmG[ig].resize(lm_tot);
471  }
472  SoaSphericalTensor<double> Ylm(lmax);
473 
474 #pragma omp for
475  for (size_t tile_id = 0; tile_id < num_pw_tiles; tile_id++)
476  {
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++)
480  {
481  const size_t ig_local = ig - ig_first;
482  // calculate phase shift for all the centers of this group
483  Gvecs.calc_phase_shift(myRSoA, ig, phase_shift_r[ig_local], phase_shift_i[ig_local]);
484  Gvecs.calc_Ylm_G(ig, Ylm, YlmG[ig_local]);
485  }
486 
487  for (int ip = 0; ip < spline_npoints; ip++)
488  {
489  double r = delta * static_cast<double>(ip);
490  const size_t ip_idx = tid * spline_npoints + ip;
491 
492  for (size_t ig = ig_first; ig < ig_last; ig++)
493  {
494  const size_t ig_local = ig - ig_first;
495  // calculate spherical bessel function
496  Gvecs.calc_jlm_G(lmax, r, ig, j_lm_G);
497  for (size_t lm = 0; lm < lm_tot; lm++)
498  j_lm_G[lm] *= YlmG[ig_local][lm];
499 
500  const double cG_r = cG[ig + gvec_first].real();
501  const double cG_i = cG[ig + gvec_first].imag();
502  if (policy == 1)
503  {
504  for (size_t lm = 0; lm < lm_tot; lm++)
505  {
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++)
514  {
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;
519  }
520  }
521  }
522  else
523  {
524  for (size_t idx = 0; idx < natoms; idx++)
525  {
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++)
533  {
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;
537  }
538  }
539  }
540  }
541  }
542  }
543 
544 #pragma omp for collapse(2)
545  for (int ip = 0; ip < spline_npoints; ip++)
546  for (size_t idx = 0; idx < natoms; idx++)
547  {
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++)
551  {
552  double vals_th_r, vals_th_i;
553  const size_t ip_idx = tid * spline_npoints + ip;
554  if (policy == 1)
555  {
556  vals_th_r = vals_local[ip_idx][lm * 2][idx];
557  vals_th_i = vals_local[ip_idx][lm * 2 + 1][idx];
558  }
559  else
560  {
561  vals_th_r = vals_local[ip_idx][idx * 2][lm];
562  vals_th_i = vals_local[ip_idx][idx * 2 + 1][lm];
563  }
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;
568  }
569  }
570  }
571  //app_log() << "Building band " << iorb << " at center " << center_idx << std::endl;
572 
573  for (size_t idx = 0; idx < natoms; idx++)
574  {
575  // reduce all_vals
576  band_group_comm.reduce_in_place(all_vals[idx].data(), all_vals[idx].size());
577  if (!band_group_comm.isGroupLeader())
578  continue;
579 #pragma omp parallel for
580  for (int lm = 0; lm < lm_tot; lm++)
581  {
582  auto& mycenter = centers[mygroup[idx]];
583  aligned_vector<double> splineData_r(spline_npoints);
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)));
589  if (!bspline.isComplex())
590  {
591  mycenter.set_spline(atomic_spline_r, lm, iorb);
592  einspline::destroy(atomic_spline_r);
593  }
594  else
595  {
596  aligned_vector<double> splineData_i(spline_npoints);
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);
606  }
607  }
608  }
609  }
610 }
double bspline(double x, const std::vector< double > &t, const std::vector< double > &c, int k)
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 ...
Definition: Ylm.h:89
std::ostream & app_log()
Definition: OutputManager.h:65
struct qmcplusplus::EinsplineSetBuilder::CenterInfo AtomicCentersInfo
CrystalLattice< ParticleSet::Scalar_t, DIM > UnitCellType
int size() const
return the number of tasks
Definition: Communicate.h:118
T min(T a, T b)
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
Definition: FairDivide.h:114
Wrapping information on parallelism.
Definition: Communicate.h:68
omp_int_t omp_get_thread_num()
Definition: OpenMP.h:25
omp_int_t omp_get_max_threads()
Definition: OpenMP.h:26
bool isGroupLeader()
return true if the current MPI rank is the group lead
Definition: Communicate.h:134
omp_int_t omp_get_num_threads()
Definition: OpenMP.h:27
void reduce_in_place(T *restrict, int n)
std::vector< std::vector< TinyVector< int, 3 > > > Gvecs
EinsplineSetBuilder * mybuilder
pointer to the EinsplineSetBuilder
Definition: BsplineReader.h:42
void bcast(T &)
hFile create(filename)

◆ create_spline_set()

std::unique_ptr< SPOSet > create_spline_set ( const std::string &  my_name,
int  spin,
const BandInfoGroup bandgroup 
)
overridevirtual

create the actual spline sets

Implements BsplineReader.

Definition at line 139 of file HybridRepSetReader.cpp.

References qmcplusplus::app_log(), bspline(), hdf_archive::close(), hdf_archive::create(), Timer::elapsed(), hdf_archive::open(), and hdf_archive::write().

142 {
143  auto bspline = std::make_unique<SA>(my_name);
144  app_log() << " ClassName = " << bspline->getClassName() << std::endl;
145  // set info for Hybrid
147  bool foundspline = spline_reader_.createSplineDataSpaceLookforDumpFile(bandgroup, *bspline);
148  typename SA::HYBRIDBASE& hybrid_center_orbs = *bspline;
149  hybrid_center_orbs.resizeStorage(bspline->myV.size());
150  if (foundspline)
151  {
152  Timer now;
153  hdf_archive h5f(myComm);
154  const auto splinefile = getSplineDumpFileName(bandgroup);
155  h5f.open(splinefile, H5F_ACC_RDONLY);
156  foundspline = bspline->read_splines(h5f);
157  if (foundspline)
158  app_log() << " Successfully restored 3D B-spline coefficients from " << splinefile << ". The reading time is "
159  << now.elapsed() << " sec." << std::endl;
160  }
161 
162  if (!foundspline)
163  {
164  hybrid_center_orbs.flush_zero();
165  initialize_hybrid_pio_gather(spin, bandgroup, *bspline);
166 
167  if (saveSplineCoefs && myComm->rank() == 0)
168  {
169  Timer now;
170  const std::string splinefile(getSplineDumpFileName(bandgroup));
171  hdf_archive h5f;
172  h5f.create(splinefile);
173  std::string classname = bspline->getClassName();
174  h5f.write(classname, "class_name");
175  int sizeD = sizeof(DataType);
176  h5f.write(sizeD, "sizeof");
177  bspline->write_splines(h5f);
178  h5f.close();
179  app_log() << " Stored spline coefficients in " << splinefile << " for potential reuse. The writing time is "
180  << now.elapsed() << " sec." << std::endl;
181  }
182  }
183 
184  {
185  Timer now;
186  bspline->bcast_tables(myComm);
187  app_log() << " Time to bcast the table = " << now.elapsed() << std::endl;
188  }
189  return bspline;
190 }
double bspline(double x, const std::vector< double > &t, const std::vector< double > &c, int k)
int rank() const
return the rank
Definition: Communicate.h:116
Communicate * myComm
communicator
Definition: BsplineReader.h:44
std::ostream & app_log()
Definition: OutputManager.h:65
bool createSplineDataSpaceLookforDumpFile(const BandInfoGroup &bandgroup, SA &bspline) const
create data space in the spline object and try open spline dump files.
void initialize_hybridrep_atomic_centers(SA &bspline) const
initialize basic parameters of atomic orbitals
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...
std::string getSplineDumpFileName(const BandInfoGroup &bandgroup) const
Definition: BsplineReader.h:59
bool saveSplineCoefs
save spline coefficients to storage
Definition: BsplineReader.h:49

◆ initialize_hybrid_pio_gather()

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.

Parameters
spinorbital dataset spin index
bandgroupband info
bsplinethe spline object being worked on

Definition at line 613 of file HybridRepSetReader.cpp.

References qmcplusplus::app_log(), Communicate::bcast(), bspline(), Timer::elapsed(), FairDivideLow(), Communicate::getGroupID(), Communicate::getGroupLeaderComm(), BandInfoGroup::getNumDistinctOrbitals(), Communicate::isGroupLeader(), omptarget::min(), and BandInfoGroup::myBands.

616 {
618  //distribute bands over processor groups
619  int Nbands = bandgroup.getNumDistinctOrbitals();
620  const int Nprocs = myComm->size();
621  const int Nbandgroups = std::min(Nbands, Nprocs);
622  Communicate band_group_comm(*myComm, Nbandgroups);
623  std::vector<int> band_groups(Nbandgroups + 1, 0);
624  FairDivideLow(Nbands, Nbandgroups, band_groups);
625  int iorb_first = band_groups[band_group_comm.getGroupID()];
626  int iorb_last = band_groups[band_group_comm.getGroupID() + 1];
627 
628  app_log() << "Start transforming plane waves to 3D B-splines and atomic radial orbital 1D B-splines." << std::endl;
629  OneSplineOrbData oneband(mybuilder->MeshSize, bspline.HalfG, bspline.isComplex());
630  hdf_archive h5f(&band_group_comm, false);
631  Vector<std::complex<double>> cG(mybuilder->Gvecs[0].size());
632  const std::vector<BandInfo>& cur_bands = bandgroup.myBands;
633  if (band_group_comm.isGroupLeader())
634  h5f.open(mybuilder->H5FileName, H5F_ACC_RDONLY);
635  for (int iorb = iorb_first; iorb < iorb_last; iorb++)
636  {
637  if (band_group_comm.isGroupLeader())
638  {
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);
644  }
645  band_group_comm.bcast(cG);
646  create_atomic_centers_Gspace(cG, band_group_comm, iorb, oneband.getRotatePhase(), bspline);
647  }
648 
649  myComm->barrier();
650  if (band_group_comm.isGroupLeader())
651  {
652  Timer now;
653  bspline.gather_tables(band_group_comm.getGroupLeaderComm());
654  app_log() << " Time to gather the table = " << now.elapsed() << std::endl;
655  }
656 }
double bspline(double x, const std::vector< double > &t, const std::vector< double > &c, int k)
void barrier() const
Communicate * myComm
communicator
Definition: BsplineReader.h:44
std::ostream & app_log()
Definition: OutputManager.h:65
int size() const
return the number of tasks
Definition: Communicate.h:118
T min(T a, T b)
void readOneOrbitalCoefs(const std::string &s, hdf_archive &h5f, Vector< std::complex< double >> &cG) const
read planewave coefficients from h5 file
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
Definition: FairDivide.h:114
Wrapping information on parallelism.
Definition: Communicate.h:68
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
std::string psi_g_path(int ti, int spin, int ib) const
return the path name in hdf5
std::vector< std::vector< TinyVector< int, 3 > > > Gvecs
std::vector< TinyVector< double, OHMMS_DIM > > primcell_kpoints
EinsplineSetBuilder * mybuilder
pointer to the EinsplineSetBuilder
Definition: BsplineReader.h:42
bool rotate
apply orbital rotations
Definition: BsplineReader.h:51

◆ initialize_hybridrep_atomic_centers()

void initialize_hybridrep_atomic_centers ( SA &  bspline) const

initialize basic parameters of atomic orbitals

Definition at line 193 of file HybridRepSetReader.cpp.

References OhmmsAttributeSet::add(), APP_ABORT, qmcplusplus::app_error(), qmcplusplus::app_log(), bspline(), qmcplusplus::ceil(), qmcplusplus::COSCOS, qmcplusplus::Units::charge::e, qmcplusplus::LEKS2018, qmcplusplus::LINEAR, omptarget::min(), OhmmsAttributeSet::put(), and AtomicOrbitals< ST >::set_info().

194 {
196 
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);
203  // assign smooth_scheme
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;
210  else
211  APP_ABORT("initialize_hybridrep_atomic_centers wrong smoothing_scheme name! Only allows Consistent, SmoothAll or "
212  "SmoothPartial.");
213 
214  // assign smooth_function
215  if (s_function_name == "LEKS2018")
216  bspline.smooth_func_id = smoothing_functions::LEKS2018;
217  else if (s_function_name == "coscos")
218  bspline.smooth_func_id = smoothing_functions::COSCOS;
219  else if (s_function_name == "linear")
220  bspline.smooth_func_id = smoothing_functions::LINEAR;
221  else
222  APP_ABORT(
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;
226 
228  auto& centers = bspline.AtomicCenters;
229  auto& ACInfo = mybuilder->AtomicCentersInfo;
230  // load atomic center info only when it is not initialized
231  if (centers.size() == 0)
232  {
233  bool success = true;
234  app_log() << "Reading atomic center info for hybrid representation" << std::endl;
235  for (int center_idx = 0; center_idx < ACInfo.Ncenters; center_idx++)
236  {
237  const int my_GroupID = ACInfo.GroupID[center_idx];
238  if (ACInfo.cutoff[center_idx] < 0)
239  {
240  app_error() << "Hybrid orbital representation needs parameter 'cutoff_radius' for atom " << center_idx
241  << std::endl;
242  success = false;
243  }
244 
245  if (ACInfo.inner_cutoff[center_idx] < 0)
246  {
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;
250  // overwrite the inner_cutoff of all the atoms of the same species
251  for (int id = 0; id < ACInfo.Ncenters; id++)
252  if (my_GroupID == ACInfo.GroupID[id])
253  ACInfo.inner_cutoff[id] = inner_cutoff;
254  }
255  else if (ACInfo.inner_cutoff[center_idx] > ACInfo.cutoff[center_idx])
256  {
257  app_error() << "Hybrid orbital representation 'inner_cutoff' must be smaller than 'spline_radius' for atom "
258  << center_idx << std::endl;
259  success = false;
260  }
261 
262  if (ACInfo.cutoff[center_idx] > 0)
263  {
264  if (ACInfo.lmax[center_idx] < 0)
265  {
266  app_error() << "Hybrid orbital representation needs parameter 'lmax' for atom " << center_idx << std::endl;
267  success = false;
268  }
269 
270  if (ACInfo.spline_radius[center_idx] < 0 && ACInfo.spline_npoints[center_idx] < 0)
271  {
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] + 1e-4) / delta) + 3;
276  for (int id = 0; id < ACInfo.Ncenters; id++)
277  if (my_GroupID == ACInfo.GroupID[id])
278  {
279  ACInfo.spline_npoints[id] = n_grid_point;
280  ACInfo.spline_radius[id] = (n_grid_point - 1) * delta;
281  }
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;
285  }
286  else
287  {
288  if (ACInfo.spline_radius[center_idx] < 0)
289  {
290  app_error() << "Hybrid orbital representation needs parameter 'spline_radius' for atom " << center_idx
291  << std::endl;
292  success = false;
293  }
294 
295  if (ACInfo.spline_npoints[center_idx] < 0)
296  {
297  app_error() << "Hybrid orbital representation needs parameter 'spline_npoints' for atom " << center_idx
298  << std::endl;
299  success = false;
300  }
301  }
302 
303  // check maximally allowed cutoff_radius
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)
307  {
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
310  << std::endl;
311  success = false;
312  }
313  }
314  else
315  {
316  // no atomic regions for this atom type
317  ACInfo.spline_radius[center_idx] = 0.0;
318  ACInfo.spline_npoints[center_idx] = 0;
319  ACInfo.lmax[center_idx] = 0;
320  }
321  }
322 
323  if (!success)
325  "initialize_hybridrep_atomic_centers Failed to initialize atomic centers "
326  "in hybrid orbital representation!");
327 
328  for (int center_idx = 0; center_idx < ACInfo.Ncenters; center_idx++)
329  {
330  AtomicOrbitals<DataType> oneCenter(ACInfo.lmax[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);
335  }
336  }
337 }
double bspline(double x, const std::vector< double > &t, const std::vector< double > &c, int k)
Communicate * myComm
communicator
Definition: BsplineReader.h:44
std::ostream & app_log()
Definition: OutputManager.h:65
ParticleSet & TargetPtcl
quantum particle set
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
std::ostream & app_error()
Definition: OutputManager.h:67
struct qmcplusplus::EinsplineSetBuilder::CenterInfo AtomicCentersInfo
ParticleSet * SourcePtcl
ionic system
T min(T a, T b)
MakeReturn< UnaryNode< FnCeil, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t ceil(const Vector< T1, C1 > &l)
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
xmlNodePtr XMLRoot
root XML node with href, sort, tilematrix, twistnum, source, precision,truncate,version ...
EinsplineSetBuilder * mybuilder
pointer to the EinsplineSetBuilder
Definition: BsplineReader.h:42
void barrier_and_abort(const std::string &msg) const
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42

Member Data Documentation

◆ spline_reader_

SplineReader spline_reader_
private

Definition at line 48 of file HybridRepSetReader.h.


The documentation for this class was generated from the following files: