// FICHIER : LoiDeformationsPlanes.cp
// CLASSE : LoiDeformationsPlanes


// 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 "Debug.h"
#include "LesLoisDeComp.h"

# include <iostream>
using namespace std;  //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "TypeQuelconqueParticulier.h"
#include "TypeConsTens.h"
#include "NevezTenseurQ.h"
#include "Util.h"

#include "LoiDeformationsPlanes.h"


//==================== cas de la class de sauvegarde SaveResul ===================

// constructeur  par défaut à ne pas utiliser
LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes() :
	le_SaveResul(NULL) ,l_sigoHH(NULL),l_sigoHH_t(NULL),sigInvar(3),sigInvar_t(3),l_energ(),l_energ_t()
  { cout << "\n erreur, le constructeur par defaut ne doit pas etre utilise !"
	     << "\n LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes()";
    Sortie(1);
   }; 

// le constructeur courant
LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes
                        (SaveResul* l_des_SaveResul):
	le_SaveResul(NULL) ,l_sigoHH(NULL),l_sigoHH_t(NULL),sigInvar(3),sigInvar_t(3)
	,l_energ(),l_energ_t() 
	 { if (l_des_SaveResul != NULL) le_SaveResul = l_des_SaveResul->Nevez_SaveResul();
		// par défaut les contraintes sont en dim 3
      l_sigoHH=NevezTenseurHH(3,0);
      // idem interHH,  par défaut les contraintes sont en dim 3
      l_sigoHH_t =NevezTenseurHH(3,0.);
	   }; 

// constructeur de copie 
LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes
                                         (const LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes& sav ):
	le_SaveResul(NULL) ,l_sigoHH(NULL),l_sigoHH_t(NULL),sigInvar(sav.sigInvar),sigInvar_t(sav.sigInvar_t)
	,l_energ(sav.l_energ),l_energ_t(sav.l_energ_t)
	 { if (sav.le_SaveResul != NULL) {le_SaveResul=(sav.le_SaveResul)->Nevez_SaveResul();};
      // automatiquement les tenseurs sont non nul 
      l_sigoHH=NevezTenseurHH(*(sav.l_sigoHH));
      l_sigoHH_t =NevezTenseurHH(*(sav.l_sigoHH_t));
	  }; 
	        // destructeur
LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::~SaveResul_LoiDeformationsPlanes()
      { if (le_SaveResul != NULL) delete le_SaveResul;  
        delete l_sigoHH; 
		  delete l_sigoHH_t;
       };
  
// affectation
Loi_comp_abstraite::SaveResul &
     LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::operator = ( const Loi_comp_abstraite::SaveResul & a)
  { LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes& sav
                      = *((LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes*) &a);

    // on affecte si non dimensionné, sinon on crée à l'identique
    if (sav.le_SaveResul != NULL)
     { if (le_SaveResul == NULL)
         {le_SaveResul = sav.le_SaveResul->Nevez_SaveResul();}
       else
         {(*le_SaveResul) = *(sav.le_SaveResul);};
     };
    // idem pour les tenseurs
    if (sav.l_sigoHH != NULL)
     { if (l_sigoHH == NULL)
         l_sigoHH = NevezTenseurHH(*(sav.l_sigoHH));
       else
         *(l_sigoHH) = *(sav.l_sigoHH);
     };
    if (sav.l_sigoHH_t != NULL)
     { if (l_sigoHH_t == NULL)
         l_sigoHH_t = NevezTenseurHH(*(sav.l_sigoHH_t));
       else
         *(l_sigoHH_t) = *(sav.l_sigoHH_t);
     };
    // puis les grandeurs qui ne posent pas de pb
    sigInvar = sav.sigInvar;
    sigInvar_t = sav.sigInvar_t;
	   l_energ = sav.l_energ;
    l_energ_t = sav.l_energ_t;
    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 LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::Lecture_base_info 
                                                 (istream& ent,const int cas)
  {  // ici toutes les données sont toujours a priori variables
     // ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas
     string toto; ent >> toto;
     #ifdef MISE_AU_POINT	 	 
      if (toto != "S_D_Plane")
          { cout << "\n erreur en lecture du conteneur pour la loi de contrainte plane generique "
                 << " \n LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::Lecture_base_info(..";
            Sortie(1);     
          }
     #endif
     
     if (le_SaveResul != NULL)
	      le_SaveResul->Lecture_base_info(ent,cas);
      // la contrainte sauvegardée est celle stable uniquement
      l_sigoHH_t->Lecture(ent); // lecture du tenseur à t
      (*l_sigoHH) = (*l_sigoHH_t); // init à la même valeur de la contrainte à tdt
      // invariants de contraintes
      ent >> toto >> sigInvar_t(1) >> sigInvar_t(2) >> sigInvar_t(3);
      sigInvar = sigInvar_t; 
      // lecture de l'énergie à t
      ent >> l_energ_t; 
      l_energ = l_energ_t; // puis init au cas où de la valeur à tdt
    }; 

// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::Ecriture_base_info
                                                 (ostream& sort,const int cas)
   {  // ici toutes les données sont toujours a priori variables
      // ou en tout cas pour les méthodes appelées, elles sont gérées par le paramètre: cas
      sort << "\n S_D_Plane  ";
      // données de la loi
      if (le_SaveResul != NULL) 
			le_SaveResul->Ecriture_base_info(sort,cas);sort << "  ";
      // la contrainte sauvegardée est celle stable uniquement
      l_sigoHH_t->Ecriture(sort); sort << " " ;// écriture du tenseur
      // invariants de contraintes
      sort << " invarsig: " << sigInvar_t(1) << " " << sigInvar_t(2) <<" " << sigInvar_t(3) ;
      sort << " " << l_energ_t; // écriture de l'énergie à t
	 }; 
	        
	        // mise à jour des informations transitoires en définitif s'il y a convergence 
	        // par exemple (pour la plasticité par exemple)
void LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::TdtversT() 
  { if (le_SaveResul != NULL)    // mise à jour du conteneur éventuel de la loi interne
      le_SaveResul->TdtversT();
    (*l_sigoHH_t) = (*l_sigoHH);
    sigInvar_t = sigInvar;
    l_energ_t = l_energ;
	}; 

void LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::TversTdt() 
  { if (le_SaveResul != NULL)    // mise à jour du conteneur éventuel de la loi interne
      le_SaveResul->TversTdt();
    (*l_sigoHH) = (*l_sigoHH_t);
    sigInvar = sigInvar_t;
    l_energ = l_energ_t;
	}; 
			  
// affichage à l'écran des infos
void LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::Affiche() const 
{ cout << "\n SaveResul_LoiDeformationsPlanes: " ; 
  cout << "\n SaveResul: ";
  if (le_SaveResul != NULL) { cout << "\n "; le_SaveResul->Affiche();};
  cout << "\n l_sigoHH: ";
  l_sigoHH->Ecriture(cout);
  cout << "\n l_sigoHH_t: ";
  l_sigoHH_t->Ecriture(cout);
  cout << "\n invariants_contraintes_t: " << sigInvar_t(1) << " " << sigInvar_t(2) <<" " << sigInvar_t(3) ;
  cout << "\n l_energ: ";
  cout << l_energ;
  cout << "\n l_energ_t: ";
  cout << l_energ_t;
  cout << "\n .. fin SaveResul_LoiDeformationsPlanes:.. \n" ; 
};

//changement de base de toutes les grandeurs internes tensorielles stockées
// beta(i,j) represente les coordonnees de la nouvelle base naturelle gpB dans l'ancienne gB
// gpB(i) = beta(i,j) * gB(j), i indice de ligne, j indice de colonne
// gpH(i) = gamma(i,j) * gH(j)
void LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma)
{ // on ne s'intéresse qu'aux grandeurs tensorielles
  if (le_SaveResul != NULL) // s'il y a un conteneur affecté
      le_SaveResul->ChBase_des_grandeurs(beta,gamma);
  l_sigoHH->ChBase(gamma);
  l_sigoHH_t->ChBase(gamma);
  // les vecteurs sont un moyen de stockage mais pas dépendant de la base, donc pas de chgt de coordonnées
};

// procedure permettant de completer éventuellement les données particulières
// de la loi stockées
// au niveau du point d'intégration par exemple: exemple: un repère d'anisotropie
// completer est appelé apres sa creation avec les donnees du bloc transmis
// peut etre appeler plusieurs fois
Loi_comp_abstraite::SaveResul* LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes
         ::Complete_SaveResul(const BlocGen & bloc, const Tableau <Coordonnee>& tab_coor
                             ,const Loi_comp_abstraite* loi)
  {// on transmet au conteneur 3D interne
   const LoiDeformationsPlanes * loi_DP = (const LoiDeformationsPlanes*) loi;
   le_SaveResul->Complete_SaveResul(bloc,tab_coor,loi_DP->lois_interne);
   return this;
  };

	        // ---- récupération d'information: spécifique à certaine classe dérivée
