Exemple #1
0
 def to_meshmagick(self):
     """Convert the Mesh object as a Mesh object from meshmagick.
     Mostly for debugging."""
     from meshmagick.mesh import Mesh
     meshmagick_mesh = Mesh(self.vertices, self.faces, name=self.name)
     meshmagick_mesh.heal_mesh()
     return meshmagick_mesh
Exemple #2
0
    def extract_faces(self, id_faces_to_extract, return_index=False):
        """Create a new FloatingBody by extracting some faces from the mesh."""
        if return_index:
            new_body, id_v = Mesh.extract_faces(self, id_faces_to_extract, return_index)
        else:
            new_body = Mesh.extract_faces(self, id_faces_to_extract, return_index)
        new_body.__class__ = FloatingBody
        new_body.nb_matrices_to_keep = self.nb_matrices_to_keep
        LOG.info(f"Extract floating body from {self.name}.")

        new_body.dofs = {}
        for name, dof in self.dofs.items():
            new_body.dofs[name] = dof[id_faces_to_extract]

        if return_index:
            return new_body, id_v
        else:
            return new_body
Exemple #3
0
def test_clipper():
    vertices, faces = mmio.load_VTP('meshmagick/tests/data/SEAREV.vtp')
    searev = Mesh(vertices, faces)

    plane = Plane()
    clipper = mc.MeshClipper(searev,
                             plane,
                             assert_closed_boundaries=True,
                             verbose=False)

    for iter in range(50):
        thetax, thetay = np.random.rand(2) * 2 * math.pi
        plane.rotate_normal(thetax, thetay)
        clipper.plane = plane
Exemple #4
0
    def extract_faces(self,
                      id_faces_to_extract,
                      return_index=False,
                      name=None):
        """
        Extracts a new mesh from a selection of faces ids

        Parameters
        ----------
        id_faces_to_extract : ndarray
            Indices of faces that have to be extracted
        return_index: bool, optional
            Flag to output old indices
        name: string, optional
            Name for the new mesh

        Returns
        -------
        Mesh
            A new Mesh instance composed of the extracted faces
        """
        nv = self.nb_vertices

        # Determination of the vertices to keep
        vertices_mask = np.zeros(nv, dtype=bool)
        vertices_mask[self._faces[id_faces_to_extract].flatten()] = True
        id_v = np.arange(nv)[vertices_mask]

        # Building up the vertex array
        v_extracted = self._vertices[id_v]
        new_id__v = np.arange(nv)
        new_id__v[id_v] = np.arange(len(id_v))

        faces_extracted = self._faces[id_faces_to_extract]
        faces_extracted = new_id__v[faces_extracted.flatten()].reshape(
            (len(id_faces_to_extract), 4))

        extracted_mesh = Mesh(v_extracted, faces_extracted)

        for prop in self.__internals__:
            if prop[:4] == "face":
                extracted_mesh.__internals__[prop] = self.__internals__[prop][
                    id_faces_to_extract]

        if name is None:
            if self.name is not None and self.name.startswith(
                    "mesh_extracted_from_"):
                extracted_mesh.name = self.name
            else:
                extracted_mesh.name = f"mesh_extracted_from_{self.name}"
        else:
            extracted_mesh.name = name

        if return_index:
            return extracted_mesh, id_v
        else:
            return extracted_mesh
Exemple #5
0
    def from_set_of_faces(set_of_faces):
        faces = []
        vertices = []
        for face in set_of_faces:
            ids_of_vertices_in_face = []

            for vertex in face:
                if vertex not in vertices:
                    i = len(vertices)
                    vertices.append(vertex)
                else:
                    i = vertices.index(vertex)
                ids_of_vertices_in_face.append(i)

            if len(ids_of_vertices_in_face) == 3:
                # Add a fourth node identical to the first one
                ids_of_vertices_in_face.append(ids_of_vertices_in_face[0])

            faces.append(ids_of_vertices_in_face)
        return Mesh(vertices=vertices, faces=faces)
    def as_FloatingBody(self, name=None):
        """Merge the mesh of the bodies of the collection into one mesh."""

        if name is None:
            name = f"union_of_{'_and_'.join((body.name for body in self.subbodies))}"
            if len(name) > NAME_MAX_LENGTH:
                name = name[:NAME_MAX_LENGTH - 3] + "..."

        new_body = self.subbodies[0].as_FloatingBody().copy(name=name)
        for body in self.subbodies[1:]:
            new_body = Mesh.__add__(new_body, body.as_FloatingBody())
            LOG.debug(f"Add mesh of {body.name} to {name}.")
        new_body.name = name
        new_body.merge_duplicates()
        new_body.heal_triangles()
        new_body.__class__ = FloatingBody
        new_body.dofs = self.dofs
        new_body.nb_matrices_to_keep = 1
        LOG.info(
            f"Merged collection of bodies {self.name} into floating body {new_body.name}."
        )
        return new_body
