
// 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-2022 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 "PtIntegMecaInterne.h"

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

// contructeur par défaut
PtIntegMecaInterne::PtIntegMecaInterne():
  epsBB(NULL),depsBB(NULL),deltaEpsBB(NULL),sigHH(NULL),sigHH_t(NULL)
  ,epsInvar(NULL),depsInvar(NULL),sigInvar(NULL)
  ,module_compressibilite(-1.),module_cisaillement(-1.),volume_pti(-1.)
  ,def_equi(4,0.),def_equi_t(4,0.)
  ,sig_equi_t(2,0.), sig_equi(2,0.)
  ,M0(ParaGlob::Dimension()),Mt(ParaGlob::Dimension()),Mtdt(ParaGlob::Dimension())
  ,mail(0),nele(0),npti(0)
//  ,tab_baseB_0_t_tdt(NULL)
  ,tpsMetrique(),tps_cpu_loi_comp()
    {};
    
// contructeur fonction de la dimension de tenseurs
PtIntegMecaInterne::PtIntegMecaInterne(int dimtens) :
  epsBB(NULL),depsBB(NULL),deltaEpsBB(NULL),sigHH(NULL),sigHH_t(NULL)
  ,epsInvar(NULL),depsInvar(NULL),sigInvar(NULL)
  ,module_compressibilite(-1.),module_cisaillement(-1.),volume_pti(-1.)
  ,def_equi(4,0.),def_equi_t(4,0.)
  ,sig_equi_t(2,0.), sig_equi(2,0.)
  ,tpsMetrique(),tps_cpu_loi_comp()
  ,M0(ParaGlob::Dimension()),Mt(ParaGlob::Dimension()),Mtdt(ParaGlob::Dimension())
  ,mail(0),nele(0),npti(0)
//  ,tab_baseB_0_t_tdt(NULL)
    { switch(dimtens)
      {case 3: 
        {epsBB = NevezTenseurBB (3);
         depsBB = NevezTenseurBB (3);
         deltaEpsBB = NevezTenseurBB (3);
         sigHH = NevezTenseurHH (3);
         sigHH_t = NevezTenseurHH (3);
         // comme on est en dimension 3, on a trois invariants
//	     epsInvar.Change_taille(3);
//	     depsInvar.Change_taille(3);
//	     sigInvar.Change_taille(3);
         break;
        }
       case 2: 
        {epsBB = NevezTenseurBB (2);
         depsBB = NevezTenseurBB (2);
         deltaEpsBB = NevezTenseurBB (2);
         sigHH = NevezTenseurHH (2);
         sigHH_t = NevezTenseurHH (2);
         // comme on est en dimension 2, on a 2 invariants
//	     epsInvar.Change_taille(2);
//	     depsInvar.Change_taille(2);
//	     sigInvar.Change_taille(2);
         break;
        }
       case 1: 
        {epsBB = NevezTenseurBB (1);
         depsBB = NevezTenseurBB (1);
         deltaEpsBB = NevezTenseurBB (1);
         sigHH = NevezTenseurHH (1);
         sigHH_t = NevezTenseurHH (1);
         // comme on est en dimension 1, on a 1 invariants
//	     epsInvar.Change_taille(1);
//	     depsInvar.Change_taille(1);
//	     sigInvar.Change_taille(1);
         break;
        }
       default:
         cout << "\n *** erreur: cas non prevu: dimtens= " << dimtens
              << "\n PtIntegMecaInterne::PtIntegMecaInterne(int dimtens)";
         Sortie(1);
      };
    };
    
// contructeur de copie
PtIntegMecaInterne::PtIntegMecaInterne(const PtIntegMecaInterne& pti):
  epsBB(NULL),depsBB(NULL),deltaEpsBB(NULL),sigHH(NULL),sigHH_t(NULL)
  ,epsInvar(NULL),depsInvar(NULL),sigInvar(NULL)
  ,module_compressibilite(pti.module_compressibilite),module_cisaillement(pti.module_cisaillement)
  ,volume_pti(pti.volume_pti)
  ,def_equi(pti.def_equi),def_equi_t(pti.def_equi_t)
  ,sig_equi_t(pti.sig_equi_t), sig_equi(pti.sig_equi)
  ,tpsMetrique(pti.tpsMetrique),tps_cpu_loi_comp(pti.tps_cpu_loi_comp)
  ,M0(pti.M0),Mt(pti.Mt),Mtdt(pti.Mtdt)
  ,mail(pti.mail),nele(pti.nele),npti(pti.npti)
