// FICHIER : PoutTimo.h
// CLASSE : PoutTimo

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

/************************************************************************
 *     DATE:        20/05/98                                            *
 *                                                                $     *
 *     AUTEUR:      G RIO   (mailto:gerardrio56@free.fr)                *
 *                                                                $     *
 *     PROJET:      Herezh++                                            *
 *                                                                $     *
 ************************************************************************
 *     BUT:  // La classe PoutTimo permet de declarer des elements      *
 *  poutTimos et de realiser le calcul du residu local et de la raideur *
 * locale pour une loi de comportement donnee. La dimension de l'espace *
 * pour un tel element est 1.                                           *
 * Le modèle de poutre de Timoshenko repose sur des fonctions d'interpo-*
 * lation de l'Hermite, il y a donc 2*dim ddl par noeud, les positions  *
 * et les dérivées.
 *                                                                      *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     VERIFICATION:                                                    *
 *                                                                      *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *     !        !            !                                    !     *
 *                                                                $     *
 *     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
 *     MODIFICATIONS:                                                   *
 *     !  date  !   auteur   !       but                          !     *
 *     ------------------------------------------------------------     *
 *                                                                $     *
 ************************************************************************/
// -----------classe pour un calcul de mecanique---------



#ifndef BIELLETTE_H
#define BIELLETTE_H

#include "ParaGlob.h"
#include "ElemMeca.h"
//#include "Loi_comp_abstraite.h"
#include "Met_abstraite.h"
#include "Met_biellette.h"
#include "Noeud.h"
#include "UtilLecture.h"
#include "Tenseur.h"
#include "NevezTenseur.h"
#include "Deformation.h"
#include "ElFrontiere.h"
#include "GeomSeg.h"
#include "FrontSegLine.h"

class ConstrucElementbiel;

/// @addtogroup groupe_des_elements_finis
///  @{
///


class PoutTimo : public ElemMeca
{
		
	public :
	
		// CONSTRUCTEURS :
		// Constructeur par defaut
		PoutTimo ();
		
		// Constructeur fonction d'une section et eventuellement d'un numero
		// d'identification 
		PoutTimo (double sect,int num_id=-3);
		
		// Constructeur fonction  d'un numero d'identification  
		PoutTimo (int num_id);
		
		// Constructeur fonction d'une section, d'un numero d'identification,
		// du tableau de connexite des noeuds 
		PoutTimo (double sect,int num_id,const Tableau<Noeud *>& tab);
		
		// Constructeur de copie
		PoutTimo (PoutTimo& pout);
		
		
		// DESTRUCTEUR :
		~PoutTimo ();
		
		
		// Surcharge de l'operateur = : realise l'egalite entre deux instances de PoutTimo
		PoutTimo& operator= (PoutTimo& pout);
		
		// METHODES :
  // 1) derivant des virtuelles pures
		// Lecture des donnees de la classe sur fichier
		void LectureDonneesParticulieres (UtilLecture *,Tableau<Noeud  *> * );
		
		// Calcul du residu local et de la raideur locale,
		//  pour le schema implicite
		Element::ResRaid  Calcul_implicit ();
		
		// Calcul du residu local a t
		// pour le schema explicit par exemple 
		Vecteur* CalculResidu_t ();
		
		// retourne les tableaux de ddl gere par l'element
		// ce tableau et specifique a l'element
		DdlElement & TableauDdl();

			
		// Libere la place occupee par le residu et eventuellement la raideur
		// par l'appel de Libere de la classe mere et libere les differents tenseurs
		// intermediaires cree pour le calcul et les grandeurs pointee
		// de la raideur et du residu
		void Libere ();
		
		// acquisition  d'une loi de comportement
		void DefLoi (LoiAbstraiteGeneral * NouvelleLoi);
		
       // test si l'element est complet
       // = 1 tout est ok, =0 element incomplet
		int TestComplet();
		
		// procesure permettant de completer l'element apres
		// sa creation avec les donnees du bloc transmis
		// peut etre appeler plusieurs fois
		Element* Complete(BlocGen & bloc,LesFonctions_nD*  lesFonctionsnD);                         
		
		// ramene l'element geometrique correspondant
		ElemGeom& ElementGeometrique()  { return doCo->segment;};

  // affichage dans la sortie transmise, des variables duales "nom"
  // dans le cas ou nom est vide, affichage de "toute" les variables
  void AfficheVarDual(ostream& sort, Tableau<string>& nom);
			
