
// 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 "LesChargeExtSurElement.h"


// contructeur par défaut
LesChargeExtSurElement::LesChargeExtSurElement():
  lesPressionsExternes(NULL),force_volume(NULL),lesEffortsDirFixe(NULL),lesPressDir(NULL),lesHydroDyna(NULL)
  ,lesLineique(NULL),lesLineiqueSuiveuse(NULL)
    {};
    
    
// contructeur de copie
LesChargeExtSurElement::LesChargeExtSurElement(const LesChargeExtSurElement& a):
  lesPressionsExternes(a.lesPressionsExternes),force_volume(NULL),lesEffortsDirFixe(NULL),lesPressDir(NULL),lesHydroDyna(NULL)
  ,lesLineique(NULL),lesLineiqueSuiveuse(NULL)
{ // on relie les tableaux entre eux
  //---- dimensionnement des charges externes éventuellement ----
  // dimensionnement des forces de pression
  if (a.lesPressionsExternes != NULL)
    lesPressionsExternes = new Tableau <Tableau <Pression_appliquee> >(*a.lesPressionsExternes);
  // dimensionnement des forces de volumes
  if (a.force_volume != NULL)
    force_volume = new Tableau < Coordonnee >(*a.force_volume);
  // cas des densités d'effort de direction fixe
  if (a.lesEffortsDirFixe != NULL)
    lesEffortsDirFixe = new Tableau <Tableau <Coordonnee> >(*a.lesEffortsDirFixe);
  // cas des densités d'effort suiveur
  if (a.lesPressDir != NULL)
    lesPressDir = new Tableau <Tableau <Coordonnee> >(*a.lesPressDir);
  // cas des densités d'effort de type hydrodynamique
  if (a.lesHydroDyna != NULL)
    lesHydroDyna = new Tableau <Tableau <Force_hydroDyna> >(*a.lesHydroDyna);
  // cas des charges linéiques
  if (a.lesLineique != NULL)
    lesLineique = new Tableau <Tableau <Coordonnee> >(*a.lesLineique);
  // cas des linéiques suiveuses
  if (a.lesLineiqueSuiveuse != NULL)
    lesLineiqueSuiveuse = new Tableau <Tableau <Coordonnee> >(*a.lesLineiqueSuiveuse);
};
    
// DESTRUCTEUR :
// normalement il n'y a rien n'a faire car les pointeurs sont des copies
LesChargeExtSurElement::~LesChargeExtSurElement()
{
  // suppression éventuelle des forces de pressions
  if (lesPressionsExternes != NULL)
    delete lesPressionsExternes;
  // suppression éventuelle des forces de volumes
  if (force_volume != NULL)
    delete force_volume;
  // cas des densités d'effort de direction fixe
  if (lesEffortsDirFixe != NULL)
    delete lesEffortsDirFixe ;
  // cas des densités d'effort suiveur
  if (lesPressDir != NULL)
    delete lesPressDir ;
  // cas des densités d'effort de type hydrodynamique
  if (lesHydroDyna != NULL)
    delete lesHydroDyna ;
  // cas des charges linéiques
  if (lesLineique != NULL)
    delete lesLineique ;
  // cas des linéiques suiveuses
  if (lesLineiqueSuiveuse != NULL)
    delete lesLineiqueSuiveuse ;
};
    
