// 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-2022 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 "Fonction_expression_litterale_nD.h"
#include "Sortie.h"
#include "ConstMath.h"
#include "MathUtil.h"
#include "ParaGlob.h"
#include "MotCle.h"
#include "TypeQuelconqueParticulier.h"
#include "CharUtil.h"
// CONSTRUCTEURS :
Fonction_expression_litterale_nD::Fonction_expression_litterale_nD(string nom) :
Fonction_nD(nom,FONCTION_EXPRESSION_LITTERALE_nD)
,expression_fonction(),p(),tab_fVal(),tab_ret()
// ,ordre_troncature(2)
{};
// def de toutes les grandeurs -> donne une fonction utilisable
Fonction_expression_litterale_nD::Fonction_expression_litterale_nD
( string nom_ref // nom de ref de la fonction
,Tableau & nom_variables_non_globales // les variables non globales
,Tableau & enu_variables_globale // enu globaux
,Tableau & nom_variables_globales_ // idem sous forme de strings
,string& express_fonction) : // la formule de la fonction
Fonction_nD(nom_ref,nom_variables_non_globales,enu_variables_globale
,nom_variables_globales_,FONCTION_EXPRESSION_LITTERALE_nD )
// ---- la partie spécifiques à la fonction analytique
,expression_fonction(express_fonction),p(),tab_fVal(),tab_ret()
{// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
// --> c'est déjà effectué dans le constructeur de Fonction_nD
//et on définie la fonction et les variables attachées
Fonction_expression_litterale_nD::Init_fonction_analytique();
};
// de copie
Fonction_expression_litterale_nD::Fonction_expression_litterale_nD(const Fonction_expression_litterale_nD& Co) :
Fonction_nD(Co)
,expression_fonction(Co.expression_fonction),p(),tab_fVal(Co.tab_fVal)
,tab_ret(Co.tab_ret)
{ // 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
Fonction_expression_litterale_nD::Init_fonction_analytique();
};
// de copie à partir d'une instance générale
Fonction_expression_litterale_nD::Fonction_expression_litterale_nD(const Fonction_nD& Coo) :
Fonction_nD(Coo)
,expression_fonction(),p(),tab_fVal(),tab_ret()
{ if (Coo.Type_Fonction() != FONCTION_EXPRESSION_LITTERALE_nD)
{ cout << "\n erreur dans le constructeur de copie pour une Fonction_expression_litterale_nD "
<< " à partir d'une instance générale ";
cout << "\n Fonction_expression_litterale_nD::Fonction_expression_litterale_nD(const Fonction_nD& Co) ";
Sortie(1);
};
// définition des données
Fonction_expression_litterale_nD & Co = (Fonction_expression_litterale_nD&) Coo;
tab_fVal=Co.tab_fVal;
expression_fonction = Co.expression_fonction;
// 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
Fonction_expression_litterale_nD::Init_fonction_analytique();
};
// DESTRUCTEUR :
Fonction_expression_litterale_nD::~Fonction_expression_litterale_nD()
{};
// METHODES PUBLIQUES :
// --------- virtuelles ---------
// Surcharge de l'operateur = : realise l'egalite de deux fonctions
Fonction_nD& Fonction_expression_litterale_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 Fonction_expression_litterale_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 Fonction_expression_litterale_nD & Co = ((Fonction_expression_litterale_nD &) elt);
tab_fVal=Co.tab_fVal;
expression_fonction = Co.expression_fonction;
// 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
Fonction_expression_litterale_nD::Init_fonction_analytique();
return *this;
};
// affichage de la fonction
void Fonction_expression_litterale_nD::Affiche(int niveau) const
{ cout << " Fonction_expression_litterale_nD " << nom_ref ;
cout << " \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(niveau);
if (niveau > 0)
{ cout << "\n derniers parametres d'appel: ";
int nb_var = tab_fVal.Taille();
for (int j=1;j<=nb_var;j++)
{ cout << " para("<entree) >> nom_ref;}
else {nom_ref=nom;};
entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne
// on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_fonction_expression_litterale_"
// 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; // idem enum glob
// list < string> list_de_variables_nom_globales; // idem string glob
string titi;
while (strstr(entreePrinc->tablcar,"fin_parametres_fonction_expression_litterale_")==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 courbe avec expression litterale : on n'a pas trouve le mot cle "
<< " fin_parametres_fonction_expression_litterale_ et par contre la ligne courante contient un mot cle global ";
entreePrinc->MessageBuffer("** erreur des parametres d'une courbe 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_expression_litterale_")
// 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 courbe expression litterale**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// on lit maintenant l'expression littérale ou la ou les variables
if (titi == "fct=")
{ std::getline (*(entreePrinc->entree), expression_fonction);
}
// cas de la lecture d'une variable
else if (Fonction_nD::Est_relatif_a_lecture_variable(titi))
{Fonction_nD::Lecture_variables(titi,entreePrinc);
}
/* else if(titi == "un_argument=")
{string truc; *(entreePrinc->entree) >> truc;
// on regarde s'il s'agit d'une variable globale correspondant à un énuméré global
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 courbe expression litterale **");
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_expression_litterale_")
{ cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu "
<< " on a lu : " << titi << endl;
entreePrinc->MessageBuffer("**Fonction_expression_litterale_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 f(x) , l'expression est absente "
<< " ou il y a une erreur de syntaxe ";
entreePrinc->MessageBuffer("**Fonction_expression_litterale_nD::LectureDonneesParticulieres**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
/* // on supprime les doublons dans les variables globales
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.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(ienu) = *il;
};
// idem pour les noms de ref
int nb_nom = list_de_variables_nom_globales.size();
int i_nom=1; 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(i_nom) = *il;
};
// for (Enum_GrandeurGlobale enu : list_enu_variables_glob)
// { enu_variables(ienu) = enu;
// ienu++;
// };
// --- on définie les variables qui ne sont pas globales ---
// par contre on va changer l'ordre d'apparition des variables
// en 1) les scalaires, 2) les coordonnées , 3) les tenseurs
// et .... rajouter
// cas des variables non globales
list < string>::iterator il,ilfin = list_de_variables.end();
int i= 1;
for (il = list_de_variables.begin();il != ilfin;il++,i++)
{ nom_variables(i)=(*il); // on récupère le nom
};
*/
// affichage de l'expression si niveau suffisant
if (permet_affichage > 6)
cout << "\n expression de la fonction: " << expression_fonction;
int taille = nom_variables.Taille(); // récup des tailles
int nb_enu = enu_variables_globale.Taille();
int nb_nom = nom_variables_globales.Taille();
tab_fVal.Change_taille(taille+nb_enu+nb_nom); // idem mais en tenant compte des var globales
// on définie la fonction et les variables attachées
Fonction_expression_litterale_nD::Init_fonction_analytique();
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
Fonction_nD::Construction_index_conteneurs_evoluees();
// on définit le paramètre depend_M de la classe maître en fonction des nom_variables
if (permet_affichage > 6)
cout << "\n == >>> lecture donnees particuliere de la fct: " << nom_ref << ") "
<< " operations finales: " ;
Fonction_nD::Definition_depend_M();
// idem pour le temps
Fonction_nD::Definition_depend_temps();
Fonction_nD::Affichage_variables(); // affichage éventuel
};
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
// globales en cours de calcul
void Fonction_expression_litterale_nD::Mise_a_jour_variables_globales()
{ // appel de la fonction interne pour modifier les noms de variables
bool a_changer = Fonction_nD::Mise_a_jour_variables_globales_interne();
// maintenant il faut redéfinir l'ordre d'appel de la fonction
if (a_changer)
{ // 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
Fonction_expression_litterale_nD::Init_fonction_analytique();
};
};
// def info fichier de commande
void Fonction_expression_litterale_nD::Info_commande_Fonctions_nD(UtilLecture & entreePrinc)
{ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
cout << "\n cas de la fonction Fonction_expression_litterale_nD : "
<< " \ndefinition standart (rep o) ou documentation exhaustive (rep n'importe quoi) ? ";
string rep = "_"; rep = lect_return_defaut(false,"o");
sort << "\n# ....... fonction litterale nD ........";
// cas particulier
if ((rep != "o") && (rep != "O" ) && (rep != "0") )
{sort << "\n# exemple de definition d'une fonction Fonction_expression_litterale_nD"
<< " ( f(i,j) = une expression de i et j|"
<< "\n exemple_fonct_litt_nD FONCTION_EXPRESSION_LITTERALE_nD "
<< "\n un_argument= i un_argument= j "
<< "\n fct= (i < 2) ? ((j < 1000) ? -50. : 0. ): ((j < 2000) ? -10. : 0. ) "
<< "\n fin_parametres_fonction_expression_litterale_ "
<< endl;
}
else // cas d'une description exhaustive
{ sort << "\n# Il s'agit d'une fonction definie "
<< "\n# sous forme d'une expression analytique quelconque "
<< "\n# "
<< "\n# 1) --- on definit la liste de variables "
<< "\n# cette liste inclu des 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# 2) --- on definit l'expression de la fonction globale "
<< "\n# l'expression s'ecrit sur 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, et des constantes "
<< "\n# "
<< "\n# La liste des variables et la definition de l'expression "
<< "\n# generale doit se terminer par le mot cle (sur une ligne seule ): "
<< "\n# fin_parametres_fonction_expression_litterale_ "
<< "\n# "
<< "\n#............................................"
<< "\n# exemple de definition d'une fonction Fonction_expression_litterale_nD"
<< " ( f(i,j) = une expression de i et j|"
<< "\n exemple_fonct_litt_nD FONCTION_EXPRESSION_LITTERALE_nD "
<< "\n un_argument= i un_argument= j "
<< "\n fct= (i < 2) ? ((j < 1000) ? -50. : 0. ): ((j < 2000) ? -10. : 0. ) "
<< "\n fin_parametres_fonction_expression_litterale_ "
<< "\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# 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_expression_litterale_ "
<< endl;
};
};
// calcul des valeurs de la fonction, retour d'un tableau de scalaires
// pas d'affichage sauf s'il y a une erreur
Tableau & Fonction_expression_litterale_nD::Valeur_FnD_interne(Tableau * xi)
{ 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=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 celle 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
try
{int nb_var_int = nom_variables.Taille();
int tail_enu = enu_variables_globale.Taille(); // les variables globales
int tail_nom = nom_variables_globales.Taille(); // idem avec des noms
#ifdef MISE_AU_POINT
if (tab_fVal.Taille() != (taille_xi+tail_enu+tail_nom))
{ cout << "\n *** pb de dimensions d'argument non coherentes !! "
<< " taille_xi "<Affiche();
// on génère une interruption ce qui permettra de dépiler les appels
ErrCalculFct_nD toto;
throw (toto);
Sortie(1);
};
#endif
// on remplit le tableau de passage pour la fonction maître
// 1) tout d'abord pour les variables patentées
for (int ii = 1;ii<= nb_var_int;ii++,i_fval++)
{
// on se déplace d'abord dans xi
if (i_in_xi <= taille_xi)
{tab_fVal(i_fval) = xi->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(i_fval) = 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: ";
this->Affiche();
cout << "\n revoir la mise en donnees "
<< "\n Fonction_expression_litterale_nD::Valeur_FnD_interne(..."< 0)
{double absret_Fi= 0.;
for (int i=0; i>> arbre d'appel : fonction this : ";
this->Affiche(5);
cout << endl;
// on génère une interruption ce qui permettra de dépiler les appels
ErrCalculFct_nD toto;throw (toto);Sortie(1);
};
};
#endif
}
catch(mu::Parser::exception_type &e)
{ cout << "\n ** erreur dans l'appel de la fonction "
<< nom_ref << " d'expression " << expression_fonction
<< " \n xi= "<Affiche();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= "<Affiche();
cout << "\n Fonction_expression_litterale_nD::Valeur_FnD_interne(...";
// on génère une interruption ce qui permettra de dépiler les appels
ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
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 & Fonction_expression_litterale_nD::Valeur_pour_variables_globales_interne()
{
try
{
// on récupère les grandeurs globales
Fonction_nD::Recup_Grandeurs_globales();
// on affecte les grandeurs
int taille = x_glob.Taille();
for (int i=1;i<= taille;i++)
tab_fVal(i) = x_glob(i);
if (permet_affichage > 5)
{cout << "\n parametres d'appel: ";
int nb_var = tab_fVal.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;
// 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 dans l'appel de la fonction "
<< nom_ref << " d'expression " << expression_fonction
<< "\n Fonction_expression_litterale_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();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
return tab_ret;
};
//----- 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 Fonction_expression_litterale_nD::Lecture_base_info(ifstream& ent,const int cas)
{ // on n'a que des grandeurs constantes
if (cas == 1)
{ string nom;
// lecture et vérification de l'entête
ent >> nom;
if (nom != "Fonction_expression_litterale_nD")
{ cout << "\n erreur dans la vérification du type de courbe lue ";
cout << "\n Fonction_expression_litterale_nD::Lecture_base_info(... ";
Sortie(1);
}
// lecture des infos
// les arguments gérés par la classe mère
Fonction_nD::Lect_base_info(ent,cas);
// maintenant l'expression
ent >> nom >> expression_fonction ;
// redef de la fonction
Fonction_expression_litterale_nD::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();
Fonction_nD::Affichage_variables(); // affichage éventuelle
}
};
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Fonction_expression_litterale_nD::Ecriture_base_info(ofstream& sort,const int cas)
{ // on n'a que des grandeurs constantes
if (cas == 1)
{ sort << "\n ";
sort << " Fonction_expression_litterale_nD ";
// 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
<< " ";
sort << "\n \n";
};
};
// sortie du schemaXML: en fonction de enu
void Fonction_expression_litterale_nD::SchemaXML_Fonctions_nD(ofstream& ,const Enum_IO_XML enu)
{
switch (enu)
{ case XML_TYPE_GLOBAUX :
{
break;
}
case XML_IO_POINT_INFO :
{
break;
}
case XML_IO_POINT_BI :
{
break;
}
case XML_IO_ELEMENT_FINI :
{
break;
}
};
};
// initialisation de la fonction analytique
void Fonction_expression_litterale_nD::Init_fonction_analytique()
{
try
{
// on supprime les variables existantes éventuelles
p.ClearVar();
// le nombre de variables pour l'appel de la fonction, ne change pas
// donc la dimension de tab_fVal demeure identique
// on parcours l'ensemble des variables
int nb_var_int = nom_variables.Taille();
int index_var = 1;
for (int i = 1;i<= nb_var_int;i++,index_var++)
{ p.DefineVar(nom_variables(i), &tab_fVal(index_var)); // on définit la variable
};
// cas des variables globales sous forme d'énuméré
int nb_enu = enu_variables_globale.Taille();
for (int inunu = 1; inunu <= nb_enu; inunu++,index_var++)
{ // on utilise l'identificateur interne
string nom_variables_global=Nom_GrandeurGlobale(enu_variables_globale(inunu)); // récup du nom
p.DefineVar(nom_variables_global, &tab_fVal(index_var)); // on définit la variable
};
// idem pour les noms de variables globales
int nb_nom = nom_variables_globales.Taille();
for (int inom = 1; inom <= nb_nom; inom++,index_var++)
p.DefineVar(nom_variables_globales(inom), &tab_fVal(index_var)); // on définit la variable
// arrivée ici on définie (ou redéfinie) la fonction
// on le fait systématiquement, pour que l'expression soit cohérente avec les variables
// définies
p.SetExpr(expression_fonction);
// dimensionne correctement le vecteur de retour
// pour cela il faut faire au moins un appel
int nNum;
double * v = p.Eval(nNum);
tab_ret.Change_taille(nNum);
}
catch(mu::Parser::exception_type &e)
{ cout << "\n ** erreur dans l'appel l'initialisation de la fonction "
<< nom_ref << " d'expression " << expression_fonction
<< " \n xi= "<