// 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-2022 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . #include "DdlLim.h" #include #include #include # include using namespace std; //introduces namespace std #include #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 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 ::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 ::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 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 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: "<= 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 "< 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 "< 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 "< 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 "<> (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::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 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::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 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; };