This notebook covers the following aspects: * Initialize and setup of the finite element solution for the 1D wave equation * Define the Mass Matrix and Stiffness Matrix and visually inspect their structure * Implementation of a finite difference scheme for comparision with the finite element scheme * The finite element solution using the computed mass matrix M and stiffness matrix K
Basic Equations
This notebook presents a finite element code for the 1D elastic wave equation. Additionally, a solution using finite difference scheme is given for comparison.
using the finite element method is done after a series of steps performed on the above equation.
We first obtain a weak form of the wave equation by integrating over the entire physical domain \(D\) and at the same time multiplying by some basis \(\varphi_{i}\).
Integration by parts and implementation of the stress-free boundary condition is performed.
We approximate our unknown displacement field \(u(x, t)\) by a sum over space-dependent basis functions \(\varphi_i\) weighted by time-dependent coefficients \(u_i(t)\).
where \(\mathbf{M}\) is known as the mass matrix, and \(\mathbf{K}\) the stiffness matrix.
As interpolating functions, we choose interpolants such that \(\varphi_{i}(x_{i}) = 1\) and zero elsewhere. Then, we transform the space coordinate into a local system. According to \(\xi = x − x_{i}\) and \(h_{i} = x_{i+1} − x_{i}\), we have:
The figure on the left-hand side illustrates the shape of \(\varphi_{i}(\xi)\) and \(\partial_{\xi}\varphi_{i}(\xi)\) with varying \(h\).
Code implementation starts with the initialization of a particular setup of our problem. Then, we define the source that introduces perturbations following by initialization of the mass and stiffness matrices. Finally, time extrapolation is done.
Code
# Import all necessary libraries, 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 pltimport matplotlib.animation as animation
1. Initialization of setup
Code
# Initialization of setup# ---------------------------------------------------------------# Basic parametersnx =1000# Number of collocation points xmax =10000.# Physical dimension [m]vs =3000# Wave velocity [m/s] ro0 =2500# Density [kg/m^3]nt =2000# Number of time stepsisx =500# Source location [m] eps =0.5# Stability limitiplot =20# Snapshot frequencydx = xmax/(nx-1) # calculate space incrementx = np.arange(0, nx)*dx # initialize space coordinatesx = np.transpose(x)h = np.diff(x) # Element sizes [m]# parametersro = x*0+ ro0mu = x*0+ ro*vs**2# time step from stabiity criteriondt =0.5*eps*dx/np.max(np.sqrt(mu/ro))# initialize time axist = np.arange(1, nt+1)*dt # ---------------------------------------------------------------# Initialize fields# ---------------------------------------------------------------u = np.zeros(nx)uold = np.zeros(nx)unew = np.zeros(nx)p = np.zeros(nx)pold = np.zeros(nx)pnew = np.zeros(nx)
2. Source time function
In 1D the propagating signal is an integral of the source time function. As we look for a Gaussian waveform, we initialize the source time function \(f(t)\) using the first derivative of a Gaussian function.
Initialize a source time function called ‘src’. Use \(\sigma = 20 dt\) as Gaussian width, and time shift \(t_0 = 3\sigma\). Then, visualize the source in a given plot.
Code
# Initialization of the source time function# ---------------------------------------------------------------pt =20*dt # Gaussian widtht0 =3*pt # Time shiftsrc =-2/pt**2* (t-t0) * np.exp(-1/pt**2* (t-t0)**2)# Source vector# ---------------------------------------------------------------f = np.zeros(nx); f[isx:isx+1] = f[isx:isx+1] +1.# ---------------------------------------------------------------# Plot source time fuction# ---------------------------------------------------------------plt.plot(t, src, color='b', lw=2, label='Source time function')plt.ylabel('Amplitude', size=16)plt.xlabel('time', size=16)plt.legend()plt.grid(True)plt.show()
3. The Mass Matrix
Having implemented the desired source, now we initialize the mass and stiffness matrices. In general, the mass matrix is given by
To bring the finite-difference scheme formally to the same structure we also need the corresponding mass matrix simply using the inverse densities, we initialize with
Finally we implement the finite element solution using the computed mass \(M\) and stiffness \(K\) matrices together with a finite differences extrapolation scheme