Exemplo n.º 1
0
 def _run(self):
     """SPEC_OSCI"""
     import aster_fonctions
     f_in = self._lf[0]
     l_freq, l_amor = self._dat['FREQ'], self._dat['AMOR']
     kw = self.kw
     l_fonc_f = []
     # construction de la nappe
     vale_para = l_amor
     para = {
         'INTERPOL': ['LIN', 'LOG'],
         'NOM_PARA_FONC': 'FREQ',
         'NOM_PARA': 'AMOR',
         'PROL_DROITE': 'EXCLU',
         'PROL_GAUCHE': 'EXCLU',
         'NOM_RESU': kw['NATURE']
     }
     para_fonc = {
         'INTERPOL': ['LOG', 'LOG'],
         'NOM_PARA': 'FREQ',
         'PROL_DROITE': 'CONSTANT',
         'PROL_GAUCHE': 'EXCLU',
         'NOM_RESU': kw['NATURE']
     }
     if kw['NATURE'] == 'DEPL':
         ideb = 0
     elif kw['NATURE'] == 'VITE':
         ideb = 1
     else:
         ASSERT(kw['NATURE'] == 'ACCE')
         ideb = 2
     if kw['METHODE'] == 'RICE':
         # appel à DSP2SRO
         ASSERT(kw['NATURE_FONC'] == 'DSP')
         deuxpi = 2. * math.pi
         f_dsp = t_fonction(f_in.vale_x * deuxpi, f_in.vale_y / deuxpi,
                            f_in.para)
         for iamor in l_amor:
             spectr = DSP2SRO(f_dsp, iamor, kw['DUREE'], l_freq, ideb)
             vale_y = spectr.vale_y / kw['NORME']
             l_fonc_f.append(t_fonction(l_freq, vale_y, para_fonc))
     elif kw['METHODE'] == 'NIGAM':
         # appel à SPEC_OSCI
         ASSERT(kw['NATURE_FONC'] == 'ACCE')
         spectr = aster_fonctions.SPEC_OSCI(f_in.vale_x, f_in.vale_y,
                                            l_freq, l_amor)
         for iamor in range(len(l_amor)):
             vale_y = spectr[iamor, ideb, :] / kw['NORME']
             l_fonc_f.append(t_fonction(l_freq, vale_y, para_fonc))
     elif kw['METHODE'] == 'HARMO':
         # appel à ACCE2DSP
         ASSERT(kw['NATURE_FONC'] == 'ACCE')
         for iamor in l_amor:
             spectr = ACCE2SRO(f_in, iamor, l_freq, ideb)
             vale_y = spectr.vale_y / kw['NORME']
             l_fonc_f.append(t_fonction(l_freq, vale_y, para_fonc))
     self.resu = t_nappe(vale_para, l_fonc_f, para)
Exemplo n.º 2
0
 def _build_data(self):
     """Read keywords to build the data"""
     CalcFonctionOper._build_list_fonc(self)
     kw = self.kw
     self._dat = {}
     # amor
     if kw['AMOR_REDUIT'] is None:
         l_amor = [0.02, 0.05, 0.1]
         UTMESS('I', 'FONCT0_31', valr=l_amor)
     else:
         l_amor = force_list(kw['AMOR_REDUIT'])
     eps = 1.e-6
     for amor in l_amor:
         if amor > (1 - eps):
             UTMESS('S', 'FONCT0_36')
     self._dat['AMOR'] = l_amor
     # freq
     if kw['LIST_FREQ'] is not None:
         l_freq = kw['LIST_FREQ'].Valeurs()
     elif kw['FREQ'] is not None:
         l_freq = force_list(kw['FREQ'])
     else:
         l_freq = []
         for i in range(56):
             l_freq.append(0.2 + 0.050 * i)
         for i in range(8):
             l_freq.append(3.0 + 0.075 * i)
         for i in range(14):
             l_freq.append(3.6 + 0.100 * i)
         for i in range(24):
             l_freq.append(5.0 + 0.125 * i)
         for i in range(28):
             l_freq.append(8.0 + 0.250 * i)
         for i in range(6):
             l_freq.append(15.0 + 0.500 * i)
         for i in range(4):
             l_freq.append(18.0 + 1.0 * i)
         for i in range(10):
             l_freq.append(22.0 + 1.500 * i)
         texte = []
         for i in range(len(l_freq) / 5):
             texte.append(' %f %f %f %f %f' %
                          tuple(l_freq[i * 5:i * 5 + 5]))
         UTMESS('I',
                'FONCT0_32',
                vali=len(l_freq),
                valk=os.linesep.join(texte))
     if min(l_freq) < 1.E-10:
         UTMESS('F', 'FONCT0_43')
     self._dat['FREQ'] = l_freq
     # check
     if abs(kw['NORME']) < 1.E-10:
         UTMESS('S', 'FONCT0_33')
     if kw['NATURE_FONC'] == 'DSP':
         ASSERT(kw['METHODE'] == 'RICE')
Exemplo n.º 3
0
def lire_nb_valeurs(file_object,
                    nb,
                    extend_to,
                    conversion,
                    nb_bloc=1,
                    nb_ignore=0,
                    max_per_line=-1,
                    regexp_label=None):
    """Lit nb valeurs dans file_object et les ajoute à extend_to
    après les avoir converties en utilisant la fonction conversion.
    Ignore nb_ignore lignes pour chacun des nb_bloc lus et lit au
    maximum max_per_line valeurs par ligne.
    Retourne le nombre de lignes lues."""
    if max_per_line < 0:
        max_per_line = nb
    ln = 0
    _printDBG("LIRE_NB_VALEURS nb=", nb, ", nb_bloc=", nb_bloc, ", nb_ignore=",
              nb_ignore)
    for i in range(nb_bloc):
        val = []
        j = 0
        label = []
        while j < nb_ignore:
            ln += 1
            line = file_object.readline()
            if line.strip() == '':
                continue
            j += 1
            label.append(line)
        if nb_ignore:
            _printDBG("IGNORE", label)
            slabel = ''.join(label)
            if regexp_label:
                mat = re.search(regexp_label, slabel, re.M)
                if mat is None:
                    _printDBG("LABEL", regexp_label, "non trouve, recule de",
                              nb_ignore, "lignes.", i, "bloc(s) lu(s).")
                    curpos = file_object.tell()
                    file_object.seek(curpos - len(slabel))
                    return 0
        while len(val) < nb:
            ln += 1
            line = file_object.readline()
            if line.strip() == '':
                continue
            add = [conversion(v) for v in line.split()[:max_per_line]]
            val.extend(add)
        ASSERT(
            len(val) == nb,
            "%d valeurs attendues, %d valeurs lues" % (nb, len(val)))
        extend_to.extend(val)
        _printDBG("BLOC", i, ",", nb, "valeurs lues, debut :", repr(val[:3]))
    return ln
