26 #include <string_view> 47 app_error() <<
"Could not open HDF5 file \"" <<
H5FileName <<
"\" in EinsplineSetBuilder::ReadOrbitalInfo.\n";
56 if (format.find(
"ES") == std::string::npos)
57 throw std::runtime_error(
"Format string input \"" + format +
"\" doesn't contain \"ES\" keyword.");
62 catch (
const std::exception&
e)
65 <<
"EinsplineSetBuilder::ReadOrbitalInfo h5 file format is too old or it is not a bspline orbital file!" 75 app_log() <<
" Reading orbital file in ESHDF format.\n";
81 std::array<char, 1000> buff;
82 int length = std::snprintf(buff.data(), buff.size(),
83 " Lattice = \n [ %9.6f %9.6f %9.6f\n" 84 " %9.6f %9.6f %9.6f\n" 85 " %9.6f %9.6f %9.6f ]\n",
86 Lattice(0, 0),
Lattice(0, 1),
Lattice(0, 2),
Lattice(1, 0),
Lattice(1, 1),
Lattice(1, 2),
89 throw std::runtime_error(
"Error converting lattice to a string");
90 app_log() << std::string_view(buff.data(), length);
92 std::snprintf(buff.data(), buff.size(),
93 " SuperLattice = \n [ %9.6f %9.6f %9.6f\n" 94 " %9.6f %9.6f %9.6f\n" 95 " %9.6f %9.6f %9.6f ]\n",
96 SuperLattice(0, 0),
SuperLattice(0, 1),
SuperLattice(0, 2),
SuperLattice(1, 0),
SuperLattice(1, 1),
99 throw std::runtime_error(
"Error converting SuperLattice to a string");
100 app_log() << std::string_view(buff.data(), length) << std::endl;
102 throw std::runtime_error(
"CheckLattice failed");
104 for (
int i = 0; i < 3; i++)
105 for (
int j = 0; j < 3; j++)
107 int have_dpsi =
false;
121 H5File.
read(species_ids,
"/atoms/species_ids");
123 H5File.
read(num_species,
"/atoms/number_of_species");
124 std::vector<int> atomic_numbers(num_species);
125 for (
int isp = 0; isp < num_species; isp++)
127 std::ostringstream name;
128 name <<
"/atoms/species_" << isp <<
"/atomic_number";
132 for (
int i = 0; i < species_ids.
size(); i++)
133 IonTypes[i] = atomic_numbers[species_ids[i]];
145 std::vector<int> prim_atom_counts;
146 prim_atom_counts.resize(
IonPos.size(), 0);
150 for (
int j = 0; j <
IonPos.size(); j++)
154 dr[k] -= round(dr[k]);
160 prim_atom_counts[j]++;
165 <<
" was found twice in the primitive cell as ion " <<
Super2Prim[i] <<
" and " << j
174 app_error() <<
"Supercell ion " << i <<
" not found in the primitive cell" << std::endl;
184 for (
int i = 0; i <
IonPos.size(); i++)
185 if (prim_atom_counts[i] != tiling_size)
187 app_error() <<
"Primitive cell ion " << i <<
" was found only " << prim_atom_counts[i]
188 <<
" times in the supercell rather than " << tiling_size << std::endl;
194 for (
int i = 0; i <
IonPos.size(); i++)
201 for (
int i = 0; i <
IonPos.size(); i++)
215 app_error() <<
"Primitive cell ion " << i <<
" vs supercell ion " << j
216 <<
" atomic number not matching: " <<
IonTypes[i] <<
" vs " 224 ii_table.get_first_neighbor(j, r, dr,
false);
226 APP_ABORT(
"EinsplineSetBuilder::ReadOrbitalInfo_ESHDF too close ions <1e-3 bohr!");
233 const int inner_cutoff_ind = source_species.findAttribute(
"inner_cutoff");
234 const int cutoff_radius_ind = source_species.findAttribute(
"cutoff_radius");
235 const int spline_radius_ind = source_species.findAttribute(
"spline_radius");
236 const int spline_npoints_ind = source_species.findAttribute(
"spline_npoints");
237 const int lmax_ind = source_species.findAttribute(
"lmax");
242 if (inner_cutoff_ind >= 0)
244 if (cutoff_radius_ind >= 0)
246 if (spline_radius_ind >= 0)
248 if (spline_npoints_ind >= 0)
260 std::ostringstream path;
261 path <<
"/electrons/kpoint_" << ti <<
"/reduced_k";
284 #pragma omp parallel for 285 for (
int iG = 0; iG < numG; iG++)
287 app_log() <<
" Read " << numG <<
" density G-vectors.\n";
288 for (
int ispin = 0; ispin <
NumSpins; ispin++)
290 std::ostringstream density_r_path, density_g_path;
291 density_r_path <<
"/electrons/density/spin_" << ispin <<
"/density_r";
292 density_g_path <<
"/electrons/density/spin_" << ispin <<
"/density_g";
297 app_log() <<
" EinsplineSetBuilder found density in the HDF5 file.\n";
298 std::vector<ComplexType> density_G;
299 std::vector<std::complex<double>> Density_G_DP;
300 H5File.
read(Density_G_DP, density_g_path.str());
301 density_G.assign(Density_G_DP.begin(), Density_G_DP.end());
302 if (!density_G.size())
304 app_error() <<
" Density reduced G-vectors defined, but not the" <<
" density.\n";
312 for (
int iG = 0; iG < density_G.size(); iG++)
331 #pragma omp parallel for 332 for (
int iG = 0; iG < numG; iG++)
334 app_log() <<
" Read " << numG <<
" VHXC G-vectors.\n";
335 for (
int ispin = 0; ispin <
NumSpins; ispin++)
338 std::ostringstream VHXC_r_path, VHXC_g_path;
339 VHXC_r_path <<
"/electrons/VHXC/spin_" << ispin <<
"/VHXC_r";
340 VHXC_g_path <<
"/electrons/VHXC/spin_" << ispin <<
"/VHXC_g";
345 app_log() <<
" EinsplineSetBuilder found VHXC in the HDF5 file.\n";
346 std::vector<std::complex<double>> VHXC_G_DP;
347 std::vector<ComplexType> VHXC_G;
349 VHXC_G.assign(VHXC_G_DP.begin(), VHXC_G_DP.end());
352 app_error() <<
" VHXC reduced G-vectors defined, but not the" <<
" VHXC.\n";
364 app_log() <<
" Skip initialization of the density" << std::endl;
385 int allowed[] = {72, 75, 80, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150,
386 160, 162, 180, 192, 200, 216, 225, 240, 243, 250, 256, 270, 288, 300,
387 320, 324, 360, 375, 384, 400, 405, 432, 450, 480, 486, 500, 512, 540,
388 576, 600, 625, 640, 648, 675, 720, 729, 750, 768, 800, 810, 864, 900,
389 960, 972, 1000, 1024, 1080, 1125, 1152, 1200, 1215, 1250, 1280, 1296, 1350, 1440,
390 1458, 1500, 1536, 1600, 1620, 1728, 1800, 1875, 1920, 1944, 2000, 2025, 2048, 2160,
391 2187, 2250, 2304, 2400, 2430, 2500, 2560, 2592, 2700, 2880, 2916, 3000, 3072, 3125,
392 3200, 3240, 3375, 3456, 3600, 3645, 3750, 3840, 3888, 4000, 4050, 4096, 4320, 4374,
393 4500, 4608, 4800, 4860, 5000, 5120, 5184, 5400, 5625, 5760, 5832, 6000, 6075, 6144,
394 6250, 6400, 6480, 6561, 6750, 6912, 7200, 7290, 7500, 7680, 7776, 8000, 8100, 8192,
395 8640, 8748, 9000, 9216, 9375, 9600, 9720, 10000, 10125, 10240, 10368, 10800, 10935, 11250,
396 11520, 11664, 12000, 12150, 12288, 12500, 12800, 12960, 13122, 13500, 13824, 14400, 14580, 15000,
397 15360, 15552, 15625, 16000, 16200, 16384, 16875, 17280, 17496, 18000, 18225, 18432, 18750, 19200,
398 19440, 19683, 20000, 20250, 20480, 20736, 21600, 21870, 22500, 23040, 23328, 24000, 24300, 24576,
399 25000, 25600, 25920, 26244, 27000, 27648, 28125, 28800, 29160, 30000, 30375, 30720, 31104, 31250,
400 32000, 32400, 32768, 32805, 33750, 34560, 34992, 36000, 36450, 36864, 37500, 38400, 38880, 39366,
401 40000, 40500, 40960, 41472, 43200, 43740, 45000, 46080, 46656, 46875, 48000, 48600, 49152, 50000,
402 50625, 51200, 51840, 52488, 54000, 54675, 55296, 56250, 57600, 58320, 59049, 60000, 60750, 61440,
403 62208, 62500, 64000, 64800, 65536};
413 std::ostringstream Gpath;
414 Gpath <<
"/electrons/kpoint_0/gvectors";
416 numg =
Gvecs[0].size();
420 Gvecs[0].resize(numg);
423 for (
int ig = 0; ig <
Gvecs[0].size(); ig++)
425 maxIndex[0] = std::max(maxIndex[0],
std::abs(
Gvecs[0][ig][0]));
426 maxIndex[1] = std::max(maxIndex[1],
std::abs(
Gvecs[0][ig][1]));
427 maxIndex[2] = std::max(maxIndex[2],
std::abs(
Gvecs[0][ig][2]));
447 app_log() <<
" Assumes distinct Gvecs set for different twists. Regenerate orbital files using updated QE." 457 std::ostringstream Gpath;
458 Gpath <<
"/electrons/kpoint_" << ik <<
"/gvectors";
460 numg =
Gvecs[ik].size();
472 std::ostringstream o;
473 o <<
"Twist " << ik <<
": The number of Gvecs is different from kpoint_0." 474 <<
" This is not supported anymore. Rerun pw2qmcpack.x or equivalent";
478 Gvecs[ik].resize(numg);
496 std::vector<BandInfo>& SortBands(*
FullBands[spin]);
503 std::ostringstream ePath;
504 ePath <<
"/electrons/kpoint_" << tindex <<
"/spin_" << spin <<
"/eigenvalues";
505 std::vector<double> eigvals;
507 for (
int bi = 0; bi <
NumBands; bi++)
513 band.
Energy = eigvals[bi];
514 if (band.
Energy > -1.0e100)
515 SortBands.push_back(band);
523 app_log() << SortBands.size() <<
" complex-valued orbitals supplied by h5 can be expanded up to " << maxOrbs
524 <<
" SPOs." << std::endl;
525 if (maxOrbs < numOrbs)
527 "more orbitals than what the h5 file supplies.");
532 app_log() <<
"Sorting the bands by index now:\n";
533 sort(SortBands.begin(), SortBands.end(),
sortByIndex);
535 else if (sortBands == 1)
537 app_log() <<
"Sorting the bands now:\n";
538 sort(SortBands.begin(), SortBands.end());
541 std::vector<int> gsOcc(maxOrbs);
542 int N_gs_orbs = numOrbs;
544 for (
int ti = 0; ti < SortBands.size(); ti++)
546 if (nocced < N_gs_orbs)
553 else if ((SortBands[ti].
MakeTwoCopies && (N_gs_orbs - nocced == 1)) || !SortBands[ti].MakeTwoCopies)
562 app_log() <<
" Occupying bands based on energy in mode " << (
Occ.size() > 0 ?
"\"excited\"" :
"\"ground\"")
565 std::vector<int> Removed(0, 0);
566 std::vector<int> Added(0, 0);
567 for (
int ien = 0; ien <
Occ.size(); ien++)
570 Removed.push_back(-
Occ[ien]);
571 else if (
Occ[ien] > 0)
572 Added.push_back(
Occ[ien]);
574 if (Added.size() - Removed.size() != 0)
576 app_log() <<
"need to add and remove same number of orbitals. " << Added.size() <<
" " << Removed.size()
580 std::vector<int> DiffOcc(maxOrbs, 0);
582 for (
int i = 0; i < Removed.size(); i++)
583 DiffOcc[Removed[i] - 1] -= 1;
584 for (
int i = 0; i < Added.size(); i++)
585 DiffOcc[Added[i] - 1] += 1;
586 std::vector<int> SumOrb(SortBands.size(), 0);
588 for (
int i = 0; i < SumOrb.size(); i++)
592 SumOrb[i] = gsOcc[i] + DiffOcc[doi++];
593 SumOrb[i] += DiffOcc[doi++];
596 SumOrb[i] = gsOcc[i] + DiffOcc[doi++];
598 std::vector<BandInfo> ReOrderedBands;
599 std::vector<BandInfo> RejectedBands;
600 for (
int i = 0; i < SumOrb.size(); i++)
604 SortBands[i].MakeTwoCopies =
true;
605 ReOrderedBands.push_back(SortBands[i]);
607 else if (SumOrb[i] == 1)
609 SortBands[i].MakeTwoCopies =
false;
610 ReOrderedBands.push_back(SortBands[i]);
612 else if (SumOrb[i] == 0)
614 SortBands[i].MakeTwoCopies =
false;
615 RejectedBands.push_back(SortBands[i]);
619 app_log() <<
" Trying to add the same orbital (" << i <<
") less than zero or more than 2 times." << std::endl;
623 ReOrderedBands.insert(ReOrderedBands.end(), RejectedBands.begin(), RejectedBands.end());
624 SortBands = ReOrderedBands;
628 app_log() <<
" Occupying bands based on (ti,bi) data." << std::endl;
631 app_log() <<
" Need Occ = pairs*4. Occ is (ti,bi) of removed, then added." << std::endl;
636 for (
int ien = 0; ien < SortBands.size(); ien++)
638 if ((
Occ[cnt] == SortBands[ien].TwistIndex) && (
Occ[cnt + 1] == SortBands[ien].BandIndex))
644 app_log() <<
"removing orbital " << ien << std::endl;
649 app_log() <<
"adding orbital " << ien << std::endl;
654 std::vector<BandInfo> ReOrderedBands;
655 std::vector<BandInfo> RejectedBands;
656 for (
int i = 0; i < SortBands.size(); i++)
660 SortBands[i].MakeTwoCopies =
true;
661 ReOrderedBands.push_back(SortBands[i]);
663 else if (gsOcc[i] == 1)
665 SortBands[i].MakeTwoCopies =
false;
666 ReOrderedBands.push_back(SortBands[i]);
668 else if (gsOcc[i] == 0)
670 SortBands[i].MakeTwoCopies =
false;
671 RejectedBands.push_back(SortBands[i]);
675 app_log() <<
" Trying to add the same orbital (" << i <<
") less than zero or more than 2 times." << std::endl;
679 ReOrderedBands.insert(ReOrderedBands.end(), RejectedBands.begin(), RejectedBands.end());
680 SortBands = ReOrderedBands;
689 int numOrbs_counter = 0;
690 while (numOrbs_counter < numOrbs)
693 numOrbs_counter += 2;
void set(const Tensor< TT, D > &lat)
set the lattice vector from the command-line options
void resize(size_type n, Type_t val=Type_t())
Resize the container.
a class that defines a supercell in D-dimensional Euclean space.
double Energy
energy associated with this band
Tensor< int, OHMMS_DIM > TileMatrix
bool open(const std::filesystem::path &fname, unsigned flags=H5F_ACC_RDWR)
open a file
void resize(int ncenters)
helper functions for EinsplineSetBuilder
int rank() const
return the rank
std::vector< double > spline_radius
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
Array< RealType, OHMMS_DIM > Density_r
QTBase::RealType RealType
std::vector< int > DistinctTwists
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
size_t getTotalNum() const
ParticleSet & TargetPtcl
quantum particle set
std::vector< TinyVector< double, OHMMS_DIM > > ion_pos
std::ostream & app_error()
Builder class for einspline-based SPOSet objects.
void OccupyBands_ESHDF(int spin, int sortBands, int numOrbs)
struct qmcplusplus::EinsplineSetBuilder::CenterInfo AtomicCentersInfo
TinyVector< int, 3 > Version
ParticleSet * SourcePtcl
ionic system
std::vector< int > Super2Prim
std::vector< double > non_overlapping_radius
void update(bool skipSK=false)
update the internal data
std::vector< int > spline_npoints
std::vector< std::unique_ptr< std::vector< BandInfo > > > FullBands
Helper vector for sorting bands.
TinyVector< T, 3 > lower_bound(const TinyVector< T, 3 > &a, const TinyVector< T, 3 > &b)
helper function to determine the lower bound of a domain (need to move up)
std::vector< double > inner_cutoff
ParticleIndex GroupID
Species ID.
bool HaveOrbDerivs
This is true if we have the orbital derivatives w.r.t. the ion positions.
Vector< TinyVector< double, OHMMS_DIM > > IonPos
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
std::vector< ComplexType > VHXC_G[2]
TinyVector< int, 3 > MeshSize
size_type size() const
return the current size
MakeReturn< UnaryNode< FnCeil, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t ceil(const Vector< T1, C1 > &l)
SingleParticlePos toUnit_floor(const TinyVector< T1, D > &r) const
Communicate * myComm
pointer to Communicate
bool ReadOrbitalInfo(bool skipChecks=false)
std::vector< ComplexType > Density_G
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
bool MakeTwoCopies
This is true if we should make distinct copies represeninting a +k, -k pair.
std::vector< bool > MakeTwoCopies
auto & getDistTable(int table_ID) const
get a distance table by table_ID
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
std::vector< double > cutoff
bool sortByIndex(BandInfo leftB, BandInfo rightB)
int TwistIndex
twist index
bool ReadGvectors_ESHDF()
read gvectors for each twist
Tensor< T, D > inverse(const Tensor< T, D > &a)
Tensor< double, OHMMS_DIM > LatticeInv
std::filesystem::path H5FileName
Array< RealType, OHMMS_DIM > VHXC_r[2]
Tensor< double, OHMMS_DIM > SuperLattice
const auto & getLattice() const
std::vector< std::vector< TinyVector< int, 3 > > > Gvecs
std::vector< TinyVector< double, OHMMS_DIM > > primcell_kpoints
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
void read(T &data, const std::string &aname)
read the data from the group aname and check status runtime error is issued on I/O error ...
bool ReadOrbitalInfo_ESHDF(bool skipChecks=false)
QMCState qmc_common
a unique QMCState during a run
void barrier_and_abort(const std::string &msg) const
bool readEntry(T &data, const std::string &aname)
read the data from the group aname and return status use read() for inbuilt error checking ...
A D-dimensional Array class based on PETE.
int findAttribute(const std::string &name) const
almost all code ignores this and just uses addAttribute for the same purpose.
Tensor< double, OHMMS_DIM > RecipLattice
std::vector< TinyVector< int, OHMMS_DIM > > DensityReducedGvecs
Particle density in G-space for MPC interaction.
std::vector< int > GroupID
std::vector< TinyVector< int, OHMMS_DIM > > VHXCReducedGvecs
DFT potential.
Tensor< double, OHMMS_DIM > Lattice
bool use_density
true, if density is used, e.g. MPC