// 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) <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 <stdlib.h>
#include "Sortie.h"
#include "ConstMath.h"
#include "MathUtil.h"
#include <iomanip>
#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<dim;i++)
		coord[i]=0.0;
		
};

// Constructeur pour un point a une dimension
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB::CoordonneeB (double x) :
 dim (1),memoire(true)
{	coord=new double;
	coord[0]=x;
	
};

// Constructeur pour un point a deux dimensions
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB::CoordonneeB (double x,double y) :
 dim (2),memoire(true)
{	coord=new double [2];
	coord[0]=x;
	coord[1]=y;
	
};	

// Constructeur pour un point a trois dimensions
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB::CoordonneeB (double x,double y,double z) :
 dim (3) ,memoire(true)
{	coord=new double [3];
	coord[0]=x;
	coord[1]=y;
	coord[2]=z;
	
};

// constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
// et d'une dimension ( l'existance de la place mémoire est a la charge
//  de l'utilisateur.
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB::CoordonneeB (int dimension,double* t) :
 dim ((short)dimension),coord (t),memoire(false)
  {};  						


// Constructeur de copie
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB::CoordonneeB (const CoordonneeB& c) :
 dim (c.dim),memoire(true)
{

	if ( dim==0 )
		coord=NULL;
	else
	{	coord=new double [dim];
		for (int i=0;i<dim;i++)
		// copie des coordonnees
			coord[i]=c.coord[i];
	};
		
};

// Destructeur
// Desallocation de la place memoire allouee
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB::~CoordonneeB ()
{ if (memoire)
   { if  (dim > 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<dim;i++)
          coord[i] = sauve[i];
        if (dim != 0) delete [] sauve;
        for (int i=dim;i<dimen;i++)
          coord[i] = 0.;
        dim = (short) dimen;
       }
    else if (dim > dimen)
      { coord = new double [dimen];
        for (int i=0;i<dimen;i++)
          coord[i] = sauve[i];
        dim = (short) dimen;
        delete [] sauve;
       }
   // dans le cas ou dim = dimen on ne fait rien                  
  };
  
// Surcharge de l'operateur = : realise l'affectation entre deux points 
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB& CoordonneeB::operator= (const CoordonneeB& c)
		{	if (dim==c.dim)
			  { for (int i=0;i<dim;i++)
				      coord[i]=c.coord[i];
       return (*this);
     }
    else if ( c.dim==0 )
     { Libere();}
    else
     {
      #ifdef MISE_AU_POINT
       if (dim != 0)
        {  cout << "\n attention, on change la dimension du point !!!"
                << " de "<<dim<<" a "<<c.dim << endl;
        }
      #endif
				  Libere();
      dim=c.dim;
				  coord=new double [dim];
				  for (int i=0;i<dim;i++)
					   coord[i]=c.coord[i];
			  };
			return (*this);			
		};
  		

// Surcharge de l'operateur - : renvoie l'oppose d'un point
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB CoordonneeB::operator- () const 
		{	CoordonneeB result(dim);
			for (int i=0;i<dim;i++)
				result.coord[i]=-coord[i];
			return result;			
		};
		
// Surcharge de l'operateur - : realise la soustraction des
// coordonnees de deux points
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB CoordonneeB::operator- (const CoordonneeB& c) const 
		{ 
         #ifdef MISE_AU_POINT		
		  if ( dim!=c.dim )
			{
				cout << "\nErreur : dimensions non egales !\n";
				cout << "CoordonneeB::OPERATOR- (CoordonneeB ) \n";
				Sortie(1);
			};
         #endif
			CoordonneeB result(dim);
			for (int i=0;i<dim;i++)
				result.coord[i]=coord[i]-c.coord[i];
			return result;			
		};

// Surcharge de l'operateur + : realise l'addition des 
// coordonnees de deux points
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB CoordonneeB::operator+ (const CoordonneeB& c) const 
		{	
          #ifdef MISE_AU_POINT		
		    if ( dim!=c.dim )
			{	cout << "\nErreur : dimensions non egales !\n";
				cout << "CoordonneeB::OPERATOR+ (CoordonneeB ) \n";
				Sortie(1);
			};
          #endif
			CoordonneeB result(dim);
			for (int i=0;i<dim;i++)
				result.coord[i]=coord[i]+c.coord[i];
			return result;		
		};
		
