(9.1) Consider the damped wave equation $$\frac{\partial^2 u}{\partial t^2} = v^2 \frac{\partial^2 u}{\partial x^2} + \gamma \frac{\partial}{\partial t} \frac{\partial^2 u}{\partial x^2} $$

Take the solution domain to be the interval [0,1].

(a) Use the Galerkin method to find an approximating system of differenctial equations.
(b) Evaluate the matrix coefficent for linear hat functions, using elements with a fixed size of h.
Write-up

(c) Now find the matrix coefficient for Hermit polynomial interpolation basis functions, once again using elements with a fixed size of h. A symbolic math enviroment is useful for this problem.

In [0]:
#%matplotlib inline
#import matplotlib.pyplot as plt
from sympy import *
import math
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
In [0]:
 
In [0]:
#init_printing()

# or with older versions of sympy/ipython, load the IPython extension
#%load_ext sympy.interactive.ipythonprinting
# or
#%load_ext sympyprinting

Define Matrix

In [0]:
u_0,du_0,u_h,du_h,a_0,a_1,a_2,a_3,h,x,f,df,temp = symbols("u_0, du_0,u_h,du_h,a_0,a_1,a_2,a_3,h,x,f,df,temp ")
In [4]:
U = Matrix([[u_0],[du_0],[u_h],[du_h]])
M = Matrix([[1,0,0,0], [0,1,0,0],[1,h,h**2,h**3],[0,1,2*h,3*h**2]])
A = Matrix([[a_0],[a_1],[a_2],[a_3]])
X = Matrix([[1, x, x**2, x**3]])
X
Out[4]:
Matrix([[1, x, x**2, x**3]])
In [5]:
f =[]
df =[]
Minv = M.inv()
##print(Minv)
for i in range(0,4):
  temp = 0
  for j in range(0,4):
    temp += Minv[:, i][j]*X[j]
  f.append(temp)
  df.append(diff(temp,x))
print(f)
print(df)
[1 - 3*x**2/h**2 + 2*x**3/h**3, x - 2*x**2/h + x**3/h**2, 3*x**2/h**2 - 2*x**3/h**3, -x**2/h + x**3/h**2]
[-6*x/h**2 + 6*x**2/h**3, 1 - 4*x/h + 3*x**2/h**2, 6*x/h**2 - 6*x**2/h**3, -2*x/h + 3*x**2/h**2]

For coeff A and B:
1) when |i-j| = 0, $\phi_i = u_3,\phi_j = u_3 $
2) when |i-j| = 0, $\phi_i = u_3,\phi_j = u_4 $
3) when |i-j| = 0, $\phi_i = u_4,\phi_j = u_4 $
4) when |i-j| = 1, $\phi_i = u_3,\phi_j = u_3 $
5) when |i-j| = 1, $\phi_i = u_3,\phi_j = u_4 $
6) when |i-j| = 1, $\phi_i = u_4,\phi_j = u_4 $
7) when |i-j| > 1

In [6]:
## integrate(f[2]*f[2], (x, 0, 2*h)) // if we do so, we need to define M value again , since boundary condition is changed. So, we use rather shifted graph for get integration.
A_0_3_3 = integrate(f[2]*f[2], (x, 0, h)) + integrate(f[0]*f[0], (x, 0, h))
A_0_3_4 = integrate(f[2]*f[3], (x, 0, h)) + integrate(f[0]*f[1], (x, 0, h))
A_0_4_4 = integrate(f[3]*f[3], (x, 0, h)) + integrate(f[1]*f[1], (x, 0, h))  

A_1_3_3 = integrate(f[0]*f[2], (x, 0, h))
A_1_3_4 = integrate(f[1]*f[2], (x, 0, h))
A_1_4_4 = integrate(f[1]*f[3], (x, 0, h))

B_0_3_3 = integrate(df[2]*df[2], (x, 0, h)) + integrate(df[0]*df[0], (x, 0, h))
B_0_3_4 = integrate(df[2]*df[3], (x, 0, h)) + integrate(df[0]*df[1], (x, 0, h))
B_0_4_4 = integrate(df[3]*df[3], (x, 0, h)) + integrate(df[1]*df[1], (x, 0, h))

B_1_3_3 = integrate(df[0]*df[2], (x, 0, h))
B_1_3_4 = integrate(df[1]*df[2], (x, 0, h))
B_1_4_4 = integrate(df[1]*df[3], (x, 0, h))


