MADNESS  version 0.9
function_factory.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$
32 */
33 
34 
35 #ifndef MADNESS_MRA_FUNCTION_FACTORY_H__INCLUDED
36 #define MADNESS_MRA_FUNCTION_FACTORY_H__INCLUDED
37 
38 #include <madness/tensor/tensor.h>
40 #include <madness/mra/key.h>
42 
43 
45 
53 namespace madness {
54 
55  // needed for the CompositeFactory
56  template<typename T, std::size_t NDIM>
57  class FunctionImpl;
58 
59  template<typename T, std::size_t NDIM>
60  class Function;
61 
62  template<typename T, std::size_t NDIM>
63  Tensor<T> fcube(const Key<NDIM>&, T (*f)(const Vector<double,NDIM>&), const Tensor<double>&);
64 
66 
78  template<typename T, std::size_t NDIM>
79  class FunctionFactory {
80  friend class FunctionImpl<T, NDIM> ;
82  protected:
84  int _k;
85  double _thresh;
89  bool _refine;
90  bool _empty;
93  bool _fence;
95  //Tensor<int> _bc;
97 
98  private:
99  // need to keep this private, access only via get_functor();
100  // reason is that the functor must only be constructed when the actual
101  // FuncImpl is constructed, otherwise we might depend on the ordering
102  // of the chaining (specifically, if the functor is constructed before
103  // of after the threshold is changed)
105 
106  public:
107 
109  _world(world),
110  _k(FunctionDefaults<NDIM>::get_k()),
111  _thresh(FunctionDefaults<NDIM>::get_thresh()),
112  _initial_level(
113  FunctionDefaults<NDIM>::get_initial_level()),
114  _max_refine_level(
115  FunctionDefaults<NDIM>::get_max_refine_level()),
116  _truncate_mode(
117  FunctionDefaults<NDIM>::get_truncate_mode()),
118  _refine(FunctionDefaults<NDIM>::get_refine()),
119  _empty(false),
120  _autorefine(FunctionDefaults<NDIM>::get_autorefine()),
121  _truncate_on_project(
122  FunctionDefaults<NDIM>::get_truncate_on_project()),
123  _fence(true), // _bc(FunctionDefaults<NDIM>::get_bc()),
124  _is_on_demand(false),
125  _pmap(FunctionDefaults<NDIM>::get_pmap()), _functor() {
126  }
127  virtual ~FunctionFactory() {};
131  _functor = f;
132  return self();
133  }
134  template<typename opT>
136  functor2(const opT& op) {
139  return self();
140  }
141 
144  _functor.reset();
145  return self();
146  }
148  f(T
149  (*f)(const coordT&)) {
152  return self();
153  }
154 
155  virtual FunctionFactory& k(int k) {
156  _k = k;
157  return self();
158  }
159 
160  virtual FunctionFactory& thresh(double thresh) {
161  _thresh = thresh;
162  return self();
163  }
164 
167  _initial_level = initial_level;
168  return self();
169  }
170 
173  _max_refine_level = max_refine_level;
174  return self();
175  }
178  _truncate_mode = truncate_mode;
179  return self();
180  }
182  refine(bool refine = true) {
183  _refine = refine;
184  return self();
185  }
187  norefine(bool norefine = true) {
188  _refine = !norefine;
189  return self();
190  }
192  empty() {
193  _empty = true;
194  return self();
195  }
198  _autorefine = true;
199  return self();
200  }
203  _autorefine = false;
204  return self();
205  }
208  _truncate_on_project = true;
209  return self();
210  }
213  _truncate_on_project = false;
214  return self();
215  }
217  fence(bool fence = true) {
218  _fence = fence;
219  return self();
220  }
223  _fence = false;
224  return self();
225  }
226  virtual FunctionFactory&
228  _is_on_demand = true;
229  return self();
230  }
233  _pmap = pmap;
234  return self();
235  }
236 
237  int get_k() const {return _k;};
238  double get_thresh() const {return _thresh;};
239  World& get_world() const {return _world;};
240 
243  return _functor;
244  }
245 
247  FunctionFactory& self() {return *this;}
248 
249  };
250 
251 
253 
263  template<typename T, std::size_t NDIM, std::size_t MDIM>
264  class CompositeFactory : public FunctionFactory<T, NDIM> {
265  public:
272 
273  private:
275 
276  friend class CompositeFunctorInterface<T, NDIM, MDIM>;
277 
278  public:
279 
281  : FunctionFactory<T,NDIM>(world)
282  , _ket()
283  , _g12()
284  , _v1()
285  , _v2()
286  , _particle1()
287  , _particle2()
288  , _func() {
289 
290  // there are certain defaults that make only sense here
291  this->_is_on_demand=true;
292  }
293 
296 // ket(const std::shared_ptr<FunctionImpl<T, NDIM> >& f) {
298  _ket = f.get_impl();
299  return self();
300  }
301 
305  _g12 = f.get_impl();
306  return self();
307  }
308 
312  _v1 = f.get_impl();
313  return self();
314  }
315 
319  _v2 = f.get_impl();
320  return self();
321  }
322 
327  _particle1 = f.get_impl();
328  return self();
329  }
330 
335  _particle2 = f.get_impl();
336  return self();
337  }
338 
339  // access to the functor *only* via this
341 
342  // return if we already have a valid functor
343  if (this->_func) return this->_func;
344 
345  // construction of the functor is const in spirit, but non-const in sad reality..
346  // this Factory not only constructs the Function, but also the functor, so
347  // pass *this to the interface
348  const_cast< std::shared_ptr<CompositeFunctorInterface<T, NDIM, MDIM> >& >(this->_func)=
351  this->_world,_ket,_g12,_v1,_v2,_particle1,_particle2
352  ));
353 
354  return this->_func;
355  }
356 
357  CompositeFactory& self() {return *this;}
358  };
359 
361  class TwoElectronFactory : public FunctionFactory<double,6> {
362 
363  protected:
365 
366  public:
368  : FunctionFactory<double,6>(world)
369  , type_(coulomb_)
370  , interface_()
372  , gamma_(-1.0)
373  , bc_(FunctionDefaults<6>::get_bc()) {
374  _is_on_demand=true;
375  this->_thresh=(FunctionDefaults<3>::get_thresh());
376  this->_k=(FunctionDefaults<3>::get_k());
377 
378  }
379 
382  dcut_=dcut;
383  return self();
384  }
385 
388  _thresh=thresh;
389  return self();
390  }
391 
394  gamma_=g;
395  return self();
396  }
397 
400  type_=f12_;
401  return self();
402  }
403 
406  type_=slater_;
407  return self();
408  }
409 
410  // access to the functor *only* via this
411  InterfacePtr get_functor() const {
412 
413  // return if we already have a valid interface
414  if (this->interface_) return this->interface_;
415 
416  // construction of the functor is const in spirit, but non-const in sad reality..
417  if (type_==coulomb_) {
418  const_cast<InterfacePtr& >(this->interface_)=
420  dcut_,_thresh,bc_,_k));
421  } else if (type_==f12_) {
422  // make sure gamma is set
423  MADNESS_ASSERT(gamma_>0);
424  const_cast<InterfacePtr& >(this->interface_)=
426  gamma_,dcut_,_thresh,bc_,_k));
427  } else if (type_==slater_) {
428  // make sure gamma is set
429  MADNESS_ASSERT(gamma_>0);
430  const_cast<InterfacePtr& >(this->interface_)=
432  gamma_,dcut_,_thresh,bc_,_k));
433  } else {
434  MADNESS_EXCEPTION("unimplemented integral kernel",1);
435  }
436  return this->interface_;
437  }
438 
439  TwoElectronFactory& self() {return *this;}
440 
441  protected:
442 
444 
446 
448  InterfacePtr interface_;
449 
450  double dcut_;
451 
452  double gamma_;
453 
455 
456  };
457 
458 #if 0
459  class ERIFactory : public TwoElectronFactory<ERIFactory> {
460  public:
461  ERIFactory(World& world) : TwoElectronFactory<ERIFactory>(world) {}
462 
463  // access to the functor *only* via this
464  InterfacePtr get_functor() const {
465 
466  // return if we already have a valid interface
467  if (this->interface_) return this->interface_;
468 
469  // construction of the functor is const in spirit, but non-const in sad reality..
470  const_cast<InterfacePtr& >(this->interface_)=
471  InterfacePtr(new ElectronRepulsionInterface(
472  dcut_,thresh_,bc_,k_));
473  return this->interface_;
474  }
475 
476  ERIFactory& self() {return *this;}
477 
478  };
479 
481  class SlaterFunctionFactory : public TwoElectronFactory<SlaterFunctionFacto> {
482  public:
483  SlaterFunctionFactory(World& world)
484  : TwoElectronFactory(world), gamma_(-1.0), f12_(false) {}
485 
487  SlaterFunctionFactory& gamma(double gamma) {
488  this->gamma_ = gamma;
489  return self();
490  }
491 
493  SlaterFunctionFactory& f12() {
494  this->f12_=true;
495  return self();
496  }
497 
498  // access to the functor *only* via this
499  InterfacePtr get_functor() const {
500 
501  // return if we already have a valid interface
502  if (this->interface_) return this->interface_;
503 
504  // make sure gamma is set
505  MADNESS_ASSERT(gamma_>0);
506 
507  // construction of the functor is const in spirit, but non-const in sad reality..
508  if (f12_) {
509  const_cast<InterfacePtr& >(this->interface_)=
510  InterfacePtr(new SlaterF12Interface(
511  gamma_,dcut_,this->_thresh,bc_,this->_k));
512  } else {
513  const_cast<InterfacePtr& >(this->interface_)=
514  InterfacePtr(new SlaterFunctionInterface(
515  gamma_,dcut_,this->_thresh,bc_,this->_k));
516  }
517  return this->interface_;
518  }
519 
520  SlaterFunctionFactory& self() {return *this;}
521 
522  private:
523 
524  double gamma_;
525  bool f12_;
526  };
527 
529  template<typename T, std::size_t NDIM>
530  class ERIFactory : public FunctionFactory<T, NDIM> {
531 
532  private:
534 
535  public:
536 
538  double _dcut;
539  BoundaryConditions<NDIM> _bc;
540 
541  public:
542  ERIFactory(World& world)
543  : FunctionFactory<T,NDIM>(world)
544  , _eri()
545  , _dcut(FunctionDefaults<NDIM>::get_thresh())
546  , _bc(FunctionDefaults<NDIM>::get_bc())
547  {
548  this->_is_on_demand=true;
549  MADNESS_ASSERT(NDIM==6);
550  }
551 
552  ERIFactory&
553  thresh(double thresh) {
554  this->_thresh = thresh;
555  return *this;
556  }
557 
558  ERIFactory&
559  dcut(double dcut) {
560  this->_dcut = dcut;
561  return *this;
562  }
563 
564  // access to the functor *only* via this
566 
567  // return if we already have a valid eri
568  if (this->_eri) return this->_eri;
569 
570 // if (this->_world.rank()==0) print("set dcut in ERIFactory to ", _dcut);
571 
572  // construction of the functor is const in spirit, but non-const in sad reality..
573  const_cast< std::shared_ptr<ElectronRepulsionInterface>& >(this->_eri)=
575  new ElectronRepulsionInterface(_dcut,this->_thresh,
576  _bc,this->_k));
577 
578  return this->_eri;
579  }
580 
581  };
582 #endif
583 
585  template<typename T, std::size_t NDIM>
586  class FGFactory : public FunctionFactory<T, NDIM> {
587 
588  private:
590 
591  public:
592 
594  double _dcut;
595  double _gamma;
597 
598  public:
599  FGFactory(World& world, double gamma)
600  : FunctionFactory<T,NDIM>(world)
601  , _fg()
602  , _dcut(FunctionDefaults<NDIM>::get_thresh())
603  , _gamma(gamma)
604  , _bc(FunctionDefaults<NDIM>::get_bc())
605  {
606  this->_is_on_demand=true;
607  MADNESS_ASSERT(NDIM==6);
608  }
609 
610  FGFactory&
611  thresh(double thresh) {
612  this->_thresh = thresh;
613  return *this;
614  }
615 
616  FGFactory&
617  dcut(double dcut) {
618  this->_dcut = dcut;
619  return *this;
620  }
621 
622  // access to the functor *only* via this
624 
625  // return if we already have a valid eri
626  if (this->_fg) return this->_fg;
627 
628 // if (this->_world.rank()==0) print("set dcut in ERIFactory to ", _dcut);
629 
630  // construction of the functor is const in spirit, but non-const in sad reality..
631  const_cast< std::shared_ptr<FGInterface>& >(this->_fg)=
633  new FGInterface(this->_world,_dcut,this->_thresh,
634  _gamma,_bc,this->_k));
635 
636  return this->_fg;
637  }
638 
639  };
640 
641 }
642 
643 #endif // MADNESS_MRA_FUNCTION_FACTORY_H__INCLUDED
std::shared_ptr< FunctionImpl< T, MDIM > > _particle1
supposedly particle 1
Definition: function_factory.h:270
const double thresh
Definition: dielectric.cc:185
std::shared_ptr< FunctionFunctorInterface< T, NDIM > > get_functor() const
return the functor; override this if the functor needs deferred construction
Definition: function_factory.h:623
std::shared_ptr< FunctionImpl< T, MDIM > > _particle2
supposedly particle 2
Definition: function_factory.h:271
a function like f(x)=exp(-mu x)
Definition: function_interface.h:446
CompositeFactory & V_for_particle2(const Function< T, MDIM > &f)
a one-particle potential, acting on particle 2
Definition: function_factory.h:318
factory for generating TwoElectronInterfaces
Definition: function_factory.h:361
virtual std::shared_ptr< FunctionFunctorInterface< T, NDIM > > get_functor() const
return the functor; override this if the functor needs deferred construction
Definition: function_factory.h:242
Definition: shared_ptr_bits.h:38
FunctionFactory & max_refine_level(int max_refine_level)
Definition: function_factory.h:172
NDIM const Function< R, NDIM > & g
Definition: mra.h:2179
CompositeFactory & ket(const Function< T, NDIM > &f)
provide directly the NDIM (6D) pair function ket
Definition: function_factory.h:297
FunctionFactory & functor2(const opT &op)
Definition: function_factory.h:136
virtual FunctionFactory & k(int k)
Definition: function_factory.h:155
FunctionDefaults holds default paramaters as static class members.
Definition: funcdefaults.h:175
CompositeFactory & V_for_particle1(const Function< T, MDIM > &f)
a one-particle potential, acting on particle 1
Definition: function_factory.h:311
bool _fence
Definition: function_factory.h:93
const int NDIM
Definition: tdse1.cc:44
Factory to set up an ElectronRepulsion Function.
Definition: function_factory.h:586
operatortype
Definition: function_factory.h:443
CompositeFactory & particle1(const Function< T, MDIM > &f)
Definition: function_factory.h:326
TwoElectronFactory(World &world)
Definition: function_factory.h:367
int _k
Definition: function_factory.h:84
const std::shared_ptr< FunctionImpl< T, NDIM > > & get_impl() const
Returns a shared-pointer to the implementation.
Definition: mra.h:589
Definition: function_factory.h:443
Provides a tensor with taking advantage of possibly low rank.
FunctionFactory & initial_level(int initial_level)
Definition: function_factory.h:166
FunctionInterface implements a wrapper around any class with the operator()()
Definition: function_interface.h:243
double get_thresh() const
Definition: function_factory.h:238
a function like f(x) = (1 - exp(-mu x))/x
Definition: function_interface.h:516
BoundaryConditions< NDIM > _bc
Definition: function_factory.h:596
double gamma_
Definition: function_factory.h:452
NDIM & f
Definition: mra.h:2179
FunctionFactory & nofence()
Definition: function_factory.h:222
TwoElectronFactory & dcut(double dcut)
the smallest length scale to be represented (aka lo)
Definition: function_factory.h:381
static const double & get_thresh()
Returns the default threshold.
Definition: funcdefaults.h:225
Tensor< T > fcube(const Key< NDIM > &, T(*f)(const Vector< double, NDIM > &), const Tensor< double > &)
Definition: mraimpl.h:2047
Vector< double, 3 > coordT
Definition: chem/corepotential.cc:57
BoundaryConditions< 6 > bc_
Definition: function_factory.h:454
FunctionFactory & norefine(bool norefine=true)
Definition: function_factory.h:187
virtual FunctionFactory & thresh(double thresh)
Definition: function_factory.h:160
double _dcut
cutoff radius for 1/r12, aka regularization
Definition: function_factory.h:594
std::shared_ptr< FunctionImpl< T, MDIM > > _v1
supposedly a potential for particle 1
Definition: function_factory.h:268
FunctionImpl holds all Function state to facilitate shallow copy semantics.
Definition: funcdefaults.h:48
std::shared_ptr< FunctionImpl< T, MDIM > > _v2
supposedly a potential for particle 2
Definition: function_factory.h:269
FunctionFactory & refine(bool refine=true)
Definition: function_factory.h:182
FunctionFactory & noautorefine()
Definition: function_factory.h:202
std::shared_ptr< FunctionImpl< T, NDIM > > _g12
supposedly a interaction potential
Definition: function_factory.h:267
FunctionFactory & autorefine()
Definition: function_factory.h:197
Defines and implements most of Tensor.
FunctionFactory & fence(bool fence=true)
Definition: function_factory.h:217
int get_k() const
Definition: function_factory.h:237
CompositeFunctorInterface implements a wrapper of holding several functions and functors.
Definition: funcimpl.h:73
FGFactory & thresh(double thresh)
Definition: function_factory.h:611
FunctionFactory & empty()
Definition: function_factory.h:192
double _gamma
Definition: function_factory.h:595
Factory for facile setup of a CompositeFunctorInterface and its FuncImpl.
Definition: function_factory.h:264
TwoElectronFactory & slater()
return the operator (1 - exp(-gamma x) / (2 gamma)
Definition: function_factory.h:405
CompositeFactory & particle2(const Function< T, MDIM > &f)
Definition: function_factory.h:334
double dcut_
cutoff radius for 1/r12, aka regularization
Definition: function_factory.h:450
const T1 &f1 return GTEST_2_TUPLE_() T(f0, f1)
TwoElectronFactory & gamma(double g)
the exponent of a slater function
Definition: function_factory.h:393
FGFactory & dcut(double dcut)
Definition: function_factory.h:617
World & _world
Definition: function_factory.h:83
static int get_k()
Returns the default wavelet order.
Definition: funcdefaults.h:212
virtual ~FunctionFactory()
Definition: function_factory.h:127
FunctionFactory & functor(const std::shared_ptr< FunctionFunctorInterface< T, NDIM > > &f)
Definition: function_factory.h:129
FunctionFactory & notruncate_on_project()
Definition: function_factory.h:212
std::shared_ptr< FunctionFunctorInterface< T, NDIM > > get_functor() const
return the functor; override this if the functor needs deferred construction
Definition: function_factory.h:340
FunctionFactory & truncate_mode(int truncate_mode)
Definition: function_factory.h:177
TwoElectronFactory & thresh(double thresh)
the requested precision
Definition: function_factory.h:387
std::shared_ptr< FunctionImpl< T, NDIM > > _ket
supposedly a 6D pair function ket
Definition: function_factory.h:266
bool _autorefine
Definition: function_factory.h:91
bool _empty
Definition: function_factory.h:90
bool _truncate_on_project
Definition: function_factory.h:92
Definition: function_factory.h:443
a function like f(x) = (1 - exp(-mu x))/(2 gamma)
Definition: function_interface.h:473
int _max_refine_level
Definition: function_factory.h:87
FunctionFactory & truncate_on_project()
Definition: function_factory.h:207
ElementaryInterface (formerly FunctorInterfaceWrapper) interfaces a c-function.
Definition: function_interface.h:207
a function like f(x)=1/x
Definition: function_interface.h:394
bool _is_on_demand
Definition: function_factory.h:94
A parallel world with full functionality wrapping an MPI communicator.
Definition: worldfwd.h:416
const mpreal gamma(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2429
A multiresolution adaptive numerical function.
Definition: derivative.h:61
FunctionFactory & pmap(const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap)
Definition: function_factory.h:232
operatortype type_
Definition: function_factory.h:445
Definition: function_factory.h:443
InterfacePtr get_functor() const
return the functor; override this if the functor needs deferred construction
Definition: function_factory.h:411
Abstract base class interface required for functors used as input to Functions.
Definition: function_interface.h:58
std::shared_ptr< FunctionFunctorInterface< double, 6 > > InterfacePtr
Definition: function_factory.h:364
TwoElectronFactory & f12()
return the operator (1 - exp(-gamma x) / (2 gamma)
Definition: function_factory.h:399
int _initial_level
Definition: function_factory.h:86
void reset()
Definition: shared_ptr_bits.h:459
FunctionFactory & f(T(*f)(const coordT &))
Definition: function_factory.h:148
Definition: function_factory.h:443
World & get_world() const
Definition: function_factory.h:239
CompositeFactory & g12(const Function< T, NDIM > &f)
g12 is the interaction potential (6D)
Definition: function_factory.h:304
virtual FunctionFactory & is_on_demand()
Definition: function_factory.h:227
int _truncate_mode
Definition: function_factory.h:88
Tensor< double > op(const Tensor< double > &x)
Definition: kain.cc:508
Interface to be provided by any process map.
Definition: worlddc.h:64
#define MADNESS_EXCEPTION(msg, value)
Definition: worldexc.h:88
std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > _pmap
Definition: function_factory.h:96
InterfacePtr interface_
the interface providing the actual coefficients
Definition: function_factory.h:448
FunctionFactory(World &world)
Definition: function_factory.h:108
Multidimension Key for MRA tree and associated iterators.
CompositeFactory(World &world)
Definition: function_factory.h:280
FunctionFactory implements the named-parameter idiom for Function.
Definition: funcimpl.h:70
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
FGFactory(World &world, double gamma)
Definition: function_factory.h:599
bool _refine
Definition: function_factory.h:89
double _thresh
Definition: function_factory.h:85
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:69
FunctionFactory & no_functor()
Definition: function_factory.h:143
Definition: function_factory.h:443