Herezh_dev/Util/Courbes/Fonction_nD.cc

1956 lines
86 KiB
C++
Raw Normal View History

// 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 "Fonction_nD.h"
#include <stdarg.h> /* va_list, va_start, va_copy, va_arg, va_end */
#include "Enum_ddl.h"
#include "NevezTenseur.h"
#include "TypeQuelconqueParticulier.h"
// les différentes fonctions existantes
#include "F_nD_courbe1D.h"
#include "Fonc_scal_combinees_nD.h"
#include "Fonction_expression_litterale_nD.h"
#include "Fonction_externe_nD.h"
#include "MotCle.h"
// CONSTRUCTEURS :
// par défaut
Fonction_nD::Fonction_nD(string nom, EnumFonction_nD typ)
: nom_variables(),t_inter_double()
,enu_variables_globale(),nom_ref(nom),typeFonction(typ)
,nom_variables_globales()
,tab_enu_etendu(),tab_enu_quelconque()
,equivalence_nom_enu_etendu_et_enu_quelconque(false)
,index_enu_etendu(),index_enu_quelconque()
,x_x_i(),x_glob(),xinter(NULL)
,depend_M(0),depend_Mt(0),depend_M0(0),depend_temps(0),permet_affichage(0)
//------ grandeurs évoluées -------
,type_des_variables(),val_ddl_enum(),li_enu_etendu_scalaire()
,coor_ddl_enum(),num_dans_coor(),premier_famille_Coord()
,tens_ddl_enum(),ind_tens(),premier_famille_tenseur(),absolue(false)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens()
,posi_ddl_enum(),tailles_tab()
{ // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
// non car au début il n'y a rien comme variable !!
// Fonction_nD::Construction_index_conteneurs_evoluees();
};
// constructeur avec plus d'info
// dans le cas ou les variables sont associées à des types quelconques, par défaut on considère qu'il
// s'agit de conteneur d'un scalaire simple. Dans le cas contraire il faut utiliser
// Preparation_Grandeur_quelconque( pour spécifier les tailles réelles
Fonction_nD::Fonction_nD(const Tableau <string >& var, string nom, EnumFonction_nD typ )
: nom_variables(var),t_inter_double(var.Taille())
,enu_variables_globale(),nom_ref(nom),typeFonction(typ)
,nom_variables_globales()
,tab_enu_etendu(),tab_enu_quelconque()
,equivalence_nom_enu_etendu_et_enu_quelconque(false)
,index_enu_etendu(),index_enu_quelconque()
,x_x_i(),x_glob(),xinter(NULL)
,depend_M(0),depend_Mt(0),depend_M0(0),depend_temps(0),permet_affichage(0)
//------ grandeurs évoluées -------
,type_des_variables(),val_ddl_enum(),li_enu_etendu_scalaire()
,coor_ddl_enum(),num_dans_coor(),premier_famille_Coord()
,tens_ddl_enum(),ind_tens(),premier_famille_tenseur(),absolue(false)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens()
,posi_ddl_enum(),tailles_tab()
{// comme on a le tableau de variables, on tente une équivalence éventuelle
// 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();
};
// def de tous les paramètres: utile pour être appelé par les classes dérivées
Fonction_nD::Fonction_nD
( string nom_ref_ // nom de ref de la fonction
,Tableau <string >& nom_variables_non_globales // les variables non globales
,Tableau <Enum_GrandeurGlobale >& enu_variables_globale_ // enu globaux
,Tableau <string >& nom_variables_globales_ // idem sous forme de strings
,EnumFonction_nD typ ) // le type de fonction
: nom_variables(nom_variables_non_globales),t_inter_double(nom_variables_non_globales.Taille())
,enu_variables_globale(enu_variables_globale_),nom_ref(nom_ref_),typeFonction(typ)
,nom_variables_globales(nom_variables_globales_)
,tab_enu_etendu(),tab_enu_quelconque()
,equivalence_nom_enu_etendu_et_enu_quelconque(false)
,index_enu_etendu(),index_enu_quelconque()
,x_x_i(),x_glob(),xinter(NULL)
,depend_M(0),depend_Mt(0),depend_M0(0),depend_temps(0),permet_affichage(0)
//------ grandeurs évoluées -------
,type_des_variables(),val_ddl_enum(),li_enu_etendu_scalaire()
,coor_ddl_enum(),num_dans_coor(),premier_famille_Coord()
,tens_ddl_enum(),ind_tens(),premier_famille_tenseur(),absolue(false)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens()
,posi_ddl_enum(),tailles_tab()
{// comme on a le tableau de variables, on tente une équivalence éventuelle
// 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();
};
// de copie
Fonction_nD::Fonction_nD(const Fonction_nD& Co) :
nom_variables(Co.nom_variables),t_inter_double(Co.t_inter_double)
,enu_variables_globale(Co.enu_variables_globale)
,nom_variables_globales(Co.nom_variables_globales)
,nom_ref(Co.nom_ref),typeFonction(Co.typeFonction)
,tab_enu_etendu(Co.tab_enu_etendu),tab_enu_quelconque(Co.tab_enu_quelconque)
,equivalence_nom_enu_etendu_et_enu_quelconque(Co.equivalence_nom_enu_etendu_et_enu_quelconque)
,index_enu_etendu(Co.index_enu_etendu),index_enu_quelconque(Co.index_enu_quelconque)
,x_x_i(Co.x_x_i),x_glob(Co.x_glob),xinter(NULL)
,depend_M(Co.depend_M),depend_Mt(Co.depend_Mt),depend_M0(Co.depend_M0)
,depend_temps(Co.depend_temps)
//------ grandeurs évoluées -------
,type_des_variables(Co.type_des_variables),val_ddl_enum(Co.val_ddl_enum)
,li_enu_etendu_scalaire() // reconstruit avec les index
,coor_ddl_enum(Co.coor_ddl_enum),num_dans_coor(Co.num_dans_coor)
,premier_famille_Coord(Co.premier_famille_Coord)
,tens_ddl_enum(Co.tens_ddl_enum),ind_tens(Co.ind_tens)
,premier_famille_tenseur(Co.premier_famille_tenseur)
,absolue(Co.absolue)
,li_equi_Quel_evolue(),tab_equi_Coor(),tab_equi_tens() // est reconstruit ensuite
,posi_ddl_enum(Co.posi_ddl_enum),tailles_tab(Co.tailles_tab)
,permet_affichage(Co.permet_affichage)
{if (Co.xinter != NULL)
xinter = new Tableau <double >(*(Co.xinter));
// comme on a le tableau de variables, on tente une équivalence éventuelle
// 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();
};
// DESTRUCTEUR :
Fonction_nD::~Fonction_nD()
{if (xinter != NULL)
delete xinter;
if (tens_ddl_enum.Taille() != 0)
{int taille = tens_ddl_enum.Taille();
for (int i=1; i<= taille; i++)
if (tens_ddl_enum(i) != NULL)
delete tens_ddl_enum(i);
};
};
// METHODES PUBLIQUES :
// ---------- non virtuelle ---------
//// complète les tableaux internes en fonction de la taille des conteneurs
//// associés aux types quelconques éventuelles
//// *** doit -être appelée s'il y a des grandeurs quelconque dont les conteneurs
//// sont associés à plusieurs scalaires
//void Fonction_nD::Preparation_Grandeur_quelconque(const Tableau <TypeQuelconque >& tqi)
// {// on parcourt la liste des enumérés de grandeurs quelconque
// int tail = tab_enu_quelconque.Taille();
// if (tqi.Taille() != tail)
// { cout << "\n *** pb dans Fonction_nD::Preparation_Grandeur_quelconque( "
// << " le tableau en parametre " << tqi.Taille()
// << " n'a pas la meme taille que le nombre de grandeur quelconque enregistrees "
// << tail
// << " on ne peut pas continuer " <<endl;
// Sortie(1);
// };
// // --- l'objectif est de dimensionner correctement le tableau de passage de réelles
// // x_x_i
// int nb_scalaire_type_quelconque = 0; // init
// for (int i=1;i<= tail; i++)
// {nb_scalaire_type_quelconque += tqi(i).NbMaxiNumeroOrdre();
// #ifdef MISE_AU_POINT
// if ((tqi)(i).EnuTypeQuelconque() != tab_enu_quelconque(i))
// { cout << "\n *** pb dans la preparation de l'utilisation de type quelconque "
// << " au niveau des parametres d'appel "
// << " la grandeur quelconque "<< i<< "correspondante a "
// << NomTypeQuelconque((tqi)(i).EnuTypeQuelconque())
// << " est differente de celle deja enregistree "
// << NomTypeQuelconque(tab_enu_quelconque(i))
// << " ce n'est pas normal !! , on arrete le calcul "
// << "\n Fonction_nD::Preparation_Grandeur_quelconque(..."<<endl;
// Sortie(1);
// };
// #endif
// };
// // on dimensionne le tableau de passage
// // chaque ddl est associé à un seul scalaire
// x_x_i.Change_taille(nb_scalaire_type_quelconque+tab_enu_etendu.Taille());
// };
// calcul équivalent, mais pour des paramètres de type ddl enum étendu et/ou type quelconque
// pour que l'appel à cette méthode soit correcte, il faut que la dimension de t_enu + celle de tqi
// soit identique à celle du tableau Nom_variables() : en fait t_enu et tqi doivent représenter les variables
Tableau <double> & Fonction_nD::Valeur_FnD(Tableau <Ddl_etendu> * t_enu,Tableau <const TypeQuelconque * > * t_qi
,Tableau <int> * t_num_ordre)
{// on se sert des tableaux d'adressage indirect pour remplir le tableau de passage
// tab_enu_etendu(i) correspond à nom_variables(index_enu_etendu(i))
// tab_enu_quelconque(i) correspond à nom_variables(index_enu_quelconque(i))
// un tableau intermédiaire qui sert pour Valeur(Tableau <Ddl_etendu> ...
// Tableau <double > x_x_i;
#ifdef MISE_AU_POINT
// on vérifie qu'il y a bien équivalence entre les variables
if (!equivalence_nom_enu_etendu_et_enu_quelconque)
{ cout << "\n *** pb dans les parametres de passage pour l'appel de la fonction nD "
<< " les variables de passage ne sont pas tous des ddl etendue ou des grandeurs "
<< " quelconque scalaire "
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Valeur(Tableau <Ddl_etendu>..."<<endl;
Sortie(1);
};
#endif
try
{int tail_tab_enu_etendu = tab_enu_etendu.Taille();
if (t_enu != NULL)
{Tableau <Ddl_etendu>& tenu = *t_enu; // pour simplifier l'appel
for (int i= 1; i<= tail_tab_enu_etendu;i++)
{x_x_i(index_enu_etendu(i)) = tenu(i).Valeur();
};
};
int tail_tab_enu_quelc = tab_enu_quelconque.Taille();
if (t_qi != NULL)
{Tableau <const TypeQuelconque * >& tqi = *t_qi; // pour simplifier l'appel
for (int i= 1; i<= tail_tab_enu_quelc;i++)
{ x_x_i(index_enu_quelconque(i)) = tqi(i)->GrandeurNumOrdre(1);
#ifdef MISE_AU_POINT
int nb_scalaire_type_quelconque = tqi(i)->NbMaxiNumeroOrdre();
if (nb_scalaire_type_quelconque != 1)
{ cout << "\n *** pb dans le nombre de parametre de passage pour l'appel de la fonction nD "
<< " au niveau des parametres d'appel "
<< " la grandeur quelconque "<< i<< "correspondante a "
<< (tqi)(i)->EnuTypeQuelconque().NomPlein()
<< " n'est pas une grandeur scalaire "
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Valeur(Tableau <Ddl_etendu>..."<<endl;
Sortie(1);
};
#endif
};
};
// on peut maintenant appeler la fonction de base
// avec que des scalaires
#ifdef MISE_AU_POINT
if (permet_affichage > 4)
{cout << "\n retour fonction: "<<nom_ref<<" : ";
Tableau <double> & inter = Valeur_FnD_interne(&x_x_i);
int nb_val = inter.Taille();
for (int i=1;i<=nb_val;i++)
cout << " val("<<i<<")= "<<inter(i);
if (permet_affichage > 5)
{cout << "\n parametres d'appel: ";
int nb_var = x_x_i.Taille();
for (int j=1;j<=nb_var;j++)
{ cout << " para("<<j<<")= "<< x_x_i(j);}
};
return inter;
}
else
#endif
return Valeur_FnD_interne(&x_x_i);
}
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 \n Valeur_FnD(..."<<endl;
this->Affiche();Sortie(1);
};
};
// ramène un pointeur sur la fonction correspondant au type de fonction passé en paramètre
Fonction_nD* Fonction_nD::New_Fonction_nD(string& nom,EnumFonction_nD typeFonction)
{ // définition du pointeur de retour
Fonction_nD* fonction;
// choix en fonction du typeCourbe
switch (typeFonction)
{
case FONCTION_EXPRESSION_LITTERALE_nD :
fonction= new Fonction_expression_litterale_nD(nom); break;
case FONCTION_COURBE1D : fonction= new F_nD_courbe1D(nom); break;
case FONC_SCAL_COMBINEES_ND : fonction= new Fonc_scal_combinees_nD(nom); break;
case FONCTION_EXTERNE_ND : fonction= new Fonction_externe_nD(nom); break;
default :
{ cout << "\nErreur : valeur incorrecte du type de Fonction_nD : "
<< typeFonction << "\n";
cout << "\n New_Fonction_nD(EnumFonction_nD typeFonction) \n";
Sortie(1);
}
};
return fonction;
};
// ramène un pointeur sur une courbe copie de celle passée en paramètre
// IMPORTANT : il y a création d'une courbe (utilisation d'un new)
Fonction_nD* Fonction_nD::New_Fonction_nD(const Fonction_nD& Co)
{ // définition du pointeur de retour
Fonction_nD* fonction;
// choix en fonction du typeFonction
switch (Co.Type_Fonction())
{
case FONCTION_EXPRESSION_LITTERALE_nD : fonction= new Fonction_expression_litterale_nD( Co); break;
case FONCTION_COURBE1D : fonction= new F_nD_courbe1D(Co); break;
case FONC_SCAL_COMBINEES_ND : fonction= new Fonc_scal_combinees_nD(Co); break;
case FONCTION_EXTERNE_ND : fonction= new Fonction_externe_nD(Co); break;
default :
{ cout << "\nErreur : valeur incorrecte du type de Fonction_nD : "
<< Co.Type_Fonction() << "\n";
cout << "\n New_Fonction_nD(const Fonction_nD& Co) \n";
Sortie(1);
}
};
return fonction;
};
// ramène la liste des identificateurs de courbes actuellement disponibles
list <EnumFonction_nD> Fonction_nD::Liste_Fonction_disponible()
{ // définition de la liste de retour
list <EnumFonction_nD> list_ret;
// remplissage de la liste
list_ret.push_back(FONCTION_EXPRESSION_LITTERALE_nD);
list_ret.push_back(FONCTION_COURBE1D);
list_ret.push_back(FONC_SCAL_COMBINEES_ND);
list_ret.push_back(FONCTION_EXTERNE_ND);
// retour de la liste
return list_ret;
};
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
// globales en cours de calcul
// méthode interne: qui est utilisé par les fonctions dérivées pour la méthode:
// Mise_a_jour_variables_globales
// retourne false si rien n'a changé
bool Fonction_nD::Mise_a_jour_variables_globales_interne()
{// on passe en revue les variables normales et on regarde s'il s'agit de nouvelles variables globales
int taille = nom_variables.Taille();
list <string> li_variable; // liste de travail
list <string> li_globale; // ""
bool a_changer = false; // a priori rien ne change
// maintenant on parcours les variables
for (int i=1;i<=taille;i++)
{if (ParaGlob::param->GrandeurGlobal(nom_variables(i)) != NULL)
// il s'agit d'une variable globale
{// on n'ajoute que si elle n'est pas déjà présente
std::list <string>::iterator it
= find (li_globale.begin(), li_globale.end(),nom_variables(i));
if (it == li_globale.end())
{li_globale.push_back(nom_variables(i));
};
// quelque soit le cas il faut valider
a_changer=true;
}
else // sinon c'est toujours une variable
li_variable.push_back(nom_variables(i));
};
// on met à jour les tableaux
if (a_changer)
{// on ajoute maintenant les variables globales déjà existantes
int taille_globale = nom_variables_globales.Taille(); // Init_from_list
for (int j=1;j<= taille_globale;j++)
{// on n'ajoute que si elle n'est pas déjà présente
list <string>::iterator it
= find (li_globale.begin(), li_globale.end(),nom_variables_globales(j));
if (it == li_globale.end())
{li_globale.push_back(nom_variables_globales(j));}
};
// on met à jour les tableaux
nom_variables.Init_from_list(li_variable);
t_inter_double.Change_taille(nom_variables.Taille());
// pour les variables globales on considère les points suivants:
// leur nombre ne peut pas décroitre
// l'ordre n'a pas vraiment d'importance
// int taille_ajout = li_globale.size();
int taille_finale = li_globale.size();
if (taille_finale < nom_variables_globales.Taille())
{cout << "\n erreur changement de taille des variables globales "
<< "\n Fonction_nD::Mise_a_jour_variables_globales_interne() "
<< endl;
Sortie(1);
};
nom_variables_globales.Init_from_list(li_globale);
// int taille_ini = nom_variables_globales.Taille();
// nom_variables_globales.Change_taille(taille_ini+taille_ajout);
// nom_variables_globales.Change_taille(taille_finale);
// list <string>::iterator il,ilfin=li_globale.end();
// int ip = 1; //taille_ini+1;
// for (il = li_globale.begin();il != ilfin; il++,ip++)
// nom_variables_globales(ip) = (*il);
// nom_variables_globales.Init_from_list(li_globale);
};
// on met à jour le tableau d'échange interne : x_glob
int nb_tot_glob = enu_variables_globale.Taille() + nom_variables_globales.Taille();
x_glob.Change_taille(nb_tot_glob);
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
Fonction_nD::Construction_index_conteneurs_evoluees();
return a_changer;
};
// Tableau <string > nom_variables; //variables de la fonction, vu de l'extérieur
//
// Tableau <Enum_GrandeurGlobale > enu_variables_globale; //tableau des énumérés
// // de variables globales
// // éventuellement vide s'il ne sert pas
// Tableau <string > nom_variables_globales; //tableau des énumérés
// 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this
list <string>& Fonction_nD::ListDependanceCourbes(list <string>& lico) const
{ // par défaut, ne dépend pas de fonctions, donc on ramène une liste vide
// ce sera surchargé dans les classes qui elles éventuellement dépendent de quelque chose
if (lico.size() != 0)
lico.clear();
return lico;
};
// 3) retourne une liste de nom correspondant aux noms de fonctions dont dépend *this
list <string>& Fonction_nD::ListDependanceFonctions(list <string>& lico) const
{ // par défaut, ne dépend pas de fonctions, donc on ramène une liste vide
// ce sera surchargé dans les classes qui elles éventuellement dépendent de quelque chose
if (lico.size() != 0)
lico.clear();
return lico;
};
// ---------- METHODES PROTEGEES :-------------------
// ramène true si les variables de la classe mère sont complèté
bool Fonction_nD::Complet_var() const
{ bool ret = true;
if (typeFonction == AUCUNE_FONCTION_nD) ret = false;
if (nom_ref == "") ret = false;
return ret;
};
// définit le paramètre depend_M en fonction des nom_variables
// 3 indicateurs permettant de connaître rapidement si
// la fonction dépend de la position d'un point M à tdt, t et t=0
// 0 : la fonction ne dépend pas de la position d'un point M
// non nul : la fonction dépend de la position d'un point M
// dans ce cas, une au moins un des nom_variables
// a un nom de la même famille que le ddl X1
// et depend_M = nombre de composantes demandés (ne sert pas vraiment)
// si = -1 : cela signifie que la fonction dépend "que" de M
void Fonction_nD::Definition_depend_M()
{// on parcours les noms des variables
int taille = nom_variables.Taille();
depend_M=0; // init a priori
depend_Mt=0; // idem à t
depend_M0 = 0; // idem à 0
Ddl_enum_etendu d_X1_t = Ddl_enum_etendu(X1,"X1_t");
Ddl_enum_etendu d_X1_t0 = Ddl_enum_etendu(X1,"X1_t0");
if (permet_affichage > 6)
cout << "\n == >>> Fonction_nD::Definition_depend_M ( fct= " << nom_ref << ") ";
list<string> var_X_deja_enreg; // une liste de travail
list<string> var_independante; // une liste de travail
for (int i=1; i<= taille; i++)
{// on ne traite que si la variable n'a pas déjà été traité
if (find(var_independante.begin(),var_independante.end(),nom_variables(i)) == var_independante.end())
{var_independante.push_back(nom_variables(i));
if (ExisteEnum_ddl(nom_variables(i))) // on regarde s'il s'agit d'un ddl patenté
{if (permet_affichage > 7)
cout << "\n cas d'un ddl de base: nom_variables("<<i<<") = "<<nom_variables(i);
if ( Meme_famille(Id_nom_ddl(nom_variables(i)),X1))
// si c'est de la famille d'X1 c'est ok, on regarde s'il ne s'agit pas d'une variable
// déjà consultée, car nom_variables peut contenir plusieurs fois la même variable
{if (find(var_X_deja_enreg.begin(),var_X_deja_enreg.end(),nom_variables(i)) == var_X_deja_enreg.end())
{depend_M += 1; // ok et la variable n'a pas été encore enregistrée
if (permet_affichage > 7)
cout << " depend_M += 1 ";
var_X_deja_enreg.push_back(nom_variables(i));
};
};
}
// sinon on regarde s'il s'agit d'un ddl étendu relatif à t = 0 ou t
else if (Ddl_enum_etendu::VerifExistence(nom_variables(i)))
{ if (permet_affichage > 7)
cout << "\n cas d'un ddl etendu relatif a t=0 ou t : nom_variables("<<i<<") = "<<nom_variables(i);
// on a un ddl enum
Ddl_enum_etendu dd_et = Ddl_enum_etendu::RecupDdl_enum_etendu(nom_variables(i));
if ( Ddl_enum_etendu::PremierDdlEnumEtenduFamille(dd_et) == d_X1_t)
// si c'est de la famille d'X1_t c'est ok, on regarde s'il ne s'agit pas d'une variable
// déjà consultée, car nom_variables peut contenir plusieurs fois la même variable
{if (find(var_X_deja_enreg.begin(),var_X_deja_enreg.end(),nom_variables(i)) == var_X_deja_enreg.end())
{depend_Mt += 1;
if (permet_affichage > 7)
cout << " depend_Mt += 1 ";
var_X_deja_enreg.push_back(nom_variables(i)); // on peut utiliser la même liste de travail
}
};
if ( Ddl_enum_etendu::PremierDdlEnumEtenduFamille(dd_et) == d_X1_t0)
// si c'est de la famille d'X1_t0 c'est ok, on regarde s'il ne s'agit pas d'une variable
// déjà consultée, car nom_variables peut contenir plusieurs fois la même variable
{if (find(var_X_deja_enreg.begin(),var_X_deja_enreg.end(),nom_variables(i)) == var_X_deja_enreg.end())
{depend_M0 += 1;
if (permet_affichage > 7)
cout << " depend_M0 += 1 ";
var_X_deja_enreg.push_back(nom_variables(i)); // on peut utiliser la même liste de travail
}
};
};
}
};
// le nombre de variables indépendantes, car nom_variables peut contenir plusieurs fois la même variable
int nb_var_inde = var_independante.size();
if (permet_affichage > 6)
cout << "\n nb de variables independantes : "<< nb_var_inde << " ";
// maintenant si depend_M est > à la dimension => il n'y a pas qu'une dépendance à M
// if ((depend_M <= ParaGlob::Dimension()) && (depend_M > 0))
if ((depend_M <= taille) && (depend_M > 0))
{// on vérifie que l'on n'a pas utilisé plus de composantes que la dimension
if (depend_M <= ParaGlob::Dimension())
{if (depend_M == nb_var_inde)
depend_M = -1; // cas d'une dépendance stricte à M
}
else
{ cout << "\n **** erreur le nombre de composante de dependance a M_tdt "<<taille
<< " est plus grand que la dimension " << ParaGlob::Dimension()
<< " de l'espace !! "
<< "\n Fonction_nD::Definition_depend_M() "
<< endl;
Sortie(1);
};
};
if ((depend_Mt <= taille) && (depend_Mt > 0))
{// on vérifie que l'on n'a pas utilisé plus de composantes que la dimension
if (depend_Mt <= ParaGlob::Dimension())
{if (depend_Mt == nb_var_inde)
depend_Mt = -1;// cas d'une dépendance stricte à Mt
}
else
{ cout << "\n **** erreur le nombre de composante de dependance a M_t"<<taille
<< " est plus grand que la dimension " << ParaGlob::Dimension()
<< " de l'espace !! "
<< "\n Fonction_nD::Definition_depend_M() "
<< endl;
Sortie(1);
};
};
if ((depend_M0 <= taille) && (depend_M0 > 0))
{// on vérifie que l'on n'a pas utilisé plus de composantes que la dimension
if (depend_M0 <= ParaGlob::Dimension())
{if (depend_M0 == nb_var_inde)
depend_M0 = -1; // cas d'une dépendance stricte à M0
}
else
{ cout << "\n **** erreur le nombre de composante de dependance a M_t=0 : "<<taille
<< " est plus grand que la dimension " << ParaGlob::Dimension()
<< " de l'espace !! "
<< "\n Fonction_nD::Definition_depend_M() "
<< endl;
Sortie(1);
};
};
if (permet_affichage > 6)
{cout << "\n == >>> Fonction_nD::Definition_depend_M : valeur des indicateurs finaux "
<< "\n pour memoire: = 0 -> la fct ne depend pas de la position "
<< " = -1 : la fct depend que de la position "
<< " > 0 : la fct depend de la position mais pas seulement "
<< "\n depend_M = " << depend_M << ",depend_Mt = " << depend_Mt
<< ", depend_M0 = " << depend_M0 << " ";
};
};
// définit le paramètre depend_temps en fonction des nom_variables
void Fonction_nD::Definition_depend_temps()
{// on parcours les identifiants globaux
int taille = enu_variables_globale.Taille();
depend_temps=false; // init a priori
// le temps est une grandeurs globales
for (int i=1; i<= taille; i++)
if (enu_variables_globale(i) == TEMPS_COURANT) // on regarde s'il s'agit d'un ddl patenté
{depend_temps = true;
break;
};
};
//// construction à partir des noms de variables, des tableaux tab_enu_etendu et
//// tab_enu_quelconque
//void Fonction_nD::Construction_enu_etendu_et_quelconque()
// {// on parcours les noms des variables
// int taille = nom_variables.Taille();
// // a priori on considère qu'il y a équivalence
// equivalence_nom_enu_etendu_et_enu_quelconque = true;
// list <Ddl_enum_etendu> li_inter_enu; // une liste intermédiaire de travail
// list <int> li_index_enu;
// list <EnumTypeQuelconque> li_inter_tyQ; // idem
// list <int> li_index_quelc;
//
// // un conteneur de service: un réel par ddl
// Ddl_enum_etendu ddl_de_service;
// // par contre pour les grandeurs quelconques, on peut avoir plusieurs
// // réels par grandeur quelconque
//
//
// for (int i=1; i<= taille; i++)
// {if (ddl_de_service.VerifExistence(nom_variables(i)))
// {li_inter_enu.push_back(Ddl_enum_etendu(nom_variables(i)));
// li_index_enu.push_back(i);
// }
// else if (Existe_typeQuelconque(nom_variables(i)))
// {li_inter_tyQ.push_back(Id_nomTypeQuelconque(nom_variables(i)));
// li_index_quelc.push_back(i);
// }
// else equivalence_nom_enu_etendu_et_enu_quelconque = false ;
// };
// // maintenant on peut définir les tableaux
// int tail_enu_ddl = li_inter_enu.size();
// { tab_enu_etendu.Change_taille(tail_enu_ddl);
// index_enu_etendu.Change_taille(tail_enu_ddl);
// int i_enu=1; // un compteur pour le tableau
// list <Ddl_enum_etendu>::iterator il,ilfin=li_inter_enu.end();
// list <int>::iterator i_int=li_index_enu.begin();
// for (il=li_inter_enu.begin();il!=ilfin;il++,i_enu++,i_int++)
// {tab_enu_etendu(i_enu)=(*il);
// index_enu_etendu(i_enu)=(*i_int);
// };
// };
// int tail_enuquel = li_inter_tyQ.size();
// { tab_enu_quelconque.Change_taille(tail_enuquel);
// index_enu_quelconque.Change_taille(tail_enuquel);
// int i_enu=1; // un compteur pour le tableau
// list <EnumTypeQuelconque>::iterator il,ilfin=li_inter_tyQ.end();
// list <int>::iterator i_int=li_index_quelc.begin();
// for (il=li_inter_tyQ.begin();il!=ilfin;il++,i_enu++,i_int++)
// {tab_enu_quelconque(i_enu)=(*il);
// index_enu_quelconque(i_enu) = (*i_int);
// #ifdef MISE_AU_POINT
// EnumTypeQuelconque inter = (*il);
// if (NombreElementFoncDim(Type_de_grandeur_associee(inter)) != 1)
// { cout << "\n *** pb de dimensions d'argument non coherentes !! "
// << " la grandeur quelconque "<< NomTypeQuelconque(inter)
// << ", n'est pas un scalaire simple "
// << "\n Fonction_nD::Construction_enu_etendu_et_quelconque(..."<<endl;
// Sortie(1);
// };
// #endif
// };
// };
// // on met à jour le tableau de transfert
// // ici par défaut chaque type quelconque est associé à un conteneur scalaire
// // si ce n'est pas le cas, on considère que l'utilisateur utilisera la méthode
// // Preparation_Grandeur_quelconque( pour mettre les bonnes dimensions
// x_x_i.Change_taille(tail_enu_ddl+tail_enuquel);
// };
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
void Fonction_nD::Construction_index_conteneurs_evoluees()
{// on parcours les noms des variables
int taille = nom_variables.Taille();
t_inter_double.Change_taille(taille);
// on dimensionne le tableau des types de variables
type_des_variables.Change_taille(taille);
// on nettoie les listes
li_enu_etendu_scalaire.clear();
// on part avec l'idée que toutes les grandeurs seront reconnues localement
equivalence_nom_enu_etendu_et_enu_quelconque = true;
// def de listes intermédiaires
list <int> li_inter_posi_ddl_enum; // liste des positions
// --- cas des tenseurs
list <TenseurBB* > li_inter_tens_ddl_enum; // pour les tenseurs
// list <Deuxentiers_enu > li_ind_tens; // pour les indices dans les tenseurs
List_io <Ddl_enum_etendu> li_premier_famille_tenseur; // pour savoir si c'est déjà enregistré
// --- cas des coordonnées
list <Coordonnee > li_coor_ddl_enum;
// list <int > li_num_dans_coor;
List_io <Ddl_enum_etendu> li_premier_famille_Coord; // pour savoir si c'est déjà enregistré
// --- init de la liste équivalente de grandeurs quelconques évoluées
li_equi_Quel_evolue.clear(); // on remet à 0
// on défini des conteneurs ad hoc
int dim = ParaGlob::Dimension(); // la dimension globale
// ... cas des Coordonnees
Coordonnee v_rep(dim); // un vecteur de travail
Grandeur_coordonnee grand5(v_rep); // def d'une grandeur courante coordonnée
// ... cas des tenseurs
TenseurBB* tens = NevezTenseurBB(dim); // un tenseur typique
// maintenant on définit une grandeur typique de type tenseurBB
Grandeur_TenseurBB gtBB(*tens);
list < int > li_position; // liste de la position des variables dans les tableaux
// on parcours les noms de variables
list <Ddl_enum_etendu> li_inter_enu; // une liste intermédiaire de travail
list <int> li_index_enu;
list <EnumTypeQuelconque> li_inter_tyQ; // idem
list <int> li_index_quelc;
// un conteneur de service: un réel par ddl
Ddl_enum_etendu ddl_de_service;
list <double> list_inter_val_ddl_enum; // inter qui donnera ensuite: val_ddl_enum
// par contre pour les grandeurs quelconques, on peut avoir plusieurs
// réels par grandeur quelconque
int indice_enu_ddl = 0; // init
int indice_t_quelconque = 0; // init
for (int i=1; i<= taille; i++) // on balaie les noms de variable
{// on sépare tout d'abord entre ddl_enum_etendu et type quelconque
if (ddl_de_service.VerifExistence(nom_variables(i)))
{ddl_de_service = Ddl_enum_etendu(nom_variables(i));
li_inter_enu.push_back(ddl_de_service);
li_index_enu.push_back(i);
// def de la position du ddl dans le tableau final des ddl (créé à la fin)
indice_enu_ddl++;li_inter_posi_ddl_enum.push_back(indice_enu_ddl);
// récup du type de grandeur auquel apartient l'énumération
// l'idée est de passer en revue le type de grandeur
EnumTypeGrandeur enu_type_grandeur = ddl_de_service.TypeDeGrandeur();
switch (enu_type_grandeur)
{case SCALAIRE : case SCALAIRE_ENTIER : case SCALAIRE_DOUBLE :
{// dans le cas d'un scalaire on a directement une équivalence à Ddl_enum_etendu
// quelque soit le scalaire, on le stocke en double
list_inter_val_ddl_enum.push_back(0.); // on ajoute une valeur 0. arbitraire
li_enu_etendu_scalaire.push_back(ddl_de_service);
type_des_variables(i)=1;
break;
}
case TENSEUR : case TENSEUR_NON_SYM : case TENSEURBB : case TENSEURHH :
case TENSEURBH : case TENSEURHB : case TENSEUR_NON_SYM_BB :
case TENSEUR_NON_SYM_HH :
{ // on considère que c'est toujours un tenseur en absolu et par défaut c'est un tenseur BB
type_des_variables(i)=3;
// maintenant il faut savoir si on a déjà enregistré un tenseur qui contiend la composante
if (!(Ddl_enum_etendu::Existe_dans_la_liste(li_premier_famille_tenseur,Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service))))
// s'il n'existe pas on rajoute le premier de la famille
{ TenseurBB * pt_tens= NevezTenseurBB(dim);
li_inter_tens_ddl_enum.push_back(pt_tens);
li_premier_famille_tenseur.push_back
(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service));
// on s'occupe de la grandeur quelconque équivalente
EnumTypeQuelconque enuQ = Ddl_enum_etendu::Equivalent_en_grandeur_quelconque(ddl_de_service);
TypeQuelconque typQ6(enuQ,ddl_de_service.Enum(),gtBB);
li_equi_Quel_evolue.push_back(typQ6);
};
// // maintenant il faut récupérer la position = l'indice, de l'enu dans le tenseur
// Deuxentiers_enu deux = IJind(ddl_de_service.Enum(),dim);
// li_ind_tens.push_back(deux);
break;
}
case COORDONNEE : case COORDONNEEB : case COORDONNEEH :
{// on considère que c'est toujours un type coordonnée en absolu et par défaut c'est un Coordonnee
type_des_variables(i)=2;
// maintenant il faut savoir si on a déjà enregistré un Coordonnee qui contiend la composante
if (!(Ddl_enum_etendu::Existe_dans_la_liste(li_premier_famille_Coord,Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service))))
// s'il n'existe pas on rajoute le premier de la famille
{ Coordonnee pt_coor(dim);
li_coor_ddl_enum.push_back(pt_coor);
li_premier_famille_Coord.push_back(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddl_de_service));
// on s'occupe de la grandeur quelconque équivalente
EnumTypeQuelconque enuQ = Ddl_enum_etendu::Equivalent_en_grandeur_quelconque(ddl_de_service);
TypeQuelconque typQ6(enuQ,ddl_de_service.Enum(),grand5);
li_equi_Quel_evolue.push_back(typQ6);
};
// // maintenant il faut récupérer la position = l'indice, de l'enu dans Coordonnee
// int indice_coor = Indice_coor(ddl_de_service.Enum(),dim);
// li_num_dans_coor.push_back(indice_coor);
break;
}
default : // pour l'instant les autres cas, par exemple Vecteur, ne sont pas pris en compte
cout << "\nErreur : la grandeur " << nom_variables(i)
<< " n'est pas pris en compte pour les fonctions nD !\n";
cout << "\n Fonction_nD::Construction_index_conteneurs_evoluees(.. \n";
Sortie(1);
}; // fin du switch
} // fin du cas où c'est un ddl_enum_etendu
else if (Existe_typeQuelconque(nom_variables(i)))
{li_inter_tyQ.push_back(Id_nomTypeQuelconque(nom_variables(i)));
li_index_quelc.push_back(i);
type_des_variables(i)=4;
}
else
{// il y a des variables qui ne rentrent pas dans le cadre dd enu étendu et grandeur quelconque
// on ne pourra pas utiliser l'appel via des grandeurs évoluées: on le sauvegarde
// pour signaler des erreurs mais cela peut changer ensuite
// par exemple via la transformation de variables locales en variables globales qui sont
// dynamiquement créés, du coup on laisse l'algo
equivalence_nom_enu_etendu_et_enu_quelconque = false ;
type_des_variables(i)=0;
};
};
// on poursuit même s'il n'y a pas équivalence parfaite
// de manière a remplacer la méthode : Construction_enu_etendu_et_quelconque()
// cependant s'il y a une équivalence parfaite
// on ne pourra pas utiliser l'appel évolué
// donc certains indexes ne seront pas utilisables
// if (equivalence_nom_enu_etendu_et_enu_quelconque)
{// maintenant on va construire les tableaux qui sont équivalent aux listes
tailles_tab.Change_taille(4);
tailles_tab(1)=list_inter_val_ddl_enum.size();
tailles_tab(2)=li_coor_ddl_enum.size();
tailles_tab(3)=li_inter_tens_ddl_enum.size();
tailles_tab(4)=li_inter_tyQ.size();
// .... pour les ddl étendue
// le tableau global de ddl étendu
tab_enu_etendu.Init_from_list(li_inter_enu);
posi_ddl_enum.Init_from_list(li_inter_posi_ddl_enum);
val_ddl_enum.Init_from_list(list_inter_val_ddl_enum);
coor_ddl_enum.Init_from_list(li_coor_ddl_enum);
premier_famille_Coord.Init_from_list(li_premier_famille_Coord);
// num_dans_coor.Init_from_list(li_num_dans_coor);
num_dans_coor.Change_taille(tab_enu_etendu.Taille());
tens_ddl_enum.Init_from_list(li_inter_tens_ddl_enum);
premier_famille_tenseur.Init_from_list(li_premier_famille_tenseur);
// ind_tens.Init_from_list(li_ind_tens);
ind_tens.Change_taille(tab_enu_etendu.Taille());
index_enu_etendu.Init_from_list(li_index_enu);
// .... pour les grandeurs quelconques
// le tableau global de grandeurs quelconque
tab_enu_quelconque.Init_from_list(li_inter_tyQ);
index_enu_quelconque.Init_from_list(li_index_quelc);
// il faut maintenant revoir le tableau posi_ddl_enum dans le cas
// ou un tenseur et/ou un Coordonnee contient plusieurs Ddl_enum_etendu
// on fait systématiquement le test
// if (tab_enu_etendu.Taille() > (tailles_tab(1)+tailles_tab(2)+tailles_tab(3)))
{// on utilise les premiers de famille dont l'indice est le même que les
// tableau de tenseur et de Coordonnee
int nb_enu = tab_enu_etendu.Taille();
for (int i=1;i<=nb_enu;i++)
{// récup du type de grandeur auquel apartient l'énumération
// l'idée est de passer en revue le type de grandeur
Ddl_enum_etendu & ddenumetendu = tab_enu_etendu(i); // pour simplifier
EnumTypeGrandeur enu_type_grandeur = ddenumetendu.TypeDeGrandeur();
//TypeGrandeur(ddenumetendu.Enum());
switch (enu_type_grandeur)
{case TENSEUR : case TENSEUR_NON_SYM : case TENSEURBB : case TENSEURHH :
case TENSEURBH : case TENSEURHB : case TENSEUR_NON_SYM_BB :
case TENSEUR_NON_SYM_HH :
{ // on récupère la position dans le tableau de tenseur
int position = premier_famille_tenseur.Contient
(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddenumetendu));
posi_ddl_enum(i)=position;
// maintenant il faut récupérer la position = l'indice, de l'enu dans le tenseur
Deuxentiers_enu deux = IJind(ddl_de_service.Enum(),dim);
ind_tens(i) = deux;
break;
}
case COORDONNEE : case COORDONNEEB : case COORDONNEEH :
{ // on récupère la position dans le tableau de Coordonnee
int position = premier_famille_Coord.Contient
(Ddl_enum_etendu::PremierDdlEnumEtenduFamille(ddenumetendu));
posi_ddl_enum(i)=position;
// maintenant il faut récupérer la position = l'indice, de l'enu dans Coordonnee
int indice_coor = Indice_coor(ddenumetendu.Enum(),dim);
num_dans_coor(i) = indice_coor;
break;
}
default : break;// sinon c'est des scalaires
}; // fin du switch
};
}; // fin du if (tab_enu_etendu.Taille() > (tailles_tab(1)+tailles_tab(2)+tailles_tab(3)))
////------- debug
//cout << "\n\n debug Fonction_nD::Construction_index_conteneurs_evoluees() : FCT= " << nom_ref
// << "\n les variables: "<< nom_variables
// << "\n li_equi_Quel_evolue= " << li_equi_Quel_evolue
// << " num_dans_coor= "<<num_dans_coor;
////------- fin debug
// .... pour les grandeurs quelconques équivalentes aux grandeurs
// évoluées non scalaires
// l'ordre d'apparition dans la liste est le même que celui dans les tableaux
// donc on parcours deux fois la liste des grandeurs, une fois pour les coordonnées et
// une fois pour les tenseurs
int nb_etendu = tab_enu_etendu.Taille();
int nb_coor = coor_ddl_enum.Taille();
tab_equi_Coor.Change_taille(nb_coor);
int nb_tenseur = tens_ddl_enum.Taille();
tab_equi_tens.Change_taille(nb_tenseur);
List_io <TypeQuelconque >::iterator iqc,iqc_fin=li_equi_Quel_evolue.end();
// cout << "\n posi_ddl_enum= " << posi_ddl_enum << endl;
for (int i=1;i<=nb_etendu;i++)
if ((type_des_variables(index_enu_etendu(i)) == 2)
|| (type_des_variables(index_enu_etendu(i)) == 3))
{EnumTypeQuelconque enuQ =
Ddl_enum_etendu::Equivalent_en_grandeur_quelconque(tab_enu_etendu(i));
TypeQuelconque tq(enuQ);
// on cherche dans la liste enregistrée
List_io <TypeQuelconque >::iterator result1 =
std::find(li_equi_Quel_evolue.begin(),li_equi_Quel_evolue.end(), tq);
if (result1 == li_equi_Quel_evolue.end())
{cout << "\n *** erreur d'adressage dans "
<< "Fonction_nD::Construction_index_conteneurs_evoluees()";
this->Affiche();
Sortie(1);
};
if (type_des_variables(index_enu_etendu(i)) == 2) // cas de coordonnées
tab_equi_Coor(posi_ddl_enum(i))=result1;
else if (type_des_variables(index_enu_etendu(i)) == 3) // cas des tenseurs
tab_equi_tens(posi_ddl_enum(i))=result1;
};
delete tens; // car on n'en a plus besoin
// on met à jour le tableau de transfert
// ici par défaut chaque type quelconque est associé à un conteneur scalaire
// si ce n'est pas le cas, on considère que l'utilisateur utilisera la méthode
// Preparation_Grandeur_quelconque( pour mettre les bonnes dimensions
x_x_i.Change_taille(tab_enu_etendu.Taille()+tab_enu_quelconque.Taille());
}; // fin du cas où il y a une équivalence parfaite
};
// Passage des infos variables évoluées en tableau de réels
// I/O : di
Tableau <double > & Fonction_nD::Vers_tab_double(Tableau <double > & di
,const Tableau <double >* val_ddl_enum
,const Tableau <Coordonnee> * coor_ddl_enum
,const Tableau <TenseurBB* >* tens_ddl_enum
,const Tableau <const TypeQuelconque * >* tqi
,const Tableau <int> * t_num_ordre)
{
#ifdef MISE_AU_POINT
if (di.Taille() != (tab_enu_etendu.Taille() + tab_enu_quelconque.Taille()))
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " tab_enu_etendu.Taille()= " << tab_enu_etendu.Taille()
<< " tab_enu_quelconque.Taille()= "<< tab_enu_quelconque.Taille()
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if (tailles_tab(1) != 0) // cas où il existe des scalaires
{if (val_ddl_enum == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " val_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir des scalaires purs !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
}
else
{if (val_ddl_enum->Taille() != tailles_tab(1))
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " taille val_ddl_enum = " << val_ddl_enum->Taille()
<< " est different du nombre prevu !" << tailles_tab(1)
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
};
if (tailles_tab(2) != 0)
{if (coor_ddl_enum == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " coor_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir des coordonnees !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
if (tailles_tab(3) != 0)
{if (tens_ddl_enum == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " tens_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir des tenseurs !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
if (tailles_tab(4) != 0)
{if (tqi == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " tqi pointe sur NULL "
<< " et il est prevu d'avoir des grandeurs quelconques !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
}
else if (t_num_ordre != NULL)
{if (t_num_ordre->Taille() != tqi->Taille())
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " taille tqi = " << tqi->Taille()
<< " est different du nombre de numero d'ordre prevu !" << t_num_ordre->Taille()
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
};
#endif
// on va boucler sur les arguments:
// on utilise les index, pour un adressage indirect, pour le tableau de retour "et"
// la grandeur, normalement, cela devrait être ok
// 1) sur les enum
int nb_enu = index_enu_etendu.Taille();
for (int ienu=1;ienu <= nb_enu; ienu++)
{int num_variable = index_enu_etendu(ienu); // le numéro de nom_variable
switch (type_des_variables(num_variable))
{ case 1: // scalaire
{di(num_variable) = val_ddl_enum->operator()(posi_ddl_enum(ienu));
break;}
case 2: // Coordonnee
{int j = posi_ddl_enum(ienu);
di(num_variable) = (*coor_ddl_enum)(j)(num_dans_coor(ienu));
break;}
case 3: // tenseur
{int j = posi_ddl_enum(ienu);
int k = ind_tens(ienu).i; int l = ind_tens(ienu).j;
di(num_variable) = (*(*tens_ddl_enum)(j))(k,l);
break;}
default:
break;
};
}; // fin de la boucle sur les enum
// 2) sur les grandeurs quelconques
int nb_quelc = index_enu_quelconque.Taille();
for (int ieq = 1; ieq <= nb_quelc; ieq++)
{ int num_variable = index_enu_quelconque(ieq);
int nb_ordre = 1; // init par défaut
if (t_num_ordre != NULL)
nb_ordre = (*t_num_ordre)(ieq);
di(num_variable) = (*tqi)(ieq)->GrandeurNumOrdre(nb_ordre);
}; // fin de la boucle sur les enu quelconques
// retour
return di;
};
// idem, mais via les listes
// val_ddl_enum(k) correspond à li_evolue_scalaire de rang i
Tableau <double > & Fonction_nD::Vers_tab_double(Tableau <double > & di
,const Tableau <double >* val_ddl_enum
,List_io <Ddl_enum_etendu>* li_evolue_scalaire
,List_io <TypeQuelconque >* li_evoluee_non_scalaire
,const Tableau <const TypeQuelconque * >* tqi
,const Tableau <int> * t_num_ordre)
{
#ifdef MISE_AU_POINT
// on vérifie qu'il s'agit bien des mêmes listes
if ((&li_enu_etendu_scalaire) != li_evolue_scalaire)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " la liste des enum etendu scalaires n'est pas celle fournie par la fonction"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if ((&li_equi_Quel_evolue) != li_evoluee_non_scalaire)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " la liste des grandeurs evoluees non scalaire n'est pas celle fournie par la fonction"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if (li_enu_etendu_scalaire.size() != 0)
{if (val_ddl_enum==NULL)
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " val_ddl_enum pointe sur NULL "
<< " et il est prevu d'avoir "<< li_enu_etendu_scalaire.size() << " grandeurs scalaires !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
if (val_ddl_enum->Taille() != li_enu_etendu_scalaire.size())
{ cout << "\n *** pb dans le transfert des grandeurs evoluees vers scalaires "
<< " val_ddl_enum est de taille " << val_ddl_enum->Taille()
<< " alors qu'il est prevu d'avoir "<< li_enu_etendu_scalaire.size() << " grandeurs scalaires !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
if (tailles_tab(4) != 0)
{if (tqi == NULL)
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " tqi pointe sur NULL "
<< " et il est prevu d'avoir des grandeurs quelconques !"
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
}
else if (t_num_ordre != NULL)
{if (t_num_ordre->Taille() != tqi->Taille())
{ cout << "\n *** pb dans le transfert des grandeurs quelconques vers scalaires "
<< " taille tqi = " << tqi->Taille()
<< " est different du nombre de numero d'ordre prevu !" << t_num_ordre->Taille()
<< " ce n'est pas normal !! , on arrete le calcul "
<< "\n Fonction_nD::Vers_tab_double(..."<<endl;
Sortie(1);
};
};
};
#endif
// on va boucler sur les arguments:
List_io <Ddl_enum_etendu>::iterator i_scal = li_enu_etendu_scalaire.begin();
List_io <TypeQuelconque >::iterator i_evol = li_equi_Quel_evolue.begin();
int indice_scal=1; // init : indice dans le tableau val_ddl_enum
////------- debug
//cout << "\n\n debug Fonction_nD::Vers_tab_double( : FCT= " << nom_ref
// << "\n les variables: "<< nom_variables
// << "\n li_equi_Quel_evolue= " << li_equi_Quel_evolue
// << " num_dans_coor= "<<num_dans_coor;
////------- fin debug
// 1) sur les enum
int nb_enu = index_enu_etendu.Taille();
// qui a la même taille que tab_enu_etendu, et dans le même ordre
for (int ienu=1;ienu <= nb_enu; ienu++)
{int num_variable = index_enu_etendu(ienu); // le numéro de nom_variable
switch (type_des_variables(num_variable))
{ case 1: // scalaire
{di(num_variable) = (*val_ddl_enum)(posi_ddl_enum(ienu));
break;}
case 2: // Coordonnee
{int j = posi_ddl_enum(ienu);
// pour simplifier l'écriture
List_io<TypeQuelconque >::iterator& il = tab_equi_Coor(j);
Grandeur_coordonnee& coo = *((Grandeur_coordonnee*) (*il).Grandeur_pointee());
Coordonnee& coord = *(coo.ConteneurCoordonnee());
di(num_variable) = coord(num_dans_coor(ienu));
////------- debug
//cout << "\n num_variable= "<<num_variable
// << " di (num_variable)= "<<di(num_variable)
// << " num_dans_coor("<<ienu<<")= "<<num_dans_coor(ienu)
// << "\n coord= "<<coord ;
////------- fin debug
i_evol++;
break;}
case 3: // tenseur
{int j = posi_ddl_enum(ienu);
int k = ind_tens(ienu).i; int l = ind_tens(ienu).j;
// pour simplifier l'écriture
List_io<TypeQuelconque >::iterator& il = tab_equi_tens(j);
Grandeur_TenseurBB& ten = *((Grandeur_TenseurBB*) (*il).Grandeur_pointee());
TenseurBB& tensBB = ten.RefConteneurTenseur();
di(num_variable) = tensBB(k,l);
i_evol++;
break;}
default:
break;
};
}; // fin de la boucle sur les enum
// 2) sur les grandeurs quelconques
int nb_quelc = index_enu_quelconque.Taille();
for (int ieq = 1; ieq <= nb_quelc; ieq++)
{ int num_variable = index_enu_quelconque(ieq);
int nb_ordre = 1; // init par défaut
if (t_num_ordre != NULL)
nb_ordre = (*t_num_ordre)(ieq);
di(num_variable) = (*tqi)(ieq)->GrandeurNumOrdre(nb_ordre);
}; // fin de la boucle sur les enu quelconques
////------ debug
//cout << "\n debug Fonction_nD::Vers_tab_double( ";
//cout << di << endl;
//
////------ fin debug
// retour
return di;
};
// appel de la fonction sous forme d'une méthode avec un nombre non limité
// de paramètres: en fait utilise Valeur
// c'est une méthode avec retour uniquement en scalaire, sinon -> erreur
// calcul des valeurs de la fonction
double Fonction_nD::Val_avec_nbArgVariable(double x,...)
{
// un certain nombre de variables utilisée pour gérer
// http://www.cplusplus.com/reference/cstdarg/va_copy/
// cf. variadic function
int count = 0;
double val = x;
va_list vl,vl_count;
va_start(vl,x);
// on va remplir le tableau xinter, pour faire un appel classique
int nb_var = this->NbVariable();
if (xinter == NULL)
xinter = new Tableau <double >(nb_var);
if (nb_var != 0)
{(*xinter)(count+1)=val;
/* count number of arguments: */
va_copy(vl_count,vl);
while (val != 0)
{if (count < nb_var) // cas normal
{val=va_arg(vl_count,double);
++count;
(*xinter)(count+1)=val;
}
else // sinon il y a plus d'argument que prévu, on génère une erreur
{ cout << "\n *** erreur dans l'appel de la fonction " << nom_ref
<< " le nombre d'argument est superieur a "<< nb_var
<< " ce qui n'est pas prevu dans la definition de la fonction "
<< "\n Fonction_nD::Val_avec_nbArgVariable( ";
if (ParaGlob::NiveauImpression() > 1)
this->Affiche();
cout << endl;
Sortie(1);
};
};
va_end(vl_count);
};
// maintenant on peut utiliser la méthode classique
Tableau <double> & ret = this->Valeur_FnD_interne(xinter);
return ret(1);
};
// méthode utilisée par les classes dérivées, pour transférer les infos qui sont
// gérées au niveau de Fonction_nD
Fonction_nD& Fonction_nD::Transfert_info(const Fonction_nD& elt)
{ // on reprend toutes les données gérées par Fonction_nD
typeFonction = elt.typeFonction;
nom_ref = elt.nom_ref;
nom_variables = elt.nom_variables;
t_inter_double = elt.t_inter_double;
enu_variables_globale = elt.enu_variables_globale;
nom_variables_globales = elt.nom_variables_globales;
tab_enu_etendu = elt.tab_enu_etendu;
type_des_variables = elt.type_des_variables;
val_ddl_enum = elt.val_ddl_enum;
li_enu_etendu_scalaire = elt.li_enu_etendu_scalaire;
coor_ddl_enum = elt.coor_ddl_enum;
num_dans_coor = elt.num_dans_coor;
tens_ddl_enum = elt.tens_ddl_enum;
premier_famille_tenseur = elt.premier_famille_tenseur;
ind_tens = elt.ind_tens;
posi_ddl_enum = elt.posi_ddl_enum;
tailles_tab = elt.tailles_tab;
tab_enu_quelconque = elt.tab_enu_quelconque;
equivalence_nom_enu_etendu_et_enu_quelconque = elt.equivalence_nom_enu_etendu_et_enu_quelconque;
index_enu_etendu = elt.index_enu_etendu;
index_enu_quelconque = elt.index_enu_quelconque;
// les listes pour les appels via les listes
li_enu_etendu_scalaire = elt.li_enu_etendu_scalaire;
li_equi_Quel_evolue = elt.li_equi_Quel_evolue;
tab_equi_Coor = elt.tab_equi_Coor;
tab_equi_tens = elt.tab_equi_tens;
x_x_i = elt.x_x_i;
x_glob = elt.x_glob;
depend_M = elt.depend_M;
depend_Mt = elt.depend_Mt;
depend_M0 = elt.depend_M0;
depend_temps = elt.depend_temps;
};
// affichage des données internes, utilisée par les fonctions dérivées
// niveau donne le degré d'affichage
void Fonction_nD::Affiche_interne(int niveau) const
{ if (niveau > 0)
{ cout << "\n type_de_fonction: "<< Nom_Fonction_nD(typeFonction)
<< " nom_ref= " << nom_ref
<< "\n les_variables_lues: " << nom_variables ;
if (niveau > 1)
{ // les énumérés globaux éventuels
int taille_enu_variables_globale= enu_variables_globale.Taille();
if (taille_enu_variables_globale != 0)
{ cout << "\n enumeres_globaux:_taille " << enu_variables_globale.Taille();
for (int i=1;i<= taille_enu_variables_globale;i++)
cout << " " << Nom_GrandeurGlobale(enu_variables_globale(i));
};
// les noms de variables globales éventuelles
int taille_nom_variables_globales= nom_variables_globales.Taille();
if (taille_nom_variables_globales != 0)
{ cout << "\n noms_variables_globales:_taille " << nom_variables_globales.Taille();
for (int i=1;i<= taille_nom_variables_globales;i++)
cout << " " << nom_variables_globales(i);
};
// enu étendu équivalent aux variables non globales
int taille_tab_enu_etendu= tab_enu_etendu.Taille();
if (taille_tab_enu_etendu != 0)
{ cout << "\n enum_etendu_locaux:_taille " << tab_enu_etendu.Taille();
for (int i=1;i<= taille_tab_enu_etendu;i++)
{cout << " " << tab_enu_etendu(i).Nom_plein();
int j = posi_ddl_enum(i);
switch (type_des_variables(i))
{case 1: cout << " type scalaire: valeur actuelle= "
<< val_ddl_enum(j) ;
break;
case 2: cout << " type coordonnees: valeur actuelle= "
<< coor_ddl_enum(j)(num_dans_coor(j));
break;
case 3: cout << " type tenseur: valeur actuelle= "
<< (*tens_ddl_enum(j))(ind_tens(j).i,ind_tens(j).j) ;
break;
default: cout << "\n type non reconnue= " << type_des_variables(i)
<< "\n Fonction_nD::Affiche_interne( ";
Sortie(1);
};
};
// bilan des variables évoluées
cout << "\n il y a: "
<< tailles_tab(1) << " scalaire(s) "
<< tailles_tab(2) << " coordonnee(s) "
<< tailles_tab(3) << " composante(s) de tenseur "
<< endl;
};
// grandeurs quelconques équivalentes aux variables non globales
int taille_tab_enu_quelconque= tab_enu_quelconque.Taille();
if (taille_tab_enu_quelconque != 0)
{ cout << "\n enum_quelconque:_taille " << tab_enu_quelconque.Taille()
<< "\n liste: ";
for (int i=1;i<= taille_tab_enu_quelconque;i++)
cout << NomTypeQuelconque(tab_enu_quelconque(i)) << ", ";
};
};
// autres infos
cout << "\n il y a " << this->NbComposante() << " valeur(s) en retour de la fonction ";
if (depend_temps || depend_M || depend_Mt ||depend_M0 )
{ cout << "\n ";
if (depend_temps)
cout << " la fonction depend du temps, ";
if (depend_M || depend_Mt ||depend_M0 )
cout << " la fonction depend du point M : ";
if (depend_M)
cout << " courant, ";
if (depend_Mt)
cout << " a t, ";
if (depend_M0)
cout << " a 0, ";
};
};
};
//------ méthodes appelée par les classes dérivées ----
// relatives aux données gérées par Fonction_nD
// 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_nD::Lect_base_info(ifstream& ent,const int cas)
{
if (cas == 1)
{ string toto; string nom;
// lecture des arguments
ent >> nom >> nom_variables;
t_inter_double.Change_taille(nom_variables.Taille());
// les énumérés des variables globales
ent >> nom;
int nb_enu=0;
ent >> nom >> nb_enu;
enu_variables_globale.Change_taille(nb_enu);
for (int i=1;i<= nb_enu;i++)
{ ent >> nom;
enu_variables_globale(i) = Id_nom_GrandeurGlobale(nom);
};
// les nom des variables globales indicées en string
ent >> nom;
int nb_nom=0;
ent >> nom >> nb_nom;
nom_variables_globales.Change_taille(nb_nom);
for (int i=1;i<= nb_nom;i++)
{ ent >> nom;
nom_variables_globales(i) = nom;
};
// enu étendu équivalent aux variables non globales
ent >> nom >> tab_enu_etendu;
// grandeurs quelconques équivalentes aux variables non globales
int taille_tab_enu_quelconque; // init
ent >> nom >> taille_tab_enu_quelconque >> toto;
tab_enu_quelconque.Change_taille(taille_tab_enu_quelconque);
for (int i=1;i<= taille_tab_enu_quelconque;i++)
{ent >> nom;
tab_enu_quelconque(i) = Id_nomTypeQuelconque(nom);
};
// bilan des variables évoluées (on lit pour passer les infos
// dans le .BI, mais cela va être recalculé au moment de la fabrication
// des index
tailles_tab.Change_taille(4);
ent >> nom
>> tailles_tab(1) >> nom
>> tailles_tab(2) >> nom
>> tailles_tab(3) >> nom
>> tailles_tab(4) >> nom;
ent >> nom >> permet_affichage ;
// 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 Fonction_nD::Ecrit_base_info(ofstream& sort,const int cas)
{
if (cas == 1)
{ // les variables
sort << " \n arguments= " << nom_variables
<< " \n variables_globales_en_enumere= " ;
int nb_enu = enu_variables_globale.Taille();
sort << "taille " << nb_enu << " ";
for (int i=1;i<= nb_enu;i++)
sort << Nom_GrandeurGlobale(enu_variables_globale(i)) << " ";
sort << " \n variables_globales_en_string= " ;
int nb_str = nom_variables_globales.Taille();
sort << "taille " << nb_str << " ";
for (int i=1;i<= nb_str;i++)
sort << nom_variables_globales(i) << " ";
// enu étendu équivalent aux variables non globales
int taille_tab_enu_etendu= tab_enu_etendu.Taille();
sort << "\n enum_etendu_locaux: " << tab_enu_etendu;
// grandeurs quelconques équivalentes aux variables non globales
int taille_tab_enu_quelconque= tab_enu_quelconque.Taille();
sort << "\n enum_quelconque:_taille " << tab_enu_quelconque.Taille()
<< "\n liste: ";
for (int i=1;i<= taille_tab_enu_quelconque;i++)
sort << NomTypeQuelconque(tab_enu_quelconque(i)) << " ";
// bilan des variables évoluées
sort << "\n bilan_var_evolue_il_y_a: "
<< tailles_tab(1) << " scalaire(s) "
<< tailles_tab(2) << " coordonnee(s) "
<< tailles_tab(3) << " composante(s)_de_tenseur "
<< tailles_tab(4) << " grandeur_quelconque "
;
sort << "\n permet_affichage_ "<<permet_affichage << " ";
};
};
// sortie du schemaXML: en fonction de enu
void Fonction_nD::SchemXML_Fonctions_nD(ofstream& sort,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;
}
};
};
// lecture d'une ou plusieurs variables
// peut-être appelée plusieurs fois,
// stockage des infos dans Fonction_nD
void Fonction_nD::Lecture_variables(string& nom_lu,UtilLecture * entreePrinc)
{
// on lit tant que l'on ne rencontre pas une ligne contenant
// une info ne correspondant pas à des variables // ou un nouveau mot clé global auquel cas il y a pb !!
MotCle motCle; // ref aux mots cle
// on utilise des listes pour éviter les doublons
list <Enum_GrandeurGlobale > list_enu_variables_glob; // enum glob
// on transvase le tableau dans la liste
enu_variables_globale.Init_list(list_enu_variables_glob);
// idem pour les noms globaux
list < string> list_de_variables_nom_globales; // string glob
nom_variables_globales.Init_list(list_de_variables_nom_globales);
// puis les variables qui ne sont pas globales
list < string> list_de_variables; // liste
nom_variables.Init_list(list_de_variables);
bool lecture_effective = false; // init
while (( (strstr(entreePrinc->tablcar,"un_argument=")==0)
&& (strstr(entreePrinc->tablcar,"deb_list_var_")==0)
)
|| (nom_lu == "un_argument=")
|| (nom_lu == "deb_list_var_")
)
{
// 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 de mot cle relatif a une variable"
<< " et par contre la ligne courante contient un mot cle global "
<< " *** a priori il y a une erreur de mise en donnees ! " ;
entreePrinc->MessageBuffer("** erreur des parametres d'une fonction nD **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
};
// lecture d'un mot clé éventuellement
if (( (nom_lu != "un_argument=")
&& (nom_lu != "deb_list_var_")
)
|| lecture_effective
)
*(entreePrinc->entree) >> nom_lu;
// sinon cela veut dire que nom_lu a déjà été lu et repéré
// relatif à une variable
// ou que l'on vient de terminer une lecture de variabl
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) >>nom_lu;
}
#else
else if ((entreePrinc->entree)->eof())
// la lecture est bonne mais on a atteind la fin de la ligne
{ if(nom_lu != "fin_parametres_fonction_expression_litterale_")
// on lit sans tenir compte des < éventuelles
{entreePrinc->NouvelleDonneeSansInf();
*(entreePrinc->entree) >> nom_lu;
};
}
#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);
};
// cas de la lecture d'une variable
if(nom_lu == "un_argument=")
{*(entreePrinc->entree) >> nom_lu;
// on regarde s'il s'agit d'une variable globale correspondant à un énuméré global
if (EstUneGrandeurGlobale(nom_lu))
{ list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (nom_lu));}
// idem mais sous forme d'un string
else if (ParaGlob::param->GrandeurGlobal(nom_lu) != NULL)
{ list_de_variables_nom_globales.push_back(nom_lu);}
else // sinon ce n'est pas une grandeur globale
{list_de_variables.push_back(nom_lu);};
// on signale que la lecture a été effective
lecture_effective = true;
}
else if(nom_lu == "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
{*(entreePrinc->entree) >> nom_lu;
if (nom_lu == "fin_list_var_")
break;
// on regarde s'il s'agit d'une variable globale
if (EstUneGrandeurGlobale(nom_lu))
{ list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (nom_lu));}
// idem mais sous forme d'un string
else if (ParaGlob::param->GrandeurGlobal(nom_lu) != NULL)
{ list_de_variables_nom_globales.push_back(nom_lu);}
else // sinon ce n'est pas une grandeur globale
{list_de_variables.push_back(nom_lu);};
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 d'une fonction nD ** **");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else // sinon c'est ok
// on signale que la lecture a été effective
lecture_effective = true;
}
; // sinon rien, ce n'est plus une variable, on va donc sortir
// du while à la suite
}; // fin du while
// nom_lu contient la dernière information lue qui ne correspond pas à une variable
//--- maintenant on va gérer les variables lues
// 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 remet à jour le tableau des énumérés globaux
enu_variables_globale.Init_from_list(list_enu_variables_glob);
// idem pour les noms de reférence globaux
nom_variables_globales.Init_from_list(list_de_variables_nom_globales);
// puis pour les variables qui ne sont pas globales
nom_variables.Init_from_list(list_de_variables);
// on met à jour les tableaux internes de passage de valeurs
x_x_i.Change_taille(nom_variables.Taille());
x_glob.Change_taille(enu_variables_globale.Taille()+nom_variables_globales.Taille());
};
// affichage des variables de la fonction, dépend du niveau d'impression
void Fonction_nD::Affichage_variables() const
{
if (permet_affichage > 5)
{ cout << "\n ---- Fonction_nD " << nom_ref ;
cout << " \n arguments_specifiques= " << 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) << " ";
};
};
// récupération des valeurs des variables globales et stockage dans le tableau
// interne x_glob
void Fonction_nD::Recup_Grandeurs_globales()
{ // --- on parcours les variables globales:
// 1) les énumérés
int index_glob=1;
int tail_enu = enu_variables_globale.Taille();
if (tail_enu>0)
{
// en debug on vérifie que les grandeurs globales sont présentent
#ifdef MISE_AU_POINT
try
{ 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 l'appel de la fonction " << nom_ref << " !! "
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->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 ;
cout << " verifier la presence des grandeurs globales voulues "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
for (int i=1;i<= tail_enu;i++,index_glob++)
{// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(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
x_glob(index_glob) = *(gr.ConteneurEntier());
break;
}
case PARTICULIER_SCALAIRE_DOUBLE:
{Grandeur_scalaire_double& gr
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
case PARTICULIER_DDL_ETENDU:
{Grandeur_Ddl_etendu& gr
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (gr.GrandeurNumOrdre(1));
break;
}
case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER:
{Grandeur_Double_Nommer_indicer& gr
= *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
}
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
};
if (permet_affichage > 5)
{cout << "\n " << Nom_GrandeurGlobale(enu_variables_globale(i))
<< " " << x_glob(index_glob);
};
};
};
// 2) idem pour les globaux en nom c-a-d typées sous forme de string
int tail_nom = nom_variables_globales.Taille();
if (tail_nom>0)
{
// en debug on vérifie que les grandeurs globales sont présentent
#ifdef MISE_AU_POINT
try
{ 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 Fonction_expression_litterale_nD " << nom_ref << " !! "
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas disponible, on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->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 ;
cout << " verifier la presence des grandeurs globales voulues "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
// on parcours les variables globales
int taille = nom_variables_globales.Taille();
for (int i=1;i<= taille;i++,index_glob++)
{// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(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
x_glob(index_glob) = *(gr.ConteneurEntier());
break;
}
case PARTICULIER_SCALAIRE_DOUBLE:
{Grandeur_scalaire_double& gr
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
case PARTICULIER_DDL_ETENDU:
{Grandeur_Ddl_etendu& gr
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (gr.GrandeurNumOrdre(1));
break;
}
case PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER:
{Grandeur_Double_Nommer_indicer& gr
= *((Grandeur_Double_Nommer_indicer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = *(gr.ConteneurDouble());
break;
}
case PARTICULIER_VECTEUR_NOMMER:
{Grandeur_Vecteur_Nommer& gr
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (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 "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
<< " compte pour l'intant, on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
}
break;
}
case TABLEAU_T: // valable uniquement pour les vecteur nommer
// dans ce cas on n'utilise pour l'instant que la première valeur
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
{ case PARTICULIER_VECTEUR_NOMMER:
{Grandeur_Vecteur_Nommer& gr
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
x_glob(index_glob) = (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 "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
<< " compte pour l'intant, on ne peut pas continuer "
<< "\n grandeur= "<<gr<< " NbMaxiNumeroOrdre()= "<< gr.NbMaxiNumeroOrdre()
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
#endif
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
}
break;
}
default:
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
<< " la variable globale "<< nom_variables_globales(i)
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
<< "\n Fonction_nD::Recup_Grandeurs_globales(..."
<<endl;
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
};
if (permet_affichage > 5)
{cout << "\n " << nom_variables_globales(i)
<< " " << x_glob(index_glob);
};
};
};
};