// 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 "Ponderation.h" #include "CharUtil.h" // ============ cas de la class Ponderation_temps =============== Ponderation_Consultable::Ponderation_Consultable() : // le constructeur par défaut type_grandeur_Consultable(),c_proport(),tab_nom_fonction() {}; Ponderation_Consultable::Ponderation_Consultable(const Ponderation_Consultable& a) : // le constructeur de copie c_proport(a.c_proport),type_grandeur_Consultable(a.type_grandeur_Consultable) ,tab_nom_fonction(a.tab_nom_fonction) {// cas des courbes int taille = a.c_proport.Taille(); for (int i=1;i<=taille;i++) {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi) string non_courbe("_"); c_proport(i) = Courbe1D::New_Courbe1D(*a.c_proport(i)); }; } }; Ponderation_Consultable::~Ponderation_Consultable () // destructeur {// cas des courbes int taille = c_proport.Taille(); for (int i=1;i<=taille;i++) {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); }; }; // -------- affectation des fonctions à partir des noms sauvegardés // intéressant quand cette affectation à lieu longtemps après la lecture void Ponderation_Consultable::Affectation_fonctions(LesCourbes1D& lesCourbes1D) { // tout d'abord on regarde si ce n'est pas déjà effectué correctement int taille = tab_nom_fonction.Taille(); // on réajuste les tailles si besoin est if (c_proport.Taille() > taille) // là il faut diminuer. Avant il faut supprimer les fonctions si nécessaire {for (int i=taille+1;i<= c_proport.Taille();i++) if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); }; // maintenant on peut changer la taille dans tous les cas c_proport.Change_taille(taille); // on boucle pour l'affectation for (int i=1;i<=taille;i++) { // premier cas: courbe déjà affectée if (c_proport(i) != NULL) // on regarde s'il s'agit de la même courbe {if (tab_nom_fonction(i) != c_proport(i)->NomCourbe()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); // puis on affecte if (lesCourbes1D.Existe(tab_nom_fonction(i))) { c_proport(i) = lesCourbes1D.Trouve(tab_nom_fonction(i));} else { cout << "\n **** erreur1 Ponderation_Consultable::Affectation_fonctions(..." << "\n on ne trouve pas la courbe "<> nom >> tab_nom_fonction; int taille = tab_nom_fonction.Taille(); c_proport.Change_taille(taille); // ne change rien si la dimension est déjà bonne for (int i=1;i<=taille;i++) {ent >> nom; if (nom == "pointeur_null ") // cas où il n'y a rien à lire { if (c_proport != NULL) if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); } else { c_proport(i) = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport(i)); }; }; }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Ponderation_Consultable::Ecriture_base_info(ofstream& sort,const int cas) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs if (cas == 1) { sort << "\n Ponderation_Consultable " << tab_nom_fonction ; int taille = c_proport.Taille(); for (int i=1;i<= taille;i++) {sort << type_grandeur_Consultable(i); if (c_proport(i) == NULL) { sort << "pointeur_null " ;} else { sort << "courbe= "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,c_proport(i)); }; }; }; }; //============== fin de la classe Ponderation_Consultable =============== // ============ cas de la class Ponderation_GGlobal =============== // défaut Ponderation_GGlobal::Ponderation_GGlobal() : // le constructeur par défaut c_proport(NULL),nom_fonction("..") {}; Ponderation_GGlobal::Ponderation_GGlobal(const Ponderation_GGlobal& a) : // le constructeur de copie c_proport(a.c_proport),nom_fonction(a.nom_fonction) {// cas de la fonction // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale if (c_proport != NULL) if (c_proport->NomFonction() == "_") {// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi) string non_courbe("_"); c_proport = Fonction_nD::New_Fonction_nD(*a.c_proport); }; }; // lecture sur le flot d'entrée // on part du principe que les grandeurs transmises doivent faire partie des grandeurs // gérées par la fonction nD, mais il peut y en avoir plus dans la fonction // dans ce cas, on sort un warning // NB: si aucune grandeur n'est passée en argument, on ne vérifie rien // ce qui représente une lecture brut void Ponderation_GGlobal::LecturePonderation(const List_io & grandeurs , UtilLecture * entreePrinc,LesFonctions_nD& lesFonctionsnD) { // lecture du nom de la loi d'évolution *(entreePrinc->entree) >> nom_fonction; // premier cas: courbe déjà affectée if (c_proport != NULL) // on regarde s'il s'agit de la même fonction {if (nom_fonction != c_proport->NomFonction()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport->NomFonction() == "_") delete c_proport; // puis on affecte if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction);} else { // sinon il faut la lire maintenant string non_fonction("_"); c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str())); // lecture de la fonction c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc); }; }; // sinon la fonction est déjà identique, on ne fait rien } else // pas d'affectation, on affecte donc { // on regarde si la fonction existe, si oui on récupère la référence if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction); } else { // sinon il faut la lire maintenant string non_fonction("_"); c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str())); // lecture de la fonction c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc); }; }; // maintenant on s'intéresse aux grandeurs // on part du principe que les grandeurs transmises doivent faire partie des grandeurs // gérées par la fonction nD, mais il peut y en avoir plus dans la fonction // dans ce cas, on sort un warning // NB: si aucune grandeur n'est passée en argument, on ne vérifie rien // ce qui représente une lecture brut int nb_grandeurs_globales = grandeurs.size(); if (nb_grandeurs_globales != 0) {// on vérifie tout d'abord que la fonction est utilisable if (c_proport->NbVariable_globale() < nb_grandeurs_globales ) { cout << "\n erreur en lecture, la fonction nD " << nom_fonction << " utilise " << c_proport->NbVariable_globale() << " variables alors qu'il en faut " << nb_grandeurs_globales << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; if (c_proport->NbVariable_locale() != 0 ) { cout << "\n erreur en lecture, la fonction nD " << nom_fonction << " utilise " << c_proport->NbVariable_locale() << " variables locales alors qu'elle ne doit utiliser que des variables globales " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; if (c_proport->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonction << " est une fonction vectorielle a " << c_proport->NbComposante() << " composante alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on vérifie que les grandeurs transmises font quand même partie des variables utilisées // par la fonction nD const Tableau & enu_glob = c_proport->Enu_variables_globales(); const Tableau & nom_glob = c_proport->Nom_variables_globales(); List_io ::const_iterator ili,ilifin=grandeurs.end(); for (ili=grandeurs.begin();ili != ilifin; ili++) { if (!(nom_glob.Contient(*ili) || enu_glob.Contient(Id_nom_GrandeurGlobale(Minuscules(*ili))))) { cout << "\n erreur en lecture, la fonction " << nom_fonction << " devrait contenir la grandeur globale " << (*ili) << " et ce n'est pas le cas ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n Ponderation_GGlobal::LecturePonderation(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } }; }; Ponderation_GGlobal::~Ponderation_GGlobal () // destructeur {// cas des courbes // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale if (c_proport != NULL) if (c_proport->NomFonction() == "_") delete c_proport; }; // -------- affectation de la fonction à partir du nom sauvegardé // intéressant quand cette affectation à lieu longtemps après la lecture // string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction // // différée avec la lecture: 1) lecture 2) affectation de la fonction ... après // List_io type_grandeur_GGlob; // les arguments de la fonction // Tableau tab_argument; //argument pour la fonction // Fonction_nD* c_proport; // la fonction multidimentionnel void Ponderation_GGlobal::Affectation_fonctions(LesFonctions_nD& lesFonctionsnD) { // tout d'abord on regarde si ce n'est pas déjà effectué correctement // premier cas: courbe déjà affectée if (c_proport != NULL) // on regarde s'il s'agit de la même courbe {if (nom_fonction != c_proport->NomFonction()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport->NomFonction() == "_") delete c_proport; // puis on affecte if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction);} else { cout << "\n **** erreur1 Ponderation_GGlobal::Affectation_fonctions(..." << "\n on ne trouve pas la fonction " << nom_fonction << " il vaut mieux s'arreter !! car il manque des donnees " << endl; Sortie(1); }; }; // sinon la fonction est déjà identique, on ne fait rien } else // pas d'affectation, on affecte donc {if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction);} else { cout << "\n **** erreur2 Ponderation_GGlobal::Affectation_fonctions(..." << "\n on ne trouve pas la courbes "<< nom_fonction << " il vaut mieux s'arreter !! car il manque des donnees " << endl; Sortie(1); }; }; }; //-- vérification que tout est ok pour le calcul ------ void Ponderation_GGlobal::Verif_complet() const { // on vérifie que la fonction est bien instanciée if (c_proport == NULL) { cout << "\n **** erreur1 Ponderation_GGlobal::Verif_complet(..." << "\n la fonction " << " n'est pas definie on ne peut pas continuer " << endl; Sortie(1); }; }; // affichage void Ponderation_GGlobal::Affiche() { cout << "\n Ponderation_GGlobal " << nom_fonction; if (c_proport == NULL) { cout << "pointeur_null " ;} else { cout << "fonction "; c_proport->Affiche(); }; }; //----- 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 Ponderation_GGlobal::Lecture_base_info(ifstream& ent,const int cas,LesFonctions_nD& lesFonctionsnD) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs string nom; if (cas == 1) { ent >> nom >> nom_fonction; ent >> nom; if (nom == "pointeur_null ") // cas où il n'y a rien à lire { if (c_proport != NULL) if (c_proport->NomFonction() == "_") delete c_proport; } else { c_proport = lesFonctionsnD.Lecture_pour_base_info(ent,cas,c_proport); }; }; }; // idem mais sans définition de la courbe: // correspond au cas de la sauvegarde avec san_courbe = true void Ponderation_GGlobal::Lecture_base_info(ifstream& ent,const int cas) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs string nom; if (cas == 1) { ent >> nom >> nom_fonction; ent >> nom; }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) // sans_courbe: indique si on sauve oui ou non la courbe elle-même // true: on sauve la courbe // false : on sauve uniquement le nom de la courbe void Ponderation_GGlobal::Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs if (cas == 1) { sort << "\n Ponderation_GGlobal " << nom_fonction; if (!sans_courbe) {if (c_proport == NULL) { sort << "pointeur_null " ;} else { sort << "fonction "; LesFonctions_nD::Ecriture_pour_base_info(sort,cas,c_proport); }; }; }; }; // sortie du schemaXML: en fonction de enu void Ponderation_GGlobal::SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu) { }; //============== fin de la classe Ponderation_GGlobal =============== // ============ cas de la class Ponderation_TypeQuelconque =============== // défaut Ponderation_TypeQuelconque::Ponderation_TypeQuelconque() : // le constructeur par défaut type_grandeur_Quelconque(),tab_argument(),c_proport(NULL),nom_fonction("..") {}; Ponderation_TypeQuelconque::Ponderation_TypeQuelconque(const Ponderation_TypeQuelconque& a) : // le constructeur de copie type_grandeur_Quelconque(a.type_grandeur_Quelconque) ,tab_argument(a.tab_argument),c_proport(a.c_proport),nom_fonction(a.nom_fonction) {// cas de la fonction // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale if (c_proport != NULL) if (c_proport->NomFonction() == "_") {// comme il s'agit d'une fonction locale on la redéfinie (sinon pb lors du destructeur de loi) string non_courbe("_"); c_proport = Fonction_nD::New_Fonction_nD(*a.c_proport); }; }; Ponderation_TypeQuelconque::~Ponderation_TypeQuelconque () // destructeur {// cas des courbes // on regarde s'il s'agit d'une fonction locale ou d'une fonction globale if (c_proport != NULL) if (c_proport->NomFonction() == "_") delete c_proport; }; // lecture sur le flot d'entrée // on part du principe que les grandeurs transmises doivent faire partie des grandeurs // gérées par la fonction nD, mais il peut y en avoir plus dans la fonction // dans ce cas, on sort un warning // NB: si aucune grandeur n'est passée en argument, on ne vérifie rien // ce qui représente une lecture brut void Ponderation_TypeQuelconque::LecturePonderation(const List_io & grandeurs , UtilLecture * entreePrinc,LesFonctions_nD& lesFonctionsnD) { // lecture du nom de la loi d'évolution *(entreePrinc->entree) >> nom_fonction; // premier cas: fonction déjà affectée if (c_proport != NULL) // on regarde s'il s'agit de la même fonction {if (nom_fonction != c_proport->NomFonction()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport->NomFonction() == "_") delete c_proport; // puis on affecte if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction);} else { // sinon il faut la lire maintenant string non_fonction("_"); c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str())); // lecture de la fonction c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc); }; }; // sinon la fonction est déjà identique, on ne fait rien } else // pas d'affectation, on affecte donc { // on regarde si la fonction existe, si oui on récupère la référence if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction); } else { // sinon il faut la lire maintenant string non_fonction("_"); c_proport = Fonction_nD::New_Fonction_nD(non_fonction,Id_Nom_Fonction_nD (non_fonction.c_str())); // lecture de la fonction c_proport->LectDonnParticulieres_Fonction_nD (non_fonction,entreePrinc); }; }; // maintenant on s'intéresse aux grandeurs // on part du principe que les grandeurs transmises doivent faire partie des grandeurs // gérées par la fonction nD, mais il peut y en avoir plus dans la fonction // dans ce cas, on sort un warning // NB: si aucune grandeur n'est passée en argument, on ne vérifie rien // ce qui représente une lecture brut int nb_grandeurs = grandeurs.size(); if (nb_grandeurs != 0) {// on vérifie tout d'abord que la fonction est utilisable if (c_proport->NbVariable() < nb_grandeurs ) { cout << "\n erreur en lecture, la fonction nD " << nom_fonction << " utilise " << c_proport->NbVariable() << " variables alors qu'il en faut " << nb_grandeurs << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n Ponderation_TypeQuelconque::LecturePonderation(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; if (c_proport->NbComposante() != 1 ) { cout << "\n erreur en lecture, la fonction " << nom_fonction << " est une fonction vectorielle a " << c_proport->NbComposante() << " composante(s) alors qu'elle devrait etre scalaire ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n Ponderation_TypeQuelconque::LecturePonderation(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; // on vérifie que les grandeurs transmises font quand même partie des variables utilisées // par la fonction nD const Tableau & enu_glob = c_proport->Enu_variables_globales(); const Tableau & nom_glob = c_proport->Nom_variables_globales(); // récup des noms des variables locales, indépendamment des variables globales const Tableau & nom_loc = c_proport->Nom_variables(); List_io ::const_iterator ili,ilifin=grandeurs.end(); for (ili=grandeurs.begin();ili != ilifin; ili++) { if (!(nom_glob.Contient(*ili) || (EstUneGrandeurGlobale(*ili) // on ne peut tester que si c'est réellement une grandeur patentée ? enu_glob.Contient(Id_nom_GrandeurGlobale(Minuscules(*ili))) : false ) || nom_glob.Contient(*ili) || nom_loc.Contient(*ili))) { cout << "\n erreur en lecture, la fonction " << nom_fonction << " devrait contenir la grandeur " << (*ili) << " et ce n'est pas le cas ! " << " elle n'est donc pas utilisable !! "; string message("\n**erreur** \n Ponderation_TypeQuelconque::LecturePonderation(..."); entreePrinc->MessageBuffer(message); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; } }; }; // -------- affectation de la fonction à partir du nom sauvegardé // intéressant quand cette affectation à lieu longtemps après la lecture // string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction // // différée avec la lecture: 1) lecture 2) affectation de la fonction ... après // List_io type_grandeur_Quelconque; // les arguments de la fonction // Tableau tab_argument; //argument pour la fonction // Fonction_nD* c_proport; // la fonction multidimentionnel void Ponderation_TypeQuelconque::Affectation_fonctions(LesFonctions_nD& lesFonctionsnD) { // tout d'abord on regarde si ce n'est pas déjà effectué correctement // premier cas: courbe déjà affectée if (c_proport != NULL) // on regarde s'il s'agit de la même courbe {if (nom_fonction != c_proport->NomFonction()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport->NomFonction() == "_") delete c_proport; // puis on affecte if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction);} else { cout << "\n **** erreur1 Ponderation_TypeQuelconque::Affectation_fonctions(..." << "\n on ne trouve pas la fonction " << nom_fonction << " il vaut mieux s'arreter !! car il manque des donnees " << endl; Sortie(1); }; }; // sinon la fonction est déjà identique, on ne fait rien } else // pas d'affectation, on affecte donc {if (lesFonctionsnD.Existe(nom_fonction)) { c_proport = lesFonctionsnD.Trouve(nom_fonction);} else { cout << "\n **** erreur2 Ponderation_TypeQuelconque::Affectation_fonctions(..." << "\n on ne trouve pas la courbes "<< nom_fonction << " il vaut mieux s'arreter !! car il manque des donnees " << endl; Sortie(1); }; }; }; //-- vérification que tout est ok pour le calcul ------ void Ponderation_TypeQuelconque::Verif_complet() const { // on vérifie que la fonction est bien instanciée if (c_proport == NULL) { cout << "\n **** erreur1 Ponderation_TypeQuelconque::Verif_complet(..." << "\n la fonction " << " n'est pas definie on ne peut pas continuer " << endl; Sortie(1); }; // on vérifie que les tailles sont correctes if (c_proport->NbVariable_locale() != type_grandeur_Quelconque.size()) { cout << "\n **** erreur2 Ponderation_TypeQuelconque::Verif_complet(..." << "\n le nombre d'argument de la fonction "<NbVariable_locale() << " est different du nombre de grandeurs quelconques " << type_grandeur_Quelconque.size() << " on ne peut pas continuer " << endl; Sortie(1); }; // on vérifie la taille des argument if (tab_argument.Taille() != type_grandeur_Quelconque.size()) { cout << "\n **** erreur3 Ponderation_TypeQuelconque::Verif_complet(..." << "\n la taille du tableau d'argument de la fonction "<> nom >> nom_fonction; ent >> nom; if (nom == "pointeur_null ") // cas où il n'y a rien à lire { if (c_proport != NULL) if (c_proport->NomFonction() == "_") delete c_proport; } else { c_proport = lesFonctionsnD.Lecture_pour_base_info(ent,cas,c_proport); }; // les arguments: type_grandeur_Quelconque.clear(); // au cas où ent >> nom; // l'identificateur ent >> nom; // le premier argument while (nom != "fin_argu") { type_grandeur_Quelconque.push_back(Id_nomTypeQuelconque(nom)); ent >> nom; }; // on met à jour le tableau des arguments pour l'appel des fonctions tab_argument.Change_taille(type_grandeur_Quelconque.size()); }; }; // idem mais sans définition de la courbe: // correspond au cas de la sauvegarde avec san_courbe = true void Ponderation_TypeQuelconque::Lecture_base_info(ifstream& ent,const int cas) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs string nom; if (cas == 1) { ent >> nom >> nom_fonction; ent >> nom; // les arguments: type_grandeur_Quelconque.clear(); // au cas où ent >> nom; // l'identificateur ent >> nom; // le premier argument while (nom != "fin_argu") { type_grandeur_Quelconque.push_back(Id_nomTypeQuelconque(nom)); ent >> nom; }; // on met à jour le tableau des arguments pour l'appel des fonctions tab_argument.Change_taille(type_grandeur_Quelconque.size()); }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) // sans_courbe: indique si on sauve oui ou non la courbe elle-même // true: on sauve la courbe // false : on sauve uniquement le nom de la courbe void Ponderation_TypeQuelconque::Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs if (cas == 1) { sort << "\n Ponderation_TypeQuelconque " << nom_fonction; if (!sans_courbe) {if (c_proport == NULL) { sort << "pointeur_null " ;} else { sort << "fonction "; LesFonctions_nD::Ecriture_pour_base_info(sort,cas,c_proport); }; }; // les arguments: List_io ::iterator ili,iliend=type_grandeur_Quelconque.end(); sort << "\n argument(s): "; for (ili = type_grandeur_Quelconque.begin(); ili != iliend; ili++) sort << NomTypeQuelconque(*ili) << " "; sort << " fin_argu"; }; }; // sortie du schemaXML: en fonction de enu void Ponderation_TypeQuelconque::SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu) { }; //============== fin de la classe Ponderation_TypeQuelconque =============== // ============ cas de la class Ponderation =============== Ponderation::Ponderation() : // le constructeur par défaut type_grandeur(),valeur_aux_noeuds(),c_proport(),tab_nom_fonction() {}; Ponderation::Ponderation(const Ponderation& a) : // le constructeur de copie type_grandeur(a.type_grandeur),valeur_aux_noeuds(a.valeur_aux_noeuds) ,c_proport(a.c_proport),tab_nom_fonction(a.tab_nom_fonction) {// cas des courbes int tail = c_proport.Taille(); for (int i=1;i<= tail;i++) {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi) string non_courbe("_"); c_proport(i) = Courbe1D::New_Courbe1D(*a.c_proport(i)); }; }; }; Ponderation::~Ponderation () // destructeur {// cas des courbes int tail = c_proport.Taille(); for (int i=1;i<= tail;i++) {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); }; }; // -------- opération de lecture sur le flot d'entrée ------ // lecture d'une courbe: intéressant si on lit courbe par courbe // le dimensionnement est mis à jour à chaque appel void Ponderation::LectureDonneesPonderation_uneCourbe (Ddl_enum_etendu ddl,UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D) { string st1; // on lit la courbe *(entreePrinc->entree) >> st1; Courbe1D* inter=NULL; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(st1)) { inter = lesCourbes1D.Trouve(st1); } else { // sinon il faut la lire maintenant string non_courbe("_"); inter = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (st1.c_str())); // lecture de la courbe inter->LectDonnParticulieres_courbes (non_courbe,entreePrinc); }; // maintenant on redimensionne les tableaux // ce n'est pas performant, mais normalement cela n'arrive pas souvent (?) int taille = type_grandeur.Taille() +1 ; type_grandeur.Change_taille(taille);type_grandeur(taille)=ddl; c_proport.Change_taille(taille);c_proport(taille)=inter; tab_nom_fonction.Change_taille(taille);tab_nom_fonction(taille)=st1; // et il faut lire en plus le fait que ce soit au noeud ou au pti string st2; *(entreePrinc->entree) >> st2; valeur_aux_noeuds.Change_taille(taille); if (st2 == "AuxNoeuds_") {valeur_aux_noeuds(taille)=true;} else if (st2 == "AuPti_") {valeur_aux_noeuds(taille)=false;} else { cout << "\n erreur en lecture, de positionnement de la grandeur: " << ddl.Nom() << " qui doit etre AuxNoeuds_ ou AuPti_ " << " et on a lu" << st2 << " qui n'est pas acceptable " << "\nPonderation::LectureDonneesPonderation_uneCourbe(..."; entreePrinc->MessageBuffer("**erreur**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; // lecture de l'ensemble de la pondération void Ponderation::LectureDonneesPonderation (const List_io & list_id_ddl_etendu , UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D) { // on commence par tout redimensionner et initialiser si les tailles ne sont pas identiques int nb_fonc = list_id_ddl_etendu.size(); if (type_grandeur.Taille() != nb_fonc) { type_grandeur.Change_taille(nb_fonc); valeur_aux_noeuds.Change_taille(nb_fonc); // on supprime les fonctions et on redimensionne le tableau int tail = c_proport.Taille(); for (int i=1;i<= tail;i++) {// on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); }; c_proport.Change_taille(nb_fonc); tab_nom_fonction.Change_taille(nb_fonc); }; // on boucle sur les ddl pour lire les fonctions individuelles List_io ::const_iterator ili,ilifin = list_id_ddl_etendu.end(); int i_tab=1; // indice de tableau for (ili=list_id_ddl_etendu.begin();ili != ilifin; ili++,i_tab++) { string st1; // on lit la courbe *(entreePrinc->entree) >> st1; Courbe1D* inter=NULL; // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(st1)) { inter = lesCourbes1D.Trouve(st1); } else { // sinon il faut la lire maintenant string non_courbe("_"); inter = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (st1.c_str())); // lecture de la courbe inter->LectDonnParticulieres_courbes (non_courbe,entreePrinc); }; // maintenant on alimente les tableaux type_grandeur(i_tab)=Ddl_enum_etendu(*ili); c_proport(i_tab)=inter; tab_nom_fonction(i_tab)=st1; // et il faut lire en plus le fait que ce soit au noeud ou au pti string st2; *(entreePrinc->entree) >> st2; valeur_aux_noeuds.Change_taille(i_tab); if (st2 == "AuxNoeuds_") {valeur_aux_noeuds(i_tab)=true;} else if (st2 == "AuPti_") {valeur_aux_noeuds(i_tab)=false;} else { cout << "\n erreur en lecture, de positionnement de la grandeur: " << (*ili) << " qui doit etre AuxNoeuds_ ou AuPti_ " << " et on a lu" << st2 << " qui n'est pas acceptable " << "\nPonderation::LectureDonneesPonderation_uneCourbe(..."; entreePrinc->MessageBuffer("**erreur**"); throw (UtilLecture::ErrNouvelleDonnee(-1)); Sortie(1); }; }; }; // -------- affectation des fonctions à partir des noms sauvegardés // intéressant quand cette affectation à lieu longtemps après la lecture void Ponderation::Affectation_fonctions(LesCourbes1D& lesCourbes1D) { // tout d'abord on regarde si ce n'est pas déjà effectué correctement int taille = tab_nom_fonction.Taille(); // on réajuste les tailles si besoin est if (c_proport.Taille() > taille) // là il faut diminuer. Avant il faut supprimer les fonctions si nécessaire {for (int i=taille+1;i<= c_proport.Taille();i++) if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); }; // maintenant on peut changer la taille dans tous les cas c_proport.Change_taille(taille); // on boucle pour l'affectation for (int i=1;i<=taille;i++) { // premier cas: courbe déjà affectée if (c_proport(i) != NULL) // on regarde s'il s'agit de la même courbe {if (tab_nom_fonction(i) != c_proport(i)->NomCourbe()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); // puis on affecte if (lesCourbes1D.Existe(tab_nom_fonction(i))) { c_proport(i) = lesCourbes1D.Trouve(tab_nom_fonction(i));} else { cout << "\n **** erreur1 Ponderation_Consultable::Affectation_fonctions(..." << "\n on ne trouve pas la courbe "<Valeur(grand); proportion *= fonc; // on accumule multiplicativement } else // sinon il s'agit d'une grandeur directement accessible au point d'intégration // pour l'instant il n'y a pas de procédure générale de récupération, seulement des cas particuliers { // deux cas suivant que l'on a affaire à un ddl de base ou à un vrai ddl étendu if (type_grandeur(i).Nom_vide()) {switch (type_grandeur(i).Enum()) { case PROP_CRISTA: { const double* taux_crita = dTP.TauxCrista(); if (taux_crita != NULL) { double fonc = c_proport(i)->Valeur(*taux_crita); proportion *= fonc; // on accumule multiplicativement } else {cout << "\n erreur, le taux de cristalinite n'est pas disponible au point d'integration " << " il n'est pas possible de calculer le niveau_declenchement_critere " << "\n Ponderation::CalculPonderMultiplicatif(.... "; }; break; } default: cout << "\n erreur, le type " << type_grandeur(i) << " n'est pas disponible " << " pour l'instant au point d'integration ! " << "\n Ponderation::CalculPonderMultiplicatif(.... "; }; } else {// cas d'un vrai ddl étendue Ddl_enum_etendu enu_etendu = type_grandeur(i); // pour simplifier switch (enu_etendu.Position()-NbEnum_ddl()) {case 87: // cas de "def_equivalente" {const double def_equivalente = ptintmeca.Deformation_equi_const()(1); // recup de la def equi double fonc = c_proport(i)->Valeur(def_equivalente); proportion *= fonc; // on accumule multiplicativement break; } case 88: // cas de "def_duale_mises_maxi" {const double def_duale_mises_maxi = ptintmeca.Deformation_equi_const()(3); // recup de la def equi double fonc = c_proport(i)->Valeur(def_duale_mises_maxi); proportion *= fonc; // on accumule multiplicativement break; } case 89: // cas de "vitesse_def_equivalente" {const double delta_def_equivalente = ptintmeca.Deformation_equi_const()(4); // recup du delta def equi // recup de l'incrément de temps double deltat=ParaGlob::Variables_de_temps().IncreTempsCourant(); double unSurDeltat=0; if (Abs(deltat) >= ConstMath::trespetit) {unSurDeltat = 1./deltat;} else // si l'incrément de temps est tres petit on remplace 1/deltat par un nombre tres grand { // un pas de temps doit être positif !! or certaine fois il peut y avoir des pb if (unSurDeltat < 0) { cout << "\n le pas de temps est négatif !! "; }; unSurDeltat = ConstMath::tresgrand; }; double vitesse_def_equi = delta_def_equivalente * unSurDeltat; double fonc = c_proport(i)->Valeur(vitesse_def_equi); proportion *= fonc; // on accumule multiplicativement break; } case 77: // cas de "def_duale_mises" {const double def_duale_mises = ptintmeca.Deformation_equi_const()(2); // recup de la def equi double fonc = c_proport(i)->Valeur(def_duale_mises); proportion *= fonc; // on accumule multiplicativement break; } case 78: // cas de "Spherique_eps" {const Vecteur & epsInvar = ptintmeca.EpsInvar_const(); // recup des invariants double spherique_eps = epsInvar(1); double fonc = c_proport(i)->Valeur(spherique_eps); proportion *= fonc; // on accumule multiplicativement break; } case 81: // cas de "Spherique_sig" {const Vecteur & sigInvar = ptintmeca.SigInvar_const(); // recup des invariants double spherique_sig = sigInvar(1); double fonc = c_proport(i)->Valeur(spherique_sig); proportion *= fonc; // on accumule multiplicativement break; } default: cout << "\n erreur, le type " << enu_etendu << " n'est pas disponible " << " pour l'instant au point d'integration ! " << "\n Ponderation::CalculPonderMultiplicatif(.... "; break; }; }; }; }; return proportion; // retour de la proportion calculée }; //----- 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 Ponderation::Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs string nom; if (cas == 1) { ent >> nom >> nom >> tab_nom_fonction; ent >> nom >> type_grandeur >> nom >> valeur_aux_noeuds; int taille = type_grandeur.Taille(); c_proport.Change_taille(taille); // ne change rien si la taille est déjà bonne for (int i=1;i<= taille;i++) {ent >> nom; if (nom == "pointeur_null ") // cas où il n'y a rien à lire { if (c_proport(i) != NULL) if (c_proport(i)->NomCourbe() == "_") delete c_proport(i); } else { c_proport(i) = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport(i)); }; }; }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Ponderation::Ecriture_base_info(ofstream& sort,const int cas) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs if (cas == 1) { sort << "\n Ponderation " << "nom_courbes " << tab_nom_fonction; sort << "\n type_grandeur "<< type_grandeur << " valeur_aux_noeuds "<< valeur_aux_noeuds; int taille = c_proport.Taille(); // normalement = la même que celle de type_grandeur for (int i=1;i<= taille ; i++) {if (c_proport(i) == NULL) { sort << "pointeur_null " ;} else { sort << "courbe= "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,c_proport(i)); }; }; }; }; // sortie du schemaXML: en fonction de enu void Ponderation::SchemaXML_Fonctions_nD(ofstream& sort,const Enum_IO_XML enu) { }; //============== fin de la classe Ponderation =============== // ============ cas de la class Ponderation_temps =============== Ponderation_temps::Ponderation_temps() : // le constructeur par défaut c_proport(NULL),nom_fonction("..") {}; Ponderation_temps::Ponderation_temps(const Ponderation_temps& a) : // le constructeur de copie c_proport(a.c_proport),nom_fonction(a.nom_fonction) {// cas de la courbe // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport != NULL) if (c_proport->NomCourbe() == "_") {// comme il s'agit d'une courbe locale on la redéfinie (sinon pb lors du destructeur de loi) string non_courbe("_"); c_proport = Courbe1D::New_Courbe1D(*a.c_proport); }; }; Ponderation_temps::~Ponderation_temps () // destructeur {// cas de la courbe // on regarde s'il s'agit d'une courbe locale ou d'une courbe globale if (c_proport != NULL) if (c_proport->NomCourbe() == "_") delete c_proport; }; // string nom_fonction; // le nom de la fonction, sert en particulier pour une définition de la fonction // // différée avec la lecture: 1) lecture 2) affectation de la fonction ... après // Courbe1D* c_proport; // la fonctions 1D, fonction du temps // lecture sur le flot d'entrée void Ponderation_temps::LectureDonneesPonderation (UtilLecture * entreePrinc,LesCourbes1D& lesCourbes1D) { // lecture du nom de la loi d'évolution *(entreePrinc->entree) >> nom_fonction; // premier cas: courbe déjà affectée if (c_proport != NULL) // on regarde s'il s'agit de la même courbe {if (nom_fonction != c_proport->NomCourbe()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport->NomCourbe() == "_") delete c_proport; // puis on affecte if (lesCourbes1D.Existe(nom_fonction)) { c_proport = lesCourbes1D.Trouve(nom_fonction);} else { // sinon il faut la lire maintenant string non_courbe("_"); c_proport = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom_fonction.c_str())); // lecture de la courbe c_proport->LectDonnParticulieres_courbes (non_courbe,entreePrinc); }; }; // sinon la courbe est déjà identique, on ne fait rien } else // pas d'affectation, on affecte donc { // on regarde si la courbe existe, si oui on récupère la référence if (lesCourbes1D.Existe(nom_fonction)) { c_proport = lesCourbes1D.Trouve(nom_fonction); } else { // sinon il faut la lire maintenant string non_courbe("_"); c_proport = Courbe1D::New_Courbe1D(non_courbe,Id_Nom_Courbe1D (nom_fonction.c_str())); // lecture de la courbe c_proport->LectDonnParticulieres_courbes (non_courbe,entreePrinc); }; }; }; // -------- affectation des fonctions à partir des noms sauvegardés // intéressant quand cette affectation à lieu longtemps après la lecture void Ponderation_temps::Affectation_fonctions(LesCourbes1D& lesCourbes1D) { // premier cas: courbe déjà affectée if (c_proport != NULL) // on regarde s'il s'agit de la même courbe {if (nom_fonction != c_proport->NomCourbe()) {// cas où c'est différent: on commence éventuellement par supprimer if (c_proport->NomCourbe() == "_") delete c_proport; // puis on affecte if (lesCourbes1D.Existe(nom_fonction)) { c_proport = lesCourbes1D.Trouve(nom_fonction);} else { cout << "\n **** erreur1 Ponderation_temps::Affectation_fonctions(..." << "\n on ne trouve pas la courbe "<< nom_fonction << " il vaut mieux s'arreter !! car il manque des donnees " << endl; Sortie(1); }; }; // sinon la courbe est déjà identique, on ne fait rien } else // pas d'affectation, on affecte donc {if (lesCourbes1D.Existe(nom_fonction)) { c_proport = lesCourbes1D.Trouve(nom_fonction);} else { cout << "\n **** erreur2 Ponderation_temps::Affectation_fonctions(..." << "\n on ne trouve pas la courbes "<< nom_fonction << " il vaut mieux s'arreter !! car il manque des donnees " << endl; Sortie(1); }; }; }; //-- vérification que tout est ok pour le calcul ------ void Ponderation_temps::Verif_complet() const { // on vérifie que la fonction est bien instanciée if (c_proport == NULL) { cout << "\n **** erreur1 Ponderation_temps::Verif_complet(..." << "\n la fonction " << " n'est pas definie on ne peut pas continuer " << endl; Sortie(1); }; }; // affichage void Ponderation_temps::Affiche() { cout << "\n Ponderation_temps " << nom_fonction; if (c_proport == NULL) { cout << "pointeur_null " ;} else { cout << "courbe= "; c_proport->Affiche(); }; }; // calcul de la pondération // par défaut ramène 1. si la fonction du temps est inactive par exemple // sinon ramène la valeur de la fonction du temps actuel double Ponderation_temps::CalculPonder() { const VariablesTemps& var_temps = ParaGlob::Variables_de_temps(); double fonc = c_proport->Valeur(var_temps.TempsCourant()); return fonc; }; //----- 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 Ponderation_temps::Lecture_base_info(ifstream& ent,const int cas,LesCourbes1D& lesCourbes1D) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs string nom; if (cas == 1) { ent >> nom >> nom_fonction; ent >> nom; if (nom == "pointeur_null ") // cas où il n'y a rien à lire { if (c_proport != NULL) if (c_proport->NomCourbe() == "_") delete c_proport; } else { c_proport = lesCourbes1D.Lecture_pour_base_info(ent,cas,c_proport); }; }; }; // idem mais sans définition de la courbe void Ponderation_temps::Lecture_base_info(ifstream& ent,const int cas) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs string nom; if (cas == 1) { ent >> nom >> nom_fonction; }; }; // cas donne le niveau de sauvegarde // = 1 : on sauvegarde tout // = 2 : on sauvegarde uniquement les données variables (supposées comme telles) // sans_courbe: indique si on sauve oui ou non la courbe elle-même // true: on sauve la courbe // false : on sauve uniquement le nom de la courbe void Ponderation_temps::Ecriture_base_info(ofstream& sort,const int cas,bool sans_courbe) { // ici on ne sort que pour le cas 1, ce qui fait qu'en restart on peut changer les valeurs if (cas == 1) { sort << "\n Ponderation_temps " << nom_fonction; if (!sans_courbe) {if (c_proport == NULL) { sort << "pointeur_null " ;} else { sort << "courbe= "; LesCourbes1D::Ecriture_pour_base_info(sort,cas,c_proport); }; }; }; };