
// 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 : Point.                                        *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *                                                                      *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
#ifndef FRONTPOINTF_H
#define FRONTPOINTF_H

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


class FrontPointF : public ElFrontiere
{
  public :
    // CONSTRUCTEURS :
    //par defaut
    FrontPointF ();
    // fonction du tableau des noeuds  sommets
    // T est un vecteur normal optionnel au plan tangent au point 
    FrontPointF ( const Tableau <Noeud *>& tab, const DdlElement& ddlElem,Coordonnee* T = NULL);
    FrontPointF( const FrontPointF& a);  // de copie
    // DESTRUCTEUR :
    ~FrontPointF ();
    // 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 point;};
    // creation d'un nouvelle element frontiere du type FrontPointF
    ElFrontiere * NevezElemFront() const ;  
    // creation d'un nouvelle element frontiere du type FrontPointF
    // avec des donnees differentes
    ElFrontiere * NevezElemFront
       ( const Tableau <Noeud *>& tab, const DdlElement& ddlElem) const ;
     
    // METHODES PUBLIQUES :
    
    
    // ramene les coordonnees du point de reference de l'element
    // ici ramene les coordonnees du noeud a tdt
    Coordonnee Ref()  { return tabNoeud(1)->Coord2();} ;
    
    // ramene un plan tangent ou une droite tangente au point de reference
    // si indic = 0 -> point, indic = 1 -> une droite, =2 -> un plan
    // ces infos sont stocke et sauvegardees dans l'element de frontiere
    // ici il s'agit uniquement d'un point, donc pas de droite ou de plan tangent
    void TangentRef(Droite& , Plan& , int& indic) { indic = 0;};
    
    // M est un point du dernier plan tangent sauvegarde dans l'element frontiere
    //  - calcul du point M1 correspondant sur la surface, M1 est stocke
    //  - calul et retour du plan tangent (ou une droite tangente) au point M1
    // si indic = 0 -> un point, indic = 1 -> une droite, =2 -> un plan
    // ces infos sont stocke et sauvegardees dans l'element de frontiere
    // ici il s'agit uniquement d'un point, donc pas de droite ou de plan tangent
    void Tangent(const  Coordonnee& ,Coordonnee& M1, Droite& , Plan& , int& indic)
      { M1 = tabNoeud(1)->Coord2(); indic = 0; };
      
    // ramene un autre plan tangent ou une droite tangente genere de maniere pseudo aleatoire
    // si indic = 0 -> un point, indic = 1 -> une droite, =2 -> un plan
    // ces infos sont stocke et sauvegardees dans l'element de frontiere
    // ici il s'agit uniquement d'un point, donc pas de droite ou de plan tangent
    void AutreTangent(Droite& , Plan& , int& indic)
       { indic = 0;};
       
    // ramene true si le dernier point M1 est dans l'element et que sa position precedente 
    // est situee du bon cote de la frontiere , sinon false
    // la verif sur a est executer uniquement dans les cas suivant :
    // 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 !!
    
    // ici  ramene vrai tjours
    bool InSurf(const double& ) const
     { return true; };
    
    // affichage des infos de l'elements frontiere
    void Affiche(Enum_dure temp )  const
     { cout << "\n element frontiere de type FrontPointF , de noeuds sommets : \n ";
       int nbn=1;
       switch (temp)
           {case TEMPS_tdt: for  (int i =1;i<=nbn;i++)
              cout <<" noe: " << tabNoeud(i)->Num_noeud() << " "
                   << tabNoeud(i)->Coord2() << ", " ; break;
            case TEMPS_t : for  (int i =1;i<=nbn;i++)
              cout <<" noe: " << tabNoeud(i)->Num_noeud() << " "
                   << tabNoeud(i)->Coord1() << ", " ; break;
            case TEMPS_0 : for  (int i =1;i<=nbn;i++)
              cout <<" noe: " << tabNoeud(i)->Num_noeud() << " "
                   << tabNoeud(i)->Coord0() << ", " ; break;
            default: break;
           };
     };
     
    // actualise et ramene le dernier plan tangent (ou  droite tangente) calcule
    // si indic = 0 -> un point, indic = 1 -> une droite, =2 -> un plan
    // ici il s'agit uniquement d'un point, donc pas de droite ou de plan tangent
    // 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& , Plan& , int& indic,bool )
	     { indic = 0; return NULL;};	 
    
    // test si la position d'un point est du bon cote ( c-a-d hors matiere) ou non
    // si le point est sur la surface, ramène false
    // ramene true si hors matiere, sinon false
    // le test  sur a est executer uniquement dans les cas suivants :
    // dimension 3D et  frontiere 2D
    // dimension 3D axi et frontière 1D
    // dimension 2D et frontiere 1D
    // ->>> dimension 3D et frontiere 1D, pas de verif
    // ->>> autre cas ne doivent pas arriver normalement !!
    /// --------->>> sans objet ici ramene par defaut false
    // retour de r = distance du point à la surface, ligne
    bool BonCote_t( const Coordonnee& ,double& r)  const { return false;}; // cas ou on utilise la frontiere a t
    bool BonCote_tdt( const Coordonnee& ,double& r) const { return false;}; // cas ou on utilise la frontiere a tdt
    
    // calcul les fonctions d'interpolation au dernier point de projection sauvegarde
    const Vecteur& Phi() { return phi_M;};
     
    // 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
    // normalement ne doit pas servir donc message d'erreur
    Met_abstraite * Metrique() 
      { cout << "\n erreur on ne doit pas calculer la métrique d'un point frontière!!";
       cout << "\n Met_abstraite * FrontPointFMetrique() " << endl;
       Sortie (1);
       Met_abstraite * toto = NULL;
       return toto;
      };
    
  //----------- fonction publique particulière à l'élément point ------------
  // fonction permettant de renseigner un vecteur normal au plan tangent au point
  // ce vecteur, s'il existe est utilisé par les fonctions  BonCote_t et BonCote_tdt
  void Def_Normale(const Coordonnee& V) {if (T == NULL) {T = new Coordonnee(V);} else *T=V;};

	 //----- 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(ifstream& ent) ;
	 void Ecriture_base_info_ElFrontiere_pour_projection(ofstream& sort) ;
       
  private :  
   // VARIABLES PROTEGEES :
    static GeomPoint point; // le point  de reference
    Coordonnee* T; // le vecteur normal au plan tangent au point s'il existe
    Vecteur phi_M;
   // METHODES PROTEGEES :

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

#endif  
