def _calculate_points(function, num_points, dimension, cell_mask=None): """Calculate points in physical space of given function with given number of sampling points at given dimension :arg function: function to be sampled :arg num_points: number of sampling points :arg dimension: dimension of the function :arg cell_mask: Masks for cell node list """ function_space = function.function_space() mesh = function_space.mesh() if mesh.ufl_cell() == Cell('interval'): points = np.linspace(0.0, 1.0, num=num_points, dtype=float).reshape(-1, 1) elif mesh.ufl_cell() == Cell('quadrilateral'): points_1d = np.linspace(0, 1.0, num=num_points, dtype=float).reshape(-1, 1) points = np.array(np.meshgrid(points_1d, points_1d)).T.reshape(-1, 2) elif mesh.ufl_cell() == Cell('triangle'): points_1d = np.linspace(0, 1.0, num=num_points, dtype=float).reshape(-1, 1) points_1d_rev = np.fliplr([points_1d]).reshape(-1) iu = np.triu_indices(num_points) points = np.array(np.meshgrid(points_1d, points_1d_rev)).T[iu] else: raise NotImplementedError("Unsupported cell type %r", mesh.ufl_cell()) y_vals = _calculate_values(function, points, dimension, cell_mask) x_vals = _calculate_values(mesh.coordinates, points, dimension, cell_mask) return x_vals, y_vals
def _two_dimension_triangle_func_val(function, num_sample_points): """Calculate the triangulation and function values for a given 2D function :arg function: 2D function :arg num_sample_points: Number of sampling points. This is not obeyed exactly, but a linear triangulation is created which matches it reasonably well. """ from math import log try: from matplotlib.tri import Triangulation, UniformTriRefiner except ImportError: raise RuntimeError("Matplotlib not importable, is it installed?") if function.function_space().mesh().ufl_cell() == Cell('triangle'): x = np.array([0, 0, 1]) y = np.array([0, 1, 0]) elif function.function_space().mesh().ufl_cell() == Cell('quadrilateral'): x = np.array([0, 0, 1, 1]) y = np.array([0, 1, 0, 1]) else: raise RuntimeError("Unsupported Functionality") base_tri = Triangulation(x, y) refiner = UniformTriRefiner(base_tri) sub_triangles = int(log(num_sample_points, 4)) tri = refiner.refine_triangulation(False, sub_triangles) triangles = tri.get_masked_triangles() x_ref = tri.x y_ref = tri.y num_verts = triangles.max() + 1 num_cells = function.function_space().cell_node_list.shape[0] ref_points = np.dstack([x_ref, y_ref]).reshape(-1, 2) z_vals = _calculate_values(function, ref_points, 2) coords_vals = _calculate_values(function.function_space(). mesh().coordinates, ref_points, 2) Z = z_vals.reshape(-1) X = coords_vals.reshape(-1, 2).T[0] Y = coords_vals.reshape(-1, 2).T[1] add_idx = np.arange(num_cells).reshape(-1, 1, 1) * num_verts all_triangles = (triangles + add_idx).reshape(-1, 3) triangulation = Triangulation(X, Y, triangles=all_triangles) return triangulation, Z
def src_locate_cell(mesh): src = '#include <evaluate.h>\n' src += compile_coordinate_element(mesh.ufl_coordinate_element()) src += make_wrapper(mesh.coordinates, forward_args=["void*", "double*", "int*"], kernel_name="to_reference_coords_kernel", wrapper_name="wrap_to_reference_coords") with open(path.join(path.dirname(__file__), "locate.c")) as f: src += f.read() return src cellname = { Cell("interval"): "interval_1d", Cell("interval", 2): "interval_2d", Cell("interval", 3): "interval_3d", Cell("triangle"): "triangle_2d", Cell("triangle", 3): "triangle_3d", Cell("tetrahedron"): "tetrahedron_3d", Cell("quadrilateral"): "quad_2d", Cell("quadrilateral", 3): "quad_3d", TensorProductCell(Cell("interval"), Cell("interval")): "quad_2d", TensorProductCell(Cell("interval"), Cell("interval"), geometric_dimension=3): "quad_3d", TensorProductCell(Cell("triangle"), Cell("interval")): "prism_3d", TensorProductCell(Cell("quadrilateral"), Cell("interval")): "hex_3d", }
import os from pyop2.logger import warning, RED from pyop2.mpi import MPI import firedrake.functionspace as fs import firedrake.projection as projection __all__ = ['File'] # Dictionary used to translate the cellname of firedrake # to the celltype of evtk module. _cells = {} _cells[Cell("interval")] = hl.VtkLine _cells[Cell("interval", 2)] = hl.VtkLine _cells[Cell("interval", 3)] = hl.VtkLine _cells[Cell("triangle")] = hl.VtkTriangle _cells[Cell("triangle", 3)] = hl.VtkTriangle _cells[Cell("tetrahedron")] = hl.VtkTetra _cells[OuterProductCell(Cell("triangle"), Cell("interval"))] = hl.VtkWedge _cells[OuterProductCell(Cell("triangle", 3), Cell("interval"))] = hl.VtkWedge _cells[Cell("quadrilateral")] = hl.VtkQuad _cells[Cell("quadrilateral", 3)] = hl.VtkQuad _cells[OuterProductCell(Cell("interval"), Cell("interval"))] = hl.VtkQuad _cells[OuterProductCell(Cell("interval", 2), Cell("interval"))] = hl.VtkQuad _cells[OuterProductCell(Cell("interval", 2), Cell("interval"), gdim=3)] = hl.VtkQuad _cells[OuterProductCell(Cell("interval", 3), Cell("interval"))] = hl.VtkQuad _cells[OuterProductCell(Cell("quadrilateral"), Cell("interval"))] = hl.VtkHexahedron _cells[OuterProductCell(Cell("quadrilateral", 3), Cell("interval"))] = hl.VtkHexahedron
def mesh_3D_dolfin(theta=0, ct=CellType.tetrahedron, ext="tetrahedron", num_refinements=0, N0=5): timer = Timer("Create mesh") def find_plane_function(p0, p1, p2): """ Find plane function given three points: http://www.nabla.hr/CG-LinesPlanesIn3DA3.htm """ v1 = np.array(p1) - np.array(p0) v2 = np.array(p2) - np.array(p0) n = np.cross(v1, v2) D = -(n[0] * p0[0] + n[1] * p0[1] + n[2] * p0[2]) return lambda x: np.isclose(0, np.dot(n, x) + D) def over_plane(p0, p1, p2): """ Returns function that checks if a point is over a plane defined by the points p0, p1 and p2. """ v1 = np.array(p1) - np.array(p0) v2 = np.array(p2) - np.array(p0) n = np.cross(v1, v2) D = -(n[0] * p0[0] + n[1] * p0[1] + n[2] * p0[2]) return lambda x: n[0] * x[0] + n[1] * x[1] + D > -n[2] * x[2] tmp_mesh_name = "tmp_mesh.xdmf" r_matrix = rotation_matrix([1 / np.sqrt(2), 1 / np.sqrt(2), 0], -theta) if MPI.COMM_WORLD.rank == 0: # Create two coarse meshes and merge them mesh0 = create_unit_cube(MPI.COMM_SELF, N0, N0, N0, ct) mesh0.geometry.x[:, 2] += 1 mesh1 = create_unit_cube(MPI.COMM_SELF, 2 * N0, 2 * N0, 2 * N0, ct) tdim0 = mesh0.topology.dim num_cells0 = mesh0.topology.index_map(tdim0).size_local cells0 = entities_to_geometry( mesh0, tdim0, np.arange(num_cells0, dtype=np.int32).reshape((-1, 1)), False) tdim1 = mesh1.topology.dim num_cells1 = mesh1.topology.index_map(tdim1).size_local cells1 = entities_to_geometry( mesh1, tdim1, np.arange(num_cells1, dtype=np.int32).reshape((-1, 1)), False) cells1 += mesh0.geometry.x.shape[0] # Concatenate points and cells points = np.vstack([mesh0.geometry.x, mesh1.geometry.x]) cells = np.vstack([cells0, cells1]) cell = Cell(ext, geometric_dimension=points.shape[1]) domain = Mesh(VectorElement("Lagrange", cell, 1)) # Rotate mesh points = np.dot(r_matrix, points.T).T mesh = create_mesh(MPI.COMM_SELF, cells, points, domain) with XDMFFile(MPI.COMM_SELF, tmp_mesh_name, "w") as xdmf: xdmf.write_mesh(mesh) MPI.COMM_WORLD.barrier() with XDMFFile(MPI.COMM_WORLD, tmp_mesh_name, "r") as xdmf: mesh = xdmf.read_mesh() # Refine coarse mesh for i in range(num_refinements): mesh.topology.create_entities(mesh.topology.dim - 2) mesh = refine(mesh, redistribute=True) tdim = mesh.topology.dim fdim = tdim - 1 # Find information about facets to be used in meshtags bottom_points = np.dot( r_matrix, np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]]).T) bottom = find_plane_function(bottom_points[:, 0], bottom_points[:, 1], bottom_points[:, 2]) bottom_facets = locate_entities_boundary(mesh, fdim, bottom) top_points = np.dot( r_matrix, np.array([[0, 0, 2], [1, 0, 2], [0, 1, 2], [1, 1, 2]]).T) top = find_plane_function(top_points[:, 0], top_points[:, 1], top_points[:, 2]) top_facets = locate_entities_boundary(mesh, fdim, top) # Determine interface facets if_points = np.dot( r_matrix, np.array([[0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]]).T) interface = find_plane_function(if_points[:, 0], if_points[:, 1], if_points[:, 2]) i_facets = locate_entities_boundary(mesh, fdim, interface) mesh.topology.create_connectivity(fdim, tdim) top_interface = [] bottom_interface = [] facet_to_cell = mesh.topology.connectivity(fdim, tdim) num_cells = mesh.topology.index_map(tdim).size_local # Find top and bottom interface facets cell_midpoints = compute_midpoints(mesh, tdim, range(num_cells)) top_cube = over_plane(if_points[:, 0], if_points[:, 1], if_points[:, 2]) for facet in i_facets: i_cells = facet_to_cell.links(facet) assert (len(i_cells == 1)) i_cell = i_cells[0] if top_cube(cell_midpoints[i_cell]): top_interface.append(facet) else: bottom_interface.append(facet) # Create cell tags num_cells = mesh.topology.index_map(tdim).size_local cell_midpoints = compute_midpoints(mesh, tdim, range(num_cells)) top_cube_marker = 2 indices = [] values = [] for cell_index in range(num_cells): if top_cube(cell_midpoints[cell_index]): indices.append(cell_index) values.append(top_cube_marker) ct = meshtags(mesh, tdim, np.array(indices, dtype=np.intc), np.array(values, dtype=np.intc)) # Create meshtags for facet data markers = { 3: top_facets, 4: bottom_interface, 9: top_interface, 5: bottom_facets } # , 6: left_facets, 7: right_facets} indices = np.array([], dtype=np.intc) values = np.array([], dtype=np.intc) for key in markers.keys(): indices = np.append(indices, markers[key]) values = np.append(values, np.full(len(markers[key]), key, dtype=np.intc)) sorted_indices = np.argsort(indices) mt = meshtags(mesh, fdim, indices[sorted_indices], values[sorted_indices]) mt.name = "facet_tags" fname = f"meshes/mesh_{ext}_{theta:.2f}.xdmf" with XDMFFile(MPI.COMM_WORLD, fname, "w") as o_f: o_f.write_mesh(mesh) o_f.write_meshtags(ct) o_f.write_meshtags(mt) timer.stop()