Skip to content

Commit eb1203e

Browse files
authored
Merge pull request #5380 from rcclay/j3_ion_deriv
Replace J3 Finite Difference Ion Derivatives with Analytic
2 parents 4cb4d78 + 42e2c3b commit eb1203e

File tree

3 files changed

+351
-85
lines changed

3 files changed

+351
-85
lines changed

src/QMCWaveFunctions/Jastrow/JeeIOrbitalSoA.h

+140-84
Original file line numberDiff line numberDiff line change
@@ -1121,45 +1121,50 @@ class JeeIOrbitalSoA : public WaveFunctionComponent
11211121

11221122
inline GradType evalGradSource(ParticleSet& P, ParticleSet& source, int isrc) override
11231123
{
1124-
ParticleSet::ParticleGradient tempG;
1125-
ParticleSet::ParticleLaplacian tempL;
1126-
tempG.resize(P.getTotalNum());
1127-
tempL.resize(P.getTotalNum());
1128-
QTFull::RealType delta = 0.00001;
1129-
QTFull::RealType c1 = 1.0 / delta / 2.0;
1130-
QTFull::RealType c2 = 1.0 / delta / delta;
1131-
1132-
GradType g_return(0.0);
1133-
// GRAD TEST COMPUTATION
1134-
PosType rI = source.R[isrc];
1135-
for (int iondim = 0; iondim < 3; iondim++)
1136-
{
1137-
source.R[isrc][iondim] = rI[iondim] + delta;
1138-
source.update();
1139-
P.update();
1140-
1141-
LogValue log_p = evaluateLog(P, tempG, tempL);
1124+
constexpr valT czero(0);
1125+
constexpr valT cone(1);
1126+
constexpr valT cminus(-1);
1127+
constexpr valT ctwo(2);
1128+
constexpr valT lapfac = OHMMS_DIM - cone;
11421129

1143-
source.R[isrc][iondim] = rI[iondim] - delta;
1144-
source.update();
1145-
P.update();
1146-
LogValue log_m = evaluateLog(P, tempG, tempL);
1130+
const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
1131+
const auto& ee_dists = ee_table.getDistances();
1132+
const auto& ee_displs = ee_table.getDisplacements();
11471133

1148-
QTFull::RealType log_p_r(0.0), log_m_r(0.0);
1134+
TinyVector<RealType, 3> u3grad;
1135+
Tensor<RealType, 3> u3hess;
1136+
const int iat = isrc;
11491137

1150-
log_p_r = log_p.real();
1151-
log_m_r = log_m.real();
1152-
//symmetric finite difference formula for gradient.
1153-
g_return[iondim] = c1 * (log_p_r - log_m_r);
1138+
posT ion_deriv(0);
1139+
const int ig = Ions.GroupID[iat];
1140+
for (int jg = 0; jg < eGroups; ++jg)
1141+
for (int jind = 0; jind < elecs_inside(jg, iat).size(); jind++)
1142+
{
1143+
const int jel = elecs_inside(jg, iat)[jind];
1144+
const valT r_Ij = elecs_inside_dist(jg, iat)[jind];
1145+
const posT disp_Ij = cminus * elecs_inside_displ(jg, iat)[jind];
1146+
const valT r_Ij_inv = cone / r_Ij;
11541147

1155-
//reset everything to how it was.
1156-
source.R[isrc][iondim] = rI[iondim];
1157-
}
1158-
// this last one makes sure the distance tables and internal neighbourlist correspond to unperturbed source.
1159-
source.update();
1160-
P.update();
1161-
build_compact_list(P);
1162-
return g_return;
1148+
for (int kg = 0; kg < eGroups; ++kg)
1149+
for (int kind = 0; kind < elecs_inside(kg, iat).size(); kind++)
1150+
{
1151+
const FT& feeI(*F(ig, jg, kg));
1152+
const int kel = elecs_inside(kg, iat)[kind];
1153+
if (kel < jel)
1154+
{
1155+
const valT r_Ik = elecs_inside_dist(kg, iat)[kind];
1156+
const posT disp_Ik = cminus * elecs_inside_displ(kg, iat)[kind];
1157+
const valT r_Ik_inv = cone / r_Ik;
1158+
1159+
const valT r_jk = ee_dists[jel][kel];
1160+
const posT disp_jk = ee_displs[jel][kel];
1161+
const valT r_jk_inv = cone / r_jk;
1162+
feeI.evaluate(r_jk, r_Ij, r_Ik, u3grad, u3hess);
1163+
ion_deriv += u3grad[1] * disp_Ij * r_Ij_inv + u3grad[2] * disp_Ik * r_Ik_inv;
1164+
}
1165+
}
1166+
}
1167+
return ion_deriv;;
11631168
}
11641169

