Upload ex6 and ex7

This commit is contained in:
jakob.schratter 2026-01-04 20:15:55 +01:00
commit 6c2d96ff4d
44 changed files with 15291 additions and 0 deletions

83
ex6/adaptivity_schemes.py Normal file
View file

@ -0,0 +1,83 @@
import numpy as np
def flux_jumps(mesh, u):
N = len(mesh) - 1 # number of elements
jumps = np.zeros(N + 1) # N-1 edges
for i in range(1, N):
upper = (u[i + 1] - u[i])/(mesh[i + 1] - mesh[i])
lower = (u[i] - u[i - 1])/(mesh[i] - mesh[i - 1])
jumps[i] = upper - lower
return jumps
def residual_errors(mesh, u):
N = len(mesh) - 1 # number of elements
errors = np.zeros(N)
jumps = flux_jumps(mesh, u)
for i in range(N):
errors[i] = np.sqrt((jumps[i]**2 + jumps[i + 1]**2)/2) # Braess (8.10)
#print("errors:\n", errors)
return errors
def adapt_h(mesh, u, alpha):
N = len(mesh) - 1 # number of elements
errors = residual_errors(mesh, u)
threshhold = alpha * abs(max(errors))
# refine mesh
refined_mesh = [mesh[0]]
for i in range(N):
if abs(errors[i]) <= threshhold:
refined_mesh.append(mesh[i + 1])
else:
refined_mesh.append(mesh[i] + (mesh[i + 1] - mesh[i])/2)
refined_mesh.append(mesh[i + 1])
#print("refined mesh:\n", refined_mesh)
return refined_mesh
def adapt_r(mesh, u):
N = len(mesh) - 1 # number of elements
rho = np.abs(flux_jumps(mesh, u)) # rho ... mesh density function
p = np.zeros(N) # piecewise constant function on the mesh elements
for i in range(N):
p[i] = (rho[i] + rho[i + 1])/2
P = np.zeros(N + 1) # \int_0^{x_j} p(x) dx for j = 1,...,N
for j in range(1, N + 1):
h_j = mesh[j] - mesh[j - 1]
P[j] = P[j - 1] + h_j*p[j - 1] # add integral over j-th interval
moved_mesh = np.zeros(N + 1)
moved_mesh[0] = mesh[0]
moved_mesh[-1] = mesh[-1]
for j in range(1, N): # calculate the new nodes with De Boor's algorithm
xi_j = j/N
k = np.searchsorted(P, xi_j*P[-1], side="left") # searches for index k, such that xi_j*P[-1] > P[k]
assert(P[k - 1] < xi_j*P[-1])
assert(xi_j*P[-1] <= P[k])
moved_mesh[j] = mesh[k - 1] + (xi_j*P[-1] - P[k - 1])/p[k - 1]
print("orign_mesh[j] =", mesh[j])
print("moved_mesh[j] =", moved_mesh[j])
print("done\n")
#print("moved mesh:\n", moved_mesh)
return moved_mesh

139
ex6/ex_6A.py Normal file
View file

