From 0fc9c9c3496c2d41aa81f89c60e1f7665cefe364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Rio?= Date: Sat, 25 Sep 2021 11:38:58 +0200 Subject: [PATCH] =?UTF-8?q?int=C3=A9gration=20des=20diff=C3=A9rents=20char?= =?UTF-8?q?gements:=20r=C3=A9pertoire=20"Chargement"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chargement/BlocCharge.cc | 1248 ++++++++++++++++++++ Chargement/BlocCharge.h | 260 +++++ Chargement/BlocCharge_T.h | 695 +++++++++++ Chargement/Charge.cc | 1305 +++++++++++++++++++++ Chargement/Charge.h | 428 +++++++ Chargement/Charge2.cc | 2145 ++++++++++++++++++++++++++++++++++ Chargement/Charge3.cc | 1381 ++++++++++++++++++++++ Chargement/VariablesTemps.cc | 117 ++ Chargement/VariablesTemps.h | 141 +++ 9 files changed, 7720 insertions(+) create mode 100644 Chargement/BlocCharge.cc create mode 100644 Chargement/BlocCharge.h create mode 100644 Chargement/BlocCharge_T.h create mode 100644 Chargement/Charge.cc create mode 100644 Chargement/Charge.h create mode 100644 Chargement/Charge2.cc create mode 100644 Chargement/Charge3.cc create mode 100644 Chargement/VariablesTemps.cc create mode 100644 Chargement/VariablesTemps.h 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