// 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/>.

/************************************************************************
 *     DATE:        30/05/2004                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:  classes qui permettent de définir des identificateurs de   *
 *           grandeurs particulières héritants du TypeQuelconque.       *
 *           Ces idendificateurs sont prévue en particulier pour gérer  *
 *           les sorties de résultats.                                  *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *                                                                $     *
 ************************************************************************/
#ifndef TYPE_QUELCONQUE_PARTICULIER_H
#define TYPE_QUELCONQUE_PARTICULIER_H

#include <string.h>
#include "EnumTypeGrandeur.h"

#include "List_io.h"
#include <iomanip>
#include <algorithm>
#include "TypeQuelconque.h"
#include "Tenseur.h"
#include "NevezTenseur.h"
#include "Tableau_T.h"
#include "Tableau2_T.h"
#include "Ddl_etendu.h"
#include "Fonction_nD.h"
#include "Base.h"


    /** @defgroup Les_grandeurs_particulieres Les_grandeurs_particulieres
    *
    *     BUT:  classes qui permettent de définir des identificateurs de
    *           grandeurs particulières héritants du TypeQuelconque.
    *           Ces idendificateurs sont prévue en particulier pour gérer
    *           les sorties de résultats.
    *
    *
    * \author     Gérard Rio
    * \version    1.0
    * \date       30/05/2004
    * \brief      Définition des grandeurs particulières.
    *
    */

    //--------------------------------------------------------------------------------
    //| définition des fonctions permettant la création de la grandeur particulière  |
    //| en lecture  après la lecture d'un énuméré de type particulier                |
    //--------------------------------------------------------------------------------
    
 TypeQuelconque::Grandeur* NevezGrandeurParticuliereEnLecture(EnuTypeQuelParticulier enu,istream & ent); 
 
    
    
/// @addtogroup Les_grandeurs_particulieres
///  @{
///

///----------------------------------------------------------------
/// grandeur par défaut: TypeQuelconque::Grandeur::Grandeur_defaut|
///----------------------------------------------------------------
    class Grandeur_defaut : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_defaut & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_defaut & a) ;
         public: 
         // constructeur par défaut
         Grandeur_defaut() {};
         ~Grandeur_defaut() {};
         TypeQuelconque::Grandeur* New_idem_grandeur() const; // ramène une grandeur identique, créée 
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // ***** ici toutes ces opérations sont illicites !!! ********
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val);
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const; // sortie de la grandeur brut sur sort
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return RIEN_TYPEGRANDEUR;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() 
                  const{return RIEN_TYPE_QUELCONQUE_PARTICULIER;};
         // change de repère de la grandeur si nécessaire 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma) {};
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///

