You are on page 1of 5

W2_P2-1

September 30, 2020

<div style="font-size: xx-large ; font-weight: 900 ; color: rgba(0 , 0 , 0 , 0.8) ; lin


<div style="font-size: large ; padding-top: 20px ; color: rgba(0 , 0 , 0 , 0.5)">Finite
</div>
</div>

This exercise covers the following aspects:

• Initializing a Gaussian test function


• Calculation of numerical second derivative with 3-point operator
• Accuracy improvement of numerical derivative with 5-point operator

Note: * Loop boundaries changed for 5-point operator, May 2020

In [1]: # Import Libraries


import numpy as np
from math import *
import matplotlib.pyplot as plt

We initialize a Gaussian function

( x − x0 )2
1 −
f (x) = √ e 2a (1)
2πa

Note that this specific definition is a δ−generating function. This means that f ( x )dx = 1 and
in the limit a → 0 the function f(x) converges to a δ−function.

In [2]: # Initialization
xmax=10.0 # physical domain (m)
nx=100 # number of space samples
a=.25 # exponent of Gaussian function
dx=xmax/(nx-1) # Grid spacing dx (m)
x0 = xmax/2 # Center of Gaussian function x0 (m)

x=np.linspace(0,xmax,nx) # defining space variable

# Initialization of Gaussian function


f=(1./sqrt(2*pi*a))*np.exp(-(((x-x0)**2)/(2*a)))

1
In [3]: # Plotting of gaussian
plt.figure(figsize=(10,6))
plt.plot(x, f)
plt.title('Gaussian function')
plt.xlabel('x, m')
plt.ylabel('Amplitude')
plt.xlim((0, xmax))
plt.grid()
plt.show()

Now let us calculate the second derivative using the finite-difference operator with three points

′′ f ( x + dx ) − 2 f ( x ) + f ( x − dx )
f num (x) = (2)
dx2
and compare it with the analytical solution

( x − x0 )2
1 ( x − x0 )2 1 −
f ′′ ( x ) = √ ( − )e 2a (3)
2πa a2 a

In [4]: # Second derivative with three-point operator

# Initiation of numerical and analytical derivatives


nder3=np.zeros(nx) # numerical derivative
ader=np.zeros(nx) # analytical derivative

2
# Numerical second derivative of the given function
for i in range (1, nx-1):
nder3[i]=(f[i+1] - 2*f[i] + f[i-1])/(dx**2)

# Analytical second derivative of the Gaissian function


ader=1./sqrt(2*pi*a)*((x-x0)**2/a**2 -1/a)*np.exp(-1/(2*a)*(x-x0)**2)
# Exclude boundaries
ader[0]=0.
ader[nx-1]=0.

# Calculate rms error of numerical derivative


rms = np.sqrt(np.mean((nder3-ader)**2))

In [5]: # Plotting
plt.figure(figsize=(10,6))
plt.plot (x, nder3,label="Numerical Derivative, 3 points", lw=2, color="violet")
plt.plot (x, ader, label="Analytical Derivative", lw=2, ls="--")
plt.plot (x, nder3-ader, label="Difference", lw=2, ls=":")
plt.title("Second derivative, Err (rms) = %.6f " % (rms) )
plt.xlabel('x, m')
plt.ylabel('Amplitude')
plt.legend(loc='lower left')
plt.grid()
plt.show()

3
In the cell below calculation of the first derivative with four points is provided with the fol-
lowing weights:

1 4 5 4 1
− f ( x − 2dx ) + f ( x − dx ) − f ( x ) + f ( x + dx ) − f ( x + 2dx )
f ′′ ( x ) = 12 3 2 3 12 (4)
dx2
In [6]: # First derivative with four points

# Initialisation of derivative
nder5=np.zeros(nx)

# Calculation of 2nd derivative


for i in range (2, nx-2):
nder5[i] = (-1./12 * f[i - 2] + 4./3 * f[i - 1] - 5./2 * f[i] \
+4./3 * f[i + 1] - 1./12 * f[i + 2]) / dx ** 2

# Exclude boundaries
ader[1]=0.
ader[nx-2]=0.

# Calculate rms error of numerical derivative


rms=rms*0
rms = np.sqrt(np.mean((nder5-ader)**2))

In [7]: # Plotting
plt.figure(figsize=(10,6))
plt.plot (x, nder5,label="Numerical Derivative, 5 points", lw=2, color="violet")
plt.plot (x, ader, label="Analytical Derivative", lw=2, ls="--")
plt.plot (x, nder5-ader, label="Difference", lw=2, ls=":")
plt.title("Second derivative, Err (rms) = %.6f " % (rms) )
plt.xlabel('x, m')
plt.ylabel('Amplitude')
plt.legend(loc='lower left')
plt.grid()
plt.show()

4
0.0.1 Conclusions
• 3-point finite-difference approximations can provide estimates of the 2nd derivative of a
function
• We can increase the accuracy of the approximation by using further functional values further
• A 5-point operator leads to substantially more accurate results

You might also like