Exemplo n.º 1
0
    def _choix_interspectre(self, root, **args):
        """ Choix de l'interspectre"""

        self.var_resu_fonc = StringVar()  # le nom de l'interspectre
        self.typ_resu_fonc = StringVar()  # le type de 'interspectre
        fra = Frame(root, args)
        desc = "Interspectre en fonctionnement"
        Label(fra, text=desc).grid(row=1, column=0, sticky='w')

        options = self.objects.get_inter_spec_name()
        self.menu_resu_fonc = MyMenu(fra, options, self.var_resu_fonc,
                                     self._get_inter_spec)
        self.menu_resu_fonc.grid(row=1, column=1)
        Label(fra, text="Type champ",).grid(row=1, column=2)
        opt_cham = ['DEPL', 'VITE', 'ACCE']
        typ_cham = MyMenu(fra, opt_cham, self.typ_resu_fonc)
        self.typ_resu_fonc.set('DEPL')
        typ_cham.grid(row=1, column=3, sticky='e')

        return fra
Exemplo n.º 2
0
class InterfaceParametres(Frame):

    """!Interface principale de l'outil de projection des modes
    expérimentaux sur les modes numériques

    permet la sélection et de calcul des modes en air et écoulement"""

    def __init__(self,
                 root,
                 objects,
                 macro,
                 mess,
                 ):
        """!Constructeur
        """

        Frame.__init__(
            self, root, relief='sunken', borderwidth=1)  # Première frame

        self.mess = mess
        self.root = root
        self.logiciel = StringVar()
        self.salome_port = IntVar()
        self.machine_locale_name = self.get_machine_name()
        self.type_visu = StringVar()
        self.user = StringVar()
        self.protocole = StringVar()
        self.machine_name = self.machine_locale_name
        self.salome_widgets = []
        self.distant_widgets = []
        self.protocole_ok = None
        self.logiciel_courbes = None

        self.macro = macro
        self.objects = objects
        self.param_visu = self
        self.is_resu1 = IntVar()
        self.is_resu2 = IntVar()
        self.use_nume_mass = IntVar()
        self.proj_champ_meth = StringVar()
        self.proj_svd_param = StringVar()
        self.calculs = CalcEssaiExpansion(macro, mess, objects)
        self.type_resu_exp = StringVar()
        self.term = []
        self.mac_windows = []
        self.afreq = None
        self.anum = None
        self.resu_num = None   # base d'expansion (instance de ModeMeca)
        self.resu_exp = None   # donnees exp (instance de ModeMeca ou de DynaHarmo)
        self.interface_param()

    def setup(self):
        """!Appelée par le gestionnaire de tab lors de l'affichage"""

        mdo = self.objects
        mdo.recup_objects()

        self.menu_resu1.update(
            mdo.get_resultats_name(), self.var_resu1, self.visu1_changed)
        self.menu_resu2.update(
            mdo.get_resultats_name(), self.var_resu2, self.visu2_changed)
        pass

    def teardown(self):
        """!Appelée par le gestionnaire de tab lors
           du masquage (passage à un autre tab)"""
        return

    def _observabilite_changed(self):
        nom_resu = self.nom_obs_resu.get()
        if nom_resu.strip() != 'Choisir':
            resu = self.objects.get_resultats(nom_resu)

        nom_modele = self.nom_obs_modele.get()
        if nom_modele.strip() != 'Choisir':
            modele = self.objects.get_model(nom_modele)
            self.obs_noeuds.set_resultat(resu.modele)
            self.obs_mailles.set_resultat(resu.modele)

    def interface_param(self):
        """!Fonction principale de création de l'interface"""

        self.columnconfigure(0, weight=1)
        self.rowconfigure(2, weight=1)
        l = Label(self, text=u" CALC_ESSAI : Paramètres de visualisation",
                  padx=270, pady=5, font=("Helvetica", "16"))
        l.grid(row=0, sticky='nsew')

        select_box = self.interface_parametres(self)
        select_box.grid(row=1, sticky='nsew')

        visu_param = self.interface_visu(self)
        visu_param.grid(row=3, sticky='nsew')

        self.main = self

    def interface_selection(self, root):

        self.var_resu_num = StringVar()
        self.menu_resu_num = MyMenu(
            f, options=self.objects.get_mode_meca_name(),
            var=self.var_resu_num, cmd=self.num_changed)

        self.var_resu_exp = StringVar()
        self.menu_resu_exp = MyMenu(
            f, options=self.objects.get_resultats_name(),
            var=self.var_resu_exp, cmd=self.exp_changed)

        return f

    def interface_visu(self, root):
        """!Création de l'interface de visualisation

        permet de choisir d'afficher les matrices MAC ou les modes avec gmsh
        gère la compatibilité des choix de l'utilisateur (les calculs de MAC
        ne sont pas tous possibles)
        """

        mdo = self.objects

        f = Frame(root, relief='sunken', borderwidth=1)
        Label(f, text="   ").grid(
            row=0, column=1, columnspan=3, sticky='w' + 'e')
        Label(f, text="   ").grid(
            row=2, column=1, columnspan=3, sticky='w' + 'e')
        f.columnconfigure(0, weight=3)
        f.columnconfigure(1, weight=3)

        f1 = Frame(f)
        f1.grid(row=1, column=0, sticky='ew')
        f1.columnconfigure(1, weight=4)
        f1.columnconfigure(2, weight=4)

        bir1 = Checkbutton(f1, variable=self.is_resu1, command=self.cb_changed)
        bir1.grid(row=0, column=0, sticky='e', padx=20)
        bir2 = Checkbutton(f1, variable=self.is_resu2, command=self.cb_changed)
        bir2.grid(row=1, column=0, sticky='e', padx=20)

        Label(f1, text=u"Résultat 1").grid(row=0, column=1, sticky='w')
        self.var_resu1 = StringVar()
        self.menu_resu1 = MyMenu(f1, options=mdo.get_resultats_name(),
                                 var=self.var_resu1, cmd=self.visu1_changed)
        self.menu_resu1.grid(row=0, column=2, sticky='ew', padx=20)

        Label(f1, text=u"Résultat 2").grid(row=1, column=1, sticky='w')
        self.var_resu2 = StringVar()
        self.menu_resu2 = MyMenu(f1, options=mdo.get_resultats_name(),
                                 var=self.var_resu2, cmd=self.visu2_changed)
        self.menu_resu2.grid(row=1, column=2, sticky='ew', padx=20)

        f2 = Frame(f)
        f2.grid(row=1, column=1)

        self.mac_button = Button(
            f2, text="    MAC    ", command=self.view_macs, state='disabled')
        self.mac_button.grid(row=1, column=2, sticky='ew')
        self.phi_button = Button(
            f2, text=u"Déformées", command=self.view_modes, state='disabled')
        self.phi_button.grid(row=2, column=2, sticky='ew')
        self.frf_button = Button(f2, text="    FRF    ", command=self.view_frf)
        self.frf_button.grid(row=3, column=2, sticky='ew')
        self.frf_button = Button(
            f1, text=" Observation ", command=self.view_obs_1)
        self.frf_button.grid(row=0, column=3, sticky='ew')
        self.frf_button = Button(
            f1, text=" Observation ", command=self.view_obs_2)
        self.frf_button.grid(row=1, column=3, sticky='ew')

        return f

    def visu1_changed(self):
        """ desactivation du bouton concernant le visu1"""
        self.is_resu1.set(1)
        self.check_state()

    def visu2_changed(self):
        """ desactivation du bouton concernant le visu1"""
        self.is_resu2.set(1)
        self.check_state()

    def cb_changed(self):
        self.check_state()

    def check_state(self):
        """Verifie la compatibilite des bases pour le MAC et l'existence
           des donnees necessaires pour la visu des deformees et des FRF"""
        mdo = self.objects

        # Y a-t-il un MAC a calculer ?
        if (self.is_resu1.get() and not self.is_resu2.get()) or (self.is_resu2.get() and not self.is_resu1.get()):
            self.mac_button.configure(state='normal')
        elif self.is_resu1.get() and self.is_resu2.get():
            resu1 = mdo.get_resultats(self.var_resu1.get())
            resu2 = mdo.get_resultats(self.var_resu2.get())
            if resu1.modele_name.strip() and resu1.modele_name == resu2.modele_name:
                self.mac_button.configure(state='normal')
            else:
                self.mac_button.configure(state='disabled')
        else:
            self.mac_button.configure(state='disabled')

        # Y a-t-il des deformees a representer ?
        if self.is_resu1.get() or self.is_resu2.get():
            self.phi_button.configure(state='normal')
        else:
            self.phi_button.configure(state='disabled')

    def view_frf(self):
        """lancement d'une fenetre de visualisation des frf"""
        mdo = self.objects
        resu1 = None
        resu2 = None
        if self.is_resu1.get():
            resu1 = mdo.get_resultats(self.var_resu1.get())
        if self.is_resu2.get():
            resu2 = mdo.get_resultats(self.var_resu2.get())
        fenetre = DispFRFDialogue(
            self.mess, self.objects, self.param_visu, resu1, resu2)

    def view_obs_1(self):
        if self.is_resu1.get():
            self.view_obs(self.var_resu1)
        else:
            self.mess.disp_mess(u"Choisir un résultat")
            return
        self.setup()

    def view_obs_2(self):
        if self.is_resu2.get():
            self.view_obs(self.var_resu2)
        else:
            self.mess.disp_mess(u"Choisir un résultat")
            return
        self.setup()

    def view_obs(self, var_resu):
        """lancement d'une fenetre d'observation"""
        mdo = self.objects
        resu = mdo.get_resultats(var_resu.get())
        fenetre = DispObs(self, self.mess, self.objects, resu)
        fenetre.set_resu(resu.nom)

    def view_modes(self, *args):
        """!Visualisation des modes par GMSH ou Salome"""

        mdo = self.objects
        l_resultat = []
        l_modele = []
        if self.is_resu1.get():
            resu1 = mdo.get_resultats(self.var_resu1.get())

            l_resultat.append(resu1.obj)
        if self.is_resu2.get():
            resu2 = mdo.get_resultats(self.var_resu2.get())
            l_resultat.append(resu2.obj)
        term = self.param_visu.visu_resu(resultat=l_resultat)

        self.term.append(term)
        return

    def view_macs(self):
        """!Creation d'une nouvelle fenetre de visu MAC"""
        mdo = self.objects
        resu1 = None
        resu2 = None
        if self.is_resu1.get() and self.is_resu2.get():
            resu1 = mdo.get_resultats(self.var_resu1.get())
            resu2 = mdo.get_resultats(self.var_resu2.get())
        elif self.is_resu1.get():
            resu1 = mdo.get_resultats(self.var_resu1.get())
            resu2 = mdo.get_resultats(self.var_resu1.get())
        elif self.is_resu2.get():
            resu1 = mdo.get_resultats(self.var_resu2.get())
            resu2 = mdo.get_resultats(self.var_resu2.get())

        mac = self.calculs.calc_mac_mode(resu1, resu2, norme=None)

        self.param_visu.visu_mac(mac, resu1, resu2)

    def activate_salome_widgets(self):
        StateActivate(self.salome_widgets)

    def desactivate_salome_widgets(self):
        StateDesactivate(self.salome_widgets)

    def interface_parametres(self, root):
        """!Création de l'interface de choix des logiciels de visualisation
        On permet à l'utilisateur de choisir Gmsh/Xmgrace ou Salome
        """

        main_param = Frame(root)
        main_param.rowconfigure(1, weight=1)
        main_param.columnconfigure(0, weight=1)

        f = Frame(main_param, relief='sunken', borderwidth=1)
        # les parametres vont dans 'f'
        logiciels_frame = Frame(f, borderwidth=4)

        label_parametres_salome = Label(
            logiciels_frame, text=u"Paramètres Salome")
        label_parametres_salome.grid(row=2, column=1, columnspan=2)
        self.salome_widgets.append(label_parametres_salome)

        label_port = Label(logiciels_frame, text=u"Port")
        label_port.grid(row=3, column=1, sticky='w')
        self.salome_widgets.append(label_port)

        entry_salome_port = Entry(
            logiciels_frame, textvariable=self.salome_port)
        entry_salome_port.grid(row=3, column=2)
        self.salome_widgets.append(entry_salome_port)
        self.salome_port.set(self.get_runnig_salome_port())
        self.ce_salome = None

        liste_etudes = StudyList(
            logiciels_frame, self, u"choix de l'étude Salomé")
        liste_etudes.grid(row=4, column=2, sticky='w')
        self.salome_widgets.append(liste_etudes.liste)
        self.salome_widgets.append(liste_etudes.titre)
        liste_etudes.actualiser()

        label_choix_logiciel = Label(
            logiciels_frame, text=u"Choix du logiciel")
        label_choix_logiciel.grid(row=0, column=0, columnspan=3)
        button_gmsh = Radiobutton(
            logiciels_frame, text=u"Gmsh/Xmgrace", value="Gmsh/Xmgrace", variable=self.logiciel,
                                  command=self.desactivate_salome_widgets)
        button_gmsh.grid(row=1, column=0, sticky='w')

        button_salome = Radiobutton(
            logiciels_frame, text=u"Salomé", value="Salome", variable=self.logiciel,
            command=self.activate_salome_widgets)
        button_salome.grid(row=2, column=0, rowspan=3, sticky='w')

        self.logiciel.set("Salome")

        logiciels_frame.grid(row=1)

        f.grid(row=1, sticky='w' + 'e' + 's' + 'n')
        return main_param

    def get_user(self):
        import getpass
        user = getpass.getuser()
        return user

    def get_machine_name(self):
        """! Recupere le nom de la machine distante pour les parametres corba"""
        # on retourne le nom de la machine locale
        # XXX on ne peut pas utiliser un salome distant,
        #     il faudrait un utilisateur et un chemin
        import socket
        machine_name = socket.gethostname()
        return machine_name

    def is_salome_launched(self):
        """! Determine si Salome est lance"""
        ok = False
        ret = os.system("ps auxw | grep -v grep | grep omniNames > /dev/null")
        if ret != 256:
            # Salome est lance
            ok = True
        return ok

    def get_runnig_salome_port(self):
        """! Recupere le port CORBA sur lequel est lance Salome pour les parametres corba"""
        salome_port = 2810
        if self.is_salome_launched():
            try:
                cmd = "ps auxw | grep -v grep | grep omniNames"
                p = Popen([cmd], shell=True, stdout=PIPE)
                data = p.communicate()[0]
                # On recupere la derniere ligne de ps pour avoir le dernier
                # numero de port
                l_data = data.split("\n")
                last_line = l_data[-2]
                omniNames_params = last_line.split(" ")
                idx = omniNames_params.index("-start") + 1
                salome_port = int(omniNames_params[idx])
            except:
                msg = u"Problème lors de la détermination du port Salome.\n"
                msg += u"Veuillez déterminer manuellement le port de Salome, en tapant ceci dans l'interpréteur python embarqué de Salome:\n"
                msg += u"import NSparam\n"
                msg += u"NSparam.getNSparams()"
                self.mess.disp_mess(msg)
        return salome_port

    def save_parameters(self, do_check_protocole=True):
        """! Sauvegarde les parametres dans une classe parente pour qu'ils soient communs a tous les onglets """
        self.machine_name = self.machine_locale_name

    def get_logiciel(self):
        self.save_parameters()
        if self.logiciel.get() == "Gmsh/Xmgrace":
            return CalcEssaiGmsh(self.mess)
        else:
            if self.ce_salome:
                return self.ce_salome
            else:
                return CalcEssaiSalome(
                    self.mess, self.machine_name, self.salome_port.get(),
                    self.user.get(), self.protocole.get(),
                    self.protocole_ok, self)
        pass

    def get_logiciel_courbes(self):
        # Les courbes sont transferees par CORBA
        # => Pas besoin de verifier le protocole rcp/scp
        self.save_parameters(do_check_protocole=False)
        if self.logiciel.get() == "Gmsh/Xmgrace":
            return CalcEssaiXmgrace()
        else:
            if self.ce_salome_courbes:
                return self.ce_salome_courbes
            else:
                return CalcEssaiSalomeCourbes(self.mess, self.machine_name, self.salome_port.get(), self)
        pass

    def visu_studylist(self):
        self.ce_salome = CalcEssaiSalome(
            self.mess, self.machine_name, self.salome_port.get(),
            self.user.get(), self.protocole.get(),
            self.protocole_ok, self)

        self.ce_salome_courbes = CalcEssaiSalomeCourbes(
            self.mess, self.machine_name, self.salome_port.get(), self)

        studylist = self.ce_salome.studylist()
        return studylist

    def set_study(self, study):
        self.ce_salome.study_name = study
        self.ce_salome_courbes.study_name = study
        self.mess.disp_mess(
            u"Les courbes et vues seront affichées dans l'étude Salomé " + study)

    # fonction proxy vers le bon logiciel
    def visu_resu(self, resultat, nume_mode=None):
        logiciel = self.get_logiciel()
        self.param_visu.type_visu.set('deformee')
        term = logiciel.visu_resu(resultat, nume_mode)
        return term

    def visu_mac(self, mac, resu1, resu2):
        logiciel = self.get_logiciel()
        term = logiciel.visu_mac(mac, resu1, resu2)
        return term

    def visu_courbe(
        self, l_x, ll_y, couleur=None, titre='Courbe', l_legende=None,
        legende_x="Abscisses", legende_y="Ordonnées",
            unite_x="ua", unite_y="ua"):
        self.logiciel_courbes = self.get_logiciel_courbes()
        self.logiciel_courbes.affiche(l_x, ll_y,
                                      couleur, titre,
                                      l_legende,
                                      legende_x, legende_y,
                                      unite_x, unite_y)
        pass

    def quit(self):
        for term in self.term:
            if term is not None:
                term.Fermer()
