// FICHIER : Met_PiPoCo2.cp
// CLASSE : Met_PiPoCo


// 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 <iostream>
using namespace std;  //introduces namespace std
#include <math.h>
#include <stdlib.h>
#include "Sortie.h"
#include "Util.h"
#include "MathUtil.h"


#include "Met_PiPoCo.h"

// il faut regarder et mettre à jour le calcul avec l'indicateur premier_calcul ********
// comme sur les métriques standards, pour l'instant rien n'est fait,           ***********
// il faut calculer 	   Calcul_giH_0();     // base duale        **********************
// il faut également changer les fonctions d'interpolation: ici il y a un mixte dans les mêmes tableaux
// phi et dphi, il y a les interpolations suivant la surface et l'épaisseurs, alors que dans pp
// les fonctions sont séparées: donc il faut faire comme dans sfe, et changer le nom de la fonction
// d'appel !!
// dans le cas du premier passage, pour l'instant pas fait !!!!!!!!!!!!!!!!!!!!!!!!!!

//  =========================================================================================
//  vu la taille des executables le fichier est decompose en trois
// le premier : Met_PiPoCo1.cp concerne les constructeurs, destructeur et 
//              la gestion des variables
// le second :  Met_PiPoCo2.cp concerne  le calcul des grandeurs publics
// le troisieme : Met_PiPoCo3.cp concerne  le calcul des grandeurs protegees
//  =========================================================================================

// METHODES PUBLIQUES :
//  ------------------------ calculs ----------------------------------------
	 // cas explicite à t, toutes les grandeurs sont a 0 ou t	
	 // gradV_instantane : true : calcul du gradient de vitesse instantannée 
     // premier_calcul : true : cas d'un premier calcul -> toutes les grandeurs sont calculées
     //                  false: uniquement les grandeurs à t sont calculées	    
 const Met_abstraite::Expli&  Met_PiPoCo::Cal_explicit_t
                (const  Tableau<Noeud *>& tab_noeud,bool gradV_instantane, 
		         Tableau<Mat_pleine const *>& tabdphi,int nombre_noeud,Tableau<Vecteur const *>& tabphi
		         ,bool premier_calcul)
	{ // pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	 // initialisation des variations par rapport aux ddl externes pour tous les termes
	 // relatif a la base ai
     int nbddl_x = tab_ddl.NbDdl_famille(X1); // nombre de ddl en position
	 for (int i=1;i<=nbddl_x;i++)
	   for (int jve=1;jve<=nbvec_base;jve++)
	    { (*d_giB_t)(i).CoordoB(jve).Zero();
	      (*d_giH_t)(i).CoordoH(jve).Zero();
	     }
	  // Base a t=0 : tout d'abord on calcul les elements relatifs a la facette (ou l'axe)
	 Met_abstraite::Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t=0
	 *aiB_0 = *giB_0; // sauvegarde
	 Met_abstraite::Calcul_gijBB_0 ();    // metrique base naturelle
	 *aijBB_0 = *gijBB_0;
	 Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	 *aijHH_0 = *gijHH_0;	
     Met_abstraite::Calcul_giH_0(); 
	 *aiH_0 = *giH_0; // sauvegarde
	 // calcul de la coubure a 0
	 curb_0 = courbure_0(tab_noeud);
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base a t=t : 
	 Met_abstraite::Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t
	 *aiB_t = *giB_t; // sauvegarde
	 Met_abstraite::Calcul_gijBB_t ();    // metrique base naturelle
	 *aijBB_t = *gijBB_t;
	 Met_abstraite::Calcul_gijHH_t (); *aijHH_t = *gijHH_t; // composantes contravariantes	 	
     Met_abstraite::Calcul_giH_t(); *aiH_t = *giH_t; // calcul et sauvegarde la base duale
     // les termes de variation des ai 
     Met_abstraite::D_giB_t(dphi1,nombre_noeud,phi1); *d_aiB_t = *d_giB_t;	  
	 Met_abstraite::D_giH_t();  *d_aiH_t = *d_giH_t;
	 // calcul de la coubure et variation a t
	 Dcourbure_t (tab_noeud,curb_t,dcurb_t);
	 //la base a t
	 Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi2);
  // les termes relatif aux gi (et non a la facette)
	  Met_abstraite::Calcul_gijBB_0 ();  // metrique base naturelle
	  Met_abstraite::Calcul_gijHH_0 ();  // composantes controvariantes à 0
	  Met_abstraite::Jacobien_0();         // calcul du jacobien a 0
	  Met_abstraite::Calcul_gijBB_t ();  //      "
	  Met_abstraite::Calcul_gijHH_t ();        // composantes controvariantes
	  Met_abstraite::Jacobien_t();         // calcul du jacobien a t
	  Met_abstraite::Calcul_giH_t ();        // base duale
  // les termes de variation des gi
  	  D_giB_t(dphi1,nombre_noeud,phi2);   // pour les gi
	  Met_abstraite::D_gijBB_t();    //variation de la  metrique en BB
	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
	  // retour des infos
