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