
// 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 "Deformation.h"
#include "ParaGlob.h"

// ----------------------------------------------------------------------------------------------
//     conteneurs pour le stockage de variables spécifiques à un point de calcul
//      cas des éléments généraux 		 
// ----------------------------------------------------------------------------------------------

   // stockage éléments de métrique: uniquement les grandeurs à un instant donnée t, sans les variations
   // >>>> Grandeurs réellement créées (et non des pointeurs!!) -> sert pour les déformations par exemple	

   // constructeur par défaut
Deformation::Stmet::Stmet () : 
      giB_(NULL),giH_(NULL),gijBB_(NULL),gijHH_(NULL)
      ,gradVmoyBB_(NULL),gradVBB_(NULL),jacobien_(NULL)
		  	   {};
		  	   
   // constructeur normal : 
   //       dim_base: dimension des vecteurs de base, 
   //       nbvec_base : nb de vecteur de la base naturelle	
Deformation::Stmet::Stmet (int dim_base, int nbvec_base)	  	        
     {giB_=new BaseB(dim_base,nbvec_base);
	  giH_=new BaseH(dim_base,nbvec_base);gijBB_=NevezTenseurBB(nbvec_base);
	  gijHH_=NevezTenseurHH(nbvec_base);gradVmoyBB_=NevezTenseurBB(nbvec_base);
	  gradVBB_=NevezTenseurBB(nbvec_base);jacobien_=new double;*jacobien_ = 0.;}
		  	          
   // constructeur de copie	  	          		  	        
Deformation::Stmet::Stmet (const Deformation::Stmet& ex) : 
	  giB_(new BaseB(*(ex.giB_))),giH_(new BaseH(*(ex.giH_))),gijBB_(NevezTenseurBB(*(ex.gijBB_)))
	  ,gijHH_(NevezTenseurHH(*(ex.gijHH_))),gradVmoyBB_(NevezTenseurBB(*(ex.gradVmoyBB_)))
	  ,gradVBB_(NevezTenseurBB(*(ex.gradVBB_))),jacobien_(new double(*(ex.jacobien_)))
		  	   {};

   // destructeur	  	          		  	        
Deformation::Stmet::~Stmet ()  
   { if (giB_ != NULL) delete (giB_); if (giH_ != NULL) delete (giH_);if (gijBB_ != NULL) delete (gijBB_); 
     if (gijHH_ != NULL)delete (gijHH_); if (gradVmoyBB_ != NULL) delete (gradVmoyBB_);
     if (gradVBB_ != NULL) delete (gradVBB_); if (jacobien_ != NULL) delete (jacobien_); };

   // surcharge d'affectation
Deformation::Stmet& Deformation::Stmet::operator= (const Deformation::Stmet& ex)  
	{ if (ex.giB_ != NULL)
     {if (giB_ == NULL) {giB_= new BaseB(*(ex.giB_));} else {(*giB_) = *(ex.giB_);};}
   else {if (giB_ != NULL) {delete giB_;giB_=NULL;}};
  
	  if (ex.giH_ != NULL)
     {if (giH_ == NULL) {giH_= new BaseH(*(ex.giH_));} else {(*giH_) = *(ex.giH_);};}
   else {if (giH_ != NULL) {delete giH_;giH_=NULL;}};
  
	  if (ex.gijBB_ != NULL)
     {if (gijBB_ == NULL) {gijBB_= NevezTenseurBB(*(ex.gijBB_));} else {(*gijBB_) = *(ex.gijBB_);};}
   else {if (gijBB_ != NULL) {delete gijBB_;gijBB_=NULL;}};
  
	  if (ex.gijHH_ != NULL)
     {if (gijHH_ == NULL) {gijHH_= NevezTenseurHH(*(ex.gijHH_));} else {(*gijHH_) = *(ex.gijHH_);};}
   else {if (gijHH_ != NULL) {delete gijHH_;gijHH_=NULL;}};
  
	  if (ex.gradVmoyBB_ != NULL)
     {if (gradVmoyBB_ == NULL) {gradVmoyBB_= NevezTenseurBB(*(ex.gradVmoyBB_));}
	      else {(*gradVmoyBB_) = *(ex.gradVmoyBB_);};
     }
   else {if (gradVmoyBB_ != NULL) {delete gradVmoyBB_;gradVmoyBB_=NULL;}};
  
	  if (ex.gradVBB_ != NULL)
     {if (gradVBB_ == NULL) {gradVBB_= NevezTenseurBB(*(ex.gradVBB_));}
	      else {(*gradVBB_) = *(ex.gradVBB_);};
     }
   else {if (gradVBB_ != NULL) {delete gradVBB_;gradVBB_=NULL;}};
  
	  if (ex.jacobien_ != NULL)
    {if (jacobien_ == NULL) {jacobien_= new double(*(ex.jacobien_));}
	      else {(*jacobien_) = *(ex.jacobien_);};
    }
   else {if (jacobien_ != NULL) {delete jacobien_;jacobien_=NULL;}};
  
   return *this;
 };

    // affichage des infos