//	  Expli ex(giB_0,giB_t,giH_t,gijBB_0,gijBB_t,gijHH_t,
//               gradVBB_t,&d_gijBB_t,jacobien_t,jacobien_0);
      // liberation des tenseurs intermediaires
      LibereTenseur();   
      return ex_expli;	  
	};   
// calcul simplifie, a utiliser lorsque l'on se sert des grandeurs
// liers a la facette deja calculee, ainsi que la courbure
// cas explicite à t, toutes les grandeurs sont a 0 ou t	
	 // gradV_instantane : true : calcul du gradient de vitesse instantannée 
     // premier_calcul : true : cas d'un premier calcul -> toutes les grandeurs sont calculées
     //                  false: uniquement les grandeurs à t sont calculées	    
const Met_abstraite::Expli& Met_PiPoCo::Cal_explicit_simple_t(const Tableau<Noeud *>& tab_noeud,bool gradV_instantane, 
		        Tableau<Mat_pleine const *>& tabdphi,int nombre_noeud,Tableau<Vecteur const *>& tabphi
		        ,bool premier_calcul)
	{ // pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	 // initialisation des variations par rapport aux ddl externes pour tous les termes
	 // relatif a la base ai
     int nbddl_x = tab_ddl.NbDdl_famille(X1); // nombre de ddl en position
	 for (int i=1;i<=nbddl_x;i++)
	   for (int jve=1;jve<=nbvec_base;jve++)
	    { (*d_giB_t)(i).CoordoB(jve).Zero();
	     }
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
	 //la base a t
	 Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi2);
  // les termes relatif aux gi (et non a la facette)
	  Met_abstraite::Calcul_gijBB_0 ();  // metrique base naturelle
	  Met_abstraite::Calcul_gijHH_0 ();  // composantes controvariantes à 0
	  Met_abstraite::Jacobien_0();         // calcul du jacobien a 0
	  Met_abstraite::Calcul_gijBB_t ();  //      "
	  Met_abstraite::Calcul_gijHH_t ();        // composantes controvariantes
	  Met_abstraite::Jacobien_t();         // calcul du jacobien a t
	  Met_abstraite::Calcul_giH_t ();        // base duale
  // les termes de variation des ai puis des gi
      Met_abstraite::D_giB_t(dphi1,nombre_noeud,phi1); *d_aiB_t = *d_giB_t;	  
  	  D_giB_t(dphi1,nombre_noeud,phi2);   // pour les gi
	  Met_abstraite::D_gijBB_t();    //variation de la  metrique en BB

// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  

	  // retour des infos
