Salome HOME
cf3a2062cc8577a752f2598d70c6675d3873e5d8
[plugins/ghs3dprlplugin.git] / src / tools / testMesh.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 \r
4 # %% LICENSE_SALOME_CEA_BEGIN\r
5 # Copyright (C) 2008-2016  CEA/DEN\r
6\r
7 # This library is free software; you can redistribute it and/or\r
8 # modify it under the terms of the GNU Lesser General Public\r
9 # License as published by the Free Software Foundation; either\r
10 # version 2.1 of the License, or (at your option) any later version.\r
11\r
12 # This library is distributed in the hope that it will be useful,\r
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
15 # Lesser General Public License for more details.\r
16\r
17 # You should have received a copy of the GNU Lesser General Public\r
18 # License along with this library; if not, write to the Free Software\r
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
20\r
21 # See http://www.salome-platform.org or email : webmaster.salome@opencascade.com\r
22 # %% LICENSE_END\r
23 \r
24 \r
25 """\r
26 run coherency tests on one and some mesh.\r
27 initially used for test output(s) mg_tetra_hpc_mpi.exe\r
28 \r
29 WARNING: is for small meshes, obviously no optimisation.\r
30 WARNING: printing and .mesh indices are 1 to n when stored list python 0 to n-1\r
31 \r
32 example linux usage:\r
33 - simple run:\r
34   ./testMesh.py --verbose --testall --files ./GHS3DPRL_out.000001.mesh ./GHS3DPRL_out.000002.mesh\r
35   ./testMesh.py -a -f /tmp/GHS3DPRL_out.00000?.mesh\r
36 """\r
37 \r
38 import os\r
39 import sys\r
40 import platform\r
41 import argparse as AP\r
42 import pprint as PP #pretty print\r
43 \r
44 verbose = False\r
45 \r
46 OK = "ok"\r
47 KO = "KO"\r
48 OKSYS = 0 #for linux\r
49 KOSYS = 1 #for linux\r
50 \r
51 \r
52 #########################################\r
53 # utilities\r
54 \r
55 def okToSys(aResult, verbose=False):\r
56   """to get windows or linux result of script"""\r
57   
58   def extendList(alist):
59     """utility extend list of lists of string results with ok or KO"""\r
60     #bad: list(itertools.chain.from_list(alist)) iterate on str\r
61     res = []\r
62     if type(alist) != list:\r
63       return [alist]\r
64     else:\r
65       for i in alist:\r
66         if type(i) == str:\r
67            res.append(i)\r
68         else:\r
69            res.extend(extendList(i))\r
70     return res\r
71       \r
72   resList = extendList(aResult)\r
73   if resList == []:\r
74     if verbose: print("WARNING: result no clear: []")\r
75     return KOSYS\r
76     \r
77   rr = OK\r
78   for ri in resList:\r
79     if ri[0:2] != OK:\r
80       if verbose: print ri\r
81       rr = KO\r
82 \r
83   if verbose: print("INFO: result: %s" % rr)\r
84   if rr == OK:\r
85     return OKSYS\r
86   else:\r
87     return KOSYS\r
88 \r
89 def getDirAndName(datafile):\r
90   path, namefile = os.path.split(os.path.realpath(datafile))\r
91   rootpath = os.getcwd()\r
92   return (path, rootpath, namefile)\r
93 \r
94 def resumeList(aList):\r
95   if len(aList) == 0: \r
96     return []\r
97   if len(aList) < 3:\r
98     return aList\r
99   res = [aList[0], "...", aList[-1]]\r
100   return res\r
101 \r
102 def resumeLines(aList, ilines):\r
103   if verbose: print("INFO: resumeLines", ilines)\r
104   if len(aList) == 0: \r
105     return []\r
106   if len(aList) < 3:\r
107     return aList\r
108   res = []\r
109   for i in ilines:
110     if i != None: # if not existing tetrahedra for example\r
111       resi = [ii.strip("\n") for ii in aList[i:i+4]]\r
112       resi.append("...")\r
113       res.append(resi)\r
114   return res\r
115 \r
116 \r
117 #########################################\r
118 class XXVert(object): \r
119   """Vertices, Nodes"""\r
120   def __init__(self, x, y, z, color=0, indexglobal=0):\r
121     self.x = x\r
122     self.y = y\r
123     self.z = z\r
124     self.color = color\r
125     self.indexglobal = indexglobal\r
126 \r
127   def compare(self, vb, args, withAll=True):\r
128     if self.x != vb.x: return False\r
129     if self.y != vb.y: return False\r
130     if self.z != vb.z: return False\r
131     if withAll:\r
132       if args.withColor:\r
133         if self.color != vb.color: return False\r
134       if args.withIndex:\r
135         if self.indexglobal != vb.indexglobal: return False\r
136     return True\r
137 \r
138   def __eq__(self, vb):\r
139     """equality test without color or indexglobal"""\r
140     #print "vertice equality"\r
141     if self.x != vb.x: return False\r
142     if self.y != vb.y: return False\r
143     if self.z != vb.z: return False\r
144     return True\r
145 \r
146   def __ne__(self, vb):\r
147     """inequality test without color or indexglobal"""\r
148     #print "vertice inequality"\r
149     if self.x == vb.x and self.y == vb.y and self.z != vb.z: \r
150       return True\r
151     return False\r
152 \r
153   def __repr__(self):\r
154     return "XXVert(%.4f %.4f %.4f (%i %i))" % \\r
155            (self.x, self.y, self.z, self.color, self.indexglobal)\r
156 \r
157   def __str__(self):\r
158     return "(%s %s %s (%i %i))" % \\r
159            (self.x, self.y, self.z, self.color, self.indexglobal)\r
160 \r
161   def dist(self, vb):\r
162     res = (self.x - vb.x)**2 + (self.y - vb.y)**2 + (self.z -vb.z)**2\r
163     return res**.5\r
164 \r
165 \r
166 \r
167 #########################################\r
168 class XXEdge(object):\r
169   """Edges, 2 Nodes"""\r
170   def __init__(self, a, b, color=0, indexglobal=0):\r
171     self.a = a\r
172     self.b = b\r
173     self.color = color\r
174     self.indexglobal = indexglobal\r
175 \r
176   def compare(self, eb, args):\r
177     res = self.a.compare(eb.a, args) and \\r
178           self.b.compare(eb.b, args)\r
179     if res:\r
180       if args.withColor:\r
181         if self.color != eb.color: return False\r
182       if args.withIndex:\r
183         if self.indexglobal != eb.indexglobal: return False\r
184     return res\r
185 \r
186   def __repr__(self):\r
187     return "XXEdge(%i %i (%i %i))" % \\r
188            (self.a, self.b, self.color, self.indexglobal)\r
189 \r
190   def __str__(self):\r
191     return "(%i %i (%i %i))" % \\r
192            (self.a, self.b, self.color, self.indexglobal)\r
193 \r
194   def inTria(self, tria, args):\r
195     t = [tria.a, tria.b, tria.c]\r
196     if not self.a in t: return False\r
197     if not self.b in t: return False\r
198     return True\r
199 \r
200   def getVertices(self, mesh):\r
201     v1 = mesh.verts[self.a - 1]\r
202     v2 = mesh.verts[self.b - 1]\r
203     return [v1, v2]\r
204 \r
205 \r
206 #########################################\r
207 class XXTria(object):\r
208   """Triangles, Faces, 3 nodes"""\r
209   def __init__(self, a, b, c, color=0, indexglobal=0):\r
210     self.a = a\r
211     self.b = b\r
212     self.c = c\r
213     self.color = color\r
214     self.indexglobal = indexglobal\r
215 \r
216   def compare(self, trb, args):\r
217     res = self.a.compare(trb.a, args) and \\r
218           self.b.compare(trb.b, args) and \\r
219           self.c.compare(trb.c, args)\r
220     if res:\r
221       if args.withColor:\r
222         if self.color != trb.color: return False\r
223       if args.withIndex:\r
224         if self.indexglobal != trb.indexglobal: return False\r
225     return res\r
226 \r
227   def __repr__(self):\r
228     return "XXTria(%i %i %i (%i %i))" % \\r
229            (self.a, self.b, self.c, self.color, self.indexglobal)\r
230 \r
231   def __str__(self):\r
232     return "(%i %i %i (%i %i))" % \\r
233            (self.a, self.b, self.c, self.color, self.indexglobal)\r
234 \r
235   def inTetra(self, tetra, args):\r
236     t = [tetra.a, tetra.b, tetra.c, tetra.d]\r
237     if not self.a in t: return False\r
238     if not self.b in t: return False\r
239     if not self.c in t: return False\r
240     return True\r
241 \r
242   def getVertices(self, mesh):\r
243     v1 = mesh.verts[self.a - 1]\r
244     v2 = mesh.verts[self.b - 1]\r
245     v3 = mesh.verts[self.c - 1]\r
246     return [v1, v2, v3]\r
247 \r
248 \r
249 \r
250 #########################################\r
251 class XXTetra(object):\r
252   """Tetra, 4 nodes"""\r
253   def __init__(self, a, b, c, d, color=0, indexglobal=0):\r
254     self.a = a\r
255     self.b = b\r
256     self.c = c\r
257     self.d = d\r
258     self.color = color\r
259     self.indexglobal = indexglobal\r
260 \r
261   def compare(self, teb, args):\r
262     res = self.a.compare(teb.a, args) and \\r
263           self.b.compare(teb.b, args) and \\r
264           self.c.compare(teb.c, args) and \\r
265           self.d.compare(teb.d, args)\r
266     if res:\r
267       if args.withColor:\r
268         if self.color != teb.color: return False\r
269       if args.withIndex:\r
270         if self.indexglobal != teb.indexglobal: return False\r
271     return res\r
272 \r
273   def __repr__(self):\r
274     return "XXTetra(%i %i %i %i (%i %i))" % \\r
275            (self.a, self.b, self.c, self.d, self.color, self.indexglobal)\r
276 \r
277   def __str__(self):\r
278     return "(%i %i %i %i (%i %i))" % \\r
279            (self.a, self.b, self.c, self.d, self.color, self.indexglobal)\r
280 \r
281   def getVertices(self, mesh):\r
282     v1 = mesh.verts[self.a - 1]\r
283     v2 = mesh.verts[self.b - 1]\r
284     v3 = mesh.verts[self.c - 1]\r
285     v4 = mesh.verts[self.d - 1]\r
286     return [v1, v2, v3, v4]\r
287 \r
288 \r
289 #########################################\r
290 class XXMesh(object):\r
291   """Mesh: vertices, edges, triangles, tetrahedra"""\r
292   def __init__(self):\r
293     self.nameFile = ""\r
294     self.verts = []\r
295     self.edges = []\r
296     self.trias = []\r
297     self.tetras = []\r
298 \r
299   def initFromFileMesh(self, fileName, args, withGlobal=True):\r
300     if not os.path.isfile(fileName):\r
301       raise Exception("ERROR: inexisting file '%s'" % fileName)\r
302     with open(fileName, "r") as f:\r
303       lines = f.readlines()\r
304     iverts, iedges, itrias, itetras = self.getIndexInMeshFile(lines)\r
305     self.verts = self.getMeshVerts(lines, iverts)\r
306     self.edges = self.getMeshEdges(lines, iedges)\r
307     self.trias = self.getMeshTrias(lines, itrias)\r
308     self.tetras = self.getMeshTetras(lines, itetras)\r
309     self.nameFile = fileName\r
310     if args.globalNumerotation == True and withGlobal==True:\r
311       self.initFromFileGlobal(fileName, args)\r
312     if verbose: \r
313       print("\nINFO: initFromFileMesh: read file: %s" % str(self))\r
314       print(self.strResume())\r
315       print(PP.pformat(resumeLines(lines, [iverts, iedges, itrias, itetras])))\r
316 \r
317   def initFromFileGlobal(self, fileNameMeshOrGlobal, args):\r
318     shortname, extension = os.path.splitext(fileNameMeshOrGlobal)\r
319     if extension == ".mesh":\r
320       fileName = shortname +  ".global"\r
321     elif extension == "global":\r
322       fileName = fileNameMeshOrGlobal\r
323     else:\r
324       raise Exception("ERROR: initFromFileGlobal: unexpected file '%s'" % fileName)\r
325     if not os.path.isfile(fileName):\r
326       raise Exception("ERROR: initFromFileGlobal: inexisting file '%s'" % fileName)\r
327     \r
328     with open(fileName, "r") as f:\r
329       lines = f.readlines()\r
330     nbverts, nbedges, nbtrias, nbtetras = [int(i) for i in lines[0].split()]\r
331     if verbose:\r
332       print("\nINFO: initFromFileGlobal: read file: %s" % str(self))\r
333       print("  nbverts %i\n  nbedges %i\n  nbtrias %i\n  nbtetras %i" % (nbverts, nbedges, nbtrias, nbtetras))\r
334     if nbverts != len(self.verts): \r
335       raise Exception("ERROR: in file '%s' unexpected number of Vertices %i<>%i" % (fileName, nbverts, len(self.verts)))\r
336     if nbedges != len(self.edges): \r
337       raise Exception("ERROR: in file '%s' unexpected number of Edges %i<>%i" % (fileName, nbedges, len(self.edges)))\r
338     if nbtrias != len(self.trias): \r
339       raise Exception("ERROR: in file '%s' unexpected number of Triangles %i<>%i" % (fileName, nbtrias, len(self.trias)))\r
340     if nbtetras != len(self.tetras): \r
341       raise Exception("ERROR: in file '%s' unexpected number of Tetrahedra %i<>%i" % (fileName, nbtetras, len(self.tetras)))\r
342     i = 1 #begin index line 1\r
343     for ii in range(nbverts):\r
344       self.verts[ii].indexglobal = long(lines[i])\r
345       i +=1\r
346     for ii in range(nbedges):\r
347       self.edges[ii].indexglobal = long(lines[i])\r
348       i +=1\r
349     for ii in range(nbtrias):\r
350       self.trias[ii].indexglobal = long(lines[i])\r
351       i +=1\r
352     for ii in range(nbtetras):\r
353       self.tetras[ii].indexglobal = long(lines[i])\r
354       i +=1\r
355 \r
356 \r
357   def __repr__(self):\r
358     return "XXMesh(nameFile='%s', nbverts=%i, nbedges=%i, nbtrias=%i, nbtetras=%i)" % \\r
359            (self.nameFile, len(self.verts), len(self.edges), len(self.trias), len(self.tetras))\r
360 \r
361   def strResume(self):\r
362     res = str(self)\r
363     contents = {\r
364       "Vertices": resumeList(self.verts),\r
365       "Edges": resumeList(self.edges),\r
366       "Triangles": resumeList(self.trias),\r
367       "Tetrahedra": resumeList(self.tetras),\r
368     }\r
369     res = res + "\n" + PP.pformat(contents)\r
370     return res\r
371 \r
372   def getIndexInMeshFile(self, lines):\r
373     res = []\r
374     for s in ["Vertices", "Edges", "Triangles", "Tetrahedra"]:\r
375       try:\r
376         i = lines.index(s+"\n")\r
377       except:\r
378         i = None\r
379       res.append(i)\r
380     return res\r
381 \r
382   def getMeshVerts(self, lines, i):\r
383     res=[]\r
384     try:\r
385       idep = i+2\r
386       ilen = int(lines[i+1])\r
387       ifin =  idep+ilen\r
388       for line in lines[idep:ifin]:\r
389         li = line.split(" ")\r
390         x, y, z, color = float(li[0]), float(li[1]), float(li[2]), int(li[3])\r
391         res.append(XXVert(x, y, z, color))\r
392       return res\r
393     except:\r
394       return res\r
395 \r
396   def getMeshEdges(self, lines, i):\r
397     res=[]\r
398     try:\r
399       idep = i+2\r
400       ilen = int(lines[i+1])\r
401       ifin =  idep+ilen\r
402       for line in lines[idep:ifin]:\r
403         li = line.split(" ")\r
404         a, b, color = int(li[0]), int(li[1]), int(li[2])\r
405         res.append(XXEdge(a, b, color))\r
406       return res\r
407     except:\r
408       return res\r
409 \r
410   def getMeshTrias(self, lines, i):\r
411     res=[]\r
412     try:\r
413       idep = i+2\r
414       ilen = int(lines[i+1])\r
415       ifin =  idep+ilen\r
416       for line in lines[idep:ifin]:\r
417         li = line.split(" ")\r
418         a, b, c, color = int(li[0]), int(li[1]), int(li[2]), int(li[3])\r
419         res.append(XXTria(a, b, c, color))\r
420       return res\r
421     except:\r
422       return res\r
423 \r
424   def getMeshTetras(self, lines, i):\r
425     res=[]\r
426     try:\r
427       idep = i+2\r
428       ilen = int(lines[i+1])\r
429       ifin =  idep+ilen\r
430       for line in lines[idep:ifin]:\r
431         li = line.split(" ")\r
432         a, b, c, d, color = int(li[0]), int(li[1]), int(li[2]), int(li[3]), int(li[4])\r
433         res.append(XXTetra(a, b, c, d, color))\r
434       return res\r
435     except:\r
436       return res\r
437 \r
438   def haveVertsDistinct(self, args):\r
439     """stop a first KO"""\r
440     i = 0\r
441     verts = self.verts\r
442     for v1 in verts[:-1]:\r
443       i += 1\r
444       j = i\r
445       for v2 in verts[i:]:\r
446         j += 1\r
447         if v1.compare(v2, args):\r
448           #printing indices 1 to n\r
449           print("ERROR: %s vert[%i] equal vert[%i]: v1=%s v2=%s" % (self.nameFile, i, j, v1, v2))\r
450           return KO + " ERROR: %s some equal vertices" % self.nameFile #stop a first KO\r
451     return OK + " INFO: no equal vertices"\r
452 \r
453   def getVertices(self, elem):\r
454     """functionnal raccourci to XXElem.getVertices(XXMesh)"""\r
455     return elem.getVertices(self)\r
456 \r
457   def compareListOfVertices(self, v1s, v2s, ordered=False):\r
458     """not ordered for now"""\r
459     if ordered:\r
460       res = [i for i, j in zip(v1s, v2s) if i == j]\r
461       return len(res)==len(v1s)\r
462     else:       \r
463       res = 0\r
464       for i in v1s:\r
465         for j in v2s:\r
466           if i == j: \r
467             res += 1\r
468             break\r
469       return res==len(v1s)\r
470     \r
471     \r
472   def getCommonVerts(self, mesh, args):\r
473     res = []\r
474     for v1 in self.verts:\r
475       for v2 in mesh.verts:\r
476         if v1.compare(v2, args, withAll=False):\r
477           res.append((v1, v2))\r
478     return res\r
479 \r
480   def getVertices(self, elem):\r
481     return elem.getVertices(self)\r
482 \r
483   def getCommonEdges(self, mesh, args):\r
484     res = []\r
485     for e1 in self.edges:\r
486       v1s = self.getVertices(e1)\r
487       for e2 in mesh.edges:\r
488         v2s = mesh.getVertices(e2)\r
489         if self.compareListOfVertices(v1s, v2s):\r
490           res.append((e1, e2))\r
491     return res\r
492 \r
493   def getCommonTriangles(self, mesh, args):\r
494     res = []\r
495     for e1 in self.trias:\r
496       v1s = self.getVertices(e1)\r
497       for e2 in mesh.trias:\r
498         v2s = mesh.getVertices(e2)\r
499         if self.compareListOfVertices(v1s, v2s):\r
500           res.append((e1, e2))\r
501     return res\r
502 \r
503   def getCommonTetras(self, mesh, args):\r
504     res = []\r
505     for e1 in self.tetras:\r
506       v1s = self.getVertices(e1)\r
507       for e2 in mesh.tetras:\r
508         v2s = mesh.getVertices(e2)\r
509         if self.compareListOfVertices(v1s, v2s):\r
510           res.append((e1, e2))\r
511     return res\r
512 \r
513   def areEdgesInTrias(self, args):\r
514     """stop a first KO"""\r
515     done = False\r
516     i = 0\r
517     edges = self.edges\r
518     trias = self.trias\r
519     res = OK + " INFO: %s all edges in trias" % self.nameFile\r
520     for e in edges:\r
521       i += 1\r
522       j = 0\r
523       found = False\r
524       for t in trias:\r
525         j += 1\r
526         if e.inTria(t, args):\r
527           #if verbose: print("INFO: %s edges[%i] in trias[%i]: edge=%s tria=%s" % (self.nameFile, i, j, e, t))\r
528           found = True\r
529           break\r
530       if not found:\r
531         print("ERROR: %s edges[%i] not in trias: edge=%s" % (self.nameFile, i, e))\r
532         if verbose and not done: \r
533           print("Triangles:\n%s" % PP.pformat(self.trias))\r
534           done = True\r
535         res = KO+" ERROR: %s some edges not in trias" % (self.nameFile)\r
536     return res\r
537 \r
538 \r
539   def areTriasInTetras(self, args):\r
540     """no stop a first KO"""\r
541     done = False\r
542     i = 0\r
543     trias = self.trias\r
544     tetras = self.tetras
545     if tetras == []: #supposed skin without tetrahedra
546       res = OK +" WARNING: %s no tetrahedra in mesh" % (self.nameFile)
547       return res\r
548     res = OK + " INFO: %s all trias in tetras" % self.nameFile\r
549     for t in trias:\r
550       i += 1\r
551       j = 0\r
552       found = False\r
553       for h in tetras:\r
554         j += 1\r
555         if t.inTetra(h, args):\r
556           #if verbose: print("INFO: %s trias[%i] in tetras[%i]: tria=%s tetra=%s" % (self.nameFile, i, j, t, h))\r
557           found = True\r
558           break\r
559       if not found:\r
560         if verbose: print("ERROR: %s trias[%i] not in tetras: tria=%s" % (self.nameFile, i, t))\r
561         if verbose and not done: \r
562           print("INFO: Tetrahedra:\n%s" % PP.pformat(self.tetras))\r
563           done = True\r
564         res = KO+" ERROR: %s some trias not in tetras" % (self.nameFile)\r
565     return res\r
566 \r
567   def testIntersection(self, mesh, args):\r
568     """intersection coherency between self and mesh"""\r
569 \r
570     def storeAndInfoIntersection():\r
571       """used as macro: avoid duplicate code"""\r
572       #store info in args to use later...\r
573       args.intersections[title+name] = commons\r
574       if commons == []:\r
575         res.append(OK + " INFO: no %s" % title+name)\r
576       else:\r
577         res.append(OK + " INFO: existing %s" % title+name)\r
578       return\r
579       \r
580     res=[]\r
581     name = "%s<->%s" % (self.nameFile, mesh.nameFile)\r
582     \r
583     title = "Vertices intersection: "\r
584     commons = self.getCommonVerts(mesh, args)\r
585     storeAndInfoIntersection()\r
586 \r
587     title = "Edges intersection: "\r
588     commons = self.getCommonEdges(mesh, args)\r
589     storeAndInfoIntersection()\r
590 \r
591     title = "Triangles intersection: "\r
592     commons = self.getCommonTriangles(mesh, args)\r
593     storeAndInfoIntersection()\r
594 \r
595     title = "Tetrahedra intersection: "\r
596     commons = self.getCommonTetras(mesh, args)\r
597     storeAndInfoIntersection()\r
598 \r
599     return res\r
600       \r
601   def testIndexGlobal(self, mesh, args):\r
602     """global index coherency between self and mesh"""\r
603     \r
604     def storeAndInfoIndexGlobal():\r
605       """used as macro: avoid duplicate code"""\r
606       #store info in args to use later...\r
607       args.indexglobal[title+name] = problems\r
608       if verbose: print("\nINFO: %s\n%s" % (title+name, PP.pformat(problems)))\r
609       if problems == []:\r
610         res.append(OK + " INFO: coherent %s" % title+name)\r
611       else:\r
612         res.append(KO + " ERROR: some problems %s" % title+name)\r
613       return\r
614 \r
615     def testIndexGlobal():\r
616       """used as macro: avoid duplicate code"""\r
617       nameElem = title.split(' ')[0]\r
618       #something like 'Vertices intersection: /tmp/GHS3DPRL_out.000002.mesh<->/tmp/GHS3DPRL_out.000003.mesh'\r
619       commonsTitle = nameElem + " intersection: "+ name\r
620       #if verbose: print "testIndexGlobal",title,commonsTitle\r
621       try:\r
622         intersection = args.intersections[commonsTitle]\r
623       except:\r
624         intersection = []\r
625       problems = []\r
626       for ii, jj in intersection:\r
627         if ii.indexglobal != jj.indexglobal:\r
628           problems.append((ii, jj))\r
629       return problems\r
630 \r
631     res=[]\r
632     name = "%s<->%s" % (self.nameFile, mesh.nameFile)\r
633 \r
634     title = "Vertices indexglobal: "\r
635     problems = testIndexGlobal()\r
636     storeAndInfoIndexGlobal()\r
637 \r
638     title = "Edges indexglobal: "\r
639     problems = testIndexGlobal()\r
640     storeAndInfoIndexGlobal()\r
641 \r
642     title = "Triangles indexglobal: "\r
643     problems = testIndexGlobal()\r
644     storeAndInfoIndexGlobal()\r
645 \r
646     title = "Tetrahedra indexglobal: "\r
647     problems = testIndexGlobal()\r
648     storeAndInfoIndexGlobal()\r
649 \r
650     return res\r
651 \r
652 \r
653 #########################################\r
654 # tests\r
655  \r
656 def testAll(args):
657   """test all on meshes from tetra_hpc_mpi"""\r
658   res = [] 
659   if verbose: print("\n*****testAll*****\n")
660   args.skinMesh = None
661   if args.skinInputFile != None:
662     args.skinMesh = XXMesh()
663     #a priori no global numerotation file.global for input tetra_hpc_mpi mesh\r
664     args.skinMesh.initFromFileMesh(args.skinInputFile, args, withGlobal=False)
665     res.append(testStandaloneMesh(args.skinMesh, args))
666     print("\nINFO: testAll skin input file:\n%s" % (PP.pformat(args.skinMesh)))\r
667     \r
668   meshes = []\r
669   for fileName in args.files:\r
670     xxmesh = XXMesh()\r
671     xxmesh.initFromFileMesh(fileName, args)\r
672     meshes.append(xxmesh)\r
673   print("\nINFO: testAll ouput files:\n%s\n" % (PP.pformat(meshes)))\r
674   #test coherence of one by one meshes\r
675   for mesh in meshes:\r
676     res.append(testStandaloneMesh(mesh, args))\r
677   #test coherence of intersections an global numerotation of tetra_hpc_mpi output meshes
678   res.append(testParallelMesh(meshes, args))
679   res.append(testParallelMeshAndSkin(meshes, args))\r
680   res.append(testParallelMeshAndSkinColor(meshes, args))\r
681   return res\r
682
683   \r
684 def testStandaloneMesh(mesh, args):
685   """test coherence of one mesh alone"""\r
686   if verbose: print("\nINFO: testStandaloneMesh:\n%s" % PP.pformat(mesh))\r
687   res = []\r
688   res.append(mesh.haveVertsDistinct(args))\r
689   res.append(mesh.areEdgesInTrias(args))\r
690   res.append(mesh.areTriasInTetras(args))\r
691   return res\r
692
693 \r
694 def testParallelMesh(meshes, args):\r
695   """test intersection and overriding in tetra_hpc_mpi outputs GHS3DPRL_out.00000?.mesh"""\r
696   i = 0\r
697   res = []\r
698   args.intersections = {}\r
699   args.indexglobal = {}\r
700   for m1 in meshes[:-1]:\r
701     i += 1\r
702     for m2 in meshes[i:]:\r
703       res.append(m1.testIntersection(m2, args))\r
704       res.append(m1.testIndexGlobal(m2, args))\r
705   if verbose: \r
706     print("\nINFO: intersections\n%s" % PP.pformat(args.intersections))\r
707     print("\nINFO: indexglobal\n%s" % PP.pformat(args.indexglobal))\r
708   return res\r
709 \r
710 def testParallelMeshAndSkin(meshes, args):\r
711   """test coherency between input skin and tetra_hpc_mpi outputs GHS3DPRL_out.00000?.mesh"""\r
712   res = []\r
713   if args.skinMesh == None:
714     print("INFO: no skin Mesh for testing intersectionsSkin\n")
715     res = OK + "INFO: no skin Mesh for testing intersectionsSkin"
716     return res
717   nbtriasskin = len(args.skinMesh.trias)\r
718   for m1 in meshes:\r
719     res.append(args.skinMesh.testIntersection(m1, args))\r
720     res.append(args.skinMesh.testIndexGlobal(m1, args))
721   
722   #test total Triangles in output parallel meshes vs input skin mesh\r
723   if True:
724     kk = {} 
725     nbtriaspara = 0
726     for k in args.intersections.keys():
727       if args.skinMesh.nameFile in k:
728         ll = len(args.intersections[k])
729         if "Triangles intersection" in k: 
730           nbtriaspara += ll
731         kk[k] = len(args.intersections[k])\r
732     print("INFO: skin intersections\n%s\n" % PP.pformat(kk))\r
733     if nbtriaspara < nbtriasskin:
734       res.append(KO + " ERROR: problem all skin triangles not in parallel meshes: %i<->%i" % (nbtriasskin, nbtriaspara))\r
735   return res\r
736
737 def testParallelMeshAndSkinColor(meshes, args):\r
738   """test coherency between color input skin and tetra_hpc_mpi outputs GHS3DPRL_out.00000?.mesh"""
739   res = []
740   if args.color == True:\r
741     res.append(KO + " ERROR: test color TODO!!!")
742   else:
743     res.append(OK + " WARNING: test color not done")
744   return res\r
745 \r
746 if __name__ == '__main__':\r
747   parser = AP.ArgumentParser(description='launch test(s) on tetra_hpc_mpi mesh(es)', argument_default=None)\r
748   parser.add_argument(\r
749     '-a', '--testAll', \r
750     help='test all on all meshes',\r
751     action='store_true',\r
752   )\r
753   parser.add_argument(\r
754     '-v', '--verbose', \r
755     help='set verbose, for deep debug',\r
756     action='store_true',\r
757   )\r
758   parser.add_argument(\r
759     '-g', '--globalNumerotation', \r
760     help='read and set files .global, if associated',\r
761     action='store_true',\r
762   )\r
763   parser.add_argument(\r
764     '-c', '--color', \r
765     help='read and test with color',\r
766     action='store_true',\r
767   )\r
768   parser.add_argument(\r
769     '-f', '--files', \r
770     help='launch test(s) on file(s)',\r
771     nargs='*',\r
772     metavar='.../file.mesh'\r
773   )\r
774   parser.add_argument(\r
775     '-s', '--skinInputFile', \r
776     help='launch test(s) on tetra_hpc_mpi input file',\r
777     nargs='?',\r
778     metavar='.../skinInputFile.mesh'\r
779   )\r
780   """\r
781   parser.add_argument(\r
782     '-x', '--xoneargument', \r
783     nargs='?',\r
784     metavar='0|1',\r
785     choices=['0', '1'],\r
786     help='one argument, for example',\r
787     default='0'\r
788   )\r
789   """\r
790   \r
791     \r
792   """
793   args is Namespace, use it as global to store 
794   parameters, data, used arrays and results and other...
795   """\r
796   args = parser.parse_args()
797   \r
798   verbose = args.verbose\r
799   if verbose: print("INFO: args:\n%s" % PP.pformat(args))\r
800 \r
801   if len(sys.argv) == 1: #no args as --help\r
802     parser.print_help()\r
803     sys.exit(KOSYS)\r
804 \r
805   if args.files == None:\r
806     print("\nERROR: Nothing to do: no files\n%s" % PP.pformat(args))\r
807     parser.print_help()\r
808     sys.exit(KOSYS)\r
809   \r
810   if args.testAll: \r
811     result = testAll(args)\r
812   else:\r
813     result = KO\r
814     print("\nERROR: Nothing to do:\n%s" % PP.pformat(args))\r
815   sys.exit(okToSys(result, verbose=True))\r
816   \r