Exemplo n.º 3
0
class InterfaceCouplage(Frame):

    def __init__(self, root, modif_struct, param_visu, mess):
        """!Creation de l'interface pour le couplage des deux modeles : mesure condense / modification

        """
        Frame.__init__(self, root, relief='sunken', borderwidth=1)
        self.root = root
        self.modif_struct = modif_struct
        self.param_visu = param_visu
        self.mess = mess
        self.term = []

        # Titre du panneau
        # ----------------
        Label(self, text="Couplage modification / modele condense",
              bg='#f0f0f0', font=self.root.font2,
              ).grid(row=0, column=0, padx=60, columnspan=3, sticky='new')

        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        # self.columnconfigure(2,weight=1)
        self.rowconfigure(1, weight=1)

        # Parametres de PROJ_MESU_MODAL pour le couplage
        # ----------------------------------------------
        f1 = Frame(self, relief='sunken', borderwidth=1)
        f1.rowconfigure(0, weight=1)
        f1.grid(row=1, column=0, sticky='nsew', padx=60)

        Label(f1, text=" Parametres de PROJ_MESU_MODAL",
              bg='#f0f0f0').grid(row=0, column=0, sticky='nw')

        self.var_expans_param_frame_visible = IntVar()
        Checkbutton(f1, text="Reglages",
                    command=self.display_expans_param_frame,
                    variable=self.var_expans_param_frame_visible,
                    indicatoron=0).grid(row=1, column=1, sticky='e')

        self.expans_param_frame = frm1 = Toplevel()
        frm1.rowconfigure(0, weight=1)
        frm1.columnconfigure(0, weight=1)

        self.param_proj_mesu = ParamProjMesuModal(
            frm1, "Parametres de PROJ_MESU_MODAL")
        self.param_proj_mesu.grid(row=0, column=0, sticky='nsew')

        frm1.protocol("WM_DELETE_WINDOW", self.hide_expans_param_frame)
        Button(frm1, text="OK", command=self.hide_expans_param_frame).grid(
            row=1, column=0)
        frm1.withdraw()

        # Frame de parametrage du couplage : calcul modal
        # -----------------------------------------------
        f2 = Frame(self, relief='sunken', borderwidth=1)
        f2.rowconfigure(0, weight=1)
        f2.grid(row=2, column=0, sticky='nsew', padx=60)

        Label(f2, text="Calcul modal sur le modele couple",
              bg='#f0f0f0').grid(row=0, column=0, sticky='nw')

        Label(f2, text="Critère de recherche des modes ").grid(row=1, column=0, sticky='w')
        self.var_couplage_param_frame_visible = IntVar()
        Checkbutton(f2, text="Reglages",
                    command=self.display_couplage_param_frame,
                    variable=self.var_couplage_param_frame_visible,
                    indicatoron=0).grid(row=1, column=1, sticky='e')

        self.couplage_param_frame = frm2 = Toplevel()
        frm2.rowconfigure(0, weight=1)
        frm2.columnconfigure(0, weight=1)

        self.param_simult_modes_couple = ParamModelCouple(frm2, "Modele couple")
        self.param_simult_modes_couple.grid(row=0, column=0, sticky='nsew')

        frm2.protocol("WM_DELETE_WINDOW", self.hide_couplage_param_frame)
        Button(frm2, text="OK", command=self.hide_couplage_param_frame).grid(
            row=1, column=0)
        frm2.withdraw()

        f3 = Frame(self, borderwidth=1)
        f3.grid(row=3, column=0, padx=60)
        self.button_condensation = Button(f3, text='Calculer',
                                          command=self.calc_condensation)
        self.button_condensation.grid(row=0, column=0, sticky="es")

        f4 = Frame(self, relief='sunken', borderwidth=1)
        f4.rowconfigure(0, weight=1)
        # f4.grid(row=1,column=2,rowspan=3,sticky='nsew',padx=60)
        f4.grid(row=1, column=2, rowspan=4, sticky='nsew', padx=60)

        self.liste_resu = ModeFreqList(f4, "Frequences structure modifiee")
        self.liste_resu.grid(row=0, column=0, sticky='nsew')

        # Frame pour calcul de critere de qualite de la base d'expansion
        # -----------------------------------------------
        f5 = Frame(self, relief='sunken', borderwidth=1)
        f5.rowconfigure(0, weight=1)
        f5.grid(row=4, column=0, sticky='nsew', padx=60, pady=30,)

        Label(f5, text="Qualite de la base expansion",
              bg='#f0f0f0').grid(row=0, column=0, sticky='nw')

        self.dic_mac_meth = {
            "MAC": "Calcul de MAC classic",
            "IERI": "Critere IERI",
        }

        Label(f5, text="Critere").grid(row=1, column=0, sticky='w')
        self.mac_meth = StringVar()
        self.menu_mac_meth = MyMenu(f5, self.dic_mac_meth.keys(),
                                    self.mac_meth,
                                    self.mac_changed)
        self.menu_mac_meth.grid(row=1, column=1, sticky='e')

        Label(f5, text="Ponderation").grid(row=2, column=0, sticky='w')
        self.crit_ponder = StringVar()
        self.menu_ponder = MyMenu(f5, ['SANS', 'RIGIDITE', 'MASSE'],
                                  self.crit_ponder,
                                  self.choix_ponder)
        self.menu_ponder.grid(row=2, column=1, sticky='e')

        Button(f5, text="Valider", command=self.indic_qualite).grid(row=3,
                                                                    column=2,
                                                                    sticky='e')

        # Affichage de MAC_MODE / comparaison frequences
        # ---------------------
        f = Frame(self, relief='sunken', borderwidth=1)
        # f.grid(row=4,column=1,columnspan=2,pady =10,sticky='nsew')
        f.grid(row=6, column=0, padx=60, pady=10, sticky='nsew')
        f.rowconfigure(0, weight=1)
        f.columnconfigure(0, weight=1)

        self.mw = MacWindowFrame(
            f, "Critere de qualite de la base", "Frequences propres", "(structure modifiee)")
        self.mw.grid(row=1, column=0, columnspan=3, sticky='nsew')

        return

    def setup(self, mdo):
        pass

    def display_couplage_param_frame(self):
        state = self.var_couplage_param_frame_visible.get()
        if state:
            self.couplage_param_frame.deiconify()
        else:
            self.couplage_param_frame.withdraw()

    def display_expans_param_frame(self):
        state = self.var_expans_param_frame_visible.get()
        if state:
            self.expans_param_frame.deiconify()
        else:
            self.expans_param_frame.withdraw()

    def hide_couplage_param_frame(self):
        self.var_couplage_param_frame_visible.set(0)
        self.couplage_param_frame.withdraw()

    def hide_expans_param_frame(self):
        self.var_expans_param_frame_visible.set(0)
        self.expans_param_frame.withdraw()

    def notify_expans_ok(self):
        mdo = self.root.objects
        mstruct = self.root.modifstruct

    def refresh_list_resu(self):
        resu = self.modif_struct.modes_couple
        self.liste_resu.set_resu(resu)

    def _can_set_modif_struct_para(self):
        """Renvoit True si tous les paramêtres pour lancer le calcul
        sur la stucture modifiée ont pu être obtenu."""
        expans = self.root.expansion
        disp_mess = self.root.mess.disp_mess
        retour = True

        # resultat experimentaux
        resu_exp_name = expans.var_resu_exp.get()
        try:
            self.modif_struct.find_experimental_result_from(resu_exp_name)
        except KeyError:
            disp_mess("Il faut fournir les donnees experimentales")
            retour = False
        # caracteristiques du modele support
        modlsup_name = expans.var_modl_sup.get()
        try:
            self.modif_struct.find_support_modele_from(modlsup_name)
        except KeyError:
            disp_mess("Il faut donner le modele support")

        grno_capt = expans.capteur.get_selected()
        self.modif_struct.set_sensor_groups(grno_capt)
        grno_iface = expans.iface.get_selected()
        self.modif_struct.set_interface_groups(grno_iface)

        modes_ide = expans.liste_exp.get_selection()
        if not modes_ide:
            disp_mess(u"Il faut sélectionner des modes "
                      u"du modèle experimental pour la condensation")
            retour = False
        else:
            self.modif_struct.set_modes_ide(modes_ide)

        modes_expansion = [int(m) for m in expans.liste_sup.get_selection()]
        if not modes_expansion:
            disp_mess(u"Il faut sélectionner des modes "
                      u"de la base d'expansion pour la condensation")
            retour = False
        else:
            self.modif_struct.set_modes_expansion(modes_expansion)

        choix = self.param_simult_modes_couple.var_meth_modes_couple.get()
        self.modif_struct.set_resolution_calc_modal(choix)

        if not self.modif_struct._can_get_nume_support_model():
            retour = False

        modlx_name = self.root.expansion.var_modlx.get()
        try:
            self.modif_struct.find_maillage_modif_from(modlx_name)
        except KeyError:
            disp_mess("Il faut donner le modele associe a la modification")
            retour = False

        if retour == False:
            disp_mess("Calcul impossible !!")
            return False

        return True

    def calc_condensation(self):
        """Lance le calcul de condensation sur la structure modifiée."""

        if not self._can_set_modif_struct_para():
            return

        self.mw.clear_modes()

        reso = self.param_proj_mesu.get_resolution()
        self.modif_struct.set_param_condens(reso)
        self.modif_struct.creation_modele_couple()

        if self.modif_struct.resolution_calc_modal == 'MODE_ITER_SIMULT':
            mode_simult = 1
            calc_freq = self.param_simult_modes_couple.get_calc_freq()
            calc_freq['SEUIL_FREQ'] = 1e-4
        else:
            calc_freq = self.param_simult_modes_couple.get_calc_freq()
            mode_simult = 0
        self.modif_struct.calc_modes_modele_couple(mode_simult, calc_freq)

        self.refresh_list_resu()

    def indic_qualite(self):
        """Lance le calcul du critere de qualite de la base d'expansion.
           Et affiche dans l'interface Tk le critere de qualite de la base.
        """

        if not self.modif_struct.is_valid():
            disp_mess = self.root.mess.disp_mess
            disp_mess("Resultats sur la structure modifiee non disponibles!")
            return

        self.mw.clear_modes()
        self.modif_struct.indicateur_choix_base_expansion()

        modes1 = self.modif_struct.i_deplint
        modes2 = self.modif_struct.i_deplxint

        freq1 = modes1.get_modes_data()['FREQ']
        freq2 = modes2.get_modes_data()['FREQ']

        self.mw.set_modes(freq1, freq2, self.modif_struct.mac_val)

    def mac_changed(self):
        self.modif_struct.set_crit_method(self.mac_meth.get())

    def choix_ponder(self):
        self.modif_struct.set_crit_ponder(self.crit_ponder.get())