// Surcharge de l'operateur = 
LesChargeExtSurElement& LesChargeExtSurElement::operator= ( const LesChargeExtSurElement& a)
{ // on relie les tableaux entre eux
  //---- dimensionnement des charges externes éventuellement ----
   // cas des pression
  if (a.lesPressionsExternes != NULL)
    { if (lesPressionsExternes == NULL)
        {lesPressionsExternes = new Tableau <Tableau <Pression_appliquee> >(*a.lesPressionsExternes);}
      else // sinon le conteneur existe, il suffit de faire une affectation
        {(*lesPressionsExternes) = (*a.lesPressionsExternes);};
    }
  else // sinon cela veut dire que a.lesPressionsExternes est un pointeur nul
    { if (lesPressionsExternes != NULL)
        {delete lesPressionsExternes;};
      lesPressionsExternes = NULL;
    };

  // dimensionnement des forces de volumes
  if (a.force_volume != NULL)
    { if (force_volume == NULL)
        {force_volume = new Tableau < Coordonnee >(*a.force_volume);}
      else // sinon il suffit de faire une affectation
        {(*force_volume) = (*a.force_volume);};
    }
  else // sinon cela veut dire que a.force_volume est un pointeur nul
    { if (force_volume != NULL)
        {delete force_volume;};
      force_volume = NULL;
    };
   
  // cas des densités d'effort de direction fixe
  if (a.lesEffortsDirFixe != NULL)
    { if (lesEffortsDirFixe == NULL)
        {lesEffortsDirFixe = new Tableau <Tableau <Coordonnee> >(*a.lesEffortsDirFixe);}
      else // sinon le conteneur existe, il suffit de faire une affectation
        {(*lesEffortsDirFixe) = (*a.lesEffortsDirFixe);};
    }
  else // sinon cela veut dire que a.lesEffortsDirFixe est un pointeur nul
    { if (lesEffortsDirFixe != NULL)
        {delete lesEffortsDirFixe;};
      lesEffortsDirFixe = NULL;
    };
        
  // cas des densités d'effort suiveur
  if (a.lesPressDir != NULL)
    { if (lesPressDir == NULL)
        {lesPressDir = new Tableau <Tableau <Coordonnee> >(*a.lesPressDir);}
      else // sinon le conteneur existe, il suffit de faire une affectation
        {(*lesPressDir) = (*a.lesPressDir);};
    }
  else // sinon cela veut dire que a.lesPressDir est un pointeur nul
    { if (lesPressDir != NULL)
        {delete lesPressDir;};
      lesPressDir = NULL;
    };
  // cas des densités d'effort de type hydrodynamique
  if (a.lesHydroDyna != NULL)
    { if (lesHydroDyna == NULL)
        {lesHydroDyna = new Tableau <Tableau <Force_hydroDyna> >(*a.lesHydroDyna);}
      else // sinon le conteneur existe, il suffit de faire une affectation
        {(*lesHydroDyna) = (*a.lesHydroDyna);};
    }
  else // sinon cela veut dire que a.lesHydroDyna est un pointeur nul
    { if (lesHydroDyna != NULL)
        {delete lesHydroDyna;};
      lesHydroDyna = NULL;
    };
 
  // cas des charges linéiques
  if (a.lesLineique != NULL)
    { if (lesLineique == NULL)
        {lesLineique = new Tableau <Tableau <Coordonnee> >(*a.lesLineique);}
      else // sinon le conteneur existe, il suffit de faire une affectation
        {(*lesLineique) = (*a.lesLineique);};
    }
  else // sinon cela veut dire que a.lesLineique est un pointeur nul
    { if (lesLineique != NULL)
        {delete lesLineique;};
      lesLineique = NULL;
    };

  // cas des charges linéiques suiveuses
  if (a.lesLineiqueSuiveuse != NULL)
    { if (lesLineiqueSuiveuse == NULL)
        {lesLineiqueSuiveuse = new Tableau <Tableau <Coordonnee> >(*a.lesLineiqueSuiveuse);}
      else // sinon le conteneur existe, il suffit de faire une affectation
        {(*lesLineiqueSuiveuse) = (*a.lesLineiqueSuiveuse);};
    }
  else // sinon cela veut dire que a.lesLineiqueSuiveuse est un pointeur nul
    { if (lesLineiqueSuiveuse != NULL)
        {delete lesLineiqueSuiveuse;};
      lesLineiqueSuiveuse = NULL;
    };
 
  return *this;
};

 // initialisation à 0 de tous les conteneurs existants
