1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2014-2023 EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 """Fonctions générrales sur les maillages
22 Created on Mon Jun 23 14:49:36 2014
23 @author: I48174 (Olivier HOAREAU)
29 from .geomsmesh import smesh
31 from .putName import putName
33 def lookForCorner(maillageAScanner):
35 """ Cette fonction permet de scanner la liste de noeuds qui composent le
36 maillage passé en paramètre. On recherche un ou plusieurs coins, ce
37 qui implique les caractéristiques suivantes:
38 - le noeud doit appartenir au moins à trois éléments distincts
39 - chaque élément doit appartenir à un ensemble distinct
40 La fonction renvoie une liste de coins par l'intermédiaire de l'IDs
41 chaque noeud. La liste contient en général au maximum deux coins.
46 allNodeIds = maillageAScanner.GetNodesId() # On stocke tout les noeuds
47 listOfCorners = list()
48 for noeud in allNodeIds:
49 # On parcours la liste de noeuds
50 listOfElements = maillageAScanner.GetNodeInverseElements(noeud)
51 if len(listOfElements) >=3:
52 # On teste le nombre d'éléments qui partagent le même noeud
53 # --- Filtre selon le critère 'coplanar' --- #
54 listOfCriterion = [smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \
55 SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30) \
56 for elem in listOfElements]
57 listOfFilters = [smesh.GetFilterFromCriteria([criteria]) for criteria in listOfCriterion]
58 listOfSets = [maillageAScanner.GetIdsFromFilter(filtre) for filtre in listOfFilters]
59 if listOfSets.count(listOfSets[0]) == len(listOfSets):
60 # Si toutes les listes d'éléments sont similaires, on retourne
61 # au début pour éviter de travailler sur des éléments inutiles.
62 # Exemple : un noeud appartenant à 4 éléments sur la même face.
64 for l_aux in listOfSets:
65 while listOfSets.count(l_aux) > 1:
66 # On supprime tant que la liste d'éléments n'est pas unique.
67 listOfSets.remove(l_aux)
68 if len(listOfSets) >= 3:
69 # Si on a au moins 3 listes d'élements différentes, on considère
70 # qu'il y a présence d'un coin.
71 listOfCorners.append(noeud)
75 def createLinesFromMesh(maillageSupport):
77 """ Cette fonction permet de générer une liste de lignes à partir du
78 maillage support passé en paramètre. On démarre à partir d'un coin
79 simple et on parcourt tout les noeuds pour former une ligne. Soit la
82 1_____4_____7 On part du coin N1, et on cherche les noeuds
83 | | | successifs tels que [1, 2, 3]. Lorsqu'on arrive
84 | 1 | 3 | arrive sur le noeud de fin de ligne N3, on repart
85 | | | du noeud précédent du premier élément (E1), à
86 2_____5_____8 savoir le noeud N4. On suit les noeuds succesifs
87 | | | [4, 5, 6] comme précédemment et ainsi de suite.
88 | 2 | 4 | Lorsqu'on arrive sur le dernier noeud de la
89 | | | dernière ligne, à savoir le noeud N9, on considère
90 3_____6_____9 que toutes les lignes sont créées.
92 La fonction retourne une liste de lignes utilisées par la suite.
97 allNodeIds = maillageSupport.GetNodesId()
98 while len(allNodeIds):
100 for idNode in nodeIds: # rechercher un coin
101 elems = maillageSupport.GetNodeInverseElements(idNode)
103 # un coin: un noeud, un element quadrangle
107 idStart = idNode_c # le noeud de coin
108 elemStart = elem # l'élément quadrangle au coin
109 xyz = maillageSupport.GetNodeXYZ(idStart)
110 logging.debug("idStart %s, coords %s", idStart, str(xyz))
112 nodelines = list() # on va constituer une liste de lignes de points
116 logging.debug("--- une ligne")
120 agauche = False # sens de parcours des 4 noeuds d'un quadrangle
124 ligneIncomplete = True # on commence une ligne de points
128 while ligneIncomplete: # compléter la ligne de points
129 nodeline.append(idNode)
130 allNodeIds.remove(idNode)
131 elemline.append(elem)
132 nodes = maillageSupport.GetElemNodes(elem)
133 i_aux = nodes.index(idNode) # repérer l'index du noeud courant (i_aux) dans l'élément quadrangle (0 a 3)
134 if agauche: # déterminer le noeud suivant (j_aux) et celui opposé (k_aux) dans le quadrangle
152 isuiv = nodes[j_aux] # noeud suivant
153 iapres = nodes[k_aux] # noeud opposé
156 # précédent a trouver, dernière ligne : précédent au lieu de suivant
159 iprec = nodes[i_aux -1]
163 elems3 = maillageSupport.GetNodeInverseElements(iprec)
164 if len(elems3) == 1: # autre coin
172 #print nodes, idNode, isuiv, iapres
173 elems1 = maillageSupport.GetNodeInverseElements(isuiv)
174 elems2 = maillageSupport.GetNodeInverseElements(iapres)
175 ligneIncomplete = False
177 if elems1.count(elem2) and elem2 != elem:
178 ligneIncomplete = True
182 if not ligneIncomplete:
183 nodeline.append(isuiv)
184 allNodeIds.remove(isuiv)
185 logging.debug("nodeline %s", nodeline)
186 logging.debug("elemline %s", elemline)
187 nodelines.append(nodeline)
189 # on a constitué une liste de lignes de points connexes
190 logging.debug("dimensions [%s, %s]", len(nodelines), len(nodeline))
194 def createNewMeshesFromCorner(maillageSupport, listOfCorners, \
197 """ Cette fonction permet de générer un nouveau maillage plus facile à
198 utiliser. On démarre d'un coin et on récupère les trois éléments
199 auquel le noeud appartient. Grâce à un filtre 'coplanar' sur les trois
200 éléments, on peut générer des faces distinctes.
203 logging.info("start")
206 listOfNewMeshes = list()
208 for corner in listOfCorners:
209 elems = maillageSupport.GetNodeInverseElements(corner)
211 # --- Filtre selon le critère 'coplanar' --- #
212 critere = smesh.GetCriterion(SMESH.FACE, SMESH.FT_CoplanarFaces, \
213 SMESH.FT_Undefined, elem, SMESH.FT_Undefined, SMESH.FT_Undefined, 30)
214 filtre = smesh.GetFilterFromCriteria([critere])
216 nom = "coin_{}".format(n_msh)
217 grp = maillageSupport.GroupOnFilter(SMESH.FACE, nom, filtre)
218 # On copie le maillage en fonction du filtre
219 msh = smesh.CopyMesh(grp, nom, False, True)
220 putName(msh, nom, i_pref=nro_cas)
221 # On stocke l'ensemble des noeuds du maillage dans tmp
222 # On ajoute le maillage à la liste des nouveaux maillages
223 # seulement s'il n'y est pas déjà
224 tmp.append(msh.GetNodesId())
225 if ( tmp.count(msh.GetNodesId()) <= 1 ):
226 putName(msh, "Face", len(listOfNewMeshes), nro_cas)
227 listOfNewMeshes.append(msh)
229 return listOfNewMeshes