11 std::vector<std::vector<double>>
quad = {{1, 0, 0},
12 {-1, 1.224646853e-16, 0},
13 {0.4472135901, 0.8944271803, 0},
14 {-0.4472135901, 0.7236068249, 0.5257310867},
15 {0.4472135901, 0.2763932049, 0.8506507874},
16 {-0.4472135901, -0.2763932049, 0.8506507874},
17 {0.4472135901, -0.7236068249, 0.5257310867},
18 {-0.4472135901, -0.8944271803, 1.095357398e-16},
19 {0.4472135901, -0.7236068249, -0.5257310867},
20 {-0.4472135901, -0.2763932049, -0.8506507874},
21 {0.4472135901, 0.2763932049, -0.8506507874},
22 {-0.4472135901, 0.7236068249, -0.5257310867}};
23 std::vector<double>
wt = {0.08333333582, 0.08333333582, 0.08333333582, 0.08333333582, 0.08333333582, 0.08333333582,
24 0.08333333582, 0.08333333582, 0.08333333582, 0.08333333582, 0.08333333582, 0.08333333582};
27 double B(
double x,
int k,
int i,
const std::vector<double>& t)
31 return (x >= t[i] && x < t[i + 1]) ? 1.0 : 0.0;
35 c1 = (x - t[i]) / (t[i + k] - t[i]) *
B(x, k - 1, i, t);
36 if (t[i + k + 1] == t[i + 1])
39 c2 = (t[i + k + 1] - x) / (t[i + k + 1] - t[i + 1]) *
B(x, k - 1, i + 1, t);
43 double bspline(
double x,
const std::vector<double>& t,
const std::vector<double>& c,
int k)
45 int n = t.size() - k - 1;
47 assert(
n <= c.size());
49 for (
int i = 0; i <
n; i++)
50 val += c[i] *
B(x, k, i, t);
57 cubicBSpline(
double rcut,
double cusp_val,
const std::vector<double>& coeffs)
59 int numknots = coeffs.size();
61 knots_.resize(numknots + 6);
64 delta_ = rcut / (numknots + 1);
69 for (
int i = 0; i <
knots_.size(); i++)
78 const int ic = ip + 1;
80 std::vector<double> finite_diff_coeffs = {-1. / 60, 3. / 20, -3. / 4, 0, 3. / 4, -3. / 20, 1. / 60};
81 std::vector<double> values(finite_diff_coeffs.size());
83 int offset = (finite_diff_coeffs.size() - 1) / 2;
84 for (
int id = 0;
id < finite_diff_coeffs.size();
id++)
86 double newval = inital_value + (
id - offset) * dp;
93 for (
int id = 0;
id < finite_diff_coeffs.size();
id++)
94 deriv += finite_diff_coeffs[
id] * values[
id] / dp;
117 const double rcut = 10;
118 const double cusp = 2.0;
120 std::vector<double> coeffs = {-0.2032153051, -0.1625595974, -0.143124599, -0.1216434956,
121 -0.09919771951, -0.07111729038, -0.04445345869, -0.02135082917};
126 std::vector<double> refVals = {-0.9304041433, -0.252599792, -0.1637586749, -0.1506226948, -0.1394848415,
127 -0.128023472, -0.1161729491, -0.1036884223, -0.08992443283, -0.07519614609,
128 -0.06054074137, -0.04654631918, -0.03347994129, -0.0211986378, -0.01004416026,
129 -0.002594125744, -0.000166024047};
131 std::vector<double> rvals(refVals.size());
132 for (
int i = 0; i < refVals.size(); i++)
136 for (
int i = 0; i < refVals.size(); i++)
139 std::cout <<
"error: " << rvals[i] <<
" " << refVals[i] <<
" != " << spl.
getVal(rvals[i]) << std::endl;
142 std::cout <<
"1b jastrow w/ cusp correct: " << good << std::endl;
147 const double rcut = 10;
148 const double cusp = -0.5;
150 std::vector<double> coeffs = {0.02904699284, -0.1004179, -0.1752703883, -0.2232576505, -0.2728029201,
151 -0.3253286875, -0.3624525145, -0.3958223107, -0.4268582166, -0.4394531176};
156 std::vector<double> refVals = {0.1374071801, -0.04952403966, -0.121361995, -0.1695590431, -0.2058414025,
157 -0.2382237097, -0.2712606182, -0.3047843679, -0.3347515004, -0.3597048574,
158 -0.3823503292, -0.4036800017, -0.4219818468, -0.4192355508, -0.3019238309,
159 -0.09726352421, -0.006239062395};
162 double r = 0.6935647049;
163 double val = spl.
getVal(r);
164 std::cout << r <<
" " << val << std::endl;
165 std::vector<double> rvals(refVals.size());
166 for (
int i = 0; i < refVals.size(); i++)
170 for (
int i = 0; i < refVals.size(); i++)
173 std::cout <<
"error: " << rvals[i] <<
" " << refVals[i] <<
" != " << spl.
getVal(rvals[i]) << std::endl;
176 std::cout <<
"2b jastrow correct: " << good << std::endl;
180 std::complex<double>
I = std::complex<double>(0, 1);
182 std::complex<double>
Ylm(
int l,
int m,
const std::vector<double>& sph)
189 return std::complex<double>(0.5 *
std::sqrt(1. /
PI), 0.0);
276 std::vector<double>
cart2sph(
const std::vector<double>& cart)
279 std::vector<double> sph(3);
280 sph[0] =
std::sqrt(cart[0] * cart[0] + cart[1] * cart[1] + cart[2] * cart[2]);
286 std::vector<double>
sph2cart(
const std::vector<double>& sph)
289 std::vector<double> cart(3);
292 cart[2] = sph[0] *
std::cos(sph[1]);
301 std::complex<double>
orbu(
const std::vector<double>& sph)
303 std::vector<double> cart =
sph2cart(sph);
304 return std::exp(
I * (cart[0] + cart[1] + cart[2]));
306 std::complex<double>
orbd(
const std::vector<double>& sph)
308 std::vector<double> cart =
sph2cart(sph);
309 return std::exp(2. *
I * (cart[0] + cart[1] + cart[2]));
313 std::complex<double>
spinor0(
const std::vector<double>& sph,
double s)
317 std::complex<double>
spinor1(
const std::vector<double>& sph,
double s)
328 return std::complex<double>(
std::cos(s1 + s2), 0.0);
331 return std::complex<double>(
std::sin(s1 + s2), 0.0);
334 return std::complex<double>(0.0,
std::sin(s1 - s2));
347 double pref1, pref2, val;
351 pref1 =
std::sqrt(l * (l + 1) - m2 * (m2 + 1));
352 pref2 =
std::sqrt(l * (l + 1) - m2 * (m2 - 1));
354 return std::complex<double>(val, 0.0);
357 pref1 =
std::sqrt(l * (l + 1) - m2 * (m2 - 1));
358 pref2 =
std::sqrt(l * (l + 1) - m2 * (m2 + 1));
360 return std::complex<double>(0.0, val);
373 double Wso(
int l,
double r) {
return exp(-l * r * r); }
375 std::complex<double>
TWF(std::vector<std::vector<double>>& positions,
376 std::vector<double>& spins,
379 std::vector<double> cart0 =
sph2cart(positions[0]);
380 std::vector<double> cart1 =
sph2cart(positions[1]);
381 double dx = (cart1[0] - cart0[0]);
382 double dy = (cart1[1] - cart0[1]);
383 double dz = (cart1[2] - cart0[2]);
384 double r12 =
std::sqrt(dx * dx + dy * dy + dz * dz);
385 std::complex<double>
det =
spinor0(positions[0], spins[0]) *
spinor1(positions[1], spins[1]) -
386 spinor1(positions[0], spins[0]) *
spinor0(positions[1], spins[1]);
391 std::vector<std::vector<double>>& positions,
392 std::vector<double>& spins,
395 std::vector<double> cart0 =
sph2cart(positions[0]);
396 std::vector<double> cart1 =
sph2cart(positions[1]);
397 double dx = (cart1[0] - cart0[0]);
398 double dy = (cart1[1] - cart0[1]);
399 double dz = (cart1[2] - cart0[2]);
400 double r12 =
std::sqrt(dx * dx + dy * dy + dz * dz);
407 std::vector<std::vector<double>>& positions,
408 std::vector<double>& spins,
411 std::complex<double> angint(0.0, 0.0);
412 for (
int i = 0; i <
quad.size(); i++)
415 sph2[0] *= positions[iel][0];
417 std::vector<std::vector<double>> newpositions = positions;
418 std::vector<double> newspins = spins;
419 newpositions[iel] = sph2;
422 std::complex<double> integrand(0.0, 0.0);
423 for (
int l = 1; l <= 3; l++)
425 std::complex<double> msum(0.0, 0.0);
426 for (
int m1 = -l; m1 <= l; m1++)
428 for (
int m2 = -l; m2 <= l; m2++)
430 std::complex<double> ldots(0.0, 0.0);
431 for (
int d = 0; d < 3; d++)
433 msum +=
Ylm(l, m1, positions[iel]) *
std::conj(
Ylm(l, m2, newpositions[iel])) * ldots;
436 integrand +=
Wso(l, positions[iel][0]) * msum;
439 std::complex<double> num =
TWF(newpositions, newspins, J2);
440 std::complex<double> denom =
TWF(positions, spins, J2);
441 integrand *= num / denom;
442 angint += integrand *
wt[i] * 4.0 *
PI;
449 std::vector<std::vector<double>>& positions,
450 std::vector<double>& spins,
453 std::complex<double> sint(0.0, 0.0);
455 double smax = 2 *
PI;
456 double h = (smax - smin) / npts;
457 for (
int k = 1; k <= npts - 1; k += 2)
459 double s2 = smin + k * h;
460 std::complex<double> angint =
calcAngInt(iel, s2, positions, spins, J2);
461 sint += 4 * h / 3. * angint;
463 for (
int k = 2; k <= npts - 2; k += 2)
465 double s2 = smin + k * h;
466 std::complex<double> angint =
calcAngInt(iel, s2, positions, spins, J2);
467 sint += 2 * h / 3. * angint;
469 sint += h / 3. *
calcAngInt(iel, smin, positions, spins, J2);
470 sint += h / 3. *
calcAngInt(iel, smax, positions, spins, J2);
479 std::vector<double> pos_e1 = {0.138, -0.24, 0.216};
480 std::vector<double> pos_e2 = {-0.216, 0.24, -0.138};
481 std::vector<std::vector<double>> positions = {
cart2sph(pos_e1),
cart2sph(pos_e2)};
482 double spin_e1 = 0.2;
483 double spin_e2 = 0.51;
484 std::vector<double> spins = {spin_e1, spin_e2};
488 std::vector<double> coeffs = {0.02904699284, -0.1004179, -0.1752703883, -0.2232576505, -0.2728029201};
491 std::complex<double> val;
492 for (
int iel = 0; iel < 2; iel++)
493 val +=
calcVal(npts, iel, positions, spins, J2);
494 std::cout << npts <<
" " << std::setprecision(10) <<
std::real(val) <<
" " <<
std::imag(val) << std::endl;
501 std::vector<double> pos_e1 = {0.138, -0.24, 0.216};
502 std::vector<double> pos_e2 = {-0.216, 0.24, -0.138};
503 std::vector<std::vector<double>> positions = {
cart2sph(pos_e1),
cart2sph(pos_e2)};
504 double spin_e1 = 0.2;
505 double spin_e2 = 0.51;
506 std::vector<double> spins = {spin_e1, spin_e2};
510 std::vector<double> coeffs = {0.02904699284, -0.1004179, -0.1752703883, -0.2232576505, -0.2728029201};
516 std::vector<double> dhpsioverpsi = {-3.807451601, 0.1047251267, 3.702726474, 0, 0};
518 std::complex<double> soecp_value;
520 for (
int iel = 0; iel < 2; iel++)
523 std::vector<std::vector<std::vector<double>>> positions_vp;
524 std::vector<std::vector<double>> spins_vp;
525 std::vector<double> spin_quad_wts;
527 auto add_quad_points = [&](
const double spinval,
const double spin_wt) {
528 for (
int i = 0; i <
quad.size(); i++)
531 sph2[0] *= positions[iel][0];
532 positions_vp.push_back(positions);
533 spins_vp.push_back(spins);
534 positions_vp.back()[iel] = sph2;
535 spins_vp.back()[iel] = spinval;
536 double spin_norm = 1.0 / (2.0 *
PI);
537 double spatial_norm = 4.0 *
PI;
538 double norm = spin_norm * spatial_norm;
539 spin_quad_wts.push_back(spin_wt *
wt[i] *
norm);
543 double smax = 2 *
PI;
544 double h = (smax - smin) / npts;
545 for (
int k = 1; k <= npts - 1; k += 2)
547 double newspin = smin + k * h;
548 double spinwt = 4. * h / 3.;
549 add_quad_points(newspin, spinwt);
551 for (
int k = 2; k <= npts - 2; k += 2)
553 double newspin = smin + k * h;
554 double spinwt = 2. * h / 3.;
555 add_quad_points(newspin, spinwt);
557 add_quad_points(smin, h / 3.);
558 add_quad_points(smax, h / 3.);
559 assert(positions_vp.size() == spins_vp.size());
560 assert(spins_vp.size() == spin_quad_wts.size());
561 assert(spin_quad_wts.size() == (npts + 1) *
quad.size());
563 std::vector<std::complex<double>> dlogpsi(coeffs.size());
564 for (
int ip = 0; ip < dlogpsi.size(); ip++)
565 dlogpsi[ip] =
dratioTWF(ip, positions, spins, spl);
568 std::cout <<
"std::vector<RealType> dlogpsi_refs = { ";
569 for (
int ip = 0; ip < dlogpsi.size(); ip++)
572 (ip != dlogpsi.size() - 1) ? std::cout << std::setprecision(10) <<
real <<
", " 573 : std::cout << std::setprecision(10) <<
real <<
"};" << std::endl;
577 std::vector<std::vector<std::complex<double>>> dratio;
578 for (
int iq = 0; iq < spin_quad_wts.size(); iq++)
580 std::vector<std::complex<double>> dratio_row(coeffs.size());
581 for (
int ip = 0; ip < dratio_row.size(); ip++)
582 dratio_row[ip] =
dratioTWF(ip, positions_vp[iq], spins_vp[iq], spl) - dlogpsi[ip];
583 dratio.push_back(dratio_row);
587 auto SOECP_spin_quad = [&](std::vector<std::vector<double>>& newpos, std::vector<std::vector<double>>& oldpos,
588 std::vector<double>& newspin, std::vector<double>& oldspin,
const cubicBSpline& J2) {
589 std::complex<double> integrand;
590 for (
int l = 1; l <= 3; l++)
592 std::complex<double> msum;
593 for (
int m1 = -l; m1 <= l; m1++)
595 for (
int m2 = -l; m2 <= l; m2++)
597 std::complex<double> ldots;
598 for (
int id = 0;
id < 3;
id++)
600 msum +=
Ylm(l, m1, oldpos[iel]) *
std::conj(
Ylm(l, m2, newpos[iel])) * ldots;
603 integrand +=
Wso(l, oldpos[iel][0]) * msum;
605 std::complex<double> psinew =
TWF(newpos, newspin, J2);
606 std::complex<double> psiold =
TWF(oldpos, oldspin, J2);
607 integrand *= psinew / psiold;
611 std::vector<std::complex<double>> wvec(spin_quad_wts.size());
612 for (
int iq = 0; iq < spin_quad_wts.size(); iq++)
614 wvec[iq] = spin_quad_wts[iq] * SOECP_spin_quad(positions_vp[iq], positions, spins_vp[iq], spins, spl);
615 soecp_value += wvec[iq];
619 for (
int ip = 0; ip < dhpsioverpsi.size(); ip++)
621 std::complex<double> sum;
622 for (
int iq = 0; iq < wvec.size(); iq++)
623 sum += wvec[iq] * dratio[iq][ip];
627 std::cout << std::setprecision(10) <<
"SOECP Value: " << soecp_value << std::endl;
628 std::cout <<
"std::vector<RealType> dhpsioverpsi_refs = { ";
629 for (
int ip = 0; ip < dhpsioverpsi.size(); ip++)
630 (ip != dhpsioverpsi.size() - 1) ? std::cout << std::setprecision(10) << dhpsioverpsi[ip] <<
", " 631 : std::cout << std::setprecision(10) << dhpsioverpsi[ip] <<
"};" << std::endl;
double bspline(double x, const std::vector< double > &t, const std::vector< double > &c, int k)
std::complex< double > spinor0(const std::vector< double > &sph, double s)
std::complex< double > dratioTWF(const int ip, std::vector< std::vector< double >> &positions, std::vector< double > &spins, cubicBSpline &J2)
std::vector< double > knots_
Tensor< T, D >::Type_t det(const Tensor< T, D > &a)
std::complex< double > calcVal(int npts, int iel, std::vector< std::vector< double >> &positions, std::vector< double > &spins, const cubicBSpline &J2)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
MakeReturn< UnaryNode< FnSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sin(const Vector< T1, C1 > &l)
std::complex< double > orbd(const std::vector< double > &sph)
std::complex< double > orbu(const std::vector< double > &sph)
int kroneckerDelta(int x, int y)
void setCoeff(int i, double newcoeff)
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
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)
float imag(const float &c)
imaginary part of a scalar. Cannot be replaced by std::imag due to AFQMC specific needs...
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
double parmDeriv(const int ip, double x)
double norm(const zVec &c)
MakeReturn< UnaryNode< FnArcCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t acos(const Vector< T1, C1 > &l)
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)
std::vector< double > coeffs_
MakeReturn< UnaryNode< FnArcTan, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t atan(const Vector< T1, C1 > &l)
std::vector< double > cart2sph(const std::vector< double > &cart)
std::complex< double > spinor1(const std::vector< double > &sph, double s)
void evaluateValueAndDerivative()
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
std::vector< std::vector< double > > quad
std::complex< double > Ylm(int l, int m, const std::vector< double > &sph)
std::vector< double > sph2cart(const std::vector< double > &sph)
float conj(const float &c)
Workaround to allow conj on scalar to return real instead of complex.
cubicBSpline(double rcut, double cusp_val, const std::vector< double > &coeffs)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
double getVal(double x) const
std::complex< double > calcAngInt(int iel, double s2, std::vector< std::vector< double >> &positions, std::vector< double > &spins, const cubicBSpline &J2)
std::complex< double > sMatrixElement(double s1, double s2, int d)
std::complex< double > TWF(std::vector< std::vector< double >> &positions, std::vector< double > &spins, const cubicBSpline &J2)
double B(double x, int k, int i, const std::vector< double > &t)
std::complex< double > chiu(double s)
double Wso(int l, double r)
std::complex< double > chid(double s)
std::complex< double > lMatrixElement(int l, int m1, int m2, int d)
double getCoeff(int i) const