def _cooks(cls, **kwargs): mesh = UnitSquareMesh(10, 5) def cooks_domain(x, y): return [48 * x, 44 * (x + y) - 18 * x * y] mesh.coordinates()[:] = np.array(cooks_domain(mesh.coordinates()[:, 0], mesh.coordinates()[:, 1])).transpose() # plot(mesh, interactive=True, axes=True) maxx, minx, maxy, miny = 48, 0, 60, 0 # setup boundary parts llc, lrc, tlc, trc = compile_subdomains(['near(x[0], 0.) && near(x[1], 0.)', 'near(x[0], 48.) && near(x[1], 0.)', 'near(x[0], 0.) && near(x[1], 60.)', 'near(x[0], 48.) && near(x[1], 60.)']) top, bottom, left, right = compile_subdomains([ 'x[0] >= 0. && x[0] <= 48. && x[1] >= 44. && on_boundary', 'x[0] >= 0. && x[0] <= 48. && x[1] <= 44. && on_boundary', 'near(x[0], 0.) && on_boundary', 'near(x[0], 48.) && on_boundary']) # the corners llc.minx = minx llc.miny = miny lrc.maxx = maxx lrc.miny = miny tlc.minx = minx tlc.maxy = maxy trc.maxx = maxx trc.maxy = maxy # the edges top.minx = minx top.maxx = maxx bottom.minx = minx bottom.maxx = maxx left.minx = minx right.maxx = maxx return mesh, {'top':top, 'bottom':bottom, 'left':left, 'right':right, 'llc':llc, 'lrc':lrc, 'tlc':tlc, 'trc':trc, 'all': DomainBoundary()}, 2
def test_meshpool_base_functionality(dim): if dim == 2: mesh1 = UnitSquareMesh(6, 6) mesh2 = UnitSquareMesh(6, 6) mesh3 = UnitSquareMesh(6, 6) mesh4 = UnitSquareMesh(7, 7) elif dim == 3: mesh1 = UnitCubeMesh(6, 6, 6) mesh2 = UnitCubeMesh(6, 6, 6) mesh3 = UnitCubeMesh(6, 6, 6) mesh4 = UnitCubeMesh(7, 7, 7) mp = argmin(norm(mesh3.coordinates() - array([0.5] * dim), axis=1)) mesh3.coordinates()[mp, :] += 0.00001 mesh1 = MeshPool(mesh1) mesh2 = MeshPool(mesh2) mesh3 = MeshPool(mesh3) mesh4 = MeshPool(mesh4) assert mesh1.id() == mesh2.id(), "1!=2" assert mesh1.id() != mesh3.id(), "1==3" assert mesh1.id() != mesh4.id(), "1==4" assert mesh3.id() != mesh4.id(), "3==4" # FIXME: While weak referencing meshes don't work, we can not run the following tests """
def img2funvec(img: np.array) -> np.array: """Takes a 2D array and returns an array suited to assign to piecewise linear approximation on a triangle grid. Each pixel corresponds to one vertex of a triangle mesh. Args: img (np.array): The input array of shape (m, n). Returns: np.array: A vector of shape (m * n,). """ m, n = img.shape # Create mesh and function space. mesh = UnitSquareMesh(m - 1, n - 1) xm = mesh.coordinates().reshape((-1, 2)) # Create function space. V = create_function_space(mesh, 'default') # Evaluate function at vertices. hx, hy = 1 / (m - 1), 1 / (n - 1) x = np.array(np.round(xm[:, 0] / hx), dtype=int) y = np.array(np.round(xm[:, 1] / hy), dtype=int) fv = img[x, y] # Map pixel values to vertices. d2v = dof_to_vertex_map(V) return fv[d2v]
def neumann_elasticity_data(): ''' Return: a bilinear form in the neumann elasticity problem L linear form in therein V function space, where a, L are defined bc homog. dirichlet conditions for case where we want pos. def problem z list of orthonormal vectors in the nullspace of A that form basis of ker(A) ''' mesh = UnitSquareMesh(40, 40) V = VectorFunctionSpace(mesh, 'CG', 1) u = TrialFunction(V) v = TestFunction(V) f = Expression(('sin(pi*x[0])', 'cos(pi*x[1])')) epsilon = lambda u: sym(grad(u)) # Material properties E, nu = 10.0, 0.3 mu, lmbda = Constant(E/(2*(1 + nu))), Constant(E*nu/((1 + nu)*(1 - 2*nu))) sigma = lambda u: 2*mu*epsilon(u) + lmbda*tr(epsilon(u))*Identity(2) a = inner(sigma(u), epsilon(v))*dx L = inner(f, v)*dx # Zero stress bc = DirichletBC(V, Constant((0, 0)), DomainBoundary()) z0 = interpolate(Constant((1, 0)), V).vector() normalize(z0, 'l2') z1 = interpolate(Constant((0, 1)), V).vector() normalize(z1, 'l2') X = mesh.coordinates().reshape((-1, 2)) c0, c1 = np.sum(X, axis=0)/len(X) z2 = interpolate(Expression(('x[1]-c1', '-(x[0]-c0)'), c0=c0, c1=c1), V).vector() normalize(z2, 'l2') z = [z0, z1, z2] # Check that this is orthonormal basis I = np.zeros((3, 3)) for i, zi in enumerate(z): for j, zj in enumerate(z): I[i, j] = zi.inner(zj) print I print la.norm(I-np.eye(3)) assert la.norm(I-np.eye(3)) < 1E-13 return a, L, V, bc, z
def test_ale(self): print "" print "Testing ALE::move(Mesh& mesh0, const Mesh& mesh1)" # Create some mesh mesh = UnitSquareMesh(4, 5) # Make some cell function # FIXME: Initialization by array indexing is probably # not a good way for parallel test cellfunc = CellFunction('size_t', mesh) cellfunc.array()[0:4] = 0 cellfunc.array()[4:] = 1 # Create submeshes - this does not work in parallel submesh0 = SubMesh(mesh, cellfunc, 0) submesh1 = SubMesh(mesh, cellfunc, 1) # Move submesh0 disp = Constant(("0.1", "-0.1")) submesh0.move(disp) # Move and smooth submesh1 accordignly submesh1.move(submesh0) # Move mesh accordingly parent_vertex_indices_0 = \ submesh0.data().array('parent_vertex_indices', 0) parent_vertex_indices_1 = \ submesh1.data().array('parent_vertex_indices', 0) mesh.coordinates()[parent_vertex_indices_0[:]] = \ submesh0.coordinates()[:] mesh.coordinates()[parent_vertex_indices_1[:]] = \ submesh1.coordinates()[:] # If test passes here then it is probably working # Check for cell quality for sure magic_number = 0.28 rmin = MeshQuality.radius_ratio_min_max(mesh)[0] self.assertTrue(rmin > magic_number)
def generate_square(Nelements, length, refinements=0): """ Creates a square mesh of given elements and length with markers on the sides: left, bottom, right and top """ from dolfin import UnitSquareMesh, SubDomain, MeshFunction, Measure, near, refine mesh = UnitSquareMesh(Nelements, Nelements) for i in range(refinements): mesh = refine(mesh) mesh.coordinates()[:] *= length # Subdomains: Solid class Left(SubDomain): def inside(self, x, on_boundary): return near(x[0], 0.0) and on_boundary class Right(SubDomain): def inside(self, x, on_boundary): return near(x[0], length) and on_boundary class Top(SubDomain): def inside(self, x, on_boundary): return near(x[1], length) and on_boundary class Bottom(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0.0) and on_boundary left, right, top, bottom = Left(), Right(), Top(), Bottom() LEFT, RIGHT, TOP, BOTTOM = 1, 2, 3, 4 # Set numbering NONE = 99 # Marker for empty boundary markers = MeshFunction("size_t", mesh, 1) markers.set_all(0) boundaries = (left, right, top, bottom) def_names = (LEFT, RIGHT, TOP, BOTTOM) for side, num in zip(boundaries, def_names): side.mark(markers, num) return mesh, markers, LEFT, RIGHT, TOP, BOTTOM, NONE
def test_vertex_2d(self): mesh = UnitSquareMesh(8, 8) x = mesh.coordinates() min_ = np.min(x, axis=0) max_ = np.max(x, axis=0) tol = 1E-9 # The precision in gmsh isn't great, probably why DOLFIN's # periodic boundary computation is not working # Check x periodicity master = CompiledSubDomain('near(x[0], A, tol)', A=min_[0], tol=tol) slave = CompiledSubDomain('near(x[0], A, tol)', A=max_[0], tol=tol) shift_x = np.array([max_[0]-min_[0], 0]) to_master = lambda x, shift=shift_x: x - shift error, mapping = compute_vertex_periodicity(mesh, master, slave, to_master) self.assertTrue(error < 10*tol) _, mapping = compute_entity_periodicity(1, mesh, master, slave, to_master) self.assertTrue(len(list(mapping.keys())) == 8)
def funvec2img_pb(v: np.array, m: int, n: int) -> np.array: """Takes values of piecewise linear interpolation of a function at the vertices and returns a 2-dimensional array. Each degree of freedom corresponds to one pixel in the array of size (m, n). Args: v (np.array): Values at vertices of triangle mesh. m (int): The number of rows. n (int): The number of columns. Returns: np.array: An array of shape (m, n). """ # Create image. img = np.zeros((m, n)) # Create mesh and function space. mesh = UnitSquareMesh(m - 1, n - 1) xm = mesh.coordinates().reshape((-1, 2)) # Create function space. V = create_function_space(mesh, 'periodic') # Evaluate function at vertices. hx, hy = 1 / (m - 1), 1 / (n - 1) x = np.array(np.round(xm[:, 0] / hx), dtype=int) y = np.array(np.round(xm[:, 1] / hy), dtype=int) # Create image from function. v2d = vertex_to_dof_map(V) values = v[v2d] for (i, j, v) in zip(x, y, values): img[i, j] = v return img
def mesh(Nx=50, Ny=50, **params): m = UnitSquareMesh(Nx, Ny) x = m.coordinates() # x[:] = (x - 0.5) * 2 # x[:] = 0.5*(cos(pi*(x-1.) / 2.) + 1.) return m
if __name__ == '__main__': #from dolfin import * from dolfin import (Expression, UnitSquareMesh, errornorm) #expr_scalar = Expression("1+x[0]*x[1]", degree=1) #expr_vector = Expression(("1+x[0]*x[1]", "x[1]-2"), degree=1) expr_scalar = Expression("1+x[0]", degree=1) expr_vector = Expression(("1+x[0]", "x[1]-2"), degree=1) mesh = UnitSquareMesh(12,12) submesh = UnitSquareMesh(6,6) submesh.coordinates()[:] /= 2.0 submesh.coordinates()[:] += 0.2 Q = FunctionSpace(mesh, "CG", 1) V = VectorFunctionSpace(mesh, "CG", 1) Q_sub = FunctionSpace(submesh, "CG", 1) V_sub = VectorFunctionSpace(submesh, "CG", 1) u = interpolate(expr_scalar, Q) v = interpolate(expr_vector, V) u_sub = interpolate(expr_scalar, Q_sub) v_sub = interpolate(expr_vector, V_sub) from fenicstools import interpolate_nonmatching_mesh
mesh_f[child] = graph_colors[parent] # TODO: put tikz here File('%s.pvd' % name) << mesh_f code = tikzify_2d_mesh(facet_f, facet_style_map, mesh_f, cell_style_map) with open('%s.tex' % name, 'w') as out: out.write(code) # --- from dolfin import * mesh = UnitIntervalMesh(10) x = mesh.coordinates() for cell in cells(mesh): assert abs(simplex_area(x[cell.entities(0)]) - cell.volume()) < 1E-15 p = cell.midpoint().array()[:1] assert point_is_inside(p, x[cell.entities(0)], 1E-10) mesh = UnitSquareMesh(10, 10) x = mesh.coordinates() for cell in cells(mesh): assert abs(simplex_area(x[cell.entities(0)]) - cell.volume()) < 1E-15 p = cell.midpoint().array()[:2] assert point_is_inside(p, x[cell.entities(0)], 1E-10) mesh = UnitCubeMesh(3, 3, 3)
def test_multiplication(self): print( '== testing multiplication of system matrix for problem of weighted projection ====' ) for dim, pol_order in itertools.product([2, 3], [1, 2]): N = 2 # no. of elements print('dim={0}, pol_order={1}, N={2}'.format(dim, pol_order, N)) # creating MESH and defining MATERIAL if dim == 2: mesh = UnitSquareMesh(N, N) m = Expression("1+10*16*x[0]*(1-x[0])*x[1]*(1-x[1])", degree=4) # material coefficients elif dim == 3: mesh = UnitCubeMesh(N, N, N) m = Expression("1+10*16*x[0]*(1-x[0])*(1-x[1])*x[2]", degree=1) # material coefficients mesh.coordinates()[:] += 0.1 * np.random.random( mesh.coordinates().shape) # mesh perturbation V = FunctionSpace(mesh, "CG", pol_order) # original FEM space W = FunctionSpace(mesh, "DG", 2 * (pol_order - 1)) # double-grid space print('assembling local matrices for DoGIP...') Bhat = get_Bhat( dim, pol_order, problem=1 ) # interpolation between V on W on a reference element AT_dogip = get_A_T(m, V, W, problem=1) dofmapV = V.dofmap() def system_multiplication_DoGIP(AT_dogip, Bhat, u_vec): # matrix-vector mutliplication in DoGIP Au = np.zeros_like(u_vec) for ii, cell in enumerate(cells(mesh)): ind = dofmapV.cell_dofs(ii) # local to global map Bu = Bhat.dot(u_vec[ind]) ABu = np.einsum('rsj,sj->rj', AT_dogip[ii], Bu) Au[ind] += np.einsum('rjl,rj->l', Bhat, ABu) return Au print('assembling system matrix for FEM') u, v = TrialFunction(V), TestFunction(V) Asp = assemble(m * inner(grad(u), grad(v)) * dx, tensor=EigenMatrix()) Asp = Asp.sparray() # sparse FEM matrix print('multiplication...') ur = Function(V) # creating random vector ur_vec = 10 * np.random.random(V.dim()) ur.vector().set_local(ur_vec) Au_DoGIP = system_multiplication_DoGIP( AT_dogip, Bhat, ur_vec) # DoGIP multiplication Auex = Asp.dot(ur_vec) # FEM multiplication with sparse matrix # testing the difference between DoGIP and FEniCS self.assertAlmostEqual(0, np.linalg.norm(Auex - Au_DoGIP)) print('...ok')
def test_DoGIP_vs_FEniCS(self): print( '\n== testing DoGIP vs. FEniCS for problem of weighted projection ====' ) for dim, pol_order in itertools.product([2, 3], [1, 2]): print('dim={}; pol_order={}'.format(dim, pol_order)) N = 2 # no. of elements # creating MESH, defining MATERIAL and SOURCE if dim == 2: mesh = UnitSquareMesh(N, N) m = Expression("1+10*16*x[0]*(1-x[0])*x[1]*(1-x[1])", degree=4) f = Expression("80*x[0]*(0.5-x[0])*(1.-x[0])*x[1]*(1.-x[1])", degree=5) elif dim == 3: mesh = UnitCubeMesh(N, N, N) m = Expression("1+10*16*x[0]*(1-x[0])*(1-x[1])*x[2]", degree=4) f = Expression("80*x[0]*(0.5-x[0])*(1.-x[0])*x[1]*(1.-x[1])", degree=5) mesh.coordinates()[:] += 0.1 * np.random.random( mesh.coordinates().shape) # mesh perturbation ## standard approach with FEniCS ############################################# V = FunctionSpace(mesh, "CG", pol_order) # original FEM space bc = DirichletBC(V, Constant(0.0), lambda x, on_boundary: on_boundary) u, v = TrialFunction(V), TestFunction(V) u_fenics = Function(V) # the vector for storing the solution solve(m * inner(grad(u), grad(v)) * dx == f * v * dx, u_fenics, bc) # solution by FEniCS ## DoGIP - double-grid integration with interpolation-projection ############# W = FunctionSpace(mesh, "DG", 2 * (pol_order - 1)) # double-grid space Wvector = VectorFunctionSpace( mesh, "DG", 2 * (pol_order - 1)) # vector variant of double-grid space w = TestFunction(W) A_dogip = assemble( m * w * dx).get_local() # diagonal matrix of material coefficients A_dogip_full = np.einsum( 'i,jk->ijk', A_dogip, np.eye(dim)) # block-diagonal mat. for non-isotropic mat. bv = assemble(f * v * dx) bc.apply(bv) b = bv.get_local() # vector of right-hand side # assembling global interpolation-projection matrix B B = get_B(V, Wvector, problem=1) # solution to DoGIP problem def Afun(x): Axd = np.einsum('...jk,...j', A_dogip_full, B.dot(x).reshape((-1, dim))) Afunx = B.T.dot(Axd.ravel()) Afunx[list(bc.get_boundary_values() )] = 0 # application of Dirichlet BC return Afunx Alinoper = linalg.LinearOperator((b.size, b.size), matvec=Afun, dtype=np.float) # system matrix x, info = linalg.cg(Alinoper, b, x0=np.zeros_like(b), tol=1e-8, maxiter=1e2) # conjugate gradients # testing the difference between DoGIP and FEniCS self.assertAlmostEqual( 0, np.linalg.norm(u_fenics.vector().get_local() - x)) print('...ok')
def mesh(Nx=160, Ny=160, **params): m = UnitSquareMesh(Nx, Ny) x = m.coordinates() #x[:] = (x - 0.5) * 2 #x[:] = 0.5*(cos(pi*(x-1.) / 2.) + 1.) return m
if calculate in [-1, 0, 1]: Ne = int(Ne_max / p) else: Ne = int(Ne_max) print('-- p = {0}, N = {1} --------'.format(p, Ne)) filen_data = 'data/t%d_d%d_Nm%d_p%.2d_Ne%.3d' % (problem, dim, Ne_max, p, Ne) if dim == 2: mesh = UnitSquareMesh(Ne, Ne) Amat = Expression("1+10*exp(x[0])*exp(x[1])", degree=2) elif dim == 3: mesh = UnitCubeMesh(Ne, Ne, Ne) Amat = Expression("1+100*exp(x[0])*exp(x[1])*x[2]*x[1]", degree=3) mesh.coordinates()[:] += 0.1 * np.random.random( mesh.coordinates().shape) # mesh perturbation V = FunctionSpace(mesh, 'CG', p) print('V.dim = {0}'.format(V.dim())) if calculate in [1, -1]: ut, vt = TrialFunction(V), TestFunction(V) print('generating matrices A, Ad, A_T') if problem == 0: AG = assemble(Amat * ut * vt * dx, tensor=EigenMatrix()) A_T = get_A_T_empty(V, problem=problem, full=False) else: AG = assemble(inner(Amat * grad(ut), grad(vt)) * dx, tensor=EigenMatrix()) A_T = get_A_T_empty(V, problem=problem, full=False)