//------------------------------------------------------------------
/// grandeur TenseurHH: TypeQuelconque::Grandeur::Grandeur_TenseurHH|
//------------------------------------------------------------------
    class Grandeur_TenseurHH : public TypeQuelconque::Grandeur 
       { friend class Tab_Grandeur_TenseurHH;friend class  Tab2_Grandeur_TenseurHH;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_TenseurHH & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_TenseurHH & a); 
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Grandeur_TenseurHH();
         // constructeur légal
         Grandeur_TenseurHH(const TenseurHH& tens): ptTens(NevezTenseurHH(tens)) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_TenseurHH(istream & ent);
         // constructeur de copie
         Grandeur_TenseurHH(const Grandeur_TenseurHH& a): ptTens(NevezTenseurHH(*a.ptTens)) {};
         // destructeur
         ~Grandeur_TenseurHH();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_TenseurHH(*ptTens);}; 
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_TenseurHH & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         void operator+= (const Grandeur_TenseurHH& aa) {(*ptTens) += (*(aa.ptTens));};
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         void operator-= (const Grandeur_TenseurHH& aa) {(*ptTens) -= (*(aa.ptTens));};
         // Surcharge de l'operateur *=
         void operator*= (double val) {*ptTens *= val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {*ptTens /= val;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const ;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURHH;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TENSEURHH;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {ptTens->Inita(0.);};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         TenseurHH* ConteneurTenseur() const {return ptTens;};
         // la référence est un peu plus sur (il est toujours possible de faire un delete sur un pointeur de ref
         // mais c'est plus difficile de le faire en se trompant ! enfin j'espère)
         TenseurHH& RefConteneurTenseur() const {return *ptTens;};
         
         protected:
         TenseurHH* ptTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------
/// grandeur TenseurBB: TypeQuelconque::Grandeur::Grandeur_TenseurBB|
//------------------------------------------------------------------
    class Grandeur_TenseurBB : public TypeQuelconque::Grandeur 
       { friend class Tab_Grandeur_TenseurBB;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_TenseurBB & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_TenseurBB & a); 
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Grandeur_TenseurBB();
         // constructeur légal
         Grandeur_TenseurBB(const TenseurBB& tens): ptTens(NevezTenseurBB(tens)) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_TenseurBB(istream & ent);
         // constructeur de copie
         Grandeur_TenseurBB(const Grandeur_TenseurBB& a): ptTens(NevezTenseurBB(*a.ptTens)) {};
         // destructeur
         ~Grandeur_TenseurBB();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_TenseurBB(*ptTens);}; 
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_TenseurBB & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         void operator+= (const Grandeur_TenseurBB& aa) {(*ptTens) += (*(aa.ptTens));};
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         void operator-= (const Grandeur_TenseurBB& aa) {(*ptTens) -= (*(aa.ptTens));};
         // Surcharge de l'operateur *=
         void operator*= (double val) {*ptTens *= val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {*ptTens /= val;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const ;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURBB;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TENSEURBB;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {ptTens->Inita(0.);};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         TenseurBB* ConteneurTenseur() const {return ptTens;};
         // la référence est un peu plus sur (il est toujours possible de faire un delete sur un pointeur de ref
         // mais c'est plus difficile de le faire en se trompant ! enfin j'espère)
         TenseurBB& RefConteneurTenseur() const {return *ptTens;};
          
         protected:
         TenseurBB* ptTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------
/// grandeur TenseurBH: TypeQuelconque::Grandeur::Grandeur_TenseurBH|
//------------------------------------------------------------------
    class Grandeur_TenseurBH : public TypeQuelconque::Grandeur 
       { friend class Tab_Grandeur_TenseurBH;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_TenseurBH & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_TenseurBH & a); 
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Grandeur_TenseurBH();
         // constructeur légal
         Grandeur_TenseurBH(const TenseurBH& tens): ptTens(NevezTenseurBH(tens)) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_TenseurBH(istream & ent);
         // constructeur de copie
         Grandeur_TenseurBH(const Grandeur_TenseurBH& a): ptTens(NevezTenseurBH(*a.ptTens)) {};
         // destructeur
         ~Grandeur_TenseurBH();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_TenseurBH(*ptTens);}; 
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_TenseurBH & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         void operator+= (const Grandeur_TenseurBH& aa) {(*ptTens) += (*(aa.ptTens));};
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         void operator-= (const Grandeur_TenseurBH& aa) {(*ptTens) -= (*(aa.ptTens));};
         // Surcharge de l'operateur *=
         void operator*= (double val) {*ptTens *= val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {*ptTens /= val;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const ;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURBH;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TENSEURBH;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta, const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {ptTens->Inita(0.);};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         // le pb avec le pointeur c'est que l'on peut faire un delete en erreur
         TenseurBH* ConteneurTenseur() const {return ptTens;};
         // la référence est un peu plus sur (il est toujours possible de faire un delete sur un pointeur de ref
         // mais c'est plus difficile de le faire en se trompant ! enfin j'espère)
         TenseurBH& RefConteneurTenseur() const {return *ptTens;};
         
         protected:
         TenseurBH* ptTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------
/// grandeur TenseurHB: TypeQuelconque::Grandeur::Grandeur_TenseurHB|
//------------------------------------------------------------------
    class Grandeur_TenseurHB : public TypeQuelconque::Grandeur 
       { friend class Tab_Grandeur_TenseurHB;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_TenseurHB & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_TenseurHB & a); 
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Grandeur_TenseurHB();
         // constructeur légal
         Grandeur_TenseurHB(const TenseurHB& tens): ptTens(NevezTenseurHB(tens)) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_TenseurHB(istream & ent);
         // constructeur de copie
         Grandeur_TenseurHB(const Grandeur_TenseurHB& a): ptTens(NevezTenseurHB(*a.ptTens)) {};
         // destructeur
         ~Grandeur_TenseurHB();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_TenseurHB(*ptTens);}; 
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_TenseurHB & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         void operator+= (const Grandeur_TenseurHB& aa) {(*ptTens) += (*(aa.ptTens));};
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         void operator-= (const Grandeur_TenseurHB& aa) {(*ptTens) -= (*(aa.ptTens));};
         // Surcharge de l'operateur *=
         void operator*= (double val) {*ptTens *= val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {*ptTens /= val;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const ;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURHB;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TENSEURHB;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {ptTens->Inita(0.);};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         // le pb avec le pointeur c'est que l'on peut faire un delete en erreur
         TenseurHB* ConteneurTenseur() const {return ptTens;};
         // la référence est un peu plus sur (il est toujours possible de faire un delete sur un pointeur de ref
         // mais c'est plus difficile de le faire en se trompant ! enfin j'espère)
         TenseurHB& RefConteneurTenseur() const {return *ptTens;};
         
         protected:
         TenseurHB* ptTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de TenseurHH: TypeQuelconque::Grandeur::Tab_Grandeur_TenseurHH|
/// tous les tenseurs doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------
    class Tab_Grandeur_TenseurHH : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_TenseurHH & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_TenseurHH & a);
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Tab_Grandeur_TenseurHH();
         // constructeur légal
         // nb indique le nombre de tenseur
         Tab_Grandeur_TenseurHH( TenseurHH& tens,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_TenseurHH(istream & ent);
         // constructeur de copie
         Tab_Grandeur_TenseurHH(const Tab_Grandeur_TenseurHH& a) ;
         // destructeur
         ~Tab_Grandeur_TenseurHH();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_TenseurHH(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_TenseurHH & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURHH;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_TENSEURHH;};
         // acces au tenseur de numéro i en lecture écriture
         TenseurHH& operator () ( int i)const {return (*(tabTens(i)->ptTens));};
         // ramène la grandeur_Tenseur associée
         const Grandeur_TenseurHH& Grandeur_TenseurHH_associee(int i) const {return *(tabTens(i));};
         // ramène la dimension du tableau de tenseur
         int Taille() const {return tabTens.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut de Grandeur_TenseurHH, d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_TenseurHH* > tabTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de TenseurBH: TypeQuelconque::Grandeur::Tab_Grandeur_TenseurBH|
/// tous les tenseurs doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------
    class Tab_Grandeur_TenseurBH : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_TenseurBH & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_TenseurBH & a);
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Tab_Grandeur_TenseurBH();
         // constructeur légal
         // nb indique le nombre de tenseur
         Tab_Grandeur_TenseurBH( TenseurBH& tens,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_TenseurBH(istream & ent);
         // constructeur de copie
         Tab_Grandeur_TenseurBH(const Tab_Grandeur_TenseurBH& a) ;
         // destructeur
         ~Tab_Grandeur_TenseurBH();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_TenseurBH(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_TenseurBH & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURBH;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_TENSEURBH;};
         // acces au tenseur de numéro i en lecture écriture
         TenseurBH& operator () ( int i)const {return (*(tabTens(i)->ptTens));};
         // ramène la grandeur_Tenseur associée
         const Grandeur_TenseurBH& Grandeur_TenseurBH_associee(int i) const {return *(tabTens(i));};
         // ramène la dimension du tableau de tenseur
         int Taille() const {return tabTens.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut de Grandeur_TenseurBH, d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_TenseurBH* > tabTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de TenseurBB: TypeQuelconque::Grandeur::Tab_Grandeur_TenseurBB|
/// tous les tenseurs doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------
    class Tab_Grandeur_TenseurBB : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_TenseurBB & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_TenseurBB & a);
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Tab_Grandeur_TenseurBB();
         // constructeur légal
         // nb indique le nombre de tenseur
         Tab_Grandeur_TenseurBB( TenseurBB& tens,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_TenseurBB(istream & ent);
         // constructeur de copie
         Tab_Grandeur_TenseurBB(const Tab_Grandeur_TenseurBB& a) ;
         // destructeur
         ~Tab_Grandeur_TenseurBB();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_TenseurBB(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_TenseurBB & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURBB;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_TENSEURBB;};
         // acces au tenseur de numéro i en lecture écriture
         TenseurBB& operator () ( int i)const {return (*(tabTens(i)->ptTens));};
         // ramène la grandeur_Tenseur associée
         const Grandeur_TenseurBB& Grandeur_TenseurBB_associee(int i) const {return *(tabTens(i));};
         // ramène la dimension du tableau de tenseur
         int Taille() const {return tabTens.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut de Grandeur_TenseurBB, d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_TenseurBB* > tabTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de TenseurHB: TypeQuelconque::Grandeur::Tab_Grandeur_TenseurHB
/// tous les tenseurs doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------
    class Tab_Grandeur_TenseurHB : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_TenseurHB & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_TenseurHB & a);
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Tab_Grandeur_TenseurHB();
         // constructeur légal
         // nb indique le nombre de tenseur
         Tab_Grandeur_TenseurHB( TenseurHB& tens,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_TenseurHB(istream & ent);
         // constructeur de copie
         Tab_Grandeur_TenseurHB(const Tab_Grandeur_TenseurHB& a) ;
         // destructeur
         ~Tab_Grandeur_TenseurHB();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_TenseurHB(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_TenseurHB & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURHB;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_TENSEURHB;};
         // acces au tenseur de numéro i en lecture écriture
         TenseurHB& operator () ( int i)const {return (*(tabTens(i)->ptTens));};
         // ramène la grandeur_Tenseur associée
         const Grandeur_TenseurHB& Grandeur_TenseurHB_associee(int i) const {return *(tabTens(i));};
         // ramène la dimension du tableau de tenseur
         int Taille() const {return tabTens.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut de Grandeur_TenseurHB, d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_TenseurHB* > tabTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------------------
/// grandeur un tableau à 2 dim de TenseurHH: TypeQuelconque::Grandeur::Tab2_Grandeur_TenseurHH
//------------------------------------------------------------------------------------------------
    class Tab2_Grandeur_TenseurHH : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab2_Grandeur_TenseurHH & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab2_Grandeur_TenseurHH & a);
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // ptTens défini, donc -> erreur
         Tab2_Grandeur_TenseurHH();
         // constructeur légal
         // nb1,nb2 indique la dimension du tableau(nb1,nb2) de tenseur
         Tab2_Grandeur_TenseurHH( TenseurHH& tens,int nb1, int nb2);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab2_Grandeur_TenseurHH(istream & ent);
         // constructeur de copie
         Tab2_Grandeur_TenseurHH(const Tab2_Grandeur_TenseurHH& a) ;
         // destructeur
         ~Tab2_Grandeur_TenseurHH();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab2_Grandeur_TenseurHH(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab2_Grandeur_TenseurHH & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val);
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return TENSEURHH;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU2_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU2_TENSEURHH;};
         // acces au tenseur de numéro i,j en lecture écriture
         TenseurHH& operator () ( int i,int j) const {return (*(tabTens(i,j)->ptTens));};
         // ramène la grandeur_Tenseur associée
         const Grandeur_TenseurHH& Grandeur_TenseurHH_associee(int i, int j) const {return *(tabTens(i,j));};
         // changement de taille -> n :
         // si ni < taille_actuelle --> les taille_actuelle - ni sont supprimé
         // si ni > taille_actuelle --> le dernier élément existant est dupliqué ni-taille_actuelle fois,
         void Change_taille(int n1, int n2);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut de Grandeur_TenseurHH, d'où la nécessité d'une construction
         // en deux temps !!
         Tableau2 <Grandeur_TenseurHH* > tabTens;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//-----------------------------------------------------------------------------
/// grandeur scalaire réel: TypeQuelconque::Grandeur::Grandeur_scalaire_double
//-----------------------------------------------------------------------------
    class Grandeur_scalaire_entier : public TypeQuelconque::Grandeur
       { friend  class Tab_Grandeur_scalaire_entier;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_scalaire_entier & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_scalaire_entier & a);
         public: 
         // constructeur par défaut:
         Grandeur_scalaire_entier();
         // constructeur légal
         Grandeur_scalaire_entier(const double& va): val(va) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_scalaire_entier(istream & ent);
         // constructeur de copie
         Grandeur_scalaire_entier(const Grandeur_scalaire_entier& a): val(a.val) {};
         // destructeur
         ~Grandeur_scalaire_entier(){};
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_scalaire_entier(val);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_scalaire_entier & a)
                              {val=a.val;return *this;}; // surcharge d'affectation
         Grandeur & operator = ( const double& b) {val=b;return *this;}; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double x) {val*=x;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double x) {val/=x;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const {if(num==1) return val; else return 0.;};
         int NbMaxiNumeroOrdre() const {return 1;}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const
           {sort <<" "<< setw(nbcar)<< setprecision(nbcar)  << val << " ";};
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return SCALAIRE;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_SCALAIRE_ENTIER;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& ,const Mat_pleine& ){};
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> val ;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort) const { sort <<" "<< val << " "; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut(){val = 0.;};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         int* ConteneurEntier() {return &val;};
         
         protected:
         int val;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//---------------------------------------------------------------------------------------------
/// grandeur tableau de scalaires entière: TypeQuelconque::Grandeur::Tab_Grandeur_scalaire_entière
//---------------------------------------------------------------------------------------------
    class Tab_Grandeur_scalaire_entier : public TypeQuelconque::Grandeur
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_scalaire_entier & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_scalaire_entier & a);
         public: 
         // constructeur par défaut:
         Tab_Grandeur_scalaire_entier();
         // constructeur légal
         Tab_Grandeur_scalaire_entier(const Tableau <int>& tab_va);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_scalaire_entier(istream & ent);
         // constructeur de copie
         Tab_Grandeur_scalaire_entier(const Tab_Grandeur_scalaire_entier& a): tab_val(a.tab_val) {};
         // destructeur
         ~Tab_Grandeur_scalaire_entier(){};
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_scalaire_entier(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tableau <int>& b) ; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double x);
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double x);
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const;
         int NbMaxiNumeroOrdre() const {return tab_val.Taille();}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const ;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return SCALAIRE;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_SCALAIRE_DOUBLE;};
         // ramène un Grandeur_scalaire_entier associé
         Grandeur_scalaire_entier& Grandeur_scalaire_associee(int i) {return tab_val(i);};
         // ramène la dimension du tableau 
         int Taille() const {return tab_val.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& ,const Mat_pleine& ){};
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { tab_val.Entree(ent);return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { tab_val.Sortir_sansRet(sort); return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         Tableau <Grandeur_scalaire_entier>& ConteneurTabEntier() {return tab_val;};
         // acces au double de numéro i en lecture écriture
         int& operator () ( const int i) {return tab_val(i).val;};
         
         protected:
         Tableau <Grandeur_scalaire_entier> tab_val;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//-----------------------------------------------------------------------------
/// grandeur scalaire réel: TypeQuelconque::Grandeur::Grandeur_scalaire_double
//-----------------------------------------------------------------------------
    class Grandeur_scalaire_double : public TypeQuelconque::Grandeur 
       { friend  class Tab_Grandeur_scalaire_double;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_scalaire_double & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_scalaire_double & a); 
         public: 
         // constructeur par défaut:
         Grandeur_scalaire_double();
         // constructeur légal
         Grandeur_scalaire_double(const double& va): val(va) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_scalaire_double(istream & ent);
         // constructeur de copie
         Grandeur_scalaire_double(const Grandeur_scalaire_double& a): val(a.val) {};
         // destructeur
         ~Grandeur_scalaire_double(){};
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_scalaire_double(val);}; 
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_scalaire_double & a)
                              {val=a.val;return *this;}; // surcharge d'affectation
         Grandeur & operator = ( const double& b) {val=b;return *this;}; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double x) {val*=x;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double x) {val/=x;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const {if(num==1) return val; else return 0.;};
         int NbMaxiNumeroOrdre() const {return 1;}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const
           {sort <<" "<< setw(nbcar)<< setprecision(nbcar)  << val << " ";};
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return SCALAIRE;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_SCALAIRE_DOUBLE;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma){};
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> val ;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort) const { sort <<" "<< val << " "; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut(){val = 0.;};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         double* ConteneurDouble() {return &val;};
         // idem en const
         double ContDouble() const {return val;};
         
         protected:
         double val;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//---------------------------------------------------------------------------------------------
/// grandeur tableau de scalaires réel: TypeQuelconque::Grandeur::Tab_Grandeur_scalaire_double
//---------------------------------------------------------------------------------------------
    class Tab_Grandeur_scalaire_double : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_scalaire_double & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_scalaire_double & a); 
         public: 
         // constructeur par défaut:
         Tab_Grandeur_scalaire_double();
         // constructeur légal
         Tab_Grandeur_scalaire_double(const Tableau <double>& tab_va);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_scalaire_double(istream & ent);
         // constructeur de copie
         Tab_Grandeur_scalaire_double(const Tab_Grandeur_scalaire_double& a): tab_val(a.tab_val) {};
         // destructeur
         ~Tab_Grandeur_scalaire_double(){};
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_scalaire_double(*this);}; 
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tableau <double>& b) ; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double x);
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double x);
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const;
         int NbMaxiNumeroOrdre() const {return tab_val.Taille();}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const ;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return SCALAIRE;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_SCALAIRE_DOUBLE;};
         // ramène un Grandeur_scalaire_double associé
         Grandeur_scalaire_double& Grandeur_scalaire_associee(int i) {return tab_val(i);};
         // ramène la dimension du tableau 
         int Taille() const {return tab_val.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma){};
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { tab_val.Entree(ent);return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { tab_val.Sortir_sansRet(sort); return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         Tableau <Grandeur_scalaire_double>& ConteneurTabDouble() {return tab_val;};
         // acces au double de numéro i en lecture écriture
         double& operator () ( const int i) {return tab_val(i).val;};
         
         protected:
         Tableau <Grandeur_scalaire_double> tab_val;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//-----------------------------------------------------------------------------
/// grandeur vecteur: TypeQuelconque::Grandeur::Grandeur_vecteur
//-----------------------------------------------------------------------------
    class Grandeur_Vecteur : public TypeQuelconque::Grandeur
       { friend class Tab_Grandeur_Vecteur;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_Vecteur & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_Vecteur & a);
         public:
         // constructeur par défaut:
         Grandeur_Vecteur();
         // constructeur légal
         Grandeur_Vecteur(const Vecteur& v): ve(v) {}; // à partir d'un vecteur
         Grandeur_Vecteur(int n): ve(n) {}; // à partir d'une dimension
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_Vecteur(istream & ent);
         // constructeur de copie
         Grandeur_Vecteur(const Grandeur_Vecteur& a): ve(a.ve) {};
         // destructeur
         ~Grandeur_Vecteur(){};
         // ramène une grandeur identique, créée
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_Vecteur(ve);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Vecteur& b) {ve=b;return *this;}; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double val) {ve*=val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {ve/=val;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const;
         int NbMaxiNumeroOrdre() const {return ve.Taille();}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const
           {sort <<" "<< setprecision(nbcar) << ve; };
         // ramène le type de grandeur associée de la grandeur de base, car
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return VECTEUR;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_VECTEUR;};
         // change de repère de la grandeur
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture
         istream & Lecture_grandeur(istream & ent)  { ent >> ve ;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort <<" " << ve << " "; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {ve.Zero();};
         // ----------- méthodes spécifiques d'acces à la grandeur -------------
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         Vecteur* ConteneurVecteur() {return &ve;};
         // idem en const
         const Vecteur& ConteneurVecteur_const() const {return ve;};

         protected:
         Vecteur ve;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de Vecteur: TypeQuelconque::Grandeur::Tab_Grandeur_Vecteur|
/// tous les Vecteurs  doivent avoir la même dimension !! pour la routine GrandeurNumOrdre ?? à voir
//------------------------------------------------------------------------------------
    class Tab_Grandeur_Vecteur : public TypeQuelconque::Grandeur
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_Vecteur & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_Vecteur & a);
         public:
         // constructeur par défaut: ne doit pas être utilisé
         Tab_Grandeur_Vecteur();
         // constructeur légal
         // nb indique le nombre de Vecteur
         Tab_Grandeur_Vecteur( Vecteur & vect,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_Vecteur(istream & ent);
         // constructeur de copie
         Tab_Grandeur_Vecteur(const Tab_Grandeur_Vecteur& a) ;
         // destructeur
         ~Tab_Grandeur_Vecteur();
         // ramène une grandeur identique, créée
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_Vecteur(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_Vecteur & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return VECTEUR;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_VECTEUR;};
         // acces au Vecteur de numéro i en lecture écriture
         Vecteur& operator () ( int i)const {return (tabVe(i)->ve);};
         // ramène la grandeur_Vecteur associée
         const Grandeur_Vecteur& Grandeur_Vecteur_associee(int i) const {return *(tabVe(i));};
         // ramène la dimension du tableau de Vecteur
         int Taille() const {return tabVe.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
        
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut de Grandeur_Vecteur, d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_Vecteur* > tabVe;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//-----------------------------------------------------------------------------
/// grandeur coordonnée: TypeQuelconque::Grandeur::Grandeur_coordonnee
//-----------------------------------------------------------------------------
    class Grandeur_coordonnee : public TypeQuelconque::Grandeur 
       { friend class Tab_Grandeur_Coordonnee;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_coordonnee & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_coordonnee & a); 
         public: 
         // constructeur par défaut:
         Grandeur_coordonnee();
         // constructeur légal
         Grandeur_coordonnee(const Coordonnee& v): co(v) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_coordonnee(istream & ent);
         // constructeur de copie
         Grandeur_coordonnee(const Grandeur_coordonnee& a): co(a.co) {};
         // destructeur
         ~Grandeur_coordonnee(){};
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_coordonnee(co);}; 
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Coordonnee& b) {co=b;return *this;}; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double val) {co*=val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {co/=val;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const;
         int NbMaxiNumeroOrdre() const {return co.Dimension();}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const
           {sort <<" "<< setprecision(nbcar) ; co.Affiche(sort,nbcar) ;};
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return COORDONNEE;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_COORDONNEE;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> co ;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort <<" " << co << " "; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {co.Zero();};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         Coordonnee* ConteneurCoordonnee() {return &co;};
         // idem en const
         const Coordonnee& ConteneurCoordonnee_const() const {return co;};
         
         protected:
         Coordonnee co;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de Coordonnee: TypeQuelconque::Grandeur::Tab_Grandeur_CoordonneeHH
/// tous les coordonnees doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------
    class Tab_Grandeur_Coordonnee : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_Coordonnee & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_Coordonnee & a);
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // co défini, donc -> erreur (en fait ce n'est sûr, mais on fait comme pour les tenseurs)
         Tab_Grandeur_Coordonnee();
         // constructeur légal
         // nb indique le nombre de Coordonnee
         Tab_Grandeur_Coordonnee( Coordonnee & coor,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_Coordonnee(istream & ent);
         // constructeur de copie
         Tab_Grandeur_Coordonnee(const Tab_Grandeur_Coordonnee& a) ;
         // destructeur
         ~Tab_Grandeur_Coordonnee();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_Coordonnee(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_Coordonnee & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return COORDONNEE;}; 
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_COORDONNEE;};
         // acces au Coordonnee de numéro i en lecture écriture
         Coordonnee& operator () ( int i)const {return (tabCoor(i)->co);};
         // ramène la grandeur_Coordonnee associée
         const Grandeur_coordonnee& Grandeur_Coordonnee_associee(int i) const {return *(tabCoor(i));};
         // ramène la dimension du tableau de Coordonnee
         int Taille() const {return tabCoor.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut de Grandeur_coordonnee, d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_coordonnee* > tabCoor;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//-------------------------------------------------------------------------------
/// grandeur Ddl_etendu: TypeQuelconque::Grandeur::Grandeur_Ddl_etendu
//-------------------------------------------------------------------------------
    class Grandeur_Ddl_etendu : public TypeQuelconque::Grandeur
       { friend class Tab_Grandeur_Ddl_etendu;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_Ddl_etendu & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_Ddl_etendu & a);
         public: 
         // constructeur par défaut:
         Grandeur_Ddl_etendu();
         // constructeur légal
         Grandeur_Ddl_etendu(const Ddl_etendu& v,const string& nom): co(v) ,nom_ref(nom){};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_Ddl_etendu(istream & ent);
         // constructeur de copie
         Grandeur_Ddl_etendu(const Grandeur_Ddl_etendu& a): co(a.co),nom_ref(a.nom_ref) {};
         // destructeur
         ~Grandeur_Ddl_etendu(){};
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_Ddl_etendu(co,nom_ref);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_Ddl_etendu& b)
            {co=b.co;nom_ref=b.nom_ref; return *this;}; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double val) {co*=val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {co/=val;};
         // récup du nom de référence
         virtual const string* Nom_ref() const {return &nom_ref;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const
          {if (num == 1) {return co.ConstValeur();} else {return 0.;}};
         int NbMaxiNumeroOrdre() const {return 1;}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const
           {sort <<" "<< setprecision(nbcar) << co.ConstValeur()<<" " ;};
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return SCALAIRE_DOUBLE;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_DDL_ETENDU;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma) // a priori on ne fait rien sur la grandeur scalaire
          {};
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> nom_ref >> co ;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort <<" " << nom_ref <<" " << co << " "; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {co.Valeur()=0.;};
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         Ddl_etendu* ConteneurDdl_etendu() {return &co;};
         void Change_nom_ref(const string& nom) {nom_ref = nom;};
         
         protected:
         Ddl_etendu co;
         string nom_ref; // un nom de référence qui permet ensuite de discriminer les différents conteneurs
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de Coordonnee: TypeQuelconque::Grandeur::Tab_Grandeur_CoordonneeHH
/// tous les coordonnees doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------
    class Tab_Grandeur_Ddl_etendu : public TypeQuelconque::Grandeur
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_Ddl_etendu & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_Ddl_etendu & a);
         public: 
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // co défini, donc -> erreur (en fait ce n'est sûr, mais on fait comme pour les tenseurs)
         Tab_Grandeur_Ddl_etendu();
         // constructeur légal
         // nb indique le nombre de Ddl_etendu
         Tab_Grandeur_Ddl_etendu( Grandeur_Ddl_etendu & coor,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_Ddl_etendu(istream & ent);
         // constructeur de copie
         Tab_Grandeur_Ddl_etendu(const Tab_Grandeur_Ddl_etendu& a) ;
         // destructeur
         ~Tab_Grandeur_Ddl_etendu();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_Ddl_etendu(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_Ddl_etendu & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return SCALAIRE_DOUBLE;}; // vecteur à 1 élément
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_DDL_ETENDU;};
         // acces au Coordonnee de numéro i en lecture écriture
         Ddl_etendu& operator () ( int i)const {return (tabDdlEte(i)->co);};
         // ramène la Grandeur_Ddl_etendu associée
         const Grandeur_Ddl_etendu& Grandeur_Ddl_etendu_associee(int i) const {return *(tabDdlEte(i));};
         // ramène la dimension du tableau
         int Taille() const {return tabDdlEte.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma) {}; // ne fait rien ici car ce sont des scalaires uniques
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut , d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_Ddl_etendu* > tabDdlEte;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//-------------------------------------------------------------------------------
/// grandeur vecteur nommé : TypeQuelconque::Grandeur::Grandeur_Vecteur_Nommer
///   contient un nom d'identificateur (utilisé par exemple pour un nom de fonc
//-------------------------------------------------------------------------------
    class Grandeur_Vecteur_Nommer : public TypeQuelconque::Grandeur
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_Vecteur_Nommer & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_Vecteur_Nommer & a);
         public: 
         // constructeur par défaut:
         Grandeur_Vecteur_Nommer();
         // constructeur légal
         Grandeur_Vecteur_Nommer(const string & nom_ref_, const int taille,Fonction_nD * fct_ =NULL)
            : nom_ref(nom_ref_),fct(fct_)
              {v.Change_taille(taille);};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_Vecteur_Nommer(istream & ent);
         // constructeur de copie
         Grandeur_Vecteur_Nommer(const Grandeur_Vecteur_Nommer& a):
           nom_ref(a.nom_ref),v(a.v),fct(a.fct) {};
         // destructeur
         ~Grandeur_Vecteur_Nommer(){};
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_Vecteur_Nommer(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_Vecteur_Nommer& b)
             {v=b.v;nom_ref = b.nom_ref; fct=b.fct; return *this;}; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double val) {v *=val;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) {v /=val;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const
          {if ((num <= v.Taille())&&(num>0)) {return v(num);} else {return 0.;}};
         // récup du nom de référence
         virtual const string* Nom_ref() const {return &nom_ref;};
         int NbMaxiNumeroOrdre() const {return v.Taille();}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car 
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return VECTEUR;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_VECTEUR_NOMMER;};
         // change de repère de la grandeur 
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma) // a priori on ne fait rien sur la grandeur vectoriel
          {};
         // lecture 
         istream & Lecture_grandeur(istream & ent)  { ent >> nom_ref >> v ;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort <<" " << nom_ref << " "<< v ; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut() {v.Zero();};
         // ----------- méthodes spécifiques d'acces à la grandeur -------------
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         Vecteur& ConteneurVecteur() {return v;};
         Fonction_nD * Fct() const {return fct;};
//         const string& Nom_vec() const {return nom_ref;};
         void Change_fonction_nD(Fonction_nD * fct_) {fct = fct_;};
        
         
       protected:
         Fonction_nD * fct; // la fonction nD qui permet le calcul du résultat stocké dans v
         // n'est pas forcément définit
         string nom_ref ; // un nom de référence qui permet de discriminer une même intégrale de fonction nD, ou une statistique par exemple
         // mais sur des volumes ou des ref différents
         Vecteur v;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//----------------------------------------------------------------------------------------------------------------
/// grandeur un tableau de Grandeur_Vecteur_Nommer: TypeQuelconque::Grandeur::Tab_Grandeur_Grandeur_Vecteur_Nommer
//----------------------------------------------------------------------------------------------------------------
    class Tab_Grandeur_Vecteur_Nommer : public TypeQuelconque::Grandeur
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_Vecteur_Nommer & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_Vecteur_Nommer & a);
         public:
         // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
         // co défini, donc -> erreur (en fait ce n'est sûr, mais on fait comme pour les tenseurs)
         Tab_Grandeur_Vecteur_Nommer();
         // constructeur légal
         // nb indique le nombre de Grandeur_Vecteur_Nommer
         Tab_Grandeur_Vecteur_Nommer( Grandeur_Vecteur_Nommer & grno,int nb);
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_Vecteur_Nommer(istream & ent);
         // constructeur de copie
         Tab_Grandeur_Vecteur_Nommer(const Tab_Grandeur_Vecteur_Nommer& a) ;
         // destructeur
         ~Tab_Grandeur_Vecteur_Nommer();
         // ramène une grandeur identique, créée
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_Vecteur_Nommer(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_Vecteur_Nommer & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const {return 0;};
         // ici c'est le maxi des vecteurs nommés * le nombre
         int NbMaxiNumeroOrdre() const {return 0;}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return VECTEUR;}; // vecteur à 1 élément
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_VECTEUR_NOMMER;};
         // acces au Grandeur_Vecteur_Nommer de numéro i en lecture écriture
         Grandeur_Vecteur_Nommer& operator () ( int i)const {return (*(tabVN(i)));};
         // ramène la Grandeur_Vecteur_Nommer associée
         const Grandeur_Vecteur_Nommer& Grandeur_Vecteur_Nommer_associee(int i) const {return *(tabVN(i));};
         // ramène la dimension du tableau
         int Taille() const {return tabVN.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma) {}; // ne fait rien ici car ce sont des scalaires uniques
         // lecture
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
        
         protected:
         // on utilise un tableau de pointeur et non de valeur car pour la construction il ne faut pas
         // utiliser le constructeur par défaut , d'où la nécessité d'une construction
         // en deux temps !!
         Tableau <Grandeur_Vecteur_Nommer* > tabVN;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------
