2021-09-07 09:51:43 +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-07 09:51:43 +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/>.
|
|
|
|
|
|
|
|
#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;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|