Herezh_dev/herezh_pp/Util/Courbes/Fonction_nD.h

803 lines
40 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/>.
// fichier : Fonction_nD.h
// classe : Fonction_nD
/************************************************************************
* DATE: 01/06/2016 *
* $ *
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
* $ *
* PROJET: Herezh++ *
* $ *
************************************************************************
* BUT: Classe virtuelle permettant le calcul d'une fonction nD *
* ainsi qu'éventuellement un certain nombre d'information supplé- *
* mentaires telles que dérivées. *
* si le nom de la Fonction = "_" il s'agit d'une Fonction interne *
* à un objet, c'est-à-dire gérée seulement par l'entité qui la *
* contient, donc pas besoin de nom (elle n'est pas utilisée autre *
* part). Si le nom est différent de "_" c'est une Fonction qui est *
* gérée et référencée dans LesFonctions, donc à partir de son nom, *
* on peut la retrouver. *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS: *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* $ *
************************************************************************/
#ifndef FONCTION_N_D_H
#define FONCTION_N_D_H
#include "UtilLecture.h"
#include "EnumFonction_nD.h"
#include "Enum_IO_XML.h"
#include "Tableau_T.h"
#include "Enum_GrandeurGlobale.h"
#include "Courbe1D.h"
#include "Coordonnee.h"
#include "Ddl_etendu.h"
#include "TypeQuelconque.h"
#include "Tenseur.h"
/** @defgroup Les_fonctions_nD Les_fonctions_nD
*
* \author Gérard Rio
* \version 1.0
* \date 01/06/2016
* \brief Def des fonctions nD
*
*/
/// @addtogroup Les_fonctions_nD
/// @{
///
/// gestion d'exception pour des erreurs d'appel de fonction nD
class ErrCalculFct_nD
{ public :
ErrCalculFct_nD () {} ; // CONSTRUCTEURS
~ErrCalculFct_nD () {};// DESTRUCTEUR :
};
/// @} // end of group
/// @addtogroup Les_fonctions_nD
/// @{
///
/**
*
* BUT: Classe virtuelle d'interface permettant le calcul d'une fonction nD
* ainsi qu'éventuellement un certain nombre d'informations supplé-
* mentaires telles que dérivées.
* si le nom de la Fonction = "_" il s'agit d'une Fonction interne
* à un objet, c'est-à-dire gérée seulement par l'entité qui la
* contient, donc pas besoin de nom (elle n'est pas utilisée autre
* part). Si le nom est différent de "_" c'est une Fonction qui est
* gérée et référencée dans LesFonctions, donc à partir de son nom,
* on peut la retrouver.
*
*
* \author Gérard Rio
* \version 1.0
* \date 01/06/2016
* \brief Classe virtuelle d'interface permettant le calcul d'une fonction nD ainsi qu'éventuellement un certain nombre d'informations supplémentaires telles que dérivées.
*
*/
class Fonction_nD
{
public :
// CONSTRUCTEURS :
// par défaut
Fonction_nD(string nom = "", EnumFonction_nD typ = AUCUNE_FONCTION_nD);
// constructeur avec plus d'info
// dans le cas ou les variables sont associées à des types quelconques, il
// s'agit que de conteneur d'un scalaire simple. Dans le cas contraire il y a erreur !
Fonction_nD(const Tableau <string >& var, string nom = "", EnumFonction_nD typ = AUCUNE_FONCTION_nD);
// def de tous les paramètres: utile pour être appelé par les classes dérivées
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
// de copie
Fonction_nD(const Fonction_nD& Co);
// DESTRUCTEUR :
virtual ~Fonction_nD();
// METHODES PUBLIQUES :
//
// // 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
// // la fonction nD ne doit pas pouvoir fonctionner s'il y a des types complexes
// // et que cette méthode n'a pas été appelé
// void Preparation_Grandeur_quelconque(const Tableau <TypeQuelconque >& tqi);
// --------- virtuelles ---------
// Surcharge de l'operateur = : realise l'egalite de deux fonctions
virtual Fonction_nD& operator= (const Fonction_nD& elt) = 0;
// affichage de la Fonction
// = 0, 1 ou 2 (le plus précis)
virtual void Affiche(int niveau = 0) const = 0;
// ramène le nom de la Fonction
const string& NomFonction() const {return nom_ref;};
// vérification que tout est ok, pres à l'emploi
// ramène true si ok, false sinon
virtual bool Complet_Fonction(bool affichage = true)const =0 ;
// ramène le nombre total de variables de la fonction
// c-a-dire locale et globales
virtual int NbVariable()const
{return nom_variables.Taille()+enu_variables_globale.Taille()
+ nom_variables_globales.Taille();
};
// ramène le nombre de variables locales
// c-a-dire à l'exclusion des variables globales
virtual int NbVariable_locale()const
{return nom_variables.Taille();
};
// ramène le nombre de variables globales
// c-a-dire à l'exclusion des variables locales
virtual int NbVariable_globale()const
{return (enu_variables_globale.Taille()+nom_variables_globales.Taille());
};
// ramène le noms des variables, indépendamment des variables globales
const Tableau <string >& Nom_variables() const {return nom_variables;};
// ramène les énumérés des variables globales éventuelles
const Tableau <Enum_GrandeurGlobale >& Enu_variables_globales() const {return enu_variables_globale;};
// ramène les noms string des variables globales éventuelles
const Tableau <string >& Nom_variables_globales() const {return nom_variables_globales;};
// ramène l'équivalent des nom_variables sous forme de Ddl_enum_etendu et
// d'EnumTypeQuelconque
// permet ensuite d'appeler la méthode Valeur(.. mais à la condition
// que l'ensemble des Nom_variables() sont représenté soit par des Ddl_enum_etendu
// et ou soit par des EnumTypeQuelconque
const Tableau <Ddl_enum_etendu>& Tab_enu_etendu()const {return tab_enu_etendu;};
const Tableau <EnumTypeQuelconque>& Tab_enu_quelconque() const {return tab_enu_quelconque;};
// un booléen pour noter l'équivalence parfaite ou non
bool Equivalence_nom_enu_etendu_et_enu_quelconque() const {return equivalence_nom_enu_etendu_et_enu_quelconque;};
// tab_enu_etendu(i) correspond à nom_variables(index_enu_etendu(i))
const Tableau <int>& Iindex_enu_etendu() const {return index_enu_etendu;};
// tab_enu_quelconque(i) correspond à nom_variables(index_enu_quelconque(i))
const Tableau <int>& Iindex_enu_quelconque() const {return index_enu_quelconque;};
// .. chaque type_des_variables tab_enu_etendu(i) est associé à :
// si type_des_variables(i) = 1 -> un scalaire
// si type_des_variables(i) = 2 -> des coordonnées de dim absolue
// si type_des_variables(i) = 3 -> un tenseur de dim absolue
// si type_des_variables(i) = 4 -> une grandeur quelconque
// retour du tableau des indicateurs
const Tableau <int>& Type_des_variables_locales() const {return type_des_variables;};
// retour du tableau posi_ddl_enum, qui est nécessaire pour l'appel de la fonction
// Val_FnD_Evoluee(Tableau <double >* xi_,Tableau <Coordonnee> * tab_coor_,Tableau <TenseurBB* >* tab_tensBB_
// Tableau <TypeQuelconque >* t_quelc_ )
// -> Pour le Ddl_enum_etendu (i) dont on récupère la liste via Tab_enu_etendu()
// si (i) est un scalaire alors: posi_ddl_enum(i) représente la position que doit
// avoir de Ddl_enum_etendu(i) dans xi_
// si (i) est de type Coordonnee -> position du ddl_enum_etendu(i) dans tab_coor_
// si (i) un tenseur -> position du ddl_enum_etendu(i) dans tab_tensBB_
// si (i) une grandeur quelconque -> position du ddl_enum_etendu(i) dans t_quelc_
const Tableau <int>& Index_dans_tableau() const {return posi_ddl_enum;};
// retour des tailles qu'ont les différents tableaux associés au ddl_enum
// tailles_tab(1) -> nb de scalaires
// (2) -> nb de Coordonnee
// (3) -> nb de tenseur
// (4) -> nb de grandeurs quelconques
const Tableau <int>& Tailles_tab() const {return tailles_tab;};
// ramène le nombre de composantes de la fonction
virtual int NbComposante() const =0;
// 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
virtual void LectDonnParticulieres_Fonction_nD(const string& nom, UtilLecture * ) = 0;
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
// globales en cours de calcul
virtual void Mise_a_jour_variables_globales() = 0;
// établir le lien entre la Fonction et des Fonctions déjà existantes dont
// on connait que le nom
// permet ainsi de complèter la Fonction
// 1) renseigne si la Fonction dépend d'autre Fonction ou non
virtual bool DependAutreFoncCourbes() const {return false;}; // par défaut non
// 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this
virtual list <string>& ListDependanceCourbes(list <string>& lico) const;
// 3) retourne une liste de nom correspondant aux noms de Fonction dont dépend *this
virtual list <string>& ListDependanceFonctions(list <string>& lico) const;
// 4) établit la connection entre la demande de *this et les Fonctions passées en paramètres
virtual void Lien_entre_fonc_courbe(list <Fonction_nD *>& liptfonc,list <Courbe1D *>& liptco) {};
// def info fichier de commande
virtual void Info_commande_Fonctions_nD(UtilLecture & entreePrinc) = 0;
// calcul des valeurs de la fonction, avec comme argument: uniquement des grandeurs
// scalaires simples
// retour d'un tableau de scalaires
Tableau <double> & Valeur_FnD_tab_scalaire(Tableau <double >* val_double)
{try
{
// #ifdef MISE_AU_POINT
if (permet_affichage > 4)
{
cout << "\n fonction: "<<nom_ref<<" : ";
if (permet_affichage > 5)
{cout << "\n parametres d'appel: ";
int nb_var = val_double->Taille();
for (int j=1;j<=nb_var;j++)
{ cout << " para("<<j<<")= "<< (*val_double)(j);}
};
Tableau <double> & inter = Valeur_FnD_interne(val_double);
cout << "\n retour fonction: ";
int nb_val = inter.Taille();
for (int i=1;i<=nb_val;i++)
cout << " val("<<i<<")= "<<inter(i);
return inter;
}
else
// #endif
return Valeur_FnD_interne(val_double);
}
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_tab_scalaire(..."<<endl;
this->Affiche();
ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
// on ne doit jamais arriver ici !
return Valeur_FnD_interne(val_double); // pour taire le compilo
};
// calcul des valeurs de la fonction, à l'aide de paramètres = grandeurs évoluées
// retour d'un tableau de scalaires
// les différents tableaux doivent contenir toutes les informations nécessaires pour l'appel
// NB: il peut y avoir plus d'info que nécessaire
// l'ordre des paramètres doit respecter celui donné par les fonctions Index_dans_tableau()
// il peut y avoir éventuellement des grandeurs quelconques et éventuellement des types non scalaire
// dans ce dernier cas il faut renseigner le tableau de numéro d'ordre t_num_ordre
Tableau <double> & Val_FnD_Evoluee(Tableau <double >* val_ddl_enum
,Tableau <Coordonnee> * coor_ddl_enum
,Tableau <TenseurBB* >* tens_ddl_enum
,Tableau <const TypeQuelconque * >* tqi = NULL
,Tableau <int> * t_num_ordre = NULL
)
{ if (equivalence_nom_enu_etendu_et_enu_quelconque)
{try
{ Vers_tab_double(t_inter_double,val_ddl_enum,coor_ddl_enum,tens_ddl_enum
,tqi,t_num_ordre);
// #ifdef MISE_AU_POINT
if (permet_affichage > 4)
{cout << "\n fonction: "<<nom_ref<<" : ";
if (permet_affichage > 5)
{cout << "\n parametres d'appel: ";
int nb_var = t_inter_double.Taille();
for (int j=1;j<=nb_var;j++)
{ cout << " para("<<j<<")= "<< t_inter_double(j);}
};
Tableau <double> & inter = Valeur_FnD_interne(&t_inter_double);
cout << "\n retour fonction: ";
int nb_val = inter.Taille();
for (int i=1;i<=nb_val;i++)
cout << " val("<<i<<")= "<<inter(i);
return inter;
}
else
// #endif
return Valeur_FnD_interne(&t_inter_double);
}
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_Evoluee(..."<<endl;
ErrCalculFct_nD toto;throw (toto);
this->Affiche();Sortie(1);
};
}
else {cout << "\n erreur appel Val_FnD_Evoluee(, variables non definies ! ";
this->Affiche();
ErrCalculFct_nD toto;throw (toto);Sortie(1);
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilateur
};
// on ne doit jamais arriver ici !
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilo
};
// mise à disposition des conteneurs pour l'appel de Valeur_FnD sans paramètres
// il n'est pas autorisé de changer la taille du conteneur, c'est seulement les valeurs qui doivent
// être modifiées sinon il y aura des pb
// l'ordre des paramètres doit respecter celui donné par les fonctions Index_dans_tableau()
Tableau <double >& Val_ddl_enum() {return val_ddl_enum;} // valeur associé à l'enu_etendu(i) si scalaire
Tableau <Coordonnee >& Coor_ddl_enum() {return coor_ddl_enum;}; // idem si Coordonnées (en orthonormée)
// retourne le tableau de l'ensemble des grandeurs de type Coordonnee qui sont nécessaire pour l'appel
// chaque type est repéré par premier_famille_Coord(j) ce qui correspond à coor_ddl_enum(j)
Tableau <Ddl_enum_etendu>& Premier_famille_Coor() {return premier_famille_Coord;}
Tableau <TenseurBB* >& Tens_ddl_enum() {return tens_ddl_enum;}; // idem si Tenseur (en orthonormée !)
int Absolue() const {return absolue;} // indique si les tenseurs sont en absolue ou non
Tableau <Ddl_enum_etendu>& Premier_famille_tenseur() {return premier_famille_tenseur;}
// -- retourne une liste de grandeurs quelconques équivalentes aux types évoluées non scalaires
// li_equi_Quel_evolue : est l'équivalent des grandeurs évoluées: coor_ddl_enum et tens_ddl_enum
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs évoluées
// non scalaires
// l'ordre l'apparition dans la liste est telle que l'on a:
// 1) tous les Coordonnees 2) puis tous les tenseurs
// dans le même ordre que pour les tableaux: coor_ddl_enum puis tens_ddl_enum
// =>=>=> important: il est permis "que" de changer les valeurs dans les conteneurs
List_io <TypeQuelconque >& Li_equi_Quel_evolue() {return li_equi_Quel_evolue;};
// -- retourne une liste des grandeurs évoluées uniquement scalaire
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs scalaires
// est équivalent à val_ddl_enum, l'ordre d'apparition est celui de val_ddl_enum
// =>=>=> important: il est permis "que" de changer les valeurs dans les conteneurs
List_io <Ddl_enum_etendu>& Li_enu_etendu_scalaire() {return li_enu_etendu_scalaire;}
// calcul équivalent, cf. les paramètres de passage
// pour que l'appel à cette méthode soit correcte, il faut que les listes correspondent
// à celles de Li_equi_Quel_evolue(), et Li_enu_etendu_scalaire(),
// =>=>=> il faut donc utiliser ces listes en les récupérants auparavant !!
// Si t_num_ordre est Null cela signifie que tous les tqi sont de grandeurs scalaire
// dans le cas contraire t_num_ordre(i) donne le numéro d'ordre du scalaire dans tqi qui correspond à Nom_variable(i)
// =>=>=> important: il est permis "que" de changer les valeurs dans les conteneurs
Tableau <double> & Valeur_FnD_Evoluee(Tableau <double >* val_ddl_enum
,List_io <Ddl_enum_etendu>* li_evolue_scalaire
,List_io <TypeQuelconque >* li_evoluee_non_scalaire
,Tableau <const TypeQuelconque * >* tqi
,Tableau <int> * t_num_ordre)
{ if (equivalence_nom_enu_etendu_et_enu_quelconque)
{ try
{Vers_tab_double(t_inter_double,val_ddl_enum,li_evolue_scalaire,li_evoluee_non_scalaire,tqi,t_num_ordre);
// #ifdef MISE_AU_POINT
if (permet_affichage > 4)
{cout << "\n fonction: "<<nom_ref<<" : ";
if (permet_affichage > 5)
{cout << "\n parametres d'appel: ";
int nb_var = t_inter_double.Taille();
for (int j=1;j<=nb_var;j++)
{ cout << " para("<<j<<")= "<< t_inter_double(j);}
};
Tableau <double> & inter = Valeur_FnD_interne(&t_inter_double);
cout << "\n retour fonction: ";
int nb_val = inter.Taille();
for (int i=1;i<=nb_val;i++)
cout << " val("<<i<<")= "<<inter(i);
return inter;
}
else
// #endif
return Valeur_FnD_interne(&t_inter_double);
}
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_Evoluee(..."<<endl;
this->Affiche();
ErrCalculFct_nD toto;throw (toto);
Sortie(1);
};
}
else {cout << "\n erreur appel Val_FnD_Evoluee(, variables non definies ! ";
// on génère une interruption ce qui permettra de dépiler les appels
this->Affiche();
ErrCalculFct_nD toto;throw (toto);
Sortie(1);
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilateur
};
// on ne doit jamais arriver ici !
return Valeur_FnD_interne(&t_inter_double); // pour taire le compilo
};
// 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
// Si t_num_ordre est Null cela signifie que tous les tqi sont de grandeurs scalaire
// dans le cas contraire t_num_ordre(i) donne le numéro d'ordre du scalaire dans tqi qui correspond à Nom_variable(i)
Tableau <double> & Valeur_FnD(Tableau <Ddl_etendu> * t_enu,Tableau <const TypeQuelconque * > * tqi
,Tableau <int> * t_num_ordre);
// indicateur permettant de connaître rapidement si
// la fonction dépend de la position d'un point M: ici au temps tdt
// 0 : la fonction ne dépend pas de la position d'un point M
// =i non nul : la fonction dépend de la position d'un point M
// et = le nombre de composantes demandés (ne sert pas vraiment)
// dans ce cas, une au moins des nom_variables a un nom de la même famille que le ddl X1
// si = -1 : cela signifie que la fonction dépend "que" de M
int Depend_M() const {return depend_M;}; // cas d'une position courante
int Depend_Mt() const {return depend_Mt;}; // cas de la position spécifiquement a t
int Depend_M0() const {return depend_M0;}; // cas de la position initiale
// calcul des valeurs de la fonction, dans le cas où les variables
// sont "tous" des grandeurs globales
Tableau <double> & Valeur_pour_variables_globales()
{ try
{
// #ifdef MISE_AU_POINT
if (permet_affichage > 4)
{cout << "\n fonction: "<<nom_ref<<" : ";
Tableau <double> & inter = Valeur_pour_variables_globales_interne();
cout << "\n retour fonction: ";
int nb_val = inter.Taille();
for (int i=1;i<=nb_val;i++)
cout << " val("<<i<<")= "<<inter(i);
return inter;
}
else
// #endif
return Valeur_pour_variables_globales_interne();
}
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 Valeur_pour_variables_globales(..."<<endl;
ErrCalculFct_nD toto;throw (toto);
this->Affiche();Sortie(1);
};
// on ne doit jamais arriver ici !
return Valeur_pour_variables_globales_interne(); // pour taire le compilo
};
// ---- fonctions internes qui ne "doivent pas !!!" être utilisée directement ---
// elles sont mises en public, pour pouvoir être appelées par les classes dérivées
// sans avoir à déclarer en friend les classes dérivées, sinon cela fait une boucle
// sans fin, d'où la solution choisit pour éviter ce pb
// calcul des valeurs de la fonction, retour d'un tableau de scalaires
virtual Tableau <double> & Valeur_FnD_interne(Tableau <double >* val_ddl_enum) = 0;
// calcul des valeurs de la fonction, dans le cas où les variables
// sont "tous" des grandeurs globales
virtual Tableau <double> & Valeur_pour_variables_globales_interne() = 0;
//----- 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)
virtual void Lecture_base_info(ifstream& ent,const int cas) = 0;
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
virtual void Ecriture_base_info(ofstream& sort,const int cas) = 0;
// sortie du schemaXML: en fonction de enu
virtual void SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu) = 0;
// ---------- static ---------
// ramène un pointeur sur la Fonction correspondant au type de Fonction passé en paramètre
// IMPORTANT : il y a création d'une Fonction (utilisation d'un new)
static Fonction_nD* New_Fonction_nD(string& nom,EnumFonction_nD typeFonction);
// ramène un pointeur sur une Fonction copie de celle passée en paramètre
// IMPORTANT : il y a création d'une Fonction (utilisation d'un new)
static Fonction_nD* New_Fonction_nD(const Fonction_nD& Co);
// ramène la liste des identificateurs de Fonctions actuellement disponibles
static list <EnumFonction_nD> Liste_Fonction_disponible();
// ---------- non virtuelle ---------
// ramène le type de la Fonction
EnumFonction_nD Type_Fonction() const { return typeFonction;};
protected :
// VARIABLES PROTEGEES :
EnumFonction_nD typeFonction; // type de la fonction
string nom_ref; // nom de référence de la Fonction
Tableau <string > nom_variables; //variables de la fonction, vu de l'extérieur
Tableau <double > t_inter_double; // tableau de même dimension que nom_variable
// sert pour passer les infos à la méthode Valeur_FnD_interne(..
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 noms en string
// de variables globales
// éventuellement vide s'il ne sert pas
// *** important: les tableaux nom_variables, enu_variables_globales et
// nom_variables_globales s'ajoutent
// ils ne sont pas liés entre eux: le nombre total de variables est
// la somme des trois tableaux. En général c'est soit l'un , soit l'autre
// ou le dernier mais on peut avoir un mixte
// ---- tableaux de grandeurs équivalentes aux nom_variables (locales) -----
// un tableau tab_enu_etendu et un tableau tab_enu_quelconque:
// tab_enu_etendu.Taille()+tab_enu_quelconque.Taille() == nom_variables.Taille() -> grandeurs locales
Tableau <Ddl_enum_etendu> tab_enu_etendu;
// tab_enu_etendu peut se décomposer de deux manières équivalentes :
// 1) tableaux: val_ddl_enum (scalaires) , coor_ddl_enum (Coordonnees) , tens_ddl_enum (tenseur)
// permet aux utilisateurs d'obtenir un stockage et un appel avec des grandeurs évoluées, distinctes
// 2) list: li_enu_etendu_scalaire (scalaires) , li_equi_Quel_evolue (Coordonnees "et" tenseurs)
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs scalaires
// et permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs évoluées
// excluant les scalaire, et appels associés
// li_equi_Quel_evolue correspond à des grandeurs quelconques contenant Coordonnees et tenseur,
// est indépendant de tab_enu_quelconque, qui lui est complètement quelconque, on ne sait pas a priori
// ce qu'il y a dedans
// .. chaque grandeur quelconque doit être associé, lors de l'appel de la fonction, à un numéro d'ordre
// du coup, pour l'instant on n'utilise qu'un scalaire par grandeur quelconque, mais le conteneur
// peut en contenir plusieurs
Tableau <EnumTypeQuelconque> tab_enu_quelconque;
// ----- grandeurs évoluées y compris les grandeurs quelconques -------
// .. chaque nom_variables(j) est associé à :
Tableau <int> type_des_variables; // si type_des_variables(j) = 1 -> un scalaire
// si type_des_variables(j) = 2 -> des coordonnées de dim absolue
// si type_des_variables(j) = 3 -> un tenseur de dim absolue
// si type_des_variables(j) = 4 -> une grandeur quelconque
// si type_des_variables(j) = 0 -> une grandeur qui n'est pas reconnue en local
// .... dans le cas d'un Ddl_enum_etendu : donc c'est relatif au tableau: tab_enu_etendu
Tableau <double > val_ddl_enum; // valeur associé au ddl tab_enu_etendu(i) si scalaire
// tab_enu_etendu(i) <=> val_ddl_enum(posi_ddl_enum(i))
List_io <Ddl_enum_etendu> li_enu_etendu_scalaire; // est équivalent à val_ddl_enum,
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs scalaires
Tableau <Ddl_enum_etendu> premier_famille_Coord; // les ddl du premier de famille
//coor_ddl_enum(j) est associé avec premier_famille_Coord(j)
Tableau <Coordonnee > coor_ddl_enum; // le vecteur Coordonnée associé au ddl tab_enu_etendu(i) si Coordonnées
Tableau <int > num_dans_coor; // le numéro dans le vecteur associé au ddl tab_enu_etendu(i)
// avec j = posi_ddl_enum(i)
// tab_enu_etendu(i) <=> coor_ddl_enum(j)(num_dans_coor(i))
// bien noter qu'un objet Coordonnee peut contenir plusieurs Ddl_enum_etendu
Tableau <Ddl_enum_etendu> premier_famille_tenseur; // les ddl du premier de famille
// (*tens_ddl_enum)(j) est associé avec premier_famille_tenseur(j)
Tableau <TenseurBB* > tens_ddl_enum; // tenseur associé au ddl tab_enu_etendu(i) si Tenseur
int absolue; // indique si les tenseurs sont en absolue ou non
Tableau <Deuxentiers_enu > ind_tens; // indice dans le tenseur de la grandeur
// avec j = posi_ddl_enum(i)
// avec k = ind_tens(i).i et l = ind_tens(i).j
// tab_enu_etendu(i) <=> (*tens_ddl_enum)(j)(k,l)
// bien noter qu'un objet Tenseur peut contenir plusieurs Ddl_enum_etendu
// li_equi_Quel_evolue : est l'équivalent des grandeurs évoluées: coor_ddl_enum et tens_ddl_enum
// permet aux utilisateurs d'accèder à un stockage transitoire contenant "que" les grandeurs évoluées
List_io <TypeQuelconque > li_equi_Quel_evolue; // non scalaires
// tab_equi_Coor(j) contient un Coordonnee équivalent à coor_ddl_enum(j)
Tableau <List_io<TypeQuelconque >::iterator > tab_equi_Coor;
//tab_equi_tens(j) contient un tenseur équivalent à tens_ddl_enum(j)
Tableau <List_io<TypeQuelconque >::iterator > tab_equi_tens;
// un système d'adressage indirect pour le passage : tab_enu_etendu(i) <-> grandeur évoluée
Tableau <int> posi_ddl_enum; // posi_ddl_enum(i) donne la position de tab_enu_etendu(i)
// dans le tableau :
// si scalaire : dans le tableau val_ddl_enum ->val_ddl_enum(posi_ddl_enum(i))
// si Coordonnées : dans le tableau coor_ddl_enum -> coor_ddl_enum(posi_ddl_enum(i))
// ici il s'agira de tous les ddl de la même famille,
// et c'est num_dans_coor qui permet de trouver la position
// si Tenseur : dans le tableau tens_ddl_enum -> tens_ddl_enum(posi_ddl_enum(i))
// et c'est ind_tens qui permettra de trouver les indices
// un système d'adressage indirect pour le passage : nom_variables(j) <-> grandeur évoluée
// tab_enu_etendu(i) correspond à nom_variables(index_enu_etendu(i))
Tableau <int> index_enu_etendu;
// .... dans le cas d'une grandeur quelconque
// pour les grandeurs quelconques, l'utilisateur doit transmettre le numéro d'ordre correspondant à l'équivalence
// du ddl_etendu, du coup on ne s'occupe pas de gérer les numéros d'ordre pour les grandeurs quelconques
// un système d'adressage indirect pour le passage : nom_variables(j) <-> grandeur quelconque
// tab_enu_quelconque(i) correspond à nom_variables(index_enu_quelconque(i))
Tableau <int> index_enu_quelconque;
// stockage des tailles qu'ont les différents tableaux associés
Tableau <int> tailles_tab; // tailles_tab(1) -> nb de scalaires
// (2) -> nb de Coordonnee
// (3) -> nb de tenseur
// (4) -> nb de grandeurs quelconques
// ----- fin grandeurs évoluées y compris les grandeurs quelconques-------
// ces deux tableaux permettent d'appeler la méthode Valeur(..
// un booléen pour noter l'équivalence parfaite ou non
bool equivalence_nom_enu_etendu_et_enu_quelconque;
// un tableau intermédiaire qui sert pour Valeur(Tableau <Ddl_etendu> ...
// c-a-d pour les variables non globales
Tableau <double > x_x_i;
// un tableau intermédiaire qui sert pour toutes les variables globales
Tableau <double > x_glob;
int depend_M; // indicateur permettant de connaître rapidement si
// la fonction dépend de la position courante d'un point M
// 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
int depend_Mt; // idem pour le temps t
int depend_M0; // idem pour le temps 0
bool depend_temps; // indicateur permettant de connaître rapidement si
// la fonction dépend du temps ou non
// ----- controle de la sortie des informations: utilisé par les classes dérivées
int permet_affichage; // pour permettre un affichage spécifique dans les méthodes, pour les erreurs et warning
//-------------------------------------------------------------------------------
// METHODES PROTEGEES :
// ramène true si les variables de la classe mère sont complèté
bool Complet_var() const;
// définit le paramètre depend_M en fonction des nom_variables
void Definition_depend_M();
// définit le paramètre depend_temps en fonction des nom_variables
void Definition_depend_temps();
// construction à partir des noms de variables, des tableaux tab_enu_etendu et
// tab_enu_quelconque
// void Construction_enu_etendu_et_quelconque();
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
void Construction_index_conteneurs_evoluees();
// Passage des infos variables évoluées en tableau de réels
// I/O : d
Tableau <double > & 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 = NULL
,const Tableau <int> * t_num_ordre = NULL);
// idem, mais via les listes
// val_ddl_enum(k) correspond à li_evolue_scalaire de rang i
Tableau <double > & 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 = NULL
,const Tableau <int> * t_num_ordre = NULL);
// 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 Mise_a_jour_variables_globales_interne();
// 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
// ****** fonction a priori dangereuse, à éviter , pour l'instant ne sert pas !! ****
double Val_avec_nbArgVariable(double x,...);
// 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& Transfert_info(const Fonction_nD& elt);
// affichage des données internes, utilisée par les fonctions dérivées
// niveau donne le degré d'affichage
void Affiche_interne(int niveau) const;
//------ 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 Lect_base_info(ifstream& ent,const int cas);
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Ecrit_base_info(ofstream& sort,const int cas);
// sortie du schemaXML: en fonction de enu
void SchemXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu);
// lecture d'une ou plusieurs variables
// peut-être appelée plusieurs fois,
// stockage des infos dans Fonction_nD
void Lecture_variables(string& nom_lu,UtilLecture * entreePrinc);
// méthode pour savoir si le nom_lu est un mot clé relatif à la lecture de variables
bool Est_relatif_a_lecture_variable(string& nom_lu)
{if ( (nom_lu == "un_argument=")
|| (nom_lu == "deb_list_var_")
)
return true;
else return false;
};
// affichage des variables de la fonction, dépend du niveau d'impression
void Affichage_variables() const;
// récupération des valeurs des variables globales et stockage dans le tableau
// interne x_glob
void Recup_Grandeurs_globales();
private :
// un tableau intermédiaire, en général vide, mais qui sert si on utilise
// la méthode Val_avec_nbArgVariable
Tableau <double >* xinter=NULL;
};
/// @} // end of group
#endif