// 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 "Fonction_externe_nD.h" #include "Sortie.h" #include "ConstMath.h" #include "MathUtil.h" #include "ParaGlob.h" #include "MotCle.h" #include "TypeQuelconqueParticulier.h" #include "CharUtil.h" // --- fichier pour le tube ------ #ifdef SYSTEM_MAC_OS_CARBON #include #include #else #include #include #endif #include #include /* Pour O_WRONLY, etc */ #include // pour les ordres read write close int stat(const char *path, struct stat *buf); // CONSTRUCTEURS : Fonction_externe_nD::Fonction_externe_nD(string nom) : Fonction_nD(nom,FONCTION_EXTERNE_ND) ,passage(0),envoi(nom+"_envoi_Hz.FIFO"),reception(nom+"_reception_Hz.FIFO") ,tab_fVal(),tab_ret() // ,ordre_troncature(2) {}; // def de toutes les grandeurs -> donne une fonction utilisable Fonction_externe_nD::Fonction_externe_nD ( string nom_ref // nom de ref de la fonction ,Tableau & nom_variables_non_globales // les variables non globales ,Tableau & enu_variables_globale // enu globaux ,Tableau & nom_variables_globales_ // idem sous forme de strings ,int nb_double_ret): // nombre de grandeur en retour de fonction externe Fonction_nD(nom_ref,nom_variables_non_globales,enu_variables_globale ,nom_variables_globales_,FONCTION_EXTERNE_ND ) // ---- la partie spécifiques à la fonction externe ,passage(0),envoi(nom_ref+"_envoi_Hz.FIFO"),reception(nom_ref+"_reception_Hz.FIFO") ,tab_fVal(),tab_ret(nb_double_ret) {// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs // --> c'est déjà effectué dans le constructeur de Fonction_nD }; // de copie Fonction_externe_nD::Fonction_externe_nD(const Fonction_externe_nD& Co) : Fonction_nD(Co) ,passage(Co.passage),envoi(Co.envoi),reception(Co.reception) ,tab_fVal(Co.tab_fVal) ,tab_ret(Co.tab_ret) { // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); }; // de copie à partir d'une instance générale Fonction_externe_nD::Fonction_externe_nD(const Fonction_nD& Coo) : Fonction_nD(Coo) ,tab_fVal(),tab_ret() { if (Coo.Type_Fonction() != FONCTION_EXTERNE_ND) { cout << "\n erreur dans le constructeur de copie pour une Fonction_externe_nD " << " à partir d'une instance générale "; cout << "\n Fonction_externe_nD::Fonction_externe_nD(const Fonction_nD& Co) "; Sortie(1); }; // définition des données Fonction_externe_nD & Co = (Fonction_externe_nD&) Coo; tab_fVal=Co.tab_fVal; // opérations pipe passage = Co.passage; envoi = Co.envoi; reception = Co.reception; // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); }; // DESTRUCTEUR : Fonction_externe_nD::~Fonction_externe_nD() {}; // METHODES PUBLIQUES : // --------- virtuelles --------- // Surcharge de l'operateur = : realise l'egalite de deux fonctions Fonction_nD& Fonction_externe_nD::operator= (const Fonction_nD& elt) { // la suite ne peut fonctionner que s'il s'agit d'une fonction de même type if (typeFonction != elt.Type_Fonction()) {cout << "\n *** erreur d'affectation entre fonction nD " << nom_ref << " et " << elt.NomFonction() << "\n Fonction_externe_nD::operator= (..." << endl; Sortie(1); }; // on commence par appeler la méthode ad hoc pour la fonction Fonction_nD Fonction_nD::Transfert_info(elt); // puis on s'occupe des variables de la fonction const Fonction_externe_nD & Co = ((Fonction_externe_nD &) elt); tab_fVal=Co.tab_fVal; // opérations pipe passage = Co.passage; envoi = Co.envoi; reception = Co.reception; // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); return *this; }; // affichage de la courbe void Fonction_externe_nD::Affiche(int niveau) const { cout << " Fonction_externe_nD " << nom_ref ; cout << " \n arguments= " << nom_variables << " \n variables_globales_en_enumere= " ; int nb_enu = enu_variables_globale.Taille(); cout << "taille " << nb_enu << " "; for (int i=1;i<= nb_enu;i++) cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " "; cout << " \n variables_globales_en_string= " ; int nb_str = nom_variables_globales.Taille(); cout << "taille " << nb_str << " "; for (int i=1;i<= nb_str;i++) cout << nom_variables_globales(i) << " "; cout << "\n taille vecteur de retour: "<< this->NbComposante() << "\n f(x)= fonction utilisateur externe, dialogue via des pipes nommes" << "\n pipe d'envoi: "<< envoi << " , pipe de reception: "<< reception ; // appel de la méthode associée de la classe virtuelle Affiche_interne(niveau); if (niveau > 0) { cout << "\n derniers parametres d'appel: "; int nb_var = tab_fVal.Taille(); for (int j=1;j<=nb_var;j++) { cout << " para("<entree) >> nom_ref;} else {nom_ref=nom;}; entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne // on initialise le tableau de retour qui doit-être redimensionné en lecture tab_ret.Change_taille(0); // on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_fonction_externe_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle list < string> list_de_variables; // liste intermédiaire list list_enu_variables_glob; // idem enum glob list < string> list_de_variables_nom_globales; // idem string glob string titi; while (strstr(entreePrinc->tablcar,"fin_parametres_fonction_externe_")==0) { // si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur if ( motCle.SimotCle(entreePrinc->tablcar)) { cout << "\n erreur de lecture des parametre de definition d'une courbe avec expression litterale : on n'a pas trouve le mot cle " << " fin_parametres_fonction_externe_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer("** erreur des parametres d'une courbe expression litterale **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // lecture d'un mot clé *(entreePrinc->entree) >> titi; if ((entreePrinc->entree)->rdstate() == 0) {} // lecture normale #ifdef ENLINUX else if ((entreePrinc->entree)->fail()) // on a atteind la fin de la ligne et on appelle un nouvel enregistrement { // on lit sans tenir compte des < éventuelles entreePrinc->NouvelleDonneeSansInf(); *(entreePrinc->entree) >>titi; } #else else if ((entreePrinc->entree)->eof()) // la lecture est bonne mais on a atteind la fin de la ligne { if(titi != "fin_parametres_fonction_externe_") // on lit sans tenir compte des < éventuelles {entreePrinc->NouvelleDonneeSansInf(); *(entreePrinc->entree) >> titi; }; } #endif else // cas d'une erreur de lecture { cout << "\n erreur de lecture inconnue "; entreePrinc->MessageBuffer("** erreur2 des parametres d'une courbe expression litterale**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on lit maintenant la ou les variables // cas de la lecture d'une variable if(titi == "un_argument=") {string truc; *(entreePrinc->entree) >> truc; // on regarde s'il s'agit d'une variable globale correspondant à un énuméré global if (EstUneGrandeurGlobale(truc)) { list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (truc));} // idem mais sous forme d'un string else if (ParaGlob::param->GrandeurGlobal(truc) != NULL) { list_de_variables_nom_globales.push_back(truc);} else // sinon ce n'est pas une grandeur globale {list_de_variables.push_back(truc);}; } else if(titi == "deb_list_var_") // lecture d'une liste d'argument {// on va lire juqu'au mot clé fin_list_var_ int nb_boucle = 0; // indicateur pour éviter une boucle infinie do {string truc; *(entreePrinc->entree) >> truc; if (truc == "fin_list_var_") break; // on regarde s'il s'agit d'une variable globale if (EstUneGrandeurGlobale(truc)) { list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (truc));} // idem mais sous forme d'un string else if (ParaGlob::param->GrandeurGlobal(truc) != NULL) { list_de_variables_nom_globales.push_back(truc);} else // sinon ce n'est pas une grandeur globale {list_de_variables.push_back(truc);}; nb_boucle++; } while (nb_boucle < 200); if (nb_boucle > 199) { cout << "\n erreur de lecture au niveau d'une liste de variable " << " deb_list_var_ nom1 nom2 ... fin_list_var_"; entreePrinc->MessageBuffer("** erreur lecture parametre d'une courbe expression litterale **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } else // sinon la lecture est ok a priori ; } // cas de la lecture du niveau d'impression pour les erreurs else if(titi == "permet_affichage_") {*(entreePrinc->entree) >> permet_affichage; } // cas de la lecture du type d'expression du tenseur else if(titi == "Tenseur_base_ad_hoc_") {*(entreePrinc->entree) >> absolue; } // cas de la lecture de la taille du vecteur retour else if(titi == "nb_double_ret_") {int nb_double_ret; // nombre de grandeur en retour de fonction externe *(entreePrinc->entree) >> nb_double_ret; if (nb_double_ret < 1) {cout << "\n erreur en lecture du nombre de grandeur en retour de fonction externe " << " qui doit etre >= 1, on a lu : " << nb_double_ret << endl; entreePrinc->MessageBuffer("**Fonction_externe_nD::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } else tab_ret.Change_taille(nb_double_ret); // cas ok } // sinon ce n'est pas un mot clé connu, on le signale else if(titi != "fin_parametres_fonction_externe_") { cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu " << " on a lu : " << titi << endl; entreePrinc->MessageBuffer("**Fonction_externe_nD::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; //-- fin du while // on vérifie que l'on a bien redimensionné le tableau de retour if ( tab_ret.Taille() == 0) {cout << "\n erreur en definition de la fonction externe, il manque le dimensionnement du vecteur de retour !! " << " qui doit etre >= 1 " << endl; entreePrinc->MessageBuffer("**Fonction_externe_nD::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on supprime les doublons dans les variables globales list_enu_variables_glob.sort(); list_enu_variables_glob.unique(); list_de_variables_nom_globales.sort(); list_de_variables_nom_globales.unique(); // on parcours les variables globales patentées int nb_enu = list_enu_variables_glob.size(); int ienu=1; enu_variables_globale.Change_taille(nb_enu); {list ::iterator il,ilfin=list_enu_variables_glob.end(); for (il=list_enu_variables_glob.begin();il!=ilfin;il++,ienu++) enu_variables_globale(ienu) = *il; }; // idem pour les noms de ref int nb_nom = list_de_variables_nom_globales.size(); int i_nom=1; nom_variables_globales.Change_taille(nb_nom); {list ::iterator il,ilfin=list_de_variables_nom_globales.end(); for (il=list_de_variables_nom_globales.begin();il!=ilfin;il++,i_nom++) nom_variables_globales(i_nom) = *il; }; // --- on définie les variables qui ne sont pas globales --- // par contre on va changer l'ordre d'apparition des variables // en 1) les scalaires, 2) les coordonnées , 3) les tenseurs // et .... rajouter int taille = list_de_variables.size(); // récup de la taille nom_variables.Change_taille(taille); // mise à jour de la taille tab_fVal.Change_taille(taille+nb_enu+nb_nom); // idem mais en tenant compte des var globales // vérif qui normalement est inutile, mais on ne sait jamais if (tab_fVal.Taille() > 115) { cout << "\n ** erreur dans la construction de la fonction " << nom_ref ; cout << " le nombre de parametres d'appel:" << tab_fVal.Taille() << " est superieur a 115 = la limite superieur autorisee " << "\n Fonction_externe_nD::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; // cas des variables non globales list < string>::iterator il,ilfin = list_de_variables.end(); int i= 1; for (il = list_de_variables.begin();il != ilfin;il++,i++) { nom_variables(i)=(*il); // on récupère le nom }; // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); // on définit le paramètre depend_M de la classe maître en fonction des nom_variables if (permet_affichage > 6) cout << "\n == >>> lecture donnees particuliere de la fct: " << nom_ref << ") " << " operations finales: " ; Fonction_nD::Definition_depend_M(); // idem pour le temps Fonction_nD::Definition_depend_temps(); // initialisation des pipes Fonction_externe_nD::InitialisationPipesNommes(); }; // mise à jour des variables globales: en fonction de l'apparition de nouvelles variables // globales en cours de calcul void Fonction_externe_nD::Mise_a_jour_variables_globales() { // appel de la fonction interne pour modifier les noms de variables Fonction_nD::Mise_a_jour_variables_globales_interne(); }; // def info fichier de commande void Fonction_externe_nD::Info_commande_Fonctions_nD(UtilLecture & entreePrinc) { ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier cout << "\n cas de la fonction Fonction_externe_nD : " << " \ndefinition standart (rep o) ou documentation exhaustive (rep n'importe quoi) ? "; string rep = "_"; rep = lect_return_defaut(false,"o"); sort << "\n# ....... fonction litterale nD ........"; // cas particulier if ((rep == "o") || (rep == "O" ) || (rep == "0") ) {sort << "\n# exemple de definition d'une fonction Fonction_externe_nD" << " qui renvoi une seule valeur (un reel) " << "\n exemple_fonct_ext_nD FONCTION_EXTERNE_ND " << "\n un_argument= i un_argument= j " << "\n nb_double_ret_ 1 " << "\n fin_parametres_fonction_externe_ " << endl; } else // cas d'une description exhaustive { sort << "\n# Il s'agit d'une fonction utilisateur qui est definie en dehors d'Herezh " << "\n# a chaque appel de la fonction: " << "\n# 1) les variables sont copiees sur le pipe nomme _envoi_Hz.FIFO " << "\n# 2) puis Herezh lit la reponse sur le pipe nomme: _reception_Hz.FIFO " << "\n# ==> tant que les informations ne sont pas disponibles sur le pipe de reception " << "\n# l'execution d'Herezh est stoppee " << "\n# " << "\n# L'utilisation de cette fonction impose donc a l'utilisateur, de construire un programme" << "\n# externe qui lit les donnes sur _envoi_Hz.FIFO, en deduit les valeurs de retour " << "\n# qui doivent etre ecrite sur _reception_Hz.FIFO " << "\n# " << "\n# Format d'echange: " << "\n# en ecriture, Herezh ecrit sur le pipe d'envoi: " << "\n# - 2 entiers codes sur 4 octets chacun, qui representent: " << "\n# . le premier n1 = le nombre de variables de la fonction" << "\n# . le second n2 = la taille du vecteur de retour attendu sur le pipe de reception " << "\n# - puis n1 reels, chacun code sur 8 octets " << "\n# " << "\n# en retour, Herezh lit sur le pipe de reception: " << "\n# - 2 entiers codes sur 4 octets chacun, qui representent: " << "\n# . le premier n1 = le nombre de variables de la fonction" << "\n# . le second n2 = la taille du vecteur de retour attendu sur le pipe de reception " << "\n# - puis n2 reels, chacun code sur 8 octets " << "\n# " << "\n# NB: le nombre maximal possible de reels est actuellement de 115 " << "\n# " << "\n# " << "\n# Par exemple, pour une utilisation via un programme C ou C++, une methode est de definir " << "\n# une structure union. Supposons 4 variables, et un vecteur de 2 composantes en retour " << "\n# cela signifie qu'il faut une taille minimale de tampon de passage de: 2*4+4*8= 40 octets" << "\n# equivalent a 5 reels, 10 entiers d'ou un exemple de declaration: " << "\n# union Tab_car_double_int " << "\n# { char tampon[40]; " << "\n# double x[5]; " << "\n# int n[10]; " << "\n# } ; " << "\n# Ensuite, le programme C lit l'information sur le pipe d'envoi de nom ici: envoi, ex: " << "\n# Tab_car_double_int t_car_x_n; " << "\n# char* tampon = &(t_car_x_n.tampon[0]); " << "\n# int nb_carac_a_lire = 40 ; " << "\n# int tub = open(envoi.c_str(),O_RDONLY); " << "\n# read (tub,tampon_,nb_carac_a_lire); " << "\n# close (tub); " << "\n# " << "\n# Les variables sont alors disponible dans le tableau x " << "\n# Puis le programme C calcule les valeurs de retour et les sauvegarde dans x " << "\n# Reste a ramener les infos a Herezh. Pour cela le programme C doit ecrire dans " << "\n# le pipe de retour, ici de nom reception, par ex: " << "\n# " << "\n# int tub = open(reception.c_str(),O_WRONLY); " << "\n# int nb_carac_a_ecrire = 2 * 8 + 2*4 ; " << "\n# write (tub,t_car_x_n.reception,nb_carac_a_ecrire); " << "\n# close (tub); " << "\n# " << "\n# ======= definition d'une fonction externe ===== " << "\n# 1) --- on definit la liste de variables " << "\n# cette liste inclu des variables avec les 2 syntaxes suivantes " << "\n# a) soit une variable par ligne selon la syntaxe: " << "\n# un_argument= nom_argument" << "\n# ou " << "\n# un_argument= : le mot cle " << "\n# nom_argument : le nom de la variable " << "\n# b) soit une liste de variables (sur une ligne) selon la syntaxe " << "\n# deb_list_var_ nom1 nom2 ... fin_list_var_ " << "\n# ou " << "\n# deb_list_var_ et fin_list_var_ : balises encadrant la liste" << "\n# nom1 nom2 ... : le nom de chaque variable " << "\n# " << "\n# NB: les variables peuvent etre des grandeurs locales ou globales" << "\n# " << "\n# 2) --- on definit la taille du vecteur de retour de la fonction externe " << "\n# (note n2 dans les explications precedantes) " << "\n# NB: il n'y a pas de definition par defaut " << "\n# la definition s'effectue via le mot cle: nb_double_ret_ " << "\n# suivi de la taille du vecteur de retour, ex: " << "\n# nb_double_ret_ 1 " << "\n# La liste des variables et la definition de n2 " << "\n# doit se terminer par le mot cle (sur une ligne seule ): " << "\n# fin_parametres_fonction_externe_ " << "\n# " << "\n#............................................" << "\n# exemple de definition d'une fonction Fonction_externe_nD" << " qui renvoi une seule valeur (un reel) " << "\n exemple_fonct_ext_nD FONCTION_EXTERNE_ND " << "\n un_argument= i un_argument= j " << "\n nb_double_ret_ 1 " << "\n fin_parametres_fonction_externe_ " << "\n# " << "\n# type d'expression des tenseurs: " << "\n# Tenseur_base_ad_hoc_ suivi de " << "\n# 0 si dans la base ad hoc " << "\n# 1 si dans une base globale " << "\n# NB: les deux sont en orthonorme " << "\n# par defaut, c'est dans une base ad hoc" << "\n# ex: Tenseur_base_ad_hoc_ 0 " << "\n# " << "\n# niveau d'impression: dans certain cas il peut-etre utile d'afficher " << "\n# les resultats intermediaires des calculs et egalement des erreurs intermediaires " << "\n# pour mettre en route ce fonctionnement il faut indiquer sur une ligne seule le mot cle " << "\n# permet_affichage_ suivi d'un chiffre donnant le niveau d'impression (entre 0 et 10) " << "\n# ex: permet_affichage_ 5 " << "\n# Remarques: 1) ceci ne fonctionne qu'avec la version non fast " << "\n# cependant, la lecture reste correcte avec le mot cle permet_affichage_ " << "\n# mais la presence du mot cle n'entraine aucune action en fast " << "\n# 2) le mot cle doit etre indique avant le dernier mot cle : " << "\n# fin_parametres_fonction_externe_ " << endl; }; }; // calcul des valeurs de la fonction, retour d'un tableau de scalaires Tableau & Fonction_externe_nD::Valeur_FnD_interne(Tableau * xi) { int i_in_xi=1; // indice pour se déplacer dans xi int i_fval=1; // indice pour se déplacer dans fval_int int taille_xi=0; // init par défaut if (xi != NULL) taille_xi=xi->Taille(); try { int nb_var_int = nom_variables.Taille(); int tail_enu = enu_variables_globale.Taille(); // les variables globales int tail_nom = nom_variables_globales.Taille(); // idem avec des noms #ifdef MISE_AU_POINT if (tab_fVal.Taille() != (taille_xi+tail_enu+tail_nom)) { cout << "\n *** pb de dimensions d'argument non coherentes !! " << " taille_xi "<Affiche(); // on génère une interruption ce qui permettra de dépiler les appels ErrCalculFct_nD toto; throw (toto); Sortie(1); }; #endif // on remplit le tableau de passage pour la fonction maître // 1) tout d'abord pour les variables patentées for (int ii = 1;ii<= nb_var_int;ii++,i_fval++) { // on se déplace d'abord dans xi if (i_in_xi <= taille_xi) {tab_fVal(i_fval) = xi->operator()(i_in_xi);i_in_xi++;} else { cout << "\n *** pb de nombre d'argument non coherentes !! " << " on n'a pas assez d'arguments pour l'appel de la fonction globale: "; this->Affiche(); cout << "\n revoir la mise en donnees " << "\n Fonction_externe_nD::Valeur_FnD_interne(..."<0) { // en debug on vérifie que les grandeurs globales sont présentent #ifdef MISE_AU_POINT try { int taille = enu_variables_globale.Taille(); for (int i=1;i<= taille;i++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i))); if (pointe == NULL) { cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! " << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i)) << ", n'est pas disponible, on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; } catch(...) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref ; cout << " verifier la presence des grandeurs globales voulues " << "\n Fonction_externe_nD::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif // on parcours les variables globales int taille = enu_variables_globale.Taille(); for (int i=1;i<= taille;i++,i_fval++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; }; }; // 3) idem pour les globaux en nom c-a-d typées sous forme de string if (tail_nom>0) { // en debug on vérifie que les grandeurs globales sont présentent #ifdef MISE_AU_POINT try { for (int i=1;i<= tail_nom;i++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i))); if (pointe == NULL) { cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! " << " la variable globale "<< nom_variables_globales(i) << ", n'est pas disponible, on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; } catch(...) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref ; cout << " verifier la presence des grandeurs globales voulues " << "\n Fonction_externe_nD::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif // on parcours les variables globales int taille = nom_variables_globales.Taille(); for (int i=1;i<= taille;i++,i_fval++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); break; } case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; } break; } case TABLEAU_T: // valable uniquement pour les vecteur nommer // dans ce cas on n'utilise pour l'instant que la première valeur { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) { case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n grandeur= "<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; }; }; */ // on récupère les grandeurs globales Fonction_nD::Recup_Grandeurs_globales(); // on affecte les grandeurs int taille = x_glob.Taille(); for (int i=1;i<= taille;i++,i_fval++) tab_fVal(i_fval) = x_glob(i); // maintenant on appelle la fonction et on récupère les grandeurs // 1) écriture des données sur le pipe EcritureDonneesPipe(); // 2) lecture des données sur le pipe LectureResultatsPipe(); #ifdef MISE_AU_POINT // vérification d'une norme infinie // if (permet_affichage > 0) {int nNum = tab_ret.Taille(); double absret_Fi= 0.; for (int i=0; i>> arbre d'appel : fonction this : "; this->Affiche(5); cout << endl; // on génère une interruption ce qui permettra de dépiler les appels ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; #endif } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) { cout << "\n ** erreur non determinee dans l'appel de la fonction " << nom_ref << " d'expression " << " \n xi= "<Affiche(); cout << "\n Fonction_externe_nD::Valeur_FnD_interne(..."; // on génère une interruption ce qui permettra de dépiler les appels ErrCalculFct_nD toto;throw (toto); Sortie(1); }; return tab_ret; }; // calcul des valeurs de la fonction, dans le cas où les variables // sont toutes des grandeurs globales: pour l'instant que pour des variables scalaires Tableau & Fonction_externe_nD::Valeur_pour_variables_globales_interne() { /* // en debug on vérifie que les grandeurs globales sont présentent #ifdef MISE_AU_POINT try { // on vérifie tout d'abord que toutes les variables sont globales if (nom_variables.Taille() != 0) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref ; cout << " toutes les variables ne sont pas globales !! " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<Affiche(); // on génère une interruption ce qui permettra de dépiler les appels ErrCalculFct_nD toto;throw (toto); Sortie(1); }; // maintenant on vérifie la présence des variables globales int taille = enu_variables_globale.Taille(); for (int i=1;i<= taille;i++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i))); if (pointe == NULL) { cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! " << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i)) << ", n'est pas disponible, on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<Affiche(); // on génère une interruption ce qui permettra de dépiler les appels ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; } catch(...) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref ; cout << " verifier la presence des grandeurs globales voulues " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<Affiche(); // on génère une interruption ce qui permettra de dépiler les appels ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif // idem pour les grandeurs indicées avec des string #ifdef MISE_AU_POINT try { int tail_nom = nom_variables_globales.Taille(); for (int i=1;i<= tail_nom;i++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i))); if (pointe == NULL) { cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! " << " la variable globale "<< nom_variables_globales(i) << ", n'est pas disponible, on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; } catch(...) { cout << "\n ** erreur dans l'appel de la fonction " << nom_ref ; cout << " verifier la presence des grandeurs globales voulues " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<Affiche(); // on génère une interruption ce qui permettra de dépiler les appels ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif */ // arrivée ici toutes les grandeurs existent try { /* // on parcours les variables globales int i_fval=1; // indice pour se déplacer dans plusieurs boucles int taille = enu_variables_globale.Taille(); for (int i=1;i<= taille;i++,i_fval++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; }; // idem mais typées sous forme de string {// on parcours les variables globales int taille = nom_variables_globales.Taille(); for (int i=1;i<= taille;i++,i_fval++) {// on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i))); TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()) { case TYPE_SIMPLE: { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) {case PARTICULIER_SCALAIRE_ENTIER: {Grandeur_scalaire_entier& gr = *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); break; } case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; } break; } case TABLEAU_T: // valable uniquement pour les vecteur nommer // dans ce cas on n'utilise pour l'instant que la première valeur { switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()) { case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1)); #ifdef MISE_AU_POINT // on vérifie qu'une seule grandeur est stockée if (gr.NbMaxiNumeroOrdre() > 1) { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n grandeur= "<Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref << " la variable globale "<< nom_variables_globales(i) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; }; }; }; */ // on récupère les grandeurs globales Fonction_nD::Recup_Grandeurs_globales(); // on affecte les grandeurs int taille_x_glob = x_glob.Taille(); for (int i=1;i<= taille_x_glob;i++) tab_fVal(i) = x_glob(i); // maintenant on appelle la fonction et on récupère les grandeurs // 1) écriture des données sur le pipe EcritureDonneesPipe(); // 2) lecture des données sur le pipe LectureResultatsPipe(); #ifdef MISE_AU_POINT // vérification d'une norme infinie // if (permet_affichage > 0) {int nNum = tab_ret.Taille(); double absret_Fi= 0.; for (int i=0; i>> arbre d'appel : fonction this : "; this->Affiche(5); cout << endl; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; #endif } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) { cout << "\n ** erreur non determinee dans l'appel de la fonction " << nom_ref << "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."; // // on génère une interruption ce qui permettra de dépiler les appels this->Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; return tab_ret; }; //----- lecture écriture de restart ----- // cas donne le niveau de la récupération // = 1 : on récupère tout // = 2 : on récupère uniquement les données variables (supposées comme telles) void Fonction_externe_nD::Lecture_base_info(ifstream& ent,const int cas) { // on n'a que des grandeurs constantes if (cas == 1) { string nom; // lecture et vérification de l'entête ent >> nom; if (nom != "Fonction_externe_nD") { cout << "\n erreur dans la vérification du type de courbe lue "; cout << "\n Fonction_externe_nD::Lecture_base_info(... "; Sortie(1); } // lecture des infos // les arguments gérés par la classe mère Fonction_nD::Lect_base_info(ent,cas); // retour des valeurs string toto; ent >> toto ; if (toto != "taille_vecteur_de_retour:") {cout << "\n erreur en lecture sur base info du nombre de grandeur en retour de fonction externe " << " on a lu : " << toto << " alors que l'on attendait: taille_vecteur_de_retour:" << "\n Fonction_externe_nD::Lecture_base_info(..." << endl; Sortie(1); }; // cas où c'est ok int nb_double_ret; ent >> nb_double_ret; tab_ret.Change_taille(nb_double_ret); // on définit le paramètre depend_M de la classe maître en fonction des nom_variables Fonction_nD::Definition_depend_M(); // idem pour le temps Fonction_nD::Definition_depend_temps(); // idem pour la cohérence avec les enu // Fonction_nD::Construction_enu_etendu_et_quelconque(); // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs Fonction_nD::Construction_index_conteneurs_evoluees(); // initialisation des pipes au cas où Fonction_externe_nD::InitialisationPipesNommes(); } }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Fonction_externe_nD::Ecriture_base_info(ofstream& sort,const int cas) { // on n'a que des grandeurs constantes if (cas == 1) { sort << "\n "; sort << " Fonction_externe_nD "; // les arguments gérés par la classe mère Fonction_nD::Ecrit_base_info(sort,cas); // retour des valeurs sort << "\n taille_vecteur_de_retour: "<< this->NbComposante() << " "; sort << "\n \n"; }; }; // sortie du schemaXML: en fonction de enu void Fonction_externe_nD::SchemaXML_Fonctions_nD(ofstream& ,const Enum_IO_XML enu) { switch (enu) { case XML_TYPE_GLOBAUX : { break; } case XML_IO_POINT_INFO : { break; } case XML_IO_POINT_BI : { break; } case XML_IO_ELEMENT_FINI : { break; } }; }; // initialisation des pipes void Fonction_externe_nD::InitialisationPipesNommes() { try { // pipe de sortie // on test l'existence du pipe struct stat buf; int tub=0; // init int etat = stat(envoi.c_str(), &buf); int tube_a_cree = 0; if (etat == -1) // cela veut dire que la fonction stat n'a pas fonctionné // on part sur le principe que les tubes n'existent pas {tube_a_cree=1;} else if (!S_ISFIFO(buf.st_mode)) {tube_a_cree=1;}; if (tube_a_cree ) // cas où le tube n'existe pas {tub = mkfifo (envoi.c_str(), S_IRWXU); if (tub == -1 ) // gestion d'erreur éventuelle {cout << "\n *** erreur en creation du tube nomme: " << envoi << ", de sortie d'herezh pour la " << " fonction externe "<< nom_ref << "\n Fonction_externe_nD::InitialisationPipesNommes() "< 3) || (permet_affichage > 0 )) { cout << "\n creation du pipe nomme: "<< envoi << " pour la " << " fonction externe "<< nom_ref << flush; // partie affichage du nom des variables if (permet_affichage > 5) { cout << "\n ---- Fonction_externe_nD " << nom_ref ; cout << " \n arguments= " << nom_variables << " \n variables_globales_en_enumere= " ; int nb_enu = enu_variables_globale.Taille(); cout << "taille " << nb_enu << " "; for (int i=1;i<= nb_enu;i++) cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " "; cout << " \n variables_globales_en_string= " ; int nb_str = nom_variables_globales.Taille(); cout << "taille " << nb_str << " "; for (int i=1;i<= nb_str;i++) cout << nom_variables_globales(i) << " "; }; } ; close (tub); // fermeture du tampon } else if ((ParaGlob::NiveauImpression() > 3) || (permet_affichage > 0 )) { cout << "\n utilisation du pipe nomme: "<< reception << " pour la " << " fonction externe "<< nom_ref << flush; // partie affichage du nom des variables if (permet_affichage > 5) { cout << "\n ---- Fonction_externe_nD " << nom_ref ; cout << " \n arguments= " << nom_variables << " \n variables_globales_en_enumere= " ; int nb_enu = enu_variables_globale.Taille(); cout << "taille " << nb_enu << " "; for (int i=1;i<= nb_enu;i++) cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " "; cout << " \n variables_globales_en_string= " ; int nb_str = nom_variables_globales.Taille(); cout << "taille " << nb_str << " "; for (int i=1;i<= nb_str;i++) cout << nom_variables_globales(i) << " "; }; } ; tub = 0; // réinit tube_a_cree = 0; // réinit // ouverture du tube nommé en lecture etat = stat(reception.c_str(), &buf); if (etat == -1) // cela veut dire que la fonction stat n'a pas fonctionné // on part sur le principe que les tubes n'existent pas {tube_a_cree=1;} else if (!S_ISFIFO(buf.st_mode)) {tube_a_cree=1;}; if (tube_a_cree ) // cas où le tube n'existe pas {tub = mkfifo (reception.c_str(), S_IRWXU); if (tub == -1 ) // gestion d'erreur éventuelle {cout << "\n *** erreur en creation du tobe nomme: " << reception << ", de lecture d'herezh pour la " << " fonction externe "<< nom_ref << "\n Fonction_externe_nD::InitialisationPipesNommes() "< 3) || (permet_affichage > 0 )) { cout << "\n creation du pipe nomme: "<< reception << " pour la " << " fonction externe "<< nom_ref << flush; } ; close (tub); // fermeture du tampon } else if ((ParaGlob::NiveauImpression() > 3) || (permet_affichage > 0 )) { cout << "\n utilisation du pipe nomme: "<< reception << " pour la " << " fonction externe "<< nom_ref << flush; } ; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) {cout << "\n *** erreur inconnue lors de l'initialisation des pipes I/O pour la " << " fonction externe "<< nom_ref << "\n Fonction_externe_nD::InitialisationPipesNommes() "< 5) cout << "\n hzpp: ouverture du tube en lecture, lecture sur le tube: " << reception << endl; // union Tab_car_double_int_1 // { char tampon[928]; // double x[116]; // int n[232]; // } ; // Tab_car_double_int_1 t_car_x_n; // tableau de caractères, réels et entiers // Tableau tab_fVal; // les variables internes dont le nombre doit être // // égal à celui du tableau nom_variables + les enum globaux + les noms globaux // Tableau tab_ret; // le tableau de retour // le premier élément est le nombre de grandeurs à écrire (et donc à lire du coté externe) // le second élément est le nombre de grandeurs que l'on attend en retour t_car_x_n.n[1] = tab_ret.Taille(); char* tampon = &(t_car_x_n.tampon[0]); int nb_carac_a_lire = t_car_x_n.n[1] * 8 + 2*4 ; int tub = open(reception.c_str(),O_RDONLY); read (tub,tampon,nb_carac_a_lire); close (tub); // fermeture du tampon // on récupère les informations du tampon int nb_doublePlusUn = tab_ret.Taille() +1; for (int i=1;i2 ) {cout << "\n lecture de " << t_car_x_n.n[1] << " reels "; if (permet_affichage > 3) {for (int i=1;i <= t_car_x_n.n[1]; i++) cout << "\n resultat "<< i<< "= " << t_car_x_n.x[i]; }; cout << "\n HZpp: fermeture du tube en lecture: " << reception << endl; }; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) {cout << "\n *** erreur en lecture des resultats de la fonction externe " << nom_ref ; Affiche(permet_affichage); cout << flush; Sortie(1); }; // à chaque lecture on incrémente un compteur passage++; // pour des comptes éventuelles }; // écriture des variables de passage void Fonction_externe_nD::EcritureDonneesPipe() {try {// Creation d'un processus d'ecriture des variables // en fait l'objectif est d'ecrire que les variables qui évoluent if (permet_affichage > 5) cout << "\n hzpp: ouverture du tube en ecriture, ecriture sur le tube: " << envoi << endl; // union Tab_car_double_int_1 // { char tampon[928]; // double x[116]; // int n[232]; // } ; // Tab_car_double_int_1 t_car_x_n; // tableau de caractères, réels et entiers // Tableau tab_fVal; // les variables internes dont le nombre doit être // // égal à celui du tableau nom_variables + les enum globaux + les noms globaux // Tableau tab_ret; // le tableau de retour // le premier élément est le nombre de réel à écrire (et donc à lire du coté externe) t_car_x_n.n[0]=tab_fVal.Taille(); int nb_doublePlusUn = t_car_x_n.n[0]+1; // le second élément est le nombre de grandeurs que l'on attend en retour t_car_x_n.n[1] = tab_ret.Taille(); // après on transfert dans le tampon for (int i=1;i 2) {cout << "\n ecriture de " << t_car_x_n.n[0] << " reels "; if (permet_affichage > 3) {for (int i=1;i <= t_car_x_n.n[0]; i++) cout << "\n variable "<< i<< "= " << t_car_x_n.x[i]; }; if (permet_affichage > 7) cout << "\n HZpp: fermeture du tube en ecriture: " << envoi << endl; }; } catch (ErrSortieFinale) // cas d'une direction voulue vers la sortie // on relance l'interuption pour le niveau supérieur { ErrSortieFinale toto; throw (toto); } catch(...) {cout << "\n *** erreur en ecriture des parametre de la fonction externe " << nom_ref ; Affiche(permet_affichage); cout << flush; Sortie(1); }; };