MADNESS 0.10.1
function_interface.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30
31 $Id: function_factory_and_interface.h 3422 2014-03-24 09:16:15Z 3ru6ruWu $
32*/
33
34
35#ifndef MADNESS_MRA_FUNCTION_INTERFACE_H__INCLUDED
36#define MADNESS_MRA_FUNCTION_INTERFACE_H__INCLUDED
37
40#include <madness/mra/key.h>
41
42// needed for the TwoElectronInterface
44#include <madness/mra/gfit.h>
47
48namespace madness {
49
50 // forward declaration needed for CompositeFunctorInterface
51 template<typename T, std::size_t NDIM>
52 class FunctionImpl;
53
54 template<typename T, std::size_t NDIM>
55 class Function;
56
57 template<typename T, std::size_t NDIM>
58 Tensor<T> fcube(const Key<NDIM>&, T (*f)(const Vector<double,NDIM>&), const Tensor<double>&);
59
60// template <typename T, std::size_t NDIM>
61// const std::vector<Function<T,NDIM>>& change_tree_state(const std::vector<Function<T,NDIM>>& v,
62// const TreeState finalstate,
63// const bool fence);
64
65
66 /// Abstract base class interface required for functors used as input to Functions
67 template<typename T, std::size_t NDIM>
69 public:
70
72 typedef Key<NDIM> keyT;
73 typedef T value_type;
74
76
78
79 /// adapt the special level to resolve the smallest length scale
80 void set_length_scale(double lo) {
82 double lo_sim=lo/Lmax; // lo in simulation coordinates;
84 }
85
86 /// Can we screen this function based on the bounding box information?
87 virtual bool screened(const Vector<double,NDIM>& c1, const Vector<double,NDIM>& c2) const {
88 return false;
89 }
90
91 /// Does the interface support a vectorized operator()?
92 virtual bool supports_vectorized() const {return false;}
93
95MADNESS_PRAGMA_GCC(diagnostic ignored "-Woverloaded-virtual")
97MADNESS_PRAGMA_CLANG(diagnostic ignored "-Woverloaded-virtual")
98
99 virtual void operator()(const Vector<double*,1>& xvals, T* fvals, int npts) const {
100 MADNESS_EXCEPTION("FunctionFunctorInterface: This function should not be called!", 0);
101 }
102
103 virtual void operator()(const Vector<double*,2>& xvals, T* fvals, int npts) const {
104 MADNESS_EXCEPTION("FunctionFunctorInterface: This function should not be called!", 0);
105 }
106
107 virtual void operator()(const Vector<double*,3>& xvals, T* fvals, int npts) const {
108 MADNESS_EXCEPTION("FunctionFunctorInterface: This function should not be called!", 0);
109 }
110
111 virtual void operator()(const Vector<double*,4>& xvals, T* fvals, int npts) const {
112 MADNESS_EXCEPTION("FunctionFunctorInterface: This function should not be called!", 0);
113 }
114
115 virtual void operator()(const Vector<double*,5>& xvals, T* fvals, int npts) const {
116 MADNESS_EXCEPTION("FunctionFunctorInterface: This function should not be called!", 0);
117 }
118
119 virtual void operator()(const Vector<double*,6>& xvals, T* fvals, int npts) const {
120 MADNESS_EXCEPTION("FunctionFunctorInterface: This function should not be called!", 0);
121 }
124
125 /// You should implement this to return \c f(x)
126 virtual T operator()(const Vector<double, NDIM>& x) const = 0;
127
128 /// Override this to return list of special points to be refined more deeply
129 virtual std::vector< Vector<double,NDIM> > special_points() const {
130 return std::vector< Vector<double,NDIM> >();
131 }
132
133 /// Override this to change the minimum level of refinement at special points (default is 6)
134 virtual Level special_level() const {return special_level_;}
135
137
138 virtual coeffT coeff(const keyT&) const {
139 MADNESS_EXCEPTION("implement coeff for FunctionFunctorInterface",0);
140 return coeffT();
141 }
142
143 virtual coeffT values(const keyT& key, const Tensor<double>& tensor) const {
144 MADNESS_EXCEPTION("implement values for FunctionFunctorInterface",0);
145 return coeffT();
146 }
147
148 /// does this functor directly provide sum coefficients? or only function values?
149 virtual bool provides_coeff() const {
150 return false;
151 }
152
153 };
154
155
156
157 ///forward declaration
158 template <typename T, std::size_t NDIM>
159 // void FunctionImpl<T,NDIM>::fcube(const keyT& key, const FunctionFunctorInterface<T,NDIM>& f, const Tensor<double>& qx, tensorT& fval) const {
160 void fcube(const Key<NDIM>& key, const FunctionFunctorInterface<T,NDIM>& f, const Tensor<double>& qx, Tensor<T>& fval);
161
162 /// CompositeFunctorInterface implements a wrapper of holding several functions and functors
163
164 /// Use this to "connect" several functions and/or functors and to return their coefficients
165 /// e.g. connect f1 and f2 with an addition, you can request the coefficients of any node
166 /// and they will be computed on the fly and returned. Mainly useful to connect a functor
167 /// with a function, if the functor is too large to be represented in MRA (e.g. 1/r12)
168 ///
169 /// as of now, the operation connecting the functions/functors is simply addition.
170 /// need to implement expression templates, if I only knew what that was...
171 template<typename T, std::size_t NDIM, std::size_t MDIM>
173
174 typedef Vector<double, NDIM> coordT; ///< Type of vector holding coordinates
177 typedef std::shared_ptr<implT> pimplT;
178 typedef std::shared_ptr<implL> pimplL;
179
181
182 public:
183 /// various MRA functions of NDIM dimensionality
184 std::vector<std::shared_ptr<implT>> impl_ket_vector; ///< supposedly the pair function
185 std::shared_ptr<implT> impl_eri; ///< supposedly 1/r12
186
187 /// various MRA functions of MDIM dimensionality (e.g. 3, if NDIM==6)
188 std::shared_ptr<implL> impl_m1; ///< supposedly 1/r1
189 std::shared_ptr<implL> impl_m2; ///< supposedly 1/r2
190 std::vector<std::shared_ptr<implL>> impl_p1_vector; ///< supposedly orbital 1
191 std::vector<std::shared_ptr<implL>> impl_p2_vector; ///< supposedly orbital 2
192
193 public:
194
196
197 /// constructor takes its Factory
198 CompositeFunctorInterface(World& world, std::vector<pimplT> ket, pimplT g12,
199 pimplL v1, pimplL v2, std::vector<pimplL> p1, std::vector<pimplL> p2)
200 : world(world), impl_ket_vector(ket), impl_eri(g12)
202 {
203
204 // some consistency checks
205 // either a pair ket is provided, or two particles (tba)
206 MADNESS_CHECK_THROW(impl_p1_vector.size()==impl_p2_vector.size(), "CompositeFunctorInterface: p1 and p2 must have the same size");
207 MADNESS_CHECK_THROW(impl_ket_vector.size()>0 or (impl_p1_vector.size()>0),"CompositeFunctorInterface: either ket or p1 must be provided");
208
209 }
210
211 /// replicate low-dimensional functions over all ranks of this world
212 void replicate_low_dim_functions(const bool fence) {
213 if (impl_m1 and (not impl_m1->is_on_demand())) impl_m1->replicate(false);
214 if (impl_m2 and (not impl_m2->is_on_demand())) impl_m2->replicate(false);
215
216 for (auto& p1 : impl_p1_vector) if (p1 and (not p1->is_on_demand())) p1->replicate(false);
217 for (auto& p2 : impl_p2_vector) if (p2 and (not p2->is_on_demand())) p2->replicate(false);
218 if (fence) world.gop.fence();
219 }
220
221 void make_redundant(const bool fence) {
222 // prepare base functions that make this function
223 for (auto& k : impl_ket_vector) if (k and (not k->is_on_demand())) k->change_tree_state(redundant,false);
224 if (impl_eri) {
225 if (not impl_eri->is_on_demand()) impl_eri->change_tree_state(redundant,false);
226 }
227 if (impl_m1 and (not impl_m1->is_on_demand())) impl_m1->change_tree_state(redundant,false);
228 if (impl_m2 and (not impl_m2->is_on_demand())) impl_m2->change_tree_state(redundant,false);
229
232// for (auto& k : impl_p1_vector) if (k and (not k->is_on_demand())) k->change_tree_state(redundant,false);
233// for (auto& k : impl_p2_vector) if (k and (not k->is_on_demand())) k->change_tree_state(redundant,false);
234// if (impl_p1 and (not impl_p1->is_on_demand())) impl_p1->change_tree_state(redundant,false);
235// if (impl_p2 and (not impl_p2->is_on_demand())) impl_p2->change_tree_state(redundant,false);
236 if (fence) world.gop.fence();
237 }
238
239 /// return true if all constituent functions are in redundant tree state
240 bool check_redundant() const {
241 for (auto& k : impl_ket_vector) if (k and (not k->is_redundant())) return false;
242// if (impl_ket and (not impl_ket->is_redundant())) return false;
243 if (impl_eri) MADNESS_ASSERT(impl_eri->is_on_demand());
244 if (impl_m1 and (not impl_m1->is_redundant())) return false;
245 if (impl_m2 and (not impl_m2->is_redundant())) return false;
246 for (auto& k : impl_p1_vector) if (k and (not k->is_redundant())) return false;
247 for (auto& k : impl_p2_vector) if (k and (not k->is_redundant())) return false;
248// if (impl_p1 and (not impl_p1->is_redundant())) return false;
249// if (impl_p2 and (not impl_p2->is_redundant())) return false;
250 return true;
251 }
252
253 /// return value at point x; fairly inefficient
254 T operator()(const coordT& x) const {
255 print("there is no operator()(coordT&) in CompositeFunctorInterface, for good reason");
257 return T(0);
258 };
259
260 bool provides_coeff() const {
261 return false;
262 }
263
264 };
265
266
267 /// ElementaryInterface (formerly FunctorInterfaceWrapper) interfaces a c-function
268
269 /// hard-code your favorite function and interface it with this; Does only
270 /// provide function values, no MRA coefficients. Care must be taken if the
271 /// function we refer to is a singular function, and a on-demand function
272 /// at the same time, since direct computation of coefficients via mraimpl::project
273 /// might suffer from inaccurate quadrature.
274 template<typename T, std::size_t NDIM>
276
277 public:
278 typedef Vector<double, NDIM> coordT; ///< Type of vector holding coordinates
280
282
283 T (*f)(const coordT&);
284
285 ElementaryInterface(T (*f)(const coordT&)) : f(f) {}
286
287 T operator()(const coordT& x) const {return f(x);}
288
289 coeffT values(const Key<NDIM>& key, const Tensor<double>& quad_x) const {
290 typedef Tensor<T> tensorT;
291 tensorT fval=madness::fcube(key,f,quad_x);
293 }
294 };
295
296 /// FunctorInterface interfaces a class or struct with an operator()()
297 template<typename T, std::size_t NDIM, typename opT>
299
300 public:
301 typedef Vector<double, NDIM> coordT; ///< Type of vector holding coordinates
303
305
306 opT op;
307
308 FunctorInterface(const opT& op) : op(op) {}
309
310 T operator()(const coordT& x) const {return op(x);}
311 };
312
313 /// FunctionInterface implements a wrapper around any class with the operator()()
314 template<typename T, size_t NDIM, typename opT>
316
318 typedef Vector<double, NDIM> coordT; ///< Type of vector holding coordinates
319
320 const opT op;
321
322 public:
323
325
326 FunctionInterface(const opT& op) : op(op) {}
327
328 T operator()(const coordT& coord) const {return op(coord);}
329
330 bool provides_coeff() const {return false;}
331
332 };
333
334 /// base class to compute the wavelet coefficients for an isotropic 2e-operator
335
336 /// all classes that derive from this base class use the Gaussian fitting
337 /// procedure that has been developed for the BSH operator. We simply
338 /// reuse the wavelet coefficients that we get from there to avoid
339 /// evaluating the functions themselves, since the quadrature of singular
340 /// functions is imprecise and slow.
341 template<typename T, std::size_t NDIM>
343 protected:
344 static constexpr std::size_t LDIM=NDIM/2;
345 public:
346
348
350
351 /// constructor: cf the Coulomb kernel
352
353 /// @param[in] lo the smallest length scale to be resolved
354 /// @param[in] eps the accuracy threshold
355 TwoElectronInterface(double lo, double eps,
358 :rank(), k(kk), lo(lo), hi(1.0) {
359
360 // Presently we must have periodic or non-periodic in all dimensions.
361 for (std::size_t d=1; d<NDIM; ++d) {MADNESS_ASSERT(bc(d,0)==bc(0,0));}
362
364 hi = width.normf(); // Diagonal width of cell
365 if (bc(0,0) == BC_PERIODIC) hi *= 100; // Extend range for periodic summation
366
367 }
368
369 bool provides_coeff() const {
370 return true;
371 }
372
373 /// return the coefficients of the function in 6D (x1,y1,z1, x2,y2,z2)
378
380 print("there is no operator()(coordT&) in TwoElectronInterface, for good reason");
382 return T(0);
383 }
384
385 protected:
386
387 /// make the coefficients from the 1d convolution
389 const Level n=key.level();
391
392 // get the displacements for all 3 dimensions: x12, y12, z12
394 if (NDIM==2) {
395 l0=l[0]-l[1];
396 } else if (NDIM==4) {
397 l0=(l[0]-l[2]);
398 l1=(l[1]-l[3]);
399 } else if (NDIM==6) {
400 l0=(l[0]-l[3]);
401 l1=(l[1]-l[4]);
402 l2=(l[2]-l[5]);
403 } else {
404 MADNESS_EXCEPTION("TwoElectronInterface: NDIM must be 2, 4, or 6",1);
405 }
406
408
409 // lump all the terms together
410 for (long mu=0; mu<rank; mu++) {
411 Tensor<double> r0, r1, r2;
412 if (NDIM>=2) r0=(ops[mu].getop(0)->rnlij(n,l0)).reshape(k*k);
413 if (NDIM>=4) r1=(ops[mu].getop(1)->rnlij(n,l1)).reshape(k*k);
414 if (NDIM>=6) r2=(ops[mu].getop(2)->rnlij(n,l2)).reshape(k*k);
415
416 // include weights in first vector
417 scr1(mu,Slice(_))=r0*ops[mu].getfac();
418
419 if (NDIM==2) {
420 ;
421 } else if (NDIM==4) {
422 scr3(mu,Slice(_))=r1;
423 } else if (NDIM==6) {
424 // merge second and third vector to scr(r,k1,k2)
425 scr2(mu,Slice(_),Slice(_))=outer(r1,r2);
426 } else {
427 MADNESS_EXCEPTION("TwoElectronInterface: NDIM must be 2, 4, or 6",1);
428 }
429 }
430
431 if (NDIM==2) {
432 // perform sum over the rank
433 Tensor<double> result(scr1.dim(1));
434 for (long mu=0; mu<rank; ++mu) result(_)+= scr1(mu,_);
435 return result;
436 }
437 else if (NDIM==4) return inner(scr1,scr3,0,0);
438 else if (NDIM==6) return inner(scr1,scr2,0,0);
439 else {
440 MADNESS_EXCEPTION("TwoElectronInterface: NDIM must be 2, 4, or 6",1);
441 return Tensor<double>();
442 }
443 }
444
445 /// the dimensions are a bit confused (x1,x2, y1,y2, z1,z2) -> (x1,y1,z1, x2,y2,z2)
447 std::vector<long> map(NDIM);
448 if (NDIM==2) {
449 map[0]=0; map[1]=1;
450 return copy(c.reshape(k,k));
451 } else if (NDIM==4) {
452 map[0]=0; map[1]=2;
453 map[2]=1; map[3]=3;
454 return copy(c.reshape(k,k,k,k).mapdim(map));
455 } else if (NDIM==6) {
456 map[0]=0; map[1]=3; map[2]=1;
457 map[3]=4; map[4]=2; map[5]=5;
458 return copy(c.reshape(k,k,k,k,k,k).mapdim(map));
459 }
460 return Tensor<double>();
461 }
462
463 /// initialize the Gaussian fit; uses the virtual function fit() to fit
464 void initialize(const double eps) {
465 GFit<double,LDIM> fit=this->fit(eps);
466 Tensor<double> coeff=fit.coeffs();
467 Tensor<double> expnt=fit.exponents();
468
469 // set some parameters
470 rank=coeff.dim(0);
471 ops.resize(rank);
473
474 // construct all the terms
475 for (int mu=0; mu<rank; ++mu) {
476 // double c = std::pow(sqrt(expnt(mu)/pi),static_cast<int>(NDIM)); // Normalization coeff
477 double c = std::pow(sqrt(expnt(mu)/constants::pi),LDIM); // Normalization coeff
478
479 // We cache the normalized operator so the factor is the value we must multiply
480 // by to recover the coeff we want.
481 ops[mu].setfac(coeff(mu)/c);
482
483 // only 3 dimensions here!
484 for (std::size_t d=0; d<LDIM; ++d) {
485 ops[mu].setop(d,GaussianConvolution1DCache<double>::get(k, expnt(mu)*width[d]*width[d], 0, LatticeRange(false)));
486 }
487 }
488 }
489
490 /// derived classes must implement this -- cf GFit.h
491 virtual GFit<double,LDIM> fit(const double eps) const = 0;
492
493 /// storing the coefficients
494 mutable std::vector< ConvolutionND<double,NDIM> > ops;
495
496 /// the number of terms in the Gaussian quadrature
497 int rank;
498
499 /// the wavelet order
500 int k;
501
502 /// the smallest length scale that needs to be represented
503 double lo;
504
505 /// the largest length scale that needs to be represented
506 double hi;
507
508 };
509
510
511 /// a function like f(x)=1/x
512 template<typename T, std::size_t NDIM>
514 public:
515
516 /// constructor: cf the Coulomb kernel
517
518 /// @param[in] lo the smallest length scale to be resolved
519 /// @param[in] eps the accuracy threshold
524
525 if (info.hi<0) {
527 if (bc(0,0) == BC_PERIODIC) hi *= 100; // Extend range for periodic summation
528 this->info.hi=hi;
529 }
530 this->initialize(info.thresh);
531 }
532
533 private:
535 static constexpr std::size_t LDIM=NDIM/2;
536
537 GFit<double,LDIM> fit(const double eps) const {
538 return GFit<double,LDIM>(info);
539 }
540 };
541
542 /// a function like f(x)=1/x
543 template<typename T, std::size_t NDIM>
545
546 public:
547
548 /// constructor: cf the Coulomb kernel
549
550 /// @param[in] lo the smallest length scale to be resolved
551 /// @param[in] eps the accuracy threshold
559
560 private:
561 static constexpr std::size_t LDIM=NDIM/2;
562
563 GFit<double,LDIM> fit(const double eps) const {
564 return GFit<double,LDIM>::CoulombFit(this->lo,this->hi,eps,false);
565 }
566 };
567
568 /// a function like f(x) = exp(-mu x)/x
570 public:
571
572 /// constructor: cf the Coulomb kernel
573
574 /// @param[in] mu the exponent of the BSH/inverse Laplacian
575 /// @param[in] lo the smallest length scale to be resolved
576 /// @param[in] eps the accuracy threshold
577 BSHFunctionInterface(double mu, double lo, double eps,
580 : TwoElectronInterface<double,6>(lo,eps,bc,kk), mu(mu) {
581
582 initialize(eps);
583 }
584
585 private:
586
587 double mu;
588
589 GFit<double,3> fit(const double eps) const {
590 return GFit<double,3>::BSHFit(mu,lo,hi,eps,false);
591 }
592 };
593
594 /// a function like f(x)=exp(-mu x)
596 public:
597
598 /// constructor: cf the Coulomb kernel
599
600 /// @param[in] mu the exponent of the Slater function
601 /// @param[in] lo the smallest length scale to be resolved
602 /// @param[in] eps the accuracy threshold
603 SlaterFunctionInterface(double mu, double lo, double eps,
606 : TwoElectronInterface<double,6>(lo,eps,bc,kk), mu(mu) {
607 initialize(eps);
608 }
609
610 private:
611
612 double mu;
613
614 GFit<double,3> fit(const double eps) const {
615 return GFit<double,3>::SlaterFit(mu,lo,hi,eps,false);
616 }
617 };
618
619 /// a function like f(x) = (1 - exp(-mu x))/(2 gamma)
620 class SlaterF12Interface : public TwoElectronInterface<double,6> {
621 public:
622
623 /// constructor: cf the Coulomb kernel
624
625 /// @param[in] mu the exponent of the Slater function
626 /// @param[in] lo the smallest length scale to be resolved
627 /// @param[in] eps the accuracy threshold
628 SlaterF12Interface(double mu, double lo, double eps,
631 : TwoElectronInterface<double,6>(lo,eps,bc,kk), mu(mu) {
632
633 initialize(eps);
634 }
635
636// /// overload the function of the base class
637// coeffT coeff(const Key<6>& key) const {
638//
639// Tensor<double> c=make_coeff(key);
640//
641// // subtract 1 from the (0,0,..,0) element of the tensor,
642// // which is the 0th order polynomial coefficient
643// double one_coeff1=1.0*sqrt(FunctionDefaults<6>::get_cell_volume())
644// *pow(0.5,0.5*6*key.level());
645// std::vector<long> v0(6,0L);
646// c(v0)-=one_coeff1;
647//
648// c.scale(-0.5/mu);
649// return coeffT(map_coeff(c),FunctionDefaults<6>::get_thresh(),TT_FULL);
650// }
651
652 private:
653
654 double mu;
655
656 GFit<double,3> fit(const double eps) const {
657 return GFit<double,3>::F12Fit(mu,lo,hi,eps,false);
658 }
659 };
660
661// Not right
662// /// a function like f(x) = (1 - exp(-mu x))/x
663// class FGInterface : public TwoElectronInterface<double,6> {
664// public:
665//
666// /// constructor: cf the Coulomb kernel
667//
668// /// @param[in] mu the exponent of the Slater function
669// /// @param[in] lo the smallest length scale to be resolved
670// /// @param[in] eps the accuracy threshold
671// FGInterface(double mu, double lo, double eps,
672// const BoundaryConditions<6>& bc=FunctionDefaults<6>::get_bc(),
673// int kk=FunctionDefaults<6>::get_k())
674// : TwoElectronInterface<double,6>(lo,eps,bc,kk), mu(mu) {
675//
676// initialize(eps);
677// }
678//
679// private:
680//
681// double mu;
682//
683// GFit<double,3> fit(const double eps) const {
684// return GFit<double,3>::SlaterFit(mu,lo,hi,eps,false);
685// }
686// };
687
688
689#if 0
690
691 /// ElectronRepulsionInterface implements the electron repulsion term 1/r12
692
693 /// this is essentially just a wrapper around ElectronRepulsion
694 template<typename T, std::size_t NDIM>
695 class ElectronRepulsionInterface : public FunctionFunctorInterface<T,NDIM> {
696
697 typedef GenTensor<T> coeffT;
698 typedef Vector<double, NDIM> coordT; ///< Type of vector holding coordinates
699
700 /// the class computing the coefficients
702
703 public:
704
705 /// constructor takes the same parameters as the Coulomb operator
706 /// which it uses to compute the coefficients
707 ElectronRepulsionInterface(World& world,double lo,double eps,
710 : eri(ElectronRepulsion(eps,eps,bc,k)) {
711 }
712
713
714 /// return value at point x; fairly inefficient
715 T operator()(const coordT& x) const {
716 print("there is no operator()(coordT&) in ElectronRepulsionInterface, for good reason");
718 return T(0);
719 };
720
721
722 /// return sum coefficients for imagined node at key
723 coeffT coeff(const Key<NDIM>& key) const {
724 return coeffT(this->eri.coeff(key),FunctionDefaults<NDIM>::get_thresh(),
725 TT_FULL);
726 }
727
728 };
729
730 /// FGIntegralInterface implements the two-electron integral (1-exp(-gamma*r12))/r12
731
732 /// this is essentially just a wrapper around ElectronRepulsion
733 /// The integral expressed as: 1/r12 - exp(-gamma*r12)/r12
734 /// which can be expressed with an eri and a bsh
735 template<typename T, std::size_t NDIM>
736 class FGIntegralInterface : public FunctionFunctorInterface<T,NDIM> {
737
738 typedef GenTensor<T> coeffT;
739 typedef Vector<double, NDIM> coordT; ///< Type of vector holding coordinates
740
741 /// the class computing the coefficients
744
745 public:
746
747 /// constructor takes the same parameters as the Coulomb operator
748 /// which it uses to compute the coefficients
749 FGIntegralInterface(World& world, double lo, double eps, double gamma,
752 : eri(ElectronRepulsion(eps,eps,0.0,bc,k))
753 , bsh(BSHFunction(eps,eps,gamma,bc,k)) {
754 }
755
756 bool provides_coeff() const {
757 return true;
758 }
759
760 /// return value at point x; fairly inefficient
761 T operator()(const coordT& x) const {
762 print("there is no operator()(coordT&) in FGIntegralInterface, for good reason");
764 return T(0);
765 };
766
767 /// return sum coefficients for imagined node at key
768 coeffT coeff(const Key<NDIM>& key) const {
769 typedef Tensor<T> tensorT;
770 tensorT e_b=eri.coeff(key)-bsh.coeff(key);
772 }
773
774 };
775
776#endif
777
778}
779
780#endif // MADNESS_MRA_FUNCTION_INTERFACE_H__INCLUDED
a function like f(x) = exp(-mu x)/x
Definition function_interface.h:569
GFit< double, 3 > fit(const double eps) const
derived classes must implement this – cf GFit.h
Definition function_interface.h:589
double mu
Definition function_interface.h:587
BSHFunctionInterface(double mu, double lo, double eps, const BoundaryConditions< 6 > &bc=FunctionDefaults< 6 >::get_bc(), int kk=FunctionDefaults< 6 >::get_k())
constructor: cf the Coulomb kernel
Definition function_interface.h:577
This class is used to specify boundary conditions for all operators.
Definition bc.h:72
CompositeFunctorInterface implements a wrapper of holding several functions and functors.
Definition function_interface.h:172
FunctionImpl< T, NDIM > implT
Definition function_interface.h:175
CompositeFunctorInterface(World &world, std::vector< pimplT > ket, pimplT g12, pimplL v1, pimplL v2, std::vector< pimplL > p1, std::vector< pimplL > p2)
constructor takes its Factory
Definition function_interface.h:198
std::vector< std::shared_ptr< implT > > impl_ket_vector
various MRA functions of NDIM dimensionality
Definition function_interface.h:184
std::shared_ptr< implT > pimplT
Definition function_interface.h:177
bool provides_coeff() const
does this functor directly provide sum coefficients? or only function values?
Definition function_interface.h:260
T operator()(const coordT &x) const
return value at point x; fairly inefficient
Definition function_interface.h:254
World & world
Definition function_interface.h:180
std::vector< std::shared_ptr< implL > > impl_p1_vector
supposedly orbital 1
Definition function_interface.h:190
std::shared_ptr< implL > pimplL
Definition function_interface.h:178
std::shared_ptr< implL > impl_m1
various MRA functions of MDIM dimensionality (e.g. 3, if NDIM==6)
Definition function_interface.h:188
FunctionImpl< T, MDIM > implL
Definition function_interface.h:176
std::shared_ptr< implT > impl_eri
supposedly 1/r12
Definition function_interface.h:185
std::shared_ptr< implL > impl_m2
supposedly 1/r2
Definition function_interface.h:189
void make_redundant(const bool fence)
Definition function_interface.h:221
bool check_redundant() const
return true if all constituent functions are in redundant tree state
Definition function_interface.h:240
std::vector< std::shared_ptr< implL > > impl_p2_vector
supposedly orbital 2
Definition function_interface.h:191
Vector< double, NDIM > coordT
Type of vector holding coordinates.
Definition function_interface.h:174
void replicate_low_dim_functions(const bool fence)
replicate low-dimensional functions over all ranks of this world
Definition function_interface.h:212
a function like f(x)=1/x
Definition function_interface.h:544
static constexpr std::size_t LDIM
Definition function_interface.h:561
GFit< double, LDIM > fit(const double eps) const
derived classes must implement this – cf GFit.h
Definition function_interface.h:563
ElectronRepulsionInterface(double lo, double eps, const BoundaryConditions< NDIM > &bc=FunctionDefaults< NDIM >::get_bc(), int kk=FunctionDefaults< NDIM >::get_k())
constructor: cf the Coulomb kernel
Definition function_interface.h:552
ElementaryInterface (formerly FunctorInterfaceWrapper) interfaces a c-function.
Definition function_interface.h:275
ElementaryInterface(T(*f)(const coordT &))
Definition function_interface.h:285
T operator()(const coordT &x) const
You should implement this to return f(x)
Definition function_interface.h:287
T(* f)(const coordT &)
Definition function_interface.h:283
coeffT values(const Key< NDIM > &key, const Tensor< double > &quad_x) const
Definition function_interface.h:289
GenTensor< T > coeffT
Definition function_interface.h:279
Vector< double, NDIM > coordT
Type of vector holding coordinates.
Definition function_interface.h:278
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:100
static int get_k()
Returns the default wavelet order.
Definition funcdefaults.h:164
static const double & get_thresh()
Returns the default threshold.
Definition funcdefaults.h:177
static const Tensor< double > & get_cell_width()
Returns the width of each user cell dimension.
Definition funcdefaults.h:381
static const BoundaryConditions< NDIM > & get_bc()
Returns the default boundary conditions.
Definition funcdefaults.h:311
Abstract base class interface required for functors used as input to Functions.
Definition function_interface.h:68
virtual ~FunctionFunctorInterface()
Definition function_interface.h:136
virtual bool provides_coeff() const
does this functor directly provide sum coefficients? or only function values?
Definition function_interface.h:149
virtual void operator()(const Vector< double *, 4 > &xvals, T *fvals, int npts) const
Definition function_interface.h:111
virtual bool supports_vectorized() const
Does the interface support a vectorized operator()?
Definition function_interface.h:92
GenTensor< T > coeffT
Definition function_interface.h:71
virtual coeffT coeff(const keyT &) const
Definition function_interface.h:138
virtual coeffT values(const keyT &key, const Tensor< double > &tensor) const
Definition function_interface.h:143
virtual bool screened(const Vector< double, NDIM > &c1, const Vector< double, NDIM > &c2) const
Can we screen this function based on the bounding box information?
Definition function_interface.h:87
T value_type
Definition function_interface.h:73
Level special_level_
Definition function_interface.h:75
void set_length_scale(double lo)
adapt the special level to resolve the smallest length scale
Definition function_interface.h:80
virtual void operator()(const Vector< double *, 2 > &xvals, T *fvals, int npts) const
Definition function_interface.h:103
virtual Level special_level() const
Override this to change the minimum level of refinement at special points (default is 6)
Definition function_interface.h:134
virtual void operator()(const Vector< double *, 5 > &xvals, T *fvals, int npts) const
Definition function_interface.h:115
virtual void operator()(const Vector< double *, 3 > &xvals, T *fvals, int npts) const
Definition function_interface.h:107
FunctionFunctorInterface()
Definition function_interface.h:77
Key< NDIM > keyT
Definition function_interface.h:72
virtual std::vector< Vector< double, NDIM > > special_points() const
Override this to return list of special points to be refined more deeply.
Definition function_interface.h:129
virtual void operator()(const Vector< double *, 6 > &xvals, T *fvals, int npts) const
Definition function_interface.h:119
FunctionImpl holds all Function state to facilitate shallow copy semantics.
Definition funcimpl.h:945
FunctionInterface implements a wrapper around any class with the operator()()
Definition function_interface.h:315
const opT op
Definition function_interface.h:320
bool provides_coeff() const
does this functor directly provide sum coefficients? or only function values?
Definition function_interface.h:330
Vector< double, NDIM > coordT
Type of vector holding coordinates.
Definition function_interface.h:318
GenTensor< T > coeffT
Definition function_interface.h:317
FunctionInterface(const opT &op)
Definition function_interface.h:326
T operator()(const coordT &coord) const
You should implement this to return f(x)
Definition function_interface.h:328
FunctorInterface interfaces a class or struct with an operator()()
Definition function_interface.h:298
GenTensor< T > coeffT
Definition function_interface.h:302
Vector< double, NDIM > coordT
Type of vector holding coordinates.
Definition function_interface.h:301
FunctorInterface(const opT &op)
Definition function_interface.h:308
opT op
Definition function_interface.h:306
T operator()(const coordT &x) const
You should implement this to return f(x)
Definition function_interface.h:310
Definition gfit.h:57
static GFit BSHFit(double mu, double lo, double hi, double eps, bool prnt=false)
return a fit for the bound-state Helmholtz function
Definition gfit.h:117
static GFit F12Fit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the F12 correlation factor
Definition gfit.h:183
static GFit SlaterFit(double gamma, double lo, double hi, double eps, bool prnt=false)
return a fit for the Slater function
Definition gfit.h:140
static GFit CoulombFit(double lo, double hi, double eps, bool prnt=false)
return a fit for the Coulomb function
Definition gfit.h:102
Definition lowranktensor.h:59
long dim(const int i) const
return the number of entries in dimension i
Definition lowranktensor.h:391
a function like f(x)=1/x
Definition function_interface.h:513
static constexpr std::size_t LDIM
Definition function_interface.h:535
GeneralTwoElectronInterface(OperatorInfo info, const BoundaryConditions< NDIM > &bc=FunctionDefaults< NDIM >::get_bc(), int kk=FunctionDefaults< NDIM >::get_k())
constructor: cf the Coulomb kernel
Definition function_interface.h:520
GFit< double, LDIM > fit(const double eps) const
derived classes must implement this – cf GFit.h
Definition function_interface.h:537
OperatorInfo info
Definition function_interface.h:534
Key is the index for a node of the 2^NDIM-tree.
Definition key.h:70
Level level() const
Definition key.h:169
const Vector< Translation, NDIM > & translation() const
Definition key.h:174
Denotes lattice summation over range [-N, N]; N=0 is equivalent to including the simulation cell only...
Definition kernelrange.h:17
a function like f(x) = (1 - exp(-mu x))/(2 gamma)
Definition function_interface.h:620
GFit< double, 3 > fit(const double eps) const
derived classes must implement this – cf GFit.h
Definition function_interface.h:656
double mu
Definition function_interface.h:654
SlaterF12Interface(double mu, double lo, double eps, const BoundaryConditions< 6 > &bc=FunctionDefaults< 6 >::get_bc(), int kk=FunctionDefaults< 6 >::get_k())
constructor: cf the Coulomb kernel
Definition function_interface.h:628
a function like f(x)=exp(-mu x)
Definition function_interface.h:595
GFit< double, 3 > fit(const double eps) const
derived classes must implement this – cf GFit.h
Definition function_interface.h:614
SlaterFunctionInterface(double mu, double lo, double eps, const BoundaryConditions< 6 > &bc=FunctionDefaults< 6 >::get_bc(), int kk=FunctionDefaults< 6 >::get_k())
constructor: cf the Coulomb kernel
Definition function_interface.h:603
double mu
Definition function_interface.h:612
A slice defines a sub-range or patch of a dimension.
Definition slice.h:103
A tensor is a multidimensional array.
Definition tensor.h:318
float_scalar_type normf() const
Returns the Frobenius norm of the tensor.
Definition tensor.h:1727
T max(long *ind=0) const
Return the maximum value (and if ind is non-null, its index) in the Tensor.
Definition tensor.h:1704
base class to compute the wavelet coefficients for an isotropic 2e-operator
Definition function_interface.h:342
double hi
the largest length scale that needs to be represented
Definition function_interface.h:506
coeffT coeff(const Key< NDIM > &key) const
return the coefficients of the function in 6D (x1,y1,z1, x2,y2,z2)
Definition function_interface.h:374
TwoElectronInterface(double lo, double eps, const BoundaryConditions< NDIM > &bc=FunctionDefaults< NDIM >::get_bc(), int kk=FunctionDefaults< NDIM >::get_k())
constructor: cf the Coulomb kernel
Definition function_interface.h:355
int rank
the number of terms in the Gaussian quadrature
Definition function_interface.h:497
T operator()(const Vector< double, NDIM > &x) const
You should implement this to return f(x)
Definition function_interface.h:379
Tensor< double > map_coeff(const Tensor< double > &c) const
the dimensions are a bit confused (x1,x2, y1,y2, z1,z2) -> (x1,y1,z1, x2,y2,z2)
Definition function_interface.h:446
std::vector< ConvolutionND< double, NDIM > > ops
storing the coefficients
Definition function_interface.h:494
Tensor< double > make_coeff(const Key< NDIM > &key) const
make the coefficients from the 1d convolution
Definition function_interface.h:388
bool provides_coeff() const
does this functor directly provide sum coefficients? or only function values?
Definition function_interface.h:369
virtual GFit< double, LDIM > fit(const double eps) const =0
derived classes must implement this – cf GFit.h
double lo
the smallest length scale that needs to be represented
Definition function_interface.h:503
static constexpr std::size_t LDIM
Definition function_interface.h:344
void initialize(const double eps)
initialize the Gaussian fit; uses the virtual function fit() to fit
Definition function_interface.h:464
int k
the wavelet order
Definition function_interface.h:500
GenTensor< T > coeffT
Definition function_interface.h:349
A simple, fixed dimension vector.
Definition vector.h:64
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition worldgop.cc:176
A parallel world class.
Definition world.h:132
WorldGopInterface & gop
Global operations.
Definition world.h:207
Computes most matrix elements over 1D operators (including Gaussians)
static double lo
Definition dirac-hatom.cc:23
fit isotropic functions to a set of Gaussians with controlled precision
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:28
Multidimension Key for MRA tree and associated iterators.
#define MADNESS_PRAGMA_CLANG(x)
Definition madness_config.h:200
#define MADNESS_PRAGMA_GCC(x)
Definition madness_config.h:205
#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
Vector< double, 3 > coordT
Definition mcpfit.cc:48
constexpr double pi
Mathematical constant .
Definition constants.h:48
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
@ BC_PERIODIC
Definition bc.h:52
Vector< double, 3 > coordT
Definition corepotential.cc:54
@ redundant
s coeffs everywhere
Definition funcdefaults.h:65
static double r2(const coord_3d &x)
Definition smooth.h:45
Tensor< double > tensorT
Definition distpm.cc:21
std::vector< Function< T, NDIM > > impl2function(const std::vector< std::shared_ptr< FunctionImpl< T, NDIM > > > vimpl)
Definition vmra.h:718
int64_t Translation
Definition key.h:58
static const Slice _(0,-1, 1)
int Level
Definition key.h:59
std::enable_if< std::is_base_of< ProjectorBase, projT >::value, OuterProjector< projT, projQ > >::type outer(const projT &p0, const projQ &p1)
Definition projector.h:457
static double pop(std::vector< double > &v)
Definition SCF.cc:115
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:226
Tensor< T > fcube(const Key< NDIM > &, T(*f)(const Vector< double, NDIM > &), const Tensor< double > &)
Definition mraimpl.h:2146
@ TT_FULL
Definition gentensor.h:120
NDIM & f
Definition mra.h:2603
const Function< T, NDIM > & change_tree_state(const Function< T, NDIM > &f, const TreeState finalstate, bool fence=true)
change tree state of a function
Definition mra.h:2929
double inner(response_space &a, response_space &b)
Definition response_functions.h:639
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition nonlinsol.h:371
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:2171
Definition mraimpl.h:51
const double mu
Definition navstokes_cosines.cc:95
static const double d
Definition nonlinschro.cc:121
static const double c
Definition relops.cc:10
static const double thresh
Definition rk.cc:45
static const long k
Definition rk.cc:44
Definition test_dc.cc:47
Definition convolution1d.h:989
Definition operatorinfo.h:58
double hi
Definition operatorinfo.h:67
double thresh
Definition operatorinfo.h:65
Defines and implements most of Tensor.
constexpr std::size_t NDIM
Definition testgconv.cc:54
const auto npts
Definition testgconv.cc:52