void LesChargeExtSurElement::Zero()
{
  // cas des forces de pression
  if (lesPressionsExternes != NULL)
   {int tail=lesPressionsExternes->Taille();
    for (int i=1;i<=tail;i++)
     { int nta=(*lesPressionsExternes)(i).Taille();
       Tableau <Pression_appliquee>& tab_inter= (*lesPressionsExternes)(i);
       for (int j=1;j<=nta;j++)
         tab_inter(j).Zero();
     };
   };

  // cas des forces de volumes
  if (force_volume != NULL)
   {int tail = force_volume->Taille();
    for (int i=1;i<=tail;i++)
      (*force_volume)(i).Zero();
   };
  // cas des densités d'effort de direction fixe
  if (lesEffortsDirFixe != NULL)
   {int tail=lesEffortsDirFixe->Taille();
    for (int i=1;i<=tail;i++)
     { int nta=(*lesEffortsDirFixe)(i).Taille();
       Tableau <Coordonnee>& tab_inter= (*lesEffortsDirFixe)(i);
       for (int j=1;j<=nta;j++)
         tab_inter(j).Zero();
     };
   };
  // cas des densités d'effort suiveur
  if (lesPressDir != NULL)
   {int tail=lesPressDir->Taille();
    for (int i=1;i<=tail;i++)
     { int nta=(*lesPressDir)(i).Taille();
       Tableau <Coordonnee>& tab_inter= (*lesPressDir)(i);
       for (int j=1;j<=nta;j++)
         tab_inter(j).Zero();
     };
   };
  // cas des densités d'effort de type hydrodynamique
  if (lesHydroDyna != NULL)
   {int tail=lesHydroDyna->Taille();
    for (int i=1;i<=tail;i++)
     { int nta=(*lesHydroDyna)(i).Taille();
       Tableau <Force_hydroDyna>& tab_inter= (*lesHydroDyna)(i);
       for (int j=1;j<=nta;j++)
         tab_inter(j).Zero();
     };
   };
  // cas des charges linéiques
  if (lesLineique != NULL)
   {int tail=lesLineique->Taille();
    for (int i=1;i<=tail;i++)
     { int nta=(*lesLineique)(i).Taille();
       Tableau <Coordonnee>& tab_inter= (*lesLineique)(i);
       for (int j=1;j<=nta;j++)
         tab_inter(j).Zero();
     };
   };
  // cas des linéiques suiveuses
  if (lesLineiqueSuiveuse != NULL)
   {int tail=lesLineiqueSuiveuse->Taille();
    for (int i=1;i<=tail;i++)
     { int nta=(*lesLineiqueSuiveuse)(i).Taille();
       Tableau <Coordonnee>& tab_inter= (*lesLineiqueSuiveuse)(i);
       for (int j=1;j<=nta;j++)
         tab_inter(j).Zero();
     };
   };
};

// cas d'un changement de taille pour les pressions appliquées
void LesChargeExtSurElement::LesPressionsExternes_Change_taille(int n)
  {if (lesPressionsExternes==NULL) {lesPressionsExternes = new Tableau <Tableau <Pression_appliquee> >(n);}
   else if (lesPressionsExternes->Taille() == n) {return;} //cas le plus courant
   else {lesPressionsExternes->Change_taille(n);};
  };

// cas d'un changement de taille pour les forces volumiques 
void LesChargeExtSurElement::Force_volume_Change_taille(int n)
  {if (force_volume==NULL) {force_volume = new Tableau < Coordonnee >(n,Coordonnee(ParaGlob::Dimension()));}
   else if (force_volume->Taille() == n) {return;} //cas le plus courant
   else if (force_volume->Taille() > n)
    {force_volume->Change_taille(n);} // si on réduit pas de pb
   else if (force_volume->Taille() < n); // cas qui n'arrive pas souvent normalement
    {force_volume->Change_taille(n,Coordonnee(ParaGlob::Dimension()));} // tout est redimensionné à la dimension du pb    
  };
// cas d'un changement de taille pour les densité d’effort dont la direction reste fixe 
void LesChargeExtSurElement::LesEffortsDirFixe_Change_taille(int n)
  {if (lesEffortsDirFixe==NULL)
    {lesEffortsDirFixe = new Tableau <Tableau <Coordonnee> >(n);}
   else if (lesEffortsDirFixe->Taille() == n) {return;} //cas le plus courant
   else {lesEffortsDirFixe->Change_taille(n);}; 
  };

// cas d'un changement de taille pour les densités éventuelles d’effort de surface dont la direction suit la face face de l'élément
void LesChargeExtSurElement::LesPressDir_Change_taille(int n)
  {if (lesPressDir==NULL) {lesPressDir = new Tableau <Tableau <Coordonnee> >(n);}
   else if (lesPressDir->Taille() == n) {return;} //cas le plus courant
   else {lesPressDir->Change_taille(n);};
  };
// cas d'un changement de taille pour les densités éventuelles d’effort de surface d'origine hydrodynamique
void LesChargeExtSurElement::LesHydroDyna_Change_taille(int n)
  {if (lesHydroDyna==NULL) {lesHydroDyna = new Tableau <Tableau <Force_hydroDyna> >(n);}
   else {lesHydroDyna->Change_taille(n);};
  };
// cas d'un changement de taille pour charge linéique
void LesChargeExtSurElement::LesLineique_Change_taille(int n)
  {if (lesLineique==NULL) {lesLineique = new Tableau <Tableau <Coordonnee> >(n);}
   else if (lesLineique->Taille() == n) {return;} //cas le plus courant
   else {lesLineique->Change_taille(n);};
  };
