// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL  : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.

#include "TypeQuelconqueParticulier.h"

#include "Tenseur1.h"
#include "Tenseur2.h"
#include "Tenseur3.h"
#include "MathUtil2.h"



//-----------------------------------------------------------------------------
//| grandeur Vecteur: TypeQuelconque::Grandeur::Grandeur_Vecteur |
//-----------------------------------------------------------------------------

// surcharge de l'operator de lecture
istream & operator >> (istream & ent, Grandeur_Vecteur & a)
 { string toto; ent >> toto; // passage de l'entête
   #ifdef MISE_AU_POINT
   if (toto != "Grandeur_Vecteur=")
       {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Vecteur= "
             << "\n operator << (ostream & sort , const Grandeur_Vecteur & a)";
        Sortie(1);
       };
   #endif
   ent >> a.ve;
   return ent;
  };
// surcharge de l'operator d'ecriture
ostream & operator << (ostream & sort , const Grandeur_Vecteur & a)
   {sort << " Grandeur_Vecteur= " << a.ve << " " ;
    return sort;
   };

// constructeur par défaut:
Grandeur_Vecteur::Grandeur_Vecteur():
    ve() {};

// 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::Grandeur_Vecteur(istream & ent):
  ve()
 { string entete,nom; ent >> entete >> nom; // passage de l'entête
   #ifdef MISE_AU_POINT
   if (entete != "Grandeur_Vecteur=")
       {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Vecteur= "
             << "\n Grandeur_Vecteur::Grandeur_Vecteur(istream & ent)";
        Sortie(1);
       };
   #endif
   // lecture de la dimension
   int dim; ent >> dim;
   ve.Change_taille(dim);
   // fin de la lecture
   ent >> ve;
  };

// sauvegarde sur le stream des informations permettant ensuite  en lecture de créer via
// le constructeur adoc l'objet correcte et valide
void Grandeur_Vecteur::EcriturePourLectureAvecCreation(ostream & sort)
 {sort << " Grandeur_Vecteur= " << ve.Taille() << " "<< ve << " ";};

// surcharge d'affectation
TypeQuelconque::Grandeur & Grandeur_Vecteur::operator = ( const TypeQuelconque::Grandeur & a)
 {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur a l'affectation: type de l'objet: "
             << "\n Grandeur_Vecteur::operator = (..";
        Sortie(1);
       }
   #endif
   Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a);
   ve=aa.ve;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 Grandeur_Vecteur::Affectation_numerique( const TypeQuelconque::Grandeur & a)
 {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Grandeur_Vecteur::Affectation_numerique(..";
        Sortie(1);
       }
   #endif
   Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a);
   ve=aa.ve;
   };

   // Surcharge de l'operateur +=
void Grandeur_Vecteur::operator+= (const Grandeur& a)
  {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Grandeur_Vecteur::operator+= (..";
        Sortie(1);
       }
   #endif
   Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a);
   ve+=aa.ve;
   };
   // Surcharge de l'operateur -=
void Grandeur_Vecteur::operator-= (const Grandeur& a)
  {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Grandeur_Vecteur::operator-= (..";
        Sortie(1);
       }
   #endif
   Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a);
   ve-=aa.ve;
   };

// récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre
// si pas possible, ramène 0
double Grandeur_Vecteur::GrandeurNumOrdre(int num) const
  {if((num>0)&&(num<=ve.Taille())) return ve(num); else return 0.;};

// change de repère de la grandeur
void Grandeur_Vecteur::Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma )
 {cout << "\n **** non implante !!! "
       << "\n Grandeur_Vecteur::Change_repere(";
  Sortie(1);
  };

//------------------------------------------------------------------------------------
// grandeur un tableau de Vecteur: TypeQuelconque::Grandeur::Tab_Grandeur_Vecteur |
// tous les coordonnees doivent avoir la même dimension !! pour la routine GrandeurNumOrdre
//------------------------------------------------------------------------------------

// surcharge de l'operator de lecture
istream & operator >> (istream & ent, Tab_Grandeur_Vecteur & a)
 { int taille = a.tabVe.Taille(); string entete;
   ent >> entete; // passage de l'entête
   #ifdef MISE_AU_POINT
   if (entete != "Tableau_de_Vecteur_nb=")
       {cout << "\n erreur en lecteur, on attendait le mot cle: Tableau_de_Vecteur_nb= "
             << "\n istream & operator >> (istream & ent, Tab_Grandeur_Vecteur & a)";
        Sortie(1);
       };
   #endif
   int nb;
   ent >> nb;
   if (nb != taille)
     { cout << "\n erreur en lecteur, la taille actuelle du tableau: " << taille
            << " est differente de la taille lue: " << nb
            << "\n operator >> (istream & ent, Tab_Grandeur_Vecteur & a)";
       Sortie(1);
      };
   for (int i=1;i<=taille;i++)
     ent >> *(a.tabVe(i)); // on utilise la lecture de Grandeur_Vecteur
   return ent;
  };

