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