QMCPACK
SoaSphericalTensor< T > Class Template Reference

SoaSphericalTensor that evaluates the Real Spherical Harmonics. More...

+ Inheritance diagram for SoaSphericalTensor< T >:
+ Collaboration diagram for SoaSphericalTensor< T >:

Public Member Functions

 SoaSphericalTensor (const int l_max, bool addsign=false)
 constructor More...
 
 SoaSphericalTensor (const SoaSphericalTensor &rhs)=default
 
void evaluateV (T x, T y, T z, T *Ylm) const
 compute Ylm More...
 
void batched_evaluateV (const OffloadArray3D &xyz, OffloadArray3D &Ylm) const
 evaluate V for multiple electrons and multiple pbc images More...
 
void batched_evaluateVGL (const OffloadArray3D &xyz, OffloadArray4D &Ylm_vgl) const
 evaluate VGL for multiple electrons and multiple pbc images More...
 
void evaluateV (T x, T y, T z)
 compute Ylm More...
 
void evaluateVGL (T x, T y, T z)
 makes a table of $ r^l S_l^m $ and their gradients up to Lmax. More...
 
void evaluateVGH (T x, T y, T z)
 makes a table of $ r^l S_l^m $ and their gradients up to Lmax. More...
 
void evaluateVGHGH (T x, T y, T z)
 makes a table of $ r^l S_l^m $ and their gradients up to Lmax. More...
 
const T * operator[] (size_t component) const
 return the starting address of the component More...
 
size_t size () const
 
int lmax () const
 

Static Public Member Functions

static void evaluate_bare (T x, T y, T z, T *Ylm, int lmax, const T *factorL, const T *factorLM)
 compute Ylm for single position More...
 
static void evaluateVGL_impl (const T x, const T y, const T z, T *restrict Ylm_vgl, int lmax, const T *factorL, const T *factorLM, const T *factor2L, const T *normfactor, size_t offset)
 compute Ylm_vgl for single position More...
 
static int index (int l, int m)
 returns the index/locator for ( $l,m$) combo, $ l(l+1)+m $ More...
 

Private Types

using OffloadVector = Vector< T, OffloadPinnedAllocator< T > >
 
using OffloadArray2D = Array< T, 2, OffloadPinnedAllocator< T > >
 
using OffloadArray3D = Array< T, 3, OffloadPinnedAllocator< T > >
 
using OffloadArray4D = Array< T, 4, OffloadPinnedAllocator< T > >
 

Private Attributes

int Lmax
 maximum angular momentum for the center More...
 
const std::shared_ptr< OffloadVectornorm_factor_ptr_
 Normalization factors. More...
 
const std::shared_ptr< OffloadVectorfactorLM_ptr_
 pre-evaluated factor $1/\sqrt{(l+m)\times(l+1-m)}$ More...
 
const std::shared_ptr< OffloadVectorfactorL_ptr_
 pre-evaluated factor $\sqrt{(2l+1)/(4\pi)}$ More...
 
const std::shared_ptr< OffloadVectorfactor2L_ptr_
 pre-evaluated factor $(2l+1)/(2l-1)$ More...
 
OffloadVectornorm_factor_
 norm_factor reference More...
 
OffloadVectorfactorLM_
 factorLM reference More...
 
OffloadVectorfactorL_
 factorL reference More...
 
OffloadVectorfactor2L_
 factor2L reference More...
 
VectorSoaContainer< T, 5 > cYlm
 composite More...
 

Detailed Description

template<typename T>
class qmcplusplus::SoaSphericalTensor< T >

SoaSphericalTensor that evaluates the Real Spherical Harmonics.

The template parameters

  • T, the value_type, e.g. double
  • Point_t, a vector type to provide xyz coordinate. Point_t must have the operator[] defined, e.g., TinyVector<double,3>.

Real Spherical Harmonics Ylm $=r^l S_l^m(x,y,z) $ is stored in an array ordered as [0,-1 0 1,-2 -1 0 1 2, -Lmax,-Lmax+1,..., Lmax-1,Lmax] where Lmax is the maximum angular momentum of a center. All the data members, e.g, Ylm and pre-calculated factors, can be accessed by index(l,m) which returns the locator of the combination for l and m.

Definition at line 40 of file SoaSphericalTensor.h.

Member Typedef Documentation

◆ OffloadArray2D