double LoiDeformationsPlanes::SaveResul_LoiDeformationsPlanes::Deformation_plastique() 
   { cout << "\n pour l'instant cette option n'est pas implante dans le cas d'une loi"
          << "\n contrainte plane quelconque "
          << "\n double Loi_comp_abstraite::SaveResul_LoiDeformationsPlanes::Deformation_plastique()";
     Sortie(1);
     return 0.; // pour taire le warning, mais on ne passe jamais là
     };

//==================== fin du cas de la class de sauvegarde SaveResul ============

LoiDeformationsPlanes::LoiDeformationsPlanes ()  : // Constructeur par defaut
  Loi_comp_abstraite(LOI_DEFORMATIONS_PLANES,RIEN_CATEGORIE_LOI_COMP,2)
  ,lois_interne(NULL)
  ,d_sigma_deps_inter(NULL)
  // -- conteneur des métriques
  ,expli_3D(NULL),impli_3D(NULL),umat_cont_3D(NULL) 
  // -- les variables pointées dans les conteneurs, et leur pointeur associé éventuellement
  ,giB_0_3D(),giH_0_3D(),giB_t_3D(),giH_t_3D(),giB_tdt_3D(),giH_tdt_3D()   
  ,gijBB_0_3D(),gijHH_0_3D(),gijBB_t_3D(),gijHH_t_3D()
  ,gijBB_tdt_3D(),gijHH_tdt_3D()
  
  ,gradVmoyBB_t_3D(),gradVmoyBB_tdt_3D(),gradVBB_tdt_3D()
  ,gradVmoyBB_t_3D_P(NULL),gradVmoyBB_tdt_3D_P(NULL),gradVBB_tdt_3D_P(NULL)
  
  ,jacobien_tdt_3D(0.),jacobien_0_3D(0.)
  
  
       // les vrais tableaux associés aux tableaux de pointeurs
  ,d_giB_tdt_3D(),d_giH_tdt_3D() 
  
  ,d_gijBB_tdt_3D(),d2_gijBB_tdt_3D(),d_gijHH_tdt_3D()
  ,d_gijBB_tdt_3D_P(NULL),d2_gijBB_tdt_3D_P(NULL),d_gijHH_tdt_3D_P(NULL)
  
  ,d_jacobien_tdt_3D(NULL)
  
  ,d_gradVmoyBB_t_3D(),d_gradVmoyBB_tdt_3D(),d_gradVBB_t_3D(),d_gradVBB_tdt_3D()
  ,d_gradVmoyBB_t_3D_P(NULL),d_gradVmoyBB_tdt_3D_P(NULL),d_gradVBB_t_3D_P(NULL),d_gradVBB_tdt_3D_P(NULL)
		 
  // puis les grandeurs hors métriques
  ,sig_HH_t_3D(),sig_HH_3D(),Deps_BB_3D(),eps_BB_3D(),delta_eps_BB_3D()
  ,d_eps_BB_3D_P(),d_sig_HH_3D_P()
  ,d_eps_BB_3D(),d_sig_HH_3D(),d_sigma_deps_3D()
  
     // un conteneur d'un point d'intégration courant
  ,ptintmeca(3)

    { // conteneurs des métriques
	   // a priori seules les grandeurs principales sont affecté
	   expli_3D = new Met_abstraite::Expli_t_tdt  // constructeur normal
                          (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D
                          ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D
                          ,&gijBB_tdt_3D,&gijHH_tdt_3D
                          ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut
                          ,&d_gijBB_tdt_3D_P,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D);
      impli_3D = new  Met_abstraite::Impli  // constructeur normal 
                       (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&d_giB_tdt_3D,&giH_tdt_3D,&d_giH_tdt_3D
                        ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D,&gijBB_tdt_3D,&gijHH_tdt_3D
                        ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut
                        ,&d_gijBB_tdt_3D_P
								                ,d2_gijBB_tdt_3D_P // pas affecté par défaut
								                ,&d_gijHH_tdt_3D_P
                        ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D,&d_jacobien_tdt_3D
                        ,d_gradVmoyBB_t_3D_P,d_gradVmoyBB_tdt_3D_P     // pas affecté par défaut
		  	               ,d_gradVBB_t_3D_P,d_gradVBB_tdt_3D_P);	        // pas affecté par défaut
	   umat_cont_3D = new Met_abstraite::Umat_cont  // constructeur normal
                          (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D
                          ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D
                          ,&gijBB_tdt_3D,&gijHH_tdt_3D
                          ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P      // pas affecté par défaut
                          ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D);
		// on ajoute les invariants au pt integ courant
		ptintmeca.Change_statut_Invariants_contrainte (true);						  
	 };
	
