// 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:        04/07/2016                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:                                                             *
 *    Def de classes conteneurs pour manipuler différentes pondérations *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 ************************************************************************/
 
#ifndef PONDERATION_H
#define PONDERATION_H


#include <string>
#include "Tableau_T.h"
#include "Enum_GrandeurGlobale.h"
#include "Fonction_nD.h"
#include "Ddl_enum_etendu.h"
#include "Courbe1D.h"
#include "LesCourbes1D.h"
#include "LesFonctions_nD.h"
#include "Enum_TypeQuelconque.h"
#include "LesPtIntegMecaInterne.h"
#include "Noeud.h"
#include "Deformation.h"

/** @defgroup Les_classes_Ponderation
*
*     BUT:   Def de classes conteneurs pour manipuler différentes pondérations
*
*
* \author    Gérard Rio
* \version   1.0
* \date      04/07/2016
* \brief       Def de classes conteneurs pour manipuler différentes pondérations
*
*/

/// @addtogroup Les_classes_Ponderation
///  @{
///

  // --------------------------------------------------------------------------------------
  /// une classe de travail, qui permet d'utiliser une pondération qui dépend de  plusieurs
  /// courbe1D, chacune dépendant d'une grandeur consultable par un string
  // --------------------------------------------------------------------------------------

		 class Ponderation_Consultable
    {	public:
			     Ponderation_Consultable (); // le constructeur par défaut
			     Ponderation_Consultable (const Ponderation_Consultable& a); // le constructeur de copie
			     ~Ponderation_Consultable (); // destructeur
     
        // -------- affectation des fonctions à partir des noms sauvegardés
        // intéressant quand cette affectation à lieu longtemps après la lecture
        void Affectation_fonctions(LesCourbes1D& lesCourbes1D);

        // --- acces aux données---
        // à chaque grandeur est associé une fonction 1D
        Tableau <string>& Type_grandeur_Consultable() {return type_grandeur_Consultable;};

        // les fonctions 1D
        Tableau <Courbe1D*>& C_proport() {return c_proport;};

        // le nom des fonctions, sert en particulier pour une définition
        //  différée avec la lecture: 1) lecture 2) affectation des courbes ... après
        Tableau <string>&  Tab_nom_fonction() {return tab_nom_fonction;};
     
        //-- vérification que tout est ok pour le calcul ------
        void Verif_complet() const;

	       //----- 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 Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D);
        // cas donne le niveau de sauvegarde
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
        void Ecriture_base_info(ofstream& sort,const int cas);
        // sortie du schemaXML: en fonction de enu 
        void SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu);
     
      protected:
			     Tableau <string>  type_grandeur_Consultable; // à chaque grandeur est associé une fonction 1D
			     Tableau <Courbe1D*> c_proport; // les fonctions 1D
        Tableau <string> tab_nom_fonction; // le nom des fonctions, sert en particulier pour une définition
                             //  différée avec la lecture: 1) lecture 2) affectation des courbes ... après
			 };
/// @}  // end of group
/// @addtogroup Les_classes_Ponderation
///  @{
///

  // --------------------------------------------------------------------------------------
  /// une classe de travail, qui permet d'utiliser une pondération qui dépend d'un ensemble
  /// de grandeurs globales au travers d'une fonction nD
  // --------------------------------------------------------------------------------------

		 class Ponderation_GGlobal
    {	public:
			     Ponderation_GGlobal (); // le constructeur par défaut
			     Ponderation_GGlobal (const Ponderation_GGlobal& a); // le constructeur de copie
			     ~Ponderation_GGlobal (); // destructeur
     
        // lecture sur le flot d'entrée
        void LecturePonderation(const List_io <string>& grandeurs
                                , UtilLecture * entreePrinc,LesFonctions_nD& lesFonctionsnD);

        // -------- affectation de la fonction à partir du nom sauvegardé
        // intéressant quand cette affectation à lieu longtemps après la lecture
        void Affectation_fonctions(LesFonctions_nD& lesFonctionsnD);

        // --- acces aux données---
        // le nom de la fonction
        string& Nom_fonction() {return nom_fonction;}

        // la fonction multidimentionnel pour l'utilisation
			     Fonction_nD* C_proport() {return c_proport;};
        // la fonction multidimentionnel pour sont affectation
			     void Assigne_proport(Fonction_nD* pt) {c_proport = pt;};
     
        //-- vérification que tout est ok pour le calcul ------
        void Verif_complet() const;
     
        // affichage
        void Affiche();

	       //----- 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 Lecture_base_info(ifstream& ent,const int cas,LesFonctions_nD& lesFonctionsnD);
	       // idem mais sans définition de la courbe:
        // correspond au cas de la sauvegarde avec san_courbe = true
	       void Lecture_base_info(ifstream& ent,const int cas);
        // cas donne le niveau de sauvegarde
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
        // sans_courbe: indique si on sauve oui ou non la courbe elle-même
        // true: on sauve la courbe
        // false : on sauve uniquement le nom de la courbe
        void Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe=false);
        // sortie du schemaXML: en fonction de enu 
        void SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu);
     
      protected:
        string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction
                             //  différée avec la lecture: 1) lecture 2) affectation de la fonction ... après
			     Fonction_nD* c_proport; // la fonction multidimentionnel
			 };
