// 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: . #include "TypeQuelconque.h" #include "TypeQuelconqueParticulier.h" // CONSTRUCTEURS : // constructeur par défaut TypeQuelconque::TypeQuelconque(): enuType(RIEN_TYPEQUELCONQUE),enu_ddl_posi(NU_DDL),pt_grandeur(new Grandeur_defaut()) ,actif(true) {}; // constructeur fonction d'un type donnée et d'une grandeur // c'est le 1er constructeur officiel, qui sert // posi_ddl: inique un ddl dont les points de calcul (ex: les pt d'integ) sont les même // que la grandeur particulière TypeQuelconque::TypeQuelconque(TypeQuelconque_enum_etendu enu,Enum_ddl posi_ddl,const Grandeur& pt_gr): enuType(enu),enu_ddl_posi(posi_ddl),pt_grandeur(NULL),actif(true) {if (pt_gr.Type_grandeurAssocie() != enuType.TypeDeGrandeurTG()) { cout << "\n erreur , le type de la grandeur associe: " << NomTypeGrandeur(pt_gr.Type_grandeurAssocie()) << " n'est pas identique au type quelconque transmis !! " << enuType; Sortie(1); }; // c'est ok on peut attribuer la grandeur pt_grandeur = pt_gr.New_idem_grandeur(); }; // constructeur fonction d'un type donnée et d'une grandeur // c'est le 1er constructeur officiel, qui sert // posi_ddl: inique un ddl dont les points de calcul (ex: les pt d'integ) sont les même // que la grandeur particulière TypeQuelconque::TypeQuelconque(EnumTypeQuelconque enu,Enum_ddl posi_ddl,const Grandeur& pt_gr): enuType(enu),enu_ddl_posi(posi_ddl),pt_grandeur(NULL),actif(true) {if (pt_gr.Type_grandeurAssocie() != enuType.TypeDeGrandeurTG()) { cout << "\n erreur , le type de la grandeur associe: " << NomTypeGrandeur(pt_gr.Type_grandeurAssocie()) << " n'est pas identique au type quelconque transmis !! " << enuType; Sortie(1); }; // c'est ok on peut attribuer la grandeur pt_grandeur = pt_gr.New_idem_grandeur(); }; // constructeur fonction d'un type donnée uniquement // c'est le 2er constructeur officiel, qui sert // ici il n'y a pas de grandeur associée, util uniquement pour gérer le type mais pas la grandeur TypeQuelconque::TypeQuelconque(TypeQuelconque_enum_etendu enu) : enuType(enu),enu_ddl_posi(NU_DDL),pt_grandeur(NULL),actif(true) {}; // constructeur fonction d'un type donnée uniquement // c'est le 2er constructeur officiel, qui sert // ici il n'y a pas de grandeur associée, util uniquement pour gérer le type mais pas la grandeur TypeQuelconque::TypeQuelconque(EnumTypeQuelconque enu) : enuType(enu),enu_ddl_posi(NU_DDL),pt_grandeur(NULL),actif(true) {}; // constructeur de copie TypeQuelconque::TypeQuelconque(const TypeQuelconque& a) : enuType(a.enuType),enu_ddl_posi(a.enu_ddl_posi),pt_grandeur(NULL),actif(a.actif) {if (a.pt_grandeur != NULL) pt_grandeur = a.pt_grandeur->New_idem_grandeur(); }; // DESTRUCTEUR : TypeQuelconque::~TypeQuelconque() {if (pt_grandeur != NULL) delete pt_grandeur; }; // changement d'une grandeur quelconque // la grandeur initiale est transformée en la grandeur passée en paramètre // utile après une contruction par défaut void TypeQuelconque::ChangeGrandeur(const TypeQuelconque& a) { // cout << *this << a << endl; if (enuType != a.enuType) { // cas où la nouvelle grandeur est différente de la grandeur actuelle if (pt_grandeur != NULL) delete pt_grandeur; pt_grandeur = a.pt_grandeur->New_idem_grandeur(); } else { // cas où la grandeur est identique // mais même identique, elle peut ne pas avoir été affectée donc on regarde if (pt_grandeur == NULL) // cas où il faut définir une grandeur identique {pt_grandeur = a.pt_grandeur->New_idem_grandeur();} else // sinon il suffit de recopier {*pt_grandeur = *(a.pt_grandeur);}; }; // on met à jour les énumérations enuType=a.enuType; enu_ddl_posi=a.enu_ddl_posi; }; // surcharge d'affectation // ne doit concerner que des grandeurs quelconques de même type // il n'y a donc pas de changement automatique de type, volontairement pour éviter des erreurs // et un long temps de traitement // sauf dans le cas où le type this n'est pas pour l'instant affecté, dans ce cas on en crée un // identique à celui de a (permet d'utiliser des tableaux de typeQuelconque, sinon c'est impossible) TypeQuelconque & TypeQuelconque::operator = ( const TypeQuelconque & a) { enuType=a.enuType; enu_ddl_posi=a.enu_ddl_posi; // dans le cas où le type this n'est pas pour l'instant affecté, dans ce cas on en crée un // identique à celui de a (permet d'utiliser des tableaux de typeQuelconque, sinon c'est impossible) if (pt_grandeur->Type_enumGrandeurParticuliere() == RIEN_TYPE_QUELCONQUE_PARTICULIER) { delete pt_grandeur; pt_grandeur = a.pt_grandeur->New_idem_grandeur(); }; #ifdef MISE_AU_POINT if (pt_grandeur->Type_enumGrandeurParticuliere() != a.pt_grandeur->Type_enumGrandeurParticuliere()) { cout << "\n erreur d'affectation entre deux types quelconque qui sont de type different !! " << NomTypeQuelParticulier(pt_grandeur->Type_enumGrandeurParticuliere()) << " et " << NomTypeQuelParticulier(a.pt_grandeur->Type_enumGrandeurParticuliere()) << " "; Sortie(1); }; #endif *pt_grandeur=*a.pt_grandeur; actif = a.actif; return *this; }; // change de repère de la grandeur si nécessaire void TypeQuelconque::Change_repere(const Mat_pleine& beta0,const Mat_pleine& betat,const Mat_pleine& betatdt ,const Mat_pleine& gamma0,const Mat_pleine& gammat,const Mat_pleine& gammatdt) { if (EnumTypeQuelconqueGlobale(enuType.EnumTQ())==0) { switch (EnumTypeQuelconqueTemps(enuType.EnumTQ())) { case TEMPS_0: pt_grandeur->Change_repere(beta0,gamma0); break; case TEMPS_t: pt_grandeur->Change_repere(betat,gammat);break; case TEMPS_tdt: pt_grandeur->Change_repere(betatdt,gammatdt);break; }; }; }; #ifdef MISE_AU_POINT // gestion de l'erreur dans le cas où il n'y a pas de grandeur associée void TypeQuelconque::Gestion_erreur() const { if (pt_grandeur == NULL) { cout << "\n erreur dans l'utilisation d'une fonction de TypeQuelconque, la grandeur associee" << " n'est pas defini, d'ou pb !!" << "\n TypeQuelconque::Gestion_erreur()"; Sortie(1); }; }; #endif // écriture de l'entête de la grandeur : EnumTypeQuelconque EnumType2Niveau EnumTypeGrandeur et nombre de grandeur // numérique équivalente si c'est une grandeur numérique void TypeQuelconque::Ecriture_entete_grandeur(ostream & sort) { sort << enuType << " " << NomType2Niveau(pt_grandeur->Type_structure_grandeurAssocie()) << " " << NomTypeGrandeur(pt_grandeur->Type_grandeurAssocie()) << " " << pt_grandeur->NbMaxiNumeroOrdre() << " "; }; // lecture des infos internes sauf de la grandeur // retour de l'EnuTypeQuelParticulier de la grandeur EnuTypeQuelParticulier TypeQuelconque::Lecture_un (istream & ent) { string nom; ent >> enuType; //enuType = Id_nomTypeQuelconque(nom); ent >> nom ; enu_ddl_posi = Id_nom_ddl(nom.c_str()); // l'EnuTypeQuelParticulier de la grandeur EnuTypeQuelParticulier t; ent >> t; actif = true; // par défaut grandeur active return t; }; // idem mais avec création du TypeQuelconque_enum_etendu interne // s'il n'existe pas,: il s'agit uniquement du nom de def, mais les infos // associées: EnumTypeQuelconque et EnumTypeGrandeur sont lues et vérifiés // le string, lui peut ne pas exister: intéressant lorsqu'il s'agit de grandeurs // qui sont crées pendant le calcul et/ou en restart EnuTypeQuelParticulier TypeQuelconque::Lecture_un_avec_creation_TypeQuelconque_enum_etendu(istream & ent) { string nom; // lecture du nom de ref // lecture avec création éventuelle si le type n'existe pas enuType = TypeQuelconque_enum_etendu::Lecture_avec_creation_eventuelle(ent); ent >> nom ; enu_ddl_posi = Id_nom_ddl(nom.c_str()); // l'EnuTypeQuelParticulier de la grandeur EnuTypeQuelParticulier t; ent >> t; actif = true; // par défaut grandeur active return t; }; // surcharge de l'operator de lecture istream & operator >> (istream & ent, TypeQuelconque & a) { string nom; ent >> a.enuType; //a.enuType = Id_nomTypeQuelconque(nom); ent >> nom ; a.enu_ddl_posi = Id_nom_ddl(nom.c_str()); EnuTypeQuelParticulier titi; ent >> titi; // passage, ici à ne pas sauvegarder car sera lu dans la grandeur ent >> (*a.pt_grandeur); a.actif = true; // par défaut grandeur active return ent; }; // surcharge de l'operator d'ecriture ostream & operator << (ostream & sort , const TypeQuelconque & a) { sort << a.enuType //NomTypeQuelconque(a.enuType) << " " << Nom_ddl(a.enu_ddl_posi) << " " ; // on écrit également le EnuTypeQuelParticulier de la grandeur, même si elle sera reécrite par // la surcharge d'écriture de la grandeur, cela permet des choix a ce niveau, avant d'avoir // défini la grandeur, on utilise le type énuméré (et non le string associé) pour optimiser sort << a.pt_grandeur->Type_enumGrandeurParticuliere() << " " << (*a.pt_grandeur); return sort; };