The following notebook presents a basic integration scheme that we’re going to use in the Spectral Element Code to calculate the entries of the mass and stiffness matrices.
Fundamental principal: Replace the function \(f(x)\) that we want to integrate by a polynomial approximation that can be integrated analytically.
As interpolating functions we use the Lagrange polynomials \(l_i\) and obtain the following integration scheme for an arbitrary function \(f(x)\) defined on the interval \([-1,1]\) : \[\begin{eqnarray*} \int_{-1}^1 f(x) \ dx \approx \int _{-1}^1 P_N(x) dx = \sum_{i=1}^{N+1} w_i f(x_i) \end{eqnarray*}\] with \[\begin{eqnarray*}
P_N(x)= \sum_{i=1}^{N+1} f(x_i) \ l_i^{(N)}(x).
\end{eqnarray*}\] As collocation points we use the Gauss-Lobatto-Legendre points \(x_i\) and the corresponding weights that are needed to evaluate the integral are calculated as follows: \[\begin{eqnarray*} w_i= \int_{-1}^1 l_i^{(N)}(x) \ dx \end{eqnarray*}\].
We want to investigate the performance of the numerical integration scheme. You can use the gll() routine to obtain the differentiation weights \(w_i\) for an arbitrary function f(x) and the relevant integration points \(x_i\).
1. Numerical integration of an arbritrary function:
Define a function \(f(x)\) of your choice and calculate analytically the integral \(\int f(x) \ dx\) for the interval \([−1, 1]\). Perform the integration numerically and compare the results.
2. The order of integration
Take a closer look and modify the function and the order of the numerical integration.
Code
# This is a configuration step for the exercise. Please run it before the simulation code!import numpy as npimport matplotlib# Show Plot in The Notebookmatplotlib.use("nbagg")import matplotlib.pyplot as pltfrom gll import gllfrom lagrange2 import lagrange2# Prettier plots.plt.style.use('ggplot')
Code
# Exercise for Gauss integrationn =1000x = np.linspace(-1, 1, n)# MODIFY f and intf to test different functions!#f = np.sin(x * np.pi) f = x + x * x + np.sin(x)# Analytical value of the DEFINITE integral from -1 to 1#intf = 1.0 / np.pi * (-np.cos(1.0 * np.pi) + np.cos(-1.0 * np.pi))intf =2./3.# Choose orderN =2# Get integration points and weights from the gll routinexi, w = gll(N)# Initialize function at points xifi = np.interp(xi, x, f)################################################# Evaluate integralintfn =0for i inrange(len(w)): intfn = intfn + w[i] * fi[i]################################################ # Calculate Lagrange Interpolant for plotting purposes.lp = np.zeros((N +1, len(x)))for i inrange(0, len(x)):for j inrange(-1, N): lp[j +1, i] = lagrange2(N, j, x[i], xi)s = np.zeros_like(x)for j inrange(0, N +1): s = s + lp[j, :] * fi[j]print('Solution of the analytical integral: %g'% intf)print('Solution of the numerical integral: %g'% intfn)# -------------------# Plot resultsplt.figure(figsize=(10, 6))plt.plot(x, f, 'k-', label='Analytical Function')plt.plot(xi, fi, 'bs', label='GLL points')plt.plot(x, s, label='Lagrange Interpolation')plt.fill_between(x, s, np.zeros_like(x), alpha=0.3)plt.xlabel('x')plt.ylabel('y')plt.title('Numerical vs. Analytical Function')plt.legend()plt.show()
Solution of the analytical integral: 0.666667
Solution of the numerical integral: 0.666668