Exemplo n.º 4
0
class InterfaceExpansion(Frame):

    def __init__(self, root, modifstruct, param_visu, mess):
        """!Creation de l'interface pour le calcul de condensation de la mesure

        """
        Frame.__init__(self, root, relief='sunken', borderwidth=1)
        self.root = root
        self.modif_struct = modifstruct
        self.param_visu = param_visu
        self.mess = mess
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=1)
        self.rowconfigure(1, weight=1)
        self.term = []

        objects = self.root.objects
        # Déclaration des variables Tk
        self.var_resu_exp = StringVar()
        self.condens_meth = StringVar()
        self.var_modl_sup = StringVar()
        self.var_grno_capt = StringVar()
        self.var_grno_intf = StringVar()
        self.var_raid_name = StringVar()
        self.var_modlx = StringVar()
        self.sumail_name = StringVar()

        self.param_mode_iter_simult_lmme = None
        self.param_dlg = None

        # -----------------------------------------------------------------
        # Titre
        #
        Label(self, text="Choix de la base d'expansion", font=self.root.font2
              ).grid(row=0, column=0, columnspan=3, sticky="ew")

        # -----------------------------------------------------------------
        # Definition du modele support
        f = Frame(self)
        f.grid(row=1, column=0, sticky='nsew', padx=60)
        f.columnconfigure(0, weight=3)

        # menu de selection des modes identifies
        Label(f, text="Modes experimentaux").grid(row=0, column=0, sticky='w')
        self.menu_resu_exp = MyMenu(f, objects.get_mode_meca_name(),
                                    self.var_resu_exp, self.refresh_list_exp)
        self.menu_resu_exp.grid(row=0, column=1, sticky='ew')

        # menu de selection du modele support
        Label(f, text="Modele support").grid(row=1, column=0, sticky='w')
        self.menu_modl_sup = MyMenu(f, objects.get_model_name(),
                                    self.var_modl_sup, self.modele_support_changed)
        self.menu_modl_sup.grid(row=1, column=1, sticky='ew')

        # menu de selection de la matrice de raideur assemblee du modele
        # support
        Label(f, text="Matrice raideur (support)",
              justify='left').grid(row=2, column=0, sticky='w')
        self.menu_raid_name = MyMenu(f, objects.get_matr_name(),
                                     self.var_raid_name,
                                     self.mat_raideur_changed)
        self.menu_raid_name.grid(row=2, column=1, sticky='ew')

        Label(f, text="Methode (base expansion)").grid(
            row=3, column=0, sticky='w')

        self.dic_condens_meth = {
            "ES": "Expansion statique",
            "LMME": "Expansion statique projetee",
        }

        self.menu_condens_meth = MyMenu(f, self.dic_condens_meth.keys(),
                                        self.condens_meth,
                                        self.condens_changed)
        self.menu_condens_meth.grid(row=3, column=1, sticky='ew')
        self.condens_meth.set("ES")

        # menu selection du modele modification
        Label(f, text="Modele modification").grid(row=4, column=0, sticky='w')
        self.menu_modlx = MyMenu(f, objects.get_model_name(),
                                 self.var_modlx, self.modele_modif_changed)
        self.menu_modlx.grid(row=4, column=1, sticky='ew')

        # menu de selection du groupe de noeuds capteur
        self.capteur = SelectionNoeuds(f, "Noeuds et DDL capteur",
                                       bg='#90a090', command=self.capteur_changed)
        self.capteur.grid(row=5, column=0, columnspan=2, pady=3, sticky='ew')

        # menu de selection du groupe de noeuds interface
        self.iface = SelectionNoeuds(f, "Noeuds et DDL interface",
                                     bg='#9090a0', command=self.iface_changed)
        self.iface.grid(row=6, column=0, columnspan=2, pady=3, sticky='ew')

        Label(f, text="Nom de la super maille : ").grid(
            row=7, column=0, sticky='w')
        Entry(f, textvariable=self.sumail_name).grid(row=7, column=1)
        self.sumail_name.set("SUMAIL")

        Button(f, text="Valider", command=self.anything_changed).grid(row=8,
                                                                      column=1,
                                                                      sticky='e')

        # -----------------------------------------------------------------
        # menu de selection des modes identifies experimentalement
        f = Frame(self)
        f.grid(row=1, column=1, sticky='nsew')
        f.rowconfigure(0, weight=1)
        self.liste_exp = ModeFreqList(f, "Modes du modele experimental")
        self.liste_exp.grid(row=0, column=0, columnspan=2, sticky='nsew')
        Button(f, text="Voir", command=self.view_model_exp).grid(row=1,
                                                                 column=0,
                                                                 columnspan=2)

        # -----------------------------------------------------------------
        # menu de selection de la methode pour
        # le calcul de la base d'expansion
        f = Frame(self)
        f.grid(row=1, column=2, sticky='nsew')
        f.rowconfigure(0, weight=1)
        self.liste_sup = ModeFreqList(f, "Base d'expansion")
        self.liste_sup.grid(row=0, column=0, sticky='snew')

        Button(f, text="Voir", command=self.view_expansion).grid(
            row=1, column=0)

        self.reglage_lmme_visible = IntVar()
        self.button_reglage_lmme = Checkbutton(f, text="Reglages LMME",
                                               variable=self.reglage_lmme_visible,
                                               command=self.show_param_dialog,
                                               state='disabled', indicatoron=0)

        self.reglage_lmme_visible.set(0)
        self.button_reglage_lmme.grid(row=1, column=1)
        self.configure_param_lmme_dialog()

    def setup(self, mdo):
        """ Actualisation des concepts dans les listes lorsqu'on a change de tab"""
        self.menu_resu_exp.update(
            mdo.get_mode_meca_name(), self.var_resu_exp, self.refresh_list_exp)
        self.menu_modl_sup.update(
            mdo.get_model_name(), self.var_modl_sup, self.modele_support_changed)
        self.menu_modlx.update(
            mdo.get_model_name(), self.var_modlx, self.modele_modif_changed)

    def configure_param_lmme_dialog(self):
        w = Toplevel()
        w.protocol('WM_DELETE_WINDOW', self.hide_param_dialog)
        self.param_dlg = w
        w.withdraw()  # cache la fenetre
        w.rowconfigure(0, weight=1)
        w.columnconfigure(0, weight=1)
        prm = ParamModeLMME(
            w, "Paramètres du calcul modal pour la méthode LMME",
            relief='sunken', borderwidth=2)
        prm.grid(row=0, column=0)
        self.param_mode_iter_simult_lmme = prm
        Button(w, text="Appliquer", command=self.anything_changed).grid(
            row=1, column=0)
        Button(w, text="OK", command=self.hide_param_dialog).grid(
            row=2, column=0)

    def show_param_dialog(self):
        state = self.reglage_lmme_visible.get()
        if state:
            self.param_dlg.deiconify()
        else:
            self.param_dlg.withdraw()

    def hide_param_dialog(self):
        self.anything_changed()
        self.reglage_lmme_visible.set(0)
        self.param_dlg.withdraw()

    def modele_support_changed(self):
        """Selectionne les matrices de raideur compatibles avec le modèle
        support sélectionné
        """
        obj_dict = CONTEXT.get_current_step().get_contexte_courant()
        modsup = self.var_modl_sup.get()
        # choix des matrices de raideur assemblees de ce modele support
        mat_asse = self.root.objects.matrices.items()
        mat_rigi = []
        for name, obj in mat_asse:
            LIME = obj.sdj.LIME.get()
            if not LIME:
                continue
            for k in LIME:
                obj = obj_dict[k.strip()]
                refe = obj.sdj.RERR.get()
                modl = refe[0].strip()  # Modele
                typ = refe[1].strip()   # Type matrice (Masse ou raideur)
                if typ == "RIGI_MECA" and modl == modsup:
                    mat_rigi.append(name)
        self.menu_raid_name.update(
            mat_rigi, self.var_raid_name, self.mat_raideur_changed)
        old_rigi = self.var_raid_name.get()
        if old_rigi not in mat_rigi:
            self.var_raid_name.set(mat_rigi[0])
        # choix des groupno capteur
        self.capteur.set_modele(obj_dict[modsup], obj_dict)
        self.iface.set_modele(obj_dict[modsup], obj_dict)

    def refresh_list_exp(self):
        resu_exp = self.var_resu_exp.get()
        resu = self.root.objects.get_mode_meca(resu_exp)
        self.liste_exp.set_resu(resu)

    def anything_changed(self):
        # if self.valid():
        self.refresh_list_sup()

    def condens_changed(self):
        meth = self.condens_meth.get()
        if meth == "ES":
            self.button_reglage_lmme['state'] = 'disabled'
        else:
            self.button_reglage_lmme['state'] = 'normal'
        self.anything_changed()

    def group_no_capteur_changed(self):
        """modif : on ne fait les calculs qu'une fois qu'on a appuye sur "Valider" """
        pass
