
// 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 "Resultats.h"
#include "LectBlocMot.h"
#include "CharUtil.h"
#include "MathUtil.h"
#include <iomanip>
#include "ElemMeca.h"
#include "ElFrontiere.h"
#include "ReferenceNE.h"
#include "ReferenceAF.h"
#include "TypeConsTens.h"

// CONSTRUCTEURS :
// entreePrinc gere les entrees sorties
Resultats::Resultats(UtilLecture* ent) :
 lesValVecPropres(),tabRegion(),pas_de_sortie(false) 
  { entreePrinc = ent;
    // parametres par defaut
    copie = 1; // recopie de la lecture
   };
// DESTRUCTEUR :
Resultats::~Resultats()
 { };
    
// METHODES PUBLIQUES :
// lecture des parametres de gestions de la sortie des resultats
void Resultats::Lecture(LesReferences* lesRef)
  {try
   {
     if (ParaGlob::NiveauImpression() >= 4)
       cout << " debut de la lecture de la sortie automatique de resultats " << endl;
     MotCle motCle; // ref aux mots cle
      { // on se positionne sur un mot cle
        while ( !motCle.SimotCle(entreePrinc->tablcar))
             entreePrinc->NouvelleDonnee();
        if (strstr(entreePrinc->tablcar,"resultats")!=NULL)
         {  // on regarde si l'utilisateur éventuellement ne veut aucune sortie
            if (strstr(entreePrinc->tablcar,"pas_de_sortie_finale_")!=NULL)
              {pas_de_sortie = true;
               entreePrinc->NouvelleDonnee();
               if (strstr(entreePrinc->tablcar,"COPIE")!=NULL)
                 {string nom;*(entreePrinc->entree) >> nom;
                  if (nom == "COPIE")
                   { *(entreePrinc->entree) >> copie;
                     entreePrinc->NouvelleDonnee();
                   }
                 }
               else
                 {copie=0;};
              }
            else
             {// on lit jusqu'au prochain mot cle
              string nom;
              entreePrinc->NouvelleDonnee();
              // definition d'un tableau de sous mot cle permettant
              // l'arret a chaque sous mot cle dans les procedures specifiques
              // de lecture
              Tableau<string> tsousMot(5);
              tsousMot(1) = "COPIE";tsousMot(2) = "POINTS_INTEGRATION";
              tsousMot(3) = "REACTIONS";tsousMot(4) = "DEGRE_DE_LIBERTE";
              tsousMot(5) = "DEFORMEE";
              // lecture
              while ( !motCle.SimotCle(entreePrinc->tablcar))
               { *(entreePrinc->entree) >> nom;
                 if (nom == "COPIE")
                  { *(entreePrinc->entree) >> copie;
                    entreePrinc->NouvelleDonnee();
                  }
                 else if (nom == "POINTS_INTEGRATION")
                  // cas des sorties au points d'integrations
                  {ReadPtInteg(lesRef,tsousMot);}
                else if (nom == "REACTIONS")
                  {ReadReac(lesRef);}
                else if (nom == "DEGRE_DE_LIBERTE")
                  {ReadNoeuds(lesRef);}
                else if (nom == "DEFORMEE")
                  { ReadDeformee(lesRef);
                    entreePrinc->NouvelleDonnee();
                    }
                else
                  { cout << "\n ** erreur en lecture des parametre de gestion des resultats"
                           << " , nom lu : "<< nom;
                    entreePrinc->MessageBuffer
                        ("** lecture des parametres de gestion des resultats **");
                    Affiche();
                    throw (UtilLecture::ErrNouvelleDonnee(-1));
                    Sortie (1);
                  };
               }; // fin du while
             }; // fin du if sur pas de sortie finale
         }
        else
         { cout << "\n lecture des parametres de gestion des resultats : pas d'informations particulières";
           cout << "\n **** d'où : utilisation de TOUS les parametres par defaut !! ";
           cout << endl;
         };
      };// fin d'un bloc
     if (ParaGlob::NiveauImpression() >= 4)
        cout << " fin de la lecture de la sortie automatique de resultats " << endl;
   }
   catch (UtilLecture::ErrNouvelleDonnee erreur)
     {  if ( erreur.lecture == 1)
          { // fin de fichier atteind, ce n'est peut-être pas une erreur,
            cout << "\n --- fin de fichier atteind sans mot cle ??? --- "
                 << " \n (return pour continuer !) "<< flush;
                 // -------- utilitaire pour lire une chaine de caractères:
                 // si retour chariot, retourne la valeur par défaut passée en paramètre
                 // sinon retourne le string lue au clavier
                 // gestion d'erreur si lecture non correcte
                      // si avec_ecriture = true: on écrit "--> valeur par defaut : n " val_defaut
            lect_return_defaut(false,"");
            return;
          }
        else
          {cout << "\n ===============================================\n" ;
           // on signale l'erreur
           cout << "\n **** bizarre, erreur inconnue en lecture des parametres de sortie de 'resultats' ( fin du .info ) ";
           throw (erreur);
          };
     }
    catch (ErrSortieFinale)
         // cas d'une direction voulue vers la sortie
         // on relance l'interuption pour le niveau supérieur
       { ErrSortieFinale toto;
         throw (toto);
       }
    catch ( ... )
     { // on signale l'erreur
       cout << "\n **** bizarre, erreur inconnue en lecture des parametres de sortie de resultats ";
       throw (UtilLecture::ErrNouvelleDonnee(-1));
     };
   };

// affichage des parametres de gestions de la sortie des resultats
void Resultats::Affiche() const 
  { cout << "\n  parametres de gestion des resultats \n";
    cout << "recopie de la lecture ?          = " << copie      << '\n';
   };
	 
