Salome HOME
Merge branch 'gni/evolution' of https://codev-tuleap.cea.fr/plugins/git/salome/smesh...
[modules/smesh.git] / src / Tools / blocFissure / gmu / construitFissureGenerale.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2014-2020  EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 import os
22
23 import logging
24 import salome
25 from .geomsmesh import geompy
26 from .geomsmesh import geomPublish
27 from .geomsmesh import geomPublishInFather
28 from . import initLog
29 import GEOM
30 from .geomsmesh import smesh
31 from salome.smesh import smeshBuilder
32 import SMESH
33 import math
34 import bisect
35 import traceback
36
37 # from extractionOrientee import extractionOrientee
38 # from extractionOrienteeMulti import extractionOrienteeMulti
39 # from sortFaces import sortFaces
40 #from sortEdges import sortEdges
41 # from eliminateDoubles import eliminateDoubles
42 # from substractSubShapes import substractSubShapes
43 # from produitMixte import produitMixte
44 # from findWireEndVertices import findWireEndVertices
45 #from findWireIntermediateVertices import findWireIntermediateVertices
46 from .orderEdgesFromWire import orderEdgesFromWire
47 # from getSubshapeIds import getSubshapeIds
48 from .putName import putName
49 # from distance2 import distance2
50 from .enleveDefaut import enleveDefaut
51 from .shapeSurFissure import shapeSurFissure
52 from .regroupeSainEtDefaut import RegroupeSainEtDefaut
53 from .triedreBase import triedreBase
54 # from checkDecoupePartition import checkDecoupePartition
55 # from whichSide import whichSide
56 # from whichSideMulti import whichSideMulti
57 #from whichSideVertex import whichSideVertex
58 #from projettePointSurCourbe import projettePointSurCourbe
59 # from prolongeWire import prolongeWire
60 from .restreintFaceFissure import restreintFaceFissure
61 from .partitionneFissureParPipe import partitionneFissureParPipe
62 from .construitPartitionsPeauFissure import construitPartitionsPeauFissure
63 from .compoundFromList import compoundFromList
64 from .identifieElementsGeometriquesPeau import identifieElementsGeometriquesPeau
65 from .identifieFacesEdgesFissureExterne import identifieFacesEdgesFissureExterne
66 from .calculePointsAxiauxPipe import calculePointsAxiauxPipe
67 from .elimineExtremitesPipe import elimineExtremitesPipe
68 from .construitEdgesRadialesDebouchantes import construitEdgesRadialesDebouchantes
69 from .creePointsPipePeau import creePointsPipePeau
70 from .ajustePointsEdgePipeFissure import ajustePointsEdgePipeFissure
71 from .construitMaillagePipe import construitMaillagePipe
72 from .mailleAretesEtJonction import mailleAretesEtJonction
73 from .mailleFacesFissure import mailleFacesFissure
74 from .mailleFacesPeau import mailleFacesPeau
75 from .fissError import fissError
76
77 # -----------------------------------------------------------------------------
78 # --- procédure complète fissure générale
79
80 def construitFissureGenerale(maillagesSains, \
81                              shapesFissure, shapeFissureParams, \
82                              maillageFissureParams, elementsDefaut, \
83                              step=-1, mailleur="MeshGems"):
84   """
85   TODO: a completer
86   """
87   logging.info('start')
88   logging.info(mailleur)
89
90   shapeDefaut       = shapesFissure[0] # faces de fissure, débordant
91   fondFiss          = shapesFissure[4] # groupe d'edges de fond de fissure
92
93   rayonPipe = shapeFissureParams['rayonPipe']
94   if 'lenSegPipe' in shapeFissureParams:
95     lenSegPipe = shapeFissureParams['lenSegPipe']
96   else:
97     lenSegPipe = rayonPipe
98
99   nomRep            = maillageFissureParams['nomRep']
100   nomFicSain        = maillageFissureParams['nomFicSain']
101   nomFicFissure     = maillageFissureParams['nomFicFissure']
102
103   nbsegRad          = maillageFissureParams['nbsegRad']      # nombre de couches selon un rayon du pipe
104   nbsegCercle       = maillageFissureParams['nbsegCercle']   # nombre de secteur dans un cercle du pipe
105   areteFaceFissure  = maillageFissureParams['areteFaceFissure']
106   lgAretesVives     = 0
107   if 'aretesVives' in maillageFissureParams:
108     lgAretesVives   = maillageFissureParams['aretesVives']
109
110   pointIn_x = 0.0
111   pointIn_y = 0.0
112   pointIn_z = 0.0
113   isPointInterne = False
114   if 'pointIn_x' in shapeFissureParams:
115     pointIn_x = shapeFissureParams['pointIn_x']
116     isPointInterne = True
117   if 'pointIn_y' in shapeFissureParams:
118     pointIn_y = shapeFissureParams['pointIn_y']
119     isPointInterne = True
120   if 'pointIn_z' in shapeFissureParams:
121     pointIn_z = shapeFissureParams['pointIn_z']
122     isPointInterne = True
123   if isPointInterne:
124     pointInterne = geompy.MakeVertex(pointIn_x, pointIn_y, pointIn_z)
125   else:
126     pointInterne = None
127
128   fichierMaillageFissure = os.path.join (nomRep , '{}.med'.format(nomFicFissure))
129
130   # fillings des faces en peau
131   facesDefaut              = elementsDefaut[0]
132   #centresDefaut            = elementsDefaut[1]
133   #normalsDefaut            = elementsDefaut[2]
134   #extrusionsDefaut         = elementsDefaut[3]
135   dmoyen                   = elementsDefaut[4]
136   bordsPartages            = elementsDefaut[5]
137   #fillconts                = elementsDefaut[6]
138   #idFilToCont              = elementsDefaut[7]
139   maillageSain             = elementsDefaut[8]
140   internalBoundary         = elementsDefaut[9]
141   zoneDefaut               = elementsDefaut[10]
142   zoneDefaut_skin          = elementsDefaut[11]
143   zoneDefaut_internalFaces = elementsDefaut[12]
144   zoneDefaut_internalEdges = elementsDefaut[13]
145   #edgeFondExt              = elementsDefaut[14]
146   centreFondFiss           = elementsDefaut[15]
147   #tgtCentre                = elementsDefaut[16]
148   if lgAretesVives == 0:
149     lgAretesVives = dmoyen
150
151
152   O, OX, OY, OZ = triedreBase()
153
154   # --- restriction de la face de fissure au domaine solide :
155   #     partition face fissure étendue par fillings, on garde la face interne
156
157   facesPortFissure = restreintFaceFissure(shapeDefaut, facesDefaut, pointInterne)
158
159   # --- pipe de fond de fissure, prolongé, partition face fissure par pipe
160   #     identification des edges communes pipe et face fissure
161
162   (fissPipe, edgesPipeFiss, edgesFondFiss, wirePipeFiss, wireFondFiss) = partitionneFissureParPipe(shapesFissure, elementsDefaut, rayonPipe)
163   edgesFondFiss, edgesIdByOrientation = orderEdgesFromWire(wireFondFiss)
164
165   for i,edge in enumerate(edgesFondFiss):
166     geomPublishInFather(initLog.debug, wireFondFiss, edge, "edgeFondFiss%d"%i)
167
168   # --- peau et face de fissure
169   #
170   # --- partition peau défaut - face de fissure prolongée - wire de fond de fissure prolongée
171   #     il peut y avoir plusieurs faces externes, dont certaines sont découpées par la fissure
172   #     liste de faces externes : facesDefaut
173   #     liste de partitions face externe - fissure : partitionPeauFissFond (None quand pas d'intersection)
174
175   partitionsPeauFissFond = construitPartitionsPeauFissure(facesDefaut, fissPipe)
176
177   # --- arêtes vives détectées (dans quadranglesToShapeNoCorner
178   #                             et quadranglesToShapeWithCorner)
179
180   aretesVivesC = compoundFromList(bordsPartages, "areteVive")
181   aretesVivesCoupees = list()  # ensembles des arêtes vives identifiées sur les faces de peau dans l'itération sur partitionsPeauFissFond
182
183   # --- inventaire des faces de peau coupées par la fissure
184   #     pour chaque face de peau : 0, 1 ou 2 faces débouchante du fond de fissure
185   #                                0, 1 ou plus edges de la face de fissure externe au pipe
186
187   nbFacesFilling = len(partitionsPeauFissFond)
188   texte = "nbFacesFilling : {} ".format(nbFacesFilling)
189   logging.info(texte)
190
191   ptEdgeFond = [ list()  for i in range(nbFacesFilling)] # pour chaque face [points edge fond de fissure aux débouchés du pipe]
192   fsPipePeau = [ list()  for i in range(nbFacesFilling)] # pour chaque face [faces du pipe débouchantes]
193   edRadFPiPo = [ list()  for i in range(nbFacesFilling)] # pour chaque face [edge radiale des faces du pipe débouchantes ]
194   fsFissuExt = [ list()  for i in range(nbFacesFilling)] # pour chaque face [faces de fissure externes au pipe]
195   edFisExtPe = [ list()  for i in range(nbFacesFilling)] # pour chaque face [edge en peau des faces de fissure externes (pas subshape facePeau)]
196   edFisExtPi = [ list()  for i in range(nbFacesFilling)] # pour chaque face [edge commun au pipe des faces de fissure externes]
197   facesPeaux = [None for i in range(nbFacesFilling)] # pour chaque face : la face de peau finale a mailler (percée des faces débouchantes)
198   edCircPeau = [ list()  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge circulaire aux débouchés du pipe]
199   ptCircPeau = [ list()  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape point sur edge circulaire aux débouchés du pipe]
200   gpedgeBord = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupe subshape des edges aux bords liés à la partie saine
201   gpedgeVifs = [None for i in range(nbFacesFilling)] # pour chaque face de peau : groupes subshape des edges aux arêtes vives entre fillings
202   edFissPeau = [ list()  for i in range(nbFacesFilling)] # pour chaque face de peau : [subshape edge en peau des faces de fissure externes]
203   ptFisExtPi = [ list()  for i in range(nbFacesFilling)] # pour chaque face de peau : [point commun edFissPeau edCircPeau]
204
205   for ifil, partitionPeauFissFond in enumerate(partitionsPeauFissFond):
206     if partitionPeauFissFond is not None:
207       dataPPFF,aretesVivesCoupees = identifieElementsGeometriquesPeau(ifil, partitionPeauFissFond, edgesPipeFiss,
208                                                                       edgesFondFiss, wireFondFiss, aretesVivesC,
209                                                                       facesDefaut, centreFondFiss, rayonPipe,
210                                                                       aretesVivesCoupees)
211       ptEdgeFond[ifil] = dataPPFF['endsEdgeFond']
212       fsPipePeau[ifil] = dataPPFF['facesPipePeau']
213       edRadFPiPo[ifil] = dataPPFF['edgeRadFacePipePeau']
214       fsFissuExt[ifil] = dataPPFF['facesFissExt']
215       edFisExtPe[ifil] = dataPPFF['edgesFissExtPeau']
216       edFisExtPi[ifil] = dataPPFF['edgesFissExtPipe']
217       facesPeaux[ifil] = dataPPFF['facePeau']
218       edCircPeau[ifil] = dataPPFF['edgesCircPeau']
219       ptCircPeau[ifil] = dataPPFF['verticesCircPeau']
220       gpedgeBord[ifil] = dataPPFF['groupEdgesBordPeau']
221       gpedgeVifs[ifil] = dataPPFF['bordsVifs']
222       edFissPeau[ifil] = dataPPFF['edgesFissurePeau']
223       ptFisExtPi[ifil] = dataPPFF['verticesPipePeau']
224
225   facesPipePeau = list()
226   edgeRadFacePipePeau = list()
227   for ifil in range(nbFacesFilling):
228     facesPipePeau += fsPipePeau[ifil]
229     edgeRadFacePipePeau += edRadFPiPo[ifil]
230
231   for i, avc in enumerate(aretesVivesCoupees):
232     name = "areteViveCoupee%d"%i
233     geomPublish(initLog.debug, avc, name)
234
235   # --- identification des faces et edges de fissure externe pour maillage
236
237   (faceFissureExterne, edgesPipeFissureExterneC, wirePipeFissureExterne, edgesPeauFissureExterneC) = \
238       identifieFacesEdgesFissureExterne(fsFissuExt, edFisExtPe, edFisExtPi, edgesPipeFiss)
239
240   # --- preparation maillage du pipe :
241   #     - détections des points a respecter : jonction des edges/faces constituant la face de fissure externe au pipe
242   #     - points sur les edges de fond de fissure et edges pipe/face fissure,
243   #     - vecteurs tangents au fond de fissure (normal au disque maillé)
244
245   (centres, gptsdisks, raydisks) = calculePointsAxiauxPipe(edgesFondFiss, edgesIdByOrientation, facesDefaut,
246                                                            centreFondFiss, wireFondFiss, wirePipeFiss,
247                                                            lenSegPipe, rayonPipe, nbsegCercle, nbsegRad)
248
249   # --- recherche des points en trop (externes au volume à remailler)
250   #     - on associe chaque extrémité du pipe à une face filling
251   #     - on part des disques aux extrémités du pipe
252   #     - pour chaque disque, on prend les vertices de géométrie,
253   #       on marque leur position relative à la face.
254   #     - on s'arrete quand tous les noeuds sont dedans
255
256   (idFillingFromBout, idisklim, idiskout) = elimineExtremitesPipe(ptEdgeFond, facesDefaut, centres, gptsdisks, nbsegCercle)
257
258   # --- construction des listes d'edges radiales sur chaque extrémité débouchante
259
260   (listEdges, idFacesDebouchantes) = construitEdgesRadialesDebouchantes(idisklim, idiskout, gptsdisks, raydisks,
261                                                                         facesPipePeau, edgeRadFacePipePeau, nbsegCercle)
262
263   # --- création des points du maillage du pipe sur la face de peau
264
265   (gptsdisks, idisklim) = creePointsPipePeau(listEdges, idFacesDebouchantes, idFillingFromBout,
266                                              ptEdgeFond, ptFisExtPi, edCircPeau, gptsdisks, idisklim, nbsegRad)
267
268   # --- ajustement precis des points sur edgesPipeFissureExterneC
269
270   gptsdisks = ajustePointsEdgePipeFissure(edgesPipeFissureExterneC, wirePipeFissureExterne, gptsdisks, idisklim)
271
272    # --- maillage effectif du pipe
273
274   (meshPipe, meshPipeGroups, edgesCircPipeGroup) = construitMaillagePipe(gptsdisks, idisklim, nbsegCercle, nbsegRad)
275
276   # --- edges de bord, faces défaut à respecter
277
278   (internalBoundary, bordsLibres, grpAretesVives) = mailleAretesEtJonction(internalBoundary, aretesVivesCoupees, lgAretesVives)
279
280   # --- maillage faces de fissure
281
282   (meshFaceFiss, grpFaceFissureExterne, grpEdgesPeauFissureExterne, grpEdgesPipeFissureExterne) = \
283       mailleFacesFissure(faceFissureExterne, \
284                          edgesPipeFissureExterneC, edgesPeauFissureExterneC, \
285                          meshPipeGroups, areteFaceFissure, rayonPipe, nbsegRad, \
286                          mailleur)
287
288   # --- maillage faces de peau
289
290   meshesFacesPeau = mailleFacesPeau(partitionsPeauFissFond, idFillingFromBout, facesDefaut, \
291                                     facesPeaux, edCircPeau, ptCircPeau, gpedgeBord, gpedgeVifs, edFissPeau, \
292                                     bordsLibres, grpEdgesPeauFissureExterne, grpAretesVives, \
293                                     edgesCircPipeGroup, dmoyen, rayonPipe, nbsegRad, \
294                                     mailleur)
295
296   # --- regroupement des maillages du défaut
297
298   listMeshes = [internalBoundary.GetMesh(),
299                 meshPipe.GetMesh(),
300                 meshFaceFiss.GetMesh()]
301   for mp in meshesFacesPeau:
302     listMeshes.append(mp.GetMesh())
303
304   meshBoiteDefaut = smesh.Concatenate(listMeshes, 1, 1, 1e-05,False)
305   # pour aider l'algo hexa-tetra à ne pas mettre de pyramides à l'exterieur des volumes repliés sur eux-mêmes
306   # on désigne les faces de peau en quadrangles par le groupe "skinFaces"
307   group_faceFissOutPipe = None
308   group_faceFissInPipe = None
309   groups = meshBoiteDefaut.GetGroups()
310   for grp in groups:
311     if grp.GetType() == SMESH.FACE:
312       if grp.GetName() == "fisOutPi":
313         group_faceFissOutPipe = grp
314       elif grp.GetName() == "fisInPi":
315         group_faceFissInPipe = grp
316
317   # le maillage NETGEN ne passe pas toujours ==> on force l'usage de MG_Tetra
318   mailleur = "MeshGems"
319   logging.info("Maillage avec %s", mailleur)
320   if ( mailleur == "MeshGems"):
321     algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.MG_Tetra)
322   else:
323     algo3d = meshBoiteDefaut.Tetrahedron(algo=smeshBuilder.NETGEN)
324     hypo3d = algo3d.MaxElementVolume(1000.0)
325     hypo3d.SetVerboseLevel( 0 )
326     hypo3d.SetStandardOutputLog( 0 )
327     hypo3d.SetRemoveLogOnSuccess( 1 )
328   putName(algo3d.GetSubMesh(), "boiteDefaut")
329   putName(algo3d, "algo3d_boiteDefaut")
330   putName(meshBoiteDefaut, "boiteDefaut")
331
332   is_done = meshBoiteDefaut.Compute()
333   text = "meshBoiteDefaut.Compute"
334   if is_done:
335     logging.info(text+" OK")
336   else:
337     text = "Erreur au calcul du maillage.\n" + text
338     logging.info(text)
339     raise Exception(text)
340
341   faceFissure = meshBoiteDefaut.GetMesh().UnionListOfGroups( [ group_faceFissOutPipe, group_faceFissInPipe ], \
342                                                              'FACE1' )
343   maillageSain = enleveDefaut(maillageSain, zoneDefaut, zoneDefaut_skin,
344                               zoneDefaut_internalFaces, zoneDefaut_internalEdges)
345   putName(maillageSain, nomFicSain+"_coupe")
346   _, normfiss = shapeSurFissure(facesPortFissure)
347   maillageComplet = RegroupeSainEtDefaut(maillageSain, meshBoiteDefaut, \
348                                          None, None, 'COMPLET', normfiss)
349
350   logging.info("conversion quadratique")
351   maillageComplet.ConvertToQuadratic( 1 )
352   logging.info("groupes")
353   groups = maillageComplet.GetGroups()
354   grps = [ grp for grp in groups if grp.GetName() == 'FONDFISS']
355   fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FONDFISS' )
356
357   logging.info("réorientation face de fissure FACE1")
358   grps = [ grp for grp in groups if grp.GetName() == 'FACE1']
359   nb = maillageComplet.Reorient2D( grps[0], normfiss, grps[0].GetID(1))
360
361   logging.info("réorientation face de fissure FACE2")
362   plansim = geompy.MakePlane(O, normfiss, 10000)
363   fissnorm = geompy.MakeMirrorByPlane(normfiss, plansim)
364   grps = [ grp for grp in groups if grp.GetName() == 'FACE2']
365   nb = maillageComplet.Reorient2D( grps[0], fissnorm, grps[0].GetID(1))
366   fond = maillageComplet.GetMesh().CreateDimGroup( grps, SMESH.NODE, 'FACE2' )
367
368   logging.info("export maillage fini")
369   maillageComplet.ExportMED(fichierMaillageFissure)
370   putName(maillageComplet, nomFicFissure)
371   logging.info("fichier maillage fissure %s", fichierMaillageFissure)
372
373   if salome.sg.hasDesktop():
374     salome.sg.updateObjBrowser()
375
376   logging.info("maillage fissure fini")
377
378   return maillageComplet