Ejemplo n.º 1
0
    def _generate_mesh_using_symmetry(self, ntheta, nphi, clip_free_surface,
                                      mesh_name):
        if clip_free_surface:
            if self.geometric_center[2] < -self.radius:  # fully immersed
                theta_max = np.pi
            elif self.geometric_center[2] < self.radius:
                theta_max = np.arccos(self.geometric_center[2] / self.radius)
            else:
                raise ValueError(
                    "Impossible to mesh the immersed hull of a sphere completely out of the water"
                )
        else:
            theta_max = np.pi

        theta = np.linspace(0.0, theta_max, ntheta + 1)
        points_on_a_meridian = (self.radius * np.stack(
            [np.sin(theta),
             np.zeros_like(theta), -np.cos(theta)], axis=1) +
                                self.geometric_center)

        symmetry_axis = Axis(vector=[0, 0, 1], point=self.geometric_center)
        return AxialSymmetricMesh.from_profile(points_on_a_meridian,
                                               axis=symmetry_axis,
                                               nphi=nphi,
                                               name=mesh_name)
Ejemplo n.º 2
0
    def _generate_clever_sphere_mesh(self,
                                     ntheta=10,
                                     nphi=10,
                                     clip_free_surface=False,
                                     name=None):
        if clip_free_surface:
            if self.geometric_center[2] < -self.radius:  # fully immersed
                theta_max = np.pi
            elif self.geometric_center[2] < self.radius:
                theta_max = np.arccos(self.geometric_center[2] / self.radius)
            else:
                raise Exception("Sphere out of the water")
        else:
            theta_max = np.pi

        theta = np.linspace(0.0, theta_max, ntheta + 1)

        circle_profile = np.zeros((ntheta + 1, 3), dtype=float)
        circle_profile[:, 0] = np.sin(theta)
        circle_profile[:, 2] = -np.cos(theta)
        circle_profile *= self.radius

        return AxialSymmetricMesh.from_profile(circle_profile,
                                               nphi=nphi,
                                               name=f"{name}_mesh")
Ejemplo n.º 3
0
def test_odd_axial_symmetry():
    """Buoy with odd number of slices."""
    def shape(z):
        return 0.1 * (-(z + 1)**2 + 16)

    buoy = FloatingBody(
        AxialSymmetricMesh.from_profile(shape,
                                        z_range=np.linspace(-5.0, 0.0, 9),
                                        nphi=5))
    buoy.add_translation_dof(direction=(0, 0, 1), name="Heave")

    problem = RadiationProblem(body=buoy, omega=2.0)
    result1 = solver_with_sym.solve(problem)

    full_buoy = FloatingBody(buoy.mesh.merged())
    full_buoy.add_translation_dof(direction=(0, 0, 1), name="Heave")
    problem = RadiationProblem(body=full_buoy, omega=2.0)
    result2 = solver_with_sym.solve(problem)

    volume = buoy.mesh.volume
    assert np.isclose(result1.added_masses["Heave"],
                      result2.added_masses["Heave"],
                      atol=1e-4 * volume * problem.rho)
    assert np.isclose(result1.radiation_dampings["Heave"],
                      result2.radiation_dampings["Heave"],
                      atol=1e-4 * volume * problem.rho)
Ejemplo n.º 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)}"

        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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
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)