/// grandeur BaseH: TypeQuelconque::Grandeur::Grandeur_BaseH
//------------------------------------------------------------------
    class Grandeur_BaseH : public TypeQuelconque::Grandeur
       { friend class Tab_Grandeur_BaseH;
         // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_BaseH & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_BaseH & a);
         public:
         // constructeur par défaut:
         Grandeur_BaseH(): baseH() {};
         // constructeur fonction du nombre de vecteur et de la dimension des vecteurs de base
         Grandeur_BaseH(int dim, int nb_vec ): baseH(dim,nb_vec) {};
         // constructeur légal
         Grandeur_BaseH(const BaseH& basH): baseH(basH) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_BaseH(istream & ent);
         // constructeur de copie
         Grandeur_BaseH(const Grandeur_BaseH& a): baseH(a.baseH) {};
         // destructeur
         ~Grandeur_BaseH() {};
         // ramène une grandeur identique, créée
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_BaseH(baseH);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_BaseH & a) // surcharge d'affectation
            {baseH = a.baseH; return *this; }
         Grandeur & operator = ( const BaseH & a) // surcharge d'affectation
            {baseH = a; return *this; }
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         void operator+= (const Grandeur_BaseH& aa);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         void operator-= (const Grandeur_BaseH& aa);
         // Surcharge de l'operateur *=
         void operator*= (double val);
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val);
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const ;
         // ramène le type de grandeur associée de la grandeur de base, car
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return BASE__H;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_BASE_H;};
         // change de repère de la grandeur
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         BaseH* ConteneurBaseH() {return &baseH;};
         // la référence est un peu plus sur (il est toujours possible de faire un delete sur un pointeur de ref
         // mais c'est plus difficile de le faire en se trompant ! enfin j'espère)
         const BaseH& RefConteneurBaseH() const {return baseH;};
        
         protected:
         BaseH baseH;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------