print("Matrix_|i-j|_fuction1_fuction2 : "+ "coefficient value")
print("A_0_3_3 : "+ str(A_0_3_3))
print("A_0_3_4 : "+ str(A_0_3_4))
print("A_0_4_4 : "+ str(A_0_4_4))
print("A_1_3_3 : "+ str(A_1_3_3))
print("A_1_3_4 : "+ str(A_1_3_4))
print("A_1_4_4 : "+ str(A_1_4_4))

print("B_0_3_3 : "+ str(B_0_3_3))
print("B_0_3_4 : "+ str(B_0_3_4))
print("B_0_4_4 : "+ str(B_0_4_4))
print("B_1_3_3 : "+ str(B_1_3_3))
print("B_1_3_4 : "+ str(B_1_3_4))
print("B_1_4_4 : "+ str(B_1_4_4))
Matrix_|i-j|_fuction1_fuction2 : coefficient value
A_0_3_3 : 26*h/35
A_0_3_4 : 0
A_0_4_4 : 2*h**3/105
A_1_3_3 : 9*h/70
A_1_3_4 : 13*h**2/420
A_1_4_4 : -h**3/140
B_0_3_3 : 12/(5*h)
B_0_3_4 : 0
B_0_4_4 : 4*h/15
B_1_3_3 : -6/(5*h)
B_1_3_4 : -1/10
B_1_4_4 : -h/30

Now Let's implement this to wave equation

In [0]:
## let's use both 3,3
## if |i-j|=0, value is Aij = 26*h/35, Bij = 12/(5*h)
## if |i-j|=1, value is Aij = 9*h/70, Bij = -6/(5*h)

h = 0.1
boundary = 1
count = int(boundary/h)
A = []
B = []
for j in range (0,count):
  tempA = []
  tempB = []
  for i in range(0,count):
    if (abs(i-j)==0 ):
      ##tempA.append(26*h/35)
      ##tempB.append(12/(5*h))
      tempA.append(2*h/3)
      tempB.append(2/h)
    elif (abs(i-j)==1):
      ##tempA.append(9*h/70)
      ##tempB.append(-6/(5*h))
      tempA.append(1*h/6)
      tempB.append(-1/h)
    else:
      tempA.append(0)
      tempB.append(0)
  A.append(tempA)
  B.append(tempB)

M_A = Matrix(A)
M_B = Matrix(B)
 
In [0]:
##M_A_inv = M_A.inv()
##Result = M_B*M_A_inv
##Result

From 9.1 (a),

$$ A_{ij}\cdot \frac{d^2 \vec{a}}{d t^2} + \gamma\cdot B_{ij} \cdot \frac{d\vec{a}}{dt} + v^2\cdot B_{ij} \cdot \vec{a} = \vec{0}$$


when at certain t, from equation(9.9)
$$u(x_{i}) = a_i $$
so vector a is value of u in certain time. $$\vec{a} = \vec{u}$$

From partial difference chapter(8) we got,
$$ \frac{\partial u}{\partial t} = \frac{u_{j}^{n+1} - u_j^n}{{\Delta t}} $$
$$ \frac{\partial^2 u}{\partial t^2} = \frac{u_{j}^{n+1} - 2 u_j^n + u_{j}^{n-1}}{({\Delta t})^2}$$

So, 9.1(a) is again,

$$A \cdot (\vec{u}^{n+1}-2\vec{u}^{n}+\vec{u}^{n-1}) + \gamma B \cdot dt \cdot (\vec{u}^{n+1} - \vec{u}^{n}) + v^2 B \cdot dt^2 \cdot \vec{u}^n = \vec{0}$$


$$\vec{u}^{n+1} =(A+\gamma B \cdot dt)^{-1}[(2A+\gamma B \cdot dt - v^2 B\cdot dt^2)\cdot \vec{u}^n - A\cdot \vec{u}^{n-1}]$$


So, this indicates, if we know $u^0$ and $u^1$, we can get $u^n$.
Let's $$\vec{u}^{n+1} =M_1[M_2\cdot \vec{u}^n - A\cdot \vec{u}^{n-1}]$$

In [0]:
## let's make a wave

dt = 0.01
gamma = 0
v = 1
##h = 1

