import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import solve
# Finite element solution setup
N = 5
h = 1 / (N + 1)
A = np.zeros((N, N))
u = np.zeros(N)
x1 = np.linspace(0, 1, N + 2)
b = np.zeros(N)
A[0, 0] = 2 / 3 * h - 2 / h
A[1, 0] = h / 6 + 1 / h
A[N - 1, N - 1] = 2 / 3 * h - 2 / h
A[N - 2, N - 1] = h / 6 + 1 / h
for i in range(1, N - 1):
A[i, i] = 2 / 3 * h - 2 / h
A[i - 1, i] = h / 6 + 1 / h
A[i + 1, i] = h / 6 + 1 / h
b = - (np.arange(N)+1)*h**2
u = solve(A, b)
us1 = np.zeros(N + 2)
us1[1:-1] = u
# Exact solution
Nex = 100
hex = 1 / (Nex + 1)
xex = np.linspace(0, 1, Nex + 2)
uex = -xex + np.sin(xex) / np.sin(1)
# Finite element solution with larger N
N = 11
h = 1 / (N + 1)
A = np.zeros((N, N))
u = np.zeros(N)
x2 = np.linspace(0, 1, N + 2)
b = np.zeros(N)
A[0, 0] = 2 / 3 * h - 2 / h
A[1, 0] = h / 6 + 1 / h
A[N - 1, N - 1] = 2 / 3 * h - 2 / h
A[N - 2, N - 1] = h / 6 + 1 / h
for i in range(1, N - 1):
A[i, i] = 2 / 3 * h - 2 / h
A[i - 1, i] = h / 6 + 1 / h
A[i + 1, i] = h / 6 + 1 / h
b = - (np.arange(N)+1)*h**2
u = solve(A, b)
us2 = np.zeros(N + 2)
us2[1:-1] = u
# Plotting
plt.plot(xex, uex, '-', x1, us1, '-.', x2, us2, '--')
plt.legend(['Exact', 'N=6', 'N=12'])
plt.show(block=False)
# Save data
t1 = np.column_stack((xex, uex))
t2 = np.column_stack((x1, us1))
t3 = np.column_stack((x2, us2))
with open("FEGalerkin1.dat", "w") as f:
np.savetxt(f, t1, fmt='%f', header="Exact Solution")
f.write("\n\n")
np.savetxt(f, t2, fmt='%f', header="Finite Element N=6")
f.write("\n\n")
np.savetxt(f, t3, fmt='%f', header="Finite Element N=12")