def dirichlet_ex2(n=16, deg=1, plot=True, gauss=4, diag='right'): # <---------------------------- works """ Poisson w/ Dirichlet bc in 2D - P1 conv rate: ~2 - P2 conv rate: ~8 - P3 conv rate: ~.5 (not working) """ print "\nDirichlet ex2 in 2D" # data mesh = UnitSquareMesh(n, n, diag=diag) f = lambda x: -6 * x[0] * x[1] * (1. - x[1]) + 2 * pow(x[0], 3) g = lambda x: x[1] * (1. - x[1]) u_ex = lambda x: x[1] * (1. - x[1]) * pow(x[0], 3) # assemble fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss) A = fs.stiffness() rhs = fs.rhs(f) bc1 = Dirichlet(fs, 0, 'bottom', 'top', 'left') bc2 = Dirichlet(fs, g, 'right') # solve u = fem_solver(fs, A, rhs, [bc1, bc2]) nodes = fs.node_to_coords() if plot: plot_sol(u, nodes, u_ex) # return error and mesh size U_ex = [u_ex(node) for node in nodes] return norm(U_ex - u), mesh.mesh_size()
def integral_test(): mesh = UnitSquareMesh(16, 16) #mesh.set_degree(0) sfns = Lagrange(1, 2) meas = [] for n in range(mesh.n_cells()): cell = mesh.cells(n) vertices = mesh.vertices(n) fe = LagrangeElt(cell, vertices, sfns) a = fe.measure() meas.append(a) ass1 = fe.assemble(derivative=True) E = vertices[[1, 2, 0], :] - vertices[[2, 0, 1], :] ass2 = np.dot(E, E.T) / (4 * a) print "\n-----------------------------------------" print "-----------------------------------------" temp = ass1 - ass2 temp2 = sum(sum(temp)) print temp print "\n", temp2 print np.isclose(temp2, 0) print "\n-----------------------------------------" #f = lambda x: x[0] + x[1] f = lambda x: 1. c = [sum(vertices[:, 0]), sum(vertices[:, 1])] rhs = fe.rhs(f) rhs2 = f(c) * a / 3 print rhs print rhs2 print np.isclose(sum(rhs - rhs2), 0) print "measure of domain: ", sum(meas)
def dirichlet_ex1(n=16, deg=1, plot=True, gauss=4, diag='right'): # <---------------------------- works """ Poisson w/ homogenous Dirichlet bc in 2D - P1 conv rate: ~2 - P2 conv rate: ~8 - P3 conv rate: ~.5 (not working) """ print "\nDirichlet ex1 in 2D" # data mesh = UnitSquareMesh(n, n, diag=diag) f = lambda x: 32. * (x[1] * (1. - x[1]) + x[0] * (1. - x[0])) u_ex = lambda x: 16. * x[0] * (1. - x[0]) * x[1] * (1. - x[1]) # assemble fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss) A = fs.stiffness() rhs = fs.rhs(f) # solve w/ homogenous Dirichlet bc bc = Dirichlet(fs) u = fem_solver(fs, A, rhs, bc) nodes = fs.node_to_coords() if plot: plot_sol(u, nodes, u_ex) # return error and mesh size U_ex = [u_ex(node) for node in nodes] return norm(U_ex - u), mesh.mesh_size()
def boundary_integral_test(): """ boundary integral test """ import math mesh = UnitSquareMesh(1, 1) boundary = mesh.get_bdata() bvertices = mesh.bvertices() # bottom name = 'bottom' vertices = bvertices[name] fe = FiniteElement() fe.initialize(1) fe.set_vertices(vertices[0]) f = lambda x: x[0]**2 exact = [1. / 12, 1. / 4] #f = lambda x: math.sin(x[0]); exact = [1-math.sin(1), math.sin(1) - math.cos(1)] rhs = fe.rhs(f) assert np.allclose(rhs - exact, 0) # right name = 'right' vertices = bvertices[name] fe.set_vertices(vertices[0]) #f = lambda x: x[1]**2; exact = [1./12, 1./4] f = lambda x: math.sin(x[1]) exact = [1 - math.sin(1), math.sin(1) - math.cos(1)] rhs = fe.rhs(f) assert np.allclose(rhs - exact, 0) # top name = 'top' vertices = bvertices[name] fe.set_vertices(vertices[0]) #f = lambda x: x[0]**2; exact = [1./4, 1./12] f = lambda x: math.sin(x[0]) exact = [math.sin(1) - math.cos(1), 1 - math.sin(1)] rhs = fe.rhs(f) assert np.allclose(rhs - exact, 0) # left name = 'left' vertices = bvertices[name] fe.set_vertices(vertices[0]) #f = lambda x: x[1]**2; exact = [1./4, 1./12] f = lambda x: math.sin(x[1]) exact = [math.sin(1) - math.cos(1), 1 - math.sin(1)] rhs = fe.rhs(f) assert np.allclose(rhs - exact, 0) print "Boundary integral test OK."
def rt_test(): mesh = UnitSquareMesh(2, 2) #mesh.plot() rt = RTElt(mesh) n2e = rt.nodes_to_element() assert rt.n_edges() == 16, 'n_edges failed.' ext_edges = [[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0]] n2e_ee_fasit = [0, 2, 2, 6, 7, 5, 5, 1] int_edges = [[0, 4], [1, 4], [1, 5], [3, 4], [4, 5], [3, 7], [4, 7], [4, 8]] n2e_ie_fasit = [1, 0, 3, 4, 6, 5, 4, 7] i = 0 for ee in ext_edges: assert n2e[ee[0], ee[1]] == n2e_ee_fasit[i], "nodes to elt ext failed." i += 1 i = 0 for ie in int_edges: assert n2e[ie[0], ie[1]] == n2e_ie_fasit[i], "nodes to elt int failed" i += 1 """ ------------- nodes to element seems to be OK ------------- """ n2e = rt.nodes_to_edge() n2e_ee_fasit = [0, 1, 7, 14, 15, 12, 9, 2] n2e_ie_fasit = [3, 4, 6, 5, 8, 10, 11, 13] i = 0 for ee in ext_edges: assert n2e[ee[0], ee[1]] == n2e_ee_fasit[i], "nodes to edge ext failed." i += 1 i = 0 for ie in int_edges: assert n2e[ie[0], ie[1]] == n2e_ie_fasit[i], "nodes to edge int failed." i += 1 """ ------------- nodes to edge seems to be OK ------------- """ e2e = rt.edge_to_element() n_edges = rt.n_edges() edges = [[0,1], [1,2], [0,3], [0,4], [1,4], [3,4], [1,5],\ [2,5], [4,5], [3,6], [3,7], [4,7], [6,7], [4,8], [5,8], [7,8]] e2e_fasit = [[0,-1], [2,-1], [1,-1], [0,1], [0,3], [1,4], [2,3], [2,-1],\ [3,6], [5,-1], [4,5], [4,7], [5,-1], [6,7], [6,-1], [7,-1]] for j in xrange(n_edges): assert all(e2e[j, [2, 3]] == e2e_fasit[j]), 'edge to element failed.' """ ------------- edge to element seems to be OK ------------- """
def measure_test(): """ finite element measure test """ n = 3 tri_measure = pow(1. / n, 2) / 2 int_measure = 1. / n """ ---------------- 2D test ---------------- """ mesh = UnitSquareMesh(n, n) fe = FiniteElement() fe.initialize(mesh.dim()) vs = mesh.elt_to_vcoords() # 2D measure test for v in vs: fe.set_vertices(v) assert np.isclose(fe.measure() - tri_measure, 0), '2D measure test failed.' """ ---------------- 2D edge ---------------- """ nodes_to_coord, elts_to_nodes = mesh.get_data() boundary = mesh.get_bdata() bv = mesh.bvertices() fe.initialize(1) # 2D edge measure test for key in bv.keys(): vs = bv[key] for v in vs: fe.set_vertices(v) assert np.isclose( fe.measure() - int_measure, 0), '2D edge measure test ({}) failed.'.format(key) # det = abs(np.linalg.det(fe._FiniteElement__a)) # assert np.isclose(det - int_measure,0), '2D edge determinant test ({}) failed.'.format(key) """ ---------------- 1D test ---------------- """ mesh = UnitIntMesh(n) fe = FiniteElement() fe.initialize(mesh.dim()) vs = mesh.elt_to_vcoords() # 1D measure test for v in vs: fe.set_vertices(v) assert np.isclose(fe.measure() - int_measure, 0), '1D measure test failed.' # det = abs(np.linalg.det(fe._FiniteElement__a)) # assert np.isclose(det - int_measure,0), '1D determinant test failed.' print "Measure test OK."
def neuman_ex1(n=16, deg=1, plot=True, gauss=4, diag='right'): """ Poisson w/ Neuman bc in 2D ill conditioned -> use CG - P1 conv rate: ~2 - P2 conv rate: ~6 - P3 conv rate: ~.5 (not working)""" print "\nNeuman ex1 in 2D" # data mesh = UnitSquareMesh(n, n, diag=diag) c = 2 * math.pi f = lambda x: 2 * pow(c, 2) * math.sin(c * (x[0] + x[1])) u_ex = lambda x: math.sin(c * (x[0] + x[1])) g_bottom = lambda x: -c * math.cos(c * x[0]) g_right = lambda x: c * math.cos(c * (1. + x[1])) g_top = lambda x: c * math.cos(c * (1. + x[0])) g_left = lambda x: -c * math.cos(c * x[1]) # assemble fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss) A = fs.stiffness() rhs = fs.rhs(f) bottom = fs.assemble_boundary(g_bottom, 'bottom') right = fs.assemble_boundary(g_right, 'right') top = fs.assemble_boundary(g_top, 'top') left = fs.assemble_boundary(g_left, 'left') rhs += bottom + right + top + left #solve u = fem_solver(fs, A, rhs, CG=True) # u, info = cg(A, rhs) # if info == 0: # print "CG convergence OK" # else: # print "failed to converge" nodes = fs.node_to_coords() if plot: plot_sol(u, nodes, u_ex) # return error and mesh size U_ex = [u_ex(node) for node in nodes] return norm(U_ex - u), mesh.mesh_size()
def edge_mapping_test(): mesh = UnitSquareMesh() mesh.set_degree(0) sfns = Lagrange(0, 1) names = mesh.boundary_names(True) for name in names: print "\n" + name.upper() + ":\n" cells = mesh.boundary(name) vertices = mesh.edge_vertices(name) for n in range(len(cells)): cell = cells[n] vertex = vertices[n] print "cell {}: {}".format(n, cell) print "vertices:\n", vertex fe = LagrangeElt(cell, vertex, sfns) print "map to ref: ", [-1.] - fe.map_to_ref( vertex[0]), [1.] - fe.map_to_ref(vertex[1]) print "map to elt: ", vertex[0] - fe.map_to_elt( [-1.]), vertex[1] - fe.map_to_elt([1.]) print "measure: ", fe.measure() print "assemble: ", fe.assemble(gauss=4) print "rhs: ", fe.rhs(1, gauss=4) print "integrate: ", fe.integrate(1, gauss=4) print "-------------------------------------------------------------------------"
def neuman_ex3(n=16, deg=1, plot=True, gauss=4, diag='right'): # <---------------------------- works """ Poisson w/ homogenous Neuman bc in 2D ill conditioned -> use CG - P1 conv rate: ~2.3 - P2 conv rate: ~6 - P3 conv rate: ~.5 (not working)""" print "\nNeuman ex3 in 2D" # data mesh = UnitSquareMesh(n, n, diag=diag) pi = math.pi f = lambda x: pi * (math.cos(pi * x[0]) + math.cos(pi * x[1])) u_ex = lambda x: (math.cos(pi * x[0]) + math.cos(pi * x[1])) / pi # assemble fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss) A = fs.stiffness() rhs = fs.rhs(f) # solve u = fem_solver(fs, A, rhs, CG=True) # u, info = cg(A,rhs) # if info == 0: # print "CG convergence OK" # else: # print "failed to converge" nodes = fs.node_to_coords() if plot: plot_sol(u, nodes, u_ex) U_ex = [u_ex(node) for node in nodes] # return error and mesh size return norm(U_ex - u), mesh.mesh_size()
def mixed_ex2(n=16, deg=1, plot=True, gauss=4, diag='right'): # <---------------------------- works """ Poisson w/ mixed bc in 2D P1 conv rate: ~2.1 P2 conv rate: ~6 P3 conv rate: ~.5 (not working) """ print "\nMixed bc example in 2D" # data mesh = UnitSquareMesh(n, n, diag=diag) f = lambda x: 2 * (2 * pow(x[1], 3) - 3 * pow(x[1], 2) + 1.) - 6 * ( 1. - pow(x[0], 2)) * (2 * x[1] - 1.) g = lambda x: 2 * pow(x[1], 3) - 3 * pow(x[1], 2) + 1. u_ex = lambda x: (1. - pow(x[0], 2)) * (2 * pow(x[1], 3) - 3 * pow( x[1], 2) + 1.) # assemble fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss) A = fs.stiffness() rhs = fs.rhs(f) bc1 = Dirichlet(fs, 0, 'right') bc2 = Dirichlet(fs, g, 'left') # solve (homogenous Neuman on top, bottom) u = fem_solver(fs, A, rhs, [bc1, bc2]) nodes = fs.node_to_coords() if plot: plot_sol(u, nodes, u_ex) U_ex = [u_ex(node) for node in nodes] # return error and mesh size return norm(U_ex - u), mesh.mesh_size()
def boundary_map_test(): """ boundary mapping test """ mesh = UnitSquareMesh(4, 4) fe = FiniteElement() fe.initialize(1) bvertices = mesh.bvertices() for name in bvertices.keys(): vertices = np.array(bvertices[name]) # map to ref for i in xrange(len(vertices)): vertex = vertices[i] fe.set_vertices(vertex) left = fe.map_to_ref(vertex[0]) right = fe.map_to_ref(vertex[1]) mid = fe.map_to_ref((vertex[0] + vertex[1]) / 2) assert np.allclose( np.array([[-1, 0], [1, 0]]) - [left, right], 0) and np.allclose(np.array([0, 0]) - mid, 0) #print "interval: [{}, {}]. mid: {}".format(left[0], right[0], mid[0]) # map to elt for i in xrange(len(vertices)): vertex = vertices[i] fe.set_vertices(vertex) left = fe.map_to_elt([-1, 0]) mid = fe.map_to_elt([0, 0]) right = fe.map_to_elt([1, 0]) m = sum(vertex) / 2 assert np.allclose(vertex - [left, right], 0) and np.allclose( m - mid, 0) print "Boundary mapping test OK."
def p0_test(): """ test with P0 element """ u_ex = lambda x: 16. * x[0] * (1. - x[0]) * x[1] * (1. - x[1] ) # exact solution mesh = UnitSquareMesh(16, 16) fs = FunctionSpace(mesh, FiniteElement('lagrange', 0), gauss=4) A = fs.mass() rhs = fs.rhs(u_ex) #u = spsolve(A,rhs) #bc = Dirichlet(fs) u = fem_solver(fs, A, rhs, bcs=bc) plot_sol(u, fs.node_to_coords(), u_ex)
def poisson_test_2d(): """ Poisson problem 2D test with homogenous Dirichlet bc """ u_ex = lambda x: 16. * x[0] * (1. - x[0]) * x[1] * (1. - x[1] ) # exact solution f = lambda x: 32. * (x[1] * (1. - x[1]) + x[0] * (1. - x[0])) # right hand side mesh = UnitSquareMesh(16, 16, diag='right') #mesh = Gmesh('Meshes/square_P2.msh') fs = FunctionSpace(mesh, FiniteElement('lagrange', deg=1), gauss=4) A = fs.stiffness() rhs = fs.rhs(f) bc = Dirichlet(fs) u = fem_solver(fs, A, rhs, bc) plot_sol(u, fs.node_to_coords(), u_ex)
def mixed_test(): """ Poisson problem 2D test with Neuman bc enforced by Lagrange multiplier, using mixed P1-P0 elements: ------------------------------------------------------------------ find (u,c) such that (grad u, grad v) + (c,v) = (f,v) + (g,v)_gamma, forall v (P1) (u,d) = 0, forall d (P0) ------------------------------------------------------------------ """ g = lambda x: -math.sin(math.pi * x[0]) # Neuman bc f = lambda x: 10 * math.exp(-(pow(x[0] - .5, 2) + pow(x[1] - .5, 2)) / .02) # right hand side mesh = UnitSquareMesh(32, 32) # mesh me = FiniteElement('lagrange', 1) * FiniteElement('lagrange', 0) # mixed element fs = FunctionSpace(mesh, me, gauss=4) # mixed space Auu = fs.stiffness() # u stiffness matrix Auc = fs.assemble(derivative=[False, False], n=0, m=1) # mixed mass matrix rhs_u = fs.rhs(f) + fs.assemble_boundary(g) # right hand side for u n = fs.n_nodes(0) m = fs.n_nodes(1) n_nodes = n + m print "n = {} (Solution), m = {} (Lagrange)".format(n, m) print "Auu: ", Auu.shape print "Auc: ", Auc.shape # assemble global linear system A = np.zeros((n_nodes, n_nodes)) A[:n, :n] = Auu A[:n, n:] = Auc A[n:, :n] = Auc.T rhs = np.zeros(n_nodes) rhs[:n] = rhs_u u, c = fem_solver(fs, A, rhs, CG=True) print "u: ", u.shape print "c: ", c.shape plot_sol(u, fs.node_to_coords(0), contour=True, name='Solution') plot_sol(c, fs.node_to_coords(1), contour=True, name='Lagrange')
def edge_intergral_test2(): import math pi = math.pi square = UnitSquareMesh(16, 16) bottom = square.bottom() bottomv = square.edge_vertices('bottom') right = square.right() rightv = square.edge_vertices('right') top = square.top() topv = square.edge_vertices('top') left = square.bottom() leftv = square.edge_vertices('left') intv = UnitIntMesh(16) sfns = Lagrange(1, 1) gauss = 8 # bottom test ints1 = [] ints2 = [] f = lambda x: math.sin(pi * x[0]) exact = 2 / pi for n in range(intv.n_cells()): fe1 = LagrangeElt(intv.cells(n), intv.vertices(n), sfns) ints1.append(fe1.integrate(f, gauss)) fe2 = LagrangeElt(bottom[n], bottomv[n], sfns) ints2.append(fe2.integrate(f, gauss)) ints1 = np.array(ints1) ints2 = np.array(ints2) print "bottom:\n", ints1 - ints2 print "check: ", exact - sum(ints1), exact - sum(ints2) # right test ints2 = [] f = lambda x: math.sin(pi * x[1]) for n in range(intv.n_cells()): fe2 = LagrangeElt(right[n], rightv[n], sfns) ints2.append(fe2.integrate(f, gauss)) print "right:\n", ints1 - ints2 print "check: ", exact - sum(ints1), exact - sum(ints2) # top test ints2 = [] f = lambda x: math.sin(pi * x[0]) for n in range(intv.n_cells()): fe2 = LagrangeElt(top[n], topv[n], sfns) ints2.append(fe2.integrate(f, gauss)) ints2.reverse() print "top:\n", ints1 - ints2 print "check: ", exact - sum(ints1), exact - sum(ints2) # left test ints2 = [] f = lambda x: math.sin(pi * x[1]) for n in range(intv.n_cells()): fe2 = LagrangeElt(left[n], leftv[n], sfns) ints2.append(fe2.integrate(f, gauss)) ints2.reverse() print "left:\n", ints1 - ints2 print "sums: ", exact - sum(ints1), exact - sum(ints2)
def affine_mapping_test(): """ affine mapping test """ """ ---------------- 2D test ---------------- """ mesh = UnitSquareMesh(8, 8) vs = mesh.elt_to_vcoords() fe = FiniteElement() fe.initialize(mesh.dim()) # 2D map to elt test for v in vs: fe.set_vertices(v) v1 = fe.map_to_elt([0, 0]) v2 = fe.map_to_elt([1, 0]) v3 = fe.map_to_elt([0, 1]) assert np.allclose(v - np.array([v1, v2, v3]), 0), '2D map to elt failed.' # 2D map to ref test for v in vs: fe.set_vertices(v) v1 = fe.map_to_ref(v[0]) v2 = fe.map_to_ref(v[1]) v3 = fe.map_to_ref(v[2]) assert np.allclose( np.array([v1, v2, v3]) - np.array([[0, 0], [1, 0], [0, 1]]), 0), '2D map to ref failed.' """ ---------------- 2D edge ---------------- """ nodes_to_coord, elts_to_nodes = mesh.get_data() boundary = mesh.get_bdata() bv = mesh.bvertices() fe.initialize(1) # 2D map to edge test for key in bv.keys(): vs = bv[key] for v in vs: fe.set_vertices(v) assert np.allclose( v - [fe.map_to_elt([-1, 0]), fe.map_to_elt([1, 0])], 0), '2D map to edge ({}) failed.'.format(key) # 2D edge to ref test for key in bv.keys(): vs = bv[key] for v in vs: fe.set_vertices(v) assert np.allclose(np.array([[-1,0],[1,0]]) - [fe.map_to_ref(v[0]), fe.map_to_ref(v[1])],0),\ '2D edge to ref ({}) failed.'.format(key) """ ---------------- 1D test ---------------- """ mesh = UnitIntMesh(8) vs = mesh.elt_to_vcoords() fe = FiniteElement() fe.initialize(mesh.dim()) # 1D map to elt test for v in vs: fe.set_vertices(v) assert np.allclose( v - [fe.map_to_elt([-1, 0]), fe.map_to_elt([1, 0])], 0), '1D map to elt failed.' # 1D map to ref test for v in vs: fe.set_vertices(v) assert np.allclose( np.array([[-1, 0], [1, 0]]) - [fe.map_to_ref(v[0]), fe.map_to_ref(v[1])], 0), '1D map to ref failed.' print "Affine mapping test OK."