Salome HOME
Adding user documentation
[modules/smesh.git] / src / SMESH_SWIG / smesh_tools.py
1 #!/usr/bin/env python3
2
3 import sys
4 import salome
5 import medcoupling as mc
6 from math import pi
7 import numpy as np
8
9 #salome.salome_init()
10
11 import GEOM
12 from salome.geom import geomBuilder
13
14 geompy = geomBuilder.New()
15
16 import  SMESH, SALOMEDS
17 from salome.smesh import smeshBuilder
18
19 smesh = smeshBuilder.New()
20
21 from salome.kernel.logger import Logger
22 logger = Logger("salome.smesh.smesh_tools")
23 logger.setLevel("DEBUG")
24
25 def smesh_create_dual_mesh(mesh_ior, output_file, adapt_to_shape=True, mesh_name="MESH"):
26     """ Create a dual of the mesh in input_file into output_file
27
28     Args:
29         mesh_ior (string): corba Id of the Tetrahedron mesh
30         output_file (string): dual mesh file
31     """
32     # Import mesh from file
33     mesh = salome.orb.string_to_object(mesh_ior)
34     if not mesh:
35         raise Exception("Could not find mesh using id: ", mesh_ior)
36
37     shape = mesh.GetShapeToMesh()
38
39     # Creating output file
40     myfile = mc.MEDFileUMesh()
41     myfile.setName(mesh_name)
42
43
44     # We got a meshProxy so we need to convert pointer to MEDCoupling
45     int_ptr = mesh.ExportMEDCoupling(True, True)
46     dab = mc.FromPyIntPtrToDataArrayByte(int_ptr)
47     mc_mesh_file = mc.MEDFileMesh.New(dab)
48     tetras = mc_mesh_file[0]
49     # End of SMESH -> MEDCoupling part for dualmesh
50
51     tetras = mc.MEDCoupling1SGTUMesh(tetras)
52     polyh = tetras.computeDualMesh()
53
54     ## Adding skin + transfering groups on faces from tetras mesh
55     mesh2d = polyh.buildUnstructured().computeSkin()
56     mesh2d.setName(mesh_name)
57     myfile.setMeshAtLevel(-1, mesh2d)
58
59
60     for grp_name in mc_mesh_file.getGroupsOnSpecifiedLev(-1):
61         logger.debug("Transferring group: "+ grp_name)
62         grp_tria = mc_mesh_file.getGroup(-1, grp_name)
63         # Retrieve the nodes in group
64         grp_nodes = grp_tria.computeFetchedNodeIds()
65         # Find all the cells lying on one of the nodes
66         id_grp_poly = mesh2d.getCellIdsLyingOnNodes(grp_nodes, False)
67
68         grp_poly = mesh2d[id_grp_poly]
69
70         # We use the interpolation to remove the element that are not really in
71         # the group (the ones that are next to a nodes nut not in the group
72         # will have the sum of their column in the enterpolation matrix equal
73         # to zero)
74         rem = mc.MEDCouplingRemapper()
75
76         rem.prepare(grp_poly, grp_tria, "P0P0")
77         m = rem.getCrudeCSRMatrix()
78         _, id_to_keep = np.where(m.sum(dtype=np.int64, axis=0) >= 1e-07)
79
80         id_grp_poly = id_grp_poly[id_to_keep.tolist()]
81         id_grp_poly.setName(grp_name)
82
83         myfile.addGroup(-1, id_grp_poly)
84
85     # Getting list of new points added on the skin
86     skin = tetras.buildUnstructured().computeSkin()
87     skin_polyh = polyh.buildUnstructured().computeSkin()
88     allNodesOnSkinPolyh = skin_polyh.computeFetchedNodeIds()
89     allNodesOnSkin = skin.computeFetchedNodeIds()
90     ptsAdded = allNodesOnSkinPolyh.buildSubstraction(allNodesOnSkin)
91     ptsAddedMesh = mc.MEDCouplingUMesh.Build0DMeshFromCoords( skin_polyh.getCoords()[ptsAdded] )
92
93     if adapt_to_shape:
94         logger.debug("Adapting to shape")
95         ptsAddedCoo = ptsAddedMesh.getCoords()
96         ptsAddedCooModified = ptsAddedCoo[:]
97
98         # Matching faces with their ids
99         faces = geompy.ExtractShapes(shape, geompy.ShapeType["FACE"], True)
100         id2face = {}
101         for face in faces:
102             id2face[face.GetSubShapeIndices()[0]] = face
103
104         ## Projecting each points added by the dual mesh on the surface it is
105         # associated with
106         for i, tup in enumerate(ptsAddedCooModified):
107             vertex = geompy.MakeVertex(*tuple(tup))
108             shapes = geompy.GetShapesNearPoint(shape, vertex,
109                                                geompy.ShapeType["FACE"])
110             prj = geompy.MakeProjection(vertex,
111                                         id2face[shapes.GetSubShapeIndices()[0]])
112             new_coor = geompy.PointCoordinates(prj)
113             ptsAddedCooModified[i] = new_coor
114
115         polyh.getCoords()[ptsAdded] = ptsAddedCooModified
116
117     polyh.setName(mesh_name)
118     myfile.setMeshAtLevel(0, polyh)
119
120     logger.debug("Writting dual mesh in :"+output_file)
121     myfile.write(output_file, 2)