475 lines
23 KiB
C++
475 lines
23 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: Gestion des chargements. *
|
|
* Chargement en temps : *
|
|
* *
|
|
* ^ *
|
|
* 1 | t1-------- *
|
|
* | / *
|
|
* | / Type 1 = une rampe linéaire *
|
|
* | / puis un plateau horizontal *
|
|
* 0------------------> t *
|
|
* *
|
|
* *
|
|
* ^ Type 2 = une rampe linéaire *
|
|
* 1 | t1-----t2 un plateau puis arrêt *
|
|
* | / | *
|
|
* | / | *
|
|
* | / | *
|
|
* 0------------------> t *
|
|
* *
|
|
* ^ Type 3 = uniquement un plateau *
|
|
* 1 |------------------- ..... *
|
|
* | *
|
|
* | *
|
|
* | *
|
|
* 0------------------> t *
|
|
* *
|
|
* Type 4 = utilisation d'une courbe 1D quelconque *
|
|
* *
|
|
* Type 5 utilisation d'un fichier de points qui *
|
|
* impose la suite de temps de calcul, donc de pas de temps *
|
|
* *
|
|
* $ *
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
|
|
* VERIFICATION: *
|
|
* *
|
|
* ! date ! auteur ! but ! *
|
|
* ------------------------------------------------------------ *
|
|
* ! ! ! ! *
|
|
* $ *
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
* MODIFICATIONS: *
|
|
* ! date ! auteur ! but ! *
|
|
* ------------------------------------------------------------ *
|
|
* $ *
|
|
************************************************************************/
|
|
#ifndef CHARGE_H
|
|
#define CHARGE_H
|
|
|
|
#include "LectBloc_T.h"
|
|
#include "ParaGlob.h"
|
|
#include "Bloc.h"
|
|
#include <list>
|
|
#include "ParaAlgoControle.h"
|
|
#include "LesMaillages.h"
|
|
#include "Mat_abstraite.h"
|
|
#include "Assemblage.h"
|
|
#include "Nb_assemb.h"
|
|
#include "Courbe1D.h"
|
|
#include "BlocCharge_T.h"
|
|
#include "LesCourbes1D.h"
|
|
#include "LesFonctions_nD.h"
|
|
#include "BlocCharge.h"
|
|
#include "Temps_CPU_HZpp.h"
|
|
|
|
|
|
/** @defgroup Groupe_concernant_le_chargement
|
|
*
|
|
* BUT: groupe relatif aux chargements
|
|
*
|
|
*
|
|
* \author Gérard Rio
|
|
* \version 1.0
|
|
* \date 23/01/97
|
|
* \brief groupe relatif aux chargements
|
|
*
|
|
*/
|
|
|
|
/// @addtogroup Groupe_concernant_le_chargement
|
|
/// @{
|
|
///
|
|
|
|
|
|
class Charge
|
|
{
|
|
public :
|
|
// VARIABLES PUBLIQUES :
|
|
// ---- class intermédiaires -----
|
|
class PHydro : public BlocGeneEtVecMultType
|
|
{ public : // surcharge de l'operator de lecture
|
|
friend istream & operator >> (istream & entree, PHydro & coo)
|
|
{ entree >> ((BlocGeneEtVecMultType&)(coo)); return entree;};
|
|
// surcharge de l'operator d'ecriture
|
|
friend ostream & operator << (ostream & sort, const PHydro & coo)
|
|
{ sort << ((const BlocGeneEtVecMultType&)(coo)); return sort; };
|
|
PHydro(); // constructeur par défaut
|
|
PHydro (const PHydro & a) ; // constructeur par defaut
|
|
~PHydro () ; // destructeur
|
|
|
|
// mise en place de l'association des courbes
|
|
// en retour indique si l'association est ok
|
|
bool Mise_en_place_des_courbes(LesCourbes1D& lesCourbes1D);
|
|
const Coordonnee& Direction_N(); // récup de la direction N normée
|
|
const Coordonnee& Point_M(); // récup du point de la surface libre
|
|
protected :
|
|
Tableau <Courbe1D*> N; // courbes permettant de piloter éventuellement la normale
|
|
Tableau <Courbe1D*> M; // courbes permettant de piloter éventuellement le point de la surface neutre
|
|
bool normer; // dans le cas de vecteur N constant, indique si le vecteur a été normé ou pas
|
|
};
|
|
class PHydrodyna : public BlocGen
|
|
{ public : // surcharge de l'operator de lecture
|
|
friend istream & operator >> (istream & entree, PHydrodyna & coo)
|
|
{ entree >> ((BlocGen&)(coo)); return entree;};
|
|
// surcharge de l'operator d'ecriture
|
|
friend ostream & operator << (ostream & sort, const PHydrodyna & coo)
|
|
{ sort << ((const BlocGen&)(coo)); return sort; };
|
|
PHydrodyna () : BlocGen(5,1),frot_fluid(NULL),coef_aero_n(NULL),coef_aero_t(NULL) {};
|
|
// mise en place de l'association des courbes
|
|
// en retour indique si l'association est ok
|
|
bool Mise_en_place_des_courbes(LesCourbes1D& lesCourbes1D);
|
|
Courbe1D* Frot_fluid() const { return frot_fluid;};
|
|
Courbe1D* Coef_aero_n() const { return coef_aero_n;};
|
|
Courbe1D* Coef_aero_t() const { return coef_aero_t;};
|
|
protected :
|
|
Courbe1D* frot_fluid; // courbe de frottement fluide
|
|
Courbe1D* coef_aero_n; // courbe pour l'effort de traînée
|
|
Courbe1D* coef_aero_t; // courbe pour l'effort de portance
|
|
};
|
|
|
|
|
|
// ---- fin class intermédiaires -----
|
|
|
|
// CONSTRUCTEURS :
|
|
Charge () ; // constructeur par defaut
|
|
// DESTRUCTEUR :
|
|
~Charge () ;
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// affichage des differents chargements
|
|
void Affiche() const ; // affiche la totalite
|
|
void Affiche1() const ; // affiche que la premiere lecture
|
|
void Affiche2() const ; // affiche que la seconde lecture
|
|
|
|
// lecture des differents chargements actions exterieurs imposees
|
|
void Lecture1(UtilLecture & entreePrinc,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
|
|
,LesFonctions_nD& lesFonctionsnD);
|
|
|
|
// lecture du type d'application du chargements
|
|
void Lecture2(UtilLecture & entreePrinc,LesCourbes1D& lesCourbes1D
|
|
,LesFonctions_nD& lesFonctionsnD);
|
|
|
|
// initialisation du chargement
|
|
// on verifie egalement la bonne adequation des references
|
|
void Initialise(LesMaillages * lesMail,LesReferences* lesRef,ParaAlgoControle& pa
|
|
,const LesCourbes1D& lesCourbes1D,const LesFonctions_nD& lesFonctionsnD);
|
|
// dans le cas où on utilise plusieurs algorithmes, il faut pouvoir changer
|
|
// de paramètres de contrôle
|
|
void ChangeParaAlgoControle(ParaAlgoControle& pa)
|
|
{paAlgo = & pa;};
|
|
|
|
// avancement de la charge
|
|
// il peut y avoir plusieurs type d'avancement
|
|
// en fonction des donnees ( transparent pour l'utilisateur)
|
|
// mais aussi en fonction des parametres
|
|
// incrémentation d'un compteur, permet de limiter le nombre d'appel
|
|
// retourne false par défaut, mais si le pas de temps a été modifié
|
|
// retourne true !!, car par exemple de la fin du chargement, d'où une modif du pas
|
|
// pour obtenir exactement la fin
|
|
bool Avance(); // premier version
|
|
|
|
// retour de la charge au cas précédent, c'est à dire
|
|
// avant le dernier ordre d'avancement
|
|
// valeur par défaut de "exacte "
|
|
// si exacte n'est pas présent ou faux: le compteur d'appel de Avance(), n'est pas décrémenté
|
|
// exacte=true: le compteur d'appel est décrémenté, en fait on revient exactement au départ
|
|
// ce qui permet d'utiliser plusieurs fois Avance() dans un même pas de temps
|
|
// en comptabilisant par exemple qu'une seule fois un appel de Avance(), cas d'une intégration
|
|
// temporelle par exemple
|
|
void Precedant(bool exacte=false);
|
|
|
|
// diminution de l'incrément de charge dans le cas par exemple d'une non convergence
|
|
// ramène true si la diminution est effective, sinon false
|
|
bool Diminue_inc_charge(double diminue);
|
|
// augmentation de l'incrément de charge dans le cas de bonne convergence
|
|
// ramène true si l'augmentation est effective, sinon false
|
|
bool Augmente_inc_charge(double augmente);
|
|
|
|
// declaration de la fin en fonction du type de chargement
|
|
// retour:
|
|
// retour:
|
|
// 0 : la fin n'est pas valide, on continue
|
|
// 1 : temps fin dépassé
|
|
// 2 : compteur_increment dépassé
|
|
// 3 : compteur_essai_increment dépassé
|
|
// NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
|
|
// puis ensuite le compteur d'incréments
|
|
// puis le nombre d'essai maxi, puis enfin le cas normal
|
|
// si affichage est true, affichage d'un message
|
|
int Fin(const int & icharge,bool affichage = true);
|
|
|
|
// retourne l'increment du coef multiplicateur de charge, courant
|
|
inline double MultCharge()
|
|
{ return multi;};
|
|
|
|
// retourne le coef multiplicateur de charge, courant
|
|
inline double IntensiteCharge()
|
|
{ return coeff;};
|
|
|
|
// retourne le temps courant ou en est le calcul
|
|
inline double Temps_courant () {return paAlgo->Variables_de_temps().TempsCourant();};
|
|
// incrément de temps courant
|
|
inline double Increment_de_Temps() {return paAlgo->Variables_de_temps().IncreTempsCourant();};
|
|
|
|
// la manière dont on vise le temps fin
|
|
// = 0 par défaut pour les schéma implicite: indique
|
|
// que l'on doit viser le temps fin de manière stricte (pas le dépasser)
|
|
// = 1 : on doit juste le dépasser -> a priori c'est le fonctionnement par défaut des
|
|
// algo explicites, compte tenu qu'il n'y a pas de prise en compte précise
|
|
// de la variation du pas de temps
|
|
// mise à jour avec la méthode :
|
|
void Change_temps_fin_non_stricte(int methode)
|
|
{temps_fin_non_stricte = methode;};
|
|
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul parallèle: // passage des infos entre process
|
|
const Temps_CPU_HZpp& Temps_transfert_court() const {return temps_transfert_court;} ;
|
|
const Temps_CPU_HZpp& Temps_transfert_long() const {return temps_transfert_long;} ;
|
|
const Temps_CPU_HZpp& Temps_attente() const {return temps_attente;} ;
|
|
#endif
|
|
|
|
// retourne le temps cumulés relatif à tous les chargements
|
|
const Temps_CPU_HZpp& Temps_cpu_chargement() const {return temps_cpu_chargement;};
|
|
|
|
// mise en place du chargement impose sur le second membre global
|
|
// cas explicite
|
|
// la variable relative à la classe assemblage est passé en argument ce qui permet d'utiliser
|
|
// éventuellement plusieurs type d'assemblage
|
|
// retour false si problème de calcul
|
|
bool ChargeSecondMembre_Ex_mecaSolid
|
|
(Assemblage & assemb,LesMaillages * lesMail,LesReferences* lesRef,Vecteur& vecglob
|
|
,const ParaAlgoControle & pa,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD);
|
|
|
|
// cas implicite avec également modification de la raideur quand le chargement dépend
|
|
// de la géométrie, en fonction des paramètres de pa
|
|
// la variable relative à la classe assemblage est passé en argument ce qui permet d'utiliser
|
|
// éventuellement plusieurs type d'assemblage
|
|
// de plus il faut prévoir un pointeur d'assemblage pour séparer le cas d'assemblage symétrique ou non
|
|
// d'où la variable pointeur de fonction membre d'assemblage
|
|
// retour false si problème de calcul
|
|
bool ChargeSMembreRaideur_Im_mecaSolid(Assemblage & assemb,LesMaillages * lesMail,LesReferences* lesRef
|
|
,Vecteur& vecglob, Mat_abstraite& matglob
|
|
,void (Assemblage::* assembMat) // le pointeur de fonction
|
|
(Mat_abstraite & matglob,const Mat_abstraite & matloc,
|
|
const DdlElement& tab_ddl,const Tableau<Noeud *>&tab_noeud)
|
|
,const ParaAlgoControle & pa
|
|
,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD);
|
|
|
|
// lecture de donnée en fonction d'un indicateur : int type
|
|
// pour l'instant ne fait rien
|
|
void LectureDonneesExternes(UtilLecture& ,LesReferences& ,const int,const string& ) {};
|
|
|
|
// affichage et definition interactive des commandes
|
|
void Info_commande_LesCharges1(UtilLecture & entreePrinc);
|
|
|
|
// affichage et definition interactive des commandes
|
|
void Info_commande_LesCharges2(UtilLecture & entreePrinc);
|
|
|
|
//----- lecture écriture dans base info -----
|
|
// cas donne le niveau de la récupération
|
|
// = 1 : on récupère tout
|
|
// = 2 : on récupère uniquement les données variables (supposées comme telles)
|
|
void Lecture_base_info(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
|
|
,LesFonctions_nD& lesFonctionsnD);
|
|
// cas donne le niveau de sauvegarde
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
void Ecriture_base_info(ofstream& sort,const int cas);
|
|
|
|
private :
|
|
// VARIABLES PROTEGEES :
|
|
// les forces sont les entitees duales des degres de liberte
|
|
// par exemple, force ponctuelle est duale de Xi ou Ui ou Vi
|
|
|
|
// densite de force volumique dans le repère absolu
|
|
Tableau < BlocCharge< BlocDdlLim<BlocForces> > > tabFvol;
|
|
// densite de force surfacique dans le repère absolu
|
|
Tableau < BlocCharge< BlocDdlLim<BlocForces> > > tabFsurfac;
|
|
// pression uniformement reparti, appliquee normalement a la surface
|
|
Tableau < BlocCharge< BlocDdlLim<BlocIntensite> > > tabPresUnif;
|
|
// force ponctuelle sur un noeud
|
|
Tableau < BlocCharge< BlocDdlLim<BlocForces> > > tabPonctuel;
|
|
// pression unidirectionnelle type pression des fluides
|
|
Tableau < BlocCharge< BlocDdlLim<BlocForces> > > PresUniDir;
|
|
// pression hydrostatique
|
|
Tableau < BlocCharge< BlocDdlLim<PHydro> > > PresHydro;
|
|
// pression hydrodynamique
|
|
Tableau < BlocCharge< BlocDdlLim<PHydrodyna> > > coefHydroDyna;
|
|
// densite de force lineique dans le repère absolu
|
|
Tableau < BlocCharge< BlocDdlLim<BlocForces> > > tabFlineique;
|
|
// densite de force lineique suiveuse, c'est-à-dire qui suit le repère
|
|
// locale (possible uniquement pour des éléments 2D)
|
|
Tableau < BlocCharge< BlocDdlLim<BlocForces> > > tabFlineiqueSuiv;
|
|
// torseur d'effort via une répartition de charges ponctuelles
|
|
Tableau < BlocCharge< BlocDdlLim<PTorseurPonct> > > tabTorseurPonct;
|
|
Tableau < Tableau < Coordonnee > > tab_P; // tableau de travail pour tabTorseurPonct
|
|
Tableau < Tableau < Coordonnee > > t_force; // idem
|
|
|
|
// ---- type d'application du chargement -----
|
|
string nomtypeCharge; // mot cle du type de chargement
|
|
Tableau<double> tabType; // les parametres
|
|
Courbe1D* f_charge; // courbe de chargement éventuelle
|
|
bool interne_f_charge; // indique si oui ou non la courbe interne
|
|
int ancien_num_pt_type5, num_pt_courant_type5; // variables de travaille pour le type 5
|
|
|
|
// les paramètres globaux
|
|
ParaAlgoControle* paAlgo;
|
|
// le parametre global d'avancement de la charge
|
|
// double temps;
|
|
// compteur d'increment
|
|
int compteur_essai_increment;
|
|
// multi = l'increment courant de multiplication de la charge
|
|
// coeff = niveau actuel de la charge
|
|
double multi,coeff;
|
|
// la sauvegarde des paramètres d'un pas sur l'autre
|
|
double temps_sauve;
|
|
double multi_sauve,coeff_sauve;
|
|
|
|
// la manière dont on vise le temps fin
|
|
int temps_fin_non_stricte; // = 0 par défaut pour les schéma implicite: indique
|
|
// que l'on doit viser le temps fin de manière stricte (pas le dépasser)
|
|
// = 1 : on doit juste le dépasser -> a priori c'est le fonctionnement par défaut des
|
|
// algo explicites, compte tenu qu'il n'y a pas de prise en compte précise
|
|
// de la variation du pas de temps
|
|
// mise à jour avec la méthode : Change_temps_fin_non_stricte(int methode)
|
|
|
|
Temps_CPU_HZpp temps_cpu_chargement; // le temps cpu du à tous les chargements
|
|
|
|
#ifdef UTILISATION_MPI
|
|
// cas d'un calcul parallèle: // passage des infos entre process
|
|
Temps_CPU_HZpp temps_transfert_court ;
|
|
Temps_CPU_HZpp temps_transfert_long ;
|
|
Temps_CPU_HZpp temps_attente ;
|
|
|
|
// on définit les conteneurs de passage d'info
|
|
Tableau <mpi::request > tab_reqs1;
|
|
Tableau <mpi::request > tab_reqs2;
|
|
Tableau <mpi::request > tab_reqs3;
|
|
Tableau <Vecteur > tabV_transfert;
|
|
Tableau <Mat_pleine> tabMat_transfert;
|
|
Tableau <Vecteur > tab_six_faux_entiers;
|
|
|
|
// transfert du second membre "SM_transfert" et mise à jour
|
|
// de l'index des tableaux "index_transfert" par rotation cyclique
|
|
// NB: tous les tableaux doivent avoir la même taille
|
|
void Transfert_SM(bool& premier_passage,
|
|
const int& tyfront,
|
|
const int& num_front,
|
|
Vecteur & SM_transfert,
|
|
int& index_transfert,
|
|
const int & numail,
|
|
const int & numelem
|
|
);
|
|
// transfert du second membre "SM_transfert" et de la matrice "MAT_transfert" et mise à jour
|
|
// de l'index des tableaux "index_transfert" par rotation cyclique
|
|
// NB: tous les tableaux doivent avoir la même taille
|
|
void Transfert_MatSm(bool& premier_passage,
|
|
const int& tyfront,
|
|
const int& num_front,
|
|
Vecteur & SM_transfert,
|
|
Mat_pleine * MAT_transfert,
|
|
int& index_transfert,
|
|
const int & numail,
|
|
const int & numelem
|
|
);
|
|
#endif
|
|
|
|
|
|
// les autres parametres relatif au temps
|
|
//-// double deltatmaxi; // increment de temps maxi
|
|
//-// double prectemps; // precision sur le temps final
|
|
//-// double deltat; // increment de temps
|
|
//-// double tempsfin; // temps de fin de calcul
|
|
//-// int maxincre ; // maximum d'increment de temps
|
|
//-// double multiplicateur; // multiplicateur de la charge
|
|
|
|
// pointeurs des fonctions en cours
|
|
void (Charge::*PtDebut) (void);
|
|
bool (Charge::*PtAvance) (void);
|
|
void (Charge::*PtPrecedent) (void);
|
|
int (Charge::*PtFin) (const int & icharge,bool affichage); // affichage indique si oui ou non on
|
|
// on veut un affichage signifiant que l'on est à la fin du chargement
|
|
|
|
// METHODES PROTEGEES :
|
|
// declaration des initialisations en fonction du type de chargement
|
|
void Debut1();
|
|
void Debut2();
|
|
void Debut3();
|
|
void Debut4();
|
|
void Debut5();
|
|
void Debut6();
|
|
void Debut7();
|
|
// declaration de l'avancement en fonction du type de chargement
|
|
bool Avance1();
|
|
bool Avance2();
|
|
bool Avance3();
|
|
bool Avance4();
|
|
bool Avance5();
|
|
bool Avance6();
|
|
bool Avance7();
|
|
// declaration du retour à l'incrément précédent en fonction du type de chargement
|
|
void Precedent1();
|
|
void Precedent2();
|
|
void Precedent3();
|
|
void Precedent4();
|
|
void Precedent5();
|
|
void Precedent6();
|
|
void Precedent7();
|
|
// declaration de la fin en fonction du type de chargement
|
|
// 0 : la fin n'est pas valide, on continue
|
|
// 1 : temps fin dépassé
|
|
// 2 : compteur_increment dépassé
|
|
// 3 : compteur_essai_increment dépassé
|
|
// NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
|
|
// puis ensuite le compteur d'incréments
|
|
// puis le nombre d'essai maxi, puis enfin le cas normal
|
|
// si affichage est true, affichage d'un message
|
|
int Fin1(const int & icharge,bool affichage);
|
|
int Fin2(const int & icharge,bool affichage);
|
|
int Fin3(const int & icharge,bool affichage);
|
|
int Fin4(const int & icharge,bool affichage);
|
|
int Fin5(const int & icharge,bool affichage);
|
|
int Fin6(const int & icharge,bool affichage);
|
|
int Fin7(const int & icharge,bool affichage);
|
|
|
|
|
|
};
|
|
/// @} // end of group
|
|
|
|
#endif
|