def __init__(self, *, radius=1.0, center=(0, 0, 0), ntheta=10, nphi=10, clip_free_surface=False, axial_symmetry=True, clever=None, name=None): self.radius = radius self.geometric_center = np.array(center, dtype=float) if clever is not None: LOG.warning( "Deprecation warning: `clever` argument for Sphere is deprecated. " "Use `axial_symmetry` instead.") if name is None: name = f"sphere_{next(Mesh._ids)}" mesh = self._generate_mesh_using_symmetry(ntheta, nphi, clip_free_surface, f"{name}_mesh") if not axial_symmetry: mesh = mesh.merged() mesh.merge_duplicates() mesh.heal_triangles() FloatingBody.__init__(self, mesh=mesh, name=name)
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)
def __init__(self, size=(1.0, 1.0, 1.0), resolution=(4, 4, 4), center=(0, 0, 0), top=True, bottom=True, reflection_symmetry=False, translational_symmetry=False, name=None): assert len(size) == 3, "Size of a rectangular parallelepiped should be given as a 3-ple of values." assert all([h > 0 for h in size]), "Size of the rectangular mesh should be given as positive values." assert len(resolution) == 3, "Resolution of a rectangular parallelepiped should be given as a 3-ple a values." assert all([h > 0 for h in resolution]), "Resolution of the rectangular parallelepiped mesh " \ "should be given as positive values." assert all([i == int(i) for i in resolution]), "Resolution of a rectangular parallelepiped " \ "should be given as integer values." assert len(center) == 3, "Position of the center of a parallelepiped should be given a 3-ple of values." self.size = np.asarray(size, dtype=np.float) width, thickness, height = size self.geometric_center = np.asarray(center, dtype=np.float) nw, nth, nh = resolution if translational_symmetry and reflection_symmetry: raise NotImplementedError("Parallelepiped generation with both reflection and translational symmetries " "has not been implemented yet.") if reflection_symmetry and (nw % 2 == 1 or nth % 2 == 1): raise ValueError("To use the reflection symmetry of the mesh, " "it should have an even number of panels in this direction.") if name is None: name = f"rectangular_parallelepiped_{next(Mesh._ids)}" LOG.debug(f"New rectangular parallelepiped body " f"of size ({width}, {thickness}, {height}) and resolution ({resolution}), named {name}.") if reflection_symmetry: parallelepiped = self._generate_mesh_with_reflection_symmetry(resolution, top, bottom, name) else: parallelepiped = self._generate_mesh_with_translational_symmetry(resolution, top, bottom, name) if not (reflection_symmetry or translational_symmetry): parallelepiped = parallelepiped.merged(name=f"{name}_mesh") parallelepiped.merge_duplicates() parallelepiped.heal_triangles() parallelepiped.translate(center) FloatingBody.__init__(self, mesh=parallelepiped, name=name)
def __init__(self, length=10.0, radius=1.0, center=(0, 0, 0), nx=10, ntheta=10, nr=2, clever=True, 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. 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, clever=True, 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)}" open_cylinder = AxialSymmetricMesh.from_profile( lambda z: radius, z_range=np.linspace(-length / 2, length / 2, nx + 1), nphi=ntheta) if nr > 0: top_side = Disk(radius=radius, center=(0, 0, length / 2), axial_symmetry=True, normal=(0, 0, 1), resolution=(nr, ntheta), name=f"top_side_of_{name}").mesh bottom_side = top_side.copy(name=f"bottom_side_of_{name}_mesh") bottom_side.mirror(xOy_Plane) mesh = AxialSymmetricMesh.join_meshes(open_cylinder, top_side, bottom_side) else: mesh = open_cylinder if not clever: mesh = mesh.merged() mesh.merge_duplicates() mesh.heal_triangles() mesh.translate(center) mesh.name = f"{name}_mesh" FloatingBody.__init__(self, mesh=mesh, name=name)
def __init__(self, radius=1.0, center=(0, 0, 0), ntheta=10, nphi=10, clever=True, clip_free_surface=False, name=None): """Generate a sphere. Parameters ---------- radius : float radius of the sphere center : 3-ple or array of shape (3,) position of the geometric center of the sphere ntheta : int number of panels along a meridian (or number of parallels-1) nphi : int number of panels along a parallel (or number of meridian-1) clever : bool if True, use the symmetries to build the mesh (default: True) clip_free_surface : bool if True, only mesh the part of the sphere where z < 0 (default: False), can be used with center to obtain any clipped sphere. name : string a name identifying the sphere (default: "sphere_id" where id is an unique integer). """ self.radius = radius self.geometric_center = np.array(center, dtype=np.float) if name is None: name = f"sphere_{next(Mesh._ids)}" if not clever: mesh = self._generate_sphere_mesh(ntheta, nphi, clip_free_surface, name) else: mesh = self._generate_clever_sphere_mesh(ntheta, nphi, clip_free_surface, name) FloatingBody.__init__(self, mesh=mesh, name=name) self.translate(center)
def __init__(self, length=10.0, radius=1.0, center=(0, 0, 0), nx=10, ntheta=10, nr=2, clever=True, name=None): 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, radius=1.0, center=(0, 0, 0), ntheta=10, nphi=10, clever=True, clip_free_surface=False, name=None): self.radius = radius self.geometric_center = np.array(center, dtype=float) if name is None: name = f"sphere_{next(Mesh._ids)}" if not clever: mesh = self._generate_sphere_mesh(ntheta, nphi, clip_free_surface, name) else: mesh = self._generate_clever_sphere_mesh(ntheta, nphi, clip_free_surface, name) FloatingBody.__init__(self, mesh=mesh, name=name) self.translate(center)
def __init__(self, radius=1.0, resolution=(3, 5), center=(0, 0, 0), normal=(1, 0, 0), reflection_symmetry=False, axial_symmetry=False, name=None): assert radius > 0, "Radius of the disk mesh should be given as a positive value." assert len( resolution ) == 2, "Resolution of a disk should be given as a couple a values." assert all([ h > 0 for h in resolution ]), "Resolution of the disk mesh should be given as positive values." assert all([ i == int(i) for i in resolution ]), "Resolution of a disk should be given as integer values." assert len( center ) == 3, "Position of the center of a disk should be given a 3-ple of values." self.radius = float(radius) self.geometric_center = np.asarray(center, dtype=float) nr, ntheta = resolution if reflection_symmetry and ntheta % 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 and axial_symmetry: raise NotImplementedError( "Disk generators with both symmetries have not been implemented." ) if name is None: name = f"disk_{next(Mesh._ids)}" LOG.debug( f"New disk body of radius {radius} and resolution ({nr}, {ntheta}), named {name}." ) if reflection_symmetry: half_mesh = Disk.generate_disk_mesh(radius=self.radius, theta_max=np.pi / 2, nr=nr, ntheta=ntheta // 2, name=f"half_of_{name}_mesh") mesh = ReflectionSymmetricMesh(half_mesh, plane=xOz_Plane, name=f"{name}_mesh") elif axial_symmetry: mesh_slice = Disk.generate_disk_mesh(radius=self.radius, theta_max=np.pi / ntheta, nr=nr, ntheta=1, name=f"slice_of_{name}_mesh") mesh_slice.rotate_around_center_to_align_vectors( (0, 0, 0), e_x, e_z ) # Convoluted way to avoid a warning message in AxialSymmetry... mesh = AxialSymmetricMesh(mesh_slice, axis=Oz_axis, nb_repetitions=ntheta - 1, name=f"{name}_mesh") mesh.rotate_around_center_to_align_vectors((0, 0, 0), e_z, e_x) else: mesh = Disk.generate_disk_mesh(radius=self.radius, nr=nr, ntheta=ntheta, name=f"{name}_mesh") 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)
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 HorizontalCylinder 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 __init__(self, size=(1.0, 1.0, 1.0), resolution=(4, 4, 4), center=(0, 0, 0), top=True, bottom=True, reflection_symmetry=False, translational_symmetry=False, name=None): """Generate the mesh of six rectangles forming a parallelepiped. Parameters ---------- size : 3-ple of floats, optional dimensions of the parallelepiped (width, thickness, height) for coordinates (x, y, z). resolution : 3-ple of ints, optional number of faces along the three directions center : 3-ple of floats, optional coordinates of the geometric center of the parallelepiped top: bool, optional whether or not to close the parallelepiped on the top bottom: bool, optional whether or not to close the parallelepiped on the bottom reflection_symmetry : bool, optional use xOz and yOz symmetry plane to generate the mesh translational_symmetry : bool, optional if True, use the translation symmetry in the x direction to speed up the computations. To use the translation symmetry in the y direction, create a x-symmetric body and then rotate it by pi/2. name : string, optional a name for the body """ assert len( size ) == 3, "Size of a rectangular parallelepiped should be given as a 3-ple of values." assert all([ h > 0 for h in size ]), "Size of the rectangular mesh should be given as positive values." assert len( resolution ) == 3, "Resolution of a rectangular parallelepiped should be given as a 3-ple a values." assert all([h > 0 for h in resolution]), "Resolution of the rectangular parallelepiped mesh " \ "should be given as positive values." assert all([i == int(i) for i in resolution]), "Resolution of a rectangular parallelepiped " \ "should be given as integer values." assert len( center ) == 3, "Position of the center of a parallelepiped should be given a 3-ple of values." self.size = np.asarray(size, dtype=np.float) width, thickness, height = size self.geometric_center = np.asarray(center, dtype=np.float) nw, nth, nh = resolution if translational_symmetry and reflection_symmetry: raise NotImplementedError( "Parallelepiped generation with both reflection and translational symmetries " "has not been implemented yet.") if reflection_symmetry and (nw % 2 == 1 or nth % 2 == 1): raise ValueError( "To use the reflection symmetry of the mesh, " "it should have an even number of panels in this direction.") if name is None: name = f"rectangular_parallelepiped_{next(Mesh._ids)}" LOG.debug( f"New rectangular parallelepiped body " f"of size ({width}, {thickness}, {height}) and resolution ({resolution}), named {name}." ) if reflection_symmetry: parallelepiped = self._generate_mesh_with_reflection_symmetry( resolution, top, bottom, name) else: parallelepiped = self._generate_mesh_with_translational_symmetry( resolution, top, bottom, name) if not (reflection_symmetry or translational_symmetry): parallelepiped = parallelepiped.merged(name=f"{name}_mesh") parallelepiped.merge_duplicates() parallelepiped.heal_triangles() parallelepiped.translate(center) FloatingBody.__init__(self, mesh=parallelepiped, name=name)
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 a vertical 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 = AxialSymmetricMesh.from_profile( lambda z: radius, z_range=np.linspace(-length / 2, length / 2, nx + 1), nphi=ntheta) if nr > 0: top_side = Disk(radius=radius, center=(0, 0, length / 2), axial_symmetry=True, normal=(0, 0, 1), resolution=(nr, ntheta), name=f"top_side_of_{name}").mesh bottom_side = top_side.copy(name=f"bottom_side_of_{name}_mesh") bottom_side.mirror(xOy_Plane) mesh = AxialSymmetricMesh.join_meshes(open_cylinder, top_side, bottom_side) else: mesh = open_cylinder if not clever: mesh = mesh.merged() mesh.merge_duplicates() mesh.heal_triangles() mesh.translate(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, 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)