
// 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/>.

/************************************************************************
 *     DATE:        07/01/2008                                          *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:  Visualisation du maillage initiale en Gmsh.                *
 *           Uniquement l'ordre d'exécution est différent de la classe  *
 *                      vrml.                                           *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
#ifndef MAIL_INITIALE_GMSH_T
#define MAIL_INITIALE_GMSH_T

#include "OrdreVisu.h"

/// @addtogroup Les_sorties_gmsh
///  @{
///


class Mail_initiale_Gmsh : public OrdreVisu 
{
  public :
    // CONSTRUCTEURS :
    // par defaut
    Mail_initiale_Gmsh () ; 
    
    // constructeur de copie 
    Mail_initiale_Gmsh (const Mail_initiale_Gmsh& algo);
               
    // DESTRUCTEUR :
    ~Mail_initiale_Gmsh () ;
    
    // METHODES PUBLIQUES :
    // initialisation : permet d'initialiser les différents paramètres de l'ordre
    // lors d'un premier passage des différents incréments
    // en virtuelle, a priori est défini si nécessaire dans les classes dérivées
    // incre : numéro d'incrément qui en cours
    void Initialisation(ParaGlob * ,LesMaillages *,LesReferences*
                      ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*,LesContacts*
                      ,Resultats*,EnumTypeIncre type_incre,int incre
                      ,const map < string, const double * , std::less <string> >& listeVarGlob
                      ,const List_io < TypeQuelconque >& listeVecGlob
                      ,bool fil_calcul) ;
    // execution de l'ordre
    // tab_mail : donne les numéros de maillage concerné
    // incre : numéro d'incrément qui en cours
    // type_incre : indique si c'est le premier le dernier ou l'incrément courant a visualiser ou pas
    // animation : indique si l'on est en animation ou pas
    // unseul_incre : indique si oui ou non il y a un seul increment à visualiser
    void ExeOrdre(ParaGlob * ,const Tableau <int>& tab_mail ,LesMaillages *,bool unseul_incre,LesReferences*
                      ,LesLoisDeComp* ,DiversStockage*,Charge*,LesCondLim*,LesContacts*
                      ,Resultats*,UtilLecture & entreePrinc,OrdreVisu::EnumTypeIncre type_incre,int incre
                      ,bool animation,const map < string, const double * , std::less <string> >& listeVarGlob
                      ,const List_io < TypeQuelconque >& listeVecGlob);
    
    // choix de l'ordre, cet méthode peut entraîner la demande d'informations
    // supplémentaires si nécessaire. qui sont ensuite gérer par la classe elle même
    void ChoixOrdre();                   
    
    // lecture des paramètres de l'ordre dans un flux
    void Lecture_parametres_OrdreVisu(UtilLecture & entreePrinc);
    // écriture des paramètres de l'ordre dans un flux
    void Ecriture_parametres_OrdreVisu(UtilLecture & entreePrinc);
    
    // récupération éventuelle de la liste des noms des différentes référence à sortir
    // à l'écriture, chaque grandeurs s'écrit sur un fichier propre
    // cette fonction sert donc à préparer l'ouverture de ces fichiers
    // dans le cas où le tableau est vide cela signifie que les ref seront dans le fichier principal
    const Tableau <string>* NomsGrandeurSortie() const
      {if (sortie_des_references==2) {return &tab_nom_tag_ref;} else {return NULL;}};
    
    // ramène le tableau de listes de sous maillage
    const Tableau < Tableau < List_io <  Element* > > > & 
                   Tableau_de_sous_maillage() const {return tabtab_sous_mesh;};
    // ramène le tableau de le listes de types d'éléments différents
    const Tableau < List_io <Element::Signature> >& 
                   Tab_liste_type_element() const { return tabli_sig_elem;};                 
    // ramène le tableau de listes de noms des sous maillages
    const Tableau < List_io <string> >& 
                   Tab_listes_nom_sousMaillage() const { return tabli_sous_mesh;};
    // ramène le  décalages  pour les numéros de noeuds du maillage "nmail"
    int DecalNumNoeud(int nmail) const {return decal_noeud(nmail);};
    // ramène le décalages pour les numéros d'éléments du maillage "nmail"
    int DecalNumElement(int nmail) const {return decal_element(nmail);};
    
    // ramène le tableau t_Egmsh
    // t_Egmsh(im)(ie): donne pour le maillage im, et pour l'élément ie, le numéro gmsh de l'élément
    const Tableau < Tableau < int > >& TabEgmsh() const {return t_Egmsh;}; 
	 
    // indique s'il y a quelque chose à regarder du coté des homothetie sur le maillage initiale
    bool Considerer_homothetie() const {return considerer_homothetie;};
    // ramène un tableau de bool qui indique si oui ou non on fait une pseudo-homothétie sur les coordonnées initiales de chaque maillage
    const Tableau < bool >& T_homothetie() const{return t_homothetie ;};
    // ramène l'origine et les facteurs multiplicatifs pour une pseudo-homothétie pour chaque maillage
    const Tableau <Coordonnee >& T_orig()const {return t_orig;};
    const Tableau <Coordonnee >& T_fact_mult() const {return t_fact_mult;}; 
	
    // sortie maillage initiale (sans références ni tag) avec le nouveau format
    void sortie_maillage_initial(const Tableau <int>& tab_mail,LesMaillages * lesMail, ostream &sort);
    // ramène le nombre total de noeuds
    int Nb_total_noeud()const {return nb_total_noeud;};
    // ramène le nombre total d'éléments
    int Nb_total_element() const {return nb_total_element;};
 
  private :  
    // VARIABLES PROTEGEES :
    // tableau de liste de sous maillages
    // chaque sous maillage représente un type d'élément fini particulier
    // l'indice du tableau= le numéro de maillage
    Tableau < Tableau < List_io <  Element* > > > tabtab_sous_mesh;
    // tableau de listes de type d'éléments différents 
    Tableau < List_io <Element::Signature> > tabli_sig_elem;
    // tableau de listes des nom des sous_maillages créés
    Tableau < List_io <string> > tabli_sous_mesh;
    // tableau des décalages pour les numéros de noeuds et d'éléments
    Tableau <int > decal_noeud; 
    Tableau <int > decal_element;
    int nb_total_noeud; // nombre total de noeuds
    int nb_total_element; // nombre total d'éléments 
    int nb_total_ref; // nombre total de références
    int sortie_des_references; // = 0, 1 ou 2: indique si oui (diff de 0) ou non
                               //               on veut une sortie des références
                               // = 1:  par défaut sortie des ref, dans un fichier unique
                               // = 2:  sortie des refs dans des fichiers séparés
    Tableau <string> tab_nom_tag_ref; //le tableau des noms des tag correspondant aux ref
	           // tab_nom_tag_ref(i) = le nom du tag associé à la ref i, i étant le numéro d'apparition
											 // de la référence, quand on parcours toutes les références
											 // tableau construit dans la méthode: Initialisation(..
    Tableau <const Reference* > lesRefInitiales; // le tableau des ref initiales, construit avec Initialisation(..
    
    Tableau <int > tab_num_tag;  // le tableau des numéros des tag correspondant aux ref
	           // tab_num_tag(i) = le numéro du tag associé à la ref i, i étant le numéro d'apparition
											 // de la référence, quand on parcours toutes les références
											 // tableau construit dans la méthode: SortieTagPhysicalNames
    // concernant les éléments points qu'il faut rajouter pour voir sous gmsh les références de noeud !!
    // un tableau d'adressage indirecte qui permet d'utiliser ces noeuds éléments
    Tableau <Tableau <int > > t_jonction_N_Nelem;
    // t_jonction_N_Nelem(i)(j) donne le numéro de noeud_élément correspondant à l'ancien numéro j pour le maillage i
    // n'est rempli que pour les noeuds ayant conduit à la création d'un noeud_élément
    
    // concernant les ref de pti: on stocke le nombre de noeud additionnel et de noeud élément additionnel: 
    int nombre_noeud_ref_pti; // c'est le même nombre: à chaque pti on ajoute un noeud et un noeud élément
    int nombre_ref_pti; // nombre de référence de point d'intégration
    // un tableau d'adressage indirecte qui permet d'utiliser ces noeuds éléments pour les pti
    Tableau <Tableau <int > > t_jonction_N_NelemPti;
    // t_jonction_N_NelemPti(i)(j) donne le numéro de noeud_élément correspondant
    // au numéro j dans la ref, pour la référence de pti i
    // n'est rempli que pour les noeuds ayant conduit à la création d'un noeud_élément

    Tableau <int > tab_dim_de_ref; // tab_dim_de_ref(i) donne la dimension des éléments
              //                       de la ref de nom tab_nom_tag_ref(i)
              // 1 pour ligne 2 pour surface, 3 pour volume, 0 pour autre
    // un tableau de liaison entre les éléments herezh des maillages et les numéros associés de  gmsh
    // t_Egmsh(im)(ie): donne pour le maillage im, et pour l'élément ie, le numéro gmsh de l'élément
    Tableau < Tableau < int > > t_Egmsh;
    
    bool considerer_homothetie; // indique s'il y a quelque chose à regarder du coté des homotheties
              //  (on pourrait faire avec t_homothetie mais c'est plus facile avec un paramètre globale)
    Tableau < bool > t_homothetie ; // oui ou non on fait une pseudo-homothétie sur les coordonnées
                                    // initiales de chaque maillage
    // on considère un rapport d'homothétie qui peut-être différent sur les 3 axes d'ou le nom de pseudo
    Tableau <Coordonnee > t_orig,t_fact_mult; // origine et facteurs multiplicatifs pour
                                               // une pseudo-homothétie pour chaque maillage

    // METHODES PROTEGEES :
    // sortie de la définition des tag de PhysicalNames (sert pour les références)
    void SortieTagPhysicalNames(const Tableau <int>& tab_mail,LesMaillages * lesMail,ostream &sort);
    // sortie uniquement des noeuds avec éventuellement, def de noeud aux  points d'intégration
    void SortieDesNoeuds(const Tableau <int>& tab_mail,LesMaillages * lesMail, ostream &sort);
    // sortie uniquement des éléments
    void SortieDesElements(const Tableau <int>& tab_mail,LesMaillages * lesMail,ostream &sort);
    // sortie des références
    void SortieReferences(const Tableau <int>& tab_mail,LesMaillages * lesMail,UtilLecture & entreePrinc);								
    // sortie éventuelle d'un seul élément au format gmsh
    // et modification éventuelle du tableau t_Egmsh
    // num_elem : numero initial de l'élément
    // decal_ele : décalage de numéro pour tenir compte de la présence de plusieurs maillages
    //             (ou sous maillages)
    // decal_noe : décalage de numéro de noeud, pour tenir compte de la présence de plusieurs maillages
    // tab_noeud : le tableau des noeuds de la connection
    // id_geom et id_interpol : permettent de repérer un type d'élément fini associé
    //                          (donc pas seulement géométrique)
    //                        : il s'agit ici de la géométrie et interpolation "élément fini"  
    // sort  : flux de sortie
    // modifier_t_Egmsh : indique si pour l'élément considéré, on abonde le tableau t_Egmsh
    // im : num du maillage ou sous maillage
    // elem_a_sortir : indique si pour l'élémen considéré, on le sort dans le fichier gmsh
    void SortieDunElements(bool elem_a_sortir, const int& num_elem
                           , ostream &sort
                           , const int& decal_ele, Tableau<Noeud *>& tab_noeud
                           , const int& decal_noe, Enum_geom id_geom, Enum_interpol id_interpol
                           , bool modifier_t_Egmsh , int im);
     // constitution des sous maillages, utilisé par les isovaleurs par exemple
     // on suit la même logique que dans gid, un sous maillage par type d'élément
     // ce n'est pas nécessaire, c'est pas simplicité, à modifier si nécessaire par la suite
     void CreaSousMaillages(const Tableau <int>& tab_mail,LesMaillages * lesMail);                      
     // sortie sur le flot passé en paramètre, de la partie noeud du maillage sans entête ni fin
     void Sortie_noeuds_initiaux(const Tableau <int>& tab_mail,LesMaillages * lesMail, ostream &sort);
     // sortie sur le flot passé en paramètre, de la partie élément du maillage sans entête ni fin
     void Sortie_element_initiaux(const Tableau <int>& tab_mail,LesMaillages * lesMail, ostream &sort);
 };
 /// @}  // end of group

#endif  