M_1 = (M_A + M_B*gamma*dt).inv()
M_2 = 2*M_A + gamma*dt*M_B -(v**2)*(dt**2)*M_B
In [10]:
M_1
Out[10]:
Matrix([
[      16.076951545813,     -4.3078061832522,     1.15427318719576,  -0.309286565530806,  0.0828730749274871, -0.0222057341795373, 0.00594986178914454, -0.00159371297592608, 0.000424990127442128, -0.00010624754969764],
[     -4.3078061832522,     17.2312247330088,    -4.61709274878302,    1.23714626212316,  -0.331492299709808,  0.0888229367167948, -0.0237994471536714,  0.00637485189947626, -0.00169996049074226, 0.000424990038124462],
[     1.15427318719576,    -4.61709274878302,     17.3140978079363,    -4.6392984829623,     1.2430961239129,  -0.333086012689363,  0.0892479268435322,  -0.0239056946865977,  0.00637485189778504, -0.00159371294513174],
[   -0.309286565530822,     1.23714626212329,    -4.63929848296232,     17.320047669726,   -4.64089219594169,    1.24352111404078,  -0.333192260221115,   0.0892479268437953,  -0.0237994471548177,  0.00594986177727927],
[   0.0828730749275303,   -0.331492299710121,     1.24309612391296,    -4.6408921959417,    17.3204726598538,   -4.64099844347366,    1.24352111404071,   -0.333086012689405,   0.0888229367168754,  -0.0222057341777757],
[  -0.0222057341792998,   0.0888229367171992,   -0.333086012689497,    1.24352111404079,   -4.64099844347366,    17.3204726598538,   -4.64089219594169,     1.24309612391294,   -0.331492299709979,   0.0828730749269817],
[  0.00594986178966885,  -0.0237994471586754,   0.0892479268450327,  -0.333192260221455,    1.24352111404079,    -4.6408921959417,     17.320047669726,    -4.63929848296231,     1.23714626212325,   -0.309286565530835],
[ -0.00159371297937558,  0.00637485191750233,  -0.0239056946906338,  0.0892479268450327,  -0.333086012689497,    1.24309612391295,   -4.63929848296232,     17.3140978079363,    -4.61709274878302,     1.15427318719577],
[ 0.000424990127833489, -0.00169996051133396,  0.00637485191750234, -0.0237994471586754,  0.0888229367171992,  -0.331492299710121,    1.23714626212329,    -4.61709274878302,     17.2312247330088,     -4.3078061832522],
[-0.000106247531958372, 0.000424990127833489, -0.00159371297937558, 0.00594986178966884, -0.0222057341792998,  0.0828730749275303,  -0.309286565530821,     1.15427318719576,     -4.3078061832522,      16.076951545813]])
In [11]:
M_2
Out[11]:
Matrix([
[ 0.131333333333333, 0.0343333333333333,                  0,                  0,                  0,                  0,                  0,                  0,                  0,                  0],
[0.0343333333333333,  0.131333333333333, 0.0343333333333333,                  0,                  0,                  0,                  0,                  0,                  0,                  0],
[                 0, 0.0343333333333333,  0.131333333333333, 0.0343333333333333,                  0,                  0,                  0,                  0,                  0,                  0],
[                 0,                  0, 0.0343333333333333,  0.131333333333333, 0.0343333333333333,                  0,                  0,                  0,                  0,                  0],
[                 0,                  0,                  0, 0.0343333333333333,  0.131333333333333, 0.0343333333333333,                  0,                  0,                  0,                  0],
[                 0,                  0,                  0,                  0, 0.0343333333333333,  0.131333333333333, 0.0343333333333333,                  0,                  0,                  0],
[                 0,                  0,                  0,                  0,                  0, 0.0343333333333333,  0.131333333333333, 0.0343333333333333,                  0,                  0],
[                 0,                  0,                  0,                  0,                  0,                  0, 0.0343333333333333,  0.131333333333333, 0.0343333333333333,                  0],
[                 0,                  0,                  0,                  0,                  0,                  0,                  0, 0.0343333333333333,  0.131333333333333, 0.0343333333333333],
[                 0,                  0,                  0,                  0,                  0,                  0,                  0,                  0, 0.0343333333333333,  0.131333333333333]])
In [12]:
u_0=[]
u_1=[]

for i in range (0,count):
  temp_u_0 = [0]
  temp_u_1 = [0]
  u_0.append(temp_u_0)
  u_1.append(temp_u_1)

M_u_0 = Matrix(u_0)
M_u_1 = Matrix(u_1)

## update one value
M_u_1[5,0] = 5

M_u_1

  
Out[12]:
Matrix([
[0],
[0],
[0],
[0],
[0],
[5],
[0],
[0],
[0],
[0]])
In [14]:
M_u_2 = M_1*(M_2*M_u_1 - M_A*M_u_0)
M_u_0 = M_u_1
M_u_1 = M_u_2

##current
current = M_u_1.T.tolist()[0]
x=[]
for i in range(0, count):
  x.append(i)
plt.plot(x, current,'b',c='red',label="theta")
plt.xlabel("x")
plt.ylabel("y")
plt.show()