Salome HOME
feat: new crackAlong method
[tools/medcoupling.git] / src / MEDLoader / Swig / MeshFormatWriterTest1.py
1 # Copyright (C) 2007-2024  CEA, EDF
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18
19 from MEDLoader import *
20 import unittest
21 from MEDLoaderDataForTest import MEDLoaderDataForTest,WriteInTmpDir
22
23 class MeshFormatWriterTest2(unittest.TestCase):
24
25   def createMesh(self, nb_seg):
26
27     # Create mesh
28     mesh_dim = 3
29     self.bounding_box_coords = [(0, 100)]*mesh_dim
30     # with 25 segs per side, time of test run
31     # 9.12: 7.8 s
32     # 9.13: 0.1 s
33
34     # with 100 nb_segs per side:
35     # 9.12: more than 3 h
36     # 9.13: 8.14 s
37
38     nb_segs = [nb_seg]*mesh_dim
39     box_sizes = [size_coords[1]-size_coords[0] for size_coords in self.bounding_box_coords]
40     print("box_sizes: ", box_sizes)
41     box_steps = [box_sizes[i]/nb_segs[i] for i in range(mesh_dim)]
42     l_nb_nodes = [nb_segs_i+1 for nb_segs_i in nb_segs]
43     l_start = [size_coords[0] for size_coords in self.bounding_box_coords]
44     l_end = [size_coords[1] for size_coords in self.bounding_box_coords]
45
46     mesh = MEDCouplingIMesh("Mesh", mesh_dim, l_nb_nodes, l_start, box_steps)
47     self.mesh = mesh.buildUnstructured()
48     pass
49
50   def createVolumeGroups(self):
51     nb_cells = self.mesh.getNumberOfCells()
52     nb_half_cells = int(round(nb_cells/2))
53     grp0 = DataArrayInt(list(range(nb_half_cells)))
54     grp0.setName("half1")
55     grp1 = DataArrayInt(list(range(nb_half_cells, nb_cells)))
56     grp1.setName("half2")
57     self.volumeGroups = [grp0, grp1]
58     pass
59
60   def createSkinGroups(self):
61     # create groups on each side of skin mesh
62     nb_faces = self.skinMesh.getNumberOfCells()
63     #xMin, xMax, yMin, yMax, zMin, zMax
64     xMin, xMax = self.bounding_box_coords[0]
65     yMin, yMax = self.bounding_box_coords[1]
66     zMin, zMax = self.bounding_box_coords[2]
67     tol = 1e-10
68     barycenters = self.skinMesh.computeIsoBarycenterOfNodesPerCell()
69     left = []
70     right = []
71     bottom = []
72     top = []
73     back = []
74     front = []
75     for i in range(nb_faces):
76       coord = barycenters[i]
77       x, y, z = coord.getValues()
78       if abs(x-xMin) < tol:
79         left.append(i)
80       elif abs(x-xMax) < tol:
81         right.append(i)
82       elif abs(y-yMin) < tol:
83         back.append(i)
84       elif abs(y-yMax) < tol:
85         front.append(i)
86       elif abs(z-zMin) < tol:
87         bottom.append(i)
88       elif abs(z-zMax) < tol:
89         top.append(i)
90
91     grp_left = DataArrayInt(left)
92     grp_left.setName("left")
93     grp_right = DataArrayInt(right)
94     grp_right.setName("right")
95     grp_back = DataArrayInt(back)
96     grp_back.setName("back")
97     grp_front = DataArrayInt(front)
98     grp_front.setName("front")
99     grp_bottom = DataArrayInt(bottom)
100     grp_bottom.setName("bottom")
101     grp_top = DataArrayInt(top)
102     grp_top.setName("top")
103     self.skinGroups = [grp_left, grp_right, grp_back, grp_front, grp_bottom, grp_top]
104     pass
105
106   def createField(self):
107     # create a field on nodes with 1 component
108     coords = self.mesh.getCoords()
109     coords_z = coords[:,2]
110     zMin, zMax = self.bounding_box_coords[2]
111     coords_z_normed = coords_z/(zMax-zMin)
112     size_min = 1e-4
113     size_max = 1e-3
114     coords_z_normed.applyFuncOnThis('(%f-%f)*tanh(x)/tanh(1)+%f'%(size_max, size_min, size_min))
115
116     # Create the field with this array
117     self.field = MEDCouplingFieldDouble(ON_NODES,ONE_TIME)
118     self.field.setName("Elevation")
119     self.field.setMesh(self.mesh)
120     self.field.setTime(0,1,1)
121     self.field.setArray(coords_z_normed)
122     pass
123
124   def createMEDMeshFile(self):
125     self.meshMEDFile = MEDFileUMesh()
126     self.meshMEDFile.setMeshAtLevel(0, self.mesh)
127     self.meshMEDFile.setGroupsAtLevel(0, self.volumeGroups)
128     self.meshMEDFile.setMeshAtLevel(-1, self.skinMesh)
129     self.meshMEDFile.setGroupsAtLevel(-1, self.skinGroups)
130     pass
131
132   def setMeshInMEDFileData(self):
133     # Set mesh in file data structure
134     ms=MEDFileMeshes()
135     ms.pushMesh(self.meshMEDFile)
136     self.medFileData = MEDFileData()
137     self.medFileData.setMeshes(ms)
138     pass
139
140   def setFieldInMEDFileData(self):
141     mf=MEDFileFields()
142     fmts0=MEDFileFieldMultiTS()
143     mf.pushField(fmts0)
144     f1ts=MEDFileField1TS()
145     f1ts.setFieldNoProfileSBT(self.field)
146     fmts0.pushBackTimeStep(f1ts)
147     self.medFileData.setFields(mf)
148     pass
149
150   def writeToMeshFile(self, meshFileName):
151     tmpMeshWriter = MeshFormatWriter()
152     tmpMeshWriter.setMeshFileName(meshFileName)
153     tmpMeshWriter.setMEDFileDS(self.medFileData)
154     tmpMeshWriter.write()
155     pass
156
157   def readMeshFile(self, meshFileName):
158     meshFormatReader = MeshFormatReader()
159     meshFormatReader.setFile(meshFileName)
160     medFileData = meshFormatReader.loadInMedFileDS()
161     meshes = medFileData.getMeshes()
162     meshNames = meshes.getMeshesNames()
163     assert len(meshNames) == 1
164     self.meshMEDFileOut = meshes.getMeshWithName(meshNames[0])
165
166   def compareFamilies(self, levels):
167     meshRef = self.meshMEDFile
168     meshRead = self.meshMEDFileOut
169     # compare families on levels
170     for level in levels:
171       print("level: ", level)
172       # ids of families at this level
173       referenceFamilyIds = meshRef.getFamilyFieldAtLevel(level).getDifferentValues().getValues()
174       print("referenceFamilyIds; ", referenceFamilyIds)
175       readFamilyIds      = meshRead.getFamilyFieldAtLevel(level).getDifferentValues().getValues()
176       print("readFamilyIds: ", readFamilyIds)
177       assert len(readFamilyIds) == len(readFamilyIds)
178
179       for ref_id in referenceFamilyIds:
180         # by convention, the id in the .mesh file is the abs of the family
181         read_id = abs(ref_id)
182         referenceName = meshRef.getFamilyNameGivenId(ref_id)
183         readName = meshRead.getFamilyNameGivenId(read_id)
184
185         referenceFamilyArr = meshRef.getFamilyArr(level, referenceName)
186         readFamilyArr = meshRead.getFamilyArr(level, readName)
187
188         # compare family arrays
189         referenceFamilyArr = meshRef.getFamilyArr(level, referenceName)
190         readFamilyArr = meshRead.getFamilyArr(level, readName)
191         referenceFamilyArr.isEqualWithoutConsideringStr(readFamilyArr)
192         #print(readFamilyArr_i)
193
194         # compare family meshes
195         referenceFamily = meshRef.getFamily(level, referenceName)
196         readFamily = meshRead.getFamily(level, readName)
197
198         assert referenceFamily.isEqualWithoutConsideringStr(readFamily, 1e-12)
199
200   @WriteInTmpDir
201   def testMeshHexaWithoutField(self):
202     """
203     Test writing .mesh without field does not crash (as it did before 9.13)
204     """
205
206     nb_seg = 3
207     self.createMesh(nb_seg)
208
209     # Create groups
210     self.createVolumeGroups()
211     # Build 1D mesh and create groups of faces
212     self.skinMesh = self.mesh.computeSkin()
213     self.createSkinGroups()
214     self.createField()
215     self.createMEDMeshFile()
216
217     self.setMeshInMEDFileData()
218
219     # write to med (to debug if needed)
220     #medFileData.write("Mesh3D_hexa.med", 2)
221
222     # write to .mesh
223     self.writeToMeshFile("Mesh3D_hexa_%i.mesh"%nb_seg)
224     # test succeeds if there is no crash
225     pass
226
227   @WriteInTmpDir
228   def testMeshHexaWithField(self):
229     """
230     Test writing .mesh is not too slow (more than 9 seconds before 9.13)
231     """
232
233     nb_seg = 25
234     self.createMesh(nb_seg)
235
236     # Create groups
237     self.createVolumeGroups()
238     # Build 1D mesh and create groups of faces
239     self.skinMesh = self.mesh.computeSkin()
240     self.createSkinGroups()
241     self.createField()
242     self.createMEDMeshFile()
243
244     # Set mesh in file data structure
245     self.setMeshInMEDFileData()
246     # Set field in file data structure
247     self.setFieldInMEDFileData()
248
249     # Write to med (to debug if needed)
250     #medFileData.write("Mesh3D_hexa.med", 2)
251
252     # Write to .mesh
253     meshFileName = "Mesh3D_hexa_%i.mesh"%nb_seg
254     self.writeToMeshFile(meshFileName)
255
256     # Read Mesh File
257     self.readMeshFile(meshFileName)
258
259     # Compare families at levels
260     self.compareFamilies([0, -1])
261
262     pass
263
264   @WriteInTmpDir
265   def testMeshTetraWithField(self):
266     """
267     Test writing .mesh tetra
268     """
269
270     nb_seg = 3
271     self.createMesh(nb_seg)
272
273     self.mesh = self.mesh.tetrahedrize(PLANAR_FACE_5)[0].buildUnstructured()
274
275     # Create groups
276     self.createVolumeGroups()
277     # Build 1D mesh and create groups of faces
278     self.skinMesh = self.mesh.computeSkin()
279     self.createSkinGroups()
280     self.createField()
281     self.createMEDMeshFile()
282
283     # Set mesh in file data structure
284     self.setMeshInMEDFileData()
285     # Set field in file data structure
286     self.setFieldInMEDFileData()
287
288     # Write to med (to debug if needed)
289     #medFileData.write("Mesh3D_tetra.med", 2)
290
291     # Write to .mesh
292     meshFileName = "Mesh3D_hexa_%i.mesh"%nb_seg
293     self.writeToMeshFile(meshFileName)
294
295     # Read Mesh File
296     self.readMeshFile(meshFileName)
297
298     # Compare families at levels
299     self.compareFamilies([0, -1])
300
301     pass
302
303 if __name__ == '__main__':
304   unittest.main()