// def interactive des parametres de gestion de la sortie des resultats
void Resultats::Info_commande_Resultats()
{ofstream & sort = *(entreePrinc->Commande_pointInfo()); // pour simplifier
 string rep = " ";
 while (Minuscules(rep) != "f")
  { cout << "\n\n sortie standard ?                (rep o) ";
    cout << "\n infos fichiers speciaux          (rep ?) ";
    cout << "\n sorte fichiers speciaux          (rep s) ";
    cout << "\n fin                              (rep f) ";
    rep = lect_return_defaut(false,"f");

    if ((rep == "o") || (rep == "O") || (rep == "0"))
   	 { sort << "\n#  ------------------------------------------------------------------------------------ "
            << "\n      resultats  pas_de_sortie_finale_ "
            << "\n      COPIE 0   "
            << "\n#";
   	 }
    else  if (rep == "?")
   	{ cout << "\n Il s'agit uniquement des sorties automatiques effectuees a la fin de l'execution "
           << "\n donc des infos sur l'etat final en fin de calcul "
           << "\n fichiers: "
           << "\n  .res (grandeurs aux pti)           ; _cab.isoe               (tableau des contraintes)"
           << "\n  .ddl (les ddl aux noeuds)          ; .reac     (les reactions due aux blocages divers)"
           << "\n  .cont (les reactions de contact)   ; _dpl.points (tableau des deplacements des noeuds)"
           << "\n  L'eventail de choix est restreint, si l'on veut plus de choix il faut utiliser la sortie interactive " 
           << "\n  et construire un fichier .CVisu  "
           << "\n ce qui est automatique: .ddl, .reac, _cab.isoe, .cont, _dpl.points "
           << "\n ce qui peut etre modifie sont les grandeurs pour le .res "
           << "\n on indique les ref d elements ou l'on veut les sorties, puis la liste des grandeurs ";
    }
    else  if (rep == "s")
    { cout << "\n -- constitution de la liste des references ---";
      // -- construction de la liste de ref
      string rop = " ";
      list <Deux_String> list_ref;
      while (Minuscules(rop) != "f" )
       { cout << "\n non d'une ref existante                                ->  (rep : nf) "
              << "\n effacer la liste a sortir                              ->  (rep : ef) "
              << "\n la ref tout et un seul maillage(par defaut)            ->  (rep : to) "
              << "\n fin                                                    ->  (rep :  f) ";
         rop = lect_return_defaut(false,"f");
         if (rop == "nf")
           { string nom_ref;
             cout << "\n nom de la reference ? ";nom_ref=lect_chaine();
             string nom_mail; // par defaut
             cout << "\n nom du maillage (ou _ si un seul maillage) ? "; nom_mail=lect_chaine();
             list_ref.push_back(Deux_String(nom_mail,nom_ref));
           }
          else if (rop == "ef")
           { // on efface la liste des références d'éléments et la liste de pt d'integ associée
             list_ref.clear();
           }
          else if (rop == "to")
           { list_ref.push_back(Deux_String("_","E_tout"));
           };
          // visualisation de la liste actuelle
          if (list_ref.size() != 0)
           { list <Deux_String>::iterator ili,ilifin = list_ref.end();
             cout << "\n liste actuelle de ref : ";
             for (ili=list_ref.begin();ili != ilifin;ili++)
               cout << "\n maillage: "<< (*ili).nom1 << " ref: "<< (*ili).nom2 <<" ";
             cout << "\n ";
           };

       };
      // -- construction de la liste des grandeurs à sortir
      list <string> list_grandeurs;
      rop = " ";
      while (Minuscules(rop) != "f" )
       { Tableau<string> tsousMotref(9);
         tsousMotref(1) = "Green-Lagrange";tsousMotref(2) = "Almansi";
         tsousMotref(3) = "Cauchy_global";tsousMotref(4) = "Def_mixte_local";
         tsousMotref(5) = "Sigma_mixte_local";tsousMotref(6) = "Sigma_principale";
         tsousMotref(7) = "Def_principale";tsousMotref(8) = "Resultat_loi";
         tsousMotref(9) = "logarithmique";
         int pair=0;
         for (int i=1;i<= 9; i++)
           {if (pair == 0) {cout << "\n"<<tsousMotref(i);pair++;}
            else            {cout << "      " << tsousMotref(i);pair = 0;};
           };
         cout << "\n";
         cout << "\n non d'une grandeur                                ->  (rep : gr) "
              << "\n effacer la liste a sortir                         ->  (rep : ef) "
              << "\n toutes les grandeurs (par defaut)                 ->  (rep : to) "
              << "\n fin                                               ->  (rep :  f) ";
         rop = lect_return_defaut(false,"f");
         if (rop == "gr")
           { string nom_ref;
             cout << "\n nom de la grandeurs ? ";nom_ref=lect_chaine();
             // vérif que la grandeur existe
             bool existe=false;
             for (int i=1;i<=9;i++)
               if (tsousMotref(i)==nom_ref)
                 {existe = true;break;}
             if (existe)
              { list_grandeurs.push_back(nom_ref);}
             else
              { cout << "\n erreur la grandeur (** "<< nom_ref << " **)  donnee ne correspond pas a une grandeur acceptable ";};
           }
          else if (rop == "ef")
           { // on efface la liste des grandeurs
             list_grandeurs.clear();
           }
          else if (rop == "to")
           { for (int i=1;i<= 9; i++)
               list_grandeurs.push_back(tsousMotref(i));
           };
          // visualisation de la liste actuelle
          if (list_grandeurs.size() != 0)
           { list <string>::iterator ili,ilifin = list_grandeurs.end();
             cout << "\n liste actuelle de grandeurs : ";
             for (ili=list_grandeurs.begin();ili != ilifin;ili++)
               cout <<  (*ili) << " ";
             cout << "\n ";
           };
       };
      // -- on sort les infos
      sort  << "\n#  ---------------- resultats sur des fichiers particuliers -----------"; 
      sort << "\n  resultats #----------- " 
           << "\n    COPIE 0   "
           << "\n  ";
      list <string>::iterator im,imfin= list_grandeurs.end();
      list <Deux_String>::const_iterator il,ilfin=list_ref.end();
      for (il=list_ref.begin();il != ilfin;il++)
        {sort << "\nPOINTS_INTEGRATION  ";
         if ((*il).nom1 != "_")
           { sort << "nom_mail= "<<(*il).nom1 << "  ";};
         sort << (*il).nom2 << "\n";
         for (im = list_grandeurs.begin();im != imfin;im++)
           sort << (*im) << " ";
        };
      sort << "\n ";
 
   	};
  };
 sort << flush;

 /*
    sort << "\n# Il s'agit uniquement des sorties automatiques effectuees a la fin de l'execution" //
         << "\n#  Le choix est limite, si l'on veut plus de choix il faut utiliser la sortie interactive " //
         << "\n#  et construire un fichier .CVisu  " //
         << "\n#  ------------------------------------------------------------------------------------ "; //
    sort << "\n             resultats #-----------mot cle         " //
         << "\n# (( si le mot cle resultats est absent : utilisation de tous les parametres par defauts ))  " 
         << "\n#------------------------------------puis par exemple-----------------------------------    "
         << "\nCOPIE 0  # =0 par defaut, si = 1: il y a recopie a l'ecran de tout ce qui a ete lue jusqu'ici "
         << "\nPOINTS_INTEGRATION E_tout "
         << "\nGreen-Lagrange Almansi Cauchy_global Def_mixte_local Sigma_mixte_local"
         << "\n#................................................................................"
         << "\n# explication: POINTS_INTEGRATION signifie que l'on veut une sortie aux points d'integration "
         << "\n# E_tout est la reference pour laquelle on veut les infos "
         << "\n# puis on definit certaines grandeurs que l'on veut sortir aux points d'integrations "
         << "\n# qui sont a choisir entre: "
         << "\n# Green-Lagrange Almansi Cauchy_global Def_mixte_local Sigma_mixte_local Sigma_principale"
         << "\n# Def_principale Resultat_loi logarithmique "
         << "\n#................................................................................."
         << "\n#   ********* dans le cas particulier ou l'on veut aucun resultat on indique au debut "
         << "\n#             resultats  pas_de_sortie_finale_ "
         << "\n#";*/

};  

// sortie des resultats suivant les infos stockee durant la lecture du fichier d'entree
void Resultats::SortieInfo
   (ParaGlob * paraGlob,LesMaillages* lesMail,LesReferences* lesRef,
          LesCondLim * lesCondLim,LesContacts* lescontacts)
  { // sortie des frontières dans le cas ou le calcul a été  demandé
    if ((paraGlob->TypeCalcul_principal(INFORMATIONS)) &&
        (paraGlob->SousTypeCalcul(frontieres)))
        SortieFrontieres(lesMail);
    else if (!pas_de_sortie)    
     { // sortie des grandeurs duales aux points d'integration
       // sous une forme texte lisible
       PointsDintegration(lesMail,lesRef);
       // sortie des contraintes aux éléments en texte peu lisible mais condensé
       SortieElemenContrainte(lesMail,paraGlob);
       // sortie des ddls et grandeurs aux noeuds 
       SortieNoeuds(lesMail,lesRef);
       // sortie des reactions
       SortieReactions(lesMail,lesRef,lesCondLim);
       // sortie d'information concernant le contact
       if (lescontacts != NULL)
         // appel d'une routine specifique 
         SortieContacts(lescontacts);
       // cas d'un calcul de flambement  
       if (paraGlob->TypeCalcul_principal(FLAMB_LINEAIRE))
       SortieFlamb();
       // sortie des deformees pour livan
       SortieDeformee(lesMail,lesRef,paraGlob);
       // dans le cas ou l'on  a une remontée aux contraintes, sortie d'isovaleurs
       // de contraintes.
         // récup de la liste des sous types
       list <EnumSousTypeCalcul> const & lis_sous = paraGlob->LesSousTypesDeCalcul();   
       list <EnumSousTypeCalcul>::const_iterator ik,ikfin; // iterators 
       ikfin = lis_sous.end();
       for (ik= lis_sous.begin();ik!=ikfin;ik++)
        if ( (Remonte_in(*ik)) && paraGlob->SousTypeCalcul(*ik))
          SortieNoeudContaintes(lesMail,lesRef,paraGlob);
       // dans le cas ou l'on  a une remontée aux erreurs, sortie d'isovaleurs
       // d'erreurs. 
       for (ik= lis_sous.begin();ik!=ikfin;ik++)
        if (Erreur_in(*ik) && paraGlob->SousTypeCalcul(*ik))
         {SortieNoeudErreur(lesMail,lesRef,paraGlob);
          // idem mais aux éléments
          SortieElemErreur(lesMail,lesRef,paraGlob);
          }
       // sortie des frontières dans le cas ou le calcul a été  demandé
       if ((paraGlob->TypeCalcul_principal(INFORMATIONS) ) &&
           (paraGlob->SousTypeCalcul(frontieres)))
           SortieFrontieres(lesMail); 
     };       
    // sortie de la deformee du maillage pour l'article
    // tirer les commentaires !!!!!!!!
 //   DeformeeArticle(lesMail);                
     
   };
   
//----- lecture écriture base info -----
// lecture base info
void Resultats::Lect_result_base_info(ifstream& ent,const int cas)
{  if (cas == 1)
   { string toto;
     // lecture de l'entête et vérification 
     ent >> toto ;
     if (toto != "****Resultats")
       Sortie(1);
	  ent >> pas_de_sortie ; 	// lecture de l'indication éventuelle de aucune sortie  
     // entrée des  tableau des regions
     // tout d'abord le nombre d'élément
     int tabRegion_taille; 
     ent >> toto >> tabRegion_taille ;
     // on boucle sur le nombre
     BlocGen interne;
     for (int i=1;i<= tabRegion_taille;i++)
      { ent >> interne; // lecture
        // intégration dans la liste
	    tabRegion.push_back(interne);                 
       }
     //  parametres de gestion
     ent >> toto >> copie ;
    } 
  };

