// 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-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 . // // 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