1 # Copyright (C) 2007-2024 CEA, EDF
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.
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.
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
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 from MEDLoader import *
21 from MEDLoaderDataForTest import MEDLoaderDataForTest,WriteInTmpDir
23 class MeshFormatWriterTest2(unittest.TestCase):
25 def createMesh(self, nb_seg):
29 self.bounding_box_coords = [(0, 100)]*mesh_dim
30 # with 25 segs per side, time of test run
34 # with 100 nb_segs per side:
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]
46 mesh = MEDCouplingIMesh("Mesh", mesh_dim, l_nb_nodes, l_start, box_steps)
47 self.mesh = mesh.buildUnstructured()
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)))
55 grp1 = DataArrayInt(list(range(nb_half_cells, nb_cells)))
57 self.volumeGroups = [grp0, grp1]
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]
68 barycenters = self.skinMesh.computeIsoBarycenterOfNodesPerCell()
75 for i in range(nb_faces):
76 coord = barycenters[i]
77 x, y, z = coord.getValues()
80 elif abs(x-xMax) < tol:
82 elif abs(y-yMin) < tol:
84 elif abs(y-yMax) < tol:
86 elif abs(z-zMin) < tol:
88 elif abs(z-zMax) < tol:
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]
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)
114 coords_z_normed.applyFuncOnThis('(%f-%f)*tanh(x)/tanh(1)+%f'%(size_max, size_min, size_min))
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)
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)
132 def setMeshInMEDFileData(self):
133 # Set mesh in file data structure
135 ms.pushMesh(self.meshMEDFile)
136 self.medFileData = MEDFileData()
137 self.medFileData.setMeshes(ms)
140 def setFieldInMEDFileData(self):
142 fmts0=MEDFileFieldMultiTS()
144 f1ts=MEDFileField1TS()
145 f1ts.setFieldNoProfileSBT(self.field)
146 fmts0.pushBackTimeStep(f1ts)
147 self.medFileData.setFields(mf)
150 def writeToMeshFile(self, meshFileName):
151 tmpMeshWriter = MeshFormatWriter()
152 tmpMeshWriter.setMeshFileName(meshFileName)
153 tmpMeshWriter.setMEDFileDS(self.medFileData)
154 tmpMeshWriter.write()
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])
166 def compareFamilies(self, levels):
167 meshRef = self.meshMEDFile
168 meshRead = self.meshMEDFileOut
169 # compare families on 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)
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)
185 referenceFamilyArr = meshRef.getFamilyArr(level, referenceName)
186 readFamilyArr = meshRead.getFamilyArr(level, readName)
188 # compare family arrays
189 referenceFamilyArr = meshRef.getFamilyArr(level, referenceName)
190 readFamilyArr = meshRead.getFamilyArr(level, readName)
191 referenceFamilyArr.isEqualWithoutConsideringStr(readFamilyArr)
192 #print(readFamilyArr_i)
194 # compare family meshes
195 referenceFamily = meshRef.getFamily(level, referenceName)
196 readFamily = meshRead.getFamily(level, readName)
198 assert referenceFamily.isEqualWithoutConsideringStr(readFamily, 1e-12)
201 def testMeshHexaWithoutField(self):
203 Test writing .mesh without field does not crash (as it did before 9.13)
207 self.createMesh(nb_seg)
210 self.createVolumeGroups()
211 # Build 1D mesh and create groups of faces
212 self.skinMesh = self.mesh.computeSkin()
213 self.createSkinGroups()
215 self.createMEDMeshFile()
217 self.setMeshInMEDFileData()
219 # write to med (to debug if needed)
220 #medFileData.write("Mesh3D_hexa.med", 2)
223 self.writeToMeshFile("Mesh3D_hexa_%i.mesh"%nb_seg)
224 # test succeeds if there is no crash
228 def testMeshHexaWithField(self):
230 Test writing .mesh is not too slow (more than 9 seconds before 9.13)
234 self.createMesh(nb_seg)
237 self.createVolumeGroups()
238 # Build 1D mesh and create groups of faces
239 self.skinMesh = self.mesh.computeSkin()
240 self.createSkinGroups()
242 self.createMEDMeshFile()
244 # Set mesh in file data structure
245 self.setMeshInMEDFileData()
246 # Set field in file data structure
247 self.setFieldInMEDFileData()
249 # Write to med (to debug if needed)
250 #medFileData.write("Mesh3D_hexa.med", 2)
253 meshFileName = "Mesh3D_hexa_%i.mesh"%nb_seg
254 self.writeToMeshFile(meshFileName)
257 self.readMeshFile(meshFileName)
259 # Compare families at levels
260 self.compareFamilies([0, -1])
265 def testMeshTetraWithField(self):
267 Test writing .mesh tetra
271 self.createMesh(nb_seg)
273 self.mesh = self.mesh.tetrahedrize(PLANAR_FACE_5)[0].buildUnstructured()
276 self.createVolumeGroups()
277 # Build 1D mesh and create groups of faces
278 self.skinMesh = self.mesh.computeSkin()
279 self.createSkinGroups()
281 self.createMEDMeshFile()
283 # Set mesh in file data structure
284 self.setMeshInMEDFileData()
285 # Set field in file data structure
286 self.setFieldInMEDFileData()
288 # Write to med (to debug if needed)
289 #medFileData.write("Mesh3D_tetra.med", 2)
292 meshFileName = "Mesh3D_hexa_%i.mesh"%nb_seg
293 self.writeToMeshFile(meshFileName)
296 self.readMeshFile(meshFileName)
298 # Compare families at levels
299 self.compareFamilies([0, -1])
303 if __name__ == '__main__':