//	  Expli ex(giB_0,giB_t,giH_t,gijBB_0,gijBB_t,gijHH_t,
//               gradVBB_t,&d_gijBB_t,jacobien_t,jacobien_0);
      LibereTenseur();   
      return ex_expli;	  
	};   
	    // cas explicite à tdt, toutes les grandeurs sont a 0 ou tdt	
	 // gradV_instantane : true : calcul du gradient de vitesse instantannée 
     // premier_calcul : true : cas d'un premier calcul -> toutes les grandeurs sont calculées
     //                  false: uniquement les grandeurs à t sont calculées	    
 const Met_abstraite::Expli_t_tdt&  Met_PiPoCo::Cal_explicit_tdt
                (const  Tableau<Noeud *>& tab_noeud,bool gradV_instantane, 
		         Tableau<Mat_pleine const *>& tabdphi,int nombre_noeud
		         ,Tableau<Vecteur const *>& tabphi,bool premier_calcul)
	{ // pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	 // initialisation des variations par rapport aux ddl externes pour tous les termes
	 // relatif a la base ai
     int nbddl_x = tab_ddl.NbDdl_famille(X1); // nombre de ddl en position
	 for (int i=1;i<=nbddl_x;i++)
	   for (int jve=1;jve<=nbvec_base;jve++)
	    { (*d_giB_tdt)(i).CoordoB(jve).Zero();
	      (*d_giH_tdt)(i).CoordoH(jve).Zero();
	     }
	  // Base a t=0 : tout d'abord on calcul les elements relatifs a la facette (ou l'axe)
	 Met_abstraite::Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t=0
	 *aiB_0 = *giB_0; // sauvegarde
	 Met_abstraite::Calcul_gijBB_0 ();    // metrique base naturelle
	 *aijBB_0 = *gijBB_0;
	 Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	 *aijHH_0 = *gijHH_0;	
     Met_abstraite::Calcul_giH_0(); 
	 *aiH_0 = *giH_0; // sauvegarde
	 // calcul de la coubure a 0
	 curb_0 = courbure_0(tab_noeud);
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base a t=t : 
	 Met_abstraite::Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t
	 *aiB_t = *giB_t; // sauvegarde
	 Met_abstraite::Calcul_gijBB_t ();    // metrique base naturelle
	 *aijBB_t = *gijBB_t;
	 Met_abstraite::Calcul_gijHH_t (); *aijHH_t = *gijHH_t; // composantes controvariantes	 	
     Met_abstraite::Calcul_giH_t(); *aiH_t = *giH_t; // calcul et sauvegarde la base duale
	 // calcul de la coubure  a t
	 curb_t = courbure_t(tab_noeud);
	 //la base a t
	 Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base a tdt : 
	 Met_abstraite::Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a tdt
	 *aiB_tdt = *giB_tdt; // sauvegarde
	 Met_abstraite::Calcul_gijBB_tdt ();    // metrique base naturelle
	 *aijBB_tdt = *gijBB_tdt;
	 Met_abstraite::Calcul_gijHH_tdt (); *aijHH_tdt = *gijHH_tdt; // composantes controvariantes	 	
     Met_abstraite::Calcul_giH_tdt(); *aiH_tdt = *giH_tdt; // calcul et sauvegarde la base duale
     // les termes de variation des ai 
     Met_abstraite::D_giB_tdt(dphi1,nombre_noeud,phi1); *d_aiB_tdt = *d_giB_tdt;	  
	 Met_abstraite::D_giH_tdt();  *d_aiH_tdt = *d_giH_tdt;
	 // calcul de la coubure et variation a tdt
	 Dcourbure_tdt (tab_noeud,curb_tdt,dcurb_tdt);
	 //la base a tdt
	 Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi2);
  // les termes relatif aux gi (et non a la facette)
	  Met_abstraite::Calcul_gijBB_0 ();  // metrique base naturelle
	  Met_abstraite::Calcul_gijHH_0 ();  // composantes controvariantes à 0
	  Met_abstraite::Jacobien_0();         // calcul du jacobien a 0
	  Met_abstraite::Jacobien_t();         // calcul du jacobien a t
	  Met_abstraite::Calcul_gijBB_t ();  //   métrique à t
	  Met_abstraite::Calcul_gijBB_tdt ();  //      "
	  Met_abstraite::Calcul_gijHH_tdt ();        // composantes controvariantes
	  Met_abstraite::Jacobien_tdt();         // calcul du jacobien a tdt
	  Met_abstraite::Calcul_giH_tdt();        // base duale
  // les termes de variation des gi
  	  D_giB_tdt(dphi1,nombre_noeud,phi2);   // pour les gi
	  Met_abstraite::D_gijBB_tdt();    //variation de la  metrique en BB

// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  

	  // retour des infos
//	  Expli_t_tdt ex(giB_0,giB_t,giB_tdt,giH_tdt,gijBB_0,gijBB_t,gijBB_tdt,gijHH_tdt,
//               gradVBB_tdt,&d_gijBB_tdt,jacobien_tdt,jacobien_0);
      // liberation des tenseurs intermediaires
      LibereTenseur();   
      return ex_expli_t_tdt;	  
	};   
// calcul simplifie, a utiliser lorsque l'on se sert des grandeurs
// liers a la facette deja calculee, ainsi que la courbure
// cas explicite à tdt, toutes les grandeurs sont a 0 ou tdt	
	 // gradV_instantane : true : calcul du gradient de vitesse instantannée 
     // premier_calcul : true : cas d'un premier calcul -> toutes les grandeurs sont calculées
     //                  false: uniquement les grandeurs à t sont calculées	    
