예제 #1
0
def test_refine_function():
    """
    Test of the function that has been designed to quickly specify a refinement constraint.
    #* Test OK

    """
    name = "test_refine_function"
    model.add(name)
    rect_vtcs = [geo.Point(np.array(c)) for c in [(-4, -2), (4, -2), (4, 2), (-4, 2)]]
    mid_N = geo.Point(np.array((0, 2)))
    mid_S = geo.Point(np.array((0, -2)))
    attrac_NW = geo.Point(np.array((-2, 1)))
    attrac_mid = geo.Line(mid_N, mid_S)
    rect_ll = geo.LineLoop(rect_vtcs, False)
    rect_s = geo.PlaneSurface(rect_ll)
    rect_s.add_gmsh()

    f = msh.set_mesh_refinement(
        [0.2, 1],
        [0.03, 0.2],
        attractors={"points": [attrac_NW], "curves": [attrac_mid]},
        sigmoid_interpol=True,
    )
    msh.set_background_mesh(f)

    factory.synchronize()
    model.mesh.generate(2)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.msh &" % name)
예제 #2
0
def test_Restrict():
    """
    Test of the Restrict subclass of the Field base class.
    #* Test OK!

    """
    name = "test_Restrict"
    model.add(name)
    vtcs_1 = [geo.Point(np.array(c)) for c in [(-1, -1), (1, -1), (1, 1), (-1, 1)]]
    vtcs_2 = [geo.Point(np.array(c)) for c in [(0, 0), (2, 0), (2, 2), (0, 2)]]
    ll_1 = geo.LineLoop(vtcs_1, explicit=False)
    ll_2 = geo.LineLoop(vtcs_2, explicit=False)
    surf_1 = geo.PlaneSurface(ll_1)
    surf_2 = geo.PlaneSurface(ll_2)
    surf_1.add_gmsh()
    surf_2.add_gmsh()

    f = msh.MathEvalField("0.1")
    g = msh.MathEvalField("(x-0.25)*(x-0.25)+0.02")
    h = msh.RestrictField(g, surfaces=[surf_1])
    msh.set_background_mesh([f, h])

    factory.synchronize()
    model.mesh.generate(2)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.msh &" % name)
예제 #3
0
def test_Arc():
    """
    Test of the Arc class.
    Position : OK
    Mesh : OK
    """

    name = "test_Arc"
    gmsh.model.add(name)

    coords = [
        (0.05, 0.0),
        (1.8, 0.0),
        (2.0, 0.2),
        (2.0, 1.95),
        (1.95, 2.0),
        (0.2, 2.0),
        (0.0, 1.8),
        (0.0, 0.05),
    ]
    mesh_size = [0.01] * len(coords)
    pts = [geo.Point(np.array(c), m_s) for c, m_s in zip(coords, mesh_size)]
    lines = [
        geo.Line(pts[0], pts[1]),
        geo.Line(pts[2], pts[3]),
        geo.Line(pts[4], pts[5]),
        geo.Line(pts[6], pts[7]),
    ]
    centers = [(1.8, 0.2), (1.95, 1.95), (0.2, 1.8), (0.05, 0.05)]
    centers = [geo.Point(np.array(c)) for c in centers]
    arcs = [
        geo.Arc(pts[1], centers[0], pts[2]),
        geo.Arc(pts[3], centers[1], pts[4]),
        geo.Arc(pts[5], centers[2], pts[6]),
        geo.Arc(pts[7], centers[3], pts[0]),
    ]
    for ln in lines:
        ln.add_gmsh()
    for arc in arcs:
        arc.add_gmsh()

    factory.synchronize()
    data = gmsh.model.getEntities()
    print("model name : %s \n" % name, data)
    gmsh.model.mesh.generate(1)  # We can generatate 1D meshes for the 2 lines

    fig, ax = plt.subplots()
    plt.axis("equal")
    for pt in pts:
        pt.plot2D()
    for ln in lines:
        ln.plot2D()
    for arc in arcs:
        arc.plot2D()
    plt.pause(0.1)
    gmsh.model.mesh.generate(1)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #4
0
def test_fctn_restrict():
    """
    Test of the function that has been designed to quickly specify a refinement constraint with a restriction to a given surface.
    #* Test OK

    """
    name = "test_Restrict_with_fctn"
    model.add(name)
    vtcs_1 = [geo.Point(np.array(c)) for c in [(-1, -1), (1, -1), (1, 1), (-1, 1)]]
    vtcs_2 = [geo.Point(np.array(c)) for c in [(0, 0), (2, 0), (2, 2), (0, 2)]]
    ll_1 = geo.LineLoop(vtcs_1, explicit=False)
    ll_2 = geo.LineLoop(vtcs_2, explicit=False)
    surf_1 = geo.PlaneSurface(ll_1)
    surf_2 = geo.PlaneSurface(ll_2)
    surf_1.add_gmsh()
    surf_2.add_gmsh()

    f = msh.MathEvalField("0.1")
    g = msh.MathEvalField("(x-0.25)*(x-0.25)+0.02")
    h = msh.MathEvalField("(y-0.25)*(y-0.25)+0.02")
    gr = msh.RestrictField(g, surfaces=[surf_1], curves=surf_1.ext_contour.sides)
    hr = msh.RestrictField(
        h, surfaces=[surf_2], curves=surf_2.ext_contour.sides + surf_1.ext_contour.sides
    )
    msh.set_background_mesh([f, gr, hr])

    factory.synchronize()
    model.mesh.generate(2)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.msh &" % name)
예제 #5
0
def test_Threshold():
    """
    Test of the AttractorField and ThresholdField subclass of the Field base class.
    #* Test OK

    """
    name = "test_Threshold"
    model.add(name)
    rect_vtcs = [geo.Point(np.array(c)) for c in [(-4, -2), (4, -2), (4, 2), (-4, 2)]]
    mid_N = geo.Point(np.array((0, 2)))
    mid_S = geo.Point(np.array((0, -2)))
    attrac_NW = geo.Point(np.array((-2, 1)))
    attrac_mid = geo.Line(mid_N, mid_S)
    rect_ll = geo.LineLoop(rect_vtcs, False)
    rect_s = geo.PlaneSurface(rect_ll)
    rect_s.add_gmsh()

    f = msh.AttractorField(
        points=[attrac_NW], curves=[attrac_mid], nb_pts_discretization=10
    )
    g = msh.ThresholdField(f, 0.2, 1, 0.03, 0.2, True)

    msh.set_background_mesh(g)

    factory.synchronize()
    model.mesh.generate(2)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.msh &" % name)
예제 #6
0
def test_remove_ll_duplicates():
    """
    Test of the remove_duplicates static method of the class LineLoop.
    Results : OK
    """
    pts_1 = [(2, 1), (-2, 1), (-2, -1), (2, -1)]
    pts_1 = [geo.Point(np.array(c)) for c in pts_1]
    pts_2 = [(-2, -1), (2, -1), (2, 1), (-2, 1)]
    pts_2 = [geo.Point(np.array(c)) for c in pts_2]
    lines_1 = [
        [(3, 4), (-3, 4)],
        [(-3, 4), (-3, -4)],
        [(-3, -4), (3, -4)],
        [(3, -4), (3, 4)],
    ]
    lines_2 = [
        [(-3, 4), (-3, -4)],
        [(-3, -4), (3, -4)],
        [(3, -4), (3, 4)],
        [(3, 4), (-3, 4)],
    ]
    lines_1 = [
        geo.Line(*[geo.Point(np.array(c)) for c in cc]) for cc in lines_1
    ]
    lines_2 = [
        geo.Line(*[geo.Point(np.array(c)) for c in cc]) for cc in lines_2
    ]
    ll_pts_1 = geo.LineLoop(pts_1, explicit=False)
    ll_pts_2 = geo.LineLoop(pts_2, explicit=False)
    ll_lines_1 = geo.LineLoop(lines_1, explicit=True)
    ll_lines_2 = geo.LineLoop(lines_2, explicit=True)
    all_ll = [ll_lines_2, ll_pts_1, ll_pts_2, ll_lines_1]
    print(all_ll)
    plt.figure()
    plt.axis("equal")
    colors = ["red", "green", "orange", "blue"]
    for ll, c in zip(all_ll, colors):
        ll_copy = copy.deepcopy(
            ll
        )  # The plot method will creat sides and the 3 next methods have been designed to work well only if sides is empty.
        ll_copy.plot2D(c)
        plt.pause(0.2)
    unique_ll = geo.remove_duplicates(all_ll)
    print(unique_ll)
    plt.figure()
    plt.axis("equal")
    for ll, c in zip(unique_ll, colors):
        ll.plot2D(c)
        plt.pause(0.2)
예제 #7
0
def test_Point():
    """
    Test of the Point class.
    """

    name = "test_Point"
    gmsh.model.add(name)
    coords = [(0.0, 0.0), (0.0, 2.5), (SR2, SR2)]
    coords = [np.array(c) for c in coords]
    pts = [geo.Point(c) for c in coords]

    print("Before calling the API addPoint function :")
    for pt in pts:
        print("Point tag  : {}, coordinates : {}".format(pt.tag, pt.coord))
    for pt in pts:
        pt.add_gmsh()
    print("After calling the API addPoint function :")
    for pt in pts:
        print("Point tag  : {}, coordinates : {}".format(pt.tag, pt.coord))

    factory.synchronize()
    data = gmsh.model.getEntities()
    print("model name : %s" % name)
    print(data)

    plt.figure()
    plt.axis("equal")
    for pt in pts:
        pt.plot2D()
    plt.pause(0.1)
    gmsh.write("%s.brep" % name)
    os.system("gmsh %s.brep &" % name)
예제 #8
0
def test_periodic():
    name = "periodic"
    model.add(name)

    vtcs = [
        geo.Point(np.array(c), 0.5)
        for c in [(-2, +1), (0, +1), (+2, +1), (+2, -1), (0, -1), (-2, -1)]
    ]
    vtcs[0].mesh_size = 0.01
    vtcs[2].mesh_size = 0.05
    sides = [geo.Line(vtcs[i - 1], vtcs[i]) for i in range(len(vtcs))]
    surf = geo.PlaneSurface(geo.LineLoop(sides, explicit=True))
    surf.add_gmsh()
    data = gmsh.model.getEntities()
    print("model name : %s" % name)
    print(data)
    factory.synchronize()
    msh.set_periodicity_pairs([sides[3]], [sides[0]], np.array((4, 0)))
    msh.set_periodicity_pairs(
        [sides[-1], sides[-2]], [sides[1], sides[2]], np.array((0, -2))
    )
    gmsh.model.mesh.generate(2)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #9
