8#ifndef SRC_APPS_CHEM_ELECTRONIC_CORRELATION_FACTOR_H_
9#define SRC_APPS_CHEM_ELECTRONIC_CORRELATION_FACTOR_H_
24 class CorrelationFactor {
30 double tight_thresh_6d=-1.0;
34 CorrelationFactor(World& world) : world(world), _gamma(-1.0),
dcut(1.e-10),
35 lo(1.e-10), tight_thresh_6d(FunctionDefaults<6>::get_thresh()*0.1) {}
38 CorrelationFactor(World& world,
const double& gamma,
const double dcut,
39 const Molecule&
molecule) : world(world), _gamma(gamma),
dcut(
dcut), tight_thresh_6d(FunctionDefaults<6>::get_thresh()*0.1) {
48 CorrelationFactor(World& world,
const double& gamma,
const double dcut,
49 const double lo,
const double tt6=FunctionDefaults<6>::get_thresh()*0.1)
50 : world(world), _gamma(gamma),
dcut(
dcut),
lo(
lo), tight_thresh_6d(tt6) {
58 CorrelationFactor(
const CorrelationFactor& other) : world(other.world) {
59 _gamma = other._gamma;
62 tight_thresh_6d = other.tight_thresh_6d;
66 CorrelationFactor& operator=(
const CorrelationFactor& other) {
67 _gamma = other._gamma;
70 tight_thresh_6d = other.tight_thresh_6d;
75 double gamma()
const {
return _gamma; }
77 void set_truncate_mode(
int mode) {
83 const double rr = r12(r);
84 if (_gamma > 0.0)
return (1.0 - exp(-_gamma * rr)) / (2.0 * _gamma);
89 real_function_6d apply_U_local(
const real_function_3d& phi_i,
const real_function_3d& phi_j,
90 const real_convolution_6d& op_mod,
double thresh)
const {
91 if (world.rank()==0)
print(
"applying local part of Ue term");
95 print(
"factor for thresh",fac);
99 .g12(fg3).particle1(
copy(phi_i)).particle2(
copy(phi_j)).thresh(
thresh*fac)
101 mul.fill_cuspy_tree(op_mod).truncate(tight_thresh_6d);
102 mul.print_size(
"local Ue|ij>");
107 real_function_6d apply_U_semilocal(
const real_function_3d& phi_i,
const real_function_3d& phi_j,
108 const real_convolution_6d& op_mod,
double thresh,
const bool symmetric =
false)
const {
109 if (world.rank()==0)
print(
"applying semi-local part of Ue term");
113 print(
"factor for thresh",fac);
115 auto dphi_i=
grad(phi_i);
116 auto dphi_j=
grad(phi_j);
122 std::vector<real_function_3d> p1({
copy(dphi_i[
axis]),
copy(phi_i)});
123 std::vector<real_function_3d> p2({
copy(phi_j),-1.0*
copy(dphi_j[
axis])});
128 tmp.fill_cuspy_tree(op_mod).truncate(tight_thresh_6d);
129 result = result + tmp;
132 result.truncate(tight_thresh_6d).reduce_rank();
133 result.print_size(
"semi-local Ue|ij>");
140 real_function_6d apply_U_mixed_commutator(
const real_function_3d& phi_i,
const real_function_3d& phi_j,
141 const real_convolution_6d& op_mod,
double thresh,
142 const std::vector<real_function_3d> U1nuc)
const {
143 if (world.rank()==0)
print(
"applying mixed double commutator of the Ue term");
147 print(
"factor for thresh",fac);
149 auto dphi_i=U1nuc*phi_i;
150 auto dphi_j=U1nuc*phi_j;
156 std::vector<real_function_3d> p1({
copy(dphi_i[
axis]),
copy(phi_i)});
157 std::vector<real_function_3d> p2({
copy(phi_j),-1.0*
copy(dphi_j[
axis])});
162 tmp.fill_cuspy_tree(op_mod).truncate(tight_thresh_6d);
163 result = result + tmp;
166 result.truncate(tight_thresh_6d).reduce_rank();
167 result.print_size(
"mixed commutator of Ue: R^{-1} [[T,f12],R] |ij>");
186 real_function_6d apply_U(
const real_function_3d& phi_i,
const real_function_3d& phi_j,
187 const real_convolution_6d& op_mod,
const std::vector<real_function_3d>& U1nuc,
188 const std::vector<real_function_3d> ao=std::vector<real_function_3d>(),
189 const std::vector<real_function_3d> occ_ket=std::vector<real_function_3d>(),
190 const std::vector<real_function_3d> occ_bra=std::vector<real_function_3d>(),
193 const double tight_thresh_3d=-1.0)
const {
194 MADNESS_CHECK_THROW(op_mod.modified(),
"ElectronicCorrelationFactor::apply_U, op_mod must be in modified_NS form");
195 const double thresh = FunctionDefaults<6>::get_thresh();
205 run_apply_U_diagnostics(local, semilocal, mixed, phi_i, phi_j, op_mod,
206 U1nuc, ao, occ_ket, occ_bra, phi_i_bra, phi_j_bra,
209 result.print_size(
"Ue|ij>");
223 if (world.rank() == 0)
print(
"U2 for the electronic correlation factor");
224 if (world.rank() == 0)
print(
"is expensive -- do you really need it??");
232 double thresh = FunctionDefaults<3>::get_thresh();
261 nablaf2_
func(_gamma);
275 DiagnosticMatrix<> diagnose_Ue(
const real_function_6d& Uphi_local,
276 const real_function_6d& Uphi_semilocal,
277 const real_function_3d& phi_i,
const real_function_3d& phi_j,
278 const std::vector<real_function_3d>&
aobasis,
279 const std::vector<real_function_3d>& ,
280 const std::vector<real_function_3d>& ,
283 const std::vector<real_function_3d>& U1nuc = {},
284 const bool orthonormalize_basis =
true,
285 const double tight_thresh_3d = -1.0)
const {
286 DiagnosticMatrix<> dm(world,
aobasis, orthonormalize_basis);
287 const double tt = (tight_thresh_3d > 0.0) ? tight_thresh_3d : FunctionDefaults<3>::get_thresh()*0.1;
288 auto bra = dm.build_simple_bra();
289 return diagnose_Ue_impl(std::move(dm), bra,
290 Uphi_local, Uphi_semilocal, phi_i, phi_j,
291 "local",
"semilocal",
292 Uphi_mixed, U1nuc,
"mixed", tt);
322 DiagnosticMatrix<> diagnose_GUe(
const real_function_6d& GUphi_local,
323 const real_function_6d& GUphi_semilocal,
324 const real_function_3d& phi_i,
325 const real_function_3d& phi_j,
326 const std::vector<real_function_3d>&
aobasis,
327 const std::vector<real_function_3d>& ,
328 const std::vector<real_function_3d>& ,
331 const std::vector<real_function_3d>& U1nuc = {},
332 const bool orthonormalize_basis =
true,
333 const double tight_thresh_3d = -1.0)
const {
335 DiagnosticMatrix<> dm(world,
aobasis, orthonormalize_basis);
337 const double tt = (tight_thresh_3d > 0.0) ? tight_thresh_3d : FunctionDefaults<3>::get_thresh()*0.1;
338 auto bra = dm.build_Gab_bra(
energy, tt, tt);
339 return diagnose_Ue_impl(std::move(dm), bra,
340 GUphi_local, GUphi_semilocal, phi_i, phi_j,
341 "Glocal",
"Gsemilocal",
342 GUphi_mixed, U1nuc,
"Gmixed", tt);
367 DiagnosticMatrix<> diagnose_GQUe(
368 const real_function_6d& GQ12Uphi_local,
369 const real_function_6d& GQ12Uphi_semilocal,
370 const real_function_3d& phi_i,
371 const real_function_3d& phi_j,
372 const std::vector<real_function_3d>&
aobasis,
373 const std::vector<real_function_3d>& occ_ket,
374 const std::vector<real_function_3d>& occ_bra,
377 const std::vector<real_function_3d>& U1nuc = {},
378 const bool orthonormalize_basis =
true,
379 const double tight_thresh_3d = -1.0)
const;
391 void compute_3d_references(
const real_function_3d& phi_i,
const real_function_3d& phi_j,
392 const real_function_3d& phi_i_bra,
const real_function_3d& phi_j_bra,
393 const std::vector<real_function_3d>& occ_ket,
394 const std::vector<real_function_3d>& occ_bra,
395 const double energy,
const std::vector<real_function_3d>& U1nuc,
396 const double tight_thresh_3d = -1.0)
const;
401 void run_apply_U_diagnostics(
402 const real_function_6d& local,
403 const real_function_6d& semilocal,
404 const real_function_6d& mixed,
405 const real_function_3d& phi_i,
const real_function_3d& phi_j,
406 const real_convolution_6d& op_mod,
407 const std::vector<real_function_3d>& U1nuc,
408 const std::vector<real_function_3d>& ao,
409 const std::vector<real_function_3d>& occ_ket,
410 const std::vector<real_function_3d>& occ_bra,
411 const real_function_3d& phi_i_bra,
412 const real_function_3d& phi_j_bra,
413 const double tight_thresh_3d=-1.0)
const;
427 DiagnosticMatrix<> diagnose_Ue_impl(
428 DiagnosticMatrix<> dm,
429 const std::vector<CCPairFunction<double,6>>& bra,
430 const real_function_6d& Uphi_local,
431 const real_function_6d& Uphi_semilocal,
432 const real_function_3d& phi_i,
const real_function_3d& phi_j,
433 const std::string& name_local,
const std::string& name_semilocal,
435 const std::vector<real_function_3d>& U1nuc = {},
436 const std::string& name_mixed =
"",
double eps = -1.0)
const;
447 DiagnosticMatrix<>::ElementProvider ue_local_provider(
448 const real_function_3d& phi_i,
const real_function_3d& phi_j,
449 double eps = -1.0)
const;
456 DiagnosticMatrix<>::ElementProvider ue_semilocal_provider(
457 const real_function_3d& phi_i,
const real_function_3d& phi_j,
458 double eps = -1.0)
const;
464 DiagnosticMatrix<>::ElementProvider ue_mixed_provider(
465 const real_function_3d& phi_i,
const real_function_3d& phi_j,
466 const std::vector<real_function_3d>& U1nuc,
double eps = -1.0)
const;
472 struct fg_ : FunctionFunctorInterface<double, 6> {
476 fg_(
double gamma,
double dcut) : gamma(gamma),
dcut(
dcut) {
480 using FunctionFunctorInterface<double,6>::operator();
482 double operator()(
const coord_6d& r)
const override {
483 const double rr = r12(r);
484 const double e = exp(-gamma * rr);
486 double value = 1.5 * gamma - 1. * std::pow(gamma, 2) * rr + 0.41666666666666663 * std::pow(gamma, 3)
488 0.125 * std::pow(gamma, 4) * std::pow(rr, 3) + 0.029166666666666667 * std::pow(gamma, 5) *
490 + 0.005555555555555556 * std::pow(gamma, 6) * std::pow(rr, 5) +
491 0.0008928571428571429 * std::pow(gamma, 7) * std::pow(rr, 6);
496 return (1.0 -
e) / rr + 0.5 * gamma *
e;
502 struct f_over_r_ : FunctionFunctorInterface<double, 6> {
506 f_over_r_(
double gamma,
double dcut) : gamma(gamma),
dcut(
dcut) {
510 using FunctionFunctorInterface<double,6>::operator();
512 double operator()(
const coord_6d& r)
const override {
513 const double rr = r12(r);
514 const double e = exp(-gamma * rr);
515 return (1.0 -
e) *
u(rr,
dcut) / (2.0 * gamma);
520 struct U : FunctionFunctorInterface<double, 6> {
529 using FunctionFunctorInterface<double,6>::operator();
530 double operator()(
const coord_6d& r)
const override {
531 const double rr = r12(r);
532 const coord_3d vr12{r[0] - r[3], r[1] - r[4], r[2] - r[5]};
534 if (gamma > 0.0)
return -0.5 * exp(-gamma * rr) *
N[
axis];
545 struct f2_ : FunctionFunctorInterface<double, 6> {
548 using FunctionFunctorInterface<double,6>::operator();
549 double operator()(
const coord_6d& r)
const override {
550 const double rr = r12(r);
551 const double e = exp(-gamma * rr);
552 const double f = (1.0 -
e) / (2.0 * gamma);
558 struct nablaf2_ : FunctionFunctorInterface<double, 6> {
561 nablaf2_(
double gamma) : gamma(gamma) {
565 using FunctionFunctorInterface<double,6>::operator();
566 double operator()(
const coord_6d& r)
const override {
567 const double rr = r12(r);
568 const double f = exp(-2.0 * gamma * rr) / (4.0 * gamma * gamma);
574 static double u(
double r,
double c) {
576 double r2 = r * r, pot;
581 pot = erf(r) / r + exp(-r2) * 0.56418958354775630;
584 pot = 1.6925687506432689 - r2 * (0.94031597257959381 - r2 * (0.39493270848342941 - 0.12089776790309064 *
590 static double r12(
const coord_6d& r) {
591 const double x12 = r[0] - r[3];
592 const double y12 = r[1] - r[4];
593 const double z12 = r[2] - r[5];
594 const double r12 = sqrt(x12 * x12 + y12 * y12 + z12 * z12);
598 static double x12(
const coord_6d& r,
const int axis) {
602 static coord_3d smoothed_unitvec(
const coord_3d& xyz,
double smoothing) {
607 const double r = xyz.
normf();
608 const double cutoff = smoothing;
610 return 1.0 / r * xyz;
613 const double xi = r / cutoff;
614 const double xi2 =
xi *
xi;
615 const double xi3 =
xi *
xi *
xi;
617 const double nu22 = 0.5 + 1. / 64. * (105 *
xi - 175 * xi3 + 147 * xi2 * xi3 - 45 * xi3 * xi3 *
xi);
619 const double kk = 2. * nu22 - 1.0;
620 return kk / (r + 1.e-15) * xyz;
628 class CorrelationFactor2 {
631 typedef std::shared_ptr<FunctionFunctorInterface<double, 6>>
functorT;
640 CorrelationFactor2(World& world) : world(world), _gamma(0.5),
dcut(1.e-10),
641 lo(1.e-10), vtol(FunctionDefaults<3>::get_thresh() * 0.1) {
646 double gamma()
const {
return _gamma; }
677 const double bsh_thresh = 1.e-7;
682 op_mod.modified() =
true;
694 .g12(u1).ket(
copy(Drhs1));
698 .g12(u1).ket(
copy(Drhs2));
702 result = result + (tmp1 - tmp2).
truncate();
706 result.truncate().reduce_rank();
722 class R_functor :
public FunctionFunctorInterface<double, 6> {
727 R_functor(
double gamma,
int e = 1) : gamma(gamma), exponent(
e) {
731 using FunctionFunctorInterface<double,6>::operator();
734 double operator()(
const coord_6d& r)
const override {
735 const double rr = r12(r);
736 double val = (1.0 - 0.5 * exp(-gamma * rr));
737 if (exponent == 1)
return val;
738 else if (exponent == 2)
return val * val;
739 else if (exponent == -1)
return 1.0 / val;
747 class U2_functor :
public FunctionFunctorInterface<double, 6> {
751 U2_functor(
double gamma) : gamma(gamma) {
755 using FunctionFunctorInterface<double,6>::operator();
758 double operator()(
const coord_6d& r)
const override {
759 const double rr = r12(r);
762 return (5. / 4.0 - rr + (35.0 * rr * rr) / 48.0 - (101.0 * rr * rr * rr) / 192.0);
764 const double egr = exp(-gamma * rr);
765 return -(-8. * egr + 8.0 + rr * egr) / (4.0 * rr * egr - 8 * rr);
775 class U1_functor :
public FunctionFunctorInterface<double, 6> {
780 U1_functor(
double gamma,
int axis) : gamma(gamma),
axis(
axis) {
785 using FunctionFunctorInterface<double,6>::operator();
787 double operator()(
const coord_6d& r)
const override {
788 const double rr = r12(r);
789 const coord_3d vr12{r[0] - r[3], r[1] - r[4], r[2] - r[5]};
794 val = 0.5 - 0.5 * rr + 0.125 * (3. * rr * rr) - (13. * rr * rr * rr) / 48.0;
797 const double egr = exp(-gamma * rr);
798 val = egr / (4.0 - 2.0 * egr);
801 return -val *
N[
axis];
806 static double r12(
const coord_6d& r) {
807 const double x12 = r[0] - r[3];
808 const double y12 = r[1] - r[4];
809 const double z12 = r[2] - r[5];
810 const double r12 = sqrt(x12 * x12 + y12 * y12 + z12 * z12);
virtual FunctionFactory & thresh(double thresh)
Definition function_factory.h:198
FunctionFactory & functor(const std::shared_ptr< FunctionFunctorInterface< T, NDIM > > &f)
Definition function_factory.h:141
virtual FunctionFactory & is_on_demand()
Definition function_factory.h:288
FunctionFactory & truncate_mode(int truncate_mode)
Definition function_factory.h:228
Function< T, NDIM > & fill_tree(const Function< R, NDIM > &g, bool fence=true)
With this being an on-demand function, fill the MRA tree according to different criteria.
Definition mra.h:1347
Function< T, NDIM > & fill_cuspy_tree(const opT &op, const bool fence=true)
Definition mra.h:1388
double thresh() const
Returns value of truncation threshold. No communication.
Definition mra.h:674
Function< T, NDIM > & truncate(double tol=0.0, bool fence=true)
Truncate the function with optional fence. Compresses with fence if not compressed.
Definition mra.h:718
Function< T, NDIM > & reduce_rank(const double thresh=0.0, const bool fence=true)
reduce the rank of the coefficient tensors
Definition mra.h:1909
constexpr T normf() const
Calculate the 2-norm of the vector elements.
Definition vector.h:421
static const double R
Definition csqrt.cc:46
double(* f)(const coord_3d &)
Definition derivatives.cc:54
double(* energy)()
Definition derivatives.cc:58
double(* f2)(const coord_3d &)
Definition derivatives.cc:56
static double lo
Definition dirac-hatom.cc:23
std::vector< Spinor > truncate(std::vector< Spinor > arg)
Definition dirac-hatom.cc:503
Fcwf copy(Fcwf psi)
Definition fcwf.cc:374
static double function(const coord_3d &r)
Normalized gaussian.
Definition functionio.cc:100
double square(double x)
Definition gfit.cc:59
double psi(const Vector< double, 3 > &r)
Definition hatom_energy.cc:78
static double u(double r, double c)
Definition he.cc:20
static const double dcut
Definition he.cc:13
double func(double x)
A simple program for testing the CubicInterpolationTable class.
Definition interp3.cc:43
Implements (2nd generation) static load/data balancing for functions.
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition madness_exception.h:134
#define MADNESS_CHECK_THROW(condition, msg)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:207
std::shared_ptr< FunctionFunctorInterface< double, 3 > > functorT
Definition mcpfit.cc:49
void print(const tensorT &t)
Definition mcpfit.cc:140
Main include file for MADNESS and defines Function interface.
Namespace for all elements and tools of MADNESS.
Definition DFConvergence.h:9
Function< TENSOR_RESULT_TYPE(Q, T), NDIM > mul(const Q alpha, const Function< T, NDIM > &f, bool fence=true)
Returns new function equal to alpha*f(x) with optional fence.
Definition mra.h:1938
@ ao
read the AO projections (restartaodata) and iterate
Definition RestartPlan.h:57
Tensor< T > inverse(const Tensor< T > &a_in)
invert general square matrix A
Definition lapack.cc:832
constexpr Vector< T, N > unitvec(const Vector< T, N > &r, const double eps=1.e-6)
Construct a unit-Vector that has the same direction as r.
Definition vector.h:768
Function< double, 6 > real_function_6d
Definition functypedefs.h:83
Function< double, 3 > real_function_3d
Definition functypedefs.h:80
std::vector< Function< T, NDIM > > grad(const Function< T, NDIM > &f, bool refine=false, bool fence=true)
shorthand gradient operator
Definition vmra.h:2370
SeparatedConvolution< double, 6 > real_convolution_6d
Definition functypedefs.h:139
Vector< double, 3 > coord_3d
Definition funcplot.h:1074
Derivative< double, 6 > real_derivative_6d
Definition functypedefs.h:188
FunctionFactory< double, 6 > real_factory_6d
Definition functypedefs.h:111
double operator()(const std::array< double, 3 > &x) const
Evaluate the Gaussian primitive at the specified point.
static const double c
Definition relops.cc:10
static const double thresh
Definition rk.cc:45
const double xi
Exponent for delta function approx.
Definition siam_example.cc:60
void e()
Definition test_sig.cc:75
#define N
Definition testconv.cc:37
static const int truncate_mode
Definition testcosine.cc:14
std::size_t axis
Definition testpdiff.cc:59
static Molecule molecule
Definition testperiodicdft.cc:39
static AtomicBasisSet aobasis
Definition testperiodicdft.cc:40
const double R2
Definition vnucso.cc:84