2021-09-27 12:42:13 +02:00
|
|
|
|
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-27 12:42:13 +02:00
|
|
|
// 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 *
|
2023-05-03 17:23:49 +02:00
|
|
|
* éléments finis. *
|
|
|
|
* Ce conteneur est utilisé en dehors d'un élément, par exemple*
|
|
|
|
* pour le contact *
|
2021-09-27 12:42:13 +02:00
|
|
|
* $ *
|
2023-05-03 17:23:49 +02:00
|
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
|
|
* *
|
2021-09-27 12:42:13 +02:00
|
|
|
* 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
|
2023-05-03 17:23:49 +02:00
|
|
|
Front ( const ElFrontiere& el, Element * pt, int num_front,int angle_mort=0) ;
|
2021-09-27 12:42:13 +02:00
|
|
|
// de copie
|
|
|
|
Front ( const Front& a);
|
|
|
|
// destructeur
|
|
|
|
~Front() ;
|
|
|
|
|
|
|
|
// ============= METHODES ==========
|
|
|
|
|
|
|
|
// affichage à l'écran des informations liées au contact
|
2023-05-03 17:23:49 +02:00
|
|
|
// 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 ;
|
2021-09-27 12:42:13 +02:00
|
|
|
|
|
|
|
// 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)
|
2023-05-03 17:23:49 +02:00
|
|
|
&& (num_frontiere == a.num_frontiere)
|
|
|
|
&& (angle_mort == a.angle_mort)
|
|
|
|
)
|
2021-09-27 12:42:13 +02:00
|
|
|
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
|
2023-05-03 17:23:49 +02:00
|
|
|
// Important**: ne comprend pas angle_mort contrairement à la méthode de même nom dans Contact
|
2021-09-27 12:42:13 +02:00
|
|
|
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
|
2023-05-03 17:23:49 +02:00
|
|
|
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);
|
2021-09-27 12:42:13 +02:00
|
|
|
|
|
|
|
// 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;};
|
2023-05-03 17:23:49 +02:00
|
|
|
|
|
|
|
// 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;};
|
2024-03-24 11:43:58 +01:00
|
|
|
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
// cas d'un calcul parallèle: // passage des infos entre process
|
|
|
|
int NumUnique() const {return num_unique;}; // s'il est attribué (c-a-d != 0) donne un numéro unique de référencement
|
|
|
|
// est mis à jour et utilisé par les classes appelantes
|
|
|
|
void ChangeNumUnique(int num) {num_unique = num;};
|
|
|
|
#endif
|
2021-09-27 12:42:13 +02:00
|
|
|
|
|
|
|
// 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
|
2023-05-03 17:23:49 +02:00
|
|
|
|
|
|
|
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
|
2024-03-24 11:43:58 +01:00
|
|
|
|
|
|
|
#ifdef UTILISATION_MPI
|
|
|
|
// cas d'un calcul parallèle: // passage des infos entre process
|
|
|
|
int num_unique; // s'il est attribué (c-a-d != 0) donne un numéro de référencement
|
|
|
|
// est mis à jour et utilisé par les classes appelantes
|
|
|
|
#endif
|
2021-09-27 12:42:13 +02:00
|
|
|
|
|
|
|
// fonctions internes
|
|
|
|
static double prop_mini; // mini proportion à ajouter à l'encombrement
|
|
|
|
|
|
|
|
};
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
#endif
|