//   écriture base info   
void Resultats::Ecri_result_base_info(ofstream& sort,const int cas)
{  if (cas == 1)
  { sort << "\n ****Resultats "<< pas_de_sortie <<"  \n";
    // sortie des  tableau des regions
    // tout d'abord le nombre d'élément et un identificateur
    sort << "liste_region:_nb= " << tabRegion.size() << "\n";
    // on balaie la liste 
    list <BlocDdlLim< BlocGen> >::const_iterator i;
    for (i=tabRegion.begin() ; i != tabRegion.end(); i++)
       sort << (*i) ;
    sort << "\n";   
    //  parametres de gestion
    sort << "copie: " << copie << " ";
   }
  }; 
     

// =============================== fonctions privates ==============   
   
// lecture concernant les sorties aux points d'integration
void Resultats::ReadPtInteg(LesReferences* lesRef,Tableau<string>& TsousMot)
  { // definition de la liste de  mot  specifique acceptable
    Tableau<string> tsousMotref(9);
    tsousMotref(1) = "Green-Lagrange";tsousMotref(2) = "Almansi";
    tsousMotref(3) = "Cauchy_global";tsousMotref(4) = "Def_mixte_local";
    tsousMotref(5) = "Sigma_mixte_local";tsousMotref(6) = "Sigma_principale";
    tsousMotref(7) = "Def_principale";tsousMotref(8) = "Resultat_loi";
    tsousMotref(9) = "logarithmique";
    string message =
    " *** lecture des conditions de sortie des variables duales au points d\'integration";    
    // lecture 
    // on commence par passer le mot cle
    string nom;
    LectBlocmot lectBlocmot;
    BlocDdlLim< BlocGen> blocMot =   lectBlocmot.Lecture
                  (*entreePrinc,*lesRef,message,tsousMotref,TsousMot);
    // stockage
    tabRegion.push_back(blocMot);
  };
// Lectures concernant les sorties aux noeuds
void Resultats::ReadNoeuds(LesReferences* )
  {
  };
// lectures concernant les reactions
void Resultats::ReadReac(LesReferences* )
  { 
  };
// lectures concernant les deformees
void Resultats::ReadDeformee(LesReferences* )
  { 
  };

// sortie des grandeurs duales aux points d'integration
void Resultats::PointsDintegration(LesMaillages* lesMail,LesReferences* lesRef)
 { // ouverture du fichier de resultats
   char nomm[132];
   char*fileName  = nomm;
   strcpy(fileName,entreePrinc->RacineNom());
   ofstream sort(strcat(fileName,".res"));
   if(!(sort.is_open())) 
     { cout << "\n erreur en ouverture du fichier " << fileName 
            << ", Resultats::PointsDintegration(etc..." << endl;
       Sortie(1);
      };  
   // cas ou la liste est vide, on sort toutes les informations
   if (tabRegion.size() == 0)
    { for (int numMail=1;numMail<= lesMail->NbMaillage();numMail++)
        for (int numElem=1; numElem<= lesMail->Nombre_element(numMail);numElem++) 
            { // recup de l'element
              Element & elem = lesMail->Element_LesMaille(numMail,numElem);
              sort << "\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" ;
              sort << "\n   element " << numElem << " du maillage " << numMail;
              sort << "\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" ;
              Tableau <string> tab; // tableau vide
              elem.AfficheVarDual(sort,tab);
            }          
    }
   // sinon on balaie la liste de reference d'element a sortir   
   list <BlocDdlLim< BlocGen> >::iterator ibloc; // def d'un iterator adoc
   for (ibloc=tabRegion.begin(); ibloc != tabRegion.end(); ibloc++)
      { // recup de la reference correspondant au mot cle
        const ReferenceNE & ref 
            = ((ReferenceNE &)lesRef->Trouve((*ibloc).NomRef(),(*ibloc).NomMaillage()));
        if (ref.Indic() != 2)
          // cas autre que des elements
          { cout << "\n sortie de resultats aux points d\'integration "
                 << "autre que sur des elements pas d\'action implentee a ce sujet !!";
            cout << "\nResultats::PointsDintegration(etc... " << endl;
            Sortie(1);
           }
        else
         {
          // cas des elements
          Tableau <string> tab;
          if ((*ibloc).DimNom() > 1)  
            // cas ou des noms de variable duale sont specifies
           { tab.Change_taille((*ibloc).DimNom() -1);
             for (int nbnom=2; nbnom<= (*ibloc).DimNom(); nbnom++)
               tab (nbnom-1) = (*ibloc).Nom(nbnom);
            }
          for (int nn =1; nn<= ref.Taille();nn++)
            { // recup de l'element
              Element & elem = lesMail->Element_LesMaille(ref.Nbmaille(),ref.Numero(nn));
              sort << "\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" ;
              sort << "\n   element " << ref.Numero(nn) << " du maillage " << ref.Nbmaille();
              sort << "\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" ;
              elem.AfficheVarDual(sort,tab);
            }
         }
        } 
   // on vide le buffer de sortie
   sort << endl;           
 };
// sortie des ddls et grandeurs aux noeuds 
void Resultats::SortieNoeuds(LesMaillages* lesMail,LesReferences* )
  { // ouverture du fichier de resultats
   char nomm[132];
   char*fileName  = nomm;
   strcpy(fileName,entreePrinc->RacineNom());
   ofstream sort(strcat(fileName,".ddl"));
   if(!(sort.is_open())) 
     { cout << "\n erreur en ouverture du fichier " << fileName 
            << ", Resultats::SortieNoeuds(etc..." << endl;
       Sortie(1);
      };
   // on balaie tous les noeuds de tous les maillages
   int nbmaximaillage = lesMail->NbMaillage();
   for (int numMail=1;numMail<= nbmaximaillage;numMail++)
      { int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
        for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
            { // recup du noeud
              Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
              noe.Affiche(sort);
            } 
          }           
   // on vide le buffer de sortie
   sort << endl;                   
  };
// sortie des reactions
void Resultats::SortieReactions
    (LesMaillages* lesMail,LesReferences* ,LesCondLim * lesCondLim)
  { // ouverture du fichier de resultats
   char nomm[132];
   char*fileName  = nomm;
   strcpy(fileName,entreePrinc->RacineNom());
   ofstream sort(strcat(fileName,".reac"));
   if(!(sort.is_open())) 
     { cout << "\n erreur en ouverture du fichier " << fileName 
            << ", Resultats::SortieNoeuds(etc..." << endl;
       Sortie(1);
      };
   // affichage
   lesCondLim->Affiche_reaction(sort,lesMail);
   // on vide le buffer de sortie
   sort << endl;                   
      
  };
  
// sortie du contact
void Resultats::SortieContacts(LesContacts* lescontacts)
  { // ouverture du fichier de resultats
   char nomm[132];
   char*fileName  = nomm;
   strcpy(fileName,entreePrinc->RacineNom());
   ofstream sort(strcat(fileName,".cont"));
   if(!(sort.is_open())) 
     { cout << "\n erreur en ouverture du fichier " << fileName 
            << ", Resultats::SortieNoeuds(etc..." << endl;
       Sortie(1);
      };
   // affichage
   sort << "#=====================================================\n";
   sort << "#    Reactions de contact  \n";
   sort << "#=====================================================\n";
   lescontacts->Affiche(sort);
   // on vide le buffer de sortie
   sort << endl;                         
  };
//  sortie pour le flambement
void Resultats::SortieFlamb()
  { // ouverture du fichier de resultats
   char nomm[132];
   char*fileName  = nomm;
   strcpy(fileName,entreePrinc->RacineNom());
   ofstream sort(strcat(fileName,".flamb"));
   if(!(sort.is_open())) 
     { cout << "\n erreur en ouverture du fichier " << fileName 
            << ", Resultats::SortieFlamb()" << endl;
       Sortie(1);
      };
   // affichage
   sort << "#=====================================================\n";
   sort << "#    cas d'un calcul de flambement \n";
   sort << "#=====================================================\n";
   lesValVecPropres.Affiche(sort);
   // on vide le buffer de sortie
   sort << endl;                         
  };
  