// Constructeur de copie
LoiDeformationsPlanes::LoiDeformationsPlanes (const LoiDeformationsPlanes& loi) :
   Loi_comp_abstraite(loi)
   ,lois_interne(NULL)
	,d_sigma_deps_inter(NULL)
	
  // -- conteneur des métriques: ce sont des pointeurs, pour l'instant on ne les affecte pas
  ,expli_3D(NULL),impli_3D(NULL),umat_cont_3D(NULL) 
  // -- les variables pointées dans les conteneurs
  ,giB_0_3D(loi.giB_0_3D),giH_0_3D(loi.giH_0_3D),giB_t_3D(loi.giB_t_3D),giH_t_3D(loi.giH_t_3D) 
  ,giB_tdt_3D(loi.giB_tdt_3D),d_giB_tdt_3D(loi.d_giB_tdt_3D),giH_tdt_3D(loi.giH_tdt_3D)
  ,d_giH_tdt_3D(loi.d_giH_tdt_3D),gijBB_0_3D(loi.gijBB_0_3D),gijHH_0_3D(loi.gijHH_0_3D) 
  ,gijBB_t_3D(loi.gijBB_t_3D),gijHH_t_3D(loi.gijHH_t_3D),gijBB_tdt_3D(loi.gijBB_tdt_3D)
  ,gijHH_tdt_3D(loi.gijHH_tdt_3D),gradVmoyBB_t_3D(loi.gradVmoyBB_t_3D)
  ,gradVmoyBB_tdt_3D(loi.gradVmoyBB_tdt_3D),gradVBB_tdt_3D(loi.gradVBB_tdt_3D)
  ,jacobien_0_3D(loi.jacobien_0_3D),d_jacobien_tdt_3D(loi.d_jacobien_tdt_3D)
  ,d_gradVBB_t_3D_P(loi.d_gradVBB_t_3D_P),d_gradVBB_tdt_3D_P(loi.d_gradVBB_tdt_3D_P)
       // avec les vrais tableaux associés aux tableaux de pointeurs: ici uniquement le dimensionnement
  ,d_gijBB_tdt_3D(loi.d_gijBB_tdt_3D),d2_gijBB_tdt_3D(loi.d2_gijBB_tdt_3D)
  ,d_gijHH_tdt_3D(loi.d_gijHH_tdt_3D)
  ,d_gradVmoyBB_t_3D(loi.d_gradVmoyBB_t_3D),d_gradVmoyBB_tdt_3D(loi.d_gradVmoyBB_tdt_3D)
  ,d_gradVBB_t_3D(loi.d_gradVBB_t_3D),d_gradVBB_tdt_3D(loi.d_gradVBB_tdt_3D)
		 
  // puis les grandeurs hors métriques, pour les tableaux de pointeurs, c'est uniquement du dimensionnement
  ,sig_HH_t_3D(loi.sig_HH_t_3D),sig_HH_3D(loi.sig_HH_3D),Deps_BB_3D(loi.Deps_BB_3D)
  ,eps_BB_3D(loi.eps_BB_3D),delta_eps_BB_3D(loi.delta_eps_BB_3D)
  ,d_eps_BB_3D_P(loi.d_eps_BB_3D_P),d_sig_HH_3D_P(loi.d_sig_HH_3D_P)
  ,d_eps_BB_3D(loi.d_eps_BB_3D),d_sig_HH_3D(loi.d_sig_HH_3D),d_sigma_deps_3D(loi.d_sigma_deps_3D)
     // un conteneur d'un point d'intégration courant
  ,ptintmeca(loi.ptintmeca)
	
     { lois_interne = loi.lois_interne->Nouvelle_loi_identique();
	    // association des pointeurs de grandeurs si nécessaire		 
		if (loi.gradVmoyBB_t_3D_P != NULL) {gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;}; 
		if (loi.gradVmoyBB_tdt_3D_P != NULL) {gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;}; 
		if (loi.gradVBB_tdt_3D_P != NULL) {gradVBB_tdt_3D_P = &gradVBB_tdt_3D;}; 
		 
	    // def des tableaux de pointeurs pour les conteneurs de métriques
		
		 // -- cas des tableaux de pointeurs, ils ont déjà la bonne dimension
		int ta_d_gijBB_tdt_3D = loi.d_gijBB_tdt_3D.Taille();
		for (int i=1;i<= ta_d_gijBB_tdt_3D;i++) 
				d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i));

		if (loi.d2_gijBB_tdt_3D_P!= NULL)
		 { int tai_d2_gijBB_tdt_3D = d2_gijBB_tdt_3D.Taille1();
		   d2_gijBB_tdt_3D_P = new Tableau2<TenseurBB *> (tai_d2_gijBB_tdt_3D);
		   int taj_d2_gijBB_tdt_3D = d2_gijBB_tdt_3D.Taille2();
		   for (int i=1;i<= tai_d2_gijBB_tdt_3D;i++)
		     for (int j=1;j<= taj_d2_gijBB_tdt_3D;j++) 
		       (*d2_gijBB_tdt_3D_P)(i,j) = &(d2_gijBB_tdt_3D(i,j)); 
		 };		 
			 
		int ta_d_gijHH_tdt_3D = d_gijHH_tdt_3D.Taille();
		for (int i=1;i<= ta_d_gijHH_tdt_3D;i++) 
				d_gijHH_tdt_3D_P(i) = &(d_gijHH_tdt_3D(i));
			  
		if (loi.d_gradVmoyBB_t_3D_P != NULL)
		 { int ta_d_gradVmoyBB_t_3D = d_gradVmoyBB_t_3D.Taille();
		   d_gradVmoyBB_t_3D_P = new Tableau<TenseurBB *> (ta_d_gradVmoyBB_t_3D);
			for (int i=1;i<= ta_d_gradVmoyBB_t_3D;i++) 
				(*d_gradVmoyBB_t_3D_P)(i) = &(d_gradVmoyBB_t_3D(i)); 
		 };		 
			 
		if (loi.d_gradVmoyBB_tdt_3D_P != NULL)
		 { int ta_d_gradVmoyBB_tdt_3D = d_gradVmoyBB_tdt_3D.Taille();
		   d_gradVmoyBB_tdt_3D_P = new Tableau<TenseurBB *> (ta_d_gradVmoyBB_tdt_3D);
			for (int i=1;i<= ta_d_gradVmoyBB_tdt_3D;i++) 
				(*d_gradVmoyBB_tdt_3D_P)(i) = &(d_gradVmoyBB_tdt_3D(i)); 
		 };		 
			 
		if (loi.d_gradVBB_t_3D_P != NULL)
		 { int ta_d_gradVBB_t_3D = d_gradVBB_t_3D.Taille();
		   d_gradVBB_t_3D_P = new Tableau<TenseurBB *> (ta_d_gradVBB_t_3D);
			for (int i=1;i<= ta_d_gradVBB_t_3D;i++) 
				(*d_gradVBB_t_3D_P)(i) = &(d_gradVBB_t_3D(i)); 
		 };		 
			 
		if (loi.d_gradVBB_tdt_3D_P != NULL)
		 { int ta_d_gradVBB_tdt_3D = d_gradVBB_tdt_3D.Taille();
		   d_gradVBB_tdt_3D_P = new Tableau<TenseurBB *> (ta_d_gradVBB_tdt_3D);
			for (int i=1;i<= ta_d_gradVBB_tdt_3D;i++) 
				(*d_gradVBB_tdt_3D_P)(i) = &(d_gradVBB_tdt_3D(i));
		 };		 
		
	   // conteneurs des métriques
	   // a priori seules les grandeurs principales sont affecté
	   expli_3D = new Met_abstraite::Expli_t_tdt  // constructeur normal
                          (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D
                          ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D
                          ,&gijBB_tdt_3D,&gijHH_tdt_3D
                          ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut
                          ,&d_gijBB_tdt_3D_P,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D);
    impli_3D = new  Met_abstraite::Impli  // constructeur normal
                       (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&d_giB_tdt_3D,&giH_tdt_3D,&d_giH_tdt_3D
                        ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D,&gijBB_tdt_3D,&gijHH_tdt_3D
                        ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P // pas affecté par défaut
                        ,&d_gijBB_tdt_3D_P
								                ,d2_gijBB_tdt_3D_P // pas affecté par défaut
								                ,&d_gijHH_tdt_3D_P
                        ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D,&d_jacobien_tdt_3D
                        ,d_gradVmoyBB_t_3D_P,d_gradVmoyBB_tdt_3D_P     // pas affecté par défaut
		  	               ,d_gradVBB_t_3D_P,d_gradVBB_tdt_3D_P);	        // pas affecté par défaut
	   umat_cont_3D = new Met_abstraite::Umat_cont  // constructeur normal
                          (&giB_0_3D,&giH_0_3D,&giB_t_3D,&giH_t_3D,&giB_tdt_3D,&giH_tdt_3D
                          ,&gijBB_0_3D,&gijHH_0_3D,&gijBB_t_3D,&gijHH_t_3D
                          ,&gijBB_tdt_3D,&gijHH_tdt_3D
                          ,gradVmoyBB_t_3D_P,gradVmoyBB_tdt_3D_P,gradVBB_tdt_3D_P      // pas affecté par défaut
                          ,&jacobien_tdt_3D,&jacobien_t_3D,&jacobien_0_3D);
			 
	   // puis les tableaux de pointeurs de grandeurs hors métriques
		int ta_d_eps_BB_3D = d_eps_BB_3D.Taille();
		for (int i=1;i<= ta_d_eps_BB_3D;i++) 
		    d_eps_BB_3D_P(i) = &(d_eps_BB_3D(i)); 
			 
		int ta_d_sig_HH_3D = d_sig_HH_3D.Taille();
		for (int i=1;i<= ta_d_sig_HH_3D;i++) 
		    d_sig_HH_3D_P(i) = &(d_sig_HH_3D(i)); 
	  
		};

LoiDeformationsPlanes::~LoiDeformationsPlanes ()
// Destructeur 
     { if (lois_interne != NULL) delete lois_interne;
       if (d_sigma_deps_inter != NULL) delete d_sigma_deps_inter;

		 // les conteneurs de pointeurs:
		 delete expli_3D;delete  impli_3D; delete umat_cont_3D;
		 
		 // pour les grandeurs de base, pas de new, donc pas de delete
		 
		 // pour les tableaux de pointeurs, idem s'ils ne sont pas addressé par un pointeur
		 // sinon il faut détruire le tableau

		 if (d2_gijBB_tdt_3D_P!= NULL) delete d2_gijBB_tdt_3D_P;   	    
		 if (d_gradVmoyBB_t_3D_P!= NULL) delete d_gradVmoyBB_t_3D_P;  	  
		 if (d_gradVmoyBB_tdt_3D_P!= NULL) delete d_gradVmoyBB_tdt_3D_P;       
		 if (d_gradVBB_t_3D_P!= NULL) delete d_gradVBB_t_3D_P;     
		 if (d_gradVBB_tdt_3D_P!= NULL) delete d_gradVBB_tdt_3D_P;
		 
	};		    

// def d'une instance de données spécifiques, et initialisation
// valable une fois que les différentes lois internes sont définit
LoiDeformationsPlanes::SaveResul * LoiDeformationsPlanes::New_et_Initialise()  
   { // on crée éventuellement le conteneur pour la loi
     SaveResul* le_SaveResul = NULL; 
	    if (lois_interne != NULL) le_SaveResul = lois_interne->New_et_Initialise();
     // on ramène la bonne instance
     LoiDeformationsPlanes::SaveResul * retour =  new SaveResul_LoiDeformationsPlanes(le_SaveResul);
     // retour
	    return retour;
	  };

// Lecture des donnees de la classe sur fichier
void LoiDeformationsPlanes::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D
                                             ,LesFonctions_nD& lesFonctionsnD)
  { // vérification que la dimension de l'espace est 3D
    if (ParaGlob::Dimension() != 3)
     { cout << "\n *** erreur : la dimension de l'espace doit etre 3, "
            << " pour pouvoir utiliser une loi de contrainte plane ";
       if (ParaGlob::NiveauImpression() > 5)
        cout << "\n LoiDeformationsPlanes::LectureDonneesParticulieres (... ";
       Sortie(1);
     };
											 
    // lecture du nom de la loi
    string st2,nom3;
    *(entreePrinc->entree)  >> st2;
    // definition de la loi
    LoiAbstraiteGeneral * pt = LesLoisDeComp::Def_loi(st2);
    lois_interne = (Loi_comp_abstraite*) LesLoisDeComp::Def_loi(st2);
    pt = lois_interne;

    // --- lecture des informations particulières propres à la  loi   
    entreePrinc->NouvelleDonnee(); // prepa du flot de lecture
    pt->LectureDonneesParticulieres (entreePrinc,lesCourbes1D,lesFonctionsnD);
    // on s'occupe de la catégorie après la lecture des informations particulières (variable def dans LoiAbstraiteGeneral)
	   LoiAbstraiteGeneral::categorie_loi_comp = pt->Id_categorie();
    if (!GroupeMecanique(categorie_loi_comp))
      { cout << "\n erreur1 en lecture des lois constitutives elementaire"
             << " d'une loi LoiDeformationsPlanes"
             << "\n la loi lue: " << pt->Nom_comport()
             << " n'est pas une loi mecanique, elle fait partie "
             << " de la categorie: "<< Nom_categorie_loi_comp(categorie_loi_comp);
        entreePrinc->MessageBuffer("**erreur LoiDeformationsPlanes::LectureDonneesParticulieres (...**");
        throw (UtilLecture::ErrNouvelleDonnee(-1));
        Sortie(1);     
      };
    
    // si la loi est thermo dépendante on indique que la loi de contrainte plane l'est aussi
    if (((Loi_comp_abstraite*)pt)->ThermoDependante()) this->thermo_dependant = true;
       
    // lecture de l'indication de fin de lecture
    if(strstr(entreePrinc->tablcar,"fin_loi_deformation_plane")!=0)
      entreePrinc->NouvelleDonnee();

    // appel au niveau de la classe mère
    Loi_comp_abstraite::Lecture_type_deformation_et_niveau_commentaire
                 (*entreePrinc,lesFonctionsnD,false);
  };

