def rotate(self, axis: Axis, angle: float): self.plane.rotate(axis, angle) CollectionOfMeshes.rotate(self, axis, angle) return self
def mirror(self, plane: Plane): self.axis.mirror(plane) CollectionOfMeshes.mirror(self, plane) return self
def translate(self, vector): self.plane.translate(vector) CollectionOfMeshes.translate(self, vector) return self
def mirror(self, plane: Plane): self.translation -= 2 * ( self.translation @ plane.normal) * plane.normal CollectionOfMeshes.mirror(self, plane) return self
def rotate(self, other_axis: Axis, angle: float): self.axis.rotate(other_axis, angle) CollectionOfMeshes.rotate(self, other_axis, angle) return self
def translate(self, vector): CollectionOfMeshes.translate(self, vector) return self
def rotate(self, axis: Axis, angle: float): self.translation = axis.rotation_matrix(angle) @ self.translation CollectionOfMeshes.rotate(self, axis, angle) return self
def __init__(self, length=10.0, radius=1.0, center=(0, 0, 0), nx=10, ntheta=10, nr=2, clever=True, name=None): """Generate the mesh of an horizontal cylinder. Parameters ---------- length : float, optional length of the cylinder radius : float, optional radius of the cylinder center : 3-ple or array of shape (3,), optional position of the geometric center of the cylinder nx : int, optional number of circular slices ntheta : int, optional number of panels along a circular slice of the cylinder nr : int, optional number of panels along a radius on the extremities of the cylinder clever : bool, optional if True, uses the mesh symmetries name : str, optional a string naming the floating body """ self.length = length self.radius = radius self.geometric_center = np.asarray(center, dtype=np.float) if name is None: name = f"cylinder_{next(Mesh._ids)}" open_cylinder = self._generate_open_cylinder_mesh( nx, ntheta, f"body_of_{name}") if nr > 0: side = Disk(radius=radius, center=(-np.array([length / 2, 0, 0])), normal=(-1, 0, 0), resolution=(nr, ntheta), name=f"side_of_{name}").mesh other_side = side.copy(name=f"other_side_of_{name}_mesh") other_side.mirror(yOz_Plane) mesh = CollectionOfMeshes((open_cylinder, side, other_side)) else: mesh = open_cylinder if not clever: mesh = mesh.merged() mesh.merge_duplicates() mesh.heal_triangles() mesh.translate(self.geometric_center) mesh.name = f"{name}_mesh" FloatingBody.__init__(self, mesh=mesh, name=name)
def __init__(self, length=10.0, radius=1.0, center=(0, 0, 0), nx=10, ntheta=10, nr=2, reflection_symmetry=True, translation_symmetry=False, clever=None, name=None): self.length = length self.radius = radius self.geometric_center = np.asarray(center, dtype=float) if name is None: name = f"cylinder_{next(Mesh._ids)}" ntheta = 2 * (ntheta // 2) # Temporary fix to avoid mismatch in mesh # When symmetries are used, one needs an even number of panels. # TODO: When symmetries are not used, implement the odd case. if clever is not None: LOG.warning( "Deprecation warning: `clever` argument for VerticalCylinder is deprecated." "Use `reflection_symmetry` and/or `translation_symmetry` instead." ) open_cylinder = self._generate_open_cylinder_mesh( nx, ntheta, reflection_symmetry=reflection_symmetry, translation_symmetry=translation_symmetry, name=f"body_of_{name}") if nr == 0: # No sides mesh = open_cylinder else: # Sides side = Disk(radius=radius, center=(-np.array([length / 2, 0, 0])), normal=(-1, 0, 0), reflection_symmetry=reflection_symmetry, resolution=(nr, ntheta), name=f"side_of_{name}").mesh other_side = side.copy(name=f"other_side_of_{name}_mesh") other_side.mirror(yOz_Plane) if reflection_symmetry: # Knit the sides into the symmetric representation of the open cylinder half_sides = CollectionOfMeshes( (side.half, other_side.half), name="half_sides_of_{name}_mesh") half_mesh = CollectionOfMeshes( (open_cylinder.half, half_sides), name="half_{name}_mesh") mesh = ReflectionSymmetricMesh(half_mesh, plane=xOz_Plane, name=f"{name}_mesh") else: sides = CollectionOfMeshes( (side, other_side), name="sides_of_cylinder_{name}_mesh") mesh = CollectionOfMeshes((open_cylinder, sides), name=f"{name}_mesh") if not reflection_symmetry and not translation_symmetry: mesh = mesh.merged() mesh.heal_mesh() mesh.translate(self.geometric_center) mesh.name = f"{name}_mesh" FloatingBody.__init__(self, mesh=mesh, name=name)
def join_meshes(*meshes, name=None): from capytaine.meshes.collections import CollectionOfMeshes return CollectionOfMeshes(meshes, name=name).merged()
def tree_view(self, fold_symmetry=True, **kwargs): if fold_symmetry: return (str(self) + '\n' + ' ├─' + self.half.tree_view().replace('\n', '\n │ ') + '\n' + f" └─mirrored copy of the above {str(self.half)}") else: return CollectionOfMeshes.tree_view(self, **kwargs)
def tree_view(self, fold_symmetry=True, **kwargs): if fold_symmetry: return (str(self) + '\n' + ' ├─' + self.first_slice.tree_view().replace('\n', '\n │ ') + '\n' + f" └─{len(self)-1} rotated copies of the above {str(self.first_slice)}") else: return CollectionOfMeshes.tree_view(self, **kwargs)
def rotate(self, axis: Axis, angle: float): self.translation = axis.rotate_vector([self.translation], angle)[0, :] CollectionOfMeshes.rotate(self, axis, angle) return self
def join_bodies(*bodies, name=None) -> 'FloatingBody': if name is None: name = "+".join(body.name for body in bodies) meshes = CollectionOfMeshes([body.mesh for body in bodies], name=f"{name}_mesh") dofs = FloatingBody.combine_dofs(bodies) return FloatingBody(mesh=meshes, dofs=dofs, name=name)