0
def test_Min():
    """
    Test of Min subclass of the Field base class
    and of the use of set_background_mesh function with a list of fields as input.
    
    #* Test OK

    """
    name = "test_Min"
    model.add(name)
    rect_vtcs = [geo.Point(np.array(c)) for c in [(-4, -2), (4, -2), (4, 2), (-4, 2)]]
    rect_ll = geo.LineLoop(rect_vtcs, False)
    rect_s = geo.PlaneSurface(rect_ll)
    rect_s.add_gmsh()

    h1 = msh.MathEvalField("0.1")
    h2 = msh.MathEvalField("(x*x)+0.02")
    h1.add_gmsh()
    h2.add_gmsh()
    msh.set_background_mesh([h1, h2])

    factory.synchronize()
    model.mesh.generate(2)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.msh &" % name)
예제 #10
0
def test_Line():
    """
    Test of the Line class.

    Position : OK
    Mesh : OK
    """

    name = "test_Line"
    gmsh.model.add(name)

    coords = [(0.0, 0.0), (0.0, 2.5), (SR2, SR2)]
    mesh_size = [0.1, 0.1, 0.01]
    coords = [np.array(c) for c in coords]
    pts = [geo.Point(c, m_s) for c, m_s in zip(coords, mesh_size)]
    lines = [geo.Line(pts[0], pts[1]), geo.Line(pts[0], pts[2])]

    for ln in lines:
        ln.add_gmsh()

    factory.synchronize()
    data = gmsh.model.getEntities()
    print("model name : %s \n " % name, data)
    gmsh.model.mesh.generate(1)  # We can generatate 1D meshes for the 2 lines

    plt.figure()
    plt.axis("equal")
    for ln in lines:
        ln.plot2D()
    plt.pause(0.1)
    gmsh.model.mesh.generate(1)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #11
0
def test_reflections():

    name = "test_reflections"
    gmsh.model.add(name)
    pt1 = geo.Point(np.array((1.0, 0.0)))
    pt2 = geo.Point(np.array((2.0, 3.0)))
    pt_I = geo.Point(np.array((3.0, 3.0)))
    pt1_s = geo.point_reflection(pt1, pt_I)
    pt2_s = geo.point_reflection(pt2, pt_I)
    plt.figure()
    plt.axis("equal")
    for p, c in zip([pt1, pt2, pt1_s, pt2_s, pt_I],
                    ["red", "blue", "orange", "green", "black"]):
        p.plot2D(c)
        p.add_gmsh()
    plt.show()
    rect = [(-2, -3), (-5, -3), (-5, -4), (-2, -4)]
    rect = geo.LineLoop([geo.Point(np.array(c)) for c in rect], False)
    tri = [(-3, 2), (-2, 3), (-1, 2)]
    tri = geo.LineLoop([geo.Point(np.array(c)) for c in tri], False)
    tri.round_corner_incircle(0.1)
    pt_M = geo.Point(np.array((-6.0, 0.0)))
    rect_s = geo.plane_reflection(rect, pt_M, np.array((4.0, 0.0, 0.0)))
    tri_s = geo.plane_reflection(tri, pt_M, np.array((4.0, 0.0, 0.0)))
    plt.figure()
    plt.axis("equal")
    for p, c in zip([rect, tri, rect_s, tri_s, pt_M],
                    ["red", "blue", "orange", "green", "black"]):
        p.plot2D(c)
        p.add_gmsh()
    plt.show()
    factory.synchronize()
    gmsh.write("%s.brep" % name)
    os.system("gmsh %s.brep &" % name)
예제 #12
0
def test_MathEval():
    """
    Test of MathEval subclass of the Field base class.

    #* Test OK

    """
    name = "test_MathEval"
    model.add(name)
    rect_vtcs = [geo.Point(np.array(c)) for c in [(-4, -2), (4, -2), (4, 2), (-4, 2)]]
    rect_ll = geo.LineLoop(rect_vtcs, False)
    rect_s = geo.PlaneSurface(rect_ll)
    rect_s.add_gmsh()

    f = msh.MathEvalField("(Cos(3.14*x) * Sin(3.14*y)+1)*0.1+0.005")
    f.add_gmsh()  # Optional
    msh.set_background_mesh(f)

    factory.synchronize()
    model.mesh.generate(2)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.msh &" % name)
예제 #13
0
파일: __init__.py 프로젝트: bd1747/HO_homog
def Gmsh2DPartFromRVE(cell: Gmsh2DRVE, nb_cells, part_name=None):
    """[summary]

    Parameters
    ----------
    rve : Gmsh2DRVE
        [description]
    nb_cells : tuple, dimension 2 or 3
        Number of cells in each direction.
    part_name: str, optional
        Desired name for the mesh file
    Returns
    -------
    tuple
        Paths to the RVE mesh and the part mesh

    Remarques
    ----------
    Pour le moment, le RVE est composé d'une unique cellule.
    Pour le moment, le domaine macro est un parallélogramme aligné avec les axes
    de la cellule et contient un nombre entier de cellules.
    """

    name = cell.name
    cell_vect = cell.gen_vect
    # * 2D -> 3D
    if cell_vect.shape != (3, 3):
        cell_vect_3D = np.zeros((3, 3))
        cell_vect_3D[:cell_vect.shape[0], :cell_vect.shape[1]] = cell_vect
        cell_vect = cell_vect_3D
    if len(nb_cells) != 3:
        nb_cells = tuple(padded(nb_cells, 1, 3))

    # TODO : Activer le model gmsh correspondant au RVE
    model.setCurrent(name)
    # TODO : Créer un domaine macro
    part_vect = cell_vect * np.asarray(nb_cells)
    macro_vertices = [
        np.zeros((3, )),
        part_vect[0],
        part_vect[0] + part_vect[1],
        part_vect[1],
    ]
    macro_lloop = geo.LineLoop([geo.Point(c) for c in macro_vertices])
    macro_surf = geo.PlaneSurface(macro_lloop)

    translat_vectors = list()
    for translat_combination in product(*[range(i) for i in nb_cells]):
        if translat_combination == (0, 0, 0):
            continue  # Correspond à la cellule de base
        # * cell_vect : vectors in column
        t_vect = np.dot(cell_vect, np.array(translat_combination))
        translat_vectors.append(t_vect)
    # ? Exemple :
    # ? >>> nb_cells = (2,3)
    # ? >>> nb_cells = tuple(padded(nb_cells,1,3))
    # ? >>> nb_cells
    # * (2, 3, 1)
    # ? >>> translat_vectors = list()
    # ? >>> cell_vect = np.array(((4.,1.,0.),(3.,8.,0.),(0.,0.,0.)))
    # ? >>> for translat_combination in product(*[range(i) for i in nb_cells]):
    # ?         t_vect = np.dot(cell_vect, np.array(translat_combination))
    # ?         translat_vectors.append(t_vect)
    # ? >>> translat_vectors
    # * [array([0., 0., 0.]), array([1., 8., 0.]), array([ 2., 16.,  0.]), array([4., 3., 0.]), array([ 5., 11.,  0.]), array([ 6., 19.,  0.])] #noqa
    cell_surfaces_by_gp = [phy_surf.entities for phy_surf in cell.phy_surf]
    repeated_surfaces_by_gp = [list() for i in range(len(cell.phy_surf))]
    # * Structure de repeated_surfaces_by_gp :
    # * List avec :
    # *     pour chaque physical group, et pour chaque translation
    # *          la liste des surfaces (entitées) translatées

    for i, gp_surfaces in enumerate(cell_surfaces_by_gp):
        for t_vect in translat_vectors:
            dimTags = factory.copy([(2, s.tag) for s in gp_surfaces])
            factory.translate(dimTags, *(t_vect.tolist()))
            # ? Opération booléenne d'intersection ?
            # ? Pour détecter si surface entière : comparaison de boundingbox surface d'origine et bounding box resultat - vecteur translation
            this_translation_surfs = [
                geo.AbstractSurface(dt[1]) for dt in dimTags
            ]
            repeated_surfaces_by_gp[i].append(this_translation_surfs)
    factory.synchronize()
    # TODO : Contraintes de périodicité
    for j, t_vect in enumerate(translat_vectors):
        master = list(chain.from_iterable(cell_surfaces_by_gp))
        all_surfs_this_transl = [surfs[j] for surfs in repeated_surfaces_by_gp]
        slaves = list(chain.from_iterable(all_surfs_this_transl))
        msh.set_periodicity_pairs(slaves, master, t_vect)
    # TODO : Extension des physical groups
    phy_surfaces = list()
    for i in range(len(cell.phy_surf)):
        all_surfaces = cell_surfaces_by_gp[i] + list(
            flatten(repeated_surfaces_by_gp[i]))
        tag = cell.phy_surf[i].tag + 1000
        name = cell.phy_surf[i].name
        phy_surfaces.append(geo.PhysicalGroup(all_surfaces, 2, name, tag))
    for gp in cell.phy_surf:
        gp.remove_gmsh()
    factory.synchronize()
    for gp in phy_surfaces:
        gp.add_gmsh()
    # all_gp = model.getPhysicalGroups()
    # dimtags_part = [(gp.dim, gp.tag) for gp in phy_surfaces]
    # remove_gp = [dt for dt in all_gp if not dt in dimtags_part]
    # model.removePhysicalGroups(remove_gp)
    # ! Pour le moment, il semble impossible de réutiliser le tag d'un physical group
    # ! qui a été supprimé.
    # ! Voir : \Experimental\Test_traction_oct19\pb_complet\run_3\MWE_reuse_tag.py
    # ! Autre solution :
    # ! - Compléter les physical group existants ?
    # !      Impossible car groups déjà ajoutés au model
    # ! Utiliser un autre tag, avec une règle pour relier les 2.
    # !     Solution retenue. Règle choisie : le tag pour la part = 1000 + tag pour la cell

    # TODO : All mesh generation
    geo.PhysicalGroup.set_group_mesh(True)
    model.mesh.generate(1)
    model.mesh.generate(2)
    model.mesh.removeDuplicateNodes()
    gmsh.model.mesh.renumberNodes()
    gmsh.model.mesh.renumberElements()
    geo.PhysicalGroup.set_group_visibility(False)

    rve_path = cell.mesh_abs_path
    conversion = {
        "RVE": "PART",
        "rve": "part",
        "Rve": "Part",
        "cell": "part",
        "CELL": "PART",
        "Cell": "Part",
    }
    if part_name:
        part_path = rve_path.with_name(part_name).with_suffix(".msh")
    elif any(x in rve_path.name for x in conversion.keys()):
        name = rve_path.name
        for old, new in conversion.items():
            name = name.replace(old, new)
        part_path = rve_path.with_name(name).with_suffix(".msh")
    else:
        part_path = rve_path.with_name(rve_path.stem + "_part.msh")
    gmsh.write(str(part_path.with_suffix(".brep")))
    gmsh.write(str(part_path))
    return Gmsh2DPart(part_vect, nb_cells, phy_surfaces, part_path)
