// 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_nD_courbe1D.h" #include "Sortie.h" #include "ConstMath.h" #include "MathUtil.h" #include "CharUtil.h" #include "MotCle.h" #include "TypeQuelconqueParticulier.h" // CONSTRUCTEURS : F_nD_courbe1D::F_nD_courbe1D(string nom) : Fonction_nD(nom,FONCTION_COURBE1D) ,c_Fi(NULL),nom_courbe1(""),tab_ret(1) {}; // de copie F_nD_courbe1D::F_nD_courbe1D(const F_nD_courbe1D& Co) : Fonction_nD(Co) ,c_Fi(Co.c_Fi),nom_courbe1(Co.nom_courbe1),tab_ret(1) { // création de la courbe locale que si elle est déjà locale if (Co.c_Fi->NomCourbe() == "_") c_Fi=Courbe1D::New_Courbe1D(*(Co.c_Fi)); }; // de copie à partir d'une instance générale F_nD_courbe1D::F_nD_courbe1D(const Fonction_nD& Coo) : Fonction_nD(Coo),tab_ret(1) { if (Coo.Type_Fonction() != FONCTION_COURBE1D) { cout << "\n erreur dans le constructeur de copie pour une F_nD_courbe1D " << " a partir d'une instance generale "; cout << "\n F_nD_courbe1D::F_nD_courbe1D(const Fonction_nD& Co) "; Sortie(1); }; // définition des données F_nD_courbe1D & Co = (F_nD_courbe1D&) Coo; nom_courbe1 = Co.nom_courbe1; c_Fi = Co.c_Fi; // création de la courbe locale que si elle est déjà locale if (Co.c_Fi->NomCourbe() == "_") c_Fi=Courbe1D::New_Courbe1D(*(Co.c_Fi)); }; // DESTRUCTEUR : F_nD_courbe1D::~F_nD_courbe1D() { // on efface la courbe que si c'est une courbe locale if ((c_Fi != NULL)&&(nom_courbe1=="i_interne_i")) delete c_Fi; }; // METHODES PUBLIQUES : // --------- virtuelles --------- // Surcharge de l'operateur = : realise l'egalite de deux fonctions Fonction_nD& F_nD_courbe1D::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 F_nD_courbe1D::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 F_nD_courbe1D & Co = ((F_nD_courbe1D &) elt); nom_courbe1 = Co.nom_courbe1; c_Fi = Co.c_Fi; // création de la courbe locale que si elle est déjà locale if (Co.c_Fi->NomCourbe() == "_") c_Fi=Courbe1D::New_Courbe1D(*(Co.c_Fi)); tab_ret = Co.tab_ret; return *this; }; // affichage de la courbe void F_nD_courbe1D::Affiche(int niveau) const { cout << "\n fonction composee a partir d'une courbe 1D: F_nD_courbe1D : nom_ref= " << nom_ref; // si c'est une courbe interne on l'affiche globalement // si c'est une courbe globale, on n'affiche que son nom cout << ", courbe de base: " ; if (c_Fi->NomCourbe() == "_") {c_Fi->Affiche();} else {cout << c_Fi->NomCourbe() << " ";}; // affichage de la variable cout << "\n argument= " ; if (nom_variables.Taille() == 1) cout << nom_variables(1) << " "; else if (enu_variables_globale.Taille() == 1) cout << Nom_GrandeurGlobale(enu_variables_globale(1)) << " "; else if (nom_variables_globales.Taille() == 1) cout << nom_variables_globales(1) << " "; else cout << " pas_de_variable_declare!! "; // appel de la méthode associée de la classe virtuelle Affiche_interne(niveau); if (niveau > 0) { cout << "\n dernieres valeurs de retour de la fonction: "; cout << tab_ret ; }; cout << "\n ----- fin fonction F_nD_courbe1D ----- "; }; // vérification que tout est ok, pres à l'emploi // ramène true si ok, false sinon bool F_nD_courbe1D::Complet_Fonction(bool affichage)const { bool ret = false; // il faut au moins que la courbe existe if (c_Fi == NULL) {if (affichage && (ParaGlob::NiveauImpression() >0)) { cout << "\n ***** la fonction n'est pas complete (aucune courbe de base n'existe) "; this->Affiche(); } } else // on regarde du coté de la classe mère tout d'abord { ret = Complet_var(); // puis la courbe interne ret = ret && c_Fi->Complet_courbe(); if (!ret && (ParaGlob::NiveauImpression() >0) && affichage ) { cout << "\n ***** la fonction n'est pas complete "; this->Affiche(); }; }; // retour return ret; }; // 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_nD_courbe1D::LectDonnParticulieres_Fonction_nD(const string& nom,UtilLecture * entreePrinc) { // entête de la fonction if (nom == "") { *(entreePrinc->entree) >> nom_ref;} else {nom_ref=nom;}; // lecture de la courbe interne entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne // on lit tant que l'on ne rencontre pas la ligne contenant "fin_fonction_courbe1D_" // ou un nouveau mot clé global auquel cas il y a pb !! MotCle motCle; // ref aux mots cle string titi; bool lecture_variable_ok = false; // pour gérer une erreur éventuelle while (strstr(entreePrinc->tablcar,"fin_fonction_courbe1D_")==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 F_nD_courbe1D : on n'a pas trouve le mot cle " << " fin_fonction_courbe1D_ et par contre la ligne courante contient un mot cle global "; entreePrinc->MessageBuffer("** erreur des parametres d'une F_nD_courbe1D **"); 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_fonction_courbe1D_") // 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 fonction: "<< nom_ref; entreePrinc->MessageBuffer("** erreur2 des parametres d'une F_nD_courbe1D **"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on traite en fonction du mot clé if (titi == "courbe=") { string nom_lu; *(entreePrinc->entree) >> nom_lu; // on regarde si la courbe 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_courbe1 = "_"; // on signale que c'est une courbe interne c_Fi = Courbe1D::New_Courbe1D(nom_courbe1,Id_Nom_Courbe1D (nom_lu.c_str())); // lecture de la courbe c_Fi->LectDonnParticulieres_courbes (nom_courbe1,entreePrinc); nom_courbe1="i_interne_i"; } else // sinon on retiend le nom pour une complétion future {nom_courbe1 = nom_lu;}; } // cas de la lecture d'une variable else if(titi == "un_argument=") {if (lecture_variable_ok) // on n'a le droit qu'à 1 argument { cout << "\n erreur en lecture l'argument est deja defini !! c'est "; if (nom_variables.Taille() == 1) cout <MessageBuffer("**erreur1 F_nD_courbe1D::LectureDonneesParticulieres**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; string truc; *(entreePrinc->entree) >> truc; // on regarde s'il s'agit d'une variable globale if (EstUneGrandeurGlobale(truc)) {enu_variables_globale.Change_taille(1); enu_variables_globale(1) = (Id_nom_GrandeurGlobale (truc)); nom_variables.Change_taille(0); } // idem mais sous forme d'un string else if (ParaGlob::param->GrandeurGlobal(truc) != NULL) {nom_variables_globales.Change_taille(1); nom_variables_globales(1) = truc; nom_variables.Change_taille(0); } else // sinon ce n'est pas une grandeur globale {nom_variables.Change_taille(1); nom_variables(1)=truc; enu_variables_globale.Change_taille(0); nom_variables_globales.Change_taille(0); }; lecture_variable_ok = true; } // cas de la lecture du niveau d'impression pour les erreurs else if(titi == "permet_affichage_") {*(entreePrinc->entree) >> permet_affichage; } else // sinon la lecture est ok a priori ; }; //-- fin du while // 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(); }; // mise à jour des variables globales: en fonction de l'apparition de nouvelles variables // globales en cours de calcul void F_nD_courbe1D::Mise_a_jour_variables_globales() { // appel de la fonction interne pour modifier les noms de variables Fonction_nD::Mise_a_jour_variables_globales_interne(); // comme ici il n'y a qu'une variable possible, normalement l'appel de fonction ne change pas // donc c'est ok }; // 1) renseigne si la courbe dépend d'autre courbe ou non bool F_nD_courbe1D::DependAutreFoncCourbes() const { bool ret=false; if(c_Fi == NULL) {ret=true;} else if (nom_courbe1 != "i_interne_i") {ret=true;}; return ret; }; // 2) retourne une liste de nom correspondant aux noms de courbes dont dépend *this list & F_nD_courbe1D::ListDependanceCourbes(list & lico) const { // tout d'abord on vide la liste passée en paramètres if (lico.size() != 0) lico.clear(); // on remplit en fonction de l'état if(c_Fi == NULL) lico.push_back(nom_courbe1); return lico; }; // 4) établit la connection entre la demande de *this et les courbes et fonctions passées en paramètres void F_nD_courbe1D::Lien_entre_fonc_courbe (list & ,list & liptco) { Courbe1D* cc_Fi=NULL; list ::iterator ili,ilifin=liptco.end(); if (c_Fi==NULL) { // on cherche la courbe correspondante // for (Courbe1D * ic : liptco) // if (ic->NomCourbe() == nom_courbe1) {cc_Fi=ic;break;}; {list ::iterator kk,kkfin=liptco.end(); for (kk=liptco.begin();kk != kkfin; kk++) if ((*kk)->NomCourbe() == nom_courbe1) {cc_Fi=(*kk);break;}; }; }; // et on définit les courbes this->DefFoncCourbeMembre(cc_Fi); }; // def info fichier de commande void F_nD_courbe1D::Info_commande_Fonctions_nD(UtilLecture & entreePrinc) { ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier sort << "\n#............................................" << "\n# il s'agit d'une fonction qui utilise une courbe 1D " << "\n# cette derniere peut soit deja exister, soit etre definie a la suite " << "\n# exemple 1: cas d'une courbe qui existe deja sous le nom: cf1" << "\n fct1_exemple FONCTION_COURBE1D " << "\n courbe= cf1 " << "\n un_argument= x " << "\n fin_fonction_courbe1D_" << "\n# " << "\n# exemple 2: cas d'une courbe qui est definit a la suite" << "\n fct2_exemple FONCTION_COURBE1D " << "\n un_argument= x " << "\n courbe= COURBE_EXPRESSION_LITTERALE_1D " << "\n a= 0. b= 1. f(x)= (x^2+3.)/cos(x)+log((1.+x)/(1.+x^3))*23.-8. " << "\n fin_parametres_courbe_expression_litterale_ " << "\n fin_fonction_courbe1D_" << "\n# " << "\n# NB: 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 fonction 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_fonction_courbe1D_ " << "\n# " << endl; }; // calcul des valeurs de la fonction, retour d'un tableau de scalaires Tableau & F_nD_courbe1D::Valeur_FnD_interne(Tableau * xi) { try {// comme il s'agit d'une courbe 1D, on n'utilise que le premier élément des tableaux // deux cas selon que l'on utilise une variable globale ou locale if (nom_variables.Taille() == 1) // pas de variable globale {if(xi!=NULL) {tab_ret(1) = c_Fi->Valeur((*xi)(1));} // else if (tab_coor != NULL) // sinon il ne reste plus que tab_coor // {tab_ret(1) = c_Fi->Valeur((*tab_coor)(1)(1));} else // sinon c'est une erreur { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " << " pas de variable en entree !! " << ", n'est pas disponible, on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); Sortie(1); }; } else if (enu_variables_globale.Taille() == 1) // il s'agit d'une variable globale enumere { // on récupère les grandeurs globales Fonction_nD::Recup_Grandeurs_globales(); // on affecte les grandeurs tab_ret(1) = c_Fi->Valeur(x_glob(1)); /* // en debug on vérifie que les grandeurs globales sont présentent #ifdef MISE_AU_POINT try { // on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1))); if (pointe == NULL) { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(1)) << ", n'est pas disponible, on ne peut pas continuer " << "\n F_nD_courbe1D::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 de la grandeur globale voulue " << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif // arrivée ici toutes la grandeur existe double x=0.; // on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1))); 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 x = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier x = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier x = (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(1)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::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(1)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; tab_ret(1) = c_Fi->Valeur(x); */ } else // il s'agit d'une variable globale en string { // en debug on vérifie que les grandeurs globales sont présentent #ifdef MISE_AU_POINT try { // on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1))); if (pointe == NULL) { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< nom_variables_globales(1) << ", n'est pas disponible, on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } 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 dans l'appel de la fonction "<< nom_ref; cout << " verifier la presence de la grandeur globale voulue " << "\n F_nD_courbe1D::Valeur_FnD_interne(..."<Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif // arrivée ici toutes la grandeur existe double x=0.; // on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1))); 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 x = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier x = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier x = (gr.GrandeurNumOrdre(1)); break; } case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier x = (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(1) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n F_nD_courbe1D::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(1) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::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(1) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_FnD_interne(..." <Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; tab_ret(1) = c_Fi->Valeur(x); }; } 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 dans l'appel de la fonction "<< nom_ref; this->Affiche(); cout << "\n F_nD_courbe1D::Valeur_FnD_interne(..."; // on génère une interruption ce qui permettra de dépiler les appels this->Affiche();ErrCalculFct_nD toto;throw (toto); Sortie(1); }; // retour return tab_ret; }; //// calcul équivalent, mais pour des paramètres de type ddl enum étendu et/ou type quelconque //// pour que l'appel à cette méthode soit correcte, il faut que la dimension de t_enu + celle de tqi //// soit identique à celle du tableau Nom_variables() : en fait t_enu et tqi doivent représenter les variables //Tableau & F_nD_courbe1D::Valeur_FnD(Tableau * t_enu,Tableau * tqi) // { // comme il s'agit d'une courbe 1D, on n'utilise que le premier élément des tableaux // // deux cas selon que l'on utilise une variable globale ou locale // if (nom_variables.Taille() == 1) // pas de variable globale // {if(t_enu!=NULL) // { // #ifdef MISE_AU_POINT // if ((*t_enu)(1).DdlEnumEtendu() != tab_enu_etendu(1)) // { cout << "\n *** pb dans F_nD_courbe1D au niveau des parametres d'appel " // << " on demande un calcul pour le ddl "<< (*t_enu)(1).DdlEnumEtendu().Nom_plein() // << " ce qui est different du ddl prevu: "<Valeur((*t_enu)(1).Valeur()); // } // else if (tqi != NULL) // sinon il ne reste plus que tab_coor // { // #ifdef MISE_AU_POINT // if ((*tqi)(1).EnuTypeQuelconque() != tab_enu_quelconque(1)) // { cout << "\n *** pb dans F_nD_courbe1D au niveau des parametres d'appel " // << " on demande un calcul pour la grandeur quelconque " // << (*tqi)(1).EnuTypeQuelconque().NomPlein() // << " ce qui est different du type prevu: " // << NomTypeQuelconque(tab_enu_quelconque(1)) // << " ce n'est pas normal !! " // << ", il vaut mieux stopper le calcul " // << "\n F_nD_courbe1D::Valeur_FnD(..."<Valeur((*tqi)(1).GrandeurNumOrdre(1)); // } // else // sinon c'est une erreur // { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " // << " pas de variable en entree !! " // << ", n'est pas disponible, on ne peut pas continuer " // << "\n F_nD_courbe1D::Valeur_FnD(..."<GrandeurGlobal(enu_variables_globale(1))); // if (pointe == NULL) // { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " // << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(1)) // << ", n'est pas disponible, on ne peut pas continuer " // << "\n F_nD_courbe1D::Valeur_FnD(..."<GrandeurGlobal(enu_variables_globale(1))); // 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 // x = *(gr.ConteneurEntier()); // break; // } // case PARTICULIER_SCALAIRE_DOUBLE: // {Grandeur_scalaire_double& gr // = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier // x = *(gr.ConteneurDouble()); // break; // } // default: // { cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref // << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(1)) // << ", n'est pas prise en compte actuellement , on ne peut pas continuer " // << "\n F_nD_courbe1D::Valeur_FnD(..." // <Valeur(x); // } // else // il s'agit d'une variable globale en string // { // en debug on vérifie que les grandeurs globales sont présentent // #ifdef MISE_AU_POINT // try // { // on récupère le pointeur correspondant à la grandeur // const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1))); // if (pointe == NULL) // { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " // << " la variable globale "<< nom_variables_globales(1) // << ", n'est pas disponible, on ne peut pas continuer " // << "\n F_nD_courbe1D::Valeur_FnD(..."<GrandeurGlobal(nom_variables_globales(1))); // 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 // x = *(gr.ConteneurEntier()); // break; // } // case PARTICULIER_SCALAIRE_DOUBLE: // {Grandeur_scalaire_double& gr // = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier // x = *(gr.ConteneurDouble()); // break; // } // case PARTICULIER_DDL_ETENDU: // {Grandeur_Ddl_etendu& gr // = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier // x = (gr.GrandeurNumOrdre(1)); // break; // } // case PARTICULIER_VECTEUR_NOMMER: // {Grandeur_Vecteur_Nommer& gr // = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier // x = (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(1) // << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " // << " compte pour l'intant, on ne peut pas continuer " // << "\n F_nD_courbe1D::Valeur_FnD(..." // <Valeur(x); // }; // // retour // 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 & F_nD_courbe1D::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 F_nD_courbe1D::Valeur_pour_variables_globales(..."<Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; // on récupère le pointeur correspondant à la grandeur if (enu_variables_globale.Taille()) {const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1))); if (pointe == NULL) { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(1)) << ", n'est pas disponible, on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_pour_variables_globales(..."<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 F_nD_courbe1D::Valeur_pour_variables_globales(..."<Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif // idem pour les grandeurs indicées avec des string #ifdef MISE_AU_POINT try { // on récupère le pointeur correspondant à la grandeur if (nom_variables_globales.Taille()) {const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1))); if (pointe == NULL) { cout << "\n *** pb dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< nom_variables_globales(1) << ", n'est pas disponible, on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_pour_variables_globales(..."<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 F_nD_courbe1D::Valeur_pour_variables_globales(..."<Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif */ // arrivée ici toutes les grandeurs existent (normalement on n'utilise que la première !!) try { /* double argument = 0.; // init par défaut if (enu_variables_globale.Taille() == 1) { // cas d'une variable énuméré // on utilise les variables globales // on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(1))); 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 argument = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier argument = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier argument = (gr.GrandeurNumOrdre(1)); break; } default: { cout << "\n *** pb dans dans l'appel de dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(1)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_pour_variables_globales(..." <Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(1)) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_pour_variables_globales(..." <Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; }; } else // sinon il s'agit d'une grandeur indicée par un string { // on récupère le pointeur correspondant à la grandeur const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(1))); 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 argument = *(gr.ConteneurEntier()); break; } case PARTICULIER_SCALAIRE_DOUBLE: {Grandeur_scalaire_double& gr = *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier argument = *(gr.ConteneurDouble()); break; } case PARTICULIER_DDL_ETENDU: {Grandeur_Ddl_etendu& gr = *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier argument = (gr.GrandeurNumOrdre(1)); break; } case PARTICULIER_VECTEUR_NOMMER: {Grandeur_Vecteur_Nommer& gr = *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier argument = (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(1) << ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en " << " compte pour l'intant, on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_pour_variables_globales(..." <Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; #endif break; } default: { cout << "\n *** pb dans dans l'appel de dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< nom_variables_globales(1) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_pour_variables_globales(..." <Affiche();ErrCalculFct_nD toto;throw (toto);Sortie(1); }; } break; } default: { cout << "\n *** pb dans dans l'appel de dans F_nD_courbe1D " << nom_ref << " !! " << " la variable globale "<< nom_variables_globales(1) << ", n'est pas prise en compte actuellement , on ne peut pas continuer " << "\n F_nD_courbe1D::Valeur_pour_variables_globales(..." <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(); // maintenant on appelle la fonction tab_ret(1) = c_Fi->Valeur(x_glob(1)); ////---- debug //cout << "\n argument= "<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 F_nD_courbe1D::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 string type_courbe_a_lire('<'+Nom_Fonction_nD(this->Type_Fonction())+'>'); if (nom != type_courbe_a_lire) //"F_nD_courbe1D") { cout << "\n erreur dans la verification du type de courbe lue "; cout << "\n courbe en lecture: " << type_courbe_a_lire; cout << "\n F_nD_courbe1D::Lecture_base_info(... "; Sortie(1); }; // lecture des infos string nom1,nom2,nom3; // pour la courbe1 ent >> nom1 >> nom2 >> nom3; if (nom1 != "courbe1=") { cout << "\n erreur dans la verification du type, on attendait le mot cle courbe1= " << " et on a lu " << nom1 << " "; cout << "\n F_nD_courbe1D::Lecture_base_info(... "; Sortie(1); } else { if (nom2 == "COURBE_1D_INTERNE1") {// cas d'une courbe en interne // 1) on commence par effacer la courbe existante si nécessaire if (c_Fi != NULL) {if (c_Fi->NomCourbe() == "_") delete c_Fi;}; // 2) on crée la courbe adoc nom2="_"; c_Fi = Courbe1D::New_Courbe1D(nom2,Id_Nom_Courbe1D (nom3.c_str())); // 3) on lit les données particulières c_Fi->Lecture_base_info(ent,cas); nom_courbe1="i_interne_i"; } else {// cas d'une courbe externe on lit le nom nom_courbe1 = nom2; }; }; // lecture de la variable int choix=0; ent >> nom >> choix; switch (choix) {case 1: nom_variables.Change_taille(1); ent >> nom_variables(1); enu_variables_globale.Change_taille(0);nom_variables_globales.Change_taille(0); break; case 2: enu_variables_globale.Change_taille(1); ent >> nom; enu_variables_globale(1) = Id_nom_GrandeurGlobale(nom); nom_variables.Change_taille(0);nom_variables_globales.Change_taille(0); break; case 3: nom_variables_globales.Change_taille(1); ent >> nom_variables(1); enu_variables_globale.Change_taille(0);nom_variables.Change_taille(0); break; default: ent >> nom; cout << "\n *** attention aucun argument lu pour la fonction nD: FONCTION_COURBE1D "; this->Affiche(); break; } // les arguments gérés par la classe mère Fonction_nD::Lect_base_info(ent,cas); // on lit le tag de fin de définition ent >> nom; // // 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(); }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void F_nD_courbe1D::Ecriture_base_info(ofstream& sort,const int cas) { // on n'a que des grandeurs constantes if (cas == 1) { sort << "\n "; if (nom_courbe1 == "i_interne_i") {// cas d'une courbe interne sort << "\n courbe1= COURBE_1D_INTERNE1 " << c_Fi->Type_courbe(); c_Fi->Ecriture_base_info(sort,cas); } else // cas d'une courbe externe {sort << "\n courbe1= " << c_Fi->NomCourbe() << " " << c_Fi->Type_courbe();;}; // affichage de la variable sort << " argument= " ; if (nom_variables.Taille() == 1) sort << " 1 " << nom_variables(1) << " "; else if (enu_variables_globale.Taille() == 1) sort << " 2 " << Nom_GrandeurGlobale(enu_variables_globale(1)) << " "; else if (nom_variables_globales.Taille() == 1) sort << " 3 " << nom_variables_globales(1) << " "; else sort << " 4 " << " pas_de_variable_declare!! "; // les arguments gérés par la classe mère Fonction_nD::Ecrit_base_info(sort,cas); sort << "\n \n "; }; }; // sortie du schemaXML: en fonction de enu void F_nD_courbe1D::SchemaXML_Fonctions_nD(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; } }; }; // METHODES PROTEGEES : // dans le cas où la courbe membre est une courbe externe // méthode pour la définir // la courbea est défini en interne que si la courbe argument est elle même // une courbe locale. c'est-à-dire si c_Fi->NomCourbe() ="_" alors on recrée une courbe // interne avec new pour c_Fi, sinon c_Fi=cc_Fi et pas de création; // dans le cas où cc_Fi est NULL on passe, pas de traitement pour ce pointeur void F_nD_courbe1D::DefFoncCourbeMembre(Courbe1D* cc_Fi) { // création d'une courbe locale que si elle était déjà locales if (cc_Fi != NULL) {if (cc_Fi->NomCourbe() == "_") // cas où cc_Fi est une courbe non globale { if (c_Fi==NULL) { // cas où la courbe locale n'est pas défini mais on veut une courbe interne c_Fi=Courbe1D::New_Courbe1D(*(cc_Fi));nom_courbe1="i_interne_i"; } else if (c_Fi->NomCourbe() == "_") // cas où la courbe c_Fi est local et on veut la remplacer par une nouvelle locale { delete c_Fi; c_Fi=Courbe1D::New_Courbe1D(*(cc_Fi));nom_courbe1="i_interne_i"; } else // cas où la courbe c_Fi est global et on veut la remplacer par une locale { c_Fi=Courbe1D::New_Courbe1D(*(cc_Fi));nom_courbe1="i_interne_i"; }; } else // cas ou cc_Fi est une courbe globale { if (c_Fi==NULL) { // cas où la courbe locale n'est pas définir c_Fi=cc_Fi;nom_courbe1="e_externe_e"; } else if (c_Fi->NomCourbe() == "_") // cas où la courbe c_Fi est local et on veut la remplacer par une globale { delete c_Fi; c_Fi=cc_Fi;nom_courbe1="e_externe_e"; } else // cas où la courbe c_Fi est global et on veut la remplacer par une globale { c_Fi=cc_Fi;nom_courbe1="e_externe_e"; }; }; }; };