@ -0,0 +1,139 @@
import numpy as np
import scipy.integrate as integrate
import matplotlib.pyplot as plt
import adaptivity_schemes
np.set_printoptions(precision=2)
def Solve_6A(mesh, p):
N = len(mesh) - 1 # number of elements
f = lambda x : 2*p**3*x/((p**2*x**2 + 1)**2)
g_b = p/(p**2 + 1)
A = np.zeros((N + 1, N + 1))
f_vec = np.zeros(N + 1)
for i in range(1, N + 1):
h = mesh[i] - mesh[i - 1]
a_11 = 1./h
a_12 = -1./h
a_21 = -1./h
a_22 = 1./h
A[i - 1, i - 1] += a_11
A[i - 1, i] += a_12
A[i, i - 1] += a_21
A[i, i] += a_22
phi_lower = lambda x : (mesh[i] - x)/h
f_vec[i-1] += integrate.quad(lambda x : f(x)*phi_lower(x), mesh[i - 1], mesh[i])[0]
phi_upper = lambda x : (x - mesh[i - 1])/h
f_vec[i] += integrate.quad(lambda x : f(x)*phi_upper(x), mesh[i - 1], mesh[i])[0]
# take Neumann data into account
A[N, N] += 0
f_vec[N] += g_b
# take Dirichlet data into account
u_g = np.zeros(N + 1)
u_g[0] = -np.arctan(p)
#print("u_g =\n", u_g)
# remove first row of A
A_g = A[1:N+1, :]
#print("A_g =\n", A_g)
# remove first row of f_vec
f_g = f_vec[1:N+1]
# assemble RHS with dirichlet data
f_g -= A_g.dot(u_g)
#print("f_g =\n", f_g)
# matrix for the inner nodes (excluding nodes with dirichlet bcs)
A_0 = A[1:N+1, 1:N+1]
#print(A_0)
# solve for u_0 (free dofs)
u_0 = np.linalg.solve(A_0, f_g)
# assemble "u = u_0 + u_g"
u = np.concatenate([[u_g[0]], u_0])
return u
p = 100
########## h-adaptivity ##########
N = 5 # number of elements
mesh = np.linspace(-1, 1, N + 1)
u = Solve_6A(mesh, p)
plt.plot(mesh, u, '-o')
plt.grid()
plt.xlabel('x')
plt.ylabel('u_h(x)')
plt.title("h-adaptivity")
N_vec = ["0 refinements, " + str(N) + " elements"]
refinements = 4 # number of refinements
for i in range(refinements):
mesh = adaptivity_schemes.adapt_h(mesh, u, 0.7)
u = Solve_6A(mesh, p)
plt.plot(mesh, u, '-o')
N_vec.append(str(i + 1) + " refinements, " + str(len(mesh) - 1) + " elements")
# plot exact solution
x = np.linspace(-1, 1, 50)
plt.plot(x, np.arctan(p*x))
N_vec.append("exact")
plt.legend(N_vec)
plt.show()
# ########## r-adaptivity ##########
N = 5
mesh = np.linspace(-1, 1, N + 1)
u = Solve_6A(mesh, p)
plt.plot(mesh, u, '-o')
title = "r-adaptivity with " + str(N) + " elements"
plt.title(title)
adaptations_vec = ["0 adaptations"]
adaptations = 5 # number of iterations
for i in range(adaptations):
mesh = adaptivity_schemes.adapt_r(mesh, u)
u = Solve_6A(mesh, p)
plt.plot(mesh, u, '-o')
adaptations_vec.append(str(i + 1) + " adaptations")
# plot exact solution
x = np.linspace(-1, 1, 50)
plt.plot(x, np.arctan(p*x))
adaptations_vec.append("exact")
plt.legend(adaptations_vec)
plt.xlabel('x')
plt.ylabel('u_h(x)')
plt.grid()
plt.show()

120
ex6/ex_6B.py Normal file
View file

@ -0,0 +1,120 @@
import numpy as np
import matplotlib.pyplot as plt
import adaptivity_schemes
np.set_printoptions(precision=2)
def lam_func(x):
n = len(x)
lam_vec = np.zeros(n)
for i in range(n):
if (x[i] > 1/np.sqrt(2)):
lam_vec[i] = 10
else:
lam_vec[i] = 1
return lam_vec
def Solve_6B(mesh):
N = len(mesh) - 1 # number of elements
A = np.zeros((N + 1, N + 1))
lam_vec = lam_func(mesh)
for i in range(1, N + 1):
h = mesh[i] - mesh[i - 1]
a_11 = lam_vec[i]/h
a_12 = -lam_vec[i]/h
a_21 = -lam_vec[i]/h
a_22 = lam_vec[i]/h
A[i - 1, i - 1] += a_11
A[i - 1, i] += a_12
A[i, i - 1] += a_21
A[i, i] += a_22
#print("A =\n", A)
# take dirichlet data into account
u_g = np.zeros(N + 1)
u_g[0] = 0
u_g[N] = 1
#print("u_g =\n", u_g)
# remove first and last row of A
A_g = A[1:N, :]
#print("A_g =\n", A_g)
# assemble RHS with dirichlet data
f = -A_g.dot(u_g)
#print(f)
# matrix for the inner nodes (excluding nodes with dirichlet bcs)
A_0 = A[1:N, 1:N]
#print(A_0)
# solve for u_0 (free dofs)
u_0 = np.linalg.solve(A_0, f)
# assemble "u = u_0 + u_g"
u = np.concatenate([[0], u_0, [1]])
#print("u =\n", u)
return u
########## h-adaptivity ##########
N = 2 # number of elements
mesh = np.linspace(0, 1, N + 1)
u = Solve_6B(mesh)
plt.plot(mesh, u, '-o')
plt.grid()
plt.xlabel('x')
plt.ylabel('u_h(x)')
plt.title("h-adaptivity")
N_vec = ["0 refinements, " + str(N) + " elements"]
refinements = 5 # number of refinements
for i in range(refinements):
mesh = adaptivity_schemes.adapt_h(mesh, lam_func(mesh)*u, 0.9)
u = Solve_6B(mesh)
plt.plot(mesh, u, '-o')
N_vec.append(str(i + 1) + " refinements, " + str(len(mesh) - 1) + " elements")
plt.legend(N_vec)
plt.show()
########## r-adaptivity ##########
N = 5
mesh = np.linspace(0, 1, N + 1)
u = Solve_6B(mesh)
plt.plot(mesh, u, '-o')
title = "r-adaptivity with " + str(N) + " elements"
plt.title(title)
adaptations_vec = ["0 adaptations"]
adaptations = 4 # number of iterations
for i in range(adaptations):
mesh = adaptivity_schemes.adapt_r(mesh, lam_func(mesh)*u)
u = Solve_6B(mesh)
plt.plot(mesh, u, '-o')
adaptations_vec.append(str(i + 1) + " adaptations")
plt.legend(adaptations_vec)
plt.xlabel('x')
plt.ylabel('u_h(x)')
plt.grid()
plt.show()

