1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2010-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 # Author: André Ribes, andre.ribes@edf.fr, EDF R&D
22 import os, sys, shutil, tempfile, glob
23 from math import log10
34 #===============================================================================
35 def UTMESS(code='I', txt=''):
37 if code=='F': sys.exit()
39 #===============================================================================
40 def get_tables(tables_calc,tmp_repe_table,prof):
41 """ Recupere les resultats Aster (Table Aster -> Numeric Python)
45 assert (tables_calc is not None)
46 assert (tmp_repe_table is not None)
48 # Import du module lire_table
49 if os.environ.has_key('ASTER_ROOT'):
50 version = prof['version'][0]
51 bibpyt = os.path.join(os.environ['ASTER_ROOT'], version, 'bibpyt')
52 sys.path.append(bibpyt)
53 for mdl in glob.glob(os.path.join(bibpyt, '*')):
54 sys.path.append(os.path.join(os.environ['ASTER_ROOT'], version, 'bibpyt', mdl))
56 from lire_table_ops import lecture_table
58 UTMESS('F', "Impossible d'importer le module lire_table!")
60 reponses = tables_calc
62 _TB = [None]*len(reponses)
63 for i in range(len(reponses)):
64 _fic_table = tmp_repe_table + os.sep + "fort."+str(int(100+i))
67 file=open(_fic_table,'r')
70 except Exception, err:
72 message = "Erreur 1!\n" + str(err)
76 table_lue = lecture_table(texte, 1, ' ')
77 list_para = table_lue.para
78 tab_lue = table_lue.values()
79 except Exception, err:
81 message = "Erreur 2!\n" + str(err)
85 if ier!=0 : UTMESS('F', message)
88 nb_val = len(tab_lue[ list_para[0] ])
89 F = Numeric.zeros((nb_val,2), Numeric.Float)
90 for k in range(nb_val):
91 F[k][0] = tab_lue[ str(reponses[i][1]) ][k]
92 F[k][1] = tab_lue[ str(reponses[i][2]) ][k]
94 except Exception, err:
95 message = "Erreur 3!\n" + str(err)
98 if debug: print 'resu_calc:', resu_calc
101 #===============================================================================
104 #===============================================================================
105 def Calcul_Aster_Ponctuel( X0 = None ):
113 global python_version
116 if type(X0) is type(numpy.matrix([])):
120 # ----------------------------------------------------------------------------
122 #isFromYacs = globals().get('ASTER_ROOT', None) # execution via YACS ou en externe
123 #isFromYacs = ASTER_ROOT
124 #print "isFromYacs:", isFromYacs
126 # from N_Parameters import ASTER_ROOT, debug, SOURCES_ROOT, DISPLAY
127 # from N_Study_Parameters import export
128 # from N_MR_Parameters import calcul, parametres
129 os.environ['ASTER_ROOT'] = ASTER_ROOT
131 # ----------------------------------------------------------------------------
132 # Repertoire contenant les resultats des calculs Aster (None = un rep temp est cree)
133 resudir = globals().get('resudir', None)
135 # ----------------------------------------------------------------------------
136 # Parametres remis en forme
137 list_params = [x[0] for x in parametres]
140 # ----------------------------------------------------------------------------
141 # Procedure de calculs distribues
143 # Import des modules python d'ASTK
144 astk_serv_root = os.path.join(ASTER_ROOT, 'ASTK', 'ASTK_SERV')
145 sys.path.append(os.path.join(astk_serv_root, 'lib'))
146 sys.path.append(os.path.join(ASTER_ROOT, 'lib', python_version, 'site-packages'))
150 from asrun.run import AsRunFactory
151 from asrun.profil import ASTER_PROFIL
152 from asrun.common_func import get_hostrc
153 from asrun.utils import get_timeout
154 from asrun.parametric import is_list_of_dict
155 from asrun.thread import Dispatcher
156 from asrun.distrib import DistribParametricTask
159 UTMESS('F', "Impossible de determiner l'emplacement d'Aster ! Fixer le chemin avec la variable d'environnement ASTER_ROOT.")
161 # Import des modules supplementaires
162 sys.path.insert(0, SOURCES_ROOT)
163 sys.path.insert(0, os.path.join(SOURCES_ROOT, 'sources'))
168 if not os.path.isdir(resudir):
169 try: os.mkdir(resudir)
171 UTMESS('A', "Impossible de creer le repertoire : %s. On utilise un repertoire temporaire" % resudir)
173 if not resudir: resudir = tempfile.mkdtemp(prefix='tmp_macr_recal_')
174 flashdir = os.path.join(resudir,'flash')
175 UTMESS('I', "\n ASTER Exécution simple\n Répertoire temporaire de résultats : %s" % resudir)
181 prof = ASTER_PROFIL(filename=export)
182 #prof = init_profil_from(run, prof, keep_surch=True)
184 'type' : 'repe', 'isrep' : True, 'ul' : 0, 'compr' : False,
185 'path' : '/tmp/test_param' })
188 prof.WriteExportTo( os.path.join(resudir, 'master.export') )
191 hostrc = get_hostrc(run, prof)
193 # timeout before rejected a job
194 timeout = get_timeout(prof)
200 # Dictionnaire des parametres du point courant
201 dic = dict( zip( list_params, X0 ) )
202 list_val.append( dic )
204 assert is_list_of_dict(list_val)
205 nbval = len(list_val)
208 # Ajout des impressions de tables a la fin du .comm
211 for i in range(len(reponses)):
212 _ul = str(int(100+i))
215 try: os.remove( tmp_macr_recal+os.sep+"REPE_TABLE"+os.sep+"fort."+_ul )
218 t.append("\n# Recuperation de la table : " + str(reponses[i][0]) + "\n")
219 t.append("DEFI_FICHIER(UNITE=" + num_ul + ", FICHIER='" + os.path.join('.', 'REPE_OUT', 'fort.'+_ul) + "',);\n" )
220 t.append("IMPR_TABLE(TABLE="+str(reponses[i][0])+", FORMAT='ASTER', UNITE="+num_ul+", INFO=1, FORMAT_R='E30.20',);\n")
221 t.append("DEFI_FICHIER(ACTION='LIBERER', UNITE="+num_ul+",);\n")
224 # number of threads to follow execution
227 # ----- Execute calcutions in parallel using a Dispatcher object
229 task = DistribParametricTask(run=run, prof=prof, # IN
231 nbmaxitem=0, timeout=timeout,
232 resudir=resudir, flashdir=flashdir,
233 keywords={'POST_CALCUL': '\n'.join(t)},
235 nbnook=0, exec_result=[]) # OUT
236 # ... and dispatch task on 'list_tests'
237 etiq = 'calc_%%0%dd' % (int(log10(nbval)) + 1)
238 labels = [etiq % (i+1) for i in range(nbval)]
239 couples = zip(labels, list_val)
240 execution = Dispatcher(couples, task, numthread=numthread)
247 # Recuperation des tables calculees
255 tbl = get_tables(tables_calc=list_calc, tmp_repe_table=os.path.join(resudir, c, 'REPE_OUT'), prof=prof)
260 # print 'AA1:', array
262 FX.extend([ x[0] for x in array ])
263 FY.extend([ x[1] for x in array ])
264 ldims.append(len(array))
266 # Agregation des resultats
269 seq_DIMS.append(ldims)
273 # Liste des diagnostics
275 for result in task.exec_result:
279 lst_DIAG = [ d_diag[label] for label in labels]
283 print "list_calc =",list_calc
284 print "seq_FX =",seq_FX
285 print "seq_FY =",seq_FY
286 print "seq_DIMS =",seq_DIMS
287 print "lst_DIAG =",lst_DIAG
288 print "lst_iter =",lst_iter
291 # ----------------------------------------------------------------------------
292 # Procedure d'assemblage du gradient
294 # Calcul maitre (point X0)
295 idx0 = lst_iter.index(0) # index (les calculs arrivent-ils dans le desordre?)
299 # Arret si tous les jobs ne se sont pas deroules correctement
300 for diag in lst_DIAG:
301 if not diag[0:2] in ['OK', '<A']:
302 raise ValueError("Au moins un calcul ne s'est pas deroule normalement")
305 print "\nH_de_X (calcul ponstuel) au point X0: \n%s" % str(H_de_X)
309 #===============================================================================
310 def Calcul_Aster_Jacobienne( X0 = None ):
317 global python_version
320 if type(X0) is type(numpy.matrix([])):
324 # ----------------------------------------------------------------------------
326 dX = globals().get('dX', [ x*FacteurdX for x in X0 ]) # execution via YACS ou en externe
327 # dX = globals().get('dX', [ 0.1, 0.1, 0.001]) # execution via YACS ou en externe
328 # ----------------------------------------------------------------------------
330 #isFromYacs = globals().get('ASTER_ROOT', None) # execution via YACS ou en externe
332 # from N_Parameters import ASTER_ROOT, debug, SOURCES_ROOT, DISPLAY
333 # from N_Study_Parameters import export
334 # from N_MR_Parameters import calcul, parametres
335 os.environ['ASTER_ROOT'] = ASTER_ROOT
337 # ----------------------------------------------------------------------------
338 # Repertoire contenant les resultats des calculs Aster (None = un rep temp est cree)
339 resudir = globals().get('resudir', None)
341 # ----------------------------------------------------------------------------
342 # Parametres remis en forme
343 list_params = [x[0] for x in parametres]
346 # ----------------------------------------------------------------------------
347 # Procedure de calculs distribues
349 # Import des modules python d'ASTK
350 astk_serv_root = os.path.join(ASTER_ROOT, 'ASTK', 'ASTK_SERV')
351 sys.path.append(os.path.join(astk_serv_root, 'lib'))
352 sys.path.append(os.path.join(ASTER_ROOT, 'lib', python_version, 'site-packages'))
356 from asrun.run import AsRunFactory
357 from asrun.profil import ASTER_PROFIL
358 from asrun.common_func import get_hostrc
359 from asrun.utils import get_timeout
360 from asrun.parametric import is_list_of_dict
361 from asrun.thread import Dispatcher
362 from asrun.distrib import DistribParametricTask
365 UTMESS('F', "Impossible de determiner l'emplacement d'Aster ! Fixer le chemin avec la variable d'environnement ASTER_ROOT.")
367 # Import des modules supplementaires
368 sys.path.insert(0, SOURCES_ROOT)
369 sys.path.insert(0, os.path.join(SOURCES_ROOT, 'sources'))
374 if not os.path.isdir(resudir):
375 try: os.mkdir(resudir)
377 UTMESS('A', "Impossible de creer le repertoire : %s. On utilise un repertoire temporaire" % resudir)
379 if not resudir: resudir = tempfile.mkdtemp(prefix='tmp_macr_recal_')
380 flashdir = os.path.join(resudir,'flash')
381 UTMESS('I', "\n ASTER Exécutions multiples\n Répertoire temporaire de résultats : %s" % resudir)
387 prof = ASTER_PROFIL(filename=export)
388 #prof = init_profil_from(run, prof, keep_surch=True)
390 'type' : 'repe', 'isrep' : True, 'ul' : 0, 'compr' : False,
391 'path' : '/tmp/test_param' })
394 prof.WriteExportTo( os.path.join(resudir, 'master.export') )
397 hostrc = get_hostrc(run, prof)
399 # timeout before rejected a job
400 timeout = get_timeout(prof)
406 # Dictionnaire des parametres du point courant
407 dic = dict( zip( list_params, X0 ) )
408 list_val.append( dic )
410 # Dictionnaires des parametres des calculs esclaves (perturbations des differences finies)
411 for n in range(1,len(dX)+1):
414 X = [ X0[i] + l[i] for i in range(len(dX)) ]
415 dic = dict( zip( list_params, X ) )
416 list_val.append( dic )
418 assert is_list_of_dict(list_val)
419 nbval = len(list_val)
422 # Ajout des impressions de tables a la fin du .comm
425 for i in range(len(reponses)):
426 _ul = str(int(100+i))
429 try: os.remove( tmp_macr_recal+os.sep+"REPE_TABLE"+os.sep+"fort."+_ul )
432 t.append("\n# Recuperation de la table : " + str(reponses[i][0]) + "\n")
433 t.append("DEFI_FICHIER(UNITE=" + num_ul + ", FICHIER='" + os.path.join('.', 'REPE_OUT', 'fort.'+_ul) + "',);\n" )
434 t.append("IMPR_TABLE(TABLE="+str(reponses[i][0])+", FORMAT='ASTER', UNITE="+num_ul+", INFO=1, FORMAT_R='E30.20',);\n")
435 t.append("DEFI_FICHIER(ACTION='LIBERER', UNITE="+num_ul+",);\n")
438 # number of threads to follow execution
441 # ----- Execute calcutions in parallel using a Dispatcher object
443 task = DistribParametricTask(run=run, prof=prof, # IN
445 nbmaxitem=0, timeout=timeout,
446 resudir=resudir, flashdir=flashdir,
447 keywords={'POST_CALCUL': '\n'.join(t)},
449 nbnook=0, exec_result=[]) # OUT
450 # ... and dispatch task on 'list_tests'
451 etiq = 'calc_%%0%dd' % (int(log10(nbval)) + 1)
452 labels = [etiq % (i+1) for i in range(nbval)]
453 couples = zip(labels, list_val)
454 execution = Dispatcher(couples, task, numthread=numthread)
461 # Recuperation des tables calculees
469 tbl = get_tables(tables_calc=list_calc, tmp_repe_table=os.path.join(resudir, c, 'REPE_OUT'), prof=prof)
474 # print 'AA1:', array
476 FX.extend([ x[0] for x in array ])
477 FY.extend([ x[1] for x in array ])
478 ldims.append(len(array))
480 # Agregation des resultats
483 seq_DIMS.append(ldims)
487 # Liste des diagnostics
489 for result in task.exec_result:
493 lst_DIAG = [ d_diag[label] for label in labels]
497 print "list_calc =",list_calc
498 print "seq_FX =",seq_FX
499 print "seq_FY =",seq_FY
500 print "seq_DIMS =",seq_DIMS
501 print "lst_DIAG =",lst_DIAG
502 print "lst_iter =",lst_iter
506 # ----------------------------------------------------------------------------
507 # Procedure d'assemblage du gradient
509 # Calcul maitre (point X0)
510 idx0 = lst_iter.index(0) # index (les calculs arrivent-ils dans le desordre?)
514 # Arret si tous les jobs ne se sont pas deroules correctement
515 for diag in lst_DIAG:
516 if not diag[0:2] in ['OK', '<A']:
517 raise ValueError("Au moins un calcul ne s'est pas deroule normalement")
519 # Calcul du gradient (une liste de liste)
520 Gradient_de_H_en_X = []
522 for n in range(len(lst_iter))[1:]:
523 idx = lst_iter.index(n)
525 col = [ -(y-x)/dX[idx-1] for x, y in zip(FY, FY_X0) ]
526 Gradient_de_H_en_X.append(col)
527 if debug: print 'Calcul numero: %s - Diagnostic: %s' % (n, lst_DIAG[idx])
530 print "\nCalcul H au point X0: \n%s" % str(H_de_X)
532 print "\nGradient au point X0:"
533 pprint.pprint(Gradient_de_H_en_X)
535 return Gradient_de_H_en_X
537 #===============================================================================
538 def Calcul_Aster_Adjoint( (X0, dY) ):
542 print "CALCUL ADJOINT"
548 Y0 = numpy.asmatrix(dY).flatten().T
550 Delta_HX = Calcul_Aster_Jacobienne( X0 )
551 Delta_HX = numpy.matrix( Delta_HX )
553 HtY = numpy.dot(Delta_HX, Y0)
556 print "dHX =",Delta_HX