

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

/************************************************************************
 *     DATE:        13/04/2004                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:  Interface pour les lois thermo_physiques.                  *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
// FICHIER : CompThermoPhysiqueAbstraite.h
// CLASSE : CompThermoPhysiqueAbstraite

/// pour les comportements thermophysiques


#ifndef COMPTHERMOPHYSIQUEABSTRAITE_H
#define COMPTHERMOPHYSIQUEABSTRAITE_H


#include "Enum_comp.h"
#include "Tableau_T.h"
#include "Tenseur.h"
#include "Deformation.h"
#include "LoiAbstraiteGeneral.h"
#include "ThermoDonnee.h"
#include "TypeQuelconque.h"
#include "PtIntegMecaInterne.h"
#include "LesPtIntegThermiInterne.h"
#include "EnergieThermi.h"
#include "Temps_CPU_HZpp.h"
#include "Bloc.h"


class CompThermoPhysiqueAbstraite : public LoiAbstraiteGeneral
{

	public :

		// CONSTRUCTEURS :
		
		// Constructeur par defaut
		CompThermoPhysiqueAbstraite () ;
		
		// Constructeur utile si l'identificateur du nom de la loi
		// de comportement et la dimension sont connus
		CompThermoPhysiqueAbstraite (Enum_comp id_compor,Enum_categorie_loi_comp categorie_comp,int dimension);
		
		// Constructeur utile si l'identificateur du nom de la loi
		// de comportement et la dimension sont connus	
		CompThermoPhysiqueAbstraite (char* nom,Enum_categorie_loi_comp categorie_comp,int dimension);
	
		// Constructeur de copie
		CompThermoPhysiqueAbstraite (const CompThermoPhysiqueAbstraite & a );
		 
		// DESTRUCTEUR VIRTUEL :
	
		virtual ~CompThermoPhysiqueAbstraite ();
		
		
// 2) METHODES VIRTUELLES  public:
		
	 // classe de stockage de paramètres de travail, utiliser par les classes dérivées
	 class StockParaInt // on globalise, pour ne pas stocker lors que l'on ne veut pas postraiter
	  {public:
	     // constructeur par défaut
	     StockParaInt() :  pression(0.),temperature(0.) {};
	     // constructeur fonction des paramètres
	     StockParaInt(double press,  double temper) :
	        pression(press),temperature(temper) {};
	     // constructeur de copie
	     StockParaInt(const StockParaInt& a) :
	        pression(a.pression),temperature(a.temperature) {};
	        
      double pression;
	     double temperature;
	  };
	     
		// initialise les donnees particulieres a l'elements
		// de matiere traite ( c-a-dire au pt calcule)
		// Il y a creation d'une instance de SaveResul particuliere
		// a la loi concernee
		// la SaveResul classe est remplie par les instances heritantes
		// le pointeur de SaveResul est sauvegarde au niveau de l'element
		// c'a-d que les info particulieres au point considere sont stocke
		// au niveau de l'element et non de la loi.
		class SaveResul 
		 { public : 
		    // destructeur virtuelle car d'une classe virtuelle
		    virtual ~SaveResul() {};
		    // définition d'une nouvelle instance identique
		    // appelle du constructeur via new 
		    virtual SaveResul * Nevez_SaveResul() const =0;		    
      // affectation
      virtual SaveResul & operator = ( const SaveResul &) = 0;
	        //============= 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)
      virtual void Lecture_base_info (ifstream& ent,const int cas)  = 0;
            // cas donne le niveau de sauvegarde
            // = 1 : on sauvegarde tout
            // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
      virtual void Ecriture_base_info(ofstream& sort,const int cas) = 0;
	        
	     // mise à jour des informations transitoires en définitif s'il y a convergence 
	     // par exemple (pour la plasticité par exemple)
	     virtual void TdtversT() = 0;
	     virtual void TversTdt() = 0;	        	        
    
      //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)
      virtual void ChBase_des_grandeurs(const Mat_pleine& beta,const Mat_pleine& gamma) = 0;
    
      // on stocke la température initiale (les autres sont dans les ptinthermi)
      double temperature_0;
   };

		virtual SaveResul * New_et_Initialise() { return NULL;};
		
		// affichage des donnees particulieres a l'elements
		// de matiere traite ( c-a-dire au pt calcule)
		virtual void AfficheDataSpecif(ofstream& ,SaveResul * ) const {};
		
  // ramène les données thermiques défnies au point
  // P: la pression à l'énuméré temps, et P_t la pression au temps t
  virtual void Cal_donnees_thermiques(const double& P_t, CompThermoPhysiqueAbstraite::SaveResul * saveTP
	                    ,const Deformation & def,const double& P,Enum_dure temps,ThermoDonnee& donneeThermique) = 0;
		// définition du type de calcul de déformation sur une instance de déformation passée en paramètre
		void Def_type_deformation(Deformation & def);
 
  // calcul de toutes les grandeurs associées à la température (mais pas le flux), qui sont stockées
  // dans le point d'intégration : ptIntegThermi
  // et de la variation du gradient thermique / au ddl
  void Cal_cinematique_thermique(bool premier_calcul,PtIntegThermiInterne& ptIntegThermi
                                 ,Tableau <CoordonneeB >& d_gradTB
                                 ,Deformation & def,const Met_abstraite::Impli& ex);


  // schema de calcul explicite à t
//  virtual const Met_abstraite::Expli& Cal_explicit_t
//                 (Loi_comp_abstraite::SaveResul * saveDon
//                  ,Deformation & def, DdlElement & tab_ddl
//                  ,PtIntegMecaInterne& ptintmeca,Tableau <TenseurBB *> & d_epsBB,double& Jacobien
//                  ,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
//                  ,bool dilatation,EnergieMeca & energ,const EnergieMeca & energ_t,bool premier_calcul
//                  );
//         
//  // schema de calcul explicite à tdt
//  virtual const Met_abstraite::Expli_t_tdt& Cal_explicit_tdt 
//                 (Loi_comp_abstraite::SaveResul * saveDon
//                  ,Deformation & def, DdlElement & tab_ddl
//                  ,PtIntegMecaInterne& ptintmeca,Tableau <TenseurBB *> & d_epsBB,double& Jacobien
//                  ,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
//                  ,bool dilatation,EnergieMeca & energ,const EnergieMeca & energ_t,bool premier_calcul
//                  );
 
  // schema implicit	
  // P et P_t : pression actuelle et pression à t
   virtual const Met_abstraite::Impli& Cal_implicit
                 (const double & P_t,CompThermoPhysiqueAbstraite::SaveResul * saveDon
                  , const double & P,Deformation & def,DdlElement & tab_ddl
	                 ,PtIntegThermiInterne& ptIntegThermi, Tableau <CoordonneeB >& d_gradTB
		  	             ,Tableau <CoordonneeH >& d_fluxH,const ParaAlgoControle & pa
		  	             ,CompThermoPhysiqueAbstraite* loiTP
		  	             ,bool dilatation,EnergieThermi & energ,const EnergieThermi & energ_t,bool premier_calcul
                  );
		  	
//  // schema pour le flambage linéaire	
//	 virtual void Cal_flamb_lin
//                (Loi_comp_abstraite::SaveResul * saveDon,Deformation & def
//                 ,DdlElement & tab_ddl
//	                ,PtIntegMecaInterne& ptintmeca, Tableau <TenseurBB *>& d_epsBB_tdt,double& jacobien
//	                ,Vecteur& d_jacobien_tdt,Tableau <TenseurHH *>& d_sigHH,const ParaAlgoControle & pa
//		  	            ,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
//		  	            ,bool dilatation,EnergieMeca & energ,const EnergieMeca & energ_t,bool premier_calcul
//                 );
//		
//		// schema pour le calcul de la loi de comportement dans le cas de  l'umat 
//  virtual void ComportementUmat
//                ( Loi_comp_abstraite::SaveResul * saveDon
//                 ,Deformation & def,PtIntegMecaInterne& ptintmeca
//		  	            ,ParaAlgoControle & pa
//		  	            ,CompThermoPhysiqueAbstraite::SaveResul * saveTP,CompThermoPhysiqueAbstraite* loiTP
//		  	            ,bool dilatation,UmatAbaqus& umatAbaqusqus,bool premier_calcul
//                 );
 
		// 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
		virtual void Activation_donnees(Tableau<Noeud *>& tabnoeud) {Activ_donnees(tabnoeud);};
		
		// modification de l'indicateur de comportement tangent
		void Modif_comp_tangent_simplifie(bool modif)
		  { comp_tangent_simplifie = modif;};  	

  // test pour connaître l'état du comportement : simplifié ou non
  bool Test_loi_simplife()
    { return comp_tangent_simplifie;}; 

  // 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
  virtual void Grandeur_particuliere(bool absolue,List_io<TypeQuelconque>& ,CompThermoPhysiqueAbstraite::SaveResul * ,list<int>&)
      {};
  // 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
  virtual void ListeGrandeurs_particulieres(bool absolue,List_io<TypeQuelconque>& ) {};
            
  // création d'une loi à l'identique et ramène un pointeur sur la loi créée
  virtual CompThermoPhysiqueAbstraite* Nouvelle_loi_identique() const = 0;

	protected :
	
// 3) METHODES VIRTUELLES PURES protegees:
  // calcul des contraintes à un instant  t+deltat
  // les indices t se rapporte au pas précédent, sans indice au temps actuel
//  virtual void 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 & energ_t,double& module_compressibilite,double&  module_cisaillement
//		  	 ,const Met_abstraite::Expli_t_tdt& ex) = 0;
 
  // calcul du flux et ses variations  par rapport aux ddl a t+dt: stockage dans ptIntegThermi et dans d_flux
  // calcul également des paramètres thermiques dTP ainsi que des énergies mises en jeux
  // calcul des énergies thermiques
  // en entrée: température, gradient de temp, et grandeurs associées, métrique
  virtual void Calcul_DfluxH_tdt
    (const double & P_t,PtIntegThermiInterne& ptIntegThermi, const double & P,DdlElement & tab_ddl
     ,const Deformation & def  // prévue pour servir pour l'interpolation
		  	, Tableau <CoordonneeB >& d_gradTB,Tableau <CoordonneeH >& d_flux,ThermoDonnee& dTP
		  	,EnergieThermi & energ,const EnergieThermi & energ_t,const Met_abstraite::Impli& ex) = 0;
		  	
//  // 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 orthonormée
//  //                  le tenseur de déformation et son incrémentsont également en orthonormee
//  //                 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
//  virtual void 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,TenseurHHHH& d_sigma_deps
//		  	,EnergieMeca & energ,const EnergieMeca & energ_t,double& module_compressibilite,double&  module_cisaillement
//		  	,const Met_abstraite::Umat_cont& ex) ; //= 0;
 
		// affichage et definition interactive des commandes particulières à la classe CompThermoPhysiqueAbstraite
  void Info_commande_don_LoisDeComp(UtilLecture& ) const {};
	    //----- lecture écriture de restart spécifique aux données de la classe -----
	    // 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 Lecture_don_base_info(ifstream& ,const int ,LesReferences& ,LesCourbes1D& ,LesFonctions_nD&) {};
        // cas donne le niveau de sauvegarde
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
  void Ecriture_don_base_info(ofstream& ,const int ) const {};

  // 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
  // méthode appelée par Activation_donnees principal, ou des classes dérivées
  // ce qui permet de surcharger ces dernières
  void Activ_donnees(Tableau<Noeud *>& tabnoeud);
  // calcul de grandeurs de travail aux points d'intégration via la def
  // fonction surchargée dans les classes dérivée si besoin est
  virtual void CalculGrandeurTravail(const PtIntegThermiInterne& ,const Deformation & ,Enum_dure) {};
			  	
		
// VARIABLES PROTEGEES :
  // pointeur de travail utilise par les classes derivantes		
  SaveResul * saveResul; 
  // indic pour définir si oui ou non on utilise un comportement tangent simplifié 
  bool comp_tangent_simplifie;
  // --------- variables gérées en I/O par les classes dérivées -------
  //  et variables de travail
  // indique si oui ou non la loi dépend de la température
  bool thermo_dependant; // paramètre lue par les classes dérivées
  double temperature; // variable valide que si l'on est thermo_dependant
                       // utilisée par les classes dérivées
 
  Temps_CPU_HZpp   temps_loi; // spécifique à ce type de loi: cumule tous les appels
 
                    // du calcul de la contrainte
 
};


#endif