// sortie des deformees
void Resultats::SortieDeformee(LesMaillages* lesMail,LesReferences*,ParaGlob * paraGlob )
  { // on veut sortir une deforme pour chaque maillage 
     int nbmaximaillage = lesMail->NbMaillage();
     for (int numMail=1;numMail<= nbmaximaillage;numMail++)
       { // ouverture du fichier pour ecrire la deformee
          char nomm[132];
          char*fileName  = nomm;
          // transformation du nb de maillage en char*
          string toto = ChangeEntierSTring(numMail );
          char* cnbmaille = (char *) toto.c_str();
          strcpy(fileName,entreePrinc->RacineNom());
          ofstream sort(strcat(strcat(fileName,cnbmaille),"_dpl.points"));
          if(!(sort.is_open())) 
             { cout << "\n erreur en ouverture du fichier " << fileName 
                         << ", Resultats::SortieDeformee(etc..." << endl;
                 Sortie(1);
               }
          // on balaie tous les noeuds du maillage
          int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
           sort << nbmaxinoeud << "\n ";
          Coordonnee coor_zero(paraGlob->Dimension ()); // coordonnées nulles 
          for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
            { // recup du noeud
              Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
              if (noe.ExisteCoord1())
               { // ecriture de la difference de coordonnee entre 0 et t
                 sort << setw (16); (noe.Coord1() - noe.Coord0() ).Affiche(sort,16);
                }
              else
               { // cas où le noeud n'a pas bougé
                 // ecriture de la difference de coordonnee entre 0 et t
                 sort << setw (16); coor_zero.Affiche(sort,16);
                } 
              // si l'on n'est pas en dimension 3 on complete avec des zeros
              if (paraGlob->Dimension () == 2)
                { sort << setw (16) << 0 <<" ";
                 }
              else if (paraGlob->Dimension () == 1)
                 { sort << setw (16) << 0  <<" " << setw (16) << 0  <<" ";
                 }
              sort << setw (16)  << 0  << "\n  ";
              }
          // on vide le buffer de sortie
          sort << endl;                         
        };
   };         
// dans le cas ou l'on  a une remontée aux contraintes, sortie d'isovaleurs
// de contraintes.
void Resultats::SortieNoeudContaintes
              (LesMaillages* lesMail,LesReferences* ,ParaGlob * paraGlob)
  { // on sort les contraintes aux noeuds dans le cas où a priori elles ont
    // ete calculées
          // récup de la liste des sous types
   list <EnumSousTypeCalcul> const & lis_sous = paraGlob->LesSousTypesDeCalcul();   
   list <EnumSousTypeCalcul>::const_iterator ik,ikfin; // iterators 
   ikfin = lis_sous.end();
   for (ik= lis_sous.begin();ik!=ikfin;ik++)
    if ( (Remonte_in(*ik)) && paraGlob->SousTypeCalcul(*ik))
     {
     // on veut sortir des isovaleurs  pour chaque maillage 
     int nbmaximaillage = lesMail->NbMaillage();
     for (int numMail=1;numMail<= nbmaximaillage;numMail++)
       { // ouverture du fichier pour ecrire contraintes aux noeuds
          char nomm[132];
          char*fileName  = nomm;
          // transformation du nb de maillage en char*
          string toto = ChangeEntierSTring(numMail );
          char* cnbmaille = (char *) toto.c_str();
          strcpy(fileName,entreePrinc->RacineNom());
          ofstream sort(strcat(strcat(fileName,cnbmaille),"_cab.ison"));
          if(!(sort.is_open())) 
             { cout << "\n erreur en ouverture du fichier " << fileName 
                         << ", Resultats::SortieNoeudContaintes(etc..." << endl;
                 Sortie(1);
               }
          int dim = paraGlob->Dimension ();     
          // on balaie tous les noeuds du maillage
          int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
          // écriture de l'entête
          sort << nbmaxinoeud << "      0 \n";
          int nbcomposante; // nombre de composante du tenseur des contraintes
          sort << "      ";
          switch (dim)
	       { case 1 : sort << "     Sig11            SigI            Mises       "
	                       << "     Tresca" ; nbcomposante= 1;  break;
	         case 2 : sort << "     Sig11            Sig22           Sig12       "
	                       << "     SigI             SigII           Mises       "
	                       << "     Tresca" ; nbcomposante= 3; break; 
	         case 3 : sort << "     Sig11            Sig22           Sig33       "
	                       << "     Sig12            Sig13           Sig23       "
	                       << "     SigI             SigII           SigIII      "
	                       << "     Mises            Tresca"; nbcomposante= 6; break;
	        }; 
	      sort << '\n';  
	      // def d'un vecteur contenant les coordonnées du tenseur
	      Vecteur Sig; // dimension par défaut   
          Coordonnee valPropreSig; 
          
          for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
            { // recup du noeud
              Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
              bool retour = noe.Contrainte(Sig); // recup des contraintes
              // écriture
              sort << setw (5) << "-1";
              if (retour)
                { // sortie des contraintes
                  for (int i=1;i<= nbcomposante;i++)
                    sort << setw (16) << Sig(i) << " " ;
                  // ---- sortie des contraintes principales ---
                  // 1) reconstitution du tenseur
                  TenseurHB* sigHB;
                  switch (dim)
	               { case 1 : sigHB = new Tenseur1HB(Sig(1));  break;
	                 case 2 : sigHB = new Tenseur2HB(Sig(1),Sig(2),Sig(3),Sig(3)); break; 
	                 case 3 : sigHB = new Tenseur3HB(Sig(1),Sig(4),Sig(5),
	                                                 Sig(4),Sig(2),Sig(6),
	                                                 Sig(5),Sig(6),Sig(3)); break;
	                }; 
                  // 2) calcul des valeurs propres
                  int cas;
                  valPropreSig = sigHB->ValPropre(cas);
                  if (cas == -1) 
                    { cout << "\n warning *** erreur dans le calcul des valeurs propres de la contrainte";
                      if (ParaGlob::NiveauImpression() >= 7) 
                          {sigHB->Ecriture(cout); cout << "\nResultats::SortieNoeudContaintes(...";};
                      cout << endl;    
                     };   
                  // 3) sortie des contraintes principales
                  int nval = valPropreSig.Dimension();
                  for (int i=1;i<= nval;i++)
                    sort << setw (16) << valPropreSig(i) << " " ;
                  // 4) def de la contrainte de Mises et de Tresca
                  Coordonnee& vv = valPropreSig; // pour condenser l'écriture
                  double Mises = 0.; double Tresca = 0.;
                  if (dim ==1) { Mises = Dabs(vv(1)); Tresca = Mises/2.;}
                  else if (dim ==2) { Mises = Dabs(vv(1)-vv(2));Tresca = Mises/2.;}
                  else {Mises = sqrt( ((vv(1)-vv(2))*(vv(1)-vv(2)) + (vv(1)-vv(3))*(vv(1)-vv(3))
                                 + (vv(3)-vv(2))*(vv(3)-vv(2))) * 0.5);;
                        Tresca = 0.5* MaX( MaX(Dabs(vv(1)-vv(2)),Dabs(vv(1)-vv(3))), Dabs(vv(2)-vv(3)));
                        } 
                  // 5) Sortie de Mises et Tresca
                  sort << setw (16) << Mises << " " << setw (16) << Tresca << " " ;       
	                
                  sort << '\n'; 
                  }  
             } 
          // on vide le buffer de sortie
          sort << endl;                         
        };
      };  
   }; 
           
