diff --git a/Chargement/BlocCharge.cc b/Chargement/BlocCharge.cc
new file mode 100644
index 0000000..e28c373
--- /dev/null
+++ b/Chargement/BlocCharge.cc
@@ -0,0 +1,1248 @@
+
+// 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: .
+
+
+#include "BlocCharge.h"
+#include "ConstMath.h"
+#include "CharUtil.h"
+#include "Util.h"
+#include
+
+//================================================
+// 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 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 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 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 & 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 tab_M(1,M);
+ Tableau & 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 & 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 tab_M(1,M);
+ Tableau & 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 & 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 & tab_P, Tableau & 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 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 & 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 "<> V(i);
+ std::cin.ignore( std::numeric_limits::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 "<> V(i);
+ std::cin.ignore( std::numeric_limits::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 "<> V(i);
+ std::cin.ignore( std::numeric_limits::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;
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Chargement/BlocCharge.h b/Chargement/BlocCharge.h
new file mode 100644
index 0000000..adf1ea2
--- /dev/null
+++ b/Chargement/BlocCharge.h
@@ -0,0 +1,260 @@
+
+// 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. *
+ * $ *
+ * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
+ * VERIFICATION: *
+ * *
+ * ! date ! auteur ! but ! *
+ * ------------------------------------------------------------ *
+ * ! ! ! ! *
+ * $ *
+ * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
+ * MODIFICATIONS: *
+ * ! date ! auteur ! but ! *
+ * ------------------------------------------------------------ *
+ * $ *
+ ************************************************************************/
+#ifndef BLOC_CHARGE_H
+#define BLOC_CHARGE_H
+
+#include "Bloc.h"
+#include "LesFonctions_nD.h"
+#include "Noeud.h"
+
+//================================================
+// cas d'un bloc type pour charge pour
+//================================================
+// un bloc e type correspond a une reference
+// un mot cle, et une seule valeur
+// un nom de courbe de charge
+// une échelle
+
+/// @addtogroup Groupe_concernant_le_chargement
+/// @{
+///
+
+
+class BlocScalVecTypeCharge : public BlocGeneEtVecMultType
+{
+ // surcharge de l'operator de lecture
+ friend istream & operator >> (istream &, BlocScalVecTypeCharge &);
+ // surcharge de l'operator d'ecriture
+ friend ostream & operator << (ostream &, const BlocScalVecTypeCharge &);
+ public :
+ // VARIABLES PUBLIQUES :
+ // stockage d'un element
+ // class conforme a la specif de T de la class LectBloc_T
+
+ // Constructeur
+ BlocScalVecTypeCharge () ; // par defaut
+ // avec : n: le nombre de vecteurs, m le nombre de scalaires , n le nombre de ptnom
+ BlocScalVecTypeCharge(int n,int m);
+ // de copie
+ BlocScalVecTypeCharge (const BlocScalVecTypeCharge& a) ; // de copie
+ // destructeur
+ ~BlocScalVecTypeCharge () {};
+
+ // mise en place de l'association des fonctions nD, dont ensuite on garde un pointeur
+ // en retour indique si l'association est ok: ici rien n'a faire
+ bool Mise_en_place_des_fonction_nD(const LesFonctions_nD& lesFonctionsnD)
+ { return true;};
+
+ //-------- les méthodes constantes --------------
+ // indique si c'est une référence de champ ou pas
+ // = 0 : ce n'est pas une référence de champ
+ // = 1 : c'est une référence de champ de valeur
+ // = 2 : c'est une référence de champ de fonctions
+ int Champ() const {return champ;};
+ // affichage des informations
+ void Affiche() const ;
+ // surcharge des operateurs
+ bool operator == ( const BlocScalVecTypeCharge& a) const
+ { return ( (this->BlocGeneEtVecMultType::operator==(a))
+ && (champ == a.champ ) ) ;
+ };
+ bool operator != ( const BlocScalVecTypeCharge& a) const
+ { return !(*this == a);};
+
+ //------------- les méthodes qui modifient -------------
+ // lecture d'un bloc
+ void Lecture(UtilLecture & entreePrinc);
+ BlocScalVecTypeCharge& operator = (const BlocScalVecTypeCharge& a);
+
+ protected :
+ int champ; // indique si c'est une référence de champ ou pas
+ // = 0 : ce n'est pas une référence de champ
+ // = 1 : c'est une référence de champ de valeur
+ // = 2 : c'est une référence de champ de fonctions
+
+ // lecture dans le cas particulier d'un champ de valeurs
+ void Lecture_champ_de_valeurs(UtilLecture & entreePrinc);
+ // lecture dans le cas particulier d'un champ de fonctions
+ void Lecture_champ_de_fonctions(UtilLecture & entreePrinc);
+
+ };
+/// @} // end of group
+
+
+/// @addtogroup Groupe_concernant_le_chargement
+/// @{
+///
+
+/// bloc spécialisé pour les forces
+class BlocForces : public BlocScalVecTypeCharge
+{
+ public :
+ // Constructeur
+ BlocForces () : BlocScalVecTypeCharge(1,0) {}; // par defaut
+ };
+/// @} // end of group
+
+
+/// @addtogroup Groupe_concernant_le_chargement
+/// @{
+///
+
+/// bloc spécialisé pour les intensités
+class BlocIntensite : public BlocScalVecTypeCharge
+{
+ public :
+ // Constructeur
+ BlocIntensite () : BlocScalVecTypeCharge(0,1) {}; // par defaut
+ };
+/// @} // end of group
+
+
+/// @addtogroup Groupe_concernant_le_chargement
+/// @{
+///
+
+/// ---- bloc pour un torseur vers forces ponctuelles ----
+
+ class PTorseurPonct : public BlocGen
+ { public : // surcharge de l'operator de lecture
+ friend istream & operator >> (istream & entree, PTorseurPonct & coo);
+ // surcharge de l'operator d'ecriture
+ friend ostream & operator << (ostream & sort, const PTorseurPonct & coo);
+ //Constructeur par défaut
+ PTorseurPonct ();
+ // constructeur de copie
+ PTorseurPonct (const PTorseurPonct & a);
+
+ // 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);
+ // récup du nom de maillage et du nom de la ref éventuelle de noeuds
+ // pour le centre du moment
+ Deux_String Nom_Ref_pour_Ce() const
+ {return Deux_String(nom_mail_ref_pour_Ce,nom_ref_pour_Ce);}
+ // mise en place des infos pour le centre si celui-ci dépend des noeuds
+ // en retour indique si c'est ok
+ bool Def_tab_noeud_pour_centre(const list li_noe_ref_centre);
+ // 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& Resultante(const Coordonnee& M );
+ // calcul éventuel et retour du moment (qui peut varier)
+ // M: indique un point dont peut dépendre les éléments du torseur
+ Coordonnee& Moment(const Coordonnee& M );
+ // 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& Centre( );
+ // calcul de l'effort ponctuelle correspondant au torseur
+ // pour la position passée en paramètres
+ // 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 Force(const Tableau & tab_P, Tableau & t_force);
+
+ // affichage des informations
+ void Affiche() const ;
+ // surcharge des operateurs
+ bool operator == (const PTorseurPonct& a) const;
+ bool operator != (const PTorseurPonct& a) const
+ { return !(*this == a);};
+ // lecture d'un bloc
+ void Lecture(UtilLecture & entreePrinc);
+
+ // surcharge d'affectation
+ PTorseurPonct& operator = (const PTorseurPonct& a);
+
+ // 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 Info_commande_Charges(bool plusieurs_maillages, UtilLecture & entreePrinc);
+
+
+ protected :
+
+ Coordonnee Re; // résultante du torseur
+ string nom_fnD_Re; // nom éventuelle de la fonction associée
+ Fonction_nD* fnD_Re; // fonction nD associée, éventuelle
+ Coordonnee Mo; // composantes du moment
+ string nom_fnD_Mo; // nom éventuelle de la fonction associée
+ Fonction_nD* fnD_Mo; // fonction nD associée, éventuelle
+ Coordonnee Ce; // centre pour le calcul du moment
+ Fonction_nD* fnD_Ce; // fonction nD associée, éventuelle
+ string nom_fnD_Ce; // nom éventuelle de la fonction associée
+
+ // cas d'un centre à partir de position de noeud(s)
+ const Noeud* noe_Ce; // noeud centre éventuel
+ int num_noeud; // numéro du centre
+ Enum_dure temps_noe_Ce; // si noeud centre ou centre de gravité: temps associé
+ string nom_ref_pour_Ce; // si centre de gravité d'une ref de noeud
+ string nom_mail_ref_pour_Ce; // le maillage associé soit à
+ Tableau tab_noe_ref_centre; // tableau des noeuds qui correspondent à ref_pour_Ce
+ // s'il y a un seul élément, c'est le même que noe_Ce
+ int type_centre; // = 1 : centre fixe // par défaut
+ // = 2 : centre fonction nD
+ // = 3 : centre noeud
+ // = 4 : centre de gravité d'une ref de noeud
+ string nom_fnD_poids; // nom éventuelle de la fonction des poids
+ // associé à CP_i et aux grandeurs globales
+ Fonction_nD* fnD_poids; // fonction nD associée, éventuelle
+ // ------- variable de travail -------
+ Tableau t_poids; // tableau de travail
+ Tableau t_vec; // idem
+
+
+ };
+/// @} // end of group
+
+
+
+
+#endif
diff --git a/Chargement/BlocCharge_T.h b/Chargement/BlocCharge_T.h
new file mode 100644
index 0000000..371904b
--- /dev/null
+++ b/Chargement/BlocCharge_T.h
@@ -0,0 +1,695 @@
+
+// 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
diff --git a/Chargement/Charge.cc b/Chargement/Charge.cc
new file mode 100644
index 0000000..8ff804c
--- /dev/null
+++ b/Chargement/Charge.cc
@@ -0,0 +1,1305 @@
+
+// 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: .
+
+
+#include "Charge.h"
+#include "ConstMath.h"
+#include "MathUtil.h"
+#include "ReferenceNE.h"
+#include "ReferenceAF.h"
+#include "CourbePolyLineaire1D.h"
+
+// --------------- méthodes particulière pour les conteneurs de chargement ----------
+ // == cas de la classe PHydro
+ // certaines fonctions sont redéfinies en suivant le caneva de Bloc.h
+Charge::PHydro::PHydro()
+ :BlocGeneEtVecMultType(2,1),N(),M(),normer(false)
+ {};
+Charge::PHydro::PHydro(const Charge::PHydro & a) : // constructeur par defaut
+ BlocGeneEtVecMultType(a),N(a.N),M(a.M),normer(a.normer)
+ {};
+Charge::PHydro::~PHydro () // destructeur
+ {}; // les courbes éventuelles existent par ailleurs, elles n'ont pas à être supprimées
+// mise en place de l'association des courbes
+// en retour indique si l'association est ok
+bool Charge::PHydro::Mise_en_place_des_courbes(LesCourbes1D& lesCourbes1D)
+ { // on passe en revue la liste de nom pour associer éventuellement avec les courbes
+ int dim = ParaGlob::Dimension();
+ // cas du vecteur N
+ for (int i=1;i<=dim;i++)
+ { const string& nom = Nom_vect(1,i);
+ if (nom != "NULL")
+ { // cas d'une coordonnée gérée par une courbe
+ if (N.Taille() == 0) N.Change_taille(dim,NULL);
+ if (lesCourbes1D.Existe(nom))
+ { N(i) = lesCourbes1D.Trouve(nom);}
+ else
+ { cout << "\n erreur, on ne trouve pas la courbe coefficient " << i << "pour la direction normale N !!! "
+ << " de nom: " << nom
+ << "\n Charge::PHydro::Mise_en_place_des_courbes(...";
+ return false;
+ };
+ };
+ };
+ // cas du vecteur M
+ for (int i=1;i<=dim;i++)
+ { const string& nom = Nom_vect(2,i);
+ if (nom != "NULL")
+ { // cas d'une coordonnée gérée par une courbe
+ if (M.Taille() == 0) M.Change_taille(dim,NULL);
+ if (lesCourbes1D.Existe(nom))
+ { M(i) = lesCourbes1D.Trouve(nom);}
+ else
+ { cout << "\n erreur, on ne trouve pas la courbe coefficient " << i << "pour le point A de la surface libre !!! "
+ << " de nom: " << nom
+ << "\n Charge::PHydro::Mise_en_place_des_courbes(...";
+ return false;
+ };
+ };
+ };
+ // si on arrive là c'est que tous c'est bien passé
+ return true;
+ };
+// récup de la direction N normée
+const Coordonnee& Charge::PHydro::Direction_N()
+ { // on regarde s'il y a des courbes de charges
+ Coordonnee N_vect = Vect_de_coordonnee(1); // init
+ if (N.Taille() == 0)
+ // pas de courbe, on norme la première fois
+ { if (!normer)
+ { double norme = N_vect.Norme();
+ if (norme != 1.)
+ { N_vect.Normer(); Change_vect_de_coordonnee(1,N_vect);}
+ normer = true;
+ };
+ }
+ else // sinon il faut voir avec le temps
+ {int dim = N.Taille();
+ // récup des valeurs
+ for (int i=1;i <= dim; i++)
+ {if (N(i) != NULL)
+ N_vect(i) = (N(i)->Valeur(ParaGlob::Variables_de_temps().TempsCourant()));
+ };
+ // on norme le vecteur
+ double norme = N_vect.Norme();
+ if (norme != 1.)
+ { N_vect.Normer();};
+ // on met à jour le vecteur
+ Change_vect_de_coordonnee(1,N_vect);
+ };
+ // retour du vecteur qui continue à exister
+ return Vect_de_coordonnee(1);
+ };
+// récup du point de la surface libre
+const Coordonnee& Charge::PHydro::Point_M()
+ { // on regarde s'il y a des courbes de charges
+ Coordonnee M_vect = Vect_de_coordonnee(2); // init
+ if (M.Taille() != 0)
+ // il faut voir avec le temps
+ {int dim = M.Taille();
+ // récup des valeurs
+ for (int i=1;i <= dim; i++)
+ {if (M(i) != NULL)
+ M_vect(i) = (M(i)->Valeur(ParaGlob::Variables_de_temps().TempsCourant()));
+ };
+ // on met à jour le vecteur
+ Change_vect_de_coordonnee(2,M_vect);
+ };
+ // retour du vecteur qui continue à exister
+ return Vect_de_coordonnee(2);
+ };
+
+ // == cas de la classe PHydrodyna
+ // --- mise en place de l'association des courbes pour PHydrodyna
+ // en retour indique si l'association est ok
+bool Charge::PHydrodyna::Mise_en_place_des_courbes(LesCourbes1D& lesCourbes1D)
+ { // on passe en revue la liste de nom pour associer avec les courbes
+ // cas du frottement fluid
+ const string& nom = Nom(3);
+ if (nom != "NULL")
+ { // cas où le frottement fluide est actif
+ if (lesCourbes1D.Existe(nom))
+ { frot_fluid = lesCourbes1D.Trouve(nom);}
+ else
+ { cout << "\n erreur, on ne trouve pas la courbe coefficient pour le frottement fluide !!! "
+ << " de nom: " << nom
+ << "\n Charge::PHydrodyna::Mise_en_place_des_courbes(...";
+ return false;
+ };
+ };
+ // cas de l'effort de traînée
+ const string& nom1 = Nom(4);
+ if (nom1 != "NULL")
+ { // cas où l'effort de traînée est actif
+ if (lesCourbes1D.Existe(nom1))
+ { coef_aero_n = lesCourbes1D.Trouve(nom1);}
+ else
+ { cout << "\n erreur, on ne trouve pas la courbe coefficient pour l'effort de trainee !!! "
+ << " de nom: " << nom1
+ << "\n Charge::PHydrodyna::Mise_en_place_des_courbes(...";
+ return false;
+ };
+ };
+ // cas de l'effort de portance
+ const string& nom2 = Nom(5);
+ if (nom2 != "NULL")
+ { // cas où l'effort de portance est actif
+ if (lesCourbes1D.Existe(nom2))
+ { coef_aero_t = lesCourbes1D.Trouve(nom2);}
+ else
+ { cout << "\n erreur, on ne trouve pas la courbe coefficient pour l'effort de portance !!! "
+ << " de nom: " << nom2
+ << "\n Charge::PHydrodyna::Mise_en_place_des_courbes(...";
+ return false;
+ };
+ };
+ // si on arrive là c'est que tous c'est bien passé
+ return true;
+ };
+
+// cas des torseurs de charges ponctuelles
+
+
+// --------------- fin méthodes particulière pour les conteneurs de chargement ----------
+
+// ------------- fin des variables static -----------------
+
+Charge::Charge () : // constructeur par defaut
+ tabFsurfac(),tabPresUnif(),tabPonctuel(),PresUniDir(),PresHydro(),coefHydroDyna(),tabFlineique()
+ ,tabFlineiqueSuiv(),tabFvol(),f_charge(NULL),interne_f_charge(false)
+ ,tabTorseurPonct(),tab_P(),t_force()
+ ,multi(0.),coeff(0.),temps_sauve(0.),multi_sauve(0.),coeff_sauve(0.)
+ ,temps_fin_non_stricte(0)
+ ,nomtypeCharge(),ancien_num_pt_type5(0),num_pt_courant_type5(0)
+ ,temps_cpu_chargement()
+ {// mise à jour de la valeur par défaut du chargement au cas où aucun chargement
+ // n'est définit
+ nomtypeCharge ="TYPE1";
+ tabType.Change_taille(1);
+ tabType(1) = 1.;
+ }
+Charge::~Charge ()
+{ if (f_charge != NULL)
+ { // on utilise un deuxième indicateur, car si la courbe est globale, et quelle est déjà supprimée
+ // on ne peut plus la tester
+ if (interne_f_charge)
+ delete f_charge;
+ };
+ };
+
+// affichage des differents chargements
+void Charge::Affiche() const // affiche la totalite
+ { Affiche1();
+ Affiche2();
+ };
+void Charge::Affiche1() const // affiche que la premiere lecture
+ { cout << "\n ******** Charges ******** \n";
+ if (tabFvol.Taille() != 0)
+ {cout << tabFvol.Taille() << " reference de force volumique lue \n";
+ for (int i=1; i<=tabFvol.Taille(); i++)
+ tabFvol(i).Affiche();
+ cout << "\n\n";
+ }
+ if (tabFsurfac.Taille() != 0)
+ {cout << tabFsurfac.Taille() << " reference de densite de force surfacique lue \n";
+ for (int i=1; i<=tabFsurfac.Taille(); i++)
+ tabFsurfac(i).Affiche();
+ cout << "\n\n";
+ }
+ if (tabPresUnif.Taille() != 0)
+ {cout << tabPresUnif.Taille() << " reference de pression uniformement reparti lue \n";
+ for (int i=1; i<=tabPresUnif.Taille(); i++)
+ tabPresUnif(i).Affiche();
+ cout << "\n\n";
+ }
+ if (tabPonctuel.Taille() != 0)
+ {cout << tabPonctuel.Taille() << " reference de force ponctuelle lue \n";
+ for (int i=1; i<=tabPonctuel.Taille(); i++)
+ tabPonctuel(i).Affiche();
+ cout << "\n\n";
+ }
+ if (PresUniDir.Taille() != 0)
+ {cout << PresUniDir.Taille() << " reference de pression unidirectionnelle"
+ << " type pression dynamique des fluides lue \n";
+ for (int i=1; i<=PresUniDir.Taille(); i++)
+ PresUniDir(i).Affiche();
+ cout << "\n\n";
+ }
+ if (PresHydro.Taille() != 0)
+ {cout << PresHydro.Taille() << " reference de pression hydrostatique lue \n";
+ for (int i=1; i<=PresHydro.Taille(); i++)
+ PresHydro(i).Affiche();
+ cout << "\n\n";
+ }
+ if (coefHydroDyna.Taille() != 0)
+ {cout << coefHydroDyna.Taille() << " reference de pression hydrodynamique lue \n";
+ for (int i=1; i<=coefHydroDyna.Taille(); i++)
+ coefHydroDyna(i).Affiche();
+ cout << "\n\n";
+ }
+ if (tabFlineique.Taille() != 0)
+ {cout << tabFlineique.Taille() << " reference de densite de force lineique lue \n";
+ for (int i=1; i<=tabFlineique.Taille(); i++)
+ tabFlineique(i).Affiche();
+ cout << "\n\n";
+ };
+ if (tabFlineiqueSuiv.Taille() != 0)
+ {cout << tabFlineiqueSuiv.Taille() << " reference de densite de force lineique suiveuse lue \n";
+ for (int i=1; i<=tabFlineiqueSuiv.Taille(); i++)
+ tabFlineiqueSuiv(i).Affiche();
+ cout << "\n\n";
+ };
+ if (tabTorseurPonct.Taille() != 0)
+ {cout << tabTorseurPonct.Taille() << " reference de torseur de forces ponctuelles lue \n";
+ for (int i=1; i<=tabTorseurPonct.Taille(); i++)
+ tabTorseurPonct(i).Affiche();
+ cout << "\n\n";
+ };
+
+ cout << endl;
+ };
+void Charge::Affiche2() const // affiche que la seconde lecture
+ { cout << "\n ******** Type de Chargement ******** \n";
+ if ((nomtypeCharge == "TYPE1") || (nomtypeCharge == "TYPE2") )
+ { cout << " type de chargement : " << nomtypeCharge << ", parametre : ";
+ for (int i=1; i<=tabType.Taille(); i++)
+ cout << tabType(i) << " " ;
+ cout << endl;
+ }
+ else if (nomtypeCharge == "TYPE3")
+ { cout << " type de chargement : " << nomtypeCharge << ", pas de parametre " << endl ;}
+ else if ((nomtypeCharge == "TYPE4") || (nomtypeCharge == "TYPE5"))
+ { cout << " type de chargement : " << nomtypeCharge << ", fonction de charge: ";
+ if (interne_f_charge)
+ {f_charge->Affiche();}
+ else { cout << " courbe1D " << f_charge->NomCourbe() << " ";};
+ }
+ else
+ { cout << " **** type de chargement non défini !! **** " << endl ;}
+ // cas de l'application du contrôle de temps fin
+ if (temps_fin_non_stricte)
+ cout << "\n la limite de temps est non stricte ";
+ else
+ cout << "\n la limite de temps est stricte ";
+ };
+
+// lecture des actions exterieurs imposees
+void Charge::Lecture1(UtilLecture & entreePrinc,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
+ ,LesFonctions_nD& lesFonctionsnD)
+ { if (ParaGlob::NiveauImpression() >= 4)
+ cout << " debut de la lecture du chargement " << endl;
+ MotCle motCle; // ref aux mots cle
+ { // on se positionne sur un mot cle
+ while ( !motCle.SimotCle(entreePrinc.tablcar))
+ entreePrinc.NouvelleDonnee();
+ // definition de la liste de sous mot cle specifique
+ Tableau tsousMotref(10);
+ tsousMotref(1) = "UNIFORME";tsousMotref(2) = "PRESSION";
+ tsousMotref(3) = "PONCTUELLE";tsousMotref(4) = "PRESSDIR";
+ tsousMotref(5) = "PHYDRO"; tsousMotref(6) = "LINEIQUE";
+ tsousMotref(7) = "VOLUMIQUE"; tsousMotref(8) = "LINEIC_SUIVEUSE";
+ tsousMotref(9) = "P_HYDRODYNA"; tsousMotref(10) = "TORSEUR_PONCT";
+ Tableau tsousMot(tsousMotref); // copie qui varie selon l'utilisation
+
+ // lecture pour se positionner sur un premier sous mot cle
+ entreePrinc.NouvelleDonnee();
+
+ // def d'une classe de lecture de bloc BlocCharge
+ LectBloc < BlocCharge< BlocDdlLim > > lecVecType;
+ // def d'une classe de lecture de bloc BlocScalType
+ LectBloc < BlocCharge< BlocDdlLim > > lecScalType;
+ // def d'une classe de lecture de bloc PHydro
+ LectBloc < BlocCharge< BlocDdlLim > > lecPHydro;
+ // def d'une classe de lecture de bloc PHydrodyna
+ LectBloc < BlocCharge< BlocDdlLim > > lecPHydrodyna;
+ // def d'une classe de lecture de bloc PTorseurPonct
+ LectBloc < BlocCharge< BlocDdlLim > > lecPTorseurPonct;
+
+ bool avance = true;
+ while ( !motCle.SimotCle(entreePrinc.tablcar) && avance)
+ // lecture jusqu'au prochain mot cle
+ { string inter(entreePrinc.tablcar); // pour eviter la boucle infini qui n'avance pas
+ // lecture eventuelle des densite de force surfacique
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (1); // on enleve "UNIFORME"
+ lecVecType.Lecture(entreePrinc,lesRef,"UNIFORME",
+ "lecture des densite de force surfacique",tabFsurfac,tsousMot,false);
+
+ // lecture eventuelle des pressions uniformement reparti
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (2); // on enleve "PRESSION"
+ lecScalType.Lecture(entreePrinc,lesRef,"PRESSION",
+ "lecture des pressions uniformement reparti",tabPresUnif,tsousMot,false);
+
+ // lecture eventuelle des forces ponctuelles
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (3); // on enleve "PONCTUELLE"
+ lecVecType.Lecture(entreePrinc,lesRef,"PONCTUELLE",
+ "lecture des forces ponctuelles",tabPonctuel,tsousMot,false);
+
+ // lecture eventuelle des pression unidirectionnelle
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (4); // on enleve "PRESSDIR"
+ lecVecType.Lecture(entreePrinc,lesRef,"PRESSDIR",
+ "lecture des pressions unidirectionnelles",PresUniDir,tsousMot,false);
+
+ // lecture eventuelle des pressions hydrostatiques
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (5); // on enleve "PHYDRO"
+ lecPHydro.Lecture(entreePrinc,lesRef,"PHYDRO",
+ "lecture des pressions hydrostatiques",PresHydro,tsousMot,false);
+ // initialisation éventuelle
+ int taj= PresHydro.Taille(); for (int i=1;i<=taj;i++)
+ { if (!(PresHydro(i).Mise_en_place_des_courbes(lesCourbes1D))) // mise en place et test
+ { entreePrinc.MessageBuffer("** lecture des pressions hydrostatiques **");
+ throw (UtilLecture::ErrNouvelleDonnee(-1));
+ Sortie (1);
+ };
+ };
+
+ // lecture eventuelle des coeffs pour les efforts hydrodynamiques
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (9); // on enleve "P_HYDRODYNA"
+ lecPHydrodyna.Lecture(entreePrinc,lesRef,"P_HYDRODYNA",
+ "lecture des pressions hydrodynamique",coefHydroDyna,tsousMot,false);
+ // initialisation éventuelle
+ int tai= coefHydroDyna.Taille(); for (int i=1;i<=tai;i++)
+ { if (!(coefHydroDyna(i).Mise_en_place_des_courbes(lesCourbes1D))) // mise en place et test
+ { entreePrinc.MessageBuffer("** lecture des pressions hydrodynamiques **");
+ throw (UtilLecture::ErrNouvelleDonnee(-1));
+ Sortie (1);
+ };
+ };
+
+ // lecture eventuelle des forces linéique uniformement reparti
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (6); // on enleve "LINEIQUE"
+ lecVecType.Lecture(entreePrinc,lesRef,"LINEIQUE",
+ "lecture des forces lineique uniformement reparti",tabFlineique,tsousMot,false);
+
+ // lecture eventuelle des forces linéique uniformement reparti suiveuses
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (8); // on enleve "LINEIC_SUIVEUSE"
+ lecVecType.Lecture(entreePrinc,lesRef,"LINEIC_SUIVEUSE",
+ "lecture des forces lineique suiveuses uniformement reparti",tabFlineiqueSuiv,tsousMot,false);
+
+ // lecture eventuelle des forces volumiques
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (7); // on enleve "VOLUMIQUE"
+ lecVecType.Lecture(entreePrinc,lesRef,"VOLUMIQUE",
+ "lecture des forces volumique",tabFvol,tsousMot,false);
+
+
+ // lecture eventuelle des torseurs de forces ponctuelles
+ tsousMot = tsousMotref;
+ tsousMot.Enleve (10); // on enleve "TORSEUR_PONCT"
+ lecPTorseurPonct.Lecture(entreePrinc,lesRef,"TORSEUR_PONCT",
+ "lecture des torseurs de forces ponctuelles ",tabTorseurPonct,tsousMot,false);
+
+ string sortie(entreePrinc.tablcar); // pour eviter la boucle infini
+ if (inter == sortie)
+ {avance = false;
+ cout << " erreur dans la lecture des chargements, on ne trouve pas"
+ << " de sous mot cle";
+ entreePrinc.MessageBuffer("** lecture des divers chargements **");
+ Affiche1();
+ throw (UtilLecture::ErrNouvelleDonnee(-1));
+ Sortie (1);
+ }
+ }
+
+ }
+ if (ParaGlob::NiveauImpression() >= 4)
+ cout << " fin de la lecture du chargement " << endl;
+ // on dimensionne certains tableaux de travail
+ int taille_tors = tabTorseurPonct.Taille();
+ tab_P.Change_taille(taille_tors);
+ t_force.Change_taille(taille_tors);
+ };
+
+// lecture du type d'application du chargement
+void Charge::Lecture2(UtilLecture & entreePrinc,LesCourbes1D& lesCourbes1D
+ ,LesFonctions_nD& lesFonctionsnD)
+ { if (ParaGlob::NiveauImpression() >= 4)
+ cout << " debut de la lecture du type d'application du chargement " << endl;
+ MotCle motCle; // ref aux mots cle
+ while ( !motCle.SimotCle(entreePrinc.tablcar))
+ entreePrinc.NouvelleDonnee();
+ if (strstr(entreePrinc.tablcar,"typecharge")!=NULL)
+ { entreePrinc.NouvelleDonnee();
+ *(entreePrinc.entree) >> nomtypeCharge;
+ if (nomtypeCharge == "TYPE1")
+ { tabType.Change_taille(1);
+ *(entreePrinc.entree) >> tabType(1);
+ // verif de la coherence des donnees
+ if ( (Dabs(tabType(1)) <= ConstMath::trespetit) )
+ { cout << " \n erreur : type de chargement 1, le temps final lu "
+ << tabType(1) << " est trop petit " ;
+ entreePrinc.MessageBuffer("** lecture du type d\'application du chargement **");
+ Affiche2();
+ throw (UtilLecture::ErrNouvelleDonnee(-1));
+ Sortie (1);
+ }
+ }
+ else if (nomtypeCharge == "TYPE2")
+ { tabType.Change_taille(2);
+ for (int i=1; i<=2; i++)
+ *(entreePrinc.entree) >> tabType(i);
+ // verif de la coherence des donnees
+ if ( (Dabs(tabType(1)) <= ConstMath::trespetit) )
+ { cout << " \n erreur : type de chargement 2, le temps t1 lu "
+ << tabType(1) << " est trop petit " ;
+ entreePrinc.MessageBuffer("** lecture du type d\'application du chargement **");
+ Affiche2();
+ throw (UtilLecture::ErrNouvelleDonnee(-1));
+ Sortie (1);
+ }
+ if ( (Dabs(tabType(2)) <= ConstMath::trespetit) )
+ { cout << " \n erreur : type de chargement 2, le temps t2 lu "
+ << tabType(2) << " est trop petit " ;
+ entreePrinc.MessageBuffer("** lecture du type d\'application du chargement **");
+ Affiche2();
+ throw (UtilLecture::ErrNouvelleDonnee(-1));
+ Sortie (1);
+ }
+ }
+ else if (nomtypeCharge == "TYPE3")
+ { // rien à faire
+ }
+ else if ((nomtypeCharge == "TYPE4") || (nomtypeCharge == "TYPE5"))
+ { // cas d'une courbe de charge donnée par une courbe1D
+ string nom;
+ *(entreePrinc.entree) >> nom; // lecture du nom de la courbe
+ // on regarde si la courbe existe, si oui on récupère la référence
+ if (lesCourbes1D.Existe(nom))
+ { f_charge = lesCourbes1D.Trouve(nom);
+ interne_f_charge = false;
+ }
+ else
+ { // sinon il faut la lire maintenant
+ string non_courbe("_");
+ f_charge = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom.c_str()));
+ // lecture de la courbe
+ f_charge->LectDonnParticulieres_courbes (non_courbe,&entreePrinc);
+ interne_f_charge = true;
+ };
+ // dans le cas ou le type est 5, on vérifie que la courbe est de type de liste de points
+ if (nomtypeCharge == "TYPE5")
+ { if ( (f_charge->Type_courbe() != COURBEPOLYLINEAIRE_1_D)
+ && (f_charge->Type_courbe() != CPL1D))
+ {cout << "\n **** erreur en lecture de la courbe de charge associee au type TYPE5"
+ << "\n la courbe doit etre de type poly-lineaire classique ou simplifie (cf. doc) ";
+ entreePrinc.MessageBuffer("** erreur en lecture du type de chargement **");
+ throw (UtilLecture::ErrNouvelleDonnee(-1));
+ Sortie (1);
+ };
+ };
+ }
+ else if (nomtypeCharge == "TYPE6")
+ { entreePrinc.NouvelleDonnee();
+ typedef double inter ;
+ list lili;
+ inter t1,t2;
+ while ( !motCle.SimotCle(entreePrinc.tablcar))
+ { *(entreePrinc.entree) >> t1 >> t2;
+ lili.push_back(t1);
+ lili.push_back(t2);
+ entreePrinc.NouvelleDonnee();
+ }
+ // enregistrement des infos
+ tabType.Change_taille((int) lili.size());
+ list ::iterator i;
+ int j;
+ for (i=lili.begin(),j=1 ; i != lili.end(); i++,j++)
+ tabType(j) = (*i);
+ }
+ else if (nomtypeCharge == "TYPE7")
+ { entreePrinc.NouvelleDonnee();
+ typedef double inter ;
+ list lili;
+ inter t1,t2;
+ while ( !motCle.SimotCle(entreePrinc.tablcar))
+ { *(entreePrinc.entree) >> t1 >> t2;
+ lili.push_back(t1);
+ lili.push_back(t2);
+ entreePrinc.NouvelleDonnee();
+ }
+ // enregistrement des infos
+ tabType.Change_taille((int) lili.size());
+ list ::iterator i;
+ int j;
+ for (i=lili.begin(),j=1 ; i != lili.end(); i++,j++)
+ tabType(j) = (*i);
+ }
+
+ }
+ else
+ { if (ParaGlob::NiveauImpression() >= 4)
+ { cout << " \n warning : pas de mot cle typecharge, utilisation des valeurs par defaut ";
+ Affiche2();}
+ }
+ if (ParaGlob::NiveauImpression() >= 4)
+ cout << " fin de la lecture du du type d'application du chargement " << endl;
+ };
+
+// initialisation du chargement
+// on verifie egalement la bonne adequation des references
+void Charge::Initialise(LesMaillages * lesmail,LesReferences* lesRef,ParaAlgoControle& pa
+ ,const LesCourbes1D& lesCourbes1D,const LesFonctions_nD& lesFonctionsnD)
+ { // initialisation des parametres temps
+ paAlgo = & pa; // paAlgo->Multiplicateur()
+ //-// deltatmaxi = pa.Deltatmaxi() ; // increment de temps maxi
+ //-// prectemps = pa.Prectemps(); // precision sur le temps final
+ //-// deltat = pa.Deltat(); // increment de temps
+ //-// tempsfin = pa.Tempsfin(); // temps de fin de calcul
+ //-// maxincre = pa.Maxincre(); // maximum d'increments de temps
+ //-// max_essai_incre = pa.Max_essai_incre(); // maximum de tentatives d'increments de temps
+ //-// multiplicateur = pa.Multiplicateur(); // multiplicateur de la charge
+ // initialisation des pointeurs de fonction
+ if (nomtypeCharge == "TYPE1")
+ { PtDebut = &Charge::Debut1;
+ PtAvance = &Charge::Avance1;
+ PtPrecedent = &Charge::Precedent1;
+ PtFin = &Charge::Fin1;
+ }
+ else if (nomtypeCharge == "TYPE2")
+ { PtDebut = &Charge::Debut2;
+ PtAvance = &Charge::Avance2;
+ PtPrecedent = &Charge::Precedent2;
+ PtFin = &Charge::Fin2;
+ }
+ else if (nomtypeCharge == "TYPE3")
+ { PtDebut = &Charge::Debut3;
+ PtAvance = &Charge::Avance3;
+ PtPrecedent = &Charge::Precedent3;
+ PtFin = &Charge::Fin3;
+ }
+ else if (nomtypeCharge == "TYPE4")
+ { PtDebut = &Charge::Debut4;
+ PtAvance = &Charge::Avance4;
+ PtPrecedent = &Charge::Precedent4;
+ PtFin = &Charge::Fin4;
+ }
+ else if (nomtypeCharge == "TYPE5")
+ { PtDebut = &Charge::Debut5;
+ PtAvance = &Charge::Avance5;
+ PtPrecedent = &Charge::Precedent5;
+ PtFin = &Charge::Fin5;
+ }
+ else if (nomtypeCharge == "TYPE6")
+ { PtDebut = &Charge::Debut6;
+ PtAvance = &Charge::Avance6;
+ PtPrecedent = &Charge::Precedent6;
+ PtFin = &Charge::Fin6;
+ }
+ else if (nomtypeCharge == "TYPE7")
+ { PtDebut = &Charge::Debut7;
+ PtAvance = &Charge::Avance7;
+ PtPrecedent = &Charge::Precedent7;
+ PtFin = &Charge::Fin7;
+ }
+ else
+ { cout << "\n cas non prevu, ne devrait pas arriver, nomtypeCharge = ";
+ cout << nomtypeCharge << ", void Charge::Initialise(ParaAlgoControle& pa) " << endl;
+ Sortie (1);
+ }
+ // appel de la fonction ad hoc
+ coeff = 0.; // charge courante a priori, en fait si type3 elle vaut 1 tout le temps, même au début
+ (this->*PtDebut)();
+
+ // ==== verification des references ===
+
+ // --- cas des forces ponctuelles
+ // on parcours le tableau tabPonctuel
+ for (int i=1;i<= tabPonctuel.Taille();i++)
+ { // recup de la reference correspondant au mot cle
+ const Reference& ref = lesRef->Trouve(tabPonctuel(i).NomRef(),tabPonctuel(i).NomMaillage());
+ const ReferenceNE & refN = ((ReferenceNE &) ref);
+ if (ref.Indic() != 1)
+ // cas où la référence ne correspond pas à des noeuds
+ { cout << "\n ERREUR la reference: " << ref.Nom()
+ << " ne correspond pas a des noeuds !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... "
+ << "\n cas des forces ponctuelles " << endl;
+ Sortie (1);
+ }
+ // dans le cas où il s'agit d'une ref relative à un champ, on vérifie que le nombre
+ // de valeurs enregistrées correspond bien au nombre de noeuds
+ if (tabPonctuel(i).Champ() != 0)
+ { if (tabPonctuel(i).DimVect() != refN.Taille())
+ { cout << "\n ERREUR la reference: " << ref.Nom()
+ << " contiens "<Trouve(tabFsurfac(i).NomRef(),tabFsurfac(i).NomMaillage());
+ if ( ((refi.Indic() != 3)&& (ParaGlob::Dimension() == 3))
+ || ((refi.Indic() != 3)&&(refi.Indic() != 4)&&(ParaGlob::Dimension() == 2))
+ || (ParaGlob::Dimension() == 1))
+ // cas d'element
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des frontieres d'element,"
+ << " ce qui est necessaire pour les chargements surfacique !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ }
+ const ReferenceAF & ref = ((ReferenceAF &) refi);
+ // Maintenant il faut vérifier que les surfaces en question sont possible pour l'élément
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // on regarde si l'on est en 2D ou en 3D
+ bool surface_existe = false;
+ if (ParaGlob::Dimension() == 3)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).SurfExiste(ref.NumeroFA(ns));
+ else if (ParaGlob::Dimension() == 2)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).AreteExiste(ref.NumeroFA(ns));
+ if (!surface_existe)
+ { cout << "\n ERREUR l'enregistrement " <Trouve(tabPresUnif(i).NomRef(),tabPresUnif(i).NomMaillage());
+ if ( ( ((refi.Indic() != 3)&& (ParaGlob::Dimension() == 3)) // ce n'est pas une surface et on est en dim 3
+ // et ce n'est pas : une arête + dim 3 + axisymétrie
+ && !((refi.Indic() == 4)&&((ParaGlob::Dimension() == 3)&&(ParaGlob::AxiSymetrie())))
+ )
+ || ((refi.Indic() != 3)&&(refi.Indic() != 4)&&(ParaGlob::Dimension() == 2))
+ || (ParaGlob::Dimension() == 1))
+ // cas d'element
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des frontieres surfaciques d'element,"
+ << " ce qui est necessaire pour les chargements de pression !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ }
+ const ReferenceAF & ref = ((ReferenceAF &) refi);
+ // Maintenant il faut vérifier que les surfaces en question sont possible pour l'élément
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // on regarde si l'on est en 2D ou 2D axisymétrique ou en 3D,
+ bool surface_existe = false;
+ if ( (ParaGlob::Dimension() == 2)
+ || ((ParaGlob::Dimension() == 3)&&(ParaGlob::AxiSymetrie())))
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).AreteExiste(ref.NumeroFA(ns));
+ else if (ParaGlob::Dimension() == 3)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).SurfExiste(ref.NumeroFA(ns));
+ if (!surface_existe)
+ { cout << "\n ERREUR l'enregistrement " <Trouve(PresUniDir(i).NomRef(),PresUniDir(i).NomMaillage());
+ if ( ((refi.Indic() != 3)&& (ParaGlob::Dimension() == 3))
+ || ((refi.Indic() != 3)&&(refi.Indic() != 4)&&(ParaGlob::Dimension() == 2))
+ || (ParaGlob::Dimension() == 1))
+ // cas d'element
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des frontieres surfaciques d'element,"
+ << " ce qui est necessaire pour les chargements de pression unidirectionnelle!!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ }
+ const ReferenceAF & ref = ((ReferenceAF &) refi);
+ // a priori pour l'instant ce type de chargement n'est valide que pour la 3D, et plus
+ // non axisymétrique. On laisse cependant les tests pour les autres dimensions, au cas où
+ // plus-tard on change d'avis
+ if (ParaGlob::Dimension() !=3)
+ { cout << "\n ERREUR: a priori le type de chargement suiveur en surfacique ne s'utilise que dans "
+ << " un espace de travail 3D (classique), pour les autres dimensions il existe des chargements"
+ << " equivalents specifiques : cf. la documentation ! ";
+ cout << "\n ==== reference du chargement: " << ref.Nom();
+ Sortie (1);
+ }
+ else if (ParaGlob::AxiSymetrie())
+ { cout << "\n ERREUR: le type de chargement suiveur en surfacique ne s'utilise que dans "
+ << " un espace de travail 3D (classique), en axisymetrique il existe des chargements"
+ << " equivalents specifiques : cf. la documentation ! ";
+ cout << "\n ==== reference du chargement: " << ref.Nom();
+ Sortie (1);
+ };
+ // Maintenant il faut vérifier que les surfaces en question sont possible pour l'élément
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // on regarde si l'on est en 2D ou en 3D
+ bool surface_existe = false;
+ if (ParaGlob::Dimension() == 3)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).SurfExiste(ref.NumeroFA(ns));
+ else if (ParaGlob::Dimension() == 2)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).AreteExiste(ref.NumeroFA(ns));
+ if (!surface_existe)
+ { cout << "\n ERREUR l'enregistrement " <Trouve(PresHydro(i).NomRef(),PresHydro(i).NomMaillage());
+ if ( ( ((refi.Indic() != 3)&& (ParaGlob::Dimension() == 3)) // ce n'est pas une surface et on est en dim 3
+ // et ce n'est pas : une arête + dim 3 + axisymétrie
+ && !((refi.Indic() == 4)&&((ParaGlob::Dimension() == 3)&&(ParaGlob::AxiSymetrie())))
+ )
+ || ((refi.Indic() != 3)&&(refi.Indic() != 4)&&(ParaGlob::Dimension() == 2))
+ || (ParaGlob::Dimension() == 1))
+ // cas d'element
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des frontieres surfaciques d'element,"
+ << " ce qui est necessaire pour les chargements surfacique hydrostatique!!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ };
+ const ReferenceAF & ref = ((ReferenceAF &) refi);
+ // Maintenant il faut vérifier que les surfaces en question sont possible pour l'élément
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // on regarde si l'on est en 2D ou en 3D
+ bool surface_existe = false;
+ if ( (ParaGlob::Dimension() == 2)
+ || ((ParaGlob::Dimension() == 3)&&(ParaGlob::AxiSymetrie())))
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).AreteExiste(ref.NumeroFA(ns));
+ else if (ParaGlob::Dimension() == 3)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).SurfExiste(ref.NumeroFA(ns));
+ if (!surface_existe)
+ { cout << "\n ERREUR l'enregistrement " <Trouve(coefHydroDyna(i).NomRef(),coefHydroDyna(i).NomMaillage());
+ if ( ((refi.Indic() != 3)&& (ParaGlob::Dimension() == 3))
+ || ((refi.Indic() != 3)&&(refi.Indic() != 4)&&(ParaGlob::Dimension() == 2))
+ || (ParaGlob::Dimension() == 1))
+ // cas d'element
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des frontieres surfaciques d'element,"
+ << " ce qui est necessaire pour les chargements hydrosdynamiques !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ }
+ const ReferenceAF & ref = ((ReferenceAF &) refi);
+ // Maintenant il faut vérifier que les surfaces en question sont possible pour l'élément
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // on regarde si l'on est en 2D ou en 3D
+ bool surface_existe = false;
+ if (ParaGlob::Dimension() == 3)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).SurfExiste(ref.NumeroFA(ns));
+ else if (ParaGlob::Dimension() == 2)
+ surface_existe =
+ (lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).AreteExiste(ref.NumeroFA(ns));
+ if (!surface_existe)
+ { cout << "\n ERREUR l'enregistrement " <Trouve(tabFlineique(i).NomRef(),tabFlineique(i).NomMaillage());
+ if (refi.Indic() != 4)
+ // cas d'arrêtes
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des frontieres d'arête d'element,"
+ << " ce qui est necessaire pour les chargements lineique !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ };
+ const ReferenceAF & ref = ((ReferenceAF &) refi);
+ // Maintenant il faut vérifier que les aretes en question sont possible pour l'élément
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ if (!(lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).AreteExiste(ref.NumeroFA(ns)))
+ { cout << "\n ERREUR l'enregistrement " < 0)&&(ParaGlob::Dimension() != 2)&&(!ParaGlob::AxiSymetrie()))
+ { cout << "\n ERREUR la dimension est différente de 2 et il y a des forces linéiques suiveuses défini"
+ << " \n ceci n'est pas possible !! (indétermination de direction)"
+ << " \n Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ }
+
+ // on parcours le tableau tabFlineiqueSuiv dans le repère global
+ for (int i=1;i<= tabFlineiqueSuiv.Taille();i++)
+ { // recup de la reference correspondant au mot cle
+ const Reference& refi = lesRef->Trouve(tabFlineiqueSuiv(i).NomRef(),tabFlineiqueSuiv(i).NomMaillage());
+ if (refi.Indic() != 4)
+ // cas d'arrêtes
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des frontieres d'arête d'element,"
+ << " ce qui est necessaire pour les chargements lineique !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... " << endl;
+ Sortie (1);
+ }
+ const ReferenceAF & ref = ((ReferenceAF &) refi);
+ // Maintenant il faut vérifier que les aretes en question sont possible pour l'élément
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ if (!(lesmail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns))).AreteExiste(ref.NumeroFA(ns)))
+ { cout << "\n ERREUR l'enregistrement " <Trouve(tabFvol(i).NomRef(),tabFvol(i).NomMaillage());
+ if (refi.Indic() != 2)
+ // cas d'elements
+ { cout << "\n ERREUR la reference: " << refi.Nom()
+ << " ne correspond pas a des element,"
+ << " ce qui est necessaire pour les chargements volumique !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... "
+ << "\n cas des forces volumiques uniformes " << endl;
+ Sortie (1);
+ };
+ // dans le cas où il s'agit d'une ref relative à un champ, on vérifie que le nombre
+ // de valeurs enregistrées correspond bien au nombre d'éléments
+ const ReferenceNE & refE = ((ReferenceNE &) refi);
+ if (tabFvol(i).Champ() != 0)
+ { if (tabFvol(i).DimVect() != refE.Taille())
+ { cout << "\n ERREUR la reference: " << refE.Nom()
+ << " contiens "<Trouve(tabTorseurPonct(i).NomRef(),tabTorseurPonct(i).NomMaillage());
+ const ReferenceNE & refN = ((ReferenceNE &) ref);
+ if (ref.Indic() != 1)
+ // cas où la référence ne correspond pas à des noeuds
+ { cout << "\n ERREUR la reference: " << ref.Nom()
+ << " ne correspond pas a des noeuds !!";
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... "
+ << "\n cas des torseurs de forces ponctuelles " << endl;
+ Sortie (1);
+ };
+ }
+ // on met à jour les fonctions nD internes si nécessaire
+ if (!tabTorseurPonct(i).Mise_en_place_des_fonction_nD(lesFonctionsnD))
+ { cout << "\n ERREUR d'association de fonction nD: pour la condition " << tabTorseurPonct(i)
+ << " revoir la mise en donnees !!";
+ if (ParaGlob::param->NiveauImpression() > 3)
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... "
+ << "\n cas des torseurs de forces ponctuelles " << endl;
+ Sortie (1);
+ };
+ { //On s'occupe maintenant des noeuds éventuellement à rattacher
+ // récup du nom de la ref éventuelle de noeuds pour le centre du moment
+ Deux_String nom_ref = tabTorseurPonct(i).Nom_Ref_pour_Ce();
+ if ( nom_ref.nom2.length())
+ {// cas du centre de gravité d'une référence de noeuds
+ int num_mail = 1; // init par défaut
+ if ( nom_ref.nom1.length()) // s'il y a un nom de maillage
+ lesmail->NumMaillage(nom_ref.nom2); // on en récupère le numéro
+ const Reference& ref =
+ ((Reference &) lesRef->Trouve(nom_ref.nom2,num_mail));
+ if (ref.Indic() != 1)
+ // cas où la référence ne correspond pas à des noeuds
+ { cout << "\n ERREUR la reference: " << ref.Nom()
+ << " prevu pour un centre de gravite pour le calcul de torseur d'action, "
+ << " ne correspond pas a des noeuds !!";
+ if (ParaGlob::param->NiveauImpression() > 3)
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... "
+ << "\n cas des torseurs de forces ponctuelles " << endl;
+ Sortie (1);
+ };
+ const ReferenceNE & refN = ((ReferenceNE &) ref);
+ // on va constituer une liste de noeuds que l'on va transmettre au torseur
+ list < const Noeud * > liNoe;
+ int reftaille = refN.Taille();
+ for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
+ liNoe.push_back(&(lesmail->Noeud_LesMaille(refN.Nbmaille(),refN.Numero(nn))));
+ // mise en place des infos pour le centre si celui-ci dépend des noeuds
+ if (!tabTorseurPonct(i).Def_tab_noeud_pour_centre(liNoe))
+ { cout << "\n ERREUR dans la definition du centre de ref du momemt pour la condition " << tabTorseurPonct(i)
+ << " revoir la mise en donnees !!";
+ if (ParaGlob::param->NiveauImpression() > 3)
+ cout << " Charge::Initialise(LesMaillages * lesMail,etc ... "
+ << "\n cas des torseurs de forces ponctuelles " << endl;
+ Sortie (1);
+ };
+ }
+ };
+ {//On définit des places de stockage intermédiaire pour optimiser les temps de calcul
+ BlocCharge< BlocDdlLim >& tabTorseurPonct_i = tabTorseurPonct(i);
+ const ReferenceNE & ref =
+ ((ReferenceNE &) lesRef->Trouve(tabTorseurPonct_i.NomRef(),tabTorseurPonct_i.NomMaillage()));
+ int reftaille = ref.Taille();
+ tab_P(i).Change_taille(reftaille);
+ t_force(i).Change_taille(reftaille);
+ };
+
+ };
+
+ };
+
+//----- lecture écriture de base info -----
+// lecture base info
+// = 1 : on récupère tout
+// = 2 : on récupère uniquement les données variables (supposées comme telles)
+void Charge::Lecture_base_info(ifstream& entr,const int cas,LesReferences& ,LesCourbes1D& lesCourbes1D
+ ,LesFonctions_nD& lesFonctionsnD)
+{switch (cas)
+ { case 1 : // ------- on récupère tout -------------------------
+
+ { cout << "== lecture du chargement \n";
+ string toto;entr >> toto ; // lecture en tête
+ string type; entr >> type; // lecture du premier type
+ while (type != "type_de_charge")
+ { if (type == "force_volumique")
+ // cas des densites de force volumique dans le repère absolu
+ entr >> tabFvol;
+ if (type == "force_surfacique")
+ // cas des densites de force surfacique dans le repère absolu
+ entr >> tabFsurfac;
+ if (type == "force_pression_uniforme")
+ // cas des pressions uniformement repartis, appliquee normalement a la surface
+ entr >> tabPresUnif;
+ if (type == "forces_ponctuelles")
+ // cas des forces ponctuelles sur un noeud
+ entr >> tabPonctuel;
+ if (type == "pression_unidirectionnelle")
+ // pression unidirectionnelle type pression dynamique des fluides
+ entr >> PresUniDir;
+ if (type == "pression_hydrostatique")
+ // pression hydrostatique
+ entr >> PresHydro;
+ if (type == "pression_hydrodynamique")
+ // pression hydrodynamique
+ entr >> coefHydroDyna;
+ if (type == "forces_lineiques")
+ // densite de force lineique dans le repère absolu
+ entr >> tabFlineique;
+ if (type == "forces_lineiques_suiveuses")
+ // densite de force lineique suiveuse
+ entr >> tabFlineiqueSuiv;
+ if (type == "torseurs_forces_ponctuelles" )
+ // densite de torseurs de forces ponctuelles
+ entr >> tabTorseurPonct;
+ entr >> type;
+ }
+ // type d'application du chargement
+ entr >> nomtypeCharge;
+ int tabType_taille;
+ entr >> toto >> tabType_taille;
+ tabType.Change_taille(tabType_taille);
+ for (int i=1;i<= tabType_taille;i++)
+ entr >> tabType(i);
+ // cas particulier d'une fonction de charge
+ if ((nomtypeCharge == "TYPE4") || (nomtypeCharge == "TYPE5"))
+ { string nom; entr >> nom;
+ if (nom != " fonction_de_charge: ")
+ { cout << "\n erreur en lecture de la fonction de charge, "
+ << " on attendait fonction_de_charge: et on a lue " << nom
+ << "\n Charge::Lecture_base_info(...";
+ Sortie(1);
+ };
+ f_charge = lesCourbes1D.Lecture_pour_base_info(entr,cas,f_charge);
+ {if (f_charge->NomCourbe() == "_") interne_f_charge=true; else interne_f_charge=false;};
+ };
+ // on lit éventuellement les paramètres particuliers de gestion des types de chargement
+ if (nomtypeCharge == "TYPE5")
+ entr >> toto >> num_pt_courant_type5;
+ // on écrit le type de gestion du temps fin
+ entr >> toto >> temps_fin_non_stricte;
+ break;
+ }
+ case 2 : // ----------- lecture uniquement de se qui varie --------------------
+ {
+ // le parametre global d'avancement de la charge
+ string toto;
+ entr >> toto; // lecture de l'entête
+ // compteur_essai_increment d'increment
+ entr >> toto >> compteur_essai_increment;
+ // multi = l'increment courant de multiplication de la charge
+ // coeff = niveau actuel de la charge
+ entr >> toto >> multi >> coeff;
+ // on lit également le numéro du type pour la gestion éventuelle de reprise
+ // avec des types différents
+ short int numtype; entr >> numtype;
+ if ((numtype != 5) && (nomtypeCharge == "TYPE5"))
+ { // cas d'une reprise avec le type 5, à la suite d'un autre type -> a priori impossible
+ cout << "\n erreur en restart !! on ne peut pas redemarrer avec le type 5 de chargement "
+ << " a la suite d'un autre type !! ";
+ if (ParaGlob::NiveauImpression() >= 4){ cout << "\n Charge::Lecture_base_info(.... ";};
+ Sortie(1);
+ };
+ // on lit éventuellement les paramètres particuliers de gestion des types de chargement
+ if (nomtypeCharge == "TYPE5")
+ entr >> toto >> num_pt_courant_type5;
+ // temps cpu
+ entr >> toto >> temps_cpu_chargement;
+ break;
+ }
+ default :
+ { cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
+ cout << "Charge::Lecture_base_info(ifstream& entr,const int cas)"
+ << " cas= " << cas << endl;
+ Sortie(1);
+ }
+ };
+ };
+
+// écriture base info
+// = 1 : on sauvegarde tout
+// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
+void Charge::Ecriture_base_info(ofstream& sort,const int cas)
+{switch (cas)
+ { case 1 : // ------- on sauvegarde tout -------------------------
+ { sort << "\n ****chargement \n" ;
+ // cas des densites de force volumique dans le repère absolu
+ if (tabFvol.Taille() != 0)
+ sort << " force_volumique " << tabFvol;
+ // cas des densites de force surfacique dans le repère absolu
+ if (tabFsurfac.Taille() != 0)
+ sort << " force_surfacique " << tabFsurfac;
+ // cas des pressions uniformement repartis, appliquee normalement a la surface
+ if (tabPresUnif.Taille() != 0)
+ sort << " force_pression_uniforme " << tabPresUnif;
+ // cas des forces ponctuelles sur un noeud
+ if (tabPonctuel.Taille() != 0)
+ sort << " forces_ponctuelles " << tabPonctuel;
+ // pression unidirectionnelle type pression dynamique des fluides
+ if (PresUniDir.Taille() != 0)
+ sort << " pression_unidirectionnelle " << PresUniDir;
+ // pression hydrostatique
+ if (PresHydro.Taille() != 0)
+ sort << " pression_hydrostatique " << PresHydro;
+ // pression hydrodynamique
+ if (coefHydroDyna.Taille() != 0)
+ sort << " pression_hydrodynamique " << coefHydroDyna;
+ // densite de force lineique dans le repère absolu
+ if (tabFlineique.Taille() != 0)
+ sort << " forces_lineiques " << tabFlineique;
+ // densite de force lineique suiveuses
+ if (tabFlineiqueSuiv.Taille() != 0)
+ sort << " forces_lineiques_suiveuses " << tabFlineiqueSuiv;
+ // densite de torseurs de forces ponctuelles
+ if (tabTorseurPonct.Taille() != 0)
+ sort << " torseurs_forces_ponctuelles " << tabTorseurPonct;
+ // type d'application du chargement
+ sort << " type_de_charge " << nomtypeCharge;
+ int tabType_taille = tabType.Taille();
+ sort << " parametres " << tabType_taille;
+ for (int i=1;i<= tabType_taille;i++)
+ sort << " " << tabType(i);
+ // cas particulier d'une fonction de charge
+ if ((nomtypeCharge == "TYPE4") || (nomtypeCharge == "TYPE5"))
+ { sort << " fonction_de_charge: " ;
+ LesCourbes1D::Ecriture_pour_base_info(sort,cas,f_charge);
+ }
+ // on écrit également les paramètres particuliers de gestion des types de chargement
+ if (nomtypeCharge == "TYPE5")
+ sort << " para_type5 " << num_pt_courant_type5 << " ";
+ // on écrit le type de gestion du temps fin
+ sort << "\n gestion_temps_fin " << temps_fin_non_stricte;
+ break;
+ }
+ case 2 : // ----------- sauvegarde uniquement de se qui varie --------------------
+ {
+ // le parametre global d'avancement de la charge
+// sort << "\n temps " << temps << " ";
+ // compteur_essai_increment d'increment
+ sort << "\n ****chargement " ;
+ sort <<"\n compteur_essai_increment " << compteur_essai_increment << " ";
+ // multi = l'increment courant de multiplication de la charge
+ // coeff = niveau actuel de la charge
+ sort << "\n multi_et_coeff " << multi << " " << coeff << " ";
+ // on sort également le numéro du type pour la gestion éventuelle de reprise
+ // avec des types différents
+ sort << nomtypeCharge.substr(4,nomtypeCharge.length()-4) << " ";
+ if (nomtypeCharge == "TYPE5")
+ {sort << " para_type5 " << num_pt_courant_type5 << " ";};
+// else { sort << "---" << 0 ; }; // de manière à ne pas avoir de pb si on change
+ // temps cpu
+ sort << "\n temps_cpu_charge: "<< temps_cpu_chargement;
+ break;
+ }
+ default :
+ { cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
+ cout << "Charge::Ecriture_base_info(ofstream& sort,const int cas)"
+ << " cas= " << cas << endl;
+ Sortie(1);
+ }
+ };
+ };
+
+
+
diff --git a/Chargement/Charge.h b/Chargement/Charge.h
new file mode 100644
index 0000000..9663f9c
--- /dev/null
+++ b/Chargement/Charge.h
@@ -0,0 +1,428 @@
+
+// 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: 23/01/97 *
+ * $ *
+ * AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
+ * $ *
+ * PROJET: Herezh++ *
+ * $ *
+ ************************************************************************
+ * BUT: Gestion des chargements. *
+ * Chargement en temps : *
+ * *
+ * ^ *
+ * 1 | t1-------- *
+ * | / *
+ * | / Type 1 = une rampe linéaire *
+ * | / puis un plateau horizontal *
+ * 0------------------> t *
+ * *
+ * *
+ * ^ Type 2 = une rampe linéaire *
+ * 1 | t1-----t2 un plateau puis arrêt *
+ * | / | *
+ * | / | *
+ * | / | *
+ * 0------------------> t *
+ * *
+ * ^ Type 3 = uniquement un plateau *
+ * 1 |------------------- ..... *
+ * | *
+ * | *
+ * | *
+ * 0------------------> t *
+ * *
+ * Type 4 = utilisation d'une courbe 1D quelconque *
+ * *
+ * Type 5 utilisation d'un fichier de points qui *
+ * impose la suite de temps de calcul, donc de pas de temps *
+ * *
+ * $ *
+ * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
+ * VERIFICATION: *
+ * *
+ * ! date ! auteur ! but ! *
+ * ------------------------------------------------------------ *
+ * ! ! ! ! *
+ * $ *
+ * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
+ * MODIFICATIONS: *
+ * ! date ! auteur ! but ! *
+ * ------------------------------------------------------------ *
+ * $ *
+ ************************************************************************/
+#ifndef CHARGE_H
+#define CHARGE_H
+
+#include "LectBloc_T.h"
+#include "ParaGlob.h"
+#include "Bloc.h"
+#include
+#include "ParaAlgoControle.h"
+#include "LesMaillages.h"
+#include "Mat_abstraite.h"
+#include "Assemblage.h"
+#include "Nb_assemb.h"
+#include "Courbe1D.h"
+#include "BlocCharge_T.h"
+#include "LesCourbes1D.h"
+#include "LesFonctions_nD.h"
+#include "BlocCharge.h"
+#include "Temps_CPU_HZpp.h"
+
+
+/** @defgroup Groupe_concernant_le_chargement
+*
+* BUT: groupe relatif aux chargements
+*
+*
+* \author Gérard Rio
+* \version 1.0
+* \date 23/01/97
+* \brief groupe relatif aux chargements
+*
+*/
+
+/// @addtogroup Groupe_concernant_le_chargement
+/// @{
+///
+
+
+class Charge
+{
+ public :
+ // VARIABLES PUBLIQUES :
+ // ---- class intermédiaires -----
+ class PHydro : public BlocGeneEtVecMultType
+ { public : // surcharge de l'operator de lecture
+ friend istream & operator >> (istream & entree, PHydro & coo)
+ { entree >> ((BlocGeneEtVecMultType&)(coo)); return entree;};
+ // surcharge de l'operator d'ecriture
+ friend ostream & operator << (ostream & sort, const PHydro & coo)
+ { sort << ((const BlocGeneEtVecMultType&)(coo)); return sort; };
+ PHydro(); // constructeur par défaut
+ PHydro (const PHydro & a) ; // constructeur par defaut
+ ~PHydro () ; // destructeur
+
+ // mise en place de l'association des courbes
+ // en retour indique si l'association est ok
+ bool Mise_en_place_des_courbes(LesCourbes1D& lesCourbes1D);
+ const Coordonnee& Direction_N(); // récup de la direction N normée
+ const Coordonnee& Point_M(); // récup du point de la surface libre
+ protected :
+ Tableau N; // courbes permettant de piloter éventuellement la normale
+ Tableau M; // courbes permettant de piloter éventuellement le point de la surface neutre
+ bool normer; // dans le cas de vecteur N constant, indique si le vecteur a été normé ou pas
+ };
+ class PHydrodyna : public BlocGen
+ { public : // surcharge de l'operator de lecture
+ friend istream & operator >> (istream & entree, PHydrodyna & coo)
+ { entree >> ((BlocGen&)(coo)); return entree;};
+ // surcharge de l'operator d'ecriture
+ friend ostream & operator << (ostream & sort, const PHydrodyna & coo)
+ { sort << ((const BlocGen&)(coo)); return sort; };
+ PHydrodyna () : BlocGen(5,1),frot_fluid(NULL),coef_aero_n(NULL),coef_aero_t(NULL) {};
+ // mise en place de l'association des courbes
+ // en retour indique si l'association est ok
+ bool Mise_en_place_des_courbes(LesCourbes1D& lesCourbes1D);
+ Courbe1D* Frot_fluid() const { return frot_fluid;};
+ Courbe1D* Coef_aero_n() const { return coef_aero_n;};
+ Courbe1D* Coef_aero_t() const { return coef_aero_t;};
+ protected :
+ Courbe1D* frot_fluid; // courbe de frottement fluide
+ Courbe1D* coef_aero_n; // courbe pour l'effort de traînée
+ Courbe1D* coef_aero_t; // courbe pour l'effort de portance
+ };
+
+
+ // ---- fin class intermédiaires -----
+
+ // CONSTRUCTEURS :
+ Charge () ; // constructeur par defaut
+ // DESTRUCTEUR :
+ ~Charge () ;
+
+ // METHODES PUBLIQUES :
+
+ // affichage des differents chargements
+ void Affiche() const ; // affiche la totalite
+ void Affiche1() const ; // affiche que la premiere lecture
+ void Affiche2() const ; // affiche que la seconde lecture
+
+ // lecture des differents chargements actions exterieurs imposees
+ void Lecture1(UtilLecture & entreePrinc,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
+ ,LesFonctions_nD& lesFonctionsnD);
+
+ // lecture du type d'application du chargements
+ void Lecture2(UtilLecture & entreePrinc,LesCourbes1D& lesCourbes1D
+ ,LesFonctions_nD& lesFonctionsnD);
+
+ // initialisation du chargement
+ // on verifie egalement la bonne adequation des references
+ void Initialise(LesMaillages * lesMail,LesReferences* lesRef,ParaAlgoControle& pa
+ ,const LesCourbes1D& lesCourbes1D,const LesFonctions_nD& lesFonctionsnD);
+ // dans le cas où on utilise plusieurs algorithmes, il faut pouvoir changer
+ // de paramètres de contrôle
+ void ChangeParaAlgoControle(ParaAlgoControle& pa)
+ {paAlgo = & pa;};
+
+ // avancement de la charge
+ // il peut y avoir plusieurs type d'avancement
+ // en fonction des donnees ( transparent pour l'utilisateur)
+ // mais aussi en fonction des parametres
+ // incrémentation d'un compteur, permet de limiter le nombre d'appel
+ // retourne false par défaut, mais si le pas de temps a été modifié
+ // retourne true !!, car par exemple de la fin du chargement, d'où une modif du pas
+ // pour obtenir exactement la fin
+ bool Avance(); // premier version
+
+ // retour de la charge au cas précédent, c'est à dire
+ // avant le dernier ordre d'avancement
+ // valeur par défaut de "exacte "
+ // si exacte n'est pas présent ou faux: le compteur d'appel de Avance(), n'est pas décrémenté
+ // exacte=true: le compteur d'appel est décrémenté, en fait on revient exactement au départ
+ // ce qui permet d'utiliser plusieurs fois Avance() dans un même pas de temps
+ // en comptabilisant par exemple qu'une seule fois un appel de Avance(), cas d'une intégration
+ // temporelle par exemple
+ void Precedant(bool exacte=false);
+
+ // diminution de l'incrément de charge dans le cas par exemple d'une non convergence
+ // ramène true si la diminution est effective, sinon false
+ bool Diminue_inc_charge(double diminue);
+ // augmentation de l'incrément de charge dans le cas de bonne convergence
+ // ramène true si l'augmentation est effective, sinon false
+ bool Augmente_inc_charge(double augmente);
+
+ // declaration de la fin en fonction du type de chargement
+ // retour:
+ // retour:
+ // 0 : la fin n'est pas valide, on continue
+ // 1 : temps fin dépassé
+ // 2 : compteur_increment dépassé
+ // 3 : compteur_essai_increment dépassé
+ // NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
+ // puis ensuite le compteur d'incréments
+ // puis le nombre d'essai maxi, puis enfin le cas normal
+ // si affichage est true, affichage d'un message
+ int Fin(const int & icharge,bool affichage = true);
+
+ // retourne l'increment du coef multiplicateur de charge, courant
+ inline double MultCharge()
+ { return multi;};
+
+ // retourne le coef multiplicateur de charge, courant
+ inline double IntensiteCharge()
+ { return coeff;};
+
+ // retourne le temps courant ou en est le calcul
+ inline double Temps_courant () {return paAlgo->Variables_de_temps().TempsCourant();};
+ // incrément de temps courant
+ inline double Increment_de_Temps() {return paAlgo->Variables_de_temps().IncreTempsCourant();};
+
+ // la manière dont on vise le temps fin
+ // = 0 par défaut pour les schéma implicite: indique
+ // que l'on doit viser le temps fin de manière stricte (pas le dépasser)
+ // = 1 : on doit juste le dépasser -> a priori c'est le fonctionnement par défaut des
+ // algo explicites, compte tenu qu'il n'y a pas de prise en compte précise
+ // de la variation du pas de temps
+ // mise à jour avec la méthode :
+ void Change_temps_fin_non_stricte(int methode)
+ {temps_fin_non_stricte = methode;};
+
+ // retourne le temps cumulés relatif à tous les chargements
+ const Temps_CPU_HZpp& Temps_cpu_chargement() const {return temps_cpu_chargement;};
+
+ // mise en place du chargement impose sur le second membre global
+ // cas explicite
+ // la variable relative à la classe assemblage est passé en argument ce qui permet d'utiliser
+ // éventuellement plusieurs type d'assemblage
+ // retour false si problème de calcul
+ bool ChargeSecondMembre_Ex_mecaSolid
+ (Assemblage & assemb,LesMaillages * lesMail,LesReferences* lesRef,Vecteur& vecglob
+ ,const ParaAlgoControle & pa,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD);
+
+ // cas implicite avec également modification de la raideur quand le chargement dépend
+ // de la géométrie, en fonction des paramètres de pa
+ // la variable relative à la classe assemblage est passé en argument ce qui permet d'utiliser
+ // éventuellement plusieurs type d'assemblage
+ // de plus il faut prévoir un pointeur d'assemblage pour séparer le cas d'assemblage symétrique ou non
+ // d'où la variable pointeur de fonction membre d'assemblage
+ // retour false si problème de calcul
+ bool ChargeSMembreRaideur_Im_mecaSolid(Assemblage & assemb,LesMaillages * lesMail,LesReferences* lesRef
+ ,Vecteur& vecglob, Mat_abstraite& matglob
+ ,void (Assemblage::* assembMat) // le pointeur de fonction
+ (Mat_abstraite & matglob,const Mat_abstraite & matloc,
+ const DdlElement& tab_ddl,const Tableau&tab_noeud)
+ ,const ParaAlgoControle & pa
+ ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD);
+
+ // lecture de donnée en fonction d'un indicateur : int type
+ // pour l'instant ne fait rien
+ void LectureDonneesExternes(UtilLecture& ,LesReferences& ,const int,const string& ) {};
+
+ // affichage et definition interactive des commandes
+ void Info_commande_LesCharges1(UtilLecture & entreePrinc);
+
+ // affichage et definition interactive des commandes
+ void Info_commande_LesCharges2(UtilLecture & entreePrinc);
+
+ //----- lecture écriture dans base info -----
+ // cas donne le niveau de la récupération
+ // = 1 : on récupère tout
+ // = 2 : on récupère uniquement les données variables (supposées comme telles)
+ void Lecture_base_info(ifstream& ent,const int cas,LesReferences& lesRef,LesCourbes1D& lesCourbes1D
+ ,LesFonctions_nD& lesFonctionsnD);
+ // cas donne le niveau de sauvegarde
+ // = 1 : on sauvegarde tout
+ // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
+ void Ecriture_base_info(ofstream& sort,const int cas);
+
+ private :
+ // VARIABLES PROTEGEES :
+ // les forces sont les entitees duales des degres de liberte
+ // par exemple, force ponctuelle est duale de Xi ou Ui ou Vi
+
+ // densite de force volumique dans le repère absolu
+ Tableau < BlocCharge< BlocDdlLim > > tabFvol;
+ // densite de force surfacique dans le repère absolu
+ Tableau < BlocCharge< BlocDdlLim > > tabFsurfac;
+ // pression uniformement reparti, appliquee normalement a la surface
+ Tableau < BlocCharge< BlocDdlLim > > tabPresUnif;
+ // force ponctuelle sur un noeud
+ Tableau < BlocCharge< BlocDdlLim > > tabPonctuel;
+ // pression unidirectionnelle type pression des fluides
+ Tableau < BlocCharge< BlocDdlLim > > PresUniDir;
+ // pression hydrostatique
+ Tableau < BlocCharge< BlocDdlLim > > PresHydro;
+ // pression hydrodynamique
+ Tableau < BlocCharge< BlocDdlLim > > coefHydroDyna;
+ // densite de force lineique dans le repère absolu
+ Tableau < BlocCharge< BlocDdlLim > > tabFlineique;
+ // densite de force lineique suiveuse, c'est-à-dire qui suit le repère
+ // locale (possible uniquement pour des éléments 2D)
+ Tableau < BlocCharge< BlocDdlLim > > tabFlineiqueSuiv;
+ // torseur d'effort via une répartition de charges ponctuelles
+ Tableau < BlocCharge< BlocDdlLim > > tabTorseurPonct;
+ Tableau < Tableau < Coordonnee > > tab_P; // tableau de travail pour tabTorseurPonct
+ Tableau < Tableau < Coordonnee > > t_force; // idem
+
+ // ---- type d'application du chargement -----
+ string nomtypeCharge; // mot cle du type de chargement
+ Tableau tabType; // les parametres
+ Courbe1D* f_charge; // courbe de chargement éventuelle
+ bool interne_f_charge; // indique si oui ou non la courbe interne
+ int ancien_num_pt_type5, num_pt_courant_type5; // variables de travaille pour le type 5
+
+ // les paramètres globaux
+ ParaAlgoControle* paAlgo;
+ // le parametre global d'avancement de la charge
+// double temps;
+ // compteur d'increment
+ int compteur_essai_increment;
+ // multi = l'increment courant de multiplication de la charge
+ // coeff = niveau actuel de la charge
+ double multi,coeff;
+ // la sauvegarde des paramètres d'un pas sur l'autre
+ double temps_sauve;
+ double multi_sauve,coeff_sauve;
+
+ // la manière dont on vise le temps fin
+ int temps_fin_non_stricte; // = 0 par défaut pour les schéma implicite: indique
+ // que l'on doit viser le temps fin de manière stricte (pas le dépasser)
+ // = 1 : on doit juste le dépasser -> a priori c'est le fonctionnement par défaut des
+ // algo explicites, compte tenu qu'il n'y a pas de prise en compte précise
+ // de la variation du pas de temps
+ // mise à jour avec la méthode : Change_temps_fin_non_stricte(int methode)
+
+ Temps_CPU_HZpp temps_cpu_chargement; // le temps cpu du à tous les chargements
+
+ // les autres parametres relatif au temps
+ //-// double deltatmaxi; // increment de temps maxi
+ //-// double prectemps; // precision sur le temps final
+ //-// double deltat; // increment de temps
+ //-// double tempsfin; // temps de fin de calcul
+ //-// int maxincre ; // maximum d'increment de temps
+ //-// double multiplicateur; // multiplicateur de la charge
+
+ // pointeurs des fonctions en cours
+ void (Charge::*PtDebut) (void);
+ bool (Charge::*PtAvance) (void);
+ void (Charge::*PtPrecedent) (void);
+ int (Charge::*PtFin) (const int & icharge,bool affichage); // affichage indique si oui ou non on
+ // on veut un affichage signifiant que l'on est à la fin du chargement
+
+ // METHODES PROTEGEES :
+ // declaration des initialisations en fonction du type de chargement
+ void Debut1();
+ void Debut2();
+ void Debut3();
+ void Debut4();
+ void Debut5();
+ void Debut6();
+ void Debut7();
+ // declaration de l'avancement en fonction du type de chargement
+ bool Avance1();
+ bool Avance2();
+ bool Avance3();
+ bool Avance4();
+ bool Avance5();
+ bool Avance6();
+ bool Avance7();
+ // declaration du retour à l'incrément précédent en fonction du type de chargement
+ void Precedent1();
+ void Precedent2();
+ void Precedent3();
+ void Precedent4();
+ void Precedent5();
+ void Precedent6();
+ void Precedent7();
+ // declaration de la fin en fonction du type de chargement
+ // 0 : la fin n'est pas valide, on continue
+ // 1 : temps fin dépassé
+ // 2 : compteur_increment dépassé
+ // 3 : compteur_essai_increment dépassé
+ // NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
+ // puis ensuite le compteur d'incréments
+ // puis le nombre d'essai maxi, puis enfin le cas normal
+ // si affichage est true, affichage d'un message
+ int Fin1(const int & icharge,bool affichage);
+ int Fin2(const int & icharge,bool affichage);
+ int Fin3(const int & icharge,bool affichage);
+ int Fin4(const int & icharge,bool affichage);
+ int Fin5(const int & icharge,bool affichage);
+ int Fin6(const int & icharge,bool affichage);
+ int Fin7(const int & icharge,bool affichage);
+
+
+ };
+ /// @} // end of group
+
+#endif
diff --git a/Chargement/Charge2.cc b/Chargement/Charge2.cc
new file mode 100644
index 0000000..62ba1c4
--- /dev/null
+++ b/Chargement/Charge2.cc
@@ -0,0 +1,2145 @@
+
+// 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: .
+
+
+#include "Charge.h"
+#include "ConstMath.h"
+#include "MathUtil.h"
+#include "ReferenceNE.h"
+#include "ReferenceAF.h"
+
+
+
+// mise en place du chargement impose sur le second membre global
+// cas explicite
+// la variable relative à la classe assemblage est passé en argument ce qui permet d'utiliser
+// éventuellement plusieurs type d'assemblage
+// retour false si problème de calcul
+bool Charge::ChargeSecondMembre_Ex_mecaSolid
+ (Assemblage & assemb,LesMaillages * lesMail,LesReferences* lesRef,Vecteur& vecglob
+ ,const ParaAlgoControle & pa,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD)
+ {
+ temps_cpu_chargement.Mise_en_route_du_comptage(); // temps cpu
+ bool retour = true; // init par défaut
+ try
+ {
+ // pour tous les maillages, pour tous les éléments on effectue une initialisation éventuelle
+ int nb_mail = lesMail->NbMaillage();
+ for (int imail = 1;imail<=nb_mail;imail++)
+ { int nb_ele = lesMail->Nombre_element(imail);
+ for (int iele =1;iele<=nb_ele;iele++)
+ lesMail->Element_LesMaille(imail,iele).Initialisation_avant_chargement();
+ };
+
+ int posi = Id_nom_ddl("X1") -1;
+ int dim = ParaGlob::Dimension();
+
+ // $$$ --- cas des forces ponctuelles --- $$$
+
+ // on regarde si l'espace de travail est axi-symétrique, si oui on utilise une dimension réduite
+ int dima=dim; // c'est dima qui est utiliser pour la mise en place des efforts ponctuelles
+ if (ParaGlob::AxiSymetrie()) dima--;
+ // on parcours le tableau tabPonctuel
+ for (int i=1;i<= tabPonctuel.Taille();i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabPonctuel_i = tabPonctuel(i);
+ const ReferenceNE & ref =
+ ((ReferenceNE &) lesRef->Trouve(tabPonctuel_i.NomRef(),tabPonctuel_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabPonctuel_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabPonctuel_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabPonctuel_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {int reftaille = ref.Taille();
+ int cas_assemblage = (assemb.Nb_cas_assemb()).n; // récup du cas d'assemblage
+ for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
+ { Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
+ Coordonnee force; // init
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabPonctuel_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ force = (tabPonctuel_i.Vect_de_coordonnee(nn)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_nn_3 =
+ lesCourbes1D->Trouve(tabPonctuel_i.Nom_vect(nn,3));
+ force(3) = pt_courbe_force_nn_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_nn_2 =
+ lesCourbes1D->Trouve(tabPonctuel_i.Nom_vect(nn,2));
+ force(2) = pt_courbe_force_nn_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_nn_1 =
+ lesCourbes1D->Trouve(tabPonctuel_i.Nom_vect(nn,1));
+ force(1) = pt_courbe_force_nn_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ force = (tabPonctuel_i.Vect_de_coordonnee(1)); break;
+ };
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ // ou au point + grandeurs globales éventuelles
+ const string & nomF_charge = tabPonctuel_i.NomF_charge();
+ if(nomF_charge.length())
+ {Fonction_nD * pt_fonct = lesFonctionsnD->Trouve(nomF_charge);
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ { // on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des forces ponctuelles sur la ref: "<< tabPonctuel_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else if (pt_fonct->Depend_M() != 0) // signifie qu'il y a une dépendance au point M
+ { if ((pt_fonct->Depend_M()<0) && pt_fonct->Nom_variables().Taille() == dima)
+ { // on vérifie également qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ const Coordonnee& M_tdt = noe.Coord2();
+ // 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 tab_M(1,M_tdt);
+ Tableau & tava = pt_fonct->Val_FnD_Evoluee(NULL,&tab_M,NULL); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des forces ponctuelles sur la ref: "<< tabPonctuel_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 ou de la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else
+ { if ((pt_fonct->Depend_M()>0)|| pt_fonct->Nom_variables().Taille() != dima)
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisant les coordonnees du point"
+ << " cas des forces ponctuelles sur la ref: "<< tabPonctuel_i.NomRef()
+ << " actuellement la fonction doit avoir uniquement comme parametres, les coordonnees du point et eventuellement des variables globales ";
+ cout << "\n fonction nD: "; pt_fonct->Affiche();
+ Sortie(1);
+ };
+ };
+ }
+ };
+
+ if ((noe.Pointeur_assemblage(X1,cas_assemblage) != -1) && (noe.En_service(X1)) && (noe.UneVariable(X1)))
+ // les forces ponctuelles correspondent aux ddl X1 X2 ...
+ for (int di=1;di<= dima;di++)
+ {// maintenant deux cas: soit avec ou sans courbes de charge
+ int pt_adres = noe.Pointeur_assemblage(Enum_ddl(posi+di),cas_assemblage);
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ // cas d'une grandeur fixe
+ { vecglob (pt_adres) += coeff * (force(di));}
+ else // cas d'une fonction nD sans courbe
+ { vecglob (pt_adres) += (force(di))* tabPonctuel_i.Echelle_courbe();}
+ }
+ else
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabPonctuel_i.Echelle_courbe();
+ vecglob (pt_adres) += coeff_charge * (force(di));
+ };
+ };
+ };
+ };
+ };
+
+
+ // $$$ --- cas des torseurs de forces ponctuelles --- $$$
+
+ // on parcours le tableau tabTorseurPonct
+ for (int i=1;i<= tabTorseurPonct.Taille();i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabTorseurPonct_i = tabTorseurPonct(i);
+ const ReferenceNE & ref =
+ ((ReferenceNE &) lesRef->Trouve(tabTorseurPonct_i.NomRef(),tabTorseurPonct_i.NomMaillage()));
+ // dans le cas d'une courbe de charge globale on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabTorseurPonct_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabTorseurPonct_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabTorseurPonct_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {int reftaille = ref.Taille();
+ int cas_assemblage = (assemb.Nb_cas_assemb()).n; // récup du cas d'assemblage
+ // on renseigne les positions des points où vont s'appliquer les forces équivalentes au torseur
+ Tableau < Coordonnee >& tab_P_i = tab_P(i); // pour simplier
+ Tableau < Coordonnee >& t_force_i = t_force(i); // idem
+ for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
+ { Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
+ tab_P_i(nn) = noe.Coord2();
+ };
+ // on calcul les efforts ponctuelles correspondant au torseur
+ tabTorseurPonct_i.Force(tab_P_i,t_force_i);
+ // maintenant on calcule l'action de chaque force ponctuelle
+ for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
+ { Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
+ Coordonnee& force = t_force_i(nn); // pour simplifier
+ // on regarde si jamais on a une dépendance globale à des grandeurs globales
+ // ou au point + grandeurs globales éventuelles
+ const string & nomF_charge = tabTorseurPonct_i.NomF_charge();
+ if(nomF_charge.length())
+ {Fonction_nD * pt_fonct = lesFonctionsnD->Trouve(nomF_charge);
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ { // on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des torseurs de forces ponctuelles sur la ref: "
+ << tabTorseurPonct_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else if (pt_fonct->Depend_M() != 0) // signifie qu'il y a une dépendance au point M
+ { if ((pt_fonct->Depend_M()<0) && pt_fonct->Nom_variables().Taille() == dima)
+ { // on vérifie également qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ const Coordonnee& M_tdt = noe.Coord2();
+ // 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 tab_M(1,M_tdt);
+ Tableau & tava = pt_fonct->Val_FnD_Evoluee(NULL,&tab_M,NULL); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des torseurs de forces ponctuelles sur la ref: "
+ << tabTorseurPonct_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 ou de la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else
+ { if ((pt_fonct->Depend_M()>0)|| pt_fonct->Nom_variables().Taille() != dima)
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisant les coordonnees du point"
+ << " cas des forces ponctuelles sur la ref: "<< tabTorseurPonct_i.NomRef()
+ << " actuellement la fonction doit avoir uniquement comme parametres, les coordonnees du point et eventuellement des variables globales ";
+ cout << "\n fonction nD: "; pt_fonct->Affiche();
+ Sortie(1);
+ };
+ };
+ }
+ };
+
+ if ((noe.Pointeur_assemblage(X1,cas_assemblage) != -1) && (noe.En_service(X1)) && (noe.UneVariable(X1)))
+ // les forces ponctuelles correspondent aux ddl X1 X2 ...
+ for (int di=1;di<= dima;di++)
+ {// maintenant deux cas: soit avec ou sans courbes de charge
+ int pt_adres = noe.Pointeur_assemblage(Enum_ddl(posi+di),cas_assemblage);
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ // cas d'une grandeur fixe
+ { vecglob (pt_adres) += coeff * (force(di));}
+ else // cas d'une fonction nD sans courbe
+ { vecglob (pt_adres) += (force(di))* tabTorseurPonct_i.Echelle_courbe();}
+ }
+ else
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabTorseurPonct_i.Echelle_courbe();
+ vecglob (pt_adres) += coeff_charge * (force(di));
+ };
+ };
+ };
+ };
+ };
+
+ // --- cas des forces surfaciques ---$$$
+ int tabsurfactaille = tabFsurfac.Taille();
+ if ( tabsurfactaille != 0)
+ {// on parcours le tableau tabFsurfac dans le repère absolu
+ for (int i=1;i<= tabsurfactaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabFsurfac_i = tabFsurfac(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabFsurfac_i.NomRef(),tabFsurfac_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFsurfac_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFsurfac_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFsurfac_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ Coordonnee vforce; // init par défaut
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFsurfac_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ vforce = (tabFsurfac_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFsurfac_i.Nom_vect(ns,3));
+ vforce(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFsurfac_i.Nom_vect(ns,2));
+ vforce(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFsurfac_i.Nom_vect(ns,1));
+ vforce(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ vforce = (tabFsurfac_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFsurfac_i.NomF_charge();
+ Fonction_nD * pt_fonct=NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFsurfac_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {vforce *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : vforce(3) *= tava(3);
+ case 2 : vforce(2) *= tava(2);
+ case 1 : vforce(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des forces surfaciques sur la ref: "<< tabFsurfac_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { vforce *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { vforce *= tabFsurfac_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFsurfac_i.Echelle_courbe();
+ vforce *= coeff_charge;
+ };
+ // appel du calcul du second membre correspondant à la charge surfacique
+ // Coordonnee vforce = tabFsurfac_i.Coord() * coeff;
+ Vecteur SM = elem.SM_charge_surfacique_E_tdt(vforce,pt_fonct,ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL; // init
+ if (ParaGlob::AxiSymetrie())
+ // dans le cas axiSymétrique, les surfaces sont générées par les lignes,
+ {elfront = elem.Frontiere_lineique(ref.NumeroFA(ns));}
+ else // cas normale
+ {elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); };// la surface frontière
+ assemb.AssemSM (vecglob,SM,elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ };
+ };
+ };
+ };
+
+ // --- cas des pressions ---$$$
+ int tabPresUniftaille = tabPresUnif.Taille();
+ if ( tabPresUniftaille != 0)
+ {// on parcours le tableau tabPresUnif
+ for (int i=1;i<= tabPresUniftaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabPresUnif_i = tabPresUnif(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabPresUnif_i.NomRef(),tabPresUnif_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabPresUnif_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabPresUnif_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabPresUnif_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ double press_ac = 0.; // init
+ // récupération de la pression de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabPresUnif_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ press_ac = (tabPresUnif_i.Val(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ { Courbe1D * pt_courbe_force_ns =
+ lesCourbes1D->Trouve(tabPresUnif_i.Nom_val(ns));
+ press_ac = pt_courbe_force_ns->Valeur(Temps_courant());
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ press_ac = (tabPresUnif_i.Val(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabPresUnif_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabPresUnif_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {press_ac *= tava(1);}
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas de pression sur la ref: "<< tabPresUnif_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { press_ac *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { press_ac *= tabPresUnif_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabPresUnif_i.Echelle_courbe();
+ press_ac *= coeff_charge;
+ };
+ // appel du calcul du second membre correspondant à la charge de type pression
+ // double press_ac = (tabPresUnif_i.Val()) * coeff;
+ Vecteur SM = elem.SM_charge_pression_E_tdt(press_ac,pt_fonct,ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL; // init
+ if (ParaGlob::AxiSymetrie())
+ // dans le cas axiSymétrique, les surfaces sont générées par les lignes,
+ {elfront = elem.Frontiere_lineique(ref.NumeroFA(ns));}
+ else // cas normale
+ {elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); };// la surface frontière
+ assemb.AssemSM (vecglob,SM,elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ };
+ };
+ }
+ };
+
+ // --- cas des pression unidirectionnelle ---
+ // c'est-à-dire des forces qui sont appliquée sur la surface en gardant la même
+ // direction localement pendant toute la transformation
+ int PresUniDirtaille = PresUniDir.Taille();
+ if ( PresUniDirtaille != 0)
+ {// on parcours le tableau PresUniDir
+ for (int i=1;i<= PresUniDirtaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& PresUniDir_i = PresUniDir(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(PresUniDir_i.NomRef(),PresUniDir_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(PresUniDir_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(PresUniDir_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(PresUniDir_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ Coordonnee press_uni; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (PresUniDir_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ press_uni = (PresUniDir_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(PresUniDir_i.Nom_vect(ns,3));
+ press_uni(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(PresUniDir_i.Nom_vect(ns,2));
+ press_uni(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(PresUniDir_i.Nom_vect(ns,1));
+ press_uni(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ press_uni = (PresUniDir_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = PresUniDir_i.NomF_charge();
+ Fonction_nD * pt_fonct=NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(PresUniDir_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {press_uni *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : press_uni(3) *= tava(3);
+ case 2 : press_uni(2) *= tava(2);
+ case 1 : press_uni(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des pression unidirectionnelle sur la ref: "<< PresUniDir_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { press_uni *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { press_uni *= PresUniDir_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * PresUniDir_i.Echelle_courbe();
+ press_uni *= coeff_charge;
+ };
+ // appel du calcul du second membre correspondant à la charge de type pression
+ // Coordonnee press_uni = (PresUniDir_i.Coord()) * coeff;
+ Vecteur SM = elem.SM_charge_presUniDir_E_tdt(press_uni,pt_fonct,ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL; // init
+ if (ParaGlob::AxiSymetrie())
+ // dans le cas axiSymétrique, les surfaces sont générées par les lignes,
+ {elfront = elem.Frontiere_lineique(ref.NumeroFA(ns));}
+ else // cas normale
+ {elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); };// la surface frontière
+ assemb.AssemSM (vecglob,SM,elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ };
+ };
+ };
+ };
+
+ // --- cas des forces lineique ---$$$
+ int tablineiquetaille = tabFlineique.Taille();
+ if ( tablineiquetaille != 0)
+ {// on parcours le tableau tabFlineique dans le repère absolu
+ for (int i=1;i<= tablineiquetaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabFlineique_i = tabFlineique(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabFlineique_i.NomRef(),tabFlineique_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFlineique_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFlineique_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFlineique_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les aretes associes
+ int nbref = ref.Taille();
+ Coordonnee f_lin; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFlineique_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ f_lin = (tabFlineique_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFlineique_i.Nom_vect(ns,3));
+ f_lin(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFlineique_i.Nom_vect(ns,2));
+ f_lin(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFlineique_i.Nom_vect(ns,1));
+ f_lin(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ f_lin = (tabFlineique_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFlineique_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFlineique_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {f_lin *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : f_lin(3) *= tava(3);
+ case 2 : f_lin(2) *= tava(2);
+ case 1 : f_lin(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des forces lineiques sur la ref: "<< tabFlineique_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { f_lin *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { f_lin *= tabFlineique_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFlineique_i.Echelle_courbe();
+ f_lin *= coeff_charge;
+ };
+ // appel du calcul du second membre correspondant à la charge lineique
+ // Vecteur f_lin = (tabFlineique_i.Coord()) * coeff ;
+ Vecteur SM = elem.SM_charge_lineique_E_tdt(f_lin,pt_fonct,ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la ligne chargée
+ const ElFrontiere* elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // l'arete frontière
+ assemb.AssemSM (vecglob,SM,elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ };
+ };
+ }
+ };
+
+ // --- cas des forces lineiques suiveuses ---$$$
+ int tablineiqueSuivtaille = tabFlineiqueSuiv.Taille();
+ if ( tablineiqueSuivtaille != 0)
+ {// on parcours le tableau tabFlineiqueSuiv des forces exprimées dans le repère global
+ for (int i=1;i<= tablineiqueSuivtaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim > & tabFlineiqueSuiv_i = tabFlineiqueSuiv(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabFlineiqueSuiv_i.NomRef(),tabFlineiqueSuiv_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFlineiqueSuiv_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFlineiqueSuiv_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFlineiqueSuiv_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les aretes associes
+ int nbref = ref.Taille();
+ Coordonnee f_lin; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFlineiqueSuiv_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ f_lin = (tabFlineiqueSuiv_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFlineiqueSuiv_i.Nom_vect(ns,3));
+ f_lin(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFlineiqueSuiv_i.Nom_vect(ns,2));
+ f_lin(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFlineiqueSuiv_i.Nom_vect(ns,1));
+ f_lin(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ f_lin = (tabFlineiqueSuiv_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFlineiqueSuiv_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFlineiqueSuiv_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {f_lin *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : f_lin(3) *= tava(3);
+ case 2 : f_lin(2) *= tava(2);
+ case 1 : f_lin(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des forces lineiques suiveuses sur la ref: "<< tabFlineiqueSuiv_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { f_lin *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { f_lin *= tabFlineiqueSuiv_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFlineiqueSuiv_i.Echelle_courbe();
+ f_lin *= coeff_charge;
+ }
+ // appel du calcul du second membre correspondant à la charge lineique
+ // Vecteur f_lin = (tabFlineiqueSuiv_i.Coord()) * coeff ;
+ Vecteur SM = elem.SM_charge_lineique_Suiv_E_tdt(f_lin,pt_fonct,ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la ligne chargée
+ const ElFrontiere* elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // l'arete frontière
+ assemb.AssemSM (vecglob,SM,elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ };
+ };
+ }
+ };
+
+ // --- cas des forces volumiques ---$$$
+ int tabvoltaille = tabFvol.Taille();
+ if ( tabvoltaille != 0)
+ {// on parcours le tableau tabFvol dans le repère absolu
+ for (int i=1;i<= tabvoltaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabFvol_i = tabFvol(i);
+ const ReferenceNE & ref =
+ ((ReferenceNE &) lesRef->Trouve(tabFvol_i.NomRef(),tabFvol_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFvol_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFvol_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFvol_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments
+ int nbref = ref.Taille();
+ Coordonnee f_vol; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.Numero(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFvol_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ f_vol = (tabFvol_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFvol_i.Nom_vect(ns,3));
+ f_vol(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFvol_i.Nom_vect(ns,2));
+ f_vol(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFvol_i.Nom_vect(ns,1));
+ f_vol(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ f_vol = (tabFvol_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFvol_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFvol_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {f_vol *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : f_vol(3) *= tava(3);
+ case 2 : f_vol(2) *= tava(2);
+ case 1 : f_vol(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des forces lineiques sur la ref: "<< tabFvol_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { f_vol *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { f_vol *= tabFvol_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFvol_i.Echelle_courbe();
+ f_vol *= coeff_charge;
+ };
+ // on indique si éventuellement on veut se référer au volume initial
+ bool volume_finale = !(tabFvol_i.Attribut() == "sur_volume_initial_");
+ // appel du calcul du second membre correspondant à la charge volumique
+ // Vecteur f_vol = (tabFvol_i.Coord()) * coeff;
+ Vecteur SM = elem.SM_charge_volumique_E_tdt(f_vol,pt_fonct,pa,volume_finale);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à l'élément
+ assemb.AssemSM (vecglob,SM,elem.TableauDdl(),elem.Tab_noeud()); // assemblage
+ };
+ };
+ }
+ }
+
+ // --- cas des des pressions hydrostatiques ---$$$
+ int PresHydrotaille = PresHydro.Taille();
+ if ( PresHydrotaille != 0)
+ {// on parcours le tableau PresHydro
+ for (int i=1;i<= PresHydrotaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim > & PresHydro_i = PresHydro(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(PresHydro_i.NomRef(),PresHydro_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(PresHydro_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(PresHydro_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(PresHydro_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ // on récupère le vecteur normal et le point de la surface libre
+ const Coordonnee& N = PresHydro_i.Direction_N(); // récup de la direction N normée
+ const Coordonnee& A = PresHydro_i.Point_M(); // récup du point de la surface libre
+ double p_hydro_ref = (PresHydro_i.Val(1));
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ double p_hydro = p_hydro_ref;
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ { p_hydro *= coeff;} // cas d'une grandeur fixe
+ else
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * PresHydro_i.Echelle_courbe();
+ p_hydro *= coeff_charge;
+ }
+ // appel du calcul du second membre correspondant à la charge de type pression
+ bool sans_limitation=false;
+ if (PresHydro_i.Attribut() == "sans_limitation_") sans_limitation= true;
+ Vecteur SM = elem.SM_charge_hydrostatique_E_tdt
+ (N,p_hydro,ref.NumeroFA(ns),A,pa,sans_limitation) ;
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL; // init
+ if (ParaGlob::AxiSymetrie())
+ // dans le cas axiSymétrique, les surfaces sont générées par les lignes,
+ {elfront = elem.Frontiere_lineique(ref.NumeroFA(ns));}
+ else // cas normale
+ {elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); };// la surface frontière
+ assemb.AssemSM (vecglob,SM,elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ }
+ };
+ }
+ };
+
+ // --- cas des des efforts hydrodynamiques ---$$$
+ int coefHydroDynataille = coefHydroDyna.Taille();
+ if ( coefHydroDynataille != 0)
+ {// on parcours le tableau coefHydroDyna
+ for (int i=1;i<= coefHydroDynataille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim > & coefHydroDyna_i = coefHydroDyna(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(coefHydroDyna_i.NomRef(),coefHydroDyna_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(coefHydroDyna_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(coefHydroDyna_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(coefHydroDyna_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les noeuds ou arretes ou surfaces associes suivant la dimension
+ int nbref = ref.Taille();
+ // récup du poids volumique poids volumique = ro * g, qui n'est pas soumis à la courbe de charge
+ double poidvol = (coefHydroDyna_i.Val(1));
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ double coeff_charge=1.;
+ if(pt_courbe != NULL)
+ { coeff_charge = (pt_courbe->Valeur(Temps_courant())) * coefHydroDyna_i.Echelle_courbe();};
+ // appel du calcul du second membre correspondant aux efforts hydrodynamique
+ Vecteur SM = elem.SM_charge_hydrodynamique_E_tdt(coefHydroDyna_i.Frot_fluid(),poidvol
+ ,coefHydroDyna_i.Coef_aero_n(),ref.NumeroFA(ns),coeff_charge
+ ,coefHydroDyna_i.Coef_aero_t(),pa) ;
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront;
+ switch (ParaGlob::Dimension())
+ { case 3: {elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); break;};// la surface frontière
+ case 2: {elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); break;};// la ligne frontière
+ case 1: {elfront = elem.Frontiere_points(ref.NumeroFA(ns)); break;};// le point frontière
+ };
+ assemb.AssemSM (vecglob,SM,elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ };
+ };
+ };
+ }; //-- fin de hydrodyna
+
+ // affichage éventuelle du second membre
+ if (ParaGlob::NiveauImpression() >= 10)
+ { string entete = " affichage du second membre apres chargement";
+ vecglob.Affichage_ecran(entete);
+ };
+ }
+ catch (ErrSortieFinale)
+ // cas d'une direction voulue vers la sortie
+ // on relance l'interuption pour le niveau supérieur
+ { ErrSortieFinale toto;
+ throw (toto);
+ }
+ catch ( ... )
+ { if (ParaGlob::NiveauImpression() >= 1)
+ {cout << "\n\n ****!!** erreur dans le calcul du chargement impose ***";
+ if (ParaGlob::NiveauImpression() >= 4)
+ cout << "\n Charge::ChargeSecondMembre_Ex_mecaSolid(..";
+ cout << flush;
+ };
+ retour = false;
+ };
+
+ temps_cpu_chargement.Arret_du_comptage();
+ return retour;
+ };
+
+
+// cas implicite avec également modification de la raideur quand le chargement dépend
+// de la géométrie, en fonction des paramètres de pa
+// la variable relative à la classe assemblage est passé en argument ce qui permet d'utiliser
+// éventuellement plusieurs type d'assemblage
+// de plus il faut prévoir un pointeur d'assemblage pour séparer le cas d'assemblage symétrique ou non
+// d'où la variable pointeur de fonction membre d'assemblage
+// retour false si problème de calcul
+bool Charge::ChargeSMembreRaideur_Im_mecaSolid
+ (Assemblage & assemb,LesMaillages * lesMail,LesReferences* lesRef
+ ,Vecteur& vecglob, Mat_abstraite& matglob
+ ,void (Assemblage::* assembMat) // le pointeur de fonction
+ (Mat_abstraite & matglob,const Mat_abstraite & matloc,
+ const DdlElement& tab_ddl,const Tableau&tab_noeud)
+ ,const ParaAlgoControle & pa
+ ,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD)
+ {
+ temps_cpu_chargement.Mise_en_route_du_comptage();
+ bool retour = true; // init par défaut
+ try
+ {// pour tous les maillages, pour tous les éléments on effectue une initialisation éventuelle
+ int nb_mail = lesMail->NbMaillage();
+ for (int imail = 1;imail<=nb_mail;imail++)
+ { int nb_ele = lesMail->Nombre_element(imail);
+ for (int iele =1;iele<=nb_ele;iele++)
+ lesMail->Element_LesMaille(imail,iele).Initialisation_avant_chargement();
+ };
+
+ // récup
+ bool avec_raid = pa.Var_charge_externe();
+ int cas_assemblage = (assemb.Nb_cas_assemb()).n; // récup du cas d'assemblage
+ int posi = Id_nom_ddl("X1") -1;
+ int dim = ParaGlob::Dimension();
+
+ // $$$--- cas des forces ponctuelles ---$$$
+ // on regarde si l'espace de travail est axi-symétrique, si oui on utilise une dimension réduite
+ int dima=dim; // c'est dima qui est utiliser pour la mise en place des efforts ponctuelles
+ if (ParaGlob::AxiSymetrie()) dima--;
+ // on parcours le tableau tabPonctuel
+ // ici il n'y a pas d'implication sur la raideur
+ for (int i=1;i<= tabPonctuel.Taille();i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabPonctuel_i = tabPonctuel(i);
+//tabPonctuel_i.Affiche();cout << endl;
+ const ReferenceNE & ref =
+ ((ReferenceNE &) lesRef->Trouve(tabPonctuel_i.NomRef(),tabPonctuel_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabPonctuel_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabPonctuel_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabPonctuel_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {int reftaille = ref.Taille();
+ for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
+ { Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
+ Coordonnee force; // init
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabPonctuel_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ force = (tabPonctuel_i.Vect_de_coordonnee(nn)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_nn_3 =
+ lesCourbes1D->Trouve(tabPonctuel_i.Nom_vect(nn,3));
+ force(3) = pt_courbe_force_nn_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_nn_2 =
+ lesCourbes1D->Trouve(tabPonctuel_i.Nom_vect(nn,2));
+ force(2) = pt_courbe_force_nn_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_nn_1 =
+ lesCourbes1D->Trouve(tabPonctuel_i.Nom_vect(nn,1));
+ force(1) = pt_courbe_force_nn_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ force = (tabPonctuel_i.Vect_de_coordonnee(1)); break;
+ };
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabPonctuel_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(nomF_charge);
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ { // on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des forces ponctuelles sur la ref: "<< tabPonctuel_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else if (pt_fonct->Depend_M() != 0) // signifie qu'il y a une dépendance au point M
+ { if ((pt_fonct->Depend_M()<0) && pt_fonct->Nom_variables().Taille() == dima)
+ { // on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ const Coordonnee& M_tdt = noe.Coord2();
+ Tableau tab_M(1,M_tdt);
+ Tableau & tava = pt_fonct->Val_FnD_Evoluee(NULL,&tab_M,NULL); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+////----- debug ---
+//cout << "\n debug Charge::ChargeSMembreRaideur_Im_mecaSolid ** ";
+//cout << "\n tava= " << tava << endl;
+//
+////--- fin debug ---
+
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des forces ponctuelles sur la ref: "<< tabPonctuel_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 ou de la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else
+ { if ((pt_fonct->Depend_M()>0)|| pt_fonct->Nom_variables().Taille() != dima)
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisant les coordonnees du point"
+ << " cas des forces ponctuelles sur la ref: "<< tabPonctuel_i.NomRef()
+ << " actuellement la fonction doit avoir uniquement comme parametres, les coordonnees du point et eventuellement des variables globales ";
+ cout << "\n fonction nD: "; pt_fonct->Affiche();
+ Sortie(1);
+ };
+ };
+ };
+ };
+ // les efforts s'appliques sur les ddl de position, il faut donc que X1 soit actif
+ // pour le cas d'assemblage considéré et en activité
+ if ((noe.Pointeur_assemblage(X1,cas_assemblage) != -1) && (noe.En_service(X1))
+ && (noe.UneVariable(X1)))
+ // les forces ponctuelles correspondent aux ddl 1 2 ...
+ for (int di=1;di<= dima;di++)
+ {// maintenant deux cas: soit avec ou sans courbes de charge
+ int pt_adres = noe.Pointeur_assemblage(Enum_ddl(posi+di),cas_assemblage);
+ if (pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ // cas d'une grandeur fixe
+ { vecglob (pt_adres) += coeff * (force(di));}
+ else // cas d'une fonction nD sans courbe
+ { vecglob (pt_adres) += (force(di))* tabPonctuel_i.Echelle_courbe();}
+ }
+ else // cas avec courbe, avec ou sans fonction c'est pareil
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabPonctuel_i.Echelle_courbe();
+ vecglob (pt_adres) += coeff_charge * (force(di));
+ };
+ };
+ };
+ };
+ };
+
+
+ // $$$--- cas des torseurs de forces ponctuelles ---$$$
+ for (int i=1;i<= tabTorseurPonct.Taille();i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabTorseurPonct_i = tabTorseurPonct(i);
+//tabTorseurPonct_i.Affiche();cout << endl;
+ const ReferenceNE & ref =
+ ((ReferenceNE &) lesRef->Trouve(tabTorseurPonct_i.NomRef(),tabTorseurPonct_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabTorseurPonct_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabTorseurPonct_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabTorseurPonct_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {int reftaille = ref.Taille();
+ // on renseigne les positions des points où vont s'appliquer les forces équivalentes au torseur
+ Tableau < Coordonnee >& tab_P_i = tab_P(i); // pour simplier
+ Tableau < Coordonnee >& t_force_i = t_force(i); // idem
+ for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
+ { Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
+ tab_P_i(nn) = noe.Coord2();
+ };
+ // on calcul les efforts ponctuelles correspondant au torseur
+ tabTorseurPonct_i.Force(tab_P_i,t_force_i);
+ // maintenant on calcule l'action de chaque force ponctuelle
+ for (int nn =1; nn<= reftaille;nn++) // nn = position des num de noeud
+ { Noeud & noe=lesMail->Noeud_LesMaille(ref.Nbmaille(),ref.Numero(nn));
+ Coordonnee& force = t_force_i(nn); // pour simplifier
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabTorseurPonct_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(nomF_charge);
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ { // on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des torseurs de forces ponctuelles sur la ref: "<< tabTorseurPonct_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else if (pt_fonct->Depend_M() != 0) // signifie qu'il y a une dépendance au point M
+ { if ((pt_fonct->Depend_M()<0) && pt_fonct->Nom_variables().Taille() == dima)
+ { // on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ const Coordonnee& M_tdt = noe.Coord2();
+ Tableau tab_M(1,M_tdt);
+ Tableau & tava = pt_fonct->Val_FnD_Evoluee(NULL,&tab_M,NULL); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {force *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : force(3) *= tava(3);
+ case 2 : force(2) *= tava(2);
+ case 1 : force(1) *= tava(1);
+////----- debug ---
+//cout << "\n debug Charge::ChargeSMembreRaideur_Im_mecaSolid ** ";
+//cout << "\n tava= " << tava << endl;
+//
+////--- fin debug ---
+
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des torseurs de forces ponctuelles sur la ref: "<< tabTorseurPonct_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 ou de la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ }
+ else
+ { if ((pt_fonct->Depend_M()>0)|| pt_fonct->Nom_variables().Taille() != dima)
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD utilisant les coordonnees du point"
+ << " cas des des torseurs de ponctuelles sur la ref: "<< tabTorseurPonct_i.NomRef()
+ << " actuellement la fonction doit avoir uniquement comme parametres, les coordonnees du point et eventuellement des variables globales ";
+ cout << "\n fonction nD: "; pt_fonct->Affiche();
+ Sortie(1);
+ };
+ };
+ };
+ };
+ // les efforts s'appliques sur les ddl de position, il faut donc que X1 soit actif
+ // pour le cas d'assemblage considéré et en activité
+ if ((noe.Pointeur_assemblage(X1,cas_assemblage) != -1) && (noe.En_service(X1))
+ && (noe.UneVariable(X1)))
+ // les forces ponctuelles correspondent aux ddl 1 2 ...
+ for (int di=1;di<= dima;di++)
+ {// maintenant deux cas: soit avec ou sans courbes de charge
+ int pt_adres = noe.Pointeur_assemblage(Enum_ddl(posi+di),cas_assemblage);
+ if (pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ // cas d'une grandeur fixe
+ { vecglob (pt_adres) += coeff * (force(di));}
+ else // cas d'une fonction nD sans courbe
+ { vecglob (pt_adres) += (force(di))* tabTorseurPonct_i.Echelle_courbe();}
+ }
+ else // cas avec courbe, avec ou sans fonction c'est pareil
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabTorseurPonct_i.Echelle_courbe();
+ vecglob (pt_adres) += coeff_charge * (force(di));
+ };
+ };
+ };
+ };
+ };
+
+ // $$$--- cas des forces surfaciques ---$$$
+ // il y a une implication éventuelle sur la raideur
+ int tabsurfactaille = tabFsurfac.Taille();
+ if ( tabsurfactaille != 0)
+ {// on parcours le tableau tabFsurfac dans le repère absolu
+ for (int i=1;i<= tabsurfactaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabFsurfac_i = tabFsurfac(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabFsurfac_i.NomRef(),tabFsurfac_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFsurfac_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFsurfac_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFsurfac_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ Coordonnee vforce; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFsurfac_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ vforce = (tabFsurfac_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFsurfac_i.Nom_vect(ns,3));
+ vforce(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFsurfac_i.Nom_vect(ns,2));
+ vforce(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFsurfac_i.Nom_vect(ns,1));
+ vforce(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ vforce = (tabFsurfac_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFsurfac_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFsurfac_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {vforce *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : vforce(3) *= tava(3);
+ case 2 : vforce(2) *= tava(2);
+ case 1 : vforce(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des forces surfaciques sur la ref: "<< tabFsurfac_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { vforce *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { vforce *= tabFsurfac_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFsurfac_i.Echelle_courbe();
+ vforce *= coeff_charge;
+ };
+ // -- appel du calcul du second membre et de la raideur éventuelle
+ // correspondant à la charge surfacique
+ Element::ResRaid resu = elem.SMR_charge_surfacique_I(vforce,pt_fonct,ref.NumeroFA(ns),pa);
+ // ((tabFsurfac_i.Coord())*coeff ,ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL;
+ if (!ParaGlob::AxiSymetrie())
+ elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); // la surface frontière: cas normal
+ else // cas axisymétrique
+ elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // la surface arête générant une surface en rotation
+ assemb.AssemSM (vecglob,*(resu.res),elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage du second membre
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elfront->DdlElem_const(),elfront->TabNoeud_const());
+ };
+ };
+ };
+ };
+
+ // $$$--- cas des pressions ---$$$
+ int tabPresUniftaille = tabPresUnif.Taille();
+ if ( tabPresUniftaille != 0)
+ {// on parcours le tableau tabPresUnif
+ for (int i=1;i<= tabPresUniftaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabPresUnif_i = tabPresUnif(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabPresUnif_i.NomRef(),tabPresUnif_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabPresUnif_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabPresUnif_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabPresUnif_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ double press_ac = 0.; // init
+ // récupération de la pression de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabPresUnif_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ press_ac = (tabPresUnif_i.Val(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ { Courbe1D * pt_courbe_force_ns =
+ lesCourbes1D->Trouve(tabPresUnif_i.Nom_val(ns));
+ press_ac = pt_courbe_force_ns->Valeur(Temps_courant());
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ press_ac = (tabPresUnif_i.Val(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabPresUnif_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabPresUnif_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ { // on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {press_ac *= tava(1);}
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas de pression sur la ref: "<< tabPresUnif_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { press_ac *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { press_ac *= tabPresUnif_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabPresUnif_i.Echelle_courbe();
+ press_ac *= coeff_charge;
+ }
+ // appel du calcul du second membre et de la raideur éventuelle
+ // correspondant à la charge de type pression
+ Element::ResRaid resu = elem.SMR_charge_pression_I(press_ac,pt_fonct,ref.NumeroFA(ns),pa);
+ // (coeff *(tabPresUnif_i.Val()),ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL;
+ if (!ParaGlob::AxiSymetrie())
+ elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); // la surface frontière: cas normal
+ else // cas axisymétrique
+ elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // la surface arête générant une surface en rotation
+ assemb.AssemSM (vecglob,*(resu.res),elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elfront->DdlElem_const(),elfront->TabNoeud_const());
+ }
+ };
+ }
+ }
+
+
+ // $$$--- cas des pression unidirectionnelle ---$$$
+ // c'est-à-dire des forces qui sont appliquée sur la surface en gardant la même
+ // direction localement pendant toute la transformation
+ int PresUniDirtaille = PresUniDir.Taille();
+ if ( PresUniDirtaille != 0)
+ {// on parcours le tableau PresUniDir
+ for (int i=1;i<= PresUniDirtaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& PresUniDir_i = PresUniDir(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(PresUniDir_i.NomRef(),PresUniDir_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(PresUniDir_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(PresUniDir_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(PresUniDir_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ Coordonnee press_uni; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (PresUniDir_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ press_uni = (PresUniDir_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(PresUniDir_i.Nom_vect(ns,3));
+ press_uni(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(PresUniDir_i.Nom_vect(ns,2));
+ press_uni(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(PresUniDir_i.Nom_vect(ns,1));
+ press_uni(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ press_uni = (PresUniDir_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = PresUniDir_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(PresUniDir_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {press_uni *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : press_uni(3) *= tava(3);
+ case 2 : press_uni(2) *= tava(2);
+ case 1 : press_uni(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des pression unidirectionnelle sur la ref: "<< PresUniDir_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { press_uni *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { press_uni *= PresUniDir_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * PresUniDir_i.Echelle_courbe();
+ press_uni *= coeff_charge;
+ }
+ // appel du calcul du second membre et de la raideur éventuelle
+ // correspondant à la charge de type pression
+ // Vecteur pres_u = (PresUniDir_i.Coord()) * coeff;
+ Element::ResRaid resu = elem.SMR_charge_presUniDir_I(press_uni,pt_fonct,ref.NumeroFA(ns),pa);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL;
+ if (!ParaGlob::AxiSymetrie())
+ elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); // la surface frontière: cas normal
+ else // cas axisymétrique
+ elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // la surface arête générant une surface en rotation
+ assemb.AssemSM (vecglob,*(resu.res),elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elfront->DdlElem_const(),elfront->TabNoeud_const());
+ };
+ };
+ }
+ }
+
+ // $$$--- cas des forces lineique ---$$$
+ int tablineiquetaille = tabFlineique.Taille();
+ if ( tablineiquetaille != 0)
+ {// on parcours le tableau tabFlineique dans le repère absolu
+ for (int i=1;i<= tablineiquetaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabFlineique_i = tabFlineique(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabFlineique_i.NomRef(),tabFlineique_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFlineique_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFlineique_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFlineique_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les aretes associes
+ int nbref = ref.Taille();
+ Coordonnee f_lin; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFlineique_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ f_lin = (tabFlineique_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFlineique_i.Nom_vect(ns,3));
+ f_lin(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFlineique_i.Nom_vect(ns,2));
+ f_lin(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFlineique_i.Nom_vect(ns,1));
+ f_lin(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ f_lin = (tabFlineique_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFlineique_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFlineique_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {f_lin *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : f_lin(3) *= tava(3);
+ case 2 : f_lin(2) *= tava(2);
+ case 1 : f_lin(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des forces lineiques sur la ref: "<< tabFlineique_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { f_lin *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { f_lin *= tabFlineique_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFlineique_i.Echelle_courbe();
+ f_lin *= coeff_charge;
+ }
+ // appel du calcul du second membre et de la raideur éventuelle
+ // correspondant à la charge lineique
+ // Vecteur f_lin = (tabFlineique_i.Coord()) * coeff;
+ Element::ResRaid resu = elem.SMR_charge_lineique_I(f_lin,pt_fonct,ref.NumeroFA(ns),pa) ;
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la ligne chargée
+ const ElFrontiere* elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // l'arrête frontière
+ assemb.AssemSM (vecglob,*(resu.res),elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elfront->DdlElem_const(),elfront->TabNoeud_const());
+ };
+ };
+ };
+ };
+
+ // $$$--- cas des forces lineiques suiveuses ---$$$
+ int tablineiqueSuivtaille = tabFlineiqueSuiv.Taille();
+ if ( tablineiqueSuivtaille != 0)
+ {// on parcours le tableau tabFlineiqueSuiv dans le repère global
+ for (int i=1;i<= tablineiqueSuivtaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim > & tabFlineiqueSuiv_i = tabFlineiqueSuiv(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(tabFlineiqueSuiv_i.NomRef(),tabFlineiqueSuiv_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFlineiqueSuiv_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFlineiqueSuiv_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFlineiqueSuiv_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les aretes associes
+ int nbref = ref.Taille();
+ Coordonnee f_lin; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFlineiqueSuiv_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ f_lin = (tabFlineiqueSuiv_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFlineiqueSuiv_i.Nom_vect(ns,3));
+ f_lin(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFlineiqueSuiv_i.Nom_vect(ns,2));
+ f_lin(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFlineiqueSuiv_i.Nom_vect(ns,1));
+ f_lin(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ f_lin = (tabFlineiqueSuiv_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFlineiqueSuiv_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFlineiqueSuiv_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {f_lin *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : f_lin(3) *= tava(3);
+ case 2 : f_lin(2) *= tava(2);
+ case 1 : f_lin(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des forces lineiques suiveuses sur la ref: "<< tabFlineiqueSuiv_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { f_lin *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { f_lin *= tabFlineiqueSuiv_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFlineiqueSuiv_i.Echelle_courbe();
+ f_lin *= coeff_charge;
+ }
+ // appel du calcul du second membre et de la raideur éventuelle
+ // correspondant à la charge lineique
+ // Vecteur f_lin = (tabFlineiqueSuiv_i.Coord()) * coeff;
+ Element::ResRaid resu = elem.SMR_charge_lineique_Suiv_I(f_lin,pt_fonct,ref.NumeroFA(ns),pa) ;
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la ligne chargée
+ const ElFrontiere* elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // l'arrête frontière
+ assemb.AssemSM (vecglob,*(resu.res),elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elfront->DdlElem_const(),elfront->TabNoeud_const());
+ };
+ };
+ };
+ };
+
+ // $$$--- cas des forces volumiques ---$$$
+ int tabvoltaille = tabFvol.Taille();
+ if ( tabvoltaille != 0)
+ {// on parcours le tableau tabFvol dans le repère absolu
+ for (int i=1;i<= tabvoltaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim >& tabFvol_i = tabFvol(i);
+ const ReferenceNE & ref =
+ ((ReferenceNE &) lesRef->Trouve(tabFvol_i.NomRef(),tabFvol_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(tabFvol_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(tabFvol_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(tabFvol_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments
+ int nbref = ref.Taille();
+ Coordonnee f_vol; // init par défaut
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.Numero(ns));
+ // récupération de la force de référence
+ // on traite en fonction du fait que c'est un champ ou non
+ switch (tabFvol_i.Champ())
+ { case 1: // c'est un champ de valeurs
+ f_vol = (tabFvol_i.Vect_de_coordonnee(ns)); break;
+ case 2: // c'est un champ de fonctions
+ // pour l'instant, le seul cas est celui des fonctions du temps
+ // on récupère les courbes pour les dim composantes
+ { switch (dima)
+ { case 3 : {Courbe1D * pt_courbe_force_ns_3 =
+ lesCourbes1D->Trouve(tabFvol_i.Nom_vect(ns,3));
+ f_vol(3) = pt_courbe_force_ns_3->Valeur(Temps_courant());
+ }
+ case 2 : {Courbe1D * pt_courbe_force_ns_2 =
+ lesCourbes1D->Trouve(tabFvol_i.Nom_vect(ns,2));
+ f_vol(2) = pt_courbe_force_ns_2->Valeur(Temps_courant());
+ }
+ case 1 : {Courbe1D * pt_courbe_force_ns_1 =
+ lesCourbes1D->Trouve(tabFvol_i.Nom_vect(ns,1));
+ f_vol(1) = pt_courbe_force_ns_1->Valeur(Temps_courant());
+ }
+ };
+ break;
+ }
+ case 0: default:// ce n'est pas un champ
+ f_vol = (tabFvol_i.Vect_de_coordonnee(1)); break;
+ };
+
+ // on regarde si jamais on a une dépendance à des grandeurs globales
+ const string & nomF_charge = tabFvol_i.NomF_charge();
+ Fonction_nD * pt_fonct = NULL;
+ if(nomF_charge.length())
+ {pt_fonct = lesFonctionsnD->Trouve(tabFvol_i.NomF_charge());
+ if (pt_fonct->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
+ {// on vérifie qu'en retour on a un scalaire ou un vecteur de dimension = la dimension de l'espace
+ Tableau & tava = pt_fonct->Valeur_pour_variables_globales(); // pour simplifier
+ if (pt_fonct->NbComposante() == 1)
+ {f_vol *= tava(1);}
+ else if (pt_fonct->NbComposante() == dima)
+ {switch (dima)
+ { case 3 : f_vol(3) *= tava(3);
+ case 2 : f_vol(2) *= tava(2);
+ case 1 : f_vol(1) *= tava(1);
+ };
+ }
+ else
+ {cout << "\n *** erreur en retour de l'utilisation d'une fonction nD avec grandeur(s) globale(s)"
+ << " cas des des forces lineiques suiveuses sur la ref: "<< tabFvol_i.NomRef()
+ << " en retour, le nombre de composante est different de 1 et la dimension de l'espace : "
+ << dima << endl;
+ Sortie(1);
+ };
+ // on désactive la fonction nD car elle a déjà été utilisée
+ pt_fonct = NULL;
+ };
+ };
+
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ {if (!nomF_charge.length()) // pas de courbe et pas de fonction nD
+ { f_vol *= coeff;} // cas d'une grandeur fixe
+ else // sinon il ne reste plus qu'à intégrer l'échelle
+ { f_vol *= tabFvol_i.Echelle_courbe();};
+ }
+ else //sinon c'est idem avec ou sans fonction nD car c'est déjà intégré
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * tabFvol_i.Echelle_courbe();
+ f_vol *= coeff_charge;
+ }
+ // appel du calcul du second membre et de la raideur éventuelle
+ // correspondant à la charge volumique
+ // on indique si éventuellement on veut se référer au volume initial
+ bool volume_finale = !(tabFvol_i.Attribut() == "sur_volume_initial_");
+ // Vecteur f_vol = (tabFvol_i.Coord()) * coeff;
+ Element::ResRaid resu = elem.SMR_charge_volumique_I(f_vol,pt_fonct,pa,volume_finale);
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à l'élément
+ assemb.AssemSM (vecglob,*(resu.res),elem.TableauDdl(),elem.Tab_noeud()); // assemblage
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elem.TableauDdl(),elem.Tab_noeud());
+ };
+ };
+ }
+ };
+
+ // $$$--- cas des des pressions hydrostatiques ---$$$
+ int PresHydrotaille = PresHydro.Taille();
+ if ( PresHydrotaille != 0)
+ {// on parcours le tableau PresHydro
+ for (int i=1;i<= PresHydrotaille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim > & PresHydro_i = PresHydro(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(PresHydro_i.NomRef(),PresHydro_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(PresHydro_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(PresHydro_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(PresHydro_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// on récupère le vecteur normal et le point de la surface libre
+ const Coordonnee& N = PresHydro_i.Direction_N(); // récup de la direction N normée
+ const Coordonnee& A = PresHydro_i.Point_M(); // récup du point de la surface libre
+ double p_hydro_ref = (PresHydro_i.Val(1));
+ // Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ double p_hydro = p_hydro_ref;
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ if(pt_courbe == NULL)
+ { p_hydro *= coeff;} // cas d'une grandeur fixe
+ else
+ { // cas d'une courbe de charge calcul de la valeur du coeff de charge
+ double coeff_charge = (pt_courbe->Valeur(Temps_courant())) * PresHydro_i.Echelle_courbe();
+ p_hydro *= coeff_charge;
+ }
+ // appel du calcul du second membre et de la raideur éventuelle
+ // correspondant à la charge de type pression
+ bool sans_limitation=false;
+ if (PresHydro_i.Attribut() == "sans_limitation_") sans_limitation= true;
+ Element::ResRaid resu = elem.SMR_charge_hydrostatique_I
+ (N,p_hydro,ref.NumeroFA(ns),A,pa,sans_limitation) ;
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront = NULL;
+ if (!ParaGlob::AxiSymetrie())
+ elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); // la surface frontière: cas normal
+ else // cas axisymétrique
+ elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // la surface arête générant une surface en rotation
+ assemb.AssemSM (vecglob,*(resu.res),elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elfront->DdlElem_const(),elfront->TabNoeud_const());
+ };
+ };
+ }
+ };
+
+ // $$$--- cas des des efforts hydrodynamiques ---$$$
+ int coefHydroDynataille = coefHydroDyna.Taille();
+ if ( coefHydroDynataille != 0)
+ {// on parcours le tableau coefHydroDyna
+ for (int i=1;i<= coefHydroDynataille;i++)
+ { // recup de la reference correspondant au mot cle
+ BlocCharge< BlocDdlLim > & coefHydroDyna_i = coefHydroDyna(i);
+ const ReferenceAF & ref =
+ ((ReferenceAF &) lesRef->Trouve(coefHydroDyna_i.NomRef(),coefHydroDyna_i.NomMaillage()));
+ // dans le cas d'une courbe de charge on récupère l'adresse
+ Courbe1D * pt_courbe = NULL;
+ if(coefHydroDyna_i.NomCourbeCharge() != "")
+ pt_courbe = lesCourbes1D->Trouve(coefHydroDyna_i.NomCourbeCharge());
+ // pas de calcul, 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 on ne fait rien
+ if (!(coefHydroDyna_i.Pas_a_prendre_en_compte(Temps_courant())))
+ {// Maintenant les éléments et les surfaces associes
+ int nbref = ref.Taille();
+ // récup du poids volumique poids volumique = ro * g, qui n'est pas soumis à la courbe de charge
+ double poidvol = (coefHydroDyna_i.Val(1));
+ for (int ns=1;ns<= nbref;ns++)
+ { // récupération de l'élément fini
+ Element& elem = lesMail->Element_LesMaille(ref.Nbmaille(), ref.NumeroElem(ns));
+ // maintenant deux cas: soit avec ou sans courbes de charge
+ double coeff_charge=1.;
+ if(pt_courbe != NULL)
+ { coeff_charge = (pt_courbe->Valeur(Temps_courant())) * coefHydroDyna_i.Echelle_courbe();};
+ // appel du calcul du second membre correspondant aux efforts hydrodynamique
+ Element::ResRaid resu = elem.SMR_charge_hydrodynamique_I(coefHydroDyna_i.Frot_fluid(),poidvol
+ ,coefHydroDyna_i.Coef_aero_n(),ref.NumeroFA(ns),coeff_charge
+ ,coefHydroDyna_i.Coef_aero_t(),pa) ;
+ // assemblage du second membre
+ // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée
+ const ElFrontiere* elfront;
+ switch (ParaGlob::Dimension())
+ { case 3: {elfront = elem.Frontiere_surfacique(ref.NumeroFA(ns)); break;};// la surface frontière
+ case 2: {elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); break;};// la ligne frontière
+ case 1: {elfront = elem.Frontiere_points(ref.NumeroFA(ns)); break;};// le point frontière
+ };
+ assemb.AssemSM (vecglob,*(resu.res),elfront->DdlElem_const(),elfront->TabNoeud_const()); // assemblage
+ // assemblage de la raideur si nécessaire
+ if (avec_raid)
+ // appel de la fonction adoc, via le pointeur de fonction
+ (assemb.*assembMat) (matglob,*(resu.raid),elfront->DdlElem_const(),elfront->TabNoeud_const());
+ };
+ };
+ };
+ }; //-- fin de hydrodyna
+
+
+ // affichage éventuelle de la matrice de raideur et du second membre
+ if (ParaGlob::NiveauImpression() >= 10)
+ { string entete = " affichage de la matrice de raideur apres chargement d'efforts externes ";
+ matglob.Affichage_ecran(entete);
+ entete = " affichage du second membre apres chargement d'efforts externes ";
+ vecglob.Affichage_ecran(entete);
+ };
+ }
+ catch (ErrSortieFinale)
+ // cas d'une direction voulue vers la sortie
+ // on relance l'interuption pour le niveau supérieur
+ { ErrSortieFinale toto;
+ throw (toto);
+ }
+ catch ( ... )
+ { if (ParaGlob::NiveauImpression() >= 1)
+ {cout << "\n *** erreur dans le calcul du chargement impose ";
+ if (ParaGlob::NiveauImpression() >= 4)
+ cout << "\n Charge::ChargeSMembreRaideur_Im_mecaSolid(..";
+ cout << flush;
+ };
+ retour = false;
+ };
+
+ temps_cpu_chargement.Arret_du_comptage();
+ return retour;
+ };
diff --git a/Chargement/Charge3.cc b/Chargement/Charge3.cc
new file mode 100644
index 0000000..e52b99f
--- /dev/null
+++ b/Chargement/Charge3.cc
@@ -0,0 +1,1381 @@
+
+// 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: .
+
+
+#include "Charge.h"
+#include "ConstMath.h"
+#include "MathUtil.h"
+#include "ReferenceNE.h"
+#include "ReferenceAF.h"
+#include "CourbePolyLineaire1D.h"
+
+
+#include "Charge.h"
+#include "ConstMath.h"
+#include "MathUtil.h"
+#include "ReferenceNE.h"
+#include "ReferenceAF.h"
+#include "CourbePolyLineaire1D.h"
+#include "CharUtil.h"
+
+// avancement de la charge
+// il peut y avoir plusieurs type d'avancement
+// en fonction des donnees ( transparent pour l'utilisateur)
+// mais aussi en fonction des parametres
+// retourne false par défaut, mais si le pas de temps a été modifié
+// retourne true !!, car par exemple de la fin du chargement, d'où une modif du pas
+// pour obtenir exactement la fin
+bool Charge::Avance() // premier version
+ { // appel de la fonction ad hoc
+ return(this->*PtAvance)();
+ };
+
+ // retour de la charge au cas précédent, c'est à dire
+ // avant le dernier ordre d'avancement
+ // valeur par défaut de "exacte "
+ // si exacte n'est pas présent ou faux: le compteur_essai_increment d'appel de Avance(), n'est pas décrémenté
+ // exacte=true: le compteur_essai_increment d'appel est décrémenté, en fait on revient exactement au départ
+ // ce qui permet d'utiliser plusieurs fois Avance() dans un même pas de temps
+ // en comptabilisant par exemple qu'une seule fois un appel de Avance(), cas d'une intégration
+ // temporelle par exemple
+void Charge::Precedant(bool exacte)
+ { // appel de la fonction ad hoc
+ (this->*PtPrecedent)();
+ if (exacte) compteur_essai_increment--;
+ };
+
+// diminution de l'incrément de charge dans le cas par exemple d'une non convergence
+// ramène true si la diminution est effective, sinon false
+bool Charge::Diminue_inc_charge(double diminue)
+ { // si le type est 5, les temps de calcul sont bloqué
+ if (nomtypeCharge == "TYPE5")
+ { if (ParaGlob::NiveauImpression() > 4)
+ cout << "\n TYPE5: pas de temps fige, pas de diminution permise ";
+ return false;
+ };
+ // autres cas:
+// //on commence par revenir à la charge précédente
+// (this->*PtPrecedent)();
+ // on divise l'incrément de temps
+ double deltat_essai = paAlgo->Deltat() / diminue;
+ // on diminue si possible
+ return (!(paAlgo->Modif_Deltat(deltat_essai)));
+ //-// deltat /= diminue;
+ };
+
+// augmentation de l'incrément de charge dans le cas de bonne convergence
+// ramène true si l'augmentation est effective, sinon false
+bool Charge::Augmente_inc_charge(double augmente)
+ { // si le type est 5, les temps de calcul sont bloqué
+ if (nomtypeCharge == "TYPE5")
+ { if (ParaGlob::NiveauImpression() > 4)
+ cout << "\n TYPE5: pas de temps fige, pas d'augmentation permise ";
+ return false;
+ };
+ // on augmente l'incrément de temps si possible
+ double deltat_essai = paAlgo->Deltat() * augmente;
+ // on augmente si possible
+ bool test_augmente = paAlgo->Modif_Deltat(deltat_essai);
+ if (!test_augmente)
+ { return true;} // si tout est ok on ramène true
+ else
+ // sinon on essaie d'augmenter dans les bornes
+ {return paAlgo->Modif_Detat_dans_borne(deltat_essai); };
+// return (!(paAlgo->Modif_Deltat(deltat_essai)));
+ };
+
+ // declaration de la fin en fonction du type de chargement
+ // 0 : la fin n'est pas valide, on continue
+ // 1 : temps fin dépassé
+ // 2 : compteur_increment dépassé
+ // 3 : compteur_essai_increment dépassé
+ // NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
+ // puis ensuite le compteur d'incréments
+ // puis le nombre d'essai maxi, puis enfin le cas normal
+ // si affichage est true, affichage d'un message
+int Charge::Fin(const int & icharge,bool affichage)
+ { // appel de la fonction ad hoc
+////---debug
+//cout << "\n Charge::Fin(...affichage="
+// << affichage << endl;
+////--fin debug
+ return (this->*PtFin)(icharge,affichage);
+ };
+
+// affichage et definition interactive des commandes
+void Charge::Info_commande_LesCharges1(UtilLecture & entreePrinc)
+{ // ---------- définition des différents chargements ----------
+ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
+ bool plusieurs_maillages = false;
+ string rep;
+ cout << "\n cas d'un seul maillage (par defaut) : rep o "
+ << "\n cas de plusieurs maillages : rep n ";
+ // procédure de lecture avec prise en charge d'un retour chariot
+ rep = lect_return_defaut(true,"o");
+ if (rep == "n")
+ { plusieurs_maillages = true;};
+ rep="_"; // init
+
+ //On va proposer un menu
+ sort << "\n\n charges #------------# ";
+ while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
+ {
+ try
+ {cout
+ << "\n (0 ou f) (fin) "
+ << "\n (1) ponctuelle (PONCTUELLE)"
+ << "\n (2) volumique (VOLUMIQUE) "
+ << "\n (3) lineique de direction fixe (LINEIQUE) "
+ << "\n (4) lineique suiveuse (LINEIC_SUIVEUSE) "
+ << "\n (5) surfacique de direction fixe (UNIFORME)"
+ << "\n (6) pression (PRESSION)"
+ << "\n (7) surfacique suiveuse (PRESSDIR)"
+ << "\n (8) hydrostatique (PHYDRO)"
+ << "\n (9) aero - hydrodynamique (P_HYDRODYNA)"
+ << "\n (10) torseur d'efforts ponctuels (TORSEUR_PONCT)"
+ << "\n (11 ou ? ) informations "
+ << "\n ";
+ // procédure de lecture avec prise en charge d'un retour chariot
+ rep = lect_return_defaut(false,"f");
+ if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie directe
+ break;
+ int num = ChangeEntier(rep);
+ if (Minuscules(rep) == "?")
+ num = 11;
+ bool choix_valide=false;
+ if ((num >= 0)&&(num<=11))
+ { choix_valide=true; }
+ else { cout << "\n Erreur on attendait un entier entre 0 et 11 !!, "
+ << "\n redonnez une bonne valeur"
+ << "\n ou taper f ou 0 pour arreter le programme";
+ choix_valide=false;
+ }
+ switch (num)
+ { case 0: // sortie
+ { break;} // normalement cela a déjà été filtré avant
+ case 1: // ponctuelle
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference de noeud ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'N')
+ {cout << "\n *** erreur, la premiere lettre de la ref de noeud "
+ << " doit etre N et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 2: // volumique
+ {string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference d'elements ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'E')
+ {cout << "\n *** erreur, la premiere lettre de la ref d'element "
+ << " doit etre E et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+ int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ cout << "\n donner la charge volumique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 3: // lineique de direction fixe
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference d'arete ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'A')
+ {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
+ << " doit etre A et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force lineique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 4: // lineique suiveuse
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference d'arete ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'A')
+ {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
+ << " doit etre A et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force lineique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 5: // surfacique de direction fixe
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force surfacique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 6: // pression
+ {string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la charge surfacique (1 reels) ? ";
+ double charge;
+ charge=lect_double(); cout << " valeur lue ="<< charge;
+ // écriture de la condition
+ if (plusieurs_maillages)
+ {sort <<"\n nom_mail= "< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 7: // surfacique suiveuse
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force surfacique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 8: // hydrostatique
+ { string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+ int dim = ParaGlob::Dimension();
+ Coordonnee dir(dim); // direction de la force
+ cout << "\n donner la direction de la normale au plan de reference ("< > bloc;
+ // le fait de passer la chaine "sans_limitation_" en paramètre
+ // fait qu'il y aura interrogation pour savoir si l'on veut ou non
+ // cet attribut en plus
+ bloc.Info_commande_BlocCharge(sort,"sans_limitation_");
+ sort << endl;
+ break;
+ }
+ case 9: // aero - hydrodynamique
+ { string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+ string nom_courbeToVt="NULL";
+ cout << "\n nom de la courbe to(Vt), ou NULL si l'on n'en veut pas ? ";
+ nom_courbeToVt=lect_chaine();cout << " nom lu = "<< nom_courbeToVt;
+ string nom_courbef_n="NULL";
+ cout << "\n nom de la courbe f_n(V), ou NULL si l'on n'en veut pas ? ";
+ nom_courbef_n=lect_chaine();cout << " nom lu = "<< nom_courbef_n;
+ string nom_courbef_t="NULL";
+ cout << "\n nom de la courbe f_t(V), ou NULL si l'on n'en veut pas ? ";
+ nom_courbef_t=lect_chaine();cout << " nom lu = "<< nom_courbef_t;
+ cout << "\n donner la masse volumique (1 reels) ? ";
+ double charge;
+ charge=lect_double(); cout << " valeur lue ="<< charge;
+ // écriture de la condition
+ if (plusieurs_maillages)
+ {sort <<"\n nom_mail= "< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 10: // torseur d'efforts ponctuels
+ {string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+ // écriture de la condition
+ if (plusieurs_maillages)
+ {sort <<"\n nom_mail= "< > bloc_tors;
+ bool ecriture = bloc_tors.Info_commande_Charges(plusieurs_maillages,entreePrinc);
+ // maintenant on s'occupe du cas courbe de charge et bornes
+ if (ecriture)
+ {bloc_tors.Info_commande_BlocCharge(sort);
+ sort << endl;
+ };
+ break;
+ }
+ case 11: // information
+ { cout << "\n pour plus de details il faut se reporter a la documentation d'herezh++ ";
+ break;
+ }
+ default:
+ cout << "\n le cas "<= 0)&&(num<=7))
+ { choix_valide=true; }
+ else { cout << "\n Erreur on attendait un entier entre 0 et 7 !!, "
+ << "\n redonnez une bonne valeur"
+ << "\n ou taper f ou 0 pour arreter le programme";
+ choix_valide=false;
+ }
+ switch (num)
+ { case 0: // sortie
+ { break;} // normalement cela a déjà été filtré avant
+ case 1: // (courbe: rampe + palier)
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference de noeud ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'N')
+ {cout << "\n *** erreur, la premiere lettre de la ref de noeud "
+ << " doit etre N et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 2: // volumique
+ {string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference d'elements ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'E')
+ {cout << "\n *** erreur, la premiere lettre de la ref d'element "
+ << " doit etre E et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+ int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ cout << "\n donner la charge volumique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 3: // lineique de direction fixe
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference d'arete ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'A')
+ {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
+ << " doit etre A et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force lineique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 4: // lineique suiveuse
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference d'arete ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'A')
+ {cout << "\n *** erreur, la premiere lettre de la ref d'arete "
+ << " doit etre A et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force lineique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 5: // surfacique de direction fixe
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force surfacique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 6: // pression
+ {string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la charge surfacique (1 reels) ? ";
+ double charge;
+ charge=lect_double(); cout << " valeur lue ="<< charge;
+ // écriture de la condition
+ if (plusieurs_maillages)
+ {sort <<"\n nom_mail= "< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 7: // surfacique suiveuse
+ { int dim = ParaGlob::Dimension();
+ Coordonnee trans(dim);
+ string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+
+ cout << "\n donner la force surfacique ("< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 8: // hydrostatique
+ { string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+ int dim = ParaGlob::Dimension();
+ Coordonnee dir(dim); // direction de la force
+ cout << "\n donner la direction de la normale au plan de reference ("< > bloc;
+ // le fait de passer la chaine "sans_limitation_" en paramètre
+ // fait qu'il y aura interrogation pour savoir si l'on veut ou non
+ // cet attribut en plus
+ bloc.Info_commande_BlocCharge(sort,"sans_limitation_");
+ sort << endl;
+ break;
+ }
+ case 9: // aero - hydrodynamique
+ { string nom_maillage="";
+ if (plusieurs_maillages)
+ { cout << "\n nom du maillage ? ";
+ nom_maillage=lect_chaine(); cout << " nom lu = "<< nom_maillage;
+ };
+
+ cout << "\n nom de la reference surfacique ? ";
+ string nom_ref=" ";
+ nom_ref=lect_chaine();cout << " nom lu = "<< nom_ref;
+ if (nom_ref.at(0) != 'F')
+ {cout << "\n *** erreur, la premiere lettre de la ref surfacique "
+ << " doit etre F et non "<< nom_ref.at(0)<< " !!";
+ break;
+ };
+ string nom_courbeToVt="NULL";
+ cout << "\n nom de la courbe to(Vt), ou NULL si l'on n'en veut pas ? ";
+ nom_courbeToVt=lect_chaine();cout << " nom lu = "<< nom_courbeToVt;
+ string nom_courbef_n="NULL";
+ cout << "\n nom de la courbe f_n(V), ou NULL si l'on n'en veut pas ? ";
+ nom_courbef_n=lect_chaine();cout << " nom lu = "<< nom_courbef_n;
+ string nom_courbef_t="NULL";
+ cout << "\n nom de la courbe f_t(V), ou NULL si l'on n'en veut pas ? ";
+ nom_courbef_t=lect_chaine();cout << " nom lu = "<< nom_courbef_t;
+ cout << "\n donner la masse volumique (1 reels) ? ";
+ double charge;
+ charge=lect_double(); cout << " valeur lue ="<< charge;
+ // écriture de la condition
+ if (plusieurs_maillages)
+ {sort <<"\n nom_mail= "< > bloc;
+ bloc.Info_commande_BlocCharge(sort);
+ sort << endl;
+ break;
+ }
+ case 10: // information
+ { cout << "\n pour plus de details il faut se reporter a la documentation d'herezh++ ";
+ break;
+ }
+ default:
+ cout << "\n le cas "<Modif_Temps(0.);//temps = 0.;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment = 0;multi = 0.; coeff = 0.;
+ } ;
+void Charge::Debut2()
+ {paAlgo->Modif_Temps(0.);//temps = 0.;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment = 0;multi = 0.; coeff = 0.;
+ } ;
+void Charge::Debut3()
+ {paAlgo->Modif_Temps(0.);//temps = 0.;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment = 0;multi = 0.; coeff = 1.; // modif 9dec2008, car a priori dans le type 3
+ // on veut toujours un chargement, j'espère que cela sera ok pour la statique
+ } ;
+void Charge::Debut4()
+ {paAlgo->Modif_Temps(0.);//temps = 0.;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment = 0;multi = 0.; coeff = 0.;
+ } ;
+void Charge::Debut5()
+ {// on commence par récupérer la courbe
+ CourbePolyLineaire1D* fconnue_charge = (CourbePolyLineaire1D*) f_charge;
+ // s'il y a un nombre de point inférieur à 2 -> erreur
+ if (fconnue_charge->NombrePoint() < 2)
+ { cout << "\n **** erreur, le nombre de point definissant la courbe de chargement avec le TYPE5 "
+ << " doit etre au minimum de 2 (cf. doc), ajoutez des points ou changez de type de chargement ";
+ Sortie(1);
+ };
+ // cas où il y a plusieurs points
+ // on récupère le premier point de la courbe
+ Coordonnee2 poin = fconnue_charge->Pt_nbi(1);
+ paAlgo->Modif_Temps(poin(1));//temps initial;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment = 0;multi = 0.;
+ coeff = paAlgo->Multiplicateur() * poin(2);
+ num_pt_courant_type5=1; ancien_num_pt_type5 = 0;
+ // on modifie si possible également le deltat
+ Coordonnee2 poin2 = fconnue_charge->Pt_nbi(2);
+ double deltat= poin2(1)-poin(1);;
+ if (deltat <= ConstMath::trespetit)
+ { cout << "\n **** erreur, variation du temps nulle avec le TYPE5 de chargement"
+ << " temps = " << poin(1) << " numero du point " << ancien_num_pt_type5
+ << "\n evolution non permise !! modifiez votre fichier de points ";
+ if (ParaGlob::NiveauImpression() >= 4){ cout << "\n Charge::Debut5() ";};
+ Sortie(1);
+ };
+ if (paAlgo->Modif_Deltat(deltat))
+ { cout << "\n **** erreur, attention la variation de deltat a ete refusee avec le TYPE5 de chargement"
+ << " deltat demandee = " << deltat
+ << "\n erreur de coherence dans le fichier d'entree, il ne faut pas imposer de contrainte min max ou"
+ << " autre sur le pas de temps, non compatible avec le TYPE5 qui lui, necessite que le pas de temps"
+ << " soit impose par les points de la courbe de chargement "
+ << " modifiez vos donnees d'entree ! ";
+ if (ParaGlob::NiveauImpression() >= 4){ cout << "\n Charge::Debut5() ";};
+ Sortie(1);
+ };
+ };
+void Charge::Debut6()
+ { cout << "\n methode non encore implantee \n";
+ cout << "void Charge::Debut6()" << endl;
+ Sortie (1);
+ };
+void Charge::Debut7()
+ { cout << "\n methode non encore implantee \n";
+ cout << "void Charge::Debut7()" << endl;
+ Sortie (1);
+ };
+ // declaration de l'avancement en fonction du type de chargement
+bool Charge::Avance1()
+ { double vieuxcoef = coeff;
+ bool retour = false; // init
+ // sauvegarde des paramètres avant avancement
+ double temps = paAlgo->Variables_de_temps().TempsCourant();//temps;
+ temps_sauve = temps;
+ multi_sauve = multi;
+ coeff_sauve = coeff;
+ // traitement
+ temps +=paAlgo->Deltat(); // cas courant
+ // éventuellement limitation
+ if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
+ && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
+ {// calcul du nouveau deltat
+ double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
+ // on recadre éventuellement dans les bornes le delta t
+ paAlgo->Modif_Detat_dans_borne(nouveau_temps);
+ // on modifie le deltat
+ paAlgo->Modif_Deltat(nouveau_temps);
+ // on calcul le temps courant : si tout c'est bien passé on est au maxi
+ temps = temps_sauve + paAlgo->Deltat();
+ retour = true;
+ };
+ // mise à jour du temps courant
+ paAlgo->Modif_Temps(temps);
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment++;
+ if (temps < tabType(1))
+ {// fonction lineaire en fonction du temps
+ multi = paAlgo->Multiplicateur() * paAlgo->Deltat()/tabType(1);
+ coeff += multi;
+ }
+ else
+ { // palier
+ coeff = paAlgo->Multiplicateur();
+ multi = coeff - vieuxcoef;
+ };
+ // retour
+ return retour;
+ };
+bool Charge::Avance2()
+ { double vieuxcoef = coeff;
+ bool retour = false; // init
+ // sauvegarde des paramètres avant avancement
+ double temps = paAlgo->Variables_de_temps().TempsCourant();
+ temps_sauve = temps;
+ multi_sauve = multi;
+ coeff_sauve = coeff;
+ // traitement
+ temps +=paAlgo->Deltat();
+ // éventuellement limitation
+ if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
+ && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
+ {// calcul du nouveau deltat
+ double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
+ // on recadre éventuellement dans les bornes le delta t
+ paAlgo->Modif_Detat_dans_borne(nouveau_temps);
+ // on modifie le deltat
+ paAlgo->Modif_Deltat(nouveau_temps);
+ // on calcul le temps courant : si tout c'est bien passé on est au maxi
+ temps = temps_sauve + paAlgo->Deltat();
+ retour = true;
+ };
+ // mise à jour du temps courant
+ paAlgo->Modif_Temps(temps);
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment++;
+ if (temps < tabType(1))
+ {// fonction lineaire en fonction du temps
+ multi = paAlgo->Multiplicateur() * paAlgo->Deltat()/tabType(1);
+ coeff += multi;
+ }
+ else if ((temps >= tabType(1)) && (temps <= tabType(2)))
+ // phase de stabilisation c-a-dire le palier
+ { // palier
+ coeff = paAlgo->Multiplicateur();
+ multi = coeff - vieuxcoef;
+ }
+ else
+ // on a dépassé t2, les coef sont mis à zéro brutalement
+ {
+ coeff = 0.;
+ multi = 0.;
+ };
+ // retour
+ return retour;
+ };
+bool Charge::Avance3()
+ { double vieuxcoef = coeff;
+ bool retour = false; // init
+ // sauvegarde des paramètres avant avancement
+ double temps = paAlgo->Variables_de_temps().TempsCourant();
+ temps_sauve = temps;
+ multi_sauve = multi;
+ coeff_sauve = coeff;
+ // traitement
+ temps +=paAlgo->Deltat();
+ // éventuellement limitation
+ if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
+ && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
+ {// calcul du nouveau deltat
+ double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
+ // on recadre éventuellement dans les bornes le delta t
+ paAlgo->Modif_Detat_dans_borne(nouveau_temps);
+ // on modifie le deltat
+ paAlgo->Modif_Deltat(nouveau_temps);
+ // on calcul le temps courant : si tout c'est bien passé on est au maxi
+ temps = temps_sauve + paAlgo->Deltat();
+ retour = true;
+ };
+ // mise à jour du temps courant
+ paAlgo->Modif_Temps(temps);
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment++;
+ // ici le coefficient multiplicateur est 1 quelque soit le temps
+ coeff = 1.;
+ multi = coeff - vieuxcoef;;
+ // retour
+ return retour;
+ };
+
+bool Charge::Avance4()
+ { double vieuxcoef = coeff;
+ bool retour = false; // init
+ // sauvegarde des paramètres avant avancement
+ double temps = paAlgo->Variables_de_temps().TempsCourant();
+ temps_sauve = temps;
+ multi_sauve = multi;
+ coeff_sauve = coeff;
+ // traitement
+ temps +=paAlgo->Deltat();
+ // éventuellement limitation
+ if (temps >= paAlgo->Variables_de_temps().Tempsfin() // limitation du temps si l'on dépasse
+ && (!temps_fin_non_stricte) ) // si on est en non stricte on ne vise pas le temps exact final
+ {// calcul du nouveau deltat
+ double nouveau_temps = paAlgo->Variables_de_temps().Tempsfin()-temps_sauve;
+ // on recadre éventuellement dans les bornes le delta t
+ paAlgo->Modif_Detat_dans_borne(nouveau_temps);
+ // on modifie le deltat
+ paAlgo->Modif_Deltat(nouveau_temps);
+ // on calcul le temps courant : si tout c'est bien passé on est au maxi
+ temps = temps_sauve + paAlgo->Deltat();
+ retour = true;
+ };
+ // mise à jour du temps courant
+ paAlgo->Modif_Temps(temps);
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ compteur_essai_increment++;
+ coeff = paAlgo->Multiplicateur() * f_charge->Valeur(temps);
+ multi = coeff - vieuxcoef;
+ // retour
+ return retour;
+ };
+
+bool Charge::Avance5()
+ { double vieuxcoef = coeff;
+ bool retour = false; // init
+ // sauvegarde des paramètres avant avancement
+ double temps = paAlgo->Variables_de_temps().TempsCourant();
+ temps_sauve = temps;
+ multi_sauve = multi;
+ coeff_sauve = coeff;
+ // --- traitement
+ // on commence par récupérer la courbe
+ CourbePolyLineaire1D* fconnue_charge = (CourbePolyLineaire1D*) f_charge;
+ ancien_num_pt_type5 = num_pt_courant_type5;
+ // on regarde si l'on peut incrémenter le temps
+ if (num_pt_courant_type5 < fconnue_charge->NombrePoint())
+ { // ok
+ num_pt_courant_type5++; // incrémente le num de point
+ // récup du point
+ Coordonnee2 poin = fconnue_charge->Pt_nbi(num_pt_courant_type5);
+ temps = poin(1);
+ paAlgo->Modif_Temps(temps); // on affecte le temps
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ // on modifie si possible également le deltat
+ double deltat= temps-temps_sauve;
+ if (deltat <= ConstMath::trespetit)
+ { cout << "\n **** erreur, variation du temps nulle avec le TYPE5 de chargement"
+ << " temps = " << temps << " numero du point " << ancien_num_pt_type5
+ << "\n evolution non permise !! modifiez votre fichier de points ";
+ Sortie(1);
+ }
+ if (paAlgo->Modif_Deltat(deltat))
+ { cout << "\n **** Erreur , attention la variation de deltat a ete refusee avec le TYPE5 de chargement"
+ << " deltat demandee = " << deltat
+ << "\n erreur de coherence dans le fichier d'entree, il ne faut pas imposer de contrainte min max ou"
+ << " autre sur le pas de temps, non compatible avec le TYPE5 qui lui, necessite que le pas de temps"
+ << " soit impose par les points de la courbe de chargement "
+ << " modifiez vos donnees d'entree ! ";
+ Sortie(1);
+ }
+ compteur_essai_increment++;
+ coeff = paAlgo->Multiplicateur() * poin(2);
+ multi = coeff - vieuxcoef;
+ retour = true;
+ };
+ // sinon on ne fait rien, mais le calcul va s'arrêter
+ // retour
+ return retour;
+ };
+bool Charge::Avance6()
+ { cout << "\n methode non encore implantee \n";
+ cout << "double Charge::Avance6()" << endl;
+ Sortie (1);
+ return false;
+ };
+bool Charge::Avance7()
+ { cout << "\n methode non encore implantee \n";
+ cout << "double Charge::Avance7()" << endl;
+ Sortie (1);
+ return false;
+ };
+ // declaration du retour à l'incrément précédent en fonction du type de chargement
+void Charge::Precedent1()
+ { // récupération des paramètres avant avancement
+ paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ multi = multi_sauve;
+ coeff = coeff_sauve;
+ };
+void Charge::Precedent2()
+ { // récupération des paramètres avant avancement
+ paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ multi = multi_sauve;
+ coeff = coeff_sauve;
+ };
+void Charge::Precedent3()
+ { // récupération des paramètres avant avancement
+ paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ multi = multi_sauve;
+ coeff = coeff_sauve;
+ };
+void Charge::Precedent4()
+ { // récupération des paramètres avant avancement
+ paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ multi = multi_sauve;
+ coeff = coeff_sauve;
+ };
+void Charge::Precedent5()
+ { // récupération des paramètres avant avancement
+ paAlgo->Modif_Temps(temps_sauve);//temps = temps_sauve;
+ ParaGlob::param->Mise_a_jour_TEMPS_COURANT();
+ multi = multi_sauve;
+ coeff = coeff_sauve;
+ num_pt_courant_type5=ancien_num_pt_type5;
+ };
+void Charge::Precedent6()
+ { cout << "\n methode non encore implantee \n";
+ cout << "double Charge::Precedent6()" << endl;
+ Sortie (1);
+ };
+void Charge::Precedent7()
+ { cout << "\n methode non encore implantee \n";
+ cout << "double Charge::Precedent7()" << endl;
+ Sortie (1);
+ };
+
+ // declaration de la fin en fonction du type de chargement
+ // 0 : la fin n'est pas valide, on continue
+ // 1 : temps fin dépassé
+ // 2 : compteur_increment dépassé
+ // 3 : compteur_essai_increment dépassé
+ // NB: c'est d'abort le temps fin qui est testé: qui donc conduit à un arrêt normal
+ // puis ensuite le compteur d'incréments
+ // puis le nombre d'essai maxi, puis enfin le cas normal
+ // si affichage est true, affichage d'un message
+
+int Charge::Fin1(const int & icharge,bool affichage)
+ { double temps = paAlgo->Variables_de_temps().TempsCourant();
+ if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
+ { if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
+ { cout << "\n >>>> temps fin ("<Tempsfin()<<") atteint <<<<< " << temps << endl ;};
+ return 1;
+ }
+// else if (icharge >= paAlgo->Maxincre())
+ else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
+ {if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
+ << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
+ << endl ;
+ return 2;
+ }
+ else if (compteur_essai_increment > paAlgo->Max_essai_incre())
+ {if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
+ return 3;
+ }
+ else
+ return 0;
+ };
+int Charge::Fin2(const int & icharge,bool affichage)
+ { double temps = paAlgo->Variables_de_temps().TempsCourant();
+ if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
+ { if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
+ { cout << "\n >>>> temps fin ("<Tempsfin()<<") atteint <<<<< " << temps << endl ;};
+ return 1;
+ }
+// else if (icharge >= paAlgo->Maxincre())
+ else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
+ {if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
+ << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
+ << endl ;
+ return 2;
+ }
+ else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
+ {if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
+ return 3;
+ }
+ else
+ return 0;
+ };
+int Charge::Fin3(const int & icharge,bool affichage)
+ { double temps = paAlgo->Variables_de_temps().TempsCourant();
+ if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
+ { if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
+ { cout << "\n >>>> temps fin ("<Tempsfin()<<") atteint <<<<< " << temps << endl ;};
+ return 1;
+ }
+// else if (icharge >= paAlgo->Maxincre())
+ else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
+ {if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
+ << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
+ << endl ;
+ return 2;
+ }
+ else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
+ {if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
+ return 3;
+ }
+ else
+ return 0;
+ };
+int Charge::Fin4(const int & icharge,bool affichage)
+ { double temps = paAlgo->Variables_de_temps().TempsCourant();
+ if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
+ { if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
+ { cout << "\n >>>> temps fin ("<Tempsfin()<<") atteint <<<<< " << temps << endl ;};
+ return 1;
+ }
+// else if (icharge >= paAlgo->Maxincre())
+ else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
+ {if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
+ << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
+ << endl ;
+ return 2;
+ }
+ else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
+ {if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
+ return 3;
+ }
+ else
+ return 0;
+ };
+int Charge::Fin5(const int & icharge,bool affichage)
+ { // on commence par récupérer la courbe
+ CourbePolyLineaire1D* fconnue_charge = (CourbePolyLineaire1D*) f_charge;
+ double temps = paAlgo->Variables_de_temps().TempsCourant(); // puis le temps
+ if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
+ { if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
+ { cout << "\n >>>> temps fin ("<Tempsfin()<<") atteint <<<<< " << temps << endl ;};
+ return 1;
+ }
+ else if ( num_pt_courant_type5 == fconnue_charge->NombrePoint())
+ { if (affichage) cout << "\n >>>> dernier temps de la courbe de charge atteint <<<<< " << endl ;
+ return 1;
+ }
+// else if (icharge >= paAlgo->Maxincre())
+ else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
+ {if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
+ << "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
+ << endl ;
+ return 2;
+ }
+ else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
+ {if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
+ return 3;
+ }
+ else
+ return 0;
+ };
+int Charge::Fin6(const int & icharge,bool affichage)
+ { cout << "\n methode non encore implantee \n";
+ cout << "int Charge::Fin6()" << endl;
+ Sortie (1);
+ return 0;
+ };
+int Charge::Fin7(const int & icharge,bool affichage)
+ { cout << "\n methode non encore implantee \n";
+ cout << "int Charge::Fin7()" << endl;
+ Sortie (1);
+ return 0;
+ };
+
+
+
diff --git a/Chargement/VariablesTemps.cc b/Chargement/VariablesTemps.cc
new file mode 100644
index 0000000..dbeac5c
--- /dev/null
+++ b/Chargement/VariablesTemps.cc
@@ -0,0 +1,117 @@
+
+// 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: .
+
+
+#include "VariablesTemps.h"
+#include "Sortie.h"
+#include
+#include "ParaGlob.h"
+ using namespace std;
+
+
+ // CONSTRUCTEURS :
+ // par défauts
+VariablesTemps::VariablesTemps() :
+ temps(0.),deltat(0.),deltatmaxi(0.),deltatmini(0.),tempsfin(0.),prectemps(0.)
+ { };
+
+ // constructeur de copies
+VariablesTemps::VariablesTemps(const VariablesTemps& t) :
+ temps(t.temps),deltat(t.deltat),deltatmaxi(t.deltatmaxi),deltatmini(t.deltatmini)
+ ,tempsfin(t.tempsfin),prectemps(t.prectemps)
+ { };
+
+ // affichage des parametres liés au temps
+void VariablesTemps::Affiche() const
+ { cout << "temps courant = " << deltatmaxi << '\n';
+ cout << "increment de temps maxi = " << deltatmaxi << '\n';
+ cout << "increment de temps mini = " << deltatmini << '\n';
+ cout << "precision sur le temps final = " << prectemps << '\n';
+ cout << "increment de temps = " << deltat << '\n';
+ cout << "temps de fin de calcul = " << tempsfin << '\n';
+ };
+
+ //----- lecture écriture dans base info -----
+ // cas donne le niveau de la récupération
+ // = 1 : on récupère tout
+ // = 2 : on récupère uniquement les données variables (supposées comme telles)
+ // = 3 : on met à jour uniquement les données variables (supposées comme telles)
+ // dans ce cas il y a modification des grandeurs, mais pas redimentionnement
+void VariablesTemps::Lecture_base_info_temps(ifstream& entr,const int cas)
+{switch (cas)
+ { case 1 : // ------- on récupère tout -------------------------
+ { cout << "== lecture des variables temps \n";
+ string toto; entr >> toto ; // lecture en tête
+ entr >> toto >> temps >> toto >> deltat
+ >> toto >> deltatmaxi >> toto >> deltatmini >> toto >> tempsfin
+ >> toto >> prectemps;
+ break;
+ }
+ case 2 : case 3: // ----------- on récupère uniquement se qui varie --------------------
+ { string toto;
+ // entr >> toto >> temps >> toto >> deltat;
+ // si on lit le deltat on ne peut plus prendre en compte la modif éventuelle du .info !
+ entr >> toto >> temps ;
+ break;
+ }
+ default :
+ {cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
+ cout << "VariablesTemps::Lecture_base_info(ifstream& entr,const int cas)"
+ << " cas= " << cas << endl;
+ Sortie(1);
+ }
+ };
+ }; // cas donne le niveau de sauvegarde
+ // = 1 : on sauvegarde tout
+ // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
+void VariablesTemps::Ecriture_base_info_temps(ofstream& sort,const int cas) const
+{switch (cas)
+ { case 1 : // ------- on sauvegarde tout -------------------------
+ { sort << " ****info_temps " ;
+ sort << " temps_courant " << setprecision(ParaGlob::NbdigdoCA()) << temps
+ << " increment_temps " << setprecision(ParaGlob::NbdigdoCA()) << deltat
+ << " increment_maxi " << setprecision(ParaGlob::NbdigdoCA()) << deltatmaxi
+ << " increment_mini " << setprecision(ParaGlob::NbdigdoCA()) << deltatmini
+ << " temps_fin " << setprecision(ParaGlob::NbdigdoCA()) << tempsfin
+ << " precision_temps " << setprecision(ParaGlob::NbdigdoCA()) << prectemps << "\n";
+ break;
+ }
+ case 2 : // ----------- sauvegarde uniquement de se qui varie --------------------
+ { sort << "\n temps_courant " << setprecision(ParaGlob::NbdigdoCA()) << temps ;
+ // << " increment_temps " << setprecision(ParaGlob::NbdigdoCA()) << deltat;
+ break;
+ }
+ default :
+ { cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
+ cout << "VariablesTemps::Ecriture_base_info(ofstream& sort,const int cas)"
+ << " cas= " << cas << endl;
+ Sortie(1);
+ }
+ };
+ };
diff --git a/Chargement/VariablesTemps.h b/Chargement/VariablesTemps.h
new file mode 100644
index 0000000..fb00c30
--- /dev/null
+++ b/Chargement/VariablesTemps.h
@@ -0,0 +1,141 @@
+
+// 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: 23/05/2003 *
+ * $ *
+ * AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
+ * $ *
+ * PROJET: Herezh++ *
+ * $ *
+ ************************************************************************
+ * BUT: Cette classe est dédiée au passage d'informations protégées *
+ * à d'autre classes. Cependant, la gestion des datas est *
+ * effectuée directement par la classe ParaAlgoControle. *
+ * $ *
+ * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
+ * VERIFICATION: *
+ * *
+ * ! date ! auteur ! but ! *
+ * ------------------------------------------------------------ *
+ * ! ! ! ! *
+ * $ *
+ * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
+ * MODIFICATIONS: *
+ * ! date ! auteur ! but ! *
+ * ------------------------------------------------------------ *
+ * $ *
+ ************************************************************************/
+#ifndef VARIABLES_TEMPS_H
+#define VARIABLES_TEMPS_H
+
+#include
+//#include "Debug.h"
+
+#ifndef ENLINUX_STREAM
+ #include // pour le flot en memoire centrale
+#else
+ #include // pour le flot en memoire centrale
+#endif
+#include
+#include
+#include "Sortie.h"
+
+
+class ParaAlgoControle;
+
+/// @addtogroup Groupe_concernant_le_chargement
+/// @{
+///
+
+class VariablesTemps
+{
+ public :
+ friend class ParaAlgoControle;
+ friend class Loi_comp_abstraite;
+ // CONSTRUCTEURS :
+ // par défauts
+ VariablesTemps();
+
+ // constructeur de copies :
+ VariablesTemps(const VariablesTemps& t);
+
+ // DESTRUCTEUR :
+ ~VariablesTemps() {};
+
+ // METHODES PUBLIQUES :
+ // ramène le temps courant
+ const double & TempsCourant() const {return temps;};
+ // ramène l'incrément du temps en cours
+ const double & IncreTempsCourant() const { return deltat;};
+ // ramène l'incrément du temps maxi
+ const double & IncreTempsMaxi() const { return deltatmaxi;};
+ // ramène l'incrément du temps mini
+ const double & IncreTempsMini() const { return deltatmini;};
+ // ramène le temps fin
+ const double & Tempsfin() const {return tempsfin;};
+ // affichage des parametres liés au temps
+ void Affiche() const ;
+ // mise à jour des paramètres bornes
+ void Mise_a_jour_bornes(const VariablesTemps& t)
+ {deltatmaxi = t.deltatmaxi;
+ deltatmini = t.deltatmini;
+ tempsfin = t.tempsfin;
+ prectemps = t.prectemps;
+ };
+
+ //----- lecture écriture dans base info -----
+ // cas donne le niveau de la récupération
+ // = 1 : on récupère tout
+ // = 2 : on récupère uniquement les données variables (supposées comme telles)
+ // = 3 : on met à jour uniquement les données variables (supposées comme telles)
+ // dans ce cas il y a modification des grandeurs, mais pas redimentionnement
+ void Lecture_base_info_temps(ifstream& ent,const int cas);
+ // cas donne le niveau de sauvegarde
+ // = 1 : on sauvegarde tout
+ // = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
+ void Ecriture_base_info_temps(ofstream& sort,const int cas) const ;
+
+ protected :
+ // VARIABLES PROTEGEES :
+ double temps; // le temps global
+ // la sauvegarde des paramètres d'un pas sur l'autre
+ double deltat; // increment de temps
+ // les bornes
+ double deltatmaxi; // increment de temps maxi
+ double deltatmini; // increment de temps mini
+ double tempsfin; // temps de fin de calcul
+ double prectemps; // precision sur le temps final
+
+ // METHODES PROTEGEES :
+
+ };
+ /// @} // end of group
+
+#endif