// This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2021 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . #include "F_union_1D.h" #include "Sortie.h" #include "ConstMath.h" #include "MathUtil.h" #include "CharUtil.h" // CONSTRUCTEURS : F_union_1D::F_union_1D(string nom) : Courbe1D(nom,F_UNION_1D),Fi(),Xi(),nom_courbei(),indice_precedant(1) {}; // de copie F_union_1D::F_union_1D(const F_union_1D& Co) : Courbe1D(Co),indice_precedant(Co.indice_precedant) ,Fi(Co.Fi),Xi(Co.Xi),nom_courbei(Co.nom_courbei) { // création des courbes locales que si elles étaient déjà locales int tai = Fi.Taille(); for (int i=1;i<= tai; i++) if (Co.Fi(i)->NomCourbe() == "_") {Fi(i)=Courbe1D::New_Courbe1D(*(Co.Fi(i)));}; }; // de copie à partir d'une instance générale F_union_1D::F_union_1D(const Courbe1D& Coo) : Courbe1D(Coo) { if (Coo.Type_courbe() != F_UNION_1D) { cout << "\n erreur dans le constructeur de copie pour une courbe F_UNION_1D " << " a partir d'une instance générale "; cout << "\n F_union_1D::F_union_1D(const Courbe1D& Co) "; Sortie(1); }; // définition des données F_union_1D & Co = (F_union_1D&) Coo; indice_precedant=Co.indice_precedant; Fi=Co.Fi; Xi=Co.Xi; nom_courbei = Co.nom_courbei; int tai = Fi.Taille(); // création des courbes locales que si elles étaient déjà locales for (int i=1;i<= tai; i++) if (Co.Fi(i)->NomCourbe() == "_") {Fi(i)=Courbe1D::New_Courbe1D(*(Co.Fi(i)));}; }; // DESTRUCTEUR : F_union_1D::~F_union_1D() { // on efface les courbes que si c'est des courbes locales int tai = Fi.Taille(); for (int i=1;i<= tai; i++) if ((Fi(i) != NULL)&&(nom_courbei(i)=="i_interne_i")) delete Fi(i); }; // METHODES PUBLIQUES : // --------- virtuelles --------- // affichage de la courbe void F_union_1D::Affiche() const { cout << "\n courbe composee : F_union_1D : nom_ref= " << nom_ref; int tai = Fi.Taille(); // on parcours toutes les courbes for (int i=1;i<= tai; i++) { cout << "\n intervalle: [" << Xi(i) <<","<NomCourbe() == "_") {Fi(i)->Affiche();} else {cout << Fi(i)->NomCourbe() << " ";}; }; cout << "\n permet_affichage: " << permet_affichage; cout << "\n ----- fin fonction F_union_1D ----- "; }; // vérification que tout est ok, pres à l'emploi // ramène true si ok, false sinon bool F_union_1D::Complet_courbe()const { bool ret = Complet_var(); // on regarde du coté de la classe mère tout d'abord // puis les variables propres, il faut au moins une courbe if (Fi.Taille() == 0) ret = false; if (!ret && (ParaGlob::NiveauImpression() >0)) { cout << "\n ***** la courbe n'est pas complete (aucune courbe de base n'existe) "; this->Affiche(); }; return ret; } ; // dans le cas où les courbes membres sont des courbes externes // fonction pour les définir // les courbes sont défini en interne que si les courbes argument sont elles même // des courbes locales. c'est-à-dire si FFi(i)->NomCourbe() ="_" alors on recrée une courbe // interne avec new pour Fi(i), sinon Fi(i)=FFi(i) et pas de création; // dans le cas où FFi(i) est NULL on passe, pas de traitement pour ce pointeur void F_union_1D::DefCourbesMembres(Tableau & FFi) { // l'objectif est // 1) d'adapter le nombre de courbe à celui de FFi // 2) de ne changer que celle qui sont non nul dans FFi int tai = Fi.Taille(); // taille existante int taii = FFi.Taille(); // taille du nouveau tableau // on commence par effacer les courbes existantes supérieur à taii if (taii < tai) for (int i=taii;i<= tai; i++) if ((Fi(i) != NULL)&&(nom_courbei(i)=="i_interne_i")) { delete Fi(i);Fi(i)=NULL;}; // on change de taille Fi.Change_taille(taii); tai = taii; for (int i=1;i<= tai; i++) { // création d'une courbe locale que si elle était déjà locales if (FFi(i) != NULL) {if (FFi(i)->NomCourbe() == "_") // cas où FFi(i) est une courbe non globale { if (Fi(i)==NULL) // cas où la courbe locale n'est pas défini mais on veut une courbe interne { Fi(i)=Courbe1D::New_Courbe1D(*(FFi(i)));nom_courbei(i)="i_interne_i";} else if (Fi(i)->NomCourbe() == "_") // cas où la courbe F1 est local et on veut la remplacer par une nouvelle locale { delete Fi(i); Fi(i)=Courbe1D::New_Courbe1D(*(FFi(i)));nom_courbei(i)="i_interne_i"; } else // cas où la courbe Fi(i est global et on veut la remplacer par une locale { Fi(i)=Courbe1D::New_Courbe1D(*(FFi(i)));nom_courbei(i)="i_interne_i";}; } else // cas ou FFi(i) est une courbe globale { if (Fi(i)==NULL) // cas où la courbe locale n'est pas défini { Fi(i)=FFi(i);nom_courbei(i)="e_externe_e";} else if (Fi(i)->NomCourbe() == "_") // cas où la courbe Fi(i) est local et on veut la remplacer par une globale { delete Fi(i); Fi(i)=FFi(i);nom_courbei(i)="e_externe_e"; } else // cas où la courbe Fi(i) est global et on veut la remplacer par une globale { Fi(i)=FFi(i);nom_courbei(i)="e_externe_e";}; }; }; }; }; // Lecture des donnees de la classe sur fichier // le nom passé en paramètre est le nom de la courbe // s'il est vide c-a-d = "", la methode commence par lire le nom sinon // ce nom remplace le nom actuel void F_union_1D::LectDonnParticulieres_courbes(const string& nom,UtilLecture * entreePrinc) { // entête de la courbe if (nom == "") { *(entreePrinc->entree) >> nom_ref;} else {nom_ref=nom;}; // lecture de la courbe interne entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne // on lit les courbes et les intervalles à suivre jusqu'au mot de fin de courbe list < Courbe1D* > li_Fi; // un liste intermédiaire pour faciliter la lecture list li_Xi; list li_nom_courbei; // on commence par lire éventuellement la borne inférieure du domaine de définition string toto; double xmin=-ConstMath::tresgrand; // par défaut if(strstr(entreePrinc->tablcar,"Xmin=")!=0) { *(entreePrinc->entree) >> toto >> xmin; if (toto != "Xmin=") { cout << "\n erreur en lecture de la borne inferieure " << " on attendait la chaine: Xmin= et on a lue: " << toto; entreePrinc->MessageBuffer("**erreur F_union_1D::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; li_Xi.push_back(xmin); // enregistrement // maintenant lecture courante string nom_indicateur; do { // tout d'abord lecture de la courbe string toto,nom_lu,nom_courbe; Courbe1D* F=NULL; *(entreePrinc->entree) >> nom_indicateur >> nom_lu; // vérif if (nom_indicateur != "courbe=" ) { cout << "\n erreur en lecture du nom de courbe " << " on attendait la chaine: courbe= et on a lue: " << nom_indicateur; entreePrinc->MessageBuffer("**erreur F_union_1D::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on regarde si la courbe1 existe, si oui on récupère la référence if (Type_EnumCourbe1D_existe(nom_lu)) // cas ou c'est un nom de type de courbe -> lecture directe { nom_courbe = "_"; // on signale que c'est une courbe interne F = Courbe1D::New_Courbe1D(nom_courbe,Id_Nom_Courbe1D (nom_lu.c_str())); // lecture de la courbe F->LectDonnParticulieres_courbes (nom_courbe,entreePrinc); nom_courbe="i_interne_i"; entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne } else // sinon on retiend le nom pour une complétion future {nom_courbe = nom_lu;}; // stockage li_Fi.push_back(F); li_nom_courbei.push_back(nom_courbe); // lecture maintenant de la fin de l'intervalle double xmax=ConstMath::tresgrand; // par défaut bool fin_lecture=false; if (strstr(entreePrinc->tablcar,"Xmax=")!=0) {*(entreePrinc->entree) >> nom_indicateur >> xmax; // vérif if (nom_indicateur != "Xmax=" ) { cout << "\n erreur en lecture de la borne maxi de l'intervalle " << " on attendait la chaine: Xmax= et on a lue: " << nom_indicateur; entreePrinc->MessageBuffer("**erreur F_union_1D::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); } } else // sinon ça doit-être la dernière lecture {fin_lecture = true;}; li_Xi.push_back(xmax); // enregistrement // on passe une ligne si on n'est pas déjà à la fin et on vérifie que ce n'est pas finie if (strstr(entreePrinc->tablcar,"fin_courbe_union")==0) entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne // on regarde s'il n'y a pas un niveau d'affichage particulier if (strstr(entreePrinc->tablcar,"permet_affichage_")!=0) { int val_defaut = 0;int min=10;int max=0; // min > max -> pas pris en compte string nom_class_methode("F_union_1D::LectureDonneesParticulieres"); string mot_cle("permet_affichage_"); if (entreePrinc->Lecture_un_parametre_int(val_defaut,nom_class_methode ,min,max,mot_cle,permet_affichage)) entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne }; if (fin_lecture && (strstr(entreePrinc->tablcar,"fin_courbe_union")==0)) { cout << "\n erreur en lecture de la borne maxi de l'intervalle " << " le mot cle Xmax= est obligatoire sauf pour la derniere fonction "; entreePrinc->MessageBuffer("**erreur F_union_1D::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } while (strstr(entreePrinc->tablcar,"fin_courbe_union")==0); // on met en tableau int tai = li_Fi.size(); Fi.Change_taille(tai); Xi.Change_taille(tai+1); nom_courbei.Change_taille(tai); list < Courbe1D* >::iterator ili,ilifin= li_Fi.end(); list ::iterator xli= li_Xi.begin(); Xi(1)=*xli;xli++; //la borne inférieure list ::iterator sli= li_nom_courbei.begin(); int ia=1; for (ili=li_Fi.begin();ili!=ilifin;ili++,xli++,sli++,ia++) {Fi(ia)=*ili;Xi(ia+1)=*xli;nom_courbei(ia)=*sli;} }; // 1) renseigne si la courbe dépend d'autre courbe ou non bool F_union_1D::DependAutreCourbes() const { bool ret=false; int tai = Fi.Taille(); for (int i=1;i<=tai;i++) if(Fi(i) == NULL) {ret=true;} else if (nom_courbei(i)!="i_interne_i") {ret=true;}; return ret; }; // 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this list & F_union_1D::ListDependanceCourbes(list & lico) const { // tout d'abord on vide la liste passée en paramètres if (lico.size() != 0) lico.erase(lico.begin(),lico.end()); // on remplit en fonction de l'état int tai = Fi.Taille(); for (int i=1;i<=tai;i++) if(Fi(i) == NULL) lico.push_back(nom_courbei(i)); return lico; }; // 3) établit la connection entre la demande de *this et les courbes passées en paramètres void F_union_1D::Lien_entre_courbe (list & liptco) { int tai = Fi.Taille(); Tableau tab_Fi(tai); // def à null par défaut for (int i=1;i<=tai;i++) if(Fi(i) == NULL) {list ::iterator ili,ilifin=liptco.end(); for (ili=liptco.begin();ili!=ilifin;ili++) if ((*ili)->NomCourbe() == nom_courbei(i)) {tab_Fi(i)=(*ili);break;}; } else // sinon la courbe existe déjà, on met le pointeur à Null tab_Fi(i)=NULL; // et on définit les courbes this->DefCourbesMembres(tab_Fi); }; // def info fichier de commande void F_union_1D::Info_commande_Courbes1D(UtilLecture & entreePrinc) { ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier sort << "\n#............................................" << "\n# il s'agit d'une fonction qui agglomere plusieurs fonctions deja existantes" << "\n# chaque fonction est defini sur un intervalle disjoint des autres " << "\n# Les intervalles doivent se suivre " << "\n# Xmin= precise la borne inferieur de definition de la fonction" << "\n# c'est un parametre facultatif, s'il manque, la borne inf est - l'infini" << "\n# ensuite il y a une liste de courbes: " << "\n# suivi chacune de la fin de l'intervalle correspondant" << "\n# ici cf1 est pour x appartenant a [-10,0[, cf2 est pour x appartenant a [0,10[" << "\n# cf3 est pour x appartenant a [10,20[" << "\n courbe_exemple F_UNION_1D " << "\n# Xmin= -10 courbe= cf1 Xmax= 0" << "\n# courbe= cf2 Xmax= 10" << "\n# courbe= cf3 Xmax= 20" << "\n# fin_courbe_union" << "\n# " << "\n# pour la dernier courbe il est possible de ne pas faire figurer Xmax=, dans" << "\n# ce cas, cela signifie que la borne finale est l'infini" << "\n# enfin, si la valeur de x est en dehors de l'intervalle, on applique la premiere" << "\n (xXmax) " << endl; }; // ramène la valeur double F_union_1D::Valeur(double x) { // on commence par chercher l'intervalle qui contient x //tout d'abord on regarde s'il est en dehors des bornes // si oui on lui donne if (x < Xi(1)) {indice_precedant=1; return Fi(1)->Valeur(x); }; int tai = Fi.Taille(); int taiPlusUn = tai + 1; if (x > Xi(taiPlusUn)) {indice_precedant=1; // comme c'est le dernier intervalle on met à 1 car // de toute manière cela ne sert à rien de continuer return Fi(tai)->Valeur(x); }; // maintenant on cherche le couple de xi qui encadre le x int indice=0;bool trouve=false; // on commence tout d'abord à chercher à partir du précédent indice // s'il est supérieur au xi de l'indice existant, l'algo qui suit est ok if (x >= Xi(indice_precedant)) {for (int indic=indice_precedant;indic < taiPlusUn;indic++) if (x < Xi(indic+1)) {trouve=true;indice=indic; break;}; } else // sinon il est inférieur {for (int indic = 1; indic Type_courbe()) << " : nom_ref= " << nom_ref; Sortie(1); }; // calcul du y indice_precedant = indice; return Fi(indice)->Valeur(x); }; // ramène la valeur et la dérivée en paramètre Courbe1D::ValDer F_union_1D::Valeur_Et_derivee(double x) { // on commence par chercher l'intervalle qui contient x //tout d'abord on regarde s'il est en dehors des bornes // si oui on lui donne if (x < Xi(1)) {indice_precedant=1; return Fi(1)->Valeur_Et_derivee(x); }; int tai = Fi.Taille(); if (x > Xi(tai+1)) {indice_precedant=1; // comme c'est le dernier intervalle on met à 1 car // de toute manière cela ne sert à rien de continuer return Fi(tai)->Valeur_Et_derivee(x); }; // maintenant on cherche le couple de xi qui encadre le x int indice=0;bool trouve=false; // on commence tout d'abord à chercher à partir du précédent indice // s'il est supérieur au xi de l'indice existant, l'algo qui suit est ok if (x >= Xi(indice_precedant)) for (int indic=indice_precedant;indic<=tai;indic++) if (x < Xi(indic+1)) {trouve=true;indice=indic; break;}; // sinon cela veut dire qu'il se trouve dans les xi plus bas que l'indice // on repart à partir de 0 !! ***** a optimiser par dichotomie ***** if (!trouve) { // cas où on n'a pas trouver après l'indice for (int indic = 1; indic Type_courbe()) << " : nom_ref= " << nom_ref; Sortie(1); }; // calcul du retour indice_precedant = indice; return Fi(indice)->Valeur_Et_derivee(x); }; // ramène la dérivée double F_union_1D::Derivee(double x) { // on commence par chercher l'intervalle qui contient x //tout d'abord on regarde s'il est en dehors des bornes // si oui on lui donne if (x < Xi(1)) {indice_precedant=1; return Fi(1)->Derivee(x); }; int tai = Fi.Taille(); if (x > Xi(tai+1)) {indice_precedant=1; // comme c'est le dernier intervalle on met à 1 car // de toute manière cela ne sert à rien de continuer return Fi(tai)->Derivee(x); }; // maintenant on cherche le couple de xi qui encadre le x int indice=0;bool trouve=false; // on commence tout d'abord à chercher à partir du précédent indice // s'il est supérieur au xi de l'indice existant, l'algo qui suit est ok if (x >= Xi(indice_precedant)) for (int indic=indice_precedant;indic<=tai;indic++) if (x < Xi(indic+1)) {trouve=true;indice=indic; break;}; // sinon cela veut dire qu'il se trouve dans les xi plus bas que l'indice // on repart à partir de 0 !! ***** a optimiser par dichotomie ***** if (!trouve) { // cas où on n'a pas trouver après l'indice for (int indic = 1; indic Type_courbe()) << " : nom_ref= " << nom_ref; Sortie(1); }; // calcul du retour indice_precedant = indice; return Fi(indice)->Derivee(x); }; // ramène la valeur et les dérivées première et seconde en paramètre Courbe1D::ValDer2 F_union_1D::Valeur_Et_der12(double x) { // on commence par chercher l'intervalle qui contient x //tout d'abord on regarde s'il est en dehors des bornes // si oui on lui donne if (x < Xi(1)) {indice_precedant=1; return Fi(1)->Valeur_Et_der12(x); }; int tai = Fi.Taille(); if (x > Xi(tai+1)) {indice_precedant=1; // comme c'est le dernier intervalle on met à 1 car // de toute manière cela ne sert à rien de continuer return Fi(tai)->Valeur_Et_der12(x); }; // maintenant on cherche le couple de xi qui encadre le x int indice=0;bool trouve=false; // on commence tout d'abord à chercher à partir du précédent indice // s'il est supérieur au xi de l'indice existant, l'algo qui suit est ok if (x >= Xi(indice_precedant)) for (int indic=indice_precedant;indic<=tai;indic++) if (x < Xi(indic+1)) {trouve=true;indice=indic; break;}; // sinon cela veut dire qu'il se trouve dans les xi plus bas que l'indice // on repart à partir de 0 !! ***** a optimiser par dichotomie ***** if (!trouve) { // cas où on n'a pas trouver après l'indice for (int indic = 1; indic Type_courbe()) << " : nom_ref= " << nom_ref; Sortie(1); }; // calcul du retour indice_precedant = indice; return Fi(indice)->Valeur_Et_der12(x); }; // ramène la dérivée seconde double F_union_1D::Der_sec(double x) { // on commence par chercher l'intervalle qui contient x //tout d'abord on regarde s'il est en dehors des bornes // si oui on lui donne if (x < Xi(1)) {indice_precedant=1; return Fi(1)->Der_sec(x); }; int tai = Fi.Taille(); if (x > Xi(tai+1)) {indice_precedant=1; // comme c'est le dernier intervalle on met à 1 car // de toute manière cela ne sert à rien de continuer return Fi(tai)->Der_sec(x); }; // maintenant on cherche le couple de xi qui encadre le x int indice=0;bool trouve=false; // on commence tout d'abord à chercher à partir du précédent indice // s'il est supérieur au xi de l'indice existant, l'algo qui suit est ok if (x >= Xi(indice_precedant)) for (int indic=indice_precedant;indic<=tai;indic++) if (x < Xi(indic+1)) {trouve=true;indice=indic; break;}; // sinon cela veut dire qu'il se trouve dans les xi plus bas que l'indice // on repart à partir de 0 !! ***** a optimiser par dichotomie ***** if (!trouve) { // cas où on n'a pas trouver après l'indice for (int indic = 1; indic Type_courbe()) << " : nom_ref= " << nom_ref; Sortie(1); }; // calcul du retour indice_precedant = indice; return Fi(indice)->Der_sec(x); }; // ramène la valeur si dans le domaine strictement de définition // si c'est inférieur au x mini, ramène la valeur minimale possible de y // si supérieur au x maxi , ramène le valeur maximale possible de y Courbe1D::Valbool F_union_1D::Valeur_stricte(double x) { // on commence par chercher l'intervalle qui contient x //tout d'abord on regarde s'il est en dehors des bornes // si oui on lui donne if (x < Xi(1)) {indice_precedant=1; Valbool ret = Fi(1)->Valeur_stricte(x); ret.dedans = false; return ret; }; int tai = Fi.Taille(); if (x > Xi(tai+1)) {indice_precedant=1; // comme c'est le dernier intervalle on met à 1 car // de toute manière cela ne sert à rien de continuer Valbool ret = Fi(tai)->Valeur_stricte(x); ret.dedans = false; return ret; }; // maintenant on cherche le couple de xi qui encadre le x int indice=0;bool trouve=false; // on commence tout d'abord à chercher à partir du précédent indice // s'il est supérieur au xi de l'indice existant, l'algo qui suit est ok if (x >= Xi(indice_precedant)) for (int indic=indice_precedant;indic<=tai;indic++) if (x < Xi(indic+1)) {trouve=true;indice=indic; break;}; // sinon cela veut dire qu'il se trouve dans les xi plus bas que l'indice // on repart à partir de 0 !! ***** a optimiser par dichotomie ***** if (!trouve) { // cas où on n'a pas trouver après l'indice for (int indic = 1; indic Type_courbe()) << " : nom_ref= " << nom_ref; Sortie(1); }; // calcul du retour indice_precedant = indice; Valbool ret = Fi(indice)->Valeur_stricte(x); ret.dedans = true; return ret; }; // ramène la valeur et la dérivée si dans le domaine strictement de définition // si c'est inférieur au x mini, ramène la valeur minimale possible de y et Y' correspondant // si supérieur au x maxi , ramène le valeur maximale possible de y et Y' correspondant Courbe1D::ValDerbool F_union_1D::Valeur_Et_derivee_stricte(double x) { // on commence par chercher l'intervalle qui contient x //tout d'abord on regarde s'il est en dehors des bornes // si oui on lui donne if (x < Xi(1)) {indice_precedant=1; ValDerbool ret = Fi(1)->Valeur_Et_derivee_stricte(x); ret.dedans = false; return ret; }; int tai = Fi.Taille(); if (x > Xi(tai+1)) {indice_precedant=1; // comme c'est le dernier intervalle on met à 1 car // de toute manière cela ne sert à rien de continuer ValDerbool ret = Fi(tai)->Valeur_Et_derivee_stricte(x); ret.dedans = false; return ret; }; // maintenant on cherche le couple de xi qui encadre le x int indice=0;bool trouve=false; // on commence tout d'abord à chercher à partir du précédent indice // s'il est supérieur au xi de l'indice existant, l'algo qui suit est ok if (x >= Xi(indice_precedant)) for (int indic=indice_precedant;indic<=tai;indic++) if (x < Xi(indic+1)) {trouve=true;indice=indic; break;}; // sinon cela veut dire qu'il se trouve dans les xi plus bas que l'indice // on repart à partir de 0 !! ***** a optimiser par dichotomie ***** if (!trouve) { // cas où on n'a pas trouver après l'indice for (int indic = 1; indic Type_courbe()) << " : nom_ref= " << nom_ref; Sortie(1); }; // calcul du retour indice_precedant = indice; ValDerbool ret = Fi(indice)->Valeur_Et_derivee_stricte(x); ret.dedans = true; return 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 F_union_1D::Lecture_base_info(ifstream& ent,const int cas) { // on n'a que des grandeurs constantes if (cas == 1) { string nom; ent >> nom; // "\n " // string nom1=nom.substr(nom.find(<)+1,nom.find(>)-1); // lecture et vérification de l'entête string type_courbe_a_lire('<'+Nom_Courbe1D(this->Type_courbe())+'>'); if (nom != type_courbe_a_lire) //"F_union_1D") { cout << "\n erreur dans la verification du type de courbe lue "; cout << "\n courbe en lecture: " << type_courbe_a_lire; cout << "\n F_union_1D::Lecture_base_info(... "; Sortie(1); } // lecture du nombre de courbe int tai=0; ent >> nom >> tai; Fi.Change_taille(tai); Xi.Change_taille(tai+1); nom_courbei.Change_taille(tai); // lecture de la borne inf ent >> nom >> Xi(1); // lecture des courbes et des bornes string nom1,nom2,nom3; for (int i=1;i<=tai;i++) { // lecture de la courbe ent >> nom1 >> nom2 >> nom3; if (nom1 != "courbe=") { cout << "\n erreur dans la verification du type, on attendait le mot cle courbe= " << " et on a lu " << nom1 << " "; cout << "\n F1_rond_F2::Lecture_base_info(... "; Sortie(1); } else { if (nom2 == "COURBE_INTERNE") {// cas d'une courbe en interne // 1) on commence par effacer la courbe existante si nécessaire if (Fi(i) != NULL) {if (Fi(i)->NomCourbe() == "_") delete Fi(i);}; // 2) on crée la courbe adoc nom2="_"; Fi(i) = Courbe1D::New_Courbe1D(nom2,Id_Nom_Courbe1D (nom3.c_str())); // 3) on lit les données particulières Fi(i)->Lecture_base_info(ent,cas); nom_courbei(i)="i_interne_i"; } else {// cas d'une courbe externe on lit le nom nom_courbei(i) = nom2; }; }; // lecture de la borne max pour la fonction i ent >> nom1 >> Xi(i+1); }; // lecture du niveau d'affichage ent >> nom >> permet_affichage; // on lit le tag de fin de définition ent >> nom; // } }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void F_union_1D::Ecriture_base_info(ofstream& sort,const int cas) { // on n'a que des grandeurs constantes if (cas == 1) { sort << "\n "; int tai = Fi.Taille(); sort << " nbcourbe= " << tai << " "; // le nombre de courbes // la borne mini sort << " Xmin= " << Xi(1)<< " "; // on balaie les courbes for (int i=1;i<=tai;i++) {if (Fi(i)->NomCourbe() == "_") {// cas d'une courbe interne sort << "\n courbe= COURBE_INTERNE " << Fi(i)->Type_courbe(); Fi(i)->Ecriture_base_info(sort,cas); } else // cas d'une courbe externe {sort << "\n courbe= " << Fi(i)->NomCourbe() << " " << Fi(i)->Type_courbe();}; // la borne max pour la fonction i sort << " Xmax= " << Xi(i+1) << " "; }; sort << "\n permet_affichage: " << permet_affichage; sort << "\n "; } }; // sortie du schemaXML: en fonction de enu void F_union_1D::SchemaXML_Courbes1D(ofstream& ,const Enum_IO_XML enu) { switch (enu) { case XML_TYPE_GLOBAUX : {/*sort << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n" << "\n " << "\n courbe F_UNION_1D constituee de N points " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n " << "\n";*/ break; } case XML_IO_POINT_INFO : { break; } case XML_IO_POINT_BI : { break; } case XML_IO_ELEMENT_FINI : { break; } }; };