MADNESS  version 0.9
derivative.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 
32  $Id: mraimpl.h 1602 2009-12-27 19:53:06Z rjharrison $
33 */
34 
35 #ifndef MADNESS_DERIVATIVE_H__INCLUDED
36 #define MADNESS_DERIVATIVE_H__INCLUDED
37 
38 #include <iostream>
39 #include <madness/world/world.h>
40 #include <madness/world/worlddc.h>
41 #include <madness/world/print.h>
42 #include <madness/misc/misc.h>
43 
44 #include <madness/tensor/tensor.h>
46 
47 #include <madness/mra/key.h>
49 
50 
54 
55 namespace madness {
56 
57  template<typename T, std::size_t NDIM>
58  class FunctionNode;
59 
60  template<typename T, std::size_t NDIM>
61  class Function;
62 
63 }
64 
65 
66 
67 namespace madness {
68 
70 
72  template <typename T, std::size_t NDIM>
73  class DerivativeBase : public WorldObject< DerivativeBase<T, NDIM> > {
75  protected:
77  const std::size_t axis ; // Axis along which the operation is performed
78  const int k ; // Number of wavelets of the function
80  const std::vector<long> vk;
81 
82  public:
83  friend class FunctionImpl<T, NDIM>;
84 
85  typedef Tensor<T> tensorT ; //< regular tensors, like rm, etc
86  typedef GenTensor<T> coeffT ; //< holding the node's coeffs (possibly low rank)
87  typedef Key<NDIM> keyT ;
88  typedef std::pair<keyT,coeffT> argT ;
93 
94 
95  DerivativeBase(World& world, std::size_t axis, int k, BoundaryConditions<NDIM> bc)
96  : WorldObject< DerivativeBase<T, NDIM> >(world)
97  , world(world)
98  , axis(axis)
99  , k(k)
100  , bc(bc)
101  , vk(NDIM,k)
102  {
103  // No! Cannot process incoming messages until the *derived* class is constructed.
104  // this->process_pending();
105  }
106 
107  virtual ~DerivativeBase() { }
108 
109  Void forward_do_diff1(const implT* f, implT* df, const keyT& key,
110  const argT& left,
111  const argT& center,
112  const argT& right) const {
113 
114  const dcT& coeffs = f->get_coeffs();
115  ProcessID owner = coeffs.owner(key);
116 
117  if (owner == world.rank()) {
118  if (!left.second.has_data()) {
120  f, df, key, find_neighbor(f, key,-1), center, right,
122  }
123  else if (!right.second.has_data()) {
125  f, df, key, left, center, find_neighbor(f, key,1),
127  }
128  // Boundary node
129  else if (left.first.is_invalid() || right.first.is_invalid()) {
131  f, df, key, left, center, right);
132  }
133  // Interior node
134  else {
136  f, df, key, left, center, right);
137  }
138  }
139  else {
141  this, f, key, left, center, right, TaskAttributes::hipri());
142  }
143  return None;
144  }
145 
146  Void do_diff1(const implT* f, implT* df, const keyT& key,
147  const argT& left,
148  const argT& center,
149  const argT& right) const {
150  MADNESS_ASSERT(axis<NDIM);
151 
152 // if (left.second.size()==0 || right.second.size()==0) {
153  if ((!left.second.has_data()) || (!right.second.has_data())) {
154  // One of the neighbors is below us in the tree ... recur down
155  df->get_coeffs().replace(key,nodeT(coeffT(),true));
156  for (KeyChildIterator<NDIM> kit(key); kit; ++kit) {
157  const keyT& child = kit.key();
158  if ((child.translation()[axis]&1) == 0) {
159  // leftmost child automatically has right sibling
160  forward_do_diff1(f, df, child, left, center, center);
161  }
162  else {
163  // rightmost child automatically has left sibling
164  forward_do_diff1(f, df, child, center, center, right);
165  }
166  }
167  }
168  else {
169  forward_do_diff1(f, df, key, left, center, right);
170  }
171  return None;
172  }
173 
174  virtual Void do_diff2b(const implT* f, implT* df, const keyT& key,
175  const argT& left,
176  const argT& center,
177  const argT& right) const = 0;
178 
179  virtual Void do_diff2i(const implT* f, implT* df, const keyT& key,
180  const argT& left,
181  const argT& center,
182  const argT& right) const = 0;
183 
184 
186 
189  operator()(const functionT& f, bool fence=true) const {
190  if (VERIFY_TREE) f.verify_tree();
191 
192  if (f.is_compressed()) {
193  if (fence) {
194  f.reconstruct();
195  }
196  else {
197  MADNESS_EXCEPTION("diff: trying to diff a compressed function without fencing",0);
198  }
199  }
200 
201  functionT df;
202  df.set_impl(f,false);
203 
204  df.get_impl()->diff(this, f.get_impl().get(), fence);
205  return df;
206  }
207 
208 
209  static bool enforce_bc(int bc_left, int bc_right, Level n, Translation& l) {
210  Translation two2n = 1ul << n;
211  if (l < 0) {
212  if (bc_left == BC_ZERO || bc_left == BC_FREE || bc_left == BC_DIRICHLET || bc_left == BC_ZERONEUMANN || bc_left == BC_NEUMANN) {
213  return false; // f=0 BC, or no BC, or nonzero f BC, or zero deriv BC, or nonzero deriv BC
214  }
215  else if (bc_left == BC_PERIODIC) {
216  l += two2n; // Periodic BC
217  MADNESS_ASSERT(bc_left == bc_right); //check that both BCs are periodic
218  }
219  else {
220  MADNESS_EXCEPTION("enforce_bc: confused left BC?",bc_left);
221  }
222  }
223  else if (l >= two2n) {
224  if (bc_right == BC_ZERO || bc_right == BC_FREE || bc_right == BC_DIRICHLET || bc_right == BC_ZERONEUMANN || bc_right == BC_NEUMANN) {
225  return false; // f=0 BC, or no BC, or nonzero f BC, or zero deriv BC, or nonzero deriv BC
226  }
227  else if (bc_right == BC_PERIODIC) {
228  l -= two2n; // Periodic BC
229  MADNESS_ASSERT(bc_left == bc_right); //check that both BCs are periodic
230  }
231  else {
232  MADNESS_EXCEPTION("enforce_bc: confused BC right?",bc_right);
233  }
234  }
235  return true;
236  }
237 
238  Key<NDIM> neighbor(const keyT& key, int step) const {
240  l[axis] += step;
241  if (!enforce_bc(bc(axis,0), bc(axis,1), key.level(), l[axis])) {
242  return keyT::invalid();
243  }
244  else {
245  return keyT(key.level(),l);
246  }
247  }
248 
250  find_neighbor(const implT* f, const Key<NDIM>& key, int step) const {
251  keyT neigh = neighbor(key, step);
252  if (neigh.is_invalid()) {
253  return Future<argT>(argT(neigh,coeffT(vk,f->get_tensor_args()))); // Zero bc
254  }
255  else {
256  Future<argT> result;
257  f->task(f->get_coeffs().owner(neigh), &implT::sock_it_to_me, neigh, result.remote_ref(world), TaskAttributes::hipri());
258  return result;
259  }
260  }
261 
262 
263  template <typename Archive> void serialize(const Archive& ar) const {
264  throw "NOT IMPLEMENTED";
265  }
266 
267  }; // End of the DerivativeBase class
268 
269 
271  template <typename T, std::size_t NDIM>
272  class Derivative : public DerivativeBase<T, NDIM> {
273  private:
275 
276  public:
277  typedef Tensor<T> tensorT ;
278  typedef GenTensor<T> coeffT ; //< holding the node's coeffs (possibly low rank)
279  typedef Key<NDIM> keyT ;
280  typedef std::pair<keyT,coeffT> argT ;
285 
286  private:
287  const functionT g1;
288  const functionT g2;
289 
290  // Tensors for holding the modified coefficients
291  Tensor<double> rm, r0, rp ;
292  Tensor<double> rmt, r0t, rpt ;
293  Tensor<double> left_rm, left_r0 ;
294  Tensor<double> left_rmt, left_r0t ;
295  Tensor<double> right_r0, right_rp;
296  Tensor<double> right_r0t, right_rpt;
297  Tensor<double> bv_left, bv_right ;
298 
299  Void do_diff2b(const implT* f, implT* df, const keyT& key,
300  const argT& left,
301  const argT& center,
302  const argT& right) const {
304  double lev = (double) key.level();
305 
306  coeffT d;
307 
308  //left boundary
309  if (l[this->axis] == 0) {
310 
311  coeffT tensor_right=df->parent_to_child(right.second, right.first, this->neighbor(key,1));
312  coeffT tensor_center=df->parent_to_child(center.second, center.first, key);
313 
314  d= transform_dir(tensor_right,left_rmt,this->axis);
315  d+=transform_dir(tensor_center,left_r0t,this->axis);
316  }
317  else {
318 
319  coeffT tensor_left=df->parent_to_child(left.second, left.first, this->neighbor(key,-1));
320  coeffT tensor_center=df->parent_to_child(center.second, center.first, key);
321 
322  d= transform_dir(tensor_left,right_rpt,this->axis);
323  d+=transform_dir(tensor_center,right_r0t,this->axis);
324  }
325 
326  d.scale(FunctionDefaults<NDIM>::get_rcell_width()[this->axis]*pow(2.0,lev));
327  d.reduce_rank(df->get_thresh());
328  df->get_coeffs().replace(key,nodeT(d,false));
329 
330 
331  // This is the boundary contribution (formally in BoundaryDerivative)
332  int bc_left = this->bc(this->axis,0);
333  int bc_right = this->bc(this->axis,1);
334 
335  Future<argT> found_argT;
336  tensorT bf, bdry_t;
337  //left boundary
338  if (l[this->axis] == 0) {
339  if (bc_left != BC_PERIODIC && bc_left != BC_FREE && bc_left != BC_ZERO && bc_left != BC_ZERONEUMANN) {
340  bf = copy(bv_left);
341  found_argT = g1.get_impl()->find_me(key);
342  }
343  else {
344  return None;
345  }
346  }
347  else { //right boundary
348  if (bc_right != BC_PERIODIC && bc_right != BC_FREE && bc_right != BC_ZERO && bc_right != BC_ZERONEUMANN) {
349  bf = copy(bv_right);
350  found_argT = g2.get_impl()->find_me(key);
351  }
352  else {
353  return None;
354  }
355  }
356  tensorT gcoeffs = df->parent_to_child(found_argT.get().second, found_argT.get().first,key).full_tensor_copy();
357 
358  //if (this->bc.get_bc().dim(0) == 1) {
359  if (NDIM == 1) {
360  bdry_t = gcoeffs[0]*bf;
361  }
362  else {
363  tensorT slice_aid(this->k); //vector of zeros
364  slice_aid[0] = 1;
365  tensorT tmp = inner(slice_aid, gcoeffs, 0, this->axis);
366  bdry_t = outer(bf,tmp);
367  if (this->axis) bdry_t = copy(bdry_t.cycledim(this->axis,0,this->axis)); // make it contiguous
368  }
369  bdry_t.scale(FunctionDefaults<NDIM>::get_rcell_width()[this->axis]);
370 
371  if (l[this->axis]==0) {
372  if (bc_left == BC_DIRICHLET)
373  bdry_t.scale( pow(2.0,lev));
374  else if (bc_left ==BC_NEUMANN)
375  bdry_t.scale(FunctionDefaults<NDIM>::get_cell_width()[this->axis]);
376  }
377  else {
378  if (bc_right == BC_DIRICHLET)
379  bdry_t.scale( pow(2.0,lev));
380  else if (bc_right ==BC_NEUMANN)
381  bdry_t.scale(FunctionDefaults<NDIM>::get_cell_width()[this->axis]);
382  }
383 
384  bdry_t += d.full_tensor_copy();;
385  df->get_coeffs().replace(key,nodeT(coeffT(bdry_t,df->get_thresh(),df->get_tensor_type()),false));
386 
387  return None;
388  }
389 
390  Void do_diff2i(const implT* f, implT*df, const keyT& key,
391  const argT& left,
392  const argT& center,
393  const argT& right) const
394  {
395 //#if !HAVE_GENTENSOR
396 // coeffT d = madness::inner(rp,
397 // df->parent_to_child(left.second, left.first, baseT::neighbor(key,-1)).swapdim(this->axis,0),
398 // 1, 0);
399 // inner_result(r0,
400 // df->parent_to_child(center.second, center.first, key).swapdim(this->axis,0),
401 // 1, 0, d);
402 // inner_result(rm,
403 // df->parent_to_child(right.second, right.first, baseT::neighbor(key,1)).swapdim(this->axis,0),
404 // 1, 0, d);
405 // // flo thinks this is wrong for higher dimensions -- need to cycledim
406 // if (this->axis) d = copy(d.swapdim(this->axis,0)); // make it contiguous
407 // d.scale(FunctionDefaults<NDIM>::get_rcell_width()[this->axis]*pow(2.0,(double) key.level()));
408 // df->get_coeffs().replace(key,nodeT(d,false));
409 // return None;
410 //
411 //#else
412  coeffT tensor_left=df->parent_to_child(left.second, left.first, this->neighbor(key,-1));
413  coeffT tensor_center=df->parent_to_child(center.second, center.first, key);
414  coeffT tensor_right=df->parent_to_child(right.second, right.first, this->neighbor(key,1));
415 
416  coeffT d= transform_dir(tensor_left,rpt,this->axis);
417  d+=transform_dir(tensor_center,r0t,this->axis);
418  d+=transform_dir(tensor_right,rmt,this->axis);
419 
420  d.scale(FunctionDefaults<NDIM>::get_rcell_width()[this->axis]*pow(2.0,(double) key.level()));
421  d.reduce_rank(df->get_thresh());
422  df->get_coeffs().replace(key,nodeT(d,false));
423 
424  return None;
425 
426 //#endif
427 
428  }
429 
430  void initCoefficients() {
431  r0 = Tensor<double>(this->k,this->k);
432  rp = Tensor<double>(this->k,this->k);
433  rm = Tensor<double>(this->k,this->k);
434 
435  left_rm = Tensor<double>(this->k,this->k);
436  left_r0 = Tensor<double>(this->k,this->k);
437 
438  right_r0 = Tensor<double>(this->k,this->k);
439  right_rp = Tensor<double>(this->k,this->k);
440 
441  // These are the coefficients for the boundary contribution
442  bv_left = Tensor<double>(this->k);
443  bv_right = Tensor<double>(this->k);
444 
445 
446  int bc_left = this->bc(this->axis,0);
447  int bc_right = this->bc(this->axis,1);
448 
449  double kphase = -1.0;
450  if (this->k%2 == 0) kphase = 1.0;
451  double iphase = 1.0;
452  for (int i=0; i<this->k; ++i) {
453  double jphase = 1.0;
454  for (int j=0; j<this->k; ++j) {
455  double gammaij = sqrt(double((2*i+1)*(2*j+1)));
456  double Kij;
457  if (((i-j)>0) && (((i-j)%2)==1))
458  Kij = 2.0;
459  else
460  Kij = 0.0;
461 
462  r0(i,j) = 0.5*(1.0 - iphase*jphase - 2.0*Kij)*gammaij;
463  rm(i,j) = 0.5*jphase*gammaij;
464  rp(i,j) =-0.5*iphase*gammaij;
465 
466  // Constraints on the derivative
467  if (bc_left == BC_ZERONEUMANN || bc_left == BC_NEUMANN) {
468  left_rm(i,j) = jphase*gammaij*0.5*(1.0 + iphase*kphase/this->k);
469 
470  double phi_tmpj_left = 0;
471 
472  for (int l=0; l<this->k; ++l) {
473  double gammalj = sqrt(double((2*l+1)*(2*j+1)));
474  double Klj;
475 
476  if (((l-j)>0) && (((l-j)%2)==1)) Klj = 2.0;
477  else Klj = 0.0;
478 
479  phi_tmpj_left += sqrt(double(2*l+1))*Klj*gammalj;
480  }
481  phi_tmpj_left = -jphase*phi_tmpj_left;
482  left_r0(i,j) = (0.5*(1.0 + iphase*kphase/this->k) - Kij)*gammaij + iphase*sqrt(double(2*i+1))*phi_tmpj_left/pow(this->k,2.);
483  }
484  else if (bc_left == BC_ZERO || bc_left == BC_DIRICHLET || bc_left == BC_FREE) {
485  left_rm(i,j) = rm(i,j);
486 
487  // B.C. with a function
488  if (bc_left == BC_ZERO || bc_left == BC_DIRICHLET)
489  left_r0(i,j) = (0.5 - Kij)*gammaij;
490 
491  // No B.C.
492  else if (bc_left == BC_FREE)
493  left_r0(i,j) = (0.5 - iphase*jphase - Kij)*gammaij;
494  }
495 
496  // Constraints on the derivative
497  if (bc_right == BC_ZERONEUMANN || bc_right == BC_NEUMANN) {
498  right_rp(i,j) = -0.5*(iphase + kphase / this->k)*gammaij;
499 
500  double phi_tmpj_right = 0;
501  for (int l=0; l<this->k; ++l) {
502  double gammalj = sqrt(double((2*l+1)*(2*j+1)));
503  double Klj;
504  if (((l-j)>0) && (((l-j)%2)==1)) Klj = 2.0;
505  else Klj = 0.0;
506  phi_tmpj_right += sqrt(double(2*l+1))*Klj*gammalj;
507  }
508  right_r0(i,j) = -(0.5*jphase*(iphase+ kphase/this->k) + Kij)*gammaij + sqrt(double(2*i+1))*phi_tmpj_right/pow(this->k,2.);
509  }
510  else if (bc_right == BC_ZERO || bc_right == BC_FREE || bc_right == BC_DIRICHLET) {
511  right_rp(i,j) = rp(i,j);
512 
513  // Zero BC
514  if (bc_right == BC_ZERO || bc_right == BC_DIRICHLET)
515  right_r0(i,j) = -(0.5*iphase*jphase + Kij)*gammaij;
516 
517  // No BC
518  else if (bc_right == BC_FREE)
519  right_r0(i,j) = (1.0 - 0.5*iphase*jphase - Kij)*gammaij;
520 
521  }
522 
523  jphase = -jphase;
524  }
525  iphase = -iphase;
526  }
527 
528  // Coefficients for the boundary contributions
529  iphase = 1.0;
530  for (int i=0; i<this->k; ++i) {
531  iphase = -iphase;
532 
533  if (bc_left == BC_DIRICHLET)
534  bv_left(i) = iphase*sqrt(double(2*i+1)); // vector for left dirichlet BC
535  else if(bc_left == BC_NEUMANN)
536  bv_left(i) = -iphase*sqrt(double(2*i+1))/pow(this->k,2.); // vector for left deriv BC
537  else
538  bv_left(i) = 0.0;
539 
540  if (bc_right == BC_DIRICHLET)
541  bv_right(i) = sqrt(double(2*i+1)); // vector for right dirichlet BC
542  else if (bc_right == BC_NEUMANN)
543  bv_right(i) = sqrt(double(2*i+1))/pow(this->k,2.); // vector for right deriv BC
544  else
545  bv_right(i) = 0.0;
546  }
547 
548  r0t = transpose(r0);
549  rpt = transpose(rp);
550  rmt = transpose(rm);
551 
552  right_r0t = transpose(right_r0);
553  right_rpt = transpose(right_rp);
554 
555  left_rmt = transpose(left_rm);
556  left_r0t = transpose(left_r0);
557 
558 
559  //print(rm.normf(),r0.normf(),rp.normf(),left_rm.normf(),left_r0.normf(),right_r0.normf(),right_rp.normf(),bv_left.normf(),bv_right.normf());
560  }
561 
562  public:
563  typedef T opT;
564 
566 
574  std::size_t axis,
576  const functionT g1=functionT(),
577  const functionT g2=functionT(),
579  : DerivativeBase<T, NDIM>(world, axis, k, bc)
580  , g1(g1)
581  , g2(g2)
582  {
583  MADNESS_ASSERT(axis<NDIM);
584  initCoefficients();
585  g1.reconstruct();
586  g2.reconstruct();
587 
588  this->process_pending();
589  }
590 
591  virtual ~Derivative() { }
592  };
593 
594 
596  template <typename T, std::size_t NDIM>
597  Derivative<T,NDIM>
600  }
601 
602 
604  template <typename T, std::size_t NDIM>
605  Derivative<T,NDIM>
608  }
609 
611  template <typename T, std::size_t NDIM>
612  Function<T,NDIM>
613  apply(const Derivative<T,NDIM>& D, const Function<T,NDIM>& f, bool fence=true) {
614  return D(f,fence);
615  }
616 
618 
622  template <typename T, std::size_t NDIM>
623  std::vector< std::shared_ptr< Derivative<T,NDIM> > >
626  int k = FunctionDefaults<NDIM>::get_k()) {
627  std::vector< std::shared_ptr< Derivative<T,NDIM> > > r(NDIM);
628  for (std::size_t d=0; d<NDIM; ++d) {
629  MADNESS_ASSERT(bc(d,0)!=BC_DIRICHLET && bc(d,1)!=BC_DIRICHLET);
630  MADNESS_ASSERT(bc(d,0)!=BC_NEUMANN && bc(d,1)!=BC_NEUMANN);
631  r[d].reset(new Derivative<T,NDIM>(world,d,bc,Function<T,NDIM>(),Function<T,NDIM>(),k));
632  }
633  return r;
634  }
635 
636 
637  namespace archive {
638  template <class Archive, class T, std::size_t NDIM>
639  struct ArchiveLoadImpl<Archive,const DerivativeBase<T,NDIM>*> {
640  static void load(const Archive& ar, const DerivativeBase<T,NDIM>*& ptr) {
642  ar & p;
643  ptr = static_cast< const DerivativeBase<T,NDIM>* >(p);
644  }
645  };
646 
647  template <class Archive, class T, std::size_t NDIM>
648  struct ArchiveStoreImpl<Archive,const DerivativeBase<T,NDIM>*> {
649  static void store(const Archive& ar, const DerivativeBase<T,NDIM>* const & ptr) {
650  ar & ptr->id();
651  }
652  };
653  }
654 
655 } // End of the madness namespace
656 
657 #endif // MADNESS_MRA_DERIVATIVE_H_INCLUDED
void process_pending()
To be called from derived constructor to process pending messages.
Definition: worldobj.h:330
Makes a distributed container with specified attributes.
Definition: worlddc.h:55
virtual ~DerivativeBase()
Definition: derivative.h:107
Future< argT > find_neighbor(const implT *f, const Key< NDIM > &key, int step) const
Definition: derivative.h:250
GenTensor< T > full_tensor_copy() const
Definition: gentensor.h:184
double get_thresh() const
Definition: mraimpl.h:281
static TaskAttributes hipri()
Definition: worldthread.h:277
Header to declare stuff which has not yet found a home.
FunctionDefaults holds default paramaters as static class members.
Definition: funcdefaults.h:175
FunctionImpl< T, NDIM > implT
Definition: derivative.h:89
std::pair< keyT, coeffT > argT
Definition: derivative.h:280
const Vector< Translation, NDIM > & translation() const
Definition: key.h:225
const mpreal pow(const mpreal &a, const unsigned int b, mp_rnd_t rnd_mode=mpreal::default_rnd)
Definition: mpreal.h:2788
const int NDIM
Definition: tdse1.cc:44
Function< T, NDIM > functionT
Definition: derivative.h:282
DerivativeBase(World &world, std::size_t axis, int k, BoundaryConditions< NDIM > bc)
Definition: derivative.h:95
Implements derivatives operators with variety of boundary conditions on simulation domain...
Definition: derivative.h:272
virtual Void do_diff2i(const implT *f, implT *df, const keyT &key, const argT &left, const argT &center, const argT &right) const =0
const std::shared_ptr< FunctionImpl< T, NDIM > > & get_impl() const
Returns a shared-pointer to the implementation.
Definition: mra.h:589
Function< T, NDIM > operator()(const functionT &f, bool fence=true) const
Differentiate w.r.t. given coordinate (x=0, y=1, ...) with optional fence.
Definition: derivative.h:189
GenTensor< T > outer(const GenTensor< T > &left, const GenTensor< T > &right)
Outer product ... result(i,j,...,p,q,...) = left(i,k,...)*right(p,q,...)
Definition: gentensor.h:230
Provides a tensor with taking advantage of possibly low rank.
static bool enforce_bc(int bc_left, int bc_right, Level n, Translation &l)
Definition: derivative.h:209
virtual Void do_diff2b(const implT *f, implT *df, const keyT &key, const argT &left, const argT &center, const argT &right) const =0
Void do_diff1(const implT *f, implT *df, const keyT &key, const argT &left, const argT &center, const argT &right) const
Definition: derivative.h:146
WorldContainer< Key< NDIM >, FunctionNode< T, NDIM > > dcT
Definition: derivative.h:91
Derivative< T, NDIM > free_space_derivative(World &world, int axis, int k=FunctionDefaults< NDIM >::get_k())
Convenience function returning derivative operator with free-space boundary conditions.
Definition: derivative.h:598
const uniqueidT & id() const
Returns the globally unique object ID.
Definition: worldobj.h:377
NDIM & f
Definition: mra.h:2179
void verify_tree() const
Verifies the tree data structure ... global sync implied.
Definition: mra.h:452
Definition: funcdefaults.h:56
Provides FunctionDefaults and utilities for coordinate transformation.
Default store of a thingy via serialize(ar,t)
Definition: archive.h:708
const coeffT parent_to_child(const coeffT &s, const keyT &parent, const keyT &child) const
Directly project parent coeffs to child coeffs.
Definition: mraimpl.h:2983
FunctionImpl holds all Function state to facilitate shallow copy semantics.
Definition: funcdefaults.h:48
This header should include pretty much everything needed for the parallel runtime.
bool is_invalid() const
Checks if a key is invalid.
Definition: key.h:152
T inner(const vecfunc< T, NDIM > &a, const vecfunc< T, NDIM > &b)
the non-linear solver requires an inner product
Definition: nemo.h:112
Defines and implements most of Tensor.
TensorType get_tensor_type() const
Definition: mraimpl.h:275
FunctionImpl< T, NDIM > implT
Definition: derivative.h:281
FunctionNode< T, NDIM > nodeT
Definition: derivative.h:284
static void store(const Archive &ar, const DerivativeBase< T, NDIM > *const &ptr)
Definition: derivative.h:649
Void sock_it_to_me(const keyT &key, const RemoteReference< FutureImpl< std::pair< keyT, coeffT > > > &ref) const
Walk up the tree returning pair(key,node) for first node with coefficients.
Definition: mraimpl.h:2678
GenTensor< T > coeffT
Definition: derivative.h:278
T & get()
Gets the value, waiting if necessary (error if not a local future)
Definition: worldfut.h:513
const T1 &f1 return GTEST_2_TUPLE_() T(f0, f1)
Key< NDIM > neighbor(const keyT &key, int step) const
Definition: derivative.h:238
void reconstruct(bool fence=true) const
Reconstructs the function, transforming into scaling function basis. Possible non-blocking comm...
Definition: mra.h:737
Void forward_do_diff1(const implT *f, implT *df, const keyT &key, const argT &left, const argT &center, const argT &right) const
Definition: derivative.h:109
Key< NDIM > keyT
Definition: derivative.h:87
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)(a1,a2,a3,a4,a5,a6,a7,a8,a9)".
Definition: worldobj.h:493
GenTensor< T > coeffT
Definition: derivative.h:86
static Key< NDIM > invalid()
Returns an invalid key.
Definition: key.h:146
const BoundaryConditions< NDIM > bc
Definition: derivative.h:79
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:1835
Tensor< TENSOR_RESULT_TYPE(T, Q)> transform_dir(const Tensor< T > &t, const Tensor< Q > &c, int axis)
Transforms one dimension of the tensor t by the matrix c, returns new contiguous tensor.
Definition: tensor.h:1929
Tensor< T > tensorT
Definition: derivative.h:277
void replace(const pairT &datum)
Inserts/replaces key+value pair (non-blocking communication if key not local)
Definition: worlddc.h:727
This class is used to specify boundary conditions for all operatorsExterior boundary conditions (i...
Definition: funcdefaults.h:72
Level level() const
Definition: key.h:220
void reduce_rank(const double &eps)
Definition: gentensor.h:193
Default load of a thingy via serialize(ar,t)
Definition: archive.h:718
const int k
Definition: derivative.h:78
Function< T, NDIM > functionT
Definition: derivative.h:90
Implements most parts of a globally addressable object (via unique ID)
Definition: worldam.h:74
tensorT sqrt(const tensorT &s, double tol=1e-8)
Computes matrix square root (not used any more?)
Definition: DFcode/moldft.cc:446
Definition: funcdefaults.h:56
A parallel world with full functionality wrapping an MPI communicator.
Definition: worldfwd.h:416
Tensor< T > tensorT
Definition: derivative.h:85
A multiresolution adaptive numerical function.
Definition: derivative.h:61
int Level
Definition: key.h:58
static void load(const Archive &ar, const DerivativeBase< T, NDIM > *&ptr)
Definition: derivative.h:640
Derivative(World &world, std::size_t axis, const BoundaryConditions< NDIM > &bc=FunctionDefaults< NDIM >::get_bc(), const functionT g1=functionT(), const functionT g2=functionT(), int k=FunctionDefaults< NDIM >::get_k())
Constructs a derivative operator.
Definition: derivative.h:573
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:37
const std::size_t axis
Definition: derivative.h:77
void serialize(const Archive &ar) const
Definition: derivative.h:263
T opT
Definition: derivative.h:563
FunctionNode holds the coefficients, etc., at each node of the 2^NDIM-tree.
Definition: derivative.h:58
Tri-diagonal operator traversing tree primarily for derivative operator.
Definition: derivative.h:73
ProcessID rank() const
Returns the process rank in this world (same as MPI_Comm_rank()))
Definition: worldfwd.h:526
ProcessID owner(const keyT &key) const
Returns processor that logically owns key (no communication)
Definition: worlddc.h:786
virtual ~Derivative()
Definition: derivative.h:591
void set_impl(const std::shared_ptr< FunctionImpl< T, NDIM > > &impl)
Replace current FunctionImpl with provided new one.
Definition: mra.h:596
FunctionNode< T, NDIM > nodeT
Definition: derivative.h:92
World & world
Definition: derivative.h:76
remote_refT remote_ref(World &world) const
Returns a structure used to pass references to another process.
Definition: worldfut.h:552
Derivative< T, NDIM > periodic_derivative(World &world, int axis, int k=FunctionDefaults< NDIM >::get_k())
Conveinence function returning derivative operator with periodic boundary conditions.
Definition: derivative.h:606
Key< NDIM > keyT
Definition: derivative.h:279
WorldContainer< Key< NDIM >, FunctionNode< T, NDIM > > dcT
Definition: derivative.h:283
Implements WorldContainer.
Definition: funcdefaults.h:56
A future is a possibly yet unevaluated value.
Definition: ref.h:210
A type you can return when you want to return void ... use "return None".
Definition: typestuff.h:154
Definition: funcdefaults.h:56
Tensor< T > transpose(const Tensor< T > &t)
Returns a new deep copy of the transpose of the input tensor.
Definition: tensor.h:1945
Definition: funcdefaults.h:56
#define MADNESS_EXCEPTION(msg, value)
Definition: worldexc.h:88
Multidimension Key for MRA tree and associated iterators.
Definition: gentensor.h:123
std::vector< std::shared_ptr< Derivative< T, NDIM > > > gradient_operator(World &world, const BoundaryConditions< NDIM > &bc=FunctionDefaults< NDIM >::get_bc(), int k=FunctionDefaults< NDIM >::get_k())
Convenience function returning vector of derivative operators implementing grad ( ) ...
Definition: derivative.h:624
int64_t Translation
Definition: key.h:57
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
const dcT & get_coeffs() const
Definition: mraimpl.h:296
Function< T, NDIM > apply(const Derivative< T, NDIM > &D, const Function< T, NDIM > &f, bool fence=true)
Applies derivative operator to function (for syntactic equivalence to integral operator apply) ...
Definition: derivative.h:613
Definition: funcdefaults.h:56
const std::vector< long > vk
(k,...) used to initialize Tensors
Definition: derivative.h:80
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:69
TensorArgs get_tensor_args() const
Definition: mraimpl.h:278
bool is_compressed() const
Returns true if compressed, false otherwise. No communication.
Definition: mra.h:461
std::pair< keyT, coeffT > argT
Definition: derivative.h:88
Iterates in lexical order thru all children of a key.
Definition: key.h:61