const Met_abstraite::Expli_t_tdt& Met_PiPoCo::Cal_explicit_simple_tdt(const Tableau<Noeud *>& tab_noeud,bool gradV_instantane, 
		        Tableau<Mat_pleine const *>& tabdphi,int nombre_noeud,Tableau<Vecteur const *>& tabphi
		        ,bool premier_calcul)
	{ // pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	 // initialisation des variations par rapport aux ddl externes pour tous les termes
	 // relatif a la base ai
     int nbddl_x = tab_ddl.NbDdl_famille(X1); // nombre de ddl en position
	 for (int i=1;i<=nbddl_x;i++)
	   for (int jve=1;jve<=nbvec_base;jve++)
	    { (*d_giB_tdt)(i).CoordoB(jve).Zero();
	     }
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
	 //la base a t
	 Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi2);
	 //la base a tdt
	 Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi2);
  // les termes relatif aux gi (et non a la facette)
	  Met_abstraite::Calcul_gijBB_0 ();  // metrique base naturelle
	  Met_abstraite::Calcul_gijHH_0 ();  // composantes controvariantes à 0
	  Met_abstraite::Jacobien_0();         // calcul du jacobien a 0
	  Met_abstraite::Jacobien_t();         // calcul du jacobien a t
	  Met_abstraite::Calcul_gijBB_t ();  //   métrique à t
	  Met_abstraite::Calcul_gijBB_tdt ();  //      "   à tdt
	  Met_abstraite::Calcul_gijHH_tdt ();        // composantes controvariantes
	  Met_abstraite::Jacobien_tdt();         // calcul du jacobien a tdt
	  Met_abstraite::Calcul_giH_tdt();        // base duale
  // les termes de variation des ai puis des gi
      Met_abstraite::D_giB_tdt(dphi1,nombre_noeud,phi1); *d_aiB_tdt = *d_giB_tdt;	  
  	  D_giB_tdt(dphi1,nombre_noeud,phi2);   // pour les gi
	  Met_abstraite::D_gijBB_tdt();    //variation de la  metrique en BB

// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  

	  // retour des infos
//	  Expli_t_tdt ex(giB_0,giB_t,giB_tdt,giH_tdt,gijBB_0,gijBB_t,gijBB_tdt,gijHH_tdt,
//               gradVBB_tdt,&d_gijBB_tdt,jacobien_tdt,jacobien_0);
      LibereTenseur();   
      return ex_expli_t_tdt;	  
	};   
	
	
// cas implicite, toutes les grandeurs sont a 0 ou t+dt	
	 // gradV_instantane : true : calcul du gradient de vitesse instantannée 
     // premier_calcul : true : cas d'un premier calcul -> toutes les grandeurs sont calculées
     //                  false: uniquement les grandeurs à t sont calculées	    