# self.anything_changed()

    def group_no_iface_changed(self):
        """modif : on ne fait les calculs qu'une fois qu'on a appuye sur "Valider" """
        pass
# self.anything_changed()

    def mat_raideur_changed(self):
        self.anything_changed()

    def modele_modif_changed(self):
        self.anything_changed()

    def iface_changed(self):
        """modif : on ne fait les calculs qu'une fois qu'on a appuye sur "Valider" """
        pass
# self.anything_changed()

    def capteur_changed(self):
        """modif : on ne fait les calculs qu'une fois qu'on a appuye sur "Valider" """
        pass
# self.anything_changed())

    def _can_set_modif_struct_para(self):
        """Renvoit  True si tous les paramêtres pour calculer les modes
        de la structure modifiée ont pu être obtenu."""
        disp_mess = self.root.mess.disp_mess
        retour = True

        # resultat experimentaux
        resu_exp_name = self.var_resu_exp.get()
        try:
            self.modif_struct.find_experimental_result_from(resu_exp_name)
        except KeyError:
            disp_mess("Il faut donner les donnees experimentales")
            retour = False

        # modele support
        modlsup = self.var_modl_sup.get()
        try:
            self.modif_struct.find_support_modele_from(modlsup)
        except KeyError:
            disp_mess("Il faut donner un modele support")
            retour = False

        objects = self.modif_struct.objects
        matr_rig = objects.get_matr(self.var_raid_name.get())
        if matr_rig == None:
            disp_mess((u"Il faut selectionner une matrice raideur "
                       u"parmi celles proposées!"))
            retour = False
        else:
            self.modif_struct.set_stiffness_matrix(matr_rig)

        self.modif_struct.set_method_name(self.condens_meth.get())
        self.modif_struct.set_sumail_name(self.sumail_name.get())

        grno_capt = self.capteur.get_selected()
        if not grno_capt:
            disp_mess(("Il faut selectionner un GROUP_NO capteur "
                       "parmi ceux proposes!"))
            retour = False
        else:
            self.modif_struct.set_sensor_groups(grno_capt)

        grno_iface = self.iface.get_selected()
        self.modif_struct.set_interface_groups(grno_iface)

        try:
            self.modif_struct.find_maillage_modif_from(self.var_modlx.get())
        except KeyError:
            disp_mess("Il faut donner le modele associe a la modification")
            retour = False

        if retour == False:
            disp_mess("calcul impossible !!")
            return False

        return True

    def refresh_list_sup(self):
        """!Rafraichit la liste des vecteurs de base d'expansion

        depend: var_raid_name, var_grno_capt

        """
        if not self._can_set_modif_struct_para():
            return

        self.modif_struct.get_modele_support()
        self.modif_struct.find_maillage_modif_from(self.var_modlx.get())
        self.modif_struct.find_maillage_support_from(self.var_modl_sup.get())
        self.modif_struct.find_modele_modif_from(self.var_modlx.get())

        # Getting the frequency from the interface for the LMME method
        calc_freq = None
        if self.modif_struct.method_name == "LMME":
            calc_freq = self.param_mode_iter_simult_lmme.get_calc_freq()

        x_bsmo = self.modif_struct.calc_base_proj(calc_freq)
        self.liste_sup.set_resu(x_bsmo)

        # on sauve le nom du modele sup utilisé
        # pour calculer la base d'expansion (pour affichage par GMSH)
        # self.base_expansion_modl = modlsup
        # self.base_expansion = self.modif_struct.base_expansion

        self.root.expansion_completed()

    def view_expansion(self):
        """!Visualisation de la base d'expansion par GMSH ou Salome
        """
        if not self.modif_struct.base_expansion:
            return

        be = self.modif_struct.base_expansion.obj
        # print be.dump(present=True,size=150)
        # modl = self.root.objects.get_model(self.modif_struct.support_modele.nom)
        # base_mod = Resultat(self.root.objects, be.nom,
        #                    be, self.root.mess)

        # Ordres a afficher
        if self.modif_struct.method_name == "LMME":
            modes_expansion = self.liste_sup.get_selection()
        else:
            modes_expansion = []
            for num in self.liste_sup.get_selection():
                node, comp = self.modif_struct.calc_base_es().get_modes_data()[
                    'NOEUD_CMP'][num - 1].split()
                modes_expansion.append(node)
                modes_expansion.append(comp)

        # if not (isinstance(be,tuple) or isinstance(be,list)):
        #    be = tuple(be)
        term = self.param_visu.visu_resu(resultat=be,
                                         nume_mode=modes_expansion)

        self.term.append(term)

    def view_model_exp(self):
        """!Visualisation des modes identifies par GMSH ou Salome.
        """
        resu_exp = self.var_resu_exp.get()
        resu = self.root.objects.get_mode_meca(resu_exp)

        # Modes a afficher
        modes_ide = self.liste_exp.get_selection()
        term = self.param_visu.visu_resu(resultat=resu.obj,
                                         nume_mode=modes_ide)
        self.term.append(term)