127
ex6/ex_6C.py Normal file
View file

@ -0,0 +1,127 @@
import numpy as np
import matplotlib.pyplot as plt
import adaptivity_schemes
np.set_printoptions(precision=2)
def Solve_6C(mesh, p):
N = len(mesh) - 1 # number of elements
A = np.zeros((N + 1, N + 1))
for i in range(1, N + 1):
h = mesh[i] - mesh[i - 1]
a_11 = 1./h - p/2.
a_12 = -1./h + p/2.
a_21 = -1./h - p/2.
a_22 = 1./h + p/2.
A[i - 1, i - 1] += a_11
A[i - 1, i] += a_12
A[i, i - 1] += a_21
A[i, i] += a_22
#print("A =\n", A)
# take dirichlet data into account
u_g = np.zeros(N + 1)
u_g[0] = 0
u_g[N] = 1
#print("u_g =\n", u_g)
# remove first and last row of A
A_g = A[1:N, :]
#print("A_g =\n", A_g)
# assemble RHS with dirichlet data
f = -A_g.dot(u_g)
#print(f)
# matrix for the inner nodes (excluding nodes with dirichlet bcs)
A_0 = A[1:N, 1:N]
#print(A_0)
# solve for u_0 (free dofs)
u_0 = np.linalg.solve(A_0, f)
# assemble "u = u_0 + u_g"
u = np.concatenate([[0], u_0, [1]])
return u
p = 70
######### h-adaptivity ##########
N = 5 # number of elements
mesh = np.linspace(0, 1, N + 1)
u = Solve_6C(mesh, p)
plt.plot(mesh, u, '-o')
plt.grid()
plt.xlabel('x')
plt.ylabel('u_h(x)')
plt.title("h-adaptivity")
N_vec = ["0 refinements, " + str(N) + " elements"]
refinements = 4 # number of refinements
for i in range(refinements):
mesh = adaptivity_schemes.adapt_h(mesh, u, 0.7)
u = Solve_6C(mesh, p)
plt.plot(mesh, u, '-o')
N_vec.append(str(i + 1) + " refinements, " + str(len(mesh) - 1) + " elements")
# plot exact solution
x = np.linspace(0, 1, 50)
plt.plot(x, (np.exp(p*x) - 1.)/(np.exp(p) - 1.))
N_vec.append("exact")
plt.legend(N_vec)
plt.show()
########## r-adaptivity ##########
N = 10
mesh = np.linspace(0, 1, N + 1)
u = Solve_6C(mesh, p)
plt.plot(mesh, u, '-o')
title = "r-adaptivity with " + str(N) + " elements"
plt.title(title)
adaptations_vec = ["0 adaptations"]
adaptations = 4 # number of iterations
for i in range(adaptations):
mesh = adaptivity_schemes.adapt_r(mesh, u)
u = Solve_6C(mesh, p)
plt.plot(mesh, u, '-o')
adaptations_vec.append(str(i + 1) + " adaptations")
# plot exact solution
x = np.linspace(0, 1, 50)
plt.plot(x, (np.exp(p*x) - 1.)/(np.exp(p) - 1.))
adaptations_vec.append("exact")
plt.legend(adaptations_vec)
plt.xlabel('x')
plt.ylabel('u_h(x)')
plt.grid()
plt.show()