void Deformation::Stmet::Affiche() 
  { cout << "\n scockage_metrique: " << "giB: " << (*giB_) << " giH: " << (*giH_)
         << " gijBB: "; gijBB_->Ecriture(cout); cout << " gijHH: "; gijHH_->Ecriture(cout); 
    cout << " gradVmoyBB: "; gradVmoyBB_->Ecriture(cout); cout << " gradVBB: ";
    gradVBB_->Ecriture(cout); cout << " jacobien: " << (*jacobien_);
  };

// surcharge de l'operateur de lecture
istream & operator >> ( istream & ent, Deformation::Stmet & ba)
  { // lecture du type et verification
    string nomtype; ent >> nomtype;
    if (nomtype != "Stmet")
      { Sortie(1);
        return ent;
       }        
    // lecture des informations
    ent >> (*(ba.giB_)) >> (*(ba.giH_)); ba.gijBB_->Lecture(ent); ba.gijHH_->Lecture(ent); 
    ba.gradVmoyBB_->Lecture(ent); ba.gradVBB_->Lecture(ent); ent >> (*(ba.jacobien_));
    return ent;      
  };

// surcharge de l'operateur d'ecriture
ostream & operator << ( ostream & sort,const  Deformation::Stmet & ba)
  { // ecriture du type, et des informations
    sort << " Stmet  " << " " << (*(ba.giB_)) << " " << (*(ba.giH_))
         << " "; ba.gijBB_->Ecriture(sort); ba.gijHH_->Ecriture(sort); 
    ba.gradVmoyBB_->Ecriture(sort); ba.gradVBB_->Ecriture(sort); 
    sort << (*(ba.jacobien_)) << " ";
    return sort;      
  };


//----------------------------------------------------------------------------------------------
// //   implantation concernant la  classe conteneur spécifique à chaque point ou la déformation 
// //   est calculée

	// constructeur par défaut -> à ne pas utiliser -> message d'erreur
Deformation::SaveDefResul::SaveDefResul()
  { cout << "\n **** erreur d'utilisation de constructeur "
         << "\n Deformation::SaveDefResul::SaveDefResul()";
    Sortie(1);     
   };

    // le constructeur recevable
Deformation::SaveDefResul::SaveDefResul(const Met_abstraite& meta):
    meti_00(meta.Dim_vec_base(),meta.Nbvec_des_bases())
   ,meti_t(meta.Dim_vec_base(),meta.Nbvec_des_bases())
   ,meti_tdt(meta.Dim_vec_base(),meta.Nbvec_des_bases())
   ,enu_type(SAVEDEFRESUL_GENERAL)
       {D_BB_t=NevezTenseurBB(meta.Nbvec_des_bases());
        D_BB_tdt=NevezTenseurBB(meta.Nbvec_des_bases());
       };
   // le constructeur de copie
Deformation::SaveDefResul::SaveDefResul(const SaveDefResul& a):
   meti_00(a.meti_00),meti_t(a.meti_t),meti_tdt(a.meti_tdt)
   ,enu_type(SAVEDEFRESUL_GENERAL)
   ,D_BB_t(NevezTenseurBB(*(a.D_BB_t))),D_BB_tdt(NevezTenseurBB(*(a.D_BB_tdt)))
       {};
   // destructeur
Deformation::SaveDefResul::~SaveDefResul()
   {delete D_BB_t; delete D_BB_tdt; };
   // surcharge de l'opérateur d'affectation
Deformation::SaveDefResul& Deformation::SaveDefResul::operator= (const Deformation::SaveDefResul& a)
  {meti_00 = a.meti_00; meti_t = a.meti_t; meti_tdt = a.meti_tdt;
   (*D_BB_t) = (*a.D_BB_t);(*D_BB_tdt) = (*a.D_BB_tdt);
   return *this;};
   // affichage des infos
void Deformation::SaveDefResul::Affiche()
  {cout << "\n meti_00: " ; meti_00.Affiche(); cout << " meti_t: "; meti_t.Affiche(); 
   cout << " meti_tdt ";meti_tdt.Affiche(); cout <<" ";
   cout << " D_BB_t= ";D_BB_t->Ecriture(cout); cout << " D_BB_tdt= ";D_BB_tdt->Ecriture(cout);
   cout <<" ";};
   // idem sur un ostream