Exemple #7
0
    def read_mesh(self, reader, mesh_path):
        """This function reads the mesh quantities of the *.hdb5 file.

        Parameters
        ----------
        reader : string
            *.hdb5 file.
        mesh_path : string
            Path to the mesh folder.
        """

        # Mesh data.
        nb_vertices = np.array(reader[mesh_path + "/NbVertices"])
        vertices = np.array(reader[mesh_path + "/Vertices"])
        nb_faces = np.array(reader[mesh_path + "/NbFaces"])
        faces = np.array(reader[mesh_path + "/Faces"])
        mesh = Mesh(vertices, faces)

        # Verification of mesh information consistency
        assert nb_vertices == mesh.nb_vertices
        assert nb_faces == mesh.nb_faces

        return mesh
Exemple #8
0
#!/usr/bin/env python
#  -*- coding: utf-8 -*-

import meshmagick.mmio as mmio
from meshmagick.mesh import Mesh
from math import pi, fabs
import pytest

vertices, faces = mmio.load_VTP('meshmagick/tests/data/Cylinder.vtp')
cylinder = Mesh(vertices, faces)
xmin, xmax, ymin, ymax, zmin, zmax = cylinder.axis_aligned_bbox
R = (xmax - xmin) / 2.
h = zmax - zmin
V = pi * R**2 * h
Ixx = Iyy = V * (R**2 + h**2 / 3) / 4
Izz = V * R**2 / 2


def test_cylinder_inertia():
    inertia = cylinder.eval_plain_mesh_inertias(rho_medium=1.)

    assert pytest.approx(Ixx, rel=1e-1) == inertia.xx
    assert pytest.approx(Izz, rel=1e-1) == inertia.zz


def test_move_cog():
    # parallel axis theorem to find MOI at base of cylinder
    Ixx_base = Ixx + V * (h / 2)**2

    # use meshmagick to find moments of inertia
    inertia = cylinder.eval_plain_mesh_inertias(rho_medium=1.)
Exemple #9
0
 def __init__(self, *args, **kwargs):
     Mesh.__init__(self, *args, **kwargs)
     self._compute_radiuses()
     self.nb_matrices_to_keep = 1
     self.dofs = {}
     LOG.info(f"New floating body: {self.name}.")