const Met_abstraite::Impli& Met_PiPoCo::Cal_implicit
              ( const Tableau<Noeud *>& tab_noeud,bool gradV_instantane,
		         Tableau<Mat_pleine const *>& tabdphi,int nombre_noeud,
		         Tableau<Vecteur const *>& tabphi,
		         bool premier_calcul)
	{// pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	 // initialisation des variations par rapport aux ddl externes pour tous les termes
	 // relatif a la base ai
     int nbddl_x = tab_ddl.NbDdl_famille(X1); // nombre de ddl en position
	 for (int i=1;i<=nbddl_x;i++)
	   for (int jve=1;jve<=nbvec_base;jve++)
	    { (*d_giB_tdt)(i).CoordoB(jve).Zero();
	      (*d_giH_tdt)(i).CoordoH(jve).Zero();
	     }
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!

// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!

	 // Base a t=0 : tout d'abord on calcul les elements relatifs a la facette plane
	 Met_abstraite::Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t=0
	 *aiB_0 = *giB_0; // sauvegarde
	 Met_abstraite::Calcul_gijBB_0 ();    // metrique base naturelle
	 *aijBB_0 = *gijBB_0;
	 Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	 *aijHH_0 = *gijHH_0;	
     Met_abstraite::Calcul_giH_0(); 
	 *aiH_0 = *giH_0; // sauvegarde
	 // calcul de la coubure a 0
	 curb_0 = courbure_0(tab_noeud);
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base a t=t : 
	 Met_abstraite::Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t
	 *aiB_t = *giB_t; // sauvegarde
	 Met_abstraite::Calcul_gijBB_t ();    // metrique base naturelle
	 *aijBB_t = *gijBB_t;
	 Met_abstraite::Calcul_gijHH_t (); *aijHH_t = *gijHH_t; // composantes controvariantes	 	
     Met_abstraite::Calcul_giH_t(); *aiH_t = *giH_t; // calcul et sauvegar de la base duale
	 // calcul de la coubure a t
	 curb_t = courbure_t(tab_noeud);
	 //la base a t
	 Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base a t=t+dt : 
	 Met_abstraite::Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t+dt
	 *aiB_tdt = *giB_tdt; // sauvegarde
	 Met_abstraite::Calcul_gijBB_tdt ();    // metrique base naturelle
	 *aijBB_tdt = *gijBB_tdt;
	 Met_abstraite::Calcul_gijHH_tdt (); *aijHH_tdt = *gijHH_tdt; // composantes controvariantes	 	
     Met_abstraite::Calcul_giH_tdt(); *aiH_tdt = *giH_tdt; // calcul et sauvegarde la base duale
     // les termes de variation des ai naturelles et duaux 
     Met_abstraite::D_giB_tdt(dphi1,nombre_noeud,phi1); *d_aiB_tdt = *d_giB_tdt;
	 Met_abstraite::D_giH_tdt();  *d_aiH_tdt = *d_giH_tdt;
	 // calcul de la coubure et variation a t+dt
	 Dcourbure_tdt (tab_noeud,curb_tdt,dcurb_tdt);
	 //la base a tdt
	 Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi2);
  // les termes relatif aux gi (et non a la facette)
	 Met_abstraite::Calcul_gijBB_0 ();    //      "
	 Met_abstraite::Calcul_gijHH_0 ();  // composantes controvariantes à 0
	 Met_abstraite::Calcul_gijBB_t ();    //      "
	 Met_abstraite::Calcul_gijBB_tdt ();  //      "
	 Met_abstraite::Calcul_gijHH_tdt ();        // composantes controvariantes
  Met_abstraite::Jacobien_0();         // calcul du jacobien a 0
  Met_abstraite::Jacobien_t();         // calcul du jacobien a t
	 Met_abstraite::Jacobien_tdt();         // calcul du jacobien a tdt
  // les termes de variation des  gi
  D_giB_tdt(dphi1,nombre_noeud,phi2);   // pour les gi
	 Met_abstraite::D_gijBB_tdt();    //variation de la  metrique en BB
	 Met_abstraite::Calcul_giH_tdt();    // base duale
	 Met_abstraite::D_giH_tdt();         // variation de la base duale
	 Met_abstraite::D_gijHH_tdt();    //variation de la  metrique en HH
	 Met_abstraite::Djacobien_tdt();    // variation du jacobien 

// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  

	  // retour des infos
 //    Impli ex(giB_0,giB_t,giB_tdt,d_giB_tdt,giH_tdt,d_giH_tdt,gijBB_0,gijBB_t,gijBB_tdt,gijHH_tdt,
//           gradVBB_tdt,&d_gijBB_tdt,&d2_gijBB_tdt,&d_gijHH_tdt,jacobien_tdt,jacobien_0,&d_jacobien_tdt);
	// Impli ex;
	// ex.gijBB_0 = gijBB_0;
	// ex.gijBB_t = gijBB_t; ex.gijBB_tdt = gijBB_tdt;
	// ex.gijHH_tdt = gijHH_tdt;
	// ex.d_gijBB_tdt = &d_gijBB_tdt; ex.d_gijHH_tdt = &d_gijHH_tdt;
	// ex.jacobien_0 = jacobien_0;
	// ex.jacobien = jacobien_tdt; ex.d_jacobien_tdt = &d_jacobien_tdt;
     // liberation des tenseurs intermediaires
     LibereTenseur();   
	 return ex_impli;
	};
	
// calcul simplifie, a utiliser lorsque l'on se sert des grandeurs
// liers a la facette deja calculee, ainsi que la courbure et sa variation
// cas implicite, toutes les grandeurs sont a 0 ou t+dt	
	 // gradV_instantane : true : calcul du gradient de vitesse instantannée 
     // premier_calcul : true : cas d'un premier calcul -> toutes les grandeurs sont calculées
     //                  false: uniquement les grandeurs à t sont calculées	    