// cas d'un changement de taille pour charge linéique suiveuse
void LesChargeExtSurElement::LesLineiqueSuiveuse_Change_taille(int n)
  {if (lesLineiqueSuiveuse==NULL) {lesLineiqueSuiveuse = new Tableau <Tableau <Coordonnee> >(n);}
   else if (lesLineiqueSuiveuse->Taille() == n) {return;} //cas le plus courant
   else {lesLineiqueSuiveuse->Change_taille(n);};
  };

    
//============= lecture écriture dans base info ==========
// cas donne le niveau de la récupération
// = 1 : on récupère tout
// = 2 : on récupère uniquement les données variables (supposées comme telles)
void LesChargeExtSurElement::Lecture_base_info (istream& ent,const int )
 { // l'entrée est identique quelque soit la valeur de cas
   ent >>  (*this);
 };
// cas donne le niveau de sauvegarde
// = 1 : on sauvegarde tout
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
void LesChargeExtSurElement::Ecriture_base_info(ostream& sort,const int )
 { // la sortie est identique quelque soit la valeur de cas
   sort << (*this);
 };
 

// surcharge de l'operateur de lecture
istream & operator >> (istream & entree, LesChargeExtSurElement & a)
  { // vérification du type
    string nom;
    entree >> nom;
   #ifdef MISE_AU_POINT
    if (nom != "LesChargeExtSurElement")
		     {	cout << "\nErreur, en lecture d'une instance  LesChargeExtSurElement "
		            << " on attendait LesChargeExtSurElement et on a lue: " << nom ;
			      cout << "istream & operator >> (istream & entree, LesChargeExtSurElement & a)\n";
			      Sortie(1);
       };
   #endif
    // puis lecture des différents éléments
    // cas des forces de pression
   
   int tail_pression = 0.;//a.lesPressionsExternes.Taille();
    entree >> nom >> tail_pression ;
    if (tail_pression != 0)
     { if (a.lesPressionsExternes == NULL)
        // cas où il faut créer
        {a.lesPressionsExternes = new Tableau <Tableau <Pression_appliquee> >(tail_pression);}
       else if (a.lesPressionsExternes->Taille() != tail_pression)
        // cas où il faut modifier la taille
        {a.lesPressionsExternes->Change_taille(tail_pression);};
       // maintenant on peut lire
       entree >> (*a.lesPressionsExternes);
     }
    else // sinon rien n'a lire
     { if (a.lesPressionsExternes != NULL)
          delete a.lesPressionsExternes;
     };

    // cas des forces de volumes
    int tail_vol = 0.;
    entree >> nom >> tail_vol ;
    if (tail_vol != 0)
     { if (a.force_volume == NULL)
        // cas où il faut créer
        {a.force_volume = new Tableau <Coordonnee>(tail_vol);}
       else if (a.force_volume->Taille() != tail_vol)
        // cas où il faut modifier la taille
        {a.force_volume->Change_taille(tail_vol);};
       // maintenant on peut lire
       entree >> (*a.force_volume);
     }
    else // sinon rien n'a lire
     { if (a.force_volume != NULL)
          delete a.force_volume;
     };
    
    // cas des densités d'effort de direction fixe
    int tail_F_DirFixe = 0.;
    entree >> nom >> tail_F_DirFixe ;
    if (tail_F_DirFixe != 0)
     { if (a.lesEffortsDirFixe == NULL)
        // cas où il faut créer
        {a.lesEffortsDirFixe = new Tableau <Tableau <Coordonnee> >(tail_F_DirFixe);}
       else if (a.lesEffortsDirFixe->Taille() != tail_F_DirFixe)
        // cas où il faut modifier la taille
        {a.lesEffortsDirFixe->Change_taille(tail_F_DirFixe);};
       // maintenant on peut lire
       entree >> (*a.lesEffortsDirFixe);
     }
    else // sinon rien n'a lire
     { if (a.lesEffortsDirFixe != NULL)
          delete a.lesEffortsDirFixe;
     };

    // cas des densités d'effort suiveur
    int tail_F_Dir = 0.;
    entree >> nom >> tail_F_Dir ;
    if (tail_F_Dir != 0)
     { if (a.lesPressDir == NULL)
        // cas où il faut créer
        {a.lesPressDir = new Tableau <Tableau <Coordonnee> >(tail_F_Dir);}
       else if (a.lesPressDir->Taille() != tail_F_Dir)
        // cas où il faut modifier la taille
        {a.lesPressDir->Change_taille(tail_F_Dir);};
       // maintenant on peut lire
       entree >> (*a.lesPressDir);
     }
    else // sinon rien n'a lire
     { if (a.lesPressDir != NULL)
          delete a.lesPressDir;
     };

    // cas des densités d'effort de type hydrodynamique
    int tail_F_HydroDyna = 0.;
    entree >> nom >> tail_F_HydroDyna ;
    if (tail_F_HydroDyna != 0)
     { if (a.lesHydroDyna == NULL)
        // cas où il faut créer
        {a.lesHydroDyna = new Tableau <Tableau <Force_hydroDyna> >(tail_F_HydroDyna);}
       else if (a.lesHydroDyna->Taille() != tail_F_HydroDyna)
        // cas où il faut modifier la taille
        {a.lesHydroDyna->Change_taille(tail_F_HydroDyna);};
       // maintenant on peut lire
       entree >> (*a.lesHydroDyna);
     }
    else // sinon rien n'a lire
     { if (a.lesHydroDyna != NULL)
          delete a.lesHydroDyna;
     };

    // cas des charges linéiques
    int tail_F_lin = 0.;
    entree >> nom >> tail_F_lin ;
    if (tail_F_lin != 0)
     { if (a.lesLineique == NULL)
        // cas où il faut créer
        {a.lesLineique = new Tableau <Tableau <Coordonnee> >(tail_F_lin);}
       else if (a.lesLineique->Taille() != tail_F_lin)
        // cas où il faut modifier la taille
        {a.lesLineique->Change_taille(tail_F_lin);};
       // maintenant on peut lire
       entree >> (*a.lesLineique);
     }
    else // sinon rien n'a lire
     { if (a.lesLineique != NULL)
          delete a.lesLineique;
     };

    // cas des linéiques suiveuses
    int tail_F_linSuiv = 0.;
    entree >> nom >> tail_F_linSuiv ;
    if (tail_F_linSuiv != 0)
     { if (a.lesLineiqueSuiveuse == NULL)
        // cas où il faut créer
        {a.lesLineiqueSuiveuse = new Tableau <Tableau <Coordonnee> >(tail_F_linSuiv);}
       else if (a.lesLineiqueSuiveuse->Taille() != tail_F_linSuiv)
        // cas où il faut modifier la taille
        {a.lesLineiqueSuiveuse->Change_taille(tail_F_linSuiv);};
       // maintenant on peut lire
       entree >> (*a.lesLineiqueSuiveuse);
     }
    else // sinon rien n'a lire
     { if (a.lesLineiqueSuiveuse != NULL)
          delete a.lesLineiqueSuiveuse;
     };
    return entree;      
  };
  
