
// 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:   Frontiere : Facette triangulaire quadratique avec 3 points*
 *            d'integration.                                            *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
#ifndef FRONTTRIAQUAD_H
#define FRONTTRIAQUAD_H

#include "ElFrontiere.h"
#include "GeomTriangle.h"
#include "Met_abstraite.h"
         
/// @addtogroup Les_Elements_de_frontiere
///  @{
///


class FrontTriaQuad : public ElFrontiere
{
  public :
    // CONSTRUCTEURS :
    //par defaut
    FrontTriaQuad ();
    // fonction du tableau des noeuds  sommets 
    FrontTriaQuad ( const Tableau <Noeud *>& tab, const DdlElement& ddlElem);
    FrontTriaQuad( const FrontTriaQuad& a);  // de copie
    // DESTRUCTEUR :
    ~FrontTriaQuad ();
    // surcharge de l'affectation
    ElFrontiere& operator = ( const ElFrontiere& a);
    // retourne le type de l'element frontiere
    string TypeFrontiere() const ;
    // retourne l'élément géométrique attaché à l'élément frontière
    ElemGeomC0 & ElementGeometrique() const { return triangle;};
   // creation d'un nouvelle element frontiere du type FrontTriaQuad
    ElFrontiere * NevezElemFront() const ;  
    // creation d'un nouvelle element frontiere du type FrontTriaQuad
    // avec des donnees differentes
    ElFrontiere * NevezElemFront
        ( const Tableau <Noeud *>& tab, const DdlElement& ddlElem) const ;
    
    // ramene et calcul les coordonnees du point de reference de l'element
    Coordonnee Ref();
    // ramene un plan tangent  au point de reference
    // si indic =  2 -> un plan
    // ces infos sont stocke et sauvegardees dans l'element 
    void TangentRef(Droite& dr, Plan& pl, int& indic);
    // M est un point du dernier plan tangent sauvegarde dans l'element
    //  - calcul du point M1 correspondant sur la surface, M1 est stocke
    //  _ calul et retour du plan tangent  au point M1
    // si indic = 2 -> un plan
    // ces infos sont stocke et sauvegardees dans l'element 
    void Tangent(const Coordonnee& M,Coordonnee& M1, Droite& dr, Plan& pl, int& indic);
    // ramene un autre plan tangent  genere de maniere pseudo aleatoire
    // si indic = 2 -> un plan
    // ces infos sont stocke et sauvegardees dans l'element 
    void AutreTangent(Droite& dr, Plan& pl, int& indic);
    // ramene true si le dernier point M1 est dans l'element , sinon false
    // le calcul est fait à eps relatif près
    bool InSurf(const double& eps) const ;
    // actualise et ramene le dernier plan tangent (ou  droite tangente) calcule
    // si indic = 1 -> une droite, =2 -> un plan
    // ramène éventuellement la variation du vecteur normale pour un plan en 3D ou une ligne en 2D
	 // dans le cas d'une ligne en 3D ramène la variation du vecteur tangent: si var_normale = true, sinon ramène NULL
    Tableau <Coordonnee >*  DernierTangent(Droite& dr, Plan& pl, int& indic,bool avec_var=false);	 
    // test si la position d'un point est du bon cote ( c-a-d hors matiere) ou non
    // ramene true si hors matiere, sinon false
    // le test  sur a est executer uniquement dans les cas suivants :
    // dimension 3D et  frontiere 2D
    // dimension 2D et frontiere 1D
    // ->>> dimension 3D et frontiere 1D, pas de verif 
    // ->>> autre cas ne doivent pas arriver normalement !! 
    // retour de r = distance du point à la surface, ligne
    bool BonCote_t( const Coordonnee& a,double& r) const ; // cas ou on utilise la frontiere a t
    bool BonCote_tdt( const Coordonnee& a,double& r) const ; // cas ou on utilise la frontiere a tdt
    // calcul les fonctions d'interpolation au dernier point de projection sauvegarde
    const Vecteur& Phi();
    
    // affichage des infos de l'elements
    void Affiche(Enum_dure temp = TEMPS_tdt) const ;
           
    // creation et ramene des pointeurs sur les frontieres de l'element frontiere
    // au premier appel il y a construction, ensuite on ne fait que ramener le tableau
    // à moins qu'il soit effacé
    Tableau <ElFrontiere*>& Frontiere();
     
    // ramène la métrique associée à l'élément
    Met_abstraite * Metrique() {return met;};

	 //----- lecture écriture de restart -----
	 // ceci concerne uniquement les informations spécifiques 
	 // dans le cas de l'utilisation de la frontière pour la projection d'un point sur la frontière
	 // il s'agit donc d'un cas particulier 
	 void Lecture_base_info_ElFrontiere_pour_projection(istream& ent) ;
	 void Ecriture_base_info_ElFrontiere_pour_projection(ostream& sort) ;
       
  private :  
    // VARIABLES PROTEGEES :
    static GeomTriangle triangle; // le triangle  de reference
    static Met_abstraite * met; // une metrique associee
    static Vecteur phi; // interpolation au point courant
    static Mat_pleine dphi; // derivees de l'interpolation au point courant
    Coordonnee ref; // Point de reference de l'element
    Plan plan; // plan tangent 
	 Tableau <Coordonnee >  d_N,D_pasnormale; // variation du vecteur normal et variable de travail
    static BaseB giB; // base naturelle de travail 
    static BaseH giH; // base duale de travail 
    Coordonnee theta; // coordonnees du point courant projete
	 Coordonnee theta_repere; // le point où l'on calcul le repère 
            
    // METHODES PROTEGEES :
    // methodes propres a l'element
    inline Plan PL()  const { return plan; };
    inline Coordonnee Theta()  const { return theta;};
    // definition de la metrique
    void DefMetrique();
 };
 /// @}  // end of group

#endif  
