1601 lines
70 KiB
C++
1601 lines
70 KiB
C++
|
|
||
|
// This file is part of the Herezh++ application.
|
||
|
//
|
||
|
// The finite element software Herezh++ is dedicated to the field
|
||
|
// of mechanics for large transformations of solid structures.
|
||
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
||
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
||
|
//
|
||
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
||
|
//
|
||
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
||
|
// AUTHOR : Gérard Rio
|
||
|
// E-MAIL : gerardrio56@free.fr
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU General Public License as published by
|
||
|
// the Free Software Foundation, either version 3 of the License,
|
||
|
// or (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
||
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
// See the GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
//
|
||
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
||
|
|
||
|
|
||
|
|
||
|
#include "DdlLim.h"
|
||
|
#include <fstream>
|
||
|
#include <sstream>
|
||
|
#include <cstring>
|
||
|
|
||
|
|
||
|
# include <iostream>
|
||
|
using namespace std; //introduces namespace std
|
||
|
#include <stdlib.h>
|
||
|
#include "Sortie.h"
|
||
|
#include "ConstMath.h"
|
||
|
#include "CharUtil.h"
|
||
|
|
||
|
|
||
|
|
||
|
DdlLim::DdlLim () : // par defaut
|
||
|
tab(),ref(),t_min(0.),t_max(ConstMath::tresgrand),precedent(false)
|
||
|
,nom_maillage(NULL),champ(false),blocage_relatif(false),mvtsolide(NULL)
|
||
|
,nom_fnD_t_min(""),nom_fnD_t_max("")
|
||
|
,typeCL(RIEN_TYPE_CL)
|
||
|
{
|
||
|
};
|
||
|
|
||
|
// de copie
|
||
|
DdlLim::DdlLim (const DdlLim& d) :
|
||
|
t_min(d.t_min),t_max(d.t_max),ref(d.ref),tab(d.tab),precedent(d.precedent)
|
||
|
,nom_maillage(NULL),champ(d.champ),blocage_relatif(d.blocage_relatif)
|
||
|
,mvtsolide(NULL),typeCL(d.typeCL)
|
||
|
,nom_fnD_t_min(d.nom_fnD_t_min)
|
||
|
,nom_fnD_t_max(d.nom_fnD_t_max)
|
||
|
// Constructeur de copie
|
||
|
{ if (d.nom_maillage != NULL) nom_maillage = new string(*(d.nom_maillage));
|
||
|
if (d.mvtsolide != NULL)
|
||
|
mvtsolide = new MvtSolide(*(d.mvtsolide));
|
||
|
};
|
||
|
|
||
|
DdlLim::~DdlLim ()
|
||
|
// Destructeur
|
||
|
{ if (nom_maillage != NULL) delete nom_maillage;
|
||
|
if (mvtsolide != NULL) delete mvtsolide;
|
||
|
};
|
||
|
|
||
|
// Remplace la reference par nouveau
|
||
|
// ATTENTION : Les modifications liees au changement de la reference
|
||
|
// sont a la charge de l'utilisateur.
|
||
|
void DdlLim::Change_ref (string nouveau)
|
||
|
{ if (nouveau.length() == 0)
|
||
|
{ cout << "\nErreur : reference non valide car de longueur nulle !\n";
|
||
|
cout << "DdlLim::CHANGE_REF(string ) \n";
|
||
|
Sortie(1);
|
||
|
}
|
||
|
ref = nouveau;
|
||
|
};
|
||
|
|
||
|
// idem pour le changement de nom de maillage
|
||
|
void DdlLim::Change_nom_maillage(const string& nouveau)
|
||
|
{ if (nouveau.length() == 0)
|
||
|
{ cout << "\nErreur : reference de nom de maillage non valide car de longueur nulle ! "
|
||
|
<< " nom_mail= " << nouveau << "\n";
|
||
|
cout << "DdlLim::Change_nom_maillage(....) \n";
|
||
|
Sortie(1);
|
||
|
}
|
||
|
if (nom_maillage == NULL)
|
||
|
{ nom_maillage = new string(nouveau);}
|
||
|
else
|
||
|
{ *nom_maillage = nouveau;};
|
||
|
};
|
||
|
|
||
|
// lecture des degres de liberte
|
||
|
// sur le fichier d'entree
|
||
|
// util pour la lecture de ddl bloque
|
||
|
void DdlLim::Lecture(UtilLecture & entreePrinc)
|
||
|
{ // on regarde tout d'abord si il y a un nom de maillage, qui doit être le premier nom
|
||
|
string nom;
|
||
|
*(entreePrinc.entree) >> nom;
|
||
|
if (nom == "nom_mail=")
|
||
|
{ // cas où il y a un nom de maillage
|
||
|
*(entreePrinc.entree) >> nom; // lecture du nom
|
||
|
if (nom_maillage == NULL) { nom_maillage = new string(nom);}
|
||
|
else { *nom_maillage = nom;};
|
||
|
// puis on prépare la suite en lisant la référence
|
||
|
*(entreePrinc.entree) >> nom;
|
||
|
}
|
||
|
// lecture de la reference
|
||
|
char tat[250]; char * ta = tat; char tt[100]; char * t = tt;
|
||
|
char ch = '\''; char * pt = & ch; char bl = ' '; char* pbl = &bl;
|
||
|
ref = nom; // *(entreePrinc.entree) >> ref;
|
||
|
if (ref.length() == 0)
|
||
|
{ // pas de reference
|
||
|
cout << "\n erreur de lecture d'une reference de ddl bloquee "
|
||
|
<< " la chaine a une longueur nulle \n";
|
||
|
entreePrinc.MessageBuffer("*** lecture d'une reference de ddl bloquee ****" );
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
// def de la liste de ddl
|
||
|
list <Ddlbloque> lili;
|
||
|
// on regarde si un type de condition limite est indiqué
|
||
|
if (strstr(entreePrinc.tablcar,"typeCL_=")!=NULL)
|
||
|
{ string mot;
|
||
|
*(entreePrinc.entree) >> mot ;
|
||
|
if (mot != "typeCL_=")
|
||
|
{ cout << "\n erreur de lecture d'une reference "
|
||
|
<< " on s'attandait a lire le mot cle : typeCL_= et on a lue: " << mot << " \n";
|
||
|
entreePrinc.MessageBuffer("*** lecture d'une reference de ddl bloquee: mot cle typeCL_= ****" );
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// sinon c'est ok pour le mot cle, on passe au contenu,
|
||
|
*(entreePrinc.entree) >> mot;
|
||
|
if (Existe_typeCL(mot))
|
||
|
{ typeCL = Id_nomTypeCL(mot);} // cas ou le type de cl existe
|
||
|
else
|
||
|
{ cout << "\n erreur de lecture d'un type de condition limite "
|
||
|
<< " on a lue: " << mot << " \n";
|
||
|
entreePrinc.MessageBuffer("*** lecture d'une reference de ddl bloquee: type de CL ****" );
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
}
|
||
|
else // sinon on précise qu'il n'y a pas de type de CL particulier
|
||
|
{ typeCL = RIEN_TYPE_CL; };
|
||
|
|
||
|
// maintenant les cas particulier
|
||
|
if (strstr(entreePrinc.tablcar,"champ_de:")!=NULL)
|
||
|
// on regarde si c'est un champ de valeur c'est-à-dire une valeur par noeud de la ref
|
||
|
// dans ce cas appel de la procédure a doc
|
||
|
{ lili = Lecture_champ(entreePrinc); champ = true;}
|
||
|
else if (strstr(entreePrinc.tablcar,MvtSolide::MotCleMvtSolide().c_str())!=NULL)
|
||
|
// on regarde si c'est un mouvement solide, si oui appel de la procédure a doc
|
||
|
{ // petite vérif: incompatible avec la condition de tangente imposée
|
||
|
if (typeCL == TANGENTE_CL)
|
||
|
{cout << "\n erreur en lecture, la condition de mouvement solide est incompatible "
|
||
|
<< " avec une condition de tangente imposée !!! revoir l'entree de la "
|
||
|
<< " condition " ;
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
lili = Lecture_mvtSolide(entreePrinc); champ = false ;
|
||
|
}
|
||
|
else
|
||
|
{champ = false;
|
||
|
// --- dans la suite comme il ne s'agit pas d'un champ toutes les données sont sur une seule ligne -----
|
||
|
//recup de la fin de la ligne
|
||
|
char tout[150] ; char * ptout = tout;
|
||
|
(entreePrinc.entree)->get(ptout,150);
|
||
|
// avant la lecture on remplace toutes les virgules par des espaces
|
||
|
char * ii = strchr(ptout,',');
|
||
|
while (ii != NULL)
|
||
|
{ *ii = ' ';
|
||
|
ii = strchr(ptout,',');
|
||
|
}
|
||
|
// def d'un flot intermédiaire
|
||
|
#ifndef ENLINUX_STREAM
|
||
|
istringstream flot(ptout);
|
||
|
#else
|
||
|
istrstream flot(ptout);
|
||
|
#endif
|
||
|
|
||
|
// lecture tant que le flot est valide
|
||
|
while (flot.rdstate() == 0)
|
||
|
// tout d'abord on passe les espaces qui sont des séparateurs
|
||
|
// lecture du prochain caractère sans modifier le flot
|
||
|
{ char car;
|
||
|
flot >> car;
|
||
|
// éventuellement il n'avait pas bien déterminé la fin de l'enregistrement
|
||
|
// au niveau du while, dans ce cas si durant la lecture de car il y a eu un pb
|
||
|
// cela signifie qu'en fait la ligne était terminée donc on s'arrête
|
||
|
if (flot.rdstate() != 0) break;
|
||
|
while ( (car==' ') && (flot.rdstate() == 0 ))
|
||
|
// cas où le prochain caractère est un espace
|
||
|
{ flot >> car;};
|
||
|
flot.putback(car);
|
||
|
bool un_ddl_a_lire=true;
|
||
|
// on démarre une boucle qui se termine lorsqu'il n'y a plus de ddl à lire
|
||
|
while(un_ddl_a_lire)
|
||
|
{// on définit un ddl pour la lecture
|
||
|
Ddlbloque elem;
|
||
|
// deux cas, soit un ddl nulle par defaut, soit une valeur non nulle imposee
|
||
|
// soit le caractère est ' , signifie que c'est un ddl avec une valeur
|
||
|
// imposée
|
||
|
if ( (car=='\'') && (flot.rdstate() == 0 ))
|
||
|
{ // on passe le premier '
|
||
|
flot >> car;
|
||
|
// on lit jusqu'au prochain ' en non formaté
|
||
|
flot.get(ta,150,'\'');
|
||
|
// on passe ce dernier '
|
||
|
flot >> car;
|
||
|
// on recherche le = pour mettre un blanc a la place
|
||
|
char * ii = strchr(ta,'\'');char * pii=ii; // sauvegarde de l'adresse
|
||
|
ii = strchr(ta,'='); // on recherche le =
|
||
|
if (ii == NULL)
|
||
|
{ cout << "\n erreur de syntaxe dans la definition des conditions limites "
|
||
|
<< " imposees a une valeur non nulle ";
|
||
|
cout << " le ddl doit etre separe de la valeur par le signe = , caractere non"
|
||
|
<< " trouve ";
|
||
|
entreePrinc.MessageBuffer("*** lecture d'une reference de ddl bloquee ****" );
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
*ii = ' '; // supprime le =
|
||
|
// def d'un flux intermediaire
|
||
|
#ifndef ENLINUX_STREAM
|
||
|
istringstream flux (ta);
|
||
|
#else
|
||
|
istrstream flux (ta);
|
||
|
#endif
|
||
|
|
||
|
flux >> t ;
|
||
|
elem.ddl.Change_nom(t);
|
||
|
// on vérifie que le ddl est compatible avec la dimension
|
||
|
if (!CompatDim(t))
|
||
|
{ cout << "\n erreur de choix de ddl dans la definition des conditions limites "
|
||
|
<< " le ddl " << t << " n'est pas compatible avec la dimension du probleme ";
|
||
|
entreePrinc.MessageBuffer("*** lecture d'une reference de ddl bloquee ****" );
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
|
||
|
// on regarde s'il ne s'agit pas d'une courbe ou fonction de charge imposée
|
||
|
bool sans_courbe_ou_fct_nD=true; // variable locale
|
||
|
// l'ordre d'apparition de la courbe de charge ou de la fonction nD peut être
|
||
|
// quelconque
|
||
|
if ((strstr(ta,"COURBE_CHARGE:")!=0)|| (strstr(ta,"Fonction_nD_CHARGE:")!=0))
|
||
|
{string nom_fonct;string nom_cle;
|
||
|
flux >> nom_cle >> nom_fonct;
|
||
|
// a) cas d'une courbe
|
||
|
if(nom_cle == "COURBE_CHARGE:")
|
||
|
{ // cas d'une courbe de charge
|
||
|
// flux >> toto >> elem.co_charge;
|
||
|
elem.co_charge = nom_fonct;
|
||
|
sans_courbe_ou_fct_nD=false;
|
||
|
// on regarde s'il y a une fct nD qui suit
|
||
|
if(strstr(ta,"Fonction_nD_CHARGE:")!=0)
|
||
|
{ // cas d'une fonction nD
|
||
|
string toto;
|
||
|
flux >> toto >> elem.f_charge;
|
||
|
// on vérifie la présence au bon endroit du mot clé Fonction_nD_CHARGE:
|
||
|
if (toto != "Fonction_nD_CHARGE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD ";
|
||
|
cout << " on attendait Fonction_nD_CHARGE: "
|
||
|
<< " et on a lu "<< toto;
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
else if (nom_cle == "Fonction_nD_CHARGE:")
|
||
|
{ elem.f_charge = nom_fonct;
|
||
|
sans_courbe_ou_fct_nD=false;
|
||
|
// on regarde s'il y a une courbe 1D qui suit
|
||
|
if(strstr(ta,"COURBE_CHARGE:")!=0)
|
||
|
{ // cas d'une courbe de charge
|
||
|
string toto;
|
||
|
flux >> toto >> elem.co_charge;
|
||
|
elem.co_charge = nom_fonct;
|
||
|
// on vérifie la présence au bon endroit du mot clé Fonction_nD_CHARGE:
|
||
|
if (toto != "COURBE_CHARGE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du nom de la courbe ";
|
||
|
cout << " on attendait COURBE_CHARGE: "
|
||
|
<< " et on a lu "<< toto;
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{cout << "\n erreur de syntaxe en lecture du nom de la courbe ou du nom d'une fonction nD";
|
||
|
cout << " on attendait COURBE_CHARGE: ou Fonction_nD_CHARGE: "
|
||
|
<< " et on a lu "<< nom_cle;
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// on récupère l'échelle éventuellement
|
||
|
if(strstr(ta,"ECHELLE:")!=0)
|
||
|
{ // cas où il y a un facteur d'échelle
|
||
|
string toto;
|
||
|
flux >> toto;
|
||
|
if (toto != "ECHELLE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du facteur d'échelle ";
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// lecture du facteur
|
||
|
flux >> elem.echelle;
|
||
|
};
|
||
|
};
|
||
|
// // b) cas d'une fonction nD
|
||
|
// if(strstr(ta,"Fonction_nD_CHARGE:")!=0)
|
||
|
// { // cas d'une fonction nD
|
||
|
// string toto;
|
||
|
// flux >> toto >> elem.f_charge;
|
||
|
// sans_courbe_ou_fct_nD=false;
|
||
|
// // on vérifie la présence au bon endroit du mot clé Fonction_nD_CHARGE:
|
||
|
// if (toto != "Fonction_nD_CHARGE:")
|
||
|
// {cout << "\n erreur de syntaxe en lecture du nom de la fonction nD ";
|
||
|
// cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
// entreePrinc.MessageBuffer("**erreur**");
|
||
|
// throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
// Sortie(1);
|
||
|
// };
|
||
|
// };
|
||
|
|
||
|
// si aucune courbe ou fct nD
|
||
|
if (sans_courbe_ou_fct_nD)
|
||
|
// cas où c'est une valeur fixe
|
||
|
{
|
||
|
flux >> elem.ddl.Valeur();
|
||
|
}
|
||
|
elem.ddl.Change_fixe (true);
|
||
|
}
|
||
|
else if (flot.rdstate() == 0 ) // il s'agit d'un ddl à 0
|
||
|
{ //un ddl nulle par defaut
|
||
|
flot >> t;
|
||
|
// on vérifie que c'est bien un ddl
|
||
|
if (!ExisteEnum_ddl(t))
|
||
|
{ cout << "\n erreur , on s'attendait a lire un ddl et on a lue: " << t
|
||
|
<< " !!, partie de condition actuellement lue: ";
|
||
|
this->Affiche();
|
||
|
cout << " DdlLim::Lecture(UtilLecture & entreePrinc)" << endl;
|
||
|
entreePrinc.MessageBuffer("** erreur en lecture des conditions limites**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie (1);
|
||
|
};
|
||
|
elem.ddl.Change_nom(t);
|
||
|
elem.ddl.Valeur() = 0;
|
||
|
elem.ddl.Change_fixe (true);
|
||
|
};
|
||
|
// on verifie que l'on n'utilise pas deux fois le meme identificateur de ddl
|
||
|
// avec deux valeurs differentes
|
||
|
list <Ddlbloque>::iterator imi;
|
||
|
for (imi=lili.begin() ; imi != lili.end(); imi++)
|
||
|
if (((*imi).ddl.Id_nom() == elem.ddl.Id_nom()) && ((*imi).ddl.Valeur() != elem.ddl.Valeur()))
|
||
|
{ cout << "\n erreur , un meme identificateur de ddl est utilisee avec"
|
||
|
<< " deux valeurs differentes \n";
|
||
|
cout << " premiere Ddl : "; (*imi).ddl.Affiche();
|
||
|
cout << " seconde Ddl : "; elem.ddl.Affiche();
|
||
|
cout << " DdlLim::Lecture(UtilLecture & entreePrinc)" << endl;
|
||
|
entreePrinc.MessageBuffer("** erreur en lecture des conditions limites**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie (1);
|
||
|
}
|
||
|
// stockage du ddl bloque
|
||
|
lili.push_back(elem);
|
||
|
// --- maintenant on regarde si on a encore d'autre ddl à lire
|
||
|
// 1- on passe les blancs
|
||
|
flot >> car;
|
||
|
while ( (car==' ') && (flot.rdstate() == 0 ))
|
||
|
// cas où le prochain caractère est un espace
|
||
|
{ flot >> car;}
|
||
|
flot.putback(car);
|
||
|
// on enregistre la position actuelle dans le flot au premier caractère non nul
|
||
|
streampos posi=flot.tellg();
|
||
|
// maintenant on regarde s'il reste un ddl à lire
|
||
|
// en ayant passé éventuellement le caractère ', on regarde s'il s'agit
|
||
|
// d'un énum de ddl
|
||
|
// manip pour passer le caractère '
|
||
|
flot >> car; // lecture du prochain caractère
|
||
|
if (flot.rdstate() == 0 )
|
||
|
{ // s'il ne s'agit pas de ' on le remet dans le flot
|
||
|
if (!(car=='\'')) flot.putback(car);
|
||
|
// maintenant on lit la chaine
|
||
|
string ddnom;
|
||
|
flot >> ddnom; // lecture de la chaine
|
||
|
// on cherche s'il y a éventuellement un signe =, si oui
|
||
|
// on supprime le signe = et tout ce qui suit
|
||
|
string::iterator ala,alafin=ddnom.end();
|
||
|
for (ala=ddnom.begin();ala!=alafin;ala++)
|
||
|
if (*ala == '=')
|
||
|
{ ddnom.erase(ala,alafin);
|
||
|
break;
|
||
|
};
|
||
|
// est-ce que c'est un enum de ddl
|
||
|
if (ExisteEnum_ddl(ddnom))
|
||
|
{un_ddl_a_lire=true;
|
||
|
flot.clear(); // on remet ok le flot au cas où on avait été jusqu'au bout à la
|
||
|
} // dernière lecture par exemple, car de toute manière on va relire
|
||
|
else {un_ddl_a_lire=false;};
|
||
|
}
|
||
|
else {un_ddl_a_lire=false;}; // sinon fin
|
||
|
// retour avant la lecture du futur ddl éventuel
|
||
|
flot.seekg(posi, ios::beg);
|
||
|
// on prépare le prochain caractère
|
||
|
flot >> car;
|
||
|
flot.putback(car);
|
||
|
|
||
|
}; //-- fin de while(un_ddl_a_lire)
|
||
|
|
||
|
// --- lecture éventuelle des temp mini et maxi ---
|
||
|
if (((!flot.rdstate())&& (!(flot.eof())))) // lecture s'il n'y a pas d'erreur
|
||
|
{if(strstr(ptout,"TEMPS_MINI=") != 0)
|
||
|
{ // cas d'un temps mini
|
||
|
string toto;
|
||
|
flot >> toto;
|
||
|
// on vérifie la présence au bon endroit du mot clé TEMPS_MINI=
|
||
|
if (toto != "TEMPS_MINI=")
|
||
|
{cout << "\n erreur de syntaxe en lecture du temps mini, info lue: " << toto;
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
//lecture du temps mini
|
||
|
string nomOuNombre;
|
||
|
flot >> nomOuNombre;
|
||
|
if (nomOuNombre != "fct_nD:")
|
||
|
{t_min = ChangeReel(nomOuNombre);
|
||
|
nom_fnD_t_min = "";
|
||
|
}
|
||
|
else
|
||
|
{flot >> nom_fnD_t_min;};
|
||
|
}
|
||
|
};
|
||
|
if (((!flot.rdstate())&& (!(flot.eof())))) // lecture s'il n'y a pas d'erreur
|
||
|
{if(strstr(ptout,"TEMPS_MAXI=") != 0)
|
||
|
{ // cas d'un temps maxi
|
||
|
string toto;
|
||
|
flot >> toto;
|
||
|
// on vérifie la présence au bon endroit du mot clé TEMPS_MAXI=
|
||
|
if (toto != "TEMPS_MAXI=")
|
||
|
{cout << "\n erreur de syntaxe en lecture du temps maxi ";
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
//lecture du temps maxi
|
||
|
string nomOuNombre;
|
||
|
flot >> nomOuNombre;
|
||
|
if (nomOuNombre != "fct_nD:")
|
||
|
{t_max = ChangeReel(nomOuNombre);
|
||
|
nom_fnD_t_max = "";
|
||
|
}
|
||
|
else
|
||
|
{flot >> nom_fnD_t_max;};
|
||
|
}
|
||
|
};
|
||
|
// lecture éventuel de l'indicateur de blocage "relatif"
|
||
|
if (((!flot.rdstate())&& (!(flot.eof())))) // lecture s'il n'y a pas d'erreur
|
||
|
if(strstr(ptout,"BLOCAGE_RELATIF_") != 0)
|
||
|
{ string toto; flot >> toto; // on passe le mot clé
|
||
|
blocage_relatif = true;
|
||
|
// message d'avertissement éventuel
|
||
|
int taille_tab = tab.Taille();
|
||
|
bool queDesCourbesDeCharge = true;
|
||
|
for (int i=1; i<= taille_tab; i++) // on regarde s'il y n'y a que des courbes de charge
|
||
|
if (tab(i).co_charge == "")
|
||
|
{ queDesCourbesDeCharge = false;} ;
|
||
|
if (!queDesCourbesDeCharge)
|
||
|
{ // cas où il n'y a au moins un ddl sans courbe de charge
|
||
|
cout << "\n **** Warning !!! le blocage relatif ne fonctionne pas avec des blocages simples "
|
||
|
<< " le blocage relatif ne fonctionne qu'avec les ddls soumis a une courbe de charge ";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
} // -- fin de lecture tant que le flot est valide
|
||
|
}//-- fin du test sur existence de champ ou pas
|
||
|
// enregistrement des infos
|
||
|
tab.Change_taille((int) lili.size());
|
||
|
list <Ddlbloque>::iterator i;
|
||
|
int j;
|
||
|
for (i=lili.begin(),j=1 ; i != lili.end(); i++,j++)
|
||
|
tab(j) = *i;
|
||
|
// dans le cas où il s'agit d'une condition de tangente imposée, il faut que
|
||
|
// le nombre de ddl = la dimension de l'espace, car la condition représente un vecteur
|
||
|
if (typeCL == TANGENTE_CL)
|
||
|
if (tab.Taille() != ParaGlob::Dimension())
|
||
|
{cout << "\n erreur en lecture d'une condition de tangente imposée, "
|
||
|
<< " le nombre de dd (ici = " << tab.Taille() << ") doit etre egale a la dimension"
|
||
|
<< " de l'espace (ici = " << ParaGlob::Dimension()<<") ";
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// verification en fonction de la dimension du pb
|
||
|
// VerifDimDdl();
|
||
|
|
||
|
};
|
||
|
|
||
|
// examine si le ddlmin passé en argument possède les mêmes cibles que this
|
||
|
// c'est-à-dire s'il y a une intersection incohérente entre les deux tableaux de ddl de base
|
||
|
// ramène true s'il y a une intersection incohérente non nulle, false sinon
|
||
|
bool DdlLim::MemeCibleMaisDataDifferents(const DdlLim& d) const
|
||
|
{ // l'opération est malheureusement combinatoire (en N^2) à moins de classer les ddlm
|
||
|
// mais pour l'instant ce n'est pas fait, je ne suis pas sûr que ici le temps soit un pb
|
||
|
bool incoherence = false;
|
||
|
|
||
|
int tailtab = tab.Taille();
|
||
|
int tailtabex = d.Taille();
|
||
|
for (int i=1; i<= tailtab; i++)
|
||
|
for (int j=1; j<= tailtabex; j++)
|
||
|
if (tab(i).ddl.Id_nom() == d.ElemLim_const(j).Id_nom())
|
||
|
if (tab(i).ddl != d.ElemLim_const(j))
|
||
|
// si on a deux même noms de ddl et le reste qui n'est pas identique --> incohérence
|
||
|
incoherence = true;
|
||
|
// retour
|
||
|
return incoherence;
|
||
|
};
|
||
|
|
||
|
// ramène true si le DdlLim contient l'enum_ddl passé en argument, false sinon
|
||
|
bool DdlLim::Existe_ici_leDdl(Enum_ddl enu) const
|
||
|
{ // on passe en revue le tableau de ddl
|
||
|
int taille = tab.Taille();
|
||
|
for (int i=1;i<=taille;i++)
|
||
|
if (tab(i).ddl.Id_nom() == enu)
|
||
|
return true;
|
||
|
// si on arrive ici, c'est que l'on n'a rien trouvé !
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
// ramène true si le DdlLim contient au moins un déplacement, false sinon
|
||
|
bool DdlLim::Existe_ici_un_deplacement() const
|
||
|
{ // on passe en revue le tableau de ddl
|
||
|
int taille = tab.Taille();
|
||
|
for (int i=1;i<=taille;i++)
|
||
|
{switch (ParaGlob::Dimension())
|
||
|
{case 3: if (tab(i).ddl.Id_nom() == UZ)
|
||
|
return true;
|
||
|
case 2: if (tab(i).ddl.Id_nom() == UY)
|
||
|
return true;
|
||
|
case 1: if (tab(i).ddl.Id_nom() == UX)
|
||
|
return true;
|
||
|
};
|
||
|
};
|
||
|
// si on arrive ici, c'est que l'on n'a rien trouvé !
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
// Affiche les donnees liees au degre de liberte
|
||
|
void DdlLim::Affiche () const
|
||
|
{ // affichage éventuelle du nom de maillage
|
||
|
if (nom_maillage != NULL)
|
||
|
{ cout << "\n nom_mail= " << *nom_maillage;} else cout << "\n";
|
||
|
// affichage éventuelle du type de CL
|
||
|
if (typeCL != RIEN_TYPE_CL)
|
||
|
{ cout << "type_de_CL= " << NomTypeCL(typeCL);};
|
||
|
// puis le reste
|
||
|
if (champ)
|
||
|
{cout << " ref_de_champ= " << ref << ':';}
|
||
|
else if (mvtsolide != NULL)
|
||
|
{mvtsolide->Affiche();}
|
||
|
else
|
||
|
{cout << " ref= " << ref << ':';};
|
||
|
for (int i=1; i<= tab.Taille();i++)
|
||
|
{ (tab(i).ddl).Affiche();
|
||
|
if (tab(i).co_charge != "")
|
||
|
cout << " courbe_de_charge= " << (tab(i)).co_charge << " echelle= " << (tab(i)).echelle;
|
||
|
if (tab(i).f_charge != "")
|
||
|
cout << " fonction_nD_de_charge= " << (tab(i)).f_charge << " ";
|
||
|
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 << " activité_actuelle: " << precedent;
|
||
|
cout << " blocage_relatif_ " << blocage_relatif << " ";
|
||
|
};
|
||
|
cout << endl;
|
||
|
};
|
||
|
|
||
|
|
||
|
// Realise l'egalite entre deux degres de liberte
|
||
|
DdlLim& DdlLim::operator= (const DdlLim& d)
|
||
|
{ if (d.nom_maillage == NULL)
|
||
|
{ if (nom_maillage != NULL) {delete nom_maillage;nom_maillage = NULL;}}
|
||
|
else
|
||
|
{ if (nom_maillage == NULL) nom_maillage = new string(*(d.nom_maillage));
|
||
|
else *nom_maillage = *(d.nom_maillage);
|
||
|
};
|
||
|
typeCL = d.typeCL;
|
||
|
ref=d.ref;
|
||
|
tab = d.tab;
|
||
|
nom_fnD_t_min = d.nom_fnD_t_min ;
|
||
|
nom_fnD_t_max = d.nom_fnD_t_max ;
|
||
|
t_min = d.t_min;
|
||
|
t_max = d.t_max;
|
||
|
precedent = d.precedent;
|
||
|
champ = d.champ;
|
||
|
blocage_relatif = d.blocage_relatif;
|
||
|
if (d.mvtsolide != NULL)
|
||
|
{ if (mvtsolide == NULL)
|
||
|
{ mvtsolide = new MvtSolide(*(d.mvtsolide));}
|
||
|
else
|
||
|
{ (*mvtsolide) = *(d.mvtsolide);};
|
||
|
}
|
||
|
else // cas où d.mvtsolide est null
|
||
|
{ if (mvtsolide != NULL)
|
||
|
{delete mvtsolide;mvtsolide = NULL;};
|
||
|
};
|
||
|
return (*this);
|
||
|
};
|
||
|
|
||
|
//Surcharge d'operateur logique
|
||
|
bool DdlLim::operator == (const DdlLim& a) const
|
||
|
{ if (nom_maillage == NULL)
|
||
|
{ if (a.nom_maillage != NULL) return false;
|
||
|
}
|
||
|
else
|
||
|
{ if (a.nom_maillage == NULL) return false;
|
||
|
// sinon les deux sont non null: on test leur égalité
|
||
|
if (*nom_maillage != *(a.nom_maillage)) return false;
|
||
|
};
|
||
|
// maintenant on regarde les autres données
|
||
|
if (typeCL != a.typeCL) return false;
|
||
|
// 1) traitement du cas des mouvements solides
|
||
|
bool apriorivrai = true;
|
||
|
if (a.mvtsolide != NULL)
|
||
|
{ if (mvtsolide == NULL)
|
||
|
{ //apriorivrai = false;
|
||
|
return false; } // on arrete tout de suite
|
||
|
else
|
||
|
{ apriorivrai = ((*mvtsolide) == *(a.mvtsolide));};
|
||
|
};
|
||
|
// 2) traitement du rest
|
||
|
if (( ref==a.ref) && (tab==a.tab)
|
||
|
&& (t_min == a.t_min) && (t_max == a.t_max)
|
||
|
&& (nom_fnD_t_min == a.nom_fnD_t_min)
|
||
|
&& (nom_fnD_t_max == a.nom_fnD_t_max)
|
||
|
&& (precedent == a.precedent)
|
||
|
&& (champ == a.champ) && (blocage_relatif == a.blocage_relatif)
|
||
|
&& apriorivrai)
|
||
|
return true;
|
||
|
else return false;
|
||
|
};
|
||
|
|
||
|
// surcharge de l'operateur de lecture typée
|
||
|
istream & operator >> (istream & entree, DdlLim & dlim)
|
||
|
{ // vérification du type
|
||
|
string type;
|
||
|
entree >> type;
|
||
|
if (type == "DdlLim") {dlim.champ = false;}
|
||
|
else if (type == "DdlLim_de_champ") {dlim.champ = true;}
|
||
|
else
|
||
|
{cout << "\n erreur en lecture d'un DdlLim ";
|
||
|
Sortie (1);
|
||
|
return entree;
|
||
|
}
|
||
|
// lecture d'un nom de maillage éventuel
|
||
|
bool existe_nom_maillage; entree >> existe_nom_maillage;
|
||
|
string nom;
|
||
|
if (existe_nom_maillage)
|
||
|
{ entree >> nom;
|
||
|
if (dlim.nom_maillage == NULL)
|
||
|
dlim.nom_maillage = new string(nom);
|
||
|
else
|
||
|
*(dlim.nom_maillage) = nom;
|
||
|
};
|
||
|
// passage du nom de la référence puis le type de cl puis du tableau
|
||
|
entree >> dlim.ref >> nom;
|
||
|
dlim.typeCL = Id_nomTypeCL(nom);
|
||
|
entree >> dlim.tab >> nom >> dlim.t_min >> nom >> dlim.t_max >> nom >> dlim.precedent;
|
||
|
entree >> nom >> dlim.blocage_relatif;
|
||
|
// mouvement solide éventuel
|
||
|
int iii=0;
|
||
|
entree >> iii;
|
||
|
if (iii == 0) // indique qu'il n'y a pas de mouvement solide
|
||
|
{if (dlim.mvtsolide != NULL) // on supprime le mouvement solide s'il en existait un
|
||
|
{delete dlim.mvtsolide;dlim.mvtsolide=NULL;};
|
||
|
}
|
||
|
else // cas d'un mouvement solide
|
||
|
{ if (dlim.mvtsolide != NULL) // création s'il n'y en avait pas
|
||
|
dlim.mvtsolide = new MvtSolide();
|
||
|
entree >> *(dlim.mvtsolide); // lecture du mouvement solide
|
||
|
};
|
||
|
|
||
|
return entree;
|
||
|
};
|
||
|
|
||
|
// surcharge de l'operateur d'ecriture typée
|
||
|
ostream & operator << ( ostream & sort,const DdlLim & dlim)
|
||
|
{ // tout d'abord un indicateur donnant le type
|
||
|
if (dlim.champ)
|
||
|
{sort << "DdlLim_de_champ ";}
|
||
|
else
|
||
|
{sort << "DdlLim ";};
|
||
|
// puis le maillage éventuelle
|
||
|
if (dlim.nom_maillage == NULL)
|
||
|
sort << false << " ";
|
||
|
else
|
||
|
sort << true << " " << *(dlim.nom_maillage) << " ";
|
||
|
// maintenant la référence
|
||
|
sort << dlim.ref << " ";
|
||
|
// le type de condition limite
|
||
|
sort << NomTypeCL(dlim.typeCL) << " ";
|
||
|
// puis les data
|
||
|
sort << dlim.tab;
|
||
|
sort << " tmin= " << dlim.t_min << " tmax= " << dlim.t_max << " prec " << dlim.precedent;
|
||
|
sort << " blocage_relatif= " << dlim.blocage_relatif;
|
||
|
// mouvement solide éventuel
|
||
|
if (dlim.mvtsolide == NULL)
|
||
|
{ sort << " 0 ";}
|
||
|
else
|
||
|
{ sort << " 1 " << (*(dlim.mvtsolide)) << " ";};
|
||
|
sort << "\n";
|
||
|
return sort;
|
||
|
};
|
||
|
|
||
|
// affichage et definition interactive des commandes
|
||
|
void DdlLim::Info_commande_DdlLim(ofstream & sort,bool plusieurs_maillages)
|
||
|
{ //On va proposer un menu
|
||
|
string rep=" ";
|
||
|
string nom_courbe="_";
|
||
|
string nom_fonction_nD="_";
|
||
|
double echelle = ConstMath::trespetit;
|
||
|
double temps_mini = - ConstMath::trespetit;
|
||
|
double temps_maxi = ConstMath::tresgrand;
|
||
|
// tableau des choix possibles
|
||
|
Tableau <string> tab_choix(16);
|
||
|
tab_choix(1) = "\n (0 ou f) (defaut) (fin) ";
|
||
|
tab_choix(2) = "\n (1) choix d'un deplacement impose ";
|
||
|
tab_choix(3) = "\n (2) ou autre ddl impose ";
|
||
|
tab_choix(4) = "\n (3) valeur du ddl ? ";
|
||
|
tab_choix(5) = "\n (4) ou utilisation d'une courbe de charge ";
|
||
|
tab_choix(6) = "\n (5) echelle ";
|
||
|
tab_choix(7) = "\n (6) temps mini ";
|
||
|
tab_choix(8) = "\n (7) temps maxi ";
|
||
|
tab_choix(9) = "\n (8) blocage relatif ";
|
||
|
tab_choix(10) = "\n (9) condition de tangence ";
|
||
|
tab_choix(11) = "\n (10) mouvement solide impose ";
|
||
|
tab_choix(12) = "\n (11) champ de valeurs ";
|
||
|
tab_choix(13) = "\n (12) liste de ddl existant ";
|
||
|
tab_choix(14) = "\n (13 ou ? ) information ";
|
||
|
tab_choix(15) = "\n (14) plusieurs ddl de deplacement, nuls ";
|
||
|
tab_choix(16) = "\n (15) utilisation d'une fonction nD de charge ";
|
||
|
// tableau d'indexage pour limiter les choix
|
||
|
int choix=1; // type de choix: ici le cas choix d'un ddl de depart
|
||
|
Tableau <int> index(9);
|
||
|
index(1) = 1; index(2) = 2; index(3) = 3;index(4) = 10;index(5) = 11;
|
||
|
index(6) = 12; index(7) = 13; index(8) =14;index(9) =15;
|
||
|
string nom_des_ddl="";
|
||
|
bool blocage_relatif =false; // par défaut
|
||
|
double valeur_du_ddl = 0.;
|
||
|
bool plusieurs_ddl_deplacement_nul = false;
|
||
|
string nom_ref="";
|
||
|
string condition_tangence="";
|
||
|
bool condition_mvt_solide=false;
|
||
|
ostringstream flux;
|
||
|
bool champ_valeurs=false;
|
||
|
string str_champ_valeurs="";
|
||
|
|
||
|
|
||
|
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
|
||
|
{
|
||
|
try
|
||
|
{ for (int i=1;i<=index.Taille();i++)
|
||
|
cout << tab_choix(index(i));
|
||
|
cout << "\n reponse ? ";
|
||
|
rep = lect_return_defaut(false,"0"); cout << " grandeur lue " << rep;
|
||
|
if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie
|
||
|
// c'est à la sortie que ce fait l'écriture donc ici
|
||
|
{sort << "\n";
|
||
|
if ((nom_des_ddl=="")&&(condition_tangence =="")&&(!condition_mvt_solide)
|
||
|
&&(!champ_valeurs))
|
||
|
break; // arrêt s'il n'y a pas eu de choix
|
||
|
if (plusieurs_maillages)
|
||
|
{ cout << "\n nom du maillage ? ";
|
||
|
string nom_mail;
|
||
|
nom_mail= lect_chaine(); cout << " nom lu = "<< nom_mail;
|
||
|
sort << "nom_mail= "<< nom_mail << " ";
|
||
|
};
|
||
|
sort << nom_ref <<" ";
|
||
|
// ici plusieurs cas
|
||
|
if ((condition_tangence =="")&&(!condition_mvt_solide)&&(!champ_valeurs))
|
||
|
{ // cas normal
|
||
|
bool sortie_cote=false;
|
||
|
if (((valeur_du_ddl != 0.)||(nom_courbe != "_")
|
||
|
|| (nom_fonction_nD != "_"))
|
||
|
&& (!plusieurs_ddl_deplacement_nul))
|
||
|
{sort << " ' ";sortie_cote=true;};
|
||
|
sort << nom_des_ddl ;
|
||
|
if (sortie_cote) sort <<"= ";
|
||
|
if (!plusieurs_ddl_deplacement_nul)
|
||
|
{if (nom_courbe != "_")
|
||
|
{sort << " COURBE_CHARGE: "<<nom_courbe<<" ";}
|
||
|
else if (sortie_cote == true)
|
||
|
{sort << valeur_du_ddl<<" ";};
|
||
|
if (nom_fonction_nD != "_")
|
||
|
{sort << " Fonction_nD_CHARGE: "<<nom_fonction_nD<<" ";};
|
||
|
if (echelle != ConstMath::trespetit)
|
||
|
sort << " ECHELLE: "<< echelle<<" ";
|
||
|
if (sortie_cote)
|
||
|
sort << " ' ";
|
||
|
};
|
||
|
}
|
||
|
else if (condition_mvt_solide)
|
||
|
{ // cas d'un mouvement solide
|
||
|
sort << nom_des_ddl ;
|
||
|
sort <<flux.str();
|
||
|
if (nom_courbe != "_")
|
||
|
{sort << " COURBE_CHARGE: "<<nom_courbe<<" ";};
|
||
|
if (nom_fonction_nD != "_")
|
||
|
{sort << " Fonction_nD_CHARGE: "<<nom_fonction_nD<<" ";};
|
||
|
if (echelle != ConstMath::trespetit)
|
||
|
sort << " ECHELLE: "<< echelle<<" ";
|
||
|
}
|
||
|
else if (champ_valeurs)
|
||
|
{ // cas d'un champ de valeur
|
||
|
sort << str_champ_valeurs ;
|
||
|
}
|
||
|
else // cas d'une condition de tangence
|
||
|
{ sort << condition_tangence;};
|
||
|
if (temps_mini != (- ConstMath::trespetit))
|
||
|
sort << " TEMPS_MINI= "<< temps_mini<<" ";
|
||
|
if (temps_maxi != ConstMath::tresgrand)
|
||
|
sort << " TEMPS_MAXI= "<< temps_maxi<<" ";
|
||
|
if (blocage_relatif)
|
||
|
sort << " BLOCAGE_RELATIF_ "<<endl;
|
||
|
break;
|
||
|
};
|
||
|
int num = ChangeEntier(rep);
|
||
|
if (Minuscules(rep) == "?")
|
||
|
num = 13;
|
||
|
bool choix_valide=false;
|
||
|
if ((num >= 0)&&(num<=16))
|
||
|
{ choix_valide=true; }
|
||
|
else { cout << "\n Erreur on attendait un entier entre 0 et 16 !!, "
|
||
|
<< "\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: // déplacement imposé
|
||
|
{ string repi=" ";
|
||
|
cout << "\n -- choix du ddl -- ";
|
||
|
switch (ParaGlob::Dimension())
|
||
|
{case 1: cout << "\n (1) UX "; break;
|
||
|
case 2: cout << "\n (1) UX "
|
||
|
<< "\n (2) UY "; break;
|
||
|
case 3: cout << "\n (1) UX "
|
||
|
<< "\n (2) UY "
|
||
|
<< "\n (3) UZ "; break;
|
||
|
default: cout << " ";
|
||
|
}; cout << "\n";
|
||
|
repi=lect_chaine();
|
||
|
cout << " valeur lue "<<repi;
|
||
|
if ((repi == "1")) {nom_des_ddl = " UX ";}
|
||
|
else if ((repi == "2")) {nom_des_ddl = " UY ";}
|
||
|
else if ((repi == "3")) {nom_des_ddl = " UZ ";}
|
||
|
else { cout << "\n *** choix non valide !";break;};
|
||
|
cout << "\n nom de la reference de noeuds associee? ";
|
||
|
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;
|
||
|
};
|
||
|
index.Change_taille(9);
|
||
|
index(1) = 1; index(2) = 4; index(3) = 5; index(4) = 6;
|
||
|
index(5) = 7;index(6) = 8;index(7) = 9;index(8) = 14;
|
||
|
index(9) = 16;
|
||
|
break;
|
||
|
}
|
||
|
case 2: // un ddl autre qu'un déplacement
|
||
|
{ string repi="";
|
||
|
cout << "\n nom du ddl ? \n";
|
||
|
repi=lect_chaine(); cout << " valeur lue "<<repi;
|
||
|
if (!ExisteEnum_ddl(repi))
|
||
|
{cout << "\n *** erreur, ce ddl n'existe pas ****";
|
||
|
break;
|
||
|
};
|
||
|
nom_des_ddl = repi;
|
||
|
cout << "\n nom de la reference de noeuds associee? ";
|
||
|
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;
|
||
|
};
|
||
|
index.Change_taille(9);
|
||
|
index(1) = 1; index(2) = 4; index(3) = 5; index(4) = 6;
|
||
|
index(5) = 7;index(6) = 8;index(7) = 9;index(8) = 14;
|
||
|
index(9) = 16;
|
||
|
break;
|
||
|
}
|
||
|
case 3: // une valeur de ddl
|
||
|
{ cout << "\n valeur du ddl (un reel) ? ";
|
||
|
valeur_du_ddl=lect_double();cout << " valeur lue ="<< valeur_du_ddl;
|
||
|
index.Change_taille(5);
|
||
|
index(1) = 1; index(2) = 7; index(3) = 8;
|
||
|
index(4) = 9;index(5) = 14;
|
||
|
break;
|
||
|
}
|
||
|
case 4: // courbe de charge
|
||
|
{ cout << "\n nom de la courbe de charge ? ";
|
||
|
nom_courbe= lect_chaine();cout << " nom lu = "<< nom_courbe;
|
||
|
index.Change_taille(7);
|
||
|
index(1) = 1;index(2) = 6; index(3) = 7; index(4) = 8;index(5) = 9;
|
||
|
index(6) = 14;index(7) = 16;
|
||
|
break;
|
||
|
}
|
||
|
case 5: // l'echelle
|
||
|
{ cout << "\n valeur de l'echelle (un reel) ? ";
|
||
|
echelle=lect_double();cout << " valeur lue ="<< echelle;
|
||
|
index.Change_taille(6);
|
||
|
index(1) = 1;index(2) = 7; index(3) = 8; index(4) = 9;index(5) = 14;
|
||
|
index(6) = 16;
|
||
|
break;
|
||
|
}
|
||
|
case 6: // temps mini
|
||
|
{ cout << "\n valeur du temps mini (un reel) ? ";
|
||
|
temps_mini=lect_double();cout << " valeur lue ="<< temps_mini;
|
||
|
index.Change_taille(5);
|
||
|
index(1) = 1;index(2) = 7; index(3) = 8; index(4) = 9;index(5) = 14;
|
||
|
break;
|
||
|
}
|
||
|
case 7: // temps maxi
|
||
|
{ cout << "\n valeur du temps maxi (un reel) ? ";
|
||
|
temps_maxi=lect_double();cout << " valeur lue ="<< temps_maxi;
|
||
|
index.Change_taille(5);
|
||
|
index(1) = 1;index(2) = 7; index(3) = 8; index(4) = 9;index(5) = 14;
|
||
|
break;
|
||
|
}
|
||
|
case 8: // blocage relatif
|
||
|
{cout << "\n --> le blocage est mis en relatif ";
|
||
|
blocage_relatif = true;
|
||
|
index.Change_taille(5);
|
||
|
index(1) = 1;index(2) = 7; index(3) = 8; index(4) = 9;index(5) = 14;
|
||
|
break;
|
||
|
}
|
||
|
case 9: // condition de tangence
|
||
|
{cout << "\n --> condition de tangence ";
|
||
|
if (ParaGlob::Dimension() != 3)
|
||
|
{ cout << "\n **** erreur il faut etre en dimension 3 pour cette condition !!";
|
||
|
break;
|
||
|
};
|
||
|
cout << "\n nom de la ref d'arete pour l'application de la condition ? ";
|
||
|
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'aretes "
|
||
|
<< " doit etre A et non "<< nom_ref.at(0)<< " !!";
|
||
|
break;
|
||
|
};
|
||
|
cout << "\n def du vecteur tangent ";
|
||
|
condition_tangence += " typeCL_= TANGENTE_CL ";
|
||
|
|
||
|
for (int i=1;i<=3;i++) // i représente la dimention
|
||
|
{ string compo; // on defini la composante
|
||
|
switch (i){ case 1: compo="UX";break; case 2:compo="UY";break;
|
||
|
case 3: compo="UZ";break;};
|
||
|
string repi=" ";
|
||
|
bool choix_valide=false;
|
||
|
while (!choix_valide)
|
||
|
{ cout << "\n cas de "<<compo
|
||
|
<< "\n (1) valeur nulle "
|
||
|
<< "\n (2) valeur non nulle "
|
||
|
<< "\n (3) courbe de charge "
|
||
|
<< "\n (4) fonction nD de charge \n";
|
||
|
repi=lect_chaine(); cout << " valeur lue "<<repi;
|
||
|
if ((repi == "1"))
|
||
|
{condition_tangence += " "+compo+" ";
|
||
|
choix_valide=true;
|
||
|
}
|
||
|
else if ((repi == "2"))
|
||
|
{condition_tangence += "' "+compo+"= ";
|
||
|
cout << "\n valeur de "<<compo<<" ? ";
|
||
|
double val;
|
||
|
val=lect_double();cout << " valeur lue ="<< val;
|
||
|
condition_tangence += (ChangeReelSTring(val))+" ' ";
|
||
|
choix_valide=true;
|
||
|
}
|
||
|
else if ((repi == "3"))
|
||
|
{condition_tangence += "' "+compo+"= COURBE_CHARGE: ";
|
||
|
cout << "\n nom de la courbe de charge ? ";
|
||
|
string nom_c;
|
||
|
nom_c= lect_chaine();cout << " nom lu = "<< nom_c;
|
||
|
condition_tangence += nom_c;
|
||
|
cout << "\n echelle (un reel) ? ";
|
||
|
double val;
|
||
|
val=lect_double();cout << " valeur lue ="<< val;
|
||
|
condition_tangence += " ECHELLE: "+(ChangeReelSTring(val))+" ' ";
|
||
|
choix_valide=true;
|
||
|
}
|
||
|
else if ((repi == "4"))
|
||
|
{condition_tangence += "' "+compo+"= Fonction_nD_CHARGE: ";
|
||
|
cout << "\n nom de la fonction nD de charge ? ";
|
||
|
string nom_c;
|
||
|
nom_c= lect_chaine();cout << " nom lu = "<< nom_c;
|
||
|
condition_tangence += nom_c;
|
||
|
choix_valide=true;
|
||
|
}
|
||
|
else { cout << "\n *** choix non valide !";choix_valide=false;};
|
||
|
};
|
||
|
};
|
||
|
index.Change_taille(5);
|
||
|
index(1) = 1;index(2) = 7; index(3) = 8; index(4) = 9;index(5) = 14;
|
||
|
break;
|
||
|
}
|
||
|
case 10: // mouvement solide imposé
|
||
|
{cout << "\n --> mouvement solide impose ";
|
||
|
cout << "\n nom de la reference de noeuds associee? ";
|
||
|
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;
|
||
|
};
|
||
|
// ici on utilise un string intermédiaire pour capter le flux
|
||
|
MvtSolide mvt; // un mouvement par défaut
|
||
|
mvt.Info_commande_MvtSolide(flux);
|
||
|
condition_mvt_solide=true;
|
||
|
|
||
|
index.Change_taille(8);
|
||
|
index(1) = 1;index(2) = 5; index(3) = 6; index(4) = 7;index(5) = 8;
|
||
|
index(6) = 9;index(7) = 14;index(8) = 16;
|
||
|
break;
|
||
|
}
|
||
|
case 11: // champ de valeurs
|
||
|
{cout << "\n --> champ de valeurs impose ";
|
||
|
cout << "\n nom de la reference de noeuds associee? ";
|
||
|
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;
|
||
|
};
|
||
|
int nb_valeur=0;
|
||
|
cout <<"\n nombre d'elements dans la reference ? ";
|
||
|
nb_valeur=(int) lect_double(); cout << " nombre lu ="<< nb_valeur;
|
||
|
string repa;
|
||
|
str_champ_valeurs += " champ_de:\n";
|
||
|
bool erreur=false;
|
||
|
for (int i=1;i<=nb_valeur;i++)
|
||
|
{ string nom_ddl="";
|
||
|
cout << "\n nom du ddl "<<i<<" ? \n";
|
||
|
nom_ddl= lect_chaine(); cout << " nom lue "<<nom_ddl;
|
||
|
if (!ExisteEnum_ddl(nom_ddl))
|
||
|
{cout << "\n *** erreur, ce ddl n'existe pas ****, on sort de la condition !!";
|
||
|
erreur = true;
|
||
|
break;
|
||
|
};
|
||
|
str_champ_valeurs += " ' "+nom_ddl+"= ";
|
||
|
// maintenant la valeur
|
||
|
cout << "\n (1) valeur numerique ? "
|
||
|
<< "\n (2) courbe de charge ? "
|
||
|
<< "\n (4) fonction nD de charge ? ";
|
||
|
repa=lect_chaine(); cout << " rep lue: "<< repa;
|
||
|
if (repa=="1")
|
||
|
{ double val= 0.;cout << "\n valeur ? ";
|
||
|
val=lect_double();cout << " valeur lue: "<< val;
|
||
|
str_champ_valeurs += (ChangeReelSTring(val))+" ' \n";
|
||
|
}
|
||
|
else if (repa=="2")
|
||
|
{ cout << "\n nom de la courbe de charge ? ";
|
||
|
string nom;
|
||
|
nom= lect_chaine();cout << " nom lu = "<< nom;
|
||
|
str_champ_valeurs += " COURBE_CHARGE: "+nom+" ' \n";
|
||
|
}
|
||
|
else if (repa=="3")
|
||
|
{ cout << "\n nom de la fonction nD de charge ? ";
|
||
|
string nom;
|
||
|
nom= lect_chaine();cout << " nom lu = "<< nom;
|
||
|
str_champ_valeurs += " Fonction_nD_CHARGE: "+nom+" ' \n";
|
||
|
};
|
||
|
};
|
||
|
if (erreur)
|
||
|
break; // on sort s'il y a eu une erreur
|
||
|
str_champ_valeurs += "fin_champ_de_ ";
|
||
|
champ_valeurs=true;
|
||
|
index.Change_taille(5);
|
||
|
index(1) = 1;index(2) = 7; index(3) = 8; index(4) = 9;index(5) = 14;
|
||
|
break;
|
||
|
}
|
||
|
case 12: // liste des ddl existants
|
||
|
{cout << "\n --> liste des ddl existants ";
|
||
|
int nb_ddl = nombre_maxi_de_type_de_ddl;
|
||
|
cout << "\n";
|
||
|
for (int i=1;i<= nombre_maxi_de_type_de_ddl;i++)
|
||
|
cout << Nom_ddl(Enum_ddl(i)) << " ";
|
||
|
cout << "\n";
|
||
|
break;
|
||
|
}
|
||
|
case 13: // informations
|
||
|
{cout << "\n Il faut se reporter a la document pour avoir une explication detaille de chaque "
|
||
|
<< "\n conditions. Globalement les conditions possibles sont les suivantes: "
|
||
|
<< "\n (1) choix d'un deplacement impose --> UX ou UY ou UZ "
|
||
|
<< "\n (2) autre ddl impose --> a choisir dans la liste des ddl diponibles "
|
||
|
<< "\n (3) valeur du ddl --> on definit une valeur numerique "
|
||
|
<< "\n (4) utilisation d'une courbe de charge --> la valeur du ddl = la valeur d'une courbe de charge "
|
||
|
<< "\n (5) echelle --> facteur multiplicatif de la valeur du ddl (fixe ou dependant d'une fct f(t)"
|
||
|
<< "\n (6) temps mini --> en dessous du temps mini, la condition n'existe pas "
|
||
|
<< "\n (7) temps maxi --> au dessus du temps maxi la condition n'existe pas "
|
||
|
<< "\n (8) blocage relatif --> a partir de temps mini, la condition est ajoute a la valeur existante du ddl "
|
||
|
<< "\n (9) condition de tangence --> permet de definir des conditions limites pour les elements SFE "
|
||
|
<< "\n (10) mouvement solide impose --> permet de definir des mouvements d'ensemble pour un groupe de noeuds "
|
||
|
<< "\n (11) champ de valeurs --> permet de definir de maniere concise un ensemble de conditions non identiques "
|
||
|
<< "\n (12) liste de ddl existant --> donne la liste des ddl possibles "
|
||
|
<< "\n (13 ou ? ) information --> ce message "
|
||
|
<< "\n (14) plusieurs ddl de deplacement, nuls --> forme concise pour mettre des deplacements a 0 "
|
||
|
<< "\n (15) une fonction nD --> la valeur du ddl = la valeur de la fonction, eventuellement x Co charge ";
|
||
|
break;
|
||
|
}
|
||
|
case 14: // plusieurs ddl de deplacement, nuls
|
||
|
{ string repi=" ";
|
||
|
nom_des_ddl = "";
|
||
|
while (repi != "f")
|
||
|
{ cout << "\n -- choix du ddl -- ";
|
||
|
switch (ParaGlob::Dimension())
|
||
|
{case 1: cout << "\n (1) UX "
|
||
|
<< "\n (f) (defaut) fin"; break;
|
||
|
case 2: cout << "\n (1) UX "
|
||
|
<< "\n (2) UY "
|
||
|
<< "\n (f) (defaut) fin" ; break;
|
||
|
case 3: cout << "\n (1) UX "
|
||
|
<< "\n (2) UY "
|
||
|
<< "\n (3) UZ "
|
||
|
<< "\n (f) (defaut) fin" ; break;
|
||
|
default: cout << " ";
|
||
|
}; cout << "\n";
|
||
|
repi= lect_return_defaut(false,"f");; cout << " valeur lue "<<repi;
|
||
|
if ((repi == "1")) {nom_des_ddl += " UX ";}
|
||
|
else if ((repi == "2")) {nom_des_ddl += " UY ";}
|
||
|
else if ((repi == "3")) {nom_des_ddl += " UZ ";}
|
||
|
else if ((Minuscules(repi) == "f")||(Minuscules(repi) == "0")) {}
|
||
|
else { cout << "\n *** choix non valide !";};
|
||
|
};
|
||
|
valeur_du_ddl=0.;
|
||
|
cout << "\n nom de la reference de noeuds associee? ";
|
||
|
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;
|
||
|
};
|
||
|
index.Change_taille(7);
|
||
|
index(1) = 1; index(2) = 5; index(3) = 6; index(4) = 7;
|
||
|
index(5) = 8;index(6) = 9;index(7) = 14;
|
||
|
break;
|
||
|
}
|
||
|
case 15: // fonction nD de charge
|
||
|
{ cout << "\n nom de la fonction nD de charge ? ";
|
||
|
nom_fonction_nD= lect_chaine();cout << " nom lu = "<< nom_fonction_nD;
|
||
|
index.Change_taille(7);
|
||
|
index(1) = 1;index(2) = 6; index(3) = 7; index(4) = 8;index(5) = 9;
|
||
|
index(6) = 14;index(7) = 5;
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n le cas "<<rep<<" n'est pas traite !!, bizarre, il faut se plaindre !! ";
|
||
|
};
|
||
|
}
|
||
|
catch (ErrSortieFinale)
|
||
|
// cas d'une direction voulue vers la sortie
|
||
|
// on relance l'interuption pour le niveau supérieur
|
||
|
{ ErrSortieFinale toto;
|
||
|
throw (toto);
|
||
|
}
|
||
|
catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
|
||
|
{ cout << "\n Erreur on attendait un des mots cles proposes !!, "
|
||
|
<< "\n redonnez une bonne valeur"
|
||
|
<< "\n ou taper f ou 0 pour sortir ";
|
||
|
};
|
||
|
}; //-- fin du while
|
||
|
sort << flush;
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
//------------------------------ FONCTIONS PROTEGEES --------------------
|
||
|
|
||
|
// verification en fonction de la dimension du pb
|
||
|
// par exemple en dim 2 d'existance des UZ ou des X3 etc..
|
||
|
void DdlLim::VerifDimDdl()
|
||
|
{ //pour l'instant ne fait rien
|
||
|
};
|
||
|
|
||
|
// ====================================================================
|
||
|
// classe Ddlbloque
|
||
|
// ====================================================================
|
||
|
|
||
|
// surcharge de l'operateur d'ecriture
|
||
|
ostream & operator << (ostream & sort,const DdlLim::Ddlbloque & a)
|
||
|
{ // écriture du type
|
||
|
sort << "Ddlbloque ";
|
||
|
// les données
|
||
|
sort << a.ddl << " " << a.co_charge << " " << a.echelle << " "<< a.f_charge << " " ;
|
||
|
return sort;
|
||
|
};
|
||
|
// surcharge de l'operator de lecture
|
||
|
istream & operator >> (istream & entree, DdlLim::Ddlbloque& a)
|
||
|
{ // vérification du type
|
||
|
string type;
|
||
|
entree >> type;
|
||
|
if (type != "Ddlbloque")
|
||
|
{Sortie (1);
|
||
|
return entree;
|
||
|
}
|
||
|
// entrée des données
|
||
|
entree >> a.ddl;
|
||
|
entree >> a.co_charge >> a.echelle >> a.f_charge;
|
||
|
return entree;
|
||
|
};
|
||
|
|
||
|
// surcharge de l'opérateur d'affectation
|
||
|
DdlLim::Ddlbloque& DdlLim::Ddlbloque::operator= (const DdlLim::Ddlbloque& d)
|
||
|
{ ddl=d.ddl;
|
||
|
co_charge=d.co_charge;
|
||
|
echelle = d.echelle;
|
||
|
f_charge = d.f_charge;
|
||
|
return (*this);
|
||
|
};
|
||
|
|
||
|
//Surcharge d'operateur logique
|
||
|
bool DdlLim::Ddlbloque::operator == ( DdlLim::Ddlbloque& a)
|
||
|
{ if ( (ddl==a.ddl)
|
||
|
&& (co_charge == a.co_charge) && (echelle == a.echelle)
|
||
|
&& (f_charge == a.f_charge)
|
||
|
)
|
||
|
return true;
|
||
|
else return false;
|
||
|
};
|
||
|
|
||
|
bool DdlLim::Ddlbloque::operator != ( DdlLim::Ddlbloque& a)
|
||
|
{ return !(*this == a);};
|
||
|
|
||
|
// lecture dans le cas particulier d'un champ
|
||
|
list <DdlLim::Ddlbloque> DdlLim::Lecture_champ(UtilLecture & entreePrinc)
|
||
|
{ // def de variables inter
|
||
|
char tat[250]; char * ta = tat; char tt[100]; char * t = tt;
|
||
|
// def de la liste de ddl qui sera retournée
|
||
|
list <Ddlbloque> lili;
|
||
|
// le traitement qui suit s'effectue soit une fois si ce n'est pas un champ, soit n fois jusqu'a
|
||
|
// ce que la ligne contienne le mot clé fin_champ_de_ qui doit être le premier enregistrement de la ligne
|
||
|
bool derniere_ligne = true; // le cas courant c'est qu'il y a une seule ligne a exploiter
|
||
|
do ///__________ la grande boucle
|
||
|
{ // dans ce cas dans le fichier d'entrée les infos se trouvent sur les lignes qui suivent
|
||
|
// via normalement un fichier (mais ce n'est pas obligatoire) donc on passe
|
||
|
// une ligne à chaque passage jusqu'à trouver le mot clé fin_champ_de_
|
||
|
entreePrinc.NouvelleDonnee(); // lecture d'une nouvelle ligne
|
||
|
// on lira jusqu'à la ligne qui contiend le mot clé: fin_champ_de_ en début d'enregistrement
|
||
|
if (strstr(entreePrinc.tablcar,"fin_champ_de_")!=NULL)
|
||
|
{derniere_ligne= true; string toto; *(entreePrinc.entree) >> toto;
|
||
|
if (toto != "fin_champ_de_")
|
||
|
{ cout << "\n erreur de lecture d'un champ de valeurs "
|
||
|
<< " le premier mot de la derniere ligne devait etre fin_champ_de_ \n";
|
||
|
entreePrinc.MessageBuffer("*** lecture champ de valeurs ****" );
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{derniere_ligne = false;};
|
||
|
|
||
|
//recup de la fin de la ligne
|
||
|
char tout[150] ; char * ptout = tout; (entreePrinc.entree)->get(ptout,150);
|
||
|
// avant la lecture on remplace toutes les virgules par des espaces
|
||
|
char * ii = strchr(ptout,',');
|
||
|
while (ii != NULL) { *ii = ' '; ii = strchr(ptout,',');}
|
||
|
// def du flot intermédiaire
|
||
|
#ifndef ENLINUX_STREAM
|
||
|
istringstream flot(ptout);
|
||
|
#else
|
||
|
istrstream flot(ptout);
|
||
|
#endif
|
||
|
// lecture tant que le flot est valide
|
||
|
while (flot.rdstate() == 0)
|
||
|
// tout d'abord on passe les espaces qui sont des séparateurs
|
||
|
// lecture du prochain caractère sans modifier le flot
|
||
|
{char car; // = flot.peek();
|
||
|
//---- debug
|
||
|
//cout << "\n debug DdlLim::Lecture_champ( flot.rdstate()= " << flot.rdstate()<< endl;
|
||
|
//--- fin debug
|
||
|
|
||
|
flot >> car;
|
||
|
// éventuellement il n'avait pas bien déterminé la fin de l'enregistrement
|
||
|
// au niveau du while, dans ce cas si durant la lecture de car il y a eu un pb
|
||
|
// cela signifie qu'en fait la ligne était terminée donc on s'arrête
|
||
|
if (flot.rdstate() != 0) break;
|
||
|
while ( (car==' ') && (flot.rdstate() == 0 ))
|
||
|
// cas où le prochain caractère est un espace
|
||
|
{ flot >> car; }
|
||
|
flot.putback(car);
|
||
|
|
||
|
if (!derniere_ligne)
|
||
|
{// on définit un ddl pour la lecture
|
||
|
Ddlbloque elem;
|
||
|
// deux cas, soit un ddl nulle par defaut, soit une valeur non nulle imposee
|
||
|
// soit le caractère est ' , signifie que c'est un ddl avec une valeur
|
||
|
// imposée
|
||
|
if ( (car=='\'') && (flot.rdstate() == 0 ))
|
||
|
{// on passe le premier '
|
||
|
flot >> car;
|
||
|
// on lit jusqu'au prochain ' en non formaté
|
||
|
flot.get(ta,150,'\'');
|
||
|
// on passe ce dernier '
|
||
|
flot >> car;
|
||
|
// on recherche le = pour mettre un blanc a la place
|
||
|
char * ii = strchr(ta,'\'');char * pii=ii; // sauvegarde de l'adresse
|
||
|
ii = strchr(ta,'='); // on recherche le =
|
||
|
if (ii == NULL)
|
||
|
{ cout << "\n erreur de syntaxe dans la definition des conditions limites "
|
||
|
<< " imposees a une valeur non nulle ";
|
||
|
cout << " le ddl doit etre separe de la valeur par le signe = , caractere non"
|
||
|
<< " trouve ";
|
||
|
entreePrinc.MessageBuffer("*** lecture d'une reference de ddl bloquee ****" );
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
*ii = ' '; // supprime le =
|
||
|
|
||
|
// def du flux intermediaire
|
||
|
#ifndef ENLINUX_STREAM
|
||
|
istringstream flux (ta);
|
||
|
#else
|
||
|
istrstream flux (ta);
|
||
|
#endif
|
||
|
|
||
|
flux >> t ;
|
||
|
elem.ddl.Change_nom(t);
|
||
|
// on regarde s'il ne s'agit pas d'une courbe de charge imposée
|
||
|
bool sans_courbe_ou_fct_nD=true; // variable locale
|
||
|
// a) cas d'une courbe
|
||
|
if(strstr(ta,"COURBE_CHARGE:")!=0)
|
||
|
{ // cas d'une courbe de charge
|
||
|
string toto;
|
||
|
flux >> toto >> elem.co_charge;
|
||
|
// on vérifie la présence au bon endroit du mot clé COURBE_CHARGE=
|
||
|
if (toto != "COURBE_CHARGE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du nom de la courbe ";
|
||
|
cout << "\n DdlLim::Lecture_champ(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// on récupère l'échelle éventuellement
|
||
|
if(strstr(ta,"ECHELLE:")!=0)
|
||
|
{ // cas où il y a un facteur d'échelle
|
||
|
flux >> toto;
|
||
|
if (toto != "ECHELLE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du facteur d'échelle ";
|
||
|
cout << "\n DdlLim::Lecture_champ(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// lecture du facteur
|
||
|
flux >> elem.echelle;
|
||
|
};
|
||
|
};
|
||
|
// b) cas d'une fonction nD
|
||
|
if(strstr(ta,"Fonction_nD_CHARGE:")!=0)
|
||
|
{ // cas d'une fonction nD
|
||
|
string toto;
|
||
|
flux >> toto >> elem.f_charge;
|
||
|
sans_courbe_ou_fct_nD=false;
|
||
|
// on vérifie la présence au bon endroit du mot clé Fonction_nD_CHARGE:
|
||
|
if (toto != "Fonction_nD_CHARGE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD ";
|
||
|
cout << "\n DdlLim::Lecture_champ(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// si aucune courbe ou fct nD
|
||
|
if (sans_courbe_ou_fct_nD)
|
||
|
// cas où c'est une valeur fixe
|
||
|
{ flux >> elem.ddl.Valeur();}
|
||
|
elem.ddl.Change_fixe (true);
|
||
|
}
|
||
|
else if (flot.rdstate() == 0 ) // il s'agit d'un ddl à 0
|
||
|
{//un ddl nulle par defaut
|
||
|
flot >> t;
|
||
|
elem.ddl.Change_nom(t);
|
||
|
elem.ddl.Valeur() = 0;
|
||
|
elem.ddl.Change_fixe (true);
|
||
|
}
|
||
|
// on ne verifie pas que l'on n'utilise pas deux fois le meme identificateur de ddl
|
||
|
// avec deux valeurs differentes car dans le cas d'un champ il y a obligatoirement plusieurs fois le même ddl
|
||
|
// stockage
|
||
|
lili.push_back(elem);
|
||
|
}
|
||
|
else // cas de la dernière ligne
|
||
|
{// lecture éventuelle des temp mini et maxi
|
||
|
if (((!flot.rdstate())&& (!(flot.eof())))) // lecture s'il n'y a pas d'erreur
|
||
|
{if(strstr(ptout,"TEMPS_MINI=") != 0)
|
||
|
{// cas d'un temps mini
|
||
|
string toto;
|
||
|
flot >> toto;
|
||
|
// on vérifie la présence au bon endroit du mot clé TEMPS_MINI=
|
||
|
if (toto != "TEMPS_MINI=")
|
||
|
{cout << "\n erreur de syntaxe en lecture du temps mini, info lue: " << toto;
|
||
|
cout << "\n DdlLim::Lecture_champ(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
//lecture du temps mini
|
||
|
flot >> t_min;
|
||
|
}
|
||
|
}
|
||
|
if (((!flot.rdstate())&& (!(flot.eof())))) // lecture s'il n'y a pas d'erreur
|
||
|
{if(strstr(ptout,"TEMPS_MAXI=") != 0)
|
||
|
{// cas d'un temps maxi
|
||
|
string toto;
|
||
|
flot >> toto;
|
||
|
// on vérifie la présence au bon endroit du mot clé TEMPS_MAXI=
|
||
|
if (toto != "TEMPS_MAXI=")
|
||
|
{cout << "\n erreur de syntaxe en lecture du temps maxi ";
|
||
|
cout << "\n DdlLim::Lecture_champ(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
//lecture du temps maxi
|
||
|
flot >> t_max;
|
||
|
}
|
||
|
};
|
||
|
// à la fin on considère que c'est fini, il n'y a plus d'info spécifique à lire
|
||
|
// donc on sort de la boucle
|
||
|
break;
|
||
|
} //-- fin du cas de la dernière ligne
|
||
|
|
||
|
} //-- fin du while (flot.rdstate() == 0)
|
||
|
} ///__________ fin de la grande boucle
|
||
|
while(! derniere_ligne);
|
||
|
|
||
|
// dans le cas où il s'agit d'un champ de conditions de tangente imposée, il faut que
|
||
|
// la condition soit un multiple de la dimension de l'espace, car chaque condition représente un
|
||
|
// vecteur
|
||
|
if (typeCL == TANGENTE_CL)
|
||
|
{if ((tab.Taille() % ParaGlob::Dimension()) != 0)
|
||
|
{cout << "\n erreur en lecture d'un champ de condition de tangente imposée, "
|
||
|
<< " le nombre de dd (ici = " << tab.Taille() << ") doit etre multiple de la dimension"
|
||
|
<< " de l'espace (ici = " << ParaGlob::Dimension()<<") ";
|
||
|
cout << "\n DdlLim::Lecture_champ(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
return lili;
|
||
|
};
|
||
|
|
||
|
// lecture dans le cas particulier d'un mouvement solide
|
||
|
list <DdlLim::Ddlbloque> DdlLim::Lecture_mvtSolide(UtilLecture & entreePrinc)
|
||
|
{ // on commence par lire les mouvements solides
|
||
|
if (mvtsolide == NULL)
|
||
|
mvtsolide = new MvtSolide(); // création s'il n'existe pas
|
||
|
mvtsolide->Lecture_mouvements_solides(&entreePrinc);
|
||
|
// def de la liste de ddl qui sera retournée
|
||
|
list <Ddlbloque> lili;
|
||
|
// on définit les ddl bloque associés
|
||
|
int dima = ParaGlob::Dimension();
|
||
|
Ddlbloque elem; // def d'un ddl courant
|
||
|
elem.ddl.Change_fixe (true);
|
||
|
switch (dima)
|
||
|
{ case 3: {elem.ddl.Change_nom(UZ); lili.push_front(elem);}
|
||
|
case 2: {elem.ddl.Change_nom(UY); lili.push_front(elem);}
|
||
|
case 1: {elem.ddl.Change_nom(UX); lili.push_front(elem);}
|
||
|
};
|
||
|
// def d'un string pour les lectures de chaine
|
||
|
string nom;
|
||
|
// maintenant on regarde s'il y a une courbe de charge
|
||
|
// 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
|
||
|
*(entreePrinc.entree) >> nom;
|
||
|
// on vérifie la présence au bon endroit du mot clé COURBE_CHARGE=
|
||
|
if (nom != "COURBE_CHARGE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du nom de la courbe "
|
||
|
<< " on a lue " << nom << " alors que l'on attendait : COURBE_CHARGE: ";
|
||
|
cout << "\n DdlLim::Lecture_mvtSolide(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// on se sert du premier ddlbloqué pour stocker la courbe de charge
|
||
|
Ddlbloque & elem = *(lili.begin());
|
||
|
// lecture de la courbe
|
||
|
*(entreePrinc.entree) >> elem.co_charge;
|
||
|
// on récupère l'échelle éventuellement
|
||
|
if (strstr(entreePrinc.tablcar,"ECHELLE:")!=NULL)
|
||
|
{ // cas où il y a un facteur d'échelle
|
||
|
*(entreePrinc.entree) >> nom;
|
||
|
if (nom != "ECHELLE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du facteur d'echelle "
|
||
|
<< " on a lue " << nom << " alors que l'on attendait ECHELLE: ";
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
// lecture du facteur
|
||
|
*(entreePrinc.entree) >> elem.echelle;
|
||
|
};
|
||
|
};
|
||
|
if (strstr(entreePrinc.tablcar,"Fonction_nD_CHARGE:")!=NULL)
|
||
|
{ // cas d'une fonction nD de charge
|
||
|
*(entreePrinc.entree) >> nom;
|
||
|
// on vérifie la présence au bon endroit du mot clé Fonction_nD_CHARGE:
|
||
|
if (nom != "Fonction_nD_CHARGE:")
|
||
|
{cout << "\n erreur de syntaxe en lecture du nom de la fonction nD "
|
||
|
<< " on a lue " << nom << " alors que l'on attendait : Fonction_nD_CHARGE: ";
|
||
|
cout << "\n DdlLim::Lecture_mvtSolide(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// on se sert du premier ddlbloqué pour stocker la courbe de charge
|
||
|
Ddlbloque & elem = *(lili.begin());
|
||
|
// lecture de la courbe
|
||
|
*(entreePrinc.entree) >> elem.f_charge;
|
||
|
};
|
||
|
// lecture éventuelle des temp mini et maxi
|
||
|
if (strstr(entreePrinc.tablcar,"TEMPS_MINI=")!=NULL)
|
||
|
{ // cas d'un temps mini
|
||
|
*(entreePrinc.entree) >> nom;
|
||
|
// on vérifie la présence au bon endroit du mot clé TEMPS_MINI=
|
||
|
if (nom != "TEMPS_MINI=")
|
||
|
{cout << "\n erreur de syntaxe en lecture du temps mini, info lue: " << nom
|
||
|
<< " alors que l'on attendait : TEMPS_MINI=";
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
//lecture du temps mini
|
||
|
*(entreePrinc.entree) >> t_min;
|
||
|
};
|
||
|
if (strstr(entreePrinc.tablcar,"TEMPS_MAXI=")!=NULL)
|
||
|
{ // cas d'un temps maxi
|
||
|
*(entreePrinc.entree) >> nom;
|
||
|
// on vérifie la présence au bon endroit du mot clé TEMPS_MAXI=
|
||
|
if (nom != "TEMPS_MAXI=")
|
||
|
{cout << "\n erreur de syntaxe en lecture du temps maxi, info lue: " << nom
|
||
|
<< " alors que l'on attendait : TEMPS_MAXI=";
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
//lecture du temps maxi
|
||
|
*(entreePrinc.entree) >> t_max;
|
||
|
};
|
||
|
// lecture éventuel de l'indicateur de blocage "relatif"
|
||
|
if (strstr(entreePrinc.tablcar,"BLOCAGE_RELATIF_")!=NULL)
|
||
|
{ *(entreePrinc.entree) >> nom;
|
||
|
// on vérifie la présence au bon endroit du mot clé BLOCAGE_RELATIF_
|
||
|
if (nom != "BLOCAGE_RELATIF_")
|
||
|
{cout << "\n erreur de syntaxe en lecture de l'indicateur de blocage relatif, info lue: " << nom
|
||
|
<< " alors que l'on attendait : BLOCAGE_RELATIF_";
|
||
|
cout << "\n DdlLim::Lecture(.. " << endl ;
|
||
|
entreePrinc.MessageBuffer("**erreur**");
|
||
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
||
|
Sortie(1);
|
||
|
}
|
||
|
blocage_relatif = true;
|
||
|
};
|
||
|
|
||
|
return lili;
|
||
|
};
|