/// grandeur un tableau de Grandeur_BaseH: TypeQuelconque::Grandeur::Tab_Grandeur_BaseH
/// tous les coordonnees doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------
    class Tab_Grandeur_BaseH : public TypeQuelconque::Grandeur
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tab_Grandeur_BaseH & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tab_Grandeur_BaseH & a);
         public:
         // constructeur par défaut:
         Tab_Grandeur_BaseH(): tabBaseH() {};
         // constructeur légal
         // nb indique le nombre de Grandeur_BaseH
         Tab_Grandeur_BaseH( Grandeur_BaseH & baseH,int nb): tabBaseH(nb,baseH) {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Tab_Grandeur_BaseH(istream & ent);
         // constructeur de copie
         Tab_Grandeur_BaseH(const Tab_Grandeur_BaseH& a) : tabBaseH(a.tabBaseH) {};
         // destructeur
         ~Tab_Grandeur_BaseH() {};
         // ramène une grandeur identique, créée
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tab_Grandeur_BaseH(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Tab_Grandeur_BaseH & a) // surcharge d'affectation
           {tabBaseH = a.tabBaseH; };
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c) ;
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c) ;
         // Surcharge de l'operateur *=
         void operator*= (double val) ;
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val) ;
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const ;
         int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return BASE__H;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_BASE_H;};
         // acces au Grandeur_BaseH de numéro i en lecture écriture
         Grandeur_BaseH& operator () ( int i)const {return tabBaseH(i);};
         // ramène la grandeur_Grandeur_BaseH associée
         const Grandeur_BaseH& Grandeur_Grandeur_BaseH_associee(int i) const {return tabBaseH(i);};
         // ramène la dimension du tableau de Grandeur_BaseH
         int Taille() const {return tabBaseH.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma);
         // lecture
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
         // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();
        
         protected:
         // on utilise un tableau
         Tableau <Grandeur_BaseH > tabBaseH;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//------------------------------------------------------------------------------------------------------
