1248 lines
50 KiB
C++
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-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 <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;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|