// affichage de la loi
void LoiDeformationsPlanes::Affiche() const 
  {  cout << "\n .......  loi de comportement LoiDeformationsPlanes ........";	  	
     cout << "\n -- partie relative a la loi interne: ";
     lois_interne->Affiche();
     cout << "\n .......  fin de la loi de comportement LoiDeformationsPlanes ........";     
  };
            
// affichage et definition interactive des commandes particulières à chaques lois
void LoiDeformationsPlanes::Info_commande_LoisDeComp(UtilLecture& entreePrinc)
 {  ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
    sort << "\n# .......  loi de comportement LoiDeformationsPlanes ........"
         << "\n#  a)sur la premiere ligne on indique  : "
         << "\n#     Obligatoirement:  le nom de la loi de comportement 3D sur laquelle on veut imposer une condition de deformation plane "
         << "\n#								La suite des informations est relative a la loi 3D, voir donc la syntaxe associee"
         << "\n#										   "
         << "\n#	a la fin de fin de la loi, on indique un mot cle de fin		";
   sort  << "\n          fin_loi_deformation_plane   # ----- fin de Loi de deformation plane " << endl;
			
  };  		  	  

// test si la loi est complete
int LoiDeformationsPlanes::TestComplet()
    { int ret = LoiAbstraiteGeneral::TestComplet();
      ret *=lois_interne->TestComplet();
     return ret; 
    }; 
		          
// calcul d'un module d'young équivalent à la loi, ceci pour un
// chargement nul
double LoiDeformationsPlanes::Module_young_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex)
  { SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveResul_ex);
    double E =lois_interne->Module_young_equivalent(temps,def,save_resul.le_SaveResul);
    return E;
   }; 
		          
// récupération d'un module de compressibilité équivalent à la loi, ceci pour un chargement nul
// il s'agit ici de la relation -pression = sigma_trace/3. = module de compressibilité * I_eps
double LoiDeformationsPlanes::Module_compressibilite_equivalent(Enum_dure temps,const Deformation & def ,SaveResul * saveResul_ex)
  { SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveResul_ex);
    double module_compressibilite =lois_interne->Module_compressibilite_equivalent(temps,def,save_resul.le_SaveResul);
    return module_compressibilite;
   }; 
		  	
// activation des données des noeuds et/ou elements nécessaires au fonctionnement de la loi
// exemple: mise en service des ddl de température aux noeuds
// ici la grandeur qui sert de proportion entre la première loi et la seconde
void LoiDeformationsPlanes::Activation_donnees(Tableau<Noeud *>& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt)
  { // appel relatif à la lois associée
    lois_interne->Activation_donnees(tabnoeud,dilatation,lesPtMecaInt);    
    // appel de la méthode de la classe mère
    Loi_comp_abstraite::Activ_donnees(tabnoeud,dilatation,lesPtMecaInt);     
   };
   
// récupération des grandeurs particulière (hors ddl )
// correspondant à liTQ
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void LoiDeformationsPlanes::Grandeur_particuliere
              (bool absolue,List_io<TypeQuelconque>& liTQ,Loi_comp_abstraite::SaveResul * saveDon,list<int>& decal) const
 { // tout d'abord on récupère le conteneur
   SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveDon);
   int dim = ParaGlob::Dimension();
   // maintenant on s'occupe des grandeurs de la loi  elle même,
   List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end();
   list<int>::iterator idecal=decal.begin();
   for (itq=liTQ.begin();itq!=itqfin;itq++,idecal++)
    {TypeQuelconque& tipParticu = (*itq); // pour simplifier
     if (tipParticu.EnuTypeQuelconque().Nom_vide()) // veut dire que c'est un enum pur
     { EnumTypeQuelconque enuTQ = tipParticu.EnuTypeQuelconque().EnumTQ();

       SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveDon);
       // 2) -----cas des contraintes individuelles à chaque loi à t uniquement
       if (enuTQ == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
          // en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique
          // et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé
          // interne il faut que tous les tenseurs soient du même ordre
          TenseurHH* sigHH = (save_resul.l_sigoHH_t); // pour simplifier
          if (Dabs(sigHH->Dimension()) != dim)
            {tyTQ(1+(*idecal)).Affectation_trans_dimension(*sigHH,true);
            }
          else // cas même dimension
            {tyTQ(1+(*idecal)) = (*(save_resul.l_sigoHH_t));
            };
          (*idecal)++;
			     };
       // 3) -----cas de l'énergie élastique individuelles à chaque loi à t 
       if (enuTQ == ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
          tyTQ(1+(*idecal)) = save_resul.l_energ_t.EnergieElastique();  (*idecal)++;
         };
       // 4) -----cas de l'énergie plastique individuelles à chaque loi à t 
       if (enuTQ == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
          tyTQ(1+(*idecal)) = save_resul.l_energ_t.DissipationPlastique();  (*idecal)++;
         };
       // 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t 
       if (enuTQ == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
          tyTQ(1+(*idecal)) = save_resul.l_energ_t.DissipationVisqueuse();  (*idecal)++;
         };
       };
      };
   // puis appel pour la lois associée
   lois_interne->Grandeur_particuliere(absolue,liTQ,save_resul.le_SaveResul,decal);
  };