const Met_abstraite::Impli& Met_PiPoCo::Cal_implicit_simple(const Tableau<Noeud *>& tab_noeud,bool gradV_instantane,
		         Tableau<Mat_pleine const *>& tabdphi,int nombre_noeud,Tableau<Vecteur const *>& tabphi,
		         bool premier_calcul)
	{// pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	 // initialisation des variations par rapport aux ddl externes pour tous les termes
	 // relatif a la base ai
     int nbddl_x = tab_ddl.NbDdl_famille(X1); // nombre de ddl en position
	 for (int i=1;i<=nbddl_x;i++)
	   for (int jve=1;jve<=nbvec_base;jve++)
	    { (*d_giB_tdt)(i).CoordoB(jve).Zero();
	      (*d_giH_tdt)(i).CoordoH(jve).Zero();
	     }
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!
// !!!!!!!il faut faire le calcul de la dérivée seconde de la métrique !!!!!!!!

// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!
// la prise en compte du paramètre pa (calcul de dérivée seconde et variation de jacobien ne sont pas fait !!!!!

	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
	 //la base a t
	 Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi2);
	 //la base a tdt
	 Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi2);
  // les termes relatif aux gi (et non a la facette)
	 Met_abstraite::Calcul_gijBB_0 ();    //      "
	 Met_abstraite::Calcul_gijHH_0 ();  // composantes controvariantes à 0
	 Met_abstraite::Calcul_gijBB_t ();    //      "
	 Met_abstraite::Calcul_gijBB_tdt ();  //      "
	 Met_abstraite::Calcul_gijHH_tdt ();        // composantes controvariantes
	 Met_abstraite::Jacobien_0();         // calcul du jacobien a 0
	 Met_abstraite::Jacobien_t();         // calcul du jacobien a t
	 Met_abstraite::Jacobien_tdt();         // calcul du jacobien a tdt
  // les termes de variation des  gi
  D_giB_tdt(dphi1,nombre_noeud,phi2);   // pour les gi
	 Met_abstraite::D_gijBB_tdt();    //variation de la  metrique en BB
	 Met_abstraite::Calcul_giH_tdt();    // base duale
	 Met_abstraite::D_giH_tdt();         // variation de la base duale
	 Met_abstraite::D_gijHH_tdt();    //variation de la  metrique en HH
	 Met_abstraite::Djacobien_tdt();    // variation du jacobien 

// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  
// ***mise en place du calcul des gradients instantannés ou moyens et des variations associés
// ***ainsi que l'utilisation du paramétre premier_calcul comme dans les méthodes de Met_abstraite	  

	  // retour des infos
/*     Impli ex(giB_0,giB_t,giB_tdt,d_giB_tdt,giH_tdt,d_giH_tdt,gijBB_0,gijBB_t,gijBB_tdt,gijHH_tdt,
              gradVBB_tdt,&d_gijBB_tdt,&d2_gijBB_tdt,&d_gijHH_tdt,jacobien_tdt,jacobien_0,&d_jacobien_tdt);
	 //Impli ex;
	 //ex.gijBB_0 = gijBB_0;
	 //ex.gijBB_t = gijBB_t; ex.gijBB_tdt = gijBB_tdt;
	 //ex.gijHH_tdt = gijHH_tdt;
	 //ex.d_gijBB_tdt = &d_gijBB_tdt; ex.d_gijHH_tdt = &d_gijHH_tdt;
	 //ex.jacobien_0 = jacobien_0;
	 //ex.jacobien = jacobien_tdt; ex.d_jacobien_tdt = &d_jacobien_tdt;
	 return ex; */
	 
     // liberation des tenseurs intermediaires
     LibereTenseur();
     return ex_impli;  
	};
	
	
 //-------- pour la remontee aux infos duaux ------------	