		// Calcul des frontieres de l'element
		//  creation des elements frontieres et retour du tableau de ces elements
		Tableau <ElFrontiere*>& Frontiere();
  // METHODES VIRTUELLES:
      // --------- calculs utils dans le cadre de la recherche du flambement linéaire		
		// Calcul de la matrice géométrique et initiale
		ElemMeca::MatGeomInit MatricesGeometrique_Et_Initiale () ;
			
  // 2) methodes propres a l'element
		
		inline double& Section ()
		// Retourne la section de l'element
		{	return section; 	};
		
//		inline Mat_pleine& Dphi ()
		// Retourne les derivees des fonctions d'interpolation de la PoutTimo
//		{	return doCo->dphi;	};
		
		// Retourne le tenseur des deformations
		inline TenseurBB * DeformationBB ()
		  {	return epsBB;	};
		
		// Retourne le tenseur des contraintes
		inline TenseurHH * ContrainteHH ()
		  {	return sigHH;	};
		
  // ajout du tableau specific de ddl des noeuds de la  PoutTimo
  // la procedure met a jour les ddl(relatif a l'element, c-a-d Xi)
  // des noeuds constituants l'element
  void ConstTabDdl();
 
 protected:
    		
  // -------------------- calcul de frontières en protected -------------------
    
    //  --- fonction nécessaire pour la construction des Frontières linéiques ou surfaciques particulière à l'élément
    // adressage des frontières linéiques et surfacique
    // définit dans les classes dérivées, et utilisées pour la construction des frontières
    virtual ElFrontiere* new_frontiere_lin(int , Tableau <Noeud *> & tab, DdlElement& ddelem)
      { return ((ElFrontiere*) (new FrontSegLine(tab,ddelem)));};
    virtual ElFrontiere* new_frontiere_surf(int , Tableau <Noeud *> & tab, DdlElement& ddelem)
      {return NULL;} // il n'y a pas de surface possible
    
 private :

      // VARIABLES PRIVEES :
      	
		double section; // section de la poutTimo
		TenseurBB * epsBB; // deformation finale
		TenseurHH * sigHH; // contrainte finale
		// derivee de la deformation par rapport aux degres de liberte
		Tableau <TenseurBB *> d_epsBB; 
          
  class DonneeCommune
	      { public :
	        DonneeCommune (GeomSeg& seg,DdlElement& tab,
	                       Met_biellette&  met_bie) :
	          segment(seg),tab_ddl(tab),met_biellette(met_bie)
	          ,matGeom(tab.NbDdl(),tab.NbDdl())
	          ,matInit(tab.NbDdl(),tab.NbDdl())
	          ,d2_epsBB(tab.NbDdl())
	            {};
          // variables
          GeomSeg segment ; // element geometrique correspondant
          DdlElement  tab_ddl; // tableau des degres
                     //de liberte des noeuds de l'element commun a tous les
                     // elements
          Met_biellette  met_biellette;
		        Mat_pleine  matGeom ; // matrice géométrique
          Mat_pleine  matInit  ; // matrice initile
          Tableau2 <TenseurBB *> d2_epsBB;
       };
         
        // place memoire commune a tous les elements poutTimos      
        static DonneeCommune * doCo;
        static int CalculResidu_t_PoutTimo_met_abstraite;  // pour dim met_biellette      
        static int  Calcul_implicit_PoutTimo_met_abstraite; //      "
        static int Calcul_VarDualSort; // pour la sortie des valeurs au pt d'integ
        // pour l'ajout d'element dans la liste : listTypeElemen, geree par la class Element
        class ConstrucElementpoutTimo : public ConstrucElement
          { public :  ConstrucElementpoutTimo () 
               { NouvelleTypeElement nouv;
                 nouv.id_geom = POUT; nouv.id_interpol = BIE1;
                 cout << "\n initialisation PoutTimo" << endl;
                 nouv.el = this;
                 Element::listTypeElement.push_back(nouv);
                };
            Element * NouvelElement(int num) 
               {Element * pt;
                pt  = new PoutTimo (num) ;
                return pt;};	   
           }; 
        static ConstrucElementpoutTimo construcElementpoutTimo;
      // fonction privee
        void Def_DonneeCommune();
};
/// @}  // end of group
#endif