// 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) . // // 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 . // // For more information, please consult: . /************************************************************************ * 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 & 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 * 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(istream& 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(istream& ent); void Ecriture_base_info_front(ostream& 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;}; #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 // 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 * 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 #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 // fonctions internes static double prop_mini; // mini proportion à ajouter à l'encombrement }; /// @} // end of group #endif