download
raw
7.37 kB
import scitools.std as plt
from fe_approx1D import mesh_uniform, phi_glob
import numpy as np
def plot_fe_mesh(nodes, elements, element_marker=[0, 0.1]):
"""Illustrate elements and nodes in a finite element mesh."""
plt.hold('on')
all_x_L = [nodes[elements[e][0]] for e in range(len(elements))]
element_boundaries = all_x_L + [nodes[-1]]
for x in element_boundaries:
plt.plot([x, x], element_marker, 'm--') # m gives dotted lines
plt.plot(nodes, [0]*len(nodes), 'ro2')
def fe_basis_function_figure(d, target_elm=[1], N_e=3,
derivative=0, filename='tmp.pdf',
labels=False):
"""
Draw all basis functions (or their derivative), of degree d,
associated with element target_elm (may be list of elements).
Add a mesh with N_e elements.
"""
nodes, elements = mesh_uniform(N_e, d)
"""
x = 1.1
print locate_element_vectorized(x, elements, nodes)
print locate_element_scalar(x, elements, nodes)
x = 0.1, 0.4, 0.8
print locate_element_vectorized(x, elements, nodes)
"""
if isinstance(target_elm, int):
target_elm = [target_elm] # wrap in list
# Draw the basis functions for element 1
phi_drawn = [] # list of already drawn phi functions
ymin = ymax = 0
for e in target_elm:
for i in elements[e]:
if not i in phi_drawn:
x, y = phi_glob(i, elements, nodes,
derivative=derivative)
if x is None and y is None:
return # abort
ymax = max(ymax, max(y))
ymin = min(ymin, min(y))
plt.plot(x, y, '-')
plt.hold('on')
if labels:
if plt.backend == 'gnuplot':
if derivative == 0:
plt.legend(r'basis func. %d' % i)
else:
plt.legend(r'derivative of basis func. %d' % i)
elif plt.backend == 'matplotlib':
if derivative == 0:
plt.legend(r'\varphi_%d' % i)
else:
plt.legend(r"\varphi_%d'(x)" % i)
phi_drawn.append(i)
plt.axis([nodes[0], nodes[-1], ymin-0.1, ymax+0.1])
plot_fe_mesh(nodes, elements, element_marker=[ymin-0.1, ymax+0.1])
plt.hold('off')
plt.savefig(filename)
def draw_basis_functions():
"""Illustrate P1, P2, and P3 basis functions on an element."""
for ext in 'pdf', 'png':
for derivative in (0, 1):
for labels in True, False:
deriv = '' if derivative == 0 else 'd'
philab = '' if not labels else '_lab'
fe_basis_function_figure(
d=1, target_elm=1, N_e=4, derivative=derivative,
filename='fe_%sbasis_p1_4e%s.%s' % (deriv, philab, ext),
labels=labels)
plt.figure()
fe_basis_function_figure(
d=2, target_elm=1, N_e=4, derivative=derivative,
filename='fe_%sbasis_p2_4e%s.%s' % (deriv, philab, ext),
labels=labels)
plt.figure()
fe_basis_function_figure(
d=1, target_elm=1, N_e=5, derivative=derivative,
filename='fe_%sbasis_p1_5e%s.%s' % (deriv, philab, ext),
labels=labels)
plt.figure()
fe_basis_function_figure(
d=3, target_elm=1, N_e=4, derivative=derivative,
filename='fe_%sbasis_p3_4e%s.%s' % (deriv, philab, ext),
labels=labels)
plt.figure()
fe_basis_function_figure(
d=3, target_elm=2, N_e=5, derivative=derivative,
filename='fe_%sbasis_p3_5e%s.%s' % (deriv, philab, ext),
labels=labels)
def draw_sparsity_pattern(elements, num_nodes):
"""Illustrate the matrix sparsity pattern."""
import matplotlib.pyplot as plt
sparsity_pattern = {}
for e in elements:
for i in range(len(e)):
for j in range(len(e)):
sparsity_pattern[(e[i],e[j])] = 1
y = [i for i, j in sorted(sparsity_pattern)]
x = [j for i, j in sorted(sparsity_pattern)]
y.reverse()
plt.plot(x, y, 'bo')
ax = plt.gca()
ax.set_aspect('equal')
plt.axis('off')
plt.plot([-1, num_nodes, num_nodes, -1, -1], [-1, -1, num_nodes, num_nodes, -1], 'k-')
plt.savefig('tmp_sparsity_pattern.pdf')
plt.savefig('tmp_sparsity_pattern.png')
plt.show()
def u_sines():
"""
Plot sine basis functions and a resulting u to
illustrate what it means to use global basis functions.
"""
import matplotlib.pyplot as plt
x = np.linspace(0, 4, 1001)
psi0 = np.sin(2*np.pi/4*x)
psi1 = np.sin(2*np.pi*x)
psi2 = np.sin(2*np.pi*4*x)
#u = 4*psi0 - 0.5*psi1 - 0*psi2
u = 4*psi0 - 0.5*psi1
plt.plot(x, psi0, 'r-', label=r"$\psi_0$")
plt.plot(x, psi1, 'g-', label=r"$\psi_1$")
#plt.plot(x, psi2, label=r"$\psi_2$")
plt.plot(x, u, 'b-', label=r"$u=4\psi_0 - \frac{1}{2}\psi_1$")
plt.legend()
plt.savefig('u_example_sin.pdf')
plt.savefig('u_example_sin.png')
plt.show()
def u_P1():
"""
Plot P1 basis functions and a resulting u to
illustrate what it means to use finite elements.
"""
import matplotlib.pyplot as plt
x = [0, 1.5, 2.5, 3.5, 4]
phi = [np.zeros(len(x)) for i in range(len(x)-2)]
for i in range(len(phi)):
phi[i][i+1] = 1
#u = 5*x*np.exp(-0.25*x**2)*(4-x)
u = [0, 8, 5, 4, 0]
for i in range(len(phi)):
plt.plot(x, phi[i], 'r-') #, label=r'$\varphi_%d$' % i)
plt.text(x[i+1], 1.2, r'$\varphi_%d$' % i)
plt.plot(x, u, 'b-', label='$u$')
plt.legend(loc='upper left')
plt.axis([0, x[-1], 0, 9])
plt.savefig('u_example_P1.png')
plt.savefig('u_example_P1.pdf')
# Mark elements
for xi in x[1:-1]:
plt.plot([xi, xi], [0, 9], 'm--')
# Mark nodes
#plt.plot(x, np.zeros(len(x)), 'ro', markersize=4)
plt.savefig('u_example_P1_welms.png')
plt.savefig('u_example_P1_welms.pdf')
plt.show()
if __name__ == '__main__':
import sys
if len(sys.argv) == 1:
print 'Usage: %s phi | pattern | u_sines | u_P1 [num_elements] [d] [uniform | random]' % sys.argv[0]
sys.exit(1)
if sys.argv[1] == 'phi':
draw_basis_functions()
elif sys.argv[1] == 'pattern':
num_elements = int(sys.argv[2])
d = int(sys.argv[3])
uniform = sys.argv[4]
nodes, elements = mesh_uniform(num_elements, d, [0, 1])
num_nodes = len(nodes)
# Shuffle nodes in random order if necessary
if uniform == 'random':
global_node_numbering = range(0, num_nodes)
import random
random.shuffle(global_node_numbering)
for e in range(len(elements)):
for r in range(len(elements[e])):
elements[e][r] = global_node_numbering[elements[e][r]]
draw_sparsity_pattern(elements, num_nodes)
elif sys.argv[1] == 'u_sines':
u_sines()
elif sys.argv[1] == 'u_P1':
u_P1()

Xet Storage Details

Size:
7.37 kB
·
Xet hash:
4149b3f5bb1db719209e9291b9fec01ef709f1d41ab2a62708b7c95c2e3b59b8

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