17 #ifndef QMCPLUSPLUS_HYBRIDREP_CENTER_ORBITALS_H 18 #define QMCPLUSPLUS_HYBRIDREP_CENTER_ORBITALS_H 23 #include "spline2/MultiBspline1D.hpp" 29 template<
class BSPLINESPO>
36 static const int D = 3;
70 for (
int l = 0; l <=
lmax; l++)
71 for (
int m = -l;
m <= l;
m++)
74 rmin = std::max(
rmin, std::numeric_limits<ST>::epsilon());
90 Npad = getAlignedSize<ST>(Nb);
104 template<
typename PT,
typename VT>
107 const VT& cutoff_buffer_in,
108 const VT& spline_radius_in,
109 const VT& non_overlapping_radius_in,
110 const int spline_npoints_in)
132 SplineInst = std::make_shared<MultiBspline1D<ST>>();
147 einspline_engine<AtomicSplineType> bigtable(
SplineInst->getSplinePtr());
148 int lmax_in = 0, spline_npoints_in = 0;
156 return h5f.
readEntry(bigtable,
"radial_spline");
166 einspline_engine<AtomicSplineType> bigtable(
SplineInst->getSplinePtr());
167 success = success && h5f.
writeEntry(bigtable,
"radial_spline");
172 template<
typename VV>
175 if (r > std::numeric_limits<ST>::epsilon())
179 const ST* restrict Ylm_v =
Ylm[0];
181 constexpr ST
czero(0);
182 ST* restrict val = myV.data();
183 ST* restrict local_val =
localV.data();
184 std::fill(myV.begin(), myV.end(),
czero);
188 for (
size_t lm = 0; lm <
lm_tot; lm++)
190 #pragma omp simd aligned(val, local_val : QMC_SIMD_ALIGNMENT) 191 for (
size_t ib = 0; ib < myV.size(); ib++)
192 val[ib] += Ylm_v[lm] * local_val[ib];
197 template<
typename DISPL,
typename VM>
198 inline void evaluateValues(
const DISPL& Displacements,
const int center_idx,
const ST& r, VM& multi_myV)
200 if (r <= std::numeric_limits<ST>::epsilon())
202 const ST* restrict Ylm_v =
Ylm[0];
204 const size_t m = multi_myV.cols();
205 constexpr ST
czero(0);
206 std::fill(multi_myV.begin(), multi_myV.end(),
czero);
209 for (
int ivp = 0; ivp < Displacements.size(); ivp++)
211 PointType dr = Displacements[ivp][center_idx];
212 if (r > std::numeric_limits<ST>::epsilon())
215 ST* restrict val = multi_myV[ivp];
216 ST* restrict local_val =
localV.data();
217 for (
size_t lm = 0; lm <
lm_tot; lm++)
219 #pragma omp simd aligned(val, local_val : QMC_SIMD_ALIGNMENT) 220 for (
size_t ib = 0; ib <
m; ib++)
221 val[ib] += Ylm_v[lm] * local_val[ib];
228 template<
typename VV,
typename GV>
231 ST drx, dry, drz, rhatx, rhaty, rhatz, rinv;
248 const ST* restrict Ylm_v =
Ylm[0];
249 const ST* restrict Ylm_gx =
Ylm[1];
250 const ST* restrict Ylm_gy =
Ylm[2];
251 const ST* restrict Ylm_gz =
Ylm[3];
253 ST* restrict g0 = myG.data(0);
254 ST* restrict g1 = myG.data(1);
255 ST* restrict g2 = myG.data(2);
256 constexpr ST
czero(0),
cone(1), chalf(0.5);
257 std::fill(myV.begin(), myV.end(),
czero);
261 std::fill(myL.begin(), myL.end(),
czero);
262 ST* restrict val = myV.data();
263 ST* restrict lapl = myL.data();
264 ST* restrict local_val =
localV.data();
265 ST* restrict local_grad =
localG.data();
266 ST* restrict local_lapl =
localL.data();
274 ST r_power_temp =
cone;
275 for (
int l = 1; l <=
lmax; l++)
277 r_power_temp *= rinv;
278 for (
int m = -l, lm = l * l;
m <= l;
m++, lm++)
282 for (
size_t lm = 0; lm <
lm_tot; lm++)
284 const ST& l_val =
l_vals[lm];
286 const ST Ylm_rescale = Ylm_v[lm] * r_power;
287 const ST rhat_dot_G = (rhatx * Ylm_gx[lm] + rhaty * Ylm_gy[lm] + rhatz * Ylm_gz[lm]) * r_power;
288 #pragma omp simd aligned(val, g0, g1, g2, lapl, local_val, local_grad, local_lapl : QMC_SIMD_ALIGNMENT) 289 for (
size_t ib = 0; ib < myV.size(); ib++)
291 const ST local_v = local_val[ib];
292 const ST local_g = local_grad[ib];
293 const ST local_l = local_lapl[ib];
295 const ST Vpart = l_val * rinv * local_v;
296 val[ib] += Ylm_rescale * local_v;
299 const ST factor1 = local_g * Ylm_rescale;
300 const ST factor2 = local_v * r_power;
301 const ST factor3 = -Vpart * Ylm_rescale;
302 g0[ib] += factor1 * rhatx + factor2 * Ylm_gx[lm] + factor3 * rhatx;
303 g1[ib] += factor1 * rhaty + factor2 * Ylm_gy[lm] + factor3 * rhaty;
304 g2[ib] += factor1 * rhatz + factor2 * Ylm_gz[lm] + factor3 * rhatz;
307 lapl[ib] += (local_l + (local_g * (2 - l_val) - Vpart) * rinv) * Ylm_rescale + (local_g - Vpart) * rhat_dot_G;
317 std::cout <<
"Warning: an electron is very close to an ion, distance=" << r <<
" be careful!" << std::endl;
320 ST r_power_temp =
cone;
321 for (
int l = 1; l <=
lmax; l++)
323 r_power_temp *= rinv;
324 for (
int m = -l, lm = l * l;
m <= l;
m++, lm++)
328 for (
size_t lm = 0; lm <
lm_tot; lm++)
330 const ST& l_val =
l_vals[lm];
332 const ST Ylm_rescale = Ylm_v[lm] * r_power;
333 const ST rhat_dot_G = (Ylm_gx[lm] * rhatx + Ylm_gy[lm] * rhaty + Ylm_gz[lm] * rhatz) * r_power * r;
334 #pragma omp simd aligned(val, g0, g1, g2, lapl, local_val, local_grad, local_lapl : QMC_SIMD_ALIGNMENT) 335 for (
size_t ib = 0; ib < myV.size(); ib++)
337 const ST local_v = local_val[ib];
338 const ST local_g = local_grad[ib];
339 const ST local_l = local_lapl[ib];
341 const ST Vpart = Ylm_rescale * local_v;
345 const ST factor1 = local_g * Ylm_rescale;
346 const ST factor2 = local_v * r_power;
347 const ST factor3 = -l_val * Vpart * rinv;
348 g0[ib] += factor1 * rhatx + factor2 * Ylm_gx[lm] + factor3 * rhatx;
349 g1[ib] += factor1 * rhaty + factor2 * Ylm_gy[lm] + factor3 * rhaty;
350 g2[ib] += factor1 * rhatz + factor2 * Ylm_gz[lm] + factor3 * rhatz;
353 lapl[ib] += local_l * (
cone - chalf * l_val) * (3 * Ylm_rescale + rhat_dot_G);
362 std::cout <<
"Warning: an electron is on top of an ion!" << std::endl;
365 #pragma omp simd aligned(val, lapl, local_val, local_lapl : QMC_SIMD_ALIGNMENT) 366 for (
size_t ib = 0; ib < myV.size(); ib++)
369 val[ib] = Ylm_v[0] * local_val[ib];
372 lapl[ib] = local_lapl[ib] *
static_cast<ST
>(3) * Ylm_v[0];
380 for (
size_t lm = 1; lm < 4; lm++)
382 #pragma omp simd aligned(g0, g1, g2, local_grad : QMC_SIMD_ALIGNMENT) 383 for (
size_t ib = 0; ib < myV.size(); ib++)
385 const ST local_g = local_grad[ib];
387 g0[ib] += local_g * Ylm_gx[lm];
388 g1[ib] += local_g * Ylm_gy[lm];
389 g2[ib] += local_g * Ylm_gz[lm];
397 template<
typename VV,
typename GV,
typename HT>
401 APP_ABORT(
"AtomicOrbitals::evaluate_vgh");
406 const auto spline_ptr =
SplineInst->getSplinePtr();
407 const auto coefs_tot_size = spline_ptr->coefs_size;
408 coef_copy_ = std::make_shared<std::vector<ST>>(coefs_tot_size);
412 template<
typename VM>
416 const auto spline_ptr =
SplineInst->getSplinePtr();
417 assert(spline_ptr !=
nullptr);
418 const auto spl_coefs = spline_ptr->coefs;
419 const auto Nsplines = spline_ptr->num_splines;
420 const auto coefs_tot_size = spline_ptr->coefs_size;
421 const auto BasisSetSize = coefs_tot_size / Nsplines;
422 const auto TrueNOrbs = rot_mat.size1();
424 if (!use_stored_copy)
432 for (
size_t lidx = 0; lidx <
lm_tot; lidx++)
433 for (
size_t i = 0; i < BasisSetSize; i++)
434 for (
size_t j = 0; j < TrueNOrbs; j++)
436 const auto cur_elem = i * Nsplines + lidx *
Npad + 2 * j;
439 for (
size_t k = 0; k < TrueNOrbs; k++)
441 const auto index = i * Nsplines + lidx *
Npad + 2 * k;
442 ST zr = (*coef_copy_)[index];
443 ST zi = (*coef_copy_)[index + 1];
444 ST wr = rot_mat[k][j].real();
445 ST wi = rot_mat[k][j].imag();
446 newval_r += zr * wr - zi * wi;
447 newval_i += zr * wi + zi * wr;
449 spl_coefs[cur_elem] = newval_r;
450 spl_coefs[cur_elem + 1] = newval_i;
453 for (
size_t lidx = 0; lidx <
lm_tot; lidx++)
454 for (
size_t i = 0; i < BasisSetSize; i++)
455 for (
size_t j = 0; j < TrueNOrbs; j++)
457 const auto cur_elem = i * Nsplines + lidx *
Npad + j;
459 for (
size_t k = 0; k < TrueNOrbs; k++)
461 const auto index = i * Nsplines + lidx *
Npad + k;
462 newval += (*coef_copy_)[index] * rot_mat[k][j];
464 spl_coefs[cur_elem] = newval;
470 template<
typename ST>
474 static const int D = 3;
524 LocationSmoothingInfo& info)
const 527 if (r < cutoff_buffer)
533 const RealType x = (r - cutoff_buffer) * scale;
536 info.d2f_dr2 *= scale * scale;
549 atomic_center.storeParamsBeforeRotation();
552 template<
typename VM>
556 atomic_center.applyRotation(rot_mat, use_stored_copy);
567 size_t SplineCoefsBytes = 0;
572 SplineCoefsBytes +=
AtomicCenters[ic].getSplineSizeInBytes();
575 app_log() <<
"MEMORY " << SplineCoefsBytes / (1 << 20) <<
" MB allocated " 576 <<
"for the atomic radial splines in hybrid orbital representation" << std::endl;
606 h5f.
push(
"atomic_centers",
false);
612 success = success && h5f.
readEntry(ncenter,
"number_of_centers");
620 std::ostringstream gname;
621 gname <<
"center_" << ic;
624 h5f.
push(gname.str().c_str(),
false);
643 h5f.
push(
"atomic_centers",
true);
649 success = success && h5f.
writeEntry(ncenter,
"number_of_centers");
653 std::ostringstream gname;
654 gname <<
"center_" << ic;
657 h5f.
push(gname.str().c_str(),
true);
670 template<
typename Cell>
673 const Cell& PrimLattice,
677 PointType shift_unit = PrimLattice.toUnit(r - r_image);
678 for (
int i = 0; i <
D; i++)
680 ST img = round(shift_unit[i]);
681 bc_sign += HalfG[i] * (int)img;
687 template<
typename VV>
696 PointType dr(-info.dist_dr[0], -info.dist_dr[1], -info.dist_dr[2]);
697 info.r_image = myCenter.getCenterPos() + dr;
698 myCenter.evaluate_v(info.dist_r, dr, myV);
716 myCenter.getNonOverlappingRadius();
720 template<
typename VM>
732 template<
typename VM,
typename Cell,
typename SV>
734 const Cell& PrimLattice,
738 LocationSmoothingInfo& info)
748 bc_signs[ivp] =
get_bc_sign(VP.
R[ivp], myCenter.getCenterPos() - displ[ivp][center_idx], PrimLattice, HalfG);
749 myCenter.evaluateValues(displ, center_idx, info.dist_r, multi_myV);
754 template<
typename VV,
typename GV>
763 const PointType dr(-info.dist_dr[0], -info.dist_dr[1], -info.dist_dr[2]);
764 info.r_image = myCenter.getCenterPos() + dr;
765 myCenter.evaluate_vgl(info.dist_r, dr, myV, myG, myL);
770 template<
typename VV,
typename GV,
typename HT>
779 const PointType dr(-info.dist_dr[0], -info.dist_dr[1], -info.dist_dr[2]);
780 info.r_image = myCenter.getCenterPos() + dr;
781 myCenter.evaluate_vgh(info.dist_r, dr, myV, myG, myH);
786 template<
typename VV>
790 for (
size_t i = 0; i < psi.size(); i++)
791 psi[i] = psi_AO[i] * f + psi[i] * (
cone - f);
795 template<
typename VV,
typename GV>
802 const LocationSmoothingInfo& info)
const 805 const RealType rinv(1.0 / info.dist_r);
806 auto& dist_dr = info.dist_dr;
808 auto& df_dr = info.df_dr;
809 auto& d2f_dr2 = info.d2f_dr2;
811 for (
size_t i = 0; i < psi.size(); i++)
813 d2psi[i] = d2psi_AO[i] * f + d2psi[i] * (
cone - f) + df_dr * rinv * ctwo *
dot(dpsi[i] - dpsi_AO[i], dist_dr) +
814 (psi_AO[i] - psi[i]) * (d2f_dr2 + ctwo * rinv * df_dr);
815 dpsi[i] = dpsi_AO[i] * f + dpsi[i] * (
cone - f) + df_dr * rinv * dist_dr * (psi[i] - psi_AO[i]);
816 psi[i] = psi_AO[i] * f + psi[i] * (
cone - f);
819 for (
size_t i = 0; i < psi.size(); i++)
821 d2psi[i] = d2psi_AO[i] * f + d2psi[i] * (
cone - f);
822 dpsi[i] = dpsi_AO[i] * f + dpsi[i] * (
cone - f);
823 psi[i] = psi_AO[i] * f + psi[i] * (
cone - f);
826 for (
size_t i = 0; i < psi.size(); i++)
828 d2psi[i] = d2psi_AO[i] * f + d2psi[i] * (
cone - f) + df_dr * rinv * ctwo *
dot(dpsi[i] - dpsi_AO[i], dist_dr);
829 dpsi[i] = dpsi_AO[i] * f + dpsi[i] * (
cone - f);
830 psi[i] = psi_AO[i] * f + psi[i] * (
cone - f);
833 throw std::runtime_error(
"Unknown smooth scheme!");
836 template<
class BSPLINESPO>
void evaluateValuesR2R(const VirtualParticleSet &VP, const Cell &PrimLattice, TinyVector< int, D > &HalfG, VM &multi_myV, SV &bc_signs, LocationSmoothingInfo &info)
Index_t getActivePtcl() const
return active particle id
QMCTraits::RealType RealType
std::vector< AtomicOrbitals< ST > > AtomicCenters
atomic centers
void interpolate_buffer_vgl(VV &psi, GV &dpsi, VV &d2psi, const VV &psi_AO, const GV &dpsi_AO, const VV &d2psi_AO, const LocationSmoothingInfo &info) const
std::vector< T, aligned_allocator< T > > aligned_vector
RealType f
smooth function value
bool is_VP_batching_safe(const VirtualParticleSet &VP) const
ST non_overlapping_radius
const ParticleSet & getRefPS() const
ParticleSet this object refers to.
helper functions for EinsplineSetBuilder
const DistRow & getDistRow(int iel) const
return a row of distances for a given target particle
int get_bc_sign(const PointType &r, const PointType &r_image, const Cell &PrimLattice, TinyVector< int, D > &HalfG) const
const std::vector< DisplRow > & getDisplacements() const
return full table displacements
void applyRotation(const VM &rot_mat, bool use_stored_copy)
int getSplineNpoints() const
constexpr std::complex< float > czero
For distance tables of virtual particle (VP) sets constructed based on this table, whether full table is needed on host The corresponding DT of VP need to set MW_EVALUATE_RESULT_NO_TRANSFER_TO_HOST accordingly.
constexpr std::complex< float > cone
int refSourcePtcl
Reference source particle, used when onSphere=true.
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
smoothing_schemes
smoothing schemes
size_t getTotalNum() const
aligned_vector< ST > vContainer_type
int refPtcl
Reference particle.
enum qmcplusplus::HybridRepCenterOrbitals::smoothing_schemes smooth_scheme
vContainer_type r_power_minus_l
void gather_atomic_tables(Communicate *comm, std::vector< int > &offset)
bool write_splines(hdf_archive &h5f)
typename bspline_traits< ST, 1 >::BCType AtomicBCType
typename AtomicOrbitals< SPLINEBASE::DataType >::PointType PointType
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)
smoothing_functions smooth_func_id
smoothing function
void evaluateVGL(T x, T y, T z)
makes a table of and their gradients up to Lmax.
typename DistanceTable::RealType RealType
int size() const
return the number of tasks
void bcast_tables(Communicate *comm)
void evaluate_vgl(const ST &r, const PointType &dr, VV &myV, GV &myG, VV &myL)
A proxy class to the quantum ParticleSet.
void set_info(const ParticleSet &ions, ParticleSet &els, const std::vector< int > &mapping)
ST getSplineRadius() const
const DistanceTableAB & getDistTableAB(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAB
Wrapping information on parallelism.
void resizeStorage(size_t Nb)
void resizeStorage(size_t Nb)
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
Specialized paritlce class for atomistic simulations.
std::shared_ptr< std::vector< ST > > coef_copy_
coef copy for orbital rotation
ST getCutoffBuffer() const
ST getNonOverlappingRadius() const
SoaSphericalTensor< ST > Ylm
void evaluate_v(const ParticleSet &P, const int iat, VV &myV, LocationSmoothingInfo &info)
void evaluateValuesC2X(const VirtualParticleSet &VP, VM &multi_myV, LocationSmoothingInfo &info)
void gather_tables(Communicate *comm, std::vector< int > &offset)
void storeParamsBeforeRotation()
std::shared_ptr< MultiBspline1D< ST > > SplineInst
1D spline of radial functions of all the orbitals
bool read_splines(hdf_archive &h5f)
size_t getSplineSizeInBytes() const
void evaluate_vgh(const ParticleSet &P, const int iat, VV &myV, GV &myG, HT &myH, LocationSmoothingInfo &info)
RealType df_dr
smooth function first derivative
void evaluate_vgl(const ParticleSet &P, const int iat, VV &myV, GV &myG, VV &myL, LocationSmoothingInfo &info)
void selectRegionAndComputeSmoothing(const ST &cutoff_buffer, const ST &cutoff, LocationSmoothingInfo &info) const
select a region (within the buffer shell, in the buffer, interstitial region) and compute the smoothi...
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
Region region
region of the location
void bcast_tables(Communicate *comm)
RealType d2f_dr2
smooth function second derivative
T smoothing(smoothing_functions func_id, T x, T &dx, T &d2x)
QMCTraits::PosType PosType
bool write_splines(hdf_archive &h5f)
HybridRepCenterOrbitals()
void interpolate_buffer_v(VV &psi, const VV &psi_AO, const RealType f) const
void applyRotation(const VM &rot_mat, bool use_stored_copy)
void push(const std::string &gname, bool createit=true)
push a group to the group stack
RealType dist_r
r from distance table
PointType r_image
for APBC
MakeReturn< UnaryNode< FnLog, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t log(const Vector< T1, C1 > &l)
UBspline_1d_d AtomicSingleSplineType
void evaluateV(T x, T y, T z, T *Ylm) const
compute Ylm
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
sycl::event copy_n(sycl::queue &aq, const T1 *restrict VA, size_t array_size, T2 *restrict VC, const std::vector< sycl::event > &events)
const PointType & getCenterPos() const
void evaluate_v(const ST &r, const PointType &dr, VV &myV)
void storeParamsBeforeRotation()
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
std::vector< int > Super2Prim
mapping supercell to primitive cell
PosType dist_dr
dr from distance table
void set_spline(AtomicSingleSplineType *spline, int lm, int ispline)
General HybridRepSetReader to handle any unitcell.
bool readEntry(T &data, const std::string &aname)
read the data from the group aname and return status use read() for inbuilt error checking ...
void gatherv(T *sb, T *rb, int n, IT &counts, IT &displ, int dest)
virtual int get_first_neighbor(IndexType iat, RealType &r, PosType &dr, bool newpos) const =0
find the first nearest neighbor
typename DistanceTable::PosType PosType
typename bspline_traits< ST, 1 >::SplineType AtomicSplineType
void evaluate_vgh(const ST &r, const PointType &dr, VV &myV, GV &myG, HT &myH)
bool read_splines(hdf_archive &h5f)
bool writeEntry(T &data, const std::string &aname)
write the data to the group aname and return status use write() for inbuilt error checking ...
void evaluateValues(const DISPL &Displacements, const int center_idx, const ST &r, VM &multi_myV)