PLUTO
math_quadrature.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Collection of handy numerical math tools.
5 
6  This file provides a number of standard numerical routines
7  to achieve simple basic tasks such as
8 
9  - LU decomposition functions;
10  - Numerical quadrature;
11  - Ordinary differential equation solver;
12 
13  \author A. Mignone (mignone@ph.unito.it)
14  \date March 28, 2013
15 */
16 /* ///////////////////////////////////////////////////////////////////// */
17 #include "pluto.h"
18 
19 /* ********************************************************************* */
20 double GaussQuadrature(double (*func)(double), double xb, double xe,
21  int nstep, int order)
22 /*!
23  * Perform numerical quadrature of the function f(x) between
24  * the lower bound xb and upper bound xe by subdividing the interval
25  * into 'nstep' steps.
26  * A 3 or 5-point Gaussian quadrature rule is used depending on the
27  * input variable order (=3 or =5)
28  *
29  * \param [in] *func a pointer to the function func(x) (returning double)
30  * to be integrated
31  * \param [in] xb the lower interval bound
32  * \param [in] xe the upper interval bound
33  * \param [in] nstep the number of sub-intervals into which the
34  * original interval [xb,xe] has to be divided
35  * \param [in] order the number of Gaussian points (only 3 or 5)
36  *
37  *********************************************************************** */
38 {
39  int i, n;
40  double w[8], z[8], x;
41  double I, Isub;
42  double xb0, xe0, dx;
43 
44  if (order == 3){
45  double s3 = sqrt(3.0/5.0);
46 
47  z[0] = -s3; w[0] = 5.0/9.0;
48  z[1] = 0.0; w[1] = 8.0/9.0;
49  z[2] = s3; w[2] = 5.0/9.0;
50  }else if (order == 5){
51  double s1, s7;
52 
53  s1 = sqrt(10.0/7.0);
54  s7 = sqrt(70.0);
55  z[0] = -1.0/3.0*sqrt(5.0 - 2.0*s1); w[0] = (322.0 + 13.0*s7)/900.0;
56  z[1] = -z[0]; w[1] = w[0];
57 
58  z[2] = -1.0/3.0*sqrt(5.0 + 2.0*s1); w[2] = (322.0 - 13.0*s7)/900.0;
59  z[3] = -z[2]; w[3] = w[2];
60 
61  z[4] = 0.0; w[4] = 128.0/225.0;
62  }else{
63  print ("! GaussQuadrature: order must be either 3 or 5\n");
64  QUIT_PLUTO(1);
65  }
66 
67  if (nstep <= 0){
68  print ("! GaussQuadrature: nstep must be > 0\n");
69  QUIT_PLUTO(1);
70  }
71 
72  xb0 = xb; xe0 = xe; /* save original interval endpoints */
73  dx = (xe - xb)/(double)nstep; /* sub-interval length */
74  I = 0.0;
75  for (i = 0; i < nstep; i++){
76  xb = xb0 + i*dx;
77  xe = xb + dx;
78 
79  Isub = 0.0; /* intgrate sub-interval */
80  for (n = 0; n < order; n++){
81  x = 0.5*(xe - xb)*z[n] + (xe + xb)*0.5;
82  Isub += w[n]*func(x);
83  }
84  Isub *= 0.5*(xe - xb);
85  I += Isub;
86  }
87 
88  return I;
89 }
90 
static int n
Definition: analysis.c:3
double GaussQuadrature(double(*func)(double), double xb, double xe, int nstep, int order)
void print(const char *fmt,...)
Definition: amrPluto.cpp:497
PLUTO main header file.
int i
Definition: analysis.c:2
#define QUIT_PLUTO(e_code)
Definition: macros.h:125