Exemplo n.º 5
0
class InterfaceCorrelation(Frame):
    """!Interface principale de l'outil de projection des modes
    expérimentaux sur les modes numériques

    permet la sélection et de calcul des modes en air et écoulement"""
    def __init__(self, root, objects, macro, mess, param_visu):
        """!Constructeur

        :IVariable:
         - `root`: fenetre parente
         - `objects`: objet permettant d'accéder aux résultats aster existants dans le JDC
         - `mode_exp`: valeur associée au bouton de sélection des modes expérimentaux
         - `mode_etendu`: valeur associée au bouton de sélection des modes étendus
         - `mode_nume`: valeur associée au bouton de sélection des modes numériques
         - `mode_nume_red`: valeur associée au bouton de sélection des modes numériques réduits
         - `use_nume_mass`: indicateur d'utilisation de la matrice de masse numérique
         - `proj_champ_meth`: méthode à utiliser pour PROJ_CHAMP (SVD ou LU)
         - `proj_svd_param`: si méthode SVD, alors paramètre de sélection
         - `mac_windows`: liste des fenetres d'affichage de MAC modes
        """

        Frame.__init__(self, root, relief='flat',
                       borderwidth=4)  # Première frame
        self.mess = mess
        self.root = root
        self.macro = macro
        self.objects = objects  # objets Aster en mémoire
        self.param_visu = param_visu
        self.is_resu1 = IntVar()
        self.is_resu2 = IntVar()
        self.use_nume_mass = IntVar()
        self.proj_champ_meth = StringVar()
        self.proj_svd_param = StringVar()
        self.calculs = CalcEssaiExpansion(macro, mess, objects)
        self.type_resu_exp = StringVar()
        self.term = []
        self.mac_windows = []
        self.afreq = None
        self.anum = None
        self.interface_main()
        self.resu_num = None  # base d'expansion (instance de ModeMeca)
        self.resu_exp = None  # donnees exp (instance de ModeMeca ou de DynaHarmo)
        self.norme_num = None  # matrice assemblee sur modele num (non obligatoire pour calcul)
        self.norme_exp = None  # idem sur modele exp

    def setup(self):
        """!Appelée par le gestionnaire de tab lors de l'affichage
            Permet de prendre en compte des nouveaux concepts
            et de les ajouter dans les MyMenu et cie..."""
        mdo = self.objects
        mdo.recup_objects()
        # mise a jour des options des boutons : commande update de MyMenu :
        # les arguments sont, dans l'ordre : options, var, command
        self.menu_resu_num.update(mdo.get_mode_meca_name(), self.var_resu_num,
                                  self.num_changed)
        self.menu_resu_exp.update(mdo.get_resultats_name(), self.var_resu_exp,
                                  self.exp_changed)
        self.menu_resu1.update(mdo.get_resultats_name(), self.var_resu1,
                               self.visu1_changed)
        self.menu_resu2.update(mdo.get_resultats_name(), self.var_resu2,
                               self.visu2_changed)

    def teardown(self):
        """!Appelée par le gestionnaire de tab lors du masquage (passage à un autre tab)"""
        return

    def interface_main(self):
        """!Fonction principale de création de l'interface

        """
        self.columnconfigure(0, weight=1)
        self.rowconfigure(2, weight=1)
        l = Label(self,
                  text=u"Expansion de données ",
                  pady=5,
                  font=("Helvetica", "16"))
        l.grid(row=0)

        select_box = self.interface_selection(self)
        select_box.grid(row=1, sticky='nsew')

        main_param = self.interface_parametres(self)
        main_param.grid(row=2, sticky='nsew')

    def interface_selection(self, root):
        """!Creation de l'interface de selection des objets resultats"""
        f = Frame(root, relief='sunken', borderwidth=1)
        Label(f, text="   ").grid(row=0,
                                  column=0,
                                  columnspan=3,
                                  sticky='w' + 'e')

        # menu de selection du resultat numerique
        Label(f, text=u"Base numérique d'expansion").grid(row=1,
                                                          column=0,
                                                          sticky='e')
        self.var_resu_num = StringVar()
        self.menu_resu_num = MyMenu(f,
                                    options=self.objects.get_mode_meca_name(),
                                    var=self.var_resu_num,
                                    cmd=self.num_changed)
        self.menu_resu_num.grid(row=1, column=1, sticky='ew')

        # menu de selection du resultat experimental
        Label(f, text=u"Résultat expérimental").grid(row=1,
                                                     column=2,
                                                     sticky='e')
        self.var_resu_exp = StringVar()
        self.menu_resu_exp = MyMenu(f,
                                    options=self.objects.get_resultats_name(),
                                    var=self.var_resu_exp,
                                    cmd=self.exp_changed)
        self.menu_resu_exp.grid(row=1, column=3, sticky='ew')

        self.var_resu1 = StringVar()
        self.menu_resu1 = MyMenu(f,
                                 options=self.objects.get_resultats_name(),
                                 var=self.var_resu1,
                                 cmd=self.visu1_changed)

        self.var_resu2 = StringVar()
        self.menu_resu2 = MyMenu(f,
                                 options=self.objects.get_resultats_name(),
                                 var=self.var_resu2,
                                 cmd=self.visu2_changed)

        # La norme pourrait etre utilisee pour le MAC, mais elle ne l'est pas actuellement : on commente ces lignes
        # menu de selection de la norme numerique
        # Label(f,text="Norme numérique").grid(row=2,column=0,sticky='e')
        # self.var_norme_num = StringVar()
        # self.menu_norme_num = MyMenu( f, options = self.objects.get_matr_norme(),
        # var = self.var_norme_num, cmd = self.num_changed )
        # self.menu_norme_num.grid(row=2, column=1, sticky='ew')
        #
        # menu de selection de la norme experimentale
        # Label(f,text="Norme experimentale").grid(row=2,column=2,sticky='e')
        # self.var_norme_exp = StringVar()
        # self.menu_norme_exp = MyMenu( f, options = self.objects.get_matr_norme(),
        # var = self.var_norme_exp, cmd = self.exp_changed )
        # self.menu_norme_exp.grid(row=2, column=3, sticky='ew')
        # Type de resu experimental (dyna_harmo ou modes)
        Label(f, text=u"Type de résultat expérimental").grid(row=1,
                                                             column=4,
                                                             columnspan=2)
        Radiobutton(f,
                    text=u"résultat harmonique",
                    value='harmo',
                    variable=self.type_resu_exp).grid(row=2, column=4)
        Radiobutton(f,
                    text=u"modes",
                    value='mode',
                    variable=self.type_resu_exp).grid(row=2, column=5)

        Label(f, text="   ").grid(row=3,
                                  column=0,
                                  columnspan=3,
                                  sticky='w' + 'e')
        f.columnconfigure(0, weight=1)
        f.columnconfigure(1, weight=4)
        f.columnconfigure(3, weight=4)

        return f

    """ Deux routines pour mettre a jour les donnees, sd_resus et normes"""

    def num_changed(self):
        mdo = self.objects
        resu_num = norme_num = None
        if self.var_resu_num.get() != "Choisir":
            self.resu_num = mdo.get_mode_meca(self.var_resu_num.get())
            self.liste_num.set_resu(
                self.resu_num)  # remplissage de la liste des frequences
