Let us consider the equation
$$A u = f\quad \text{in } \Omega$$For an approximation $u_N$ of $u$, the residual, $R_N$, is defined by
$$R_N \equiv Au_N - f$$When the residual is made orthogonal to the subspace spanned by a base $\{\psi_k\}$, we have a weighted-residual method, i.e.,
$$\langle R_N, \psi_k\rangle =0 \quad k=1, 2, \cdots, N$$
In [1]:
from __future__ import division, print_function
import numpy as np
from sympy import *
from sympy.plotting import plot3d
from scipy.linalg import eigh
from scipy.special import jn_zeros as Jn_zeros, jn as Jn
import matplotlib.pyplot as plt
In [2]:
init_session()
%matplotlib inline
plt.style.use("seaborn-notebook")
In [3]:
def u_fun(r, m):
""" Trial function. """
c = symbols('c0:%i' % m)
w = (1 - r**2) *sum(c[k]*r**(2*k) for k in range (0, m))
return w, c
In [4]:
r = symbols('r')
m = 7
u, coef = u_fun(r, m)
In [5]:
T_inte = u**2
U_inte = diff(u, r)**2
In [6]:
display(U_inte)
display(T_inte)
In [7]:
U = integrate(expand(r*U_inte), (r, 0, 1))
T = integrate(expand(r*T_inte), (r, 0, 1))
In [8]:
K = Matrix(m, m, lambda ii, jj: diff(U, coef[ii], coef[jj]))
K
Out[8]:
In [9]:
M = Matrix(m, m, lambda ii, jj: diff(T, coef[ii], coef[jj]))
M
Out[9]:
In [10]:
Kn = np.array(K).astype(np.float64)
Mn = np.array(M).astype(np.float64)
In [11]:
vals, vecs = eigh(Kn, Mn, eigvals=(0, m-1))
np.sqrt(vals)
Out[11]:
In [23]:
lam = Jn_zeros(0, m)
In [13]:
r_vec = np.linspace(0, 1, 60)
plt.figure(figsize=(14, 5))
ax1 = plt.subplot(1, 2, 1)
ax2 = plt.subplot(1, 2, 2)
for num in range(5):
u_num = lambdify((r), u.subs({coef[kk]: vecs[kk, num] for kk in range(m)}),
"numpy")
ax1.plot(r_vec, u_num(r_vec)/u_num(0))
ax1.set_title("Approximated solution")
ax2.plot(r_vec, Jn(0, lam[num]*r_vec), label=r"$m=%i$"%num)
ax2.set_title("Exact solution")
plt.legend(loc="best", framealpha=0);
The Bubnov-Galerkint methood is a generalization of the Ritz method. As in the Ritz method, it seeks an approximate solution as a linear combination of base functions
$$u_N = \sum_{i=1}^{N} c_i \phi_i\, .$$In this case, the coefficients $c_i$ are determined from the condition that the residual $R_N$ is orthogonal to the basis functions $\phi_1, \phi_2, \cdots, \phi_N$:
$$\langle R_N, \phi_k\rangle =0\quad k=1, 2, \cdots, N \, .$$If the operator is positive-definite then $A=T^*T$ and the problem can be rewritten identically to the Ritz method.
In [14]:
def u_fun(r, m):
""" Trial function. """
c = symbols('c0:%i' % m)
w = (1 - r**2) *sum(c[k]*r**(2*k) for k in range (0, m))
return w, c
In [15]:
r = symbols('r')
m = 7
u, coef = u_fun(r, m)
In [16]:
u
Out[16]:
In [17]:
U = -integrate(diff(r*diff(u, r), r)*u, (r, 0, 1))
T = integrate(r*u**2, (r, 0, 1))
In [18]:
K = Matrix(m, m, lambda ii, jj: diff(U, coef[ii], coef[jj]))
K
Out[18]:
In [19]:
M = Matrix(m, m, lambda ii, jj: diff(T, coef[ii], coef[jj]))
M
Out[19]:
In [20]:
Kn = np.array(K).astype(np.float64)
Mn = np.array(M).astype(np.float64)
In [21]:
vals, vecs = eigh(Kn, Mn, eigvals=(0, m-1))
np.sqrt(vals)
Out[21]:
The following cell change the style of the notebook.
In [22]:
from IPython.core.display import HTML
def css_styling():
styles = open('../styles/custom_barba.css', 'r').read()
return HTML(styles)
css_styling()
Out[22]:
In [ ]: