Herezh_dev/Resolin/Matrices/Mat_abstraite.h

425 lines
22 KiB
C
Raw Normal View History

2021-09-28 17:28:23 +02:00
// FICHIER : Mat_abstraite.h
// CLASSE : Mat_abstraite
// 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) <https://www.irdl.fr/>.
//
// 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 <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
/************************************************************************
* DATE: 23/01/97 *
* $ *
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
* $ *
* PROJET: Herezh++ *
* $ *
************************************************************************
* La classe Mat_abstraite est une classe abstraite qui permet de cacher les
* implementations specifiques a un type particulier de matrices.
* Cette classe fournit un ensemble de methodes qui seront implementees dans
* les classes derivees caracterisant un type particulier de matrice.
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS: *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* $ *
************************************************************************/
// La classe Mat_abstraite est une classe abstraite qui permet de cacher les
// implementations specifiques a un type particulier de matrices.
// Cette classe fournit un ensemble de methodes qui seront implementees dans
// les classes derivees caracterisant un type particulier de matrice.
#ifndef MAT_ABSTRAITE_H
#define MAT_ABSTRAITE_H
#include "mvvtp_GR.h" // classe template MV++
#include "Vecteur.h"
#include "Tableau_T.h"
#include "Enum_matrice.h"
#include "Enum_type_resolution_matri.h"
#include "ExceptionsMatrices.h"
#include "Coordonnee3.h"
class VeurPropre;
/** @defgroup Les_classes_Matrices
*
* BUT: les différentes classes de matrices.
*
*
* \author Gérard Rio
* \version 1.0
* \date 23/01/97
* \brief les différentes classes de matrices.
*
*/
/// @addtogroup Les_classes_Matrices
/// @{
///
class Mat_abstraite
{
protected :
// grandeur par défaut déclarées avant car on s'en sert dans les passages de paramètres
static const double tol_defaut; // tolérance sur le résidu dans les méthodes itératives
static const int maxit_defaut ; // maximum d'itération dans les méthodes itératives
static const int restart_defaut ;// maximum de restart itération (nb de vecteur sauvegardé)
public :
// Constructeur par défaut
Mat_abstraite (Enum_matrice type_mat = RIEN_MATRICE,
Enum_type_resolution_matri type_resol=RIEN_TYPE_RESOLUTION_MATRI,
Enum_preconditionnement type_precondi= RIEN_PRECONDITIONNEMENT ):
type_matrice(type_mat),type_resolution(type_resol),
type_preconditionnement(type_precondi)
{}
// de copie
Mat_abstraite (const Mat_abstraite& a) :
type_matrice(a.type_matrice),type_resolution(a.type_resolution),
type_preconditionnement(a.type_preconditionnement)
{};
// DESTRUCTEUR VIRTUEL :
virtual ~Mat_abstraite ()
{};
// METHODES VIRTUELLES PURES :
// surcharge de l'opérateur d'affectation
// IMPORTANT : le fonctionnement de l'implantation dépend de la classe
// dérivée : en particulier il peut y avoir redimentionnement automatique
// de la matrice en fonction de l'attribut, cas par exemple des matrices
// pleines, ou message d'erreur car les tailles ne sont pas identiques
// exemple de la classe mat_band
virtual Mat_abstraite & operator = ( const Mat_abstraite &) = 0;
// transfert des informations de *this dans la matrice passée en paramètre
// la matrice paramètre est au préalable, mise à 0.
virtual void Transfert_vers_mat( Mat_abstraite & A ) = 0;
//-----------------------------------------------------------------------------------
// --- plusieurs fonctions virtuelles qui agissent en général sur la matrice ---------
//-----------------------------------------------------------------------------------
// ici l'idée est d'éviter de construire une nouvelle matrice pour des questions
// d'encombrement, c'est surtout des méthodes utiles pour le stockage de matrice
// de raideur. On met le nombre mini de fonction, pour pouvoir faire des expressions.
// Cependant aucune de ces fonctions n'est en désaccord avec les fonctions membres
// qui crée une matrice en résultat (cf. Mat_pleine)
// pour les 2 premières méthodes : += et -= :
// les matrices arguments sont en général du mêmes type que celui de la matrice this
// mais cela fonctionne également avec comme argument une matrice diagonale (pour tous les types)
// Surcharge de l'operateur += : addition d'une matrice a la matrice courante
virtual void operator+= (const Mat_abstraite& mat_pl) = 0;
// Surcharge de l'operateur -= : soustraction d'une matrice a la matrice courante
virtual void operator-= (const Mat_abstraite& mat_pl) = 0;
// Surcharge de l'operateur *= : multiplication de la matrice courante par un scalaire
virtual void operator*= (const double r) = 0;
//------------------------------------------------------------------------------------
// --- fin de plusieurs fonctions virtuelles qui agissent en général sur la matrice --
//------------------------------------------------------------------------------------
// Surcharge de l'operateur == : test d'egalite entre deux matrices
virtual int operator== (const Mat_abstraite& mat_pl) const =0;
inline int operator!= (const Mat_abstraite& mat_pl) const
// Surcharge de l'operateur != : test de non egalite entre deux matrices
// Renvoie 1 si les deux matrices ne sont pas egales
// Renvoie 0 sinon
{ if ( (*this)==mat_pl )
return 0;
else
return 1;
};
// fonction permettant de creer une nouvelle instance d'element
// dérivé. la nouvelle instance = *this, il y a donc utilisation du constructeur de copie
virtual Mat_abstraite * NouvelElement() const = 0;
// Affichage des valeurs de la matrice
virtual void Affiche () const =0;
// Initialisation des valeurs des composantes
virtual void Initialise (double val_init) =0;
// Liberation de la place memoire
virtual void Libere () =0;
// Retour du nombre de lignes de la matrice vue comme une matrice_rectangulaire
virtual int Nb_ligne() const =0;
// Retour du nombre de colonnes de la matrice vue comme une matrice_rectangulaire
virtual int Nb_colonne() const =0;
// Symetrie de la matrice
virtual int Symetrie () const =0;
// Acces aux valeurs de la matrices en écriture
// i : indice de ligne, j : indice de colonne
virtual double& operator () (int i, int j) =0;
// ramène true si la place (i,j) existe, false sinon
// ici on ne test pas le fait que i et j puissent être négatif ou pas
virtual bool Existe(int i, int j) const = 0;
// Acces aux valeurs de la matrices en lecture
// cas ou l'on ne veut pas modifier les valeurs
// i : indice de ligne, j : indice de colonne
// !!! important, si l'élément n'existe pas du au type de stockage
// utilisé, (mais que les indices sont possible) le retour est 0
virtual double operator () ( int i, int j) const =0;
// Retourne la ieme ligne de la matrice
// lorsque implemente ( a verifier )
virtual Vecteur& Ligne_set(int i) = 0;
// Retourne la ieme ligne de la matrice
virtual Vecteur Ligne(int i) const = 0;
// Retourne la ieme ligne de la matrice
// sous le format de stokage propre a la matrice
// donc a n'utiliser que comme sauvegarde en parralele
// avec la fonction RemplaceLigne
virtual Vecteur LigneSpe(int i) const = 0;
// remplace la ligne de la matrice par la ligne fournie
virtual void RemplaceLigneSpe(int i,const Vecteur & v) = 0;
//met une valeur identique sur toute la ligne
virtual void MetValLigne(int i,double val) = 0;
// Retourne la jeme colonne de la matrice
virtual Vecteur Colonne(int j) const = 0;
// Retourne la jeme colonne de la matrice
// sous le format de stokage propre a la matrice
// donc a n'utiliser que comme sauvegarde en parralele
// avec la fonction RemplaceColonne
virtual Vecteur ColonneSpe(int j) const = 0;
// remplace la Colonne de la matrice par la colonne fournie
virtual void RemplaceColonneSpe(int j,const Vecteur & v) = 0;
//met une valeur identique sur toute la colonne
virtual void MetValColonne(int j,double val) = 0;
// Resolution du systeme Ax=b
//1) avec en sortie un new vecteur
virtual Vecteur Resol_syst (const Vecteur& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) =0;
//2) avec en sortie le vecteur d'entree
virtual Vecteur& Resol_systID (Vecteur& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) =0;
//3) avec en entrée un tableau de vecteur second membre et
// en sortie un nouveau tableau de vecteurs
virtual Tableau <Vecteur> Resol_syst
(const Tableau <Vecteur>& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) =0;
//4) avec en entrée un tableau de vecteur second membre et
// en sortie le tableau de vecteurs d'entree
virtual Tableau <Vecteur>& Resol_systID
(Tableau <Vecteur>& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) =0;
//5) avec en sortie le dernier vecteur d'entree, le premier étant le second membre
// et restant inchangé, en sortie c'est donc soit le retour ou soit vortie, les
// deux étant identiques
virtual Vecteur& Resol_systID_2 (const Vecteur& b,Vecteur& vortie
, const double &tol = tol_defaut
,const int maxit = maxit_defaut
,const int restart = restart_defaut) =0;
// ===== RÉSOLUTION EN DEUX TEMPS ================ :
// 1) préparation de la matrice donc modification de la matrice éventuellement
// par exemple pour les matrices bandes avec cholesky : triangulation
virtual void Preparation_resol() =0 ;
// 2) *** résolution sans modification de la matrice DOIT ÊTRE PRÉCÉDÉ DE L'APPEL DE
// Preparation_resol
// a) avec en sortie un new vecteur
virtual Vecteur Simple_Resol_syst (const Vecteur& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) const =0 ;
// b) avec en sortie le vecteur d'entree
virtual Vecteur& Simple_Resol_systID (Vecteur& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) const =0 ;
// c) avec en entrée un tableau de vecteur second membre et
// en sortie un nouveau tableau de vecteurs
virtual Tableau <Vecteur> Simple_Resol_syst
(const Tableau <Vecteur>& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) const =0 ;
// d) avec en entrée un tableau de vecteur second membre et
// en sortie le tableau de vecteurs d'entree
virtual Tableau <Vecteur>& Simple_Resol_systID
(Tableau <Vecteur>& b,const double &tol = tol_defaut
,const int maxit = maxit_defaut,const int restart = restart_defaut) const =0 ;
// e) avec en sortie le dernier vecteur d'entree, le premier étant le second membre
// et restant inchangé, en sortie c'est donc soit le retour ou soit vortie, les
// deux étant identiques
virtual Vecteur& Simple_Resol_systID_2 (const Vecteur& b,Vecteur& vortie
, const double &tol = tol_defaut
,const int maxit = maxit_defaut
,const int restart = restart_defaut) const =0 ;
// ===== FIN RÉSOLUTION EN DEUX TEMPS ================ :
// Multiplication d'un vecteur par une matrice ( (vec)t * A )
virtual Vecteur Prod_vec_mat ( const Vecteur& vec) const =0;
// idem mais on utilise la place du second vecteur pour le résultat
virtual Vecteur& Prod_vec_mat ( const Vecteur& vec, Vecteur & resul) const =0;
// Multiplication d'une matrice par un vecteur ( A * vec )
virtual Vecteur Prod_mat_vec ( const Vecteur& vec) const =0;
// idem mais on utilise la place du second vecteur pour le résultat
virtual Vecteur& Prod_mat_vec ( const Vecteur& vec, Vecteur & resul) const =0;
// Multiplication d'une ligne iligne de la matrice avec un vecteur de
// dimension = le nombre de colonne de la matrice
virtual double Prod_Ligne_vec ( int iligne,const Vecteur& vec) const =0;
// Multiplication d'un vecteur avec une colonne icol de la matrice
// dimension = le nombre de ligne de la matrice
virtual double Prod_vec_col( int icol,const Vecteur& vec) const =0;
// calcul du produit : (vec_1)^T * A * (vect_2)
virtual double vectT_mat_vec(const Vecteur& vec1, const Vecteur& vec2) const =0;
// retourne la place que prend la matrice en entier
virtual int Place() const = 0;
// ------------ méthode non virtuelle pur -> générales ----------------
// Affiche une partie de la matrice (util pour le debug)
// min_ et max_ sont les bornes de la sous_matrice
// pas_ indique le pas en i et j pour les indices
virtual void Affiche1(int min_i,int max_i,int pas_i,int min_j,int max_j,int pas_j) const ;
// Affiche une partie de la matrice idem si dessus
// mais avec un nombre de digit (>7) = nd
// si < 7 ne fait rien
virtual void Affiche2
(int min_i,int max_i,int pas_i,int min_j,int max_j,int pas_j,int nd) const ;
// changement du choix de la méthode de résolution si c'est possible
// peut être surchargé par les classes dérivées en fonction des spécificités
virtual void Change_Choix_resolution(Enum_type_resolution_matri type_resol,
Enum_preconditionnement type_precondi)
{ type_resolution = type_resol; type_preconditionnement = type_precondi;};
// retourne le type de la matrice
inline const Enum_matrice Type_matrice() const {return type_matrice;};
// affichage à l'écran après une demande interactive de la matrice
// entete: une chaine explicative, a afficher en entête
void Affichage_ecran(string entete) const;
// calcul, récupération et affichage éventuelle
// des mini, maxi, et en valeur absolue la moyenne de la diagonale de la matrice
// en retour: le min, le max et la moyenne en valeur absolue
Coordonnee3 MinMaxMoy(bool affiche) const;
// limite la valeur mini de la diagonale: si un terme de la diagonale
// est inférieure à la limite passée en argument (seuil_bas), d'une manière arbitraire
// le terme à mis à une valeur égale au paramètre passé en paramètre val_a_imposer
// s'il y a eu changement retour de true
bool Limitation_min_diag(double seuil_bas, double val_a_imposer) ;
//====== quelques méthodes spécifiques à la classe MV_Vector<double>==============
// définie la surcharge de multiplication d'une matrice par un MV_Vector
// ici de type constant, ramène un nouveau MV_Vector<double>
MV_Vector <double> operator * (const MV_Vector <double> & vec) const ;
// multiplication matrice transposée fois vecteur ce qui est équivalent à
// la transposée du résultat de : multiplication vecteur transposé fois matrice
virtual MV_Vector <double> trans_mult(const MV_Vector <double> &x) const ;
//====== fin des quelques méthodes spécifiques à la classe MV_Vector <double>=======
//calcul des valeurs propres par la méthode des puissances itérées
// inverses.
// --> Utilisable que pour des matrices carrées
// Intéressant lorsque l'on veut les plus petites
// valeurs propres, en nombre restreind car seule les premières valeurs
// sont calculées avec une précision convenable. On obtiend également
// les vecteurs propres correspondant.
// résolution de : ((*this) - lambda KG) X = 0
// en entrée : KG, VP dont la dimension est défini et fourni le nombre
// de valeurs propres que l'on veut calculer
// On considère que les conditions limites sont déjà appliquées à (*this) et KG.
// c'est à dire des 1 sur la diagonale pour (*this) et des 0 sur la diagonale pour KG
// en sortie : VP contiend les valeurs propres et vecteurs propres
Tableau <VeurPropre>* V_Propres(Mat_abstraite& KG,Tableau <VeurPropre> & VP );
protected :
// VARIABLES PROTEGEES :
Enum_matrice type_matrice; // le type de la matrice, défini dans les classes dérivée
Enum_type_resolution_matri type_resolution; // le type de résolution envisagée
Enum_preconditionnement type_preconditionnement; // le type éventuelle de préconditionnement
// pour la méthode "résidu minimal généralisé"
// Méthodes protégées :
// Resolution du systeme Ax=b , méthodes générales pouvant être appelées par les classes dérivée
// en entrée : b : comme second membre
// tol : tolérance sur le résidu
// maxit : le maximum d'itération
// restart : le Maximum de restart iterations (vecteur sauvegardé) dans le cas
// de la méthode résidu minimal généralisé (GENE_MINI_RESIDUAL)
// en sortie : sol de même dimension que sol
void Resolution_syst
(const Vecteur &b, Vecteur &sol,const double &tol, const int maxit = 300
, const int restart = 32) const ;
// idem avec en entrée un tableau de vecteur second membre et
// en sortie un tableau de vecteurs solution
void Resolution_syst
(const Tableau <Vecteur>& b, Tableau <Vecteur> &sol,const double &tol
, const int maxit = 300
, const int restart = 32) const ;
};
/// @} // end of group
#include "VeurPropre.h"
#endif