1 #@ MODIF veri_matr_tang Utilitai DATE 18/09/2007 AUTEUR DURAND C.DURAND
2 # -*- coding: iso-8859-1 -*-
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2007 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 from Cata.cata import *
22 # ===========================================================================
23 # MACRO "VERI_MATR_TANG"
24 # -------------------------------------
28 import LinearAlgebra as LA
33 VERIFICATION SUR LES MATRICES TANGENTES
37 mat : matrice tangente
38 ddl : nom des degres de liberte
40 norme : norme de la matrice tangente
41 prec_zero : en-dessous de prec_zero, on ne compare pas les matrices
46 Save : sauvegarde la matrice dans un fichier
47 Load : lit la matrice depuis un fichier
48 Aster : lit la matrice depuis l'espace Aster
49 Matrice : range la matrice
50 Difference : comparaison entre la matrice tangente et une autre matrice
51 Symetrie : verification du caractere symetrique de la matrice tangente
56 def __init__(self,ddl='',prec_zero=1.E-12) :
59 ddl : chaine de caracteres designant les ddl (ex: 'UUP')
60 prec_zero : en-dessous de prec_zero, on ne compare pas les matrices
64 self.prec_zero = prec_zero
67 def Load(self,nom_fichier) :
69 fichier = file(nom_fichier,'r')
70 self.__dict__ = cPickle.load(fichier)
73 def Save(self,nom_fichier) :
75 fichier = file(nom_fichier,'w')
76 cPickle.dump(self.__dict__,fichier)
79 def Aster(self,suffixe = 'MATA') :
82 nom : suffixe de l'objet jeveux
85 nom_obj_jeveux = string.ljust('PYTHON.TANGENT.'+suffixe,24)
86 obj_jeveux = aster.getvectjev(nom_obj_jeveux)
88 raise 'TANGENT : OBJET JEVEUX DE SUFFIXE '+suffixe+' INEXISTANT'
89 self.Matrice(obj_jeveux)
94 self.vp = sort(LA.eigenvalues(self.mat))
97 def Matrice(self,matrice) :
100 matrice : la matrice tangente (rangement carre)
103 if type(matrice) == type((1,)) :
104 matrice = array(list(matrice))
105 elif type(matrice) == type([]) :
106 matrice = array(matrice)
107 matrice = matrice.astype(Float)
109 nddl = int(len(matrice)**0.5+0.5)
110 matrice.shape = (nddl,nddl)
117 elif len(self.ddl) <> nddl :
118 raise 'Nommage des DDL incoherents avec la taille de la matrice'
120 self.norme = trace(dot(transpose(self.mat),self.mat))
123 def Difference(self,matp,affi_ok=0,prec_diff = 1.E-4) :
126 COMPARAISON RELATIVE DE LA MATRICE TANGENTE AVEC UNE AUTRE MATRICE
128 matp : matrice avec laquelle self.mat est comparee
129 affi_ok : si oui, on affiche egalement les valeurs qui collent bien
130 prec_diff : ecart au-dessus duquel on considere que ce n'est pas OK
133 if type(matp) == type((1,)) :
134 matp = array(list(matp))
135 elif type(matp) == type([]) :
137 elif type(matp) == type(self) :
139 elif type(matp) == type(array([1])) :
142 raise '1er argument doit etre une matrice (tuple,liste,TANGENT ou Numeric Array)'
144 matp = matp.astype(Float)
146 if len(matp) <> self.nddl*self.nddl :
147 raise 'Matrices de tailles differentes'
148 matp.shape = (self.nddl,self.nddl)
150 refe = abs(self.mat) + abs(matp)
151 diff = where(refe > self.prec_zero,abs(self.mat-matp)/(refe+self.prec_zero),0)
152 nook = nonzero(ravel(diff) > prec_diff)
153 ok = nonzero(ravel(diff) <= prec_diff)
170 # print self.ddl[i],self.ddl[j],' ',(i+1,j+1),' ',self.mat[i,j],' ',matp[i,j]
173 liste_matt.append(self.mat[i,j])
174 liste_matp.append(matp[i,j])
175 liste_diff.append( abs(self.mat[i,j]-matp[i,j])/ ( abs(self.mat[i,j]) + abs(matp[i,j]) + self.prec_zero))
177 if self.norme > self.prec_zero :
178 ecart = (self.mat - matp)/2.
179 nor_ecart = trace(dot(transpose(ecart),ecart))
180 nor_diff= nor_ecart / self.norme
183 return liste_i,liste_j,liste_matt,liste_matp, liste_diff,nor_diff
186 def Symetrie(self,prec_diff = 1.E-4) :
189 VERIFICATION QUE LA MATRICE TANGENTE EST SYMETRIQUE
191 On retourne la norme relative de l'ecart a la symetrie : || (A-At)/2|| / ||A||
192 On affiche les termes qui s'ecartent de la symetrie
194 prec_diff : ecart au-dessus duquel on considere que ce n'est pas OK
197 tran = transpose(self.mat)
198 liste_i,liste_j,liste_matt,liste_matp,liste_diff,nor_diff=self.Difference(tran,affi_ok=0,prec_diff=prec_diff)
201 # if self.norme > self.prec_zero :
202 # ecart = (self.mat - tran)/2.
203 # nor_ecart = trace(dot(transpose(ecart),ecart))
204 # return nor_ecart / self.norme
207 return liste_i,liste_j,liste_matt,liste_matp, liste_diff,nor_diff
209 def Sauve(self,nom_fichier) :
210 cPickler.dump(self.__dict__)
212 def veri_matr_tang_ops(self,SYMETRIE,DIFFERENCE,PRECISION,**args):
215 Ecriture de la macro verif_matrice_tangente_ops
219 from Noyau.N_utils import AsType
220 from Utilitai.Utmess import UTMESS
221 from Utilitai.UniteAster import UniteAster
223 # On importe les definitions des commandes a utiliser dans la macro
224 CREA_TABLE = self.get_cmd('CREA_TABLE')
226 # La macro compte pour 1 dans la numerotation des commandes
228 # Le concept sortant (de type fonction) est nomme ROTGD dans
229 # le contexte de la macro
231 self.DeclareOut('TAB_MAT',self.sd)
233 # La macro compte pour 1 dans la numerotation des commandes
236 tgt.Aster(suffixe='MATA')
238 matp.Aster(suffixe='MATC')
239 prec_diff = PRECISION
240 if (SYMETRIE=='OUI') :
241 list1_i,list1_j,list1_matt,list1_matp,list1_diff,symetgt=tgt.Symetrie(prec_diff)
242 list2_i,list2_j,list2_matt,list2_matp,list2_diff,symeper=matp.Symetrie(prec_diff)
243 print 'Symetrie de la matrice tangente',symetgt
244 print 'Symetrie de la matrice pr pertubation',symeper
245 aster.affiche('MESSAGE',str(tgt.Difference(matp,prec_diff) ))
246 if (DIFFERENCE=='OUI'):
247 liste_i,liste_j,liste_matt,liste_matp,liste_diff,nor_diff=tgt.Difference(matp,prec_diff)
248 print 'différence entre matrice tangente et matrice par pertubation',nor_diff
249 TAB_MAT=CREA_TABLE(LISTE=(
250 _F(PARA ='I',LISTE_I = liste_i),
251 _F(PARA ='J',LISTE_I = liste_j),
252 _F(PARA ='MAT_TGTE',LISTE_R = liste_matt),
253 _F(PARA ='MAT_PERT',LISTE_R = liste_matp),
254 _F(PARA ='MAT_DIFF',LISTE_R = liste_diff),
259 VERI_MATR_TANG=MACRO(nom="VERI_MATR_TANG",op=veri_matr_tang_ops,sd_prod=table_sdaster,
260 docu="",reentrant='n',
261 fr="verification de la matrice tangente : symétrie et différence par rapport a la matrice calculée par perturbation",
262 regles=(AU_MOINS_UN('SYMETRIE','DIFFERENCE')),
263 SYMETRIE =SIMP(statut='f',typ='TXM',defaut="NON",into=("OUI","NON") ),
264 DIFFERENCE =SIMP(statut='f',typ='TXM',defaut="OUI",into=("OUI","NON") ),
265 PRECISION =SIMP(statut='f',typ='R',defaut=1.E-4 ),