Exemplo n.º 4
0
 def __setitem__(self, key, value):
     ASSERT(self.get(key) is None)
     self.set(key, value)
Exemplo n.º 5
0
    def check(self):
        """Vérification des règles impossible à écrire dans le .capy"""
        # tâches à la demande
        if self['TYPE_RESU'] in ('HARM_GENE', 'TRAN_GENE', 'TABLE', 'CHARGE'):
            self.set('_calc_impe', True)
            self.set('_calc_forc', True)
        elif self['TYPE_RESU'] in ('FICHIER', 'TABLE_CONTROL'):
            if self.get('UNITE_RESU_IMPE') is not None:
                self.set('_calc_impe', True)
            if self.get('UNITE_RESU_FORC') is not None:
                self.set('_calc_forc', True)
        else:
            if self['EXCIT_SOL'] is not None:
                self.set('_calc_forc', True)
        self.set('_hasPC', self.get('GROUP_MA_CONTROL') is not None)
        # unités logiques
        if self.get('UNITE_RESU_IMPE') is None:
            self.set('_exec_Miss', True)
            self['UNITE_RESU_IMPE'] = self.UL.Libre(action='ASSOCIER')
        if self.get('UNITE_RESU_FORC') is None:
            self.set('_exec_Miss', True)
            self['UNITE_RESU_FORC'] = self.UL.Libre(action='ASSOCIER')

        # fréquences
        if self['TYPE_RESU'] not in ('CHARGE'):
            if self['LIST_FREQ'] is not None \
                    and self['TYPE_RESU'] not in ('FICHIER', 'HARM_GENE', 'TABLE_CONTROL'):
                raise aster.error('MISS0_17')

        # si base modale, vérifier/compléter les amortissements réduits
        if self['TYPE_RESU'] not in ('CHARGE'):
            if self['BASE_MODALE']:
                res = aster.dismoi('NB_MODES_DYN', self['BASE_MODALE'].nom,
                                   'RESULTAT', 'C')
                ASSERT(res[0] == 0)
                self['_NBM_DYN'] = res[1]
                res = aster.dismoi('NB_MODES_STA', self['BASE_MODALE'].nom,
                                   'RESULTAT', 'C')
                ASSERT(res[0] == 0)
                self['_NBM_STAT'] = res[1]
                if self['AMOR_REDUIT']:
                    self.set('AMOR_REDUIT', force_list(self['AMOR_REDUIT']))
                    nval = len(self['AMOR_REDUIT'])
                    if nval < self['_NBM_DYN']:
                        # complète avec le dernier
                        nadd = self['_NBM_DYN'] - nval
                        self._keywords['AMOR_REDUIT'].extend([
                            self['AMOR_REDUIT'][-1],
                        ] * nadd)
                        nval = self['_NBM_DYN']
                    if nval < self['_NBM_DYN'] + self['_NBM_STAT']:
                        # on ajoute 0.
                        self._keywords['AMOR_REDUIT'].append(0.)
        # la règle ENSEMBLE garantit que les 3 GROUP_MA_xxx sont tous absents
        # ou tous présents
        if self['TYPE_RESU'] not in ('CHARGE'):
            if self['ISSF'] != 'NON':
                if self['GROUP_MA_FLU_STR'] is None:
                    UTMESS('F', 'MISS0_22')
                if self['MATER_FLUIDE'] is None:
                    UTMESS('F', 'MISS0_23')
Exemplo n.º 6
0
def post_erreur_ops(self, OPTION, CHAM_GD, MODELE, GROUP_MA, **args):
    """
    Macro POST_ERREUR permettant de calculer les erreurs en termes de
    norme en énergie, norme L2 du déplacement et norme L2 de la pression
    de contact
    """
    import aster

    from Accas           import _F
    from Utilitai.Utmess import UTMESS, ASSERT

    ier = 0
    # La macro compte pour 1 dans la numerotation des commandes
    self.set_icmd(1)

    # Le concept sortant (de type table_sdaster ou dérivé) est tabout
    self.DeclareOut('tabout', self.sd)

    # On importe les definitions des commandes a utiliser dans la macro
    # Le nom de la variable doit etre obligatoirement le nom de la commande
    CREA_TABLE    = self.get_cmd('CREA_TABLE')
    DETRUIRE      = self.get_cmd('DETRUIRE')
    POST_ELEM     = self.get_cmd('POST_ELEM')
    CREA_CHAMP    = self.get_cmd('CREA_CHAMP')
    CREA_RESU     = self.get_cmd('CREA_RESU')
    FORMULE       = self.get_cmd('FORMULE')
    CALC_TABLE    = self.get_cmd('CALC_TABLE')
    IMPR_RESU     = self.get_cmd('IMPR_RESU')

    # récupération du phenomene
    iret,ibid,phenomene = aster.dismoi('PHENOMENE', MODELE.nom, 'MODELE', 'F')

    # seul le phénomène mécanique est pris en charge
    if (phenomene != 'MECANIQUE'):
       UTMESS('F', 'PREPOST_11')

    # récupération de la modélisation
    iret,ibid,modelisation = aster.dismoi('MODELISATION', MODELE.nom, 'MODELE', 'F')

#    # assertion : modèle isoparamétrique
#    ASSERT(modelisation in ('D_PLAN', 'C_PLAN', 'AXIS', '3D'))

    # le modele comporte-t-il des fissures X-FEM ?
    iret,nfismo,kbid = aster.dismoi('NB_FISS_XFEM', MODELE.nom, 'MODELE', 'F')
    lxfem = nfismo > 0

    # récupération du maillage inclus dans le modele
    iret,ibid,nom_mail = aster.dismoi('NOM_MAILLA', MODELE.nom, 'MODELE', 'F')
    nom_mail = nom_mail.strip()
    __MA = self.get_concept(nom_mail)

    # récupération de la dimension géométrique
    iret,dime,kbid = aster.dismoi('DIM_GEOM', __MA.nom, 'MAILLAGE', 'F')

    # extraction des coordonnées des noeuds du maillage
    __CHXN=CREA_CHAMP(OPERATION='EXTR', TYPE_CHAM='NOEU_GEOM_R',
                      NOM_CHAM='GEOMETRIE', MAILLAGE=__MA, INFO=1);

    # calcul des coordonnées des points d'intégration des éléments du maillage
    __CHXG=CREA_CHAMP(OPERATION='DISC', TYPE_CHAM='ELGA_GEOM_R', PROL_ZERO='OUI',
                      CHAM_GD=__CHXN, MODELE=MODELE, );

    # si un seul GROUP_MA, on le convertit en liste