const Met_abstraite::InfoImp& Met_PiPoCo::Cal_InfoImp
   ( const Tableau<Noeud *>& tab_noeud,
		    Tableau<Mat_pleine const *>& tabdphi,Tableau<Vecteur const *>& tabphi, int nombre_noeud)
  { // pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	// Base et point a t=0 : tout d'abord on calcul les elements relatifs a la facette plane
	 Met_abstraite::Calcul_M0(tab_noeud,phi1,nombre_noeud); *P0 = *M0;
	 Met_abstraite::Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t=0
	 *aiB_0 = *giB_0; // sauvegarde
	 Met_abstraite::Calcul_gijBB_0 ();    // metrique base naturelle
	 *aijBB_0 = *gijBB_0;
	 Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	 *aijHH_0 = *gijHH_0;	
     Met_abstraite::Calcul_giH_0(); 
	 *aiH_0 = *giH_0; // sauvegarde
	 // calcul de la coubure a 0
	 curb_0 = courbure_0(tab_noeud);
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base et point a t=tdt : 
	 Met_abstraite::Calcul_Mtdt(tab_noeud,phi1,nombre_noeud); *Ptdt = *Mtdt;
	 Met_abstraite::Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a tdt
	 *aiB_tdt = *giB_tdt; // sauvegarde
	 Met_abstraite::Calcul_gijBB_tdt ();    // metrique base naturelle
	 *aijBB_tdt = *gijBB_tdt;
	 Met_abstraite::Calcul_gijHH_tdt (); *aijHH_tdt = *gijHH_tdt; // composantes controvariantes	 	
     Met_abstraite::Calcul_giH_tdt(); *aiH_tdt = *giH_tdt; // calcul et sauvegar de la base duale
	 // calcul de la coubure a tdt
	 curb_tdt = courbure_tdt(tab_noeud);
	 //la base a t
	 Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi2);
	 
	  // grandeurs de sortie
	  Calcul_N_0 ();
   Calcul_M0(tab_noeud,phi2,nombre_noeud);
   Calcul_N_tdt ();
   Calcul_Mtdt(tab_noeud,phi2,nombre_noeud);
	  Met_abstraite::Calcul_gijBB_0 ();  //      "
	  Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	  Met_abstraite::Calcul_gijBB_tdt ();  //      "
	  Met_abstraite::Calcul_gijHH_tdt ();        // composantes controvariantes
	  // bases duales
      Met_abstraite::Calcul_giH_0(); 
	  Met_abstraite::Calcul_giH_tdt(); 
	  
	  // retour des infos
/*      InfoImp ex;
      ex.M0 = M0;
      ex.Mtdt = Mtdt;
      ex.giB_0 = giB_0;
      ex.giB_tdt = giB_tdt;
      ex.gijBB_tdt = gijBB_tdt;
      ex.gijHH_tdt = gijHH_tdt;
      ex.giH_0 = giH_0;
      ex.giH_tdt = giH_tdt;
      return ex; */
      
      // liberation des tenseurs intermediaires
      LibereTenseur();
      return ex_InfoImp;  
   };
   
const Met_abstraite::InfoExp_t& Met_PiPoCo::Cal_InfoExp_t
     (const Tableau<Noeud *>& tab_noeud,
		   Tableau<Mat_pleine const *>& tabdphi,Tableau<Vecteur const *>& tabphi, int nombre_noeud)
  {  // pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	// Base et point a t=0 : tout d'abord on calcul les elements relatifs a la facette plane
	 Met_abstraite::Calcul_M0(tab_noeud,phi1,nombre_noeud); *P0 = *M0;
	 Met_abstraite::Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t=0
	 *aiB_0 = *giB_0; // sauvegarde
	 Met_abstraite::Calcul_gijBB_0 ();    // metrique base naturelle
	 *aijBB_0 = *gijBB_0;
	 Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	 *aijHH_0 = *gijHH_0;	
     Met_abstraite::Calcul_giH_0(); 
	 *aiH_0 = *giH_0; // sauvegarde
	 // calcul de la coubure a 0
	 curb_0 = courbure_0(tab_noeud);
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base et point a t=t : 
	 Met_abstraite::Calcul_Mt(tab_noeud,phi1,nombre_noeud); *Pt = *Mt;
	 Met_abstraite::Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t
	 *aiB_t = *giB_t; // sauvegarde
	 Met_abstraite::Calcul_gijBB_t ();    // metrique base naturelle
	 *aijBB_t = *gijBB_t;
	 Met_abstraite::Calcul_gijHH_t (); *aijHH_t = *gijHH_t; // composantes controvariantes	 	
     Met_abstraite::Calcul_giH_t(); *aiH_t = *giH_t; // calcul et sauvegar de la base duale
	 // calcul de la coubure a t
	 curb_t = courbure_t(tab_noeud);
	 //la base a t
	 Calcul_giB_t(tab_noeud,dphi1,nombre_noeud,phi2);
	 
	 // grandeurs de sortie  
	  Calcul_N_0 ();
      Calcul_M0(tab_noeud,phi2,nombre_noeud);
      Calcul_N_t ();
      Calcul_Mt(tab_noeud,phi2,nombre_noeud);
	  Met_abstraite::Calcul_gijBB_0 ();  //      "
	  Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	  Met_abstraite::Calcul_gijBB_t ();  //      "
	  Met_abstraite::Calcul_gijHH_t ();        // composantes controvariantes
	  // bases duales
      Met_abstraite::Calcul_giH_0(); 
	  Met_abstraite::Calcul_giH_t(); 
	  // retour des infos
 /*     InfoExp_t ex;
      ex.M0 = M0;
      ex.Mt = Mt;
      ex.giB_0 = giB_0;
      ex.giB_t = giB_t;
      ex.gijBB_t = gijBB_t;
      ex.gijHH_t = gijHH_t;
      ex.giH_0 = giH_0;
      ex.giH_t = giH_t;
      return ex; */
      
      // liberation des tenseurs intermediaires
      LibereTenseur(); 
      return ex_InfoExp_t;  
   };
      
   