// Surcharge de l'operateur += 
#ifndef MISE_AU_POINT
  inline 
#endif
void CoordonneeB::operator+= (const CoordonneeB& c)
		{
          #ifdef MISE_AU_POINT		
			if ( dim!=c.dim )
			{	cout << "\nErreur : dimensions non egales !\n";
				cout << "CoordonneeB::OPERATOR+= (CoordonneeB ) \n";
				Sortie(1);
			};
          #endif
			for (int i=0;i<dim;i++)
				coord[i]+=c.coord[i];
		};

// Surcharge de l'operateur -= 
#ifndef MISE_AU_POINT
  inline 
#endif
void CoordonneeB::operator-= (const CoordonneeB& c)
		{ 
          #ifdef MISE_AU_POINT		
		   if ( dim!=c.dim )
			{
				cout << "\nErreur : dimensions non egales !\n";
				cout << "CoordonneeB::OPERATOR-= (CoordonneeB ) \n";
				Sortie(1);
			};
          #endif
			for (int i=0;i<dim;i++)
				coord[i]-=c.coord[i];
		};		

// Surcharge de l'operateur *= 
#ifndef MISE_AU_POINT
  inline 
#endif
void CoordonneeB::operator*= (double val)
		{	for (int i=0;i<dim;i++)
				coord[i]*=val;
		};	
		
// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB CoordonneeB::operator* (double val) const 
		{   CoordonneeB result(dim);
			for (int i=0;i<dim;i++)
				result.coord[i]=val*coord[i];
			return result;
		};
				
// Surcharge de l'operateur * : produit scalaire entre coordonnees 
#ifndef MISE_AU_POINT
  inline 
#endif
double CoordonneeB::operator* (const CoordonneeH& c) const 
{	double res=0.0;
	for (int i=0;i<dim;i++)
	// somme des produits
		res+= coord[i] * c(i+1);
	return res;	
};
		
		
//  produit scalaire entre coordonnees covariantes et covariantes
#ifndef MISE_AU_POINT
  inline 
#endif
double CoordonneeB::ScalBB(const CoordonneeB& c) const 
{	double res=0.0;
	for (int i=0;i<dim;i++)
	// somme des produits
		res+= coord[i] * c(i+1);
	return res;	
};

// Surcharge de l'operateur / : division de coordonnees par un scalaire
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB CoordonneeB::operator/ (double val) const 
 {
   #ifdef MISE_AU_POINT
    if(Dabs(val) <= ConstMath::trespetit)
    { cout << "\n erreur, division par zero ";
      cout << "\nCoordonneeB::operator/ (double val) " << endl;
      Sortie (1);
     }
   #endif
   CoordonneeB result(dim);
   for (int i=0;i<dim;i++)
	  result.coord[i] = coord[i] / val;
   return result;  
  };
		
// Surcharge de l'operateur /= : division de coordonnees par un scalaire
#ifndef MISE_AU_POINT
  inline 
#endif
void CoordonneeB::operator/= (double val)
 {
  #ifdef MISE_AU_POINT
   if(Dabs(val) <= ConstMath::trespetit)
    { cout << "\n erreur, division par zero ";
      cout << "\nCoordonneeB::operator/= (double val) " << endl;
      Sortie (1);
     }
  #endif
   for (int i=0;i<dim;i++)
				coord[i]/=val;  
  };

// Surcharge de l'operateur == : test d'egalite 
// Renvoie 1 si les deux positions sont identiques
// Renvoie 0 sinon
#ifndef MISE_AU_POINT
  inline 
#endif
int CoordonneeB::operator== (const CoordonneeB& c) const 
		{   if ( c.dim!=dim )
				return 0;
			else
			{   for (int i=0;i<dim;i++)
				{	if ( c.coord[i]!=coord[i] )
						return 0;
				};
				return 1;
			};
		};
		
