// 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 "Algo_edp.h" // contiend que les méthodes qui ne sont pas des templates #include "MathUtil.h" #include "ConstMath.h" // ----- def des variables statiques --------- // ---- variables intermédiaires utilisées par la méthode Runge_Kutta_step23 double Algo_edp::AB1=1./6.,Algo_edp::AB2=2./3.,Algo_edp::AB3=1./6. ,Algo_edp::A2=1.,Algo_edp::aa2=0.5,Algo_edp::aa3=1. ,Algo_edp::bb21=0.5,Algo_edp::bb31=-1.,Algo_edp::bb32=2. ,Algo_edp::dA1=1./6,Algo_edp::dA2=-1./3.,Algo_edp::dA3=1./6.; // ---- variables intermédiaires utilisées par la méthode Runge_Kutta_step34 double Algo_edp::A_B1=229./1470.,Algo_edp::A_B3=1125./1813.,Algo_edp::A_B4=13718./81585. ,Algo_edp::A_B5=1./18. ,Algo_edp::A_1=79./490.,Algo_edp::A_3=2175./3626.,Algo_edp::A_4=2166./9065. ,Algo_edp::a_a2=2./7.,Algo_edp::a_a3=7./15.,Algo_edp::a_a4=35./38.,Algo_edp::a_a5=1. ,Algo_edp::b_b21=2./7. ,Algo_edp::b_b31=77./900.,Algo_edp::b_b32=343./900. ,Algo_edp::b_b41=805./1444.,Algo_edp::b_b42=-77175./54872.,Algo_edp::b_b43=97125./54872. ,Algo_edp::b_b51=79./490.,Algo_edp::b_b53=2175./3626.,Algo_edp::b_b54=2166./9065. ,Algo_edp::d_A1=0.,Algo_edp::d_A3=0.,Algo_edp::d_A4=0.,Algo_edp::d_A5=1./18.; // --- variables intermédiaires utilisées par la méthode Runge_Kutta_step45 double // d'abord les ai Algo_edp::a2=0.2,Algo_edp::a3=0.3,Algo_edp::a4=0.6,Algo_edp::a5=1.0,Algo_edp::a6=7./8.; // puis les bij double Algo_edp::b21=0.2 ,Algo_edp::b31=3.0/40.0,Algo_edp::b32=9.0/40.0 ,Algo_edp::b41=0.3,Algo_edp::b42 = -0.9,Algo_edp::b43=1.2 ,Algo_edp::b51 = -11.0/54.0, Algo_edp::b52=2.5,Algo_edp::b53 = -70.0/27.0,Algo_edp::b54=35.0/27.0 ,Algo_edp::b61=1631.0/55296.0,Algo_edp::b62=175.0/512.0,Algo_edp::b63=575.0/13824.0 ,Algo_edp::b64=44275.0/110592.0,Algo_edp::b65=253.0/4096.0; // puis les ci double Algo_edp::c1=37.0/378.0,Algo_edp::c3=250.0/621.0,Algo_edp::c4=125.0/594.0,Algo_edp::c6=512.0/1771.0; // et c5-c_étoile_5 double Algo_edp::ce5 = -277.00/14336.0; // initialisés dans le premier appel du construteur double Algo_edp::ce1=0.,Algo_edp::ce3=0.,Algo_edp::ce4=0.,Algo_edp::ce6=0.; // pour la méthode Pilotage_kutta (cf.rkf45) double Algo_edp::remin = 1.0E-12; // -------- fin des variables statiques -------- // CONSTRUCTEURS : // constructeur par défaut Algo_edp::Algo_edp() : k2(1),k3(1),k4(1),k5(1),k6(1)//,f_inter(1) ,val_inter(1),der_inter(1),estime_erreur(1),coef(0.9) ,nb_cas_test(1),permet_affichage(0) { if (ce1 == 0.) // au premier appel on initialise {ce1=c1-2825.0/27648.0; ce3=c3-18575.0/48384.0; ce4=c4-13525.0/55296.0; ce6=c6-0.25; }; if (d_A1==0.) {d_A1=A_B1-A_1; d_A3=A_B3-A_3; d_A4=A_B4-A_4; d_A5=A_B5; }; // initialisation des paramètres par défaut Init_param_val_defaut(); // --- test des routines ---- (en fonctionnement normal: commenté) // Test_template(); }; // constructeur de copie Algo_edp::Algo_edp(const Algo_edp& a) : k2(a.k2),k3(a.k3),k4(a.k4),k5(a.k5),k6(a.k6)//,f_inter(a.f_inter) ,val_inter(a.val_inter),der_inter(a.der_inter),estime_erreur(a.estime_erreur),coef(a.coef) ,estime_prec_erreur(a.estime_prec_erreur) ,nb_cas_test(1),permet_affichage(0) { if (ce1 == 0.) // au premier appel on initialise {ce1=c1-2825.0/27648.0; ce3=c3-18575.0/48384.0; ce4=c4-13525.0/55296.0; ce6=c6-0.25; }; // initialisation des paramètres par défaut Init_param_val_defaut(); }; // DESTRUCTEUR : Algo_edp::~Algo_edp() {} // METHODES PUBLIQUES : // initialisation de tous les paramètres à leurs valeurs par défaut void Algo_edp::Init_param_val_defaut() { nbMaxiAppel = 3000; }; // explication erreur // affiche à l'écran l'explication de l'erreur de Pilotage_kutta void Algo_edp::Affiche_Explication_erreur_RG(int type_erreur) { switch (type_erreur) {case 2 : cout << " calcul correct "; break; case 3 : cout << " la precision relative demandee est trop petite "; break; case 4 : cout << " nombre maxi d'appels de la fonction, atteints "; break; case 6 : cout << " integration impossible, due aux precisions demandees, on doit augmenter ces precisions ";break; case 8 : cout << " cas_kutta ne correspond pas a une routine de base existante ";break; case 9 : cout << " calcul correct, mais la derniere valeur a t, n'a pu etre calculee, " << " c'est la valeur a t - quelque chose qui est renvoyee "; break; case 0 : cout << " erreur inconnue ";break; default : cout << " type d'erreur inconnue ";break; } }; //==================================== méthodes privées ============================== // on défini une fonction a intégrer Vecteur& Algo_edp::FoncDeriv(const double & t,const Vecteur& f,Vecteur& df,int& erreur) { switch (nb_cas_test) {case 1: {df = f; // juste pour dimensionner df(1)=cos(t); erreur = 0; }break; case 2: {df = f; // juste pour dimensionner df(1)=cos(t); erreur = 0; }break; case 3: // y" + y=0 -> y'=f, f'=-y, solution cos {df(1) = f(2); // juste pour dimensionner df(2) = -f(1); erreur = 0; }break; case 4: // deux fonctions sin cos indépendantes {df(1) = cos(t); // juste pour dimensionner df(2) = -sin(t); erreur = 0; }break; default: erreur = 1; cout << "\n cas de test non implemente !! nb_cas_test="< y'=f, f'=-y, solution cos {erreur = 0; }break; case 4: // deux fonctions sin cos indépendantes {erreur = 0; }break; default: erreur = 1; cout << "\n cas de test non implemente !! nb_cas_test="<Pilotage_kutta (cas_kutta,*this,& Algo_edp::FoncDeriv,& Algo_edp::FoncVerif_fonc ,val_initiale,der_initiale ,tdeb,tfi,erreurAbsolue,erreurRelative ,val_finale,der_finale,dernierTemps,dernierdeltat ,nombreAppelF,nb_step,erreur_maxi_global); // affichage des informations switch (nb_cas_test) {case 1: {cout << "\n iter= " << iboucle << " valeur finale "<< val_finale(1) << " exacte " << sin(tfi) << " erreur " << (val_finale(1)-sin(tfi)) << " estime " << erreur_maxi_global << " nb step " << nb_step << " nombre d'appel " << nombreAppelF << " dernier temps " << dernierTemps << " dernier deltat " << dernierdeltat; break; } case 2: {cout << "\n iter= " << iboucle << " valeur finale "<< val_finale(1) << " exacte " << sin(tfi) << " erreur " << (val_finale(1)-sin(tfi)) << " estime " << erreur_maxi_global << " nb step " << nb_step << " nombre d'appel " << nombreAppelF << " dernier temps " << dernierTemps << " dernier deltat " << dernierdeltat; break; } case 3 : {cout << "\n iter= " << iboucle << " valfin1 "<< val_finale(1) << " exact " << cos(tfi) << " valfin2 "<< val_finale(2) << " exact " << -sin(tfi) << " err1 " << (val_finale(1)-cos(tfi)) << " err2 " << (val_finale(2)+sin(tfi)) << " estime " << erreur_maxi_global << " nb step " << nb_step << " nbappel " << nombreAppelF << " dertemps " << dernierTemps << " derdeltat " << dernierdeltat; break; } case 4 : {cout << "\n iter= " << iboucle << " valfin1 "<< val_finale(1) << " exact " << sin(tfi) << " valfin2 "<< val_finale(2) << " exact " << cos(tfi) << " err1 " << (val_finale(1)-sin(tfi)) << " err2 " << (val_finale(2)-cos(tfi)) << " estime " << erreur_maxi_global << " nb step " << nb_step << " nbappel " << nombreAppelF << " dertemps " << dernierTemps << " derdeltat " << dernierdeltat; break; } }; // prépa de la boucle suivante val_initiale=val_finale; der_initiale=der_finale; }; }; // fin programmé Sortie(1); }; //********************************************************************** // // Purpose: // // TIMESTAMP prints the current YMDHMS date as a time stamp. // // Example: // // May 31 2001 09:45:54 AM // // Modified: // // 24 September 2003 // // Author: // // John Burkardt // // Parameters: // // None // void Algo_edp::timestamp ( void ) { #define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; size_t len; time_t now; now = time ( NULL ); tm = localtime ( &now ); len = strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); cout << time_buffer << "\n"; return; #undef TIME_SIZE };