1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 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.
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 """Ce module contient le plugin generateur de fichier au format Code_Carmel3D pour EFICAS.
23 import xml.etree.cElementTree as ET
25 import types,string,re,os
26 from Extensions.i18n import tr
27 from generator_python import PythonGenerator
30 HARMONIC = 'HARMONIC' # probleme frequentiel
31 TIME_DOMAIN = 'TIME_DOMAIN' # probleme temporel
33 # nom du plugin, utilisé dans entryPoint et generMACRO_ETAPE()
34 nomPlugin = 'CARMEL3DTV0'
38 Retourne les informations necessaires pour le chargeur de plugins
39 Ces informations sont retournees dans un dictionnaire
44 # La factory pour creer une instance du plugin
45 'factory' : CARMEL3DTV0Generator,
50 class CARMEL3DTV0Generator(PythonGenerator):
52 Ce generateur parcourt un objet de type JDC et produit
53 un texte au format eficas et
54 un texte au format attendu par le code Code_Carmel3D (fichier '.PHYS')
57 # Les extensions de fichier permis?
60 #----------------------------------------------------------------------------------------
61 def gener(self,obj,format='brut',config=None):
67 # Cette instruction genere le contenu du fichier de commandes (persistance)
68 self.text=PythonGenerator.gener(self,obj,format)
71 print "self.text = %s" % self.text
73 # Cette instruction genere le contenu du fichier de parametres pour le code Carmel3D
74 # si le jdc est valide (sinon cela n a pas de sens)
77 # constitution du bloc VERSION du fichier PHYS (existe toujours)
78 self.generBLOC_VERSION(obj)
80 except ValueError, err:
81 raise ValueError(str(err))
88 #----------------------------------------------------------------------------------------
90 #----------------------------------------------------------------------------------------
94 self.texteCarmel3D_SH=""
95 self.debug = True # affichage de messages pour deboguage (.true.) ou non
96 self.dicoEtapeCourant=None
97 self.dicoMCFACTCourant=None
99 self.dictGroupes = {} # association des noms de groupes de maillage avec les noms de materiaux ou de sources, en sauvegardant l'ordre du JdC en separant les groupes associes a des materiaux de ceux associes a des sources
100 self.dictMacroGroupes = {} # macro-groupe et leurs propriétés
102 self.dictMouvement= {'ordre':[]} # dictionnaire contenant les mouvements, avec liste incluse pour l'ordre
103 self.nombreMouvements = 0 # nombre de mouvements définis, servant de compteur aussi
107 self.dictGroupeMilieux={"ordreSource":[], "ordreId":[]}
109 # Parametre du maillage
110 self.identification = ""
111 self.fichierMaillage = ""
112 self.echelleMaillage = ""
113 # Parametre de Precision
115 self.precisionLineaire=""
116 self.kEpsilonDistance=""
118 self.nbIterationMax=""
119 self.methodeNonLineaire = ""
120 self.kEpsilonNonLinearite=""
121 self.kCoefficientRelaxation=""
126 self.typeSolveur = "" # type de solveur, linéaire (Solveur_lineaire) ou non-linéaire (Solveur_non_lineaire)
128 self.carteChamp="" # liste des pas de temps demandés lors du post-traitement des cartes de champ
129 self.carteCourantInduit="" # liste des pas de temps demandés lors du post-traitement des cartes de courants induits
130 self.carteForce="" # liste des pas de temps demandés lors du post-traitement des cartes de force
131 self.post_global = [] # liste des grandeurs globales demandées lors du post-traitement
133 # on force le probleme a etre frequentiel, seul possible en l'etat des choses
134 self.problem = HARMONIC
136 def indent(self, elem, level=0, more_sibs=False, espace=4*' '):
137 """Transformation du XML créé par le module interne xml.etree.ElementTree afin d'écrire les indentations et retours à la ligne corrects.
138 D'après un script original de Fredrik Lundh en 2004 (http://effbot.org/zone/element-lib.htm#prettyprint),
139 modifié par Joshua Richardson en 2012 (http://stackoverflow.com/questions/749796/pretty-printing-xml-in-python)
140 et par Loic Chevallier en 2014 (ajout du reglage de l'indentation).
141 L'indentation est de 4 espaces par défaut (cf. argument optionel : espace)
142 Utilisation : self.indent(root), avant écriture dans un fichier de root = ET.Element("configuration") ou de tree = ET.ElementTree(root)
143 où ET = xml.etree.ElementTree
147 i += (level-1) * espace
150 if not elem.text or not elem.text.strip():
151 elem.text = i + espace
156 self.indent(kid, level+1, count < num_kids - 1)
158 if not elem.tail or not elem.tail.strip():
163 if level and (not elem.tail or not elem.tail.strip()):
168 #----------------------------------------------------------------------------------------
170 #----------------------------------------------------------------------------------------
172 def writeDefault(self,fn) :
173 """Ecrit les fichiers de parametres et le fichier d'execution pour le code Carmel3D"""
175 file = fn[:fn.rfind(".")] # emplacement du ficher .comm (chemin complet)
176 namefile=os.path.basename(file) # nom du fichier.comm
177 repertory=os.path.dirname(file) # répertoire contenant le fichier .comm (emplacement absolu)
179 # correspondances globales
180 correspondance_booleen = {'oui':'true', 'non':'false'}
182 fileXML = os.path.join(repertory, 'configuration.xml') # nom du fichier de configuration XML (chemin complet)
184 print "\necriture du fichier XML : ", fileXML
185 print "self.dictMaterial = ",self.dictMaterial
186 print "self.dictSource = ",self.dictSource
187 print "self.dictGroupes = ",self.dictGroupes
188 print "self.dictMacroGroupes = ",self.dictMacroGroupes
190 root = ET.Element("configuration")
192 #Bloc <Maillage></Maillage>
193 Maillage = ET.SubElement(root, "Maillage")
194 identification = ET.SubElement(Maillage, "identification")
195 identification.text = self.identification
196 fichierMaillage = ET.SubElement(Maillage, "fichierMaillage")
197 fichierMaillage.text = self.fichierMaillage
198 echelleMaillage = ET.SubElement(Maillage, "echelleMaillage")
199 correspondance_echelleMaillage = {"Metre":1.0, "Millimetre":1.0e-3}
200 echelleMaillage.text = "%f" % (correspondance_echelleMaillage[self.echelleMaillage], )
202 #Bloc <ParametrePrecision></ParametrePrecision>
203 ParametrePrecision = ET.SubElement(root, "ParametrePrecision")
204 TypeSolveurLineaire = ET.SubElement(ParametrePrecision, "TypeSolveurLineaire")
205 if self.precond=="Crout":
206 TypeSolveurLineaire.text = "1"
207 if self.precond=="Jacobi":
208 TypeSolveurLineaire.text = "2"
209 if self.precond=="MUMPS":
210 TypeSolveurLineaire.text = "3"
211 kEpsilonGCP = ET.SubElement(ParametrePrecision, "kEpsilonGCP")
212 kEpsilonGCP.text = "%s" %(self.kEpsilonGCP)
213 nbIterationMax = ET.SubElement(ParametrePrecision, "nbIterationMax")
214 nbIterationMax.text = "%s" %(self.nbIterationMax)
215 if self.typeSolveur == 'Solveur_non_lineaire': # écriture des paramètres du solveur non-linéaire seulement si défini dans l'étude
216 methodeNonLineaire = ET.SubElement(ParametrePrecision, "methodeNonLineaire")
217 methodeNonLineaire.text = "%s" %(self.methodeNonLineaire)
218 kEpsilonNonLinearite = ET.SubElement(ParametrePrecision, "kEpsilonNonLinearite")
219 kEpsilonNonLinearite.text = "%s" %(self.kEpsilonNonLinearite)
220 kCoefficientRelaxation = ET.SubElement(ParametrePrecision, "kCoefficientRelaxation")
221 kCoefficientRelaxation.text = "%s" %(self.kCoefficientRelaxation)
222 kEpsilonDistance = ET.SubElement(ParametrePrecision, "kEpsilonDistance")
223 kEpsilonDistance.text = "%s" %(self.kEpsilonDistance)
224 kdistanceRef = ET.SubElement(ParametrePrecision, "kdistanceRef")
225 kdistanceRef.text = "%s" %(self.kdistanceRef)
226 jauge = ET.SubElement(ParametrePrecision, "jauge")
227 jauge.text = "%s" %(correspondance_booleen[self.jauge], )
228 NBoucleTemps = ET.SubElement(ParametrePrecision, "NBoucleTemps")
229 NBoucleTemps.text = "%s" %(self.NBoucleTemps)
230 dt = ET.SubElement(ParametrePrecision, "dt")
231 dt.text = "%s" %(self.dt)
233 #Bloc <Milieux></Milieux>
238 listeMilieux = [] # liste des milieux, dans l'ordre de création
239 Milieux=ET.SubElement(root, "Milieux") # création du bloc <Milieux>...</Milieux>
240 for nom in self.dictGroupes: # on parcoure tous les groupes MESHGROUP
241 if self.dictGroupes[nom].has_key('MATERIAL') \
242 or self.dictGroupes[nom].has_key('SOURCE') \
243 or self.dictGroupes[nom].has_key('AIMANT') \
244 or self.dictGroupes[nom].has_key('STRANDED_INDUCTOR_GEOMETRY') : # si MESHGROUP ou MACRO_GROUPE associé à au moins un matériau, source ou géométrie d'inducteur bobiné, c'est un milieu
245 milieu=ET.SubElement(Milieux,"milieu" ) # création d'un nouveau milieu
246 listeMilieux.append(nom) # mise à jour de la liste des milieux
247 i = i+1 # incrément du numéro de milieu
248 self.dictGroupes[nom]['idMilieu'] = i # affectation de l'id à ce groupe
249 milieu.set("id", "%g" % (i, ) ) # ajout de l'attribut id, inutilisé
250 milieu.set("name", "%s" % (nom, ) ) # ajout de l'attribut name, inutilisé
251 nomGroupeMaillage = ET.SubElement(milieu, "nomGroupeMaillage") # nom du groupe de maillage
252 nomGroupeMaillage.text = nom
253 if self.dictGroupes[nom].has_key('MATERIAL'): # matériau trouvé pour ce milieu
254 material = self.dictGroupes[nom]['MATERIAL'] # on récupère le nom de la propriété du matériau, clé de self.dictMaterial
255 permeabiliteLineaire=ET.SubElement(milieu, "permeabiliteLineaire")
256 permeabiliteLineaire.text="%s"%(self.dictMaterial[material]["PERMEABILITY"]["VALUE"])
257 if self.dictMaterial[material]["PERMEABILITY"]["LAW"]=="NONLINEAR":
258 coefficientsMarrocco=ET.SubElement(milieu, "coefficientsMarrocco")
259 epsilon = self.dictMaterial[material]["PERMEABILITY"]["EPSILON"]
260 c = self.dictMaterial[material]["PERMEABILITY"]["C"]
261 alpha = self.dictMaterial[material]["PERMEABILITY"]["ALPHA"]
262 tau = self.dictMaterial[material]["PERMEABILITY"]["TAU"]
263 coefficientsMarrocco.text = '%g, %g, %g, %g' % (epsilon, c, alpha, tau)
264 if self.dictMaterial[material].has_key('CONDUCTIVITY'):
265 conductivite=ET.SubElement(milieu, "conductivite")
266 conductivite.text="%s" %(self.dictMaterial[material]["CONDUCTIVITY"]["VALUE"])
267 if self.dictMaterial[material].has_key('AIMANT'):
268 norme=ET.SubElement(milieu, "norme")
269 norme.text="%s" %(self.dictMaterial[material]["AIMANT"]["VALUE"])
270 if self.dictGroupes[nom].has_key('STRANDED_INDUCTOR_GEOMETRY'): # géométrie d'inducteur bobiné trouvée pour ce milieu
271 strand=self.dictGroupes[nom]['STRANDED_INDUCTOR_GEOMETRY'] # on récupère le nom de la géométrie d'inducteur bobiné, clé de self.dictStrand
272 axe = ET.SubElement(milieu, "axe")
273 axe.text= "%s" % ','.join(map(str,self.dictStrand[strand]["Direction"]))
274 if self.dictStrand[strand]["Forme"]=="Circulaire":
275 coordonneesPolaires=ET.SubElement(milieu, "coordonneesPolaires")
276 coordonneesPolaires.text="true"
277 origineReperePolaire=ET.SubElement(milieu, "origineReperePolaire")
278 origineReperePolaire.text= "%s" % ','.join(map(str,self.dictStrand[strand]["Centre"]))
279 section=ET.SubElement(milieu, "section")
280 section.text="%g" %(self.dictStrand[strand]["Section"], )
281 if self.dictGroupes[nom].has_key('SOURCE'): # source trouvée pour ce milieu
282 Source = self.dictGroupes[nom]['SOURCE'] # on récupère le nom de la source, clé de self.dictSource
283 self.dictSource[Source]['milieux'].append(nom) # ajout du nom du groupe à cette source
284 if self.dictSource[Source].has_key('STRANDED_INDUCTOR'):
285 nbSpires=ET.SubElement(milieu, "nbSpires")
286 nbSpires.text="%g" %(self.dictSource[Source]["STRANDED_INDUCTOR"]["NTURNS"])
288 #Bloc <ConditionsLimitesChamps>...</ConditionsLimitesChamps>
289 ConditionsLimitesChamps = ET.SubElement(root, "ConditionsLimitesChamps")
290 for nomCondition in self.dictGroupes:
291 if self.dictGroupes[nomCondition].has_key('CONDITION_LIMITE'): # condition aux limites associée à ce groupe, hors symétrie et mouvement
292 if self.dictGroupes[nomCondition].has_key('LISTE'): # MACRO_GROUPE
293 for i in range(len(self.dictGroupes[nomCondition]['LISTE'])):
294 conditionLimite = ET.SubElement(ConditionsLimitesChamps, "conditionLimitesChamps")
295 Type=ET.SubElement(conditionLimite,"type" )
296 Type.text=self.dictGroupes[nomCondition]["CONDITION_LIMITE"]
297 GroupeNoeud=ET.SubElement(conditionLimite, "groupeNoeud")
298 GroupeNoeud.text="%s" %(self.dictGroupes[nomCondition]['LISTE'][i])
300 conditionLimite = ET.SubElement(ConditionsLimitesChamps, "conditionLimitesChamps")
301 Type=ET.SubElement(conditionLimite,"type" )
302 Type.text=self.dictGroupes[nomCondition]["CONDITION_LIMITE"]
303 GroupeNoeud=ET.SubElement(conditionLimite, "groupeNoeud")
304 GroupeNoeud.text="%s" %(nomCondition)
306 for i in range(len(self.listSymetrie)): # symétries, définies dans le bloc des conditions aux limites
307 conditionLimite = ET.SubElement(ConditionsLimitesChamps, "conditionLimitesChamp")
308 Type=ET.SubElement(conditionLimite,"type" )
309 Type.text="%s" %(self.listSymetrie[i]["Type"])
310 GroupeNoeud=ET.SubElement(conditionLimite, "groupeNoeud")
311 GroupeNoeud.text="%s" %(self.listSymetrie[i]["Face1"])
312 if 'Face2' in self.listSymetrie[i] :
313 GroupeNoeud2=ET.SubElement(conditionLimite, "groupeNoeud2")
314 GroupeNoeud2.text="%s" %(self.listSymetrie[i]["Face2"])
315 if 'Mouvement_associe' in self.listSymetrie[i]:
316 MouvementAssocie=ET.SubElement(conditionLimite, "mouvementAssocie")
317 nomMouvementAssocie = self.listSymetrie[i]['Mouvement_associe'].nom # on récupère le nom du mouvement associé, car on a stocké le concept tout entier
318 MouvementAssocie.text="%i"%(self.dictMouvement[nomMouvementAssocie]['ordre'], )
319 if 'Groupe_Points' in self.listSymetrie[i] :
320 GroupePoints=ET.SubElement(conditionLimite, "groupePoints")
321 GroupePoints.text="%s" %(self.listSymetrie[i]['Groupe_Points'])
323 #Bloc <TermeSourceElectrique>...</TermeSourceElectrique>
324 TermeSourceElectrique=ET.SubElement(root, "TermeSourceElectrique")
326 if self.debug: print 'self.dictSource = ', self.dictSource
327 for source in self.dictSource.keys(): # parcours des sources
328 if len(self.dictSource[source]['milieux']) > 0: # on continue si au moins un groupe de maillage, i.e., milieux est associé à cette source
329 if self.dictSource[source].has_key('STRANDED_INDUCTOR'): # inducteur bobiné
330 inducteur=ET.SubElement(TermeSourceElectrique, "inducteur")
331 listeMilieux=ET.SubElement(inducteur, "listeMilieux") # création de la liste des milieux
332 idListeMilieux = [] # indices des milieux concernés
333 for milieu in self.dictSource[source]['milieux']: # construction de la liste des milieux
334 idListeMilieux.append(self.dictGroupes[milieu]['idMilieu'])
335 listeMilieux.text = "%s" % ','.join(map(str,idListeMilieux))
336 if self.dictSource[source]["STRANDED_INDUCTOR"]["TYPE"]=="CURRENT": # source de type courant imposé
337 couplageTension=ET.SubElement(inducteur, "couplageTension")
338 couplageTension.text = "false"
339 courant=ET.SubElement(inducteur, "courant")
340 if self.dictSource[source]["Signal"]=="WAVEFORM_CONSTANT":
341 courant.text="%g" %(self.dictSource[source]["WAVEFORM_CONSTANT"]["AMPLITUDE"])
342 if self.dictSource[source]["Signal"]=="WAVEFORM_SINUS": # écriture des 3 paramètres avec attribut spécial
343 amplitude = self.dictSource[source]["WAVEFORM_SINUS"]["AMPLITUDE"]
344 frequence = self.dictSource[source]["WAVEFORM_SINUS"]["FREQUENCY"]
345 phase = self.dictSource[source]["WAVEFORM_SINUS"]["PHASE"]
346 courant.text="%g, %g, %g" % (amplitude, frequence, phase)
347 courant.set('forme', 'sinus') # attribut forme="sinus"
348 if self.dictSource[source]["STRANDED_INDUCTOR"]["TYPE"]=="VOLTAGE": # source de type tension imposée
349 couplageTension=ET.SubElement(inducteur, "couplageTension")
350 couplageTension.text = "true"
351 tension=ET.SubElement(inducteur, "tension")
352 if self.dictSource[source]["Signal"]=="WAVEFORM_CONSTANT":
353 tension.text="%g" %(self.dictSource[source]["WAVEFORM_CONSTANT"]["AMPLITUDE"])
354 if self.dictSource[source]["Signal"]=="WAVEFORM_SINUS": # écriture des 3 paramètres avec attribut spécial
355 amplitude = self.dictSource[source]["WAVEFORM_SINUS"]["AMPLITUDE"]
356 frequence = self.dictSource[source]["WAVEFORM_SINUS"]["FREQUENCY"]
357 phase = self.dictSource[source]["WAVEFORM_SINUS"]["PHASE"]
358 tension.text="%g, %g, %g" % (amplitude, frequence, phase)
359 tension.set('forme', 'sinus') # attribut forme="sinus"
360 if self.dictSource[source]["STRANDED_INDUCTOR"].has_key('Resistance'):
361 resistance=ET.SubElement(inducteur, "resistance")
362 resistance.text="%g" %(self.dictSource[source]["STRANDED_INDUCTOR"]['Resistance'])
364 #definir Terme Source Magnetique
365 #definirTermeSourceMagnetique=ET.SubElement(root, "definirTermeSourceMagnetique")
366 #nombreTermeSourceMagnetique=ET.SubElement(definirTermeSourceMagnetique, "nombreTermeSourceMagnetique")
367 #nombreTermeSourceMagnetique.text="0"
370 #definirAimants=ET.SubElement(root, "definirAimants")
371 #nombreAimants=ET.SubElement(definirAimants, "nombreAimants")
372 #nombreAimants.text="0"
374 #Bloc <Mouvements>...</Mouvements>
376 Mouvements=ET.SubElement(root, "Mouvements")
377 for nom in self.dictMouvement['ordre']: # parcours de la liste des noms de mouvement définis, dans l'ordre
379 mouvement = ET.SubElement(Mouvements, "mouvement") # création de ce mouvement
380 mouvement.set("id", "%g" % (i, ) ) # ajout de l'attribut id, inutilisé
381 mouvement.set("name", nom ) # ajout de l'attribut name, inutilisé
382 milieuGlissement = ET.SubElement(mouvement, "milieuGlissement")
383 nomMilieuGlissement = self.dictMouvement[nom]['valeurs']['Milieu_glissement'].nom # concept stocké -> nom du concept
384 milieuGlissement.text="%i" % (self.dictGroupes[nomMilieuGlissement]['idMilieu'], ) # numéro du milieu défini par son nom, selon tableaux remplis précédemment
385 surfaceGlissement = ET.SubElement(mouvement, "surfaceGlissement")
386 surfaceGlissement.text= self.dictMouvement[nom]['valeurs']['Surface_glissement'].nom # concept stocké -> nom du concept
387 deltaMaillage = ET.SubElement(mouvement, "deltaMaillage")
388 deltaMaillage.text="%g" % (self.dictMouvement[nom]['valeurs']['Delta_maillage'], )
389 nbPermutPas = ET.SubElement(mouvement, "nbPermutPas")
390 nbPermutPas.text="%i" % (self.dictMouvement[nom]['valeurs']['Nombre_pas_permutation'], )
391 axeRotation = ET.SubElement(mouvement, "axeRotation")
392 axeRotation.text= self.dictMouvement[nom]['valeurs']['Axe_rotation']
394 #definir Force Couple
395 #definirForceCouple=ET.SubElement(root, "definirForceCouple")
396 #nombreForceCouple=ET.SubElement(definirForceCouple, "nombreForceCouple")
397 #nombreForceCouple.text="0"
399 #bloc <SpiresExploratrices></SpiresExploratrices>
400 i = 0 # compteur de spires
401 spiresExploratrices = False # pas de spires exploratrices a priori
402 for nom in self.dictGroupes.keys(): # recherche des spires exploratrices définies dans les MESHGROUP
403 if self.dictGroupes[nom].has_key('Spire_Exploratrice'):
404 spiresExploratrices = True
405 if spiresExploratrices: # on a trouvé au moins une spire exploratrice
406 SpiresExploratrices=ET.SubElement(root, "SpiresExploratrices") # création du bloc XML adéquat
407 for nom in self.dictGroupes.keys(): # recherche des spires exploratrices définies dans les MESHGROUP
408 if self.dictGroupes[nom].has_key('Spire_Exploratrice'):
409 spire = ET.SubElement(SpiresExploratrices, "spireExploratrice") # création du bloc XML pour cette spire
410 spire.text = nom # le nom du groupe de noeud est directement écrit
411 i = i+1 # incrément du numéro de spire
412 spire.set("id", "%g" % (i, ) ) # ajout de l'attribut id, inutilisé
413 spire.set("name", "%s" % (nom, ) ) # ajout de l'attribut name, inutilisé
415 #bloc <PotentielsFlottants></PotentielsFlottants>
416 i = 0 # compteur de potentiels flottants
417 potentielsFlottants = False # pas de potentiel flottant a priori
418 for nom in self.dictGroupes.keys(): # recherche des potentiels flottants définis dans les MESHGROUP
419 if self.dictGroupes[nom].has_key('Potentiel_Flottant'):
420 potentielsFlottants = True
421 if potentielsFlottants: # on a trouvé au moins un potentiel flottant
422 PotentielsFlottants=ET.SubElement(root, "PotentielsFlottants") # création du bloc XML adéquat
423 for nom in self.dictGroupes.keys(): # recherche des potentiels flottants définis dans les MESHGROUP
424 if self.dictGroupes[nom].has_key('Potentiel_Flottant'):
425 potentielFlottant = ET.SubElement(PotentielsFlottants, "potentielFlottant") # création du bloc XML pour ce potentiel flottant
426 potentielFlottant.text = nom # le nom du groupe de noeud est directement écrit
427 i = i+1 # incrément du numéro de spire
428 potentielFlottant.set("id", "%g" % (i, ) ) # ajout de l'attribut id, inutilisé
429 potentielFlottant.set("name", "%s" % (nom, ) ) # ajout de l'attribut name, inutilisé
432 #Definir Post traitement
433 postraitement=ET.SubElement(root, "postraitement")
434 # Ecriture des cartes de champ
435 carteChamp=ET.SubElement(postraitement, "carteChamp")
436 if type(self.carteChamp)==float:
437 carteChamp.text="%s" %(self.carteChamp)
439 carteChamp.text="%s" % ','.join(map(str,self.carteChamp))
440 # Ecriture des cartes de courants induits
441 carteCourantInduit=ET.SubElement(postraitement, "carteCourantInduit")
442 if type(self.carteCourantInduit)==float:
443 carteCourantInduit.text="%s" %(self.carteCourantInduit)
445 carteCourantInduit.text="%s" % ','.join(map(str,self.carteCourantInduit))
446 # Ecriture des cartes de force
447 carteForce=ET.SubElement(postraitement, "carteForce")
448 if type(self.carteForce)==float:
449 carteForce.text="%s" %(self.carteForce)
451 carteForce.text="%s" % ','.join(map(str,self.carteForce))
452 # Sortie des grandeurs globales, enregistrées dans self.post_global
453 # liste de correspondance entre la valeur du catalogue et le nom de la balise XML
454 # sous forme ordonnée (nomXML, valeur catalogue)
455 correspondance_global = (('energie', "Energie"),\
456 ('perteJoule', "Pertes Joules"),\
457 ('fluxInducteur', "Flux par inducteur"),\
458 ('courantInducteur', "Courants par inducteur"),\
459 ('tensionInducteur', "Tensions par inducteur"), \
460 ('forceCouple', "Force et couple"),\
461 ('fluxSpire', "Flux par spire exploratrice"),\
462 ('fluxGroupe', "Flux par groupe"),\
463 ('ddpElect', "Tensions electriques"),\
464 ('ddpMagn', "DDP magnetiques"), \
465 ('fluxMagn', "Flux magnetiques"),\
466 ('fluxJinduitTotal', "Flux J induit"),\
467 ('potFlottant', "Potentiel flottant"))
468 # Sortie des grandeurs demandées seulement (true)
469 for table in correspondance_global:
470 if table[1] in self.post_global:
471 post_global_item=ET.SubElement(postraitement, table[0])
472 post_global_item.text = "true"
473 # # Sortie de toutes les grandeurs possibles, avec la valeur true pour celles demandées et false sinon
474 # for table in correspondance_global:
475 # post_global_item=ET.SubElement(postraitement, table[0])
476 # if table[1] in self.post_global:
477 # post_global_item.text = "true"
479 # post_global_item.text = "false"
481 self.indent(root) # indentations et retours à la ligne, à l'aide d'une fonction maison, car xml.etree.ElementTree ne sait pas faire et le module lxml n'est pas disponible dans Salomé
483 tree = ET.ElementTree(root)
485 tree.write(fileXML, encoding="UTF-8")
487 # print "le dico complet=%s" %(self.dictGroupes)
490 print "ecriture du fichier d'execution (SH)"
491 RepCarmel=os.path.join(repertory,"lancer.sh")
492 f = open( RepCarmel, 'wb')
493 self.texteCarmel3D_SH+='cd ' + repertory + ' \n'
494 self.texteCarmel3D_SH+='./carmel << FIN\n'
495 correspondance_resolution = {"(T-)Omega seulement":"1\n","A(-Phi) seulement":"2\n", "(T-)Omega puis A(-Phi)":"1\n2\n", "A(-Phi) puis (T-)Omega":"2\n1\n"}
496 self.texteCarmel3D_SH+= correspondance_resolution[self.formulation]
497 self.texteCarmel3D_SH+='0\nFIN\n'
498 f.write(self.texteCarmel3D_SH)
502 #----------------------------------------------------------------------------------------
503 # analyse de chaque noeud de l'arbre
504 #----------------------------------------------------------------------------------------
506 def generMCSIMP(self,obj) :
507 """recuperation de l objet MCSIMP"""
509 print "MCSIMP %(v_1)s %(v_2)s" % {'v_1': obj.nom, "v_2": obj.valeur}
510 s=PythonGenerator.generMCSIMP(self,obj)
512 self.dicoCourant[obj.nom]=obj.valeurFormatee
514 print "Oubli des messages texte homo='information'"
518 #----------------------------------------------------------------------------------------
519 def generMCFACT(self,obj) :
520 """recuperation de l objet MCFACT"""
522 self.dicoMCFACTCourant=dico
523 self.dicoCourant=self.dicoMCFACTCourant
524 s=PythonGenerator.generMCFACT(self,obj)
525 self.dicoEtapeCourant[obj.nom]=self.dicoMCFACTCourant
526 self.dicoMCFACTCourant=None
527 self.dicoCourant=self.dicoEtapeCourant
531 #----------------------------------------------------------------------------------------
532 def generPROC_ETAPE(self,obj):
533 """analyse des PROC du catalogue ( VERSION )"""
535 self.dicoEtapeCourant=dico
536 self.dicoCourant=self.dicoEtapeCourant
537 s=PythonGenerator.generPROC_ETAPE(self,obj)
538 obj.valeur=self.dicoEtapeCourant
541 print "PROC_ETAPE %(v_1)s %(v_2)s" % {'v_1': unicode(obj.nom), "v_2": unicode(obj.valeur)}
542 s=PythonGenerator.generPROC_ETAPE(self,obj)
543 if obj.nom=="PARAMETERS" : self.generBLOC_PARAMETERS(obj)
544 if obj.nom=="SOLVEUR" : self.generSOLVEUR(obj)
545 if obj.nom=="SYMETRIE" : self.generBLOC_SYMETRIE(obj)
546 if obj.nom=="POST_TRAITEMENT" : self.generPOST_TRAITEMENT(obj)
551 #----------------------------------------------------------------------------------------
552 def generETAPE(self,obj):
553 """analyse des OPER du catalogue"""
555 self.dicoEtapeCourant=dico
556 self.dicoCourant=self.dicoEtapeCourant
557 s=PythonGenerator.generETAPE(self,obj)
558 obj.valeur=self.dicoEtapeCourant
560 print "ETAPE : obj.nom = %(v_1)s , obj.valeur= %(v_2)s" % {'v_1': obj.nom, 'v_2': obj.valeur}
561 if obj.nom=="MESHGROUP" : self.generMESHGROUP(obj)
562 if obj.nom=="MATERIAL" : self.generMATERIAL(obj)
563 if obj.nom=="SOURCE" : self.generSOURCE(obj)
564 if obj.nom=="STRANDED_INDUCTOR_GEOMETRY" : self.generSTRANDED_INDUCTOR_GEOMETRY(obj)
565 if obj.nom=="MACRO_GROUPE": self.generMACRO_GROUPE(obj)
566 if obj.nom=="MOUVEMENT" : self.generMOUVEMENT(obj)
567 s=PythonGenerator.generETAPE(self,obj)
570 #----------------------------------------------------------------------------------------
571 def generMACRO_ETAPE(self,obj):
572 """Utilisé par INCLUDE"""
574 self.dicoEtapeCourant=dico
575 self.dicoCourant=self.dicoEtapeCourant
577 monGenerateur=generator.plugins[nomPlugin]()
578 jdc_aux_texte=monGenerateur.gener(obj.jdc_aux)
580 print "jdc_aux_texte : %s" % jdc_aux_texte
582 # sauvegarde de tous les matériaux trouvés dans les bibliothèques INCLUDE
583 for cle in monGenerateur.dictMaterial:
584 self.dictMaterial[cle] = monGenerateur.dictMaterial[cle]
585 # sauvegarde de toutes les sources trouvées dans les bibliothèques INCLUDE
586 for cle in monGenerateur.dictSource:
587 self.dictSource[cle] = monGenerateur.dictSource[cle]
589 print "________FIN MACRO______________________________________"
590 s=PythonGenerator.generMACRO_ETAPE(self,obj)
593 #----------------------------------------------------------------------------------------
594 #----------------------------------------------------------------------------------------
595 def generMESHGROUP(self,obj):
596 """preparation de la ligne NAME referencant le groupe de mailles
597 associe le groupe de mailles au materiau ou a la source utilisateur
598 on sauvegarde aussi les noms des groupes de maillage
601 nomGroupe = obj.get_sdname() # nom du groupe de maillage, i.e. nom du concept
602 print "liste des noms sans prefixes %s" %(nomGroupe)
604 # test: un et un seul nom de materiau ou source doit etre associe a ce groupe de maillage, via les cles MATERIAL et SOURCE, respectivement.
605 # test sur un seul attribut, non pertinent car il peut y en avoir plusieurs.
606 #assert len(obj.valeur.keys())==1,"Un et un seul nom de materiau ou source doit etre associe a ce groupe du maillage :"+nomGroupe
608 # on utilise le fait que obj.valeur est un dictionnaire
609 self.dictGroupes[nomGroupe] = {}
611 print "obj.valeur.keys()= %s" % obj.valeur.keys()
612 #if 'MATERIAL' in obj.valeur.keys() and 'SOURCE' in obj.valeur.keys(): # test d'erreur lors de presence de materiau et source a la fois
613 # raise ValueError,tr(" ce groupe de maillage %s est associe a au moins un materiau et au moins une source." % nomGroupe)
614 # association a un materiau
615 if 'MATERIAL' in obj.valeur.keys():
616 self.dictGroupes[nomGroupe]['MATERIAL'] = obj.valeur['MATERIAL'].nom # sauvegarde de l'association entre ce groupe de maillage et un materiau ou source, par son nom, i.e. nom du concept du materiau ou de la source
617 # self.dictGroupes['ordreMateriauxJdC'].append(nomGroupe) # sauvegarde du nom du groupe de maillage associe a un materiau, dans l'ordre du JdC
618 # association a une source
619 if 'SOURCE' in obj.valeur.keys():
620 self.dictGroupes[nomGroupe]['SOURCE'] = obj.valeur['SOURCE'].nom # sauvegarde de l'association entre ce groupe de maillage et un materiau ou source, par son nom, i.e. nom du concept du materiau ou de la source
621 # self.dictGroupes['ordreSourcesJdC'].append(nomGroupe) # sauvegarde du nom du groupe de maillage associe a une source, dans l'ordre du JdC
622 # erreur ni materiau ni source associee
623 if 'STRANDED_INDUCTOR_GEOMETRY' in obj.valeur.keys():
624 self.dictGroupes[nomGroupe]['STRANDED_INDUCTOR_GEOMETRY'] = obj.valeur['STRANDED_INDUCTOR_GEOMETRY'].nom # sauvegarde de l'association entre ce groupe de maillage et un materiau ou source, par son nom, i.e. nom du concept du materiau ou de la source
625 # self.dictGroupes['ordreStrandJdC'].append(nomGroupe) # sauvegarde du nom du groupe de maillage associe a une source, dans l'ordre du JdC
626 if 'CONDITION_LIMITE' in obj.valeur.keys():
627 self.dictGroupes[nomGroupe]['CONDITION_LIMITE'] = obj.valeur['CONDITION_LIMITE']
628 # self.dictGroupes['ordreConditionJdC'].append(nomGroupe)
629 if 'Domaine' in obj.valeur.keys():
630 self.dictGroupes[nomGroupe]['DOMAINE'] = obj.valeur['Domaine']
631 # self.dictGroupes['ordreDomaineJdC'].append(nomGroupe)
633 texte+="%s"%(obj.valeur['Domaine'])
634 print"le texte=%s" %(texte)
635 self.dictDomaine[obj.get_sdname()]=texte
636 print "liste des domaines =%s" %(self.dictGroupes[nomGroupe]['DOMAINE'])
637 if 'Potentiel_Flottant' in obj.valeur.keys():
638 self.dictGroupes[nomGroupe]['Potentiel_Flottant'] = True
639 if 'Spire_Exploratrice' in obj.valeur.keys():
640 self.dictGroupes[nomGroupe]['Spire_Exploratrice'] = True
643 # raise ValueError, tr("ce groupe de maillage %s n'est associe a aucun materiau, source ou stranded_inductor_geometry." % nomGroupe)
645 print "self.dictGroupes= %s" % repr(self.dictGroupes)
646 except ValueError, err:
647 raise ValueError, str(err)
649 def generMACRO_GROUPE(self, obj):
650 """preparation de la ligne NAME referencant le groupe de mailles
651 associe le groupe de mailles au materiau ou a la source utilisateur
652 on sauvegarde aussi les noms des macros groupes
655 nomMacroGroupe = obj.get_sdname() # nom du macro groupe
656 print "liste des noms sans prefixes %s" %(nomMacroGroupe)
657 self.dictMacroGroupes[nomMacroGroupe] = obj.valeur # sauvegarde des propriétés du macro-groupe
660 print "obj.valeur.keys()= %s" % obj.valeur.keys()
661 # association a une source
662 if 'LISTE_MESHGROUP' in obj.valeur.keys(): # test de liste définie dans la macro-groupe, sinon erreur
663 listeGroupesMauvaisFormat = obj.valeur['LISTE_MESHGROUP'] # sauvegarde de l'association entre ce macro groupe et un materiau ou source, par son nom, i.e. nom du concept du materiau ou de la source
664 self.dictMacroGroupes[nomMacroGroupe]['LISTE'] = [] # sauvegarde de l'association entre ce macro groupe et un materiau ou source, par son nom, i.e. nom du concept du materiau ou de la source
665 for groupe in listeGroupesMauvaisFormat: # sauvegarde de la liste au format correct
666 groupe = groupe.replace("'", "") # suppression des guillement simples
667 groupe = groupe.replace('"', "") # suppression des guillement doubles
668 self.dictMacroGroupes[nomMacroGroupe]['LISTE'].append(groupe) # sauvegarde du nom au formatage correct
670 raise ValueError, nomMacroGroupe + tr(" : ce MACRO_GROUPE doit contenir une liste de groupes LISTE_MESHGROUP.")
672 for nomGroupe in self.dictMacroGroupes[nomMacroGroupe]['LISTE']: # liste des groupes MESHGROUP de ce macro-groupe. On leur associe les propriétés du MACRO_GROUPE
673 for propriete in ('SOURCE', 'MATERIAL', 'STRANDED_INDUCTOR_GEOMETRY'): # liste des propriétés automatiques à copier du MACRO_GROUPE à chaque MESHGROUP de la liste
674 if propriete in obj.valeur.keys(): # ce macro-groupe est associé à cette propriété
675 if self.dictGroupes[nomGroupe].has_key(propriete) and self.dictGroupes[nomGroupe][propriete] != self.dictGroupes[nomGroupe][propriete].nom: # erreur, ce meshgroup a déjà une telle propriéte définie, différente
676 print u"ERREUR! Conflit entre la %s : %s du MACRO_GROUPE %s et celle : %s du MESHGROUP %s associé à ce macro-groupe." % \
677 ( propriete, obj.valeur[propriete].nom, nomMacroGroupe, self.dictGroupes[nomGroupe][propriete], nomGroupe )
678 raise ValueError, propriete + ',' + obj.valeur[propriete].nom + ',' + nomMacroGroupe + ',' + self.dictGroupes[nomGroupe][propriete] + ',' + nomGroupe\
679 + tr(" : conflit entre la propriete (#1:#2) du MACRO_GROUPE (de nom #3) et celle (#4) du MESHGROUP (#5) associe a ce macro-groupe.")
680 else : # pas de conflit de cette propriété, alors copie, meme si les propriétés sont les memes pour simplifier
681 self.dictGroupes[nomGroupe][propriete] = obj.valeur[propriete].nom # sauvegarde du nom de la propriété du macro-groupe dans le meshgroup
682 for propriete in ('CONDITION_LIMITE', ): # liste des propriétés définies à l'avance automatiques à copier du MACRO_GROUPE à chaque MESHGROUP de la liste
683 if propriete in obj.valeur.keys(): # ce macro-groupe est associé à cette propriété
684 if self.dictGroupes[nomGroupe].has_key(propriete) and self.dictGroupes[nomGroupe][propriete] != self.dictGroupes[nomGroupe][propriete]: # erreur, ce meshgroup a déjà une telle propriéte définie, différente
685 print u"ERREUR! Conflit entre la %s : %s du MACRO_GROUPE %s et celle : %s du MESHGROUP %s associé à ce macro-groupe." % \
686 ( propriete, obj.valeur[propriete], nomMacroGroupe, self.dictGroupes[nomGroupe][propriete], nomGroupe )
687 raise ValueError, propriete + ',' + obj.valeur[propriete].nom + ',' + nomMacroGroupe + ',' + self.dictGroupes[nomGroupe][propriete] + ',' + nomGroupe\
688 + tr(" : conflit entre la propriete (#1:#2) du MACRO_GROUPE (de nom #3) et celle (#4) du MESHGROUP (#5) associe a ce macro-groupe.")
689 else : # pas de conflit de cette propriété, alors copie, meme si les propriétés sont les memes pour simplifier
690 self.dictGroupes[nomGroupe][propriete] = obj.valeur[propriete] # sauvegarde du nom de la propriété du macro-groupe dans le meshgroup
691 except ValueError, err:
692 raise ValueError, str(err)
695 def generSOLVEUR(self, obj):
697 print "generation solveur obj.valeur = %s" % obj.valeur
699 self.typeSolveur = obj.valeur['Type']
700 if self.typeSolveur == "Solveur_lineaire" : self.generSOLVEUR_LINEAIRE(obj)
701 if self.typeSolveur == "Solveur_non_lineaire" :
702 self.generSOLVEUR_LINEAIRE(obj)
703 self.generSOLVEUR_NON_LINEAIRE(obj)
704 except ValueError, err:
705 raise ValueError, str(err)
707 def generSOLVEUR_LINEAIRE(self, obj):
709 print "generation material obj.valeur = %s" % obj.valeur
711 nature = obj.valeur['Methode_lineaire']
712 if nature =="Methode iterative BICGCR" : self.generMETHODE_ITERATIVE_BICGCR(obj)
713 if nature =="Methode directe MUMPS" : self.generMETHODE_DIRECTE_MUMPS(obj)
714 except ValueError, err:
715 raise ValueError, str(err)
717 def generMETHODE_ITERATIVE_BICGCR(self, obj):
719 print "generation methode iterative BICGCR obj.valeur = %s" % obj.valeur
720 self.kEpsilonGCP = obj.valeur["Precision"]
721 self.precond=obj.valeur["Preconditionneur"]
722 self.nbIterationMax=obj.valeur["Nombre_iterations_max"]
725 def generMETHODE_DIRECTE_MUMPS(self, obj):
728 print "_____________directe_____________"
730 def generSOLVEUR_NON_LINEAIRE(self, obj):
732 print "generation solveur_non_lineaire obj.valeur = %s" % obj.valeur
733 correspondance_methodeNonLineaire = {"Methode de Newton":2,"Methode de substitution":1} # correspondance sur la méthode non-linéaire entre le catalogue et le XML
734 self.methodeNonLineaire = correspondance_methodeNonLineaire[obj.valeur["Methode_non_lineaire"]]
735 self.kEpsilonNonLinearite=obj.valeur["PrecisionNonLineaire"]
736 self.kCoefficientRelaxation=obj.valeur["Coefficient_de_Relaxation"]
738 def generMATERIAL(self,obj):
739 """preparation du bloc correspondant a un materiau du fichier PHYS"""
742 print "generation material obj.valeur = %s" % obj.valeur
744 nomMaterial = obj.get_sdname()
745 self.dictMaterial[nomMaterial]=obj.valeur
746 print"self.dictMaterial=%s" %(self.dictMaterial)
747 except ValueError, err:
748 raise ValueError, str(err)
749 #-------------------------------------------------------------------
751 def generSOURCE(self,obj):
752 """preparation du bloc correspondant a une source du fichier PHYS"""
754 print "generation source obj valeur = %s" % obj.valeur
757 nomSource = obj.get_sdname()
758 self.dictSource[nomSource]=obj.valeur # dictionnaire
759 self.dictSource[nomSource]['milieux'] = [] # liste ordonnée des groupes associés à cette source
760 print"mon dico des sources=%s" %(self.dictSource)
761 except ValueError, err:
762 raise ValueError, str(err)
764 #---------------------------------------------------------------------------------------
765 # traitement fichier PHYS
766 #---------------------------------------------------------------------------------------
767 def generBLOC_VERSION(self,obj) :
768 # constitution du bloc VERSION du fichier PHYS
769 # creation d une entite VERSION ; elle sera du type PROC car decrit ainsi
770 # dans le du catalogue
771 version=obj.addentite('VERSION',pos=None)
772 self.generPROC_ETAPE(obj.etapes[0])
773 self.texteCarmel3D+="["+obj.etapes[0].nom+"\n"
774 for cle in obj.etapes[0].valeur :
775 self.texteCarmel3D+=" "+cle+" "+str(obj.etapes[0].valeur[cle])+"\n"
776 self.texteCarmel3D+="]\n"
777 # destruction de l entite creee
778 obj.suppentite(version)
779 #print 'ERREUR : test erreur boite graphique BLOC_VERSION'
780 #raise ValueError, 'test erreur boite graphique BLOC_VERSION'
783 def generBLOC_PARAMETERS(self,obj):
785 print "generation parameters obj.valeur = %s" % obj.valeur
787 self.identification = obj.valeur["Identification_du_Modele"]
788 self.fichierMaillage = obj.valeur["Fichier_maillage"]
789 self.echelleMaillage = obj.valeur["Echelle_du_maillage"]
791 self.kEpsilonDistance=obj.valeur["kEpsilonDistance"]
792 self.kdistanceRef=obj.valeur["kdistanceRef"]
793 self.jauge=obj.valeur["Jauge"]
794 self.NBoucleTemps=obj.valeur["Nb_pas_de_temps"]
795 self.dt=obj.valeur["Pas_de_temps"]
797 self.repertory=obj.valeur["RepCarmel"]
798 self.fcarmel=obj.valeur["Resoudre_probleme"]
799 self.postprocess=obj.valeur["Realiser_post_traitement_aposteriori"]
800 self.formulation=obj.valeur["Formulation"]
802 def generBLOC_SYMETRIE(self, obj):
804 print "generation de la symetrie obj.valeur = %s" % obj.valeur
807 self.listSymetrie.append(obj.valeur)
808 print"ma liste symetrie =%s" %(self.listSymetrie)
809 except ValueError, err:
810 raise ValueError, str(err)
811 #----------------------------------------------------------------------------------------
813 def generMOUVEMENT(self, obj):
815 print "generation du mouvement obj.valeur = %s" % obj.valeur
818 nom = obj.get_sdname()
819 self.nombreMouvements = self.nombreMouvements+1
820 self.dictMouvement[nom] = {'ordre': self.nombreMouvements, 'valeurs': obj.valeur}
821 self.dictMouvement['ordre'].append(nom)
823 print "self.dictMouvement =%s" %(self.dictMouvement)
824 print "self.nombreMouvements =%i" %(self.nombreMouvements)
825 except ValueError, err:
826 raise valueError, str(err)
827 #----------------------------------------------------------------------------------------
828 def generSTRANDED_INDUCTOR_GEOMETRY(self, obj):
829 """preparation du bloc STRANDED_INDUCTOR_GEOMETRY"""
831 print "generation strand obj valeur = %s" % obj.valeur
833 nomStrand = obj.get_sdname()
834 self.dictStrand[nomStrand]=obj.valeur
835 print"mon dico des stranded inductor geometry=%s" %(self.dictStrand)
837 except ValueError, err:
838 raise ValueError, str(err)
840 def generPOST_TRAITEMENT(self, obj):
842 print "generation post traitement obj.valeur = %s" % obj.valeur
843 self.carteChamp=obj.valeur["Cartes_des_champs"]
844 self.carteCourantInduit=obj.valeur["Cartes_des_courants_induits"]
845 self.carteForce=obj.valeur["Cartes_des_forces"]
846 if obj.valeur.has_key('GLOBAL'):
847 self.post_global = obj.valeur['GLOBAL']
848 # sauvegarde de la liste au format correct, en supprimant les guillemets simples et doubles extra générés par Eficas
849 # car Eficas génère une liste ["'Energie'","'Flux par inducteur'","'Force et couple'"] enrichie
850 # à partir de l'instruction .comm correctement formatée : GLOBAL=('Energie','Flux par inducteur','Force et couple',)
851 for i in range(len(self.post_global)):
852 self.post_global[i] = self.post_global[i].replace("'", "") # suppression des guillement simples
853 self.post_global[i] = self.post_global[i].replace('"', "") # suppression des guillement doubles
855 #-------------------------------------
856 # Methodes utilitaires
857 # ------------------------------------
858 def formateCOMPLEX(self,nbC):
859 """prise en compte des differentes formes de description d un nombre complexe
860 3 formats possibles : 2 listes (anciennement tuples?) et 1 nombre complexe
864 print "type : %(type_nb_c)s pour %(nb_c)s" % {'type_nb_c': type(nbC), 'nb_c': nbC}
866 if isinstance(nbC,(tuple,list)):
867 if nbC[0] == "'RI'" :
868 nbformate = "COMPLEX " + str(nbC[1])+" "+str(nbC[2])
869 if nbC[0] == "'MP'" :
870 nbformate = "POLAR " + str(nbC[1])+" "+str(nbC[2])
872 nbformate = "COMPLEX " + str(nbC.real)+" "+str(nbC.imag)
874 print "nbformate : %s" % nbformate