using OffloadArray2D = Array<T, 2, OffloadPinnedAllocator<T> >
private

Definition at line 44 of file SoaSphericalTensor.h.

◆ OffloadArray3D

using OffloadArray3D = Array<T, 3, OffloadPinnedAllocator<T> >
private

Definition at line 45 of file SoaSphericalTensor.h.

◆ OffloadArray4D

using OffloadArray4D = Array<T, 4, OffloadPinnedAllocator<T> >
private

Definition at line 46 of file SoaSphericalTensor.h.

◆ OffloadVector

using OffloadVector = Vector<T, OffloadPinnedAllocator<T> >
private

Definition at line 43 of file SoaSphericalTensor.h.

Constructor & Destructor Documentation

◆ SoaSphericalTensor() [1/2]

SoaSphericalTensor ( const int  l_max,
bool  addsign = false 
)
inlineexplicit

constructor

Parameters
l_maxmaximum angular momentum
addsignflag to determine what convention to use

Evaluate all the constants and prefactors. The spherical harmonics is defined as

\[ Y_l^m (\theta,\phi) = \sqrt{\frac{(2l+1)(l-m)!}{4\pi(l+m)!}} P_l^m(\cos\theta)e^{im\phi}\]

Note that the data member Ylm is a misnomer and should not be confused with "spherical harmonics" $Y_l^m$.

  • When addsign == true, e.g., Gaussian packages

    \begin{eqnarray*} S_l^m &=& (-1)^m \sqrt{2}\Re(Y_l^{|m|}), \;\;\;m > 0 \\ &=& Y_l^0, \;\;\;m = 0 \\ &=& (-1)^m \sqrt{2}\Im(Y_l^{|m|}),\;\;\;m < 0 \end{eqnarray*}

  • When addsign == false, e.g., SIESTA package,

    \begin{eqnarray*} S_l^m &=& \sqrt{2}\Re(Y_l^{|m|}), \;\;\;m > 0 \\ &=& Y_l^0, \;\;\;m = 0 \\ &=&\sqrt{2}\Im(Y_l^{|m|}),\;\;\;m < 0 \end{eqnarray*}

Definition at line 225 of file SoaSphericalTensor.h.

226  : Lmax(l_max),
227  norm_factor_ptr_(std::make_shared<OffloadVector>()),
228  factorLM_ptr_(std::make_shared<OffloadVector>()),
229  factorL_ptr_(std::make_shared<OffloadVector>()),
230  factor2L_ptr_(std::make_shared<OffloadVector>()),
235 {
236  constexpr T czero(0);
237  constexpr T cone(1);
238  const int ntot = (Lmax + 1) * (Lmax + 1);
239  cYlm.resize(ntot);
240  norm_factor_.resize(ntot, cone);
241  const T sqrt2 = std::sqrt(2.0);
242  if (addsign)
243  {
244  for (int l = 0; l <= Lmax; l++)
245  {
246  norm_factor_[index(l, 0)] = cone;
247  for (int m = 1; m <= l; m++)
248  {
249  norm_factor_[index(l, m)] = std::pow(-cone, m) * sqrt2;
250  norm_factor_[index(l, -m)] = std::pow(-cone, -m) * sqrt2;
251  }
252  }
253  }
254  else
255  {
256  for (int l = 0; l <= Lmax; l++)
257  {
258  for (int m = 1; m <= l; m++)
259  {
260  norm_factor_[index(l, m)] = sqrt2;
261  norm_factor_[index(l, -m)] = sqrt2;
262  }
263  }
264  }
265  factorL_.resize(Lmax + 1);
266  const T omega = 1.0 / std::sqrt(16.0 * std::atan(1.0));
267  for (int l = 1; l <= Lmax; l++)
268  factorL_[l] = std::sqrt(static_cast<T>(2 * l + 1)) * omega;
269  factor2L_.resize(Lmax + 1);
270  for (int l = 1; l <= Lmax; l++)
271  factor2L_[l] = static_cast<T>(2 * l + 1) / static_cast<T>(2 * l - 1);
272  factorLM_.resize(ntot);
273  for (int l = 1; l <= Lmax; l++)
274  for (int m = 1; m <= l; m++)
275  {
276  T fac2 = 1.0 / std::sqrt(static_cast<T>((l + m) * (l + 1 - m)));
277  factorLM_[index(l, m)] = fac2;
278  factorLM_[index(l, -m)] = fac2;
279  }
282  factorL_.updateTo();
284 }
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
OffloadVector & norm_factor_
norm_factor reference
const std::shared_ptr< OffloadVector > norm_factor_ptr_
Normalization factors.
const std::shared_ptr< OffloadVector > factor2L_ptr_
pre-evaluated factor
OffloadVector & factorL_
factorL reference
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
constexpr std::complex< float > cone
Definition: BLAS.hpp:50
VectorSoaContainer< T, 5 > cYlm
composite
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
MakeReturn< UnaryNode< FnArcTan, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t atan(const Vector< T1, C1 > &l)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
const std::shared_ptr< OffloadVector > factorL_ptr_
pre-evaluated factor
int Lmax
maximum angular momentum for the center
static int index(int l, int m)
returns the index/locator for ( ) combo,
void updateTo(size_type size=0, std::ptrdiff_t offset=0)
Definition: OhmmsVector.h:263
void resize(size_type n)
resize myData
OffloadVector & factor2L_
factor2L reference
const std::shared_ptr< OffloadVector > factorLM_ptr_
pre-evaluated factor
OffloadVector & factorLM_
factorLM reference