//  ,tab_baseB_0_t_tdt(NULL)
	{if (pti.epsBB != NULL) epsBB = NevezTenseurBB (*(pti.epsBB));
	 if (pti.depsBB != NULL)depsBB = NevezTenseurBB (*(pti.depsBB));
	 if (pti.deltaEpsBB != NULL)deltaEpsBB = NevezTenseurBB (*(pti.deltaEpsBB));
	 if (pti.sigHH != NULL)sigHH = NevezTenseurHH (*(pti.sigHH));
	 if (pti.sigHH_t != NULL)sigHH_t = NevezTenseurHH (*(pti.sigHH_t));
	 
	 if (pti.epsInvar != NULL) epsInvar = new Vecteur  (*(pti.epsInvar));
	 if (pti.depsInvar != NULL) depsInvar = new Vecteur  (*(pti.depsInvar));
	 if (pti.sigInvar != NULL) sigInvar = new Vecteur  (*(pti.sigInvar));
  
//  // cas des bases éventuellement associées
//  if (pti.tab_baseB_0_t_tdt != NULL)
//   { tab_baseB_0_t_tdt = new Tableau < BaseB_0_t_tdt> (*pti.tab_baseB_0_t_tdt);
//   }
  
	 
	};     
    
// DESTRUCTEUR :
PtIntegMecaInterne::~PtIntegMecaInterne()
{ if (epsBB != NULL) delete epsBB;
  if (depsBB != NULL) delete depsBB;
  if (deltaEpsBB != NULL) delete deltaEpsBB;
  if (sigHH != NULL) delete sigHH;
  if (sigHH_t != NULL) delete sigHH_t;
  
  if (epsInvar != NULL) delete epsInvar;
  if (depsInvar != NULL) delete depsInvar;
  if (sigInvar != NULL) delete sigInvar;
//  if (tab_baseB_0_t_tdt != NULL)
//    delete tab_baseB_0_t_tdt;
//****    il faut continuer la mise en place de tab_baseB_0_t_tdt ****
 
};
    
