24 #if defined(HAVE_LIBFFTW) 29 #include <string_view> 48 b[j] = static_cast<RealType>(2.0 * M_PI) * ptcl.
getLattice().b(j);
57 PosType G = (double)gint[0] * b[0];
59 G += (
double)gint[j] * b[j];
63 maxIndex[j] = std::max(maxIndex[j],
std::abs(gint[j]));
65 Gints.push_back(gint);
69 for (
int idim = 0; idim <
OHMMS_DIM; idim++)
71 MaxDim = std::max(maxIndex[0], std::max(maxIndex[1], maxIndex[2]));
72 app_log() <<
" Using " <<
Gvecs.size() <<
" G-vectors for MPC interaction.\n";
74 <<
"] for MPC spline.\n";
80 double L = ptcl.
getLattice().WignerSeitzRadius;
81 double Linv = 1.0 / L;
82 double Linv3 = Linv * Linv * Linv;
90 double Ninv = 1.0 / (double)
N;
92 for (
int ix = 0; ix <
N; ix++)
95 for (
int iy = 0; iy <
N; iy++)
98 for (
int iz = 0; iz <
N; iz++)
104 double rmag =
std::sqrt(mybc.apply_bc(r));
106 rBox(ix, iy, iz) = -0.5 * rmag * rmag * Linv3 + 1.5 * Linv;
108 rBox(ix, iy, iz) = 1.0 / rmag;
112 fftw_plan fft = fftw_plan_dft_3d(
N,
N,
N, (fftw_complex*)rBox.
data(), (fftw_complex*)GBox.
data(), 1, FFTW_ESTIMATE);
114 fftw_destroy_plan(fft);
116 double norm = Ninv * Ninv * Ninv;
117 int numG =
Gints.size();
118 for (
int iG = 0; iG < numG; iG++)
122 gint[j] = (gint[j] +
N) %
N;
123 g_G[iG] =
norm *
real(GBox(gint[0], gint[1], gint[2]));
132 double N1inv2 = 1.0 / (double)(
N *
N);
133 double N2inv2 = 1.0 / (double)((2 *
N) * (2 *
N));
134 double N4inv2 = 1.0 / (double)((4 *
N) * (4 *
N));
137 A(0, 2) = N1inv2 * N1inv2;
140 A(1, 2) = N2inv2 * N2inv2;
143 A(2, 2) = N4inv2 * N4inv2;
153 double N1inv2 = 1.0 / (double)(
N *
N);
154 double N2inv2 = 1.0 / (double)((2 *
N) * (2 *
N));
167 int numG =
Gints.size();
169 int N = std::max(64, 2 *
MaxDim + 1);
170 std::vector<double> g_G_N(numG), g_G_2N(numG), g_G_4N(numG);
171 double g_0_N, g_0_2N, g_0_4N;
178 double volInv = 1.0 / ptcl.
getLattice().Volume;
179 double L = ptcl.
getLattice().WignerSeitzRadius;
184 app_log() <<
" Linear extrap = " << std::scientific <<
extrap(2 *
N, g0_12) << std::endl;
185 app_log() <<
" Quadratic extrap = " << std::scientific <<
f_0 << std::endl;
186 f_0 += 0.4 * M_PI * L * L * volInv;
188 double worst = 0.0, worstLin = 0.0, worstQuad = 0.0;
189 for (
int iG = 0; iG < numG; iG++)
193 double linearExtrap =
extrap(2 *
N, g_12);
194 double quadExtrap =
extrap(
N, g_124);
195 double diff =
std::abs(linearExtrap - quadExtrap);
199 worstLin = linearExtrap;
200 worstQuad = quadExtrap;
202 f_G[iG] = quadExtrap;
205 f_G[iG] += volInv * M_PI * (4.0 / G2 + 12.0 / (L * L * G2 * G2) * (
std::cos(G * L) -
std::sin(G * L) / (G * L)));
209 std::array<char, 1000> buff;
210 int length = std::snprintf(buff.data(), buff.size(),
211 " Worst MPC discrepancy:\n" 212 " Linear Extrap : %18.14e\n" 213 " Quadratic Extrap: %18.14e\n",
214 worstLin, worstQuad);
216 throw std::runtime_error(
"Error generating buffer string");
217 app_log() << std::string_view(buff.data(), length);
225 GBox = std::complex<double>();
231 for (
int iG = 0; iG <
Gvecs.size(); iG++)
235 double G2 =
dot(G, G);
240 const RealType xxx(vol * (4.0 * M_PI * volInv / G2 -
f_G[iG]));
241 if (!(index[0] == 0 && index[1] == 0 && index[2] == 0))
243 GBox(index[0], index[1], index[2]) = xxx *
Rho_G[iG];
255 GBox(0, 0, 0) = -volf *
Rho_G[0];
258 app_log() <<
" Constant potential = " <<
Vconst << std::endl;
260 (fftw_complex*)rBox.data(), -1, FFTW_ESTIMATE);
262 fftw_destroy_plan(fft);
263 for (
int i0 = 0; i0 <
SplineDim[0]; i0++)
264 for (
int i1 = 0; i1 <
SplineDim[1]; i1++)
265 for (
int i2 = 0; i2 <
SplineDim[2]; i2++)
266 splineData(i0, i1, i2) =
real(rBox(i0, i1, i2));
267 BCtype_d bc0, bc1, bc2;
268 Ugrid grid0, grid1, grid2;
278 bc0.lCode = bc0.rCode = PERIODIC;
279 bc1.lCode = bc1.rCode = PERIODIC;
280 bc2.lCode = bc2.rCode = PERIODIC;
282 std::shared_ptr<UBspline_3d_d>(create_UBspline_3d_d(grid0, grid1, grid2, bc0, bc1, bc2, splineData.
data()),
294 app_log() <<
"\n === Initializing MPC interaction === " << std::endl;
313 app_log() <<
" === MPC interaction initialized === \n\n";
318 auto newMPC = std::make_unique<MPC>(*this);
327 for (
size_t ipart = 0; ipart <
NParticles; ipart++)
330 const auto& dist = d_aa.getDistRow(ipart);
331 for (
size_t j = 0; j < ipart; ++j)
332 esum +=
cone / dist[j];
349 eval_UBspline_3d_d(
VlongSpline.get(), u[0], u[1], u[2], &val);
370 app_log() <<
" MPC cutoff not found. Set using \"cutoff\" attribute.\n" 371 <<
" Setting to default value of " <<
Ecut << std::endl;
void resetTargetParticleSet(ParticleSet &P) override
Reset the data with the target ParticleSet.
std::shared_ptr< UBspline_3d_d > VlongSpline
std::array< size_t, OHMMS_DIM > SplineDim
MPC(ParticleSet &ref, double cutoff)
std::vector< ComplexType > Rho_G
helper functions for EinsplineSetBuilder
const DistanceTableAA & getDistTableAA(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAA
Return_t evaluate(ParticleSet &P) override
Evaluate the local energy contribution of this component.
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
double extrap(int N, TinyVector< double, 3 > g_124)
size_t getTotalNum() const
bool put(xmlNodePtr cur)
assign attributes to the set
MakeReturn< UnaryNode< FnSin, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sin(const Vector< T1, C1 > &l)
constexpr std::complex< float > cone
Return_t evalLR(ParticleSet &P) const
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
void init_f_G(const ParticleSet &ptcl)
void init_gvecs(const ParticleSet &ptcl)
Specialized paritlce class for atomistic simulations.
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
double norm(const zVec &c)
class to handle a set of attributes of an xmlNode
Return_t evalSR(ParticleSet &P) const
std::vector< ComplexType > Density_G
void init_spline(const ParticleSet &ptcl)
~MPC() override
copy constructor
std::vector< RealType > f_G
FullPrecRealType Return_t
type of return value of evaluate
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
Class to represent a many-body trial wave function.
Tensor< T, D > inverse(const Tensor< T, D > &a)
Return_t value_
current value
void initBreakup(const ParticleSet &ptcl)
const auto & getLattice() const
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
std::vector< PosType > Gvecs
std::unique_ptr< OperatorBase > makeClone(ParticleSet &qp, TrialWaveFunction &psi) override
A D-dimensional Array class based on PETE.
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
whether full table needs to be ready at anytime or not after donePbyP Optimization can be implemented...
void compute_g_G(const ParticleSet &ptcl, double &g_0_N, std::vector< double > &g_G_N, int N)
std::vector< TinyVector< int, OHMMS_DIM > > DensityReducedGvecs
Particle density in G-space for MPC interaction.
Declaration of a MCWalkerConfiguration.
std::vector< TinyVector< int, OHMMS_DIM > > Gints
MakeReturn< UnaryNode< FnFloor, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t floor(const Vector< T1, C1 > &l)
bool put(xmlNodePtr cur) override
Do nothing.