Herezh_dev/Chargement/BlocCharge.cc
2023-05-03 17:23:49 +02:00

1248 lines
50 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/>.
#include "BlocCharge.h"
#include "ConstMath.h"
#include "CharUtil.h"
#include "Util.h"
#include <limits>
//================================================
// cas d'un bloc scalaire type
//================================================
// un bloc scalaire type correspond a une reference
// un mot cle, et une seule valeur
// Constructeur
BlocScalVecTypeCharge::BlocScalVecTypeCharge () : // par defaut
BlocGeneEtVecMultType(0,1) // 0 vecteur et 1 scalaire
,champ(false)
{
};
// avec : n: le nombre de vecteurs, m le nombre de scalaires , n le nombre de ptnom
BlocScalVecTypeCharge::BlocScalVecTypeCharge(int n,int m)
: BlocGeneEtVecMultType(n,m),champ(false)
{};
BlocScalVecTypeCharge::BlocScalVecTypeCharge (const BlocScalVecTypeCharge& a) : // de copie
BlocGeneEtVecMultType(a),champ(a.champ)
{
};
// lecture d'un bloc
void BlocScalVecTypeCharge::Lecture(UtilLecture & entreePrinc)
{
// tout d'abord les cas particuliers
if (strstr(entreePrinc.tablcar,"champ_de_valeurs:")!=NULL)
// on regarde si c'est un champ de valeur c'est-à-dire une valeur par item de la ref
// dans ce cas appel de la procédure a doc
{ BlocGeneEtVecMultType::Lecture_entete(entreePrinc);
Lecture_champ_de_valeurs(entreePrinc);
champ = 1;
}
else if (strstr(entreePrinc.tablcar,"champ_de_fonctions:")!=NULL)
{ BlocGeneEtVecMultType::Lecture_entete(entreePrinc);
Lecture_champ_de_fonctions(entreePrinc);
champ = 2;
}
else // sinon cas d'une simple valeur
// lecture de la classe mère
{ BlocGeneEtVecMultType::Lecture(entreePrinc);
champ = 0;
};
};
//--------------- méthodes protégées ------
// lecture dans le cas particulier d'un champ de valeurs
void BlocScalVecTypeCharge::Lecture_champ_de_valeurs(UtilLecture & entreePrinc)
{// si initialement on a un vecteur ce sera un champ de vecteur à lire
// idem si c'est un scalaire
int dima = ParaGlob::Dimension();
if (DimVect() == 0)
// cas d'un champ de scalaire
{ list <double> lili; // une liste de travail
// on va lire tant que l'on n'aura pas trouvé le mot clé de fin de champ
entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
while (strstr(entreePrinc.tablcar,"fin_champ_de_valeurs:")==NULL)
{ double grandeur;
*(entreePrinc.entree) >> grandeur;
// on contrôle le flux
if ((entreePrinc.entree)->rdstate() == 0)
// pour mémoire ici on a
/* enum io_state
{ badbit = 1<<0, // -> 1 dans rdstate()
eofbit = 1<<1, // -> 2
failbit = 1<<2, // -> 4
goodbit = 0 // -> O
};*/
{lili.push_back(grandeur); }// lecture normale
#ifdef ENLINUX
else if ((entreePrinc.entree)->fail())
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
{ entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
*(entreePrinc.entree) >> grandeur;
lili.push_back(grandeur); // lecture normale
}
#else
else if ((entreePrinc.entree)->eof())
// la lecture est bonne mais on a atteind la fin de la ligne
{ lili.push_back(grandeur); // lecture
entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
}
#endif
else // cas d'une erreur de lecture
{ cout << "\n erreur de lecture inconnue ";
entreePrinc.MessageBuffer("** lecture champ de chargement **");
cout << "\n BlocScalVecTypeCharge::Lecture_champ_de_valeurs(..." << endl;
Sortie (1);
};
};
BlocGeneEtVecMultType::Change_tab_val(lili);
}
else
// cas d'un champ de vecteur
{ list <Coordonnee> lico; // une liste de travail
// on va lire tant que l'on n'aura pas trouvé le mot clé de fin de champ
entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
Coordonnee coo(dima); // variable de travail
while (strstr(entreePrinc.tablcar,"fin_champ_de_valeurs:")==NULL)
{ coo.Lecture(entreePrinc);
// on contrôle le flux
if ((entreePrinc.entree)->rdstate() == 0)
// pour mémoire ici on a
/* enum io_state
{ badbit = 1<<0, // -> 1 dans rdstate()
eofbit = 1<<1, // -> 2
failbit = 1<<2, // -> 4
goodbit = 0 // -> O
};*/
{lico.push_back(coo); }// lecture normale
#ifdef ENLINUX
else if ((entreePrinc->entree)->fail())
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
{ entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
coo.Lecture(entreePrinc);
lico.push_back(coo); // lecture normale
}
#else
else if ((entreePrinc.entree)->eof())
// la lecture est bonne mais on a atteind la fin de la ligne
{ lico.push_back(coo); // lecture
entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
}
#endif
else // cas d'une erreur de lecture
{ cout << "\n erreur de lecture inconnue ";
entreePrinc.MessageBuffer("** lecture champ de chargement **");
cout << "\n BlocScalVecTypeCharge::Lecture_champ_de_valeurs(..." << endl;
Sortie (1);
};
};
BlocGeneEtVecMultType::Change_vect_coorpt(lico);
};
};
// lecture dans le cas particulier d'un champ de fonctions
void BlocScalVecTypeCharge::Lecture_champ_de_fonctions(UtilLecture & entreePrinc)
{ // en attente pour l'instant
cout << "\n **** pour l'instant la methode : "
<< " BlocScalVecTypeCharge::Lecture_champ_de_fonctions(..."
<< " n'est pas implemente ! "<< endl;
};
// affichage des infos
void BlocScalVecTypeCharge::Affiche() const
{ // tout d'abord affichage des infos de la classe mère
BlocGeneEtVecMultType::Affiche();
// puis les valeurs propres
cout << "\n champ: " << champ << endl;
};
BlocScalVecTypeCharge& BlocScalVecTypeCharge::operator = ( const BlocScalVecTypeCharge& a)
{ // tout d'abord la classe mère
// pour être sûr de ne pas utiliser le constructeur
const BlocGeneEtVecMultType& b = *((const BlocGeneEtVecMultType*) & a);
// une addition de l'opérateur du bloc BlocGeneEtVecMultType
// en fait cela marche en remplaçant b par a directement
this->BlocGeneEtVecMultType::operator=(b);
// puis les valeurs propres
champ = a.champ;
return *this;
};
istream & operator >> (istream & entree, BlocScalVecTypeCharge & coo)
{ // tout d'abord la classe mère
entree >> ((BlocGeneEtVecMultType&)(coo));
// puis les valeurs propres
string toto;
entree >> toto >> coo.champ ;
return entree;
};
ostream & operator << ( ostream & sort,const BlocScalVecTypeCharge & coo)
{ // tout d'abord la classe mère
sort << ((BlocGeneEtVecMultType&)(coo));
// puis les valeurs propres
sort << "\n champ: " << coo.champ << endl;
return sort;
};
//------------ cas des torseurs de forces ponctuelles ------------
istream & operator >> (istream & entree, PTorseurPonct & a)
{ entree >> ((BlocGen&)(a));
string nom;string mot_cle;
entree >> nom >> a.Re >> nom >> a.Mo;
// lecture éventuelle d'une fonction nD sur la résultante
entree >> nom >> mot_cle;
if (mot_cle != "_") {a.nom_fnD_Re = mot_cle;}
else {a.nom_fnD_Re = "";a.fnD_Re=NULL;}
// idem pour le moment
entree >> nom >> mot_cle;
if (mot_cle != "_") {a.nom_fnD_Mo = mot_cle;}
else {a.nom_fnD_Mo = "";a.fnD_Mo=NULL;}
// le centre
entree >> nom >> a.type_centre;
switch (a.type_centre)
{case 1: {entree >> nom;a.nom_fnD_Ce = "";a.fnD_Ce=NULL; break;}
case 2: {entree >> nom >> a.nom_fnD_Ce; break;}
case 3: {entree >> nom >> a.nom_mail_ref_pour_Ce
>> nom >> a.num_noeud ;
break;
}
case 4: {entree >> nom >> mot_cle >> a.nom_mail_ref_pour_Ce
>> nom >> a.nom_ref_pour_Ce;
break;
}
default: break;
};
// fonction poids
entree >> nom >> mot_cle;
if (mot_cle != "_") {a.nom_fnD_poids = mot_cle;}
else {a.nom_fnD_poids = "";a.fnD_poids=NULL;}
return entree;
};
// surcharge de l'operator d'ecriture
ostream & operator << (ostream & sort, const PTorseurPonct & a)
{ sort << ((const BlocGen&)(a));
sort << "\n TORSEUR_PONCT__Re= " << a.Re << " Mo= " << a.Mo;
if (a.nom_fnD_Re.length())
{sort << " nom_fnD_Re= "<< a.nom_fnD_Re << " ";}
else {sort << " nom_fnD_Re= _ ";};
// idem pour le moment
if (a.nom_fnD_Mo.length())
{sort << " nom_fnD_Mo= " << a.nom_fnD_Mo;}
else {sort << " nom_fnD_Mo= _ ";};
// le centre
sort << " type_centre= " << a.type_centre;
switch (a.type_centre)
{case 1: sort << " centre_fixe: "; break;
case 2: {sort << " Fonction_nD_centre_: "
<< " nom_fnD_Ce= " << a.nom_fnD_Ce;
break;
}
case 3: {sort << " centre_noeud:_nom_mail_ref_pour_Ce= "
<< a.nom_mail_ref_pour_Ce
<< " num_noeud= " << a.num_noeud ;
break;
}
case 4: {sort << " centre_de_gravite_d'un_groupe_de_noeuds: "
<< " nom_mail_ref_pour_Ce= " << a.nom_mail_ref_pour_Ce
<< " nom_ref_pour_Ce= " << a.nom_ref_pour_Ce;
break;
}
default: break;
};
if (a.nom_fnD_poids.length())
{sort << " nom_fnD_poids= " << a.nom_fnD_poids;}
else {sort << " nom_fnD_poids= _ ";};
return sort;
};
//Constructeur par défaut
PTorseurPonct::PTorseurPonct() :
BlocGen(1,0) // 1 nom = nom de la ref
,Re(ParaGlob::Dimension()),nom_fnD_Re(""),fnD_Re(NULL)
,Mo(ParaGlob::Dimension()),nom_fnD_Mo(""),fnD_Mo(NULL)
,Ce(ParaGlob::Dimension()),fnD_Ce(NULL),nom_fnD_Ce("")
,noe_Ce(NULL),temps_noe_Ce(TEMPS_0),nom_ref_pour_Ce("")
,nom_mail_ref_pour_Ce(""),tab_noe_ref_centre(),type_centre(1)
,nom_fnD_poids(""),fnD_poids(NULL),t_poids(),t_vec()
{};
// constructeur de copie
PTorseurPonct::PTorseurPonct (const PTorseurPonct & a):
BlocGen(a) // 1 nom = nom de la ref
,Re(a.Re),nom_fnD_Re(a.nom_fnD_Re),fnD_Re(a.fnD_Re),Mo(a.Mo),nom_fnD_Mo(a.nom_fnD_Mo)
,fnD_Mo(a.fnD_Mo),Ce(a.Ce),fnD_Ce(a.fnD_Ce),nom_fnD_Ce(a.nom_fnD_Ce)
,noe_Ce(a.noe_Ce),temps_noe_Ce(a.temps_noe_Ce),nom_ref_pour_Ce(a.nom_ref_pour_Ce)
,nom_mail_ref_pour_Ce(a.nom_mail_ref_pour_Ce)
,tab_noe_ref_centre(a.tab_noe_ref_centre),type_centre(a.type_centre)
,nom_fnD_poids(a.nom_fnD_poids),fnD_poids(a.fnD_poids),t_poids(a.t_poids),t_vec()
{};
// surcharge d'affectation
PTorseurPonct& PTorseurPonct::operator = (const PTorseurPonct& a)
{ BlocGen* b = ((BlocGen* ) this);
// const Tenseur3BB & epsBB = *((Tenseur3BB*) &epsBB_tdt); // passage en dim 3
(*b) = a; // affectation des grandeurs de bloc gen
Re = a.Re; nom_fnD_Re = a.nom_fnD_Re; fnD_Re = a.fnD_Re; Mo = a.Mo; nom_fnD_Mo = a.nom_fnD_Mo;
fnD_Mo = a.fnD_Mo; Ce = a.Ce; fnD_Ce = a.fnD_Ce; nom_fnD_Ce = a.nom_fnD_Ce;
noe_Ce = a.noe_Ce; temps_noe_Ce = a.temps_noe_Ce; nom_ref_pour_Ce = a.nom_ref_pour_Ce;
nom_mail_ref_pour_Ce = a.nom_mail_ref_pour_Ce;
tab_noe_ref_centre = a.tab_noe_ref_centre; type_centre = a.type_centre;
nom_fnD_poids=a.nom_fnD_poids;fnD_poids = a.fnD_poids;
t_poids.Change_taille(a.t_poids.Taille());
t_vec.Change_taille(a.t_vec.Taille());
return *this;
};
// surcharge de l'operateur d'égalité
bool PTorseurPonct::operator == (const PTorseurPonct& a) const
{ BlocGen* b = ((BlocGen* ) this);
if ( ((*b) == a)
&& (Re == a.Re) && (nom_fnD_Re == a.nom_fnD_Re) && (fnD_Re == a.fnD_Re) && (Mo == a.Mo)
&& (nom_fnD_Mo == a.nom_fnD_Mo) && (fnD_Mo == a.fnD_Mo) && (Ce == a.Ce) && (fnD_Ce == a.fnD_Ce)
&& (nom_fnD_Ce == a.nom_fnD_Ce) && (noe_Ce == a.noe_Ce) && (temps_noe_Ce == a.temps_noe_Ce)
&& (nom_fnD_poids == a.nom_fnD_poids)&&(fnD_poids == a.fnD_poids)
&& (nom_ref_pour_Ce == a.nom_ref_pour_Ce) && (nom_mail_ref_pour_Ce == a.nom_mail_ref_pour_Ce)
&& (tab_noe_ref_centre == a.tab_noe_ref_centre) && (type_centre == a.type_centre)
)
return true;
else
return false;
};
// lecture d'un bloc
void PTorseurPonct::Lecture(UtilLecture & entreePrinc)
{ BlocGen* b = ((BlocGen* ) this);
// on commence par lire le bloc gen, ce qui correspondra à la ref
b->Lecture(entreePrinc);
// arrivée ici le nom de maillage puis celui de la ref sont lue
// lecture du mot clé
string nom_charge;
string nom_class_methode(" PTorseurPonct::Lecture(");
string mot_cle("TORSEUR_PONCT");
// lecture et passage d'un mot clé: il y a simplement vérification que c'est le bon mot clé qui est lue
// ramène si oui ou non le mot clé à été lue
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
//------- lecture de la résultante ----
// idem pour le mot clé R=
mot_cle="Re=";
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
// maintenant on fait le choix entre valeur ou fonction nD
if (strstr(entreePrinc.tablcar,"Fonction_nD_Re:")!=NULL)
{// cas d'une fonction nD, 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_Re:"){bonnefin4=true; break;};
};
if (!bonnefin4)
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD pour la resultante ";
cout << "\n PTorseurPonct::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du nom de la fonction nD
{ *(entreePrinc.entree) >> nom_fnD_Re; };
} //-- fin récup de la fonction de charge
else // sinon on lit directement les coordonnées de la résultante
{ Re.Lecture(entreePrinc);};
//------- lecture du moment ----
// idem pour le mot clé M=
mot_cle="Mo=";
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
// maintenant on fait le choix entre valeur ou fonction nD
if (strstr(entreePrinc.tablcar,"Fonction_nD_Mo:")!=NULL)
{// cas d'une fonction nD, 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_Mo:"){bonnefin4=true; break;};
};
if (!bonnefin4)
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD pour le moment ";
cout << "\n PTorseurPonct::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du nom de la fonction nD
{ *(entreePrinc.entree) >> nom_fnD_Mo; };
} //-- fin récup de la fonction de charge
else // sinon on lit directement les coordonnées du moment
{ Mo.Lecture(entreePrinc);};
//------- lecture du centre ----
// idem pour le mot clé centre_=
mot_cle="centre_=";
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
// maintenant on fait le choix entre valeur, fonction nD, noeud, groupe de noeud
// 1) cas d'une fonction nD décrivant le centre
if (strstr(entreePrinc.tablcar,"Fonction_nD_centre_:")!=NULL)
{// cas d'une fonction nD, 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_centre_:"){bonnefin4=true; break;};
};
if (!bonnefin4)
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD pour le centre d'application du moment ";
cout << "\n PTorseurPonct::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du nom de la fonction nD
{ *(entreePrinc.entree) >> nom_fnD_Ce; };
type_centre = 2;
} //-- fin récup de la fonction de charge
// 2) cas d'un noeud décrivant le centre
else if (strstr(entreePrinc.tablcar,"centre_noeud_=")!=NULL)
{ // cas d'un centre donné par un numero de noeud
mot_cle="centre_noeud_=";
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
string nom_mail;
*(entreePrinc.entree) >> nom_mail;
if (nom_mail == "nom_mail=")
{ // cas où il y a un nom de maillage
*(entreePrinc.entree) >> nom_mail_ref_pour_Ce; // lecture du nom
*(entreePrinc.entree) >> num_noeud; // lecture du numero de noeud
}
else
{ // sinon cela veut dire que l'on vient de lire un numéro de noeud du premier maillage
nom_mail_ref_pour_Ce = "";
num_noeud = ChangeEntier(nom_mail);
};
// puis on lit le temps pour lequel on considère les coordonnées du noeud:
string dure;
*(entreePrinc.entree) >> dure;
temps_noe_Ce = Id_nom_dure (dure);
type_centre = 3;
}
// 3) cas du centre de gravité d'une ref de noeuds
else if (strstr(entreePrinc.tablcar,"centre_gravite_ref_=")!=NULL)
{ // cas d'un centre donné par un centre de gravité d'une ref de noeuds
mot_cle="centre_gravite_ref_=";
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
string nom_mail;
*(entreePrinc.entree) >> nom_mail;
if (nom_mail == "nom_mail=")
{ // cas où il y a un nom de maillage
*(entreePrinc.entree) >> nom_mail_ref_pour_Ce; // lecture du nom
*(entreePrinc.entree) >> nom_ref_pour_Ce; // lecture du nom de la ref de noeud
}
else
{ // sinon cela veut dire que l'on vient de lire la référence de noeud du premier maillage
nom_mail_ref_pour_Ce = "";
nom_ref_pour_Ce = nom_mail;
};
// puis on lit le temps pour lequel on considère les coordonnées du noeud:
string dure;
*(entreePrinc.entree) >> dure;
temps_noe_Ce = Id_nom_dure (dure);
type_centre = 4;
}
// 4) cas du centre de gravité fixe
else // on lit directement les coordonnées
{ Ce.Lecture(entreePrinc);
type_centre=1;
};
//------- lecture d'une fonction poids éventuelle moment ----
if (strstr(entreePrinc.tablcar,"Fonction_nD_Poids:")!=NULL)
{// cas d'une fonction nD, 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_Poids:"){bonnefin4=true; break;};
};
if (!bonnefin4)
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD pour la repartition de poids ";
cout << "\n PTorseurPonct::Lecture(.. " << endl ;
entreePrinc.MessageBuffer("**erreur**");
throw (UtilLecture::ErrNouvelleDonnee(-1));
Sortie(1);
}
else
//lecture du nom de la fonction nD
{ *(entreePrinc.entree) >> nom_fnD_poids; };
} //-- fin récup de la fonction de charge
else // sinon on vide le nom
{ nom_fnD_poids="";};
//nom_mail= petit_prisme N_bas_arriere TORSEUR_PONCT Re= 10 0 0 \
// Mo= 0 0 0 centre_= 45 45 1070
};
// mise en place de l'association des fonctions nD, dont ensuite on garde un pointeur
// en retour indique si l'association est ok
bool PTorseurPonct::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_Re.length())
{fnD_Re = lesFonctionsnD.Trouve(nom_fnD_Re);
int dima = ParaGlob::Dimension();
if (fnD_Re != NULL)
{// on vérifie qu'en retour on a un vecteur de dimension = la dimension de l'espace
if (fnD_Re->NbComposante() != dima)
{cout << "\n *** erreur dans l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
<< " cas du calcul de la resultante d'un torseur"
<< " en retour, le nombre de composante"<< fnD_Re->NbComposante()
<< " est different de la dimension de l'espace : "
<< dima << endl;
Sortie(1);
};
};
};
// idem pour le moment
if (nom_fnD_Mo.length())
{fnD_Mo = lesFonctionsnD.Trouve(nom_fnD_Mo);
int dima = ParaGlob::Dimension();
if (fnD_Mo != NULL)
{// on vérifie qu'en retour on a un vecteur de dimension = la dimension de l'espace
if (fnD_Mo->NbComposante() != dima)
{cout << "\n *** erreur dans l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
<< " cas du calcul du moment d'un torseur"
<< " en retour, le nombre de composante"<< fnD_Mo->NbComposante()
<< " est different de la dimension de l'espace : "
<< dima << endl;
Sortie(1);
};
};
};
// idem pour le centre
if (nom_fnD_Ce.length())
{fnD_Ce = lesFonctionsnD.Trouve(nom_fnD_Ce);
int dima = ParaGlob::Dimension();
if (fnD_Ce != NULL)
{// on vérifie qu'en retour on a un vecteur de dimension = la dimension de l'espace
if (fnD_Ce->NbComposante() != dima)
{cout << "\n *** erreur dans l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
<< " cas du calcul du centre d'un torseur"
<< " en retour, le nombre de composante"<< fnD_Ce->NbComposante()
<< " est different de la dimension de l'espace : "
<< dima << endl;
Sortie(1);
};
};
if ( (type_centre == 1) // 1 c'est la valeur par défaut
||(type_centre == 2)
)
{type_centre = 2;}
else // cas pb
{cout << "\n erreur de definition du centre de calcul du moment (torseur ponctuel) ";
cout << " le centre a deja ete defini comme :";
switch (type_centre)
{case 3: cout << " centre noeud "; break;
case 4: cout << " centre de gravite d'un groupe de noeuds "; break;
default: break;
};
retour=false;
};
};
if (nom_fnD_poids.length())
{fnD_poids = lesFonctionsnD.Trouve(nom_fnD_poids);
if (fnD_poids != NULL)
{// on vérifie qu'en retour on a un vecteur de dimension = 1
if (fnD_poids->NbComposante() != 1)
{cout << "\n *** erreur dans l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
<< " cas du calcul des poids aux points, pour le centre de gravite d'un torseur"
<< " en retour, le nombre de composante"<< fnD_poids->NbComposante()
<< " est different de 1 ! " << endl;
Sortie(1);
};
};
};
// la méthode de la fonction mère n'existe pas donc rien d'autre à faire
return retour;
};
// mise en place des infos pour le centre si celui-ci dépend des noeuds
// en retour indique si c'est ok
bool PTorseurPonct::Def_tab_noeud_pour_centre(const list <const Noeud * > li_noe_ref_centre)
{bool retour = true;
// on initialise à partir de la liste
tab_noe_ref_centre.Init_from_list(li_noe_ref_centre);
int nbn = tab_noe_ref_centre.Taille();
t_poids.Change_taille(nbn);
t_vec.Change_taille(nbn);
if ((type_centre == 2) && (tab_noe_ref_centre.Taille() != 0))
{cout << "\n erreur de definition du centre de calcul du moment (torseur ponctuel) ";
cout << " le centre a deja ete defini comme : fonction nD ";
retour=false;
}
else if (tab_noe_ref_centre.Taille() != 0)
{if (tab_noe_ref_centre.Taille()==1)
{ type_centre = 3;
noe_Ce=tab_noe_ref_centre(1);
}
else
{ type_centre = 4;};
};
return retour;
};
// calcul éventuel et retour de la résultante (qui peut varier)
// M: indique un point dont peut dépendre les éléments du torseur
Coordonnee& PTorseurPonct::Resultante(const Coordonnee& M )
{int dima = ParaGlob::Dimension();
if (fnD_Re != NULL)
{if (fnD_Re->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
{ Tableau <double> & tava = fnD_Re->Valeur_pour_variables_globales(); // pour simplifier
switch (dima)
{ case 3 : Re(3) = tava(3);
case 2 : Re(2) = tava(2);
case 1 : Re(1) = tava(1);
};
}
else if (fnD_Re->Depend_M() != 0) // signifie qu'il y a une dépendance au point M
{ if (fnD_Re->Depend_M()<0)
{// comme pt_fonct->Depend_M()<0, cela signifie que la fonction dépend que de M
// donc dans les paramètres d'appel on ne transmet que M
Tableau <Coordonnee> tab_M(1,M);
Tableau <double> & tava = fnD_Re->Val_FnD_Evoluee(NULL,&tab_M,NULL); // pour simplifier
switch (dima)
{ case 3 : Re(3) = tava(3);
case 2 : Re(2) = tava(2);
case 1 : Re(1) = tava(1);
};
}
else
{ if ((fnD_Re->Depend_M()>0)|| fnD_Re->Nom_variables().Taille() != dima)
{cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisant les coordonnees du point"
<< " cas du calcul de la resultante d'un torseur"
<< " actuellement la fonction doit avoir uniquement comme parametres, les coordonnees du point et/ou eventuellement des variables globales ";
cout << "\n fonction nD: "; fnD_Re->Affiche();this->Affiche();
Sortie(1);
};
};
}
};
return Re;
};
// calcul éventuel et retour du moment (qui peut varier)
// M: indique un point dont peut dépendre les éléments du torseur
Coordonnee& PTorseurPonct::Moment(const Coordonnee& M )
{int dima = ParaGlob::Dimension();
if (fnD_Mo != NULL)
{if (fnD_Mo->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
{ Tableau <double> & tava = fnD_Mo->Valeur_pour_variables_globales(); // pour simplifier
switch (dima)
{ case 3 : Mo(3) = tava(3);
case 2 : Mo(2) = tava(2);
case 1 : Mo(1) = tava(1);
};
}
else if (fnD_Mo->Depend_M() != 0) // signifie qu'il y a une dépendance au point M
{ if (fnD_Mo->Depend_M()<0)
{// comme pt_fonct->Depend_M()<0, cela signifie que la fonction dépend que de M
// donc dans les paramètres d'appel on ne transmet que M
Tableau <Coordonnee> tab_M(1,M);
Tableau <double> & tava = fnD_Mo->Val_FnD_Evoluee(NULL,&tab_M,NULL); // pour simplifier
switch (dima)
{ case 3 : Mo(3) = tava(3);
case 2 : Mo(2) = tava(2);
case 1 : Mo(1) = tava(1);
};
}
else
{ if ((fnD_Mo->Depend_M()>0)|| fnD_Mo->Nom_variables().Taille() != dima)
{cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisant les coordonnees du point"
<< " cas du calcul du moment d'un torseur"
<< " actuellement la fonction doit avoir uniquement comme parametres, les coordonnees du point et eventuellement des variables globales ";
cout << "\n fonction nD: "; fnD_Mo->Affiche();this->Affiche();
Sortie(1);
};
};
}
};
return Mo;
};
// calcul éventuel et retour du centre du moment (qui peut varier)
// M: indique un point dont peut dépendre les éléments du torseur
Coordonnee& PTorseurPonct::Centre( )
{ int dima = ParaGlob::Dimension();
switch (type_centre)
{case 1: break; // rien n'a faire
case 2: // cas d'une fonction nD
{if (fnD_Ce->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
{ Tableau <double> & tava = fnD_Ce->Valeur_pour_variables_globales(); // pour simplifier
switch (dima)
{ case 3 : Ce(3) = tava(3);
case 2 : Ce(2) = tava(2);
case 1 : Ce(1) = tava(1);
};
}
else
{cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisant les coordonnees du point"
<< " cas du calcul du centre d'un torseur"
<< " actuellement la fonction doit avoir uniquement comme parametres des variables globales ";
cout << "\n fonction nD: "; fnD_Ce->Affiche();this->Affiche();
Sortie(1);
};
break;
}
case 3: // cas ou il s'agit d'un noeud
{switch (temps_noe_Ce)
{case TEMPS_0: Ce=noe_Ce->Coord0(); break;
case TEMPS_t: Ce=noe_Ce->Coord1(); break;
case TEMPS_tdt: Ce=noe_Ce->Coord2(); break;
default:
break;
};
break;
}
case 4: // cas d'un centre de gravité
{ // on itère sur les noeuds du tableau
Ce.Zero(); // init
int nb_noe = tab_noe_ref_centre.Taille();
switch (temps_noe_Ce)
{case TEMPS_0:
{ for (int i=1;i<= nb_noe; i++)
Ce += tab_noe_ref_centre(i)->Coord0();
// on moyenne
Ce /= nb_noe;
break;
}
case TEMPS_t:
{ for (int i=1;i<= nb_noe; i++)
Ce += tab_noe_ref_centre(i)->Coord1();
// on moyenne
Ce /= nb_noe;
break;
}
case TEMPS_tdt:
{ for (int i=1;i<= nb_noe; i++)
Ce += tab_noe_ref_centre(i)->Coord2();
// on moyenne
Ce /= nb_noe;
break;
}
default:
break;
};
break;
}
default: break;
};
// retour
return Ce;
};
// affichage des informations
void PTorseurPonct::Affiche() const
{ cout << "\n TORSEUR_PONCT Re= " << Re << " Mo= " << Mo;
if (ParaGlob::NiveauImpression() > 3)
{ cout << "\n";
if (nom_fnD_Re.length())
cout << "\n nom_fnD_Re= "<< nom_fnD_Re << " ";
// idem pour le moment
if (nom_fnD_Mo.length())
cout << " nom_fnD_Mo= " << nom_fnD_Mo;
switch (type_centre)
{case 1: cout << " centre_fixe: "; break;
case 2: {cout << " Fonction_nD_centre_: "
<< " nom_fnD_Ce= " << nom_fnD_Ce;
break;
}
case 3: {cout << " centre_noeud: nom_mail_ref_pour_Ce= "
<< nom_mail_ref_pour_Ce
<< " num_noeud= " << num_noeud ;
break;
}
case 4: {cout << " centre_de_gravite_d'un_groupe_de_noeuds: "
<< " nom_mail_ref_pour_Ce= " << nom_mail_ref_pour_Ce
<< " nom_ref_pour_Ce= " << nom_ref_pour_Ce;
break;
}
default: break;
};
if (nom_fnD_poids.length())
cout << " nom_fnD_poids= " << nom_fnD_poids;
};
};
// calcul de l'effort ponctuelle correspondant au torseur
// pour la position passée en paramètres
// M: indique un point dont peut dépendre les éléments du torseur
// tab_P: tableau des points où sont exprimés les forces équivalentes au torseur
// t_force : tableau des forces calculées, équivalentes au torseur
void PTorseurPonct::Force(const Tableau <Coordonnee >& tab_P, Tableau <Coordonnee >& t_force)
{ // on commence par calculer le centre du torseur
// utile uniquement s'il varie
//--- debug
//cout << "\n debug PTorseurPonct::Force(.."
// << "\n Re= "<< Re << " Mo= "<< Mo
// << "\n tab_P= "<< tab_P
// << flush;
//--- fin debug
Centre();
//--- debug
//cout << "\n Ce= "<< Ce << flush;
//--- fin debug
// puis la résultante et le moment qui peuvent dépendre du centre
Resultante(Ce);
Moment(Ce);
// traitement du cas particulier d'un seul point
int nb_Pi = tab_P.Taille();
if (nb_Pi==1)
{// ici on a qu'un seul point
// -> le centre G = le point
// par rapport à G, on ne peut pas avoir de moment
// la résultante ne peut qu'être transférée telle quelle
// la répartition ne sert à rien
Coordonnee& G = tab_P(1); // le centre de gravité = le seul point
Coordonnee CG (G-Ce);
// on transfert le moment en G
Coordonnee MG = Mo - Util::ProdVec_coor(CG,Re);
// il faut que le moment soit nul
double M_G = MG.Norme();
if (M_G > ConstMath::petit)
{cout << "\n *** erreur dans le calcul de la repartition du moment d'un torseur d'action,"
<< " ici il n'y a qu'un point, et le moment en se point n'est pas nul, MG= " << MG
<< " le transfert n'est pas possible!! ";
this->Affiche();
Sortie(1);
};
// calcul des résultantes individuelles correspondant uniquement à Re
t_force(1) = Re;
}
else // la suite concerne le cas avec plusieurs points
{int dima = ParaGlob::Dimension();
Coordonnee G(dima);
t_force.Change_taille(nb_Pi);
double poids_total = 0.; // init
if (fnD_poids == NULL)
// si on n'a pas de fonction de répartition, cela signifie que les poids sont tous = 1
{for (int i =1; i<= nb_Pi; i++)
{Coordonnee& tab_P_i = tab_P(i);
t_force(i) = Re ; // première partie du calcul de force
G += tab_P_i ;
poids_total += 1.;
};
// d'où
double alpha = 1./poids_total;
G *= alpha; // le centre de gravité
//--- debug
//cout << "\n debug PTorseurPonct::Force(.."
// << "\n Re= "<< Re << " Mo= "<< Mo
// << "\n centre G= "<< G << flush;
//--- fin debug
Coordonnee CG (G-Ce);
// on transfert le moment en G
Coordonnee MG = Mo - Util::ProdVec_coor(CG,Re);
//--- debug
//cout << "\n moment MG= "<< MG << flush;
//--- fin debug
// calcul des résultantes individuelles correspondant uniquement à Re
for (int i =1; i<= nb_Pi; i++)
{ t_force(i) *= alpha;};
// si le moment n'est pas nul on calcule les moments individuels
double M_G = MG.Norme();
t_vec.Change_taille(nb_Pi);
if (M_G > ConstMath::petit)
{ Coordonnee m = MG/M_G;
Coordonnee GPi,GPpi; // variables de travail
double mom_quad = 0.;
for (int i =1; i<= nb_Pi; i++)
{ Coordonnee& tab_P_i = tab_P(i);
GPi = tab_P_i - G;
GPpi = GPi - (GPi * m) * m;
double GPpi2 = GPpi * GPpi;
mom_quad += GPpi2 ;
// si la norme de GPpi est trop petite, la force individuelle
// ne pourra pas contribuer au moment
t_vec(i) = Util::ProdVec_coor(GPpi,m);
};
// si le moment quadratique est nul on ne peut pas équilibrer le moment
if (mom_quad < ConstMath::petit)
{cout << "\n *** erreur dans le calcul de la repartition du moment d'un torseur d'action,"
<< " vers des forces ponctuelles"
<< " le moment quadratique est nul, on ne peut pas equilibrer le moment actuel MG= " << MG ;
this->Affiche();
Sortie(1);
};
double beta = M_G / mom_quad ; // si diff de 0.
// on calcule la part due au moment, répartie sur les points
for (int i =1; i<= nb_Pi; i++)
t_force(i) -= (beta ) * t_vec(i);
}
} // fin du cas où il n'y a pas de fonction de poids
else // cas avec une fonction de répartition de poids
{int dimPlus1 = 1+ParaGlob::Dimension();
Tableau <double> tab_d(dimPlus1);
double& CP_i = tab_d(1); // pour simplifier
for (int i =1; i<= nb_Pi; i++)
{Coordonnee& tab_P_i = tab_P(i);
Coordonnee CPi = tab_P_i - Ce;
for (int j=1;j<dimPlus1;j++)
tab_d(j+1) = CPi(j);
double CP_i_2 = CPi * CPi;
CP_i = sqrt(CP_i_2);
Tableau <double> & tava = fnD_poids->Valeur_FnD_tab_scalaire(&tab_d);
//Val_FnD_Evoluee(&tab_d,NULL,NULL); // pour simplifier
double f_opi = t_poids(i)= Dabs(tava(1));
//--- debug
//cout << "\n poids( "<< i << ")= " << f_opi << " r= " << tab_d(1) << flush;
//--- fin debug
t_force(i) = Re * f_opi; // première partie du calcul de force
G += tab_P(i) * f_opi;
poids_total += f_opi;
};
// d'où
double alpha = 1./poids_total;
G *= alpha; // le centre de gravité
Coordonnee CG (G-Ce);
// on transfert le moment en G
Coordonnee MG = Mo - Util::ProdVec_coor(CG,Re);
// calcul des résultantes individuelles correspondant uniquement à Re
for (int i =1; i<= nb_Pi; i++)
{ t_force(i) *= alpha;};
// si le moment n'est pas nul on calcule les moments individuels
double M_G = MG.Norme();
if (M_G > ConstMath::petit)
{ Coordonnee m = MG/M_G;
Coordonnee GPi,GPpi; // variables de travail
double mom_quad = 0.;
for (int i =1; i<= nb_Pi; i++)
{ Coordonnee& tab_P_i = tab_P(i);
GPi = tab_P_i - G;
GPpi = GPi - (GPi * m) * m;
double GPpi2 = GPpi * GPpi;
mom_quad += GPpi2 * t_poids(i);
// si la norme de GPpi est trop petite, la force individuelle
// ne pourra pas contribuer au moment
t_vec(i) = Util::ProdVec_coor(GPpi,m);
};
// si le moment quadratique est nul on ne peut pas équilibrer le moment
if (mom_quad < ConstMath::petit)
{cout << "\n *** erreur dans le calcul de la repartition du moment d'un torseur d'action,"
<< " vers des forces ponctuelles"
<< " le moment quadratique est nul, on ne peut pas equilibrer le moment actuel MG= " << MG ;
this->Affiche();
Sortie(1);
};
double beta = M_G / mom_quad ; // si diff de 0.
// on calcule la part due au moment, répartie sur les points
for (int i =1; i<= nb_Pi; i++)
t_force(i) -= (beta * t_poids(i)) * t_vec(i);
};
}; // fin du test sur l'existence ou non d'une fonction de poids
}; // fin du cas où il y a plusieurs points:
};
// affichage et definition interactive des commandes
// plusieurs_maillages : indique s'il y a ou pas
// renvoi : true s'il y a effectivement une écriture
bool PTorseurPonct::Info_commande_Charges(bool plusieurs_maillages,UtilLecture & entreePrinc)
{ // ---------- définition des différents paramètres de définition du chargement ----------
ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
string la_sortie(" TORSEUR_PONCT "); // la chaine de caractères qui sera finalement affichée
// on passe en revue les différents paramètres qui définissent le torseur
bool lecture_ok=true;
//------- lecture de la résultante ----
string rep(" ");
int dim = ParaGlob::Dimension();
// Résultante: on fait le choix entre valeur ou fonction nD
int int_choix=0;
while ((int_choix > 3) || (int_choix < 1))
{cout << "\n --- definition de la resultante du torseur --- "
<< "\n (1) (defaut) valeur fixe: via "<<dim<<" valeurs "
<< "\n (2) valeur via une fonction nD "
<< "\n (3 ou f ) arret "
<< "\n ";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(false,"1");
Minuscules(rep);
int_choix = ChangeEntier(rep);
if ((rep == "f")||(int_choix == 3))
{lecture_ok = false; break;
};
switch (int_choix)
{case 1:
{Coordonnee V(dim);
cout << "\n coordonnee du vecteur ("<< dim << " reels) "<< endl;
for (int i = 1; i<= dim; i++) cin >> V(i);
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
cout << "\n --> coordonnees lues: "; V.Affiche_1(cout);
Re = V;
la_sortie += " Re= ";
for (int i = 1; i<= dim; i++)
la_sortie += ChangeReelSTring(V(i))+" ";
}
break;
case 2:
{ cout << "\n nom de la fonction nD ? ";
nom_fnD_Re = lect_chaine();cout << " nom lu = "<< nom_fnD_Re;
la_sortie += " Re= Fonction_nD_Re: " + nom_fnD_Re;
};
break;
default:
{cout << "\n *** mauvais choix, vous devez donner une valeur entre 1 et 2 !"
<< "\n recommencer ";
};
};
};
// Moment: on fait le choix entre valeur ou fonction nD
rep =" ";int_choix=0;
if (lecture_ok)
while ((int_choix > 3) || (int_choix < 1))
{cout << "\n --- definition du moment du torseur --- "
<< "\n (1) (defaut) valeur fixe: via "<<dim<<" valeurs "
<< "\n (2) valeur via une fonction nD "
<< "\n (3 ou f ) arret "
<< "\n ";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(false,"1");
Minuscules(rep);
int_choix = ChangeEntier(rep);
if ((rep == "f")||(int_choix == 3))
{lecture_ok = false; break;
};
switch (int_choix)
{case 1:
{Coordonnee V(dim);
cout << "\n coordonnee du vecteur ("<< dim << " reels) "<< endl;
for (int i = 1; i<= dim; i++) cin >> V(i);
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
cout << "\n --> coordonnees lues: "; V.Affiche_1(cout);
Mo = V;
la_sortie += " Mo= ";
for (int i = 1; i<= dim; i++)
la_sortie += ChangeReelSTring(V(i))+" ";
}
break;
case 2:
{ cout << "\n nom de la fonction nD ? ";
nom_fnD_Mo = lect_chaine();cout << " nom lu = "<< nom_fnD_Mo;
la_sortie += " Mo= Fonction_nD_Mo: " + nom_fnD_Mo;
};
break;
default:
{cout << "\n *** mauvais choix, vous devez donner une valeur entre 1 et 2 !"
<< "\n recommencer ";
};
};
};
// centre: on fait le choix entre les différentes possibilités
rep =" ";int_choix=0;
if (lecture_ok)
while ((int_choix > 5) || (int_choix < 1))
{cout << "\n --- definition du centre du torseur --- "
<< "\n (1) (defaut) valeur fixe: via "<<dim<<" valeurs "
<< "\n (2) valeur via une fonction nD "
<< "\n (3) position d'un noeud "
<< "\n (4) centre de gravite d'un groupe de noeuds "
<< "\n (5 ou f ) arret "
<< "\n ";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(false,"1");
Minuscules(rep);
int_choix = ChangeEntier(rep);
if ((rep == "f")||(int_choix == 5))
{lecture_ok = false; break;
};
switch (int_choix)
{case 1:
{Coordonnee V(dim);
cout << "\n coordonnee du vecteur ("<< dim << " reels) "<< endl;
for (int i = 1; i<= dim; i++) cin >> V(i);
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
cout << "\n --> coordonnees lues: "; V.Affiche_1(cout);
Ce = V;
type_centre=1;
la_sortie += " centre_= ";
for (int i = 1; i<= dim; i++)
la_sortie += ChangeReelSTring(V(i))+" ";
}
break;
case 2:
{ cout << "\n nom de la fonction nD de charge ? ";
nom_fnD_Ce=lect_chaine();cout << " nom lu = "<< nom_fnD_Ce;
la_sortie += " centre_= Fonction_nD_centre_: " + nom_fnD_Ce;
type_centre = 2;
}
break;
case 3:
{ // cas d'un centre donné par un numero de noeud
la_sortie += " centre_= centre_noeud_= ";
nom_mail_ref_pour_Ce = "";
if (plusieurs_maillages)
{cout << "\n nom du maillage contenant le noeud ? ";
nom_mail_ref_pour_Ce = lect_chaine();
la_sortie += " nom_mail= "+nom_mail_ref_pour_Ce;
};
cout << "\n numero du noeud ? ";
num_noeud = (int) lect_double();
la_sortie += " "+ChangeEntierSTring(num_noeud)+" ";
string temps(" ");
while (!Existe_nom_dure (temps))
{cout << "\n instant auquel on considere le noeud "
<< "\n TEMPS_0 (ou) TEMPS_t (ou) TEMPS_tdt ? ";
temps = lect_chaine();
// on test
if (Existe_nom_dure (temps))
{temps_noe_Ce = Id_nom_dure(temps);
}
else
{cout << "\n *** erreur, ce temps n'est pas reconnu, nouvelle valeur ? ";};
};
la_sortie += " "+temps+" ";
type_centre = 3;
}
break;
case 4:
{ // cas d'un centre donné par un centre de gravité d'une ref de noeuds
la_sortie += " centre_= centre_gravite_ref_= ";
nom_mail_ref_pour_Ce = "";
if (plusieurs_maillages)
{string nom_mail;
cout << "\n nom du maillage contenant la ref de noeuds ? ";
nom_mail_ref_pour_Ce = lect_chaine();
la_sortie += " nom_mail= "+nom_mail_ref_pour_Ce+" ";
};
cout << "\n nom de la ref de noeuds ? ";
nom_ref_pour_Ce=lect_chaine();
la_sortie += " "+nom_ref_pour_Ce+" ";
string temps(" ");
while (!Existe_nom_dure (temps))
{cout << "\n instant auquel on considere la ref de noeuds "
<< "\n TEMPS_0 (ou) TEMPS_t (ou) TEMPS_tdt ? ";
temps=lect_chaine();
// on test
if (Existe_nom_dure (temps))
{temps_noe_Ce = Id_nom_dure(temps);
}
else
{cout << "\n *** erreur, ce temps n'est pas reconnu, nouvelle valeur ? ";};
};
la_sortie += " "+temps+" ";
type_centre = 4;
}
break;
default:
{cout << "\n *** mauvais choix, vous devez donner une valeur entre 1 et 4 !"
<< "\n recommencer ";
};
};
};
//------- lecture d'une fonction poids éventuelle moment ----
rep =" ";int_choix=0;nom_fnD_poids="";
if (lecture_ok)
while ((int_choix > 3) || (int_choix < 1))
{ cout << "\n --- definition eventuelle d'une fonction poids --- "
<< "\n (1) oui "
<< "\n (2) (defaut) non "
<< "\n (3 ou f ) arret "
<< "\n ";
// procédure de lecture avec prise en charge d'un retour chariot
rep = lect_return_defaut(false,"2");
Minuscules(rep);
int_choix = ChangeEntier(rep);
if ((rep == "f")||(int_choix == 5))
{lecture_ok = false; break;
};
switch (int_choix)
{case 1:
{ cout << "\n nom de la fonction nD ? ";
nom_fnD_poids=lect_chaine();cout << " nom lu = "<< nom_fnD_poids;
la_sortie += " Fonction_nD_Poids: "+nom_fnD_poids+" ";
};
break;
case 2: // on ne fait rien
break;
default:
{cout << "\n *** mauvais choix, vous devez donner une valeur entre 1 et 2 !"
<< "\n recommencer ";
};
};
};
//------- écriture sur le .info de la grandeur ----
if (lecture_ok)
sort << la_sortie;
return lecture_ok;
};