const Met_abstraite::InfoExp_tdt& Met_PiPoCo::Cal_InfoExp_tdt
     (const Tableau<Noeud *>& tab_noeud,
		   Tableau<Mat_pleine const *>& tabdphi,Tableau<Vecteur const *>& tabphi, int nombre_noeud)
  {  // pour commodité on change de notation
	  Mat_pleine const & dphi1 = (*tabdphi(1)); Mat_pleine const & dphi2 = (*tabdphi(2));
	  Vecteur const & phi1 = (*tabphi(1)); Vecteur const & phi2 = (*tabphi(2));
	// Base et point a t=0 : tout d'abord on calcul les elements relatifs a la facette plane
	 Met_abstraite::Calcul_M0(tab_noeud,phi1,nombre_noeud); *P0 = *M0;
	 Met_abstraite::Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a t=0
	 *aiB_0 = *giB_0; // sauvegarde
	 Met_abstraite::Calcul_gijBB_0 ();    // metrique base naturelle
	 *aijBB_0 = *gijBB_0;
	 Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	 *aijHH_0 = *gijHH_0;	
     Met_abstraite::Calcul_giH_0(); 
	 *aiH_0 = *giH_0; // sauvegarde
	 // calcul de la coubure a 0
	 curb_0 = courbure_0(tab_noeud);
	 //la base a t0
	 Calcul_giB_0(tab_noeud,dphi1,nombre_noeud,phi2);
 // Base et point a tdt : 
	 Met_abstraite::Calcul_Mtdt(tab_noeud,phi1,nombre_noeud); *Ptdt = *Mtdt;
	 Met_abstraite::Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi1); // calcul de la base a tdt
	 *aiB_tdt = *giB_tdt; // sauvegarde
	 Met_abstraite::Calcul_gijBB_tdt ();    // metrique base naturelle
	 *aijBB_tdt = *gijBB_tdt;
	 Met_abstraite::Calcul_gijHH_tdt (); *aijHH_tdt = *gijHH_tdt; // composantes controvariantes	 	
     Met_abstraite::Calcul_giH_tdt(); *aiH_tdt = *giH_tdt; // calcul et sauvegar de la base duale
	 // calcul de la coubure a tdt
	 curb_tdt = courbure_tdt(tab_noeud);
	 //la base a tdt
	 Calcul_giB_tdt(tab_noeud,dphi1,nombre_noeud,phi2);
	 
	 // grandeurs de sortie  
	  Calcul_N_0 ();
      Calcul_M0(tab_noeud,phi2,nombre_noeud);
      Calcul_N_tdt ();
      Calcul_Mtdt(tab_noeud,phi2,nombre_noeud);
	  Met_abstraite::Calcul_gijBB_0 ();  //      "
	  Met_abstraite::Calcul_gijHH_0 ();        // composantes controvariantes
	  Met_abstraite::Calcul_gijBB_tdt ();  //      "
	  Met_abstraite::Calcul_gijHH_tdt ();        // composantes controvariantes
	  // bases duales
      Met_abstraite::Calcul_giH_0(); 
	  Met_abstraite::Calcul_giH_tdt(); 
	  // retour des infos
/*      InfoExp_tdt ex;
      ex.M0 = M0;
      ex.Mtdt = Mtdt;
      ex.giB_0 = giB_0;
      ex.giB_tdt = giB_tdt;
      ex.gijBB_tdt = gijBB_tdt;
      ex.gijHH_tdt = gijHH_tdt;
      ex.giH_0 = giH_0;
      ex.giH_tdt = giH_tdt;
      // liberation des tenseurs intermediaires
      return ex; */  
      
      LibereTenseur();   
      return ex_InfoExp_tdt;  
   };
      

		  