# if self.var_norme_num.get() != 'Choisir':
# self.norme_num = mdo.get_matr(self.var_norme_num.get())

    def exp_changed(self):
        mdo = self.objects
        self.resu_exp = self.norme_exp = None
        if self.var_resu_exp.get() != "Choisir":
            self.resu_exp = mdo.get_resultats(self.var_resu_exp.get())
            if isinstance(self.resu_exp, DynaHarmo):
                self.type_resu_exp.set('harmo')
            elif isinstance(self.resu_exp, ModeMeca):
                self.type_resu_exp.set('mode')
            self.liste_exp.set_resu(
                self.resu_exp)  # remplissage de la liste des frequences
# if self.var_norme_exp.get() != 'Choisir':
# self.norme_exp = mdo.get_matr(self.var_norme_exp.get())

    def interface_parametres(self, root):
        """!Création de l'interface de choix des paramètres de calcul

        On permet à l'utilisateur de choisir les modes numériques et expérimentaux
        ainsi que la méthode de projection
        """
        self.var_expans_param_frame_visible = IntVar()
        self.export_name = StringVar()
        self.param = None
        self.suffix = ['_NX', '_EX', '_ET', '_RD']
        listres = [
            "résultat numérique   extrait  NX",
            "résultat expérimental extrait EX", "résultat étendu ET",
            "résultat réduit RD"
        ]

        f = Frame(root, relief='sunken', borderwidth=1)

        self.param_proj_mesu = ParamProjMesuModal(
            f, u"Paramètres de PROJ_MESU_MODAL")
        self.param = self.param_proj_mesu.get_option()

        # parametres de proj_mesu_modal
        paraf = Frame(f, borderwidth=1)
        Label(paraf, text=u"Paramètres de PROJ_MESU_MODAL").grid(row=0,
                                                                 column=0,
                                                                 rowspan=2,
                                                                 sticky='nswe')
        Checkbutton(paraf,
                    text=u"Réglages",
                    command=self.display_expans_param_frame,
                    variable=self.var_expans_param_frame_visible,
                    indicatoron=0).grid(row=2, column=0, pady=5, sticky='e')
        paraf.grid(row=0, column=0, sticky='ew', pady=10, padx=10)

        # lancer le calcul
        launchf = Frame(f, borderwidth=1)
        Button(launchf, text="Calculer",
               command=self.prepare_calcul).grid(row=2, column=0, sticky='w')
        Entry(launchf, textvariable=self.export_name,
              bg='white').grid(row=2, column=1, pady=2)
        launchf.grid(row=1, column=0, sticky='ew', pady=10, padx=10)

        self.liste_num = ModeFreqList(f, u"Modes Numériques")
        self.liste_num.grid(row=0,
                            column=3,
                            rowspan=3,
                            sticky='nsew',
                            pady=10,
                            padx=10)
        self.liste_exp = ModeFreqList(f, u"Modes Expérimentaux")
        self.liste_exp.grid(row=0,
                            column=4,
                            rowspan=3,
                            sticky='nsew',
                            pady=10,
                            padx=10)

        f.grid(row=1, sticky='ew')
        return f

    def display_expans_param_frame(self):
        """Affichage d'une fenetre pour reglage de PROJ_MESU_MODAL"""
        self.expans_param_frame = frm1 = Toplevel()
        frm1.rowconfigure(0, weight=1)
        frm1.columnconfigure(0, weight=1)
        self.param_proj_mesu = ParamProjMesuModal(
            frm1, u"Paramètres de PROJ_MESU_MODAL")
        self.param_proj_mesu.grid(row=0, column=0, sticky='nsew')
        if self.param:
            self.param_proj_mesu.set_option(self.param)
            self.param_proj_mesu.select_option()
        state = self.var_expans_param_frame_visible.set(1)
        frm1.protocol("WM_DELETE_WINDOW", self.hide_expans_param_frame)
        Button(frm1, text="OK",
               command=self.hide_expans_param_frame).grid(row=1, column=0)

    def hide_expans_param_frame(self):
        """Fermer la fenetre de reglage"""
        self.var_expans_param_frame_visible.set(0)
        self.expans_param_frame.withdraw()
        self.param = self.param_proj_mesu.get_option()

    def set_proj_svd(self):
        self.proj_champ_meth.set("SVD")

    def set_proj_crout(self):
        self.proj_champ_meth.set("LU")

    def visu1_changed(self):
        """ desactivation du bouton concernant le visu1"""
        self.is_resu1.set(1)
        self.check_state()

    def visu2_changed(self):
        """ desactivation du bouton concernant le visu1"""
        self.is_resu2.set(1)
        self.check_state()

    def cb_changed(self):
        self.check_state()

    def prepare_calcul(self, *args):
        """! Demande le lancement de la macro MACRO_EXPANS dans calc_proj_resu
        """
        # Validité des donnees :
        if self.resu_num == None or self.resu_exp == None:
            self.mess.disp_mess(u"Il manque des données pour le calcul")
            return
        if self.resu_num.modele == None:
            self.mess.disp_mess(
                u"Il manque le modele associe au résultat numérique")
            return
        if self.resu_exp.modele == None:
            self.mess.disp_mess(
                u"Il manque le modele associe au résultat expérimental")
            return

        self.modes_num_list = self.liste_num.get_selection()
        self.modes_exp_list = self.liste_exp.get_selection()
        param = self.param_proj_mesu.get_resolution()

        self.calculs.setup(self.resu_num, self.modes_num_list, self.resu_exp,
                           self.modes_exp_list, param)

        self.calculs.calc_proj_resu(self.suffix, self.export_name.get())
        self.setup()

    def quit(self):
        for term in self.term:
            if term is not None:
                term.Fermer()
