Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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)
Example #9
0
def import_cal_file(filepath):
    """Read a Nemoh.cal file and return a list of problems."""

    with open(filepath, 'r') as cal_file:

        cal_file.readline()  # Unused line.
        rho = float(cal_file.readline().split()[0])
        g = float(cal_file.readline().split()[0])
        depth = float(cal_file.readline().split()[0])
        if depth == 0.0:
            sea_bottom = -np.infty
        else:
            sea_bottom = -depth
        xeff, yeff = (float(x) for x in cal_file.readline().split()[0:2])

        bodies = []

        cal_file.readline()  # Unused line.
        nb_bodies = int(cal_file.readline().split()[0])
        for _ in range(nb_bodies):
            cal_file.readline()  # Unused line.
            mesh_file = cal_file.readline().split()[0].strip()
            mesh_file = os.path.join(
                os.path.dirname(filepath),
                mesh_file)  # mesh path are relative to Nemoh.cal
            cal_file.readline()  # Number of points, number of panels (unused)

            if os.path.splitext(mesh_file)[1] == '.py':
                from importlib.util import spec_from_file_location, module_from_spec
                spec = spec_from_file_location("body_initialization_module",
                                               mesh_file)
                body_initialization = module_from_spec(spec)
                spec.loader.exec_module(body_initialization)
                body = body_initialization.body
            else:
                body = FloatingBody.from_file(mesh_file)

            nb_dofs = int(cal_file.readline().split()[0])
            for i_dof in range(nb_dofs):
                dof_data = cal_file.readline().split()
                if int(dof_data[0]) == 1:
                    direction = np.array([float(x) for x in dof_data[1:4]])
                    body.add_translation_dof(direction=direction)
                elif int(dof_data[0]) == 2:
                    direction = np.array([float(x) for x in dof_data[1:4]])
                    center_of_mass = np.array(
                        [float(x) for x in dof_data[4:7]])
                    body.add_rotation_dof(
                        Axis(vector=direction, point=center_of_mass))

            nb_forces = int(cal_file.readline().split()[0])
            for i_force in range(nb_forces):
                force_data = cal_file.readline().split()
                if int(force_data[0]) == 1:
                    direction = np.array([float(x) for x in force_data[1:4]])
                elif int(force_data[0]) == 2:
                    direction = np.array([float(x) for x in force_data[1:4]])
                    center_of_mass = np.array(
                        [float(x) for x in force_data[4:7]])
            # TODO: use the generalized forces.

            nb_additional_lines = int(cal_file.readline().split()[0])
            for _ in range(nb_additional_lines):
                cal_file.readline()  # The additional lines are just ignored.

            bodies.append(body)

        if nb_bodies > 1:
            bodies = FloatingBody.join_bodies(*bodies)
        else:
            bodies = bodies[0]

        cal_file.readline()  # Unused line.
        frequency_data = cal_file.readline().split()
        omega_range = np.linspace(float(frequency_data[1]),
                                  float(frequency_data[2]),
                                  int(frequency_data[0]))

        direction_data = cal_file.readline().split()
        direction_range = np.linspace(float(direction_data[1]),
                                      float(direction_data[2]),
                                      int(direction_data[0]))
        direction_range = np.pi / 180 * direction_range  # conversion from degrees to radians.

        # The options below are not implemented yet.

        cal_file.readline()  # Unused line.
        irf_data = cal_file.readline()
        show_pressure = cal_file.readline().split()[0] == "1"
        kochin_data = cal_file.readline().split()
        kochin_range = np.linspace(float(kochin_data[1]),
                                   float(kochin_data[2]), int(kochin_data[0]))
        free_surface_data = cal_file.readline().split()

    # Generate Capytaine's problem objects
    env_args = dict(body=bodies, rho=rho, sea_bottom=sea_bottom, g=g)
    problems = []
    for omega in omega_range:
        for direction in direction_range:
            problems.append(
                DiffractionProblem(wave_direction=direction,
                                   omega=omega,
                                   **env_args))
        for dof in bodies.dofs:
            problems.append(
                RadiationProblem(radiating_dof=dof, omega=omega, **env_args))

    return problems
Example #10
0
    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)
Example #11
0
    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)
Example #12
0
    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)
Example #13
0
    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)
Example #14
0
    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)