// This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2021 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . #include "Fonc_scal_combinees_nD.h" #include "MotCle.h" #include "TypeQuelconqueParticulier.h" #include "CharUtil.h" // CONSTRUCTEURS : Fonc_scal_combinees_nD::Fonc_scal_combinees_nD(string nom) : Fonction_nD(nom,FONC_SCAL_COMBINEES_ND) ,expression_fonction(),p(),tab_fVal() ,tab_fVal_int(),nom_variables_int() ,enu_variables_globale_int(),nom_variables_globales_int() ,Fi(),nom_fonctioni(),ident_interne() ,tab_fVal_Fi(),tab_ret_Fi(),tab_ret() ,indice_precedant(1) {}; // de copie Fonc_scal_combinees_nD::Fonc_scal_combinees_nD(const Fonc_scal_combinees_nD& Co) : Fonction_nD(Co) ,expression_fonction(Co.expression_fonction),p(),tab_fVal(Co.tab_fVal) ,tab_fVal_int(Co.tab_fVal_int),nom_variables_int(Co.nom_variables_int) ,enu_variables_globale_int(Co.enu_variables_globale_int) ,nom_variables_globales_int(Co.nom_variables_globales_int) ,indice_precedant(Co.indice_precedant) ,Fi(Co.Fi),nom_fonctioni(Co.nom_fonctioni) ,ident_interne(Co.ident_interne) ,tab_fVal_Fi(Co.tab_fVal_Fi),tab_ret_Fi(Co.tab_ret_Fi) ,tab_ret(Co.tab_ret) { // création des fonctions locales que si elles étaient déjà locales int tai = Fi.Taille(); for (int i=1;i<= tai; i++) if (Co.Fi(i)->NomFonction() == "_") {Fi(i)=Fonction_nD::New_Fonction_nD(*(Co.Fi(i)));}; // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); //et on définie la fonction et les variables attachées Fonc_scal_combinees_nD::Init_fonction_analytique(); }; // de copie à partir d'une instance générale Fonc_scal_combinees_nD::Fonc_scal_combinees_nD(const Fonction_nD& Coo) : Fonction_nD(Coo) ,expression_fonction(),p(),tab_fVal() { if (Coo.Type_Fonction() != FONC_SCAL_COMBINEES_ND) { cout << "\n erreur dans le constructeur de copie pour une fonction " << " FONC_SCAL_COMBINEES_ND " << " a partir d'une instance générale "; cout << "\n Fonc_scal_combinees_nD::Fonc_scal_combinees_nD(const Fonction_nD& Co) "; Sortie(1); }; // définition des données Fonc_scal_combinees_nD & Co = (Fonc_scal_combinees_nD&) Coo; tab_fVal=Co.tab_fVal; tab_fVal_int=Co.tab_fVal_int; nom_variables_int=Co.nom_variables_int; enu_variables_globale_int = Co.enu_variables_globale_int; nom_variables_globales_int = Co.nom_variables_globales_int; expression_fonction = Co.expression_fonction; // fonctions internes indice_precedant=Co.indice_precedant; Fi=Co.Fi; nom_fonctioni = Co.nom_fonctioni; ident_interne = Co.ident_interne; int tai = Fi.Taille(); // création des fonctions locales que si elles étaient déjà locales for (int i=1;i<= tai; i++) if (Co.Fi(i)->NomFonction() == "_") {Fi(i)=Fonction_nD::New_Fonction_nD(*(Co.Fi(i)));}; // les tableaux tab_ret = Co.tab_ret; tab_fVal_Fi = Co.tab_fVal_Fi; tab_ret_Fi = Co.tab_ret_Fi; // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); // arrivée ici on définie la fonction et les variables attachées Fonc_scal_combinees_nD::Init_fonction_analytique(); }; // DESTRUCTEUR : Fonc_scal_combinees_nD::~Fonc_scal_combinees_nD() { // on efface les fonctions que si c'est des fonctions locales int tai = Fi.Taille(); for (int i=1;i<= tai; i++) if ((Fi(i) != NULL)&&(nom_fonctioni(i)=="i_interne_i")) delete Fi(i); }; // METHODES PUBLIQUES : // --------- virtuelles --------- // Surcharge de l'operateur = : realise l'egalite de deux fonctions Fonction_nD& Fonc_scal_combinees_nD::operator= (const Fonction_nD& elt) { // la suite ne peut fonctionner que s'il s'agit d'une fonction de même type if (typeFonction != elt.Type_Fonction()) {cout << "\n *** erreur d'affectation entre fonction nD " << nom_ref << " et " << elt.NomFonction() << "\n Fonc_scal_combinees_nD::operator= (..." << endl; Sortie(1); }; // on commence par appeler la méthode ad hoc pour la fonction Fonction_nD Fonction_nD::Transfert_info(elt); // puis on s'occupe des variables de la fonction const Fonc_scal_combinees_nD & Co = ((Fonc_scal_combinees_nD &) elt); tab_fVal=Co.tab_fVal; tab_fVal_int=Co.tab_fVal_int; nom_variables_int=Co.nom_variables_int; enu_variables_globale_int = Co.enu_variables_globale_int; nom_variables_globales_int = Co.nom_variables_globales_int; expression_fonction = Co.expression_fonction; // fonctions internes indice_precedant=Co.indice_precedant; Fi=Co.Fi; nom_fonctioni = Co.nom_fonctioni; ident_interne = Co.ident_interne; int tai = Fi.Taille(); // création des fonctions locales que si elles étaient déjà locales for (int i=1;i<= tai; i++) if (Co.Fi(i)->NomFonction() == "_") {Fi(i)=Fonction_nD::New_Fonction_nD(*(Co.Fi(i)));}; // les tableaux tab_ret = Co.tab_ret; tab_fVal_Fi = Co.tab_fVal_Fi; tab_ret_Fi = Co.tab_ret_Fi; // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); // arrivée ici on définie la fonction et les variables attachées Fonc_scal_combinees_nD::Init_fonction_analytique(); return *this; }; // affichage de la fonction void Fonc_scal_combinees_nD::Affiche(int niveau) const { cout << "\n fonction composee : Fonc_scal_combinees_nD : nom_ref= " << nom_ref; int tai = Fi.Taille(); // on parcours toutes les fonctions for (int i=1;i<= tai; i++) { // si c'est une fonction interne on l'affiche globalement // si c'est une fonction globale, on n'affiche que son nom cout << "\n fonction de base: " << i << " "; if (Fi(i) == NULL) { cout << "\n fonction interne ("<< i << "): "<< nom_fonctioni(i) <<", pas encore definie ";} else if(Fi(i)->NomFonction() == "_") {Fi(i)->Affiche(niveau);} else {cout << Fi(i)->NomFonction() << " ";}; }; // --- les variables en interne if (permet_affichage > 5) {cout << "\n variables en interne: nom fct int + variables de la fonction sans les variables globales "; {int nb = nom_variables_int.Taille(); for (int i= 1;i<=nb;i++) cout << nom_variables_int(i) << " "; }; // les énumérés globaux internes {int nb = enu_variables_globale_int.Taille(); if (nb != 0) {cout << " \n variables_globales_interne_en_enumere= " ; cout << "taille " << nb << " "; for (int i=1;i<= nb;i++) cout << Nom_GrandeurGlobale(enu_variables_globale_int(i)) << " "; }; }; // idem en string {int nb = nom_variables_globales_int.Taille(); if (nb != 0) {cout << " \n variables_globales_interne_en_string= " ; cout << "taille " << nb << " "; for (int i=1;i<= nb;i++) cout << nom_variables_globales_int(i) << " "; }; }; }; // --- les variables dans l'ensemble cout << "\n -- vue d'ensemble des variables: --- " << " \n arguments= " << nom_variables << " \n variables_globales_en_enumere= " ; int nb_enu = enu_variables_globale.Taille(); cout << "taille " << nb_enu << " "; for (int i=1;i<= nb_enu;i++) cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " "; cout << " \n variables_globales_en_string= " ; int nb_str = nom_variables_globales.Taille(); cout << "taille " << nb_str << " "; for (int i=1;i<= nb_str;i++) cout << nom_variables_globales(i) << " "; cout << "\n taille vecteur de retour: "<< this->NbComposante() << "\n f(x)= " << expression_fonction << " "; // appel de la méthode associée de la classe virtuelle Affiche_interne(MaX(niveau,permet_affichage)); if (niveau > 0) { cout << "\n derniers parametres d'appel: "; int nb_var = tab_fVal_int.Taille(); for (int j=1;j<=nb_var;j++) { cout << " para("<0)&& affichage) { cout << "\n ***** la fonction n'est pas complete (aucune fonction de base n'existe) "; this->Affiche(); }; return ret; } ; // Lecture des donnees de la classe sur fichier // le nom passé en paramètre est le nom de la fonction // s'il est vide c-a-d = "", la methode commence par lire le nom sinon // ce nom remplace le nom actuel void Fonc_scal_combinees_nD::LectDonnParticulieres_Fonction_nD(const string& nom,UtilLecture * entreePrinc) { // entête de la fonction if (nom == "") { *(entreePrinc->entree) >> nom_ref;} else {nom_ref=nom;}; string nom_class_methode("Fonc_scal_combinees_nD::LectDonnParticulieres_Fonction_nD("); // variable interne pour les erreurs de lecture // 1) === on lit d'abord les fonctions utilisées comme variables inter entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne // on lit les fonctions list < Fonction_nD* > li_Fi; // un liste intermédiaire pour faciliter la lecture list li_nom_fonctioni; list li_ident_interne; // maintenant lecture courante string nom_indicateur,identificateur; do { // tout d'abord lecture de la fonction de base string toto,nom_lu,nom_fonc; Fonction_nD* F=NULL; *(entreePrinc->entree) >> nom_indicateur >> nom_lu; // vérif if (nom_indicateur != "fct_base=" ) { cout << "\n erreur en lecture du nom de la fonction " << " on attendait la chaine: fct_base= et on a lue: " << nom_indicateur; entreePrinc->MessageBuffer("**erreur Fonc_scal_combinees_nD::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on regarde si la fonction existe, si oui on récupère la référence if (Type_EnumFonction_nD_existe(nom_lu)) // cas ou c'est un nom de type de fonction -> lecture directe {nom_fonc = "_"; // on signale que c'est une fonction interne // on lit l'identificateur interne string mot_cle("ident_interne_"); if (!entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle,identificateur)) { throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne F = Fonction_nD::New_Fonction_nD(nom_fonc,Id_Nom_Fonction_nD (nom_lu.c_str())); // lecture de la fonction F->LectDonnParticulieres_Fonction_nD(nom_fonc,entreePrinc); nom_fonc="i_interne_i"; // entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne } else // sinon on retiend le nom pour une complétion future // et idem pour l'identificateur {nom_fonc = identificateur = nom_lu;}; // stockage li_Fi.push_back(F); li_nom_fonctioni.push_back(nom_fonc); li_ident_interne.push_back(identificateur); // on passe une ligne si on n'est pas déjà à la fin et on vérifie que ce n'est pas finie if (strstr(entreePrinc->tablcar,"fin_fcts_interne_fonction_combinee_")==0) entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne } while (strstr(entreePrinc->tablcar,"fin_fcts_interne_fonction_combinee_")==0); // on passe à la ligne suivante entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne // on met en tableau int tai = li_Fi.size(); Fi.Change_taille(tai); nom_fonctioni.Change_taille(tai); ident_interne.Change_taille(tai); list < Fonction_nD* >::iterator ili,ilifin= li_Fi.end(); list ::iterator sli= li_nom_fonctioni.begin(); list ::iterator xli= li_ident_interne.begin(); int ia=1; for (ili=li_Fi.begin();ili!=ilifin;ili++,sli++,ia++,xli++) {Fi(ia)=*ili;nom_fonctioni(ia)=*sli; ident_interne(ia)=*xli; }; // 2) === on lit maintenant l'expression analytique de combinaison et les variables patentées expression_fonction = "aucune_expression"; // init pour le traitement d'erreur // on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_fonction_combinee_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle list < string> list_de_variables; // liste intermédiaire list list_enu_variables_glob; list < string> list_de_variables_nom_globales; // idem string glob string titi; while (strstr(entreePrinc->tablcar,"fin_parametres_fonction_combinee_")==0) { // si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur if ( motCle.SimotCle(entreePrinc->tablcar)) { cout << "\n erreur de lecture des parametre de definition d'une fonction combinee : on n'a pas trouve le mot cle " << " fin_parametres_fonction_combinee_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer("** erreur des parametres d'une fonction expression litterale **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // lecture d'un mot clé *(entreePrinc->entree) >> titi; if ((entreePrinc->entree)->rdstate() == 0) {} // lecture normale #ifdef ENLINUX else if ((entreePrinc->entree)->fail()) // on a atteind la fin de la ligne et on appelle un nouvel enregistrement { // on lit sans tenir compte des < éventuelles entreePrinc->NouvelleDonneeSansInf(); *(entreePrinc->entree) >>titi; } #else else if ((entreePrinc->entree)->eof()) // la lecture est bonne mais on a atteind la fin de la ligne { if(titi != "fin_parametres_fonction_combinee_") // on lit sans tenir compte des < éventuelles {entreePrinc->NouvelleDonneeSansInf(); *(entreePrinc->entree) >> titi; }; } #endif else // cas d'une erreur de lecture { cout << "\n erreur de lecture inconnue "; entreePrinc->MessageBuffer("** erreur2 des parametres d'une fonction combinee **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on lit maintenant l'expression littérale if (titi == "fct=") { std::getline (*(entreePrinc->entree), expression_fonction); } // cas de la lecture d'une variable else if(titi == "un_argument=") {string truc; *(entreePrinc->entree) >> truc; // on regarde s'il s'agit d'une variable globale if (EstUneGrandeurGlobale(truc)) { list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (truc)); } // idem mais sous forme d'un string else if (ParaGlob::param->GrandeurGlobal(truc) != NULL) { list_de_variables_nom_globales.push_back(truc);} else // sinon ce n'est pas une grandeur globale {list_de_variables.push_back(truc);}; } else if(titi == "deb_list_var_") // lecture d'une liste d'argument {// on va lire juqu'au mot clé fin_list_var_ int nb_boucle = 0; // indicateur pour éviter une boucle infinie do {string truc; *(entreePrinc->entree) >> truc; if (truc == "fin_list_var_") break; // on regarde s'il s'agit d'une variable globale if (EstUneGrandeurGlobale(truc)) { list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (truc));} // idem mais sous forme d'un string else if (ParaGlob::param->GrandeurGlobal(truc) != NULL) { list_de_variables_nom_globales.push_back(truc);} else // sinon ce n'est pas une grandeur globale {list_de_variables.push_back(truc);}; nb_boucle++; } while (nb_boucle < 200); if (nb_boucle > 199) { cout << "\n erreur de lecture au niveau d'une liste de variable " << " deb_list_var_ nom1 nom2 ... fin_list_var_"; entreePrinc->MessageBuffer("** erreur lecture parametre d'une fonction combinee **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } else // sinon la lecture est ok a priori ; } // cas de la lecture du niveau d'impression pour les erreurs else if(titi == "permet_affichage_") {*(entreePrinc->entree) >> permet_affichage; } // cas de la lecture du type d'expression du tenseur else if(titi == "Tenseur_base_ad_hoc_") {*(entreePrinc->entree) >> absolue; } // sinon ce n'est pas un mot clé connu, on le signale else if(titi != "fin_parametres_fonction_combinee_") { cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu " << " on a lu : " << titi << endl; entreePrinc->MessageBuffer("**Fonc_scal_combinees_nD::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; //-- fin du while // on vérifie que l'on a bien lue une expression if (expression_fonction == "aucune_expression") {cout << "\n erreur en lecture de l'expression litterale de la fonction combinee , l'expression est absente " << " ou il y a une erreur de syntaxe "; entreePrinc->MessageBuffer("**Fonc_scal_combinees_nD::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on considère que l'utilisateur donne une liste d'arguments // qui sont dédiés uniquement à l'expression globale, // car les variables des fonctions internes sont définies // au moment de la définition (lecture) des lois internes // en lecture, il y a détection des variables globales // celles-ci sont rangées dans le tableau enu_variables défini // dans Fonction_nD.h, et dans nom_variables_globales // ces tableaux contiendront à la fin, toutes les // variables globales c-a-d : celles propres et celles des fonctions membres // du coup: enu_variables_globale_int et nom_variables_globales_int // contiendront à la fin uniquement les variables globales de la fonction propre // // par contre au moment de l'appel de la fonction, toutes les variables // nécessaires sont stockés en entrée dans le tableau tab_fVal // NB: ne sont pas incluses les variables globales par ce qu'elles // sont accessibles directement // // l'ordre des variables est le suivant // 1) les variables internes à chaque fonction membre, en suivant // l'ordre d'apparition des fonctions // 2) les variables de la fonction globale //==== A) définition des éléments internes de l'appel interne // de la fonction principale // on met en ordre de marche les variables globales patentées: // tout d'abord on supprime les doublons list_enu_variables_glob.sort(); list_enu_variables_glob.unique(); list_de_variables_nom_globales.sort(); list_de_variables_nom_globales.unique(); // on parcours les variables globales patentées int nb_enu = list_enu_variables_glob.size(); int ienu=1; enu_variables_globale_int.Change_taille(nb_enu); // première def, avant de connaître les globaux des fonctions membres enu_variables_globale.Change_taille(nb_enu); {list ::iterator il,ilfin=list_enu_variables_glob.end(); for (il=list_enu_variables_glob.begin();il!=ilfin;il++,ienu++) {enu_variables_globale_int(ienu) = *il; enu_variables_globale(ienu) = *il; }; }; // idem pour les noms de ref int nb_nom = list_de_variables_nom_globales.size(); int i_nom=1; nom_variables_globales_int.Change_taille(nb_nom); // première def, avant de connaître les globaux des fonctions membres nom_variables_globales.Change_taille(nb_nom); {list ::iterator il,ilfin=list_de_variables_nom_globales.end(); for (il=list_de_variables_nom_globales.begin();il!=ilfin;il++,i_nom++) {nom_variables_globales_int(i_nom) = *il; nom_variables_globales(i_nom) = *il; }; }; // on définie les variables internes à l'expression // a) les fonctions internes qui seront également utilisés // comme variables intermédiaire int taille2 = ident_interne.Taille(); // b) les variables déclarées comme tel int taille1 = list_de_variables.size(); // récup de la taille // c) les variables globales dont la taille est déjà connue // c'est nb_enu // on met à jour les tailles nom_variables_int.Change_taille(taille1+taille2); // les noms tab_fVal_int.Change_taille(taille1+taille2+nb_enu+nb_nom); // les valeurs en double // i) on parcours les fonctions de base int i= 1; for (int iFi = 1; iFi<= taille2;iFi++,i++) { // on utilise l'identificateur interne nom_variables_int(i)=ident_interne(iFi); // récup du nom }; // ii) on parcours les variables patentées list < string>::iterator il,ilfin = list_de_variables.end(); for (il = list_de_variables.begin();il != ilfin;il++,i++) { nom_variables_int(i)=(*il); // on récupère le nom }; // // iii) on parcours les variables globales // for (int inunu = 1; inunu <= nb_enu; inunu++,i++) // { // on utilise l'identificateur interne // nom_variables_int(i)=Nom_GrandeurGlobale(enu_variables_globale(inunu)); // récup du nom // }; // // idem pour les noms de variables globales indicées en string // for (int inom = 1; inom <= nb_nom; inom++,i++) // nom_variables_int(i)=nom_variables_globales(inom); // // arrivée ici on définie la fonction Init_fonction_analytique(); //==== B) définition des éléments externes à l'appel externe // de la fonction globales // si toute les fonctions internes sont définies en internes // on peut mettre à jour les tableaux: tab_fVal et nom_variables // ainsi que tab_fVal_Fi // sinon il faut attendre l'appel de "Lien_entre_fonc_courbe" bool tous_interne = true; int tail = Fi.Taille(); tab_fVal_Fi.Change_taille(tail); tab_ret_Fi.Change_taille(tail); for (int i = 1;i<=tail;i++) if (Fi(i) == NULL) {tous_interne = false; break;} if (!tous_interne) // il y a des fct externes, on met à 0 les tableaux au cas où {tab_fVal.Change_taille(0);nom_variables.Change_taille(0);} else // sinon on renseigne {int nb_var = 0; // init for (int i = 1;i<=tail;i++) nb_var += Fi(i)->Nom_variables().Taille(); // puis les variables patentées nb_var += tab_fVal_int.Taille() - tail - nb_enu - nb_nom; // on dimensionne nom_variables.Change_taille(nb_var); tab_fVal.Change_taille(nb_var); int inom_variable = 1; // tout d'abord on s'occupe des variables des fonctions internes for (int i = 1;i<=tail;i++) {//nb_var += Fi(i)->NbVariable(); const Tableau & nom_var = Fi(i)->Nom_variables(); int tail = nom_var.Taille(); for (int i=1;i<= tail;i++,inom_variable++) {nom_variables(inom_variable)=nom_var(i); }; // les tableaux de passage tab_fVal_Fi(i).Change_taille(tail); // les tableaux de retour de chaque fonction tab_ret_Fi(i).Change_taille(Fi(i)->NbComposante()); }; // puis on s'occupe des variables patentées // on parcours les variables patentées lues en entrées list < string>::iterator il,ilfin = list_de_variables.end(); for (il = list_de_variables.begin();il != ilfin;il++,inom_variable++) nom_variables(inom_variable)=(*il); // on enregistre le nom }; // arrivée ici si le niveau d'affichage le permet on affiche ce que l'on a lue if (permet_affichage > 8) {cout << "\n == >>> Fonc_scal_combinees_nD::LectDonnParticulieres_Fonction_nD: avant la construction des index ..."; this->Affiche(); }; // //--- debug // {cout << "\n debug 1 Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne() "; // cout << "\n lecture fonction: " << nom_ref; // cout << "\n taille = "<>> Fonc_scal_combinees_nD::LectDonnParticulieres_Fonction_nD: apres la construction des index ..."; this->Affiche(); }; // //--- debug // {cout << "\n debug 2 Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne() "; // cout << "\n lecture fonction: " << nom_ref; // cout << "\n taille = "<GrandeurGlobal(nom_variables_int(i)) != NULL) // il s'agit d'une variable globale {li_globale.push_back(nom_variables_int(i)); a_changer_int=true; } else // sinon c'est toujours une variable li_variable.push_back(nom_variables_int(i)); }; // on met à jour les tableaux if (a_changer_int) {// -- pour les variables // on met à jour le tableau nom_variables_int.Init_from_list(li_variable); // -- pour les nom globaux // on ajoute les variables globales déjà existantes int taille_globale = nom_variables_globales_int.Taille(); // Init_from_list for (int j=1;j<= taille_globale;j++) li_globale.push_back(nom_variables_globales_int(j)); // on ne garde qu'une version de chaque variable globale li_globale.sort();li_globale.unique(); // on met à jour le tableau nom_variables_globales_int.Init_from_list(li_globale); }; // --- on renseigne les variables patentées de la fonction mère: Fonction_nD Fonc_scal_combinees_nD::Mise_a_jour_variables_nD(); // appel de la fonction interne pour modifier les noms de variables bool a_changer = Fonction_nD::Mise_a_jour_variables_globales_interne(); if (a_changer_int || a_changer) // maintenant il faut redéfinir l'ordre d'appel de la fonction { // si quelque chose à changé, l'ordre des variables dans l'appel de la fonction // interne a changé. Le choix qui est fait est de reconstruire la fonction interne // on ré-initialise la fonction analytique Init_fonction_analytique(); }; }; // 1) renseigne si la fonction dépend d'autre fonction ou non bool Fonc_scal_combinees_nD::DependAutreFoncCourbes() const { bool ret=false; int tai = Fi.Taille(); for (int i=1;i<=tai;i++) {if(Fi(i) == NULL) {ret=true;} else if (nom_fonctioni(i)!="i_interne_i") {ret=true;}; }; return ret; }; // 2) retourne une liste de nom correspondant aux noms de fonctions dont dépend *this list & Fonc_scal_combinees_nD::ListDependanceFonctions(list & lico) const { // tout d'abord on vide la liste passée en paramètres if (lico.size() != 0) lico.clear(); // on remplit en fonction de l'état int tai = Fi.Taille(); for (int i=1;i<=tai;i++) {if(Fi(i) == NULL) { lico.push_back(nom_fonctioni(i));} else if (nom_fonctioni(i)!="i_interne_i") //ici la fonction est déjà définie mais cela n'empèche pas de donner la dépendance { lico.push_back(nom_fonctioni(i));}; } return lico; }; // 3) établit la connection entre la demande de *this et les fonctions passées en paramètres void Fonc_scal_combinees_nD::Lien_entre_fonc_courbe (list & liptfonc,list & ) { int tai = Fi.Taille(); Tableau tab_Fi(tai); // def à null par défaut for (int i=1;i<=tai;i++) if(Fi(i) == NULL) {list ::iterator ili,ilifin=liptfonc.end(); for (ili=liptfonc.begin();ili!=ilifin;ili++) if ((*ili)->NomFonction() == nom_fonctioni(i)) {tab_Fi(i)=(*ili);break;}; } else // sinon la fonction existe déjà, on met le pointeur à Null { #ifdef MISE_AU_POINT list ::iterator ili,ilifin=liptfonc.end(); for (ili=liptfonc.begin();ili!=ilifin;ili++) if ( ((*ili)->NomFonction() == nom_fonctioni(i)) && (tab_Fi(i) != (*ili)) ) {cout << "\n *** erreur : la liaison entre la fonction externe " << nom_ref << " d'expression: " << nom_fonctioni(i) << " change de valeur " << "\n Fonc_scal_combinees_nD::Lien_entre_fonc_courbe(... "; Sortie(1); }; #endif tab_Fi(i)=NULL; }; // et on définit les fonctions membres this->DefFonctionsMembres(tab_Fi); // l'ordre des variables peut avoir changé, on redéfinit les variables // pour la fonction analytique Init_fonction_analytique(); // affichage éventuel ce que l'on a lue if (permet_affichage > 6) {cout << "\n == >>> Fonc_scal_combinees_nD::Lien_entre_fonc_courbe "; this->Affiche(); }; // on définit le paramètre depend_M de la classe maître en fonction des nom_variables Fonction_nD::Definition_depend_M(); // idem pour le temps Fonction_nD::Definition_depend_temps(); // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); }; // def info fichier de commande void Fonc_scal_combinees_nD::Info_commande_Fonctions_nD(UtilLecture & entreePrinc) { ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier cout << "\n cas de la fonction combinee Fonc_scal_combinees_nD : " << " \ndefinition standart (rep o) ou documentation exhaustive (rep n'importe quoi) ? "; string rep = "_"; rep = lect_return_defaut(false,"o"); sort << "\n# ....... fonction scalaire combinee ........"; // cas particulier if ((rep == "o") || (rep == "O" ) || (rep == "0") ) { sort << "\n# exemple 3: def de choix_selon_energie_cinetique : " << "\n# -> choix entre deux fonctions suivant la valeur de l'energie cinetique " << "\n# " << "\n# choix_selon_energie_cinetique FONC_SCAL_COMBINEES_ND " << "\n# fct_base= F1 # fct 1 " << "\n# fct_base= F2 # fct 2 " << "\n# fin_fcts_interne_fonction_combinee_ " << "\n# un_argument= ENERGIE_CINETIQUE " << "\n# fct= (ENERGIE_CINETIQUE < 2) ? F1 : F2 " << "\n# fin_parametres_fonction_combinee_ " << "\n# " << "\n# NB: ici les fonctions F1 et F2 doivent exister par ailleurs " << "\n# les parametre sont ceux de F1 + ceux de F2 + ENERGIE_CINETIQUE " << "\n# qui est une grandeur globale" << "\n# si ENERGIE_CINETIQUE < 2 alors F1 sinon F2 " << "\n# "; } else // cas d'une description exhaustive { sort << "\n#............................................" << "\n# Il s'agit d'une fonction qui peut combiner plusieurs fonctions de base" << "\n# sous forme d'une expression analytique quelconque " << "\n# " << "\n# 1) --- Tout d'abord on definit les fonctions de base " << "\n# deux possibilites pour chaque fonction de base: " << "\n# a) soit la fonction existe deja, i.e. a deja ete definit par ailleurs" << "\n# b) soit on veut definir une fonction interne a la fonction combinee" << "\n# NB: dans le cas a) la fonction existante peut etre utilisee plusieurs fois" << "\n# par exemple pour la definition de plusieurs fonctions combinees" << "\n# dans le cas b) la fonction definie en interne n'est pas accessible en" << "\n# en dehors de la fonction combinee qui est en cours de definition " << "\n# -> syntaxe cas a) : " << "\n# fct_base= nom_fonction_existante " << "\n# ou " << "\n# fct_base= : le mot cle " << "\n# nom_fonction_existante : le nom de la fonction" << "\n# -> syntaxe cas b) : " << "\n# fct_base= nom_type_fonction ident_interne_ nom_identificateur " << "\n# ou " << "\n# fct_base= : le mot cle " << "\n# nom_type_fonction : une chaine de caracteres donnant le type " << "\n# de la fonction que l'on veut definir " << "\n# ident_interne_ : mot clé indique que c'est une fonction interne " << "\n# nom_identificateur : le nom interne qu'on souhaite pour la fontion " << "\n# " << "\n# la liste des fonctions de base doit se terminer par le mot cle " << "\n# (sur une ligne seule ): " << "\n# fin_fcts_interne_fonction_combinee_ " << "\n# " << "\n# 2) --- on definit la liste de variables de la fonction globale " << "\n# cette liste inclu par defaut tout d'abord : " << "\n# i) les variables internes de chaque fonction de base, dans l'ordre " << "\n# ou les fonctions sont declarees. On n'a donc pas a les redeclarer. " << "\n# ii) de nouvelles variables avec les 2 syntaxes suivantes " << "\n# a) soit une variable par ligne selon la syntaxe: " << "\n# un_argument= nom_argument" << "\n# ou " << "\n# un_argument= : le mot cle " << "\n# nom_argument : le nom de la variable " << "\n# b) soit une liste de variables (sur une ligne) selon la syntaxe " << "\n# deb_list_var_ nom1 nom2 ... fin_list_var_ " << "\n# ou " << "\n# deb_list_var_ et fin_list_var_ : balises encadrant la liste" << "\n# nom1 nom2 ... : le nom de chaque variable " << "\n# " << "\n# NB: les variables peuvent etre des grandeurs locales ou globales" << "\n# " << "\n# 3) --- on definit l'expression de la fonction globale " << "\n# l'expression s'ecrit une une ligne (qui peut-etre fractionnee " << "\n# via le caractere \ cf. doc). Elle doit commencer par le mot " << "\n# cle fct= suivi d'une expression analytique quelconque (cf. doc " << "\n# fonction analytique) " << "\n# l'expression peut contenir : " << "\n# les noms de variables, le nom des fonctions ou de leur " << "\n# identificateur. " << "\n# " << "\n# La liste des variables (partie 2) et la definition de l'expression " << "\n# generale doit se terminer par le mot cle (sur une ligne seule ): " << "\n# fin_parametres_fonction_combinee_ " << "\n# " << "\n# exemple 1: def de la fonction addition_simple : " << "\n# somme de deux fonctions de base " << "\n# " << "\n# addition_simple FONC_SCAL_COMBINEES_ND " << "\n# fct_base= montee # fct 1 " << "\n# fct_base= relax # fct 2 " << "\n# fin_fcts_interne_fonction_combinee_ " << "\n# fct= montee + relax " << "\n# fin_parametres_fonction_combinee_ " << "\n# " << "\n# NB: ici les fonctions montee et relax doivent exister par ailleurs " << "\n# les parametre de addition_simple sont ceux de montee + ceux de " << "\n# relax " << "\n# " << "\n# exemple 2: def de la fonction addition_pondere : " << "\n# somme ponderee de deux fonctions de base definies en interne" << "\n# " << "\n# addition_pondere FONC_SCAL_COMBINEES_ND " << "\n# fct_base= FONCTION_EXPRESSION_LITTERALE_nD ident_interne_ F1 " << "\n# un_argument= x " << "\n# fct= sin(x) " << "\n# fin_parametres_fonction_expression_litterale_ " << "\n# fct_base= FONCTION_EXPRESSION_LITTERALE_nD ident_interne_ F2 " << "\n# un_argument= y " << "\n# fct= cos(y) " << "\n# fin_parametres_fonction_expression_litterale_ " << "\n# fin_fcts_interne_fonction_combinee_ " << "\n# deb_list_var_ e ENERGIE_CINETIQUE fin_list_var_ " << "\n# fct= (1.-e^2)*(ENERGIE_CINETIQUE-1.)*F1 + e^2*F2 " << "\n# fin_parametres_fonction_combinee_ " << "\n# " << "\n# NB: . ici les fonctions de base F1(x) et F2(y) sont definies en interne " << "\n# . les parametre de addition_pondere sont dans l'ordre: " << "\n# x, y, e, ENERGIE_CINETIQUE " << "\n# . le parametre ENERGIE_CINETIQUE est une grandeur globale " << "\n# " << "\n# exemple 3: def de choix_selon_energie_cinetique : " << "\n# -> choix entre deux fonctions suivant la valeur de l'energie cinetique " << "\n# " << "\n# choix_selon_energie_cinetique FONC_SCAL_COMBINEES_ND " << "\n# fct_base= F1 # fct 1 " << "\n# fct_base= F2 # fct 2 " << "\n# fin_fcts_interne_fonction_combinee_ " << "\n# un_argument= ENERGIE_CINETIQUE " << "\n# fct= (ENERGIE_CINETIQUE < 2) ? F1 : F2 " << "\n# fin_parametres_fonction_combinee_ " << "\n# " << "\n# NB: ici les fonctions F1 et F2 doivent exister par ailleurs " << "\n# les parametre sont ceux de F1 + ceux de F2 + ENERGIE_CINETIQUE" << "\n# si ENERGIE_CINETIQUE < 2 alors F1 sinon F2 " << "\n# " << "\n# " << "\n# " << "\n# type d'expression des tenseurs: " << "\n# Tenseur_base_ad_hoc_ suivi de " << "\n# 0 si dans la base ad hoc " << "\n# 1 si dans une base globale " << "\n# NB: les deux sont en orthonorme " << "\n# par defaut, c'est dans une base ad hoc" << "\n# ex: Tenseur_base_ad_hoc_ 0 " << "\n# " << "\n# " << "\n# niveau d'impression: dans certain cas il peut-etre utile d'afficher " << "\n# les resultats intermediaires des calculs et egalement des erreurs intermediaires " << "\n# pour mettre en route ce fonctionnement il faut indiquer sur une ligne seule le mot cle " << "\n# permet_affichage_ suivi d'un chiffre donnant le niveau d'impression (entre 0 et 10) " << "\n# ex: permet_affichage_ 5 " << "\n# Remarques: 1) ceci ne fonction qu'avec la version non fast " << "\n# cependant, la lecture reste correcte avec le mot cle permet_affichage_ " << "\n# mais la presence du mot cle n'entraine aucune action en fast " << "\n# 2) le mot cle doit etre indique avant le dernier mot cle : " << "\n# fin_parametres_fonction_combinee_ " << "\n# " << endl; }; }; // calcul des valeurs de la fonction, retour d'un tableau de scalaires Tableau & Fonc_scal_combinees_nD::Valeur_FnD_interne(Tableau * xi) { try {// -- il s'agit ici d'un appel générique, qui est valable pour // toute fonction combinée, pas forcément scalaire int tail = Fi.Taille(); int i_in_xi=1; // indice pour se déplacer dans xi // int i_in_tab_coor=1;// indice pour se déplacer dans tab_coor int i_fval_int=1; // indice pour se déplacer dans fval_int int taille_xi=0; // init par défaut // int taille_tab_coor = 0; // init par défaut // int taille_totale_coor = 0; // idem if (xi != NULL) taille_xi=xi->Taille(); // if (tab_coor != NULL) // taille_tab_coor = tab_coor->Taille(); // // on considère que la dimension des coordonnées est c'est de la dimension totale // const int& dim = ParaGlob::Dimension(); // taille_totale_coor = taille_tab_coor * dim; // int k_coor=1; // une variable pour se déplacer dans coor for (int i=1; i<= tail; i++,i_fval_int++) {Fonction_nD* fo = Fi(i); // récup de la fonction // on commence par remplir le tableau de passage de paramètres // il s'agit des variables patentées de la fonction int nb_var = fo->NbVariable_locale(); Tableau & fVal_Fi = tab_fVal_Fi(i); Tableau & ret_Fi = tab_ret_Fi(i); for (int j=1;j<=nb_var;j++) { // on se déplace d'abord dans xi if (i_in_xi <= taille_xi) {fVal_Fi(j) = xi->operator()(i_in_xi);i_in_xi++;} else { cout << "\n *** pb de nombre d'argument non coherentes !! " << " on n'a pas assez d'arguments pour l'appel de la fonction inter: "; fo->Affiche(5); cout << "\n revoir la mise en donnees " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..."<Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; // récup des valeurs calculées ret_Fi = fo->Valeur_FnD_interne(&fVal_Fi); // -- partie spécifique à la fonction scalaire tab_fVal_int(i_fval_int) = ret_Fi(1); // retour scalaire a priori #ifdef MISE_AU_POINT // if (permet_affichage > 0) {double absret_Fi= Dabs( tab_fVal_int(i_fval_int)); if ((!isfinite(absret_Fi)) || (isnan(absret_Fi)) ) { cout << "\n probleme dans le retour d'une fonction interne nb: "<Affiche(5); cout << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..."; cout << endl; // ret_Fi = fo->Valeur_FnD_interne(&fVal_Fi); cout <<"\n >>> arbre d'appel : fonction this : "; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; #endif }; // on finit de remplir le tableau de passage pour la fonction maître // nb_var_int = les variables internes patentées, c-a-d hors variables globales int nb_var_int = nom_variables_int.Taille() - tail; // a voir, mais je crois que la suite n'est pas une vrai vérif! // // petite vérif // #ifdef MISE_AU_POINT // if (tab_fVal_int.Taille() != (nb_var_int+tail_enu)) // { cout << "\n *** pb de nombre d'argument non coherentes !! " // << " taille_xi+taille_totale_coor-nb_var_Fi= "<operator()(i_in_xi);i_in_xi++;} // // si xi est épuisé on regarde le tableau de coordonnée // else if (i_in_tab_coor <= taille_tab_coor) // {Coordonnee& A=tab_coor->operator()(i_in_tab_coor); // tab_fVal_int(i_fval_int) = A(k_coor); // // on gère les bornes // k_coor++; // if (k_coor>dim) // {i_in_tab_coor++;k_coor=1;}; // } else { cout << "\n *** pb de nombre d'argument non coherentes !! " << " on n'a pas assez d'arguments pour l'appel de la fonction globale: "; cout << "\n revoir la mise en donnees " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..."<Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; // maintenant les variables globales éventuelles // on ne peut pas utiliser la fonction générique: // Fonction_nD::Recup_Grandeurs_globales(); // car ici on fait la distinction entre toto_int et toto // toto pour enu_variable_globale et nom_variables_globales // à voir par la suite si on ne peut pas spécialiser ... mais ce n'est pas forcément // un pb d'avoir une méthode spécifique int tail_enu = enu_variables_globale_int.Taille(); // les variables globales for (int i=1;i<= tail_enu;i++,i_fval_int++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale_int(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER: {Grandeur_Double_Nommer_indicer& gr = *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale_int "<< Nom_GrandeurGlobale(enu_variables_globale_int(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale_int "<< Nom_GrandeurGlobale(enu_variables_globale_int(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; }; // idem pour les variables globales indiçées par des strings int tail_nom = nom_variables_globales_int.Taille(); // idem avec des noms for (int i=1;i<= tail_nom;i++,i_fval_int++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales_int(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER: {Grandeur_Double_Nommer_indicer& gr = *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); break; } case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } break; } case TABLEAU_T: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; }; // appel de la fonction maître int nNum; double * v = p.Eval(nNum); for (int i=0; i 0) {double absret_Fi= 0.; for (int i=0; i>> arbre d'appel : fonction this : "; this->Affiche(5); cout << endl; // p.Eval(nNum); // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; #endif } catch(mu::Parser::exception_type &e) { cout << "\n ** Fonc_scal_combinees_nD: erreur dans l'appel de la fonction "<< expression_fonction << " \n xi= "<< *xi; cout << "\n Message: " << e.GetMsg() << "\n"; cout << "Formula: " << e.GetExpr() << "\n"; cout << "Token: " << e.GetToken() << "\n"; cout << "Position: " << e.GetPos() << "\n"; cout << "Errc: " << e.GetCode() << "\n" << endl ; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref << " d'expression: " << expression_fonction << " \n xi= "<< *xi << "\n"; this->Affiche(5); cout << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..."; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto); Sortie(1); }; // retour return tab_ret; }; // calcul des valeurs de la fonction, dans le cas où les variables // sont toutes des grandeurs globales: pour l'instant que pour des variables scalaires Tableau & Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne() { // on récupère les grandeurs globales // on ne peut pas utiliser la fonction générique: // Fonction_nD::Recup_Grandeurs_globales(); // car ici on fait la distinction entre toto_int et toto // toto pour enu_variable_globale et nom_variables_globales // à voir par la suite si on ne peut pas spécialiser ... mais ce n'est pas forcément // un pb d'avoir une méthode spécifique // en debug on vérifie que les grandeurs globales sont présentent #ifdef MISE_AU_POINT try { // on vérifie tout d'abord que toutes les variables sont globales if (nom_variables.Taille() != 0) { cout << "\n ** erreur dans l'appel de la fonction "<< nom_ref; cout << " toutes les variables ne sont pas globales !! " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..."<Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; // maintenant on vérifie la présence des variables globales int taille = enu_variables_globale.Taille(); for (int i=1;i<= taille;i++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i))); if (pointe == NULL) { cout << "\n *** pb dans Fonc_scal_combinees_nD " << nom_ref << " !! " << " la variable globale "<< nom_variables(i) << ", n'est pas disponible, on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..."<Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref << " d'expression: " << expression_fonction; cout << " verifier la presence des grandeurs globales voulues " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..."<Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif // en debug on vérifie que les grandeurs globales sont présentent #ifdef MISE_AU_POINT try { int tail_nom = nom_variables_globales.Taille(); for (int i=1;i<= tail_nom;i++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i))); if (pointe == NULL) { cout << "\n *** pb dans Fonc_scal_combinees_nD " << nom_ref << " !! " << " la variable globale "<< nom_variables_globales(i) << ", n'est pas disponible, on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..."<Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif // arrivée ici toutes les grandeurs existent try { // on va balayer les différentes fonctions internes // -- il s'agit ici d'un appel générique, qui est valable pour // toute fonction combinée, pas forcément scalaire int tail = Fi.Taille(); int i_fval_int=1; // indice pour se déplacer dans fval_int for (int i=1; i<= tail; i++,i_fval_int++) {Fonction_nD* fo = Fi(i); // récup de la fonction Tableau & ret_Fi = tab_ret_Fi(i); // récup des valeurs calculées ret_Fi = fo->Valeur_pour_variables_globales_interne(); // -- partie spécifique à la fonction scalaire tab_fVal_int(i_fval_int) = ret_Fi(1); // retour scalaire a priori #ifdef MISE_AU_POINT {double absret_Fi= Dabs( tab_fVal_int(i_fval_int)); if ((!isfinite(absret_Fi)) || (isnan(absret_Fi)) ) { cout << "\n probleme dans le retour d'une fonction interne nb: "<Affiche(5); cout << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(.."; cout << endl; cout <<"\n >>> arbre d'appel : fonction this : "; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; #endif }; int tail_enu = enu_variables_globale_int.Taille(); // les variables globale_int // les variables globales int éventuelles for (int i=1;i<= tail_enu;i++,i_fval_int++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale_int(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER: {Grandeur_Double_Nommer_indicer& gr = *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale_int "<< Nom_GrandeurGlobale(enu_variables_globale_int(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale_int "<< Nom_GrandeurGlobale(enu_variables_globale_int(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; }; // idem mais typées sous forme de string int tail_nom = nom_variables_globales_int.Taille(); for (int i=1;i<= tail_nom;i++,i_fval_int++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales_int(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER: {Grandeur_Double_Nommer_indicer& gr = *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); break; } case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } break; } case TABLEAU_T: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal_int(i_fval_int) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto); Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< expression_fonction << " la variable globale "<< nom_variables_globales_int(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..." <Affiche(5);ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; }; if (permet_affichage > 5) {cout << "\n parametres d'appel: "; int nb_var = tab_fVal_int.Taille(); for (int j=1;j<=nb_var;j++) { cout << " para("< 0) {double absret_Fi= 0.; for (int i=0; i>> arbre d'appel : fonction this : "; this->Affiche(5); cout << endl; // p.Eval(nNum); // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; #endif } catch(mu::Parser::exception_type &e) { cout << "\n ** erreur Fonc_scal_combinees_nD " << nom_ref << " d'expression: " << expression_fonction << "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..."; cout << "\n Message: " << e.GetMsg() << "\n"; cout << "Formula: " << e.GetExpr() << "\n"; cout << "Token: " << e.GetToken() << "\n"; cout << "Position: " << e.GetPos() << "\n"; cout << "Errc: " << e.GetCode() << "\n" << endl ; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref << " d'expression: " << expression_fonction; cout << "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(..."; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto); Sortie(1); }; return tab_ret; }; // 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this list & Fonc_scal_combinees_nD::ListDependanceCourbes(list & lico) const { // tout d'abord on vide la liste passée en paramètres if (lico.size() != 0) lico.clear(); return lico; }; //----- lecture écriture de restart ----- // cas donne le niveau de la récupération // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void Fonc_scal_combinees_nD::Lecture_base_info(ifstream& ent,const int cas) { // on n'a que des grandeurs constantes if (cas == 1) { string nom; ent >> nom; // "\n " // string nom1=nom.substr(nom.find(<)+1,nom.find(>)-1); // lecture et vérification de l'entête string type_fonction_a_lire('<'+Nom_Fonction_nD(this->Type_Fonction())+'>'); if (nom != type_fonction_a_lire) //"Fonc_scal_combinees_nD") { cout << "\n erreur dans la verification du type de fonction lue "; cout << "\n fonction en lecture: " << type_fonction_a_lire; cout << "\n Fonc_scal_combinees_nD::Lecture_base_info(... "; Sortie(1); }; // lecture du nom de référence ent >> nom >> nom_ref; // lecture du nombre de fonction int tai=0; ent >> nom >> tai; Fi.Change_taille(tai); nom_fonctioni.Change_taille(tai); // lecture des fonctions string nom1,nom2,nom3; for (int i=1;i<=tai;i++) { // lecture de la fonction de base ent >> nom1 >> nom2 >> nom3; if (nom1 != "fonction=") { cout << "\n erreur dans la verification du type, on attendait le mot cle fonction= " << " et on a lu " << nom1 << " "; cout << "\n Fonc_scal_combinees_nD::Lecture_base_info(... "; Sortie(1); } else { if (nom2 == "FONCTION_INTERNE") {// cas d'une fonction en interne // 1) on commence par effacer la fonction existante si nécessaire if (Fi(i) != NULL) {if (Fi(i)->NomFonction() == "_") delete Fi(i);}; // 2) on crée la fonction adoc nom2="_"; Fi(i) = Fonction_nD::New_Fonction_nD(nom2,Id_Nom_Fonction_nD (nom3.c_str())); // 3) on lit les données particulières Fi(i)->Lecture_base_info(ent,cas); nom_fonctioni(i)="i_interne_i"; } else {// cas d'une fonction externe on lit le nom nom_fonctioni(i) = nom2; }; }; }; // lecture des variables // les arguments gérés par la classe mère Fonction_nD::Lect_base_info(ent,cas); // maintenant l'expression ent >> nom >> expression_fonction ; // on lit les variables internes de travail, que l'on pourrait sans doute // reconstruire mais c'est aussi simple de les sauvegarder et en lecture // de repartir d'une forme complète ent >> nom >> nom_variables_int; // on met à jour la taille du tableau de passage de variables tab_fVal_int.Change_taille(nom_variables_int.Taille()); // on lit le tag de fin de définition ent >> nom; // "\n " // maintenant on initialise la fonction analytique Init_fonction_analytique(); // on définit le paramètre depend_M de la classe maître en fonction des nom_variables Fonction_nD::Definition_depend_M(); // idem pour le temps Fonction_nD::Definition_depend_temps(); // idem pour la cohérence avec les enu // Fonction_nD::Construction_enu_etendu_et_quelconque(); // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); } }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Fonc_scal_combinees_nD::Ecriture_base_info(ofstream& sort,const int cas) { if (cas == 1) { sort << "\n " << " nom_ref= " << nom_ref; int tai = Fi.Taille(); sort << " nbfonction= " << tai << " "; // le nombre de fonctions // on parcours toutes les fonctions for (int i=1;i<= tai; i++) { // si c'est une fonction interne on l'affiche globalement // si c'est une fonction globale, on n'affiche que son nom sort << "\n fonction_de_base: " << i << " "; if (Fi(i)->NomFonction() == "_") {// cas d'une fonction interne sort << "\n fonction= FONCTION_INTERNE " << Fi(i)->Type_Fonction(); Fi(i)->Ecriture_base_info(sort,cas); } else // cas d'une fonction externe {sort << "\n fonction= " << Fi(i)->NomFonction() << " " << Fi(i)->Type_Fonction();}; }; // les variables // les arguments gérés par la classe mère Fonction_nD::Ecrit_base_info(sort,cas); // retour des valeurs sort << "\n taille vecteur de retour: "<< this->NbComposante() << "\n f(x)= " << expression_fonction << " "; // on sort les variables internes de travail, que l'on pourrait sans doute // reconstruire mais c'est aussi simple de les sauvegarder et en lecture // de repartir d'une forme complète sort << "\n nom_variables_int= " << nom_variables_int; sort << "\n \n"; }; }; // sortie du schemaXML: en fonction de enu void Fonc_scal_combinees_nD::SchemaXML_Fonctions_nD(ofstream& ,const Enum_IO_XML enu) { switch (enu) { case XML_TYPE_GLOBAUX : {/*sort << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n" << "\n " << "\n fonction F_UNION_1D constituee de N points " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n";*/ break; } case XML_IO_POINT_INFO : { break; } case XML_IO_POINT_BI : { break; } case XML_IO_ELEMENT_FINI : { break; } }; }; // dans le cas où les fonctions membres sont des fonctions externes // fonction pour les définir // les fonctions sont défini en interne que si les fonctions argument sont elles même // des fonctions locales. c'est-à-dire si FFi(i)->NomFonction() ="_" alors on recrée une fonction // interne avec new pour Fi(i), sinon Fi(i)=FFi(i) et pas de création; // dans le cas où FFi(i) est NULL on passe, pas de traitement pour ce pointeur void Fonc_scal_combinees_nD::DefFonctionsMembres(Tableau & FFi) { // l'objectif est // 1) d'adapter le nombre de fonction à celui de FFi // 2) de ne changer que celle qui sont non nul dans FFi int tai = Fi.Taille(); // taille existante int taii = FFi.Taille(); // taille du nouveau tableau // on commence par effacer les fonctions existantes supérieur à taii if (taii < tai) for (int i=taii;i<= tai; i++) if ((Fi(i) != NULL)&&(nom_fonctioni(i)=="i_interne_i")) { delete Fi(i);Fi(i)=NULL;}; // on change de taille Fi.Change_taille(taii); tai = taii; for (int i=1;i<= tai; i++) { // création d'une fonction locale que si elle était déjà locales if (FFi(i) != NULL) {if (FFi(i)->NomFonction() == "_") // cas où FFi(i) est une fonction non globale { if (Fi(i)==NULL) // cas où la fonction locale n'est pas défini mais on veut une fonction interne { Fi(i)=Fonction_nD::New_Fonction_nD(*(FFi(i)));nom_fonctioni(i)="i_interne_i";} else if (Fi(i)->NomFonction() == "_") // cas où la fonction F1 est local et on veut la remplacer par une nouvelle locale { delete Fi(i); Fi(i)=Fonction_nD::New_Fonction_nD(*(FFi(i)));nom_fonctioni(i)="i_interne_i"; } else // cas où la fonction Fi(i est global et on veut la remplacer par une locale { Fi(i)=Fonction_nD::New_Fonction_nD(*(FFi(i)));nom_fonctioni(i)="i_interne_i";}; } else // cas ou FFi(i) est une fonction globale { if (Fi(i)==NULL) // cas où la fonction locale n'est pas défini { Fi(i)=FFi(i);nom_fonctioni(i)="e_externe_e";} else if (Fi(i)->NomFonction() == "_") // cas où la fonction Fi(i) est local et on veut la remplacer par une globale { delete Fi(i); Fi(i)=FFi(i);nom_fonctioni(i)="e_externe_e"; } else // cas où la fonction Fi(i) est global et on veut la remplacer par une globale { Fi(i)=FFi(i);nom_fonctioni(i)="e_externe_e";}; }; // on met à jour les variables de la fonction Fi(i)->Mise_a_jour_variables_globales(); }; }; // --- on renseigne les variables de la fonction mère: Fonction_nD Fonc_scal_combinees_nD::Mise_a_jour_variables_nD(); }; // mise à jour des variables de la classe mère en fonction des fonctions membres void Fonc_scal_combinees_nD::Mise_a_jour_variables_nD() { // l'opération suivante n'est possible que si les Fi sont non nulles int tail = Fi.Taille(); // les fonctions if (tail != 0) { if (Fi(1) != NULL) {// --- on renseigne les variables de la fonction mère: Fonction_nD int nb_var = 0; // init // l'ordre de lequel la mise à jour est faite est important // il faut être sûr que les fonctions membres soient elles-mêmes // mise à jour (ce qui est peut-être le cas) // dans le doute (au risque de multiplier les mises à jour mais tant pi) // on force une mise à jour préventive for (int i = 1;i<=tail;i++) if (Fi(i) != NULL) Fi(i)->Mise_a_jour_variables_globales(); for (int i = 1;i<=tail;i++) nb_var += Fi(i)->Nom_variables().Taille(); // puis les variables patentées nb_var += nom_variables_int.Taille() - tail; // on dimensionne nom_variables.Change_taille(nb_var); tab_fVal.Change_taille(nb_var); int inom_variable = 1; for (int i = 1;i<=tail;i++) {//nb_var += Fi(i)->NbVariable(); const Tableau & nom_var = Fi(i)->Nom_variables(); int tail = nom_var.Taille(); for (int i=1;i<= tail;i++,inom_variable++) {nom_variables(inom_variable)=nom_var(i); }; // les tableaux de passage tab_fVal_Fi(i).Change_taille(tail); // les tableaux de retour de chaque fonction tab_ret_Fi(i).Change_taille(Fi(i)->NbComposante()); }; // puis on s'occupe des variables patentées int ideb = ident_interne.Taille(); int nb_var_patente = nom_variables_int.Taille() - tail; for (int i=1; i<= nb_var_patente;i++,inom_variable++) nom_variables(inom_variable)=nom_variables_int(ideb+i); // -- maintenant on s'occupe des grandeurs globales // pour les variables globales on ne garder qu'un // exemplaire de chacun list li_enu_glob; list li_nom_glob; for (int i = 1;i<=tail;i++) {// pour les énumérés const Tableau & tab_enu = Fi(i)->Enu_variables_globales(); int nb_enu = tab_enu.Taille(); for (int ienu = 1; ienu <= nb_enu; ienu++) li_enu_glob.push_back(tab_enu(ienu)); // pour les noms const Tableau & tab_nom = Fi(i)->Nom_variables_globales(); int nb_nom = tab_nom.Taille(); for (int inom = 1; inom <= nb_nom; inom++) {li_nom_glob.push_back(tab_nom(inom)); //cout << "\n debug Fi("<