1 #@ MODIF impr_oar_ops Macro DATE 19/11/2007 AUTEUR COURTOIS M.COURTOIS
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2006 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 # ======================================================================
21 # protection pour eficas
24 from Utilitai.Utmess import UTMESS
25 from Utilitai.Table import Table
26 from Utilitai.partition import MAIL_PY
30 def buildTabString(tabLevel):
32 Construit une chaine de tabulation
35 for i in range(0, tabLevel) :
40 def getBornes(listIn, valTest) :
42 Retourne un doublet de valeurs qui correspond aux valeurs de la liste qui encadrent la valeur (valTest)
43 Si val n'est pas encadrée par des valeurs de la liste, une des valeurs du doublet est None
48 if valTest > val : v1 = val
49 if valTest < val : v2 = val
51 # traitement des cas limites
52 if valTest == listIn[0] : v1 = listIn[0]
53 if valTest == listIn[len(listIn)-1] : v2 = listIn[len(listIn)-1]
57 def interpoleLin(listDoublet, X) :
59 Interpole linéairement entre deux bornes définies par listDoublets[(X0, Y0), (X1, Y1)] la valeur Y en X
61 X0 = listDoublet[0][0]
62 Y0 = listDoublet[0][1]
63 X1 = listDoublet[1][0]
64 Y1 = listDoublet[1][1]
66 return Y0 + (X - X0) * (Y1 - Y0) / (X1 - X0)
68 class interpolationError(Exception) :
70 self.mess = 'Interpolation sur une valeur hors bornes'
71 self.otherExcept = Exception()
75 retourne le message associé à l'erreur
77 # Analyse les différents cas d'erreurs
78 if self.otherExcept == IOError :
79 self.mess += "\nProblème à l'ouverture du fichier\n"
85 Classe gérant un noeud de l'arborescence XML
88 - un commentaire (optionnel)
89 - un ensemble de "paramètres" (optionnels)
90 - une liste d'élément ou d'autres noeuds (optionnels/possibilité de balises vides) :
93 - une méthode "buildTree" qui parcoure le liste de manière récursive pour
94 produire l'arborescence XML en vu de son enregistrement ou son impression
95 - (TO DO) une methode statique "loadTree" qui produit un arbre XML à partir d'un fichier
97 def __init__(self, nomBalise, valeur = None, commentaire = None, **listOpt) :
98 self.nomBalise = nomBalise
99 self.commentaire = commentaire
102 if valeur != None : self.addValue(valeur) # None n'est pas 0 !
104 def getCommentaire(self) : return self.commentaire
106 def setCommentaire(sel, commentaire) : self.commentaire = commentaire
108 def getParametres(self) : return self.param
110 def setParametres(self, parametres) : self.param = parametres
112 def append(self, nodeName, valeur=None, commentaire = None, **listOpt) :
114 Ajoute un noeud à l'arborescence et retourne une référence sur ce noeud
115 On peut ajouter directement la valeur, si simple, associée à la balise
117 node = XMLNode(nodeName, valeur, commentaire)
119 self.arbre.append(node)
121 return self.arbre[len(self.arbre)-1]
123 def addValue(self, valeur):
125 Ajoute un élément "simple" (nombre, texte) à l'arborescence
127 self.arbre.append(valeur)
129 def buildTree(self, tabLevel=0) :
131 Construit l'arborescence XML en parcourant récursivement la structure de donnée
132 et la retourne sous la forme d'une chaine de caractères
134 tabLevel permet de gérer l'indentation
136 # Construction de la chaine de tabulations nécessaire à une bonne lecture du fichier XML
137 tabString = buildTabString(tabLevel)
142 # listOpt contient les paramètres optionnels de la balise
144 for v in self.param.keys() :
145 chaine = chaine + ' ' + v + '=' + self.param[v]
148 baliseOuverture=tabString + "<" + self.nomBalise + chaine +">\n"
149 XMLString += baliseOuverture
151 if self.commentaire :
152 XMLString = XMLString + tabString + "\t<!--"+self.commentaire+"-->\n"
154 for elem in self.arbre :
156 XMLString += elem.buildTree(tabLevel+1)
157 except : # l'élément n'est pas un noeud
158 XMLString = XMLString + tabString + '\t' + str(elem) + '\n'
160 XMLString = XMLString + tabString + "</"+self.nomBalise+">\n"
164 def save(self, fileObj) :
166 Construit le l'arborescence XML et l'écrit dans un fichier
167 pointé par le handler passé en paramètres
170 fileObj.write(self.buildTree())
175 Classe de base des éléments manipulés par IMPR_OAR
180 def buildTree(self) : pass
184 Renvoie le noeud XML construit par buildTree
189 class composant(OAR_element) :
191 Classe permettant de traiter les composants
194 1. L utilisateur est suppose faire la meme coupe pour le calcul mecanique et le calcul thermo-mecanique
195 2. Dans le cas d'un revetement, l'utilisateur est supposé définir son plan de coupe de telle sorte
196 que la coupe de la structure et la coupe du revetement se raccordent
198 def __init__(self, **args) :
199 self.nodeComp = XMLNode("COMPOSANT") # Racine de l'arborescence composant
201 self.diametre = args['DIAMETRE']
202 self.origine = args['ORIGINE']
203 self.coef_u = args['COEF_U']
204 self.angle_c = args['ANGLE_C']
205 self.revet = args['REVET']
207 self.lastAbscisse = None # Permet de gerer le recouvrement des points de coupe entre revetement et structure
210 self.tabAbscisses = list()
211 self.tabAbscisses_S = None
212 self.dictMeca = dict()
213 self.dictMeca_S = None # Pas créé car optionnel
215 self.epaisseur_R = 0.0
217 # dictionnaire gérant le résultat contraintes en fonction des instants et des abscisses
218 self.dictInstAbscSig = dict()
219 self.dictInstAbscSig_S = None # Création si nécessaire
220 # dictionnaire gérant le résultat température en fonction des instants et des abscisses
221 self.dictInstAbscTemp = dict()
222 self.dictInstAbscTemp_S = None # facultatif
223 self.list_inst = None
226 self.noResuMeca = False
227 self.noResuTher = False
229 # 1. resultat mecanique
231 # On ne construit qu'une table des abscisses et une table des contraintes.
232 # Le revetement est obligatoirement en interne on commence par lui
233 para_resu_meca = args['RESU_MECA']
234 self.num_char = para_resu_meca['NUM_CHAR']
235 self.type_char = para_resu_meca['TYPE']
237 if self.revet == 'OUI' :
238 # Construction de la table complementaire si revetement
239 self.dictMeca_S = dict()
240 self.tabAbscisses_S = list()
241 self.buildTablesMeca('TABLE_S', para_resu_meca, self.tabAbscisses_S, self.dictMeca_S)
242 self.epaisseur_R = abs(self.tabAbscisses_S[len(self.tabAbscisses_S)-1] - self.tabAbscisses_S[0])
244 self.buildTablesMeca('TABLE', para_resu_meca, self.tabAbscisses, self.dictMeca, offset=self.epaisseur_R)
246 if self.revet == 'OUI' :
247 self.mergeDictMeca() # merge les tableaux resultats du revetement et de la structure
249 # Calcul de l'épaisseur de la coupe.
250 self.epaisseur = abs(self.tabAbscisses[len(self.tabAbscisses)-1] - self.tabAbscisses[0])
253 self.noResuMeca = True
255 # 2. Résultat thermique
257 para_resu_ther = RESU_THER
258 self.num_tran = para_resu_ther['NUM_TRAN']
259 self.tabAbscisses = list()
260 self.tabAbscisses_S = None
263 if self.revet == 'OUI' :
264 # Le revetement est obligatoirement en interne on commence par lui
265 # 1. Construction champ temperature
266 self.dictInstAbscTemp_S = dict()
267 self.buildTemp('TABLE_ST', para_resu_ther, self.dictInstAbscTemp_S)
269 # 2. Construction de la "table" des contraintes
270 self.dictInstAbscSig_S = dict()
271 self.tabAbscisses_S = list()
272 self.buildTablesTher('TABLE_S', para_resu_ther, self.tabAbscisses_S, self.dictInstAbscSig_S)
274 # 3. calcul de l'épaisseur
275 self.epaisseur_R = abs(self.tabAbscisses_S[len(self.tabAbscisses_S)-1] - self.tabAbscisses_S[0])
278 # 1. Construction champ température
279 self.buildTemp('TABLE_TEMP', para_resu_ther, self.dictInstAbscTemp, self.epaisseur_R)
281 # 2. Construction de la table des contraintes
282 self.buildTablesTher('TABLE_T', para_resu_ther, self.tabAbscisses, self.dictInstAbscSig, offset=self.epaisseur_R)
284 if self.revet == 'OUI' :
285 self.mergeDictTher() # merge les tableaux resultats du revetement et de la structure
287 if not(self.compareListAbscTher()) :
291 self.interpoleInstants() # Interpolation des instants de la table des température sur celle de la table mécanique
292 except interpolationError, err:
293 UTMESS('F','OAR0_2',valk=err.getMess())
295 # 3. Calcul de l'épaisseur de la coupe.
296 self.epaisseur = abs(self.tabAbscisses[len(self.tabAbscisses)-1] - self.tabAbscisses[0])
299 self.noResuTher = True
301 # Construction de l arborescence
305 def getAbscisses(self, dicoTable, tableAbsc, offset=0.0) :
307 Récupère la liste des abscisses
309 # récupération des abscisses
310 ABSCISSES = dicoTable['ABSC_CURV']
313 for val in ABSCISSES :
314 valeurAbsc = val + offset
315 tableAbsc.append(valeurAbsc)
317 def buildTablesMeca(self, label, para_resu, tableAbsc, dictMeca, offset=0.0) :
319 Construction des tableaux mécanique
321 sigma_xml = ( 'S_RR', 'S_TT', 'S_ZZ', 'S_RT', 'S_TZ', 'S_ZR' )
323 table_meca = para_resu[label].EXTR_TABLE()
325 # Utilisation des méthodes de la classe table
326 dictTable = table_meca.values()
328 # récupération des abscisses
329 self.getAbscisses(dictTable, tableAbsc, offset)
331 # Construction de la table mécanique principale
332 for val in sigma_xml :
333 dictMeca[val] = list()
335 S_XX = dictTable['SIXX']
336 S_YY = dictTable['SIYY']
337 S_ZZ = dictTable['SIZZ']
338 S_XY = dictTable['SIXY']
339 S_YZ = dictTable['SIYZ']
340 S_XZ = dictTable['SIXZ']
341 for v1, v2, v3, v4, v5, v6 in zip(S_XX, S_YY, S_ZZ, S_XY, S_YZ, S_XZ) :
342 dictMeca['S_RR'].append(v1)
343 dictMeca['S_TT'].append(v2)
344 dictMeca['S_ZZ'].append(v3)
345 dictMeca['S_RT'].append(v4)
346 dictMeca['S_TZ'].append(v5)
347 dictMeca['S_ZR'].append(v6)
349 def mergeDictMeca(self) :
351 Merge des résultats mécaniques issus de la structure et du revetement
353 # Merge des listes d'abscisses
354 # Le revetement est interieur la derniere abscisse du revetement doit etre egal a la premiere de la structure
355 if self.tabAbscisses_S[len(self.tabAbscisses_S)-1] != self.tabAbscisses[0] :
358 # On construit une table des abscisses tempopraire
359 tableAbscTemp = self.tabAbscisses_S
361 # On recopie la table des abscisses en sautant le premier
363 for val in self.tabAbscisses :
367 tableAbscTemp.append(val)
369 self.tabAbscisses = tableAbscTemp
371 # On construit des listes de travail intermédiaires que l'on commence par remplir avec les tables "supplémentaires"
372 dictMecaBis = self.dictMeca_S
374 # On recopie les éléments de la structure dans le tableau
376 for v1, v2, v3, v4, v5, v6 in zip(self.dictMeca['S_RR'], self.dictMeca['S_TT'], self.dictMeca['S_ZZ'], self.dictMeca['S_RT'], self.dictMeca['S_TZ'], self.dictMeca['S_ZR']) :
380 dictMecaBis['S_RR'].append(v1)
381 dictMecaBis['S_TT'].append(v2)
382 dictMecaBis['S_ZZ'].append(v3)
383 dictMecaBis['S_RT'].append(v4)
384 dictMecaBis['S_TZ'].append(v5)
385 dictMecaBis['S_ZR'].append(v6)
387 # On restitue ensuite la liste globale dans self.dictMeca
388 self.dictMeca = dictMecaBis
391 def buildTemp(self, label, para_resu, dictInstAbscTemp, offset=0.0):
393 Récupération du champ température aux noeuds avec interpolation sur les "instants" du calcul mécanique
395 table_temp = para_resu[label].EXTR_TABLE()
397 # Utilisation des méthodes de la classe table
398 dictTable = table_temp.values()
400 # On construit un dictionnaire associant un "instant" avec un couple ("abscisse", "température")
402 # 1. Récupération de la liste des instants
403 INSTANTS = dictTable['INST']
404 for val in INSTANTS :
405 dictInstAbscTemp[val] = 0 # On crée juste les clés du dictionnaire
407 listTables = list() # liste de tables contenant une table pas instant
408 for inst in dictInstAbscTemp.keys():
409 listTables.append(table_temp.INST == inst)
411 # 2. Récupération des abscisses
413 self.getAbscisses(listTables[0].values(), tableAbsc, offset)
415 # 3. Récupération des températures
416 tableTemp = list() # liste de liste de température (1 par instant)
417 for tb in listTables :
418 TEMPERATURE = tb.values()['TEMP']
419 tableTemp.append(TEMPERATURE)
421 # 4. Construction de dictInstAbscTemp
422 for i in range(0, len(dictInstAbscTemp.keys())):
423 listDoublets = list()
424 for absc, temp in zip(tableAbsc, tableTemp[i]) :
425 listDoublets.append((absc,temp))
427 inst = dictInstAbscTemp.keys()[i]
428 dictInstAbscTemp[inst] = listDoublets
430 def buildTablesTher(self, label, para_resu, tabAbscisses, dictInstAbscSig, offset=0.0) :
432 Construction des tableaux thermo-mécanique
433 listDictTher contient un dictionnaire par numéro d'ordre
435 table_temp = para_resu[label].EXTR_TABLE()
437 # On construit un dictionnaire associant un "instant" avec une liste de couples ("abscisse", liste de "sigma")
439 # Utilisation des méthodes de la classe table
440 dictTable = table_temp.values()
442 # On construit un dictionnaire associant un "instant" avec un couple ("abscisse", "température")
444 # 1. Récupération de la liste des instants
445 INSTANTS = dictTable['INST']
446 for val in INSTANTS :
447 dictInstAbscSig[val] = 0 # On crée juste les clés du dictionnaire
449 listTables = list() # liste de tables contenant une table pas instant
450 for inst in dictInstAbscSig.keys():
451 listTables.append(table_temp.INST == inst)
453 # 2. Récupération des abscisses
454 self.getAbscisses(listTables[0].values(), tabAbscisses, offset)
456 # 3. Récupération des listes de sigma
457 listListListSigAbscInst = list() # liste des sigma par abscisse par instant
458 for tbl in listTables:
459 listListSigAbscInst = list()
461 # On crée une table pour chaque instant
462 S_XX = tbl.values()['SIXX']
463 S_YY = tbl.values()['SIYY']
464 S_ZZ = tbl.values()['SIZZ']
465 S_XY = tbl.values()['SIXY']
466 S_YZ = tbl.values()['SIYZ']
467 S_XZ = tbl.values()['SIXZ']
468 for v1, v2, v3, v4, v5, v6 in zip(S_XX, S_YY, S_ZZ, S_XY, S_YZ, S_XZ) :
469 listSigAbsc = list() # Liste des sigmas pour une abscisse
470 listSigAbsc.append(v1)
471 listSigAbsc.append(v2)
472 listSigAbsc.append(v3)
473 listSigAbsc.append(v4)
474 listSigAbsc.append(v5)
475 listSigAbsc.append(v6)
477 listListSigAbscInst.append(listSigAbsc)
479 listListListSigAbscInst.append(listListSigAbscInst)
481 # 4. Assemblage du dictionnaire
482 for i in range(0, len(dictInstAbscSig.keys())) :
484 for j in range(0, len(tabAbscisses)) :
485 listDoublet.append((tabAbscisses[j], listListListSigAbscInst[i][j]))
487 dictInstAbscSig[dictInstAbscSig.keys()[i]] = listDoublet
489 def mergeDictTher(self) :
491 Merge les resultats issus de la coupe du revetement avec ceux issus de la coupe de la structure
493 # Merge des listes d'abscisses
494 # Le revetement est interieur la derniere abscisse du revetement doit etre egal a la premiere de la structure
495 if self.tabAbscisses_S[len(self.tabAbscisses_S)-1] != self.tabAbscisses[0] :
498 # On construit une table des abscisses tempopraire
499 tableAbscTemp = self.tabAbscisses_S
501 # On recopie la table des abscisses en sautant le premier
503 for val in self.tabAbscisses :
507 tableAbscTemp.append(val)
509 self.tabAbscisses = tableAbscTemp
511 # On construit des listes de travail intermédiaires que l'on commence par remplir avec les tables "supplémentaires"
512 dictInstAbscSigBis = self.dictInstAbscSig_S
513 dictInstAbscTempBis = self.dictInstAbscTemp_S
515 # On recopie les élément thermiques de la structure principale en sautant la première abscisse de la structure
516 for key in dictInstAbscTempBis.keys() : # Les dictionnaires partagent les memes instants
518 for valTher in self.dictInstAbscTemp[key] :
522 dictInstAbscTempBis[key].append(valTher)
524 # On recopie les élément mécaniques de la structure principale en sautant la première abscisse de la structure
525 for key in dictInstAbscSigBis.keys() : # Les dictionnaires partagent les memes instants
527 for valSig in self.dictInstAbscSig[key] :
531 dictInstAbscSigBis[key].append(valSig)
533 # On restitue ensuite la liste globale dans self.dictInstAbscSig
534 self.dictInstAbscSig = dictInstAbscSigBis
535 self.dictInstAbscTemp = dictInstAbscTempBis
537 def compareListAbscTher(self) :
539 Vérifie que la coupe du champ thermique et la coupe mécanique partagent les memes abscisses
541 # 1. Récupération des abscisses associées aux températures
543 lstDoublet = self.dictInstAbscTemp[self.dictInstAbscTemp.keys()[0]]
544 for val in lstDoublet :
545 listAbsc.append(val[0])
547 # 2. Comparaison des deux listes
548 for A1, A2 in zip(self.tabAbscisses, listAbsc) :
549 if A1 != A2 : return False
553 def interpoleInstants(self) :
555 Interpole les résultats thermique sur les instants des résultats mécaniques
557 # 1. récupération des instants des deux tables
558 listInstTher = self.dictInstAbscTemp.keys()
559 listInstMeca = self.dictInstAbscSig.keys()
561 # 2. calcul de la liste des bornes de la table thermique qui encadrent les résultats mécaniques
562 dictInstAbscTemp = dict()
563 listAbscTemp = list()
565 for inst in listInstMeca :
566 bornes = getBornes(listInstTher, inst)
567 # Si une des bornes n'est pas définie, on lance une exception
568 if not(bornes[0]) or not(bornes[1]) : raise interpolationError
570 abscTempInf = self.dictInstAbscTemp[bornes[0]] # Liste de doublet (abscisse, temperature) pour la borne inférieure
571 abscTempSup = self.dictInstAbscTemp[bornes[1]] # Liste de doublet (abscisse, temperature) pour la borne supérieure
573 listAbscTemp = list() # liste de couples abscisses/Température
574 for A1, A2 in zip(abscTempInf, abscTempSup) : # A1 et A2 sont des doublets abscisse/Temperature
575 temperature = interpoleLin( ((bornes[0], A1[1]), (bornes[1], A2[1])), inst)
576 listAbscTemp.append((A1[0], temperature)) # on aurait pu tout aussi bien prendre A2[0] (c est pareil ...)
578 dictInstAbscTemp[inst] = listAbscTemp
580 # remplacement de l'ancienne table par la nouvelle
581 self.dictInstAbscTemp = dictInstAbscTemp
583 def buildTree(self) :
585 Construction (en mémoire) de l'arborescence du document XML
587 sigma_xml = ( 'S_RR', 'S_TT', 'S_ZZ', 'S_RT', 'S_TZ', 'S_ZR' )
589 # Création de l'arborescence "géométrie"
590 nodeGeomComp = self.nodeComp.append("GEOM_COMPO")
591 nodeGeomComp.append("REVETEMENT", valeur=self.revet)
592 if self.revet == 'OUI' :
593 nodeGeomComp.append("EP_REVET", valeur=self.epaisseur_R)
594 nodeLigneCoupe = nodeGeomComp.append("LIGNE_COUPE")
595 nodeLigneCoupe.append("EPAISSEUR_EF", valeur=self.epaisseur)
596 nodeLigneCoupe.append("DIAM_EXT_EF", valeur=self.diametre)
597 nodeLigneCoupe.append("ORI_ABSC", valeur=self.origine)
599 if self.noResuMeca == False :
600 # Création des abscisses
601 for val in self.tabAbscisses :
602 nodeLigneCoupe.append("ABSCISSE", val)
604 nodeLigneCoupe.append('PSI', self.angle_c)
606 # Création des résultats mécaniques
607 nodeSigma_u = self.nodeComp.append("SIGMA_UNITE")
608 nodeSigma_u.append("NUM_MECA", valeur=self.num_char)
609 nodeSigma_u.append("NOM_MECA", valeur=self.type_char)
610 nodeSigma_meca = nodeSigma_u.append("SIGMA_MECA")
612 for i in range(0, len(self.tabAbscisses)) :
613 for val in self.dictMeca.keys() :
614 nodeSigma_meca.append(val, valeur = self.dictMeca[val][i])
616 # Création de l'arborescence "résultat thermo_mécanique"
617 if self.noResuTher == False :
618 # Création des abscisses
619 listDoublet = self.dictInstAbscTemp[self.dictInstAbscTemp.keys()[0]]
620 for val in listDoublet :
621 nodeLigneCoupe.append("ABSCISSE", val[0])
623 nodeLigneCoupe.append('PSI', self.angle_c)
625 # Création des résultats mécaniques
626 nodeSigma_ther_c = self.nodeComp.append("SIGMA_THER_C")
627 nodeSigma_ther_c.append("NUM_TRANSI_THER", valeur=self.num_tran)
629 for inst in self.dictInstAbscTemp.keys() : # boucle sur les instants
630 nodeSigma_ther = nodeSigma_ther_c.append("SIGMA_THER")
631 nodeSigma_ther.append("INSTANT", valeur=inst)
633 # boucle sur les abscisses
634 for doubletAbscSig, doubletAbscTemp in zip(self.dictInstAbscSig[inst], self.dictInstAbscTemp[inst]) :
635 nodeSigma_point = nodeSigma_ther.append("SIGMA_POINT")
636 for val, label in zip(doubletAbscSig[1], sigma_xml) :
637 nodeSigma_point.append(label, valeur = val)
639 nodeSigma_point.append("TEMPERATURE", doubletAbscTemp[1])
641 class tuyauterie(OAR_element) :
643 Classe permettant de traiter les tuyauteries
645 def __init__(self, **args) :
646 self.nodeComp = XMLNode("TUYAUTERIE")
648 self.para_resu_meca = args['RESU_MECA']
649 self.num_char = self.para_resu_meca['NUM_CHAR']
652 self.maillage = self.para_resu_meca['MAILLAGE']
654 mapy.FromAster(self.maillage)
656 self.ma = [val.rstrip() for val in mapy.correspondance_mailles]
657 self.no = [val.rstrip() for val in mapy.correspondance_noeuds]
659 self.dictMailleNoeuds = dict()
661 self.dictMailleNoeuds[val] = list()
663 for i in range(0, len(mapy.co)) :
664 self.dictMailleNoeuds[self.ma[i]].append(self.no[mapy.co[i][0]])
665 self.dictMailleNoeuds[self.ma[i]].append(self.no[mapy.co[i][1]])
667 self.dictNoeudValTorseur = dict()
668 self.buildTableTorseur()
673 # Construction de l arborescence
677 def buildTableTorseur(self) :
679 Construit un dictionnaire associant un noeud à un torseur exprimé sous la forme d'une liste de valeurs
681 table_temp = self.para_resu_meca['TABLE'].EXTR_TABLE()
683 # Utilisation des méthodes de la classe table
684 dictTable = table_temp.values()
686 # 1. Récupération de la liste des noeuds
687 NOEUDS = dictTable['NOEUD']
689 self.dictNoeudValTorseur[val.rstrip()] = list() # On crée juste les clés du dictionnaire
695 MFY = dictTable['MFY']
696 MFZ = dictTable['MFZ']
698 for no, n, vy, vz, mt, mfy, mfz in zip(NOEUDS, N, VY, VZ, MT, MFY, MFZ):
700 self.dictNoeudValTorseur[no].append(n)
701 self.dictNoeudValTorseur[no].append(vy)
702 self.dictNoeudValTorseur[no].append(vz)
703 self.dictNoeudValTorseur[no].append(mt)
704 self.dictNoeudValTorseur[no].append(mfy)
705 self.dictNoeudValTorseur[no].append(mfz)
708 def buildTree(self) :
710 Construction (en mémoire) de l'arborescence du document XML
712 torseur_XML = ( 'FX', 'FY', 'FZ', 'MX', 'MY', 'MZ' )
714 # Création de l'arborescence "torseur"
715 nodeTMG = self.nodeComp.append("TORSEUR_MECA-GRP")
716 nodeTM = nodeTMG.append("TORSEUR_MECA")
717 nodeTM.append("oar:CHAR-REF", self.num_char)
718 nodeMTG = nodeTM.append("MAILLE_TORSEUR-GRP")
719 nodeMT = nodeMTG.append("MAILLE_TORSEUR")
720 for MA in self.dictMailleNoeuds.keys() : # Boucle sur les mailles
721 nodeMT.append("oar:MAILLE-REF", MA)
722 for NO in self.dictMailleNoeuds[MA] : # 2 noeuds
723 nodeTorseur = nodeMT.append("oar:TORSEUR")
724 for val, cle in zip(self.dictNoeudValTorseur[NO], torseur_XML) : # 6 valeurs
725 nodeTorseur.append(cle, val)
729 def impr_oar_ops(self, TYPE_CALC, **args) :
732 Ecrit des fichiers au format XML selon la DTD OAR Fichier
734 IMPR_OAR va etre utilise en deux fois d abord calcul mecanique,
735 ensuite calcul thermique ce qui implique qu il ne peut y avoir qu'une seule des deux options a la fois
737 # La macro compte pour 1 dans la numérotation des commandes
742 if TYPE_CALC=='COMPOSANT' :
743 obj = composant(**args)
744 elif TYPE_CALC=='MEF' :
746 elif TYPE_CALC=='TUYAUTERIE' :
747 obj = tuyauterie(**args)
751 # Ecriture dans le fichier
752 # Récupération de la LU du fichier de sortie
754 unite = args['UNITE']
763 name = 'fort.'+str(unite)
765 if ajout=='NON' : # nouveau fichier
766 fileObj = open(name, 'wt')
767 else : # extension du fichier existant
768 fileObj = open(name, 'a+t')
772 obj.getNode().save(fileObj)