def main():
    parser = argparse.ArgumentParser(
        description="""--- max_frequency_bem ---
        Command line utility to get the maximum frequency allowed by a given mesh discretization for the BEM 
        computations to be accurate.
        
        It relies on meshmagick tool for mesh reading
        
        """,
        epilog='-- FRyDoM framework.\nmax_frequency_bem utility',
        formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument(
        'infilename',  # TODO : voir pour un typ=file pour tester l'existence
        help='path of the input mesh file in any supported format',
        type=str)

    parser.add_argument(
        '-ifmt',
        '--input-format',
        help="""Input format. Meshmagick will read the input file considering the
                         INPUT_FORMAT rather than using the extension
                         """,
        type=str)

    parser.add_argument(
        '-n',
        '--nb-faces-by-wavelength',
        help=
        'Specify the number of faces by wavelength that BEM computations should take into account',
        type=int)

    parser.add_argument(
        '-g',
        '--gravity',
        help='Acceleration of gravity in m/s**2. Default is 9.81',
        type=float,
        default=9.81)

    parser.add_argument(
        '-wd',
        '--water-depth',
        help='Water depth in meters. Default is infinite (put 0 explicitely)',
        type=float,
        default=0.)

    args, unknown = parser.parse_known_args()

    if args.input_format is not None:
        ifmt = args.input_format
    else:
        _, ext = os.path.splitext(args.infilename)
        ifmt = ext[1:].lower()
        if ifmt == '':
            raise IOError(
                'Unable to determine the input file format from its extension. '
                'Please specify an input format.')

    # Loading mesh from file
    if os.path.isfile(args.infilename):
        vertices, faces = mmio.load_mesh(args.infilename, ifmt)
        mesh = Mesh(vertices, faces)
    else:
        raise IOError('file %s not found' % args.infilename)

    # Number of faces by wave length necessary to keep accuracy good in BEM computations
    nb_faces_by_wavelength = args.nb_faces_by_wavelength

    if nb_faces_by_wavelength is None:
        nb_faces_by_wavelength = 10

    max_edge_length = mesh.max_edge_length

    wave_length = nb_faces_by_wavelength * max_edge_length
    wave_number = 2. * pi / wave_length

    w2 = args.gravity * wave_number

    depth = fabs(args.water_depth)
    if depth != 0.:
        w2 *= tanh(wave_number * depth)

    w = sqrt(w2)

    print(
        '\nBased on the rule of %u faces by wavelength, the specified mesh with maximum edge length of %.3f m \n'
        'allows to perform BEM computations until the frequency:\n' %
        (nb_faces_by_wavelength, max_edge_length))

    print('\t\t*****************************')
    print('\t\t***   Wmax = %.2f rad/s   ***' % w)
    print('\t\t*****************************\n')

    print('with:')

    print('\t+ Gravity:      %.3f m/s**2' % args.gravity)

    if depth == 0.:
        print('\t+ Water depth: INFINITE')
    else:
        print('\t+ Water depth:  %.3f m (FINITE)' % depth)

    print('\n')
#!/usr/bin/env python
#  -*- coding: utf-8 -*-

from meshmagick.mmio import load_VTP
from meshmagick.mesh import Mesh
from meshmagick.inertia import right_circular_cylinder
from meshmagick.densities import get_density

# Comparaison pour un calcul au cog

vertices, faces = load_VTP('meshmagick/tests/data/Cylinder.vtp')
cyl_mesh = Mesh(vertices, faces)
xmin, xmax, ymin, ymax, zmin, zmax = cyl_mesh.axis_aligned_bbox

# Analytique
R = (xmax - xmin) / 2.
H = zmax - zmin
cyl_anal_inertia = right_circular_cylinder(R,
                                           H,
                                           density=get_density('SALT_WATER'))

# print cyl_mesh_inertia
# print cyl_anal_inertia.at_cog

# On decale
cyl_mesh.translate([1, 3, -10])
# cyl_mesh.show()

print "Numerique:"
print cyl_mesh.eval_plain_mesh_inertias(get_density('SALT_WATER'))
Exemple #12
0
    def _read_nemoh_parameters(self, pyHDB, cal_file, test=True):
        """Reads the Nemoh parameters from the Nemoh.cal file

        Parameters
        ----------
        pyHDB : object
            pyHDB object for storing the hydrodynamic database.
        cal_file : str
            Path (relative or absolute) to the Nemoh.cal file
        test : bool, optional
            If True (default), it will test against consistency between frequencies taken for BEM computations and
            meshe's discretization
        """

        if not os.path.exists(cal_file):
            raise IOError("File %s not found" % cal_file)

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

            # Getting root directory of the Nemoh computation project
            abspath = os.path.abspath(cal_file)
            dirname = os.path.dirname(abspath)

            self.dirname = dirname

            def skip_line():
                f.readline()

            # Environment parameters
            skip_line()
            skip_line() # Rho_water.
            skip_line() # Grav.
            skip_line() # Depth
            skip_line() # xreff and yreff.

            # Number of bodies
            skip_line()
            skip_line() # nb_bodies.

            for ibody in range(pyHDB.nb_bodies):
                skip_line()
                meshfile = str(f.readline().split()[0])
                abs_meshfile = os.path.join(dirname, meshfile)

                # Instantiating mesh object
                vertices, faces = load_MAR(abs_meshfile)
                mesh = Mesh(vertices, faces)

                nb_vertices, nb_faces = list(map(int, f.readline().split()[:2]))

                # Verification of mesh information consistency
                assert nb_vertices == mesh.nb_vertices
                assert nb_faces == mesh.nb_faces

                # De-symmetrizing meshes
                with open(abs_meshfile, 'r') as fmesh:
                    _, isym = fmesh.readline().split()
                if int(isym) == 1:  # Mesh is symmetric
                    mesh.symmetrize(Plane([0, 1, 0]))

                mesh.name, _ = os.path.splitext(meshfile)

                # Instantiating BodyDB.
                body = body_db.BodyDB(ibody, pyHDB.nb_bodies, pyHDB.nb_wave_freq, pyHDB.nb_wave_dir , mesh)

                # RADIATION.
                nb_dof = int(f.readline().split()[0])
                for idof in range(nb_dof):
                    dof = f.readline().split()[:7]
                    motion_type = int(dof[0])
                    direction = list(map(float, dof[1:4]))
                    point = list(map(float, dof[4:]))

                    # Center of gravity.
                    body.position = point

                    if motion_type == 1: # Translation.
                        if(direction[0] == 1):
                            body.Motion_mask[0] = 1
                        elif(direction[1] == 1):
                            body.Motion_mask[1] = 1
                        elif(direction[2] == 1):
                            body.Motion_mask[2] = 1
                        else:
                            "The linear motion direction must be a unit vector ex, ey or ez. Generalized modes are not taken into account."
                            exit()
                    elif motion_type == 2: # Rotation.
                        if (direction[0] == 1):
                            body.Motion_mask[3] = 1
                        elif (direction[1] == 1):
                            body.Motion_mask[4] = 1
                        elif (direction[2] == 1):
                            body.Motion_mask[5] = 1
                        else:
                            "The angular motion direction must be a unit vector ex, ey or ez. Generalized modes are not taken into account."
                            exit()
                    else:
                        raise UnknownMotionMode(motion_type, abspath)

                # INTEGRATION.
                nb_force = int(f.readline().split()[0])
                for iforce in range(nb_force):
                    force = f.readline().split()[:7]
                    force_type = int(force[0])
                    direction = list(map(float, force[1:4]))
                    point = list(map(float, force[4:]))
                    if force_type == 1:  # Pure force
                        if (direction[0] == 1):
                            body.Force_mask[0] = 1
                        elif (direction[1] == 1):
                            body.Force_mask[1] = 1
                        elif (direction[2] == 1):
                            body.Force_mask[2] = 1
                        else:
                            "The force direction must be a unit vector ex, ey or ez. Generalized modes are not taken into account."
                            exit()
                    elif force_type == 2:
                        if (direction[0] == 1):
                            body.Force_mask[3] = 1
                            body.point[0,:] = point
                        elif (direction[1] == 1):
                            body.Force_mask[4] = 1
                            body.point[1, :] = point
                        elif (direction[2] == 1):
                            body.Force_mask[5] = 1
                            body.point[2, :] = point
                        else:
                            "The angular motion direction must be a unit vector ex, ey or ez. Generalized modes are not taken into account."
                            exit()
                    else:
                        raise UnknownForceMode(force_type, abspath)

                # Skipping additional lines.
                nb_add_line = int(f.readline().split()[0])
                for i_add_line in range(nb_add_line):
                    skip_line()

                # Add body to pyHDB.
                pyHDB.append(body)

            # Reading discretization.
            skip_line()

            # Getting frequency discretization.
            skip_line()

            # Getting wave directions discretization.
            skip_line()

            # Getting post-processing information
            skip_line()

            # Impulse response function
            data = f.readline().split()[:3]
            # has_irf = bool(int(data[0]))
            # if has_irf:
            #     self.dt_irf, self.tf_irf = map(float, data[1:])

            # TODO: si ok lire  -> remettre en place si besoin...
            # Show pressure
            skip_line()
            # self.has_pressure = bool(int(f.readline().split()[0])) # Enlever le skip_line() ci-dessus si décommenté.

            # Kochin functions.
            data = f.readline().split()[:3]
            pyHDB.has_kochin = bool(float(data[0]))
            if pyHDB.has_kochin:
                pyHDB.nb_angle_kochin = int(data[0])
                pyHDB.min_angle_kochin, pyHDB.max_angle_kochin = list(map(float, data[1:]))
                pyHDB.set_wave_directions_Kochin()


            # # TODO: si ok, lire  -> remettre en place si besoin...
            # # Free surface elevation
            # data = f.readline().split()[:4]
            # has_fs_elevation = bool(int(data[0]))
            # if has_fs_elevation:
            #     self.nx_fs, self.ny_fs = map(int, data[:2])
            #     self.xlim_fs, self.ylim_fs = map(float, data[2:])

        if test:
            self.test_mesh_frequency_consistency(pyHDB)
#!/usr/bin/env python
#  -*- coding: utf-8 -*-

import meshmagick.mmio as mmio
import meshmagick.hydrostatics as hs
from meshmagick.mesh import Mesh
from math import pi, fabs


# Importing cylinder mesh
vertices, faces = mmio.load_VTP('meshmagick/tests/data/Cylinder.vtp')
cylinder = Mesh(vertices, faces)
# cylinder.show()

hs_cylinder = hs.Hydrostatics(cylinder)

vertices, faces = mmio.load_VTP('meshmagick/tests/data/SEAREV.vtp')
searev = Mesh(vertices, faces)

def test_verbose():
    hs_cylinder.verbose
    hs_cylinder.verbose_off()
    hs_cylinder.verbose_off()
    return

def test_accessors():
    hs_cylinder.gravity
    hs_cylinder.gravity = 9.81
    hs_cylinder.rho_water = 1025.
    mass = hs_cylinder.mass
    hs_cylinder.mass = mass