#    if type(GROUP_MA) not in (list, tuple):
#        GROUP_MA = [GROUP_MA]

    # recuperation du nombre de groupes
    nb_group=len(GROUP_MA)

    # creation de la fonction nulle
    if (dime == 3):
       __ZERO=FORMULE(NOM_PARA=('X','Y','Z'), VALE='0.')
    else:
       __ZERO=FORMULE(NOM_PARA=('X','Y'), VALE='0.')

    if(OPTION=='DEPL_RELA'):
        # 1. création du champ de fonctions solution analytiques au points d'intégration

        l_DDL=('DX', 'DY', 'DZ')

        # récuparation de la liste des fonctions correspondant à DX, DY, DZ
        # si l'utilisateur n'a pas renseigné une fonction, on prend la fonction nulle

        # on associe chaque composantes du vecteur des deplacements (DX, DY, DZ)
        # a la liste de fonctions donnees par l'utlisateur. Si l'uilisateur n'a pas renseigné une
        # composante, elle sera pas prise en compte dans l'evaluation de la solution analytique

        # dictionnaire associant une composante a la liste de fonctions correspondantes
        ddl2func={}
        # dictionnaire associant une composante a un indice pour avoir par exemple :
        # DX -> X1, DY -> X2
        ddl2ind={}
        i=1
        # boucle sur la liste des composantes (DX, DY, DZ)
        for ddl in l_DDL:
           # recuperation de la liste de fonctions associees a la composante courante
           l_ddl=args[ddl]
           # mise a jour des mappings si la liste existe
           if l_ddl != None:
              # assertion : l'utilisateur associe une et une seule fonction pour chaque groupe
              if len(l_ddl) != nb_group:
                 UTMESS('F', 'PREPOST_12', valk=ddl)
              ddl2func[ddl]=l_ddl
              ddl2ind[ddl]=i
              i=i+1

        # si l'utilisateur n'a fourni aucune composante, on construit un champ nul
        if not ddl2func:
           ddl=l_DDL[0]
           ddl2func[ddl]=[__ZERO]*nb_group
           ddl2ind[ddl]=1

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur la liste des composantes (DX, DY, DZ)
        for ddl in ddl2func:
           l_ddl=ddl2func[ddl]
           ind=ddl2ind[ddl]
           # boucle sur la liste des groupes
           for ig, group in enumerate(GROUP_MA):
              # creation du mot-clef facteur pour le groupe
              # et la composante courante
              d_affe={}
              d_affe['GROUP_MA']=group
              d_affe['NOM_CMP']='X' + str(ind)
              d_affe['VALE_F']=l_ddl[ig]
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_affe))

        __UanaFG=CREA_CHAMP(OPERATION='AFFE',
                            TYPE_CHAM='ELGA_NEUT_F',
                            MODELE=MODELE,
                            PROL_ZERO='OUI',
                            AFFE=l_F,
                           );

        # 2. Evaluation de la solution analytique aux points d'intégration

        __UanaG=CREA_CHAMP(OPERATION='EVAL',
                           TYPE_CHAM='ELGA_NEUT_R',
                           CHAM_F=__UanaFG,
                           CHAM_PARA=__CHXG,
                          );

        # 3. Conversion du champ solution analytique en champ de déplacement

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur la liste des composantes (DX, DY, DZ)
        for ddl in ddl2func:
           ind=ddl2ind[ddl]
           # boucle sur la liste des groupes
           for ig, group in enumerate(GROUP_MA):
              # creation du mot-clef facteur pour le groupe
              # et le ddl courants
              d_asse={}
              d_asse['GROUP_MA']=group
              d_asse['CHAM_GD']=__UanaG
              d_asse['NOM_CMP']='X' + str(ind)
              d_asse['NOM_CMP_RESU']=ddl
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_asse))

        __UanaR=CREA_CHAMP(OPERATION='ASSE',
                           TYPE_CHAM='ELGA_DEPL_R',
                           MODELE=MODELE,
                           PROL_ZERO='OUI',
                           ASSE=l_F);

        # 4. création d'un champ contenant les déplacements calculés sur les groupes considérés

        # cette etape est facile a faire en FEM, mais parait plus delicate en X-FEM ; elle est
        # donc laisse de cote pour le moment

        # 5. discrétisation des déplacements calculés aux points d'intégration

        if not lxfem:
           __UcalG=CREA_CHAMP(OPERATION='DISC',
                              TYPE_CHAM='ELGA_DEPL_R',
                              MODELE=MODELE,
                              PROL_ZERO='OUI',
                              CHAM_GD=CHAM_GD,
                             );
        else:
           cham_mater=args['CHAM_MATER']

        # dans le cas X-FEM, on assemble le champ de deplacement aux points de Gauss pour
        # se ramener un champ de la forme (DX, DY, H1X, H1Y, ..., E1X, E1Y, ...) a la forme
        # (DX, DY, DZ)
           if cham_mater is None:
              __UcalG=CREA_CHAMP(OPERATION='ASSE_DEPL',
                                 TYPE_CHAM='ELGA_DEPL_R',
                                 PROL_ZERO='OUI',
                                 CHAM_GD=CHAM_GD,
                                 MODELE=MODELE, );
           else:
              __UcalG=CREA_CHAMP(OPERATION='ASSE_DEPL',
                                 TYPE_CHAM='ELGA_DEPL_R',
                                 PROL_ZERO='OUI',
                                 CHAM_MATER=cham_mater,
                                 CHAM_GD=CHAM_GD,
                                 MODELE=MODELE, );

        # 6. création du champ différence entre les déplacements calculés et analytiques

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur les groupes
        for ig, group in enumerate(GROUP_MA):
           # boucles sur les ddl DX, DY et DZ
           for i in range(dime):
              # creation du mot-clef facteur pour le groupe
              # et le ddl courants

              # * traitement des déplacements calculés
              d_asse={}
              d_asse['GROUP_MA']=group
              d_asse['CHAM_GD']=__UcalG
              d_asse['CUMUL']='OUI'
              d_asse['COEF_R']=1.
              d_asse['NOM_CMP']=l_DDL[i]
              d_asse['NOM_CMP_RESU']=l_DDL[i]
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_asse))

              # * traitement des déplacements analytiques
              d_asse={}
              d_asse['GROUP_MA']=group
              d_asse['CHAM_GD']=__UanaR
              d_asse['CUMUL']='OUI'
              d_asse['COEF_R']=-1.
              d_asse['NOM_CMP']=l_DDL[i]
              d_asse['NOM_CMP_RESU']=l_DDL[i]
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_asse))

        __UdiffG=CREA_CHAMP(OPERATION='ASSE',
                            TYPE_CHAM='ELGA_DEPL_R',
                            MODELE=MODELE,
                            PROL_ZERO='OUI',
                            ASSE=l_F);

        # calcul de la norme L2 du deplacement pour la solution analytique et le champ difference, pour chaque groupe
        l_ref_norm=[]
        l_diff_norm=[]
        ref_norm_tot=0.
        diff_norm_tot=0.
        for group in GROUP_MA:
            # 8. calcul de la norme L2 du champ de déplacement analytique

            __TanaDEP =POST_ELEM(NORME=(_F(TYPE_NORM='L2',
                                           GROUP_MA=group,
                                           CHAM_GD=__UanaR,
                                           MODELE=MODELE,),));

            # extraction de la norme L2 du champ de déplacement analytique
            tab = __TanaDEP.EXTR_TABLE()

            col_ref = getattr(tab, 'VALE_NORM')
            l_ref=col_ref.values()
            ref=l_ref[0]

            # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement analytiques
            l_ref_norm.append(ref)

            # ajout e la contribution du groupe courant a la norme L2 du deplacement analytique totale
            ref_norm_tot+=ref**2

            # 9. calcul de la norme L2 du champ de déplacement différence

            __TdiffDEP=POST_ELEM(NORME=(_F(TYPE_NORM='L2',
                                           GROUP_MA=group,
                                           CHAM_GD=__UdiffG,
                                           MODELE=MODELE,),));

            # extraction de la norme L2 du champ de déplacement difference
            tab = __TdiffDEP.EXTR_TABLE()

            col_diff = getattr(tab, 'VALE_NORM')
            l_diff=col_diff.values()
            diff=l_diff[0]

            # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement difference
            l_diff_norm.append(diff)

            # ajout e la contribution du groupe courant a la norme L2 du deplacement difference totale
            diff_norm_tot+=diff**2

            # liberation des objets temporaires pour la prochaine iteration
            DETRUIRE(CONCEPT=_F(NOM=__TanaDEP), INFO=1)
            DETRUIRE(CONCEPT=_F(NOM=__TdiffDEP), INFO=1)

        # ajout de normes en energie pour l'ensemble des groupes
        ref_norm_tot=math.sqrt(ref_norm_tot)
        l_ref_norm.append(ref_norm_tot)

        diff_norm_tot=math.sqrt(diff_norm_tot)
        l_diff_norm.append(diff_norm_tot)

        # creation de la variable TITRE
        TITRE="ERREUR EN NORME L2 DU DEPLACEMENT"

        # destruction des objets temporaires pour le calcul de l'erreur en deplacement
        DETRUIRE(CONCEPT=_F(NOM=__UanaFG), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__UanaG), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__UanaR), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__UcalG), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__UdiffG), INFO=1)

    if(OPTION=='ENER_RELA'):

        #Extraction du nom de materiau
        CHAM_MATER=args['CHAM_MATER']
        #Extraction du type de deformation
        DEFORMATION=args['DEFORMATION']

        # 1. création du champ de fonctions solution analytiques au points d'intégration

        l_SIGM=('SIXX', 'SIYY', 'SIZZ', 'SIXY', 'SIXZ', 'SIYZ')

        # récuparation de la liste des fonctions correspondant à SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ
        # si l'utilisateur n'a pas renseigné une fonction, on prend la fonction nulle

        # on associe chaque composantes du tenseur des contraintes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ)
        # a la liste de fonxtions donnees par l'utlisateur. Si l'uilisateur n'a pas renseigné une
        # composante, elle sera pas prise en compte dans l'evaluation de la solution analytique

        # dictionnaire associant une composante a la liste de fonctions coreespondantes
        sig2func={}
        # dictionnaire associant une composante a un indice pour avoir par exemple :
        # SIXX -> X1, SIYY -> X2
        sig2ind={}
        i=1
        # boucle sur la liste des composantes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ)
        for sig in l_SIGM:
           # recuperation de la liste de fonctions associees a la composante courante
           l_sig=args[sig]
           # mise a jour des mappings si la liste existe
           if l_sig != None:
              # assertion : l'utilisateur associe une et une seule fonction pour chaque groupe
              if len(l_sig) != nb_group:
                 UTMESS('F', 'PREPOST_12', valk=sig)
              sig2func[sig]=l_sig
              sig2ind[sig]=i
              i=i+1

        # si l'utilisateur n'a fourni aucune composante, on construit un champ nul
        if not sig2func:
           sig=l_SIGM[0]
           sig2func[sig]=[__ZERO]*nb_group
           sig2ind[sig]=1

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur la liste des composantes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ)
        for sig in sig2func:
           l_sig=sig2func[sig]
           ind=sig2ind[sig]
           # boucle sur la liste des groupes
           for ig, group in enumerate(GROUP_MA):
              # creation du mot-clef facteur pour le groupe
              # et la composante courante
              d_affe={}
              d_affe['GROUP_MA']=group
              d_affe['NOM_CMP']='X' + str(ind)
              d_affe['VALE_F']=l_sig[ig]
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_affe))

        __SI_ana_F=CREA_CHAMP(OPERATION='AFFE',
                            TYPE_CHAM='ELGA_NEUT_F',
                            MODELE=MODELE,
                            PROL_ZERO='OUI',
                            AFFE=l_F,);


        # 2. Evaluation de la solution analytique aux points d'intégration

        __SanaCHAM=CREA_CHAMP(OPERATION='EVAL',
                           TYPE_CHAM='ELGA_NEUT_R',
                           CHAM_F=__SI_ana_F,
                           CHAM_PARA=__CHXG,
                          );

        # 3. Conversion du champ solution analytique en champ de contrainte

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur la liste des composantes (SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ)
        for sig in sig2func:
           ind=sig2ind[sig]
           # boucle sur la liste des groupes
           for ig, group in enumerate(GROUP_MA):
              # creation du mot-clef facteur pour le groupe
              # et le SIGM courants
              d_asse={}
              d_asse['GROUP_MA']=group
              d_asse['CHAM_GD']=__SanaCHAM
              d_asse['NOM_CMP']='X' + str(ind)
              d_asse['NOM_CMP_RESU']=sig
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_asse))

        __SI_ana_R=CREA_CHAMP(OPERATION='ASSE',
                           TYPE_CHAM='ELGA_SIEF_R',
                           MODELE=MODELE,
                           PROL_ZERO='OUI',
                           ASSE=l_F);

        # 4. création du champ différence entre les contraintes calculés et analytiques

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur les groupes
        for ig, group in enumerate(GROUP_MA):
           # boucles sur les composantes: SIXX, SIYY, SIZZ, SIXY, SIXZ, SIYZ
           for i in range(2*dime):
              # creation du mot-clef facteur pour le groupe
              # et le SIGM courants

              # * traitement des contraintes calculés
              d_asse={}
              d_asse['GROUP_MA']=group
              d_asse['CHAM_GD']=CHAM_GD
              d_asse['CUMUL']='OUI'
              d_asse['COEF_R']=1.
              d_asse['NOM_CMP']=l_SIGM[i]
              d_asse['NOM_CMP_RESU']=l_SIGM[i]
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_asse))

              # * traitement des contraintes analytiques
              d_asse={}
              d_asse['GROUP_MA']=group
              d_asse['CHAM_GD']=__SI_ana_R
              d_asse['CUMUL']='OUI'
              d_asse['COEF_R']=-1.
              d_asse['NOM_CMP']=l_SIGM[i]
              d_asse['NOM_CMP_RESU']=l_SIGM[i]
              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_asse))

        __SI_diff=CREA_CHAMP(OPERATION='ASSE',
                            TYPE_CHAM='ELGA_SIEF_R',
                            MODELE=MODELE,
                            PROL_ZERO='OUI',
                            ASSE=l_F);

        # 5. création d'un champ de deplacement nul partout
        # ce champ de deplacement est essentiel pour calculer les normes, mais n'aucun impact sur les resultats

        l_DDL=('DX', 'DY', 'DZ')

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur les groupes
        for ig, group in enumerate(GROUP_MA):
           # boucles sur les ddl DX, DY et DZ
           for i in range(dime):
              # creation du mot-clef facteur pour le groupe
              # et le ddl courants
              d_affe={}
              d_affe['GROUP_MA']=group
              d_affe['NOM_CMP']=l_DDL[i]
              d_affe['VALE']=0.

              # stockage du mot-clef facteur dans la liste
              l_F.append(_F(**d_affe))

        __U=CREA_CHAMP(OPERATION='AFFE',
                       TYPE_CHAM='NOEU_DEPL_R',
                       MAILLAGE=__MA,
                       AFFE=l_F);

        # 6. création d'un champ resultat a partir de champ de contrainte analytique
        __SIanaRES=CREA_RESU(OPERATION='AFFE',
                             TYPE_RESU='EVOL_NOLI',
                             NOM_CHAM='SIEF_ELGA',
                             COMPORTEMENT   = (_F(RELATION    = 'ELAS',
                                                  DEFORMATION = DEFORMATION,),),
                             AFFE=_F(CHAM_GD=__SI_ana_R,
                                     MODELE=MODELE,
                                     CHAM_MATER=CHAM_MATER,
                                     INST = (1.0),), );

        __SIanaRES=CREA_RESU(reuse=__SIanaRES,
                             OPERATION='AFFE',
                             TYPE_RESU='EVOL_NOLI',
                             NOM_CHAM='DEPL',
                             COMPORTEMENT   = (_F(RELATION    = 'ELAS',
                                                  DEFORMATION = DEFORMATION,),),
                             AFFE=_F(CHAM_GD=__U,
                                     MODELE=MODELE,
                                     CHAM_MATER=CHAM_MATER,
                                     INST = (1.0),),
                             );


        # 7. création d'un champ resultat a partir de champ de contrainte difference
        __SI_DIFFR=CREA_RESU(OPERATION='AFFE',
                             TYPE_RESU='EVOL_NOLI',
                             NOM_CHAM='SIEF_ELGA',
                             COMPORTEMENT   = (_F(RELATION    = 'ELAS',
                                                  DEFORMATION = DEFORMATION,),),
                             AFFE=_F(CHAM_GD=__SI_diff,
                                     MODELE=MODELE,
                                     CHAM_MATER=CHAM_MATER,
                                     INST = (1.0),), );

        __SI_DIFFR=CREA_RESU(reuse=__SI_DIFFR,
                             OPERATION='AFFE',
                             TYPE_RESU='EVOL_NOLI',
                             NOM_CHAM='DEPL',
                             COMPORTEMENT   = (_F(RELATION    = 'ELAS',
                                                  DEFORMATION = DEFORMATION,),),
                             AFFE=_F(CHAM_GD=__U,
                                     MODELE=MODELE,
                                     CHAM_MATER=CHAM_MATER,
                                     INST = (1.0),),
                             );


        # 8. calcul de l'energie a partir du champ de contraintes analytique

        __TanaSIG = POST_ELEM(RESULTAT=__SIanaRES,ENER_ELAS=_F(GROUP_MA=GROUP_MA), );

        # 9. calcul de l'energie a partir du champ de contraintes difference

        __TdiffSIG= POST_ELEM(RESULTAT=__SI_DIFFR,ENER_ELAS=_F(GROUP_MA=GROUP_MA), );

        #creation de la table finale

        tab = __TanaSIG.EXTR_TABLE()


        col_ref = getattr(tab, 'TOTALE')
        l_ref=col_ref.values()

        tab = __TdiffSIG.EXTR_TABLE()

        col_diff = getattr(tab, 'TOTALE')
        l_diff=col_diff.values()

        # assertion: les longueurs de l_ref et l_diff sont egales au nombre de groupes
        ASSERT( len(l_ref) == nb_group and len(l_diff) == nb_group )

        # calcul des normes en energie pour chaque groupe
        l_ref_norm=[]
        l_diff_norm=[]
        for i in range(nb_group):
            l_ref_norm.append(math.sqrt(l_ref[i]))
            l_diff_norm.append(math.sqrt(l_diff[i]))

        # ajout de normes en energie pour l'ensemble des groupes
        ref_norm_tot=math.sqrt(sum(l_ref))
        l_ref_norm.append(ref_norm_tot)

        diff_norm_tot=math.sqrt(sum(l_diff))
        l_diff_norm.append(diff_norm_tot)

        # ajout des energies pour l'ensemble des groupes
        l_ref.append(sum(l_ref))
        l_diff.append(sum(l_diff))

        # creation de la variable TITRE
        TITRE="ERREUR EN NORME ENERGIE"

        # destruction des objets temporaires pour le calcul de l'erreur en energie
        DETRUIRE(CONCEPT=_F(NOM=__SI_ana_F), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__SanaCHAM), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__SI_ana_R), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__SI_diff), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__U), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__SIanaRES), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__SI_DIFFR), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__TanaSIG), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__TdiffSIG), INFO=1)


    if(OPTION=='LAGR_RELA'):
        # le calcul de la norme L2 de la pression de contact sur une fissure XFEM n'est
        # pas encore diponible
        if lxfem:
           UTMESS('F', 'XFEM_14')

        # 1. création du champ de fonctions solution analytiques au points d'intégration

        # récuparation de la liste des fonctions correspondant à LAGS_C
        # si l'utilisateur n'a pas renseigné une fonction, on prend la fonction nulle
        l_LAGS=args['LAGS_C']
        if l_LAGS is None:
           l_LAGS=[__ZERO]*nb_group


        # assertion : ici, on a une et une seule fonction LAGS_C pour chaque groupe
        if len(l_LAGS) != nb_group:
            UTMESS('F', 'PREPOST_12', valk="LAGS_C")

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur les groupes
        for ig, group in enumerate(GROUP_MA):
            # récupération de la fonction LAGS_C pour le groupe courant

            LAGS=l_LAGS[ig]

            # creation du mot-clef facteur pour le groupe
            # courant
            d_affe={}
            d_affe['GROUP_MA']=group
            d_affe['NOM_CMP']='X3'
            d_affe['VALE_F']=LAGS
            # stockage du mot-clef facteur dans la liste
            l_F.append(_F(**d_affe))

        __PanaFG=CREA_CHAMP(OPERATION='AFFE',
                            TYPE_CHAM='ELGA_NEUT_F',
                            MODELE=MODELE,
                            PROL_ZERO='OUI',
                            AFFE=l_F,
                           );

        # 2. Evaluation de la solution analytique aux points d'intégration

        __PanaG=CREA_CHAMP(OPERATION='EVAL',
                           TYPE_CHAM='ELGA_NEUT_R',
                           CHAM_F=__PanaFG,
                           CHAM_PARA=__CHXG,
                          );

        # 3. Conversion du champ solution analytique en champ de déplacement
        # N.B.: L'intégration de la pression asocciée au ddl LAG_C donne 0 !
        #       On l'associe donc à un autre ddl choisi arbitrairement : DZ.

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur les groupes
        for ig, group in enumerate(GROUP_MA):

           # creation du mot-clef facteur pour le groupe
           # et le ddl courants
           d_asse={}
           d_asse['GROUP_MA']=group
           d_asse['CHAM_GD']=__PanaG
           d_asse['NOM_CMP']='X3'
           d_asse['NOM_CMP_RESU']='DZ'
           # stockage du mot-clef facteur dans la liste
           l_F.append(_F(**d_asse))

        __PanaR=CREA_CHAMP(OPERATION='ASSE',
                           TYPE_CHAM='ELGA_DEPL_R',
                           MODELE=MODELE,
                           PROL_ZERO='OUI',
                           ASSE=l_F);

        # 4. création d'un champ contenant les déplacements calculés sur les groupes considérés

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur les groupes
        for ig, group in enumerate(GROUP_MA):

           # creation du mot-clef facteur pour le groupe
           # et le ddl courants
           d_asse={}
           d_asse['GROUP_MA']=group
           d_asse['CHAM_GD']=CHAM_GD
           d_asse['NOM_CMP_RESU']='X3'
           d_asse['NOM_CMP']='LAGS_C'
           # stockage du mot-clef facteur dans la liste
           l_F.append(_F(**d_asse))

        __PcalN=CREA_CHAMP(OPERATION='ASSE',
                           TYPE_CHAM='NOEU_NEUT_R',
                           MAILLAGE=__MA,
                           ASSE=l_F);

        # 5. discrétisation des déplacements calculés aux points d'intégration

        __PcalG=CREA_CHAMP(OPERATION='DISC',
                           TYPE_CHAM='ELGA_NEUT_R',
                           MODELE=MODELE,
                           PROL_ZERO='OUI',
                           CHAM_GD=__PcalN,
                          );

        # 6. création du champ différence entre les déplacements calculés et analytiques

        # construction de la liste des mots-clefs facteur pour appeler CREA_CHAMP
        l_F=[]
        # boucle sur les groupes
        for ig, group in enumerate(GROUP_MA):

           # * traitement des déplacements calculés
           d_asse={}
           d_asse['GROUP_MA']=group
           d_asse['CHAM_GD']=__PcalG
           d_asse['CUMUL']='OUI'
           d_asse['COEF_R']=1.
           d_asse['NOM_CMP']='X3'
           d_asse['NOM_CMP_RESU']='DZ'
           # stockage du mot-clef facteur dans la liste
           l_F.append(_F(**d_asse))

           # * traitement des déplacements analytiques
           d_asse={}
           d_asse['GROUP_MA']=group
           d_asse['CHAM_GD']=__PanaG
           d_asse['CUMUL']='OUI'
           d_asse['COEF_R']=-1.
           d_asse['NOM_CMP']='X3'
           d_asse['NOM_CMP_RESU']='DZ'
           # stockage du mot-clef facteur dans la liste
           l_F.append(_F(**d_asse))

        __PdiffG=CREA_CHAMP(OPERATION='ASSE',
                            TYPE_CHAM='ELGA_DEPL_R',
                            MODELE=MODELE,
                            PROL_ZERO='OUI',
                            ASSE=l_F);

        # calcul de la norme L2 du deplacement pour la solution analytique et le champ difference, pour chaque groupe
        l_ref_norm=[]
        l_diff_norm=[]
        ref_norm_tot=0.
        diff_norm_tot=0.
        for group in GROUP_MA:
            # 8. calcul de la norme L2 du champ de déplacement analytique

            __TanaP =POST_ELEM(NORME=(_F(TYPE_NORM='L2',
                                           GROUP_MA=group,
                                           CHAM_GD=__PanaR,
                                           MODELE=MODELE,),));

            # extraction de la norme L2 du champ de déplacement analytique
            tab = __TanaP.EXTR_TABLE()

            col_ref = getattr(tab, 'VALE_NORM')
            l_ref=col_ref.values()
            ref=l_ref[0]

            # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement analytiques
            l_ref_norm.append(ref)

            # ajout e la contribution du groupe courant a la norme L2 du deplacement analytique totale
            ref_norm_tot+=ref**2

            # 9. calcul de la norme L2 du champ de déplacement différence

            __TdiffP=POST_ELEM(NORME=(_F(TYPE_NORM='L2',
                                           GROUP_MA=group,
                                           CHAM_GD=__PdiffG,
                                           MODELE=MODELE,),));

            # extraction de la norme L2 du champ de déplacement difference
            tab = __TdiffP.EXTR_TABLE()

            col_diff = getattr(tab, 'VALE_NORM')
            l_diff=col_diff.values()
            diff=l_diff[0]

            # ajout de la contribution du groupe courant a la liste des normes L2 des champs de déplacement difference
            l_diff_norm.append(diff)

            # ajout e la contribution du groupe courant a la norme L2 du deplacement difference totale
            diff_norm_tot+=diff**2

            # liberation des objets temporaires pour la prochaine iteration
            DETRUIRE(CONCEPT=_F(NOM=__TanaP), INFO=1)
            DETRUIRE(CONCEPT=_F(NOM=__TdiffP), INFO=1)

        # ajout de normes en energie pour l'ensemble des groupes
        ref_norm_tot=math.sqrt(ref_norm_tot)
        l_ref_norm.append(ref_norm_tot)

        diff_norm_tot=math.sqrt(diff_norm_tot)
        l_diff_norm.append(diff_norm_tot)

        # creation de la variable TITRE
        TITRE="ERREUR EN NORME L2 DE LA PRESSION"

        # destruction des objets temporaires pour le calcul de l'erreur en deplacement
        DETRUIRE(CONCEPT=_F(NOM=__PanaFG), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__PanaG), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__PanaR), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__PcalN), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__PcalG), INFO=1)
        DETRUIRE(CONCEPT=_F(NOM=__PdiffG), INFO=1)

    # ici, quelle que soit la norme considérée, les objets suivants sont définis :
    #  * l_diff_norm : liste des normes du champ différence, pour chaque groupe +
    #                  norme du champ différence sur l'union des groupes

    # creation de la liste GROUP_MA + "TOTAL"
    l_group=list(GROUP_MA)
    l_group.append("TOTAL")

    if (OPTION == 'ENER_RELA'):
       tabout=CREA_TABLE(LISTE=(_F(LISTE_K=l_group,
                                  PARA="GROUP_MA"),
                                _F(LISTE_R=l_diff,
                                  PARA   ="DIFFERENCE",),
                                _F(LISTE_R=l_ref,
                                  PARA   ="REFERENCE",),
                                ),
                         TITRE=TITRE,
                         );
    else:
       tabout=CREA_TABLE(LISTE=(_F(LISTE_K=l_group,
                                  PARA="GROUP_MA"),
                                _F(LISTE_R=l_diff_norm,
                                  PARA   ="DIFFERENCE",),
                                _F(LISTE_R=l_ref_norm,
                                  PARA   ="REFERENCE",),
                                ),
                         TITRE=TITRE,
                         );

    # on ne calcule l'erreur relative que si la reference est non nulle
    if ref_norm_tot > 1.e-16:
       __Terr=CREA_TABLE(LISTE=(_F(LISTE_K=("TOTAL"),
                                   PARA="GROUP_MA"),
                                _F(LISTE_R=(diff_norm_tot/ref_norm_tot),
                                   PARA   ="ERREUR RELATIVE")
                               )
                        )

       tabout=CALC_TABLE(reuse=tabout,
                         TABLE=tabout,
                         ACTION =_F(OPERATION="COMB",
                                    TABLE=__Terr,
                                    NOM_PARA="GROUP_MA"),
                         TITRE=TITRE,
                        )

    # destruction des objets temporaires generiques
    # N.B.: __MA est une reference au maillage, il ne faut pas le detruire !
    DETRUIRE(CONCEPT=_F(NOM=__CHXN), INFO=1)
    DETRUIRE(CONCEPT=_F(NOM=__CHXG), INFO=1)
    DETRUIRE(CONCEPT=_F(NOM=__ZERO), INFO=1)


    return ier