/// grandeur scalaire double nommé + indice: TypeQuelconque::Grandeur::Grandeur_Double_Nommer_indicer
///   contient un nom d'identificateur et un indice qui est sensé resté fixe pendant les opérations
///  la seule grandeur qui varie c'est le double: c'est donc équivalent à un scalaire double
///  l'indice et le nom_ref, servent pour la gestion
//------------------------------------------------------------------------------------------------------
    class Grandeur_Double_Nommer_indicer : public TypeQuelconque::Grandeur
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Grandeur_Double_Nommer_indicer & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Grandeur_Double_Nommer_indicer & a);
         public:
         // constructeur par défaut:
         Grandeur_Double_Nommer_indicer();
         // constructeur légal
         Grandeur_Double_Nommer_indicer(const string & nom_ref_,const double& va,int indice_ = 1)
            : nom_ref(nom_ref_),val(va),indice(indice_)
              {};
         // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée
         // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction
         // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale
         Grandeur_Double_Nommer_indicer(istream & ent);
         // constructeur de copie
         Grandeur_Double_Nommer_indicer(const Grandeur_Double_Nommer_indicer& a):
           nom_ref(a.nom_ref),val(a.val),indice(a.indice) {};
         // destructeur
         ~Grandeur_Double_Nommer_indicer(){};
         // ramène une grandeur identique, créée
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Grandeur_Double_Nommer_indicer(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         
         // la surcharge d'affectation concerne toutes les grandeurs
         Grandeur & operator = ( const Grandeur & a); // surcharge d'affectation
         Grandeur & operator = ( const Grandeur_Double_Nommer_indicer& b)
             {val=b.val;nom_ref = b.nom_ref; indice=b.indice; return *this;}; // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         
         // >>>>> ici seul le double val est concerné !! <<<<<<<<<<<<<
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double x) {val *=x;};
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double x) {val /=x;};
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const {if(num==1) return val; else return 0.;};
         // récup du nom de référence
         virtual const string* Nom_ref() const {return &nom_ref;};
         int NbMaxiNumeroOrdre() const {return 1;}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const
           {sort <<" "<< setw(nbcar)<< setprecision(nbcar)  << val << " ";};
         // ramène le type de grandeur associée de la grandeur de base, car
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return SCALAIRE;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TYPE_SIMPLE;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_SCALAIRE_DOUBLE_NOMMER_INDICER;};
         // change de repère de la grandeur
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma) // a priori on ne fait rien sur la grandeur scalaire
          {};
         // lecture
         istream & Lecture_grandeur(istream & ent)
            { ent >> nom_ref >> val >> indice ;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const
            { sort <<" " << nom_ref << " "<< val << " " << indice ; return sort;};
         // ----------- méthodes spécifiques d'acces à la grandeur -------------
         // initialise la grandeur à une valeur par défaut: = 0 pour la grandeur double
         void InitParDefaut(){val = 0.;};

         // méthode spécifique d'acces à la grandeur
         // le fait d'utiliser une méthode permet de savoir qui passe par cette méthode
         double* ConteneurDouble() {return &val;};
         // idem en const
         double ContDouble() const {return val;};
         // l'indice
         int Indice_const() const {return indice;};
         int& Indice() {return indice;};

       protected:
         string nom_ref ; // un nom de référence
         double val; // valeur
         int indice;
        };