void Deformation::SaveDefResul::Affiche(ostream& sort)			        
  {sort << "\n meti_00: " << meti_00 << " meti_t " << meti_t 
        << " meti_tdt " << meti_tdt <<" ";
   sort << " D_BB_t= ";D_BB_t->Ecriture(sort); sort << " D_BB_tdt= ";D_BB_tdt->Ecriture(sort);
   sort <<" ";};

  //============= 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 Deformation::SaveDefResul::Lecture_base_info (istream& ent,const int cas)
   { // lecture de l'entête
     string nom; 
     // lecture des données
    switch (cas)
     { case 1 :
         ent >> nom;
         if (nom != "SaveDefResul:")
         { cout << "\n erreur de lecture d'entete de SaveDefResul, nom lue: " << nom
              << "\n Deformation::SaveDefResul::Lecture_base_info (...";
         Sortie(1);
         }
         ent >> nom >>  meti_00 >> nom >> meti_t ;
         ent >> nom; D_BB_t->Lecture(ent);
         break;
       case 2 :
// -- on test --       
//         ent >> nom;
//         if (nom != "SaveDefResul:")
//         { cout << "\n erreur de lecture d'entete de SaveDefResul, nom lue: " << nom
//              << "\n Deformation::SaveDefResul::Lecture_base_info (...";
//         Sortie(1);
//         }
//         ent >> nom >>  meti_t ; 
         break;
         
       default:
          cout << "\n cas non considere !!: cas= " << cas 
               << "\n   Deformation::SaveDefResul::Lecture_base_info (...";
          Sortie(1);
       }
     };               
            // cas donne le niveau de sauvegarde
            // = 1 : on sauvegarde tout
            // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void Deformation::SaveDefResul::Ecriture_base_info(ostream& sort,const int cas)
  { // on ne sauvegarde que ce qui est à 0 et à t, ce qui est à tdt est considéré une zone de travail
    switch (cas)
     { case 1 :
         sort << " SaveDefResul: ";
         sort << " meti_00: " << meti_00 << " meti_t: " << meti_t << " ";
         sort << " D_BB_t= ";D_BB_t->Ecriture(sort);sort << " ";
         break;
       case 2 :
// -- on test --       
//         sort << " SaveDefResul: ";
//         sort << " meti_t: " << meti_t << " ";
         break;
       default:
          cout << "\n cas non considere !!: cas= " << cas 
               << "\n   Deformation::SaveDefResul::Ecriture_base_info(...";
          Sortie(1);
       }        
     };

// mise à jour des grandeurs meti_00  et meti_t
// *** non car dans le cas d'un restart ce n'est pas vrai !!!! //et init par recopie des grandeurs sur t
void Deformation::SaveDefResul::MiseAJourGrandeurs_a_0
     (const Met_abstraite * metrique)
	{ // on récupère des infos dans un conteneur qui normalement dans le cas de la déformation
	  // est correctement alimenté pour les grandeurs qui nous intéressent
      // récup du conteneur Expli_t_tdt
      const Met_abstraite::Expli_t_tdt& ex = metrique->Conteneur_Expli_tdt();
      // mise à jour des grandeurs à 0 
      *(meti_00.giB_) = *(ex.giB_0);*(meti_00.giH_) = *(ex.giH_0); 
      *(meti_00.gijBB_) = *(ex.gijBB_0);*(meti_00.gijHH_) = *(ex.gijHH_0);
      *(meti_00.jacobien_) = *(ex.jacobien_0);
      D_BB_t->Inita(0.);
// *** non car dans le cas d'un restart ce n'est pas vrai !!!!       //et init par recopie des grandeurs sur t
//      meti_t = meti_00;
      *(meti_t.giB_) = *(ex.giB_t);*(meti_t.giH_) = *(ex.giH_t);
      *(meti_t.gijBB_) = *(ex.gijBB_t);*(meti_t.gijHH_) = *(ex.gijHH_t);
      *(meti_t.jacobien_) = *(ex.jacobien_t);
  
	};	        
// mise à jour des grandeurs meti_tdt
void Deformation::SaveDefResul::MiseAJourGrandeurs_a_tdt
          (const Met_abstraite * metrique,const TenseurBB& Deps_BB)
	{ // on récupère des infos dans un conteneur qui normalement dans le cas de la déformation
	  // est correctement alimenté pour les grandeurs qui nous intéressent
      // récup du conteneur Expli_t_tdt
      const Met_abstraite::Expli_t_tdt& ex = metrique->Conteneur_Expli_tdt();
       // mise à jour des grandeurs à tdt 
      *(meti_tdt.giB_) = *(ex.giB_tdt);*(meti_tdt.giH_) = *(ex.giH_tdt); 
      *(meti_tdt.gijBB_) = *(ex.gijBB_tdt);*(meti_tdt.gijHH_) = *(ex.gijHH_tdt);
      if (ex.gradVmoyBB_tdt != NULL) *(meti_tdt.gradVmoyBB_) = *(ex.gradVmoyBB_tdt);
      if (ex.gradVBB_tdt != NULL) *(meti_tdt.gradVBB_) = *(ex.gradVBB_tdt);
      *(meti_tdt.jacobien_) = *(ex.jacobien_tdt);
      (*D_BB_tdt)=Deps_BB;
	};	        