// surcharge de l'operator d'ecriture
ostream & operator << (ostream & sort , const Tab_Grandeur_Vecteur & a)
 { int taille = a.tabVe.Taille();
   sort << " Tableau_de_Vecteur_nb= " << taille ;
   for (int i=1;i<=taille;i++)
      sort << *(a.tabVe(i)); // on utilise l'écriture de Grandeur_Vecteur
   return sort;
  };

// constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable
// ptTens défini, donc -> erreur
Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur() : tabVe()
  { cout << "\n erreur! ce constructeur ne doit pas etre utilise !!"
         << "\n Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur()";
   };

// constructeur légal
// nb indique le nombre de tenseur
Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur( Vecteur& tens,int nb) :
   tabVe(nb)
      { for (int i=1;i<=nb;i++)
           tabVe(i) = new Grandeur_Vecteur(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
Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur(istream & ent) :
   tabVe()
 { string entete,nom; ent >> entete ; // passage de l'entête
   #ifdef MISE_AU_POINT
   if (entete != "Tableau_de_Vecteur_nb=")
       {cout << "\n erreur en lecteur, on attendait le mot cle: Tableau_de_Vecteur_nb= "
             << "\n Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur(istream & ent)";
        Sortie(1);
       };
   #endif
   // lecture de la taille
   int taille; ent >> taille ;
   if (taille <= 0)
    // dans le cas où la taille est nulle on définit simplement un tableau nul
    {tabVe.Change_taille(0);}
   else // sinon il nous faut définir les éléments du tableau au fur et à mesure de la lecture
    { tabVe.Change_taille(taille);
      for (int i=1;i<=taille;i++)
        tabVe(i) = new Grandeur_Vecteur(ent); // lecture au moment de la création de chaque Vecteur
    };
  };

// constructeur de copie
Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur(const Tab_Grandeur_Vecteur& a):
  tabVe(a.tabVe.Taille())
   { int taille = tabVe.Taille();
     for (int i=1;i<=taille;i++)
       tabVe(i) = new Grandeur_Vecteur(*(a.tabVe(i)));
     };

// destructeur
Tab_Grandeur_Vecteur::~Tab_Grandeur_Vecteur()
   { int taille = tabVe.Taille();
     for (int i=1;i<=taille;i++)
       delete tabVe(i);
   };

// sauvegarde sur le stream des informations permettant ensuite  en lecture de créer via
// le constructeur adoc l'objet correcte et valide
void Tab_Grandeur_Vecteur::EcriturePourLectureAvecCreation(ostream & sort)
 { int taille = tabVe.Taille();
   sort << " Tableau_de_Vecteur_nb= " << taille << " "; //<< " dim= ";
   for (int i=1;i<=taille;i++)
      tabVe(i)->EcriturePourLectureAvecCreation(sort);
  };

// surcharge d'affectation
TypeQuelconque::Grandeur & Tab_Grandeur_Vecteur::operator = ( const TypeQuelconque::Grandeur & b)
 {
   #ifdef MISE_AU_POINT
     if ((b.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (b.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur a l'affectation: type de l'objet: "
             << "\n Tab_Grandeur_Vecteur::operator = (..";
        Sortie(1);
       }
   #endif
   Tab_Grandeur_Vecteur& a= *((Tab_Grandeur_Vecteur*) &b);
   // maintenant l'affectation
   int taille = tabVe.Taille();
   #ifdef MISE_AU_POINT
     if (taille != a.tabVe.Taille())
      { cout << "\n erreur a l'affectation: la taille de this " << taille << " n'est pas egale a celle "
             << " du parametre " << a.tabVe.Taille()
             << "\n Tab_Grandeur_Vecteur::operator = (..";
        Sortie(1);
       }
   #endif
   for (int i=1;i<=taille;i++)
    // ici on fait une grosse manip d'écriture qui revient au même qu'à la ligne suivante
    // mais il y a un pb sur linux que je ne comprend pas
     ((Grandeur_Vecteur*) tabVe(i))->operator = (*((TypeQuelconque::Grandeur*) a.tabVe(i)));
   return *this;
  };


// surcharge d'affectation
TypeQuelconque::Grandeur & Tab_Grandeur_Vecteur::operator = ( const Tab_Grandeur_Vecteur & a)
 {
   // maintenant l'affectation
   int taille = tabVe.Taille();
   #ifdef MISE_AU_POINT
     if (taille != a.tabVe.Taille())
      { cout << "\n erreur a l'affectation: la taille de this " << taille << " n'est pas egale a celle "
             << " du parametre " << a.tabVe.Taille()
             << "\n Tab_Grandeur_Vecteur::operator = (..";
        Sortie(1);
       }
   #endif
   for (int i=1;i<=taille;i++)
       *(tabVe(i))= *(a.tabVe(i));
   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 Tab_Grandeur_Vecteur::Affectation_numerique( const TypeQuelconque::Grandeur & a)
 {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Tab_Grandeur_Vecteur::Affectation_numerique(..";
        Sortie(1);
       }
   #endif
   Tab_Grandeur_Vecteur& aa= *((Tab_Grandeur_Vecteur*) &a);
   int taille = tabVe.Taille();
   int tailleN = aa.tabVe.Taille();
   if (taille != tailleN)
      { cout << "\n erreur sur les dimensions des tableaux taille  de this puis de a "
             << taille << " " << tailleN << " "
             << "\n Tab_Grandeur_Vecteur::Affectation_numerique(..";
        Sortie(1);
       };
   for (int i=1;i<=taille;i++)
      (tabVe(i))->Affectation_numerique(*(aa.tabVe(i)));
  };

   // Surcharge de l'operateur +=
void Tab_Grandeur_Vecteur::operator+= (const Grandeur& a)
 {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Tab_Grandeur_Vecteur::operator+= (..";
        Sortie(1);
       }
   #endif
   Tab_Grandeur_Vecteur& aa= *((Tab_Grandeur_Vecteur*) &a);
   int taille = tabVe.Taille();
   int tailleN = aa.tabVe.Taille();
   if (taille != tailleN)
      { cout << "\n erreur sur les dimensions des tableaux taille  de this puis de a "
             << taille << " " << tailleN << " "
             << "\n Tab_Grandeur_Vecteur::operator+= (..";
        Sortie(1);
       };
   for (int i=1;i<=taille;i++)  //(*tabVe(i)) += (*(aa.tabVe(i)));
      *(tabVe(i)) += *(aa.tabVe(i));
  };
   // Surcharge de l'operateur -=
void Tab_Grandeur_Vecteur::operator-= (const Grandeur& a)
 {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Tab_Grandeur_Vecteur::operator-= (..";
        Sortie(1);
       }
   #endif
   Tab_Grandeur_Vecteur& aa= *((Tab_Grandeur_Vecteur*) &a);
   int taille = tabVe.Taille();
   int tailleN = aa.tabVe.Taille();
   if (taille != tailleN)
      { cout << "\n erreur sur les dimensions des tableaux taille  de this puis de a "
             << taille << " " << tailleN << " "
             << "\n Tab_Grandeur_Vecteur::operator-= (..";
        Sortie(1);
       };
   for (int i=1;i<=taille;i++)  //(*tabVe(i)) -= (*(aa.tabVe(i)));
      *(tabVe(i)) -= *(aa.tabVe(i));
  };
   // Surcharge de l'operateur *=
void Tab_Grandeur_Vecteur::operator*= (double val)
 { int taille = tabVe.Taille();
   for (int i=1;i<=taille;i++) //(*tabVe(i))*=val;
      *(tabVe(i)) *=val;
  };
   // Surcharge de l'operateur /= : division  par un scalaire
void Tab_Grandeur_Vecteur::operator/= (double val)
 { int taille = tabVe.Taille();
   for (int i=1;i<=taille;i++) //(*tabVe(i))/=val;
     *(tabVe(i)) /=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 Tab_Grandeur_Vecteur::GrandeurNumOrdre(int n) const
  { int taille = tabVe.Taille();
    if (taille == 0) return 0; // cas d'un tableau vide
    int nbparcoor=tabVe(1)->NbMaxiNumeroOrdre();
    int indice_tableau = (n-1)/nbparcoor + 1;
    int r_div = (n-1)%nbparcoor+1;
    return tabVe(indice_tableau)->GrandeurNumOrdre(r_div);
   };
// récup du nb maxi de numéros d'ordres
int Tab_Grandeur_Vecteur::NbMaxiNumeroOrdre() const
  { if (tabVe.Taille() == 0) return 0; // cas d'un tableau vide
    int nbparcoor=tabVe(1)->NbMaxiNumeroOrdre();
    return (tabVe.Taille() * nbparcoor);
   };

void Tab_Grandeur_Vecteur::Grandeur_brut(ostream & sort,int nbcar) const
  { int taille = tabVe.Taille();
    for (int k=1;k<=taille;k++)
      tabVe(k)->Grandeur_brut(sort,nbcar);
   };

// 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 Tab_Grandeur_Vecteur::Change_taille(int n)
 { int taille = tabVe.Taille();
   if (n < taille)
  { for (int i=n;i<=taille;i++) delete tabVe(i);
      tabVe.Change_taille(n);
   }
 else // sinon on augmente
  { tabVe.Change_taille(n);
    for (int i=taille;i<=n;i++)
    tabVe(i) = new Grandeur_Vecteur(*tabVe(taille));
   };
  };

// change de repère de la grandeur
void Tab_Grandeur_Vecteur::Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma)
  { int taille = tabVe.Taille();
    for (int i=1;i<=taille;i++)
       tabVe(i)->Change_repere(beta,gamma);
   };

// initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques
void Tab_Grandeur_Vecteur::InitParDefaut()
 {int taille = tabVe.Taille();
    for (int i=1;i<=taille;i++)
       tabVe(i)->InitParDefaut();
   };

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

// surcharge de l'operator de lecture
istream & operator >> (istream & ent, Grandeur_Double_Nommer_indicer & a)
 { string toto; ent >> toto; // passage de l'entête
   #ifdef MISE_AU_POINT
   if (toto != "Grandeur_Double_Nommer_indicer=")
       {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Double_Nommer_indicer= "
             << "\n operator << (ostream & sort , const Grandeur_Double_Nommer_indicer & a)";
        Sortie(1);
       };
   #endif
   ent >> a.nom_ref >> a.val >> a.indice;
   return ent;
  };
// surcharge de l'operator d'ecriture
ostream & operator << (ostream & sort , const Grandeur_Double_Nommer_indicer & a)
   {sort << " Grandeur_Double_Nommer_indicer= "
         << a.nom_ref << " " << a.val << " " << a.indice << " ";
    return sort;
   };
   
// constructeur par défaut:
Grandeur_Double_Nommer_indicer::Grandeur_Double_Nommer_indicer():
    nom_ref(""),val(),indice(1) {};
                            
// 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::Grandeur_Double_Nommer_indicer(istream & ent):
  nom_ref(""),val(),indice(1)
 { string entete,nom; ent >> entete >> nom; // passage de l'entête
   #ifdef MISE_AU_POINT
   if (entete != "Grandeur_Double_Nommer_indicer=")
       {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Double_Nommer_indicer= "
             << "\n Grandeur_Double_Nommer_indicer::Grandeur_Double_Nommer_indicer(istream & ent)";
        Sortie(1);
       };
   #endif
   // fin de la lecture
   ent >> nom_ref >> val >> indice;
  };

// sauvegarde sur le stream des informations permettant ensuite  en lecture de créer via
// le constructeur adoc l'objet correcte et valide
void Grandeur_Double_Nommer_indicer::EcriturePourLectureAvecCreation(ostream & sort)
 {sort << " Grandeur_Double_Nommer_indicer= " << nom_ref << " " <<  val << " "<< indice << " ";};

// surcharge d'affectation
TypeQuelconque::Grandeur & Grandeur_Double_Nommer_indicer::operator = ( const TypeQuelconque::Grandeur & a)
 {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur a l'affectation: type de l'objet: "
             << "\n Grandeur_Double_Nommer_indicer::operator = (..";
        Sortie(1);
       }
   #endif
   Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a);
   val=aa.val;nom_ref = aa.nom_ref; indice = aa.indice; 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 Grandeur_Double_Nommer_indicer::Affectation_numerique( const TypeQuelconque::Grandeur & a)
  {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Grandeur_Double_Nommer_indicer::Affectation_numerique(..";
        Sortie(1);
       }
   #endif
   Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a);
   val = aa.val;
  };

   // Surcharge de l'operateur +=
void Grandeur_Double_Nommer_indicer::operator+= (const Grandeur& a)
  {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Grandeur_Double_Nommer_indicer::operator+= (..";
        Sortie(1);
       }
   #endif
   Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a);
   val +=aa.val;
   };
   // Surcharge de l'operateur -=
void Grandeur_Double_Nommer_indicer::operator-= (const Grandeur& a)
  {
   #ifdef MISE_AU_POINT
     if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie())
        || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie()))
      { cout << "\n erreur sur le : type de l'objet: "
             << "\n Grandeur_Double_Nommer_indicer::operator-= (..";
        Sortie(1);
       }
   #endif
   Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a);
   val -=aa.val;
   };



