
// 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:        23/01/97                                            *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:  Stockage des parametres de controle.                       *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
#ifndef PARA_ALGOCONTROLE_H
#define PARA_ALGOCONTROLE_H

#include "UtilLecture.h"
#include "Enum_matrice.h"
#include "Enum_type_resolution_matri.h"
#include "Enum_calcul_masse.h"
#include "VariablesTemps.h"
#include "Basiques.h"
#include "EnumTypePilotage.h"
#include <vector>

/// @addtogroup Les_parametres_generaux
///  @{
///


class ParaAlgoControle
      { public :    
        //  CONSTRUCTEUR
        // par défaut
        ParaAlgoControle();
        // de copie
        ParaAlgoControle(const ParaAlgoControle& p);
        //destructeur
        ~ ParaAlgoControle() {};
        // Méthodes publiques
        
        // Surcharge de l'affectation
        ParaAlgoControle& operator= (const ParaAlgoControle& p);        
        // lecture sur le flot d'entrée
        void Lecture_paraAlgoControle(UtilLecture & entreePrinc);
        // affichage des paramètres de controle
        void Affiche() const ;
        // définition interactive exhaustive des paramètres de contrôle indépendamment de l'algorithme 
        // écriture du fichier de commande
        void Info_commande_ParaAlgoControle(UtilLecture& lec);
      
        // sauvegarde sur base info
        // cas donne le niveau de sauvegarde
        // = 0 : initialisation de la sauvegarde -> c'est-à-dire de la sortie base info
        // = 1 : on sauvegarde tout
        // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
        // incre : numero d'incrément auquel on sauvegarde 
        // éventuellement est définit de manière spécifique pour chaque algorithme
        // dans les classes filles
        void Ecriture_base_info_Para
             (ostream& sort,const int cas)  const;
        // cas de la lecture spécifique à l'algorithme dans base_info
        void Lecture_base_info_Para(istream& ent,const int cas); 
        
        // --- fonctions d'accès en lecture des paramètres
        // 1) ==== parametres de controle généraux pour la résolution de l'équilibre
        //     générale
        // nombre servant à gérer la frequence de sauvegarde
        // il faut utiliser Cas_de_sauvegarde() pour gérer correctement le nombre ramené en paramètre
        bool Sauvegarde()  const { if (sauvegarde != 0.) return true; else return false;}; 
        // indique si la sauvegarde est autorisée, en fonction des paramètres données par l'utilisateur et les variables
        // passée en argument
        // dernier_calcul : indique si c'est le dernier calcul ou pas 
        bool SauvegardeAutorisee(int incre,const double& temps_derniere_sauvegarde,bool dernier_calcul) const; 
        
        // maxi d'iteration pour converger
        int Iterations()  const { return iterations;};  
        // precision de la convergence
        double Precision()  const { return precision;};  
        // precision sur le temps final
        double Prectemps()  const { return tempo_specifique_algo.prectemps;};
        // type de norme de convergence
        Deux_String Norme()  const { return norme;};  
        // cinematique sur l'increment ?
        bool Cinematique()  const { return cinematique;};  
        // convergence forcee ?
        bool Conv_forcee() const  { return conv_forcee;};  
        // multiplicateur de la charge
        double Multiplicateur() const { return multiplicateur;};  
        // increment de temps
        double Deltat()  const { return tempo_specifique_algo.deltat;};
        // increment de temps maxi
        double Deltatmaxi () const  {return tempo_specifique_algo.deltatmaxi;};
        // increment de temps mini
        double Deltatmini () const  {return tempo_specifique_algo.deltatmini;};
        // temps de fin de calcul
        double Tempsfin() const  { return tempo_specifique_algo.tempsfin;};
        // test pour savoir si les incréments de temps courant ou maxi dépendent d'un temps critique 
        bool DeltatOuDeltatmaxDependantTempsCritique() const 
         {if ((coef_pas_critique_deltat!= coef_defaut_pa_critique)
 //        ((coef_pas_critique_deltat!=0.)
         ||(coef_pas_critique_deltatmaxi!=0.)) return true; else return false;};
        double Coefficient_pas_critique_deltat() const {return coef_pas_critique_deltat;};
        static double Coef_defaut_pa_critique() {return coef_defaut_pa_critique;} // valeur par défaut de coef_pas_critique_deltat

        double Coefficient_pas_critique_deltatmaxi() const {return coef_pas_critique_deltatmaxi;};
                // maximum d'increment de temps
        int Maxincre ()  const { return maxincre;};  
                // maximum de tentative d'increment de temps permis
        int Max_essai_incre ()  const { return max_essai_incre;};
        // increment de redemarage de calcul
        int Restart() const  { return restart;};   
        // maximum de puissance tolérée
        double Max_puissance() const  { return max_puissance;};   
        // indique si oui ou non on utilise le line_search
        bool Line_search()  const { return line_search;};
        // indique si oui ou non le chargement externe participe à la raideur
        bool Var_charge_externe() const {return var_charge_externe;};
        // indique si oui ou non la variation du jacobine participe à la raideur
        bool Var_jacobien() const {return var_jacobien;};
        // indique si oui ou non la variation de la vitesse de déformation participe à la raideur
        bool Var_D() const {return var_D;};
        //--- globalisation des paramètres liés au temps
        static const VariablesTemps& Variables_de_temps() {return tempo;};
        // idem pour les grandeurs spécifique
        const VariablesTemps& Variables_de_temps_specifiques_algo() {return tempo_specifique_algo;};

        // 2) ==== paramètres liés au système d'équations linéaires
        // type de stockage matriciel
        Enum_matrice Type_Matrice()  const { return type_matrice;};
        // assemblage symétrique ou non
        bool Symetrie_matrice () const  {return symetrie_matrice;};
        // type de résolution
        Enum_type_resolution_matri Type_resolution()  const { return type_resolution;};  
        // type de préconditionnement
        Enum_preconditionnement Type_preconditionnement() const  { return type_preconditionnement;};   
        // nombre d'itération dans le cas d'une méthode itérative
        int Nb_iter_nondirecte()  const { return nb_iter_nondirecte;};  
        // tolerance de convergence dans le cas d'une méthode itérative
        double Tolerance()  const { return tolerance;};  
        // nombre de vecteur sauvegardé dans le cas d'une méthode
        // itérative avec redépart
        int Nb_vect_restart()  const { return nb_vect_restart;};
        // même chose pour les matrices secondaires éventuelles
        // a priori les listes sont parcourues selon l'orde de type_matrice_secondaire, si les listes ont des
        // tailles différentes, les algos s'en débrouillent (à voir dans la doc et les algos)
        // *** ce n'est pas la peine d'essayer de remplacer les listes par des tableaux, c'est impossible
        // car Tableau_T intègre ParaGlob qui intègre ParaAgloControle et donc c'est un cercle infernal
        // donc si l'on veut vraiment des tableaux il faut passer par Tableau<T>::Init_from_list
        // et en dehors de la classe ParaAlgoControle !!
        const list < Enum_matrice >& Type_matrice_secondaire() const {return  type_matrice_secondaire;};
        const list < Enum_type_resolution_matri >& Type_resolution_secondaire() const {return  type_resolution_secondaire;};
        const list < Enum_preconditionnement >& Type_preconditionnement_secondaire() const {return  type_preconditionnement_secondaire;};
        const list < int >& Nb_iter_nondirecte_secondaire() const {return  nb_iter_nondirecte_secondaire;};
        const list < double >& Tolerance_secondaire() const {return  tolerance_secondaire;};
        const list < int >& NB_vect_restart_secondaire() const {return  nb_vect_restart_secondaire;};
       
        // indique si l'on veut ou non une optimisation des pointeurs d'assemblage
        // notamment en fonction des CLL
        int Optimisation_pointeur_assemblage() const {return opti_pointeur_assemblage;};
                      
        // 3) ==== paramètres liés au pilotage de l'équilibre global
        // indication du type de pilotage retenu
        EnumTypePilotage  TypeDePilotage() const {return type_de_pilotage;}
        // facteur   de diminution de l'incrément de chargement
        double Facteur_diminution()  const {return facteur_diminution;};
        // facteur d'augmentation de l'incrément de chargement
        double Facteur_augmentation()  const {return facteur_augmentation;};
        // facteurs de diminution après une mauvaise convergence
        double Fact_dim_en_mauvaiseConv()  const {return fact_dim_en_mauvaiseConv;};
        // nb de bonne convergence -> augmentation du deltatt
        int Nb_bonne_convergence() const {return nb_bonne_convergence;};
        // nb d'iter pour statuer sur la bonne convergence                    
        int Nb_iter_pour_bonne_convergence() const {return nb_iter_pour_bonne_convergence;};
        // nb d'iter pour statuer sur une mauvaise convergence 
        int Nb_iter_pour_mauvaise_convergence() const {return nb_iter_pour_mauvaise_convergence;};
        // nombre d'itération avec un comportement tangent simple
        // type élasticité par exemple, pour stabiliser les itérations avec des 
        // comportements plus complexes.
        int Init_comp_tangent_simple() const {return init_comp_tangent_simple;};
        // récup du facteur de sur ou sous relaxation
        double SurSousRelaxation() const {return sur_sous_relaxation;};
        // récup de la limitation maxi de l'incrément de ddl
        double NormeMax_increment() const {return norme_incre_max;};
        // récup de la limitation maxi de l'incrément de ddl sur les déplacements
        double NormeMax_X_increment() const {return norme_incre_X_max;};
        // récup de la limitation maxi de l'incrément de ddl sur les vitesses
        double NormeMax_V_increment() const {return norme_incre_V_max;};
        // récup de la limite supérieure permise pour la variation des ddl, pour le test convergence
        double VarMaxiDdl() const {return varMaxiDdl;};
        // récup de la limite inférieure permise pour la variation des ddl, pour le test convergence
        double VarMiniDdl() const {return varMiniDdl;};
        // récup du nombre de cycle pour le controle du max de résidu
        int NbCycleControleResidu() const {return nbCycleControleResidu;};
        // récup de combien de fois à suivre il faut que le controle de variation de résidu soit faux
        // pour conclure à la non convergence
        int PlageControleResidu() const {return plageControleResidu;}; 
        // initialisation de l'incrément avec l'incrément du pas précédent  : oui ou non
        double IniIncreAvecDeltaDdlPrec() const { return initIncreAvecDeltaDdlPrec; };      
        // ramène l'indicateur de cas : pour le traitement du cas d'un jacobien négatif
        int JabobienNegatif() const { return jabobien_negatif; };      
        // ramène la variation maxi autorisé pour le jacobien
        // si <=1 veut dire que le paramètre n'est pas activé (il ne faut pas en tenir compte)
        double  MaxiVarJacobien() const { return var_maxi_jacobien; };
       
        // ramène l'indicateur de cas : pour le traitement ou une fonction nD
        // pour le chargement, signale un pb
        int Cas_fctnD_charge() const { return cas_fctnD_charge; };
       
        // 4) paramètres liès à la dynamique
        // type de calcul de la masse
        Enum_calcul_masse Type_calcul_masse() const {return type_calcul_masse;};
        // limitation du temps maxi stable : active ou pas
        bool Limit_temps_stable() const { return limitation_temps_maxi_stable;};
        // indique si l'on inclut automatiquement un amortissement visqueux artificiel
        // =0 pas d'amortissement, = 1 amortissement de tyme rayleigh
        // = 2 amortissement calculé à partir de l'amortissement critique approché(première méthode)
        // = 3 idem 2, mais autre méthode de calcul
        // = 4 amortissement critique utilisé avec les algo de relaxation dynamique
        int Amort_visco_artificielle() const {return amort_visco_arti;};
        // change le paramètre indiquant l'amortissement visqueux artificiel
        void Change_amort_visco_artificielle(int val_amort)  { amort_visco_arti = val_amort;};
        // valeur de la viscosité dynamique
        double Visco_artificielle() const {return visco_arti; };
            // la matrice d'amortissement dynamique [C] est  construite à partir des coeffs de rayleigh
            // sur la masse et sur la raideur 
        // coefficient de rayleigh  sur la masse, pour la construction de la matrice de viscosité    
        double CoefRayleighMasse( )const {return coef_rayleigh_masse;};
        // coefficient de rayleigh  sur la raideur, pour la construction de la matrice de viscosité    
        double CoefRayleighRaideur() const {return coef_rayleigh_raideur;};
        // cas du calcul de la viscosité critique : coef de bornage de la viscosité critique
        double BorneMaxiSurCfonctionDeLaMasse() const {return maxi_C_en_fonction_M;}; 
            // booleen indiquant si l'on veut l'intervention du bulk viscosity ou non
        int BulkViscosity() const { return bulk_viscosity;}; 
            // les deux coefficients de la formule du bulk viscosity: q=ro l (coef1 l trace(D) - coef2 a trace(D)^2)
        DeuxDoubles CoefsBulk() const { return  DeuxDoubles(c_Tracebulk,c_Trace2bulk);};

        // 5) paramètres liès à l'affichage des résultats 
        // fréquence sur les increments de l'affichage des résultats
        int Freq_affich_incre() const {return frequence_affichage_increment;}; 
        // fréquence sur les itération de l'affichage des résultats
        int freq_affich_iter() const {return frequence_affichage_iteration;}; 
        
        // nombre servant à gérer la frequence de sauvegarde au fil du calcul 
        // il faut utiliser SauvegardeFilCalculAutorisee() pour gérer correctement le nombre ramené en paramètre
        bool Sortie_fil_calcul()  const { if (sortie_fil_calcul > 0.) return true; else return false;}; 
        // indique si la sauvegarde au fil du calcul est autorisée, en fonction des paramètres données par l'utilisateur et les variables
        // passée en argument
        bool SauvegardeFilCalculAutorisee(int incre,const double& temps_derniere_sauvegarde,bool dernier_calcul) const; 

        // ramène vraie si le numéro d'increment est nulle modulo la frequence d'affichage d'incrément
        // si ce dernier est > 0, sinon =0 modulo la fréquence de sauvegarde si celle-ci est > 0 sinon false
        // dans le cas où les sorties s'effectue en fonction du temps, passage du dernier temps de sauvegarde
        bool Vrai_commande_sortie(int icharge,const double& temps_derniere_sauvegarde) const;
        // nombre de diggit utilisé pour afficher des réels en double précision pour l'archivage calcul (restart
        // on sortie des résultats) (en fait utilisé avec ParaGlob avec une fonction statique)
        int Nb_diggit_double_calcul() const { return nb_diggit_double_calcul;};
        // nombre de diggit utilisé pour afficher des réels en double précision pour la visualisation graphique
        // (en fait utilisé avec ParaGlob avec une fonction statique)
        int Nb_diggit_double_graphique() const { return nb_diggit_double_graphique;};
        // nombre de diggit utilisé pour afficher des réels en double précision sur l'écran
        // (en fait utilisé avec ParaGlob avec une fonction statique)
        int Nb_diggit_double_ecran() const { return nb_diggit_double_ecran;};

        // 6) paramètres liès au contact
        // ramène la précision voulu sur le test de la pénétration d'un point initial avant le début du calcul
        double Precision_point_interne_debut() const   { return prec_pt_int_deb; };
		      // ramène un facteur multiplicatif du déplacement maxi entre t et tdt, donnant la 
		      // distance maxi admissible entre le point et le point projeté
        double FacPourRayonAccostage() const {return factPourRayonAccostage;}; 
		      // ramène la distance maxi adminssible entre le point et le point projeté
		      double DistanceMaxiAuPtProjete() const {return distanceMaxiAuPtProjete;};
        // ramène le pourcentage de plus que l'on prend pour les boites de prélocalisation d'élément  
        double Extra_boite_prelocalisation()  const { return extra_boite_prelocalisation; };
        // ramène un paramètre "r"  qui multiplié par la taille maxi d'un élément donne l'épaisseur
        // que l'on met autour de la boite de prélocalisation pour éviter certaine dimension nulle à cette boite
        double Rapport_Extra_boite_mini_prelocalisation() const { return mini_extra_boite_prelocalisation; };
        // ajout_extra_boite_prelocalisation est un paramètre qui est ajouté dans tous les directions aux boites de préloca
        double Ajout_extra_boite_prelocalisation() const {return ajout_extra_boite_prelocalisation;};

        // ramène le type de contact et son existance
        // ==0 : pas de contact, !=0 -> le type de contact
        // ==1 : contact cinématique, sans multiplicateur ni pénalisation (contact original)
        // ==2 : contact avec pénalisation
        int ContactType() const {return contact_type;};
        // ramène un string décrivant une fonction nD de pilotage pour le type de contact 4
        // = "_" si aucune fonction n'est définit
        string Fct_nD_bascul_contact_type_4() const {return fct_nD_bascul_contact_type_4;};
        
        // ramène le facteur brut de pénalisation pour la pénétration 
        double PenalisationPenetrationContact() const {return penalisationPenetration;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_penalisationPenetration() const {return fct_nD_penalisationPenetration;};

        // ramène le type de contrôle du facteur de pénalisation pour la pénétration
        int TypeCalculPenalisationPenetration() const {return typePenalisationPenetration;};
        // ramène  une borne maxi de pénétration (dont l'utilisation dépend de l'algo)
        double Penetration_contact_maxi() const {return penetration_contact_maxi;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_penetration_contact_maxi() const {return fct_nD_penetration_contact_maxi;};

        // ramène  une borne de régularisation sur la penetration (dont l'utilisation dépend de l'algo)
        double Penetration_borne_regularisation() const {return penetration_borne_regularisation;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_penetration_borne_regularisation() const {return fct_nD_penetration_borne_regularisation;};

        // ramène  une borne maxi pour la force de réaction du noeud (dont l'utilisation dépend de l'algo)
        double Force_contact_noeud_maxi() const {return force_contact_noeud_maxi;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_force_contact_noeud_maxi() const {return fct_nD_force_contact_noeud_maxi;};

        // ramène le facteur de pénalisation pour le déplacement tangentiel
        double PenalisationTangentielleContact() const {return penalisationTangentielle;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_penalisationTangentielle() const {return fct_nD_penalisationTangentielle;};

        // ramène le type de contrôle du facteur de pénalisation pour le dep tangentiel
        int TypeCalculPenalisationTangentielle() const {return typePenalisationTangentielle;};
        // ramène  une borne maxi de dep tangentiel (dont l'utilisation dépend de l'algo)
        double Tangentielle_contact_maxi() const {return tangentielle_contact_maxi;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_tangentielle_contact_maxi() const {return fct_nD_tangentielle_contact_maxi;};

        // ramène  une borne de régularisation sur le dep tangentiel (dont l'utilisation dépend de l'algo)
        double Tangentielle_borne_regularisation() const {return tangentielle_borne_regularisation;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_tangentielle_borne_regularisation() const {return fct_nD_tangentielle_borne_regularisation;};

        // ramène  une borne maxi pour la force tangentiel sur le noeud (dont l'utilisation dépend de l'algo)
        double Force_tangentielle_noeud_maxi() const {return force_tangentielle_noeud_maxi;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_nD_force_tangentielle_noeud_maxi() const {return fct_nD_force_tangentielle_noeud_maxi;};

        // précision de positionnement sur les X^ar d'un pt en contact sur une frontière
        double Precision_pt_sur_front() const {return prec_pt_sur_frontiere;};
        // nb de boucle maxi pour la recherche du positionnement du pt en contact    
        int Nb_boucle_newton_position_sur_frontiere()const {return nb_boucle_newton_position_frontiere;};
        // nb de fois un noeud décolle pour n'être plus considéré en contact
        int NbDecolAutorise()const {return nbDecolAutorise;};
		      // retourne le type de méthode utilisée pour gérer le décollement 
        int TypeDeDecolement() const {return typeDeDecolement;};
		      // retourne le nombre de positions successives, utilisé pour faire une moyenne glissante de ces positions 
        int Nb_moy_glissant() const {return nb_glissant;};
         // retourne le nb de changement maxi de frontière toléré
        int NB_change_frontiere_max() const {return nb_change_frontiere_max;};
        
        // retourne le niveau de commentaire entre 0 et 10, pour la gestion globale
        // du contact (class LesContacts)
        // le niveau utilisé est a priori le max du niveau général et de celui-ci
        int Niveau_commentaire_LesContact() const {return niveau_commentaire_lescontacts;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_niveau_commentaire_LesContact() const {return fct_niveau_commentaire_lescontacts;};
        
        // retourne le niveau de commentaire entre 0 et 10, pour les algo de contact
        // : concerne les éléments de contact
        // le niveau utilisé est a priori le max du niveau général et de celui-ci
        int Niveau_commentaire_contact() const {return niveau_commentaire_contact;};
        // ramène un string décrivant une fonction nD de pilotage équivalente
        // = "_" si aucune fonction n'est définit
        string Fct_niveau_commentaire_contact() const {return fct_niveau_commentaire_contact;};
       
        // retour d'un indication concernant une optimisation éventuelle
        //de la numerotation en tenant compte des éléments de contact
        int Optimisation_numerotation() const {return  optimisation_numerotation;};

        //  7) paramètres liés aux calculs des énergies 
        // ramène l'incrément mini à partir duquel on calcul les énergies cumulées
        int  NbIncrCalEnergie() const {return nb_incr_cal_ener;};
        // indique si oui ou non le calcul et l'affichage des énergies sur l'incrément est effectué
        bool AfficheIncrEnergie() const {return affiche_incr_energie;}; 
                  
        // 8) paramètres liés aux calculs géométriques sur les éléments
        //  -- paramètres relatifs à la recherche d'un point interne à un élément (dans ElemMeca)
          // coordonnée thetai ok si delta thetai < à la prec
        double PointInterneDeltaThetaiMaxi() const {return point_interne_delta_thetai_maxi;};
          // precision sur thetai sur le test du point interne
        double PointInternePrecThetaiInterne() const {return point_interne_prec_thetai_interne;};
          // maxi boucle de Newton sur la recherche des thetai
        int PointInterneNbBoucleSurDeltaThetai() const {return point_interne_nb_boucle_sur_delta_thetai;}; 
          //nb max de test positif "externe" pour statuer un point externe
        int PointInterneNbExterne() const {return point_interne_nb_externe;}; 
		      // indique si oui ou non on calcul les volumes entre la surface et les 3 plans de ref (valable uniquement en 3D pour des surfaces)
		      bool CalVolTotalEntreSurfaceEtPlansRef() const {return cal_vol_total_entre_surface_et_plans_ref;};
        // indique le rapport maxi autorisé entre le jacobien de la facette centrale
        // et le jacobien au pti pour les éléments coques
        double Ratio_maxi_jacoMembrane_jacoPti() const {return ratio_maxi_jacoMembrane_jacoPti;};
        // indique quelle méthode numérique est utilisée pour effectuer
		      // l'inversion des tenseurs métriques: exe : utilisation de la méthode de Cramer (méthode historique)
		      // ou encore : utilisation d'une méthode LU avec équilibrage des ligne (second méthode implantée)		  
		      Enum_type_resolution_matri Type_calnum_inversion_metrique() const {return type_calnum_inversion_metrique;};

        // --- fonctions d'accès en modification des paramètres -----------
        // 1) ==== parametres de controle généraux pour la résolution de l'équilibre
        //     générale
        // modification de l'increment de temps, 
        // si c'est >= au deltat mini et <= deltat maxi, => retour 0
        // si c'est < au deltat mini  et que l'on est déjà au temps mini ==> retour -1 : pas de modification du deltat
        // si c'est > au deltat maxi et que l'on est déjà au temps maxi ==> retour 1  : pas de modification du deltat
        int Modif_Deltat(double nouveau_temps);
        // modification de l'incrément dans les bornes
        // si nouveau_temps < deltat mini ==> nouveau_temps = deltat mini
        // si nouveau temps > deltat maxi ==> nouveau_temsp = deltat maxi
        // sinon on laisse le delta_t à la valeur qu'il a actuellement
        // ramène oui ou non si ça a été modifié
        bool Modif_Detat_dans_borne(double& nouveau_temps);
        // modification directe du temps
        void Modif_Temps(double nouveau_temps) { tempo_specifique_algo.temps = tempo.temps = nouveau_temps;};
        // mise à jour éventuel du pas de temps et du pas de temps maxi et mini dans le cas où ils sont définit avec des coeff
        // d'un pas critique, ramène true s'il y a eu modification du pas de temps courant, false sinon
        // temps_critique : temps critique de l'algorithme
        // temps_critiqueDFC : temps critique de l'algo DFC = condition de courant
        bool Modif_Deltat_DeltatMaxi(double temps_critique, double temps_critiqueDFC);
        // modif arbitraire (sans aucune vérification) des paramètres de temps courant
        // ** a utiliser à bon essient
        void Modif_temps(const double& tem,const double& deltatem)
         {tempo_specifique_algo.temps = tempo.temps = tem;
          tempo_specifique_algo.deltat = tempo.deltat = deltatem;};
        // modification de var_D
        void Modif_Var_D(bool va_D) {var_D = va_D;}; 
        // modification de var_jacobien 
        void Modif_Var_jacobien(bool va_jacobien) {var_jacobien = va_jacobien;};  
         
        //------------ gestion de certaines interruptions systèmes ---------
        // ces variables ne sont pas sauvegardées, elles sont accessibles de partout pour un projet donné
        // on se sert de ParaAlgoControle pour le stockage, l'accès et la modification
        //---
        void ChangeSortieEquilibreGlobal(bool val) {sortieEquilibreGlobal=val;};
        bool EtatSortieEquilibreGlobal() const {return sortieEquilibreGlobal;};
        //---
        void ChangeSortieEtatActuelDansBI(bool val) {sortieEtatActuelDansBI=val;};
        bool EtatSortieEtatActuelDansBI() const {return sortieEtatActuelDansBI;};
        //---
        void ChangeSortieEtatActuelDansCVisu(bool val) {sortieEtatActuelDansCVisu=val;};
        bool EtatSortieEtatActuelDansCVisu() const {return sortieEtatActuelDansCVisu;};
        // on met à jour les infos globales
        std::vector <double>& Mise_a_jour_Grandeurs_globales();

  protected :  
   // VARIABLES PROTEGEES :
        // 1)  parametres de controle généraux pour la résolution de l'équilibre
        //     générale
        double sauvegarde; // un entier ou double servant a  contrôler la frequence de sauvegarde
          // dans le cas le plus simple : = le nombre d'incrément séparant deux pas de sauvegarde
        int cas_de_sauvegarde; // associé au paramètre sauvegarde: indique comment le contrôle de la fréquence de 
          // sauvegarde s'effectue: =1 : cas le plus simple (cf si-dessus)
          //                        =2 : cas où sauvegarde indique le  deltat  qui existe entre 2 sauvegardes
          //                        =3 : cas où on sauvegarde l'incrément 0 et le dernier incrément    
          //                        =4 : cas 1 + le dernier incrément
          //                        =5 : cas 2 + le dernier incrément
        int iterations; // maxi d'iteration pour converger
        double precision; // precision de la convergence
        Deux_String norme; // type de norme de convergence: le premier string = la norme sauf si
                            //  le premier=  fonction_nD: dans ce cas le second = le nom de la fonction nD
        bool cinematique; // cinematique sur l'increment ?
        bool conv_forcee; // convergence forcee ?
        double multiplicateur; // multiplicateur de la charge
        // ----  le temps, 
        // contrairement aux autres variables, il s'agit d'une variable static pour qu'il n'y ait qu'un seul
        // temps dans le calcul. C'est aussi une nécessité pour la liaison avec la classe ParaGlob,
        // sinon cela pose des pbs dans le cas de plusieurs variable ParaAlgoControle  
        static VariablesTemps tempo; // contients les grandeurs courantes:
                                     // temps courant, l'increment de temps, l'incrément de temps maxi
                                     // le temps fin, la précision sur les tests sur les temps
        // les grandeurs spécifiques de l'algo:
        // la seule grandeurs qui est commune c'est le temps courant: celui stocké dans "tempo"
        VariablesTemps tempo_specifique_algo;
        bool force_deltat;  // indique si oui ou non, lors d'un restart on force l'utilisation de l'incrément de temps
                            // indiqué dans le .info, ou au contraire on reprend celui du pas précédent
                            // ne sert qu'une fois, ensuite elle est mise à false !!
        double coef_pas_critique_deltat; // coeff  du pas critique pour deltat s'il existe
        static double coef_defaut_pa_critique; // valeur par défaut de coef_pas_critique_deltat
        double coef_pas_critique_deltatmaxi; // coeff  du pas critique pour deltatmaxi s'il existe
        double coef_pas_critique_deltatmini; // coeff  du pas critique pour deltatmini s'il existe
        bool typeDFC_pas_critique_deltat; // = true: il s'agit du pas critique de DFC, false : pas critique spécifique
        bool typeDFC_pas_critique_deltatmaxi; //   idem 
        bool typeDFC_pas_critique_deltatmini; //   idem 
        // --- fin pour le tempq   
        int maxincre ; // maximum d'increment de temps
        int max_essai_incre ; // maximum de tentative d'increment de temps permis
        int restart;  // increment de redemarage de calcul
        double max_puissance;  // maximum de puissance tolérée
        bool line_search; // indique si oui ou non on utilise le line_search
        bool var_charge_externe; // indique si oui ou non le chargement externe
                                 // participe à la raideur
        bool var_jacobien; // indique si l'on tiend compte de la variation du jacobien
                           // dans le calcul de la raideur
        bool var_D; // indique si l'on tiend compte de la variation de D* dans la raideur                                            
       
        // 2) paramètres liés au système d'équations linéaires
        
        bool symetrie_matrice; // indique si le stockage est symétrique ou non
        Enum_matrice type_matrice; // type de stockage matriciel
        Enum_type_resolution_matri type_resolution; // type de résolution
        Enum_preconditionnement type_preconditionnement; // type de préconditionnement 
        int nb_iter_nondirecte; // nombre d'itération dans le cas d'une méthode itérative
        double tolerance; // tolerance de convergence dans le cas d'une méthode itérative
        int nb_vect_restart; // nombre de vecteur sauvegardé dans le cas d'une méthode
                             // itérative avec redépart
        // même chose pour les matrices secondaires éventuelles
        list < Enum_matrice >  type_matrice_secondaire; // type de stockage matriciel
        list < Enum_type_resolution_matri > type_resolution_secondaire; // type de résolution
        list < Enum_preconditionnement >  type_preconditionnement_secondaire; // type de préconditionnement
        list < int >  nb_iter_nondirecte_secondaire; // nombre d'itération dans le cas d'une méthode itérative
        list < double >  tolerance_secondaire; // tolerance de convergence dans le cas d'une méthode itérative
        list < int >  nb_vect_restart_secondaire; // nombre de vecteur sauvegardé dans le cas d'une méthode
                             // itérative avec redépart
        // indique si l'on veut ou non une optimisation des pointeurs d'assemblage
        // notamment en fonction des CLL
        int opti_pointeur_assemblage; // = 0 : pas d'optimisation,
       
        // 3) paramètres liés au pilotage de l'équilibre global
        EnumTypePilotage type_de_pilotage;     // définit le type de pilotage retenue
        double facteur_diminution;   // facteurs d'augmentation, ou de diminution
        double facteur_augmentation; // de l'incrément  de chargement
        double fact_dim_en_mauvaiseConv; // facteurs de diminution après une mauvaise convergence
        int nb_bonne_convergence;    // nb de bonne convergence -> augmentation du deltatt
        int nb_iter_pour_bonne_convergence; // nb d'iter pour statuer sur la bonne convergence 
        int nb_iter_pour_mauvaise_convergence; // nb d'iter pour statuer sur une mauvaise convergence 
        double varMiniDdl, varMaxiDdl;  // limites mini et maxi des ddl
        int nbCycleControleResidu,plageControleResidu; // nb cycle et plage de controle du résidu                   
        int init_comp_tangent_simple; // nombre d'itération avec un comportement tangent simple
                  // type élasticité par exemple, pour stabiliser les itérations avec des 
                  // comportements plus complexes.
        double sur_sous_relaxation; // facteur de sur ou sous relaxation
        double norme_incre_max; // limitation de l'incrément maxi des ddl 
        double norme_incre_X_max; // limitation de l'incrément maxi des ddl de déplacement
        double norme_incre_V_max; // limitation de l'incrément maxi des ddl de vitesse
        double initIncreAvecDeltaDdlPrec; // initialisation de l'incrément avec l'incrément du pas précédent
        int jabobien_negatif; // traitement des jacobiens négatifs      
        double var_maxi_jacobien; // variation maxi autorisée du jacobien, si <= 0 pas pris en compte
        int cas_fctnD_charge; // traitement du cas ou une fonction nD pour le chargement, signale un pb
                
        // 4) paramètres liès à la dynamique
        Enum_calcul_masse type_calcul_masse; // type de calcul de la masse
             // le type de stockage de la matrice masse est celui de type_matrice
             // utilisé que si la matrice masse n'est pas diagonale
        bool limitation_temps_maxi_stable; // booléen qui indique si la limitation supérieur
             // du temps pour satisfaire la stabilité, est active ou pas
        int amort_visco_arti; // indique si l'on inclut automatiquement un amortissement visqueux artificiel
                // =0 pas d'amortissement, = 1 amortissement de tyme rayleigh
                // = 2 amortissement calculé à partir de l'amortissement critique approché                
        double visco_arti; // valeur de la viscosité dynamique ou de la proportion d'amortissement critique
        double maxi_C_en_fonction_M; // bornage de C: maxi C = maxi_C_en_fonction_M * M (cas du calcul de C critique)
            // la matrice d'amortissement dynamique [C] est  construite à partir des coeffs de rayleigh
            // sur la masse et sur la raideur 
        double coef_rayleigh_masse,coef_rayleigh_raideur; 
            // int indiquant si l'on veut l'intervention du bulk viscosity ou non
            // =0 pas d'intervention, =1 intervention si I_D est négatif, =2 intervention quelque soit I_D
        int bulk_viscosity; 
            // les deux coefficients de la formule du bulk viscosity: q=ro l (coef1 l trace(D) - coef2 a trace(D)^2)
        double c_Tracebulk,c_Trace2bulk; 
        
        // 5) paramètres liès à l'affichage des résultats 
        // ---- a l'écran
        int frequence_affichage_increment; // fréquence sur les increments de l'affichage des résultats
        int frequence_affichage_iteration; // fréquence sur les itération de l'affichage des résultats
        //  --- en sortie au fil du calcul
        double sortie_fil_calcul; // fréquence sur les incréments, pour la sortie au fil du calcul
        int cas_de_sortie_fil_calcul; // associé au paramètre sortie_fil_calcul: 
          //indique comment le contrôle de la fréquence de sortie au fil du calcul s'effectue
          //  =1 : cas le plus simple (cf si-dessus)
          //  =2 : cas où sauvegarde indique le  deltat  qui existe entre 2 sauvegardes   
        // nombre de chiffre significatifs utilisé pour l'affichage des double précision: le premier pour
        // l'archivage du calcul le secon pour la visualisation graphique
        // le troisième pour l'affichage à l'écran
        int nb_diggit_double_calcul; 
        int nb_diggit_double_graphique; 
        int nb_diggit_double_ecran;

        // 6) paramètres liès au contact
        double prec_pt_int_deb; // précision du test: point à l'intérieur d'un élément
		      double factPourRayonAccostage; // facteur multiplicatif du déplacement maxi entre t et tdt, donnant
										        // distance maxi admissible entre le point et le point projeté
		      double distanceMaxiAuPtProjete; // distance maxi admissible entre le point et le point projeté										  
        double extra_boite_prelocalisation; // donne la proportion de plus que l'on prend pour les boites
        // mini_extra_boite_prelocalisation est un paramètre qui multiplié par la taille maxi d'un élément donne 
        // l'épaisseur que l'on met autour de la boite de prélocalisation pour éviter certaine dimension nulle à cette boite
        double mini_extra_boite_prelocalisation;
        // ajout_extra_boite_prelocalisation est un paramètre qui est ajouté dans tous les directions aux boites de préloca
        double ajout_extra_boite_prelocalisation;
        int contact_type; // indique si oui (!= 0) ou non (==0) il y a contact, et le nombre indique le type de contact
        string  fct_nD_bascul_contact_type_4; // fonction nD qui permet de piloter le type 4
       
        double penalisationPenetration; // facteur de pénalisation pour la pénétration
        string fct_nD_penalisationPenetration; // fct nD dans le cas d'une valeur pilotée

        int typePenalisationPenetration; // indique le type de calcul pour la pénalisation en pénétration
		      double penetration_contact_maxi; // indique une borne maxi de pénétration (dont l'utilisation dépend de l'algo)
        string fct_nD_penetration_contact_maxi; // fct nD dans le cas d'une valeur pilotée

		      double penetration_borne_regularisation; // borne de régularisation sur la penetration (dont l'utilisation dépend de l'algo)
        string fct_nD_penetration_borne_regularisation; // fct nD dans le cas d'une valeur pilotée

		      double force_contact_noeud_maxi; // indique une borne maxi pour la force de réaction du noeud (dont l'utilisation dépend de l'algo)
        string fct_nD_force_contact_noeud_maxi; // fct nD dans le cas d'une valeur pilotée

        double penalisationTangentielle; // facteur de pénalisation pour le déplacement tangentiel
        string fct_nD_penalisationTangentielle;
        int typePenalisationTangentielle; // indique le type de calcul pour la pénalisation en dep tangentiel

        double tangentielle_contact_maxi; // indique une borne maxi de dep tangentiel (dont l'utilisation dépend de l'algo)
        string fct_nD_tangentielle_contact_maxi; // fct nD dans le cas d'une valeur pilotée

        double tangentielle_borne_regularisation; // borne de régularisation sur le dep tangentiel
        string fct_nD_tangentielle_borne_regularisation; // fct nD dans le cas d'une valeur pilotée
        
        double force_tangentielle_noeud_maxi; // indique une borne maxi pour la force tangentielle sur le noeud
        string fct_nD_force_tangentielle_noeud_maxi; // fct nD dans le cas d'une valeur pilotée

        double prec_pt_sur_frontiere; // précision de positionnement sur les X^ar d'un pt en contact sur une frontière
        int nb_boucle_newton_position_frontiere; // nb de boucle maxi pour la recherche du positionnement du pt en contact    
        int nbDecolAutorise;// nb de fois un noeud décolle pour n'être plus considéré en contact
		      int typeDeDecolement; // indique le type de méthode utilisée pour gérer le décollement
        int nb_glissant; // le nombre de positions successives du noeud esclave, utilisé pour faire une moyenne glissante
        int nb_change_frontiere_max = 4; // nb de changement maxi de frontière
        
        int niveau_commentaire_lescontacts; // de 0 à 10: niveau des commentaires pour la gestion globale du contact: i.e. LesContacts
        string fct_niveau_commentaire_lescontacts; // fct nD dans le cas d'une valeur pilotée
        int niveau_commentaire_contact; // de 0 à 10: niveau des commentaires dans les algo de contact: niveau élément de contact
        string fct_niveau_commentaire_contact; // fct nD dans le cas d'une valeur pilotée

        int optimisation_numerotation; // indique éventuellement une optimisation de la numerotation en tenant compte
                                       // des éléments de contact

        //  7) paramètres liés aux calculs des énergies et puissances
        int  nb_incr_cal_ener; // donne l'incrément mini, à partir duquel on calcul les énergie cumulée
        bool affiche_incr_energie; // affichage oui ou non de l'énergie et du bilan sur l'incrément 
        
        // 8) paramètres liés aux calculs géométriques sur les éléments
        double point_interne_delta_thetai_maxi; // coordonnée thetai ok si delta thetai < à la prec
        double point_interne_prec_thetai_interne; // precision sur thetai sur le test du point interne
        int point_interne_nb_boucle_sur_delta_thetai; // maxi boucle de Newton sur la recherche des thetai 
        int point_interne_nb_externe; // nb max de test positif "externe" pour statuer un point externe 
        bool cal_vol_total_entre_surface_et_plans_ref; // indique si oui ou non on calcul ces volumes (entre la surface et les 3 plans)
        double ratio_maxi_jacoMembrane_jacoPti; // rapport maxi autorisé entre le jacobien de la facette centrale
                    // et le jacobien au pti pour les éléments coques
                    
        Enum_type_resolution_matri type_calnum_inversion_metrique; // indique quelle méthode numérique est utilisée pour effectuer
		       // l'inversion des tenseurs métriques: ex: utilisation de la méthode de Cramer (méthode historique)
				     // ou utilisation d'une méthode LU avec équilibrage des ligne (second méthode implantée)
         
        //------------ gestion de certaines interruptions systèmes ---------
        // ces variables ne sont pas sauvegardées, elles sont accessibles de partout pour un projet donné
        // on se sert de ParaAlgoControle pour le stockage, l'accès et la modification
        bool sortieEquilibreGlobal; // par défaut non
        bool sortieEtatActuelDansBI; // par défaut non
        bool sortieEtatActuelDansCVisu; // par défaut non
        
           
  };
/// @}  // end of group

#endif  