◆ SoaSphericalTensor() [2/2]

SoaSphericalTensor ( const SoaSphericalTensor< T > &  rhs)
default

Member Function Documentation

◆ batched_evaluateV()

void batched_evaluateV ( const OffloadArray3D xyz,
OffloadArray3D Ylm 
) const
inline

evaluate V for multiple electrons and multiple pbc images

Parameters
[in]xyzelectron positions [Nelec, Npbc, 3(x,y,z)]
[out]YlmSpherical tensor elements [Nelec, Npbc, Nlm]

Definition at line 101 of file SoaSphericalTensor.h.

102  {
103  const size_t nElec = xyz.size(0);
104  const size_t Npbc = xyz.size(1); // number of PBC images
105  assert(xyz.size(2) == 3);
106 
107  assert(Ylm.size(0) == nElec);
108  assert(Ylm.size(1) == Npbc);
109  const size_t Nlm = Ylm.size(2);
110 
111  size_t nR = nElec * Npbc; // total number of positions to evaluate
112 
113  auto* xyz_ptr = xyz.data();
114  auto* Ylm_ptr = Ylm.data();
115  auto* factorLM__ptr = factorLM_.data();
116  auto* factorL__ptr = factorL_.data();
117  auto* norm_factor__ptr = norm_factor_.data();
118 
119  PRAGMA_OFFLOAD("omp target teams distribute parallel for \
120  map(to:factorLM__ptr[:Nlm], factorL__ptr[:Lmax+1], norm_factor__ptr[:Nlm]) \
121  map(to: xyz_ptr[:3*nR], Ylm_ptr[:Nlm*nR])")
122  for (uint32_t ir = 0; ir < nR; ir++)
123  {
124  evaluate_bare(xyz_ptr[0 + 3 * ir], xyz_ptr[1 + 3 * ir], xyz_ptr[2 + 3 * ir], Ylm_ptr + (ir * Nlm), Lmax,
125  factorL__ptr, factorLM__ptr);
126  for (int i = 0; i < Nlm; i++)
127  Ylm_ptr[ir * Nlm + i] *= norm_factor__ptr[i];
128  }
129  }
OffloadVector & norm_factor_
norm_factor reference
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
OffloadVector & factorL_
factorL reference
static void evaluate_bare(T x, T y, T z, T *Ylm, int lmax, const T *factorL, const T *factorLM)
compute Ylm for single position
for(int i=0;i< size_test;++i) CHECK(Approx(gauss_random_vals[offset_for_rs+i])
int Lmax
maximum angular momentum for the center
OffloadVector & factorLM_
factorLM reference

◆ batched_evaluateVGL()

void batched_evaluateVGL ( const OffloadArray3D xyz,
OffloadArray4D Ylm_vgl 
) const
inline

evaluate VGL for multiple electrons and multiple pbc images

when offload is enabled, xyz is assumed to be up to date on the device before entering the function Ylm_vgl will be up to date on the device (but not host) when this function exits

Parameters
[in]xyzelectron positions [Nelec, Npbc, 3(x,y,z)]
[out]Ylm_vglSpherical tensor elements [5(v, gx, gy, gz, lapl), Nelec, Npbc, Nlm]

Definition at line 140 of file SoaSphericalTensor.h.

141  {
142  const size_t nElec = xyz.size(0);
143  const size_t Npbc = xyz.size(1); // number of PBC images
144  assert(xyz.size(2) == 3);
145 
146  assert(Ylm_vgl.size(0) == 5);
147  assert(Ylm_vgl.size(1) == nElec);
148  assert(Ylm_vgl.size(2) == Npbc);
149  const size_t Nlm = Ylm_vgl.size(3);
150  assert(norm_factor_.size() == Nlm);
151 
152  const size_t nR = nElec * Npbc; // total number of positions to evaluate
153  const size_t offset = Nlm * nR; // stride for v/gx/gy/gz/l
154 
155  auto* xyz_ptr = xyz.data();
156  auto* Ylm_vgl_ptr = Ylm_vgl.data();
157  auto* factorLM__ptr = factorLM_.data();
158  auto* factorL__ptr = factorL_.data();
159  auto* factor2L__ptr = factor2L_.data();
160  auto* norm_factor__ptr = norm_factor_.data();
161 
162  PRAGMA_OFFLOAD("omp target teams distribute parallel for \
163  map(to:factorLM__ptr[:Nlm], factorL__ptr[:Lmax+1], norm_factor__ptr[:Nlm], factor2L__ptr[:Lmax+1]) \
164  map(to: xyz_ptr[:nR*3], Ylm_vgl_ptr[:5*nR*Nlm])")
165  for (uint32_t ir = 0; ir < nR; ir++)
166  evaluateVGL_impl(xyz_ptr[0 + 3 * ir], xyz_ptr[1 + 3 * ir], xyz_ptr[2 + 3 * ir], Ylm_vgl_ptr + (ir * Nlm), Lmax,
167  factorL__ptr, factorLM__ptr, factor2L__ptr, norm_factor__ptr, offset);
168  }
OffloadVector & norm_factor_
norm_factor reference
OffloadVector & factorL_
factorL reference
for(int i=0;i< size_test;++i) CHECK(Approx(gauss_random_vals[offset_for_rs+i])
size_type size() const
return the current size
Definition: OhmmsVector.h:162
int Lmax
maximum angular momentum for the center
static void evaluateVGL_impl(const T x, const T y, const T z, T *restrict Ylm_vgl, int lmax, const T *factorL, const T *factorLM, const T *factor2L, const T *normfactor, size_t offset)
compute Ylm_vgl for single position
OffloadVector & factor2L_
factor2L reference
OffloadVector & factorLM_
factorLM reference

◆ evaluate_bare()

void evaluate_bare ( x,
y,
z,
T *  Ylm,
int  lmax,
const T *  factorL,
const T *  factorLM 
)
inlinestatic

compute Ylm for single position

Definition at line 288 of file SoaSphericalTensor.h.

Referenced by SoaSphericalTensor< ST >::batched_evaluateV(), and SoaSphericalTensor< ST >::evaluateV().

295 {
296  constexpr T czero(0);
297  constexpr T cone(1);
298  const T pi = 4.0 * std::atan(1.0);
299  const T omega = 1.0 / std::sqrt(4.0 * pi);
300  constexpr T eps2 = std::numeric_limits<T>::epsilon() * std::numeric_limits<T>::epsilon();
301 
302  /* Calculate r, cos(theta), sin(theta), cos(phi), sin(phi) from input
303  coordinates. Check here the coordinate singularity at cos(theta) = +-1.
304  This also takes care of r=0 case. */
305  T cphi, sphi, ctheta;
306  T r2xy = x * x + y * y;
307  T r = std::sqrt(r2xy + z * z);
308  if (r2xy < eps2)
309  {
310  cphi = czero;
311  sphi = cone;
312  ctheta = (z < czero) ? -cone : cone;
313  }
314  else
315  {
316  ctheta = z / r;
317  //protect ctheta, when ctheta is slightly >1 or <-1
318  if (ctheta > cone)
319  ctheta = cone;
320  if (ctheta < -cone)
321  ctheta = -cone;
322  T rxyi = cone / std::sqrt(r2xy);
323  cphi = x * rxyi;
324  sphi = y * rxyi;
325  }
326  T stheta = std::sqrt(cone - ctheta * ctheta);
327  /* Now to calculate the associated legendre functions P_lm from the
328  recursion relation from l=0 to Lmax. Conventions of J.D. Jackson,
329  Classical Electrodynamics are used. */
330  Ylm[0] = cone;
331  // calculate P_ll and P_l,l-1
332  T fac = cone;
333  int j = -1;
334  for (int l = 1; l <= lmax; l++)
335  {
336  j += 2;
337  fac *= -j * stheta;
338  int ll = index(l, l);
339  int l1 = index(l, l - 1);
340  int l2 = index(l - 1, l - 1);
341  Ylm[ll] = fac;
342  Ylm[l1] = j * ctheta * Ylm[l2];
343  }
344  // Use recurence to get other plm's //
345  for (int m = 0; m < lmax - 1; m++)
346  {
347  int j = 2 * m + 1;
348  for (int l = m + 2; l <= lmax; l++)
349  {
350  j += 2;
351  int lm = index(l, m);
352  int l1 = index(l - 1, m);
353  int l2 = index(l - 2, m);
354  Ylm[lm] = (ctheta * j * Ylm[l1] - (l + m - 1) * Ylm[l2]) / (l - m);
355  }
356  }
357  // Now to calculate r^l Y_lm. //
358  T sphim, cphim, temp;
359  Ylm[0] = omega; //1.0/sqrt(pi4);
360  T rpow = 1.0;
361  for (int l = 1; l <= lmax; l++)
362  {
363  rpow *= r;
364  //fac = rpow*sqrt(static_cast<T>(2*l+1))*omega;//rpow*sqrt((2*l+1)/pi4);
365  //factorL[l] = sqrt(2*l+1)/sqrt(4*pi)
366  fac = rpow * factorL[l];
367  int l0 = index(l, 0);
368  Ylm[l0] *= fac;
369  cphim = cone;
370  sphim = czero;
371  for (int m = 1; m <= l; m++)
372  {
373  temp = cphim * cphi - sphim * sphi;
374  sphim = sphim * cphi + cphim * sphi;
375  cphim = temp;
376  int lm = index(l, m);
377  fac *= factorLM[lm];
378  temp = fac * Ylm[lm];
379  Ylm[lm] = temp * cphim;
380  lm = index(l, -m);
381  Ylm[lm] = temp * sphim;
382  }
383  }
384  //for (int i=0; i<Ylm.size(); i++)
385  // Ylm[i]*= norm_factor_[i];
386 }
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
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
const double pi
Definition: Standard.h:56
constexpr std::complex< float > cone
Definition: BLAS.hpp:50
MakeReturn< UnaryNode< FnArcTan, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t atan(const Vector< T1, C1 > &l)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
static int index(int l, int m)
returns the index/locator for ( ) combo,

◆ evaluateV() [1/2]

void evaluateV ( x,
y,
z,
T *  Ylm 
) const
inline

compute Ylm

Definition at line 88 of file SoaSphericalTensor.h.

Referenced by AtomicOrbitals< ST >::evaluate_v(), and AtomicOrbitals< ST >::evaluateValues().

89  {
90  evaluate_bare(x, y, z, Ylm, Lmax, factorL_.data(), factorLM_.data());
91  for (int i = 0, nl = cYlm.size(); i < nl; i++)
92  Ylm[i] *= norm_factor_[i];
93  }
OffloadVector & norm_factor_
norm_factor reference
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
OffloadVector & factorL_
factorL reference
VectorSoaContainer< T, 5 > cYlm
composite
static void evaluate_bare(T x, T y, T z, T *Ylm, int lmax, const T *factorL, const T *factorLM)
compute Ylm for single position
int Lmax
maximum angular momentum for the center
size_type size() const
return the physical size
OffloadVector & factorLM_
factorLM reference

◆ evaluateV() [2/2]

void evaluateV ( x,
y,
z 
)
inline

compute Ylm

Definition at line 171 of file SoaSphericalTensor.h.

172  {
173  T* restrict Ylm = cYlm.data(0);
174  evaluate_bare(x, y, z, Ylm, Lmax, factorL_.data(), factorLM_.data());
175  for (int i = 0, nl = cYlm.size(); i < nl; i++)
176  Ylm[i] *= norm_factor_[i];
177  }
OffloadVector & norm_factor_
norm_factor reference
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
OffloadVector & factorL_
factorL reference
VectorSoaContainer< T, 5 > cYlm
composite
static void evaluate_bare(T x, T y, T z, T *Ylm, int lmax, const T *factorL, const T *factorLM)
compute Ylm for single position
int Lmax
maximum angular momentum for the center
size_type size() const
return the physical size
OffloadVector & factorLM_
factorLM reference

◆ evaluateVGH()

void evaluateVGH ( x,
y,
z 
)
inline

makes a table of $ r^l S_l^m $ and their gradients up to Lmax.

Definition at line 510 of file SoaSphericalTensor.h.

511 {
512  throw std::runtime_error("SoaSphericalTensor<T>::evaluateVGH(x,y,z): Not implemented\n");
513 }

◆ evaluateVGHGH()

void evaluateVGHGH ( x,
y,
z 
)
inline

makes a table of $ r^l S_l^m $ and their gradients up to Lmax.

Definition at line 516 of file SoaSphericalTensor.h.

517 {
518  throw std::runtime_error("SoaSphericalTensor<T>::evaluateVGHGH(x,y,z): Not implemented\n");
519 }

◆ evaluateVGL()

void evaluateVGL ( x,
y,
z 
)
inline

makes a table of $ r^l S_l^m $ and their gradients up to Lmax.

Definition at line 503 of file SoaSphericalTensor.h.

Referenced by AtomicOrbitals< ST >::evaluate_vgl().

504 {
506  cYlm.capacity());
507 }
OffloadVector & norm_factor_
norm_factor reference
size_type capacity() const
return the physical size
OffloadVector & factorL_
factorL reference
VectorSoaContainer< T, 5 > cYlm
composite
int Lmax
maximum angular momentum for the center
static void evaluateVGL_impl(const T x, const T y, const T z, T *restrict Ylm_vgl, int lmax, const T *factorL, const T *factorLM, const T *factor2L, const T *normfactor, size_t offset)
compute Ylm_vgl for single position
OffloadVector & factor2L_
factor2L reference
OffloadVector & factorLM_
factorLM reference

◆ evaluateVGL_impl()

void evaluateVGL_impl ( const T  x,
const T  y,
const T  z,
T *restrict  Ylm_vgl,
int  lmax,
const T *  factorL,
const T *  factorLM,
const T *  factor2L,
const T *  normfactor,
size_t  offset 
)
inlinestatic

compute Ylm_vgl for single position

Definition at line 392 of file SoaSphericalTensor.h.

Referenced by SoaSphericalTensor< ST >::batched_evaluateVGL().

402 {
403  T* restrict Ylm = Ylm_vgl;
404  // T* restrict Ylm = cYlm.data(0);
405  evaluate_bare(x, y, z, Ylm, lmax, factorL, factorLM);
406  const size_t Nlm = (lmax + 1) * (lmax + 1);
407 
408  constexpr T czero(0);
409  constexpr T ahalf(0.5);
410  T* restrict gYlmX = Ylm_vgl + offset * 1;
411  T* restrict gYlmY = Ylm_vgl + offset * 2;
412  T* restrict gYlmZ = Ylm_vgl + offset * 3;
413  T* restrict lYlm = Ylm_vgl + offset * 4; // just need to set to zero
414 
415  gYlmX[0] = czero;
416  gYlmY[0] = czero;
417  gYlmZ[0] = czero;
418  lYlm[0] = czero;
419 
420  // Calculating Gradient now//
421  for (int l = 1; l <= lmax; l++)
422  {
423  //T fac = ((T) (2*l+1))/(2*l-1);
424  T fac = factor2L[l];
425  for (int m = -l; m <= l; m++)
426  {
427  int lm = index(l - 1, 0);
428  T gx, gy, gz, dpr, dpi, dmr, dmi;
429  const int ma = std::abs(m);
430  const T cp = std::sqrt(fac * (l - ma - 1) * (l - ma));
431  const T cm = std::sqrt(fac * (l + ma - 1) * (l + ma));
432  const T c0 = std::sqrt(fac * (l - ma) * (l + ma));
433  gz = (l > ma) ? c0 * Ylm[lm + m] : czero;
434  if (l > ma + 1)
435  {
436  dpr = cp * Ylm[lm + ma + 1];
437  dpi = cp * Ylm[lm - ma - 1];
438  }
439  else
440  {
441  dpr = czero;
442  dpi = czero;
443  }
444  if (l > 1)
445  {
446  switch (ma)
447  {
448  case 0:
449  dmr = -cm * Ylm[lm + 1];
450  dmi = cm * Ylm[lm - 1];
451  break;
452  case 1:
453  dmr = cm * Ylm[lm];
454  dmi = czero;
455  break;
456  default:
457  dmr = cm * Ylm[lm + ma - 1];
458  dmi = cm * Ylm[lm - ma + 1];
459  }
460  }
461  else
462  {
463  dmr = cm * Ylm[lm];
464  dmi = czero;
465  //dmr = (l==1) ? cm*Ylm[lm]:0.0;
466  //dmi = 0.0;
467  }
468  if (m < 0)
469  {
470  gx = ahalf * (dpi - dmi);
471  gy = -ahalf * (dpr + dmr);
472  }
473  else
474  {
475  gx = ahalf * (dpr - dmr);
476  gy = ahalf * (dpi + dmi);
477  }
478  lm = index(l, m);
479  if (ma)
480  {
481  gYlmX[lm] = normfactor[lm] * gx;
482  gYlmY[lm] = normfactor[lm] * gy;
483  gYlmZ[lm] = normfactor[lm] * gz;
484  }
485  else
486  {
487  gYlmX[lm] = gx;
488  gYlmY[lm] = gy;
489  gYlmZ[lm] = gz;
490  }
491  }
492  }
493  for (int i = 0; i < Nlm; i++)
494  {
495  Ylm[i] *= normfactor[i];
496  lYlm[i] = 0;
497  }
498  //for (int i=0; i<Ylm.size(); i++) gradYlm[i]*= norm_factor_[i];
499 }
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
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
constexpr std::complex< float > czero
Definition: BLAS.hpp:51
static void evaluate_bare(T x, T y, T z, T *Ylm, int lmax, const T *factorL, const T *factorLM)
compute Ylm for single position
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
static int index(int l, int m)
returns the index/locator for ( ) combo,

◆ index()

static int index ( int  l,
int  m 
)
inlinestatic

returns the index/locator for ( $l,m$) combo, $ l(l+1)+m $

Definition at line 189 of file SoaSphericalTensor.h.

189 { return (l * (l + 1)) + m; }

◆ lmax()

int lmax ( ) const
inline

Definition at line 199 of file SoaSphericalTensor.h.

199 { return Lmax; }
int Lmax
maximum angular momentum for the center

◆ operator[]()

const T* operator[] ( size_t  component) const
inline

return the starting address of the component

component=0(V), 1(dx), 2(dy), 3(dz), 4(Lap)

Definition at line 195 of file SoaSphericalTensor.h.

195 { return cYlm.data(component); }
VectorSoaContainer< T, 5 > cYlm
composite

◆ size()

size_t size ( void  ) const
inline

Definition at line 197 of file SoaSphericalTensor.h.

197 { return cYlm.size(); }
VectorSoaContainer< T, 5 > cYlm
composite
size_type size() const
return the physical size

Member Data Documentation

◆ cYlm

◆ factor2L_

OffloadVector& factor2L_
private

factor2L reference

Definition at line 64 of file SoaSphericalTensor.h.

Referenced by SoaSphericalTensor< ST >::batched_evaluateVGL().

◆ factor2L_ptr_

const std::shared_ptr<OffloadVector> factor2L_ptr_
private

pre-evaluated factor $(2l+1)/(2l-1)$

Definition at line 56 of file SoaSphericalTensor.h.

◆ factorL_

◆ factorL_ptr_

const std::shared_ptr<OffloadVector> factorL_ptr_
private

pre-evaluated factor $\sqrt{(2l+1)/(4\pi)}$

Definition at line 54 of file SoaSphericalTensor.h.

◆ factorLM_

◆ factorLM_ptr_

const std::shared_ptr<OffloadVector> factorLM_ptr_
private

pre-evaluated factor $1/\sqrt{(l+m)\times(l+1-m)}$

Definition at line 52 of file SoaSphericalTensor.h.

◆ Lmax

◆ norm_factor_

◆ norm_factor_ptr_

const std::shared_ptr<OffloadVector> norm_factor_ptr_
private

Normalization factors.

Definition at line 50 of file SoaSphericalTensor.h.


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