def _generate_mesh_with_translational_symmetry(self, resolution, top, bottom, name): width, thickness, height = self.size nw, nth, nh = resolution front_panel = Rectangle.generate_rectangle_mesh( width=width / nw, height=height, nw=1, nh=nh, center=(-width / 2 + width / (2 * nw), thickness / 2, 0), normal=(0, 1, 0), name=f"front_panel_of_{name}_mesh") back_panel = front_panel.mirror(plane=xOz_Plane, inplace=False, name=f"back_panel_of_{name}_mesh") top_panel = Rectangle.generate_rectangle_mesh( width=thickness, height=width / nw, nw=nth, nh=1, center=(-width / 2 + width / (2 * nw), 0, height / 2), normal=(0, 0, 1), name=f"top_panel_of_{name}_mesh") bottom_panel = top_panel.mirror(plane=xOy_Plane, inplace=False, name=f"bottom_panel_of_{name}_mesh") panels = [front_panel, back_panel] if top: panels.append(top_panel) if bottom: panels.append(bottom_panel) ring = CollectionOfMeshes(panels, name=f"ring_of_{name}_mesh").merged() ring.merge_duplicates() ring.heal_triangles() open_parallelepiped = TranslationalSymmetricMesh( ring, translation=(width / nw, 0, 0), nb_repetitions=int(nw) - 1, name=f"body_of_{name}_mesh") side = Rectangle.generate_rectangle_mesh(width=thickness, height=height, nw=nth, nh=nh, center=(width / 2, 0, 0), normal=(1, 0, 0), name=f"side_of_{name}_mesh") other_side = side.mirror(plane=yOz_Plane, inplace=False, name=f"other_side_of_{name}_mesh") return CollectionOfMeshes([open_parallelepiped, side, other_side], name=f"{name}_mesh")
def _generate_open_cylinder_mesh(self, nx, ntheta, name=None): """Open horizontal cylinder using the symmetry to speed up the computations""" theta_max = np.pi theta = np.linspace(0, theta_max, ntheta // 2 + 1) X = np.array([0, self.length / nx]) # Nodes nodes = np.zeros(((ntheta // 2 + 1) * 2, 3), dtype=float) for i, (t, x) in enumerate(product(theta, X)): y = +self.radius * np.sin(t) z = -self.radius * np.cos(t) nodes[i, :] = (x, y, z) nodes += -np.array([self.length / 2, 0, 0]) # Connectivities panels = np.zeros((ntheta // 2, 4), dtype=int) for k, i in enumerate(range(0, ntheta // 2)): panels[k, :] = (2 * i, 2 * i + 2, 2 * i + 3, 2 * i + 1) half_ring = Mesh(nodes, panels, name=f"half_ring_of_{name}_mesh") ring = ReflectionSymmetricMesh(half_ring, plane=xOz_Plane, name=f"ring_of_{name}_mesh") if nx == 1: return ring else: return TranslationalSymmetricMesh( ring, translation=np.asarray([self.length / nx, 0.0, 0.0]), nb_repetitions=nx - 1, name=f"{name}_mesh")
def __init__(self, size=(5.0, 5.0), resolution=(5, 5), center=(0, 0, 0), normal=(1, 0, 0), translational_symmetry=False, reflection_symmetry=False, name=None): assert len(size) == 2, "Size of a rectangle should be given as a couple of values." assert all([h > 0 for h in size]), "Size of the rectangle mesh should be given as positive values." assert len(resolution) == 2, "Resolution of a rectangle should be given as a couple a values." assert all([h > 0 for h in resolution]), "Resolution of the rectangle mesh should be given as positive values." assert all([i == int(i) for i in resolution]), "Resolution of a rectangle should be given as integer values." assert len(center) == 3, "Position of the center of a rectangle should be given a 3-ple of values." self.size = np.asarray(size, dtype=np.float) width, height = self.size self.geometric_center = np.asarray(center, dtype=np.float) nw, nh = resolution if translational_symmetry and reflection_symmetry: raise NotImplementedError("Rectangle generation with both reflection and translational symmetries " "has not been implemented yet.") if translational_symmetry and nw == 1: LOG.warning("To use the translation symmetry of the mesh, " "it should have more than one panel in this direction. " "Will return a standard mesh instead.") if reflection_symmetry and nw % 2 == 1: raise ValueError("To use the reflection symmetry of the mesh, " "it should have an even number of panels in this direction.") if (reflection_symmetry or translational_symmetry) and normal[2] != 0: raise ValueError("To use the symmetry of the mesh, it should be vertical.") if name is None: name = f"rectangle_{next(Mesh._ids)}" LOG.debug(f"New rectangle body of size ({width}, {height}) and resolution ({nw}, {nh}), named {name}.") if reflection_symmetry: half_mesh = Rectangle.generate_rectangle_mesh( width=width/2, height=height, nw=nw//2, nh=nh, center=(0, -width/4, 0), name=f"half_of_{name}_mesh" ) mesh = ReflectionSymmetricMesh(half_mesh, plane=xOz_Plane, name=f"{name}_mesh") elif translational_symmetry and nw > 1: strip = Rectangle.generate_rectangle_mesh( width=width/nw, height=height, nw=1, nh=nh, center=(0, -width/2 + width/(2*nw), 0), name=f"strip_of_{name}_mesh" ) mesh = TranslationalSymmetricMesh(strip, translation=np.asarray([0, width/nw, 0]), nb_repetitions=int(nw)-1, name=name) else: mesh = Rectangle.generate_rectangle_mesh(width=width, height=height, nw=nw, nh=nh, name=name) mesh.rotate_around_center_to_align_vectors((0, 0, 0), mesh.faces_normals[0], normal) mesh.translate(center) FloatingBody.__init__(self, mesh=mesh, name=name)