// récupération de la liste de tous les grandeurs particulières
// ces grandeurs sont ajoutées à la liste passées en paramètres
// absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière
void LoiDeformationsPlanes::ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& liTQ) const
{  // tout d'abord on passe en revue les grandeurs des lois associées
   // ** au niveau de l'exécution ce sera l'inverse de cette ordre: on s'occupera d'abord de this puis les lois internes
	  // ** mais a priori cela n'a pas d'importance
   // appel de la loi 3D
	  int nb_loi = 1; // pour être identique pour la loi additive !!
   lois_interne->ListeGrandeurs_particulieres(absolue,liTQ);
	
   // ... maintenant on s'occupe des grandeurs de la loi  elle même,   
   // 1) -----cas des contraintes individuelles à la loi à t uniquement
   {// ici il s'agit du tenseur des contraintes du pas précédent ou du pas actuel
    //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
	   {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
	    for (itq=liTQ.begin();itq!=itqfin;itq++)
       if ((*itq).EnuTypeQuelconque() == CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_TenseurHH& tyTQ= *((Tab_Grandeur_TenseurHH*) (*itq).Grandeur_pointee()); // pour simplifier
		        int taille = tyTQ.Taille()+nb_loi;
			       tyTQ.Change_taille(taille); nexistePas = false;
		      };
     if (nexistePas)
	     {TenseurHH* tens = NevezTenseurHH(ParaGlob::Dimension()); // un tenseur typique
       // en fait on utilise systématiquement un tenseur d'ordre le + élevé, car c'est le conteneur le plus générique
       // et Tab_Grandeur_TenseurHH ne supporte que des tenseurs du même ordre donc s'il y a un tenseur élevé
       // interne il faut que tous les tenseurs soient du même ordre
       Tab_Grandeur_TenseurHH gtHH(*tens,nb_loi); 
       // def d'un type quelconque représentatif 
       TypeQuelconque typQ(CONTRAINTE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,gtHH);
       liTQ.push_back(typQ);
       delete tens; // car on n'en a plus besoin
		    };
    };
   };
   // pour toutes les énergies
   Tableau <double> tab_double(nb_loi);   
   Tab_Grandeur_scalaire_double grand_courant(tab_double); 
   // 3) -----cas de l'énergie élastique individuelles à chaque loi à t uniquement
   //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
	  {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
	   for (itq=liTQ.begin();itq!=itqfin;itq++)
       if ((*itq).EnuTypeQuelconque() == ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
		        int taille = tyTQ.Taille()+nb_loi;
			       tyTQ.Change_taille(taille); nexistePas = false;
		      };
	   if (nexistePas)
	      {TypeQuelconque typQ1(ENERGIE_ELASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant);
        liTQ.push_back(typQ1);
		     };
   };
   // 4) -----cas de l'énergie plastique individuelles à chaque loi à t uniquement
   //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
	  {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
	   for (itq=liTQ.begin();itq!=itqfin;itq++)
       if ((*itq).EnuTypeQuelconque() == ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
		        int taille = tyTQ.Taille()+nb_loi;
			       tyTQ.Change_taille(taille); nexistePas = false;
		      };
    if (nexistePas)
	      {TypeQuelconque typQ1(ENERGIE_PLASTIQUE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant);
        liTQ.push_back(typQ1);
		     };
   };
   // 5) -----cas de l'énergie visqueuse individuelles à chaque loi à t uniquement
   //on regarde si ce type d'info existe déjà: si oui on augmente la taille du tableau, si non on crée
	  {List_io<TypeQuelconque>::iterator itq,itqfin=liTQ.end(); bool nexistePas = true;
	   for (itq=liTQ.begin();itq!=itqfin;itq++)
       if ((*itq).EnuTypeQuelconque() == ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T)
        { Tab_Grandeur_scalaire_double& tyTQ= *((Tab_Grandeur_scalaire_double*) (*itq).Grandeur_pointee()); // pour simplifier
		        int taille = tyTQ.Taille()+nb_loi;
			       tyTQ.Change_taille(taille); nexistePas = false;
		      };
	   if (nexistePas)
	       {TypeQuelconque typQ1(ENERGIE_VISQUEUSE_INDIVIDUELLE_A_CHAQUE_LOI_A_T,SIG11,grand_courant);
         liTQ.push_back(typQ1);
		      };
   };
};
  
	   //----- lecture écriture de restart -----
	   // cas donne le niveau de la récupération
       // = 1 : on récupère tout
       // = 2 : on récupère uniquement les données variables (supposées comme telles)
 void LoiDeformationsPlanes::Lecture_base_info_loi(istream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
                                             ,LesFonctions_nD& lesFonctionsnD)
  { if (cas == 1) 
     { string st1; string nom;
       ent >> st1 >> nom ;
 	   if (st1 != "LOI_DEFORMATIONS_PLANES")
	     { cout << "\n erreur en lecture de la loi : LOI_DEFORMATIONS_PLANES, on attendait le mot cle : LOI_DEFORMATIONS_PLANES "
	            << " et on a lue: " << st1
					<< "\n LoiDeformationsPlanes::Lecture_base_info_loi(...";
	       Sortie(1);
	      };

       // on lit la loi 3D
       ent >> st1; lois_interne = (Loi_comp_abstraite *) LesLoisDeComp::Def_loi(st1);
       lois_interne->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
      }
    else
     { // on utilise directement la  loi déjà défini
       lois_interne->Lecture_base_info_loi(ent,cas,lesRef,lesCourbes1D,lesFonctionsnD);
     };
 };

       // cas donne le niveau de sauvegarde
       // = 1 : on sauvegarde tout
       // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LoiDeformationsPlanes::Ecriture_base_info_loi(ostream& sort,const int cas)
  { if (cas == 1) 
     { sort << "\n  LOI_DEFORMATIONS_PLANES  loi_associe: ";

       sort << lois_interne->Nom_comport() << "  "; lois_interne->Ecriture_base_info_loi(sort,cas);
     }
    else
     { lois_interne->Ecriture_base_info_loi(sort,cas);
     };
  };
            

 // ========== codage des METHODES VIRTUELLES  protegees:================
 
        // calcul des contraintes a t+dt
void LoiDeformationsPlanes::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl,
             TenseurBB & gijBB_t,TenseurHH & gijHH_t,BaseB& giB,BaseH& gi_H, TenseurBB & epsBB_,
             TenseurBB & delta_epsBB,
             TenseurBB & gijBB_,TenseurHH & gijHH_,Tableau <TenseurBB *>& d_gijBB_,
             double& jacobien_0,double& jacobien,TenseurHH & sigHH
		  	,EnergieMeca & energ,const EnergieMeca & 
		  	,double& module_compressibilite,double&  module_cisaillement
		  	,const Met_abstraite::Expli_t_tdt& ex)
 { // récup du conteneur spécifique
   SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveResul);
   module_compressibilite=module_cisaillement=0.; // init
   energ.Inita(0.); // initialisation des énergies mises en jeux
   
   // initialisation du tenseurs contrainte
   sig_HH_3D.Inita(0.);
  
   // passage des informations spécifique à la loi le_SaveResul
   lois_interne->IndiqueSaveResult(save_resul.le_SaveResul); 
   lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
   lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
   // passage des métriques de l'ordre 2 vers 3
   Passage_metrique_ordre2_vers_3(ex);
   // passage des informations liées à la déformation  de 2 vers 3, et variation de volume éventuelle
   Vecteur* d_jacobien_tdt = NULL;      // ne sert pas ici
   Tableau <TenseurBB *>* d_epsBB=NULL; //   "    "
   Passage_deformation_volume_ordre2_vers_3(DepsBB,epsBB_,d_epsBB,delta_epsBB
                                                ,jacobien_0,jacobien,d_jacobien_tdt);
   
   lois_interne->Calcul_SigmaHH((*save_resul.l_sigoHH_t),Deps_BB_3D,tab_ddl,gijBB_t_3D,gijHH_t_3D,giB_tdt_3D,giH_tdt_3D
                          ,eps_BB_3D,delta_eps_BB_3D,
                            gijBB_tdt_3D,gijHH_tdt_3D,d_gijBB_tdt_3D_P,jacobien_0_3D,jacobien_tdt_3D,sig_HH_3D
                            ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite,module_cisaillement,*expli_3D
                            );
      
   // sig_HH_3D.Ecriture(cout);
            
   (*save_resul.l_sigoHH) = sig_HH_3D; // sauvegarde en locale
   // calcul des invariants de contrainte
   Tenseur3BH sigBH = gijBB_tdt_3D * sig_HH_3D;
   save_resul.sigInvar(1) =  sigBH.Trace();
   save_resul.sigInvar(2) =  sigBH.II();
   save_resul.sigInvar(3) =  sigBH.Det();
   
   energ = save_resul.l_energ; // récup des énergies
   // passage des tenseurs résultats à l'ordre 2
   ((Tenseur2HH*) &sigHH)->Affectation_3D_a_2D(sig_HH_3D);
   //	sigHH_tdt.Ecriture(cout);
   LibereTenseur();   
 };
        
        // calcul des contraintes a t+dt et de ses variations  