Exemplo n.º 7
0
def bloc_cara(typ_carel, l_elem, epx, group, select, directive, mot_cle_aster,
              mot_cle_epx, cara_aster, cara_epx, coef_mult, is_vale_aster,
              mode_epx, mode_from_cara, titre, verif,
              dic_gr_cara_supp):
    """
        Analyse les données contenues dans une liste d'instances 'l_elem' du
        mot clé facteur 'typ_carel' de AFFE_CARA_ELEM.
        'l_elem' contient la plupart du temps un seul élément, sauf dans le
        cas de typ_carel='DISCRET'.
    """
    l_elem = tolist(l_elem)
    mot_cle_epx_select = None
    l_cara = []
    l_vale = []
    mot_cle_ignor = ['GROUP_MA']
    for elem in l_elem:
        for i_dic, sele in enumerate(select):
            # sélection de la bonne traduction
            good_trad = True
            for cle in sele.keys():
                if elem.has_key(cle):
                    if sele[cle] is not None:
                        valcle = elem[cle]
                        if type(elem[cle]) is list or type(elem[cle]) is tuple:
                            if len(elem[cle]) == 1:
                                valcle = elem[cle][0]
                        if valcle != sele[cle]:
                            good_trad = False
                            break
            if not good_trad:
                continue
            # la traduction est sélectionnée
            mot_cle_ok = []
            mot_cle_ok.extend(sele.keys())
            if mot_cle_aster[i_dic]:
                # le mot-clé est présent en tant que mot-clé
                if elem.has_key(mot_cle_aster[i_dic]):
                    val_cle = elem[mot_cle_aster[i_dic]]*coef_mult[i_dic]
                    vale = []
                    cara = []
                    if not mot_cle_aster[i_dic] in mot_cle_ok:
                        mot_cle_ok.append(mot_cle_aster[i_dic])
                # le mot-clé est la valeur de 'CARA'
                else:
                    cara_in = tolist(elem['CARA'])
                    ASSERT(len(cara_in) == 1)
                    ASSERT(cara_in[0] == mot_cle_aster[i_dic])
                    if not 'CARA' in mot_cle_ok:
                        mot_cle_ok.append('CARA')
                    if not 'VALE' in mot_cle_ok:
                        mot_cle_ok.append('VALE')
                    valeur = tolist(elem['VALE'])
                    if cara_epx[i_dic]:
                        # is_vale_aster est obligatoire dans ce cas
                        ASSERT(is_vale_aster[i_dic])
                        cara = list(cara_epx[i_dic])
                        vale = [None] * len(cara)
                        k_valeur = 0
                        for i_log, logi in enumerate(is_vale_aster[i_dic]):
                            if logi:
                                vale[i_log] = valeur[k_valeur]*coef_mult[i_dic][i_log]
                                k_valeur += 1
                        val_cle = ''
                    else:
                        ASSERT(len(valeur) == 1)
                        val_cle = valeur[0]*coef_mult[i_dic]
                        vale = []
                        cara = []
            # couple CARA/VALE avec plusieurs caractéristiques
            else:
                if not 'CARA' in mot_cle_ok:
                    mot_cle_ok.append('CARA')
                if not 'VALE' in mot_cle_ok:
                    mot_cle_ok.append('VALE')
                val_cle = ''
                cara_in = tolist(elem['CARA'])
                vale_in = tolist(elem['VALE'])
                cara = cara_epx[i_dic]
                vale = [None] * len(cara)
                for i, car in enumerate(cara_in):
                    if not car in cara_aster[i_dic]:
                        UTMESS('F', 'PLEXUS_8', valk=(car, typ_carel))
                    val = vale_in[i]
                    index = cara_aster[i_dic].index(car)
                    vale[index] = val*coef_mult[i_dic][index]
            # traitement des doublons (cas ou aster est plus riche qu'EPX
            # on verifie que les doublons ont la meme valeur
            i = 0
            while i< len(cara):
                car1 = cara[i]
                while cara.count(car1)>1:
                    index = cara[i+1:].index(car1)
                    index+= i+1
                    if vale[i] == vale[index]:
                        cara.pop(index)
                        vale.pop(index)
                    else:
                        UTMESS('F','PLEXUS_16', valk = [typ_carel, mot_cle_aster[i_dic]],
                               vali = [i+1, index+1])
                i+=1

