// 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 using namespace std; //introduces namespace std #include #include "Sortie.h" #include "UtilLecture.h" #include "Sortie.h" #include #include #include #include #include "ParaGlob.h" #include // pour la gestion de l'ouverture de directory #include // idem #include "CharUtil.h" // ouverture du fichier base_info après le .info dans le cas d'un restart par exemple // s'il est déjà ouvert on ne fait rien // a priori le fichier est ouvert en lecture : lecture // mais il peut également être en écriture : ecriture void UtilLecture::Ouverture_base_info(string type_entree) { char nomm[132]; char*fileName = nomm; strcpy(fileName, pteurnom); // on définit des noms explicites std::string nom_BI(pteurnom); std::string nom_PI(pteurnom); #ifdef UTILISATION_MPI // cas d'un calcul //, // on prend en compte le numéro du CPU int num_cpu = ParaGlob::Monde()->rank(); nom_BI += ChangeEntierSTring(num_cpu); nom_PI += ChangeEntierSTring(num_cpu); #endif nom_BI += ".BI"; nom_PI += ".PI"; if (type_entree == "lecture") // cas d'une lecture // on regarde si on a déjà une ouverture en écriture si oui on ferme { if (sort_BI != NULL) Fermeture_base_info(); // maintenant on regarde si la lecture est déjà en cours #ifdef UTILISATION_MPI // cas d'un calcul //, et que l'on a une lecture en cours // on regarde si on a changé de CPU // si oui, on ferme tout if (ent_BI != NULL) {if (num_cpu_en_cours_BI != num_cpu) {Fermeture_base_info(); // on met à jour le numéro en cours num_cpu_en_cours_BI = num_cpu; }; }; #endif // si pas de fichier ouvert, on ouvre if (ent_BI == NULL) { //ent_BI = new fstream(strcat(fileName,".BI"), ios::out | ios::in); ent_BI = new fstream(nom_BI.c_str(), ios::out | ios::in); if(!(ent_BI->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour la lecture du fichier " << nom_BI << "\n" << " UtilLecture::Ouverture_base_info() " << endl; Sortie(1); }; // cas du fichier de pointeur, traitement presque analogue // strcpy(fileName, pteurnom); // ent_PI = new fstream(strcat(fileName,".PI"), ios::out | ios::in); ent_PI = new fstream(nom_PI.c_str(), ios::out | ios::in); if(!(ent_PI->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour la lecture du fichier " << nom_PI << "\n" << " le fichier de pointeur ne peut etre lu, on essaie de faire uniquement avec le .BI " << endl; ent_PI = NULL; }; bool positionPI = false; // pour de la gestion de cas if (ent_PI!=NULL) // si le fichier n'est pas vide { // et on récupère les pointeurs d'incrément string toto;int nb_position; // on lit la première ligne (*ent_PI) >> toto >> nb_position; // dans le cas ou il n'y a pas d'erreur // on effectue la lecture des positions si seulement // le nombre de position actuellement en service est différent if (ent_PI->rdstate() == 0) {// si le nombre de position actuelle est non valide, on lit if (liste_posi_BI.size() != nb_position) { // on efface les positions actuelles liste_posi_BI.clear(); // lecture des positions for (int i=1;i<= nb_position;i++) { Position_BI truc; (*ent_PI) >> truc; liste_posi_BI.push_back(truc); }; }; positionPI = true; } } // si les positions n'ont pas été validé, on essaie de les recréer if (!positionPI) // le fichier de pointeur n'est pas exploitable // on redéfinit par lecture le tableau de pointeur à partir du .BI { cout << "\n attention, le fichier de pointeur .PI n'est pas exploitable " << " \n on va donc essayer de retrouver les positions des increments " << " dans .BI mais ce sera plus long !! " << endl; if (ent_PI != NULL) {ent_PI->close();ent_PI = NULL;}; // on efface les positions actuelles liste_posi_BI.clear(); // on se positionne au premier incrément et si c'est ok on continue int incre = 0; streampos debut_increment(0); if (Positionnement_base_info(incre)) { // enregistrement et bouclage Position_BI truc(debut_increment,incre); liste_posi_BI.push_back(truc); while (Increment_suivant_base_info(debut_increment,incre)) { // dans la fonction il y a l'enregistrement dans la liste // d'où on ne fait rien ici }; // maintenant on se repositionne au début du fichier pour le BI ent_BI->clear(); ent_BI->seekg(ios::beg); dernier_increment_lu = 0; // on sauvegarde les positions pour une prochaine utilisation // strcpy(fileName, pteurnom); // sort_PI = new fstream(strcat(fileName,".PI"), ios::out | ios::in); sort_PI = new fstream(nom_PI.c_str(), ios::out | ios::in); if(!(sort_PI->is_open())) // le fichier ne peut être ouvert, il n'existe pas donc on l'ouvre { //sort_PI = new fstream(fileName, ios::out | ios::ate); sort_PI = new fstream(nom_PI.c_str(), ios::out | ios::in); if(!(sort_PI->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour la lecture du fichier " << nom_PI << "\n" << " UtilLecture::Ouverture_base_info() " << endl; Sortie(1); }; }; list::iterator iter,iter_fin = liste_posi_BI.end(); (*sort_PI) << "liste_des_positions_et_de_pointeur_dans_base_info,_taille_: " << liste_posi_BI.size() << "\n"; for (iter = liste_posi_BI.begin();iter != iter_fin;iter++) (*sort_PI) << (*iter) << "\n"; (*sort_PI) << endl; sort_PI->close();sort_PI=NULL; }; } } } else if (type_entree == "ecriture") // cas d'une ecriture // on regarde si on a déjà une ouverture en lecture si oui on ferme { if (ent_BI != NULL) Fermeture_base_info(); #ifdef UTILISATION_MPI // cas d'un calcul //, et que l'on a une écriture en cours // on regarde si on a changé de CPU // si oui, on ferme tout if (sort_BI != NULL) {if (num_cpu_en_cours_BI != num_cpu) {Fermeture_base_info(); // on met à jour le numéro en cours num_cpu_en_cours_BI = num_cpu; }; }; #endif // maintenant on regarde si la lecture est déjà en cours si oui on ne fait rien // sinon on ouvre et on se place à la fin if (sort_BI == NULL) { sort_BI = new fstream(nom_BI.c_str(), ios::out | ios::in | ios::ate); if(!(sort_BI->is_open())) // le fichier ne peut être ouvert, il n'existe pas donc on l'ouvre { sort_BI = new fstream(nom_BI.c_str(), ios::out | ios::ate); if(!(sort_BI->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour la lecture du fichier " << nom_BI << "\n" << " UtilLecture::Ouverture_base_info() " << endl; Sortie(1); } } // même traitement pour le fichier de pointeur d'incrément // qui est cependant systématiquement mis à 0, on écrit du début sort_PI = new fstream(nom_PI.c_str(), ios::out | ios::in); if(!(sort_PI->is_open())) // le fichier ne peut être ouvert, il n'existe pas donc on l'ouvre { sort_PI = new fstream(nom_PI.c_str(), ios::out | ios::ate); if(!(sort_PI->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour la lecture du fichier " << nom_PI << "\n" << " UtilLecture::Ouverture_base_info() " << endl; Sortie(1); } } } } // essai /* // essai fstream * toto; toto = new fstream("toto", ios::out | ios::in ); toto->clear(); (*toto) << "truc \n";(*toto) << "tric"; // positionnement au début du fichier toto->seekp(0,ios::beg); string titi; (*toto) >> titi; // récup de l'adresse streampos adresse = toto->tellp(); // ouverture d'un stream en écriture er positionnement fstream * toutou; toto->seekp(0,ios::beg); toto->close (); toutou = new fstream("toto",ios::out | ios::in | ios::ate); toutou->seekp(adresse); // (*toutou) >> titi; (*toutou) << "\nfin\n"; toutou->close(); */ }; // fermeture du fichier base_info void UtilLecture::Fermeture_base_info() { if (ent_BI != NULL) {// cas du fichier ouvert en lecture delete ent_BI; ent_BI = NULL; if(ent_PI != NULL) delete ent_PI; ent_PI = NULL; } if (sort_BI != NULL) {// cas du fichier ouvert en écriture delete sort_BI; sort_BI = NULL; // on sauvegarde le tableau de pointeur d'incrément sort_PI->seekp( ios::beg); list::iterator iter,iter_fin = liste_posi_BI.end(); (*sort_PI) << "liste_des_positions_et_de_pointeur_dans_base_info,_taille_: " << liste_posi_BI.size() << "\n"; for (iter = liste_posi_BI.begin();iter != iter_fin;iter++) (*sort_PI) << (*iter) << "\n"; (*sort_PI) << endl; // puisque le fichier base_info est fermé, on suprime la liste de pointeur // elle sera remise à jour lors de l'ouverture du .BI list::iterator iter_debut = liste_posi_BI.begin(); liste_posi_BI.erase(iter_debut,iter_fin); // fermeture du fichier delete sort_PI; sort_PI = NULL; } }; //fichier base_info dans lequel sont lus les enregistrements ifstream * UtilLecture::Ent_BI() { if (ent_BI == NULL) { // cas ou le fichier n'est pas ouvert on l'ouvre Ouverture_base_info("lecture"); } return (ifstream*) ent_BI; }; // et pour l'écriture ofstream * UtilLecture::Sort_BI() { if (sort_BI == NULL) { // cas ou le fichier n'est pas ouvert on l'ouvre Ouverture_base_info("ecriture"); } return (ofstream*) sort_BI; } ; // positionnement dans le fichier d'entrès au niveau d'un numéro d'incrément // si l'on ne trouve pas le numéro on renvoi un indicateur à false bool UtilLecture::Positionnement_base_info(int inc_voulu) { streampos debut_increment(0); // tout d'abord on vérifie que le fichier base_info est disponible en lecture // sinon on l'ouvre en lecture if (ent_BI == NULL) Ouverture_base_info("lecture"); // --- on ne fait pas une recherche en boucle, comme commencé dans les lignes commentées qui suivent // car on considère que la liste BI doit exister et contenir les info ha doc // // on regarde si l'on est au début du fichier sinon dans le cas d'une recherche // // infructueuse à la fin il faudra aussi faire une recherche au début // bool debut = true; // if (std::ios::beg != ( ent_BI->tellg())) debut = false; // on regarde si l'incrément demandé n'a pas déjà été enregistré Position_BI pos_ent(ios::beg,inc_voulu); list ::iterator iposi = find(liste_posi_BI.begin(),liste_posi_BI.end(),pos_ent); if (iposi != liste_posi_BI.end()) // dans le cas ou l'incrément existe, on se positionne à l'adresse mémorisée {ent_BI->clear(); // on remet à 0 les bits de contrôle car si lors d'une précédente lecture // on est par exemple arrivée à la fin du fichier, la fonction seekg ne fonctionnera // pas !! car le bit de eof est activé ent_BI->seekg((*iposi).position, ios::beg); }; // maintenant on lit string toto; int titi; int inc; bool inc_trouve = false; // def d'un tableau d'entrée en flot d'entrée pour faire de la lecture non formaté char * tableau; int longueur = 250; tableau = new char [longueur] ; // def du tableau intermediaire istrstream * intar; // on définit une position intermédiaire dans le fichier pour bien se positionner // pour l'écriture ensuite éventuelle des incréments streampos position_inter=0; // lecture tant que l'on n'a pas atteint la fin du fichier do { // tout d'abord on mémorise l'ancienne position et on récupère la nouvelle debut_increment = position_inter; position_inter = ent_BI->tellg(); // si la ligne est la bonne debut_increment sera positionné sur le début // de la ligne qui contiend des ==== ent_BI->getline(tableau,longueur,'\n'); // lecture d'une ligne dans le fichier if (strstr(tableau,"INCREMENT_DE_CHARGE_:")!=NULL) { // on repositionne le flot au debut du tableau de carractere // ouverture du flot a la longueur sans blanc intar = new istrstream(tableau,short(strlen (tableau))) ; (*intar) >> toto >> inc; if (inc == inc_voulu) // ok on a l'incrément voulu // fin de la préparation de la lecture pour l'incrément {(*intar) >> toto >> titi >> toto ; inc_trouve = true; } delete intar; } // test pour vérifier l'intégrité du flot if (ent_BI->rdstate() != 0) // si l'on est arrivé à la fin du fichier il n'y a rien à faire // sinon on remet à flot le flot (cas par exemple d'entier au lieu de caractère)! if (!(ent_BI->eof())) ent_BI->clear(); } while ((!(ent_BI->eof()))&& (!inc_trouve)); delete[] tableau; if (!inc_trouve) return false; else { // on passe la ligne des === (*ent_BI) >> toto; // on met à jour la variable dernier_increment_lu dernier_increment_lu = inc_voulu; return true; }; }; // positionnement dans le fichier d'entrès au niveau du numéro d'incrément suivant // si l'on ne trouve pas de numéro on renvoi un indicateur à false // la méthode renvoie également la position du début de l'incrément // et le numéro trouvé d'incrément bool UtilLecture::Increment_suivant_base_info(streampos& debut_increment,int& inc_lu) { // tout d'abord on vérifie que le fichier base_info est disponible en lecture // sinon on l'ouvre en lecture if (ent_BI == NULL) Ouverture_base_info("lecture"); // on regarde si dans la liste des incréments enregistrés, la position du suivant // s'il existe Position_BI pos_int(ios::beg,dernier_increment_lu); list ::iterator iposi = find(liste_posi_BI.begin(),liste_posi_BI.end(),pos_int); // iposi représente la position du dernier incrément enregistré if (iposi != liste_posi_BI.end()) // cas ou l'incrément existe, on prend le suivant {list ::iterator iposa = iposi; // sauvegarde iposi++; // on vérifie qu'il existe et dans ce cas on se positionne correctement if (iposi != liste_posi_BI.end()) ent_BI->seekg((*iposi).position, ios::beg); else // sinon on se met à la dernière position ent_BI->seekg((*iposa).position, ios::beg); } else // si c'était le dernier enregistré on se met à la dernière position // au cas ou le fichier de pointeur n'est pas complet ent_BI->seekg(pos_int.position, ios::beg); // maintenant on lit string toto; bool inc_trouve = false; // def d'un tableau d'entrée en flot d'entrée pour faire de la lecture non formaté char * tableau; int longueur = 250; tableau = new char [longueur] ; // def du tableau intermediaire istrstream * intar; // on définit une position intermédiaire dans le fichier pour bien se positionner // pour l'écriture ensuite éventuelle des incréments streampos position_inter=0; // lecture tant que l'on n'a pas atteint la fin du fichier do { // tout d'abord on mémorise l'ancienne position et on récupère la nouvelle debut_increment = position_inter; position_inter = ent_BI->tellg(); // si la ligne est la bonne debut_increment sera positionné sur le début // de la ligne qui contiend des ==== ent_BI->getline(tableau,longueur,'\n'); // lecture d'une ligne dans le fichier if (strstr(tableau,"INCREMENT_DE_CHARGE_:")!=NULL) { // on repositionne le flot au debut du tableau de carractere // ouverture du flot a la longueur sans blanc intar = new istrstream(tableau,short(strlen (tableau))) ; (*intar) >> toto >> inc_lu; // le nouvel incrément n'est valide que s'il est différent de l'ancien if (inc_lu != dernier_increment_lu) inc_trouve = true; delete intar; } // test pour vérifier l'intégrité du flot if (ent_BI->rdstate() != 0) // si l'on est arrivé à la fin du fichier il n'y a rien à faire // sinon on remet à flot le flot (cas par exemple d'entier au lieu de caractère)! if (!(ent_BI->eof())) ent_BI->clear(); } while ((!(ent_BI->eof()))&& (!inc_trouve)); delete[] tableau; // dans le cas où on n'a pas trouvé de bon incrément if (!inc_trouve) { inc_lu = -1; return false; } else { // on passe la ligne des === (*ent_BI) >> toto; // on enregistre la position dans la liste de position // on regarde si l'incrément demandé n'a pas déjà été enregistré Position_BI pos_ent(debut_increment,inc_lu); list ::iterator iposi_end = liste_posi_BI.end(); list ::iterator iposi = find(liste_posi_BI.begin(),liste_posi_BI.end(),pos_ent); if (iposi == liste_posi_BI.end()) {// le nouvel incrément n'existait pas mais // éventuellement le nouvel incrément peut-être intercalé entre des anciens // -- on ré-ordonne la liste, qui normalement ne doit avoir que des singletons liste_posi_BI.sort(); iposi_end = liste_posi_BI.end(); // au cas où // -- on regarde si effectivement on est intercalé if ((* liste_posi_BI.begin() < (*iposi) ) && ((*iposi) < (*iposi_end ))) {// on recherche l'encadrement ad hoc list ::iterator ipopo; for (ipopo = liste_posi_BI.begin(); ipopo != iposi_end; ipopo++) if ((* ipopo) > (*iposi)) break; if (ipopo != liste_posi_BI.end()) {// dans le cas où la position existe déjà on efface le reste de la liste // qui est maintenant inutile liste_posi_BI.erase(ipopo,liste_posi_BI.end()); }; }; liste_posi_BI.push_back(pos_ent); // // on ré-ordonne la liste, qui normalement ne doit avoir que des singletons // liste_posi_BI.sort(); // normalement ne sert à rien }; // on met à jour la variable dernier_increment_lu dernier_increment_lu = inc_lu; // retour return true; }; }; // enregistrement de la position // normalement correspond à un début d'incrément void UtilLecture::Enregistrement_position_increment_base_info(int incr) { // récup de la position streampos position_inter=0; position_inter = sort_BI->tellp(); // on enregistre la position dans la liste de position // on regarde si l'incrément demandé n'a pas déjà été enregistré Position_BI pos_ent(position_inter,incr); list ::iterator iposi = find(liste_posi_BI.begin(),liste_posi_BI.end(),pos_ent); if (iposi != liste_posi_BI.end()) {// dans le cas où la position existe déjà on efface le reste de la liste // qui est maintenant inutile liste_posi_BI.erase(iposi,liste_posi_BI.end()); }; // on écrit la nouvelle position liste_posi_BI.push_back(pos_ent); }; // renvoi tous les incréments actuellements enregistré list UtilLecture::Liste_increment() { // création de la liste de retour list list_incr; // on parcourt la liste des positions d'incréments // et on remplit la liste des numéros d'incréments list::iterator iter,iter_fin = liste_posi_BI.end(); for (iter = liste_posi_BI.begin();iter != iter_fin;iter++) list_incr.push_back((*iter).num_incr); // retour return list_incr; }; // -------------- cas des temps de calcul ---------------- // ouverture du fichier spécifique des temps cpu void UtilLecture::Ouverture_fichier_temps_cpu() { // si le fichier est déjà ouvert on ne fait rien if (sort__temps_cpu != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); // on définit des noms explicites std::string nom_CPU(ptnomCVisu); #ifdef UTILISATION_MPI // cas d'un calcul //, // on prend en compte le numéro du CPU int num_cpu = ParaGlob::Monde()->rank(); nom_CPU += ChangeEntierSTring(num_cpu); #endif nom_CPU += "_temps.cpu"; sort__temps_cpu = new ofstream(nom_CPU.c_str()); if(!(sort__temps_cpu->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << nom_CPU << "\n" << " UtilLecture::Ouverture_fichier_temps_cpu() " << endl; Sortie(1); }; }; // fermeture du fichier des temps cpu void UtilLecture::Fermeture_fichier_temps_cpu() { if (sort__temps_cpu != NULL) { delete(sort__temps_cpu); sort__temps_cpu = NULL; }; }; // -------------- cas de la visualisation ---------------- // +++ vrml ++++_____________________________________ // ouverture du fichier principal vrml void UtilLecture::Ouverture_fichier_principal_vrml() { // si le fichier est déjà ouvert on ne fait rien if (sort_princ_vrml != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_princ_vrml = new ofstream(strcat(fileName,"_princ.wrl")); if(!(sort_princ_vrml->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_principal_vrml() " << endl; Sortie(1); } }; // fermeture du fichier principal vrml void UtilLecture::Fermeture_fichier_principal_vrml() { if (sort_princ_vrml != NULL) { delete(sort_princ_vrml); sort_princ_vrml = NULL; } }; // ouverture du fichier de légendes vrml void UtilLecture::Ouverture_fichier_legende_vrml() { // si le fichier est déjà ouvert on ne fait rien if (sort_legende_vrml != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_legende_vrml = new ofstream(strcat(fileName,"_legende.wrl")); if(!(sort_legende_vrml->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_legende_vrml() " << endl; Sortie(1); } }; // fermeture du fichier légendes vrml void UtilLecture::Fermeture_fichier_legende_vrml() { if (sort_legende_vrml != NULL) { delete(sort_legende_vrml); sort_legende_vrml = NULL; } }; // +++ maple ++++ ____________________________________________ // ouverture du fichier maple void UtilLecture::Ouverture_fichier_principal_maple() { // si le fichier est déjà ouvert on ne fait rien if (sort_princ_maple != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_princ_maple = new ofstream(strcat(fileName,"_princ.maple")); if(!(sort_princ_maple->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_principal_maple() " << endl; Sortie(1); } }; // fermeture du fichier principal maple void UtilLecture::Fermeture_fichier_principal_maple() { if (sort_princ_maple != NULL) { delete(sort_princ_maple); sort_princ_maple = NULL; } }; // +++ geomview ++++_____________________________________ // ouverture du fichier principal geomview void UtilLecture::Ouverture_fichier_principal_geomview() { // si le fichier est déjà ouvert on ne fait rien if (sort_princ_geomview != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_princ_geomview = new ofstream(strcat(fileName,"_princ.oogl")); if(!(sort_princ_geomview->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_principal_geomview() " << endl; Sortie(1); } }; // fermeture du fichier principal geomview void UtilLecture::Fermeture_fichier_principal_geomview() { if (sort_princ_geomview != NULL) { delete(sort_princ_geomview); sort_princ_geomview = NULL; } }; // ouverture du fichier de légendes geomview void UtilLecture::Ouverture_fichier_legende_geomview() { // si le fichier est déjà ouvert on ne fait rien if (sort_legende_geomview != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_legende_geomview = new ofstream(strcat(fileName,"_legende.oogl")); if(!(sort_legende_geomview->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_legende_geomview() " << endl; Sortie(1); } }; // fermeture du fichier légendes geomview void UtilLecture::Fermeture_fichier_legende_geomview() { if (sort_legende_geomview != NULL) { delete(sort_legende_geomview); sort_legende_geomview = NULL; } }; // +++ Gid ++++_____________________________________ // ouverture du fichier maillage initial Gid void UtilLecture::Ouverture_fichier_initial_Gid() { // si le fichier est déjà ouvert on ne fait rien if (sort_initial_Gid != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_initial_Gid = new ofstream(strcat(fileName,"_Gid.msh")); if(!(sort_initial_Gid->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_initial_Gid() " << endl; Sortie(1); } }; // fermeture du fichier maillage initial Gid void UtilLecture::Fermeture_fichier_initial_Gid() { if (sort_initial_Gid != NULL) { delete(sort_initial_Gid); sort_initial_Gid = NULL; } }; // ouverture du fichier maillage initial Gid void UtilLecture::Ouverture_fichier_resultat_Gid() { // si le fichier est déjà ouvert on ne fait rien if (sort_resultat_Gid != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_resultat_Gid = new ofstream(strcat(fileName,"_Gid.res")); if(!(sort_resultat_Gid->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_resultat_Gid() " << endl; Sortie(1); } }; // fermeture du fichier maillage initial Gid void UtilLecture::Fermeture_fichier_resultat_Gid() { if (sort_resultat_Gid != NULL) { delete(sort_resultat_Gid); sort_resultat_Gid = NULL; } }; // +++ Gmsh ++++_____________________________________ // ouverture du fichier maillage initial Gmsh void UtilLecture::Ouverture_fichier_initial_Gmsh() { // si le fichier est déjà ouvert on ne fait rien if (sort_initial_Gmsh != NULL) return; // sinon on ouvre le fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); sort_initial_Gmsh = new ofstream(strcat(fileName,"_Gmsh.msh")); if(!(sort_initial_Gmsh->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_initial_Gmsh() " << endl; Sortie(1); } }; // fermeture du fichier maillage initial Gmsh void UtilLecture::Fermeture_fichier_initial_Gmsh() { if (sort_initial_Gmsh != NULL) { delete(sort_initial_Gmsh); sort_initial_Gmsh = NULL; } }; // création du répertoire contenant tous les fichiers résultats void UtilLecture::CreationRepertoireResultat() { // création du nom char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); // system(strcat(fileName,"_Gmsh")); // fonctionne mais on ne peut pas savoir // si le répertoire existe déjà, on utilise donc opendir (mais qui n'est pas // présent partout !! DIR * ouvre_dir = opendir(strcat(fileName,"_Gmsh")); if(ouvre_dir == NULL) { // la première fois cela veut dire que le répertoire n'existe pas on le crée avec // un ordre système // int toto = mkdir(fileName, 775); char ordre[132]; char* pordre = ordre; strcpy(pordre, "mkdir ");strcat(pordre,fileName); system(pordre); // et on retente une ouverture ouvre_dir = opendir(fileName); }; // maintenant s'il y a pb, c'est vraiment un pb if(ouvre_dir == NULL) // le répertoire ne peut être créé, message d'erreur { cout << "\n erreur en creation du repertoire " << fileName << "\n" << " UtilLecture::CreationRepertoireResultat(.. " << endl; Sortie(1); } }; // ouverture d'un fichier résultat Gmsh, comprenant un nom particulier void UtilLecture::Ouverture_fichier_resultat_Gmsh(const string& nom) { // on commence par voir si le fichier existe déjà map < string, ofstream * , std::less >::iterator ili = sort_resultat_Gmsh.find(nom); // dans le cas où le fichier existe déjà on ne fait rien if (ili == sort_resultat_Gmsh.end()) {// --- cas où le fichier n'existe pas // on construit le nom de fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); strcat(fileName,"_Gmsh/"); // là il contient la racine du répertoire strcat(fileName,ptnomCVisu); // on rajoute le début du nom du fichier strcat(fileName,"_"); // on rajoute un séparateur strcat(fileName,nom.c_str()); // on rajoute le nom passé en paramètre strcat(fileName,"_Gmsh.pos"); // ajout de la fin noms_base_fichiers_gmsh.push_back(nom); sort_resultat_Gmsh[nom] = new ofstream(fileName); if (ParaGlob::NiveauImpression()> 7) cout << "\n ouverture du fichier "<< fileName << endl; if(!(sort_resultat_Gmsh[nom]->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_resultat_Gmsh(list ) " << endl; Sortie(1); }; }; }; // ouverture d'un ensemble de fichiers: ces fichiers seront ensuite accessibles void UtilLecture::Ouverture_fichier_resultat_Gmsh(const list & t_nom) { // on va itérer sur les noms list ::const_iterator iti,itifin=t_nom.end(); for (iti=t_nom.begin();iti != itifin; iti++) { const string & nom = (*iti); // pour simplifier // on commence par voir si le fichier existe déjà map < string, ofstream * , std::less >::iterator ili = sort_resultat_Gmsh.find(nom); // dans le cas où le fichier existe déjà on ne fait rien if (ili == sort_resultat_Gmsh.end()) {// --- cas où le fichier n'existe pas // on construit le nom de fichier char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); strcat(fileName,"_Gmsh/"); // là il contient la racine du répertoire strcat(fileName,ptnomCVisu); // on rajoute le début du nom du fichier strcat(fileName,"_"); // on rajoute un séparateur strcat(fileName,nom.c_str()); // on rajoute le nom passé en paramètre strcat(fileName,"_Gmsh.pos"); // ajout de la fin noms_base_fichiers_gmsh.push_back(nom); sort_resultat_Gmsh[nom] = new ofstream(fileName); if (ParaGlob::NiveauImpression()> 7) cout << "\n ouverture du fichier "<< fileName << endl; if(!(sort_resultat_Gmsh[nom]->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_fichier_resultat_Gmsh(list ) " << endl; Sortie(1); }; }; }; }; // fermeture du fichier résultat Gmsh void UtilLecture::Fermeture_fichier_resultat_Gmsh(const string& nom) { // on commence par voir si le fichier existe map < string, ofstream * , std::less >::iterator ili = sort_resultat_Gmsh.find(nom); // dans le cas où le fichier n'existe pas on ne fait rien // mais on sort un message if (ili == sort_resultat_Gmsh.end()) { cout << "\n erreur en fermeture du fichier relatif au nom " << nom << " ce fichier n'existe pas ??? , on continue mais ...." << "\n UtilLecture::Fermeture_fichier_resultat_Gmsh(string nom)"; } else// sinon fct normal { delete(ili->second); sort_resultat_Gmsh.erase(ili); // suppression du nom de la liste noms_base_fichiers_gmsh.remove(nom); }; }; // fermeture de tous les fichiers résultat void UtilLecture::Fermeture_TousLesFichiersResultats_Gmsh() { map < string, ofstream * , std::less >::iterator ili,ilifin = sort_resultat_Gmsh.end(); for (ili=sort_resultat_Gmsh.begin();ili != ilifin;ili++) { delete(ili->second); }; sort_resultat_Gmsh.erase(sort_resultat_Gmsh.begin(),sort_resultat_Gmsh.end()); noms_base_fichiers_gmsh.clear(); }; // récupération d'un fichier résultats Gmsh ofstream & UtilLecture::Sort_resultat_Gmsh(const string& nom) { #ifdef MISE_AU_POINT // on commence par voir si le fichier existe map < string, ofstream * , std::less >::iterator ili = sort_resultat_Gmsh.find(nom); // dans le cas où le fichier n'existe pas on sort un message if (ili == sort_resultat_Gmsh.end()) { cout << "\n erreur en recuperation du fichier relatif au nom " << nom << " ce fichier n'existe pas ??? " << "\n UtilLecture::Sort_resultat_Gmsh(string nom)"; Sortie(1); return *(sort_resultat_Gmsh[nom]); // pour faire taire le compilo } else// sinon fct normal #endif { return *(sort_resultat_Gmsh[nom]); }; }; // ouverture du fichier CommandeVisu s'il est déjà ouvert on ne fait rien // a priori le fichier est ouvert en lecture : lecture // mais il peut également être en écriture : ecriture void UtilLecture::Ouverture_CommandeVisu(string type_entree) { char nomm[132]; char*fileName = nomm; strcpy(fileName, ptnomCVisu); if (type_entree == "lecture") // cas d'une lecture // on regarde si on a déjà une ouverture en écriture si oui on ferme { if (sort_CommandeVisu != NULL) Fermeture_CommandeVisu(); // maintenant on regarde si la lecture est déjà en cours si oui on ne fait rien // si le flot est correcte, sinon on ouvre if (ent_CommandeVisu == NULL) { ent_CommandeVisu = new fstream(strcat(fileName,".CVisu"), ios::out | ios::in); if(!(ent_CommandeVisu->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour la lecture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_CommandeVisu() " << endl; throw (ErrNouvelleDonneeCVisu(0)); // erreur en ouverture fichier pour la lecture Sortie(1); } } else if ( ent_CommandeVisu->rdstate() != 0) // pb éventuelle on redémarre le flux {Fermeture_CommandeVisu(); ent_CommandeVisu = new fstream(strcat(fileName,".CVisu"), ios::out | ios::in); if(!(ent_CommandeVisu->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur2 en ouverture pour la lecture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_CommandeVisu() " << endl; throw (ErrNouvelleDonneeCVisu(0)); // erreur en ouverture fichier pour la lecture Sortie(1); } } } else if (type_entree == "ecriture") // cas d'une ecriture // on regarde si on a déjà une ouverture en lecture si oui on ferme { if (ent_CommandeVisu != NULL) Fermeture_CommandeVisu(); // maintenant on regarde si la lecture est déjà en cours si oui on ne fait rien // sinon on ouvre et on se place à la fin if (sort_CommandeVisu == NULL) { sort_CommandeVisu = new fstream(strcat(fileName,".CVisu"), ios::out | ios::in ); if(!(sort_CommandeVisu->is_open())) // le fichier ne peut être ouvert, il n'existe pas donc on l'ouvre { sort_CommandeVisu = new fstream(fileName, ios::out | ios::ate); if(!(sort_CommandeVisu->is_open())) // le fichier ne peut être ouvert, message d'erreur { cout << "\n erreur en ouverture pour l'ecriture du fichier " << fileName << "\n" << " UtilLecture::Ouverture_CommandeVisu() " << endl; throw (ErrNouvelleDonneeCVisu(10)); // erreur en ouverture fichier pour l'écriture Sortie(1); }; }; }; }; //-- fin du cas écriture }; // fermeture du fichier CommandeVisu void UtilLecture::Fermeture_CommandeVisu() { if (ent_CommandeVisu != NULL) {// cas du fichier ouvert en lecture delete ent_CommandeVisu; ent_CommandeVisu = NULL; } if (sort_CommandeVisu != NULL) {// cas du fichier ouvert en écriture delete sort_CommandeVisu; sort_CommandeVisu = NULL; } }; // changement du nom de fichier .CVisu // entraîne la fermeture du fichier en cours, en lecture et en écriture // il n'y a pas de vérification à ce niveau d'existence éventuelle // car on ne sait pas ce que l'on veut en faire void UtilLecture::Changement_NomCVisu(string nouveauNomCvisu) { // on commence par fermer le fichier en cours Fermeture_CommandeVisu(); // maintenant on regarde si la chaine passée en paramètre est non nulle if (nouveauNomCvisu != "") // on définit directement le nouveau nom {nomRacineCVisu = nouveauNomCvisu;} else // sinon on passe en interactif { cout << "\n entrez le nouveau nom: "; string nom; nom= lect_chaine(); cout << " nom_lue: " << nom; // dans le cas où ".CVisu" figure dans la racine, on supprime cette chaine int posi = nomRacine.find(".CVisu"); if (posi != string::npos) { string nom_inter = nomRacine.substr(0,posi); nom = nom_inter; }; nomRacineCVisu = nom; }; // on met à jour le pointeur ptnomCVisu = (char*)nomRacineCVisu.c_str(); }; // lecture d'une nouvelle ligne de donnee utilisable pour l'entree de donnee // dans le fichier de commande de visualisation (idem NouvelleDonnee mais en plus simple // car il n'y a pas de fichier inclus) void UtilLecture::NouvelleDonneeCVisu() { // on lit jusqu'à la fin de fichier(boucle infini) // int boucle=0; try { Nouvel_enregCvisu (); // lecture d'un enreg ds le fichier courant // on repositionne le flot au debut du tableau de carractere // ouverture du flot a la longueur sans blanc delete entCVisu; #ifndef ENLINUX_STREAM entCVisu = new istringstream(tablcarCVisu,strlen (tablcarCVisu)) ; #else entCVisu = new istrstream(tablcarCVisu,(long)strlen (tablcarCVisu)) ; #endif } // sortie anormale du programme catch (ErrNouvelEnregCVisu erreur) { if ( erreur.lecture == 1) // on a atteind une fin de fichier throw (ErrNouvelleDonneeCVisu(1)); else throw (ErrNouvelleDonneeCVisu(-1)); // erreur inconnue } }; // recherche dans le fichier de commande la chaine de caractère passée en paramètre // retour false: si on ne trouve pas la chaine // retour true: si on la trouve, et dans ce cas le pointeur courant du fichier est // positionné sur la ligne de la chaine bool UtilLecture::PositionEtExisteCVisu(const string chaine) { // on ouvre le fichier en lecture si ce n'est pas fait try{ Ouverture_CommandeVisu("lecture"); // on commence par se positionner en début du fichier ent_CommandeVisu->seekg(ios::beg); // on effectue la lecture jusqu'à trouver la chaine while (strstr(tablcarCVisu,chaine.c_str())==NULL) NouvelleDonneeCVisu(); // arrêt, on a trouvé la chaine et on est bien positionné return true; } // sortie de la lecture hors du while catch (UtilLecture::ErrNouvelleDonneeCVisu erreur) { if ( erreur.lecture != 1) { // erreur en lecture cout << "\n **** ERREUR en lecture du fichier de commande de visualisation " << "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite"; if (ParaGlob::NiveauImpression() >= 4) cout << "\n UtilLecture::PositionEtExisteCVisu(.."; } } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch (...)// erreur inconnue { cout << "\n **** ERREUR inconnuee en lecture du fichier de commande de visualisation " << "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite"; if (ParaGlob::NiveauImpression() >= 4) cout << "\n 2 UtilLecture::PositionEtExisteCVisu(.."; } // quelque soit la cause, on n'a pas trouvé la chaine return false; }; //fichier CommandeVisu dans lequel sont lus les enregistrements // en lecture directe ifstream * UtilLecture::Ent_CommandeVisu() { if (ent_CommandeVisu == NULL) { // cas ou le fichier n'est pas ouvert on l'ouvre Ouverture_CommandeVisu("lecture"); } return (ifstream*) ent_CommandeVisu; }; //------------ utilitaire de lecture d'un parametre précédé d'un mot clé, avec une restriction // sur les valeurs // lecture_effective: indique si oui ou non il y a eu lecture // val_defaut: si la grandeur n'est pas lue, elle est mise par défaut = val_defaut // nom_class_methode: le nom de la methode qui appel l'utilitaire -> sortie dans le message si pb // min max : les bornes entre lesquelles doit se trouver le parametre lue sinon -> génération d'une erreur et arrêt // si max < min alors la condition n'est pas prise en compte // mot_cle : mot_cle devant précéder le parametre // parametre: le parametre à lire // retourne le parametre lue ou la valeur par défaut bool UtilLecture::Lecture_un_parametre_int(int val_defaut,const string& nom_class_methode ,int min, int max, string& mot_cle, int& parametre ) const { string nom; bool lecture_effective=false; if (strstr(tablcar,mot_cle.c_str())!=NULL) { *(entree) >> nom; if (nom != mot_cle) { cout << "\n erreur en lecture du parametre "<< mot_cle << "\n on attendait la chaine " << mot_cle << " au lieu de: " << nom << "\n " << nom_class_methode << "( ... " << endl ; Sortie(1); }; //sinon c'est ok *(entree) >> parametre; if (max > min) {if ((parametre < min ) || (parametre > max )) { cout << "\n erreur en lecture du parametre " << mot_cle << "\n pour l'instant seuls les types " << min << " a " << max << " sont implantes, valeur lue: " << parametre << "\n " << nom_class_methode << "( ... " << endl ; Sortie(1); }; }; lecture_effective = true; } else // sinon on met la valeur par défaut { parametre = val_defaut;}; // retour return lecture_effective; }; // idem pour un double bool UtilLecture::Lecture_un_parametre_double(double val_defaut,const string& nom_class_methode ,double min, double max,const string& mot_cle, double& parametre ) const { string nom; bool lecture_effective=false; if (strstr(tablcar,mot_cle.c_str())!=NULL) { *(entree) >> nom; if (nom != mot_cle) { cout << "\n erreur en lecture du parametre "<< mot_cle << "\n on attendait la chaine " << mot_cle << " au lieu de: " << nom << "\n " << nom_class_methode << "( ... " << endl ; Sortie(1); }; //sinon c'est ok *(entree) >> parametre; if (max > min) {if ((parametre < min ) || (parametre > max )) { cout << "\n erreur en lecture du parametre " << mot_cle << "\n pour l'instant seuls les types " << min << " a " << max << " sont implantes, valeur lue: " << parametre << "\n " << nom_class_methode << "( ... " << endl ; Sortie(1); }; }; lecture_effective = true; } else // sinon on met la valeur par défaut { parametre = val_defaut;}; // retour return lecture_effective; }; // lecture et passage d'un mot clé: il y a simplement vérification que c'est le bon mot clé qui est lue // ramène si oui ou non le mot clé à été lue bool UtilLecture::Lecture_et_verif_mot_cle(const string& nom_class_methode,const string& mot_cle) const { string nom; bool lecture_effective=false; if (strstr(tablcar,mot_cle.c_str())!=NULL) { *(entree) >> nom; if (nom != mot_cle) { cout << "\n erreur en lecture du mot cle "<< mot_cle << "\n on a lue " << nom << nom_class_methode << "( ... "; Sortie(1); }; //sinon c'est ok lecture_effective = true; } else // sinon problème { cout << "\n erreur en lecture du mot cle "<< mot_cle << "\n il n'existe pas sur la ligne " << tablcar << nom_class_methode << "( ... "; Sortie(1); }; // retour return lecture_effective; }; // idem pour un mot clé et un string: nom bool UtilLecture::Lecture_mot_cle_et_string(const string& nom_class_methode,const string& mot_cle,string& nom_ret) const { string nom; bool lecture_effective=false; if (strstr(tablcar,mot_cle.c_str())!=NULL) { *(entree) >> nom; if (nom != mot_cle) { cout << "\n erreur en lecture du mot cle "<< mot_cle << "\n on a lue " << nom << nom_class_methode << "( ... "; Sortie(1); }; //sinon c'est ok lecture_effective = true; } else // sinon problème { cout << "\n erreur en lecture du mot cle "<< mot_cle << "\n il n'existe pas sur la ligne " << tablcar << nom_class_methode << "( ... "; Sortie(1); }; // puis lecture du string *(entree) >> nom_ret; // retour return lecture_effective; }; // ------------------------------- méthodes protégées --------------------------------- //fichier CommandeVisu dans lequel sont lus les enregistrements // en écriture ofstream * UtilLecture::Sort_CommandeVisu() { if (sort_CommandeVisu == NULL) { // cas ou le fichier n'est pas ouvert on l'ouvre Ouverture_CommandeVisu("ecriture"); } return (ofstream*) sort_CommandeVisu; } ;