// 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: . /************************************************************************ * DATE: 11/10/2003 * * $ * * AUTEUR: G RIO (mailto:gerardrio56@free.fr) * * $ * * PROJET: Herezh++ * * $ * ************************************************************************ * BUT: Algorithmes de base pour la recherche de zéro d'une * * fonction ou d'un ensemble de fonctions. * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * $ * ************************************************************************/ #ifndef ALGO_ZERO_H #define ALGO_ZERO_H #include "Vecteur.h" #include "Mat_abstraite.h" #include "Racine.h" #include /// @addtogroup Les_classes_algo /// @{ /// /** * * BUT: pour la gestion d'exception pour non convergence * * * \author Gérard Rio * \version 1.0 * \date 11/10/2003 * \brief pour la gestion d'exception pour non convergence * */ class ErrNonConvergence_Newton // =0 cas courant, pas d'information particulière // =1 cas où l'erreur est sévère et ne pourra pas être corrigé en refaisant un calcul avec un // pas de temps plus petit. Il faut refaire le calcul en se positionnant plusieurs pas de temps // auparavant (utilisé par l'hystérésis par exemple) { public : int cas; ErrNonConvergence_Newton () : cas(0) {} ; // par défaut ErrNonConvergence_Newton (int ca) : cas(ca) {} ; // pb }; /// @} // end of group /// @addtogroup Les_classes_algo /// @{ /// /** * * BUT: Algorithmes de base pour la recherche de zéro d'une * fonction ou d'un ensemble de fonctions. * * * \author Gérard Rio * \version 1.0 * \date 11/10/2003 * \brief Algorithmes de base pour la recherche de zéro d'une fonction ou d'un ensemble de fonctions. * */ class Algo_zero { public : // CONSTRUCTEURS : /// constructeur par défaut Algo_zero(); /// constructeur de copie Algo_zero(const Algo_zero& a); /// DESTRUCTEUR : ~Algo_zero(); // METHODES PUBLIQUES : /// recherche du zéro d'une équation du second degré dans l'espace des réels: ax^2+bx+c=0. /// cas indique les différents cas: /// = 1 : il y a deux racines , racine2 > racine1 /// = 2 : il y a une racine double /// = 0 : pas de racine /// = -1 : pas de racine car a,b,c sont tous inférieur à la précision de traitement /// = -2 : pas de racine car a,b sont inférieur à la précision de traitement tandis que c est non nul /// = -3 : une racine simple car a est inférieur à la précision de traitement, donc considéré comme nul /// b et c sont non nul -> equa du premier degré, solution: racine1 void SecondDegre(double a, double b, double c, double& racine1, double& racine2, int& cas) const ; /// recherche du zéro d'une équation du troisième degré dans l'espace des réels: ax^3+bx^2+cx+d=0. /// cas indique les différents cas: /// = 1 : il y a deux racines , racine2 > racine1 /// = 2 : il y a une racine double /// = 3 : il y a une seule racine réelle racine1 (et deux complexes non calculées) /// = 4 : il y a une racine simple: racine1, et une racine double: racine 2 /// = 5 : il y a 3 racines réelles: racine1, racine2, racine3 /// = 0 : pas de racine /// = -1 : pas de racine car a,b,c sont tous inférieur à la précision de traitement /// = -2 : pas de racine car a,b sont inférieur à la précision de traitement tandis que c est non nul /// = -3 : une racine simple car a est inférieur à la précision de traitement, donc considéré comme nul /// b et c sont non nul -> equa du premier degré, solution: racine1 void TroisiemeDegre(double a, double b, double c, double d, double& racine1 , double& racine2, double& racine3, int& cas) ; ///recherche du zéro d'une fonction en utilisant la méthode de Newton-Raphson incrémentale /// ici il s'agit d'une fonction à une variable /// *Ptfonc : le pointeur de la fonction dont il faut chercher le zéro /// *Ptder_fonc : pointeur de la dérivée de la fonction /// pour ces deux fonctions, la variable alpha est un facteur de charge qui varie de /// 0 à 1. Lorsque alpha=0, la racine vaut val_initiale, et ce que l'on /// cherche c'est la racine pour alpha = 1. Lorsque alpha varie progressivement /// de 0 à 1, la racine est sensée varier progressivement de val_initiale à résidu /// l'utilisation d'alpha permet de faire du Newton incrémentale. /// pour ces deux fonctions, l'argument test ramène /// . 1 si le calcul a été ok, -1 s'il y a eu un pb, mais on peut continuer, 0 s'il y a eu un pb /// fatal, qui invalide le calcul de la fonction et/ou de la dérivée /// val_initiale : une valeur initiale de x pour la recherche de zéro /// max_delta_x : si > 0 donne le norme maxi permise sur delta_x au cours d'une itération /// si ||delta_x|| est plus grand on fait delta_x = max_delta_x * delta_x / || delta_x|| /// ramène en sortie: /// un booléen qui indique si la résolution est correcte ou non /// racine : la racine trouvée /// der_at_racine : contient en retour la valeur de la dérivée pour la racine trouvée /// nb_incr_total : le nombre total d'incrément qui a été nécessaire /// nb_iter_total : le nombre total d'itération, qui cumule les iter de tous les incréments template bool Newton_raphson (T& instance,double (T::*Ptfonc) (double & alpha,double & x,int& test) ,double (T::*Ptder_fonc) (double & alpha,double & x,int& test) ,double val_initiale,double & racine,double & der_at_racine ,int& nb_incr_total, int& nb_iter_total ,double max_delta_x) const ; /// idem précédemment, mais pour une fonction à valeur vectorielle /// les matrices sont telles que: der_at_racine(i,j) = df(i)/d(x(j), soit: df = der_at_racine * dx template bool Newton_raphson (T& instance,Vecteur& (T::*Ptfonc) (const double & alpha,const Vecteur & x,int& test) ,Mat_abstraite& (T::*Ptder_fonc) (const double & alpha,const Vecteur & x,int& test) ,const Vecteur& val_initiale,Vecteur & racine,Mat_abstraite & der_at_racine ,int& nb_incr_total, int& nb_iter_total ,double max_delta_x) const; /// idem précédemment, mais pour une fonction à valeur vectorielle et .. /// la méthode externe calcul la valeur de la fonction et de la dérivée en même temps /// mais on utilise également la fonction résidu toute seule /// les matrices sont telles que: der_at_racine(i,j) = df(i)/d(x(j), soit: df = der_at_racine * dx template bool Newton_raphson (T& instance,Vecteur& (T::*Ptfonc) (const double & alpha,const Vecteur & x,int& test) ,Mat_abstraite& (T::*Ptder_fonc) (const double & alpha,const Vecteur & x,Vecteur& res,int& test) ,const Vecteur& val_initiale,Vecteur & racine,Mat_abstraite & der_at_racine ,int& nb_incr_total, int& nb_iter_total ,double max_delta_x) const ; /// méthodes pour modifier les différents paramètres /// précision sur le résidu à convergence void Modif_prec_res_abs (double eps) {prec_res_abs = eps;}; ///< précision absolue void Modif_prec_res_rel (double eps) {prec_res_rel = eps;}; ///< précision relative /// nombre d'itération maxi pour un incrément void Modif_iter_max (double eps) { iter_max = eps;}; /// précision relative sur le mini de l'incrément de x void Modif_coef_mini_delta_x (double eps) {coef_mini_delta_x = eps;}; /// minimum de delta x permis void Modif_mini_delta_x (double eps) {mini_delta_x = eps;}; /// maximum de delta x permis void Modif_maxi_delta_x (double eps) {maxi_delta_x = eps;}; /// nombre maxi d'incrément permis void Modif_nbMaxiIncre (int nb) {nbMaxiIncre = nb;}; /// nombre maxi de test -1 permis void Modif_nbMaxi_test_moins1 (int nb) {maxi_test_moins1 = nb;}; /// initialisation de tous les paramètres à leurs valeurs par défaut void Init_param_val_defaut(); /// le niveau d'affichage void Modif_affichage(int niveau) {permet_affichage = niveau;}; /// récup en lecture des différents paramètres const double& Prec_res_abs() const {return prec_res_abs;}; ///< précision absolue sur le résidu à convergence const double& Prec_res_rel() const {return prec_res_rel;};///< précision relative sur le résidu à convergence const int& Iter_max() const {return iter_max;};///< nombre d'itération maxi pour un incrément const double& Coef_mini_delta_x() const {return coef_mini_delta_x;};///< précision relative sur le mini de l'incrément de x const double& Mini_delta_x() const {return mini_delta_x;};///< minimum de delta x permis const double& Maxi_delta_x() const {return maxi_delta_x;};///< maximum de delta x permis const int& NbMaxiIncre() const {return nbMaxiIncre;};///< nombre maxi d'incrément permis const int& Maxi_test_moins1() const {return maxi_test_moins1;};///< nombre maxi de test -1 permis const int& Permet_affichage() const {return permet_affichage;}; ///< le niveau d'affichage /// affichage à l'écran des infos void Affiche() const; ///----- 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 Lecture_base_info(ifstream& ent,const int cas); /// cas donne le niveau de sauvegarde /// = 1 : on sauvegarde tout /// = 2 : on sauvegarde uniquement les données variables (supposées comme telles) void Ecriture_base_info(ofstream& sort,const int cas); private : // VARIABLES PROTEGEES : double prec_res_abs; // précision absolue sur le résidu à convergence double prec_res_rel; // précision relative sur le résidu à convergence int iter_max; // nombre d'itération maxi pour un incrément double coef_mini_delta_x; // précision relative sur le mini de l'incrément de x double mini_delta_x; // minimum de delta x permis double maxi_delta_x; // maximum de delta x permis int nbMaxiIncre; // nombre maxi d'incrément permis int maxi_test_moins1; // nombe maxi de test = -1 permi // ----- controle de la sortie des informations int permet_affichage; // pour permettre un affichage spécifique dans les méthodes, // pour les erreurs et des wernings Quartic algo_quartic; // une suite d'algo pour résoudre une quartic et des cubic // METHODES PROTEGEES : }; // pour faire de l'inline: nécessaire avec les templates // on n'inclut que les méthodes templates #include "Algo_zero_2.cc" #define Algo_zero_deja_inclus /// @} // end of group #endif