11651170
inline GradType evalGradSource(ParticleSet& P,
@@ -1168,55 +1173,106 @@ class JeeIOrbitalSoA : public WaveFunctionComponent
11681173
TinyVector<ParticleSet::ParticleGradient, OHMMS_DIM>& grad_grad,
11691174
TinyVector<ParticleSet::ParticleLaplacian, OHMMS_DIM>& lapl_grad) override
11701175
{
1171-
ParticleSet::ParticleGradient Gp, Gm, dG;
1172-
ParticleSet::ParticleLaplacian Lp, Lm, dL;
1173-
Gp.resize(P.getTotalNum());
1174-
Gm.resize(P.getTotalNum());
1175-
dG.resize(P.getTotalNum());
1176-
Lp.resize(P.getTotalNum());
1177-
Lm.resize(P.getTotalNum());
1178-
dL.resize(P.getTotalNum());
1179-
1180-
QTFull::RealType delta = 0.00001;
1181-
QTFull::RealType c1 = 1.0 / delta / 2.0;
1182-
QTFull::RealType c2 = 1.0 / delta / delta;
1183-
GradType g_return(0.0);
1184-
// GRAD TEST COMPUTATION
1185-
PosType rI = source.R[isrc];
1186-
for (int iondim = 0; iondim < 3; iondim++)
1187-
{
1188-
Lp = 0;
1189-
Gp = 0;
1190-
Lm = 0;
1191-
Gm = 0;
1192-
source.R[isrc][iondim] = rI[iondim] + delta;
1193-
source.update();
1194-
P.update();
1195-
1196-
LogValue log_p = evaluateLog(P, Gp, Lp);
1197-
1198-
source.R[isrc][iondim] = rI[iondim] - delta;
1199-
source.update();
1200-
P.update();
1201-
LogValue log_m = evaluateLog(P, Gm, Lm);
1202-
QTFull::RealType log_p_r(0.0), log_m_r(0.0);
1203-
1204-
log_p_r = log_p.real();
1205-
log_m_r = log_m.real();
1206-
dG = Gp - Gm;
1207-
dL = Lp - Lm;
1208-
//symmetric finite difference formula for gradient.
1209-
g_return[iondim] = c1 * (log_p_r - log_m_r);
1210-
grad_grad[iondim] += c1 * dG;
1211-
lapl_grad[iondim] += c1 * dL;
1212-
//reset everything to how it was.
1213-
source.R[isrc][iondim] = rI[iondim];
1214-
}
1215-
// this last one makes sure the distance tables and internal neighbourlist correspond to unperturbed source.
1216-
source.update();
1217-
P.update();
1218-
build_compact_list(P);
1219-
return g_return;
1176+
constexpr valT czero(0);
1177+
constexpr valT cone(1);
1178+
constexpr valT cminus(-1);
1179+
constexpr valT ctwo(2);
1180+
constexpr valT lapfac = OHMMS_DIM - cone;
1181+
1182+
const auto& ee_table = P.getDistTableAA(ee_Table_ID_);
1183+
const auto& ee_dists = ee_table.getDistances();
1184+
const auto& ee_displs = ee_table.getDisplacements();
1185+
1186+
ParticleSet::ParticleGradient G;
1187+
ParticleSet::ParticleLaplacian L;
1188+
G.resize(4);
1189+
L.resize(4);
1190+
1191+
TinyVector<RealType, 3> grad;
1192+
Tensor<RealType, 3> hess;
1193+
TinyVector<Tensor<RealType, 3>, 3> d3;
1194+
1195+
TinyVector<RealType, 3> e1(1, 0, 0);
1196+
TinyVector<RealType, 3> e2(0, 1, 0);
1197+
TinyVector<RealType, 3> e3(0, 0, 1);
1198+
1199+
TinyVector<TinyVector<RealType, 3>, 3> identmat(e1, e2, e3);
1200+
1201+
const int iat = isrc;
1202+
1203+
posT ion_deriv(0);
1204+
const int ig = Ions.GroupID[iat];
1205+
for (int jg = 0; jg < eGroups; ++jg)
1206+
for (int jind = 0; jind < elecs_inside(jg, iat).size(); jind++)
1207+
{
1208+
const int jel = elecs_inside(jg, iat)[jind];
1209+
const valT r_Ij = elecs_inside_dist(jg, iat)[jind];
1210+
const posT disp_Ij = cminus * elecs_inside_displ(jg, iat)[jind];
1211+
const valT r_Ij_inv = cone / r_Ij;
1212+
const posT disp_Ij_unit = disp_Ij * r_Ij_inv;
1213+
1214+
for (int kg = 0; kg < eGroups; ++kg)
1215+
for (int kind = 0; kind < elecs_inside(kg, iat).size(); kind++)
1216+
{
1217+
const FT& feeI(*F(ig, jg, kg));
1218+
const int kel = elecs_inside(kg, iat)[kind];
1219+
if (kel < jel)
1220+
{
1221+
const valT r_Ik = elecs_inside_dist(kg, iat)[kind];
1222+
const posT disp_Ik = cminus * elecs_inside_displ(kg, iat)[kind];
1223+
const valT r_Ik_inv = cone / r_Ik;
1224+
const posT disp_Ik_unit = disp_Ik * r_Ik_inv;
1225+
1226+
const valT r_jk = ee_dists[jel][kel];
1227+
const posT disp_jk = ee_displs[jel][kel];
1228+
const valT r_jk_inv = cone / r_jk;
1229+
const posT disp_jk_unit = disp_jk * r_jk_inv;
1230+
1231+
const valT dot_ujk_uIj = dot(disp_jk_unit, disp_Ij_unit);
1232+
const valT dot_ujk_uIk = dot(disp_jk_unit, disp_Ik_unit);
1233+
grad = 0.0;
1234+
hess = 0.0;
1235+
d3 = 0.0;
1236+
feeI.evaluate(r_jk, r_Ij, r_Ik, grad, hess, d3);
1237+
ion_deriv += grad[1] * disp_Ij * r_Ij_inv + grad[2] * disp_Ik * r_Ik_inv;
1238+
1239+
for (int idim = 0; idim < OHMMS_DIM; idim++)
1240+
{
1241+
const posT igrad_r_Ij_unit =
1242+
-(identmat[idim] * r_Ij_inv - disp_Ij * disp_Ij[idim] * r_Ij_inv * r_Ij_inv * r_Ij_inv);
1243+
const posT igrad_r_Ik_unit =
1244+
-(identmat[idim] * r_Ik_inv - disp_Ik * disp_Ik[idim] * r_Ik_inv * r_Ik_inv * r_Ik_inv);
1245+
const posT igrad_g0 = -(hess(0, 1) * disp_Ij_unit[idim] + hess(0, 2) * disp_Ik_unit[idim]);
1246+
const posT igrad_g1 = -(hess(1, 1) * disp_Ij_unit[idim] + hess(1, 2) * disp_Ik_unit[idim]);
1247+
const posT igrad_g2 = -(hess(1, 2) * disp_Ij_unit[idim] + hess(2, 2) * disp_Ik_unit[idim]);
1248+
1249+
const posT igrad_h00 =
1250+
-(d3[0](0, 1) * disp_Ij[idim] * r_Ij_inv + d3[0](0, 2) * disp_Ik[idim] * r_Ik_inv);
1251+
const posT igrad_h11 =
1252+
-(d3[1](1, 1) * disp_Ij[idim] * r_Ij_inv + d3[1](1, 2) * disp_Ik[idim] * r_Ik_inv);
1253+
const posT igrad_h22 =
1254+
-(d3[1](2, 2) * disp_Ij[idim] * r_Ij_inv + d3[2](2, 2) * disp_Ik[idim] * r_Ik_inv);
1255+
const posT igrad_h01 =
1256+
-(d3[0](1, 1) * disp_Ij[idim] * r_Ij_inv + d3[0](1, 2) * disp_Ik[idim] * r_Ik_inv);
1257+
const posT igrad_h02 =
1258+
-(d3[0](1, 2) * disp_Ij[idim] * r_Ij_inv + d3[0](2, 2) * disp_Ik[idim] * r_Ik_inv);
1259+
const posT igrad_dot_ujk_uIj = -(disp_jk_unit[idim] - dot_ujk_uIj * disp_Ij_unit) * r_Ij_inv;
1260+
const posT igrad_dot_ujk_uIk = -(disp_jk_unit[idim] - dot_ujk_uIk * disp_Ik_unit) * r_Ik_inv;
1261+
1262+
grad_grad[idim][jel] -= igrad_g1 * disp_Ij_unit + grad[1] * igrad_r_Ij_unit - igrad_g0 * disp_jk_unit;
1263+
grad_grad[idim][kel] -= igrad_g2 * disp_Ik_unit + grad[2] * igrad_r_Ik_unit + igrad_g0 * disp_jk_unit;
1264+
1265+
lapl_grad[idim][jel] -= igrad_h00[idim] + lapfac * igrad_g0[idim] * r_jk_inv -
1266+
ctwo * (igrad_h01[idim] * dot_ujk_uIj + hess(0, 1) * igrad_dot_ujk_uIj[idim]) + igrad_h11[idim] +
1267+
lapfac * (igrad_g1[idim] * r_Ij_inv - grad[1] * r_Ij_inv * r_Ij_inv * (-disp_Ij_unit[idim]));
1268+
lapl_grad[idim][kel] -= igrad_h00[idim] + lapfac * igrad_g0[idim] * r_jk_inv +
1269+
ctwo * (igrad_h02[idim] * dot_ujk_uIk + hess(0, 2) * igrad_dot_ujk_uIk[idim]) + igrad_h22[idim] +
1270+
lapfac * (igrad_g2[idim] * r_Ik_inv - grad[2] * r_Ik_inv * r_Ik_inv * (-disp_Ik_unit[idim]));
1271+
}
1272+
}
1273+
}
1274+
}
1275+
return ion_deriv;;
12201276
}
12211277
};
12221278

src/QMCWaveFunctions/Jastrow/PolynomialFunctor3D.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ struct PolynomialFunctor3D : public OptimizableFunctorBase
591591
const real_type r_2I,
592592
TinyVector<real_type, 3>& grad,
593593
Tensor<real_type, 3>& hess,
594-
TinyVector<Tensor<real_type, 3>, 3>& d3)
594+
TinyVector<Tensor<real_type, 3>, 3>& d3) const
595595
{
596596
grad = 0.0;
597597
hess = 0.0;

0 commit comments

Comments
 (0)