1 #@ MODIF partition Utilitai DATE 10/02/2005 AUTEUR ASSIRE A.ASSIRE
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2004 EDF R&D WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
9 # (AT YOUR OPTION) ANY LATER VERSION.
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
18 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
19 # ======================================================================
20 # RESPONSABLE ASSIRE A.ASSIRE
23 import string, os, time, sys, UserList, types
27 from Noyau.N_utils import AsType
29 # ------------------------------------------------------------------ #
31 def enleve_doublons_liste(liste):
32 """ A partir d une liste qui peut contenir des doublons, on renvoie une liste sans
33 doublons (et qui reviendra triée)
36 """ Au cas ou ca ne serait pas deja un vecteur numpy """ # Exemple
37 liste=N.sort(N.array(liste,copy=0)) # [1, 2, 2, 3, 3, 4, 5]
38 liste_diff=liste[1:]-liste[:-1] # [1, 0, 1, 0, 1, 1]
39 liste_temp=N.nonzero(liste_diff) # [0, 2, 4, 5]
40 liste_indice=N.zeros(liste_temp.shape[0]+1)
42 liste_indice[1:]=liste_temp+1 # [0, 1, 3, 5, 6]
43 liste2=N.take(liste,liste_indice) # [1, 2, 3, 4, 5]
47 # ============================================================================ #
50 class CONNEC(UserList.UserList) :
52 Connectivite : sequence mutable de sequences de noeuds
53 Pour l'instant, on s'appuie sur une liste de liste.
56 def __init__(self,nma) :
58 UserList.UserList.__init__(self,[None]*nma)
63 Retourne la connectivite sous forme de deux vecteurs numpy :
64 ind -> tableau des index (y compris le n+1 eme)
65 noe -> tableau des listes de noeuds
68 # Dimension des deux vecteurs
70 ltot = N.reduce(lambda x,y : x+len(y), self,0)
71 ind = N.zeros(nma+1,Int)
72 noe = N.zeros(ltot,Int)
74 # Construction des vecteurs
78 ind[i+1] = ind[i] + len(m)
79 noe[ind[i]:ind[i+1]] = N.array(m)
84 # ============================================================================ #
85 # ============================================================================ #
91 La numeration est 0..N-1 pour les noeuds et 0..M-1 pour les mailles
94 def __init__(self,nno=0,nma=0) :
96 self.cn = N.zeros((nno,3),N.Float)
97 self.tm = N.zeros(nma,N.Int)
101 self.indice_noeuds = N.arange(nno)
103 self.correspondance_noeuds = []
104 self.correspondance_mailles = []
108 nom_mailles = (None,) + string.strip(aster.getvectjev('&CATA.TM.NOMTM'))
111 'POI1', 'SEG2', 'SEG22', 'SEG3', 'SEG33', 'SEG4', 'TRIA3',
112 'TRIA33', 'TRIA6', 'TRIA66', 'TRIA7', 'QUAD4', 'QUAD44', 'QUAD8',
113 'QUAD88', 'QUAD9', 'QUAD99', 'TETRA4', 'TETRA10','PENTA6', 'PENTA15',
114 'PYRAM5', 'PYRAM13','HEXA8', 'HEXA20', 'HEXA27', 'TR3QU4', 'QU4TR3',
115 'TR6TR3', 'TR3TR6', 'TR6QU4', 'QU4TR6', 'TR6QU8', 'QU8TR6', 'TR6QU9',
116 'QU9TR6', 'QU8TR3', 'TR3QU8', 'QU8QU4', 'QU4QU8', 'QU8QU9', 'QU9QU8',
117 'QU9QU4', 'QU4QU9', 'QU9TR3', 'TR3QU9', 'SEG32', 'SEG23' )
120 for i in range(len(nom_mailles)) :
121 dic_mailles[nom_mailles[i]] = i
123 self.nom = nom_mailles
124 self.dic = dic_mailles
127 psyco.bind(self.FromAster)
131 # -------------------------------------------------------------
133 def get_connexite(self, nom, nma):
135 dico_connexite = aster.getcolljev(nom)
136 for element in dico_connexite.keys() :
137 co[int(element)-1] = (N.array(dico_connexite[element])-1)
141 def get_coordonnees_noeuds(self, nom, nombre_noeuds):
142 coordonnees_noeuds = aster.getvectjev(nom)
143 coordonnees_noeuds = N.array(coordonnees_noeuds)
144 coordonnees_noeuds.shape = (nombre_noeuds,3)
145 cn = coordonnees_noeuds
149 # -------------------------------------------------------------
151 def FromAster(self,nom) :
153 # On accepte le concept Aster ou bien la chaine texte de son nom
154 if type(nom)!=types.StringType:
155 nom_maillage = nom.nom
159 nom_maillage=string.ljust(nom_maillage,8)
161 # recuperation de la taille
162 self.dime_maillage = aster.getvectjev(nom_maillage+'.DIME')
163 nombre_noeuds = self.dime_maillage[0]
164 nombre_mailles = self.dime_maillage[2]
166 # coordonnees des noeuds
167 self.cn = self.get_coordonnees_noeuds(nom_maillage+'.COORDO .VALE', nombre_noeuds)
170 self.tm = N.array(aster.getvectjev(nom_maillage+'.TYPMAIL'))
173 self.co = self.get_connexite(nom_maillage+'.CONNEX', nombre_mailles)
175 self.indice_noeuds=N.arange(nombre_noeuds)
178 Lno_groupno_tot = aster.getcolljev(nom_maillage+'.GROUPENO')
181 for key in Lno_groupno_tot :
182 # Tolerance car parfois defi_group crée des groupes nuls à clé entiere
184 Lno_groupno[key.strip()]=N.array(Lno_groupno_tot[key])-1
189 Lma_groupma_tot = aster.getcolljev(nom_maillage+'.GROUPEMA')
191 for key in Lma_groupma_tot :
192 Lma_groupma[key.strip()]=N.array(Lma_groupma_tot[key])-1
197 # listes de correspondance entre Aster et Mail-Py
198 self.correspondance_noeuds = aster.getvectjev(nom_maillage+'.NOMNOE')
199 self.correspondance_mailles = aster.getvectjev(nom_maillage+'.NOMMAI')
202 # -------------------------------------------------------------
207 INFO_EXEC_ASTER = self.jdc.get_cmd('INFO_EXEC_ASTER')
208 DETRUIRE = self.jdc.get_cmd('DETRUIRE')
209 LIRE_MAILLAGE = self.jdc.get_cmd('LIRE_MAILLAGE')
212 from Cata.cata import INFO_EXEC_ASTER
213 from Cata.cata import DETRUIRE
214 from Cata.cata import LIRE_MAILLAGE
216 print "\n\nERREUR : il faut lancer ce programme depuis Aster pour pouvoir \ngénérer un maillage Aster.\n\n"
219 # Recuperation d'une unité logique libre
220 _UL=INFO_EXEC_ASTER(LISTE_INFO='UNITE_LIBRE')
221 ul1=_UL['UNITE_LIBRE',1]
222 DETRUIRE(CONCEPT=(_F(NOM=_UL),), INFO=1)
224 # Sauvegarde du maillage dans un fichier .mail
225 fichier = 'fort.'+str(ul1)
226 f = open(fichier, 'w')
227 f.write( self.Voir_Mail() )
230 # Récupération des concepts Aster présents dans la base
231 # Note AA : ne marche pas encore bien :
232 # Limitation : ne gere qu'un seul maillage genere par ToAster
236 # self.jdc_recupere=CONTEXT.get_current_step()
238 # for i in self.jdc_recupere.sds_dict.keys( ):
239 # if self.jdc_recupere.sds_dict[i].__class__.__name__ == 'maillage_sdaster':
240 # if (mail[0:4]==nom):
241 # t_maillage.append( i )
247 # Lecture de ce fichier .mail pour l'injecter dans l'espace Aster
248 _SMESH_ = LIRE_MAILLAGE(UNITE = ul1)
252 # -------------------------------------------------------------
255 return self.Voir_Mail()
257 # -------------------------------------------------------------
259 def Voir_Mail(self) :
261 Impression au format ASTER
266 l.append('% CLASSE PY_MAIL -> MAIL')
270 (nno,ndim) = self.cn.shape
273 # Coordonnees des noeuds
276 # Si le maillage initial ne provient pas d'Aster
277 if len(self.correspondance_noeuds) == 0:
278 for i in range(nno) :
279 ch = 'N'+repr(i)+' '+`self.cn[i,0]` + ' ' + `self.cn[i,1]` + ' ' + `self.cn[i,2]`
280 # ch = 'N'+repr(i+1)+' '+`self.cn[i,0]` + ' ' + `self.cn[i,1]` + ' ' + `self.cn[i,2]`
283 # Si le maillage initial provient d'Aster
285 for i in range(nno) :
286 ch = self.correspondance_noeuds[i]+' '+`self.cn[i,0]` + ' ' + `self.cn[i,1]` + ' ' + `self.cn[i,2]`
287 # ch = 'N'+repr(i+1)+' '+`self.cn[i,0]` + ' ' + `self.cn[i,1]` + ' ' + `self.cn[i,2]`
290 # Connectivité des mailles
291 ind = N.argsort(self.tm)
294 # Si le maillage initial ne provient pas d'Aster
295 if len(self.correspondance_mailles) == 0:
297 if self.tm[m] <> ty :
298 l.append('FINSF') ; l.append('%')
300 l.append(self.nom[ty])
303 for n in self.co[m] :
304 ch = ch + 'N'+`n` + ' '
305 # ch = ch + 'N'+`n+1` + ' '
308 # Si le maillage initial provient d'Aster
311 if self.tm[m] <> ty :
312 l.append('FINSF') ; l.append('%')
314 l.append(self.nom[ty])
315 ch = self.correspondance_mailles[m]+' '
317 for n in self.co[m] :
318 ch = ch + self.correspondance_noeuds[n] + ' '
319 # ch = ch + 'N'+`n+1` + ' '
322 l.append('FINSF') ; l.append('%')
325 # Group_ma et Group_no
326 entete = ['GROUP_MA','GROUP_NO']
327 d_gp = [self.gma,self.gno]
330 # Si le maillage initial ne provient pas d'Aster
331 if len(self.correspondance_mailles) == 0:
333 for (d_gp,entete,prefixe) in [(self.gma,'GROUP_MA','M'),(self.gno,'GROUP_NO','N')] :
335 if len(d_gp[gp])>0: # On ne prend en compte que les group_* non vides
341 i+=1 # on ne met que 8 mailles sur une meme ligne
342 if (len(ch) > 60 or i>7):
346 ch = ch + prefixe + `o` + ' '
348 l.append('FINSF') ; l.append('%')
350 # Si le maillage initial provient d'Aster
353 for (d_gp,entete,prefixe) in [(self.gma,'GROUP_MA','M'),(self.gno,'GROUP_NO','N')] :
355 if len(d_gp[gp])>0: # On ne prend en compte que les group_* non vides
361 i+=1 # on ne met que 8 mailles sur une meme ligne
362 if (len(ch) > 60 or i>7):
366 # ch = ch + prefixe + `o` + ' '
368 ch = ch + self.correspondance_mailles[o] + ' '
370 ch = ch + self.correspondance_noeuds[o] + ' '
372 l.append('FINSF') ; l.append('%')
376 return string.join(l,'\n')
381 # ============================================================================ #
382 # ============================================================================ #
386 def __init__(self, jdc=None ,nb=0):
390 self.fichier_out = ''
391 self.liste_mailles = N.array( [] )
392 self.liste_sd = N.array( [] )
393 self.liste_mailles_bord = []
394 self.liste_sd_bord = []
396 self.MAILLAGE_Python = None
398 self.RELATIONS = { 'C_plus' : None,
402 self.ASTER = { 'MAILLAGE' : None,
405 'GROUP_MA_BORD' : None,
406 'DICO_SD_MAILLES' : None,
409 self.OPTIONS = { 'NB_PART' : '',
412 'rep_metis' : aster.repout(),
413 'exe_metis' : aster.repout() + 'pmetis',
414 'fichier_in' : 'fort.66',
415 'fichier_out' : 'fort.68',
416 'elimine_bords': 'OUI',
419 self.Creation_Dico_Correspondance_Type_Maille()
423 # ---------------------------------------------------------------------------- #
427 Impression du contenu de la partition
430 l.append( 'Contenu de la partition :' )
431 l.append( '-------------------------' )
432 try: l.append( '- Maillage : ' + str(self.ASTER['MAILLAGE'].nom) )
434 try: l.append( '- Modele : ' + str(self.ASTER['MODELE'].nom) )
436 l.append( '- Nb part : ' + str(self.OPTIONS['NB_PART']) )
437 l.append( '- Niveau INFO : ' + str(self.OPTIONS['INFO']) )
438 l.append( '- Liste group_ma : ' + str(self.ASTER['GROUP_MA']) )
440 return string.join(l,'\n')
442 # ---------------------------------------------------------------------------- #
444 def Partitionne_Aster(self, MAILLAGE, NB_PART, MODELE=None, METHODE=None, LOGICIEL=None, INFO=1):
446 self.t00 = time.clock()
448 self.OPTIONS['INFO'] = INFO
451 # Recuperation de la liste des mailles à perndre en compte
452 self.ASTER['MODELE'] = MODELE
453 self.ASTER['MAILLAGE'] = MAILLAGE
454 _LST_MA = self.Modele_to_Liste_Mailles(MODELE)
457 self.ASTER['MAILLAGE'] = MAILLAGE
461 # Creation du maillage Python correspondant au maillage Aster
462 MAILLAGE_Python = MAIL_PY()
463 MAILLAGE_Python.FromAster(MAILLAGE.nom)
465 # Partitionne le maillage Python avec la liste de mailles _LST_MA
466 self.Partitionne_Maillage(MAILLAGE_Python, NB_PART, MAILLE=_LST_MA, METHODE=METHODE, LOGICIEL=LOGICIEL, INFO=INFO)
471 # ---------------------------------------------------------------------------- #
473 def Partitionne_Maillage(self, MAILLAGE_Python, NB_PART, MAILLE=None, METHODE=None, LOGICIEL=None, INFO=1):
475 self.t00 = time.clock()
478 self.OPTIONS['exe_metis'] = aster.repout() + string.lower(METHODE)
480 self.OPTIONS['exe_metis'] = LOGICIEL
482 self.OPTIONS['NB_PART'] = NB_PART
483 self.OPTIONS['INFO'] = INFO
484 self.MAILLAGE_Python = MAILLAGE_Python
486 exe_metis = self.OPTIONS['exe_metis']
487 f_metis = self.OPTIONS['fichier_in']
488 fw_metis = self.OPTIONS['fichier_out']
492 # On initialise la connectivité et la connectivité inverse des aretes
493 self.MAILLAGE_Python.ca = {}
494 self.MAILLAGE_Python.cia = {}
496 _DIM = self.MAILLAGE_Python.dime_maillage[5]
497 _LST_TMA = self.MAILLAGE_Python.tm
499 if self.OPTIONS['INFO']>=5:
500 print 'cn=', self.MAILLAGE_Python.cn
501 print 'tm=', self.MAILLAGE_Python.tm
502 print 'co=', self.MAILLAGE_Python.co
503 print 'gma=', self.MAILLAGE_Python.gma
504 print 'gno=', self.MAILLAGE_Python.gno
505 print 'dim=', self.MAILLAGE_Python.dime_maillage
506 if self.OPTIONS['INFO']>=5: print '_LST_MA=', _LST_MA
509 # Elimination des mailles de bords
510 if self.OPTIONS['elimine_bords']!='NON':
512 # Liste des mailles à prendre en compte : dimension _DIM
513 _D_DIM_MAILLES = self.Creation_Listes_Mailles_Par_Dim(self.MAILLAGE_Python.tm, _LST_MA=_LST_MA)
515 # Connectivité et connectivité inverse sur les bords
516 self.Connectivite_Aretes()
518 self.liste_mailles = _D_DIM_MAILLES[ _DIM ]
520 # Pour prendre en compte des mélanges d'elements de dimension differente
521 _LST, _LST_BD = self.Elimination_Mailles_de_bords(MAILLAGE_Python, _D_DIM_MAILLES, _DIM)
522 self.liste_mailles = N.concatenate( (self.liste_mailles,N.array(_LST)) )
524 if self.OPTIONS['INFO']>=5:
525 print '_LST_BD=',_LST_BD
529 self.liste_mailles = _LST_MA
532 # Restriction des connectivités aux mailles à prendre en compte
533 self.Connectivite_Aretes(OPTION='all', _LST_OK=self.liste_mailles)
535 # Creation de l'arbre de connectivité des bords
536 self.Creation_Graphe()
538 # Reduction de l'arbre de connectivité des bords
539 _nb = self.Reduction_Graphe(_DIM)
541 # Ecriture du fichier pour Metis/Chaco/Jostle
542 _D_CORRES = self.Ecrire_Graphe(f_metis, _nb)
544 # Lancement de metis sur le fichier fort.UL (production de fort.UL.part.N)
545 txt = exe_metis + ' ' + f_metis + ' ' + str(NB_PART)
546 print 'Commande : ',txt
549 # Lecture du fichier resultant de Metis
550 self.fichier_out = f_metis + '.part.' + str(NB_PART)
551 self.liste_sd = self.Lecture_fichier_sdd(self.fichier_out, self.liste_mailles)
553 # Traitement des mailles de bords (on les reinjecte dans un SD)
554 if self.OPTIONS['elimine_bords']!='NON':
555 self.Affectation_Mailles_de_bords(_LST_BD, _DIM)
558 print "--- FIN PARTITIONNEMENT : ", t1 - self.t00
564 # ---------------------------------------------------------------------------- #
566 def Creation_Dico_Correspondance_Type_Maille(self):
568 # TYPE_ELEM : CF. &CATA.TM
569 # 1 - >POI1 <>SEG2 <>SEG22 <>SEG3 <>SEG33 <>SEG4 <>TRIA3 <
570 # 8 - >TRIA33 <>TRIA6 <>TRIA66 <>TRIA7 <>QUAD4 <>QUAD44 <>QUAD8 <
571 # 15 - >QUAD88 <>QUAD9 <>QUAD99 <>TETRA4 <>TETRA10 <>PENTA6 <>PENTA15 <
572 # 22 - >PYRAM5 <>PYRAM13 <>HEXA8 <>HEXA20 <>HEXA27 <>TR3QU4 <>QU4TR3 <
573 # 29 - >TR6TR3 <>TR3TR6 <>TR6QU4 <>QU4TR6 <>TR6QU8 <>QU8TR6 <>TR6QU9 <
574 # 36 - >QU9TR6 <>QU8TR3 <>TR3QU8 <>QU8QU4 <>QU4QU8 <>QU8QU9 <>QU9QU8 <
575 # 43 - >QU9QU4 <>QU4QU9 <>QU9TR3 <>TR3QU9 <>SEG32 <>SEG23 <
577 # Creation du dictionnaire des correspondance type_maille -> liste des aretes
580 maille2aretes[1] = [ ]
582 maille2aretes[2] = [ (0,1) ]
583 maille2aretes[3] = maille2aretes[4] = maille2aretes[5] = maille2aretes[6] = maille2aretes[2]
585 maille2aretes[7] = [ (0,1),(1,2),(0,2) ]
586 maille2aretes[8] = maille2aretes[9] = maille2aretes[10] = maille2aretes[11] = maille2aretes[7]
588 maille2aretes[12] = [ (0,1),(1,2),(2,3),(0,3) ]
589 maille2aretes[13] = maille2aretes[14] = maille2aretes[15] = maille2aretes[16] = maille2aretes[17] = maille2aretes[12]
591 maille2aretes[18] = [ (0,1,2),(0,1,3),(0,2,3),(1,3,2) ]
592 maille2aretes[19] = maille2aretes[18]
594 maille2aretes[20] = [ (0,1,2),(3,4,5),(0,2,5,3),(0,1,4,3),(2,1,4,5) ]
595 maille2aretes[21] = maille2aretes[20]
597 maille2aretes[22] = [ (0,1,4),(1,2,4),(2,3,4),(3,0,4),(0,1,2,3) ]
598 maille2aretes[23] = maille2aretes[22]
600 maille2aretes[24] = [ (0,1,2,3), (4,5,6,7), (1,2,6,5), (2,3,7,6), (7,4,0,3), (4,5,1,0) ]
601 maille2aretes[25] = maille2aretes[26] = maille2aretes[24]
604 # dictionnaire de correspondance entre type_maille -> nb noeud (maille linéaire)
610 maille2nb[3] = maille2nb[4] = maille2nb[5] = maille2nb[6] = maille2nb[2]
613 maille2nb[8] = maille2nb[9] = maille2nb[10] = maille2nb[11] = maille2nb[7]
616 maille2nb[13] = maille2nb[14] = maille2nb[15] = maille2nb[16] = maille2nb[17] = maille2nb[12]
619 maille2nb[19] = maille2nb[18]
622 maille2nb[21] = maille2nb[20]
625 maille2nb[23] = maille2nb[22]
628 maille2nb[25] = maille2nb[26] = maille2nb[24]
631 # dictionnaire de correspondance entre type_maille -> dimension
637 maille2dim[3] = maille2dim[4] = maille2dim[5] = maille2dim[6] = maille2dim[2]
640 maille2dim[8] = maille2dim[9] = maille2dim[10] = maille2dim[11] = maille2dim[7]
643 maille2dim[13] = maille2dim[14] = maille2dim[15] = maille2dim[16] = maille2dim[17] = maille2dim[12]
646 maille2dim[19] = maille2dim[18]
649 maille2dim[21] = maille2dim[20]
652 maille2dim[23] = maille2dim[22]
655 maille2dim[25] = maille2dim[26] = maille2dim[24]
657 # On stocke les dictionnaires
658 self.maille2aretes = maille2aretes
659 self.maille2nb = maille2nb
660 self.maille2dim = maille2dim
665 # ---------------------------------------------------------------------------- #
667 def Modele_to_Liste_Mailles(self, MODELE):
669 nommod = string.ljust(MODELE.nom,8)
670 _DIC_MA = aster.getcolljev(nommod.ljust(8)+'.MODELE .LIEL')
672 # Creation de la liste des mailles
674 for type_maille in _DIC_MA.keys():
675 ll.extend( _DIC_MA[type_maille][0:-1] )
676 _LST_MA = N.array( ll ) - 1
678 if self.OPTIONS['INFO']>=5:
679 print '\n# ----- MODELE ----- #\n'
680 print '_LST_MA=',len(_LST_MA),_LST_MA
681 print '_DIC_MA=',len(_DIC_MA),_DIC_MA
686 # ---------------------------------------------------------------------------- #
688 def Creation_Listes_Mailles_Par_Dim(self, _LST_TMA, _LST_MA=None):
692 # Si _LST_MA est renseigné on extrait la liste des TMA correspondante aux mailles de _LST_MA
694 _LST_TMA = N.take(_LST_TMA,_LST_MA)
696 _LST_MA = N.arange(len(_LST_TMA))
700 # Liste des mailles 3D (type maille de 18 à 26)
701 _lst = N.where( _LST_TMA>=18, -3, _LST_TMA )
702 _tmp = N.where( _lst==-3, -1, 0 )
703 # _D_DIM_MAILLES[3] = N.nonzero( _tmp )
704 _D_DIM_MAILLES[3] = N.take(_LST_MA, N.nonzero( _tmp ) )
706 # Liste des mailles 2D (type maille de 7 à 17)
707 _lst = N.where( _lst>=7, -2, _lst )
708 _tmp = N.where( _lst==-2, -1, 0 )
709 _D_DIM_MAILLES[2] = N.take(_LST_MA, N.nonzero( _tmp ) )
711 # Liste des mailles 1D (type maille de 2 à 6)
712 _lst = N.where( _lst>=2, -1, _lst )
713 _tmp = N.where( _lst==-1, -1, 0 )
714 _D_DIM_MAILLES[1] = N.take(_LST_MA, N.nonzero( _tmp ) )
716 # Liste des mailles 0D (type maille 1)
717 _lst = N.where( _lst>=1, -4, _lst )
718 _tmp = N.where( _lst==-4, -1, 0 )
719 _D_DIM_MAILLES[0] = N.take(_LST_MA, N.nonzero( _tmp ) )
722 if self.OPTIONS['INFO']>=5:
723 for i in _D_DIM_MAILLES.keys():
724 print "-----------------"
725 print 'Dim:',i, _D_DIM_MAILLES[i]
726 print "-----------------"
728 print "--- FIN Creation des listes de mailles par Dim : ", time.clock() - t0
730 return _D_DIM_MAILLES
733 # ---------------------------------------------------------------------------- #
735 def Connectivite_Aretes(self, OPTION=None, _LST_OK=None):
739 # Si _LST_OK n'est pas renseigné on prend toutes les mailles
740 if not _LST_OK: _LST_OK = N.arange(len(self.MAILLAGE_Python.tm))
742 if self.OPTIONS['INFO']>=5: print '_LST_OK (ca)=',_LST_OK
744 maille2aretes = self.maille2aretes
747 # - connectivite des aretes (self.MAILLAGE_Python.ca) : m1 -> [ (a1, a2), .. ]
748 # - connectivite inverse des aretes (self.MAILLAGE_Python.cia) : (a1, a2) -> [ m1, m2, ... ]
750 self.MAILLAGE_Python.ca = {}
751 self.MAILLAGE_Python.cia = {}
755 n1 = self.MAILLAGE_Python.tm[n]
757 l_aretes = maille2aretes[n1] # liste des aretes de la maille n
758 l_noeuds = self.MAILLAGE_Python.co[n] # liste des noeuds de la maille n
760 for arete in l_aretes:
763 ll.append( l_noeuds[i] )
767 # Table de connectivité des aretes
769 if not self.MAILLAGE_Python.ca.has_key(n): self.MAILLAGE_Python.ca[n]=[]
770 self.MAILLAGE_Python.ca[n].append(ll)
772 # self.MAILLAGE_Python.ca[n].append(ll)
774 # self.MAILLAGE_Python.ca[n]=[ll]
776 # Table de connectivité inverse des aretes
777 if not self.MAILLAGE_Python.cia.has_key(ll): self.MAILLAGE_Python.cia[ll]=[]
778 self.MAILLAGE_Python.cia[ll].append(n)
780 # self.MAILLAGE_Python.cia[ll].append(n)
782 # self.MAILLAGE_Python.cia[ll]=[n]
785 if self.OPTIONS['INFO']>=5:
786 for k in self.MAILLAGE_Python.cia.keys():
787 print 'cia:',k, ' ', self.MAILLAGE_Python.cia[k]
789 for k in self.MAILLAGE_Python.ca.keys():
790 print 'ca: ',k, ' ', self.MAILLAGE_Python.ca[k]
793 print "--- FIN Creation de la connectivite simple et inverse des aretes : ", time.clock() - t0
798 # ---------------------------------------------------------------------------- #
800 def Elimination_Mailles_de_bords(self, MAILLAGE_Python, _D_DIM_MAILLES, _DIM):
802 Extraction des mailles de bords (mailles incluses dans un bord d une autre maille)
807 _LST_TMA = self.MAILLAGE_Python.tm
809 if self.OPTIONS['INFO']>=5:
810 MAILLAGE = self.ASTER['MAILLAGE']
811 nommail = string.ljust(MAILLAGE.nom,8)
812 _LST_MAI = aster.getvectjev(nommail.ljust(8)+'.NOMMAI')
814 # Le dico maille2nb donne le nombre de noeuds definissant un bord (lineaire)
815 maille2nb = self.maille2nb
818 # construction des listes des mailles de dim N-1 :
819 # _LST_OK : Mailles de dim N-i qui ne sont pas un bord des mailles de dim N
820 # _LST_BD : Mailles de dim N-i qui sont un bord
822 if self.OPTIONS['INFO']>=5: print '\n\nElimination des mailles de bord de DIM', _DIM - 1
824 _LST4 = _D_DIM_MAILLES[ _DIM - 1 ]
825 _LST_IND = N.arange( len(_LST4) ) + 1 # on ajoute 1 pour eviter le premier 0 dans les test nonzero plus bas
827 if self.OPTIONS['INFO']>=5: print ' Mailles concernées=',_LST4
831 if self.OPTIONS['INFO']>=5: print '\n Maille de dim N-1:',m, ' Aster:',string.strip(_LST_MAI[m]), ' TMA:',self.MAILLAGE_Python.tm[m], ' CO:',self.MAILLAGE_Python.co[m], '(noeuds de cette maille)'
832 nb = maille2nb[ self.MAILLAGE_Python.tm[m] ]
833 ll = self.MAILLAGE_Python.co[m][0:nb]
837 if self.OPTIONS['INFO']>=5: print ' Bord (lineaire)', ll, nb
840 if self.OPTIONS['INFO']>=5: print ' CIA=', self.MAILLAGE_Python.cia[ ll ], '(mailles de dim N qui ont cette maille pour bord)'
842 for maille in self.MAILLAGE_Python.cia[ ll ]:
843 if self.OPTIONS['INFO']>=5: print ' Maille N:', maille, 'Aster:', string.strip(_LST_MAI[maille]), ' TMA:', self.MAILLAGE_Python.tm[maille]
844 # self.liste_mailles_bord.append(m)
846 if self.OPTIONS['INFO']>=5: print ' Maille non-bord'
851 # Recuperation des mailles de bords et non-bords
852 _LST_BD = N.nonzero(_LST_IND)
853 _LST_BD = N.take(_LST4,_LST_BD)
855 _LST_OK = N.where( _LST_IND==0, 1 , 0 )
856 _LST_OK = N.nonzero(_LST_OK)
857 _LST_OK = N.take(_LST4,_LST_OK)
859 if self.OPTIONS['INFO']>=5: print '\nListe Maille de bords de DIM', _DIM - 1,' :',_LST_BD
860 if self.OPTIONS['INFO']>=5: print 'Liste Maille de DIM', _DIM - 1,'qui ne sont pas des bords :',_LST_OK
862 print "--- FIN Maille de bords de DIM",_DIM - 1, " : ", time.clock() - t0
866 # On cherche à marier les mailles de dimension N-2, N-3
867 # Peut etre lent car on utilise la connectivité ! Mais pour le moment on a rien d'autre.
872 for d in range(_DIM-1):
873 _LST4 = _D_DIM_MAILLES[ d ]
874 if self.OPTIONS['INFO']>=5: print '\n\nElimination des mailles de bord de DIM', d
875 if self.OPTIONS['INFO']>=5: print ' Mailles concernées=',_LST4
877 if self.OPTIONS['INFO']>=5: print '\n Maille:', mai, ' Aster:',string.strip(_LST_MAI[mai]), ' TMA:',self.MAILLAGE_Python.tm[mai], ' CO:',self.MAILLAGE_Python.co[mai], '(noeuds de cette maille)'
879 nb = maille2nb[ self.MAILLAGE_Python.tm[mai] ]
880 ll = self.MAILLAGE_Python.co[mai][0:nb]
884 # _tmp = self.MAILLAGE_Python.co[mai]
886 if self.OPTIONS['INFO']>=5: print ' Bord (lineaire):', _tmp, nb
889 for arete in self.MAILLAGE_Python.cia:
892 if noe in arete: _nb+=1
894 if self.OPTIONS['INFO']>=5: print ' Maille N+i:', self.MAILLAGE_Python.cia[arete], '- Arete:', arete
895 _LST_BD0.append( mai )
897 # if not _D_BD.has_key( mai ): _D_BD[mai] = []
898 # _D_BD[mai].append( self.MAILLAGE_Python.cia[arete] )
901 _LST_OK0.append( mai )
903 # print 'Mai:',mai, '_D_BD[mai]=',_D_BD[mai]
906 if self.OPTIONS['INFO']>=5: print '\nListe Maille de bords de DIM', d,' :',_LST_BD0
907 if self.OPTIONS['INFO']>=5: print 'Liste Maille de DIM', d,'qui ne sont pas des bords :',_LST_OK0
910 print '--- FIN Maille de bords de DIM', d, ' :',time.clock() - t0
914 _LST_OK = N.concatenate( (_LST_OK, N.array(_LST_OK0)) )
915 _LST_BD = N.concatenate( (_LST_BD, N.array(_LST_BD0)) )
917 if self.OPTIONS['INFO']>=5: print '\nTotal:\nListe Maille de bords=',_LST_BD
918 if self.OPTIONS['INFO']>=5: print 'Liste Maille non-bords=',_LST_OK,'\n'
920 # print "--- FIN Maille de bords 3 : ", time.clock() - t0
922 return _LST_OK, _LST_BD
925 # ---------------------------------------------------------------------------- #
927 def Affectation_Mailles_de_bords(self, _LST_BD, _DIM):
929 Affectation a un SD des mailles de bords (mailles incluses dans un bord d une autre maille)
932 if self.OPTIONS['INFO']>=5:
933 print 'liste_mailles_bord=', self.liste_mailles_bord
934 print 'liste_sd_bord', self.liste_sd_bord
935 print '_LST_BD=',_LST_BD
938 MAILLAGE = self.ASTER['MAILLAGE']
939 _LST_TMA = self.MAILLAGE_Python.tm
941 if self.OPTIONS['INFO']>=5:
942 nommail = string.ljust(MAILLAGE.nom,8)
943 _LST_MAI = aster.getvectjev(nommail.ljust(8)+'.NOMMAI')
947 # Affectation des mailles de bords à chacun des SD
949 # Le dico maille2nb donne le nombre de noeuds definissant un bord (lineaire)
950 maille2nb = self.maille2nb
954 if self.OPTIONS['INFO']>=5: print '\n Maille de dim N-1:',m, ' Aster:',string.strip(_LST_MAI[m]), ' TMA:',self.MAILLAGE_Python.tm[m], ' CO:',self.MAILLAGE_Python.co[m], '(noeuds de cette maille)'
955 nb = maille2nb[ self.MAILLAGE_Python.tm[m] ]
956 ll = self.MAILLAGE_Python.co[m][0:nb]
960 if self.OPTIONS['INFO']>=5: print ' Bord (lineaire)', ll, nb
962 # Cas particulier des POI1 en 2D et 3D (ils ne peuvent etre des bords d'elements 2D ou 3D)
963 if ( (nb==1) and (_DIM>=2) ):
965 for arete in self.MAILLAGE_Python.cia.keys():
967 for maille in self.MAILLAGE_Python.cia[ arete ]:
968 if self.OPTIONS['INFO']>=5: print ' Maille N+i:', maille, ' Aster:',string.strip(_LST_MAI[maille]), ' Arete:', arete
969 _tmp.append( self.liste_sd[maille] )
971 # Cas particulier des SEG en 3D (ils ne peuvent etre des bords d'elements 3D)
972 elif ( (nb==2) and (_DIM==3) ):
974 for arete in self.MAILLAGE_Python.cia.keys():
977 if noe in arete: _nb+=1
979 for maille in self.MAILLAGE_Python.cia[arete]:
980 if self.OPTIONS['INFO']>=5: print ' Mailles N+i:', maille, ' Aster:',string.strip(_LST_MAI[maille]), ' Arete:', arete
981 _tmp.append( self.liste_sd[maille] )
983 # Autres mailles de bord
985 if self.OPTIONS['INFO']>=5: print ' CIA=', self.MAILLAGE_Python.cia[ ll ], '(mailles de dim N qui ont cette maille pour bord)'
987 for maille in self.MAILLAGE_Python.cia[ ll ]:
988 if self.OPTIONS['INFO']>=5: print ' Maille N+i:', maille, 'Aster:', string.strip(_LST_MAI[maille]), ' SD:', self.liste_sd[maille], ' TMA:', self.MAILLAGE_Python.tm[maille]
989 _tmp.append( self.liste_sd[maille] )
991 # integre la maille au SD le plus faible (pour que des groupes de bords se retrouvent dans le meme SD)
993 self.liste_mailles_bord.append(m)
994 self.liste_sd_bord.append( _tmp[0] )
996 if self.OPTIONS['INFO']>=5: print ' ---> Maille:',m,'integree au SD:', _tmp[0]
998 if self.OPTIONS['INFO']>=5:
999 print '\n\nliste_mailles_bord=', self.liste_mailles_bord
1000 print 'liste_sd_bord=', self.liste_sd_bord
1003 print "--- FIN Affectation des mailles de bords : ", time.clock() - t0
1008 # ---------------------------------------------------------------------------- #
1010 def Creation_Graphe(self):
1014 # Creation du graphe complet
1017 for mai in self.liste_mailles:
1019 for are in self.MAILLAGE_Python.ca[mai]:
1020 _ll.extend( self.MAILLAGE_Python.cia[are] )
1021 _mm = enleve_doublons_liste(_ll) # coute cher!
1024 self.GRAPH[mai] = _tmp
1026 if self.OPTIONS['INFO']>=5: print 'self.GRAPH['+str(mai)+']=', self.GRAPH[mai]
1028 print "--- FIN Creation du graphe complet : ", time.clock() - t0
1033 # ---------------------------------------------------------------------------- #
1035 def Reduction_Graphe(self, _DIM):
1039 # Elimination des connectivités à interface nulle
1040 maille2dim = self.maille2dim
1042 for mai in self.liste_mailles:
1043 if self.OPTIONS['INFO']>=5: print '\nmai:', mai, 'co:', self.MAILLAGE_Python.co[mai], 'tm:', self.MAILLAGE_Python.tm[mai]
1044 _DIM1 = maille2dim[ self.MAILLAGE_Python.tm[mai] ]
1046 for mai2 in self.GRAPH[mai]:
1047 if self.OPTIONS['INFO']>=5: print 'mai2:', mai2, 'co:', self.MAILLAGE_Python.co[mai2], 'tm:', self.MAILLAGE_Python.tm[mai2]
1048 # calcule le nombre de noeuds communs aux deux mailles
1050 for noe in self.MAILLAGE_Python.co[mai2]:
1051 if noe in self.MAILLAGE_Python.co[mai]: _nb += 1
1052 _DIM2 = maille2dim[ self.MAILLAGE_Python.tm[mai2] ]
1053 if _nb >= min(_DIM1, _DIM2): # le min permet de faire du collage 3D-coque par exemple
1054 _tmp2.append( mai2 )
1058 self.GRAPH[mai] = _tmp2
1060 print "--- FIN Elimination des connectivités avec une interface nulle : ", time.clock() - t0
1064 # Calcul du nombre d'aretes
1065 # A voir : normalement il n'y a rien a faire car nb0 = 2*nb (a verifier...)
1075 if self.OPTIONS['INFO']>=5:
1076 print '----------------------------------------------'
1077 for mai in self.liste_mailles:
1078 print 'self.GRAPH['+str(mai)+']=', self.GRAPH[mai]
1079 print '----------------------------------------------'
1084 # ------------------------------------------------------------------ #
1086 def Ecrire_Graphe(self, f_metis, _nb):
1090 # On doit renumeroter les mailles qui arrivent dans self.liste_mailles pour avoir 0... N-1
1092 for i in N.arange(len(self.liste_mailles)):
1093 _D_CORRES[ self.liste_mailles[i] ] = i
1095 # Ecriture du fichier fort.UL pour metis
1096 fw = open(f_metis,'w')
1097 fw.write( str(len(self.liste_mailles)) + ' ' + str(_nb) + '\n')
1098 for l in self.liste_mailles:
1101 for t in self.GRAPH[l]:
1104 _tmp.append( str(t+1) ) # Necessaire car metis numerote de 1 à N
1106 print 'on oublie le bord:', t
1107 fw.write( string.join(_tmp, ' ') + '\n' )
1109 # print 'Probleme ecriture graphe! On continue..'
1112 print "--- FIN Ecriture du fichier du graphe pour metis : ", time.clock() - t0
1117 # ---------------------------------------------------------------------------- #
1119 def Lecture_fichier_sdd(self, fichier, _LST_OK):
1123 # Lecture du fichier produit par metis (partie a optimiser)
1125 f = open( fichier, 'r' )
1127 print "\n\n ERREUR: le fichier est introuvable! Le partitionneur \n ne s'est probablement pas lancé.\n\n"
1131 for l in f.readlines():
1132 _tmp.append( int(string.strip(l)) )
1134 _l_domaines = N.array(_tmp,copy=0)
1136 # Pour garder le fichier metis
1137 os.system( 'mv ' + fichier + ' REPE_OUT/' )
1139 if self.OPTIONS['INFO']>=5: print '_l_domaines=',_l_domaines
1141 print "--- FIN Lecture du fichier produit par metis : ", time.clock() - t0
1146 # ---------------------------------------------------------------------------- #
1148 def Creation_Group_ma_Python_par_SD(self, NOM='SD', NOM2='B'):
1152 NB_PART = self.OPTIONS['NB_PART']
1154 # Creation du dictionnaire des listes des mailles par SD
1155 # d_gma : { num sd -> [ liste mailles ] }
1157 for i in range(NB_PART):
1161 for sdd in self.liste_sd:
1162 d_gma[sdd].append( self.liste_mailles[i] )
1166 # Creation du dictionnaire des listes des mailles de bord par SD
1167 # d_gma_bord : { num sd -> [ liste mailles ] }
1169 for i in range(NB_PART):
1173 for sdd in self.liste_sd_bord:
1174 d_gma_bord[sdd].append( self.liste_mailles_bord[i] )
1178 # Generation des listes de noms de groupes
1181 for i in range(NB_PART):
1183 _l_sd.append( NOM + str(i) )
1184 if d_gma_bord[i] != []:
1185 _l_bord.append( NOM2 + str(i) )
1188 self.ASTER['GROUP_MA'] = _l_sd
1189 self.ASTER['GROUP_MA_BORD'] = _l_bord
1192 # Creation des groupes de mailles dans le Maillage Python
1193 for i in range(NB_PART):
1194 self.MAILLAGE_Python.gma[NOM+str(i)] = d_gma[i]
1195 self.MAILLAGE_Python.gma[NOM2+str(i)] = d_gma_bord[i]
1197 print "--- FIN creation du dictionnaire des listes des mailles par SD ", time.clock() - t0
1202 # ---------------------------------------------------------------------------- #
1204 def Creation_Group_ma_Aster_par_SD(self, NOM='SD', NOM2='B', INCLUSE='NON'):
1208 MAILLAGE = self.ASTER['MAILLAGE']
1209 NB_PART = self.OPTIONS['NB_PART']
1211 nommail = string.ljust(MAILLAGE.nom,8)
1212 _LST_MAI = aster.getvectjev(nommail.ljust(8)+'.NOMMAI')
1215 # Creation du dictionnaire des listes des mailles par SD
1216 # d_gma : { num sd -> [ liste mailles ] }
1218 for i in range(NB_PART):
1222 for sdd in self.liste_sd:
1223 d_gma[sdd].append( string.strip(_LST_MAI[ self.liste_mailles[m] ]) ) # voir si le strip coute cher !
1227 # Creation du dictionnaire des listes des mailles de bord par SD
1228 # d_gma_bord : { num sd -> [ liste mailles ] }
1230 for i in range(NB_PART):
1233 # On inclus directement les mailles de bords dans les SD
1236 for sdd in self.liste_sd_bord:
1237 d_gma[sdd].append( string.strip(_LST_MAI[ self.liste_mailles_bord[m] ]) ) # voir si le strip coute cher !
1242 for sdd in self.liste_sd_bord:
1243 d_gma_bord[sdd].append( string.strip(_LST_MAI[ self.liste_mailles_bord[m] ]) ) # voir si le strip coute cher !
1247 print "--- FIN creation du dictionnaire des listes des mailles par SD ", time.clock() - t0
1251 # Creation et lancement de la commande DEFI_GROUP associée
1253 DEFI_GROUP = self.jdc.get_cmd('DEFI_GROUP')
1256 from Cata.cata import DEFI_GROUP
1258 print "\n\nERREUR : il faut lancer ce programme depuis Aster pour pouvoir \ngénérer les groupes de mailles Aster.\n\n"
1264 for i in range(NB_PART):
1266 _tmp.append( {'MAILLE': d_gma[i],'NOM': NOM + str(i)} )
1267 _l_sd.append( NOM + str(i) )
1268 if d_gma_bord[i] != []:
1269 _tmp.append( {'MAILLE': d_gma_bord[i],'NOM': NOM2 + str(i)} )
1270 _l_bord.append( NOM2 + str(i) )
1272 motscle2= {'CREA_GROUP_MA': _tmp }
1274 DEFI_GROUP( reuse=MAILLAGE,
1281 self.ASTER['DICO_SD_MAILLES'] = d_gma
1282 self.ASTER['GROUP_MA'] = _l_sd
1283 self.ASTER['GROUP_MA_BORD'] = _l_bord
1285 print "--- FIN Creation et lancement de la commande DEFI_GROUP associée : ", time.clock() - t0
1289 # ---------------------------------------------------------------------------- #