Herezh_dev/General/herezh.cc
2023-05-03 17:23:49 +02:00

562 lines
24 KiB
C++

/*! \file herezh.cc
\brief programme principal herezh++.
*/
// 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: 15/01/97 *
* $ *
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
* $ *
* PROJET: Herezh++ *
* $ *
************************************************************************
* BUT: programme de calcul de structure par elements finis *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* ! ! ! ! *
* *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* MODIFICATIONS:
* *
* ! date ! auteur ! but ! *
* ------------------------------------------------------------ *
* *
* $ *
* *
************************************************************************/
//#include <altivec.h>
# include <iostream>
using namespace std; //introduces namespace std
#include "herezh.h"
//#include "Debug.h"
//#include "DebugNew.h" // peut-etre à virer ensuite ?
#include <math.h>
//# include "EnteteParaGlob.h"
#include "ConstantePrinc.h"
# include "ParaGlob.h"
// ------- specifiques tenseur -------------------------------
// 1- second ordre
# include "Tenseur3.h"
# include "Tenseur2.h"
# include "Tenseur1.h"
// 2- quatrieme ordre
# include "TenseurQ-3.h"
# include "TenseurQ-2.h"
# include "TenseurQ-1.h"
#include "Tenseur1_TroisSym.h"
#include "Tenseur2_TroisSym.h"
#include "Tenseur3_TroisSym.h"
// def des variables statiques permettant entre autre d'effacer les tenseurs intermediaires
# include "EnteteTenseur.h"
// fonction permettant la definition de nouveaux tenseurs
#include "NevezTenseur.h"
// def des constantes tenseur
# include "TypeConsTensPrinc.h"
// lorsque l'on veut faire reference a des constantes tenseurs dans un autre
// fichier que le prog principal il faut inclure :
// # include "TypeConsTens.h"
// uniquement, ceci a la place de :
// "TypeConsTensPrinc.h"
// "DefValConsTens.h"
// est a placer dans le fichier qui defini les valeurs des constantes
// --------- fin specifique tenseur ---------------
//-------- listes globales de petits tableaux ------------
//#include "PtTabRel_Princ.h"
#include "Projet.h"
#include "Biellette.h"
#include "BielletteQ.h"
#include "Biel_axi.h"
#include "Biel_axiQ.h"
#include "TriaMembL1.h"
#include "TriaMembQ3.h"
#include "TriaMembQ3_cm1pti.h"
#include "TriaQ3_cmpti1003.h"
#include "TriaCub.h"
#include "TriaCub_cm4pti.h"
#include "Quad.h"
#include "Quad_cm1pti.h"
#include "QuadQ.h"
#include "QuadQCom.h"
#include "QuadQCom_cm4pti.h"
#include "Hexa.h"
#include "Hexa_cm1pti.h"
#include "Hexa_cm27pti.h"
#include "Hexa_cm64pti.h"
#include "HexaQ.h"
#include "HexaQ_cm1pti.h"
#include "HexaQ_cm27pti.h"
#include "HexaQ_cm64pti.h"
#include "HexaQComp.h"
#include "HexaQComp_cm1pti.h"
#include "HexaQComp_cm27pti.h"
#include "HexaQComp_cm64pti.h"
#include "Tetra.h"
#include "TetraQ.h"
#include "TetraQ_cm1pti.h"
#include "TetraQ_cm15pti.h"
#include "PentaL.h"
#include "PentaL_cm1pti.h"
#include "PentaL_cm6pti.h"
#include "PentaQ.h"
#include "PentaQ_cm3pti.h"
#include "PentaQ_cm9pti.h"
#include "PentaQ_cm12pti.h"
#include "PentaQ_cm18pti.h"
#include "PentaQComp.h"
#include "PentaQComp_cm9pti.h"
#include "PentaQComp_cm12pti.h"
#include "PentaQComp_cm18pti.h"
#include "TriaSfe1.h"
#include "TriaSfe1_cm5pti.h"
#include "TriaSfe2.h"
#include "TriaSfe3.h"
#include "TriaSfe3_3D.h"
#include "TriaSfe3_cm3pti.h"
#include "TriaSfe3_cm4pti.h"
#include "TriaSfe3_cm5pti.h"
#include "TriaSfe3_cm6pti.h"
#include "TriaSfe3_cm7pti.h"
#include "TriaSfe3_cm12pti.h"
#include "TriaSfe3_cm13pti.h"
#include "TriaSfe3C.h"
#include "TriaQSfe3.h"
#include "TriaQSfe1.h"
#include "PoutSimple1.h"
#include "QuadCCom.h"
#include "QuadCCom_cm9pti.h"
#include "TriaAxiL1.h"
#include "TriaAxiQ3.h"
#include "TriaAxiQ3_cm1pti.h"
#include "TriaAxiQ3_cmpti1003.h"
#include "QuadAxiL1.h"
#include "QuadAxiL1_cm1pti.h"
#include "QuadAxiQ.h"
#include "QuadAxiQComp.h"
#include "QuadAxiQComp_cm4pti.h"
#include "QuadAxiCCom.h"
#include "QuadAxiCCom_cm9pti.h"
#include "ElemPoint.h"
#include "ElemPoint_CP.h"
#include "BielletteThermi.h"
#include <iostream>
//#ifdef ENLINUX_STREAM
// #include "Profiler.h"
//#endif
//#define USE_PROFILE
#ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST
#include <boost/chrono/include.hpp>
#include <boost/system/error_code.hpp>
#endif
#ifdef UTILISATION_MPI
#include "mpi.h"
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/serialization/string.hpp>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
#endif
#include "Temps_CPU_HZpp.h"
#include "Temps_CPU_HZpp_3.h"
#ifdef SYSTEM_MAC_OS_X
int main (int argc, const char * argv[]) {
#else
#ifdef ENLINUX_STREAM //ENLINUX
int main (int argc, const char * argv[]) {
#else
#ifdef SYSTEM_MAC_OS_X_unix
int main (int argc, const char * argv[]) {
#else
int main ()
{ int argc=0; const char ** argv = NULL ;
#endif
#endif
#endif
#ifdef UTILISATION_MPI
#ifdef EN_DEBUG_MPI
// intro d'une boucle infinie pour mettre en place les process en debug
{volatile int i = 0;
char hostname[256];
gethostname(hostname, sizeof(hostname));
printf("PID %d on %s ready for attach\n", getpid(), hostname);
fflush(stdout);
while (0 == i)
sleep(5);
}
#endif
// --- mise en route de la parallèlisation
mpi::environment env;
// def global d'un communicator
mpi::communicator world;
// on renseigne paraglob
ParaGlob::Init_boost_environnement(&env);
ParaGlob::Init_boost_communicator (& world);
#endif
// gestion du temps cpu global
Temps_CPU_HZpp_3 temps_CPU_Herezh_total;
temps_CPU_Herezh_total.Mise_en_route_du_comptage(); // comptage cpu
UtilLecture* pt_UtilLecture = NULL; // un pointeur qui doit-être renseigné par le projet
// écriture de l'entête du programme
#ifdef UTILISATION_MPI
if (world.rank() == 0)
#endif
Presentation();
// definition d'un projet
string retour ;
try
{
#ifdef UTILISATION_MPI
// on dit à tous les process d'attendre sauf le master
world.barrier(); // synchronisation ici de tous les process
std::string message_mpi;
if (world.rank() == 0)
{ cout << " ==> execution parallele (MPI) "<< world.size() << " proc ";
message_mpi = "process_en_attente";
// broadcast(world, message_mpi, 0); // 0 cas c'est le rang 0 qui cause
};
// envoi pour le maitre et réception pour les autres via broadcast
broadcast(world, message_mpi, 0); // 0 cas c'est le rang 0 qui cause
world.barrier(); // synchronisation ici de tous les process
if (world.rank() == 0)
{ cout << "\n process 0: creation du projet ";
}
else
{ cout << "\n " << message_mpi << " " << world.rank() ;
// attente jusqu'à ce que l'on récupère de 0 le tag 1
// ce qui est effectué plus bas, juste après: projet.Lecture();
world.probe(0, 1);
};
#endif
// par la définition du projet, est définit également l'algo
// on définit le projet en dehors du try qui suit, pour le projet demeure valide même s'il y a
// une exception, ce qui permet quand même d'utiliser des fonction du projet,
// par exemple l'acces aux fichier qui sont définit dans UtilLecture
Projet projet(retour,argc,argv);
if (retour != "fin")
try
{
// les differents elements
// (sont ici définit pour qu'ils soient pris en compte à l'édition de lien !!)
Biellette b1; // biellette
BielletteQ b11; // biellette quadratique
Biel_axi baxi; // biellette axisymétrique linéaire
Biel_axiQ baxiQ; // biellette axisymétrique quadratique
TriaMembL1 t1; // triangle membranne, lineaire 1 pt d'integ
TriaMembQ3 t2; // triangle membranne, quadratique 3 pt d'integ
TriaMembQ3_cm1pti triaMembQ3_cm1pti; // triangle membranne, quadratique 1 pt d'integ
TriaQ3_cmpti1003 t_cmpti1003; // triangle membranne, quadratique avec 3 pt d'integ interne
TriaCub triacub; // triangle cubique
TriaCub_cm4pti triacub_cm4pti; // triangle cubique avec 4 pti
Quad q1; // quadrangle membranne, lineaire 4 pt d'integ
Quad_cm1pti quad_cm1pti; // quadrangle membranne, lineaire 1 pt d'integ
QuadQ q2; // quadrangle membranne, quadratique incomplet 4 pt d'integ
QuadQCom q3; // quadrangle membranne, quadratique complet 9 pt d'integ
QuadQCom_cm4pti quadQCom_cm4pti; // quadrangle membranne, quadratique complet 4 pt d'integ
QuadCCom q4; // quadrangle membranne, cubique complet 16 pt d'integ
QuadCCom_cm9pti q4_9pti; // quadrangle membranne, cubique complet 9 pt d'integ
Hexa h1; // un hexaedre trilineaire, 8 pt d'integ
Hexa_cm1pti h1_cm1pti; // un hexaedre trilineaire, 1 pt d'integ
Hexa_cm27pti h1_cm27pti; // un hexaedre trilineaire, 27 pt d'integ
Hexa_cm64pti h1_cm64pti; // un hexaedre trilineaire, 64 pt d'integ
HexaQ h2; // un hexaedre trilquadratique incomplet, 8 pt d'integ
HexaQ_cm1pti h2_cm1pti; // un hexaedre trilquadratique incomplet, 1 pt d'integ
HexaQ_cm27pti h2_cm27pti; // un hexaedre trilquadratique incomplet, 27 pt d'integ
HexaQ_cm64pti h2_cm64pti; // un hexaedre trilquadratique incomplet, 64 pt d'integ
HexaQComp h2comp; // un hexaedre trilquadratique complet, 8 pt d'integ
HexaQComp_cm1pti h2comp_1pti; // un hexaedre trilquadratique complet, 1 pt d'integ
HexaQComp_cm27pti h2comp_27pti; // un hexaedre trilquadratique complet, 27 pt d'integ
HexaQComp_cm64pti h2comp_64pti; // un hexaedre trilquadratique complet, 64 pt d'integ
Tetra te1; // un tetraedre trilineaire, 1 pt d'integ
TetraQ te2; // un tetraedre triquadratique, 4 pt d'integ
TetraQ_15pti te3; // un tetraedre triquadratique, 15 pt d'integ
TetraQ_cm1pti te2_cm1pti; // un tetraedre triquadratique, 1 pt d'integ
PentaL pe1; // un pentaedre trilinéaire, 2 pts d'intégration
PentaL_cm1pti pe1_cm1pti; // un pentaedre trilinéaire, 1 pts d'intégration
PentaL_cm6pti pe1_cm6pti; // un pentaedre trilinéaire, 6 pts d'intégration
PentaQ pe2; // un pentaedre triquadratique incomplet, 6 pts d'intégration
PentaQ_cm3pti pe2_cm3pti; // un pentaedre triquadratique incomplet, 3 pts d'intégration
PentaQ_cm9pti pe2_cm9pti; // un pentaedre triquadratique incomplet, 9 pts d'intégration
PentaQ_cm12pti pe2_cm12pti; // un pentaedre triquadratique incomplet, 12 pts d'intégration
PentaQ_cm18pti pe2_cm18pti; // un pentaedre triquadratique incomplet, 18 pts d'intégration
PentaQComp pe2Comp; // un pentaedre triquadratique complet, 6 pts d'intégration
PentaQComp_cm9pti pe2Comp_cm9pti; // un pentaedre triquadratique complet, 9 pts d'intégration
PentaQComp_cm12pti pe2Comp_cm12pti; // un pentaedre triquadratique complet, 12 pts d'intégration
PentaQComp_cm18pti pe2Comp_cm18pti; // un pentaedre triquadratique complet, 18 pts d'intégration
TriaSfe1 t3; // un triangle SFE1
TriaSfe1_cm5pti tfe1_cm5pti; // idem avec 5 pti
TriaSfe2 t3_2; // un triangle SFE2
TriaSfe3 t3_3; // un triangle SFE3
TriaSfe3_3D t3_3_3D; // un triangle SFE3_3D
TriaSfe3_cm4pti t3_3_cm4pti; // un triangle SFE3 avec 4pt d'integ
TriaSfe3_cm6pti t3_3_cm6pti; // un triangle SFE3 avec 6pt d'integ
TriaSfe3_cm12pti t3_3_cm12pti; // un triangle SFE3 avec 12pt d'integ
TriaSfe3_cm3pti t3_3_cm3pti; // un triangle SFE3 avec 3pt d'integ type Gauss Lobatto
TriaSfe3_cm5pti t3_3_cm5pti; // un triangle SFE3 avec 5pt d'integ type Gauss Lobatto
TriaSfe3_cm7pti t3_3_cm7pti; // un triangle SFE3 avec 7pt d'integ type Gauss Lobatto
TriaSfe3_cm13pti t3_3_cm13pti; // un triangle SFE3 avec 13pt d'integ type Gauss Lobatto
TriaSfe3C t3_3C; // un triangle SFE3C
TriaQSfe3 tqSfe3; // un triangle QSFE3
TriaQSfe1 tqSfe1; // un triangle QSFE1
PoutSimple1 p1; // poutre simple, interpolation quadratique en 2 D
TriaAxiL1 triAxil1; // triangle axisymétrique linéaire
TriaAxiQ3 triAxiq3; // triangle axisymétrique quadratique 3 pti
TriaAxiQ3_cm1pti triaAxiQ3_cm1pti; // triangle axisymétrique quadratique 1 pti
TriaAxiQ3_cmpti1003 triaAxiQ3_cmpti1003; // triangle axi quadra 3 pti hors arêtes
QuadAxiL1 quadAxil1; // quadrangle axisymétrique linéaire
QuadAxiL1_cm1pti quadAxiL1_cm1pti; // idem avec 1 pti
QuadAxiQ quadAxiq; // quadrangle axisymétrique quadratique incomplet
QuadAxiQComp quadAxiqcomp; // quad quadratique axisymétrique complet
QuadAxiQComp_cm4pti quadAxiQComp_cm4pti; // idem mais avec 4 pti
QuadAxiCCom quadAxicCom; // quad cubique axi complet
QuadAxiCCom_cm9pti quadAxiCCom_cm9pti; // idem avec 9 pti
ElemPoint elemPoint; // élément pour umat abaqus
ElemPoint_CP elemPoint_CP; // idem mais pour les contraintes planes
//.... cas de la thermique
BielletteThermi bielletteThermi; // une biellette thermique
// le projet étant définit, on peut définir le fichier de stockage des temps cpu
pt_UtilLecture = projet.Def_sortie_temps_cpu();
//il y a deux types d'entrée de donnée soit via un fichier info
// --------------------------------------------------------
// choix en fonction de la construction du projet
// --------------------------------------------------------
if (retour == "def_fichier_commande")
// -------------------------------------------------
// cas de la définition d'un fichier de commandes
// -------------------------------------------------
{projet.Def_fichier_commande(retour);}
else if (retour == "def_schema_XML")
// ----------------------------------------------------------------------
// cas de la définition d'un fichier de de shema XML d'entrée de données
// ----------------------------------------------------------------------
{projet.Def_fichier_SchemaXML(retour);}
else if (retour != "fin")
// --------------------------------------------------------
// cas d'un calcul
// definition des quatres grandes etapes du calcul
// --------------------------------------------------------
{
projet.Lecture(); // 1- lecture initiale
// #ifdef USE_PROFILE
// // préparation du profiler
// if (!ProfilerInit(collectDetailed, bestTimeBase,8000, 100))
// {
// #endif
#ifdef UTILISATION_MPI
//int rank = world.rank();
//cout << "\n *** je suis le process " << rank << endl;
if (world.rank() == 0)
// on va demander successivement à tous les process de lire le .info
// il s'agit d'un procédé séquentiel,
// NB: je pense que c'est plus rapide et plus sûr de passer par le .info
// pour construire et remplir dans chaque process la structure de stockage, que de le faire
// en passant les données via mpi entre le master et les sous_process
{int nb_process = world.size();
// NB: le process 0 c'est le main
for (int i=1;i<nb_process;i++) // < absolu, donc le max c'est nb_process-1
{ // on envoie un signal de démarrage au process i
world.send(i, 1, std::string("lecture_info_sous_process"));
// on demande au projet de transmettre les info ad hoc
projet.Transmission_process_Lecture(i);
// et on attend du process i un signal de fin d'exécution
std::string msg;
world.recv(i, 2, msg);
// gestion d'erreur éventuelle
if (msg == "erreur_en_lecture")
// arrêt du traitement
Sortie(1);
};
}
else
{// on envoie à 0 le message de fin de lecture
world.send(0, 2, std::string("OK"));
};
// arrivé ici tous les process ont la structuration interne les données de bases ad hoc
#endif
do
{ projet.Calcul(); // 2- calcul
// #ifdef USE_PROFILE
// int erro;
// // sortie des infos pour le profiler
// erro= ProfilerDump("\pHerezh.prof");
// ProfilerTerm();
// }
// #endif
projet.SortieDesResultats(); // 3- sortie automatique résultats
projet.Visualisation_interactive(); // 4- sortie interactive résultats
// ou automatique via un fichier de commande
} while (projet.Lecture_secondaire());
};
// fermeture des fichiers de visualisation liés au projet
projet.FermetureFichiersVisualisation();
// on sauvegarde les différents temps cpu, et on récupère l'adresse d'UtilLecture
pt_UtilLecture = projet.Sortie_temps_cpu();
// gestion du temps cpu global
temps_CPU_Herezh_total.Arret_du_comptage(); // fin comptage cpu
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(cout);
if (pt_UtilLecture != NULL) // sortie sur fichier si le fichier a été créé
{ // récupération du fichier des temps cpu
ofstream & sort_cpu = pt_UtilLecture->Sort_temps_cpu();
sort_cpu << "\n ------- temps globaux jour/heure:minute:seconde:centieme ------\n";
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(pt_UtilLecture->Sort_temps_cpu());
};
} // fin de la surveillance
catch (ErrSortie erreur)
{
#ifndef UTILISATION_MPI
cout << "\n ======== erreur (Sortie) detectee ====== " << endl;
#else
cout << "\n *** process " << world.rank() << " ======== erreur (Sortie) detectee ====== " << endl;
#endif
// on sauvegarde les différents temps cpu, et on récupère l'adresse d'UtilLecture
projet.Arret_du_comptage_CPU(); // on termine les comptages non fermés
pt_UtilLecture = projet.Sortie_temps_cpu();
// gestion du temps cpu global
temps_CPU_Herezh_total.Arret_du_comptage(); // fin comptage cpu
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(cout);
if (pt_UtilLecture != NULL) // sortie sur fichier si le fichier a été créé
{ // récupération du fichier des temps cpu
ofstream & sort_cpu = pt_UtilLecture->Sort_temps_cpu();
sort_cpu << "\n ------- temps globaux jour/heure:minute:seconde:centieme ------\n";
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(pt_UtilLecture->Sort_temps_cpu());
};
}
catch (ErrSortieFinale erreur)
{
#ifndef UTILISATION_MPI
cout << "\n ======== erreur (Sortie) detectee ====== " << endl;
#else
cout << "\n *** process " << world.rank() << " ======== erreur (Sortie) detectee ====== " << endl;
#endif
// on sauvegarde les différents temps cpu, et on récupère l'adresse d'UtilLecture
projet.Arret_du_comptage_CPU(); // on termine les comptages non fermés
pt_UtilLecture = projet.Sortie_temps_cpu();
// gestion du temps cpu global
temps_CPU_Herezh_total.Arret_du_comptage(); // fin comptage cpu
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(cout);
if (pt_UtilLecture != NULL) // sortie sur fichier si le fichier a été créé
{ // récupération du fichier des temps cpu
ofstream & sort_cpu = pt_UtilLecture->Sort_temps_cpu();
sort_cpu << "\n ------- temps globaux jour/heure:minute:seconde:centieme ------\n";
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(pt_UtilLecture->Sort_temps_cpu());
};
}
catch ( ... )
{
#ifndef UTILISATION_MPI
cout << "\n ======== erreur detectee ====== " << endl;
#else
cout << "\n *** process " << world.rank() << " ======== erreur detectee ====== " << endl;
#endif
projet.Arret_du_comptage_CPU(); // on termine les comptages non fermés
// on sauvegarde les différents temps cpu, et on récupère l'adresse d'UtilLecture
pt_UtilLecture = projet.Sortie_temps_cpu();
// gestion du temps cpu global
temps_CPU_Herezh_total.Arret_du_comptage(); // fin comptage cpu
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(cout);
if (pt_UtilLecture != NULL) // sortie sur fichier si le fichier a été créé
{ // récupération du fichier des temps cpu
ofstream & sort_cpu = pt_UtilLecture->Sort_temps_cpu();
sort_cpu << "\n ------- temps globaux jour/heure:minute:seconde:centieme ------\n";
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(pt_UtilLecture->Sort_temps_cpu());
};
};
}
catch (ErrSortieFinale erreur)
{
#ifndef UTILISATION_MPI
cout << "\n *** ======== erreur fatale detectee ======*** " << endl;
#else
cout << "\n *** process " << world.rank() << " ======== erreur fatale detectee ======*** " << endl;
#endif
// gestion du temps cpu global
temps_CPU_Herezh_total.Arret_du_comptage(); // fin comptage cpu
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(cout);
if (pt_UtilLecture != NULL) // sortie sur fichier si le fichier a été créé
{ // récupération du fichier des temps cpu
ofstream & sort_cpu = pt_UtilLecture->Sort_temps_cpu();
sort_cpu << "\n ------- temps globaux jour/heure:minute:seconde:centieme ------\n";
temps_CPU_Herezh_total.Affiche_hh_mn_s_ml(pt_UtilLecture->Sort_temps_cpu());
};
}
catch ( ... )
{ cout << "\n *** ======== erreur fatale detectee ======*** " << endl;
};
// écriture de la fin du programme
#ifdef UTILISATION_MPI
if (world.rank() == 0) // uniquement le process 0
#endif
{cout << "\n =============================================================\n";
cout << " | fin HEREZH++ |\n";
cout << " =============================================================";
cout << endl;
};
};