16 #ifndef QMCPLUSPLUS_EINSPLINEBUILDER_HELPER_H 17 #define QMCPLUSPLUS_EINSPLINEBUILDER_HELPER_H 37 Array<std::complex<T>, 3>& fftbox)
39 fftbox = std::complex<T>();
40 const int upper_bound[3] = {(maxg[0] - 1) / 2, (maxg[1] - 1) / 2, (maxg[2] - 1) / 2};
45 for (
int iG = 0; iG < cG.size(); iG++)
56 fftbox((gvecs[iG][0] + maxg[0]) % maxg[0], (gvecs[iG][1] + maxg[1]) % maxg[1], (gvecs[iG][2] + maxg[2]) % maxg[2]) =
69 template<
typename T,
typename T1,
typename T2>
76 const T two_pi = -2.0 * M_PI;
77 const int nx = in.size(0);
78 const int ny = in.size(1);
79 const int nz = in.size(2);
80 T nx_i = 1.0 /
static_cast<T
>(nx);
81 T ny_i = 1.0 /
static_cast<T
>(ny);
82 T nz_i = 1.0 /
static_cast<T
>(nz);
84 T rNorm = 0.0, iNorm = 0.0, riNorm = 0.0;
85 #pragma omp parallel for reduction(+ : rNorm, iNorm, riNorm) 86 for (
int ix = 0; ix < nx; ix++)
89 std::complex<T>* restrict in_ptr = in.data() + ix * ny * nz;
90 T rux =
static_cast<T
>(ix) * nx_i * twist[0];
91 for (
int iy = 0; iy < ny; iy++)
93 T ruy =
static_cast<T
>(iy) * ny_i * twist[1];
94 for (
int iz = 0; iz < nz; iz++)
96 T ruz =
static_cast<T
>(iz) * nz_i * twist[2];
98 std::complex<T> eikr(c,
s);
100 rNorm += in_ptr->real() * in_ptr->real();
101 iNorm += in_ptr->imag() * in_ptr->imag();
102 riNorm += in_ptr->real() * in_ptr->imag();
108 const T x = (rNorm - iNorm) / riNorm;
109 const T y = 1.0 /
std::sqrt(x * x + 4.0);
114 #pragma omp parallel for 115 for (
int ix = 0; ix < nx; ix++)
117 const std::complex<T>* restrict in_ptr = in.data() + ix * ny * nz;
118 T1* restrict out_ptr = out.
data() + ix * ny * nz;
119 for (
int iy = 0; iy < ny; iy++)
120 for (
int iz = 0; iz < nz; iz++)
122 *out_ptr =
static_cast<T1
>(phase_r * in_ptr->real() - phase_i * in_ptr->imag());
129 template<
typename T,
typename T1,
typename T2>
131 Array<std::complex<T1>, 3>& out,
134 const int nx = in.size(0);
135 const int ny = in.size(1);
136 const int nz = in.size(2);
141 #pragma omp parallel for 142 for (
int ix = 0; ix < nx; ++ix)
144 const std::complex<T>* restrict in_ptr = in.data() + ix * ny * nz;
145 std::complex<T1>* restrict out_ptr = out.data() + ix * ny * nz;
146 for (
int iy = 0; iy < ny; ++iy)
147 for (
int iz = 0; iz < nz; ++iz)
149 *out_ptr = std::complex<T1>(
static_cast<T1
>(phase_r * in_ptr->real() - phase_i * in_ptr->imag()),
150 static_cast<T1>(phase_i * in_ptr->real() + phase_r * in_ptr->imag()));
157 template<
typename T,
typename T1,
typename T2>
165 const int nx = in.size(0);
166 const int ny = in.size(1);
167 const int nz = in.size(2);
171 #pragma omp parallel for 172 for (
size_t ix = 0; ix < nx; ++ix)
173 for (
size_t iy = 0; iy < ny; ++iy)
175 const size_t offset = ix * ny * nz + iy * nz;
176 const std::complex<T>* restrict in_ptr = in.data() + offset;
177 T1* restrict r_ptr = out_r.
data() + offset;
178 T1* restrict i_ptr = out_i.
data() + offset;
179 for (
size_t iz = 0; iz < nz; ++iz)
181 r_ptr[iz] =
static_cast<T1
>(phase_r * in_ptr[iz].real() - phase_i * in_ptr[iz].imag());
182 i_ptr[iz] =
static_cast<T1
>(phase_i * in_ptr[iz].real() + phase_r * in_ptr[iz].imag());
192 template<
typename T,
typename T1>
195 const int nx = in.size(0);
196 const int ny = in.size(1);
197 const int nz = in.size(2);
199 #pragma omp parallel for 200 for (
size_t ix = 0; ix < nx; ++ix)
201 for (
size_t iy = 0; iy < ny; ++iy)
203 const size_t offset = ix * ny * nz + iy * nz;
204 const std::complex<T>* restrict in_ptr = in.data() + offset;
205 T1* restrict r_ptr = out_r.
data() + offset;
206 T1* restrict i_ptr = out_i.
data() + offset;
207 for (
size_t iz = 0; iz < nz; ++iz)
209 r_ptr[iz] =
static_cast<T1
>(in_ptr[iz].real());
210 i_ptr[iz] =
static_cast<T1
>(in_ptr[iz].imag());
223 #pragma omp parallel for reduction(+ : total_norm2) 224 for (
size_t ig = 0; ig < cG.size(); ++ig)
225 total_norm2 += cG[ig].
real() * cG[ig].real() + cG[ig].imag() * cG[ig].imag();
235 template<
typename T,
typename T2>
238 const T two_pi = -2.0 * M_PI;
239 const size_t nx = in.size(0);
240 const size_t ny = in.size(1);
241 const size_t nz = in.size(2);
243 const T nx_i = 1.0 /
static_cast<T
>(nx);
244 const T ny_i = 1.0 /
static_cast<T
>(ny);
245 const T nz_i = 1.0 /
static_cast<T
>(nz);
247 T rNorm = 0.0, iNorm = 0.0, riNorm = 0.0;
248 #pragma omp parallel for reduction(+ : rNorm, iNorm, riNorm) 249 for (
size_t ix = 0; ix < nx; ++ix)
251 for (
size_t iy = 0; iy < ny; ++iy)
253 const T rux =
static_cast<T
>(ix) * nx_i * twist[0];
255 T rsum = 0, isum = 0, risum = 0.0;
256 const T ruy =
static_cast<T
>(iy) * ny_i * twist[1];
257 const std::complex<T>* restrict in_ptr = in.
data() + ix * ny * nz + iy * nz;
258 for (
size_t iz = 0; iz < nz; ++iz)
260 const T ruz =
static_cast<T
>(iz) * nz_i * twist[2];
262 const T re = c * in_ptr[iz].real() -
s * in_ptr[iz].imag();
263 const T im =
s * in_ptr[iz].real() + c * in_ptr[iz].imag();
274 const T x = (rNorm - iNorm) / riNorm;
275 const T y = 1.0 /
std::sqrt(x * x + 4.0);
287 const int nx = e2pi.size(0);
288 const int ny = e2pi.size(1);
289 const int nz = e2pi.size(2);
290 T rNorm = 0.0, iNorm = 0.0;
292 for (
int ix = 0; ix < nx; ix++)
294 T rpart = 0.0, ipart = 0.0;
295 const std::complex<T>* restrict p_ptr = e2pi.data() + ix * ny * nz;
296 std::complex<T>* restrict in_ptr = in.data() + ix * ny * nz;
297 for (
int iyz = 0; iyz < ny * nz; ++iyz)
299 in_ptr[iyz] *= p_ptr[iyz];
300 rpart += in_ptr[iyz].real() * in_ptr[iyz].real();
301 ipart += in_ptr[iyz].imag() * in_ptr[iyz].imag();
313 for (
int ix = 0; ix < nx; ix++)
315 const std::complex<T>* restrict in_ptr = in.data() + ix * ny * nz;
316 T* restrict out_ptr = out.
data() + ix * ny * nz;
317 for (
int iyz = 0; iyz < ny * nz; iyz++)
318 out_ptr[iyz] = phase_r * in_ptr[iyz].
real() - phase_i * in_ptr[iyz].imag();
helper functions for EinsplineSetBuilder
void fix_phase_rotate_c2c(const Array< std::complex< T >, 3 > &in, Array< std::complex< T1 >, 3 > &out, const TinyVector< T2, 3 > &twist)
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
void fix_phase_rotate(const Array< std::complex< T >, 3 > &e2pi, Array< std::complex< T >, 3 > &in, Array< T, 3 > &out)
rotate the state after 3dfft
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)
T compute_norm(const Vector< std::complex< T >> &cG)
Compute the norm of an orbital.
MakeReturn< BinaryNode< FnArcTan2, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t atan2(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
TinyVector< T, 3 > upper_bound(const TinyVector< T, 3 > &a, const TinyVector< T, 3 > &b)
helper function to determine the upper bound of a domain (need to move up)
void fix_phase_rotate_c2r(Array< std::complex< T >, 3 > &in, Array< T1, 3 > &out, const TinyVector< T2, 3 > &twist, T &phase_r, T &phase_i)
rotate the state after 3dfft
void compute_phase(const Array< std::complex< T >, 3 > &in, const TinyVector< T2, 3 > &twist, T &phase_r, T &phase_i)
Compute the phase factor for rotation.
void split_real_components_c2c(const Array< std::complex< T >, 3 > &in, Array< T1, 3 > &out_r, Array< T1, 3 > &out_i)
Split FFTs into real/imaginary components.
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
Declaraton of Vector<T,Alloc> Manage memory through Alloc directly and allow referencing an existing ...
void sincos(T a, T *restrict s, T *restrict c)
sincos function wrapper
A D-dimensional Array class based on PETE.
void unpack4fftw(const Vector< std::complex< T >> &cG, const std::vector< TinyVector< int, 3 >> &gvecs, const TinyVector< int, 3 > &maxg, Array< std::complex< T >, 3 > &fftbox)
unpack packed cG to fftbox