// surcharge de l'operateur d'ecriture 
ostream & operator << ( ostream & sort,const  LesChargeExtSurElement & a)
  { // tout d'abord un indicateur donnant le type
    sort << "\n LesChargeExtSurElement \n" ;
    // cas des forces de pression
    sort << "Press: ";
    if (a.lesPressionsExternes != NULL)
     {sort << a.lesPressionsExternes->Taille() << " ";
      sort << (*a.lesPressionsExternes);
     }
    else {sort << " 0 ";};

    // cas des forces de volumes
    sort << "F_vol: ";
    if (a.force_volume != NULL)
      {sort << a.force_volume->Taille() << " ";
       sort << (*a.force_volume);}
    else {sort << " 0 ";};
    
    // cas des densités d'effort de direction fixe
    sort << "F_DirFixe: ";
    if (a.lesEffortsDirFixe != NULL)
     {sort << a.lesEffortsDirFixe->Taille() << " ";
      sort << (*a.lesEffortsDirFixe);
     }
    else {sort << " 0 ";};

    // cas des densités d'effort suiveur
    sort << "F_Dir: ";
    if (a.lesPressDir != NULL)
     {sort << a.lesPressDir->Taille() << " ";
      sort << (*a.lesPressDir);
     }
    else {sort << " 0 ";};

    // cas des densités d'effort de type hydrodynamique
    sort << "F_HydroDyna: ";
    if (a.lesHydroDyna != NULL)
     {sort << a.lesHydroDyna->Taille() << " ";
      sort << (*a.lesHydroDyna);
     }
    else {sort << " 0 ";};

    // cas des charges linéiques
    sort << "F_lin: ";
    if (a.lesLineique != NULL)
     {sort << a.lesLineique->Taille() << " ";
      sort << (*a.lesLineique);
     }
    else {sort << " 0 ";};

    // cas des linéiques suiveuses
    sort << "F_linSuiv: ";
    if (a.lesLineiqueSuiveuse != NULL)
     {sort << a.lesLineiqueSuiveuse->Taille() << " ";
      sort << (*a.lesLineiqueSuiveuse);
     }
    else {sort << " 0 ";};

    return sort;
  };


    
    
    