/// @}  // end of group

/// @addtogroup Les_grandeurs_particulieres
///  @{
///
                                    
//-----------------------------------------------------------------------------
/// un tableau de grandeur quelconque                                         
//-----------------------------------------------------------------------------
// on arrête le développement car c'est pas sûr que c'est utile en fait !!
    class Tableau_Grandeur_quelconque : public TypeQuelconque::Grandeur 
       { // surcharge de l'operator de lecture
         friend istream & operator >> (istream & ent, Tableau_Grandeur_quelconque & a);
         // surcharge de l'operator d'ecriture
         friend ostream & operator << (ostream & sort , const Tableau_Grandeur_quelconque & a); 
         public: 
         // constructeur par défaut:
         Tableau_Grandeur_quelconque();
         // constructeur légal: on recopie nfois
         // nb indique le nombre de grandeur quelconque que contient le tableau
         Tableau_Grandeur_quelconque(const TypeQuelconque::Grandeur& tg,int nb);
         // cas d'un tableau déjà connu
//         Tableau_Grandeur_quelconque(const Tableau <TypeQuelconque::Grandeur> & tab);
         // idem pour des pointeurs
         Tableau_Grandeur_quelconque(const Tableau <TypeQuelconque::Grandeur*> & tab);
         // idem pour des grandeurs quelconques
         Tableau_Grandeur_quelconque(const Tableau <TypeQuelconque> & tab);
         // constructeur de copie
         Tableau_Grandeur_quelconque(const Tableau_Grandeur_quelconque& a);
         // destructeur
         ~Tableau_Grandeur_quelconque();
         // ramène une grandeur identique, créée 
         TypeQuelconque::Grandeur* New_idem_grandeur() const {return new Tableau_Grandeur_quelconque(*this);};
         // sauvegarde sur le stream des informations permetant ensuite  en lecture de créer via
         // le constructeur adoc l'objet correcte et valide
         void EcriturePourLectureAvecCreation(ostream & sort);
         TypeQuelconque::Grandeur & operator = ( const TypeQuelconque::Grandeur & a); // surcharge d'affectation
         // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur
         // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs  de même type
         // affectation uniquement des données numériques (pas les pointeurs, pas les string)
         void Affectation_numerique( const TypeQuelconque::Grandeur & a);
         // Surcharge de l'operateur +=
         void operator+= (const Grandeur& c);
         // Surcharge de l'operateur -=
         void operator-= (const Grandeur& c);
         // Surcharge de l'operateur *=
         void operator*= (double val);
         // Surcharge de l'operateur /= : division  par un scalaire
         void operator/= (double val);
         // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
         // si pas possible, ramène 0
         double GrandeurNumOrdre(int num) const  {return 0;};
         int NbMaxiNumeroOrdre()  const {return 0;}; // récup du nb maxi de numéros d'ordres
         void Grandeur_brut(ostream & sort,int nbcar) const;
         // ramène le type de grandeur associée de la grandeur de base, car
         // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base
         EnumTypeGrandeur Type_grandeurAssocie() const {return GRANDEUR_QUELCONQUE;};
         // ramène le type de la structure: tableau, liste ext..
         EnumType2Niveau  Type_structure_grandeurAssocie() const {return TABLEAU_T;};
         // ramène le type de la grandeur particulière
         EnuTypeQuelParticulier Type_enumGrandeurParticuliere() const{return PARTICULIER_TABLEAU_QUELCONQUE;};
         // acces au Grandeur_Vecteur_Nommer de numéro i en lecture écriture
         TypeQuelconque::Grandeur& operator () ( int i)const {return (*(tab_grandeur(i)));};
         // ramène la Grandeur_Vecteur_Nommer associée
         const TypeQuelconque::Grandeur& ConteneurGrandeurQuelconque(int i) const {return *(tab_grandeur(i));};
         // ramène la dimension du tableau
         int Taille() const {return tab_grandeur.Taille();};
         // changement de taille -> n :
         // si n < taille_actuelle --> les taille_actuelle - n sont supprimé
         // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois,
         void Change_taille(int n);
         // change de repère de la grandeur
         void Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma );
         // lecture
         istream & Lecture_grandeur(istream & ent)  { ent >> *this;return ent;};
         // ecriture
         virtual ostream & Ecriture_grandeur(ostream & sort ) const { sort << *this; return sort;};
        // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
         void InitParDefaut();

         protected:
         Tableau <TypeQuelconque::Grandeur*>  tab_grandeur;
        };
/// @}  // end of group

  
#endif  
