20#ifndef MADNESS_MRA_COMPOSITE_PRODUCT_OP_H__
21#define MADNESS_MRA_COMPOSITE_PRODUCT_OP_H__
31template <
typename T, std::
size_t NDIM>
34 static_assert(
NDIM == 2 *
LDIM,
"composite_term requires NDIM = 2*LDIM");
54template <
typename T, std::
size_t NDIM,
typename opT, std::
size_t LDIM>
56 static_assert(
NDIM == 2 * LDIM,
"composite_product_op_NS requires NDIM = 2*LDIM");
84 template <
typename Archive>
void serialize(Archive& ar) {
106 const std::vector<TermImpl>&
terms,
117 "inner mode requires exactly one bra: either on-demand (bra) "
118 "or explicit-NDIM (cbra)");
120 "inner mode: on-demand bra pointer must point to an on-demand FunctionImpl");
129 template <
typename CT,
typename KEY>
130 static std::pair<double, double>
sd_norm(
const CT& ct,
const KEY& key) {
131 if (!ct.get_impl())
return {1.0, 0.0};
132 return {ct.coeff(key).normf(), ct.dnorm(key)};
139 if (!extra)
return {1.0, 0.0};
141 const double sn =
c(extra->
get_cdata().s0).normf();
144 return {sn,
d.normf()};
150 double total = 1.0, sprod = 1.0;
151 for (
const auto& [s,
d] : sd) { total *= (s +
d); sprod *= s; }
152 return total - sprod;
159 const std::vector<ctL>& iap2,
162 double s = 0.0,
d = 0.0;
163 for (std::size_t
k = 0;
k < iap1.size(); ++
k) {
167 d += s1 * d2 + d1 * s2 + d1 * d2;
175 std::vector<std::pair<double, double>> sd;
192 return eri->
get_functor()->coeff(key).full_tensor();
207 result->get_tensor_args());
208 for (std::size_t
k = 1;
k < t.
iap1.size(); ++
k) {
210 result->get_tensor_args());
212 acc.reduce_rank(
result->get_tensor_args().thresh);
224 typename implT::template pointwise_multiplier<LDIM> pm(key, current);
230 typename implT::template pointwise_multiplier<LDIM> pm(key, current);
237 typename implT::template pointwise_multiplier<LDIM> pm(key, current);
244 if (t.
coeff != 1.0) {
245 current.scale(t.
coeff);
248 return {current, err};
261 for (
const auto& t :
terms) {
267 if (
terms.size() > 1) cresult.reduce_rank(
result->get_tensor_args().thresh);
268 return {cresult,
error};
274 ?
cbra.coeff(key).full_tensor_copy()
277 for (
const auto& t :
terms) {
281 sum += cbra_t.trace(
c.full_tensor_copy());
295 result->get_coeffs().task(key, &nodeT::accumulate, coeff,
296 result->get_coeffs(), key,
result->get_tensor_args(),
false);
314 if (
leaf_op.do_pre_screening()) {
315 if (
leaf_op.pre_screening(key)) {
323 const size_t il =
result->get_initial_level();
325 if (key.
level() < min_lvl)
329 leaf_op.special_refinement_needed(key))
335 if (
leaf_op.post_screening(key,
c) || err < tol) {
344 const keyT& key)
const {
347 const keyT child = kit.key();
348 if (child_is_leaf[i]) {
351 result->get_tensor_args()),
true);
358 result->task(
p, ft, child_op, no, child);
366 std::vector<TermImpl> child_terms;
367 child_terms.reserve(
terms.size());
368 for (
const auto& t :
terms) {
372 ct.
iap1.reserve(t.iap1.size());
373 ct.
iap2.reserve(t.iap2.size());
374 for (
const auto&
p : t.iap1) ct.
iap1.push_back(
p.make_child(
k1));
375 for (
const auto&
p : t.iap2) ct.
iap2.push_back(
p.make_child(
k2));
381 child_terms.push_back(std::move(ct));
401 const size_t N =
terms.size();
402 std::vector<Future<ctT>> t_futs(
N + 1);
403 std::vector<Future<ctL>> l_futs;
404 for (
size_t i = 0; i <
N; ++i) {
405 const auto& t =
terms[i];
407 t_futs[i] = t.iaket.activate();
410 for (
const auto&
p : t.iap1) l_futs.push_back(
p.activate());
411 for (
const auto&
p : t.iap2) l_futs.push_back(
p.activate());
414 for (
size_t i = 0; i <
N; ++i) {
415 const auto& t =
terms[i];
416 l_futs.push_back(t.have_factor1() ? t.ifactor1.activate() :
Future<ctL>(
ctL{}));
418 for (
size_t i = 0; i <
N; ++i) {
419 const auto& t =
terms[i];
420 l_futs.push_back(t.have_factor2() ? t.ifactor2.activate() :
Future<ctL>(
ctL{}));
423 return result->world.taskq.add(
430 const std::vector<TermImpl>& orig_terms,
Mode mode1,
431 const implT* bra1,
double target_precision1,
int oversampling1,
435 auto& tf =
const_cast<std::vector<Future<ctT>
>&>(t_futs);
436 auto& lf =
const_cast<std::vector<Future<ctL>
>&>(l_futs);
437 const size_t N = orig_terms.size();
440 for (
size_t i = 0; i <
N; ++i)
441 if (!orig_terms[i].have_ket()) p_total += 2 * orig_terms[i].iap1.size();
442 std::vector<TermImpl> activated(
N);
444 for (
size_t i = 0; i <
N; ++i) {
445 const auto& t = orig_terms[i];
446 activated[i].extra = t.extra;
447 activated[i].coeff = t.coeff;
449 activated[i].iaket = tf[i].get();
451 const size_t np = t.iap1.size();
452 for (
size_t k = 0;
k <
np; ++
k)
453 activated[i].iap1.push_back(lf[p_idx +
k].get());
454 for (
size_t k = 0;
k <
np; ++
k)
455 activated[i].iap2.push_back(lf[p_idx +
np +
k].get());
458 if (t.have_factor1()) activated[i].ifactor1 = lf[p_total + i].get();
459 if (t.have_factor2()) activated[i].ifactor2 = lf[p_total +
N + i].get();
461 return this_type(result1, leaf_op1, activated, mode1, bra1,
462 target_precision1, oversampling1, tf[
N].get());
465 template <
typename Archive>
void serialize(Archive& ar) {
478template <
typename T, std::
size_t NDIM>
481 for (
auto&
p : term.
p1)
p.change_tree_state(
redundant,
false);
482 for (
auto&
p : term.
p2)
p.change_tree_state(
redundant,
false);
489template <
typename T, std::
size_t NDIM>
499template <
typename T, std::
size_t NDIM,
typename OP>
501 constexpr std::size_t LDIM =
NDIM / 2;
502 typename OP::TermImpl x;
507 x.iap1.reserve(term.
p1.size());
508 x.iap2.reserve(term.
p2.size());
509 for (
const auto&
p : term.
p1) x.iap1.emplace_back(
p.get_impl().get());
510 for (
const auto&
p : term.
p2) x.iap2.emplace_back(
p.get_impl().get());
517 x.coeff = term.
coeff;
527template <
typename T, std::
size_t NDIM,
typename leaf_opT>
531 double target_precision,
534 constexpr std::size_t LDIM =
NDIM / 2;
541 if (target_precision == 0.0) target_precision = result->
get_thresh();
543 std::vector<typename OP::TermImpl> impl_terms;
544 impl_terms.reserve(terms.size());
545 for (
const auto& t : terms) {
549 OP coeff_op(result,
leaf_op, impl_terms, OP::Mode::function,
550 nullptr, target_precision, oversampling);
556 coeff_op, apply_op, result->
get_cdata().key0);
582template <
typename T, std::
size_t NDIM,
typename leaf_opT>
588 double target_precision,
590 constexpr std::size_t LDIM =
NDIM / 2;
594 "composite_inner: bra Function must be initialised");
599 for (
auto& t : terms) {
606 typename OP::ctT cbra_tracker;
607 if (!on_demand_bra) {
609 cbra_tracker =
typename OP::ctT(bra_impl);
615 if (target_precision == 0.0) target_precision = acc.
get_thresh() * 0.01;
617 std::vector<typename OP::TermImpl> impl_terms;
618 impl_terms.reserve(terms.size());
619 for (
const auto& t : terms) {
623 OP coeff_op(&acc,
leaf_op, impl_terms, OP::Mode::inner,
624 on_demand_bra ? bra_impl :
nullptr,
625 target_precision, oversampling,
632 coeff_op, apply_op, acc.
get_cdata().key0);
644 scalar =
a->second.coeff().full_tensor_copy().flat()(0
L);
a class to track where relevant (parent) coeffs are
Definition funcimpl.h:887
const implT * get_impl() const
const reference to impl
Definition funcimpl.h:931
const coeffT & coeff() const
const reference to the coeffs
Definition funcimpl.h:934
CoeffTracker make_child(const keyT &child) const
make a child of this, ignoring the coeffs
Definition funcimpl.h:964
static bool get_refine()
Gets the default adaptive refinement flag.
Definition funcdefaults.h:248
FunctionImpl holds all Function state to facilitate shallow copy semantics.
Definition funcimpl.h:1043
World & world
Definition funcimpl.h:1062
FunctionNode< T, NDIM > nodeT
Type of node.
Definition funcimpl.h:1053
const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > & get_pmap() const
Definition mraimpl.h:209
double get_thresh() const
Definition mraimpl.h:340
void fcube(const keyT &key, const FunctionFunctorInterface< T, NDIM > &f, const Tensor< double > &qx, tensorT &fval) const
Evaluate function at quadrature points in the specified box.
Definition mraimpl.h:2605
void set_tree_state(const TreeState &state)
Definition funcimpl.h:1539
void flo_unary_op_node_inplace(const opT &op, bool fence)
Definition funcimpl.h:2416
GenTensor< Q > values2coeffs(const keyT &key, const GenTensor< Q > &values) const
Definition funcimpl.h:2130
GenTensor< T > coeffT
Type of tensor used to hold coeffs.
Definition funcimpl.h:1054
const dcT & get_coeffs() const
Definition mraimpl.h:355
const FunctionCommonData< T, NDIM > & get_cdata() const
Definition mraimpl.h:361
void sum_down(bool fence)
After 1d push operator must sum coeffs down the tree to restore correct scaling function coefficients...
Definition mraimpl.h:1017
std::shared_ptr< FunctionFunctorInterface< T, NDIM > > get_functor()
Definition mraimpl.h:312
bool is_on_demand() const
Definition mraimpl.h:285
TensorArgs get_tensor_args() const
Definition mraimpl.h:334
A multiresolution adaptive numerical function.
Definition mra.h:141
const Function< T, NDIM > & change_tree_state(const TreeState finalstate, bool fence=true) const
changes tree state to given state
Definition mra.h:960
const std::shared_ptr< FunctionImpl< T, NDIM > > & get_impl() const
Returns a shared-pointer to the implementation.
Definition mra.h:730
bool is_initialized() const
Returns true if the function is initialized.
Definition mra.h:169
A future is a possibly yet unevaluated value.
Definition future.h:370
const Tensor< T > & full_tensor() const
Definition gentensor.h:200
Iterates in lexical order thru all children of a key.
Definition key.h:624
Key is the index for a node of the 2^NDIM-tree.
Definition key.h:71
Level level() const
Definition key.h:170
void break_apart(Key< LDIM > &key1, Key< KDIM > &key2) const
break key into two low-dimensional keys
Definition key.h:500
A tensor is a multidimensional array.
Definition tensor.h:313
Tensor< T > flat()
Returns new view/tensor rehshaping to flat (1-d) tensor.
Definition tensor.h:1560
bool find(accessor &acc, const keyT &key)
Write access to LOCAL value by key. Returns true if found, false otherwise (always false for remote).
Definition worlddc.h:1469
ProcessID owner(const keyT &key) const
Returns processor that logically owns key (no communication).
Definition worlddc.h:1516
implT::const_accessor const_accessor
Definition worlddc.h:1312
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition worldgop.cc:177
void sum(T *buf, size_t nelem)
Inplace global sum while still processing AM & tasks.
Definition worldgop.h:890
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)().
Definition world_object.h:1132
A parallel world class.
Definition world.h:134
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:344
WorldGopInterface & gop
Global operations.
Definition world.h:216
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
Provides FunctionCommonData, FunctionImpl and FunctionFactory.
static double function(const coord_3d &r)
Normalized gaussian.
Definition functionio.cc:100
static const double v
Definition hatom_sf_dirac.cc:20
#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
Definition potentialmanager.cc:41
MemFuncWrapper< objT *, memfnT, typename result_of< memfnT >::type > wrap_mem_fn(objT &obj, memfnT memfn)
Create a member function wrapper (MemFuncWrapper) from an object and a member function pointer.
Definition mem_func_wrapper.h:251
void make_term_inputs_reconstructed(composite_term< T, NDIM > &term)
Restore every input of a composite_term to reconstructed state.
Definition composite_product_op.h:490
void make_term_inputs_redundant(composite_term< T, NDIM > &term)
Bring every input of a composite_term into redundant state.
Definition composite_product_op.h:479
OP::TermImpl make_term_impl(const composite_term< T, NDIM > &term)
Translate a composite_term<T,NDIM> into the op's CoeffTracker-based TermImpl.
Definition composite_product_op.h:500
Namespace for all elements and tools of MADNESS.
Definition DFConvergence.h:9
int FunctionDefaults< NDIM >::k
Definition mraimpl.h:3878
@ redundant_after_merge
s coeffs everywhere, must be summed up to yield the result
Definition funcdefaults.h:67
@ reconstructed
s coeffs at the leaves only
Definition funcdefaults.h:61
@ redundant
s coeffs everywhere
Definition funcdefaults.h:66
T composite_inner_apply(World &world, const FunctionImpl< T, NDIM > *like, const leaf_opT &leaf_op, std::vector< composite_term< T, NDIM > > &terms, Function< T, NDIM > &bra_function, double target_precision, int oversampling)
Definition composite_product_op.h:583
Function< T, NDIM > sum(World &world, const std::vector< Function< T, NDIM > > &f, bool fence=true)
Returns new function — q = sum_i f[i].
Definition vmra.h:1774
std::enable_if< std::is_base_of< ProjectorBase, projT >::value, OuterProjector< projT, projQ > >::type outer(const projT &p0, const projQ &p1)
Definition projector.h:476
@ TT_FULL
Definition gentensor.h:120
void error(const char *msg)
Definition world.cc:147
void composite_product_apply(FunctionImpl< T, NDIM > *result, const leaf_opT &leaf_op, std::vector< composite_term< T, NDIM > > &terms, double target_precision, int oversampling, bool fence)
Definition composite_product_op.h:528
Function< T, CCPairFunction< T, NDIM >::LDIM > inner(const CCPairFunction< T, NDIM > &c, const Function< T, CCPairFunction< T, NDIM >::LDIM > &f, const std::tuple< int, int, int > v1, const std::tuple< int, int, int > v2)
Definition ccpairfunction.h:1007
Function< T, NDIM > copy(const Function< T, NDIM > &f, const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap, bool fence=true)
Create a new copy of the function with different distribution and optional fence.
Definition mra.h:2239
static long abs(long a)
Definition tensor.h:214
static const double d
Definition nonlinschro.cc:121
static const double a
Definition nonlinschro.cc:118
static const double c
Definition relops.cc:10
static const double L
Definition rk.cc:46
Definition funcimpl.h:2903
TensorArgs holds the arguments for creating a LowRankTensor.
Definition gentensor.h:134
internal serialisable view of a term (CoeffTracker-based)
Definition composite_product_op.h:72
std::vector< ctL > iap2
sum-of-hartree-products ket if iaket is null
Definition composite_product_op.h:74
ctT iaket
NDIM ket (optional, exclusive with iap*).
Definition composite_product_op.h:73
ctL ifactor1
Definition composite_product_op.h:75
bool have_extra() const
Definition composite_product_op.h:82
double coeff
scalar prefactor (DSL)
Definition composite_product_op.h:77
std::vector< ctL > iap1
Definition composite_product_op.h:74
const implT * extra
NDIM extra factor (function mode only).
Definition composite_product_op.h:76
bool have_ket() const
Definition composite_product_op.h:79
bool have_factor1() const
Definition composite_product_op.h:80
void serialize(Archive &ar)
Definition composite_product_op.h:84
ctL ifactor2
single per-particle LDIM factor (each optional)
Definition composite_product_op.h:75
bool have_factor2() const
Definition composite_product_op.h:81
Adaptive sum-of-products operator over a vector of composite_terms.
Definition composite_product_op.h:55
int oversampling
Definition composite_product_op.h:99
void serialize(Archive &ar)
Definition composite_product_op.h:465
Mode mode
Definition composite_product_op.h:94
this_type make_child(const keyT &child) const
Definition composite_product_op.h:364
composite_product_op_NS(implT *result, const opT &leaf_op, const std::vector< TermImpl > &terms, Mode mode, const implT *bra, double target_precision, int oversampling, const ctT &cbra=ctT{})
Definition composite_product_op.h:105
typename implT::nodeT nodeT
Definition composite_product_op.h:65
opT leaf_op
Definition composite_product_op.h:92
coeffT make_term_ket(const TermImpl &t, const keyT &key, const keyL &k1, const keyL &k2) const
Definition composite_product_op.h:202
CoeffTracker< T, LDIM > ctL
Definition composite_product_op.h:69
ctT cbra
Definition composite_product_op.h:96
composite_product_op_NS()
Definition composite_product_op.h:103
static tensorT eri_coeffs(const implT *eri, const keyT &key)
fetch coeffs of an on-demand NDIM function at key
Definition composite_product_op.h:189
static std::pair< double, double > sd_norm_extra(const implT *extra, const keyT &key)
Definition composite_product_op.h:138
std::pair< coeffT, double > make_term_coeffs(const TermImpl &t, const keyT &key) const
Definition composite_product_op.h:218
CoeffTracker< T, NDIM > ctT
Definition composite_product_op.h:68
FunctionImpl< T, LDIM > implL
Definition composite_product_op.h:62
bool have_explicit_bra() const
Definition composite_product_op.h:101
std::pair< bool, coeffT > operator()(const keyT &key) const
Definition composite_product_op.h:311
Mode
Definition composite_product_op.h:58
@ function
Definition composite_product_op.h:58
@ inner
Definition composite_product_op.h:58
typename implT::coeffT coeffT
Definition composite_product_op.h:66
Tensor< T > tensorT
Definition composite_product_op.h:67
std::pair< double, double > sd_norm_pair_sum(const std::vector< ctL > &iap1, const std::vector< ctL > &iap2, const keyL &k1, const keyL &k2) const
Definition composite_product_op.h:158
composite_product_op_NS< T, NDIM, opT, LDIM > this_type
Definition composite_product_op.h:60
double target_precision
Definition composite_product_op.h:98
this_type forward_ctor(implT *result1, const opT &leaf_op1, const std::vector< TermImpl > &orig_terms, Mode mode1, const implT *bra1, double target_precision1, int oversampling1, const std::vector< Future< ctT > > &t_futs, const std::vector< Future< ctL > > &l_futs)
Definition composite_product_op.h:429
const implT * bra
inner-mode on-demand bra (e.g., ERI)
Definition composite_product_op.h:95
implT * result
output tree (function mode) or scalar sink (inner)
Definition composite_product_op.h:91
static double cross_term_error(const std::vector< std::pair< double, double > > &sd)
Definition composite_product_op.h:149
Key< NDIM > keyT
Definition composite_product_op.h:63
std::pair< coeffT, double > make_sum_coeffs(const keyT &key) const
Definition composite_product_op.h:255
void leaf_action(const keyT &key, const coeffT &coeff) const
Definition composite_product_op.h:299
Future< this_type > activate() const
Definition composite_product_op.h:388
std::vector< TermImpl > terms
Definition composite_product_op.h:93
bool randomize() const
Definition composite_product_op.h:89
Key< LDIM > keyL
Definition composite_product_op.h:64
static std::pair< double, double > sd_norm(const CT &ct, const KEY &key)
retrieve scaling- and detail-norm at the given key from a CoeffTracker
Definition composite_product_op.h:130
FunctionImpl< T, NDIM > implT
Definition composite_product_op.h:61
void accumulate_into_result(const keyT &key, const coeffT &coeff) const
Definition composite_product_op.h:294
double term_refinement_error(const TermImpl &t, const keyT &key, const keyL &k1, const keyL &k2) const
full inaccurate-refinement error for one term, scaled by the term's coeff.
Definition composite_product_op.h:173
std::pair< bool, coeffT > continue_recursion(const std::vector< bool > child_is_leaf, const tensorT &coeffs, const keyT &key) const
Definition composite_product_op.h:342
Definition composite_product_op.h:32
Function< T, LDIM > FL
Definition composite_product_op.h:37
std::vector< FL > p1
parallel vectors forming the ket as a sum of hartree products (p1.size() == p2.size())
Definition composite_product_op.h:42
double coeff
Definition composite_product_op.h:50
Function< T, NDIM > FN
Definition composite_product_op.h:36
FL factor1
single LDIM factor per particle (uninitialized = skip)
Definition composite_product_op.h:44
FN ket
NDIM ket factor. If uninitialized, the term ket is Σ_k p1[k] ⊗ p2[k].
Definition composite_product_op.h:40
static constexpr std::size_t LDIM
Definition composite_product_op.h:33
FL factor2
Definition composite_product_op.h:44
std::vector< FL > p2
Definition composite_product_op.h:42
FN extra
Definition composite_product_op.h:47
insert/replaces the coefficients into the function
Definition funcimpl.h:788
Definition funcimpl.h:776
int np
Definition tdse1d.cc:165
void e()
Definition test_sig.cc:75
#define N
Definition testconv.cc:37
constexpr std::size_t NDIM
Definition testgconv.cc:54
double k2
Definition testperiodic.cc:68
double k1
Definition testperiodic.cc:67
int ProcessID
Used to clearly identify process number/rank.
Definition worldtypes.h:43