Exemplo n.º 6
0
class InterfaceIdentification(Frame):

    """
    Classe qui fabrique l'interface graphique permettant de réaliser une identification
    d'efforts turbulents, et de controler les calculs. On y trouve les méthodes suivantes :
     - choix_donnees, choix_projection, frame_meth, _choix_methode, visu_resu : définition
       frame d'interface graphique,
     - get_list, plot_curve : résultats à visualiser, affichage des courbes,
     - calculate_force : dirige les calculs (effectués dans la classe CalculInverse)
     - crea_champ, proj_champ : utilitaires utilisant les op aster du meme nom
    """

    def __init__(self, root, ce_objects, mess, out, param_visu):
        Frame.__init__(self, root, borderwidth=4)

        # Classe de calculs appelable ici, ou dans ce_test.py pour validation
        self.calcturb = CalcEssaiIdentification(ce_objects, mess)

        # Objets aster en memoire, et initialisation des noms generiques donnes
        self.objects = ce_objects                                                  # concepts aster dans le dictionnaire
        self.mess = mess                                                           # fichier de message en bs de la fenetre
        self.out = out                                                             # concepts sortants pre-declares a l'appel de la macro
        self.param_visu = param_visu                                               # parametre pour l'affichage des courbes

        self.opt_noms = []
            # ['Depl Phy', 'Eff Phy', Eff Mod'...]
        self.opt_data = {}
            # {'Depl Phy':{'function':self.calcul_depl_phy,'resultat_attr':'Syy','nume':'nume_phy'},'Eff Phy':{...},...}
        self._create_opt_data()

        self.font1 = tkFont.Font(family="Helvetica", size=16)
        self.font2 = tkFont.Font(family="Helvetica", size=14)

        # Initialisation des inter-spectres calcules (taille nulle a priori)
        nb_freq = nb_mod = nb_mes = nb_act = 0
        # nb_freq = nombre de frequences de discretisations
        # nb_mes = nombre de mesures
        # nb_act = nombre d'actionneurs
        # nb_mod : nombre de modes pour le modele modal
        self.Syy = zeros((nb_freq, nb_mes, nb_mes))
        self.Syy_R = zeros((nb_freq, nb_mes, nb_mes))
        self.Sqq = zeros((nb_freq, nb_mod, nb_mod))
        self.SQQ = zeros((nb_freq, nb_mod, nb_mod))
        self.SQQ_R = zeros((nb_freq, nb_mod, nb_mod))
        self.Sff = zeros((nb_freq, nb_act, nb_act))
        self.Syy_S = zeros((nb_freq, nb_mes, nb_mes))

        self.alpha = StringVar()
                               # parametre de regularisation de Thikonov
        self.epsilon = StringVar()
                                 # regularisation par svd tronquee
        self.mcoeff = StringVar()
                                # modulation de alpha selon la frequence

        self.chgt_rep = ChgtRepereDialogue(mess)
        self.obs_co = None                                                         # observabilite (base de modes projetee sur les capteurs
        self.com_co = None                                                         # commandabilite (bdm projetee sur les actionneurs)

        self.inter_spec = None

        self.base = None                                                           # base de mode dont on extrait les caracteristiques modales

        lab = Label(self, text="Identification de chargement",
                    pady=5, font=self.font1)
        lab.grid(row=0, columnspan=8)

        colonne_1 = self._construit_colonne_1()
        colonne_2 = self._construit_colonne_2()

        colonne_1.grid(row=1, column=0, rowspan=1, sticky='ew')
        colonne_2.grid(row=1, column=1, rowspan=1, sticky='new')
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=2)

    def setup(self):
        "Utilisé par outils_ihm.TabbedWindow"
        mdo = self.objects
        self.menu_resu_fonc.update(mdo.get_inter_spec_name(),
                                   self.var_resu_fonc, self._get_inter_spec)
        self.menu_resu_mod.update(mdo.get_mode_meca_name(),
                                  self.var_resu_mod, self._get_base)

    def _create_opt_data(self):
        opt_res_definitions = [
            ("Depl phy", self.calcul_depl_phy, 'Syy', 'nume_phy'),
            ("Eff mod", self.calcul_eff_mod, 'SQQ', 'nume_gene'),
            ("Depl phy r", self.calcul_depl_phy, 'Syy_R', 'nume_phy'),
            ("Eff mod r", self.calcul_eff_mod, 'SQQ_R', 'nume_gene'),
            ("Eff phy", self.calcul_eff_phy, 'Sff', 'nume_phy'),

            ("Depl synt", self.calcul_depl_phy, 'Syy_S', 'nume_phy'),
            ("Valeurs sing", self.calcul_valeurs, 'val_sing', 'nume_gene'),
            ("regul", self.calcul_valeurs, 'regul', None),
        ]
        for nom, function, res_attr, num in opt_res_definitions:
            self.opt_data[nom] = {"function": function,
                                  "resultat_attr": res_attr,
                                  "nume": num}
            self.opt_noms.append(nom)

    def _construit_colonne_1(self):
        col = Frame(self, relief='sunken', borderwidth=1)
        # Menu de choix des donnes de calcul en entree
        Label(col, text=u"Choix des données de calcul",
              font=self.font2).grid(row=0, padx=50, pady=2)

        box_cd = self._choix_base_modale(col, relief='flat')
        box_obs = self._definit_observabilite(col, self, relief='flat')
        box_cmd = self._definit_commandabilite(col, self, relief='flat')
        box_int = self._choix_interspectre(col, relief='flat')
        box_cm = self._choix_methode(col, relief='flat')

        for idx, box in enumerate([box_cd, box_obs, box_cmd, box_int, box_cm]):
            box.grid(row=idx + 1, sticky='ew', padx=4, pady=2)
        Button(col, text="Calculer",
               command=self.calculs).grid(row=6, sticky='s' + 'e',
                                          padx=4, pady=2)

        return col

    def _choix_base_modale(self, parent, **args):
        """Choix des données d'entrée"""
        fra = Frame(parent, args)

        # Menu choix de la base modale
        Label(fra, text="Base modale").grid(row=1, column=0, sticky='w')

        options = self.objects.get_mode_meca_name()
        self.var_resu_mod = StringVar()
        self.menu_resu_mod = MyMenu(fra, options, self.var_resu_mod,
                                    self._get_base)
        self.menu_resu_mod.grid(row=1, column=1)

        return fra

    def _definit_observabilite(self, parent, root, **args):
        """Définition du concept d'observabilité."""

        self.observabilite = ObservationWindow(
            parent, root, self.mess, self.objects,
            None, u"'observabilité", 0, **args)
        return self.observabilite

    def _definit_commandabilite(self, parent, root, **args):
        """Définition du concept de commandabilité."""
        self.commandabilite = ObservationWindow(
            parent, root, self.mess, self.objects,
            None, u"e commandabilité", 0, **args)
        return self.commandabilite

    def _choix_interspectre(self, root, **args):
        """ Choix de l'interspectre"""

        self.var_resu_fonc = StringVar()  # le nom de l'interspectre
        self.typ_resu_fonc = StringVar()  # le type de 'interspectre
        fra = Frame(root, args)
        desc = "Interspectre en fonctionnement"
        Label(fra, text=desc).grid(row=1, column=0, sticky='w')

        options = self.objects.get_inter_spec_name()
        self.menu_resu_fonc = MyMenu(fra, options, self.var_resu_fonc,
                                     self._get_inter_spec)
        self.menu_resu_fonc.grid(row=1, column=1)
        Label(fra, text="Type champ",).grid(row=1, column=2)
        opt_cham = ['DEPL', 'VITE', 'ACCE']
        typ_cham = MyMenu(fra, opt_cham, self.typ_resu_fonc)
        self.typ_resu_fonc.set('DEPL')
        typ_cham.grid(row=1, column=3, sticky='e')

        return fra

    def _choix_methode(self, root, **args):
        """Choix de la méthode de résolution (techniques de régularisation)"""
        fra = Frame(root, args)

        # Menu de choix de la methode de calcul des efforts
        Label(fra, text="Définition du calcul",
              font=self.font2).grid(row=0, column=0, columnspan=3)

        Label(fra, text="Tikhonov")
        Label(fra, text="Alpha =").grid(row=1, column=1)
        entree1 = Entry(fra, textvariable=self.alpha)
        entree1.grid(row=1, column=2)
        self.alpha.set(0.0)

        Label(fra, text="SVD tronquée").grid(row=2, column=0)
        Label(fra, text="Eps =").grid(row=2, column=1)
        entree2 = Entry(fra, textvariable=self.epsilon)
        entree2.grid(row=2, column=2)
        self.epsilon.set(0.0)

        Label(fra, text="puissance").grid(row=3, column=0)
        Label(fra, text="m =").grid(row=3, column=1)
        entree2 = Entry(fra, textvariable=self.mcoeff)
        entree2.grid(row=3, column=2)
        self.mcoeff.set(2.0)

        return fra

    def _construit_colonne_2(self):
        """ Affichage dans une fenetre des voies à afficher, possibilité
        de visualiser les autospectres et les interspectres"""
        # variables pour la visu
        self.nb_col_visu = 2
        self.var_visu_resu = [StringVar()
                              for kk in range(self.nb_col_visu)]  # ,StringVar()]#*self.nb_col_visu
        self.var_export = [StringVar()] * self.nb_col_visu
        self.label_visu = [
            StringVar()] * self.nb_col_visu                    # variable pour le label de la colonne de visu
        self.curve_list = [None] * self.nb_col_visu
        self.radio_donnees = IntVar()
                                    # visu reel, abs, imag, phase
        self.xlinlog = IntVar()
                              # axe x lin ou log
        self.ylinlog = IntVar()
                              # axe y lin ou log

        fra = VisuSpectre(
            self, self.nb_col_visu, choix=self.opt_noms, export='oui',
            label_visu=self.label_visu,
            relief='sunken', borderwidth=1)

        for label in self.label_visu:
            label.set(u"Noeuds/numéros d'ordre")

        return fra

    def _get_base(self):
        """ Va chercher l'instance de la classe ModeMeca correspondant
        au nom de base choisi
        """
        nom_base = self.var_resu_mod.get()
        self.base = self.objects.resultats[nom_base]

    def _get_inter_spec(self):
        """ Va chercher l'instance de la classe InteSpectre correspondant
        au nom de l'inter-spectre choisi
        """
        nom_intsp = self.var_resu_fonc.get()
        self.inter_spec = self.objects.inter_spec[nom_intsp]

    def check_data(self):
        """verification des donnees d'entree"""
        # TODO : on pourrait ajouter ici la verification sur les
        # dimensions des matrices
        self.objects.recup_objects()
        if self.var_resu_fonc.get() == 'Choisir':
            self.mess.disp_mess("Il faut choisir la base modale")
            return 0
        if not self.observabilite.obs_co:
            self.mess.disp_mess(u"Il faut définir le concept d'observabilité")
            return 0
        self.obs_co = self.observabilite.obs_co
        if not self.commandabilite.obs_co:
            self.mess.disp_mess(
                u"Il faut définir le concept de commandabilité")
            return 0
        self.com_co = self.commandabilite.obs_co
        if self.var_resu_fonc.get() == 'Choisir':
            self.mess.disp_mess("Il faut choisir l'inter-spectre des mesures")
            return 0

        return 1

    def calculs(self):
        """!Lance la classe CalculAster, qui dirige toutes les routines
            Aster et python
        """

        iret = self.check_data()
        if iret == 0:
            return

        self.calcturb.set_base(self.base)
        self.calcturb.set_observabilite(self.observabilite.obs_co)
        self.calcturb.set_commandabilite(self.commandabilite.obs_co)
        self.calcturb.set_interspectre(self.inter_spec)
        self.calcturb.set_type_intsp(self.typ_resu_fonc.get())
        self.calcturb.set_alpha(self.alpha.get())
        self.calcturb.set_epsilon(self.epsilon.get())
        self.calcturb.set_mcoeff(self.mcoeff.get())

        # Lancement des calculs
        self.calcturb.calculate_force()

        # Rafraichissement des donnees dans la classe InterfaceTurbulent
        self.Syy = self.Syy_R = self.Sqq = self.SQQ = None
        self.SQQ_R = self.Sff = self.Syy_S = None
        # self.calcturb.is_XX = 1 quand les calculs se sont bien passes
        if self.calcturb.is_Syy == 1:
            self.Syy = self.calcturb.Syy
        if self.calcturb.is_SQQ == 1:
            self.SQQ = self.calcturb.SQQ
            self.val_sing = self.calcturb.val_sing
            self.regul = self.calcturb.regul
        if self.calcturb.is_SQQ_R == 1:
            self.SQQ_R = self.calcturb.SQQ_R
        if self.calcturb.is_Sff == 1:
            self.Sff = self.calcturb.Sff
        if self.calcturb.is_Syy_S == 1:
            self.Syy_S = self.calcturb.Syy_S
        if self.calcturb.is_Syy_R == 1:
            self.Syy_R = self.calcturb.Syy_R

    def get_list(self):
        """Routine qui crée les liste de courbes à afficher.
        Choix de la donnée à représenter:
            Depl phy <=> déplacements physiques,
            Eff mod <=> efforts modaux,
            Depl phy r <=>
            Eff mod r <=> efforts modaux reconstitués,
            Eff phy r <=> efforts physiques
            Depl synt <=> déplacements physiques resynthétisés
            Valeurs  synt <=> valeurs singulieres de la matrice C.phi.Zm1
            regul <=> parametres de regulation"""
        self.var_list = [[], []]
        mess_err = "!! Impossible de créer la liste des courbes à afficher !!"
        self.mess.disp_mess(" ")
        for ind_tabl in range(2):
            opt_key = self.var_visu_resu[ind_tabl].get()
            if opt_key.split()[0] == "Choisir":
                continue
            optdict = self.opt_data[opt_key]
            # Récupération de la fonction à appeler
            calc_func = optdict["function"]
            calc_func(optdict["resultat_attr"], ind_tabl)

    def calcul_depl_phy(self, resultat_attr, ind_tabl):
        """Calcul les paramètres: 'Depl phy', 'Depl phy r','Depl synt'."""
        liste = nume_ddl_phy(self.obs_co)

        for ind in range(len(liste)):
            lst = crea_list_no(ind, liste)
            for ind in lst:
                self.var_list[ind_tabl].append(ind)
        self.curve_list[ind_tabl].set_values(self.var_list[ind_tabl])

    def calcul_eff_phy(self, resultat_attr, ind_tabl):
        """Calcul les paramètres: 'Eff Phy'."""
        liste = nume_ddl_phy(self.com_co)

        for ind in range(len(liste)):
            lst = crea_list_no(ind, liste)
            for ind in lst:
                self.var_list[ind_tabl].append(ind)
        self.curve_list[ind_tabl].set_values(self.var_list[ind_tabl])

    def calcul_eff_mod(self, resultat_attr, ind_tabl):
        """Calcul les paramètres: 'Eff mod', 'Eff mod r'."""
        liste = nume_ddl_gene(self.calcturb.res_base)

        for mode in range(len(liste)):
            lst = crea_list_mo(mode, liste)
            for ind in lst:
                self.var_list[ind_tabl].append(ind)
        self.curve_list[ind_tabl].set_values(self.var_list[ind_tabl])

    def calcul_valeurs(self, resultat_attr, ind_tabl):
        """Calcul les paramètres: 'Valeurs sing', 'regul'."""
        if not self.calcturb.inter_spec.nume_gene:
            liste = nume_ddl_gene(self.calcturb.res_base)
        for ind in liste:
            self.var_list[ind_tabl].append(ind)
        self.curve_list[ind_tabl].set_values(self.var_list[ind_tabl])

    def _get_selected_variables(self, ind_tab):
        """Retourne les variables selectionées dans une colonne
        affichant les résultats."""
        var_list = []
        liste = self.curve_list[ind_tab].get_selection()
        for idx in liste:
            var_list.append(idx[1])
        return var_list

    def _get_graph_data(self):
        """Retourne les valeurs et les légendes pour les courbes de résultats.
           Remarque importante : ici les fonctions sont extraites de la matrice
           inter-spectrale python alors que dans ce_calc_spec, on fait un RECU_FONCTION
           sur le concept inter-spectre aster.
           TODO : homogénéiser les deux procédures dans une méthiode commune à mettre
           dans la classe VisuSpectre (dans outils_ihm.py)"""
        # values = liste dont chaque elmt est une courbe
        values = []
        captions = []

        freq = self.inter_spec.f

        for ind_tab in range(2):
            opt_key = self.var_visu_resu[ind_tab].get()
            if opt_key.split()[0] == "Choisir":
                continue

            optdict = self.opt_data[opt_key]
            res = getattr(self, optdict["resultat_attr"])
            num_option = self.opt_noms.index(opt_key)

            for var in self._get_selected_variables(ind_tab):
                vect = None
                # Type de resultat a representer
                if num_option <= 5:
                    num = getattr(res, optdict["nume"])
                    ikey, jkey = var.split(',')
                    iidx = num.index(ikey)
                    jidx = num.index(jkey)
                    vect = getattr(res, 'matr_inte_spec')[:, iidx, jidx]
                elif num_option == 6 or num_option == 7:
                    idx = int(var[2:])
                    vect = res[idx - 1, 1:]

                # Options de visualisation : reel, abs, imag, phase
                if self.radio_donnees.get() == 0:
                    vect = vect.real
                elif self.radio_donnees.get() == 1:
                    vect = abs(vect)
                elif self.radio_donnees.get() == 2:
                    vect = vect.imag
                elif self.radio_donnees.get() == 3:
                    vect = arctan(vect.imag / vect.real)

                # axes de visu : lin ou log
                # en log y, on ne visualise que la valeur absolue
                if self.ylinlog.get() == 1:
                    self.radio_donnees.set(1)
                    vect = log(abs(vect)) / log(10)
                if self.xlinlog.get() == 1:
                    # on supprime le pas de frequence nulle si on visualise en
                    # log x
                    vect = vect[1:]

                values.append(vect)
                captions.append("%s %s" % (opt_key, var))

            if self.xlinlog.get() == 1 and self.radio_donnees.get() == 'Phase':
                self.mess.disp_mess("Impossible de représenter la phase dans un\n"
                                    "diagramme logarithmique !")
                return ([], [], [])

        if self.xlinlog.get() == 1:
            freq = log(freq[1:]) / log(10.0)

        return freq, values, captions

    def display_curve(self):
        """Selection dans les interspectres disponibles des resultats
        sélectionnées dans les listes curve_list, et plot
        des courbes correspondantes"""
        freq, values, caption = self._get_graph_data()
        if freq == []:
            return

        self.param_visu.visu_courbe(freq, values,
                                    couleur=None,
                                    titre='Inter-spectres',
                                    l_legende=caption,
                                    legende_x='Frequence',
                                    legende_y='Amplitude',
                                    unite_x='Hz',
                                    unite_y='u^2/Hz')

    def export_inte_spec1(self):
        option = self.var_visu_resu[0].get()
        titre = self.var_export[0].get()
        self.export_inte_spec(option, titre)

    def export_inte_spec2(self):
        option = self.var_visu_resu[1].get()
        titre = self.var_export[1].get()
        self.export_inte_spec(option, titre)

    def export_inte_spec(self, option, titre):
        out = self.out
        if option == self.opt_noms[0]:
            self.Syy.make_inte_spec(titre, out)
        elif option == self.opt_noms[1]:
            self.SQQ.make_inte_spec(titre, out)
        elif option == self.opt_noms[2]:
            self.Syy_R.make_inte_spec(titre, out)
        elif option == self.opt_noms[3]:
            self.SQQ_R.make_inte_spec(titre, out)
        elif option == self.opt_noms[4]:
            self.Sff.make_inte_spec(titre, out)
        elif option == self.opt_noms[5]:
            self.Syy_S.make_inte_spec(titre, out)
        else:
            self.mess.disp_mess("!! Il n'est pas possible "
                                "d'exporter ces données !!")
            self.mess.disp_mess("  ")

    def teardown(self):
        "Utilisé par outils_ihm.TabbedWindow"
        pass