// dans le cas ou l'on  a une remontée aux erreurs, sortie d'isovaleurs
// d'erreur aux noeuds.
 void Resultats::SortieNoeudErreur
              (LesMaillages* lesMail,LesReferences* ,ParaGlob * paraGlob)
  { // on sort les erreurs aux noeuds dans le cas où a priori elles ont
    // ete calculées
         // récup de la liste des sous types
   list <EnumSousTypeCalcul> const & lis_sous = paraGlob->LesSousTypesDeCalcul();   
   list <EnumSousTypeCalcul>::const_iterator ik,ikfin; // iterators 
   ikfin = lis_sous.end();
   for (ik= lis_sous.begin();ik!=ikfin;ik++)
    if (Erreur_in(*ik) && paraGlob->SousTypeCalcul(*ik))
     {
     // on veut sortir des isovaleurs  pour chaque maillage 
     int nbmaximaillage = lesMail->NbMaillage();
     for (int numMail=1;numMail<= nbmaximaillage;numMail++)
       { // ouverture du fichier pour ecrire contraintes aux noeuds
          char nomm[132];
          char*fileName  = nomm;
          // transformation du nb de maillage en char*
          string toto = ChangeEntierSTring(numMail );
          char* cnbmaille = (char *) toto.c_str();
          strcpy(fileName,entreePrinc->RacineNom());
          ofstream sort(strcat(strcat(fileName,cnbmaille),"_err.ison"));
          if(!(sort.is_open())) 
             { cout << "\n erreur en ouverture du fichier " << fileName 
                         << ", Resultats::SortieNoeudErreur(etc..." << endl;
                 Sortie(1);
               }
          //int dim = paraGlob->Dimension ();     
          // on balaie tous les noeuds du maillage
          int nbmaxinoeud = lesMail->Nombre_noeud(numMail);
          // écriture de l'entête
          sort << nbmaxinoeud << "      0 \n";
          sort << "              ERREUR    \n";
          // tout d'abord on fait un premier passage pour déterminer le
          // minimum de l'erreur
          double miniErreur =0.;
          for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
            { // recup du noeud
              Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
              miniErreur = MiN(noe.Valeur_t(ERREUR),miniErreur); 
              }
          // sortie des erreurs traités avec les log pour augmenter 
          // la plage de concentration
          for (int numNoeud=1; numNoeud<= nbmaxinoeud;numNoeud++) 
            { // recup du noeud
              Noeud & noe = lesMail->Noeud_LesMaille(numMail,numNoeud);
              // écriture conditionnelle
              if (noe.Existe_ici(ERREUR))
               { sort << setw (5) << "-1";
                 double erreur = noe.Valeur_t(ERREUR); // l'erreur
                 // finalement on sort une grandeur régulée par le log
                 // avec un décalage sur 1 pour le mini, d'où un log nul
                 sort << setw (16) << (log(erreur-miniErreur+1.)) << " " ;
 //                sort << setw (16) << erreur << " " ;
                 sort << '\n'; 
                } 
             } 
          // on vide le buffer de sortie
          sort << endl;                         
        };
      };  
   }; 
           
