1 #@ MODIF macr_recal_ops Macro DATE 14/11/2006 AUTEUR ASSIRE A.ASSIRE
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2002 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
22 import os, sys, types, copy, math
33 type_fonctionnelle = 'float'
35 # --------------------------------------------------------------------------------------------------
36 def UTMESS(code,sprg,texte):
37 fmt='\n <%s> <%s> %s\n\n'
38 if INFO>0 or code=='F': print fmt % (code,sprg,texte)
43 # --------------------------------------------------------------------------------------------------
44 def Ecriture_Fonctionnelle(output_file, type_fonctionnelle, fonctionnelle):
46 try: os.remove(output_file)
49 f=open(output_file, 'w')
50 if type_fonctionnelle == 'vector':
51 fonctionnelle = str(fonctionnelle.tolist())
52 fonctionnelle = fonctionnelle.replace('[','')
53 fonctionnelle = fonctionnelle.replace(']','')
54 f.write(str(fonctionnelle))
58 # --------------------------------------------------------------------------------------------------
59 def Ecriture_Derivees(output_file, derivees):
61 try: os.remove(output_file)
64 # On sort si il n'y a pas de derivees a imprimer
65 if not derivees: return
69 for l in range(len(a[:,0])):
71 for c in range(len(a[0,:])):
72 ligne.append( str(a[l,c]) )
73 txt += ','.join(ligne) + '\n'
75 f=open(output_file, 'w')
80 # --------------------------------------------------------------------------------------------------
81 def Sortie(LIST_NOM_PARA, LIST_PARA, val, CALCUL_ASTER, Mess):
82 """Sortie de la macro, on renvoit les parametres obtenus"""
84 import Cata, aster, Macro
85 from Cata.cata import DEFI_LIST_REEL
87 from Utilitai.Utmess import UTMESS
88 from Macro import reca_message
89 from Macro import reca_algo
90 from Macro import reca_interp
91 from Macro import reca_utilitaires
92 from Macro import reca_calcul_aster
93 from Macro.reca_controles import gestion
95 if CALCUL_ASTER.METHODE != 'EXTERNE':
96 txt = "Nombre d'evaluation de la fonction : " + str(CALCUL_ASTER.evaluation_fonction)
97 UTMESS('I','MACR_RECAL',txt)
100 LIST_NOM_PARA_ALPHA = [ para[0] for para in LIST_PARA ]
101 LIST_NOM_PARA_ALPHA.sort()
103 for i in LIST_NOM_PARA:
104 lival.append( val[ LIST_NOM_PARA_ALPHA.index(i) ] )
105 nomres = DEFI_LIST_REEL(VALE=lival)
110 # --------------------------------------------------------------------------------------------------
111 def macr_recal_externe( RESU_EXP, LIST_PARA, RESU_CALC, UNITE_ESCL=3, POIDS=None, LIST_DERIV=None,
112 ITER_MAXI=10, ITER_FONC_MAXI=100, RESI_GLOB_RELA=1.e-6, UNITE_RESU=91, PARA_DIFF_FINI=0.001,
113 GRAPHIQUE=None, SUIVI_ESCLAVE='NON', METHODE='EXTERNE', INFO=1, **args ):
119 GRAPHIQUE0 = {'INTERACTIF': 'NON', 'AFFICHAGE': 'TOUTE_ITERATION', 'UNITE': 90, 'FORMAT': 'XMGRACE'}
120 for k in GRAPHIQUE0.keys():
121 if not GRAPHIQUE.has_key(k): GRAPHIQUE[k] = GRAPHIQUE0[k]
123 if optparse_prefix_graph: args['prefix_graph'] = opts.prefix_graph
124 else: args['prefix_graph'] = os.getcwd() + os.sep + 'graph'
126 # Les parametres passes sur la ligne de commande surchargent les parametres de la commande MACR_RECAL
127 if optparse_INFO: INFO=opts.INFO
128 if optparse_follow_output:
129 if opts.follow_output == True: SUIVI_ESCLAVE='OUI'
130 else: SUIVI_ESCLAVE='NON'
132 if optparse_objective:
133 if type_fonctionnelle=='vector': args['FONCTIONNELLE']='VECTORIELLE'
134 else: args['FONCTIONNELLE']='SCALAIRE'
136 if optparse_gradient:
137 if opts.gradient=='normal': args['GRADIENT']='NORMAL'
138 elif opts.gradient=='adim': args['GRADIENT']='ADIMENSIONNE'
139 else: args['GRADIENT']='NON_CALCULE'
142 fonctionnelle, gradient = macr_recal(UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC,
143 ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA, UNITE_RESU, PARA_DIFF_FINI,
144 GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args )
146 return fonctionnelle, gradient
149 # --------------------------------------------------------------------------------------------------
150 def macr_recal_ops(self,UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC,
151 ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA,UNITE_RESU,PARA_DIFF_FINI,
152 GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args ):
153 """Macro commande realisant le recalage de modeles Aster"""
154 # Initialisation du compteur d'erreurs
159 from Cata import cata
160 from Cata.cata import DEFI_LIST_REEL, CREA_TABLE, TEST_TABLE
162 from Macro import reca_message
163 from Macro import reca_algo
164 from Macro import reca_interp
165 from Macro import reca_utilitaires
166 from Macro import reca_calcul_aster
167 from Macro.reca_controles import gestion
168 from Utilitai.Utmess import UTMESS
170 # Gestion des Exceptions
171 prev_onFatalError = aster.onFatalError()
172 aster.onFatalError('EXCEPTION')
174 # La macro compte pour 1 dans l'execution des commandes
178 self.DeclareOut('nomres',self.sd)
180 # Declaration de toutes les commandes Aster
181 for k,v in cata.__dict__.items() :
182 if type(v)==types.InstanceType:
183 if v.__class__.__name__ in ('OPER','MACRO'):
184 self.current_context[k]= v
185 self.current_context['_F']=cata.__dict__['_F']
187 macr_recal(UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC,
188 ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA,UNITE_RESU,PARA_DIFF_FINI,
189 GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args)
194 # --------------------------------------------------------------------------------------------------
195 def macr_recal(UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC,
196 ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA,UNITE_RESU,PARA_DIFF_FINI,
197 GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args ):
201 if os.environ.has_key('ASTER_ROOT'):
202 sys.path.append(os.path.join(os.environ['ASTER_ROOT'], 'ASTK', 'ASTK_SERV', 'lib'))
204 try: sys.path.append(os.path.join(aster.repout, '..', 'ASTK', 'ASTK_SERV', 'lib'))
207 from as_profil import ASTER_PROFIL
209 UTMESS('F','MACR_RECAL',"Impossible d'importer le module as_profil ! Vérifier la variable d'environnement ASTER_ROOT ou mettez a jour ASTK.")
211 import Macro, Utilitai
212 from Macro import reca_message
213 from Macro import reca_algo
214 from Macro import reca_interp
215 from Macro import reca_utilitaires
216 from Macro import reca_calcul_aster
217 from Macro.reca_controles import gestion
218 if( METHODE != 'EXTERNE'):
219 from Utilitai.optimize import fmin, line_search, line_search_BFGS, approx_fprime, approx_fhess_p, fminBFGS, fminNCG
221 if( METHODE == 'EXTERNE'):
225 dGRAPHIQUE=GRAPHIQUE[0].cree_dict_valeurs(GRAPHIQUE[0].mc_liste)
226 if dGRAPHIQUE.has_key('FORMAT') and dGRAPHIQUE['FORMAT'] == 'GNUPLOT':
227 # On essaie d'importer Gnuplot -> PAS DE GRAPHIQUE
232 if INFO>=1: UTMESS('A','MACR_RECAL',"Le logiciel Gnuplot ou le module python Gnuplot.py n'est pas disponible. On desactive l'affichage des courbes par Gnuplot.")
235 #_____________________________________________
237 # VERIFICATION PREALABLE SUR MEM_ASTER
238 #_____________________________________________
240 # Lecture du fichier .export
241 list_export = glob('*.export')
242 if len(list_export) == 0:
243 UTMESS('F','MACR_RECAL',"Probleme : il n'y a pas de fichier .export dans le repertoire de travail!")
244 elif len(list_export) >1:
245 UTMESS('F','MACR_RECAL',"Probleme : il y a plus d'un fichier .export dans le repertoire de travail!")
247 prof = ASTER_PROFIL(list_export[0])
249 mem_aster = prof['mem_aster'][0]
250 memjeveux = prof.args.get('memjeveux')
252 if mem_aster in ('', '100'):
253 if INFO>=1: UTMESS('A','MACR_RECAL',"Attention : il faut specifier une valeur pour 'mem_aster' (menu Option de ASTK) " \
254 "pour limiter la memoire allouee au calcul maitre.")
257 UTMESS('F','MACR_RECAL',"Probleme : aucune valeur pour le parametre 'memjeveux'. Verifier le .export")
261 memjeveux_esclave = float(memjeveux)
263 memjeveux_esclave = float(memjeveux) / float(mem_aster) * 100. - float(memjeveux)
265 UTMESS('F','MACR_RECAL',"Probleme : verifier les valeurs des parametres 'mem_aster' et 'memjeveux'")
267 if INFO>=1: UTMESS('I','MACR_RECAL',"Information : les calculs esclaves utiliseront : %.1f Mega Mots." % memjeveux_esclave)
270 #_____________________________________________
273 #_____________________________________________
275 # Liste des parametres utilisant la sensibilité
276 if not LIST_DERIV: LIST_DERIV = {}
277 LIST_SENSI = LIST_DERIV.keys()
279 # Stocke l'ordre initial des parametres pour restituer dans le bon ordre les valeurs en sortie de la macro
280 LIST_NOM_PARA = [ para[0] for para in LIST_PARA ]
282 # On classe les parametres
286 # Defini si on utilise le mot-clé SENSIBILITE pour IMPR_TABLE ou non
287 if len(LIST_SENSI) >0: table_sensibilite = True
288 else: table_sensibilite = False
290 # Defini si on ajoute l'echo des calculs esclaves dans le mess du calcul maitre
291 follow_output = False
292 if SUIVI_ESCLAVE and SUIVI_ESCLAVE=='OUI': follow_output = True
293 # if( METHODE == 'EXTERNE') and mode_python: follow_output = opts.follow_output
295 # Pour les algorithmes d'optimize, on a des limitations
296 if METHODE in ['FMIN', 'FMINBFGS', 'FMINNCG']:
297 # On ne peut tracer qu'a la derniere iteration
299 if GRAPHIQUE['AFFICHAGE']=='TOUTE_ITERATION': UTMESS('I','MACR_RECAL',"Pour l'algorithme " + METHODE + " on ne peut tracer qu'a la derniere iteration")
300 # Les bornes ne sont pas gerees
301 UTMESS('I','MACR_RECAL',"Pour l'algorithme " + METHODE + " on ne tient pas compte des bornes sur les parametres.")
303 #_______________________________________________
305 # GESTION DE L'OPTION FACULTATIVE POUR LES POIDS
306 #_______________________________________________
308 POIDS=Numeric.ones(len(RESU_EXP))
311 #_____________________________________________
313 # GESTION DES ERREURS DE SYNTAXE
314 #_____________________________________________
315 texte_erreur = gestion(UNITE_ESCL,LIST_PARA,RESU_CALC,RESU_EXP,POIDS,GRAPHIQUE,UNITE_RESU,METHODE)
316 if (texte_erreur != ""):
317 UTMESS('F', "MACR_RECAL", texte_erreur)
320 #_____________________________________________
323 #_____________________________________________
325 if( METHODE != 'EXTERNE'):
327 restant,temps_iter=0.,0.
328 restant,temps_iter,err=reca_utilitaires.temps_CPU(restant,temps_iter)
330 para,val,borne_inf,borne_sup = reca_utilitaires.transforme_list_Num(LIST_PARA,RESU_EXP)
332 # Pour l'algorithme externe, les valeurs sont celles lues dans le fichier input.txt
333 if( METHODE == 'EXTERNE') and mode_python: val = val_externe
335 val_init = copy.copy(val)
337 # OBJET "PARAMETRES GLOBAUX"
338 PARAMETRES = reca_calcul_aster.PARAMETRES(
340 UNITE_RESU=UNITE_RESU,
342 fich_output='./REPE_OUT/output_esclave.txt',
344 follow_output=follow_output,
345 table_sensibilite=table_sensibilite,
346 memjeveux_esclave=memjeveux_esclave,
347 PARA_DIFF_FINI=PARA_DIFF_FINI,
349 ITER_FONC_MAXI=ITER_FONC_MAXI,
352 if( METHODE == 'EXTERNE'):
353 PARAMETRES.fich_output = './tmp_macr_recal/output_esclave.txt'
354 type_fonctionnelle = 'float'
355 if args.has_key('FONCTIONNELLE') and args['FONCTIONNELLE'] == 'VECTORIELLE':
356 PARAMETRES.vector_output = True
357 type_fonctionnelle = 'vector'
359 # On utilise le critere en erreur plutot que normalise
360 elif METHODE in ['FMIN', 'FMINBFGS', 'FMINNCG']: PARAMETRES.error_output = True
363 CALCUL_ASTER = reca_calcul_aster.CALCUL_ASTER(PARAMETRES, UL=UNITE_ESCL, para=para, reponses=RESU_CALC, LIST_SENSI=LIST_SENSI, LIST_DERIV=LIST_DERIV)
365 # Instances des classes pour le calcul de l'erreur et le dimensionnemnt/adim
366 Simul = reca_interp.Sim_exp(RESU_EXP,POIDS)
367 Dim = reca_algo.Dimension(copy.copy(val_init),para)
369 CALCUL_ASTER.Simul = Simul
370 CALCUL_ASTER.Dim = Dim
371 CALCUL_ASTER.reca_algo = reca_algo
374 CALCUL_ASTER.UNITE_GRAPHIQUE = GRAPHIQUE['UNITE']
377 # Instance de la classe gérant l'affichage des resultats du calcul de l'optimisation
378 Mess = reca_message.Message(para,RESU_EXP,copy.copy(val_init),UNITE_RESU)
380 if( METHODE != 'EXTERNE'):
382 txt = "Lancement de l'optimisation avec la methode : " + METHODE
383 if INFO>=1: UTMESS('I','MACR_RECAL',txt)
388 #-------------------------------------------------------------------------------
389 # Methode EXTERNE (en fait juste une evaluation de la fonction puis on sort)
391 if( METHODE == 'EXTERNE'):
393 # On sauvegarde le fichier esclave si celui-ci est fort.UL (sinon il sera ecrase)
394 fic_esclave = './fort.'+str(UNITE_ESCL)
395 txt_old_esclave = None
396 if os.path.isfile(fic_esclave):
397 f = open(fic_esclave,'r')
398 txt_old_esclave = f.read()
401 # try: os.remove('./fort.'+str(UNITE_ESCL))
405 txt = '\nPARAMETRES : ' + str([ para[0] for para in LIST_PARA ]) + ' ' + str(val)
408 # Execution de l'esclave
409 if args.has_key('GRADIENT') and args['GRADIENT']!='NON_CALCULE':
412 fonctionnelle, residu, A_nodim, A = CALCUL_ASTER.calcul_FG(val)
414 # Ecriture du fichier grad.txt contenant les derivees
415 if args['GRADIENT'] == 'ADIMENSIONNE': gradient = A
416 else: gradient = A_nodim
418 # Ecriture du fichier contenant le gradient
419 if not mode_python: Ecriture_Derivees(output_file='./fort.1901', derivees=gradient)
423 fonctionnelle = CALCUL_ASTER.calcul_F(val)
426 # Ecriture du fichier contenant la fonctionnelle
427 if not mode_python: Ecriture_Fonctionnelle(output_file='./fort.1900', type_fonctionnelle=type_fonctionnelle, fonctionnelle=fonctionnelle)
430 if type(fonctionnelle) == types.FloatType: txt = '---> fonctionnelle : ' + str(fonctionnelle)
431 else: txt = '---> norme fonctionnelle : ' + str( math.sqrt( (Numeric.sum( [x**2 for x in fonctionnelle] )) ) )
434 # Affichage de la valeur de la fonctionnelle
435 if mode_python and opts.INFO==-1: print txt
437 # Affichage de la norme du gradient (AA: a remplacer par une formule de norme L2 !!)
440 for l in range(len(gradient[:,0])):
441 for c in range(len(gradient[0,:])):
442 norme += ( gradient[l,c] * gradient[l,c] )
443 norme = math.sqrt(norme)
444 txt = '---> norme du gradient : ' + str(norme)
446 if mode_python and opts.INFO==-1: print txt
449 try: os.remove('./fort.'+str(UNITE_ESCL))
452 # On remet l'ancien fichier esclave si c'etait fort.UL
454 f = open(fic_esclave,'w')
455 f.write(txt_old_esclave)
462 # On va ensuite jusqu'au bout (pour l'impression des graphes)
466 #-------------------------------------------------------------------------------
467 # Algorithme FMIN (pas d'adimensionnement car n'utilise pas de gradient)
469 elif( METHODE == 'FMIN'):
470 val, fval, warnflag = fmin(CALCUL_ASTER.calcul_F, val, maxiter=ITER_MAXI, maxfun=ITER_FONC_MAXI, fulloutput=1)
472 iter_fonc = CALCUL_ASTER.evaluation_fonction
474 Mess.ecrire("\nDerniere iteration : ")
475 Mess.affiche_etat_final_convergence(iter,ITER_MAXI,iter_fonc,ITER_FONC_MAXI, RESI_GLOB_RELA,residu=0,Act=[])
476 Mess.affiche_fonctionnelle(fval)
477 Mess.affiche_valeurs(val)
478 if warnflag==1: Mess.ecrire("Attention : le nombre maximum d'evaluations de la fonction (ITER_FONC_MAXI) a ete atteint")
479 if warnflag==2: Mess.ecrire("Attention : le nombre maximum d'iteration de l'algorithme (ITER_MAXI) a ete atteint")
481 nomres = Sortie(LIST_NOM_PARA, LIST_PARA, val, CALCUL_ASTER, Mess)
485 #-------------------------------------------------------------------------------
486 # Pour tous les autres methodes, on adimensionne
488 # Calcul d'initialisation de F, ici L_deriv_sensible ne contient que les termes calculés par la sensibilité, les autres termes sont nuls
489 L_init, L_deriv_sensible = CALCUL_ASTER.calcul_Aster(val, INFO)
491 L_J_init, erreur = Simul.multi_interpole(L_init, RESU_CALC)
492 J_init = Simul.norme_J(copy.copy(L_J_init),copy.copy(L_J_init),UNITE_RESU)
495 A = Simul.sensibilite(CALCUL_ASTER, L_init, L_deriv_sensible, val, PARA_DIFF_FINI)
496 A = Dim.adim_sensi(A)
498 l = reca_algo.lambda_init(Numeric.matrixmultiply(Numeric.transpose(A),A))
499 gradient_init =reca_algo.calcul_gradient(A,erreur) #utile pour le test de convergence, on prend les valeurs dimensionnées
500 residu = reca_algo.test_convergence(gradient_init,erreur,A,Numeric.zeros(len(gradient_init),Numeric.Float))
502 Mess.affiche_result_iter(iter,J,val,residu,Numeric.array([]))
503 # On teste un manque de temps CPU
504 restant,temps_iter,err=reca_utilitaires.temps_CPU(restant,temps_iter)
509 CALCUL_ASTER.L_init = L_init
510 CALCUL_ASTER.L_J_init = L_J_init
511 CALCUL_ASTER.J_init = J_init
512 CALCUL_ASTER.A_init = A
513 CALCUL_ASTER.gradient_init = gradient_init
514 CALCUL_ASTER.residu_init = residu
517 #-------------------------------------------------------------------------------
518 # Methode FMINBFGS et FMINNCG
520 if METHODE in ['FMINBFGS', 'FMINNCG']:
522 fprime=CALCUL_ASTER.calcul_G
525 if args.has_key('GRADIENT') and args['GRADIENT'] == 'NON_CALCULE': fprime=None
527 if fprime: UTMESS('I','MACR_RECAL',"Les derivees sont calculees par Aster")
528 else: UTMESS('I','MACR_RECAL',"Les derivees sont calculees par l'algorithme")
530 # Lancement de l'optimisation
531 if METHODE == 'FMINBFGS':
532 val, fval, func_calls, grad_calls, warnflag = fminBFGS(CALCUL_ASTER.calcul_F, val, fprime=fprime, maxiter=ITER_MAXI, avegtol=RESI_GLOB_RELA, fulloutput=1)
534 elif METHODE == 'FMINNCG':
535 val, fval, func_calls, grad_calls, hcalls, warnflag = fminNCG(CALCUL_ASTER.calcul_F, val, fprime=fprime, fhess_p=None, fhess=None, maxiter=ITER_MAXI, avextol=RESI_GLOB_RELA, fulloutput=1)
537 # Affichage des messages de sortie
538 iter_fonc = CALCUL_ASTER.evaluation_fonction
539 Mess.ecrire("\nDerniere iteration : ")
540 Mess.affiche_etat_final_convergence(iter,ITER_MAXI,iter_fonc,ITER_FONC_MAXI, RESI_GLOB_RELA,residu=0,Act=[])
541 Mess.affiche_fonctionnelle(fval)
542 Mess.affiche_valeurs(val)
543 # if warnflag==1: Mess.ecrire("\nAttention : le nombre maximum d'evaluations de la fonction (ITER_FONC_MAXI) a ete atteint")
544 # if warnflag==2: Mess.ecrire("\nAttention : le nombre maximum d'iteration de la methode (ITER_MAXI) a ete atteint")
546 # Permet d'avoir un diagnostic NOOK pour le job
547 if warnflag: iter=ITER_MAXI
555 #-------------------------------------------------------------------------------
556 # Methode Levenberg-Marquardt
559 #_____________________________________________
561 # BOUCLE PRINCIPALE DE L'ALGORITHME
562 #_____________________________________________
563 epsilon = 10.*RESI_GLOB_RELA
564 while((residu > RESI_GLOB_RELA) & (iter<ITER_MAXI)):
566 new_val, s, l, Act = reca_algo.Levenberg_bornes(val,Dim,val_init,borne_inf,borne_sup,A,erreur,l,UNITE_RESU)
568 # Calcul de F, ici L_deriv_sensible ne contient que les termes calculés par la sensibilité, les autres termes sont nuls
569 L_F, L_deriv_sensible = CALCUL_ASTER.calcul_Aster(new_val, INFO)
571 new_L_J,new_erreur = Simul.multi_interpole(L_F, RESU_CALC)
572 new_J = Simul.norme_J(L_J_init,new_L_J,UNITE_RESU)
573 l = reca_algo.actualise_lambda(l,Dim.adim(val),Dim.adim(new_val),A,erreur,new_J,J)
575 val = copy.copy(new_val)
576 erreur = copy.copy(new_erreur)
579 # Calcul de la matrice des sensibilites
580 A = Simul.sensibilite(CALCUL_ASTER, L_F, L_deriv_sensible, val, PARA_DIFF_FINI)
581 A = Dim.adim_sensi(A)
584 residu = reca_algo.test_convergence(gradient_init,erreur,A,s)
586 # Affichage iteration
587 Mess.affiche_result_iter(iter,J,val,residu,Act)
588 txt = "Informations de convergence :"
589 txt += '\n=======================================================\n'
590 txt += "Fin de l'iteration "+str(iter)+" :\n"
591 txt += '\n=> Fonctionnelle = '+str(J)
592 txt += '\n=> Residu = '+str(residu)
593 txt += '\n=======================================================\n'
594 if INFO>=1: UTMESS('I','MACR_RECAL',txt)
597 if GRAPHIQUE['AFFICHAGE']=='TOUTE_ITERATION':
598 GRAPHE_UL_OUT=GRAPHIQUE['UNITE']
599 interactif=(GRAPHIQUE['INTERACTIF']=='OUI')
600 reca_utilitaires.graphique(GRAPHIQUE['FORMAT'],L_F,RESU_EXP,RESU_CALC,iter,GRAPHE_UL_OUT,interactif)
602 # On teste un manque de temps CPU
603 restant,temps_iter,err=reca_utilitaires.temps_CPU(restant,temps_iter)
609 #_____________________________________________
612 # CONVERGENCE OU ECHEC
613 #_____________________________________________
614 iter_fonc = CALCUL_ASTER.evaluation_fonction
615 Mess.affiche_etat_final_convergence(iter,ITER_MAXI,iter_fonc,ITER_FONC_MAXI, RESI_GLOB_RELA,residu,Act)
616 reca_algo.calcul_etat_final(para,A,iter,ITER_MAXI,RESI_GLOB_RELA,residu,Mess)
619 #-------------------------------------------------------------------------------
622 #_____________________________________________
624 # FIN DES ITERATIONS POUR TOUS LES ALGOS
625 #_____________________________________________
630 # Pour les algorithmes d'optimize.py, on ne peut tracer qu'a la derniere iteration
631 if (GRAPHIQUE['AFFICHAGE']=='ITERATION_FINALE') or (METHODE in ['FMIN', 'FMINBFGS', 'FMINNCG']):
633 if (METHODE=='EXTERNE' and GRAPHIQUE['AFFICHAGE']=='TOUTE_ITERATION'):
635 fichier = args['prefix_graph']
637 if INFO>=1: UTMESS('I','MACR_RECAL',"Trace des graphiques")
638 GRAPHE_UL_OUT=GRAPHIQUE['UNITE']
639 interactif=(GRAPHIQUE['INTERACTIF']=='OUI')
640 reca_utilitaires.graphique(GRAPHIQUE['FORMAT'],L_F,RESU_EXP,RESU_CALC,iter,GRAPHE_UL_OUT,interactif,fichier)
642 if( METHODE == 'EXTERNE'):
643 if mode_python: return fonctionnelle, gradient
645 # print residu, RESI_GLOB_RELA
647 # Si pas de convergence alors diagnostic NOOK_TEST_RESU
648 if residu > RESI_GLOB_RELA:
649 from Cata.cata import CREA_TABLE, TEST_TABLE
651 _tmp.append( { 'PARA': 'ITER_MAXI', 'LISTE_R': 0.0, } )
652 motscle= {'LISTE': _tmp }
654 TBL=CREA_TABLE(**motscle);
656 TEST_TABLE(TABLE=TBL,
658 NOM_PARA='ITER_MAXI',
661 #_____________________________________________
663 # CREATIONS DE LA LISTE DE REELS CONTENANT
664 # LES VALEURS DES PARAMETRES A CONVERGENCE
665 #_____________________________________________
668 nomres = Sortie(LIST_NOM_PARA, LIST_PARA, val, CALCUL_ASTER, Mess)
683 #-------------------------------------------------------------------------------
684 if __name__ == '__main__':
688 from optparse import OptionParser, OptionGroup
690 p = OptionParser(usage='usage: %s fichier_export [options]' % sys.argv[0])
691 p.add_option('-i', '--input', action='store', dest='input', type='string', default='input.txt', help='fichier contenant les parametres')
692 p.add_option('-o', '--output', action='store', dest='output', type='string', default='output.txt', help='fichier contenant la fonctionnelle')
693 p.add_option('-g', '--output_grad', action='store', dest='output_grad', type='string', default='grad.txt', help='fichier contenant le gradient')
694 p.add_option('-p', '--prefix_graph', action='store', dest='prefix_graph', type='string', help='prefixe des fichiers contenant les courbes')
695 p.add_option('-v', '--info', action='store', dest='INFO', type='int', help='niveau de message (-1, 0, 1, 2)')
696 p.add_option('-f', '--follow', action='store', dest='follow_output', type='string', help="affiche ou non l'output du fichier Aster (True/False)")
697 p.add_option('-F', '--objective', action='store', dest='objective', type='string', help="type de la fonctionnelle (float/vector)")
698 p.add_option('-G', '--gradient', action='store', dest='gradient' , type='string', default='no', help="calcul du gradient par Aster (no/normal/adim)")
699 p.add_option('-d', '--display', action='store', dest='display' , type='string', help="renvoi du DISPLAY (pour que la creation des courbes soit moins genante)")
701 # p.add_option('-n', '--name', action='store', dest='name', type='string', default='optim', help="prefixe du fichier de bilan")
703 opts, args = p.parse_args()
705 # renvoi du DISPLAY (pour que la creation des courbes soit moins genante)
706 if opts.display: os.environ['DISPLAY'] = opts.display
710 optparse_input = optparse_output = optparse_output_grad = optparse_prefix_graph = optparse_INFO = optparse_follow_output = optparse_objective = optparse_gradient = optparse_name = None
712 if opts.INFO==None: opts.INFO=0
714 if opts.input: optparse_input = True
715 if opts.output: optparse_output = True
716 if opts.output_grad: optparse_output_grad = True
717 if opts.prefix_graph: optparse_prefix_graph = True
718 if opts.INFO in [-1, 0, 1, 2]: optparse_INFO = True
719 if opts.follow_output in ['True', 'False']: optparse_follow_output = True
720 if opts.objective in ['float', 'vector']: optparse_objective = True
721 if opts.gradient in ['no', 'normal', 'adim']: optparse_gradient = True
722 # if opts.name: optparse_name = True
724 if opts.follow_output=='True': opts.follow_output=True
725 if opts.follow_output=='False': opts.follow_output=False
730 fichier_export = args[0]
731 if not os.path.isfile(fichier_export): fichier_export = None
734 input_file = opts.input
735 output_file = opts.output
736 output_grad = opts.output_grad
737 type_fonctionnelle = opts.objective
740 if os.environ.has_key('ASTER_ROOT'):
741 sys.path.append(os.path.join(os.environ['ASTER_ROOT'], 'ASTK', 'ASTK_SERV', 'lib'))
743 from as_profil import ASTER_PROFIL
745 UTMESS('F','MACR_RECAL',"Impossible de determiner l'emplacement d'Aster ! Fixer le chemin avec la variable d'environnement ASTER_ROOT.")
747 # Efface les fichiers resultats
748 try: os.remove(output)
750 try: os.remove(output_grad)
754 # Si le fichier export n'est pas en argument on prend l'export qui est dans le rep courant
755 if not fichier_export:
756 # Lecture du fichier .export
757 list_export = glob('*.export')
758 if len(list_export) != 1:
759 UTMESS('F','MACR_RECAL',"Impossible de determiner le fichier .export a utiliser. Specifier le sur la ligne de commande.")
761 fichier_export = list_export[0]
762 prof = ASTER_PROFIL(fichier_export)
764 # Execution du fichier .comm
767 for lab in ('data', 'resu'):
768 l_fr = getattr(prof, lab)
773 if not dico['isrep']:
774 # Ancien .comm a executer
775 if dico['type'] == 'comm' and dico['ul'] == '1':
776 nom_comm = dico['path']
779 for lab in ('param',):
780 l_fr = getattr(prof, lab)
782 # print l_fr['version']
783 try: os.environ['ASTER_VERSION'] = l_fr['version'][0]
788 UTMESS('F','MACR_RECAL',"Probleme : le fichier .comm n'est pas defini dans le .export.")
789 if not os.path.isfile(nom_comm):
790 UTMESS('F','MACR_RECAL',"Probleme : le fichier .comm suivant n'est pas defini : " + nom_comm)
794 # -------------------------------------------------------------------
795 # Lecture des valeurs d'entree
796 if INFO==2: UTMESS('I',NOMPRO,"Lecture du fichier : " + input_file)
798 f = open(input_file, 'r')
801 txt = txt.replace(',', ' ')
802 val_externe = [ float(x) for x in txt.strip().split() ]
804 UTMESS('F',NOMPRO,"Probleme : impossible de lire le fichier d'entree :\n" + input_file)
805 if INFO>=2: UTMESS('I',NOMPRO,"Parametres d'entree : " + str(val_externe))
806 if optparse_INFO and opts.INFO == -1: print '\n'+ str(val_externe)
809 # -------------------------------------------------------------------
810 # Efface les fichiers d'entree et de sortie
811 try: os.remove(input_file)
813 try: os.remove(output_file)
815 try: os.remove(output_grad)
821 # --------------------------------------------------------------------------------------------------------
822 # --------------------------------------------------------------------------------------------------------
823 # --------------------------------------------------------------------------------------------------------
824 # Ci-dessous on extrait le fichier de commande jusqu'a la commande MACR_RECAL exclue (fichiernew)
825 # Puis la commande MACR_RECAL (commandenew)
826 # Ensuite on annule l'effet des commandes Aster et on evalue en Python les deux chaines de textes
828 # Lecture du fichier .comm
833 # Extraction des deux parties dans le fichier de commande
840 for ligne in fichier.split('\n'):
841 if ligne.find( txt1 )!=-1 and ligne.find( txt2 )!=-1 and ligne.strip()[0]!='#':
843 index_deb1 = fichier.index(ligne)
844 fichiernew=fichier[:index_deb1]
845 # if debug: print 80*'*' + 2*'\n'+fichiernew+80*'*' + 2*'\n'
846 if fichiernew and ligne.find( txt2 )!=-1: nb_par+=1
847 if fichiernew and ligne.find( txt3 )!=-1: nb_par-=1
848 if fichiernew and nb_par==0:
849 index_fin1 = fichier.index(ligne)+len(ligne)
850 commandenew=fichier[index_deb1:index_fin1]
852 # Remplace le nom de concept a gauche du signe egal
853 index_deb2 = commandenew.index(txt1)
854 commandenew='fonctionnelle, gradient='+commandenew[index_deb2:]+ '\n'
856 if debug: print 80*'*' + 2*'\n'+commandenew+80*'*' + 2*'\n'
858 if not fichiernew or not commandenew:
859 txt = "Probleme : Le fichier de commande :\n" + nom_comm + "\n ne semble pas comporter la commande MACR_RECAL"
860 UTMESS('F',NOMPRO,txt)
863 # -------------------------------------------------------------------
864 # Import du module Utilitai
865 sys.path.append(os.path.join(os.getcwd(), 'Python'))
866 sys.path.append(os.path.join(os.environ['ASTER_ROOT'], os.environ['ASTER_VERSION'], 'bibpyt'))
869 from Utilitai.System import ExecCommand
871 UTMESS('F','MACR_RECAL',"Probleme : impossible d'importer le module Utilitai! Prevenir la maintenance.")
874 # -------------------------------------------------------------------
875 # On annule les commandes Aster du fichier maitre .comm
876 def DEBUT(*args, **kwargs): pass
877 def FIN(*args, **kwargs): pass
878 def MACR_RECAL(*args, **kwargs): pass
879 def _F(*args, **kwargs): return kwargs
880 def DEFI_LIST_REEL(*args, **kwargs): pass
881 def DEFI_FONCTION(*args, **kwargs): pass
882 def TEST_FONCTION(*args, **kwargs): pass
883 def DEFI_CONSTANTE(*args, **kwargs): pass
886 # -------------------------------------------------------------------
887 # Evaluation du fichier de commande Aster jusqu'a MACR_RECAL
892 txt = "Le mode EXTERNE tourne en mode degrade. Lire la documentation."
893 UTMESS('A',NOMPRO,txt)
896 exec(commandenew.replace(txt1, 'macr_recal_externe'))
898 # exec(commandenew.replace(txt1, 'macr_recal_externe'))
899 # except Exception, err:
901 # txt = "Erreur lors de l'execution de la commande MACR_RECAL"
902 # UTMESS('F',NOMPRO,txt)
904 Ecriture_Fonctionnelle(output_file, type_fonctionnelle, fonctionnelle)
905 Ecriture_Derivees(output_grad, gradient)
909 # --------------------------------------------------------------------------------------------------------
910 # --------------------------------------------------------------------------------------------------------
911 # --------------------------------------------------------------------------------------------------------
912 # Si l'evaluation du fichier de commande Aster jusqu'a MACR_RECAL a echoue, on execute Aster "normalement"
916 new_fichier_comm = os.getcwd() + os.sep + 'tmp_comm'
917 new_fichier_export = os.getcwd() + os.sep + fichier_export.split('/')[-1] + '_new'
919 # Lecture du fichier .comm
924 # -------------------------------------------------------------------
925 # Modification du fichier .comm (changement des valeurs, ecriture du resultat dans un fichier)
926 if INFO==2: UTMESS('I',NOMPRO,"Lecture du fichier : " + nom_comm)
927 f = open(nom_comm, 'r')
928 ok1 = ok3 = ok4 = False
931 if ligne.find('MACR_RECAL')!=-1 and ligne.strip()[0]!='#': # On determine le nom du concept sortant de MACR_RECAL
933 _RESU_ = ligne.split('=')[0].strip()
935 elif ligne.strip()[:len(_PARAM_)] == _PARAM_: # On change les parametres : la variables _PARAM_
937 txt += _PARAM_ + " = " + str(val_externe) + '\n'
938 elif ligne.find('METHODE')!=-1 and ligne.strip()[0]!='#': # On verifie bien que la methode externe est choisi
939 if ligne.find("EXTERNE")!=-1:
945 if not ok1: UTMESS('F',NOMPRO,"Probleme : il faut mettre les parametres sous la forme d'une ligne python " + str(_PARAM_) + " = [param1, param2, ...]")
946 if not ok3: UTMESS('F',NOMPRO,"Probleme : la commande MACR_RECAL n'a pas ete trouvee dans le .comm")
947 if not ok4: UTMESS('F',NOMPRO,"Probleme : dans la commande MACR_RECAL, il faut choisir METHODE='EXTERNE'")
949 txt = txt.replace('_RESU_', _RESU_)
951 # Ecriture du nouveau fichier comm temporaire
952 if INFO==2: UTMESS('I',NOMPRO,"Ecriture du fichier : " + new_fichier_comm)
953 f = open(new_fichier_comm, 'w')
957 # On remplace dans l'export par le nouveau .comm
958 prof = ASTER_PROFIL(fichier_export)
959 for lab in ('data', 'resu'):
960 l_fr = getattr(prof, lab)
964 if not dico['isrep']:
965 # On remplace par le nouveau .comm
966 if dico['type'] == 'comm' and dico['ul'] == '1':
967 dico['path'] = new_fichier_comm
970 # dico['path'] = os.path.join(tmp_macr_recal, os.path.basename(dico['path']))
972 # On ajoute au profil le fichier output.txt (unite logique 1900)
973 try: os.remove('./fort.1900')
975 if not output_file.find(os.sep)!=-1: output_file = os.getcwd() + os.sep + output_file
976 prof.Set('R', {'type':'libr', 'isrep':False, 'path': output_file, 'ul':1900, 'compr': False} )
978 # On ajoute au profil le fichier grad.txt (unite logique 1901)
979 if optparse_gradient and opts.gradient!='no':
980 try: os.remove('./fort.1901')
982 output_grad = opts.gradient
983 if not output_grad.find(os.sep)!=-1: output_grad = os.getcwd() + os.sep + output_grad
984 prof.Set('R', {'type':'libr', 'isrep':False, 'path': output_grad, 'ul':1901, 'compr': False} )
987 # Ecriture du nouveau fichier export
989 if INFO==2: UTMESS('I',NOMPRO,"Ecriture du fichier : " + new_fichier_export)
990 prof.WriteExportTo(new_fichier_export)
992 UTMESS('F',NOMPRO,"Probleme : Impossible d'ecrire le fichier export : " + new_fichier_export)
993 prof.WriteExportTo('/tmp/exp')
997 if os.environ.has_key('ASTER_ROOT'):
998 as_run = os.path.join(os.environ['ASTER_ROOT'], 'ASTK', 'ASTK_SERV', 'bin', 'as_run')
1001 if INFO>=1: UTMESS('A', nompro, "Variable d'environnement ASTER_ROOT absente, " \
1002 "on essaiera avec 'as_run' dans le $PATH.")
1005 # Import du module Utilitai
1006 sys.path.append(os.path.join(os.environ['ASTER_ROOT'], os.environ['ASTER_VERSION'], 'bibpyt'))
1009 from Utilitai.System import ExecCommand
1011 UTMESS('F','MACR_RECAL',"Probleme : impossible d'importer le module Utilitai! Prevenir la maintenance.")
1014 # Lancement d'Aster avec le deuxieme export
1015 cmd = '%s %s' % (as_run, new_fichier_export)
1016 if INFO>=2: UTMESS('I','MACR_RECAL',"Lancement de la commande : " + cmd)
1017 iret, txt_output = ExecCommand(cmd, follow_output=opts.follow_output,verbose=opts.follow_output)
1018 if INFO>=2: UTMESS('I','MACR_RECAL',"Fin du lancement de la commande : " + cmd)
1020 try: os.remove(new_fichier_comm)
1022 try: os.remove(new_fichier_export)