Herezh_dev/Elements/Geometrie/Frontiere/Front.h
2023-05-03 17:23:49 +02:00

225 lines
11 KiB
C++

// 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: definir un element de stockage de frontiere relatif à un *
* éléments finis. *
* Ce conteneur est utilisé en dehors d'un élément, par exemple*
* pour le contact *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS: *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* $ *
************************************************************************/
#ifndef FRONT_H
#define FRONT_H
#include "Element.h"
#include "ElemMeca.h"
#include "ElFrontiere.h"
/// @addtogroup Les_Elements_de_frontiere
/// @{
///
// la classe Front stock un pointeur d'element frontiere, le nb de
// l'element finis auquel il se rapporte
class Front
{ public :
// constructeur
//par defaut
Front();
// normal
Front ( const ElFrontiere& el, Element * pt, int num_front,int angle_mort=0) ;
// de copie
Front ( const Front& a);
// destructeur
~Front() ;
// ============= METHODES ==========
// affichage à l'écran des informations liées au contact
// cas = 0 : affichage en fonction du niveau de commentaire voulu
// cas = 1 : affichage minimal nécessaire pour repérer l'élément
void Affiche(int cas=0) const ;
// operator
// affectation de toute les donnees
Front& operator = ( const Front& a);
// test d'egalite total
inline bool operator == ( const Front& a) const
{ if ((*(this->elem) == *(a.elem))
&& (this->ptEl == a.ptEl) && (this->tabmitoyen == a.tabmitoyen)
&& (num_frontiere == a.num_frontiere)
&& (angle_mort == a.angle_mort)
)
return true;
else
return false;
};
// test d'egalite sur les éléments originaux :
// l'élément elem, ptEI, et num_frontiere, mais qui ne comprend pas tabmitoyen
// Important**: ne comprend pas angle_mort contrairement à la méthode de même nom dans Contact
inline bool MemeOrigine( const Front& a) const
{ if ( (*(this->elem) == *(a.elem)) && (this->ptEl == a.ptEl)
&& (num_frontiere == a.num_frontiere))
return true;
else
return false;
};
inline bool operator != ( const Front& a) const
{ if (*this == a) return false; else return true;};
// definition des elements mitoyens
void DefMitoyen(const Tableau <Front*>& tabmitoyen);
// ajout d'un élément mitoyens (l'ajout est effectif uniquement s'il n'existe pas déjà)
void AjoutMitoyen(Front * mitoyen);
// retourne les donnees
inline const Tableau <Front*>* TabMitoyen() const { return tabmitoyen;};
// ramène l'encombrement de l'élément frontière sous forme du point
//ayant les coordonnées mini et le point ayant les coordonnées les maxi
const Coordonnee& Encom_mini_FR() {return boite_Front.Premier();};
const Coordonnee& Encom_maxi_FR() {return boite_Front.Second();};
// test si le point passé en argument appartient à la boite d'encombrement de la frontière
// tous les points sont supposées avoir la même dimension
bool In_boite_emcombrement_front(const Coordonnee& M) const;
// test si le point passé en argument appartient à la boite d'encombrement de la frontière
// tous les points sont supposées avoir la même dimension
// ici la boite est augmentée de extra dans tous les sens
bool In_boite_emcombrement_front(const Coordonnee& M,double extra) const;
// mise à jour de la boite d'encombrement de la frontière
// dep_max : déplacement maxi des noeuds du maillage
// dans le cas d'un dep_max != 0., on agrandit la boite (défavorable !!)
// , sert pour def des boites d'encombrement maxi des frontières
void Boite_encombrement_frontiere(Enum_dure temps,double dep_max=0.);
//----- lecture écriture de restart -----
// définition d'un conteneur signature permettant de définir les grandeurs internes de front
class Signature_Front { public: int numelem; int numMail;};
// la lecture s'effectue uniquement au niveau de la signature
// 1) lecture et retour de la signature
Signature_Front Lecture_base_info_Signature_Front(ifstream& ent);
// ici la lecture n'est pas complète il faut ensuite mettre à jour l'élément
// frontière en fonction de son numéro qui est déjà stocké dans l'élément, et le pointeur de l'élément
// -> utilisation de : Change_elem_frontiere, Change_PtEI
void Lecture_base_info_front(ifstream& ent);
void Ecriture_base_info_front(ofstream& sort);
// changement d'élément frontière, il faut également le numéro de l'élément fini associé
void Change_elem_frontiere(const ElFrontiere& el, int num_front)
{ if (elem != NULL) {*elem = el;} else { elem = el.NevezElemFront();}; num_frontiere= num_front;};
// ici il faut faire attention, car il faut que le numéro de frontière soit cohérent avec l'élément
// donc normalement Change_PtEI doit s'utiliser avec Change_elem_frontiere
void Change_PtEI(Element * ptei) { ptEl = ptei;};
// routine de récupération d'informations
// récup de l'element frontiere en modification éventuelle
// si le retour est NULL, c'est que l'élément frontière n'est pas définit
ElFrontiere* Eleme() const {return elem;}
// idem mais en constant
const ElFrontiere* Eleme_const() const {return elem;}
// récup du numero du maillage rattache
int NumMail() {return ptEl->Num_maillage();};
// récup du pointeur sur l'element fini qui a cree elem
Element * PtEI() const { return ptEl;};
// récup du numéro de frontière associé à l'élément fini
int Num_frontiere() const {return num_frontiere;};
// récupération de l'indicateur d'angle mort
int Angle_mort() const {return angle_mort;};
// changement de l'indicateur d'angle mort
void Change_angle_mort(int new_angle_mort) {angle_mort= new_angle_mort;};
// 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 !!
// ..... fonctions identique à celles définit dans ElFrontiere sauf pour le cas 1D
// où la fonction de ElFrontiere ne fonctionne pas, il faut utiliser celle_ci
//!!! il n'y a pas de vérification que l'élément frontière existe !!
// 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
{ if (ParaGlob::Dimension() != 1) return elem->BonCote_t(a,r);
else { r=ConstMath::grand; return (!((ElemMeca *)ptEl)->Interne_t(a));}};
bool BonCote_tdt( const Coordonnee& a,double& r) const // cas ou on utilise la frontiere a tdt
{ if (ParaGlob::Dimension() != 1) return elem->BonCote_tdt(a,r);
else { r=ConstMath::grand; return (!((ElemMeca *)ptEl)->Interne_tdt(a));}};
// variables
protected:
ElFrontiere* elem; // un pointeur d'élement frontiere:
// on est obligé d'avoir un pointeur car l'élément frontière est virtuel pur
Element * ptEl; // pointeur sur l'element fini qui a cree elem
int num_frontiere; // le numéro de la frontière relatif à l'élément finis associé
// def d'une boite d'encombrement pour les noeuds de la frontière
DeuxCoordonnees boite_Front; // le premier le min, le second le max
Tableau <Front*>* tabmitoyen; // tableau des elements mitoyens
int angle_mort; // indicateur par défaut = 0, ==1 s'il s'agit d'un front
// qui est construit pour représenter un angle mort
// fonctions internes
static double prop_mini; // mini proportion à ajouter à l'encombrement
};
/// @} // end of group
#endif