// FICHIER : CoordonneeB.cp
// CLASSE : CoordonneeB
// 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-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 .
//
// For more information, please consult: .
//#include "Debug.h"
# include
using namespace std; //introduces namespace std
#include
#include "Sortie.h"
#include "ConstMath.h"
#include "MathUtil.h"
#include
#include "ParaGlob.h"
#include "Coordonnee.h"
#ifndef COORDONNEE_H_deja_inclus
// Constructeur par defaut
// avant ->// N.B. : la dimension est affectee a 3 et les valeurs a 0
#ifndef MISE_AU_POINT
inline
#endif
CoordonneeB::CoordonneeB () :
dim (0) , coord (NULL),memoire(true)
{};
// Constructeur utile si le nombre de coordonnees est connue
// N.B. : les valeurs sont affectees a 0.0
#ifndef MISE_AU_POINT
inline
#endif
CoordonneeB::CoordonneeB (int dimension) :
dim ((short)dimension),memoire(true)
{
#ifdef MISE_AU_POINT
if ( (dimension<1) || (dimension>3) )
{
cout << "\nErreur de dimension !\n";
cout << "CoordonneeB::CoordonneeB (int ) \n";
Sortie(1);
};
#endif
coord=new double [dim];
for (int i=0;i 0)
{ delete [] coord;
coord=NULL;
dim=0;
}
#ifdef MISE_AU_POINT
else
{if ( coord!=NULL )
{ cout << "\nErreur de liberation de la place memoire\n";
cout << "CoordonneeB::LIBERE () \n";
Sortie(1);
}
}
#endif
}
};
// construction "explicite" à partir d'une instance de CoordonneeB
// intéressant si this est initialement construit par defaut (donc vide)
// cela permet de créer un CoordonneeH à partir d'un B, mais de manière explicite,
// donc activé quand on le veux (et non pas par le compilo au gré de conversion pas toujours clair!!)
#ifndef MISE_AU_POINT
inline
#endif
void CoordonneeB::ConstructionAPartirDe_H(const CoordonneeH& aH)
{ if (dim != aH.dim) Change_dim(aH.dim);
memoire = true;
dim = aH.dim;
switch (dim)
{ case 3 : coord[2] = aH.coord[2];
case 2 : coord[1] = aH.coord[1];
case 1 : coord[0] = aH.coord[0];
case 0 : ; // on ne fait rien
};
};
#ifndef MISE_AU_POINT
inline
#endif
// change les valeurs en fonction d'un point sans variance
void CoordonneeB::Change_val(const Coordonnee& c)
{ int c_dim = c.Dimension();
if (dim != c_dim) Change_dim(c_dim);
memoire = true;
dim = c_dim;
switch (dim)
{ case 3 : coord[2] = c(3);
case 2 : coord[1] = c(2);
case 1 : coord[0] = c(1);
case 0 : ; // on ne fait rien
};
};
// Renvoie le nombre de coordonnees
#ifndef MISE_AU_POINT
inline
#endif
int CoordonneeB::Dimension () const
{ return dim; };
// Desallocation de la place memoire allouee
#ifndef MISE_AU_POINT
inline
#endif
void CoordonneeB::Libere ()
{ if ( dim>0 )
delete [] coord;
else
{if ( coord!=NULL )
{ cout << "\nErreur de liberation de la place memoire\n";
cout << "CoordonneeB::LIBERE () \n";
Sortie(1);
}
}
coord=NULL;
dim=0;
};
// Renvoie la ieme coordonnee
#ifndef MISE_AU_POINT
inline
#endif
double& CoordonneeB::operator() (int i)
{
#ifdef MISE_AU_POINT
if ( (i<1) || (i>dim) )
{ cout << "\nErreur de dimension !\n";
cout << "CoordonneeB::OPERATOR() (int ) \n";
Sortie(1);
};
#endif
return coord[i-1];
};
// Renvoie une copie de la ieme coordonnee
#ifndef MISE_AU_POINT
inline
#endif
double CoordonneeB::operator() (int i) const
{
#ifdef MISE_AU_POINT
if ( (i<1) || (i>dim) )
{ cout << "\nErreur de dimension !\n";
cout << "CoordonneeB::OPERATOR() (int ) \n";
Sortie(1);
};
#endif
return coord[i-1];
};
// changement de la dimension
// dans le cas d'une nouvelle dimension inferieur on supprime les dernieres coord
// dans le cas d'une dimension superieur, on ajoute des coord initialisees a zero`
#ifndef MISE_AU_POINT
inline
#endif
void CoordonneeB::Change_dim(int dimen)
{
#ifdef MISE_AU_POINT
if ((dimen<1) || (dimen>3))
{ cout << "\n erreur, la nouvelle dimension doit etre comprise entre 1 et 3 ! ";
cout << "\n dim voulue = " << dimen ;
cout << "\nCoordonneeB::Change_dim(int dim) " << endl;
Sortie(1);
}
#endif
double * sauve = coord;
if (dim < dimen)
{ coord = new double [dimen];
for (int i=0;i dimen)
{ coord = new double [dimen];
for (int i=0;idim-1; i++)
sort << setw (nb) << this->coord[i] << " ";
};
// conversion explicite en coordonnées sans variance
#ifndef MISE_AU_POINT
inline
#endif
Coordonnee CoordonneeB::Coor()const
// ici on pourrait optimiser en créant un coordonnée const, avec la mémoire au même endroit
// non !!! car this pourrait ne plus exister alors que le retour continue à exister !! donc pas bon
{ switch (dim)
{ case 1: {return Coordonnee(coord[0]); break;}
case 2: {return Coordonnee(coord[0],coord[1]); break;}
case 3: {return Coordonnee(coord[0],coord[1],coord[2]); break;}
default:
{ cout << "\n erreur de dimension: dim= " << dim
<< " il n'est pas possible de transformer en Coordonnee !"
<< "\n CoordonneeB::Coor()const" ;
Sortie(1);
};
};
return Coordonnee(0.); // pour éviter le warning
};
// création explicite en coordonnées sans variance
// mais le vecteur est à la même place pour un coût de construction minimum,
// il est accessible en lecture uniquement
#ifndef MISE_AU_POINT
inline
#endif
const Coordonnee CoordonneeB::Coor_const()const
{ return Coordonnee(dim,coord);
};
// conversion explicite de B en H
#ifndef MISE_AU_POINT
inline
#endif
CoordonneeH CoordonneeB::Bas_haut()const
// ici on pourrait optimiser en créant un coordonnée const, avec la mémoire au même endroit
// non !!! car this pourrait ne plus exister alors que le retour continue à exister !! donc pas bon
{ switch (dim)
{ case 1: {return CoordonneeH(coord[0]); break;}
case 2: {return CoordonneeH(coord[0],coord[1]); break;}
case 3: {return CoordonneeH(coord[0],coord[1],coord[2]); break;}
default:
{ cout << "\n erreur de dimension: dim= " << dim
<< " il n'est pas possible de transformer en CoordonneeH !"
<< "\n CoordonneeB::Bas_haut()const" ;
Sortie(1);
};
};
return CoordonneeH(0.); // pour éviter le warning
};
// mise a zero des coordonnées
#ifndef MISE_AU_POINT
inline
#endif
void CoordonneeB::Zero()
{ for (int i=0;i> tab[i];
switch (dim)
{ case 1 : {CoordonneeB c1(tab[0]);(*this) = c1; break;}
case 2 : {CoordonneeB c1(tab[0],tab[1]);(*this) = c1; break;}
case 3 : {CoordonneeB c1(tab[0],tab[1],tab[2]);(*this) = c1; break;}
}
};
// surcharge de l'operateur de lecture
#ifndef MISE_AU_POINT
inline
#endif
istream & operator >> ( istream & ent, CoordonneeB & coo)
{ // lecture du type et vérification
string nomtype; ent >> nomtype;
if (nomtype != "CoordonneeB")
{ Sortie(1);
return ent;
}
// lecture de la dimension
int dim;
ent >> nomtype >> dim ;
// on redimensionne éventuellement la taille
if (coo.dim != dim)
{ if (coo.memoire) // cas ou c'est un vrai point
{ if (coo.coord != NULL) { delete [] coo.coord;}
coo.coord = new double [dim];
coo.dim = dim;
}
else
{ cout << "\n erreur en lecture la dimension du point conteneur "<< dim << " est differente de celle lue "
<< dim << " et memoire est faux, donc on ne peut pas changer la dimension "
<< "\n operator >> ( istream & ent, CoordonneeB & coo) " << endl ;
Sortie(2);
};
};
// les data
for (int i = 0; i<= coo.dim-1; i++)
ent >> coo.coord[i] ;
return ent;
};
// surcharge de l'operateur d'ecriture
#ifndef MISE_AU_POINT
inline
#endif
ostream & operator << ( ostream & sort,const CoordonneeB & coo)
{ // écriture du type et de la dimension
sort << "CoordonneeB dim= " << coo.dim << " ";
// les data
for (int i = 0; i<= coo.dim-1; i++)
sort << setprecision(ParaGlob::NbdigdoCA()) << coo.coord[i] << " ";
// sort << "\n";
return sort;
};
// Calcul de la norme euclidienne des composantes du point
#ifndef MISE_AU_POINT
inline
#endif
double CoordonneeB::Norme () const
{ double norme=0.0;
for (int i=0;iNorme();
#ifdef MISE_AU_POINT
if(Dabs(norme) <= ConstMath::trespetit)
{ cout << "\n erreur, division par zero ";
cout << "\nCoordonneeB::Normer () " << endl;
Sortie (1);
}
#endif
*this /= norme;
return *this ;
};
#ifndef MISE_AU_POINT
inline
#endif
// Retourne le maximum en valeur absolue des composantes
double CoordonneeB::Max_val_abs () const
{ double maxi=0.;
switch (dim)
{ case 3: maxi=DabsMaX(maxi,coord[2]);
case 2: maxi=DabsMaX(maxi,coord[1]);
case 1: maxi=DabsMaX(maxi,coord[0]);
case 0: break;
};
return maxi;
};
#ifndef MISE_AU_POINT
inline
#endif
// Retourne le maximum en valeur absolue des composantes et l'indice correspondant
double CoordonneeB::Max_val_abs (int& in) const
{ double maxi=0.;
in = 0;
switch (dim)
{ case 3: if (maxi < Dabs(coord[2])) {maxi=coord[2]; in=3;}
case 2: if (maxi < Dabs(coord[1])) {maxi=coord[1]; in=2;}
case 1: if (maxi < Dabs(coord[0])) {maxi=coord[0]; in=1;}
case 0: break;
};
return maxi;
};
#ifndef MISE_AU_POINT
inline
#endif
// Retourne le maximum en valeur absolue des composantes du Coordonnee
// mais ramène la grandeur signée (avec son signe)
double CoordonneeB::Max_val_abs_signe () const
{ double maxi=0.;
int in = 0;
switch (dim)
{ case 3: if (maxi < Dabs(coord[2])) {maxi=coord[2]; in=3;}
case 2: if (maxi < Dabs(coord[1])) {maxi=coord[1]; in=2;}
case 1: if (maxi < Dabs(coord[0])) {maxi=coord[0]; in=1;}
case 0: break;
};
if (in != 0) {return coord[in-1];}
else {return maxi;};
};
#ifndef MISE_AU_POINT
inline
#endif
// Retourne le maximum en valeur absolue des composantes du Coordonnee
// mais ramène la grandeur signée (avec son signe) et l'indice
double CoordonneeB::Max_val_abs_signe (int& in) const
{ double maxi=0.;
in = 0;
switch (dim)
{ case 3: if (maxi < Dabs(coord[2])) {maxi=coord[2]; in=3;}
case 2: if (maxi < Dabs(coord[1])) {maxi=coord[1]; in=2;}
case 1: if (maxi < Dabs(coord[0])) {maxi=coord[0]; in=1;}
case 0: break;
};
if (in != 0) {return coord[in-1];}
else {return maxi;};
};
#ifndef MISE_AU_POINT
inline
#endif
// modifie éventuellement les coordonnées de this pour quelles soient supérieures ou égales
// aux coordonnées en paramètre
void CoordonneeB::Modif_en_max(const CoordonneeB& v)
{ for (int i=1;i<=dim;i++)
if (coord[i-1] < v(i)) coord[i-1]=v(i);
};
#ifndef MISE_AU_POINT
inline
#endif
// modifie éventuellement les coordonnées de this pour quelles soient inférieures ou égales
// aux coordonnées en paramètre
void CoordonneeB::Modif_en_min(const CoordonneeB& v)
{ for (int i=1;i<=dim;i++)
if (coord[i-1] > v(i)) coord[i-1]=v(i);
};
#ifndef MISE_AU_POINT
inline
#endif
// ajoute une même valeur à tous les coordonnées
void CoordonneeB::Ajout_meme_valeur(double val)
{ for (int i=0;i"
<< "\n"
<< "\n "
<< "\n coordonnee de dimension 1 ou 2 ou 3: elements: "
<< "\n un entier (dim) donnant la dimension, et dim reels "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n "
<< "\n";
break;
}
case XML_IO_POINT_INFO :
{
break;
}
case XML_IO_POINT_BI :
{
break;
}
case XML_IO_ELEMENT_FINI :
{
break;
}
};
};
#endif