#           verif des mots-clés autorisés
            mc_verif = []
            if verif[i_dic]:
                mc_verif = verif[i_dic].keys()
            for key in elem.keys():
                if key in mot_cle_ok:
                    continue
                elif key in mot_cle_ignor:
                    continue
                elif key in mc_verif:
                    continue
                else:
                    UTMESS('F', 'PLEXUS_45', valk=[key, typ_carel])

            # on complete VALE avec des donnees provenant d'ailleurs
            if None in vale:
                for i, val in enumerate(vale):
                    if val is None:
                        car = cara[i]
                        # s'il y a en même temps K_T_D_L et A_T_D_L sur des DISCRET en repère local
                        # VX, VY et VZ vont être présents deux fois : on ne les ajoutes pas dans ce cas
                        if car in l_cara:
                            cara[i] = None
                            continue
                        if not dic_gr_cara_supp.has_key(group):
                            UTMESS(
                                'F', 'PLEXUS_12', valk=(car, typ_carel, group))
                        if not car in dic_gr_cara_supp[group]:
                            UTMESS(
                                'F', 'PLEXUS_12', valk=(car, typ_carel, group))
                        if type(dic_gr_cara_supp[group][car]) == int:
                            vale[i] = dic_gr_cara_supp[group][car]*int(coef_mult[i_dic][i])
                        else:
                            vale[i] = dic_gr_cara_supp[group][car]*coef_mult[i_dic][i]
            while None in cara:
                cara.remove(None)
                vale.remove(None)
            #
            if verif[i_dic]:
                for mc_aster in verif[i_dic].keys():
                    if verif[i_dic][mc_aster] is None:
                        continue
                    elif elem.has_key(mc_aster):
                        if elem[mc_aster] not in verif[i_dic][mc_aster]:
                            liste_ok = ', '.join(verif[i_dic][mc_aster])
                            UTMESS('F', 'PLEXUS_4', valk=(typ_carel, mc_aster,
                                                          elem[mc_aster], liste_ok))
                    else:
                        UTMESS('F', 'PLEXUS_56', valk=(typ_carel, mc_aster))

            if mot_cle_epx_select == None:
                mot_cle_epx_select = mot_cle_epx[i_dic]
                directive_select = directive[i_dic]
                val_cle_select = val_cle
                titre_select = titre[i_dic]
                mode_epx_select = mode_epx[i_dic]
            else:
                if (mot_cle_epx_select != mot_cle_epx[i_dic] or
                    directive_select != directive[i_dic] or
                    val_cle_select != val_cle or
                    titre_select != titre[i_dic] or
                        mode_epx_select != mode_epx[i_dic]):
                    raise Exception('Erreur dev : Incohérence des donnees')
            l_cara.extend(cara)
            l_vale.extend(vale)
    if mot_cle_epx_select == None:
        UTMESS('F','PLEXUS_52',valk = [typ_carel])
    bloc_donnees = BLOC_DONNEES(mot_cle_epx_select, l_group=group,
                                val_cle=val_cle_select,
                                cara=l_cara, vale=l_vale, titre=titre_select)
    epx[directive_select].add_bloc(bloc_donnees)
    if mode_epx_select is not None:
        if not mode_from_cara.has_key(group):
            mode_from_cara[group] = mode_epx_select
        else:
            if mode_from_cara[group] != mode_epx_select:
                UTMESS('F', 'PLEXUS_9', valk=(mode_from_cara[group],
                                              mode_epx_select, group))
    return epx, mode_from_cara