void LoiDeformationsPlanes::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& DepsBB,DdlElement & tab_ddl
            ,BaseB& giB_t,TenseurBB & gijBB_t,TenseurHH & gijHH_t
            ,BaseB& giB_tdt,Tableau <BaseB> & d_giB_tdt,BaseH& giH_tdt,Tableau <BaseH> & d_giH_tdt
            ,TenseurBB & epsBB_tdt,Tableau <TenseurBB *>& d_epsBB,
            TenseurBB & delta_epsBB,TenseurBB & gijBB_tdt,TenseurHH & gijHH_tdt,
		    Tableau <TenseurBB *>& d_gijBB_tdt,
		  	Tableau <TenseurHH *>& d_gijHH_tdt,double& jacobien_0,double& jacobien,
		  	Vecteur& d_jacobien_tdt,TenseurHH& sigHH_tdt,Tableau <TenseurHH *>& d_sigHH
		  	,EnergieMeca & energ,const EnergieMeca & 
		  	,double& module_compressibilite,double&  module_cisaillement
		  	,const Met_abstraite::Impli& ex)
 {  // récup du conteneur spécifique
    SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveResul);
    module_compressibilite=module_cisaillement=0.; // init
    energ.Inita(0.); // initialisation des énergies mises en jeux
	
    // on vérifie que le tableau de travail intermédiaire statique est correctement 
    // dimensionné sinon on le modifie   
    int taille = d_sigHH.Taille();

    // on affecte et/ou on redimensionne éventuellement les tableaux contraintes-déformation fonction du nombre de ddl
    // pour le passage 3D: on considère que tous les tableaux doivent avoir la même dimension: la même que dans le cas 2D
    int ta_d_sig_HH_3D = d_sig_HH_3D.Taille();
    if (ta_d_sig_HH_3D != taille)
      { // cela veut dire que tous les tableaux sont mal dimensionnés
      int ta_d_sig_HH = d_sigHH.Taille();
        d_sig_HH_3D.Change_taille(ta_d_sig_HH); d_sig_HH_3D_P.Change_taille(ta_d_sig_HH);
        for (int i=1;i<=ta_d_sig_HH;i++) {d_sig_HH_3D_P(i) = &(d_sig_HH_3D(i));}
      };
    for (int i=1;i<=ta_d_sig_HH_3D;i++) {d_sig_HH_3D_P(i)->Inita(0.);};
       
    // initialisation du tenseurs contrainte
    sig_HH_3D.Inita(0.);
    // passage des informations spécifique à la loi le_SaveResul
    lois_interne->IndiqueSaveResult(save_resul.le_SaveResul);
    lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
    lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours
    // passage des métriques de l'ordre 2 vers 3
    Passage_metrique_ordre2_vers_3(ex);
    // passage des informations liées à la déformation  de 2 vers 3, et variation de volume
    Passage_deformation_volume_ordre2_vers_3(DepsBB,epsBB_tdt,&d_epsBB,delta_epsBB
                                                 ,jacobien_0,jacobien,&d_jacobien_tdt);

    lois_interne->Calcul_DsigmaHH_tdt
                  ((*save_resul.l_sigoHH_t),Deps_BB_3D,tab_ddl,giB_t_3D,gijBB_t_3D,gijHH_t_3D
	                   ,giB_tdt_3D,d_giB_tdt_3D,giH_tdt_3D,d_giH_tdt_3D
							             ,eps_BB_3D,d_eps_BB_3D_P,delta_eps_BB_3D,gijBB_tdt_3D,gijHH_tdt_3D,d_gijBB_tdt_3D_P
		  	               ,d_gijHH_tdt_3D_P,jacobien_0_3D,jacobien_tdt_3D,d_jacobien_tdt_3D
							             ,sig_HH_3D,d_sig_HH_3D_P
                    ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite,module_cisaillement,*impli_3D
                  );
    // sig_HH_3D.Ecriture(cout);
			       
	   (*save_resul.l_sigoHH) = sig_HH_3D; // sauvegarde en locale
    // calcul des invariants de contrainte
    Tenseur3BH sigBH = gijBB_tdt_3D * sig_HH_3D;
    save_resul.sigInvar(1) =  sigBH.Trace();
    save_resul.sigInvar(2) =  sigBH.II();
    save_resul.sigInvar(3) =  sigBH.Det();
  
    energ = save_resul.l_energ; // récup des énergies
    // passage des tenseurs résultats à l'ordre 2
    ((Tenseur2HH*) &sigHH_tdt)->Affectation_3D_a_2D(sig_HH_3D);
    //	sigHH_tdt.Ecriture(cout);
    // récup de l'opérateur tangent
	   for (int k=1;k<=taille;k++)
       ((Tenseur2HH*) d_sigHH(k))->Affectation_3D_a_2D(*d_sig_HH_3D_P(k)); 
    LibereTenseur();
   //---debug
   //fichier.close();
   //---fin debug
 };
		  	
        // calcul des contraintes et ses variations  par rapport aux déformations a t+dt
        // en_base_orthonormee:  le tenseur de contrainte en entrée est  en orthonormee
        //                  le tenseur de déformation et son incrémentsont également en orthonormees
        //                 si = false: les bases transmises sont utilisées
        // ex: contient les éléments de métrique relativement au paramétrage matériel = X_(0)^a
void LoiDeformationsPlanes::Calcul_dsigma_deps (bool en_base_orthonormee, TenseurHH & sigHH_t,TenseurBB& DepsBB
            ,TenseurBB & epsBB_tdt,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien
		  	,TenseurHH& sigHH_tdt,TenseurHHHH& d_sigma_deps
		  	,EnergieMeca & energ,const EnergieMeca & 
		  	,double& module_compressibilite,double&  module_cisaillement
		  	,const Met_abstraite::Umat_cont& ex)
 { // on commence par créer un tenseur contrainte qui totalisera toutes les contraintes
   // le tenseurs est initialisé à 0.
//   int dim_tens = sigHH_tdt.Dimension();
//   TenseurHH * sigtotalHH = (NevezTenseurHH(dim_tens,0.));
//   TenseurHH * zeroHH = (NevezTenseurHH(dim_tens,0.));
//   TenseurHH * deltaSigHH = (NevezTenseurHH(dim_tens,0.)); // pour la variation de contraintes
   SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveResul);
   module_compressibilite=module_cisaillement=0.; // init
   energ.Inita(0.); // initialisation des énergies mises en jeux
   // redimentionnement éventuel pour le comportement tangent
   if (d_sigma_deps_inter != NULL)
         { if (d_sigma_deps_inter->Dimension() != d_sigma_deps.Dimension())
         	{ delete d_sigma_deps_inter; d_sigma_deps_inter = NevezTenseurHHHH(d_sigma_deps);}
         }
   else {d_sigma_deps_inter = NevezTenseurHHHH(d_sigma_deps);};
       
	  // initialisation du tenseurs contrainte
	  save_resul.l_sigoHH->Inita(0.);
   // initialisation du comportement tangent
   d_sigma_deps_inter->Inita(0.);
   // passage des informations spécifique à la loi le_SaveResul
   lois_interne->IndiqueSaveResult(save_resul.le_SaveResul); 
   lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
   lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours

	  lois_interne->Calcul_dsigma_deps (en_base_orthonormee, (*save_resul.l_sigoHH_t),DepsBB,epsBB_tdt,delta_epsBB,jacobien_0,jacobien
		  	              ,(*save_resul.l_sigoHH),*d_sigma_deps_inter
		  	              ,save_resul.l_energ,save_resul.l_energ_t,module_compressibilite,module_cisaillement,ex
                   );
	  energ = save_resul.l_energ; // récup des énergies
   // on sauvegarde la contrainte partielle totale
   sigHH_tdt=(*save_resul.l_sigoHH); 
   // récup de l'opérateur tangent
	  d_sigma_deps=*d_sigma_deps_inter;

   //    delete sigtotalHH; delete zeroHH;delete deltaSigHH;
   LibereTenseur();LibereTenseurQ();
 };


   
       // fonction interne utilisée par les classes dérivées de Loi_comp_abstraite
       // pour répercuter les modifications de la température
       // ici utiliser pour modifier la température des lois élémentaires
       // l'Enum_dure: indique quel est la température courante : 0 t ou tdt
 void LoiDeformationsPlanes::RepercuteChangeTemperature(Enum_dure temps)
  { lois_interne->temperature_0 = this->temperature_0;
    lois_interne->temperature_t = this->temperature_t;
    lois_interne->temperature_tdt = this->temperature_tdt;
    lois_interne->dilatation=dilatation;
    if (dilatation)
     {//  a- dimensionnement des tenseurs intermédiaires 
      int dim_tens = epsBB_therm->Dimension();
          // -- cas de la déformation
      if (lois_interne->epsBB_therm == NULL) { lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);}
      else if (lois_interne->epsBB_therm->Dimension() != dim_tens)
         { delete lois_interne->epsBB_therm;lois_interne->epsBB_therm = NevezTenseurBB(dim_tens);};
          // -- cas de la vitesse de déformation
      if (lois_interne->DepsBB_therm == NULL) { lois_interne->DepsBB_therm = NevezTenseurBB(dim_tens);}
      else if (lois_interne->DepsBB_therm->Dimension() != dim_tens)
       { delete lois_interne->DepsBB_therm;lois_interne->DepsBB_totale = NevezTenseurBB(dim_tens);};
      // b- affectation des tenseurs
      (*lois_interne->epsBB_therm)=(*epsBB_therm);
      (*lois_interne->DepsBB_therm)=(*DepsBB_therm);
     };
    lois_interne->RepercuteChangeTemperature(temps);
    switch (temps)
      { case TEMPS_0: 
         {lois_interne->temperature = &lois_interne->temperature_0;
          break;
          }
        case TEMPS_t: 
         {lois_interne->temperature = &lois_interne->temperature_t;
          break;
          }
        case TEMPS_tdt: 
         {lois_interne->temperature = &lois_interne->temperature_tdt;
          break;
          }
        default:
             { cout << "\n erreur, cas de temps non prevu !! "
                    << "\n LoiDeformationsPlanes::RepercuteChangeTemperature(...";
               Sortie(1);      
              };
      }; 

   };
	
