# Auto name the Part name from .inp file by gmsh

**URL:** <https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430>\
**Category:** General Questions\
**Created:** [October 1, 2022, 1:36pm UTC](https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430 "2022-10-01T13:36:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lu.Henry](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Lu.Henry](https://prepomax.discourse.group/u/Lu.Henry)\
**Post date:** [October 1, 2022, 1:36pm UTC](https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430/1 "2022-10-01T13:36:40Z")

</div>

Hello,

I have the assembly with lots of part (more than 100). So I used gmsh to mesh it first, and got lots of .inp files.  
When I import .inp files, the part name in PrePoMax only name Solid\_part-~.

My .inp file like follows  
my\_part.inp

```auto
*Part, name=my_part
*NODE
...node...
...node...
*******E L E M E N T S*************
*ELEMENT, type=C3D10, ELSET=my_part_element
...element...
...element...

```

I can only get Element set with the name which I set “my\_part\_element”. But when I remove the Element set, it is very difficult to find related Part with Element set.

Is there any way to name the Part name automatically?

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [October 1, 2022, 3:13pm UTC](https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430/2 "2022-10-01T15:13:36Z")

</div>

At the moment this is not possible. Can you share one of the .inp files?

---

<div class="post-metadata">

**Author:** ![Lu.Henry](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Lu.Henry](https://prepomax.discourse.group/u/Lu.Henry)\
**Post date:** [October 2, 2022, 2:56am UTC](https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430/3 "2022-10-02T02:56:25Z")

</div>

Hi Matej :

Here you are.  
[frame\_fixed\_gmsh.inp](https://inventeccorp-my.sharepoint.com/:u:/g/personal/lu_henry_inventec_com/EdmC1JxGj_VPgkRi8RpE7RoBKn2JwLploeivDBqe3TX-rg?e=rKX6g6)  
The link is valid until 2022/10/31.

My solution is using “Convert to Part” to convert Element sets to Parts. And then, delete each “Solid\_part-”.  
 ![image](https://global.discourse-cdn.com/free1/uploads/prepomax/original/1X/d5ae3e70c40da92021aae7d181fcaf6d28805662.png)

---

<div class="post-metadata">

**Author:** ![Lu.Henry](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Lu.Henry](https://prepomax.discourse.group/u/Lu.Henry)\
**Post date:** [October 2, 2022, 3:01am UTC](https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430/4 "2022-10-02T03:01:05Z")

</div>

My code of Gmsh as follows:

```auto
def gmsh_step_to_stl(file_address, size=3):
    try:
        file_name = file_address.split('\\')[-1]
        size = 0.5 if size < 0.5 else size

        gmsh.initialize()
        gmsh.open(file_address)

        # ent = gmsh.model.getEntities()
        # for e in ent:
        # n = gmsh.model.getEntityName(e[0], e[1])

        # if n and e[0]==3:
        # part_name = n.split('/')[-1]
        # print(part_name,e)

        gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0)
        gmsh.option.setNumber('Mesh.MeshSizeFromCurvature', 8)
        gmsh.option.setNumber('Mesh.MeshSizeMax', size)
        if size/5<0.3:
            gmsh.option.setNumber("Mesh.MeshSizeMin", 0.3)
        else:
            gmsh.option.setNumber("Mesh.MeshSizeMin", size/5)

        try:
            # if second_order_bool:
            # gmsh.model.mesh.generate(3)
            # gmsh.model.mesh.setOrder(2)
            # else:
            # gmsh.model.mesh.generate(3)
            gmsh.model.mesh.generate(2)
        except:
            print(f'WARNING : {file_name} need OCC heal.')
            gmsh.finalize()
            gmsh.initialize()
            gmsh.open(file_address)
            gmsh.model.occ.healShapes()
            gmsh.model.occ.synchronize()
            gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0)
            gmsh.option.setNumber('Mesh.MeshSizeFromCurvature', 8)
            gmsh.option.setNumber('Mesh.MeshSizeMax', size)
            if size/5<0.3:
                gmsh.option.setNumber("Mesh.MeshSizeMin", 0.3)
            else:
                gmsh.option.setNumber("Mesh.MeshSizeMin", size/5)
            # if second_order_bool:
            # gmsh.model.mesh.generate(3)
            # gmsh.model.mesh.setOrder(2)
            # else:
            # gmsh.model.mesh.generate(3)
            gmsh.model.mesh.generate(2)
            file_address = file_address.replace(".stp","_OCCHealShape.stp").replace(".step","_OCCHealShape.step")

        file_address = file_address.replace(".stp",".stl").replace(".step",".stl")
        gmsh.write(file_address)

        print(f'{file_name} : Gmsh convert STEP to STL FINISHED.')
        print(f'## Gmsh STEP to STL saved : "{file_address}"')
        gmsh.finalize()
        return file_address
    except:
        [print("\t<<<"+line+">>>") for line in traceback.format_exc().split("\n")]

        print(f'ERROR : gmsh_step_to_stl in {file_address}')
        gmsh.finalize()
        return file_address

```

```auto
def gmsh_stl_to_inp(file_address, size = 3,
                    second_order_bool = True,
                    with_surface_bool = True,
                    remove_degenerate_element_bool = True):
    
    def tetrahedron_volume(tetrahedron_index):
        node_indexs = gmsh.model.mesh.getElement(tetrahedron_index)[1]
        node0 = gmsh.model.mesh.getNode(node_indexs[0])[0]
        u = gmsh.model.mesh.getNode(node_indexs[1])[0] - node0
        v = gmsh.model.mesh.getNode(node_indexs[2])[0] - node0
        w = gmsh.model.mesh.getNode(node_indexs[3])[0] - node0
        d = u[0]*(v[1]*w[2]-v[2]*w[1])+\
            u[1]*(v[2]*w[0]-v[0]*w[2])+\
            u[2]*(v[0]*w[1]-v[1]*w[0])
        return 1.0/(1.0*2.0*3.0) * abs(d)
    
    try:
        gmsh.initialize()

        file_name = file_address.split('\\')[-1]
        print(f'{file_name} : Gmsh convert stl to inp ...')

        # Clear all models and merge an STL mesh that we would like to remesh (from
        # the parent directory):
        gmsh.clear()
        gmsh.merge(file_address)

        # Create a volume from all the surfaces
        s = gmsh.model.getEntities(2)
        l = gmsh.model.geo.addSurfaceLoop([e[1] for e in s])
        gmsh.model.geo.addVolume([l])

        gmsh.model.geo.synchronize()

        # We specify element sizes imposed by a size field, just because we can :-)
        f = gmsh.model.mesh.field.add("MathEval")
        gmsh.model.mesh.field.setString(f, "F", str(int(size)))
        gmsh.model.mesh.field.setAsBackgroundMesh(f)

        if second_order_bool:
            gmsh.model.mesh.generate(3)
            gmsh.model.mesh.setOrder(2)
        else:
            gmsh.model.mesh.generate(3)

        if not with_surface_bool:
            surface_elements_index = []
            for i in [2,3]+[9,10]+[16]+[20,21,22,23,24,25]:
                surface_elements_index += gmsh.model.mesh.getElementsByType(i)[0].tolist()
            gmsh.model.mesh.setVisibility(surface_elements_index, 0)
            gmsh.plugin.setNumber('Invisible', 'DeleteElements', 1)
            gmsh.plugin.run('Invisible')

        if remove_degenerate_element_bool:
            tetrahedron_indexs = gmsh.model.mesh.getElementsByType(11)[0]
            degenerate_element_indexs = []
            for index in tetrahedron_indexs:
                volume = tetrahedron_volume(index)
                if volume<1e-05:
                    degenerate_element_indexs.append(index)
                    print(f'{file_name.replace(".stl","")} tetrahedron element {index} is degenerated, vol= {volume}')
            gmsh.model.mesh.setVisibility(degenerate_element_indexs, 0)
            gmsh.plugin.setNumber('Invisible', 'DeleteElements', 1)
            gmsh.plugin.run('Invisible')
            print(f'Remove {len(degenerate_element_indexs)} degenerated tetrahedrons')

        #gmsh.option.setNumber('Mesh.SaveGroupsOfNodes', 1)
        file_address = file_address.replace("_blender","_gmsh").replace(".stl",".inp")
        gmsh.write(file_address)
        gmsh.finalize()
        
        print(f'{file_name} : Gmsh convert stl to inp FINISHED.')

        f = open(file_address, 'r+',encoding="utf-8")
        f.write( f'*Part, name={file_name.replace("_blender","_gmsh").replace(".stl","")}\n**')
        f.close()
        
        print(f'## Gmsh stl to inp saved : "{file_address}"')
        
        return file_address
    except:
        [print("\t<<<"+line+">>>") for line in traceback.format_exc().split("\n")]
        
        ## open Gmsh
        #gmsh.fltk.run()
        # file_address = file_address.replace("_blender","_error_gmsh").replace(".stl",".inp")
        # gmsh.write(file_address)

        print(f'ERROR : gmsh_stl_to_inp in {file_address}')
        
        gmsh.finalize()
        return file_address

```

---

<div class="post-metadata">

**Author:** ![Matej](https://avatars.discourse-cdn.com/v4/letter/m/a698b9/32.png) [@Matej](https://prepomax.discourse.group/u/Matej)\
**Post date:** [October 2, 2022, 3:14pm UTC](https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430/5 "2022-10-02T15:14:48Z")

</div>

I have changed the .inp reader to account for the `*Part` keyword, even though Gmesh does not use it correctly. Each `*Part` keyword should namely end with the `*End part` keyword.

The problem with the current implementation is that it will work only for a single part saved in a single .inp file. Supporting the whole Abaqus `*Assembly` keyword is too much work for now.

Why do you mesh the geometry in Gmesh if you are using only tetrahedrons?

---

<div class="post-metadata">

**Author:** ![Lu.Henry](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Lu.Henry](https://prepomax.discourse.group/u/Lu.Henry)\
**Post date:** [October 2, 2022, 4:44pm UTC](https://prepomax.discourse.group/t/auto-name-the-part-name-from-inp-file-by-gmsh/430/6 "2022-10-02T16:44:32Z")

</div>

Hi Matej,  
Thanks for your reply.

> Why do you mesh the geometry in Gmesh if you are using only tetrahedrons?

I guess you mean that why don’t I mesh tetrahedrons directly but mesh 2D surface in stl first and then convert it to tetrahedrons.  
The reason is that the stp file with defect sometime cannot mesh tetrahedrons directly, even used occ.healShapes ( occ is OpenCascade. It packaged by Gmsh.), so I will get 2D surface mesh in stl and fix it by Blender script automatically.

In addition, I choose Gmsh is just because it is fast, and the mesh kernel in PrePoMax is a little bit slow.