예제 #14
0
파일: __init__.py 프로젝트: bd1747/HO_homog
    def __init__(self, pattern_ll, cell_vect, nb_cells, offset, attractors,
                 soft_mat, name):
        """
        Contrat : Créer un maillage pour des RVE 2D, plans, comportant au plus 2 matériaux constitutifs et pouvant contenir plusieurs cellules.

        cell_vect : Vecteurs de périodicité en colonne, définit également le parallélogramme qui contient la cellule.
        #! La cellule doit être un parallélogramme.

        Parameters
        ----------
        pattern_ll : list
            Instances of LineLoop that define the contours of the microstructure.
        cell_vect : 2D array
            dimensions of the unit cell and directions of periodicity.
            (given in a 2D cartesian coordinate system)
        nb_cells : 1D array
            Numbers of cells in each direction of repetition/periodicity.
        offset : 1D array
            Relative position inside a cell of the point that will coincide with the origin of the global domain.
        attractors : list
            Instances of Point.
            Can also be = None or empty.
            It represent the points that will be used as attractors in the definition of the element characteristic length fields.
            Attractors are geometrical elements of the cell around which mesh refinement constraints will be set.
        name : string or Path
        """

        self.name = name.stem if isinstance(name, PurePath) else name
        model.add(self.name)
        model.setCurrent(self.name)

        if offset.any():
            nb_pattern = [
                math.ceil(val + 1) if offset[i] != 0 else math.ceil(val)
                for i, val in enumerate(nb_cells)
            ]
            nb_pattern = np.array(nb_pattern, dtype=np.int8)
            pattern_ll = offset_pattern(pattern_ll, offset, cell_vect)
        else:
            nb_pattern = np.int8(np.ceil(nb_cells))

        if not np.equal(nb_pattern, 1).all():
            duplicate_pattern(pattern_ll, nb_pattern, cell_vect)

        rve_vect = cell_vect * np.asarray(nb_cells)
        pt_o = np.zeros((3, ))
        macro_vtcs = [
            pt_o,
            rve_vect[:, 0],
            rve_vect[:, 0] + rve_vect[:, 1],
            rve_vect[:, 1],
        ]
        macro_ll = geo.LineLoop([geo.Point(c) for c in macro_vtcs])
        macro_s = geo.PlaneSurface(macro_ll)

        if attractors:
            if not all(isinstance(e, geo.Point) for e in attractors):
                _err_msg = """Use of curves as attractors for the refinement of the mesh
                is not yet fully supported in our python library for gmsh."""
                raise TypeError(_err_msg)
                # TODO : toujours d'actualité ?
            if offset.any():
                attractors = offset_pattern(attractors, offset, cell_vect)
            if not np.equal(nb_pattern, 1).all():
                duplicate_pattern(attractors, nb_pattern, cell_vect)

        logger.info("Start boolean operations on surfaces")
        _msg_ok = "The main material domain of the RVE is connected (topological property)."  # noqa
        _msg_no_surface = "The boolean operation for creating the main material domain of the RVE return 0 surfaces."
        _msg_not_connected = "The main material domain of the RVE obtained by a boolean operation is disconnected (topological property)."

        phy_surf = list()
        pattern_s = [geo.PlaneSurface(ll) for ll in pattern_ll]
        rve_s = geo.surface_bool_cut(macro_s, pattern_s)
        if len(rve_s) == 1:
            logger.info(_msg_ok)
        elif len(rve_s) == 0:
            logger.warning(_msg_no_surface)
        else:
            logger.warning(_msg_not_connected)

        rve_s_phy = geo.PhysicalGroup(rve_s, 2, "microstruct_domain")
        phy_surf.append(rve_s_phy)
        if soft_mat:
            soft_s = geo.surface_bool_cut(macro_s, rve_s)
            soft_s_phy = geo.PhysicalGroup(soft_s, 2, "soft_domain")
            phy_surf.append(soft_s_phy)
        logger.info("Done boolean operations on surfaces")

        if attractors:
            need_sync = False
            for entity in attractors:
                if not entity.tag:
                    entity.add_gmsh()
                    need_sync = True
            if need_sync:
                factory.synchronize()  # ? Pourrait être enlevé ?

        for gp in phy_surf:
            gp.add_gmsh()
        factory.synchronize()

        data = model.getPhysicalGroups()
        details = [
            f"Physical group id : {dimtag[1]}, " +
            f"dimension : {dimtag[0]}, " +
            f"name : {model.getPhysicalName(*dimtag)}, " +
            f"nb of entitities {len(model.getEntitiesForPhysicalGroup(*dimtag))} \n"
            for dimtag in data
        ]
        logger.debug(f"All physical groups in the model : {data}")
        logger.debug(f"Physical groups details : \n {details}")
        logger.info("Done generating the gmsh geometrical model")
        if isinstance(name, PurePath):
            gmsh.write(str(name.with_suffix(".brep")))
            logger.info(f"Saving brep at {str(name.with_suffix('.brep'))}")
        else:
            gmsh.write(f"{name}.brep")
            logger.info(f"Saving brep at {name}.brep")
        macro_bndry = macro_ll.sides
        if soft_mat:
            boundary = geo.AbstractSurface.get_surfs_boundary(rve_s + soft_s)
        else:
            try:
                s = one(rve_s)
                boundary = geo.AbstractSurface.get_surfs_boundary(
                    s, recursive=False)
            except ValueError:
                boundary = geo.AbstractSurface.get_surfs_boundary(
                    rve_s, recursive=False)
        for b in boundary:
            b.get_boundary(get_coords=True)
        # factory.synchronize()
        micro_bndry = list()
        for macro_line in macro_bndry:
            fragments = geo.macro_line_fragments(boundary, macro_line)
            for c in fragments:
                c.gmsh_type = model.getType(1, c.tag)
            lines_only = [c for c in fragments if c.gmsh_type == "Line"]
            micro_bndry.append(lines_only)
        macro_dir = list()
        for i in range(len(macro_bndry) // 2):
            macro_line = macro_bndry[i]
            direction = macro_line.def_pts[-1].coord - macro_line.def_pts[
                0].coord
            macro_dir.append(direction)
        for i, crvs in enumerate(micro_bndry):
            msh.order_curves(crvs, macro_dir[i % 2], orientation=True)
        msh.set_periodicity_pairs(micro_bndry[0], micro_bndry[2])
        msh.set_periodicity_pairs(micro_bndry[1], micro_bndry[3])
        logger.info("Done defining a mesh periodicity constraint")

        tags = [
            f"per_pair_{k}" for k in ("1_slave", "2_slave", "1_mast", "2_mast")
        ]
        per_pair_phy = list()
        for crvs, tag in zip(micro_bndry, tags):
            per_pair_phy.append(geo.PhysicalGroup(crvs, 1, tag))
        for gp in per_pair_phy:
            gp.add_gmsh()

        self.gen_vect = rve_vect
        self.nb_cells = nb_cells
        self.attractors = attractors if attractors else []
        self.phy_surf = phy_surf
        self.mesh_fields = []
        self.mesh_abs_path = ""
예제 #15
0
def auxetic_square_RVE(L,
                       a,
                       t,
                       nb_cells=(1, 1),
                       offset=(0.0, 0.0),
                       soft_mat=False,
                       name=""):
    """
    Create an instance of Gmsh2DRVE that represents a RVE of
    the auxetic square microstructure.

    The generic operations will be performed with the Gmsh2DRVE methods.

    Parameters
    ----------
    L : float
        Length of the sides of the square cell.
    a : float
        Length of the slits beetween squares.
    t : float
        Width of the slits beetween squares.
    nb_cells : tuple or 1D array
        nb of cells in each direction of repetition
    offset : tuple or 1D array
        Relative position inside a cell of the point that
        will coincide with the origin of the global domain.

    Returns
    -------
    Instance of the Gmsh2DRVE class.
    """

    name = name if name else "aux_square"
    model.add(name)
    # geo.reset()

    offset = np.asarray(offset)
    nb_cells = np.asarray(nb_cells)

    logger.info("Start defining the auxetic_square geometry")
    gen_vect = np.array(((L, 0.0), (0.0, L)))
    b = (L - a) / 2.0
    e1 = np.array((L, 0.0, 0.0))
    e2 = np.array((0.0, L, 0.0))
    C = geo.Point(1 / 2.0 * (e1 + e2))
    M = geo.Point(1 / 4.0 * (e1 + e2))

    e3 = np.array((0.0, 0.0, 1.0))

    center_pts = [[(b, 0.0), (a + b, 0.0)], [(0.0, -a / 2.0), (0.0, a / 2.0)]]
    center_pts = [[geo.Point(np.array(coord)) for coord in gp]
                  for gp in center_pts]
    center_lines = [geo.Line(*pts) for pts in center_pts]
    center_lines += [geo.point_reflection(ln, M) for ln in center_lines]
    center_lines += [geo.plane_reflection(ln, C, e1) for ln in center_lines]
    center_lines += [geo.plane_reflection(ln, C, e2) for ln in center_lines]
    center_lines = geo.remove_duplicates(center_lines)

    for ln in center_lines:
        ln.ortho_dir = np.cross(e3, ln.direction())
    pattern_ll = list()
    for ln in center_lines:
        vertices = [
            geo.translation(ln.def_pts[0], t / 2 * ln.ortho_dir),
            geo.translation(ln.def_pts[1], t / 2 * ln.ortho_dir),
            geo.translation(ln.def_pts[1], -t / 2 * ln.ortho_dir),
            geo.translation(ln.def_pts[0], -t / 2 * ln.ortho_dir),
        ]
        pattern_ll.append(geo.LineLoop(vertices))
    tmp_nb_bef = len(pattern_ll)
    pattern_ll = geo.remove_duplicates(pattern_ll)

    logger.debug(
        f"Number of line-loops removed from pattern-ll : {tmp_nb_bef - len(pattern_ll)}."
    )
    logger.debug(
        f"Final number of pattern line-loops for auxetic square : {len(pattern_ll)}"
    )

    for ll in pattern_ll:
        ll.round_corner_explicit(t / 2)
        filter_sides = list()
        # * Pour ne pas essayer d'ajouter au model gmsh des lignes de longueur nulle.
        # * (Error : could not create line)
        for crv in ll.sides:
            if not crv.def_pts[0] == crv.def_pts[-1]:
                filter_sides.append(crv)
        ll.sides = filter_sides

    fine_pts = geo.remove_duplicates(
        flatten([ln.def_pts for ln in center_lines]))

    return Gmsh2DRVE(pattern_ll, gen_vect, nb_cells, offset, fine_pts,
                     soft_mat, name)
예제 #16
0
def test_LineLoop():
    """
    Test of the LineLoop class.
    Instantiate (explicit and implicit) : #*OK
    Add to the gmsh geometry model : #*OK
    Plot : #*OK
    #TODO : Tester methodes round_corner
    #TODO : Test symétries
    """

    name = "test_LineLoop"
    gmsh.model.add(name)
    # * Explicit constructor
    coords = [
        (0.05, 0.0),
        (1.8, 0.0),
        (2.0, 0.2),
        (2.0, 1.95),
        (1.95, 2.0),
        (0.2, 2.0),
        (0.0, 1.8),
        (0.0, 0.05),
    ]
    mesh_size = [0.01] * len(coords)
    pts = [geo.Point(np.array(c), m_s) for c, m_s in zip(coords, mesh_size)]
    lines = [
        geo.Line(pts[0], pts[1]),
        geo.Line(pts[2], pts[3]),
        geo.Line(pts[4], pts[5]),
        geo.Line(pts[6], pts[7]),
    ]
    centers = [(1.8, 0.2), (1.95, 1.95), (0.2, 1.8), (0.05, 0.05)]
    centers = [geo.Point(np.array(c)) for c in centers]
    arcs = [
        geo.Arc(pts[1], centers[0], pts[2]),
        geo.Arc(pts[3], centers[1], pts[4]),
        geo.Arc(pts[5], centers[2], pts[6]),
        geo.Arc(pts[7], centers[3], pts[0]),
    ]

    elmts_1D = [item for pair in zip(lines, arcs) for item in pair]
    ll_1 = geo.LineLoop(elmts_1D, explicit=True)

    # * Implicit constructor
    coords = [(1.0, 1.0), (3.0, 1.0), (3.0, 3.0), (1.0, 3.0)]
    mesh_size = [0.01] * len(coords)
    vertc = [geo.Point(np.array(c), m_s) for c, m_s in zip(coords, mesh_size)]
    ll_2 = geo.LineLoop(vertc, explicit=False)

    ll_1.add_gmsh()
    ll_2.add_gmsh()
    factory.synchronize()
    data = gmsh.model.getEntities()
    print("model name : %s \n" % name, data)
    gmsh.model.mesh.generate(1)  # We can generatate 1D meshes for the 2 lines

    fig, ax = plt.subplots()
    plt.axis("equal")
    ll_1.plot2D()
    ll_2.plot2D()
    plt.pause(0.1)
    gmsh.model.mesh.generate(1)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #17
0
def test_order_curves():
    """
    Test of the order_curves function.
    Shoud be run after the test of the gather_boundary_fragments function.

    Test of the ordering : OK
    Reverse functionnality : #! not tested yet
    """

    name = "test_order"
    gmsh.model.add(name)
    rect_vtcs = [(-4, 2), (-4, -2), (4, -2), (4, 2)]
    rect_vtcs = [geo.Point(np.array(c), 0.2) for c in rect_vtcs]
    line_N = geo.Line(geo.Point(np.array((-4, 2))), geo.Point(np.array((4, 2))))
    line_W = geo.Line(geo.Point(np.array((-4, -2))), geo.Point(np.array((-4, 2))))
    line_S = geo.Line(geo.Point(np.array((-4, -2))), geo.Point(np.array((4, -2))))
    line_E = geo.Line(geo.Point(np.array((4, -2))), geo.Point(np.array((4, 2))))
    lines = {"N": line_N, "E": line_E, "S": line_S, "W": line_W}
    holes = list()
    hole_shape = [np.array(c) for c in [(-0.2, 0), (0, -0.4), (0.2, 0), (0, 0.4)]]
    translations = [
        (-3, 2.1),
        (-1, 2.1),
        (1, 2.1),
        (3, 2.1),
        (-3, -2.1),
        (-1, -2.1),
        (1, -2.1),
        (3, -2.1),
        (4.1, -1),
        (4.1, 1),
        (-4.1, -1),
        (-4.1, 1),
    ]
    translations = [np.array(t) for t in translations]
    for t in translations:
        holes.append([geo.Point(c + t, 0.05) for c in hole_shape])

    rect_ll = geo.LineLoop(rect_vtcs, explicit=False)
    hole_ll = [geo.LineLoop(h, explicit=False) for h in holes]
    rect_s = geo.PlaneSurface(rect_ll)
    hole_s = [geo.PlaneSurface(ll) for ll in hole_ll]
    final_s = geo.bool_cut_S(rect_s, hole_s, remove_body=False, remove_tool=False)
    factory.synchronize()
    final_s = final_s[0]
    final_s.get_boundary(recursive=True)
    fig, ax = plt.subplots()
    ax.set_xlim(-4.1, 4.1)
    ax.set_ylim(-2.1, 2.1)
    for crv in final_s.boundary:
        crv.plot("blue")
    boundaries = {"N": [], "E": [], "S": [], "W": []}
    for key, line in lines.items():
        boundaries[key] = geo.gather_boundary_fragments(final_s.boundary, line)
        random.shuffle(boundaries[key])
    fig, ax = plt.subplots()
    ax.set_xlim(-4.1, 4.1)
    ax.set_ylim(-2.1, 2.1)
    colors = {"N": "red", "E": "green", "S": "orange", "W": "blue"}
    for key in boundaries.keys():
        for l in boundaries[key]:
            l.plot(colors[key])
            plt.pause(0.5)  # In order to see the order of the curves
    basis = np.array(((1.0, 0.0), (0.0, 1.0), (0.0, 0.0)))
    dir_v = {"N": basis[:, 0], "E": basis[:, 1], "S": basis[:, 0], "W": basis[:, 1]}
    for key, lns in boundaries.items():
        msh.order_curves(lns, dir_v[key])
    fig, ax = plt.subplots()
    ax.set_xlim(-4.1, 4.1)
    ax.set_ylim(-2.1, 2.1)
    for key in boundaries.keys():
        for l in boundaries[key]:
            l.plot(colors[key])
            plt.pause(0.5)  # In order to see the order of the curves
    factory.synchronize()
    plt.show(block=True)
예제 #18
0
def test_bool_ops():
    """
    Test of boolean operations performed on PlaneSurfaces instances.
    cut : OK
    intersection : geometry : OK
    intersection : mesh size : No. Very coarse mesh if the characteristic length is set from the values at Points
    #? What the second output of the booleans operations functions is?

    """
    name = "test_PlaneSurface_bool_ops"
    gmsh.model.add(name)

    coords = [
        (0.0, 0.05),
        (0.05, 0.0),
        (1.8, 0.0),
        (2.0, 0.2),
        (2.0, 1.95),
        (1.95, 2.0),
        (0.2, 2.0),
        (0.0, 1.8),
    ]
    pts = [geo.Point(np.array(c), 0.03) for c in coords]
    lines = [
        geo.Line(pts[2 * i - 1], pts[2 * i]) for i in range(len(pts) // 2)
    ]
    centers = [
        geo.Point(np.array(c), 0.03)
        for c in [(0.05, 0.05), (1.8, 0.2), (1.95, 1.95), (0.2, 1.8)]
    ]
    arcs = [
        geo.Arc(pts[2 * i], centers[i], pts[2 * i + 1])
        for i in range(len(pts) // 2)
    ]
    elmts_1D = [item for pair in zip(lines, arcs) for item in pair]
    ll_1 = geo.LineLoop(elmts_1D, explicit=True)
    coords = [(1.0, 1.0), (3.0, 1.0), (3.0, 3.0), (1.0, 3.0)]
    vertc = [geo.Point(np.array(c), 0.1) for c in coords]
    ll_2 = geo.LineLoop(vertc, explicit=False)
    rect_vtcs = [
        geo.Point(np.array(c), 0.05) for c in [(4, 2), (4, 4), (6, 4), (6, 2)]
    ]
    hole_vtcs_1 = [
        geo.Point(np.array(c), 0.02)
        for c in [(5 - 0.1, 3), (5, 3 - 0.5), (5 + 0.1, 3), (5, 3 + 0.5)]
    ]
    hole_vtcs_2 = [
        geo.Point(np.array(c), 0.02)
        for c in [(5, 3 - 0.1), (5 - 0.5, 3), (5, 3 + 0.1), (5 + 0.5, 3)]
    ]
    rect_ll = geo.LineLoop(rect_vtcs, explicit=False)
    hole_ll_1 = geo.LineLoop(hole_vtcs_1, explicit=False)
    hole_ll_2 = geo.LineLoop(hole_vtcs_2, explicit=False)

    surf_1 = geo.PlaneSurface(ll_1)
    surf_2 = geo.PlaneSurface(ll_2)
    surf_rect = geo.PlaneSurface(rect_ll)
    surf_hole_1 = geo.PlaneSurface(hole_ll_1)
    surf_hole_2 = geo.PlaneSurface(hole_ll_2)
    for s in [surf_1, surf_2, surf_rect, surf_hole_1, surf_hole_2]:
        s.add_gmsh()
    print(f"""Tags before boolean operations :
            surf_1 : {surf_1.tag}; surf_2 : {surf_2.tag}; surf_rect : {surf_rect.tag};
            surf_hole_1 : {surf_hole_1.tag}; surf_hole_2 : {surf_hole_2.tag}"""
          )
    surf_with_hole = geo.surface_bool_cut(surf_rect,
                                          [surf_hole_1, surf_hole_2])
    print(surf_with_hole)
    surf_with_hole = surf_with_hole[0]
    surf_inter = geo.surface_bool_intersect(surf_1, surf_2)
    print(surf_inter)
    surf_inter = surf_inter[0]
    factory.synchronize()

    # * Intersection, when a surface is inside another one.
    coords3 = [
        geo.Point(np.array(c), 0.05)
        for c in [(10, 10), (10, 14), (14, 14), (14, 10)]
    ]
    coords4 = [
        geo.Point(np.array(c), 0.05)
        for c in [(11, 11), (11, 13), (13, 13), (13, 11)]
    ]
    surf3 = geo.PlaneSurface(geo.LineLoop(coords3, explicit=False))
    surf3.add_gmsh()
    surf4 = geo.PlaneSurface(geo.LineLoop(coords4, explicit=False))
    surf4.add_gmsh()
    factory.synchronize()
    surf_inter34 = geo.surface_bool_intersect(surf3, [surf4])
    factory.synchronize()
    data = gmsh.model.getEntities()
    print(f"model name : {name}")
    print(data)
    print(f"""Tags after boolean operations :
            surf_1 : {surf_1.tag}; surf_2 : {surf_2.tag}; surf_rect : {surf_rect.tag};
            surf_hole_1 : {surf_hole_1.tag}; surf_hole_2 : {surf_hole_2.tag};
            surf_with_hole : {surf_with_hole.tag}; surf_inter: {surf_inter.tag}"""
          )
    gmsh.model.mesh.generate(2)
    gmsh.write(f"{name}.brep")
    gmsh.write(f"{name}.msh")
    os.system(f"gmsh {name}.brep &")
    os.system(f"gmsh {name}.msh &")
예제 #19
0
def test_PlaneSurface():
    """
    Test of the PlaneSurface class.
    Geometry of surf_1, surf_2 and surf_with_hole : #*OK
    Mesh of the 3 surfaces : #*OK
    """

    name = "test_PlaneSurface"
    gmsh.model.add(name)

    coords = [
        (0.0, 0.05),
        (0.05, 0.0),
        (1.8, 0.0),
        (2.0, 0.2),
        (2.0, 1.95),
        (1.95, 2.0),
        (0.2, 2.0),
        (0.0, 1.8),
    ]
    pts = [geo.Point(np.array(c), 0.03) for c in coords]
    lines = [
        geo.Line(pts[2 * i - 1], pts[2 * i]) for i in range(len(pts) // 2)
    ]
    centers = [
        geo.Point(np.array(c), 0.03)
        for c in [(0.05, 0.05), (1.8, 0.2), (1.95, 1.95), (0.2, 1.8)]
    ]
    arcs = [
        geo.Arc(pts[2 * i], centers[i], pts[2 * i + 1])
        for i in range(len(pts) // 2)
    ]
    elmts_1D = [item for pair in zip(lines, arcs) for item in pair]
    ll_1 = geo.LineLoop(elmts_1D, explicit=True)
    coords = [(1.0, 1.0), (3.0, 1.0), (3.0, 3.0), (1.0, 3.0)]
    vertc = [geo.Point(np.array(c), 0.01) for c in coords]
    ll_2 = geo.LineLoop(vertc, explicit=False)

    surf_1 = geo.PlaneSurface(ll_1)
    surf_2 = geo.PlaneSurface(ll_2)

    rect_vtcs = [
        geo.Point(np.array(c), 0.05) for c in [(4, 2), (4, 4), (6, 4), (6, 2)]
    ]
    hole_vtcs = [
        geo.Point(np.array(c), 0.02)
        for c in [(5 - 0.1, 3), (5, 3 - 0.5), (5 + 0.1, 3), (5, 3 + 0.5)]
    ]
    rect_ll = geo.LineLoop(rect_vtcs, explicit=False)
    hole_ll = geo.LineLoop(hole_vtcs, explicit=False)
    surf_with_hole = geo.PlaneSurface(rect_ll, [hole_ll])

    all_surf = [surf_1, surf_2, surf_with_hole]
    print(
        "Model : %s \n Add PlaneSurface instances to a gmsh model. \n Surfaces tag :"
        % name)
    for s in all_surf:
        s.add_gmsh()
        print(s.tag)

    factory.synchronize()
    data = gmsh.model.getEntities()
    print("model name : %s" % name)
    print(data)
    print("Option Mesh.SaveAll is set to 1. Initial value : %i" %
          gmsh.option.getNumber("Mesh.SaveAll"))
    gmsh.option.setNumber("Mesh.SaveAll", 1)
    gmsh.model.mesh.generate(2)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #20
0
def test_gather_line():
    """
    Test of the macro_line_fragments function.
    colors on plots : OK

    """
    name = "test_gather_line"
    gmsh.model.add(name)
    rect_vtcs = [(-4, 2), (-4, -2), (4, -2), (4, 2)]
    rect_vtcs = [geo.Point(np.array(c), 0.2) for c in rect_vtcs]
    line_N = geo.Line(geo.Point(np.array((-4, 2))), geo.Point(np.array(
        (4, 2))))
    line_W = geo.Line(geo.Point(np.array((-4, -2))),
                      geo.Point(np.array((-4, 2))))
    line_S = geo.Line(geo.Point(np.array((-4, -2))),
                      geo.Point(np.array((4, -2))))
    line_E = geo.Line(geo.Point(np.array((4, -2))), geo.Point(np.array(
        (4, 2))))
    holes = list()
    hole_shape = [
        np.array(c) for c in [(-0.2, 0), (0, -0.4), (0.2, 0), (0, 0.4)]
    ]
    translations = [
        (-3, 2.1),
        (-1, 2.1),
        (1, 2.1),
        (3, 2.1),
        (-3, -2.1),
        (-1, -2.1),
        (1, -2.1),
        (3, -2.1),
        (4.1, -1),
        (4.1, 1),
        (-4.1, -1),
        (-4.1, 1),
    ]
    translations = [np.array(t) for t in translations]
    for t in translations:
        holes.append([geo.Point(c + t, 0.05) for c in hole_shape])

    rect_ll = geo.LineLoop(rect_vtcs, explicit=False)
    hole_ll = [geo.LineLoop(h, explicit=False) for h in holes]
    rect_s = geo.PlaneSurface(rect_ll)
    hole_s = [geo.PlaneSurface(ll) for ll in hole_ll]
    final_s = geo.surface_bool_cut(rect_s, hole_s)
    factory.synchronize()
    print("length of final_s : ", len(final_s))
    final_s = final_s[0]
    final_s.get_boundary(recursive=True)

    plt.figure()
    plt.axis("equal")
    for crv in final_s.boundary:
        crv.plot2D("blue")
    boundary_N = geo.macro_line_fragments(final_s.boundary, line_N)
    boundary_W = geo.macro_line_fragments(final_s.boundary, line_W)
    boundary_S = geo.macro_line_fragments(final_s.boundary, line_S)
    boundary_E = geo.macro_line_fragments(final_s.boundary, line_E)
    factory.synchronize()
    plt.figure()
    plt.axis("equal")
    line_lists = [boundary_N, boundary_W, boundary_S, boundary_E]
    colors = ["red", "green", "orange", "blue"]
    names = ["N", "W", "S", "E"]
    gps = list()
    for l_list, col, n in zip(line_lists, colors, names):
        gp_l = geo.PhysicalGroup(l_list, 1, n)
        gp_l.add_gmsh()
        gps.append(gp_l)
        for ln in l_list:
            ln.plot2D(col)
    factory.synchronize()

    gmsh.option.setNumber("Mesh.SaveAll", 1)
    gmsh.model.mesh.generate(2)
    gmsh.write(f"{name}.brep")
    gmsh.write(f"{name}.msh")
    os.system(f"gmsh {name}.brep &")
    os.system(f"gmsh {name}.msh &")
예제 #21
0
def test_ll_modif():
    """
    Test of the three geometry operations that can be applied to LineLoop instances :
        - offset
        - round_corner_explicit
        - round_corner_incircle
    geometry (check with plots) : OK, gmsh model : OK
    """

    name = "test_LineLoop_offset_round_corners"
    gmsh.model.add(name)

    t = math.tan(math.pi / 6)
    vertcs_lists = [None, None, None]

    vertcs_lists[0] = [
        geo.Point(np.array(c), 0.05) for c in [
            (0, 0),
            (2, 0),
            (2 - SR2, 0 + SR2),
            (2, 2),
            (2 - 1, 2 + t),
            (0, 2),
        ]
    ]  # angles : pi/4, pi/2 and 2*pi/3
    vertcs_lists[1] = [
        geo.Point(np.array(c), 0.05) for c in [
            (3, 0),
            (5, 0),
            (5 - SR2, 0 + SR2),
            (5, 2),
            (5 - 1, 2 + t),
            (3, 2),
        ]
    ]
    vertcs_lists[2] = [
        geo.Point(np.array(c), 0.05) for c in [
            (6, 0),
            (8, 0),
            (8 - SR2, 0 + SR2),
            (8, 2),
            (8 - 1, 2 + t),
            (6, 2),
        ]
    ]
    vertcs_lists = [v_list_1, v_list_2, v_list_3]

    lls = [geo.LineLoop(vl, explicit=False) for vl in vertcs_lists]
    plt.figure()
    plt.axis("equal")
    for ll in lls:
        ll_copy = copy.deepcopy(ll)
        # The plot method will creat sides
        # and the 3 next methods have been designed to work well only if sides is empty.
        ll_copy.plot2D("blue")

    lls[0].offset(0.1)
    lls[1].round_corner_explicit(0.1)
    lls[2].round_corner_incircle(0.1)
    for ll in lls:
        ll.plot2D("orange")
    surfs = [geo.PlaneSurface(ll) for ll in lls]
    for s in surfs:
        s.add_gmsh()
    factory.synchronize()
    data = gmsh.model.getEntities()
    print("model name : %s" % name)
    print(data)
    gmsh.model.mesh.generate(2)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #22
0
def pantograph_E11only_RVE(
        a,
        thickness,
        fillet_r=0.0,
        nb_cells=(1, 1),
        offset=(0.0, 0.0),
        soft_mat=False,
        name="",
):
    """
    Generate a RVE object for the simplified pantograph microstructure.
    Only one floppy mode : E11
    Junctions are obtained by creating offset curves from the microstructure contour.
    + fillets -> avoid stress concentration

    Parameters
    ----------
    a: floats
        main dimension of the microstruture
    thickness : float
        distance of translation prescribed for the vertices of the contour
    fillet_r : float
        radius of the fillets for the contour
    nb_cells : tuple or 1D array
        nb of cells in each direction of repetition
    offset : tuple or 1D array
        Relative position inside a cell of the point that will coincide with the origin of the global domain

    Returns
    -------
    Instance of the Gmsh2DRVE class.
    """
    name = name if name else "pantograph"
    offset = np.asarray(offset)
    nb_cells = np.asarray(nb_cells)
    logger.info("Start defining the pantograph geometry")
    Lx = 4 * a
    Ly = 4 * a + 2 * thickness
    cell_vect = np.array(((Lx, 0.0), (0.0, Ly)))
    e1 = np.array((a, 0.0, 0.0))
    e2 = np.array((0.0, a, 0.0))
    pt_L = 2 * (e1 + e2)

    square = [e1, e2, -e1, -e2]
    square = [p + pt_L for p in square]
    square = [geo.Point(p) for p in square]

    rhombus_v = [np.array((0.0, 0.0)), e1 + 2 * e2, 4 * e2, -e1 + 2 * e2]
    rhombus_v = [geo.Point(p) for p in rhombus_v]

    cut_shape_h = [
        np.array((0.0, 0.0)),
        0.25 * (-2 * e1 + e2),
        0.25 * (-4 * e1 + e2),
        0.25 * (-4 * e1 - e2),
        4 * e1 + 0.25 * (4 * e1 - e2),
        4 * e1 + 0.25 * (4 * e1 + e2),
        4 * e1 + 0.25 * (2 * e1 + e2),
        4 * e1,
        e2 + 2 * e1,
    ]
    cut_shape_h = [geo.Point(p) for p in cut_shape_h]

    square = geo.LineLoop(square, explicit=False)
    rhombus_v = geo.LineLoop(rhombus_v, explicit=False)
    cut_shape_h = geo.LineLoop(cut_shape_h, explicit=False)
    pattern = [square, rhombus_v, cut_shape_h]
    sym_rhombus = [
        geo.plane_reflection(rhombus_v, pt_L, e1),
        geo.plane_reflection(cut_shape_h, pt_L, e2),
    ]
    for ll in sym_rhombus:
        ll.reverse()
    pattern += sym_rhombus
    pattern = geo.remove_duplicates(pattern)
    translated_pattern = list()
    for ll in pattern:
        translated_pattern.append(
            geo.translation(ll, np.array((0.0, thickness, 0.0))))
    logger.info("Done removing of the line-loops duplicates")
    pattern = translated_pattern
    constr_pts = [
        copy.deepcopy(pt) for ll in pattern for pt in iter((ll.vertices))
    ]
    for ll in pattern:
        ll.offset(thickness)

    if fillet_r:
        for ll in pattern:
            ll.round_corner_explicit(fillet_r)
    logger.info("Done rounding all corners of pattern line-loops")
    fine_pts = geo.remove_duplicates(constr_pts)
    return Gmsh2DRVE(pattern, cell_vect, nb_cells, offset, fine_pts, soft_mat,
                     name)
예제 #23
0
def test_get_domains_gmsh(plots=False):
    """ Get subdomains and partition of the boundary from a .msh file. """
    name = "test_domains"
    local_dir = Path(__file__).parent
    mesh_file = local_dir.joinpath(name + ".msh")
    gmsh.model.add(name)
    L_x, L_y = 2.0, 2.0
    H = 1.0
    vertices = [(0.0, 0.0), (0.0, L_y), (L_x, L_y), (L_x, 0.0)]
    contour = geo.LineLoop([geo.Point(np.array(c)) for c in vertices], False)
    surface = geo.PlaneSurface(contour)
    inclusion_vertices = list()
    for coord in [
        (H / 2, -H / 2, 0.0),
        (H / 2, H / 2, 0.0),
        (-H / 2, H / 2, 0.0),
        (-H / 2, -H / 2, 0.0),
    ]:
        vertex = geo.translation(geo.Point((L_x / 2, L_y / 2)), coord)
        inclusion_vertices.append(vertex)
    inclusion = geo.PlaneSurface(geo.LineLoop(inclusion_vertices, False))
    for s in [surface, inclusion]:
        s.add_gmsh()
    factory.synchronize()
    (stiff_s, ) = geo.surface_bool_cut(surface, inclusion)
    factory.synchronize()
    (soft_s, ) = geo.surface_bool_cut(surface, stiff_s)
    factory.synchronize()
    domains = {
        "stiff": geo.PhysicalGroup(stiff_s, 2),
        "soft": geo.PhysicalGroup(soft_s, 2),
    }
    boundaries = {
        "S": geo.PhysicalGroup(surface.ext_contour.sides[0], 1),
        "W": geo.PhysicalGroup(surface.ext_contour.sides[1], 1),
        "N": geo.PhysicalGroup(surface.ext_contour.sides[2], 1),
        "E": geo.PhysicalGroup(surface.ext_contour.sides[3], 1),
    }
    for group in domains.values():
        group.add_gmsh()
    for group in boundaries.values():
        group.add_gmsh()
    charact_field = mesh_tools.MathEvalField("0.05")
    mesh_tools.set_background_mesh(charact_field)
    geo.set_gmsh_option("Mesh.SaveAll", 0)
    model.mesh.generate(1)
    model.mesh.generate(2)
    gmsh.model.mesh.removeDuplicateNodes()
    gmsh.write(str(mesh_file))
    E_1, E_2, nu = 1, 3, 0.3
    materials = {
        domains["soft"].tag: mat.Material(E_1, nu, "cp"),
        domains["stiff"].tag: mat.Material(E_1, nu, "cp"),
    }
    test_part = part.FenicsPart.part_from_file(mesh_file,
                                               materials,
                                               subdomains_import=True)
    assert test_part.mat_area == approx(L_x * L_y)
    elem_type = "CG"
    degree = 2
    V = fe.VectorFunctionSpace(test_part.mesh, elem_type, degree)
    W = fe.FunctionSpace(
        test_part.mesh,
        fe.VectorElement(elem_type, test_part.mesh.ufl_cell(), degree, dim=3),
    )
    boundary_conditions = {
        boundaries["N"].tag: fe.Expression(("x[0]-1", "1"), degree=1),
        boundaries["S"].tag: fe.Expression(("x[0]-1", "-1"), degree=1),
        boundaries["E"].tag: fe.Expression(("1", "x[1]-1"), degree=1),
        boundaries["W"].tag: fe.Expression(("-1", "x[1]-1"), degree=1),
    }
    bcs = list()
    for tag, val in boundary_conditions.items():
        bcs.append(fe.DirichletBC(V, val, test_part.facet_regions, tag))
    ds = fe.Measure("ds",
                    domain=test_part.mesh,
                    subdomain_data=test_part.facet_regions)
    v = fe.TestFunctions(V)
    u = fe.TrialFunctions(V)
    F = (fe.inner(mat.sigma(test_part.elasticity_tensor, mat.epsilon(u)),
                  mat.epsilon(v)) * fe.dx)
    a, L = fe.lhs(F), fe.rhs(F)
    u_sol = fe.Function(V)
    fe.solve(a == L, u_sol, bcs)
    strain = fe.project(mat.epsilon(u_sol), W)
    if plots:
        import matplotlib.pyplot as plt

        plt.figure()
        plot = fe.plot(u_sol)
        plt.colorbar(plot)
        plt.figure()
        plot = fe.plot(strain[0])
        plt.colorbar(plot)
        plt.figure()
        plot = fe.plot(strain[1])
        plt.colorbar(plot)
        plt.figure()
        plot = fe.plot(strain[2])
        plt.colorbar(plot)
        plt.show()
    error = fe.errornorm(
        strain,
        fe.Expression(("1", "1", "0"), degree=0),
        degree_rise=3,
        mesh=test_part.mesh,
    )
    assert error == approx(0, abs=1e-12)

    materials = {
        domains["soft"].tag: mat.Material(E_1, nu, "cp"),
        domains["stiff"].tag: mat.Material(E_2, nu, "cp"),
    }
    test_part = part.FenicsPart.part_from_file(mesh_file,
                                               materials,
                                               subdomains_import=True)
    V = fe.VectorFunctionSpace(test_part.mesh, elem_type, degree)
    W = fe.FunctionSpace(
        test_part.mesh,
        fe.VectorElement(elem_type, test_part.mesh.ufl_cell(), degree, dim=3),
    )
    bcs = list()
    for tag, val in boundary_conditions.items():
        bcs.append(fe.DirichletBC(V, val, test_part.facet_regions, tag))
    v = fe.TestFunctions(V)
    u = fe.TrialFunctions(V)
    F = (fe.inner(mat.sigma(test_part.elasticity_tensor, mat.epsilon(u)),
                  mat.epsilon(v)) * fe.dx)
    a, L = fe.lhs(F), fe.rhs(F)
    u_sol = fe.Function(V)
    fe.solve(a == L, u_sol, bcs)
    strain = mat.epsilon(u_sol)
    stress = mat.sigma(test_part.elasticity_tensor, strain)
    energy = 0.5 * fe.assemble(
        fe.inner(stress, strain) * fe.dx(test_part.mesh))
    energy_abaqus = 12.8788939
    assert energy == approx(energy_abaqus, rel=1e-3)
    geo.reset()
예제 #24
0
def rotating_squares_RVE(theta,
                         r,
                         a=None,
                         b=None,
                         nb_cells=(1, 1),
                         offset=(0.0, 0.0),
                         name=""):
    """[summary]

    Parameters
    ----------
    theta : float
        Angle d'ouverture, \in [0; \pi/4].
            0 -> configuration refermé
            \pi/4 -> configuration complètement ouverte
    r : float
        junction thinness, = rayon du cercle inscrit / côté d'un triangle
    a : float
        longueur du côté bas de la cellule
    b : float
        longueur des côtés des carrés constitutifs
    name : str


    Returns
    -------
    Instance of the Gmsh2DRVE class.

    Si a est imposée :
    La cellule est de taille fixe,
    par contre la longueur des côtés des carrés dépend de l'angle d'ouverture de la microstructure.
    Si b est imposé :
    C'est l'inverse.
    Carrés de dimensions fixes, dimensions de la cellules dépendent de l'ouverture.
    """

    logger.info("Start defining the geometry")
    name = name if name else "rot_square"

    if (not a) and (not b):
        raise ValueError("a or b (exclusive OR) must be imposed")
    elif a and b:
        raise ValueError("a and b cannot be imposed simultaneously")
    elif b:
        # si on choisit la taille des carrés b
        a = rotating_squares_square_2_cell(theta, b)
    elif a:
        b = rotating_squares_cell_2_square(theta, a)

    gen_vect = np.array(((a, 0.0), (0.0, a)))
    nb_cells, offset = np.asarray(nb_cells), np.asarray(offset)

    a0 = np.array((a, 0.0, 0.0))
    a1 = np.array((0.0, a, 0.0))

    s, c = np.sin(theta), np.cos(theta)

    vertices_base_ll = [
        [0, -b * c],
        [b * s, 0],
        [0, b * c],
        [-b * s, 0],
    ]
    translat_h = [
        (0.0, a / 2, 0.0),
        (a, a / 2, 0.0),
        (a / 2, 0.0, 0.0),
        (a / 2, a, 0.0),
    ]
    rot_1 = np.pi / 2

    translat_v = [(a / 2, a / 2, 0.0), (0.0, a, 0.0), (a, 0.0, 0.0),
                  (a, a, 0.0)]
    # translat_v2 #
    z_axis = [0, 0, 1]
    # Definition of the LineLoops
    vertices_base_ll = [geo.Point(c) for c in vertices_base_ll]
    ll_base_vert = geo.LineLoop(vertices_base_ll, explicit=False)
    ll_base_horiz = geo.rotation(ll_base_vert, rot_1, z_axis)
    pattern_ll = [ll_base_vert]
    pattern_ll += [geo.translation(ll_base_vert, t) for t in translat_v]
    pattern_ll += [geo.translation(ll_base_horiz, t) for t in translat_h]
    pattern_ll = geo.remove_duplicates(pattern_ll)
    logger.info("Removing duplicate pattern line-loops: Done")
    logger.info(f"Number of pattern line-loops: {len(pattern_ll)}")
    for ll in pattern_ll:
        ll.round_corner_incircle(r)
    logger.info("Rounding all corners of pattern line-loops: Done")

    fine_pts = [pt for ll in pattern_ll for pt in ll.vertices]
    fine_pts = geo.remove_duplicates(fine_pts)

    return Gmsh2DRVE(pattern_ll, gen_vect, nb_cells, offset, fine_pts, False,
                     name)
예제 #25
0
def test_mesh_only_phy_groups():
    """
    Test of the set_group_mesh classmethod.
    A mesh must be generated only entities that belong to physical groups.
    """

    name = "test_mesh_only_phy_groups"
    gmsh.model.add(name)
    geo.set_gmsh_option("Mesh.SaveAll", 1)

    coords = [
        (0.0, 0.05),
        (0.05, 0.0),
        (1.8, 0.0),
        (2.0, 0.2),
        (2.0, 1.95),
        (1.95, 2.0),
        (0.2, 2.0),
        (0.0, 1.8),
    ]
    pts = [geo.Point(np.array(c), 0.03) for c in coords]
    lines = [
        geo.Line(pts[2 * i - 1], pts[2 * i]) for i in range(len(pts) // 2)
    ]
    centers = [
        geo.Point(np.array(c), 0.03)
        for c in [(0.05, 0.05), (1.8, 0.2), (1.95, 1.95), (0.2, 1.8)]
    ]
    arcs = [
        geo.Arc(pts[2 * i], centers[i], pts[2 * i + 1])
        for i in range(len(pts) // 2)
    ]
    elmts_1D = [item for pair in zip(lines, arcs) for item in pair]
    ll_1 = geo.LineLoop(elmts_1D, explicit=True)
    coords = [(1.0, 1.0), (3.0, 1.0), (3.0, 3.0), (1.0, 3.0)]
    vertc = [geo.Point(np.array(c), 0.01) for c in coords]
    ll_2 = geo.LineLoop(vertc, explicit=False)
    surf_1 = geo.PlaneSurface(ll_1)
    surf_2 = geo.PlaneSurface(ll_2)

    rect_vtcs = [
        geo.Point(np.array(c), 0.05) for c in [(4, 2), (4, 4), (6, 4), (6, 2)]
    ]
    hole_vtcs = [
        geo.Point(np.array(c), 0.02)
        for c in [(5 - 0.1, 3), (5, 3 - 0.5), (5 + 0.1, 3), (5, 3 + 0.5)]
    ]
    rect_ll = geo.LineLoop(rect_vtcs, explicit=False)
    hole_ll = geo.LineLoop(hole_vtcs, explicit=False)
    surf_with_hole = geo.PlaneSurface(rect_ll, [hole_ll])

    all_surf = [surf_1, surf_2, surf_with_hole]
    for s in all_surf:
        s.add_gmsh()
    factory.synchronize()
    surf_group = geo.PhysicalGroup([surf_1, surf_with_hole], 2, "surf_group")
    line_group = geo.PhysicalGroup(ll_2.sides + ll_1.sides, 1, "line_group")
    surf_group.add_gmsh()
    line_group.add_gmsh()
    surf_group.set_color([22, 160, 133, 255])
    line_group.set_color([234, 97, 83, 255])
    geo.PhysicalGroup.set_group_mesh(True)
    factory.synchronize()  # * Important before meshing
    data = model.getPhysicalGroups()
    logger.info(
        f"All physical groups in '{name}' model : \n"
        f"{data} \n"
        f"Names : {[model.getPhysicalName(*dimtag) for dimtag in data]}")
    gmsh.model.mesh.generate(2)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #26
0
def test_physical_group():
    """
    Test of the PhysicalGroup class.
    Group membership in the gmsh model : OK
    Colors in the gmsh GUI opened with gmsh.fltk.run() : OK
    Information about Physical group membership are exported in the msh file : OK

    """
    name = "test_PhysicalGroup"
    gmsh.model.add(name)
    geo.set_gmsh_option("Mesh.SaveAll", 0)
    # gmsh.option.setNumber('Mesh.MeshOnlyVisible',1)

    coords = [
        (0.0, 0.05),
        (0.05, 0.0),
        (1.8, 0.0),
        (2.0, 0.2),
        (2.0, 1.95),
        (1.95, 2.0),
        (0.2, 2.0),
        (0.0, 1.8),
    ]
    pts = [geo.Point(np.array(c), 0.03) for c in coords]
    lines = [
        geo.Line(pts[2 * i - 1], pts[2 * i]) for i in range(len(pts) // 2)
    ]
    centers = [
        geo.Point(np.array(c), 0.03)
        for c in [(0.05, 0.05), (1.8, 0.2), (1.95, 1.95), (0.2, 1.8)]
    ]
    arcs = [
        geo.Arc(pts[2 * i], centers[i], pts[2 * i + 1])
        for i in range(len(pts) // 2)
    ]
    elmts_1D = [item for pair in zip(lines, arcs) for item in pair]
    ll_1 = geo.LineLoop(elmts_1D, explicit=True)
    coords = [(1.0, 1.0), (3.0, 1.0), (3.0, 3.0), (1.0, 3.0)]
    vertc = [geo.Point(np.array(c), 0.01) for c in coords]
    ll_2 = geo.LineLoop(vertc, explicit=False)

    surf_1 = geo.PlaneSurface(ll_1)
    surf_2 = geo.PlaneSurface(ll_2)

    rect_vtcs = [
        geo.Point(np.array(c), 0.05) for c in [(4, 2), (4, 4), (6, 4), (6, 2)]
    ]
    hole_vtcs = [
        geo.Point(np.array(c), 0.02)
        for c in [(5 - 0.1, 3), (5, 3 - 0.5), (5 + 0.1, 3), (5, 3 + 0.5)]
    ]
    rect_ll = geo.LineLoop(rect_vtcs, explicit=False)
    hole_ll = geo.LineLoop(hole_vtcs, explicit=False)
    surf_with_hole = geo.PlaneSurface(rect_ll, [hole_ll])

    all_surf = [surf_1, surf_2, surf_with_hole]
    logger.info(
        f"In model {name}, PlaneSurface instances added to the gmsh model.")
    for s in all_surf:
        s.add_gmsh()
    logger.info(f"Python objects, surfaces tag : {[s.tag for s in all_surf]}")
    logger.info(
        f"Entities in model {name} before synchronize() call : {model.getEntities()}"
    )
    factory.synchronize()
    logger.info(
        f"After synchronize() call : \n Points : {model.getEntities(0)} \n Curves : {model.getEntities(1)} \n Surfaces : {model.getEntities(2)}"
    )
    surf_group = geo.PhysicalGroup([surf_1, surf_with_hole], 2, "surf_group")
    surf_group.add_gmsh()
    factory.synchronize()
    logger.info(
        "Operations : synchronize() -> def surf_group -> adding surf_group to the model -> synchronize()"
    )
    logger.info(
        f"Physical groups in model after : {model.getPhysicalGroups()}")

    # * OK, Here is no need of a second sync or a second physical group added in the model.

    factory.synchronize()
    logger.info(
        f"Physical groups in model after a second synchronize() : {model.getPhysicalGroups()}"
    )
    # surf_group.add_to_group(surf_2) #* Raise an AttributeError, OK
    line_group = geo.PhysicalGroup(ll_2.sides, 1, "line_group")
    line_group.add_to_group(ll_1.sides)
    line_group.add_gmsh()
    factory.synchronize()
    logger.info(
        "Ops : def line_group -> adding line_group to the model -> synchronize()"
    )
    logger.info(
        f"Physical groups in model after that : {model.getPhysicalGroups()}")
    pts_group = geo.PhysicalGroup(
        [pt for crv in ll_2.sides for pt in crv.def_pts], 0, "pts_group")
    pts_group.add_gmsh()
    factory.synchronize()
    logger.info(
        "Ops : def pts_group -> adding pts_group to the model -> synchronize()"
    )
    logger.info(
        f"Physical groups in model after that : {model.getPhysicalGroups()}")
    surf_group.set_color([22, 160, 133, 255])
    line_group.set_color([234, 97, 83, 255])
    factory.synchronize()  # * Important before meshing
    data = model.getPhysicalGroups()
    logger.info(
        f"All physical groups in '{name}' model : {data} Names : {[model.getPhysicalName(*dimtag) for dimtag in data]}"
    )
    prev_val = gmsh.option.getNumber("General.Verbosity")
    geo.set_gmsh_option("General.Verbosity", 3)
    gmsh.model.mesh.generate(2)
    geo.set_gmsh_option("General.Verbosity", prev_val)
    gmsh.write("%s.brep" % name)
    gmsh.write("%s.msh" % name)
    os.system("gmsh %s.brep &" % name)
    os.system("gmsh %s.msh &" % name)
예제 #27
0
def test_mat_area():
    """FenicsPart method global_aera, for 2D parts created from a gmsh mesh and from a FEniCS mesh"""
    L_x, L_y = 4.0, 5.0
    H = 1.0
    size = 0.5
    rectangle = mshr.Rectangle(fe.Point(0.0, 0), fe.Point(L_x, L_y))
    hole = mshr.Rectangle(
        fe.Point(L_x / 2 - H / 2, L_y / 2 - H / 2),
        fe.Point(L_x / 2 + H / 2, L_y / 2 + H / 2),
    )
    domain = rectangle - hole
    domain.set_subdomain(1, rectangle)
    mesh = mshr.generate_mesh(domain, size)
    dimensions = np.array(((L_x, 0.0), (0.0, L_y)))
    material = {"0": mat.Material(1.0, 0.3, "cp")}
    rect_part = part.FenicsPart(
        mesh,
        materials=material,
        subdomains=None,
        global_dimensions=dimensions,
        facet_regions=None,
    )
    assert rect_part.mat_area == (L_x * L_y - H**2)

    name = "test_mat_area"
    local_dir = Path(__file__).parent
    mesh_file = local_dir.joinpath(name + ".msh")
    gmsh.model.add(name)
    vertices = [(0.0, 0.0), (0.0, L_y), (L_x, L_y), (L_x, 0.0)]
    contour = geo.LineLoop([geo.Point(np.array(c)) for c in vertices], False)
    surface = geo.PlaneSurface(contour)
    cut_vertices = list()
    for local_coord in [(H, 0.0, 0.0), (0.0, H, 0.0), (-H, 0.0, 0.0),
                        (0.0, -H, 0.0)]:
        vertex = geo.translation(contour.vertices[2], np.array(local_coord))
        cut_vertices.append(vertex)
    cut_surface = geo.PlaneSurface(geo.LineLoop(cut_vertices, False))
    for s in [surface, cut_surface]:
        s.add_gmsh()
    factory.synchronize()
    (surface, ) = geo.surface_bool_cut(surface, cut_surface)
    factory.synchronize()
    for dim_tag in model.getEntities(2):
        if not dim_tag[1] == surface.tag:
            model.removeEntities([dim_tag], True)
    charact_field = mesh_tools.MathEvalField("0.1")
    mesh_tools.set_background_mesh(charact_field)
    geo.set_gmsh_option("Mesh.SaveAll", 1)
    model.mesh.generate(2)
    gmsh.write(str(mesh_file))
    cmd = f"dolfin-convert {mesh_file} {mesh_file.with_suffix('.xml')}"
    run(cmd, shell=True, check=True)
    mesh = fe.Mesh(str(mesh_file.with_suffix(".xml")))
    dimensions = np.array(((L_x, 0.0), (0.0, L_y)))
    material = {"0": mat.Material(1.0, 0.3, "cp")}
    rect_part = part.FenicsPart(
        mesh,
        materials=material,
        subdomains=None,
        global_dimensions=dimensions,
        facet_regions=None,
    )
    assert rect_part.mat_area == approx(L_x * L_y - H * H / 2)
    geo.reset()
예제 #28
0
import gmsh
from ho_homog import geometry as geo
from ho_homog import mesh_tools as msh
import numpy as np
import random
import matplotlib.pyplot as plt

# nice shortcuts
model = gmsh.model
factory = model.occ

plt.ion()

# ? COMPARER AVEC DES MAILLAGES PRODUITS A LA MAIN JUSTE AVEC LA GUI GMSH ?

rect_vtcs = [geo.Point(np.array(c)) for c in [(-2, -1), (2, -1), (2, 1), (-2, 1)]]
mid_N = geo.Point(np.array((0, 1)))
mid_S = geo.Point(np.array((0, -1)))
attrac_NW = geo.Point(np.array((-1, 0.5)))
attrac_mid = geo.Line(mid_N, mid_S)

rect_ll = geo.LineLoop(rect_vtcs, False)
rect_s = geo.PlaneSurface(rect_ll)


def test_MathEval():
    """
    Test of MathEval subclass of the Field base class.

    #* Test OK
예제 #29
0
logger.info("Start defining the pantograph geometry")
a = 1
b = 1
k = 0.3
r = a / 20

Lx = 4 * a
Ly = 6 * a + 2 * b
gen_vect = np.array(((Lx, 0.0), (0.0, Ly)))

e1 = np.array((a, 0.0, 0.0))
e2 = np.array((0.0, a, 0.0))
p = np.array((k, 0.0, 0.0))
b = b / a * e2

E1 = geo.Point(e1)
E2 = geo.Point(e2)
E1m = geo.Point(-1 * e1)
E2m = geo.Point(-1 * e2)
O_pt = np.zeros((3, ))
L = geo.Point(2 * (e1 + e2))
Lm = geo.Point(2 * (e1 - e2))
M = geo.Point(e1 + 1.5 * e2 + b / 2)
N = geo.Point(2 * (e1 + 1.5 * e2 + b / 2))

contours = list()
contours.append([E1, E2, E1m, E2m])
contours.append([E1, Lm, geo.Point(3 * e1), L])
contours.append([
    E2,
    L,
예제 #30
0
def beam_pantograph_RVE(a,
                        b,
                        w,
                        junction_r=0.0,
                        nb_cells=(1, 1),
                        offset=(0.0, 0.0),
                        soft_mat=False,
                        name=""):
    """
    Create an instance of Gmsh2DRVE that represents a RVE of the beam pantograph microstructure.
    The geometry that is specific to this microstructure is defined in this staticmethod. Then, the generic operations will be performed with the Gmsh2DRVE methods.

    Parameters
    ----------
    a, b : floats
        main lengths of the microstruture
    w : float
        width of the constitutive beams
    junction_r : float, optional
        Radius of the corners/fillets that are created between concurrent borders of beams.
        The default is 0., which implies that the angles will not be rounded.
    nb_cells : tuple or 1D array, optional
        nb of cells in each direction of repetition (the default is (1, 1).)
    offset : tuple, optional
        If (0., 0.) or False : No shift of the microstructure.
        Else : The microstructure is shift with respect to the macroscopic domain.
        offset is the relative position inside a cell of the point that will coincide with the origin of the global domain.
    soft_mat : bool, optional
        If True : the remaining surface inside the RVE is associated with a second material domain and a mesh is genereted to represent it.
        Else, this space remains empty.
    name : str, optional
        The name of the RVE. It is use for the gmsh model and the mesh files.
        If name is '' (default) or False, the name of the RVE is 'beam_pantograph'.

    Returns
    -------
    Instance of the Gmsh2DRVE class.
    """

    name = name if name else "beam_pantograph"
    offset = np.asarray(offset)
    nb_cells = np.asarray(nb_cells)

    logger.info("Start defining the beam pantograph geometry")
    Lx = 4 * a
    Ly = 6 * a + 2 * b
    cell_vect = np.array(((Lx, 0.0), (0.0, Ly)))
    e1 = np.array((a, 0.0, 0.0))
    e2 = np.array((0.0, a, 0.0))
    b_ = b / a * e2
    E1 = geo.Point(e1)
    E2 = geo.Point(e2)
    E1m = geo.Point(-1 * e1)
    E2m = geo.Point(-1 * e2)
    L = geo.Point(2 * (e1 + e2))
    Lm = geo.Point(2 * (e1 - e2))
    M = geo.Point(e1 + 1.5 * e2 + b_ / 2)
    I = geo.Point(2 * (e1 + 1.5 * e2 + b_ / 2))
    contours = [
        [E1, E2, E1m, E2m],
        [E1, Lm, geo.Point(3 * e1), L],
        [E1, L, E2],
        [E2, L, geo.translation(L, b_),
         geo.translation(E2, b_)],
    ]
    pattern_ll = [
        geo.LineLoop(pt_list, explicit=False) for pt_list in contours
    ]
    pattern_ll += [geo.point_reflection(ll, M) for ll in pattern_ll]
    sym_ll = [geo.plane_reflection(ll, I, e1) for ll in pattern_ll]
    for ll in sym_ll:
        ll.reverse()
    pattern_ll += sym_ll
    sym_ll = [geo.plane_reflection(ll, I, e2) for ll in pattern_ll]
    for ll in sym_ll:
        ll.reverse()
    pattern_ll += sym_ll
    pattern_ll = geo.remove_duplicates(pattern_ll)
    constr_pts = [copy.deepcopy(pt) for ll in pattern_ll for pt in ll.vertices]
    for ll in pattern_ll:
        ll.offset(w)
    if junction_r:
        for ll in pattern_ll:
            ll.round_corner_incircle(junction_r)

    fine_pts = geo.remove_duplicates(constr_pts)
    return Gmsh2DRVE(pattern_ll, cell_vect, nb_cells, offset, fine_pts,
                     soft_mat, name)