// Surcharge de l'operateur !=
// Renvoie 1 si les deux positions ne sont pas identiques
// Renvoie 0 sinon
#ifndef MISE_AU_POINT
  inline 
#endif
int CoordonneeB::operator!= (const CoordonneeB& c) const 
		{	if ( (*this)==c )
				return 0;
			else 
				return 1; 
		};
	
// Affiche les coordonnees du point à l'écran
#ifndef MISE_AU_POINT
  inline 
#endif
void CoordonneeB::Affiche () const 
		{	cout << "\t{  ";
			for (int i=1;i<=dim;i++)
				cout << (*this)(i) << "  ";
			cout << "}\n";
		};

// Affiche les coordonnees du point dans sort
#ifndef MISE_AU_POINT
  inline 
#endif
void CoordonneeB::Affiche (ostream& sort) const 
		{	sort << "\t{  " ;
			for (int i=1;i<=dim;i++)
				sort << (*this)(i) << "  " ;
			sort << "}\n" ;
		};

// Affiche les coordonnees du point dans sort sur nb digit plus un blanc
// et rien d'autre
#ifndef MISE_AU_POINT
  inline 
#endif
void CoordonneeB::Affiche (ostream& sort,int nb) const 
 {  for (int i = 0; i<= this->dim-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<dim;i++)
		     coord[i] =0.;
		  };   
// surcharge de l'operateur de lecture dans la mémoire
#ifndef MISE_AU_POINT
  inline 
#endif
// lecture brut des coordonnées sans la dimension
void CoordonneeB::Lecture (UtilLecture& entreePrinc)
  { int dim = Dimension ();
    double tab[3];

    for (int i = 0; i<= dim-1; i++)
        *(entreePrinc.entree) >> 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;i<dim;i++)
	// somme du carre des composantes du vecteur
		norme=norme + coord[i] * coord[i];
	norme=sqrt(norme); // calcul de la norme
	return norme;	
};

// norme le vecteur coordonnée
#ifndef MISE_AU_POINT
  inline 
#endif
CoordonneeB& CoordonneeB::Normer ()
 { double norme = this->Norme();
   #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<dim;i++) coord[i] += val;  
   };

#ifndef MISE_AU_POINT
  inline 
#endif
    // sortie du schemaXML: en fonction de enu 
void CoordonneeB::SchemaXML_Coordonnee(ostream& sort,const Enum_IO_XML enu)
  {
	switch (enu)
	{ case XML_TYPE_GLOBAUX :
  	   {sort << "\n <!--  *************************** CoordonneeB  ***************************  -->"
  	         << "\n<xs:complexType name=\"COORDONNEE_B\" >"
  	         << "\n    <xs:annotation>"
  	         << "\n      <xs:documentation> coordonnee de dimension 1 ou 2 ou 3: elements: "
  	         << "\n          un entier (dim) donnant la dimension, et dim reels "
  	         << "\n      </xs:documentation>"
  	         << "\n    </xs:annotation>"
  	         << "\n    <xs:sequence>"
  	         << "\n        <xs:element name=\"dimension\" type=\"xs:double\" />"
  	         << "\n        <xs:element name=\"coordonnees\" >"
  	         << "\n            <xs:simpleType>"
  	         << "\n          	 <xs:restriction base=\"liste_de_reels\">"
  	         << "\n                <xs:minLength value=\"1\" />"
  	         << "\n                <xs:maxLength value=\"3\" />"
  	         << "\n              </xs:restriction>"  
  	         << "\n            </xs:simpleType>"
  	         << "\n        </xs:element>"
  	         << "\n    </xs:sequence>"
  	         << "\n</xs:complexType>";
		 break;
		}
		case XML_IO_POINT_INFO :
		{
		 break;
		}
		case XML_IO_POINT_BI :
		{
		 break;
		}
		case XML_IO_ELEMENT_FINI :
		{
		 break;
		}
	};		
  };

		
		
#endif