// Surcharge de l'operateur = 
PtIntegMecaInterne& PtIntegMecaInterne::operator= ( const PtIntegMecaInterne& pti)
{if (pti.epsBB != NULL) 
  { if (epsBB == NULL) {epsBB = NevezTenseurBB (*(pti.epsBB));}
    else               {*epsBB = (*(pti.epsBB));};
  }
 else if (epsBB != NULL) {delete epsBB;epsBB = NULL;}; 
     // sinon il est déjà null donc rien n'a faire
	 
 if (pti.depsBB != NULL) 
  { if (depsBB == NULL) {depsBB = NevezTenseurBB (*(pti.depsBB));}
    else               {*depsBB = (*(pti.depsBB));};
  }
 else if (depsBB != NULL) {delete depsBB;depsBB=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

 if (pti.deltaEpsBB != NULL)
  { if (deltaEpsBB == NULL) {deltaEpsBB = NevezTenseurBB (*(pti.deltaEpsBB));}
    else               {*deltaEpsBB = (*(pti.deltaEpsBB));};
  }
 else if (deltaEpsBB != NULL) {delete deltaEpsBB;deltaEpsBB=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

 if (pti.sigHH != NULL)
  { if (sigHH == NULL) {sigHH = NevezTenseurHH (*(pti.sigHH));}
    else               {*sigHH = (*(pti.sigHH));};
  }
 else if (sigHH != NULL) {delete sigHH;sigHH=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

 if (pti.sigHH_t != NULL)
  { if (sigHH_t == NULL) {sigHH_t = NevezTenseurHH (*(pti.sigHH_t));}
    else               {*sigHH_t = (*(pti.sigHH_t));};
  }
 else if (sigHH_t != NULL) {delete sigHH_t;sigHH_t=NULL;}; 
     // sinon il est déjà null donc rien n'a faire
 //--- les defs équivalentes
 def_equi_t=pti.def_equi_t; def_equi=pti.def_equi;
 // --- les contraintes équivalentes
 sig_equi_t=pti.sig_equi_t; sig_equi=pti.sig_equi;
 // --- les modules
 module_compressibilite = pti.module_compressibilite;
 module_cisaillement = pti.module_cisaillement;
 // --- volume élémentaire
 volume_pti = pti.volume_pti;

 // ---- puis les vecteurs
 
 if (pti.epsInvar != NULL)
  { if (epsInvar == NULL) {epsInvar = new Vecteur (*(pti.epsInvar));}
    else               {*epsInvar = (*(pti.epsInvar));};
  }
 else if (epsInvar != NULL) {delete epsInvar;epsInvar=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

 if (pti.depsInvar != NULL)
  { if (depsInvar == NULL) {depsInvar = new Vecteur (*(pti.depsInvar));}
    else               {*depsInvar = (*(pti.depsInvar));};
  }
 else if (depsInvar != NULL) {delete depsInvar;depsInvar=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

 if (pti.sigInvar != NULL)
  { if (sigInvar == NULL) {sigInvar = new Vecteur (*(pti.sigInvar));}
    else               {*sigInvar = (*(pti.sigInvar));};
  }
 else if (sigInvar != NULL) {delete sigInvar;sigInvar=NULL;}; 
     // sinon il est déjà null donc rien n'a faire
 // les positions
 M0 = pti.M0; Mt = pti.Mt; Mtdt = pti.Mtdt;
 mail= pti.mail;nele = pti.nele; npti = pti.npti;

 // --- les temps cpu
 tpsMetrique=pti.tpsMetrique;tps_cpu_loi_comp=pti.tps_cpu_loi_comp;
 // retour
 return *this;

};
    
//============= lecture écriture dans base info ==========
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void PtIntegMecaInterne::Lecture_base_info (istream& ent,const int )
 {  // lecture des différents éléments que l'on trouve utiles (pour l'instant)
    string nom;
    ent >> nom; epsBB->Lecture(ent); 
    ent >> nom; depsBB->Lecture(ent);
    ent >> nom; deltaEpsBB->Lecture(ent);
    ent >> nom; sigHH->Lecture(ent);
    *sigHH_t = *sigHH; // init de la grandeur à t
    ent >> nom >> def_equi(1) >> nom >> def_equi(2) >> nom >> def_equi(3) >> nom >> def_equi(4);
    def_equi_t = def_equi;
    ent >> nom >> sig_equi(1) >> nom >> sig_equi(2) ;
    sig_equi_t = sig_equi;
    ent >> nom >> module_compressibilite >> nom >> module_cisaillement
        >> nom >> volume_pti;
    int existe = 0;
    // lecture éventuelle des invariants
    
    // cas des invariants de def
    ent >> nom >> existe;
    if (existe ==0)
     {if (epsInvar != NULL) {delete epsInvar;epsInvar=NULL;};}
    else 
     {if (epsInvar == NULL) epsInvar = new Vecteur ();
      ent >> *epsInvar;
     };
   
    // cas des invariants de vitesse de def
    ent >> nom >> existe;
    if (existe ==0)
     {if (depsInvar != NULL) {delete depsInvar;depsInvar=NULL;};}
    else 
     {if (depsInvar == NULL) depsInvar = new Vecteur ();
      ent >> *depsInvar;
     };
   
    // cas des invariants de contrainte
    ent >> nom >> existe;
    if (existe ==0)
     {if (sigInvar != NULL) {delete sigInvar;sigInvar=NULL;};}
    else 
     {if (sigInvar == NULL) sigInvar = new Vecteur ();
      ent >> *sigInvar;
     };
    // position
    ent >> nom >> Mtdt;
    Mt = Mtdt; // init de la grandeur à t
    ent >> nom >> mail >> nom >> nele >> nom >> npti;
    // temps cpu
    ent >> nom >> tpsMetrique >> nom >> tps_cpu_loi_comp;
  };
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void PtIntegMecaInterne::Ecriture_base_info(ostream& sort,const int )
 { // les différents éléments que l'on considère intéressant (pour l'instant)
   sort << "\n epsBB= ";       epsBB->Ecriture(sort); 
   sort << "\n depsBB= ";      depsBB->Ecriture(sort);
   sort << "\n deltaEpsBB= ";  deltaEpsBB->Ecriture(sort);
   sort << "\n sigHH= ";       sigHH_t->Ecriture(sort);
   sort << "\n def_equi= " << def_equi(1) << " def_duale_mises= " << def_equi(2)
        << " def_duale_mises_max= " << def_equi(3) << " delta_def_equi= " << def_equi(4);
   sort << "\n sig_Mises= " << sig_equi(1) << " sig_Tresca= " << sig_equi(2);
   sort << "\n mod_compress= " << module_compressibilite << " mod_cisaill= " << module_cisaillement
        << " volume_pti= " << volume_pti;
   sort << "\n epsInvar= ";  if(epsInvar == NULL) {sort << 0;} else {sort << "1 " << *epsInvar;};
   sort << "\n depsInvar= ";  if(depsInvar == NULL) {sort << 0;} else {sort << "1 " << *depsInvar;};
   sort << "\n sigInvar= ";  if(sigInvar == NULL) {sort << 0;} else {sort << "1 " << *sigInvar;};
   // position
   sort << "\n M_tdt= "<<Mtdt << " ,Mail "<<mail<<" ,ele " << nele <<" ,pti " << npti  ;
   sort << "\n tpsmetrique= " << tpsMetrique << " tpsLoiComp= " << tps_cpu_loi_comp;
 };
    
// le changement de statut, si c'est déjà ok, on ne fait rien
// nevez_statut: indique si l'on veut activer ou au contraire désactiver
void PtIntegMecaInterne::Change_statut_Invariants_deformation (bool nevez_statut)
	{ int dimT = epsBB->Dimension();
	  if (nevez_statut)
     		{ if (epsInvar == NULL)  epsInvar = new Vecteur(abs(dimT)); // sinon rien car le vecteur existe déjà
     		}
	  else // cas où on veut désactiver	
     		{ if (epsInvar != NULL) {delete epsInvar;epsInvar=NULL;}; // sinon rien car le vecteur n'existe pas
     		};
	};
void PtIntegMecaInterne::Change_statut_Invariants_vitesseDeformation (bool nevez_statut)
	{ int dimT = epsBB->Dimension();
	  if (nevez_statut)
     		{ if (depsInvar == NULL) depsInvar = new Vecteur(abs(dimT)); // sinon rien car le vecteur existe déjà
     		}
	  else // cas où on veut désactiver	
     		{ if (depsInvar != NULL) {delete depsInvar;depsInvar=NULL;}; // sinon rien car le vecteur n'existe pas
     		};
	};
void PtIntegMecaInterne::Change_statut_Invariants_contrainte (bool nevez_statut)
	{ int dimT = epsBB->Dimension();
	  if (nevez_statut)
     		{ if (sigInvar == NULL) sigInvar = new Vecteur(abs(dimT)); // sinon rien car le vecteur existe déjà
     		}
	  else // cas où on veut désactiver	
     		{ if (sigInvar != NULL) {delete sigInvar;sigInvar=NULL;}; // sinon rien car le vecteur n'existe pas
     		};
	};
 
// actualisation des grandeurs actives de t+dt vers t, pour celles qui existent 
// sous ces deux formes    
void PtIntegMecaInterne::TdtversT()
	{ *sigHH_t = *sigHH;def_equi_t=def_equi;sig_equi_t=sig_equi;Mt = Mtdt;};
	
// actualisation des grandeurs actives de t vers tdt, pour celles qui existent 
// sous ces deux formes          
void PtIntegMecaInterne::TversTdt()
	{ *sigHH = *sigHH_t;def_equi=def_equi_t;sig_equi=sig_equi_t;Mtdt = Mt;};

// plusZero: = true: indique qu'il faut complèter les grandeurs manquantes avec des 0
//           = false: on ne complète pas
// il faut que ptintmec comporte des tenseurs d'ordre 2 et this des tenseurs 3D
void PtIntegMecaInterne::Affectation_2D_a_3D(const PtIntegMecaInterne& ptintmec,bool plusZero)
{ // vérif éventuelle des dimensions
 #ifdef MISE_AU_POINT
 { //  cas des pointeurs: la méthode est prévue pour des tenseurs déjà affectés
  if (ptintmec.epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de l'argument ne sont pas affecte: par exemple ptintmec.epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_2D_a_3D(.."; Sortie(1);};
  if (epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de this ne sont pas affecte: par exemple epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_2D_a_3D(.."; Sortie(1);};
  //  - les dimensions
  if (epsBB->Dimension() != 3) 
	  {cout << "\n *** erreur l'ordre de this ("<<epsBB->Dimension() <<") est different de 3"
	        << "\n PtIntegMecaInterne::Affectation_2D_a_3D(.."; Sortie(1);};
  if (ptintmec.epsBB->Dimension() != 2) 
	  {cout << "\n *** erreur l'ordre de ptintmec.epsBB ("<< ptintmec.epsBB->Dimension() <<") est different de 2"
	        << "\n PtIntegMecaInterne::Affectation_2D_a_3D(.."; Sortie(1);};
  }
 #endif
  // pour tout ce qui est def
  ((Tenseur3BB*) epsBB)->Affectation_2D_a_3D(*((const Tenseur2BB*) ptintmec.epsBB),plusZero);
  ((Tenseur3BB*) depsBB)->Affectation_2D_a_3D(*((const Tenseur2BB*) ptintmec.depsBB),plusZero);
  ((Tenseur3BB*) deltaEpsBB)->Affectation_2D_a_3D(*((const Tenseur2BB*) ptintmec.deltaEpsBB),plusZero);
  ((Tenseur3HH*) sigHH)->Affectation_2D_a_3D(*((const Tenseur2HH*) ptintmec.sigHH),plusZero);
  ((Tenseur3HH*) sigHH_t)->Affectation_2D_a_3D(*((const Tenseur2HH*) ptintmec.sigHH_t),plusZero);
  
  //--- les defs équivalentes
  def_equi_t=ptintmec.def_equi_t; def_equi=ptintmec.def_equi;
  //--- les contraintes équivalentes
  sig_equi_t=ptintmec.sig_equi_t; sig_equi=ptintmec.sig_equi;
  // --- les modules
  module_compressibilite = ptintmec.module_compressibilite;
  module_cisaillement = ptintmec.module_cisaillement;
  // --- volume élémentaire: ici on recopie, mais normalement il faudra le mettre à jour ensuite
  volume_pti = ptintmec.volume_pti;

  // ---- puis les vecteurs
 
  if (ptintmec.epsInvar != NULL)
   { if (epsInvar == NULL)
           {epsInvar = new Vecteur (3,0.); // init à 0 a priori
            (*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
            (*epsInvar)(2) = (*(ptintmec.epsInvar))(2);
           }
     else  {(*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
            (*epsInvar)(2) = (*(ptintmec.epsInvar))(2);
            if (plusZero)
              (*epsInvar)(3) = 0.;
           };
   }
  else if (epsInvar != NULL) {delete epsInvar;epsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.depsInvar != NULL)
   { if (depsInvar == NULL) 
           {depsInvar = new Vecteur (3,0.); // init à 0 a priori
            (*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
            (*depsInvar)(2) = (*(ptintmec.depsInvar))(2);
           }
     else  {(*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
            (*depsInvar)(2) = (*(ptintmec.depsInvar))(2);
            if (plusZero)
              (*depsInvar)(3) = 0.;
           };
   }
  else if (depsInvar != NULL) {delete depsInvar;depsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.sigInvar != NULL)
   { if (sigInvar == NULL) 
           {sigInvar = new Vecteur (3,0.); // init à 0 a priori
            (*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
            (*sigInvar)(2) = (*(ptintmec.sigInvar))(2);
           }
     else  {(*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
            (*sigInvar)(2) = (*(ptintmec.sigInvar))(2);
            if (plusZero)
              (*sigInvar)(3) = 0.;
           };
   }
  else if (sigInvar != NULL) {delete sigInvar;sigInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  // positions: sont toujours en dimensions absolues donc ont la même dimension
  M0 = ptintmec.M0;
  Mt = ptintmec.Mt;
  Mtdt = ptintmec.Mtdt;
  mail = ptintmec.mail;
  nele = ptintmec.nele;
  npti = ptintmec.npti;
 
  // --- les temps cpu
  tpsMetrique=ptintmec.tpsMetrique;tps_cpu_loi_comp=ptintmec.tps_cpu_loi_comp;
 
};

// l'inverse: comme le conteneur d'arrivée est plus petit, il n'y a pas de complétion
// il faut que ptintmec comporte des tenseurs d'ordre 3 et this des tenseurs 2D
void PtIntegMecaInterne::Affectation_3D_a_2D(const PtIntegMecaInterne& ptintmec)
{ // vérif éventuelle des dimensions
 #ifdef MISE_AU_POINT
 { //  cas des pointeurs: la méthode est prévue pour des tenseurs déjà affectés
  if (ptintmec.epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de l'argument ne sont pas affecte: par exemple ptintmec.epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_3D_a_2D(.."; Sortie(1);};
  if (epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de this ne sont pas affecte: par exemple epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_3D_a_2D(.."; Sortie(1);};
  //  - les dimensions
  if (epsBB->Dimension() != 2) 
	  {cout << "\n *** erreur l'ordre de this ("<<epsBB->Dimension() <<") est different de 2"
	        << "\n PtIntegMecaInterne::Affectation_3D_a_2D(.."; Sortie(1);};
  if (ptintmec.epsBB->Dimension() != 3) 
	  {cout << "\n *** erreur l'ordre de ptintmec.epsBB ("<< ptintmec.epsBB->Dimension() <<") est different de 3"
	        << "\n PtIntegMecaInterne::Affectation_3D_a_2D(.."; Sortie(1);};
  }
 #endif
  // pour tout ce qui est def
  ((Tenseur2BB*) epsBB)->Affectation_3D_a_2D(*((const Tenseur3BB*) ptintmec.epsBB));
  ((Tenseur2BB*) depsBB)->Affectation_3D_a_2D(*((const Tenseur3BB*) ptintmec.depsBB));
  ((Tenseur2BB*) deltaEpsBB)->Affectation_3D_a_2D(*((const Tenseur3BB*) ptintmec.deltaEpsBB));
  ((Tenseur2HH*) sigHH)->Affectation_3D_a_2D(*((const Tenseur3HH*) ptintmec.sigHH));
  ((Tenseur2HH*) sigHH_t)->Affectation_3D_a_2D(*((const Tenseur3HH*) ptintmec.sigHH_t));
  
  //--- les defs équivalentes
  def_equi_t=ptintmec.def_equi_t; def_equi=ptintmec.def_equi;
  //--- les contraintes équivalentes
  sig_equi_t=ptintmec.sig_equi_t; sig_equi=ptintmec.sig_equi;
  // --- les modules
  module_compressibilite = ptintmec.module_compressibilite;
  module_cisaillement = ptintmec.module_cisaillement;
  // --- volume_pti
  volume_pti = ptintmec.volume_pti;

  // ---- puis les vecteurs
  
  if (ptintmec.epsInvar != NULL)
   { if (epsInvar == NULL) 
           {epsInvar = new Vecteur (2,0.); // init à 0 a priori
            (*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
            (*epsInvar)(2) = (*(ptintmec.epsInvar))(2);
           }
     else  {(*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
            (*epsInvar)(2) = (*(ptintmec.epsInvar))(2);
           };
   }
  else if (epsInvar != NULL) {delete epsInvar;epsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.depsInvar != NULL)
   { if (depsInvar == NULL) 
           {depsInvar = new Vecteur (2,0.); // init à 0 a priori
            (*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
            (*depsInvar)(2) = (*(ptintmec.depsInvar))(2);
           }
     else  {(*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
            (*depsInvar)(2) = (*(ptintmec.depsInvar))(2);
           };
   }
  else if (depsInvar != NULL) {delete depsInvar;depsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.sigInvar != NULL)
          { if (sigInvar == NULL) 
           {sigInvar = new Vecteur (2,0.); // init à 0 a priori
            (*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
            (*sigInvar)(2) = (*(ptintmec.sigInvar))(2);
           }
     else  {(*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
            (*sigInvar)(2) = (*(ptintmec.sigInvar))(2);
           };
   }
  else if (sigInvar != NULL) {delete sigInvar;sigInvar=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

  // positions: sont toujours en dimensions absolues donc ont la même dimension
  M0 = ptintmec.M0;
  Mt = ptintmec.Mt;
  Mtdt = ptintmec.Mtdt;
  mail = ptintmec.mail;
  nele = ptintmec.nele;
  npti = ptintmec.npti;

  // --- les temps cpu
  tpsMetrique=ptintmec.tpsMetrique;tps_cpu_loi_comp=ptintmec.tps_cpu_loi_comp;
 
};
	     

// plusZero: = true: indique qu'il faut complèter les grandeurs manquantes avec des 0
//           = false: on ne complète pas
// il faut que ptintmec comporte des tenseurs d'ordre 1 et this des tenseurs 3D
void PtIntegMecaInterne::Affectation_1D_a_3D(const PtIntegMecaInterne& ptintmec,bool plusZero)
{ // vérif éventuelle des dimensions
 #ifdef MISE_AU_POINT
 { //  cas des pointeurs: la méthode est prévue pour des tenseurs déjà affectés
  if (ptintmec.epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de l'argument ne sont pas affecte: par exemple ptintmec.epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_1D_a_3D(.."; Sortie(1);};
  if (epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de this ne sont pas affecte: par exemple epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_1D_a_3D(.."; Sortie(1);};
  //  - les dimensions
  if (epsBB->Dimension() != 3) 
	  {cout << "\n *** erreur l'ordre de this ("<<epsBB->Dimension() <<") est different de 3"
	        << "\n PtIntegMecaInterne::Affectation_1D_a_3D(.."; Sortie(1);};
  if (ptintmec.epsBB->Dimension() != 1)
	  {cout << "\n *** erreur l'ordre de ptintmec.epsBB ("<< ptintmec.epsBB->Dimension() <<") est different de 1"
	        << "\n PtIntegMecaInterne::Affectation_1D_a_3D(.."; Sortie(1);};
  }
 #endif
  // pour tout ce qui est def
  ((Tenseur3BB*) epsBB)->Affectation_trans_dimension(*((const Tenseur1BB*) ptintmec.epsBB),plusZero);
  ((Tenseur3BB*) depsBB)->Affectation_trans_dimension(*((const Tenseur1BB*) ptintmec.depsBB),plusZero);
  ((Tenseur3BB*) deltaEpsBB)->Affectation_trans_dimension(*((const Tenseur1BB*) ptintmec.deltaEpsBB),plusZero);
  ((Tenseur3HH*) sigHH)->Affectation_trans_dimension(*((const Tenseur1HH*) ptintmec.sigHH),plusZero);
  ((Tenseur3HH*) sigHH_t)->Affectation_trans_dimension(*((const Tenseur1HH*) ptintmec.sigHH_t),plusZero);
  
  //--- les defs équivalentes
  def_equi_t=ptintmec.def_equi_t; def_equi=ptintmec.def_equi;
  //--- les contraintes équivalentes
  sig_equi_t=ptintmec.sig_equi_t; sig_equi=ptintmec.sig_equi;
  // --- les modules
  module_compressibilite = ptintmec.module_compressibilite;
  module_cisaillement = ptintmec.module_cisaillement;
  // --- volume_pti
  volume_pti = ptintmec.volume_pti;

  // ---- puis les vecteurs
  
  if (ptintmec.epsInvar != NULL)
   { if (epsInvar == NULL)
           {epsInvar = new Vecteur (3,0.); // init à 0 a priori
            (*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
           }
     else  {(*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
            if (plusZero)
              (*epsInvar)(3) = (*epsInvar)(2) = 0.;
           };
   }
  else if (epsInvar != NULL) {delete epsInvar;epsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.depsInvar != NULL)
   { if (depsInvar == NULL) 
           {depsInvar = new Vecteur (3,0.); // init à 0 a priori
            (*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
           }
     else  {(*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
            if (plusZero)
              (*depsInvar)(3) = (*depsInvar)(2) = 0.;
           };
   }
  else if (depsInvar != NULL) {delete depsInvar;depsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.sigInvar != NULL)
   { if (sigInvar == NULL) 
           {sigInvar = new Vecteur (3,0.); // init à 0 a priori
            (*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
           }
     else  {(*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
            if (plusZero)
              (*sigInvar)(3) = (*sigInvar)(2) = 0.;
           };
   }
  else if (sigInvar != NULL) {delete sigInvar;sigInvar=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

  // positions: sont toujours en dimensions absolues donc ont la même dimension
  M0 = ptintmec.M0;
  Mt = ptintmec.Mt;
  Mtdt = ptintmec.Mtdt;
  mail = ptintmec.mail;
  nele = ptintmec.nele;
  npti = ptintmec.npti;

  // --- les temps cpu
  tpsMetrique=ptintmec.tpsMetrique;tps_cpu_loi_comp=ptintmec.tps_cpu_loi_comp;
 
};

// l'inverse: comme le conteneur d'arrivée est plus petit, il n'y a pas de complétion
// il faut que ptintmec comporte des tenseurs d'ordre 3 et this des tenseurs 1D
void PtIntegMecaInterne::Affectation_3D_a_1D(const PtIntegMecaInterne& ptintmec)
{ // vérif éventuelle des dimensions
 #ifdef MISE_AU_POINT
 { //  cas des pointeurs: la méthode est prévue pour des tenseurs déjà affectés
  if (ptintmec.epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de l'argument ne sont pas affecte: par exemple ptintmec.epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_3D_a_1D(.."; Sortie(1);};
  if (epsBB == NULL)
	  {cout << "\n *** erreur les tenseurs de this ne sont pas affecte: par exemple epsBB == NULL "
	        << "\n PtIntegMecaInterne::Affectation_3D_a_1D(.."; Sortie(1);};
  //  - les dimensions
  if (epsBB->Dimension() != 1)
	  {cout << "\n *** erreur l'ordre de this ("<<epsBB->Dimension() <<") est different de 1"
	        << "\n PtIntegMecaInterne::Affectation_3D_a_1D(.."; Sortie(1);};
  if (ptintmec.epsBB->Dimension() != 3) 
	  {cout << "\n *** erreur l'ordre de ptintmec.epsBB ("<< ptintmec.epsBB->Dimension() <<") est different de 3"
	        << "\n PtIntegMecaInterne::Affectation_3D_a_1D(.."; Sortie(1);};
  }
 #endif
  // pour tout ce qui est def
  ((Tenseur1BB*) epsBB)->Affectation_trans_dimension(*((const Tenseur3BB*) ptintmec.epsBB),false);
  ((Tenseur1BB*) depsBB)->Affectation_trans_dimension(*((const Tenseur3BB*) ptintmec.depsBB),false);
  ((Tenseur1BB*) deltaEpsBB)->Affectation_trans_dimension(*((const Tenseur3BB*) ptintmec.deltaEpsBB),false);
  ((Tenseur1HH*) sigHH)->Affectation_trans_dimension(*((const Tenseur3HH*) ptintmec.sigHH),false);
  ((Tenseur1HH*) sigHH_t)->Affectation_trans_dimension(*((const Tenseur3HH*) ptintmec.sigHH_t),false);
  
  //--- les defs équivalentes
  def_equi_t=ptintmec.def_equi_t; def_equi=ptintmec.def_equi;
  //--- les contraintes équivalentes
  sig_equi_t=ptintmec.sig_equi_t; sig_equi=ptintmec.sig_equi;
  // --- les modules
  module_compressibilite = ptintmec.module_compressibilite;
  module_cisaillement = ptintmec.module_cisaillement;
  // --- volume_pti
  volume_pti = ptintmec.volume_pti;

  // ---- puis les vecteurs
  
  if (ptintmec.epsInvar != NULL)
   { if (epsInvar == NULL) 
           {epsInvar = new Vecteur (1,0.); // init à 0 a priori
            (*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
           }
     else  {(*epsInvar)(1) = (*(ptintmec.epsInvar))(1);
           };
   }
  else if (epsInvar != NULL) {delete epsInvar;epsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.depsInvar != NULL)
   { if (depsInvar == NULL) 
           {depsInvar = new Vecteur (1,0.); // init à 0 a priori
            (*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
           }
     else  {(*depsInvar)(1) = (*(ptintmec.depsInvar))(1);
           };
   }
  else if (depsInvar != NULL) {delete depsInvar;depsInvar=NULL;}; 
      // sinon il est déjà null donc rien n'a faire

  if (ptintmec.sigInvar != NULL)
          { if (sigInvar == NULL) 
           {sigInvar = new Vecteur (1,0.); // init à 0 a priori
            (*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
           }
     else  {(*sigInvar)(1) = (*(ptintmec.sigInvar))(1);
           };
   }
  else if (sigInvar != NULL) {delete sigInvar;sigInvar=NULL;}; 
     // sinon il est déjà null donc rien n'a faire

  // positions: sont toujours en dimensions absolues donc ont la même dimension
  M0 = ptintmec.M0;
  Mt = ptintmec.Mt;
  Mtdt = ptintmec.Mtdt;
  mail = ptintmec.mail;
  nele = ptintmec.nele;
  npti = ptintmec.npti;

  // --- les temps cpu
  tpsMetrique=ptintmec.tpsMetrique;tps_cpu_loi_comp=ptintmec.tps_cpu_loi_comp;
 
};
	     
// surcharge de l'operateur de lecture
istream & operator >> (istream & entree, PtIntegMecaInterne & pti)
  { // vérification du type
    string nom;
    entree >> nom;
   #ifdef MISE_AU_POINT
    if (nom != "PtIntegMecaInterne")
     		{	cout << "\nErreur, en lecture d'une instance  PtIntegMecaInterne "
	             << " on attendait PtIntegMecaInterne et on a lue: " << nom ;
      			cout << "istream & operator >> (istream & entree, PtIntegMecaInterne & pti)\n";
      			Sortie(1);
     		};
   #endif
    // puis lecture des différents éléments
    entree >> nom; (pti.epsBB)->Lecture(entree); 
    entree >> nom; (pti.depsBB)->Lecture(entree);
    entree >> nom; (pti.deltaEpsBB)->Lecture(entree);
    entree >> nom; (pti.sigHH)->Lecture(entree);
    entree >> nom; (pti.sigHH_t)->Lecture(entree);
    // -- def equi
    entree >> nom >> pti.def_equi(1) >> nom >> pti.def_equi(2) >> nom >> pti.def_equi(3)>> nom >> pti.def_equi(4);
	   entree >> nom >> pti.def_equi_t(1) >> nom >> pti.def_equi_t(2) >> nom >> pti.def_equi_t(3)>> nom >> pti.def_equi_t(4);
    // -- sig equi
    entree >> nom >> pti.sig_equi(1) >> nom >> pti.sig_equi(2) ;
    entree >> nom >> pti.sig_equi_t(1) >> nom >> pti.sig_equi_t(2);
    // -- module
    entree >> nom >> pti.module_compressibilite >> pti.module_cisaillement;
    entree >> nom >> pti.volume_pti;
    // lecture éventuelle des invariants
    int existe=0;
    entree >> nom >> existe;
   
    if (existe ==0)
     {if (pti.epsInvar != NULL) {delete pti.epsInvar;pti.epsInvar=NULL;};}
    else 
     {if (pti.epsInvar == NULL) pti.epsInvar = new Vecteur ();
      entree >> *(pti.epsInvar);
     };
   
    if (existe ==0)
     {if (pti.depsInvar != NULL) {delete pti.depsInvar;pti.depsInvar=NULL;};}
    else 
     {if (pti.depsInvar == NULL) pti.depsInvar = new Vecteur ();
      entree >> *(pti.depsInvar);
     };
   
    if (existe ==0)
     {if (pti.sigInvar != NULL) {delete pti.sigInvar;pti.sigInvar=NULL;};}
    else 
     {if (pti.sigInvar == NULL) pti.sigInvar = new Vecteur ();
      entree >> *(pti.sigInvar);
     };
    // les positions
    entree >> nom >> pti.M0 >> nom >>  pti.Mt >> nom >>  pti.Mtdt;
    entree >> nom >> pti.mail >> nom >> pti.nele >> nom >> pti.npti;
    // --- les temps cpu
    entree >> nom >> pti.tpsMetrique >> nom >> pti.tps_cpu_loi_comp;
    return entree;
  };
  
// surcharge de l'operateur d'ecriture 
ostream & operator << ( ostream & sort,const  PtIntegMecaInterne & pti)
  { // tout d'abord un indicateur donnant le type
    sort << "PtIntegMecaInterne " ; 
    // puis les différents éléments
    sort << "\n epsBB= ";  (pti.epsBB)->Ecriture(sort); 
    sort << "\n depsBB= ";  (pti.depsBB)->Ecriture(sort);
    sort << "\n deltaEpsBB= ";  (pti.deltaEpsBB)->Ecriture(sort);
    sort << "\n sigHH= ";  (pti.sigHH)->Ecriture(sort);
    sort << "\n sigHH_t= ";  (pti.sigHH_t)->Ecriture(sort);
    sort << "\n def_equi= " << pti.def_equi(1) << " def_duale_mises= " << pti.def_equi(2)
         << " def_duale_mises_max= " << pti.def_equi(3)<< " delta_def_equi= " << pti.def_equi(4);
    sort << "\n def_equi_t= " << pti.def_equi_t(1) << " def_duale_mises_t= " << pti.def_equi_t(2)
         << " def_duale_mises_max_t= " << pti.def_equi_t(3)<< " delta_def_equi= " << pti.def_equi_t(4);
    sort << "\n sig_Mises= " << pti.sig_equi(1) << " sig_Tresca= " << pti.sig_equi(2);
    sort << "\n sig_Mises_t= " << pti.sig_equi_t(1) << " sig_Tresca_t= " << pti.sig_equi_t(2);
    sort << "\n mod_compress= " << pti.module_compressibilite << " mod_cisaill= " << pti.module_cisaillement;
    sort << "\n volume_pti= "<< pti.volume_pti;
    // écriture éventuelle des invariants
    sort << "\n epsInvar= ";  if(pti.epsInvar == NULL) {sort << 0;} else {sort << "1 " << *(pti.epsInvar);};
    sort << "\n depsInvar= ";  if(pti.depsInvar == NULL) {sort << 0;} else {sort << "1 " << *(pti.depsInvar);};
    sort << "\n sigInvar= ";  if(pti.sigInvar == NULL) {sort << 0;} else {sort << "1 " << *(pti.sigInvar);};
    // les positions
    sort << "\n M0= "<< pti.M0 << " Mt= "<< pti.Mt << " Mtdt= "<< pti.Mtdt
         << " ,Mail "<< pti.mail<<" ,ele " << pti.nele <<" ,pti " << pti.npti  ;
    sort << "\n tpsmetrique= " << pti.tpsMetrique << " tpsLoiComp= " << pti.tps_cpu_loi_comp;
    return sort;
  };

		
    
    
    