void LoiDeformationsPlanes::CalculGrandeurTravail
                    (const PtIntegMecaInterne& ptintmec
                    ,const Deformation & def,Enum_dure temps,const ThermoDonnee& dTP
                    ,const Met_abstraite::Impli* ex_impli
                    ,const Met_abstraite::Expli_t_tdt* ex_expli_tdt
                    ,const Met_abstraite::Umat_cont* ex_umat
                    ,const List_io<Ddl_etendu>* exclure_dd_etend
                    ,const List_io<const TypeQuelconque *>* exclure_Q
                   )
{ // récup des infos spécifiques
  
  SaveResul_LoiDeformationsPlanes & save_resul = *((SaveResul_LoiDeformationsPlanes*) saveResul);
  // par défaut on active les invariants
  
  // ptintmeca concerne des tenseurs  d'ordres 2 donc il faut transformer en 3D 
  bool plusZero=true; // on ajoute des 0 pour les grandeurs manquantes
  // on commence par transférer le tout
  ptintmeca.Affectation_2D_a_3D(ptintmec,plusZero);
  // ensuite on traite les points particuliers
  // pour tout ce qui est def: l'ajout de 0 est ok
  // pour la contrainte à t on récupère la valeur sauvegardée, car c'est celle spécifique aux déformations planes
  (*ptintmeca.SigHH_t()) =  (*save_resul.l_sigoHH_t); 
  // pour les invariants de contraintes, on ne peut pas les recalculer, donc on récupère ce qui a été sauvegardé
  if (ptintmeca.Statut_Invariants_contrainte()) // le conteneur des invariants a pu être effacé par Affectation_2D_a_3D
     ptintmeca.SigInvar() =  save_resul.sigInvar_t; 
  // passage des informations spécifique à la loi le_SaveResul
  lois_interne->IndiqueSaveResult(save_resul.le_SaveResul);
  lois_interne->IndiquePtIntegMecaInterne(ptintmeca_en_cours);// idem pour ptintmeca
  lois_interne->IndiqueDef_en_cours(def_en_cours); // idem pour def en cours

  lois_interne->CalculGrandeurTravail(ptintmeca,def,temps,dTP
                                      ,ex_impli,ex_expli_tdt,ex_umat,exclure_dd_etend,exclure_Q); // passage  à la loi 3D
 }; 

// passage des grandeurs métriques de l'ordre 2 à 3: cas implicite
void LoiDeformationsPlanes::Passage_metrique_ordre2_vers_3(const Met_abstraite::Impli& ex)
{// on s'occupe du redimensionnement éventuel
	// on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D
	// la partie dépendant des vitesses: entre accolades pour pouvoir fermer 
	{if (ex.gradVmoyBB_t != NULL) {impli_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;}; 
	 if (ex.gradVmoyBB_tdt != NULL) {impli_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;}; 
	 if (ex.gradVBB_tdt != NULL) {impli_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;};
	
	 // on s'occupe tout d'abord des tableaux de vitesses qui peuvent ne pas exister
	 if (ex.d_gradVmoyBB_t != NULL) // cas où il existe
   { int tail=ex.d_gradVmoyBB_t->Taille();
     if (d_gradVmoyBB_t_3D_P == NULL) {d_gradVmoyBB_t_3D_P = new Tableau<TenseurBB *> (tail);
                                      impli_3D->d_gradVmoyBB_t = d_gradVmoyBB_t_3D_P;}
     else									  {d_gradVmoyBB_t_3D_P->Change_taille(tail);};
     d_gradVmoyBB_t_3D.Change_taille(tail);
     for (int i=1;i<= tail;i++)
       (*d_gradVmoyBB_t_3D_P)(i) = &(d_gradVmoyBB_t_3D(i));
   };
	 if (ex.d_gradVmoyBB_tdt != NULL) // cas où il existe
	  { int tail=ex.d_gradVmoyBB_tdt->Taille();
	    if (d_gradVmoyBB_tdt_3D_P == NULL) {d_gradVmoyBB_tdt_3D_P = new Tableau<TenseurBB *> (tail);
	                                      impli_3D->d_gradVmoyBB_tdt = d_gradVmoyBB_tdt_3D_P;}
	    else									  {d_gradVmoyBB_tdt_3D_P->Change_taille(tail);};
		   d_gradVmoyBB_tdt_3D.Change_taille(tail);
		   for (int i=1;i<= tail;i++)
			   (*d_gradVmoyBB_tdt_3D_P)(i) = &(d_gradVmoyBB_tdt_3D(i));
	  };
	 if (ex.d_gradVBB_t != NULL) // cas où il existe
   { int tail=ex.d_gradVBB_t->Taille();
     if (d_gradVBB_t_3D_P == NULL) {d_gradVBB_t_3D_P = new Tableau<TenseurBB *> (tail);
                                   impli_3D->d_gradVBB_t = d_gradVBB_t_3D_P;}
     else									  {d_gradVBB_t_3D_P->Change_taille(tail);};
     d_gradVBB_t_3D.Change_taille(tail);
     for (int i=1;i<= tail;i++)
       (*d_gradVBB_t_3D_P)(i) = &(d_gradVBB_t_3D(i));
   };
	 if (ex.d_gradVBB_tdt != NULL) // cas où il existe
   { int tail=ex.d_gradVBB_tdt->Taille();
     if (d_gradVBB_tdt_3D_P == NULL) {d_gradVBB_tdt_3D_P = new Tableau<TenseurBB *> (tail);
                                     impli_3D->d_gradVBB_tdt = d_gradVBB_tdt_3D_P;}
     else									  {d_gradVBB_tdt_3D_P->Change_taille(tail);};
     d_gradVBB_tdt_3D.Change_taille(tail);
     for (int i=1;i<= tail;i++)
      (*d_gradVBB_tdt_3D_P)(i) = &(d_gradVBB_tdt_3D(i));
   };

	}; // fin de la partie dédiée à la vitesse
	// maintenant on s'occupe uniquement du redimensionnement des tableaux restants
	   // -- on s'occupe des tableaux nécessaire à la métrique
	int ta_ex_d_giB_tdt = ex.d_giB_tdt->Taille(); // la dimension
 if (d_giB_tdt_3D.Taille() != ta_ex_d_giB_tdt)
	   { 	d_giB_tdt_3D.Change_taille(ta_ex_d_giB_tdt);};
	int ta_ex_d_giH_tdt = ex.d_giH_tdt->Taille(); // la dimension
 if (d_giH_tdt_3D.Taille() != ta_ex_d_giH_tdt)
	   { 	d_giH_tdt_3D.Change_taille(ta_ex_d_giH_tdt);};
	int ta_ex_d_gijBB_tdt = ex.d_gijBB_tdt->Taille(); // la dimension
 if (d_gijBB_tdt_3D.Taille() != ta_ex_d_gijBB_tdt)
   { d_gijBB_tdt_3D.Change_taille(ta_ex_d_gijBB_tdt); d_gijBB_tdt_3D_P.Change_taille(ta_ex_d_gijBB_tdt);
     for (int i=1;i<=ta_ex_d_gijBB_tdt;i++) {d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i));};
   };
	int ta_ex_d_gijHH_tdt = ex.d_gijHH_tdt->Taille();
 if (d_gijHH_tdt_3D.Taille() != ta_ex_d_gijHH_tdt)
   { d_gijHH_tdt_3D.Change_taille(ta_ex_d_gijHH_tdt); d_gijHH_tdt_3D_P.Change_taille(ta_ex_d_gijHH_tdt);
	    for (int i=1;i<=ta_ex_d_gijHH_tdt;i++) {d_gijHH_tdt_3D_P(i) = &(d_gijHH_tdt_3D(i));};
		 };
	if(	d_jacobien_tdt_3D.Taille() != ex.d_jacobien_tdt->Taille())
		{d_jacobien_tdt_3D.Change_taille(ex.d_jacobien_tdt->Taille());}		
																				
		       // le tableau à double dimension 				 
	if (ex.d2_gijBB_tdt != NULL) 	    
		 { int taille1=ex.d2_gijBB_tdt->Taille1(); int taille2=ex.d2_gijBB_tdt->Taille2();
			  if (d2_gijBB_tdt_3D_P == NULL)
			   { d2_gijBB_tdt_3D_P = impli_3D->d2_gijBB_tdt =  new Tableau2<TenseurBB *> (taille1,taille2);
				    d2_gijBB_tdt_3D.Change_taille(taille1,taille2);
				    for (int i=1;i<=taille1;i++) for (int j=1;j<= taille2;j++)
					     { (*d2_gijBB_tdt_3D_P)(i,j) = &d2_gijBB_tdt_3D(i,j);};
			   }
			  else if ((taille1 != d2_gijBB_tdt_3D.Taille1()) || (taille2 != d2_gijBB_tdt_3D.Taille2()))
			   { d2_gijBB_tdt_3D_P->Change_taille(taille1,taille2);
				    d2_gijBB_tdt_3D.Change_taille(taille1,taille2);
				    for (int i=1;i<=taille1;i++) for (int j=1;j<= taille2;j++)
					     { (*d2_gijBB_tdt_3D_P)(i,j) = &d2_gijBB_tdt_3D(i,j);};
			   };
		 };
 // on commence par recopier les grandeurs de l'ordre 2 à 3
 bool plusZero = true; // on complète avec des 0 dans un premier temps
 int type_recopie = 0; // on recopie les grandeurs de 0,t et tdt
	impli_3D->Passage_de_Ordre2_vers_Ordre3(ex,plusZero,type_recopie);

