// 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-2021 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: 28/01/2004 *
* $ *
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
* $ *
* PROJET: Herezh++ *
* $ *
************************************************************************
* BUT: Gestion de divers bloc courant du fichier de lecture . *
* Cas où ces blocs sont relatif au chargement, et héritent *
* de bloc classiques. *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS: *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* $ *
************************************************************************/
#ifndef BLOC_CHARGE_T_H
#define BLOC_CHARGE_T_H
#include "BlocCharge.h"
#include "ConstMath.h"
#include "CharUtil.h"
/// @addtogroup Groupe_concernant_le_chargement
/// @{
///
//================================================
/// class template: cas d'un bloc avec charge
//================================================
template
class BlocCharge : public Bloc_particulier
{
// surcharge de l'operator de lecture
friend istream & operator >> (istream & entree, BlocCharge & coo)
{ // tout d'abord la classe mère
entree >> ((Bloc_particulier&)(coo));
// puis les valeurs propres
string toto; string nomOuNombre;
entree >> toto >> coo.co_charge >> toto >> coo.echelle;
// lecture t_min en fonction d'une fonction nD ou pas
entree >> toto >> nomOuNombre;
if (nomOuNombre != "fct_nD:")
{coo.t_min = ChangeReel(nomOuNombre);
coo.nom_fnD_t_min = "";coo.fnD_t_min=NULL;
}
else
{entree >> coo.nom_fnD_t_min;};
// lecture t_max en fonction d'une fonction nD ou pas
entree >> toto >> nomOuNombre;
if (nomOuNombre != "fct_nD:")
{coo.t_max = ChangeReel(nomOuNombre);
coo.nom_fnD_t_max = "";coo.fnD_t_max=NULL;
}
else
{entree >> coo.nom_fnD_t_max;};
// entree >> toto >> coo.t_min >> toto >> coo.t_max;
entree >> toto >> coo.precedent >> coo.attribut
>> toto >> coo.f_charge;
return entree;
}
// surcharge de l'operator d'ecriture
friend ostream & operator << (ostream & sort, const BlocCharge & coo)
{ // tout d'abord la classe mère
sort << ((const Bloc_particulier&)(coo));
// puis les valeurs propres
sort << "\n nom_courbe_de_charge: " << coo.co_charge << " echelle: " << coo.echelle;
sort << " temps_mini= " ;
if (coo.nom_fnD_t_min == "")
{sort << coo.t_min;}
else {sort << " fct_nD: " << coo.nom_fnD_t_min ;};
sort << " temps_maxi= ";
if (coo.nom_fnD_t_max == "")
{sort << coo.t_max;}
else {sort << " fct_nD: " << coo.nom_fnD_t_max ;};
// sort << " temps_mini= " << coo.t_min << " temps_maxi= " << coo.t_max;
sort << " activité_actuelle: " << coo.precedent << " attribut: "<< coo.attribut
<< " f_charge: "<< coo.f_charge
<< endl;
return sort;
}
public :
// VARIABLES PUBLIQUES :
// stockage d'un element
// class conforme a la specif de T de la class LectBloc_T
// Constructeur
BlocCharge () : // par defaut
Bloc_particulier(),co_charge(""),echelle(1.),f_charge("")
,t_min(0.),t_max(ConstMath::tresgrand),precedent(false)
,attribut("_")
,nom_fnD_t_min(""),fnD_t_min(NULL),nom_fnD_t_max(""),fnD_t_max(NULL)
{};
BlocCharge (const BlocCharge& a) : // de copie
Bloc_particulier(a),co_charge(a.co_charge),echelle(a.echelle)
,t_min(a.t_min),t_max(a.t_max),precedent(a.precedent)
,attribut(a.attribut),f_charge(a.f_charge)
,nom_fnD_t_min(a.nom_fnD_t_min),fnD_t_min(a.fnD_t_min)
,nom_fnD_t_max(a.nom_fnD_t_max),fnD_t_max(a.fnD_t_max)
{};
// destructeur
~BlocCharge () {};
//-------- les méthodes constantes --------------
// retourne le nom de la courbe de charge
const string & NomCourbeCharge() const {return co_charge;};
// retourne le nom de la fonction nD
const string & NomF_charge() const {return f_charge;};
// retourne l'échelle
const double Echelle_courbe() const {return echelle;};
// retourne la chaine de caratères attribut: si = "_" , signifie qu'il n'y a pas d'attribut
const string & Attribut() const {return attribut;};
// affichage des informations
void Affiche() const ;
// surcharge des operateurs
bool operator == ( const BlocCharge& a) const;
BlocCharge& operator = (const BlocCharge& a);
bool operator != ( const BlocCharge& a) const;
// retour du statut de validation
// vrai signifie que l'état enregistré est actif
bool Etat_validation() const {return precedent;};
//------------- les méthodes qui modifient -------------
// lecture d'un bloc
void Lecture(UtilLecture & entreePrinc);
// Validation on non de l'activité de la charge
void Validation(const double& temps) {precedent = Temps_actif(temps);};
// affichage et definition interactive des commandes
// attribut : donne un attribut éventuel à afficher dans les choix
void Info_commande_BlocCharge(ofstream & sort,string attribut = "_");
// mise en place de l'association des fonctions nD, dont ensuite on garde un pointeur
// en retour indique si l'association est ok
bool Mise_en_place_des_fonction_nD(const LesFonctions_nD& lesFonctionsnD);
// retourne un booléen qui indique si oui ou non le temps passé en paramètre
// est situé entre le temps min et maxi du ddllim
bool Temps_actif(const double& temps)
{if (fnD_t_min != NULL)
{if (fnD_t_min->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
{ t_min = (fnD_t_min->Valeur_pour_variables_globales())(1);}
else
{cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisee pour donner le temps mini "
<< " seule la dependance aux grandeurs globales est autorisee ";
cout << "\n fonction nD: "; fnD_t_min->Affiche();this->Affiche();
Sortie(1);
};
};
if (fnD_t_max != NULL)
{if (fnD_t_max->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
{ t_max = (fnD_t_max->Valeur_pour_variables_globales())(1);}
else
{cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisee pour donner le temps maxi "
<< " seule la dependance aux grandeurs globales est autorisee ";
cout << "\n fonction nD: "; fnD_t_max->Affiche();this->Affiche();
Sortie(1);
};
};
if ((t_min < temps) && (temps <= t_max))
return true;
else return false;
};
// ramène vrai si le temps est inférieur au temps actif
// ou si d'une part le temps n'est pas actif et qu'au pas précédent
// il n'était pas également actif (? je ne comprends plus pourquoi j'ai fait cette fonction)
bool Pas_a_prendre_en_compte(const double& temps)
{if (fnD_t_min != NULL)
{if (fnD_t_min->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
{ t_min = (fnD_t_min->Valeur_pour_variables_globales())(1);}
else
{cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisee pour donner le temps mini "
<< " seule la dependance aux grandeurs globales est autorisee ";
cout << "\n fonction nD: "; fnD_t_min->Affiche();this->Affiche();
Sortie(1);
};
};
if (fnD_t_max != NULL)
{if (fnD_t_max->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
{ t_max = (fnD_t_max->Valeur_pour_variables_globales())(1);}
else
{cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisee pour donner le temps maxi "
<< " seule la dependance aux grandeurs globales est autorisee ";
cout << "\n fonction nD: "; fnD_t_max->Affiche();this->Affiche();
Sortie(1);
};
};
if ((temps <= t_min) || ((temps > t_max) && !precedent))
return true;
else return false;
};
protected :
string co_charge; // nom d'une courbe de charge éventuelle
string f_charge; // nom d'une fonction nD utilisant des variables globales et autres
double echelle;
double t_min,t_max; // temps mini et maxi de durée des ddl imposés
string nom_fnD_t_min; // nom éventuelle de la fonction associée
Fonction_nD* fnD_t_min; // fonction nD associée, éventuelle
string nom_fnD_t_max; // nom éventuelle de la fonction associée
Fonction_nD* fnD_t_max; // fonction nD associée, éventuelle
int precedent; // pour la description de l'évolution du ddlLim
string attribut; // une chaine de caractère qui sert pour donner une
// information particularière au Bloc_particulier associé
// apparaît uniquement si le mot clé: attribut_ est présent
// et est constitué par la chaine qui suit ce mot cle
};
/// @} // end of group
/// @addtogroup Groupe_concernant_le_chargement
/// @{
///
/// lecture d'un bloc
template
void BlocCharge::Lecture(UtilLecture & entreePrinc)
{ // tout d'abord lecture de la classe mère
Bloc_particulier::Lecture(entreePrinc);
// on regarde s'il y a un attribut ou non, si oui on le lit
attribut="_"; // init par défaut
if (strstr(entreePrinc.tablcar,"ATTRIBUT_")!=NULL)
// cas où il y a un attribut
{ string nom;
*(entreePrinc.entree) >> nom ;
if (nom != "ATTRIBUT_")
{cout << "\n erreur de syntaxe en lecture de l'attribut "
<< " on attendait le mot cle ATTRIBUT_ et on a lu"
<< nom << endl;
if (ParaGlob::NiveauImpression() > 4)
cout << "\n BlocCharge::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
{*(entreePrinc.entree) >> attribut;};
};
// puis lecture des infos de la classe
// on regarde s'il ne s'agit pas d'une courbe de charge imposée
if (strstr(entreePrinc.tablcar,"COURBE_CHARGE:")!=NULL)
{// cas d'une courbe de charge, on se positionne sur le mot clé
string titi4; bool bonnefin4=false;
while ((!entreePrinc.entree->rdstate())&& // lecture tant qu'il n'y a pas d'erreur
(!(entreePrinc.entree->eof())))
{ // lecture du prochain mot
*(entreePrinc.entree) >> titi4 ;
if (titi4 == "COURBE_CHARGE:"){bonnefin4=true; break;};
};
if (!bonnefin4)
{cout << "\n erreur de syntaxe en lecture du nom de la courbe ";
cout << "\n BlocCharge::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du nom de la courbe de charge
{ *(entreePrinc.entree) >> co_charge; };
// on récupère l'échelle éventuellement
string toto1;
if(strstr(entreePrinc.tablcar,"ECHELLE:")!=0)
{ // cas où il y a un facteur d'échelle
*(entreePrinc.entree) >> toto1;
if (toto1 != "ECHELLE:")
{cout << "\n erreur de syntaxe en lecture du facteur d'echelle ";
cout << "\n BlocCharge::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture du facteur
*(entreePrinc.entree) >> echelle;
}; //-- fin récup de l'échelle
}; //-- fin récup de la courbe de charge
// on regarde s'il n'y a pas une fonction nD de chargement
if (strstr(entreePrinc.tablcar,"Fonction_nD_CHARGE:")!=NULL)
{// cas d'une fonction de charge, on se positionne sur le mot clé
string titi4; bool bonnefin4=false;
while ((!entreePrinc.entree->rdstate())&& // lecture tant qu'il n'y a pas d'erreur
(!(entreePrinc.entree->eof())))
{ // lecture du prochain mot
*(entreePrinc.entree) >> titi4 ;
if (titi4 == "Fonction_nD_CHARGE:"){bonnefin4=true; break;};
};
if (!bonnefin4)
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD ";
cout << "\n BlocCharge::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du nom de la fonction de charge
{ *(entreePrinc.entree) >> f_charge; };
// on récupère l'échelle éventuellement
string toto1;
if(strstr(entreePrinc.tablcar,"ECHELLE:")!=0)
{ // cas où il y a un facteur d'échelle
*(entreePrinc.entree) >> toto1;
if (toto1 != "ECHELLE:")
{cout << "\n erreur de syntaxe en lecture du facteur d'echelle ";
cout << "\n BlocCharge::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
// lecture du facteur
*(entreePrinc.entree) >> echelle;
}; //-- fin récup de l'échelle
}; //-- fin récup de la courbe de charge
// lecture éventuelle des temp mini et maxi : mais on doit doir d'abord passer éventuellement des infos
if (strstr(entreePrinc.tablcar,"TEMPS_MINI=") != 0)
// on lit jusqu'à trouver le mot clé
{ string titi; bool bonnefin=false;
while ((!entreePrinc.entree->rdstate())&& // lecture tant qu'il n'y a pas d'erreur
(!(entreePrinc.entree->eof())))
{ // lecture du prochain mot
*(entreePrinc.entree) >> titi ;
if (titi == "TEMPS_MINI="){bonnefin=true; break;};
};
if (!bonnefin)
{cout << "\n erreur inconnue de syntaxe en lecture du temps mini";
cout << "\n BlocCharge::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du temps mini
{ string nomOuNombre;
*(entreePrinc.entree) >> nomOuNombre;
if (nomOuNombre != "fct_nD:")
{t_min = ChangeReel(nomOuNombre);
nom_fnD_t_min = "";fnD_t_min=NULL;
}
else
{*(entreePrinc.entree) >> nom_fnD_t_min;};
//*(entreePrinc.entree) >> t_min;
};
}; //-- fin du cas temps mini
if (strstr(entreePrinc.tablcar,"TEMPS_MAXI=") != 0)
// on lit jusqu'à trouver le mot clé
{ string titi; bool bonnefine=false;
while ((!entreePrinc.entree->rdstate())&& // lecture tant qu'il n'y a pas d'erreur
(!(entreePrinc.entree->eof())))
{ // lecture du prochain mot
*(entreePrinc.entree) >> titi ;
if (titi == "TEMPS_MAXI="){bonnefine=true; break;};
};
if (!bonnefine)
{cout << "\n erreur inconnue de syntaxe en lecture du temps maxi";
cout << "\n BlocCharge::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du temps maxi
{ string nomOuNombre;
*(entreePrinc.entree) >> nomOuNombre;
if (nomOuNombre != "fct_nD:")
{t_max = ChangeReel(nomOuNombre);
nom_fnD_t_max = "";fnD_t_max=NULL;
}
else
{*(entreePrinc.entree) >> nom_fnD_t_max;};
//*(entreePrinc.entree) >> t_max;
};
}; //-- fin du cas temps maxi
}
/// @} // end of group
/// @addtogroup Groupe_concernant_le_chargement
/// @{
///
/// affichage des infos
template
void BlocCharge::Affiche() const
{ // tout d'abord affichage des infos de la classe mère
Bloc_particulier::Affiche();
// puis des infos propres
cout << "\n nom_courbe_de_charge: " << co_charge << " echelle: " << echelle;
cout << " temps_mini= ";
if (nom_fnD_t_min == "")
{cout << t_min;}
else {cout << " fct_nD: " << nom_fnD_t_min ;};
cout << " temps_maxi= ";
if (nom_fnD_t_max == "")
{cout << t_max;}
else {cout << " fct_nD: " << nom_fnD_t_max ;};
cout << " activite_actuelle: " << precedent << " attribut: "<< attribut << endl
<< " f_charge: "<< f_charge;
}
/// @} // end of group
/// @addtogroup Groupe_concernant_le_chargement
/// @{
///
/// surcharge des operateurs
template
bool BlocCharge::operator == ( const BlocCharge& a) const
{ //if (!(((Bloc_particulier)(*this)) == ((const Bloc_particulier&)(a)) ))
if ( !(((Bloc_particulier&)(*this)).operator==(a)) )
return false;
else
{ if ((co_charge == a.co_charge) && (echelle == a.echelle)
&& (t_min == a.t_min )&& (t_max == a.t_max )&& (precedent == a.precedent )
&& (attribut == a.attribut) && (f_charge == a.f_charge)
&& (nom_fnD_t_min == a.nom_fnD_t_min) && (fnD_t_min == a.fnD_t_min)
&& (nom_fnD_t_max == a.nom_fnD_t_max) && (fnD_t_max == a.fnD_t_max)
)
return true;
else
return false;
}
}
/// @} // end of group
/// @addtogroup Groupe_concernant_le_chargement
/// @{
///
template
BlocCharge& BlocCharge::operator
= ( const BlocCharge& a)
{ // tout d'abord la classe mère
// ((Bloc_particulier)(*this)) = ((const Bloc_particulier&)(a));
// ((Bloc_particulier)(*this)) = a ;
((Bloc_particulier&)(*this)).operator=(a);
// puis les valeurs propres
co_charge = a.co_charge; echelle = a.echelle; t_min = a.t_min;
t_max = a.t_max; precedent = a.precedent;attribut = a.attribut;
f_charge = a.f_charge;
nom_fnD_t_min = a.nom_fnD_t_min ; fnD_t_min = a.fnD_t_min;
nom_fnD_t_max = a.nom_fnD_t_max ; fnD_t_max = a.fnD_t_max;
return *this;
}
/// @} // end of group
/// @addtogroup Groupe_concernant_le_chargement
/// @{
///
template
bool BlocCharge::operator
!= (const BlocCharge& a) const
{ return !(*this == a);}
/// @} // end of group
/// @addtogroup Groupe_concernant_le_chargement
/// @{
///
/// affichage et definition interactive des commandes
/// attrib : donne un attribut éventuel à afficher dans les choix
template
void BlocCharge::Info_commande_BlocCharge
(ofstream & sort,string attrib)
{ //On va proposer un menu
string rep=" ";
co_charge="_";
f_charge="_";
echelle = ConstMath::trespetit;
t_min = - ConstMath::trespetit;
t_max = ConstMath::tresgrand;
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
{
try
{ int nb_choix=5;//valeur par défaut
cout
<< "\n (0 ou f) (defaut) (fin) "
<< "\n (1) utilisation d'une courbe de charge "
<< "\n (2) fonction nD de charge "
<< "\n (3) echelle "
<< "\n (4) temps mini fixe "
<< "\n (5) temps maxi fixe "
<< "\n (6) temps mini via une fonction nD "
<< "\n (7) temps maxi via une fonction nD";
if (attrib != "_")
{cout << "\n (8) attribut: "<= 0)&&(num<=nb_choix))
{ choix_valide=true; }
else { cout << "\n Erreur on attendait un entier entre 0 et "<
bool BlocCharge::Mise_en_place_des_fonction_nD(const LesFonctions_nD& lesFonctionsnD)
{ bool retour = true;
// on regarde et on récupère s'il le faut la fct nD associée avec la résultante du torseur
if (nom_fnD_t_min.length())
{fnD_t_min = lesFonctionsnD.Trouve(nom_fnD_t_min);
if (fnD_t_min != NULL)
{// on vérifie qu'en retour on a un scalaire
if (fnD_t_min->NbComposante() != 1)
{cout << "\n *** erreur dans l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
<< " cas du calcul du temps mini"
<< " en retour, le nombre de composante"<< fnD_t_min->NbComposante()
<< " est different de 1 "
<< endl;
Sortie(1);
};
};
};
// on regarde et on récupère s'il le faut la fct nD associée avec la résultante du torseur
if (nom_fnD_t_max.length())
{fnD_t_max = lesFonctionsnD.Trouve(nom_fnD_t_max);
if (fnD_t_max != NULL)
{// on vérifie qu'en retour on a un scalaire
if (fnD_t_max->NbComposante() != 1)
{cout << "\n *** erreur dans l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
<< " cas du calcul du temps maxi"
<< " en retour, le nombre de composante"<< fnD_t_max->NbComposante()
<< " est different de 1 "
<< endl;
Sortie(1);
};
};
};
// puis on appelle la fonction membre identique
retour = retour && Bloc_particulier::Mise_en_place_des_fonction_nD(lesFonctionsnD);
return retour;
};
/// @} // end of group
#endif