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< SPOSet > create_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< SPOSet > create_spline_set (int spin, xmlNodePtr cur, SPOSetInputInfo &input_info)
 create the spline after one of the kind is created More...
 
std::unique_ptr< SPOSet > create_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
EinsplineSetBuilder * mybuilder
 pointer to the EinsplineSetBuilder More...
 
Communicate * myComm
 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: