download
raw
4.94 kB
from scitools.std import plot, savefig, hold, axis, legend
import numpy as np
def mesh(N_e, d, Omega=[0,1]):
"""
Return a 1D finite element mesh on Omega with N_e elements of
the polynomial degree d. The nodes are uniformly spaced.
Return nodes (coordinates) and elements (connectivity) arrays.
"""
# or should we just have end-nodes and leave it up to info
# elsewhere to have internal nodes and other dofs?
nodes = np.linspace(Omega[0], Omega[1], N_e*d + 1)
elements = np.asarray([[e*d + i for i in range(d+1)] \
for e in range(N_e)], int)
return nodes, elements
from Lagrange import Lagrange_polynomial, Lagrange_polynomials
def phi_r(r, X, d):
"""
Return local basis function phi_r at local point X in
a 1D element with d+1 nodes.
"""
nodes = np.linspace(-1, 1, d+1)
return Lagrange_polynomial(X, r, nodes)
def phi_r(r, X, d, point_distribution='uniform'):
"""
Return local basis function phi_r at local point X in
a 1D element with d+1 nodes.
point_distribution can be 'uniform' or 'Chebyshev'.
"""
if point_distribution == 'uniform':
nodes = np.linspace(-1, 1, d+1)
elif point_distribution == 'Chebyshev':
nodes = Chebyshev_nodes(-1, 1, d)
return Lagrange_polynomial(X, r, nodes)
def basis(X, d=1):
"""Return the finite element basis in 1D of degree d."""
phi = [phi_r(r, X, d) for r in range(d+1)]
return phi
def affine_mapping(X, Omega_e):
x_L, x_R = Omega_e
return 0.5*(x_L + x_R) + 0.5*(x_R - x_L)*X
def u_glob(U, elements, nodes, resolution_per_element=51):
"""
Compute (x, y) coordinates of a curve y = u(x), where u is a
finite element function: u(x) = sum_i of U_i*phi_i(x).
Method: Run through each element and compute cordinates
over the element.
"""
x_patches = []
u_patches = []
for e in range(len(elements)):
Omega_e = (nodes[elements[e,0]], nodes[elements[e,-1]])
local_nodes = elements[e,:]
d = len(local_nodes) - 1
X = np.linspace(-1, 1, resolution_per_element)
x = affine_mapping(X, Omega_e)
x_patches.append(x)
u_element = 0
for r in range(len(local_nodes)):
i = local_nodes[r] # global node number
u_element += U[i]*phi_r(r, X, d)
u_patches.append(u_element)
x = np.concatenate(x_patches)
u = np.concatenate(u_patches)
return x, u
def element_matrix(d, Omega_e, numint):
n = d+1
A_e = np.zeros((n, n))
h = Omega_e[1] - Omega_e[0]
detJ = h/2 # dx/dX
for j in range(len(numint[0])):
Xj, wj = numint[0][j], numint[1][j]
phi = basis(Xj, d)
for r in range(n):
for s in range(r, n):
A_e[r,s] += phi[r](Xj)*phi[s](Xj)*detJ*wj
A_e[s,r] += A_e[r,s]
return A_e
def element_vector(f, d, Omega_e, intrule):
n = d+1
b_e = np.zeros(n)
h = Omega_e[1] - Omega_e[0]
detJ = h/2 # dx/dX
for j in range(len(numint[0])):
Xj, wj = numint[0][j], numint[1][j]
phi = basis(Xj, d)
for r in range(n):
b_e[r,s] += f(Xj)*phi[r](Xj)*detJ*wj
return b_e
def assemble(nodes, elements, d, f, numint):
N_n, N_e = len(nodes), len(elements)
A = np.zeros((N_n, N_n))
b = np.zeros((N_n, 1))
for e in range(N_e):
Omega_e = [nodes[elements[e,0]], nodes[elements[e,-1]]]
A_e = element_matrix(d, Omega_e, numint)
b_e = element_vector(f, d, Omega_e, numint)
#print 'element', e
#print b_e
for r in range(len(elements[e,:])):
for s in range(len(elements[e])):
A[elements[e,r],elements[e,s]] += A_e[r,s]
b[elements[e,r]] += b_e[r]
return A, b
def approximate(f, d=1, N_e=4, numint='Gauss-Legendre2',
filename='tmp.eps'):
nodes, elements = mesh(N_e, d, [0, 1])
A, b = assemble(nodes, elements, d, f, numint)
c = A.LUsolve(b)
print('nodes:', nodes)
print ('elements:', elements)
print('A:\n', A)
print('b:\n', b)
print( sym.latex(A, mode='plain'))
#print sym.latex(b, mode='plain')
c = A.LUsolve(b)
print('c:\n', c)
print('Plain interpolation:')
x = sym.Symbol('x')
f = sym.lambdify([x], f, modules='numpy')
f_at_nodes = [f(xc) for xc in nodes]
print( f_at_nodes)
if not symbolic:
xf = np.linspace(0, 1, 10001)
U = np.asarray(c)
xu, u = u_glob(U, elements, nodes)
from scitools.std import plot
plot(xu, u, 'r-',
xf, f(xf), 'b-',
legend=('u', 'f'),
savefig=filename)
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
print( """Usage %s function arg1 arg2 arg3 ...""" % sys.argv[0])
sys.exit(0)
cmd = '%s(%s)' % (sys.argv[1], ', '.join(sys.argv[2:]))
print( cmd)
eval(cmd)

Xet Storage Details

Size:
4.94 kB
·
Xet hash:
683933d5ba531505a9cc06e198108ddbc2a62ca85a1c7ef1a4410c1bc6ceeee1

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.