Herezh_dev/herezh_pp/tenseurs_mai99/Reperes_bases/Base_1.cc

185 lines
7.8 KiB
C++
Raw Normal View History

//#include "debug.h"
#include "Base.h"
#include "Util.h"
// 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/>.
//------- contient que les méthodes qui ne sont pas inline ---------
//===============================================================
// Les base covariantes et absolus
//===============================================================
// soient une base globale orthonormée : I_a et une base locale orthonormée I'_alpha
// pour l'instant: I_a est en 3 dimensions et alpha varie de 1 à 2
// soient une base naturelle g_alpha et duale associée g^beta
// telles que : I'_alpha appartient à l'espace des g_alpha ou g^beta
// on complète avec: I'_3 = I'_1 vectoriel I'_2
// A) on a:
// g^alpha = gamma(alpha,beta) * I'^beta c-a-d : gamma^alpha_beta
// NB: 1) comme I'est orthonormée: I'^beta = I'_beta
// 2) chaque ligne de gamma représente un g^alpha
// B) dans ce contexte on a:
// inverse de gamma -> une matrice beta et chaque colonne de beta représente
// les coordonnées de g_alpha dans I'^alpha
// c-a-d g_alpha = beta (delta,alpha) * I'_delta
// C) on peut également calculer les coordonnées de I'_beta dans le repère globale
// I'_beta = gamma(alpha,beta) * g_alpha
//
// la méthode calcule à partir de this qui correspond à g_alpha dans I_a:
// apB : g_alpha dans I'^alpha
// apH : g^alpha dans I'^alpha
// IpB : I'_beta dans I_a puis I'_3 = I'_1 vectoriel I'_2
void BaseB::ChangeBase_curviligne( const Mat_pleine& gamma, BaseB& apB , BaseH& apH, BaseB& IpB ) const
{// vérif en cas de mise au point
#ifdef MISE_AU_POINT
if (dimension!= 3)
{ cout << "\n erreur, la methode n'est pour l'instant utilisable que pour la dimension 3 "
<< "\nBaseB::ChangeBase_curviligne(..";
Sortie(1);
};
if ((gamma.Nb_ligne () != 2) || (gamma.Nb_colonne () != 2))
{ cout << "\n erreur, la matrice de passage gamma de nombre de ligne : " << gamma.Nb_ligne ()
<< ", et de nombre de colonne " << gamma.Nb_colonne ()
<< " doit avoir une dimension 2x2 : on ne traite pas les autres cas pour l'instant"
<< "\n BaseB::ChangeBase_curviligne(... ";
Sortie(1);
};
#endif
// 1) calcul de la base apB c-a-d de g_alpha dans la base I'
// calcul de alpha (delta,alpha)
Mat_pleine beta = gamma.Inverse();
// g_alpha = beta (delta,alpha) * I'_delta
int dim_i = gamma.Nb_ligne(); int dim_j = gamma.Nb_colonne(); // pour la généralisation éventuelle
for (int al = 1; al <= dim_i; al++)
for (int be = 1; be <= dim_j; be++)
apB.CoordoB(al)(be) = beta(be,al);
// 2) écriture de la base apH c-a-d de g^alpha dans la base I'
// g^alpha = gamma(alpha,beta) * I'^beta
for (int al = 1; al <= dim_i; al++)
for (int be = 1; be <= dim_j; be++)
apH.CoordoH(al)(be) = gamma(al,be);
// 3) calcul des coordonnées de I' dans I_a
for (int al = 1; al <= dim_i; al++)
{IpB.CoordoB(al).Zero();
for (int be = 1; be <= dim_j; be++)
IpB.CoordoB(al) += gamma(be,al) * v(be);
};
// dans le cas en dimension 3 on complète
if (ParaGlob::Dimension() == 3)
{ apB.CoordoB(1)(3) = apB.CoordoB(2)(3) = 0; // rien concernant la direction 3
if (apB.NbVecteur() == 3)
apB.CoordoB(3).Zero();
apH.CoordoH(1)(3) = apH.CoordoH(2)(3) = 0;
if (apH.NbVecteur() == 3)
apH.CoordoH(3).Zero();
IpB.CoordoB(3) = Util::ProdVec_coorB(IpB(1),IpB(2));
};
};
//===============================================================
// Les base duales
//===============================================================
// soient une base globale orthonormée : I_a et une base locale orthonormée I'_alpha
// pour l'instant: I_a est en 3 dimensions et alpha varie de 1 à 2
// soient une base naturelle g_alpha et duale associée g^beta
// telles que : I'_alpha appartient à l'espace des g_alpha ou g^beta
// A) on a:
// g^alpha = gamma(alpha,beta) * I'^beta c-a-d : gamma^alpha_beta
// NB: 1) comme I'est orthonormée: I'^beta = I'_beta
// 2) chaque ligne de gamma représente un g^alpha
// B) dans ce contexte on a:
// inverse de gamma -> une matrice beta et chaque ligne de beta représente
// les coordonnées de g_alpha dans I'^alpha
// c-a-d g_alpha = beta (delta,alpha) * I'_delta
// C) on peut également calculer les coordonnées de I'_beta dans le repère globale
// I'^beta = beta(beta,al) * g^alpha
//
// la méthode calcule à partir de this qui correspond à g^alpha dans I_a:
// apB : g_alpha dans I'^alpha
// apH : g^alpha dans I'^alpha
// IpBH : I'^beta dans I_a puis I'_3 = I'_1 vectoriel I'_2
void BaseH::ChangeBase_curviligne( const Mat_pleine& gamma, BaseB& apB , BaseH& apH, BaseH& IpH ) const
{// vérif en cas de mise au point
#ifdef MISE_AU_POINT
if (dimension!= 3)
{ cout << "\n erreur, la methode n'est pour l'instant utilisable que pour la dimension 3 "
<< "\nBaseH::ChangeBase_curviligne(..";
Sortie(1);
};
if ((gamma.Nb_ligne () != 2) || (gamma.Nb_colonne () != 2))
{ cout << "\n erreur, la matrice de passage gamma de nombre de ligne : " << gamma.Nb_ligne ()
<< ", et de nombre de colonne " << gamma.Nb_colonne ()
<< " doit avoir une dimension 2x2 : on ne traite pas les autres cas pour l'instant"
<< "\n BaseH::ChangeBase_curviligne(... ";
Sortie(1);
};
#endif
// 1) calcul de la base apB c-a-d de g_alpha dans la base I'
// calcul de alpha (delta,alpha)
Mat_pleine beta = gamma.Inverse();
// g_alpha = beta (delta,alpha) * I'_delta
int dim_i = gamma.Nb_ligne(); int dim_j = gamma.Nb_colonne(); // pour la généralisation éventuelle
for (int al = 1; al <= dim_i; al++)
for (int be = 1; be <= dim_j; be++)
apB.CoordoB(al)(be) = beta(be,al);
// 2) écriture de la base apH c-a-d de g^alpha dans la base I'
// g^alpha = gamma(alpha,beta) * I'^beta
for (int al = 1; al <= dim_i; al++)
for (int be = 1; be <= dim_j; be++)
apH.CoordoH(al)(be) = gamma(al,be);
// 3) calcul des coordonnées de I' dans I_a
for (int al = 1; al <= dim_i; al++)
{ IpH.CoordoH(al).Zero();
for (int be = 1; be <= dim_j; be++)
IpH.CoordoH(al) += beta(al,be) * v(be);
};
// dans le cas en dimension 3 on complète
if (ParaGlob::Dimension() == 3)
{ apB.CoordoB(1)(3) = apB.CoordoB(2)(3) = 0; // rien concernant la direction 3
if (apB.NbVecteur() == 3)
apB.CoordoB(3).Zero();
apH.CoordoH(1)(3) = apH.CoordoH(2)(3) = 0;
if (apH.NbVecteur() == 3)
apH.CoordoH(3).Zero();
IpH.CoordoH(3) = Util::ProdVec_coorH(IpH(1),IpH(2));
};
};