/*! \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) . // // 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 . // // For more information, please consult: . /************************************************************************ * * * 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 # include using namespace std; //introduces namespace std #include "herezh.h" //#include "Debug.h" //#include "DebugNew.h" // peut-etre à virer ensuite ? #include //# 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 //#ifdef ENLINUX_STREAM // #include "Profiler.h" //#endif //#define USE_PROFILE #ifdef UTILISATION_DE_LA_LIBRAIRIE_BOOST #include #include #endif #ifdef UTILISATION_MPI #include "mpi.h" #include #include #include #include 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 // --- 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); #ifdef EN_DEBUG_MPI // intro d'une boucle infinie pour mettre en place les process en debug if (world.rank() == 0) //arrêt uniquement pour le proc 0 {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 #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> toto; // Sortie(1); // }; //#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; }; };