def test_cylinder(): radius = 1.0 z0 = 0.0 z1 = 1.0 edge_length = 0.1 s0 = pygalmesh.Cylinder(z0, z1, radius, edge_length) mesh = pygalmesh.generate_mesh(s0, cell_size=0.1, edge_size=edge_length, verbose=False) tol = 1.0e-1 assert abs(max(mesh.points[:, 0]) - radius) < tol assert abs(min(mesh.points[:, 0]) + radius) < tol assert abs(max(mesh.points[:, 1]) - radius) < tol assert abs(min(mesh.points[:, 1]) + radius) < tol assert abs(max(mesh.points[:, 2]) - z1) < tol assert abs(min(mesh.points[:, 2]) + z0) < tol vol = sum( helpers.compute_volumes(mesh.points, mesh.get_cells_type("tetra"))) ref_vol = numpy.pi * radius * radius * (z1 - z0) assert abs(vol - ref_vol) < tol
def test_balls_union(): radius = 1.0 displacement = 0.5 s0 = pygalmesh.Ball([displacement, 0, 0], radius) s1 = pygalmesh.Ball([-displacement, 0, 0], radius) u = pygalmesh.Union([s0, s1]) a = numpy.sqrt(radius**2 - displacement**2) edge_size = 0.1 n = int(2 * numpy.pi * a / edge_size) circ = [[ 0.0, a * numpy.cos(i * 2 * numpy.pi / n), a * numpy.sin(i * 2 * numpy.pi / n) ] for i in range(n)] circ.append(circ[0]) mesh = pygalmesh.generate_mesh(u, feature_edges=[circ], cell_size=0.15, edge_size=edge_size, verbose=False) assert abs(max(mesh.points[:, 0]) - (radius + displacement)) < 0.02 assert abs(min(mesh.points[:, 0]) + (radius + displacement)) < 0.02 assert abs(max(mesh.points[:, 1]) - radius) < 0.02 assert abs(min(mesh.points[:, 1]) + radius) < 0.02 assert abs(max(mesh.points[:, 2]) - radius) < 0.02 assert abs(min(mesh.points[:, 2]) + radius) < 0.02 vol = sum(helpers.compute_volumes(mesh.points, mesh.cells["tetra"])) h = radius - displacement ref_vol = 2 * (4.0 / 3.0 * numpy.pi * radius**3 - h * numpy.pi / 6.0 * (3 * a**2 + h**2)) assert abs(vol - ref_vol) < 0.1 return
def test_cuboids_union(): c0 = pygalmesh.Cuboid([0, 0, -0.5], [3, 3, 0.5]) c1 = pygalmesh.Cuboid([1, 1, -2], [2, 2, 2]) u = pygalmesh.Union([c0, c1]) mesh = pygalmesh.generate_mesh(u, cell_size=0.2, edge_size=0.2, verbose=False) # filter the vertices that belong to cells verts = mesh.points[numpy.unique(mesh.cells["tetra"])] tol = 1.0e-2 assert abs(max(verts[:, 0]) - 3.0) < tol assert abs(min(verts[:, 0]) - 0.0) < tol assert abs(max(verts[:, 1]) - 3.0) < tol assert abs(min(verts[:, 1]) - 0.0) < tol assert abs(max(verts[:, 2]) - 2.0) < tol assert abs(min(verts[:, 2]) + 2.0) < tol vol = sum(helpers.compute_volumes(mesh.points, mesh.cells["tetra"])) assert abs(vol - 12.0) < 0.1 return
def test_cuboids_intersection(): c0 = pygalmesh.Cuboid([0, 0, -0.5], [3, 3, 0.5]) c1 = pygalmesh.Cuboid([1, 1, -2], [2, 2, 2]) u = pygalmesh.Intersection([c0, c1]) # In CGAL, feature edges must not intersect, and that's a problem here: The # intersection edges of the cuboids share eight points with the edges of # the tall and skinny cuboid. # eps = 1.0e-2 # extra_features = [ # [[1.0, 1.0 + eps, 0.5], [1.0, 2.0 - eps, 0.5]], # [[1.0 + eps, 2.0, 0.5], [2.0 - eps, 2.0, 0.5]], # [[2.0, 2.0 - eps, 0.5], [2.0, 1.0 + eps, 0.5]], # [[2.0 - eps, 1.0, 0.5], [1.0 + eps, 1.0, 0.5]], # ] mesh = pygalmesh.generate_mesh(u, cell_size=0.1, edge_size=0.1, verbose=False) # filter the vertices that belong to cells verts = mesh.points[numpy.unique(mesh.cells["tetra"])] tol = 1.0e-2 assert abs(max(verts[:, 0]) - 2.0) < tol assert abs(min(verts[:, 0]) - 1.0) < tol assert abs(max(verts[:, 1]) - 2.0) < tol assert abs(min(verts[:, 1]) - 1.0) < tol assert abs(max(verts[:, 2]) - 0.5) < 0.05 assert abs(min(verts[:, 2]) + 0.5) < 0.05 vol = sum(helpers.compute_volumes(mesh.points, mesh.cells["tetra"])) assert abs(vol - 1.0) < 0.05 return
def ball(h): s = pygalmesh.Ball([0, 0, 0], 1.0) # The circumradius of a regular tetrahedron with the given edge_size is sqrt(3 / 8) # * edge_size ~= 0.61 * edge_size. Relax it a bit and just use h. mesh = pygalmesh.generate_mesh(s, max_cell_circumradius=h, verbose=False) return mesh.points, mesh.get_cells_type("tetra")
def test_custom_function(): class Hyperboloid(pygalmesh.DomainBase): def __init__(self, edge_size): super(Hyperboloid, self).__init__() self.z0 = -1.0 self.z1 = 1.0 self.waist_radius = 0.5 self.edge_size = edge_size return def eval(self, x): if self.z0 < x[2] and x[2] < self.z1: return x[0]**2 + x[1]**2 - (x[2]**2 + self.waist_radius)**2 return 1.0 def get_bounding_sphere_squared_radius(self): z_max = max(abs(self.z0), abs(self.z1)) r_max = z_max**2 + self.waist_radius return r_max * r_max + z_max * z_max def get_features(self): radius0 = self.z0**2 + self.waist_radius n0 = int(2 * numpy.pi * radius0 / self.edge_size) circ0 = [[ radius0 * numpy.cos((2 * numpy.pi * k) / n0), radius0 * numpy.sin((2 * numpy.pi * k) / n0), self.z0 ] for k in range(n0)] circ0.append(circ0[0]) radius1 = self.z1**2 + self.waist_radius n1 = int(2 * numpy.pi * radius1 / self.edge_size) circ1 = [[ radius1 * numpy.cos((2 * numpy.pi * k) / n1), radius1 * numpy.sin((2 * numpy.pi * k) / n1), self.z1 ] for k in range(n1)] circ1.append(circ1[0]) return [circ0, circ1] edge_size = 0.12 d = Hyperboloid(edge_size) pygalmesh.generate_mesh(d, 'out.mesh', cell_size=0.1, edge_size=edge_size, verbose=False) vertices, cells, _, _, _ = meshio.read('out.mesh') # TODO check the reference values tol = 1.0e-1 assert abs(max(vertices[:, 0]) - 1.4) < tol assert abs(min(vertices[:, 0]) + 1.4) < tol assert abs(max(vertices[:, 1]) - 1.4) < tol assert abs(min(vertices[:, 1]) + 1.4) < tol assert abs(max(vertices[:, 2]) - 1.0) < tol assert abs(min(vertices[:, 2]) + 1.0) < tol vol = sum(compute_volumes(vertices, cells['tetra'])) assert abs(vol - 2 * numpy.pi * 47.0 / 60.0) < 0.15 return
import os import matplotlib.pyplot as plt import numpy import pygalmesh s = pygalmesh.Ball([0, 0, 0], 1.0) mesh = pygalmesh.generate_mesh(s, cell_size=3.0e-2, verbose=True) mesh.cells = {"tetra": mesh.cells["tetra"]} mesh.point_data = {} mesh.cell_data = {} print("num points: {}".format(mesh.points.shape[0])) formats = { "vtu": ".vtu", "vtk": ".vtk", "gmsh": ".msh", "abaqus": ".inp", # "ansys": ".ans", "cgns": ".cgns", "dolfin-xml": ".xml", "mdpa": ".mdpa", "med": ".med", "medit": ".mesh", "moab": ".h5m", # "obj": ".obj", # "ply": ".ply", # "stl": ".stl", "nastran": ".bdf", # "off": ".off",