Flow123d  master-49d9643
adaptivesimpson.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file adaptivesimpson.cc
15  * @brief
16  */
17 
18 #include "adaptivesimpson.hh"
19 #include "functors_impl.hh"
20 
21 #include <math.h>
22 
23 double AdaptiveSimpson::Simpson(const double& h, const double &fa,
24  const double &fc, const double &fb)
25 {
26  return (fa + fb + 4.0*fc)*(h/6.0);
27 }
28 
30  const double& h, const double &a,
31  const double &c, const double &b,
32  const double &fa, const double &fc,
33  const double &fb, const double &sx,
34  const double &tol, long &recursion)
35 {
36  recursion++;
37  double ca = 0.5*(a+c);
38  double cb = 0.5*(c+b);
39  double fca = func(ca);
40  double fcb = func(cb);
41 
42  double h2 = 0.5*h;
43  double sa = Simpson(h2,fa,fca,fc);
44  double sb = Simpson(h2,fc,fcb,fb);
45 
46  double err_est = (sa+sb-sx)/15.0;
47  if (fabs(err_est) <= tol || recursion >= MAX_RECURSION)
48  {
49  return sa+sb+err_est;
50  }
51  else
52  {
53  //DebugOut().fmt("simpsonad, recursion: {} \t {}\n", recursion, err_est);
54  //std::cout << "simpsonad -else " << recursion << std::endl;
55  //std::cout << h2 << " " << a << " " << ca << " " << c << " " << fa << " " << fca << " " << fc << " " << sa << std::endl;
56  return SimpsonAd(func,h2,a,ca,c,fa,fca,fc,sa,tol,recursion)
57  + SimpsonAd(func,h2,c,cb,b,fc,fcb,fb,sb,tol,recursion);
58  }
59 }
60 
62  const double& a, const double& b,
63  const double& tol )
64 {
65  //DebugOut().fmt("AdaptiveSimpson: a({}) b({})\n",a,b);
66  double c = 0.5*(b+a);
67  double fa,fb,fc;
68  double sx,res;
69  fa = func(a);
70  fb = func(b);
71  fc = func(c);
72  long recursion = 0;
73  //DebugOut().fmt("fa={} \tfb={} \tfc={}\n",fa,fb,fc);
74  sx = Simpson(b-a, fa, fc, fb);
75  res = SimpsonAd(func,b-a,a,c,b,fa,fc,fb,sx,tol,recursion);
76  //DebugOut().fmt("\trecursions: {}\n",recursion);
77  return res;
78 }
79 
80 
81 
82 
#define MAX_RECURSION
static double SimpsonAd(FunctorBase< double > &func, const double &h, const double &a, const double &c, const double &b, const double &fa, const double &fc, const double &fb, const double &sx, const double &tol, long &recursion)
the recursive method
static double AdaptSimpson(FunctorBase< double > &func, const double &a, const double &b, const double &tol)
main method that starts the evaluation and calls the recursion
static double Simpson(const double &h, const double &fa, const double &fc, const double &fb)
Evaluates the Simpson's rule.