/// @}  // end of group

/// @addtogroup Les_classes_Ponderation
///  @{
///

  // --------------------------------------------------------------------------------------
  /// une classe de travail, qui permet d'utiliser une pondération qui dépend d'un ensemble
  /// de grandeurs quelconque au travers d'une fonction nD
  // --------------------------------------------------------------------------------------

		 class Ponderation_TypeQuelconque
    {	public:
			     Ponderation_TypeQuelconque (); // le constructeur par défaut
			     Ponderation_TypeQuelconque (const Ponderation_TypeQuelconque& a); // le constructeur de copie
			     ~Ponderation_TypeQuelconque (); // destructeur
     
        // lecture sur le flot d'entrée
        // si grandeurs n'est pas vide, on vérifie que les grandeurs passées en paramètre
        // sont bien des variables de la fonction (locale ou globale)
        void LecturePonderation(const List_io <string>& grandeurs
                                , UtilLecture * entreePrinc,LesFonctions_nD& lesFonctionsnD);

        // -------- affectation de la fonction à partir du nom sauvegardé
        // intéressant quand cette affectation à lieu longtemps après la lecture
        void Affectation_fonctions(LesFonctions_nD& lesFonctionsnD);

        // --- acces aux données---
        // le nom de la fonction
        string& Nom_fonction() {return nom_fonction;}

//        // le type des grandeurs quelconques qui représentent les arguments de la fonction
//			     List_io <EnumTypeQuelconque>&  Type_grandeur_Quelc() {return type_grandeur_Quelconque;};

//        // les arguments pour l'appel de la fonction
//        Tableau <double>& Tab_argument() {return tab_argument;};

        // la fonction multidimentionnel pour l'utilisation
			     Fonction_nD* C_proport() {return c_proport;};
        // la fonction multidimentionnel pour sont affectation
			     void Assigne_proport(Fonction_nD* pt) {c_proport = pt;};
     
        //-- vérification que tout est ok pour le calcul ------
        void Verif_complet() const;

	       //----- 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 Lecture_base_info(ifstream& ent,const int cas,LesFonctions_nD& lesFonctionsnD);
	       // idem mais sans définition de la fonction nD:
        // correspond au cas de la sauvegarde avec san_courbe = true
	       void Lecture_base_info(ifstream& ent,const int cas);
        // cas donne le niveau de sauvegarde
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
        // sans_fct: indique si on sauve oui ou non la fonction elle-même
        // true: on sauve la fonction
        // false : on sauve uniquement le nom de la fonction
        void Ecriture_base_info(ofstream& sort,const int cas,bool sans_fct=false);
        // sortie du schemaXML: en fonction de enu 
        void SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu);
     
      protected:
        string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction
                             //  différée avec la lecture: 1) lecture 2) affectation de la fonction ... après
        
        Fonction_nD* c_proport; // la fonction multidimentionnel
        
        // des variables internes qui n'ont plus à être accessible en externe,
        // c'est la fonction nD qui stocke les infos
			     List_io < EnumTypeQuelconque >  type_grandeur_Quelconque; // les arguments de la fonction
        Tableau <double> tab_argument; //argument pour la fonction

			 };
/// @}  // end of group

