442 lines
22 KiB
C++
442 lines
22 KiB
C++
// 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-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 <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
|
|
|
|
#ifdef UTILISATION_MPI
|
|
#include <boost/archive/text_oarchive.hpp>
|
|
#include <boost/archive/text_iarchive.hpp>
|
|
#endif
|
|
|
|
#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é"
|
|
|
|
#ifdef UTILISATION_MPI
|
|
friend class boost::serialization::access;
|
|
// When the class Archive corresponds to an output archive, the
|
|
// & operator is defined similar to <<. Likewise, when the class Archive
|
|
// is a type of input archive the & operator is defined similar to >>.
|
|
template<class Archive>
|
|
void serialize(Archive & ar, const unsigned int version)
|
|
{
|
|
ar & type_matrice;
|
|
ar & type_resolution;
|
|
ar & type_preconditionnement;
|
|
}
|
|
#endif
|
|
// 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
|
|
|
|
|