// dans le cas ou l'on  a une remontée aux erreurs, sortie des valeurs d'erreur
// aux éléments.
 void Resultats::SortieElemErreur
              (LesMaillages* lesMail,LesReferences* ,ParaGlob * paraGlob)
  { // on sort les erreurs aux éléments dans le cas où a priori elles ont
    // ete calculées
         // récup de la liste des sous types
   list <EnumSousTypeCalcul> const & lis_sous = paraGlob->LesSousTypesDeCalcul();   
   list <EnumSousTypeCalcul>::const_iterator ik,ikfin; // iterators 
   ikfin = lis_sous.end();
   for (ik= lis_sous.begin();ik!=ikfin;ik++)
    if (Erreur_in(*ik) && paraGlob->SousTypeCalcul(*ik))
     {
     // on veut sortir les valeurs  pour chaque maillage 
     int nbmaximaillage = lesMail->NbMaillage();
     for (int numMail=1;numMail<= nbmaximaillage;numMail++)
       { // ouverture du fichier pour ecrire  aux éléments
          char nomm[132];
          char*fileName  = nomm;
          // transformation du nb de maillage en char*
          string toto = ChangeEntierSTring(numMail );
          char* cnbmaille = (char *) toto.c_str();
          strcpy(fileName,entreePrinc->RacineNom());
          ofstream sort(strcat(strcat(fileName,cnbmaille),"_err.isoe"));
          if(!(sort.is_open())) 
             { cout << "\n erreur en ouverture du fichier " << fileName 
                         << ", Resultats::SortieElemErreur(etc..." << endl;
                 Sortie(1);
               }
          //int dim = paraGlob->Dimension ();     
          // on balaie tous les éléments du maillage
          int nbmaxiElement = lesMail->Nombre_element(numMail);
          // écriture de l'entête
          sort << nbmaxiElement << "      0 \n";
          sort << "              ERREUR    \n";
          for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
            { // recup de l'élément
              Element & noel = lesMail->Element_LesMaille(numMail,numElem);
              // écriture conditionnelle au cas mécanique et au cas ou l'erreur a été 
              // calculée
              if (noel.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
               if (((ElemMeca&) noel).ErreurDejaCalculee())
                {sort << setw (5) << "-1";
                 double erreur = noel.Erreur(); // l'erreur
                 // l'erreur doit être forcément supérieur à 0
                 // dans le cas où elle est négative, on la met à 0
                 if(erreur < 0.)
                    erreur = 0.;
                 sort << setw (16) << erreur << " " ;
                 sort << '\n'; 
                } 
             } 
          // on vide le buffer de sortie
          sort << endl;                         
        };
      };  
   };
    
// sortie des contraintes aux éléments en texte peu lisible mais condensé
void Resultats::SortieElemenContrainte
              (LesMaillages* lesMail,ParaGlob * paraGlob)
  {  // on veut sortir les valeurs  pour chaque maillage 
     int nbmaximaillage = lesMail->NbMaillage();
     for (int numMail=1;numMail<= nbmaximaillage;numMail++)
       { // ouverture du fichier pour ecrire  aux éléments
          char nomm[132];
          char*fileName  = nomm;
          // transformation du nb de maillage en char*
          string toto = ChangeEntierSTring(numMail );
          char* cnbmaille = (char *) toto.c_str();
          strcpy(fileName,entreePrinc->RacineNom());
          ofstream sort(strcat(strcat(fileName,cnbmaille),"_cab.isoe"));
          if(!(sort.is_open())) 
             { cout << "\n erreur en ouverture du fichier " << fileName 
                         << ", Resultats::SortieElemenContrainte(etc..." << endl;
                 Sortie(1);
               }
          int dim = paraGlob->Dimension ();     
          // on balaie tous les éléments du maillage
          int nbmaxiElement = lesMail->Nombre_element(numMail);
          // écriture de l'entête
          sort << "      0    " << nbmaxiElement << " \n";

          int nbcomposante; // nombre de composante du tenseur des contraintes
          sort << "      ";
          switch (dim)
	       { case 1 : sort << "     Sig11      "; nbcomposante= 1;  break;
	         case 2 : sort << "     Sig11            Sig22           Sig12"; nbcomposante= 3; break; 
	         case 3 : sort << "     Sig11            Sig22           Sig33       "
	                       << "     Sig12            Sig23           Sig13"; nbcomposante= 6; break;
	        }; 
	      sort << '\n';  
	      // def d'un tableau de vecteur contenant les coordonnées du tenseur
	      Tableau <Vecteur> tabSig; // dimension par défaut
	      // il est redimensionné dans l'élément si nécessaire  
	       
	      // on regarde sur le premier élément qui doit être de type mécanique
	      // du maillage si le calcul de contrainte
	      // est possible si oui on continu et on considère que c'est possible pour
	      // tous les autres sinon arrêt pour ce maillage
          Element & elem = lesMail->Element_LesMaille(numMail,1);
          bool possible;
          if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
             possible =  ((ElemMeca&) elem).ContrainteAbsoluePossible();
          else
             possible = false; 
          if (possible)     
           for (int numElem=1; numElem<= nbmaxiElement;numElem++) 
            { // recup de l'élément
              Element & elem = lesMail->Element_LesMaille(numMail,numElem);
              // on regarde si c'est un élément de mécanique
              // si oui on récupère le tableau des tenseurs en absolu
              bool retour = false;
              if (elem.Id_TypeProblem() == MECA_SOLIDE_DEFORMABLE)
                 retour =((ElemMeca&) elem).ContraintesAbsolues(tabSig);
              else
                 retour = false;  
              // écriture
              if (retour)
                { 
                  sort << setw (5) << "-1 " ;
                  int taille = tabSig.Taille();
                  for (int ni = 1; ni<= taille; ni++)
                    for (int i=1;i<= nbcomposante;i++)
                      sort << setw (16) << tabSig(ni)(i) << " " ;
                  sort << '\n'; 
                 }  
             } 
          // on vide le buffer de sortie
          sort << endl;                         
        };
  };
    
// sortie des frontières
void Resultats::SortieFrontieres (LesMaillages* lesMail)
  {  //récupération de la liste de frontière
     Tableau <LaLIST <Front>*>& tablist = lesMail->ListFrontiere();  
     // on veut sortir les valeurs  pour chaque maillage 
     int nbmaximaillage = lesMail->NbMaillage();
     for (int numMail=1;numMail<= nbmaximaillage;numMail++)
       { // ouverture du fichier d'écriture
          char nomm[132];
          char*fileName  = nomm;
          // transformation du nb de maillage en char*
          string toto = ChangeEntierSTring(numMail );
          char* cnbmaille = (char *) toto.c_str();
          strcpy(fileName,entreePrinc->RacineNom());
          // le .faces     
          ofstream sort(strcat(strcat(fileName,cnbmaille),"_front.faces"));
          if(!(sort.is_open())) 
             { cout << "\n erreur en ouverture du fichier .faces" << fileName 
               << ", Resultats::SortieFrontieres (LesMaillages* lesMail)" << endl;
               Sortie(1);
             };
      
          //récupération de la liste de frontière
          LaLIST <Front>& listfront = *(tablist(numMail)); // pour simplifier
          int nbmaxiElement = (int) listfront.size();
           // écriture de l'entête
          sort << "     elements  \n \n" << nbmaxiElement << " ELEMENTS \n \n";
          sort << "#-----------------------------------------------------------------------\n";
          sort << "# NO    Type                   Noeuds                                  |\n";
          sort << "#-----------------------------------------------------------------------\n \n";

          LaLIST <Front>::iterator ip;int ne;
          for (ne=1,ip = listfront.begin();ip != listfront.end(); ip++,ne++)
            { // écriture de l'élément courant
              sort << ne << "  " ;  // le numéro
              const ElemGeomC0 & geom = (*ip).Eleme()->ElementGeometrique();
              sort << Nom_geom(geom.TypeGeometrie()) << "  " ; // la géométrie
              sort << Nom_interpol(geom.TypeInterpolation()) << "  " ; // l'interpolation
              // les noeuds
              Tableau <Noeud *> tabnoeud = (*ip).Eleme()->TabNoeud();
              int taille = tabnoeud.Taille();
              for (int ine = 1; ine<=taille; ine++)
                sort << tabnoeud(ine)->Num_noeud() << " ";
              sort << "\n";
             }   
          // on vide le buffer de sortie
          sort << endl;
          // on ne continue que s'il y a des éléments frontières
          if (listfront.size() != 0)
           {// dans le cas d'un maillage 2D donc d'une frontière 1D on essaie de sortir
            // la frontière ordonnée
            // le .faces     
            ip = listfront.begin() ; // on prend le premier pour tester
            if ((*ip).Eleme()->ElementGeometrique().Dimension() == 1)
             { char nomm2[132]; 
               char*file2Name = nomm2;  
               strcpy(file2Name,entreePrinc->RacineNom());
               ofstream sirt(strcat(strcat(file2Name,cnbmaille),"_frOrdre.faces"));
               if(!(sirt.is_open())) 
                { cout << "\n erreur en ouverture du fichier .faces" << fileName 
                  << ", Resultats::SortieFrontieres (LesMaillages* lesMail)" << endl;
                  Sortie(1);
                 }
               // écriture de l'entête
               sirt << "     elements  \n \n" << nbmaxiElement << " ELEMENTS \n \n";
               sirt << "#-----------------------------------------------------------------------\n";
               sirt << "# NO    Type                   Noeuds                                  |\n";
               sirt << "#-----------------------------------------------------------------------\n \n";
               int ne = 1;
               Front * precedent = NULL;
               Front * debut =  &(*ip);
               Front* elfront = &(*ip);
               while(ne <= nbmaxiElement) 
                { // écriture de l'élément courant
                  sirt << ne << "  " ;  // le numéro
                  const ElemGeomC0 & geom = elfront->Eleme()->ElementGeometrique();
                  sirt << Nom_geom(geom.TypeGeometrie()) << "  " ; // la géométrie
                  sirt << Nom_interpol(geom.TypeInterpolation()) << "  " ; // l'interpolation
                  // les noeuds
                  Tableau <Noeud *> tabnoeud = elfront->Eleme()->TabNoeud();
                  int taille = tabnoeud.Taille();
                  for (int ine = 1; ine<=taille; ine++)
                    sirt << tabnoeud(ine)->Num_noeud() << " ";
                  sirt << "\n";
                  ne++;
                  // récupération de l'élément frontière suivant
                  const Tableau <Front*>* tabmitoyen=elfront->TabMitoyen();
                  if (tabmitoyen != NULL)
                   {for (int i=1;i<=tabmitoyen->Taille();i++)
                    if ((*tabmitoyen)(i) != precedent)
                      { elfront = &(*(*tabmitoyen)(i));
                        break;
                        }
                   };
                  // si l'on a rejoint le début on s'arrête
                  if ( elfront == debut) break;     
                 };
               ne--;   
               if (ne != nbmaxiElement) 
                // cas où l'on n'a pas parcouru toute la liste
                 cout << " \n Resultats::SortieFrontieres (LesMaillages* lesMail)" 
                      << "\n pour la sortie ordonnée, "
                      << " toutes les frontières n'ont pas été copiées !!"
                      << "\n sans doute parce que les frontières sont "
                      << " constituées de plusieurs boucles \n";  
               // on vide le buffer de sortie
               sirt << endl;
               }
           };
         };
  };

// sortie de la deformee du maillage pour l'article
void Resultats::DeformeeArticle(LesMaillages* lesmail)
  {// ouverture du fichier de resultats
   char nomm[132];
   char*fileName  = nomm;
   strcpy(fileName,entreePrinc->RacineNom());
   ofstream sort(strcat(fileName,".def"));
   if(!(sort.is_open())) 
     { cout << "\n erreur en ouverture du fichier " << fileName 
            << ", Resultats::SortieNoeuds(etc..." << endl;
       Sortie(1);
      };
   // on divise les faces des cubes en n*n petites facettes
   int n = 4 ;  // 4 par defaut
   // question sur le cas
   int cas;
   cout << " cas 1cube seule (3), avec biellette (1) , 2 cube (2) ou autre pour arreter?\n"
        << " (un nombre negatif pour avoir les ligne du cube initial) "
        << " un cube et une biellette lies (4), deux cubes lies (5)";
   cas=(int)lect_double();
   cout << "\n valeur de n ? ";
   n = (int) lect_double();
   if ((cas!=1) && (cas!=2) && (cas!=3)&&(cas!=-1) && (cas!=-2)
       && (cas!=-3) && (Dabs(cas) != 4) && (Dabs(cas) != 5) ) return;
   // si cas = 1 -> 1 cube sinon 2 cubes
   int nbface; //nb face
   int nbnoe;  // nb de noeud
   int nbface0 = 0; //nb face a t= 0
   int nbnoe0 = 0;  // nb de noeud a t = 0
   Tableau <Coordonnee> tabCgen; // tableau general des noeuds
   Tableau < Tableau <int> >  tabFgen; // tableau general des faces
   if (cas < 0)
     { nbface0 = 12;
       nbnoe0 = 8;
      } 
   Tableau <Coordonnee> tabc;      // tableau inter
   Tableau < Tableau <int> >  tabF;//    "      "
   int inNoe =1; // indice de noeud
   int inFace =1; // indice de face
   int decalNoe = 0; // decalage sur les noeuds
   
   if (Dabs(cas) == 3)
     { nbface = 6*n*n + nbface0;
       nbnoe = 8 + (n-1)*12 + (n-1)*(n-1)*6 + nbnoe0 ;
       tabCgen.Change_taille(nbnoe);
       tabFgen.Change_taille(nbface);
      // premier maillage -> le cube
       Tableau<Noeud *>& t1 = lesmail->Element_LesMaille(1,1).Tab_noeud();
       ZoomElem(t1,n,tabc,tabF);
       for (int i=1;i<=tabc.Taille();i++,inNoe++)
         tabCgen(inNoe) = tabc(i);
       for (int i=1;i<=tabF.Taille();i++,inFace++)
         tabFgen(inFace) = tabF(i);
       decalNoe += tabc.Taille();  
       // second maillage le cube initial
       if (cas < 0)
        { InitialC(t1,n,tabc,tabF);
          for (int i=1;i<=tabc.Taille();i++,inNoe++)
            tabCgen(inNoe) = tabc(i);
          for (int i=1;i<=tabF.Taille();i++,inFace++)
            { tabFgen(inFace).Change_taille(4);
              for (int j=1;j<=4;j++)
               tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
             }  
         }  
      } 
   else if (Dabs(cas) == 1)
     { nbface = 6*n*n + 1 + nbface0;
       nbnoe = 8 + (n-1)*12 + (n-1)*(n-1)*6 + 2 + nbnoe0;
       tabCgen.Change_taille(nbnoe);
       tabFgen.Change_taille(nbface);
      // 1er maillage -> la biellete
       Tableau<Noeud *>& t1 = lesmail->Element_LesMaille(1,1).Tab_noeud();
       tabFgen(1).Change_taille(4);
       tabFgen(1)(1) = 1;tabFgen(1)(2) = 2;
       tabFgen(1)(3) = 1;tabFgen(1)(4) = 1;
       tabCgen(1) = t1(1)->Coord2();tabCgen(2) = t1(2)->Coord2();
       inNoe = 3; inFace = 2; decalNoe += 2;
      // second maillage -> le cube deforme
       Tableau<Noeud *>& t2 = lesmail->Element_LesMaille(2,1).Tab_noeud();
       ZoomElem(t2,n,tabc,tabF);
       for (int i=1;i<=tabc.Taille();i++,inNoe++)
         tabCgen(inNoe) = tabc(i);
       for (int i=1;i<=tabF.Taille();i++,inFace++)
        { tabFgen(inFace).Change_taille(4);
          for (int j=1;j<=4;j++)
            tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
         }
       decalNoe += tabc.Taille();     
       // troisieme maillage le cube initial
       if (cas < 0)
        { InitialC(t2,n,tabc,tabF);
          for (int i=1;i<=tabc.Taille();i++,inNoe++)
            tabCgen(inNoe) = tabc(i);
          for (int i=1;i<=nbface0;i++,inFace++)
            { tabFgen(inFace).Change_taille(4);
              for (int j=1;j<=4;j++)
               tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
             }  
         }  
      } 
   else if (Dabs(cas) == 4)
     { nbface = 6*n*n + 1 + nbface0;
       nbnoe = 8 + (n-1)*12 + (n-1)*(n-1)*6 + 2 + nbnoe0;
       tabCgen.Change_taille(nbnoe);
       tabFgen.Change_taille(nbface);
      // 1er maillage -> la biellete -> second element
       Tableau<Noeud *>& t1 = lesmail->Element_LesMaille(1,2).Tab_noeud();
       tabFgen(1).Change_taille(4);
       tabFgen(1)(1) = 1;tabFgen(1)(2) = 2;
       tabFgen(1)(3) = 1;tabFgen(1)(4) = 1;
       tabCgen(1) = t1(1)->Coord2();tabCgen(2) = t1(2)->Coord2();
       inNoe = 3; inFace = 2; decalNoe += 2;
      // second maillage -> le cube deforme -> le premier element
       Tableau<Noeud *>& t2 = lesmail->Element_LesMaille(1,1).Tab_noeud();
       ZoomElem(t2,n,tabc,tabF);
       for (int i=1;i<=tabc.Taille();i++,inNoe++)
         tabCgen(inNoe) = tabc(i);
       for (int i=1;i<=tabF.Taille();i++,inFace++)
        { tabFgen(inFace).Change_taille(4);
          for (int j=1;j<=4;j++)
            tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
         }
       decalNoe += tabc.Taille();     
       // troisieme maillage le cube initial
       if (cas < 0)
        { InitialC(t2,n,tabc,tabF);
          for (int i=1;i<=tabc.Taille();i++,inNoe++)
            tabCgen(inNoe) = tabc(i);
          for (int i=1;i<=nbface0;i++,inFace++)
            { tabFgen(inFace).Change_taille(4);
              for (int j=1;j<=4;j++)
               tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
             }  
         }  
      } 
   else if (Dabs(cas) == 2)
     { nbface = 12*n*n + 2*nbface0;
       nbnoe = 2*(8 + (n-1)*12 + (n-1)*(n-1)*6) + 2*nbnoe0;
       tabCgen.Change_taille(nbnoe);
       tabFgen.Change_taille(nbface);
      // 1er maillage -> le premier cube deforme
       Tableau<Noeud *>& t1 = lesmail->Element_LesMaille(1,1).Tab_noeud();
       ZoomElem(t1,n,tabc,tabF);
       for (int i=1;i<=tabc.Taille();i++,inNoe++)
         tabCgen(inNoe) = tabc(i);
       for (int i=1;i<=tabF.Taille();i++,inFace++)
        { tabFgen(inFace).Change_taille(4);
          for (int j=1;j<=4;j++)
            tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
         }
       decalNoe += tabc.Taille();     
       // 2ieme maillage le 1er cube initial
       if (cas < 0)
        { InitialC(t1,n,tabc,tabF);
          for (int i=1;i<=tabc.Taille();i++,inNoe++)
            tabCgen(inNoe) = tabc(i);
          for (int i=1;i<=nbface0;i++,inFace++)
            { tabFgen(inFace).Change_taille(4);
              for (int j=1;j<=4;j++)
               tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
             } 
           decalNoe += tabc.Taille();                   
         }  
      // 3ieme maillage -> le second cube deforme
       Tableau<Noeud *>& t2 = lesmail->Element_LesMaille(2,1).Tab_noeud();
       ZoomElem(t2,n,tabc,tabF);
       for (int i=1;i<=tabc.Taille();i++,inNoe++)
         tabCgen(inNoe) = tabc(i);
       for (int i=1;i<=tabF.Taille();i++,inFace++)
        { tabFgen(inFace).Change_taille(4);
          for (int j=1;j<=4;j++)
            tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
         }
       decalNoe += tabc.Taille();     
       // 4ieme maillage le 2er cube initial
       if (cas < 0)
        { InitialC(t2,n,tabc,tabF);
          for (int i=1;i<=tabc.Taille();i++,inNoe++)
            tabCgen(inNoe) = tabc(i);
          for (int i=1;i<=nbface0;i++,inFace++)
            { tabFgen(inFace).Change_taille(4);
              for (int j=1;j<=4;j++)
               tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
             } 
           decalNoe += tabc.Taille();                   
         }  
      } 
   else if (Dabs(cas) == 5)
     { nbface = 12*n*n + 2*nbface0;
       nbnoe = 2*(8 + (n-1)*12 + (n-1)*(n-1)*6) + 2*nbnoe0;
       tabCgen.Change_taille(nbnoe);
       tabFgen.Change_taille(nbface);
      // 1er maillage -> le premier cube deforme
       Tableau<Noeud *>& t1 = lesmail->Element_LesMaille(1,1).Tab_noeud();
       ZoomElem(t1,n,tabc,tabF);
       for (int i=1;i<=tabc.Taille();i++,inNoe++)
         tabCgen(inNoe) = tabc(i);
       for (int i=1;i<=tabF.Taille();i++,inFace++)
        { tabFgen(inFace).Change_taille(4);
          for (int j=1;j<=4;j++)
            tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
         }
       decalNoe += tabc.Taille();     
       // 2ieme maillage le 1er cube initial
       if (cas < 0)
        { InitialC(t1,n,tabc,tabF);
          for (int i=1;i<=tabc.Taille();i++,inNoe++)
            tabCgen(inNoe) = tabc(i);
          for (int i=1;i<=nbface0;i++,inFace++)
            { tabFgen(inFace).Change_taille(4);
              for (int j=1;j<=4;j++)
               tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
             } 
           decalNoe += tabc.Taille();                   
         }  
      // 3ieme maillage -> le second cube deforme
       Tableau<Noeud *>& t2 = lesmail->Element_LesMaille(1,2).Tab_noeud();
       ZoomElem(t2,n,tabc,tabF);
       for (int i=1;i<=tabc.Taille();i++,inNoe++)
         tabCgen(inNoe) = tabc(i);
       for (int i=1;i<=tabF.Taille();i++,inFace++)
        { tabFgen(inFace).Change_taille(4);
          for (int j=1;j<=4;j++)
            tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
         }
       decalNoe += tabc.Taille();     
       // 4ieme maillage le 2er cube initial
       if (cas < 0)
        { InitialC(t2,n,tabc,tabF);
          for (int i=1;i<=tabc.Taille();i++,inNoe++)
            tabCgen(inNoe) = tabc(i);
          for (int i=1;i<=nbface0;i++,inFace++)
            { tabFgen(inFace).Change_taille(4);
              for (int j=1;j<=4;j++)
               tabFgen(inFace)(j) = tabF(i)(j)+decalNoe;
             } 
           decalNoe += tabc.Taille();                   
         }  
      } 
   // on ecrit l'entete 
   sort << "  dataset type = fe Ngp = " << nbnoe << ", nE =  " << nbface 
        << ", ns = 4" << '\n';
   // ecriture des noeuds
   for (int in=1;in<=nbnoe;in++)
     sort << tabCgen(in)(1) << "  " << tabCgen(in)(2) << "  " << tabCgen(in)(3) << '\n';
   // ecriture des connections des elements
   for (int iff=1;iff<=nbface;iff++)
     sort << tabFgen(iff)(1) << "  "<< tabFgen(iff)(2) << "  "
          << tabFgen(iff)(3) << "  "<< tabFgen(iff)(4) << '\n';
   // vide le buffer
   sort << endl;        
   
}; 

        //++++++++++++++++++++++++++++
        
         
// pour un cube, creation de noeuds intermediaires et de faces pour la visualisation
void Resultats::ZoomElem
   (Tableau <Noeud*>& tabN, int n, Tableau <Coordonnee>& tabc,
        Tableau < Tableau <int> >& tabF)
{  //dimensionnement des tableaux de sortie
   int nbface = 6*n*n;
   int nbnoe = 8 + (n-1)*12 + (n-1)*(n-1)*6;
   tabc.Change_taille(nbnoe);
   tabF.Change_taille(nbface);
   for (int i=1;i<=nbface;i++)
     tabF(i).Change_taille(4);
   // indice de noeud utilise pour reperer les nouveaus noeud cree
   int inoe =1; 
   // def des sommets principaux
   for (int i=1;i<=8;i++,inoe++) tabc(inoe) = tabN(i)->Coord2();
   // constitution des grandes faces
   Tableau < Tableau <int> >  tab4N(6);
   for (int i=1;i<=6;i++)
     tab4N(i).Change_taille(4);
   tab4N(1)(1) = 4;tab4N(1)(2) = 1;tab4N(1)(3) = 5;tab4N(1)(4) = 8;  
   tab4N(2)(1) = 3;tab4N(2)(2) = 7;tab4N(2)(3) = 6;tab4N(2)(4) = 2;  
   tab4N(3)(1) = 8;tab4N(3)(2) = 5;tab4N(3)(3) = 6;tab4N(3)(4) = 7;  
   tab4N(4)(1) = 1;tab4N(4)(2) = 2;tab4N(4)(3) = 6;tab4N(4)(4) = 5;  
   tab4N(5)(1) = 4;tab4N(5)(2) = 3;tab4N(5)(3) = 2;tab4N(5)(4) = 1;  
   tab4N(6)(1) = 4;tab4N(6)(2) = 8;tab4N(6)(3) = 7;tab4N(6)(4) = 3; 
   // def des arretes et def des coordonnees des noeuds intermediaires sur les arretes 
   Tableau < Tableau <int> >  tabAr(12);
   for (int i=1;i<=12;i++)
     tabAr(i).Change_taille(n-1); // on ne met pas les noeuds extremes
   int iAr = 1; // numero d'arrete
   Tableau < Tableau <int> >  tabEx(2); // tableau intermediaires des extremites des arretes
   for (int i=1;i<=2;i++)
        tabEx(i).Change_taille(2);  
   for (int nf=1;nf<=6;nf++)
    // pour chaque grande face on defini deux aretes, les deux premieres
    // ce qui permet de definir toutes les aretes
    { tabEx(1)(1) = tab4N(nf)(1);tabEx(1)(2) = tab4N(nf)(2);
      tabEx(2)(1) = tab4N(nf)(2);tabEx(2)(2) = tab4N(nf)(3);
      for (int ia=1;ia<=2;ia++,iAr++)  // pour chaque arrete
        { Coordonnee dxxy = (tabc(tabEx(ia)(2)) - tabc(tabEx(ia)(1)))/n; // delta coord
          for (int j=1;j<=n-1;j++,inoe++)
            { tabc(inoe) = tabc(tabEx(ia)(1)) + dxxy * j;
              tabAr(iAr)(j) = inoe;
             } 
         }  
     }
   // on attache a chaque grande face 4 numero d'arretes ordonnees la verticale a gauche
   // puis a droite, ce qui servira a calculer les noeuds inter, puis l'horizontale du bas
   // et enfin horizontale du haut
   Tableau < Tableau <int> > tArF(6);
   for (int i=1;i<=6;i++)
     tArF(i).Change_taille(4);
   tArF(1)(1) = 1;tArF(1)(2) = 5;tArF(1)(3) = 2;tArF(1)(4) = 11;   
   tArF(2)(1) = 3;tArF(2)(2) = 8;tArF(2)(3) = 4;tArF(2)(4) = 10;   
   tArF(3)(1) = 5;tArF(3)(2) = 4;tArF(3)(3) = 6;tArF(3)(4) = 12;   
   tArF(4)(1) = 7;tArF(4)(2) = 6;tArF(4)(3) = 8;tArF(4)(4) = 2;   
   tArF(5)(1) = 9;tArF(5)(2) = 7;tArF(5)(3) = 10;tArF(5)(4) = 1;   
   tArF(6)(1) = 11;tArF(6)(2) = 3;tArF(6)(3) = 12;tArF(6)(4) = 9;   
   // calcul des noeuds et faces
   int ifac =1; // indice de face
   for (int nf=1;nf<=6;nf++)  // boucle sur les 6 faces
    // pour chaque grande face
    { // creation des lignes horizontales complete (avec les extremites)
      Tableau < Tableau <int> >  tintAr(n+1);
      for (int i=1;i<=n+1;i++)
         tintAr(i).Change_taille(n+1);
      // cas des extremitees, la premiere ligne et la derniere
      tintAr(1)(1) = tab4N(nf)(2) ;tintAr(1)(n+1) = tab4N(nf)(3) ;     // les sommets 
      tintAr(n+1)(1) = tab4N(nf)(1) ;tintAr(n+1)(n+1) = tab4N(nf)(4) ; //     " 
      for (int i=1;i<= n-1;i++)
       { tintAr(1)(i+1) = tabAr(tArF(nf)(3))(i); // arete du bas       
         tintAr(n+1)(i+1) = tabAr(tArF(nf)(4))(i); // arete du haut
         tintAr(i+1)(1) = tabAr(tArF(nf)(1))(n-i) ; // verticale gauche    
         tintAr(i+1)(n+1) = tabAr(tArF(nf)(2))(n-i) ; // verticale droite
        }
      // cas des lignes intermediaires       
      for (int iL=1;iL<=n-1;iL++)
       {// le delta longueur
        Coordonnee dxxy = (tabc(tintAr(iL+1)(n+1)) - tabc(tintAr(iL+1)(1)))/n;
        for (int j=1;j<=n-1;j++,inoe++)
            { tabc(inoe) = tabc(tintAr(iL+1)(1)) + dxxy * j; // le noeud sup
              tintAr(iL+1)(j+1) = inoe;
             }
        }
      // creation des petites faces 
      for (int iL=1;iL<=n;iL++)
        for (int iC=1;iC<=n;iC++,ifac++)
        { tabF(ifac)(1) = tintAr(iL)(iC); tabF(ifac)(2) = tintAr(iL+1)(iC);
          tabF(ifac)(3) = tintAr(iL+1)(iC+1); tabF(ifac)(4) = tintAr(iL)(iC+1);
         }      
              
     }
 };  
   
// dessin d'un cube initial
void Resultats::InitialC
   (Tableau <Noeud*>& tabN, int , Tableau <Coordonnee>& tabc,
        Tableau < Tableau <int> >& tabF)
{  //dimensionnement des tableaux de sortie
   int nbface = 12; // chaque face represente une arete
   int nbnoe = 8;  // les sommets
   tabc.Change_taille(nbnoe);
   tabF.Change_taille(nbface);
   for (int i=1;i<=nbface;i++)
     tabF(i).Change_taille(4);
   // indice de noeud utilise pour reperer les nouveaus noeud cree
   int inoe =1; 
   // def des sommets principaux
   for (int i=1;i<=8;i++,inoe++) tabc(inoe) = tabN(i)->Coord0();
   // constitution des  faces
   tabF(1)(1) = 1;tabF(1)(2) = 4;tabF(1)(3) = 1;tabF(1)(4) = 1;
   tabF(2)(1) = 1;tabF(2)(2) = 5;tabF(2)(3) = 1;tabF(2)(4) = 1;
   tabF(3)(1) = 3;tabF(3)(2) = 7;tabF(3)(3) = 3;tabF(3)(4) = 3;
   tabF(4)(1) = 7;tabF(4)(2) = 6;tabF(4)(3) = 7;tabF(4)(4) = 7;
   tabF(5)(1) = 5;tabF(5)(2) = 8;tabF(5)(3) = 5;tabF(5)(4) = 5;
   tabF(6)(1) = 5;tabF(6)(2) = 6;tabF(6)(3) = 5;tabF(6)(4) = 5;
   tabF(7)(1) = 1;tabF(7)(2) = 2;tabF(7)(3) = 1;tabF(7)(4) = 1;
   tabF(8)(1) = 2;tabF(8)(2) = 6;tabF(8)(3) = 2;tabF(8)(4) = 2;
   tabF(9)(1) = 3;tabF(9)(2) = 4;tabF(9)(3) = 3;tabF(9)(4) = 3;
   tabF(10)(1) = 2;tabF(10)(2) = 3;tabF(10)(3) = 2;tabF(10)(4) = 2;
   tabF(11)(1) = 4;tabF(11)(2) = 8;tabF(11)(3) = 4;tabF(11)(4) = 4;
   tabF(12)(1) = 8;tabF(12)(2) = 7;tabF(12)(3) = 8;tabF(12)(4) = 8;   
};                     
   
   
   
                 
