899 lines
28 KiB
C++
899 lines
28 KiB
C++
|
|
|
|
// 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/>.
|
|
|
|
|
|
//#include "Debug.h"
|
|
# include <iostream>
|
|
using namespace std; //introduces namespace std
|
|
#include "Tenseur1.h"
|
|
#include "MathUtil.h"
|
|
#include "ConstMath.h"
|
|
|
|
#ifndef Tenseur1_H_deja_inclus
|
|
//================================================================
|
|
// mixtes HB a une dimension
|
|
//================================================================
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1HB::Tenseur1HB():
|
|
ipointe()
|
|
{ dimension = 1;
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*t = 0.; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1HB::Tenseur1HB( const double val):
|
|
ipointe()
|
|
{ dimension = 1;
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*t = val; };
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1HB::~Tenseur1HB()
|
|
{ listdouble1.erase(ipointe); // suppression de l'élément de la liste
|
|
// cout << " appel du destructeur de 1HB \n";
|
|
};
|
|
// constructeur a partir d'une instance non differenciee
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1HB::Tenseur1HB ( const TenseurHB & B):
|
|
ipointe()
|
|
{ dimension = 1;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::Tenseur1HB ( etc..");
|
|
#endif
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*(this->t) = *(B.t);
|
|
};
|
|
|
|
// constructeur de copie
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1HB::Tenseur1HB ( const Tenseur1HB & B):
|
|
ipointe()
|
|
{ dimension = 1;
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*(this->t) = *(B.t);
|
|
};
|
|
// initialise toutes les composantes à val
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1HB::Inita(double val)
|
|
{*(this->t) =val;};
|
|
// operations
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::operator + ( const TenseurHB & B) const
|
|
{ TenseurHB * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator + ( etc..");
|
|
#endif
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) + *(B.t); //somme des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1HB::operator += ( const TenseurHB & B)
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator += ( etc..");
|
|
#endif
|
|
*(this->t) += *(B.t);}; //somme des données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::operator - () const
|
|
{ TenseurHB * res;
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = - *(this->t); //oppose
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::operator - ( const TenseurHB & B) const
|
|
{ TenseurHB * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator - ( etc..");
|
|
#endif
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) - *(B.t); //soustraction des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1HB::operator -= ( const TenseurHB & B)
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator -= ( etc..");
|
|
#endif
|
|
*(this->t) -= *(B.t);}; //soustraction des données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::operator = ( const TenseurHB & B)
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator = ( etc..");
|
|
#endif
|
|
*(this->t) = *(B.t); //affectation des données
|
|
LesMaillonsHB::Libere(); // destruction des tenseurs intermediaires
|
|
return *this; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::operator * ( const double & b) const
|
|
{ TenseurHB * res;
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) * b; //multiplication des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1HB::operator *= ( const double & b)
|
|
{ *(this->t) *= b;}; //multiplication des données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::operator / ( const double & b) const
|
|
{ TenseurHB * res;
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) / b; //division des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1HB::operator /= ( const double & b)
|
|
{ *(this->t) /= b;}; //division des données
|
|
// produit contracte avec un vecteur
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
CoordonneeH Tenseur1HB::operator * ( const CoordonneeH & B) const
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != dimension)
|
|
{ cout << "\nErreur : dimensions vecteur tenseur non egales !\n";
|
|
cout << " Tenseur1HB::operator *\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
CoordonneeH v(dimension);
|
|
v(1) = *(this->t) * B(1);
|
|
return v;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHH & Tenseur1HB::operator * ( const TenseurHH & B) const
|
|
{ TenseurHH * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator * ( etc..");
|
|
#endif
|
|
res = new Tenseur1HH;
|
|
LesMaillonsHH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = (*(this->t)) * (*(B.t)); //affectation des données
|
|
return *res ;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::operator * ( const TenseurHB & B) const
|
|
{ TenseurHB * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator * ( etc..");
|
|
#endif
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = (*(this->t)) * (*(B.t)); //affectation des données
|
|
return *res ;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1HB::operator && ( const TenseurHB & B) const
|
|
{ double result;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator && ( etc..");
|
|
#endif
|
|
result = (*(this->t)) * (*(B.t)); // contraction
|
|
return result;};
|
|
// test
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
int Tenseur1HB::operator == ( const TenseurHB & B) const
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator == ( etc..");
|
|
#endif
|
|
if (*(this->t) != *(B.t))
|
|
return 0 ;
|
|
else
|
|
return 1;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
int Tenseur1HB::operator != ( const TenseurHB & B) const
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1HB::operator != ( etc..");
|
|
#endif
|
|
if (*(this->t) == *(B.t))
|
|
return 0 ;
|
|
else
|
|
return 1;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::Inverse() const
|
|
{ TenseurHB * res;
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
#ifdef MISE_AU_POINT
|
|
if (Dabs(*(this->t)) <= ConstMath::trespetit)
|
|
{ cout << "\nErreur : la coordonnee du tenseur est nulle !\n";
|
|
cout << "Tenseur1HB::Inverse() \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
*(res->t) = 1./ (*(this->t));
|
|
return *res;
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
// si au contraire la dimension de B est plus grande que *this, il y a uniquement affectation
|
|
// des données possibles
|
|
void Tenseur1HB::Affectation_trans_dimension(const TenseurHB & B,bool plusZero)
|
|
{ // dans tous les cas il suffit de récupérer le premier élément et de l'affecter
|
|
this->t[0] = B.t[0]; //on affecte le seul terme disponible
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1HB::Trace() const
|
|
{ double result = *(this->t);
|
|
return result; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1HB::II() const
|
|
{ double result = (*(this->t)) * (*(this->t)) ;
|
|
return result; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1HB::III() const
|
|
{ double result = (*(this->t)) * (*(this->t)) * (*(this->t));
|
|
return result; };
|
|
|
|
// valeurs propre dans le vecteur de retour, classée par ordres "décroissants"
|
|
// cas indique le cas de valeur propre:
|
|
// quelque soit la dimension: cas = -1, si l'extraction des valeurs propres n'a pas pu se faire
|
|
// dans ce cas les valeurs propres de retour sont nulles par défaut
|
|
// dim = 1, cas=1 pour une valeur propre;
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Coordonnee Tenseur1HB::ValPropre(int& cas) const
|
|
{ Coordonnee ret(1); ret(1)=(*(this->t)); cas = 1;
|
|
return ret;
|
|
};
|
|
|
|
// idem met en retour la matrice mat contiend par colonne les vecteurs propre
|
|
// elle doit avoir la dimension du tenseur
|
|
// les vecteurs propre sont exprime dans le repere naturel
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Coordonnee Tenseur1HB::ValPropre(int& cas, Mat_pleine& mat) const
|
|
{ Coordonnee ret(1); ret(1)=(*(this->t));
|
|
#ifdef MISE_AU_POINT
|
|
if ((mat.Nb_ligne() != 1) || (mat.Nb_colonne() != 1))
|
|
{ cout << "\nErreur : la matrice en parametre doit etre de dimension "
|
|
<< 1 << " !\n";
|
|
cout << "Tenseur1HB::ValPropre( Mat_pleine& mat) \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
mat(1,1)=1.; // vecteur unitaire de l'axe
|
|
cas = 1;
|
|
return ret;
|
|
};
|
|
|
|
// ici il s'agit uniquement de calculer les vecteurs propres, les valeurs propres
|
|
// étant déjà connues
|
|
// en retour VP les vecteurs propre : doivent avoir la dimension du tenseur
|
|
// les vecteurs propre sont exprime dans le repere naturel (pour les tenseurs dim 3
|
|
// pour dim=2:le premier vecteur propre est exprime dans le repere naturel
|
|
// le second vecteur propre est exprimé dans le repère dual
|
|
// pour dim=1 le vecteur est dans la base naturelle (mais ça importe pas)
|
|
// en sortie cas = -1 s'il y a eu un problème, dans ce cas, V_P est quelconque
|
|
// sinon si tout est ok, cas est identique en sortie avec l'entrée
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1HB::VecteursPropres(const Coordonnee& valPropre,int& cas, Tableau <Coordonnee>& V_P) const
|
|
{ // on dimensionne en conséquence
|
|
Coordonnee toto(1); // un vecteur nul
|
|
V_P.Change_taille(1,toto); // tableau initialisé à 0
|
|
// ici dans tous les cas il s'agit du vecteur unitaire
|
|
V_P(1)(1)=1.;
|
|
cas = 1;
|
|
return;
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1HB::Det() const
|
|
{ double result = *(this->t);
|
|
return result; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1HB::Transpose() const
|
|
{ TenseurBH * res;
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon(res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t);
|
|
return *res;};
|
|
|
|
//fonctions static définissant le produit tensoriel de deux vecteurs
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::Prod_tensoriel(const CoordonneeB & aB, const CoordonneeH & bH)
|
|
{ TenseurBH * res;
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = aB(1)*bH(1);
|
|
return *res;};
|
|
|
|
// lecture et écriture de données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
istream & Tenseur1BH::Lecture(istream & entree)
|
|
{ // lecture et vérification du type
|
|
string nom_type;
|
|
entree >> nom_type;
|
|
if (nom_type != "Tenseur1BH")
|
|
{ Sortie(1);
|
|
return entree;
|
|
}
|
|
// lecture des coordonnées
|
|
entree >> (*(this->t));
|
|
return entree;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
ostream & Tenseur1BH::Ecriture(ostream & sort) const
|
|
{ // écriture du type
|
|
sort << "Tenseur1BH ";
|
|
// puis les datas
|
|
sort << setprecision (ParaGlob::NbdigdoCA()) << (*(this->t)) << " ";
|
|
return sort;
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
// surcharge de l'operator de lecture
|
|
istream & operator >> (istream & entree, Tenseur1HB & A)
|
|
{ int dim = A.Dimension();
|
|
#ifdef MISE_AU_POINT
|
|
if (dim != 1) A.Message(1,"operator >> (istream & entree, Tenseur1HB & A)");
|
|
#endif
|
|
// lecture et vérification du type
|
|
string nom_type;
|
|
entree >> nom_type;
|
|
if (nom_type != "Tenseur1HB")
|
|
{ Sortie(1);
|
|
return entree;
|
|
}
|
|
// lecture des coordonnées
|
|
entree >> (*A.t);
|
|
return entree;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
// surcharge de l'operator d'ecriture
|
|
ostream & operator << (ostream & sort , const Tenseur1HB & A)
|
|
{ // écriture du type
|
|
sort << "Tenseur1HB ";
|
|
// puis les datas
|
|
sort << setprecision(ParaGlob::NbdigdoCA()) << (*A.t) << " ";
|
|
return sort;
|
|
};
|
|
|
|
//================================================================
|
|
// mixtes BH a une dimension
|
|
//================================================================
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1BH::Tenseur1BH():
|
|
ipointe()
|
|
{ dimension = 1;
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*t = 0.; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1BH::Tenseur1BH( const double val):
|
|
ipointe()
|
|
{ dimension = 1;
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*t = val; };
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1BH::~Tenseur1BH()
|
|
{ listdouble1.erase(ipointe); // suppression de l'élément de la liste
|
|
// cout << " appel du destructeur de 1BH \n";
|
|
};
|
|
// constructeur a partir d'une instance non differenciee
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1BH::Tenseur1BH ( const TenseurBH & B) :
|
|
ipointe()
|
|
{ dimension = 1;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::Tenseur1BH ( etc..");
|
|
#endif
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*(this->t) = *(B.t);
|
|
};
|
|
// constructeur de copie
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Tenseur1BH::Tenseur1BH ( const Tenseur1BH & B):
|
|
ipointe()
|
|
{ dimension = 1;
|
|
listdouble1.push_front(Reels1()); // allocation
|
|
ipointe = listdouble1.begin(); // recup de la position de la maille dans la liste
|
|
t = &((ipointe)->donnees); // recup de la position des datas dans la maille
|
|
*(this->t) = *(B.t);
|
|
};
|
|
// initialise toutes les composantes à val
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1BH::Inita(double val)
|
|
{*(this->t) =val;};
|
|
// operations
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::operator + ( const TenseurBH & B) const
|
|
{ TenseurBH * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator + ( etc..");
|
|
#endif
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) + *(B.t); //somme des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1BH::operator += ( const TenseurBH & B)
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator += ( etc..");
|
|
#endif
|
|
*(this->t) += *(B.t);}; //somme des données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::operator - () const
|
|
{ TenseurBH * res;
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = - *(this->t); //oppose
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::operator - ( const TenseurBH & B) const
|
|
{ TenseurBH * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator + ( etc..");
|
|
#endif
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) - *(B.t); //soustraction des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1BH::operator -= ( const TenseurBH & B)
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator -= ( etc..");
|
|
#endif
|
|
*(this->t) -= *(B.t);}; //soustraction des données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::operator = ( const TenseurBH & B)
|
|
{ *(this->t) = *(B.t); //affectation des données
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1)
|
|
Message(1,"Tenseur1BH::operator = ( etc..");
|
|
#endif
|
|
LesMaillonsBH::Libere(); // destruction des tenseurs intermediaires
|
|
return *this; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::operator * ( const double & b) const
|
|
{ TenseurBH * res;
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) * b; //multiplication des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1BH::operator *= ( const double & b)
|
|
{ *(this->t) *= b;}; //multiplication des données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::operator / ( const double & b) const
|
|
{ TenseurBH * res;
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t) / b; //division des données
|
|
return *res;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1BH::operator /= ( const double & b)
|
|
{ *(this->t) /= b;}; //division des données
|
|
|
|
//#ifndef MISE_AU_POINT
|
|
// inline
|
|
//#endif
|
|
//// affectation de B dans this, les données en trop sont ignorées
|
|
//void Tenseur1BH::Affectation_3D_a_1D(const Tenseur3BH & B)
|
|
//{ this->t[0] = B.t[0];};
|
|
|
|
// produit contracte avec un vecteur
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
CoordonneeB Tenseur1BH::operator * ( const CoordonneeB & B) const
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != dimension)
|
|
{ cout << "\nErreur : dimensions vecteur tenseur non egales !\n";
|
|
cout << " Tenseur1BH::operator *\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
CoordonneeB v(dimension);
|
|
v(1) = *(this->t) * B(1);
|
|
return v;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBB & Tenseur1BH::operator * ( const TenseurBB & B) const
|
|
{ TenseurBB * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator * ( etc..");
|
|
#endif
|
|
res = new Tenseur1BB;
|
|
LesMaillonsBB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = (*(this->t)) * (*(B.t)); //affectation des données
|
|
return *res ;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::operator * ( const TenseurBH & B) const
|
|
{ TenseurBH * res;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator * ( etc..");
|
|
#endif
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = (*(this->t)) * (*(B.t)); //affectation des données
|
|
return *res ;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1BH::operator && ( const TenseurBH & B) const
|
|
{ double result;
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator && ( etc..");
|
|
#endif
|
|
result = (*(this->t)) * (*(B.t)); // contraction
|
|
return result;};
|
|
// test
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
int Tenseur1BH::operator == ( const TenseurBH & B) const
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator == ( etc..");
|
|
#endif
|
|
if (*(this->t) != *(B.t))
|
|
return 0 ;
|
|
else
|
|
return 1;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
int Tenseur1BH::operator != ( const TenseurBH & B) const
|
|
{
|
|
#ifdef MISE_AU_POINT
|
|
if (B.Dimension() != 1) Message(1,"Tenseur1BH::operator != ( etc..");
|
|
#endif
|
|
if (*(this->t) == *(B.t))
|
|
return 0 ;
|
|
else
|
|
return 1;};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurBH & Tenseur1BH::Inverse() const
|
|
{ TenseurBH * res;
|
|
res = new Tenseur1BH;
|
|
LesMaillonsBH::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
#ifdef MISE_AU_POINT
|
|
if (Dabs(*(this->t)) <= ConstMath::trespetit)
|
|
{ cout << "\nErreur : la coordonnee du tenseur est nulle !\n";
|
|
cout << "Tenseur1BH::Inverse() \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
*(res->t) = 1./ (*(this->t));
|
|
return *res;
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
// affectation de B dans this, plusZero = false: les données manquantes sont inchangées,
|
|
// plusZero = true: les données manquantes sont mises à 0
|
|
// si au contraire la dimension de B est plus grande que *this, il y a uniquement affectation
|
|
// des données possibles
|
|
void Tenseur1BH::Affectation_trans_dimension(const TenseurBH & B,bool plusZero)
|
|
{ // dans tous les cas il suffit de récupérer le premier élément et de l'affecter
|
|
this->t[0] = B.t[0]; //on affecte le seul terme disponible
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1BH::Trace() const
|
|
{ double result = *(this->t);
|
|
return result; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1BH::II() const
|
|
{ double result = (*(this->t)) * (*(this->t)) ;
|
|
return result; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1BH::III() const
|
|
{ double result = (*(this->t)) * (*(this->t)) * (*(this->t));
|
|
return result; };
|
|
|
|
// valeurs propre dans le vecteur de retour, classée par ordres "décroissants"
|
|
// cas indique le cas de valeur propre:
|
|
// quelque soit la dimension: cas = -1, si l'extraction des valeurs propres n'a pas pu se faire
|
|
// dans ce cas les valeurs propres de retour sont nulles par défaut
|
|
// dim = 1, cas=1 pour une valeur propre;
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Coordonnee Tenseur1BH::ValPropre(int& cas) const
|
|
{ Coordonnee ret(1); ret(1)=(*(this->t)); cas =1;
|
|
return ret;
|
|
};
|
|
|
|
// idem met en retour la matrice mat contiend par colonne les vecteurs propre
|
|
// elle doit avoir la dimension du tenseur
|
|
// les vecteurs propre sont exprime dans le repere naturel
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
Coordonnee Tenseur1BH::ValPropre(int& cas, Mat_pleine& mat) const
|
|
{ Coordonnee ret(1); ret(1)=(*(this->t));
|
|
#ifdef MISE_AU_POINT
|
|
if ((mat.Nb_ligne() != 1) || (mat.Nb_colonne() != 1))
|
|
{ cout << "\nErreur : la matrice en parametre doit etre de dimension "
|
|
<< 1 << " !\n";
|
|
cout << "Tenseur1BH::ValPropre( Mat_pleine& mat) \n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
mat(1,1)=1.; // vecteur unitaire de l'axe
|
|
cas = 1;
|
|
return ret;
|
|
};
|
|
|
|
// ici il s'agit uniquement de calculer les vecteurs propres, les valeurs propres
|
|
// étant déjà connues
|
|
// en retour VP les vecteurs propre : doivent avoir la dimension du tenseur
|
|
// les vecteurs propre sont exprime dans le repere naturel (pour les tenseurs dim 3
|
|
// pour dim=2:le premier vecteur propre est exprime dans le repere naturel
|
|
// le second vecteur propre est exprimé dans le repère dual
|
|
// pour dim=1 le vecteur est dans la base naturelle (mais ça importe pas)
|
|
// en sortie cas = -1 s'il y a eu un problème, dans ce cas, V_P est quelconque
|
|
// sinon si tout est ok, cas est identique en sortie avec l'entrée
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
void Tenseur1BH::VecteursPropres(const Coordonnee& valPropre,int& cas, Tableau <Coordonnee>& V_P) const
|
|
{ // on dimensionne en conséquence
|
|
Coordonnee toto(1); // un vecteur nul
|
|
V_P.Change_taille(1,toto); // tableau initialisé à 0
|
|
// ici dans tous les cas il s'agit du vecteur unitaire
|
|
V_P(1)(1)=1.;
|
|
cas = 1;
|
|
return;
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
double Tenseur1BH::Det() const
|
|
{ double result = *(this->t);
|
|
return result; };
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1BH::Transpose() const
|
|
{ TenseurHB * res;
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon(res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = *(this->t);
|
|
return *res;};
|
|
|
|
//fonctions static définissant le produit tensoriel de deux vecteurs
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
TenseurHB & Tenseur1HB::Prod_tensoriel(const CoordonneeH & aH, const CoordonneeB & bB)
|
|
{ TenseurHB * res;
|
|
res = new Tenseur1HB;
|
|
LesMaillonsHB::NouveauMaillon( res); // ajout d'un tenseur intermediaire
|
|
*(res->t) = aH(1)*bB(1);
|
|
return *res;};
|
|
|
|
// lecture et écriture de données
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
istream & Tenseur1HB::Lecture(istream & entree)
|
|
{ // lecture et vérification du type
|
|
string nom_type;
|
|
entree >> nom_type;
|
|
if (nom_type != "Tenseur1HB")
|
|
{ Sortie(1);
|
|
return entree;
|
|
}
|
|
// lecture des coordonnées
|
|
entree >> (*(this->t));
|
|
return entree;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
ostream & Tenseur1HB::Ecriture(ostream & sort) const
|
|
{ // écriture du type
|
|
sort << "Tenseur1HB ";
|
|
// puis les datas
|
|
sort << setprecision (ParaGlob::NbdigdoCA()) << (*(this->t)) << " ";
|
|
return sort;
|
|
};
|
|
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
// surcharge de l'operator de lecture
|
|
istream & operator >> (istream & entree, Tenseur1BH & A)
|
|
{ int dim = A.Dimension();
|
|
#ifdef MISE_AU_POINT
|
|
if (dim != 1) A.Message(1,"operator >> (istream & entree, Tenseur1BH & A)");
|
|
#endif
|
|
// lecture et vérification du type
|
|
string nom_type;
|
|
entree >> nom_type;
|
|
if (nom_type != "Tenseur1BH")
|
|
{ Sortie(1);
|
|
return entree;
|
|
}
|
|
// lecture des coordonnées
|
|
entree >> (*A.t);
|
|
return entree;
|
|
};
|
|
#ifndef MISE_AU_POINT
|
|
inline
|
|
#endif
|
|
// surcharge de l'operator d'ecriture
|
|
ostream & operator << (ostream & sort , const Tenseur1BH & A)
|
|
{ // écriture du type
|
|
sort << "Tenseur1BH ";
|
|
// puis les datas
|
|
sort << setprecision(ParaGlob::NbdigdoCA()) << (*A.t) << " ";
|
|
return sort;
|
|
};
|
|
|
|
|
|
#endif
|
|
|