2068 lines
96 KiB
C++
Executable file
2068 lines
96 KiB
C++
Executable file
// 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) <https://www.irdl.fr/>.
|
|
//
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
#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("<<j<<")= "<< tab_fVal_int(j);}
|
|
cout << "\n dernieres valeurs de retour de la fonction: ";
|
|
cout << tab_ret ;
|
|
};
|
|
cout << "\n ----- fin affichage fonction Fonc_scal_combinees_nD ----- ";
|
|
};
|
|
|
|
// vérification que tout est ok, pres à l'emploi
|
|
// ramène true si ok, false sinon
|
|
bool Fonc_scal_combinees_nD::Complet_Fonction(bool affichage)const
|
|
{ bool ret = Complet_var(); // on regarde du coté de la classe mère tout d'abord
|
|
// puis les variables propres, il faut au moins une fonction
|
|
int nb_fct = Fi.Taille();
|
|
if (nb_fct == 0)
|
|
ret = false;
|
|
for (int i=1;i<=nb_fct;i++)
|
|
{if (Fi(i) == NULL)
|
|
ret = false; break;
|
|
};
|
|
if (!ret && (ParaGlob::NiveauImpression() >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 <string > li_nom_fonctioni;
|
|
list <string > 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 <string >::iterator sli= li_nom_fonctioni.begin();
|
|
list <string >::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 <Enum_GrandeurGlobale > 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 <Enum_GrandeurGlobale >::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 <string >::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 <string >& 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 = "<<nom_variables_globales.Taille();
|
|
// for (int j=1;j<= nom_variables_globales.Taille();j++)
|
|
// cout << " variable ("<<j<<")= "<< nom_variables_globales(j) << flush;
|
|
//// Sortie(1);
|
|
// };
|
|
// //--- fin debug
|
|
// 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();
|
|
// affichage éventuel ce que l'on a lue
|
|
if (permet_affichage > 8)
|
|
{cout << "\n == >>> 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 = "<<nom_variables_globales.Taille();
|
|
// for (int j=1;j<= nom_variables_globales.Taille();j++)
|
|
// cout << " variable ("<<j<<")= "<< nom_variables_globales(j) << flush;
|
|
//// Sortie(1);
|
|
// };
|
|
// //--- fin debug
|
|
|
|
};
|
|
|
|
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
|
|
// globales en cours de calcul
|
|
void Fonc_scal_combinees_nD::Mise_a_jour_variables_globales()
|
|
{ // --- on s'occupe des variables internes
|
|
// on passe en revue les variables patentées et on regarde s'il s'agit de nouvelles variables globales
|
|
int taille = nom_variables_int.Taille();
|
|
list <string> li_variable; // liste de travail
|
|
list <string> li_globale; // ""
|
|
bool a_changer_int = false; // a priori rien ne change
|
|
// maintenant on parcours les variables
|
|
for (int i=1;i<=taille;i++)
|
|
{if (ParaGlob::param->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 <string>& Fonc_scal_combinees_nD::ListDependanceFonctions(list <string>& 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 <Fonction_nD *>& liptfonc,list <Courbe1D *>& )
|
|
{ int tai = Fi.Taille();
|
|
Tableau <Fonction_nD *> tab_Fi(tai); // def à null par défaut
|
|
for (int i=1;i<=tai;i++)
|
|
if(Fi(i) == NULL)
|
|
{list <Fonction_nD *>::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 <Fonction_nD *>::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 <double> & Fonc_scal_combinees_nD::Valeur_FnD_interne(Tableau <double >* 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 <double>& fVal_Fi = tab_fVal_Fi(i);
|
|
Tableau <double>& 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(..."<<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);
|
|
};
|
|
};
|
|
// 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: "<<i_fval_int
|
|
<< " on obtient: " << tab_fVal_int(i_fval_int);
|
|
cout << "\n parametres d'appel: ";
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< fVal_Fi(j);}
|
|
cout <<"\n fonction: ";
|
|
fo->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= "<<nb_var_int
|
|
// << ", est different de tab_fVal_int.Taille()-nb_var_glob "
|
|
// << (tab_fVal_int.Taille()-tail_enu)
|
|
// << "\n Fonc_scal_combinees_nD::Val_FnD_Evoluee(..."<<endl;
|
|
// Sortie(1);
|
|
// };
|
|
// #endif
|
|
//
|
|
|
|
for (int ii = 1;ii<= nb_var_int;ii++,i_fval_int++)
|
|
{
|
|
// on se déplace d'abord dans xi
|
|
if (i_in_xi <= taille_xi)
|
|
{tab_fVal_int(i_fval_int) = 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_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(..."<<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);
|
|
};
|
|
};
|
|
|
|
|
|
// 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(..."
|
|
<<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);
|
|
};
|
|
}
|
|
|
|
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(..."
|
|
<<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);
|
|
};
|
|
};
|
|
};
|
|
// 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(..."
|
|
<<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
|
|
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(..."
|
|
<<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);
|
|
};
|
|
}
|
|
|
|
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(..."
|
|
<<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
|
|
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(..."
|
|
<<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);
|
|
};
|
|
}
|
|
|
|
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(..."
|
|
<<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);
|
|
};
|
|
};
|
|
};
|
|
|
|
// appel de la fonction maître
|
|
int nNum;
|
|
double * v = p.Eval(nNum);
|
|
for (int i=0; i<nNum; ++i)
|
|
tab_ret(i+1) = v[i];
|
|
#ifdef MISE_AU_POINT
|
|
// if (permet_affichage > 0)
|
|
{double absret_Fi= 0.;
|
|
for (int i=0; i<nNum; ++i)
|
|
absret_Fi += Dabs(tab_ret(i+1));
|
|
if ((!isfinite(absret_Fi)) || (isnan(absret_Fi)) )
|
|
{ cout << "\n probleme dans le calcul de la fonction "
|
|
<< " on obtient en norme euclidienne: " << absret_Fi
|
|
<< "\n Fonc_scal_combinees_nD::Valeur_FnD_interne(...";
|
|
cout << "\n parametres d'appel: ";
|
|
int nb_var = tab_fVal_int.Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< tab_fVal_int(j);}
|
|
cout <<"\n >>> 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 <double> & 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(..."<<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);
|
|
};
|
|
// 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(..."<<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 << " verifier la presence des grandeurs globales voulues "
|
|
<< "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..."<<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
|
|
|
|
// 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(..."<<endl;
|
|
////--- debug
|
|
//{cout << "\n debug Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne() ";
|
|
//cout << "\n taille = "<<nom_variables_globales.Taille();
|
|
//for (int j=1;j<= nom_variables_globales.Taille();j++)
|
|
// cout << " variable ("<<j<<")= "<< nom_variables_globales(j) << flush;
|
|
//Sortie(1);
|
|
//};
|
|
////--- fin debug
|
|
|
|
|
|
|
|
// 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 << " verifier la presence des grandeurs globales voulues "
|
|
<< "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(..."<<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
|
|
|
|
// 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 <double>& 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: "<<i_fval_int
|
|
<< " on obtient: " << tab_fVal_int(i_fval_int)
|
|
<< " dans le cas d'un appel pour des variables globales uniquement ";
|
|
cout <<"\n fonction: ";
|
|
fo->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(..."
|
|
<<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);
|
|
};
|
|
}
|
|
|
|
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(..."
|
|
<<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);
|
|
};
|
|
};
|
|
};
|
|
// 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(..."
|
|
<<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
|
|
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(..."
|
|
<<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);
|
|
};
|
|
}
|
|
|
|
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(..."
|
|
<<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
|
|
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(..."
|
|
<<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);
|
|
};
|
|
}
|
|
|
|
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(..."
|
|
<<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);
|
|
};
|
|
};
|
|
};
|
|
|
|
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("<<j<<")= "<< tab_fVal_int(j);}
|
|
};
|
|
// appel de la fonction maître
|
|
int nNum;
|
|
double * v = p.Eval(nNum);
|
|
for (int i=0; i<nNum; ++i)
|
|
tab_ret(i+1) = v[i];
|
|
#ifdef MISE_AU_POINT
|
|
// if (permet_affichage > 0)
|
|
{double absret_Fi= 0.;
|
|
for (int i=0; i<nNum; ++i)
|
|
absret_Fi += Dabs(tab_ret(i+1));
|
|
if ((!isfinite(absret_Fi)) || (isnan(absret_Fi)) )
|
|
{ cout << "\n probleme dans le calcul de la fonction "
|
|
<< " on obtient en norme euclidienne: " << absret_Fi
|
|
<< "\n Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne(...";
|
|
cout << "\n parametres d'appel: ";
|
|
int nb_var = tab_fVal_int.Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< tab_fVal_int(j);}
|
|
cout <<"\n >>> 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 <string>& Fonc_scal_combinees_nD::ListDependanceCourbes(list <string>& 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 <Fonc_scal_combinees_nD> "
|
|
// 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 </Fonc_scal_combinees_nD> "
|
|
|
|
// 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 <FONC_SCAL_COMBINEES_ND> "
|
|
<< " 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 </FONC_SCAL_COMBINEES_ND> \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 <!-- *************************** F_UNION_1D *************************** -->"
|
|
<< "\n <!-- def d'un type contenant une valeur et un boolean -->"
|
|
<< "\n <xs:complexType name=\"valeurPlusBooleen\">"
|
|
<< "\n <xs:simpleContent>"
|
|
<< "\n <xs:extension base=\"xs:double\">"
|
|
<< "\n <xs:attribute name=\"present\" type=\"xs:boolean\" />"
|
|
<< "\n </xs:extension>"
|
|
<< "\n </xs:simpleContent> "
|
|
<< "\n </xs:complexType>"
|
|
<< "\n <!-- maintenant le type de la fonction -->"
|
|
<< "\n<xs:complexType name=\"F_UNION_1D\" >"
|
|
<< "\n <xs:annotation>"
|
|
<< "\n <xs:documentation> fonction F_UNION_1D constituee de N points </xs:documentation>"
|
|
<< "\n </xs:annotation>"
|
|
<< "\n <xs:sequence>"
|
|
<< "\n <xs:element name=\"derivee_initiale_\" type=\"valeurPlusBooleen\" />"
|
|
<< "\n <xs:element name=\"derivee_finale_\" type=\"valeurPlusBooleen\" />"
|
|
<< "\n <xs:element name=\"les_points\" type=\"COORDONNEE_2\" minOccurs='0' maxOccurs=\"unbounded\" />"
|
|
<< "\n </xs:sequence>"
|
|
<< "\n</xs:complexType>";*/
|
|
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 <Fonction_nD* >& 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 <string >& 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 <Enum_GrandeurGlobale > li_enu_glob;
|
|
list <string > li_nom_glob;
|
|
for (int i = 1;i<=tail;i++)
|
|
{// pour les énumérés
|
|
const Tableau <Enum_GrandeurGlobale >& 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 <string >& 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("<<i<<"), tab_nom("<<inom<<")= "<< tab_nom(inom);
|
|
}
|
|
};
|
|
// ensuite on ajoute les grandeurs globales internes
|
|
int nb_enu = enu_variables_globale_int.Taille();
|
|
for (int ienu = 1; ienu <= nb_enu; ienu++)
|
|
li_enu_glob.push_back(enu_variables_globale_int(ienu));
|
|
int nb_nom = nom_variables_globales_int.Taille();
|
|
for (int inom = 1; inom <= nb_nom; inom++)
|
|
li_nom_glob.push_back(nom_variables_globales_int(inom));
|
|
////--debug
|
|
//{int nb_nom_glob = li_nom_glob.size();
|
|
// list <string >::iterator il,ilfin=li_nom_glob.end();
|
|
// int i= 1;
|
|
// cout << "\n debug li_nom_glob 1: avant ordonner et supprimer doublon";
|
|
// for(il = li_nom_glob.begin(); il != ilfin; il++)
|
|
// cout << "\n debug (*il)= " << (*il) ;
|
|
//};
|
|
//// -- fin debug
|
|
// maintenant on va supprimer les doublons
|
|
li_enu_glob.sort(); li_enu_glob.unique();
|
|
li_nom_glob.sort(); li_nom_glob.unique();
|
|
////--debug
|
|
//{int nb_nom_glob = li_nom_glob.size();
|
|
// list <string >::iterator il,ilfin=li_nom_glob.end();
|
|
// int i= 1;
|
|
// cout << "\n debug li_nom_glob 2: liste finale";
|
|
// for(il = li_nom_glob.begin(); il != ilfin; il++)
|
|
// cout << "\n debug (*il)= " << (*il) ;
|
|
//};
|
|
//// -- fin debug
|
|
// maintenant on définit les tableaux
|
|
{int nb_enu_glob = li_enu_glob.size();
|
|
enu_variables_globale.Change_taille(nb_enu_glob);
|
|
list <Enum_GrandeurGlobale >::iterator il,ilfin=li_enu_glob.end();
|
|
int i= 1;
|
|
for(il = li_enu_glob.begin(); il != ilfin; il++)
|
|
enu_variables_globale(i) = (*il);
|
|
};
|
|
// et pour les noms
|
|
{int nb_nom_glob = li_nom_glob.size();
|
|
nom_variables_globales.Change_taille(nb_nom_glob);
|
|
list <string >::iterator il,ilfin=li_nom_glob.end();
|
|
int i= 1;
|
|
for(il = li_nom_glob.begin(); il != ilfin; il++,i++)
|
|
nom_variables_globales(i) = (*il);
|
|
};
|
|
////--- debug
|
|
//{cout << "\n debug 3 Fonc_scal_combinees_nD::Valeur_pour_variables_globales_interne() ";
|
|
// cout << "\n lecture fonction: " << nom_ref;
|
|
// cout << "\n taille = "<<nom_variables_globales.Taille();
|
|
// for (int j=1;j<= nom_variables_globales.Taille();j++)
|
|
// cout << " variable ("<<j<<")= "<< nom_variables_globales(j) << flush;
|
|
//// Sortie(1);
|
|
//};
|
|
////--- fin debug
|
|
|
|
};
|
|
};
|
|
};
|
|
|
|
|
|
// initialisation de la fonction analytique
|
|
void Fonc_scal_combinees_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_int demeure identique
|
|
|
|
// on parcours l'ensemble des variables internes
|
|
int nb_var_int = nom_variables_int.Taille();
|
|
int index_var = 1;
|
|
for (int i = 1;i<= nb_var_int;i++,index_var++)
|
|
{ p.DefineVar(nom_variables_int(i), &tab_fVal_int(index_var)); // on définit la variable
|
|
};
|
|
// cas des variables globales locales
|
|
int nb_enu = enu_variables_globale_int.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_int(inunu)); // récup du nom
|
|
p.DefineVar(nom_variables_global, &tab_fVal_int(index_var)); // on définit la variable
|
|
};
|
|
// idem pour les noms de variables globales locales
|
|
int nb_nom = nom_variables_globales_int.Taille();
|
|
for (int inom = 1; inom <= nb_nom; inom++,index_var++)
|
|
p.DefineVar(nom_variables_globales_int(inom), &tab_fVal_int(index_var)); // on définit la variable
|
|
|
|
// arrivée ici on définie la fonction
|
|
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= "<<tab_fVal_int;
|
|
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 ;
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|