/// @addtogroup Les_classes_Ponderation
///  @{
///

  // --------------------------------------------------------------------------------------
  /// une seconde classe de travail qui permet d'utiliser une pondération qui dépend de n
  /// Courbe1D, chacune fonction d'un ddl étendu
  // --------------------------------------------------------------------------------------

		 class Ponderation
    {	public:
			     Ponderation (); // le constructeur par défaut
			     Ponderation (const Ponderation& a); // le constructeur de copie
			     ~Ponderation (); // destructeur

        // -------- opération de lecture sur le flot d'entrée ------
     
     
        // lecture d'une courbe: intéressant si on lit courbe par courbe
        // le dimensionnement est mis à jour à chaque appel
        void LectureDonneesPonderation_uneCourbe
                      (Ddl_enum_etendu ddl, UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D);
        
        // lecture de l'ensemble de la pondération
        void LectureDonneesPonderation
                      (const List_io <string> & list_id_ddl_etendu
                      , UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D);
     
        // -------- affectation de la fonction à partir du nom sauvegardé
        // intéressant quand cette affectation à lieu longtemps après la lecture
        void Affectation_fonctions(LesCourbes1D& lesCourbes1D);

        // --- acces aux données---
     
        // à chaque grandeur est associé une fonction 1D
			     Tableau <Ddl_enum_etendu>& Type_grandeur() {return type_grandeur;};
			     const Tableau <Ddl_enum_etendu>& Const_Type_grandeur() const {return type_grandeur;};
     
        // indique si la grandeur est définie aux noeuds ou au point d'integ
			     Tableau <bool>& Valeur_aux_noeuds() {return valeur_aux_noeuds;};
			     const Tableau <bool>& Const_Valeur_aux_noeuds()const {return valeur_aux_noeuds;};
     
        // les fonctions 1D
			     Tableau <Courbe1D*>& C_proport() {return c_proport;};
			     const Tableau <Courbe1D*>& Const_C_proport() const {return c_proport;};
     
        // le nom des fonctions, sert en particulier pour une définition
        //  différée avec la lecture: 1) lecture 2) affectation des courbes ... après
        Tableau <string>& Tab_nom_fonction() {return tab_nom_fonction;};
     
        //-- vérification que tout est ok pour le calcul ------
        void Verif_complet() const;
     
        // affichage
        void Affiche();
     
        // activation des données des noeuds et/ou elements nécessaires au fonctionnement
        // exemple: mise en service des ddl de température aux noeuds
        void Activation_donnees
             (Tableau<Noeud *>& tabnoeud,bool dilatation,LesPtIntegMecaInterne& lesPtMecaInt);

        // calcul global de la pondération, sous forme d'un produit
        // NB: ar défaut ramène 1. si toutes les fonctions sont inactives
        // sinon ramène le produit :
        // 1) des fonctions de Ddl_enum_etendu accessibles
        //    soit au pti méca et ou soit par interpolation via def
        // 2) d'une fonction éventuelle du temps
        // 3) d'une fonction éventuelle de thermodonnee
        double CalculPonderMultiplicatif(const PtIntegMecaInterne& ptintmeca
                              ,const Deformation & def
                              ,Enum_dure temps,const ThermoDonnee& dTP);

	       //----- 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 Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D);
        // cas donne le niveau de sauvegarde
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
        void Ecriture_base_info(ofstream& sort,const int cas);
        // sortie du schemaXML: en fonction de enu 
        void SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu);
     
      protected:
			     Tableau <Ddl_enum_etendu>  type_grandeur; // à chaque grandeur est associé une fonction 1D
			     Tableau <bool> valeur_aux_noeuds; // indique si la grandeur est définie aux noeuds ou au point d'integ
			     Tableau <Courbe1D*> c_proport; // les fonctions 1D
        Tableau <string> tab_nom_fonction; // le nom des fonctions, sert en particulier pour une définition
                             //  différée avec la lecture: 1) lecture 2) affectation des courbes ... après
			 };
/// @}  // end of group

/// @addtogroup Les_classes_Ponderation
///  @{
///

  // --------------------------------------------------------------------------------------
  /// une classe de travail qui permet d'utiliser une pondération qui dépend
  ///  du temps via une Courbe1D
  // --------------------------------------------------------------------------------------

		 class Ponderation_temps
    {	public:
			     Ponderation_temps (); // le constructeur par défaut
			     Ponderation_temps (const Ponderation_temps& a); // le constructeur de copie
			     ~Ponderation_temps (); // destructeur
     
        // lecture sur le flot d'entrée
        void LectureDonneesPonderation (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D);
        
        // -------- affectation de la fonction à partir du nom sauvegardé
        // intéressant quand cette affectation à lieu longtemps après la lecture
        void Affectation_fonctions(LesCourbes1D& lesCourbes1D);

        // --- acces aux données---
        // le nom de la fonction, sert en particulier pour une définition de la fonction
        //  différée avec la lecture: 1) lecture 2) affectation de la fonction ... après
        string& Nom_fonction() {return nom_fonction;};
     
        // la fonctions 1D, fonction du temps
			     Courbe1D* C_proport() {return c_proport;};
     
        //-- vérification que tout est ok pour le calcul ------
        void Verif_complet() const;
     
        // affichage
        void Affiche();
     
        // calcul de la pondération
        // par défaut ramène 1. si la fonction du temps est inactive par exemple
        // sinon ramène la valeur de la fonction du temps actuel
        double CalculPonder();

	       //----- 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 Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D);
	       // idem mais sans définition de la courbe:
        // correspond au cas de la sauvegarde avec sans_courbe = true
	       void Lecture_base_info(ifstream& ent,const int cas);
        // cas donne le niveau de sauvegarde
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
        // sans_courbe: indique si on sauve oui ou non la courbe elle-même
        // true: on sauve la courbe
        // false : on sauve uniquement le nom de la courbe
        void Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe=false);
        // sortie du schemaXML: en fonction de enu 
        void SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu);
     
      protected:
        string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction
                             //  différée avec la lecture: 1) lecture 2) affectation de la fonction ... après
			     Courbe1D* c_proport; // la fonctions 1D, fonction du temps
			 };
/// @}  // end of group

 
#endif  
