1 #@ MODIF impr_oar_ops Macro DATE 07/11/2006 AUTEUR DURAND C.DURAND
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 # ======================================================================
23 from Utilitai.Utmess import UTMESS
24 from Utilitai.Table import Table
25 from Utilitai.partition import MAIL_PY
29 def buildTabString(tabLevel):
31 Construit une chaine de tabulation
34 for i in range(0, tabLevel) :
39 def getBornes(listIn, valTest) :
41 Retourne un doublet de valeurs qui correspond aux valeurs de la liste qui encadrent la valeur (valTest)
42 Si val n'est pas encadrée par des valeurs de la liste, une des valeurs du doublet est None
47 if valTest > val : v1 = val
48 if valTest < val : v2 = val
50 # traitement des cas limites
51 if valTest == listIn[0] : v1 = listIn[0]
52 if valTest == listIn[len(listIn)-1] : v2 = listIn[len(listIn)-1]
56 def interpoleLin(listDoublet, X) :
58 Interpole linéairement entre deux bornes définies par listDoublets[(X0, Y0), (X1, Y1)] la valeur Y en X
60 X0 = listDoublet[0][0]
61 Y0 = listDoublet[0][1]
62 X1 = listDoublet[1][0]
63 Y1 = listDoublet[1][1]
65 return Y0 + (X - X0) * (Y1 - Y0) / (X1 - X0)
67 class interpolationError(Exception) :
69 self.mess = 'Interpolation sur une valeur hors bornes'
70 self.otherExcept = Exception()
74 retourne le message associé à l'erreur
76 # Analyse les différents cas d'erreurs
77 if self.otherExcept == IOError :
78 self.mess += "\nProblème à l'ouverture du fichier\n"
84 Classe gérant un noeud de l'arborescence XML
87 - un commentaire (optionnel)
88 - un ensemble de "paramètres" (optionnels)
89 - une liste d'élément ou d'autres noeuds (optionnels/possibilité de balises vides) :
92 - une méthode "buildTree" qui parcoure le liste de manière récursive pour
93 produire l'arborescence XML en vu de son enregistrement ou son impression
94 - (TO DO) une methode statique "loadTree" qui produit un arbre XML à partir d'un fichier
96 def __init__(self, nomBalise, valeur = None, commentaire = None, **listOpt) :
97 self.nomBalise = nomBalise
98 self.commentaire = commentaire
101 if valeur != None : self.addValue(valeur) # None n'est pas 0 !
103 def getCommentaire(self) : return self.commentaire
105 def setCommentaire(sel, commentaire) : self.commentaire = commentaire
107 def getParametres(self) : return self.param
109 def setParametres(self, parametres) : self.param = parametres
111 def append(self, nodeName, valeur=None, commentaire = None, **listOpt) :
113 Ajoute un noeud à l'arborescence et retourne une référence sur ce noeud
114 On peut ajouter directement la valeur, si simple, associée à la balise
116 node = XMLNode(nodeName, valeur, commentaire)
118 self.arbre.append(node)
120 return self.arbre[len(self.arbre)-1]
122 def addValue(self, valeur):
124 Ajoute un élément "simple" (nombre, texte) à l'arborescence
126 self.arbre.append(valeur)
128 def buildTree(self, tabLevel=0) :
130 Construit l'arborescence XML en parcourant récursivement la structure de donnée
131 et la retourne sous la forme d'une chaine de caractères
133 tabLevel permet de gérer l'indentation
135 # Construction de la chaine de tabulations nécessaire à une bonne lecture du fichier XML
136 tabString = buildTabString(tabLevel)
141 # listOpt contient les paramètres optionnels de la balise
143 for v in self.param.keys() :
144 chaine = chaine + ' ' + v + '=' + self.param[v]
147 baliseOuverture=tabString + "<" + self.nomBalise + chaine +">\n"
148 XMLString += baliseOuverture
150 if self.commentaire :
151 XMLString = XMLString + tabString + "\t<!--"+self.commentaire+"-->\n"
153 for elem in self.arbre :
155 XMLString += elem.buildTree(tabLevel+1)
156 except : # l'élément n'est pas un noeud
157 XMLString = XMLString + tabString + '\t' + str(elem) + '\n'
159 XMLString = XMLString + tabString + "</"+self.nomBalise+">\n"
163 def save(self, fileObj) :
165 Construit le l'arborescence XML et l'écrit dans un fichier
166 pointé par le handler passé en paramètres
169 fileObj.write(self.buildTree())
174 Classe de base des éléments manipulés par IMPR_OAR
179 def buildTree(self) : pass
183 Renvoie le noeud XML construit par buildTree
188 class composant(OAR_element) :
190 Classe permettant de traiter les composants
193 1. L utilisateur est suppose faire la meme coupe pour le calcul mecanique et le calcul thermo-mecanique
194 2. Dans le cas d'un revetement, l'utilisateur est supposé définir son plan de coupe de telle sorte
195 que la coupe de la structure et la coupe du revetement se raccordent
197 def __init__(self, **args) :
198 self.nodeComp = XMLNode("COMPOSANT") # Racine de l'arborescence composant
200 self.diametre = args['DIAMETRE']
201 self.origine = args['ORIGINE']
202 self.coef_u = args['COEF_U']
203 self.angle_c = args['ANGLE_C']
204 self.revet = args['REVET']
206 self.lastAbscisse = None # Permet de gerer le recouvrement des points de coupe entre revetement et structure
209 self.tabAbscisses = list()
210 self.tabAbscisses_S = None
211 self.dictMeca = dict()
212 self.dictMeca_S = None # Pas créé car optionnel
214 self.epaisseur_R = 0.0
216 # dictionnaire gérant le résultat contraintes en fonction des instants et des abscisses
217 self.dictInstAbscSig = dict()
218 self.dictInstAbscSig_S = None # Création si nécessaire
219 # dictionnaire gérant le résultat température en fonction des instants et des abscisses
220 self.dictInstAbscTemp = dict()
221 self.dictInstAbscTemp_S = None # facultatif
222 self.list_inst = None
225 self.noResuMeca = False
226 self.noResuTher = False
228 # 1. resultat mecanique
230 # On ne construit qu'une table des abscisses et une table des contraintes.
231 # Le revetement est obligatoirement en interne on commence par lui
232 para_resu_meca = args['RESU_MECA']
233 self.num_char = para_resu_meca['NUM_CHAR']
234 self.type_char = para_resu_meca['TYPE']
236 if self.revet == 'OUI' :
237 # Construction de la table complementaire si revetement
238 self.dictMeca_S = dict()
239 self.tabAbscisses_S = list()
240 self.buildTablesMeca('TABLE_S', para_resu_meca, self.tabAbscisses_S, self.dictMeca_S)
241 self.epaisseur_R = abs(self.tabAbscisses_S[len(self.tabAbscisses_S)-1] - self.tabAbscisses_S[0])
243 self.buildTablesMeca('TABLE', para_resu_meca, self.tabAbscisses, self.dictMeca, offset=self.epaisseur_R)
245 if self.revet == 'OUI' :
246 self.mergeDictMeca() # merge les tableaux resultats du revetement et de la structure
248 # Calcul de l'épaisseur de la coupe.
249 self.epaisseur = abs(self.tabAbscisses[len(self.tabAbscisses)-1] - self.tabAbscisses[0])
252 self.noResuMeca = True
254 # 2. Résultat thermique
256 para_resu_ther = RESU_THER
257 self.num_tran = para_resu_ther['NUM_TRAN']
258 self.tabAbscisses = list()
259 self.tabAbscisses_S = None
262 if self.revet == 'OUI' :
263 # Le revetement est obligatoirement en interne on commence par lui
264 # 1. Construction champ temperature
265 self.dictInstAbscTemp_S = dict()
266 self.buildTemp('TABLE_ST', para_resu_ther, self.dictInstAbscTemp_S)
268 # 2. Construction de la "table" des contraintes
269 self.dictInstAbscSig_S = dict()
270 self.tabAbscisses_S = list()
271 self.buildTablesTher('TABLE_S', para_resu_ther, self.tabAbscisses_S, self.dictInstAbscSig_S)
273 # 3. calcul de l'épaisseur
274 self.epaisseur_R = abs(self.tabAbscisses_S[len(self.tabAbscisses_S)-1] - self.tabAbscisses_S[0])
277 # 1. Construction champ température
278 self.buildTemp('TABLE_TEMP', para_resu_ther, self.dictInstAbscTemp, self.epaisseur_R)
280 # 2. Construction de la table des contraintes
281 self.buildTablesTher('TABLE_T', para_resu_ther, self.tabAbscisses, self.dictInstAbscSig, offset=self.epaisseur_R)
283 if self.revet == 'OUI' :
284 self.mergeDictTher() # merge les tableaux resultats du revetement et de la structure
286 if not(self.compareListAbscTher()) :
287 UTMESS('F', 'IMPR_OAR', 'LES COUPES MECANIQUES ET THERMIQUE DOIVENT PARTAGER LES MEMES ABSCISSES')
290 self.interpoleInstants() # Interpolation des instants de la table des température sur celle de la table mécanique
291 except interpolationError, err:
292 UTMESS('F', 'IMPR_OAR', err.getMess())
294 # 3. Calcul de l'épaisseur de la coupe.
295 self.epaisseur = abs(self.tabAbscisses[len(self.tabAbscisses)-1] - self.tabAbscisses[0])
298 self.noResuTher = True
300 # Construction de l arborescence
304 def getAbscisses(self, dicoTable, tableAbsc, offset=0.0) :
306 Récupère la liste des abscisses
308 # récupération des abscisses
309 ABSCISSES = dicoTable['ABSC_CURV']
312 for val in ABSCISSES :
313 valeurAbsc = val + offset
314 tableAbsc.append(valeurAbsc)
316 def buildTablesMeca(self, label, para_resu, tableAbsc, dictMeca, offset=0.0) :
318 Construction des tableaux mécanique
320 sigma_xml = ( 'S_RR', 'S_TT', 'S_ZZ', 'S_RT', 'S_TZ', 'S_ZR' )
322 table_meca = para_resu[label].EXTR_TABLE()
324 # Utilisation des méthodes de la classe table
325 dictTable = table_meca.values()
327 # récupération des abscisses
328 self.getAbscisses(dictTable, tableAbsc, offset)
330 # Construction de la table mécanique principale
331 for val in sigma_xml :
332 dictMeca[val] = list()
334 S_XX = dictTable['SIXX']
335 S_YY = dictTable['SIYY']
336 S_ZZ = dictTable['SIZZ']
337 S_XY = dictTable['SIXY']
338 S_YZ = dictTable['SIYZ']
339 S_XZ = dictTable['SIXZ']
340 for v1, v2, v3, v4, v5, v6 in zip(S_XX, S_YY, S_ZZ, S_XY, S_YZ, S_XZ) :
341 dictMeca['S_RR'].append(v1)
342 dictMeca['S_TT'].append(v2)
343 dictMeca['S_ZZ'].append(v3)
344 dictMeca['S_RT'].append(v4)
345 dictMeca['S_TZ'].append(v5)
346 dictMeca['S_ZR'].append(v6)
348 def mergeDictMeca(self) :
350 Merge des résultats mécaniques issus de la structure et du revetement
352 # Merge des listes d'abscisses
353 # Le revetement est interieur la derniere abscisse du revetement doit etre egal a la premiere de la structure
354 if self.tabAbscisses_S[len(self.tabAbscisses_S)-1] != self.tabAbscisses[0] :
355 UTMESS('F', 'IMPR_OAR', 'LES COUPES DU REVETEMENT ET DE LA STRUCTURE DOIVENT PARTAGER UNE ABSCISSE COMMUNE')
357 # On construit une table des abscisses tempopraire
358 tableAbscTemp = self.tabAbscisses_S
360 # On recopie la table des abscisses en sautant le premier
362 for val in self.tabAbscisses :
366 tableAbscTemp.append(val)
368 self.tabAbscisses = tableAbscTemp
370 # On construit des listes de travail intermédiaires que l'on commence par remplir avec les tables "supplémentaires"
371 dictMecaBis = self.dictMeca_S
373 # On recopie les éléments de la structure dans le tableau
375 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']) :
379 dictMecaBis['S_RR'].append(v1)
380 dictMecaBis['S_TT'].append(v2)
381 dictMecaBis['S_ZZ'].append(v3)
382 dictMecaBis['S_RT'].append(v4)
383 dictMecaBis['S_TZ'].append(v5)
384 dictMecaBis['S_ZR'].append(v6)
386 # On restitue ensuite la liste globale dans self.dictMeca
387 self.dictMeca = dictMecaBis
390 def buildTemp(self, label, para_resu, dictInstAbscTemp, offset=0.0):
392 Récupération du champ température aux noeuds avec interpolation sur les "instants" du calcul mécanique
394 table_temp = para_resu[label].EXTR_TABLE()
396 # Utilisation des méthodes de la classe table
397 dictTable = table_temp.values()
399 # On construit un dictionnaire associant un "instant" avec un couple ("abscisse", "température")
401 # 1. Récupération de la liste des instants
402 INSTANTS = dictTable['INST']
403 for val in INSTANTS :
404 dictInstAbscTemp[val] = 0 # On crée juste les clés du dictionnaire
406 listTables = list() # liste de tables contenant une table pas instant
407 for inst in dictInstAbscTemp.keys():
408 listTables.append(table_temp.INST == inst)
410 # 2. Récupération des abscisses
412 self.getAbscisses(listTables[0].values(), tableAbsc, offset)
414 # 3. Récupération des températures
415 tableTemp = list() # liste de liste de température (1 par instant)
416 for tb in listTables :
417 TEMPERATURE = tb.values()['TEMP']
418 tableTemp.append(TEMPERATURE)
420 # 4. Construction de dictInstAbscTemp
421 for i in range(0, len(dictInstAbscTemp.keys())):
422 listDoublets = list()
423 for absc, temp in zip(tableAbsc, tableTemp[i]) :
424 listDoublets.append((absc,temp))
426 inst = dictInstAbscTemp.keys()[i]
427 dictInstAbscTemp[inst] = listDoublets
429 def buildTablesTher(self, label, para_resu, tabAbscisses, dictInstAbscSig, offset=0.0) :
431 Construction des tableaux thermo-mécanique
432 listDictTher contient un dictionnaire par numéro d'ordre
434 table_temp = para_resu[label].EXTR_TABLE()
436 # On construit un dictionnaire associant un "instant" avec une liste de couples ("abscisse", liste de "sigma")
438 # Utilisation des méthodes de la classe table
439 dictTable = table_temp.values()
441 # On construit un dictionnaire associant un "instant" avec un couple ("abscisse", "température")
443 # 1. Récupération de la liste des instants
444 INSTANTS = dictTable['INST']
445 for val in INSTANTS :
446 dictInstAbscSig[val] = 0 # On crée juste les clés du dictionnaire
448 listTables = list() # liste de tables contenant une table pas instant
449 for inst in dictInstAbscSig.keys():
450 listTables.append(table_temp.INST == inst)
452 # 2. Récupération des abscisses
453 self.getAbscisses(listTables[0].values(), tabAbscisses, offset)
455 # 3. Récupération des listes de sigma
456 listListListSigAbscInst = list() # liste des sigma par abscisse par instant
457 for tbl in listTables:
458 listListSigAbscInst = list()
460 # On crée une table pour chaque instant
461 S_XX = tbl.values()['SIXX']
462 S_YY = tbl.values()['SIYY']
463 S_ZZ = tbl.values()['SIZZ']
464 S_XY = tbl.values()['SIXY']
465 S_YZ = tbl.values()['SIYZ']
466 S_XZ = tbl.values()['SIXZ']
467 for v1, v2, v3, v4, v5, v6 in zip(S_XX, S_YY, S_ZZ, S_XY, S_YZ, S_XZ) :
468 listSigAbsc = list() # Liste des sigmas pour une abscisse
469 listSigAbsc.append(v1)
470 listSigAbsc.append(v2)
471 listSigAbsc.append(v3)
472 listSigAbsc.append(v4)
473 listSigAbsc.append(v5)
474 listSigAbsc.append(v6)
476 listListSigAbscInst.append(listSigAbsc)
478 listListListSigAbscInst.append(listListSigAbscInst)
480 # 4. Assemblage du dictionnaire
481 for i in range(0, len(dictInstAbscSig.keys())) :
483 for j in range(0, len(tabAbscisses)) :
484 listDoublet.append((tabAbscisses[j], listListListSigAbscInst[i][j]))
486 dictInstAbscSig[dictInstAbscSig.keys()[i]] = listDoublet
488 def mergeDictTher(self) :
490 Merge les resultats issus de la coupe du revetement avec ceux issus de la coupe de la structure
492 # Merge des listes d'abscisses
493 # Le revetement est interieur la derniere abscisse du revetement doit etre egal a la premiere de la structure
494 if self.tabAbscisses_S[len(self.tabAbscisses_S)-1] != self.tabAbscisses[0] :
495 UTMESS('F', 'IMPR_OAR', 'LES COUPES DU REVETEMENT ET DE LA STRUCTURE DOIVENT PARTAGER UNE ABSCISSE COMMUNE')
497 # On construit une table des abscisses tempopraire
498 tableAbscTemp = self.tabAbscisses_S
500 # On recopie la table des abscisses en sautant le premier
502 for val in self.tabAbscisses :
506 tableAbscTemp.append(val)
508 self.tabAbscisses = tableAbscTemp
510 # On construit des listes de travail intermédiaires que l'on commence par remplir avec les tables "supplémentaires"
511 dictInstAbscSigBis = self.dictInstAbscSig_S
512 dictInstAbscTempBis = self.dictInstAbscTemp_S
514 # On recopie les élément thermiques de la structure principale en sautant la première abscisse de la structure
515 for key in dictInstAbscTempBis.keys() : # Les dictionnaires partagent les memes instants
517 for valTher in self.dictInstAbscTemp[key] :
521 dictInstAbscTempBis[key].append(valTher)
523 # On recopie les élément mécaniques de la structure principale en sautant la première abscisse de la structure
524 for key in dictInstAbscSigBis.keys() : # Les dictionnaires partagent les memes instants
526 for valSig in self.dictInstAbscSig[key] :
530 dictInstAbscSigBis[key].append(valSig)
532 # On restitue ensuite la liste globale dans self.dictInstAbscSig
533 self.dictInstAbscSig = dictInstAbscSigBis
534 self.dictInstAbscTemp = dictInstAbscTempBis
536 def compareListAbscTher(self) :
538 Vérifie que la coupe du champ thermique et la coupe mécanique partagent les memes abscisses
540 # 1. Récupération des abscisses associées aux températures
542 lstDoublet = self.dictInstAbscTemp[self.dictInstAbscTemp.keys()[0]]
543 for val in lstDoublet :
544 listAbsc.append(val[0])
546 # 2. Comparaison des deux listes
547 for A1, A2 in zip(self.tabAbscisses, listAbsc) :
548 if A1 != A2 : return False
552 def interpoleInstants(self) :
554 Interpole les résultats thermique sur les instants des résultats mécaniques
556 # 1. récupération des instants des deux tables
557 listInstTher = self.dictInstAbscTemp.keys()
558 listInstMeca = self.dictInstAbscSig.keys()
560 # 2. calcul de la liste des bornes de la table thermique qui encadrent les résultats mécaniques
561 dictInstAbscTemp = dict()
562 listAbscTemp = list()
564 for inst in listInstMeca :
565 bornes = getBornes(listInstTher, inst)
566 # Si une des bornes n'est pas définie, on lance une exception
567 if not(bornes[0]) or not(bornes[1]) : raise interpolationError
569 abscTempInf = self.dictInstAbscTemp[bornes[0]] # Liste de doublet (abscisse, temperature) pour la borne inférieure
570 abscTempSup = self.dictInstAbscTemp[bornes[1]] # Liste de doublet (abscisse, temperature) pour la borne supérieure
572 listAbscTemp = list() # liste de couples abscisses/Température
573 for A1, A2 in zip(abscTempInf, abscTempSup) : # A1 et A2 sont des doublets abscisse/Temperature
574 temperature = interpoleLin( ((bornes[0], A1[1]), (bornes[1], A2[1])), inst)
575 listAbscTemp.append((A1[0], temperature)) # on aurait pu tout aussi bien prendre A2[0] (c est pareil ...)
577 dictInstAbscTemp[inst] = listAbscTemp
579 # remplacement de l'ancienne table par la nouvelle
580 self.dictInstAbscTemp = dictInstAbscTemp
582 def buildTree(self) :
584 Construction (en mémoire) de l'arborescence du document XML
586 sigma_xml = ( 'S_RR', 'S_TT', 'S_ZZ', 'S_RT', 'S_TZ', 'S_ZR' )
588 # Création de l'arborescence "géométrie"
589 nodeGeomComp = self.nodeComp.append("GEOM_COMPO")
590 nodeGeomComp.append("REVETEMENT", valeur=self.revet)
591 if self.revet == 'OUI' :
592 nodeGeomComp.append("EP_REVET", valeur=self.epaisseur_R)
593 nodeLigneCoupe = nodeGeomComp.append("LIGNE_COUPE")
594 nodeLigneCoupe.append("EPAISSEUR_EF", valeur=self.epaisseur)
595 nodeLigneCoupe.append("DIAM_EXT_EF", valeur=self.diametre)
596 nodeLigneCoupe.append("ORI_ABSC", valeur=self.origine)
598 if self.noResuMeca == False :
599 # Création des abscisses
600 for val in self.tabAbscisses :
601 nodeLigneCoupe.append("ABSCISSE", val)
603 nodeLigneCoupe.append('PSI', self.angle_c)
605 # Création des résultats mécaniques
606 nodeSigma_u = self.nodeComp.append("SIGMA_UNITE")
607 nodeSigma_u.append("NUM_MECA", valeur=self.num_char)
608 nodeSigma_u.append("NOM_MECA", valeur=self.type_char)
609 nodeSigma_meca = nodeSigma_u.append("SIGMA_MECA")
611 for i in range(0, len(self.tabAbscisses)) :
612 for val in self.dictMeca.keys() :
613 nodeSigma_meca.append(val, valeur = self.dictMeca[val][i])
615 # Création de l'arborescence "résultat thermo_mécanique"
616 if self.noResuTher == False :
617 # Création des abscisses
618 listDoublet = self.dictInstAbscTemp[self.dictInstAbscTemp.keys()[0]]
619 for val in listDoublet :
620 nodeLigneCoupe.append("ABSCISSE", val[0])
622 nodeLigneCoupe.append('PSI', self.angle_c)
624 # Création des résultats mécaniques
625 nodeSigma_ther_c = self.nodeComp.append("SIGMA_THER_C")
626 nodeSigma_ther_c.append("NUM_TRANSI_THER", valeur=self.num_tran)
628 for inst in self.dictInstAbscTemp.keys() : # boucle sur les instants
629 nodeSigma_ther = nodeSigma_ther_c.append("SIGMA_THER")
630 nodeSigma_ther.append("INSTANT", valeur=inst)
632 # boucle sur les abscisses
633 for doubletAbscSig, doubletAbscTemp in zip(self.dictInstAbscSig[inst], self.dictInstAbscTemp[inst]) :
634 nodeSigma_point = nodeSigma_ther.append("SIGMA_POINT")
635 for val, label in zip(doubletAbscSig[1], sigma_xml) :
636 nodeSigma_point.append(label, valeur = val)
638 nodeSigma_point.append("TEMPERATURE", doubletAbscTemp[1])
640 class tuyauterie(OAR_element) :
642 Classe permettant de traiter les tuyauteries
644 def __init__(self, **args) :
645 self.nodeComp = XMLNode("TUYAUTERIE")
647 self.para_resu_meca = args['RESU_MECA']
648 self.num_char = self.para_resu_meca['NUM_CHAR']
651 self.maillage = self.para_resu_meca['MAILLAGE']
653 mapy.FromAster(self.maillage)
655 self.ma = [val.rstrip() for val in mapy.correspondance_mailles]
656 self.no = [val.rstrip() for val in mapy.correspondance_noeuds]
658 self.dictMailleNoeuds = dict()
660 self.dictMailleNoeuds[val] = list()
662 for i in range(0, len(mapy.co)) :
663 self.dictMailleNoeuds[self.ma[i]].append(self.no[mapy.co[i][0]])
664 self.dictMailleNoeuds[self.ma[i]].append(self.no[mapy.co[i][1]])
666 self.dictNoeudValTorseur = dict()
667 self.buildTableTorseur()
670 UTMESS('F', 'IMPR_OAR', "ERREUR D'ACCES AUX DONNEES")
672 # Construction de l arborescence
676 def buildTableTorseur(self) :
678 Construit un dictionnaire associant un noeud à un torseur exprimé sous la forme d'une liste de valeurs
680 table_temp = self.para_resu_meca['TABLE'].EXTR_TABLE()
682 # Utilisation des méthodes de la classe table
683 dictTable = table_temp.values()
685 # 1. Récupération de la liste des noeuds
686 NOEUDS = dictTable['NOEUD']
688 self.dictNoeudValTorseur[val.rstrip()] = list() # On crée juste les clés du dictionnaire
694 MFY = dictTable['MFY']
695 MFZ = dictTable['MFZ']
697 for no, n, vy, vz, mt, mfy, mfz in zip(NOEUDS, N, VY, VZ, MT, MFY, MFZ):
699 self.dictNoeudValTorseur[no].append(n)
700 self.dictNoeudValTorseur[no].append(vy)
701 self.dictNoeudValTorseur[no].append(vz)
702 self.dictNoeudValTorseur[no].append(mt)
703 self.dictNoeudValTorseur[no].append(mfy)
704 self.dictNoeudValTorseur[no].append(mfz)
707 def buildTree(self) :
709 Construction (en mémoire) de l'arborescence du document XML
711 torseur_XML = ( 'FX', 'FY', 'FZ', 'MX', 'MY', 'MZ' )
713 # Création de l'arborescence "torseur"
714 nodeTMG = self.nodeComp.append("TORSEUR_MECA-GRP")
715 nodeTM = nodeTMG.append("TORSEUR_MECA")
716 nodeTM.append("oar:CHAR-REF", self.num_char)
717 nodeMTG = nodeTM.append("MAILLE_TORSEUR-GRP")
718 nodeMT = nodeMTG.append("MAILLE_TORSEUR")
719 for MA in self.dictMailleNoeuds.keys() : # Boucle sur les mailles
720 nodeMT.append("oar:MAILLE-REF", MA)
721 for NO in self.dictMailleNoeuds[MA] : # 2 noeuds
722 nodeTorseur = nodeMT.append("oar:TORSEUR")
723 for val, cle in zip(self.dictNoeudValTorseur[NO], torseur_XML) : # 6 valeurs
724 nodeTorseur.append(cle, val)
728 def impr_oar_ops(self, TYPE_CALC, **args) :
731 Ecrit des fichiers au format XML selon la DTD OAR Fichier
733 IMPR_OAR va etre utilise en deux fois d abord calcul mecanique,
734 ensuite calcul thermique ce qui implique qu il ne peut y avoir qu'une seule des deux options a la fois
736 # La macro compte pour 1 dans la numérotation des commandes
741 if TYPE_CALC=='COMPOSANT' :
742 obj = composant(**args)
743 elif TYPE_CALC=='MEF' :
744 UTMESS('F', 'IMPR_OAR', 'FONCTION NON IMPLANTEE')
745 elif TYPE_CALC=='TUYAUTERIE' :
746 obj = tuyauterie(**args)
748 UTMESS('F', 'IMPR_OAR', 'Mot clé facteur inconnu')
750 # Ecriture dans le fichier
751 # Récupération de la LU du fichier de sortie
753 unite = args['UNITE']
762 name = 'fort.'+str(unite)
764 if ajout=='NON' : # nouveau fichier
765 fileObj = open(name, 'wt')
766 else : # extension du fichier existant
767 fileObj = open(name, 'a+t')
769 UTMESS('F', 'IMPR_OAR', "Erreur à l'ouverture du fichier")
771 obj.getNode().save(fileObj)