// --pour le debug
//  cout <<"\n LoiDeformationsPlanes::Passage_metrique_ordre2_vers_3(c "
//       << "\n 2D gijBB_tdt: "; ex.gijBB_tdt->Ecriture(cout);	
//  cout << "\n 3D gijBB_tdt: "; impli_3D->gijBB_tdt->Ecriture(cout);
// --fin pour le debug
		 	
	// maintenant on s'occupe de mettre à jour les grandeurs manquantes
	// - les bases naturelles: le vecteur normal est normé et est identique pour les bases naturelles et duales
	giB_0_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_0_3D(1),giB_0_3D(2))).Normer();
	giH_0_3D.CoordoH(3) = giB_0_3D(3).Bas_haut();
	giB_t_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_t_3D(1),giB_t_3D(2))).Normer();
	giH_t_3D.CoordoH(3) = giB_t_3D(3).Bas_haut();
	   // cas particulier du vecteur tdt
	giB_tdt_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_tdt_3D(1),giB_tdt_3D(2))); // calcul du vecteur normal non normé
	double norme_N_tdt = giB_tdt_3D(3).Norme(); // calcul de la norme qui nous servira pour les variations
 giB_tdt_3D.CoordoB(3) /= norme_N_tdt;
	giH_tdt_3D.CoordoH(3) = giB_tdt_3D(3).Bas_haut();
 //  - les tenseurs métriques: a priori 1 pour la direction 3
 gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)=gijHH_t_3D.Coor(3,3)
                     =gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.;
	//  - les variations du vecteur normal	
	CoordonneeB d_NN; // un vecteur de travail  
	#ifdef MISE_AU_POINT
	if (ex.d_giB_tdt->Taille() != ex.d_giH_tdt->Taille())
	   { cout << "\n **** sans doute une erreur: (ex.d_giB_tdt->Taille() "<< ex.d_giB_tdt->Taille()
		       << " != ex.d_giH_tdt->Taille()) " << ex.d_giH_tdt->Taille() 
				 << "\n LoiDeformationsPlanes::Passage_metrique_ordre2_vers_3(const Met_abstraite::Impli& ex)";
		  Sortie(1);
	   };
   #endif
	for (int iddl=1;iddl<= ta_ex_d_giB_tdt;iddl++)
   { // tout d'abord on calcul la variation de la normale non normée
     d_NN =   (Util::ProdVec_coorB(d_giB_tdt_3D(iddl)(1),giB_tdt_3D(2)))
    	         + (Util::ProdVec_coorB(giB_tdt_3D(1),d_giB_tdt_3D(iddl)(2)));
     // maintenant on calcul la variation du vecteur normal unitaire
     d_giB_tdt_3D(iddl).CoordoB(3) =  Util::VarUnVect_coorB(giB_tdt_3D(3),d_NN,norme_N_tdt);
		   // qui est identique pour la base duale
		   d_giH_tdt_3D(iddl).CoordoH(3) = d_giB_tdt_3D(iddl)(3).Bas_haut();
   };
	//   -- pour les tenseurs métriques, la valeur est fixe donc pas de variation	

};

// passage des grandeurs métriques de l'ordre 2 à 3: cas explicite
void LoiDeformationsPlanes::Passage_metrique_ordre2_vers_3(const Met_abstraite::Expli_t_tdt& ex)
{ // on s'occupe du redimensionnement éventuel
	 // on affecte et/ou on redimensionne éventuellement les tableaux fonction du nombre de ddl pour le passage 3D
	 // la dimension des tableaux : on considère que tous les tableaux doivent avoir la même dimension
	 int ta_ex_d_gijBB_tdt = ex.d_gijBB_tdt->Taille(); // la dimension
	 // la partie dépendant des vitesses: entre accolades pour pouvoir fermer
  {if (ex.gradVmoyBB_t != NULL) {expli_3D->gradVmoyBB_t= gradVmoyBB_t_3D_P = &gradVmoyBB_t_3D;};
   if (ex.gradVmoyBB_tdt != NULL) {expli_3D->gradVmoyBB_tdt=gradVmoyBB_tdt_3D_P = &gradVmoyBB_tdt_3D;};
   if (ex.gradVBB_tdt != NULL) {expli_3D->gradVBB_tdt=gradVBB_tdt_3D_P = &gradVBB_tdt_3D;};
  }; // fin de la partie dédiée à la vitesse
	 // maintenant on s'occupe uniquement du redimensionnement des tableaux restants
	 int ta_d_gijBB_tdt_3D = d_gijBB_tdt_3D.Taille();
	 if (ta_d_gijBB_tdt_3D != ta_ex_d_gijBB_tdt)
	  { // cela veut dire que tous les tableaux sont mal dimensionnés
	   // -- on s'occupe des tableaux nécessaire à la métrique
	   d_gijBB_tdt_3D.Change_taille(ta_ex_d_gijBB_tdt); d_gijBB_tdt_3D_P.Change_taille(ta_ex_d_gijBB_tdt);
	   for (int i=1;i<=ta_ex_d_gijBB_tdt;i++) {d_gijBB_tdt_3D_P(i) = &(d_gijBB_tdt_3D(i));};
	  };	 
  // on commence par recopier les grandeurs de l'ordre 2 à 3
  bool plusZero = true; // on complète avec des 0 dans un premier temps
  int type_recopie = 0; // on recopie les grandeurs de 0,t et tdt
	 expli_3D->Passage_de_Ordre2_vers_Ordre3(ex,plusZero,type_recopie);

// --pour le debug
//  cout <<"\n LoiDeformationsPlanes::Passage_metrique_ordre2_vers_3(c "
//       << "\n 2D gijBB_tdt: "; ex.gijBB_tdt->Ecriture(cout);	
//  cout << "\n 3D gijBB_tdt: "; expli_3D->gijBB_tdt->Ecriture(cout);
// --fin pour le debug
		 	
	 // maintenant on s'occupe de mettre à jour les grandeurs manquantes
	 // - les bases naturelles: le vecteur normal est normé et est identique pour les bases naturelles et duales
  giB_0_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_0_3D(1),giB_0_3D(2))).Normer();
  giH_0_3D.CoordoH(3) = giB_0_3D(3).Bas_haut();
  giB_t_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_t_3D(1),giB_t_3D(2))).Normer();
  giH_t_3D.CoordoH(3) = giB_t_3D(3).Bas_haut();
     // cas particulier du vecteur tdt
  giB_tdt_3D.CoordoB(3) = (Util::ProdVec_coorB(giB_tdt_3D(1),giB_tdt_3D(2))); // calcul du vecteur normal non normé
	 double norme_N_tdt = giB_tdt_3D(3).Norme(); // calcul de la norme qui nous servira pour les variations
  giB_tdt_3D.CoordoB(3) /= norme_N_tdt;
	 giH_tdt_3D.CoordoH(3) = giB_tdt_3D(3).Bas_haut();
  //  - les tenseurs métriques: a priori 1 pour la direction 3
	gijBB_0_3D.Coor(3,3)=gijHH_0_3D.Coor(3,3)=gijBB_t_3D.Coor(3,3)
                 =gijHH_t_3D.Coor(3,3)=gijBB_tdt_3D.Coor(3,3)=gijHH_tdt_3D.Coor(3,3)=1.;
	 //   -- pour les tenseurs métriques, la valeur est fixe donc pas de variation

};

  // passage des informations liées à la déformation  de 2 vers 3, et variation de volume éventuelle
void LoiDeformationsPlanes::Passage_deformation_volume_ordre2_vers_3
								(TenseurBB& DepsBB,TenseurBB & epsBB_tdt,Tableau <TenseurBB *>* d_epsBB
								,TenseurBB & delta_epsBB,double& jacobien_0,double& jacobien
								,Vecteur* d_jacobien_tdt)

{ // a priori on complète avec des 0, mais dans un second temps il faudra modifier les eps33
  bool plusZero = true;
  Deps_BB_3D.Affectation_2D_a_3D(*((Tenseur2BB*) &DepsBB),plusZero);
  eps_BB_3D.Affectation_2D_a_3D(*((Tenseur2BB*) &epsBB_tdt),plusZero);
  delta_eps_BB_3D.Affectation_2D_a_3D(*((Tenseur2BB*) &delta_epsBB),plusZero);
  if(d_epsBB != NULL)
	  {  int taille = d_epsBB->Taille();
		    // redimensionnement éventuel
      int ta_d_eps_BB_3D = d_eps_BB_3D.Taille();
      if (ta_d_eps_BB_3D != taille)
        {// cela veut dire que tous les tableaux sont mal dimensionnés
         d_eps_BB_3D.Change_taille(taille); d_eps_BB_3D_P.Change_taille(taille);
         for (int i=1;i<=taille;i++) {d_eps_BB_3D_P(i) = &(d_eps_BB_3D(i));}
        };
      // passage 2D 3D
      for (int i=1;i<=taille;i++)
         d_eps_BB_3D(i).Affectation_2D_a_3D(*((Tenseur2BB*) (*d_epsBB)(i)),plusZero);
	  };

  // calcul du jacobien 3D
  // pour l'instant on se contente de recopier, ce qui suppose une épaisseur = 1.
  jacobien_0_3D = jacobien_0;
  jacobien_tdt_3D = jacobien;
  if(d_jacobien_tdt != NULL)
    d_jacobien_tdt_3D = (*d_jacobien_tdt);
};
   
   
   
