2021-09-26 14:31:23 +02:00
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-26 14:31:23 +02:00
|
|
|
// 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 "AlgoriCombine.h"
|
|
|
|
#include "TypeQuelconqueParticulier.h"
|
|
|
|
#include "Fonction_expression_litterale_nD.h"
|
|
|
|
|
|
|
|
// CONSTRUCTEURS :
|
|
|
|
AlgoriCombine::AlgoriCombine() : // par defaut
|
|
|
|
Algori()
|
|
|
|
{// a priori ce constructeur n'est pas utilisé
|
|
|
|
cout << "\n $$$$$$$$$ a priori ce constructeur n'est pas utilisable $$$$$$$ "
|
|
|
|
<< "\n revoir: AlgoriCombine::AlgoriCombine() " << endl;
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
|
|
|
|
// constructeur en fonction du type de calcul et du sous type
|
|
|
|
// il y a ici lecture des parametres attaches au type
|
|
|
|
AlgoriCombine::AlgoriCombine (const bool avec_typeDeCal
|
|
|
|
,const list <EnumSousTypeCalcul>& soustype
|
|
|
|
,const list <bool>& avec_soustypeDeCal
|
|
|
|
,UtilLecture& entreePrinc) :
|
|
|
|
Algori(COMBINER,avec_typeDeCal,soustype,avec_soustypeDeCal,entreePrinc)
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// -- variables privées --
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
,tab_algo()
|
|
|
|
,nom_choix_algo(""),choix_algo(NULL),nom_gestion_sauvegarde(""),gestion_sauvegarde(NULL)
|
|
|
|
,nb_dernier_algo_qui_a_fait_une_sauvegarde(0)
|
|
|
|
,gestion_sortie_a_convergence(NULL),nom_gestion_sortie_a_convergence("")
|
|
|
|
,tb_combiner(NULL),cst_0(NULL),cst_1(NULL)
|
|
|
|
// des infos définit en local pour les péréniser
|
|
|
|
,list_sousTypeCalcul(),list_avec_sousCalcul()
|
|
|
|
|
|
|
|
{ // puis lecture des paramètres attachés au type de calcul
|
|
|
|
switch (entreePrinc.Lec_ent_info())
|
|
|
|
{ case 0 :
|
|
|
|
{// il s'agit tout d'abord de lire les différents algos
|
|
|
|
Lecture_algo_interne(avec_typeDeCal,soustype,avec_soustypeDeCal,entreePrinc);
|
|
|
|
// appel de la méthode de lecture de paramètre
|
|
|
|
lecture_Parametres(entreePrinc); break;}
|
|
|
|
case -11 : // cas de la création d'un fichier de commande
|
|
|
|
{ Info_commande_parametres(entreePrinc); break;}
|
|
|
|
case -12 : // cas de la création d'un schéma XML, on ne fait rien à ce niveau
|
|
|
|
{ break;}
|
|
|
|
default:
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
Creation_fct_cst(); // création de cst_0 et cst_1
|
|
|
|
};
|
|
|
|
|
|
|
|
// constructeur de copie
|
|
|
|
AlgoriCombine::AlgoriCombine (const AlgoriCombine& algo):
|
|
|
|
Algori(algo)
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// -- variables privées --
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
,tab_algo(algo.tab_algo)
|
|
|
|
,nom_choix_algo(algo.nom_choix_algo),choix_algo(NULL)
|
|
|
|
,nom_gestion_sauvegarde(algo.nom_gestion_sauvegarde),gestion_sauvegarde(NULL)
|
|
|
|
,nb_dernier_algo_qui_a_fait_une_sauvegarde(0)
|
|
|
|
,gestion_sortie_a_convergence(NULL)
|
|
|
|
,nom_gestion_sortie_a_convergence(algo.nom_gestion_sortie_a_convergence)
|
|
|
|
,tb_combiner(NULL),cst_0(NULL),cst_1(NULL)
|
|
|
|
// des infos définit en local pour les péréniser
|
|
|
|
,list_sousTypeCalcul(algo.list_sousTypeCalcul),list_avec_sousCalcul(algo.list_avec_sousCalcul)
|
|
|
|
{ // les algorithmes
|
|
|
|
list <list<EnumSousTypeCalcul> >::iterator ili=list_sousTypeCalcul.begin();
|
|
|
|
list <list<bool> >::iterator ala=list_avec_sousCalcul.begin();
|
|
|
|
// les listes sont rangées : la première -> le dernier algo, etc.
|
|
|
|
int nb_algo = algo.tab_algo.Taille();
|
|
|
|
if (nb_algo)
|
|
|
|
{for (int i=nb_algo;i>0;i--,ili++,ala++)
|
|
|
|
{tab_algo(i) = New_idem(algo.tab_algo(i));
|
|
|
|
// mise à jour des pointeurs relatifs aux types de calculs et sous types internes
|
|
|
|
tab_algo(i) -> Change_affectation_pointeur_sous_type((*ili),(*ala));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
Creation_fct_cst(); // création de cst_0 et cst_1
|
|
|
|
// on renseigne la variable: ptalgocombi de la classe Algori pour tous les sous-algo
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
tab_algo(i)->Change_ptalgocombi (this);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// destructeur
|
|
|
|
AlgoriCombine::~AlgoriCombine ()
|
|
|
|
{ // les algorithmes
|
|
|
|
if (tab_algo.Taille())
|
|
|
|
{for (int i=1;i<= tab_algo.Taille();i++)
|
|
|
|
delete tab_algo(i);
|
|
|
|
};
|
|
|
|
tab_algo.Libere();
|
|
|
|
// les fonctions constantes
|
|
|
|
delete cst_0;
|
|
|
|
delete cst_1;
|
|
|
|
// les autres fonctions sont globales, donc à ne pas supprimer !!
|
|
|
|
};
|
|
|
|
|
|
|
|
//lecture des parametres de controle
|
|
|
|
// peut être modifié dans le cas d'un algo particulier
|
|
|
|
void AlgoriCombine::Lecture(UtilLecture & entreePrinc,ParaGlob & paraglob,LesMaillages& lesMail)
|
|
|
|
{ // --- on commence par lire les infos concernant les paramètres généraux via la méthode par défaut
|
|
|
|
Algori::Lecture(entreePrinc,paraglob,lesMail);
|
|
|
|
// --- ces paramètres permettent d'initialiser les paramètres d'algo internes
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
tab_algo(i)->Init_ParaAlgoControle(pa);
|
|
|
|
// lecture des paramètres d'algo spécifiques à chaque algo
|
|
|
|
MotCle motCle; // ref aux mots cle
|
|
|
|
// on se positionne sur un mot cle
|
|
|
|
while ( !motCle.SimotCle(entreePrinc.tablcar))
|
|
|
|
entreePrinc.NouvelleDonnee();
|
|
|
|
// PARA_SPECIFIQUE_SOUS_ALGO
|
|
|
|
string nom; int num_algo=0;
|
|
|
|
int val_defaut = 0;
|
|
|
|
const string nom_class_methode("AlgoriCombine::Lecture");
|
|
|
|
int min = 1; int max=nb_algo; string mot_cle("==PARA_SPECIFIQUE_SOUS_ALGO==");
|
|
|
|
if (strstr(entreePrinc.tablcar,"==PARA_SPECIFIQUE_SOUS_ALGO==")!=NULL)
|
|
|
|
{// a priori on a des paramètres spécifiques
|
|
|
|
while (strstr(entreePrinc.tablcar,"==PARA_SPECIFIQUE_SOUS_ALGO==")!=NULL)
|
|
|
|
{// on récupère le num d'algo
|
|
|
|
bool lec_eff = entreePrinc.Lecture_un_parametre_int(val_defaut,nom_class_methode
|
|
|
|
,min,max,mot_cle,num_algo);
|
|
|
|
if (lec_eff && (num_algo != 0))
|
|
|
|
{// on lit les paramètres spécifiques de l'algo
|
|
|
|
entreePrinc.NouvelleDonnee();
|
|
|
|
tab_algo(num_algo)->pa.Lecture_paraAlgoControle(entreePrinc);
|
|
|
|
}
|
|
|
|
else // sinon pb
|
|
|
|
{ cout << "\n *** erreur en lecture de parametres specifiques d'algo interne "
|
|
|
|
<< "\n AlgoriCombine::Lecture(.. ";
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
entreePrinc.NouvelleDonnee();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// on met à jour certains conteneurs internes des sous-algo
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
tab_algo(i)->Preparation_conteneurs_interne(lesMail);
|
|
|
|
};
|
|
|
|
|
|
|
|
// execution de l'algorithme dans le cas non dynamique, implicit, sans contact
|
|
|
|
void AlgoriCombine::Execution(ParaGlob * paraGlob,LesMaillages * lesMail
|
|
|
|
,LesReferences* lesRef,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
|
|
|
|
,VariablesExporter* varExpor,LesLoisDeComp* lesLoisDeComp, DiversStockage* divStock
|
|
|
|
,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts,Resultats* resultats)
|
|
|
|
{
|
|
|
|
Tableau < Fonction_nD* > * tb_combiner = NULL;
|
|
|
|
// on définit le type de calcul a effectuer :
|
|
|
|
if ( soustypeDeCalcul->size()==0 )
|
|
|
|
// cas où il n'y a pas de sous type, on fait le calcul d'équilibre classique
|
|
|
|
// signifie que le type principal est forcément valide
|
|
|
|
{ // initialisation du calcul : deux cas, soit avec une lecture initiale du .info, soit une lecture secondaire
|
|
|
|
if (paraGlob->EtatDeLaLecturePointInfo() == 0)
|
|
|
|
{InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );}
|
|
|
|
else {MiseAJourAlgo(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );
|
|
|
|
};
|
|
|
|
// on ne continue que si on n'a pas dépasser le nombre d'incréments maxi ou le temps maxi
|
|
|
|
// bref que l'on n'a pas fini, sinon on passe
|
|
|
|
if (! (charge->Fin(icharge,true) ) )
|
|
|
|
{ // calcul de l'équilibre
|
|
|
|
CalEquilibre(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats
|
|
|
|
,tb_combiner);
|
|
|
|
// fin du calcul, pour l'instant on ne considère pas les autres sous-types
|
|
|
|
FinCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{if ( avec_typeDeCalcul )
|
|
|
|
// cas où le type principal est valide et qu'il y a des sous_types
|
|
|
|
{ // on regarde si le sous-type "commandeInteractive" existe, si oui on le met en place
|
|
|
|
// détermine si le sous type de calcul existe et s'il est actif
|
|
|
|
if (paraGlob->SousTypeCalcul(commandeInteractive))
|
|
|
|
{// -- cas avec commandes interactives
|
|
|
|
// initialisation du calcul
|
|
|
|
InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );
|
|
|
|
// calcul de l'équilibre tant qu'il y a des commandes
|
|
|
|
while (ActionInteractiveAlgo())
|
|
|
|
{// on ne continue que si on n'a pas dépasser le nombre d'incréments maxi ou le temps maxi
|
|
|
|
if (! (charge->Fin(icharge,true) ) )
|
|
|
|
CalEquilibre(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats
|
|
|
|
,tb_combiner);
|
|
|
|
};
|
|
|
|
// fin du calcul, pour l'instant on ne considère pas les autres sous-types
|
|
|
|
FinCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );
|
|
|
|
}
|
|
|
|
else // cas sans commandes interactives
|
|
|
|
{// on fait le calcul d'équilibre
|
|
|
|
// initialisation du calcul : deux cas, soit avec une lecture initiale du .info, soit une lecture secondaire
|
|
|
|
if (paraGlob->EtatDeLaLecturePointInfo() == 0)
|
|
|
|
{InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );;}
|
|
|
|
else {// on est en lecture secondaire
|
|
|
|
|
|
|
|
MiseAJourAlgo(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );;
|
|
|
|
};
|
|
|
|
|
|
|
|
// on ne continue que si on n'a pas dépasser le nombre d'incréments maxi ou le temps maxi
|
|
|
|
if (! (charge->Fin(icharge,true) ) )
|
|
|
|
{ // calcul de l'équilibre
|
|
|
|
CalEquilibre(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats
|
|
|
|
,tb_combiner);
|
|
|
|
// fin du calcul, pour l'instant on ne considère pas les autres sous-types
|
|
|
|
FinCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );
|
|
|
|
};
|
|
|
|
|
|
|
|
};// fin du cas sans commandes interactives
|
|
|
|
// ensuite on teste en fonction des calculs complémentaires
|
|
|
|
// dépendant des sous_types. Pour l'instant ici uniquement la remontée
|
2023-06-15 17:16:35 +02:00
|
|
|
list <EnumSousTypeCalcul>::const_iterator ili,ili_fin = soustypeDeCalcul->end();
|
2021-09-26 14:31:23 +02:00
|
|
|
list <bool>::const_iterator ila;
|
|
|
|
for (ili = soustypeDeCalcul->begin(),ila = avec_soustypeDeCalcul->begin();
|
|
|
|
ili!=ili_fin;ili++,ila++)
|
|
|
|
if (*ila) // cas où le sous type est valide
|
|
|
|
{if (Remonte_in(*ili)) // on test la présence du calcul de remonté
|
|
|
|
{ // certaines initialisations sont nécessaires car c'est le premier calcul
|
|
|
|
Algori::InitRemontSigma(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
|
|
|
|
Algori::InitErreur(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
|
|
|
|
Algori::RemontSigma(lesMail);
|
|
|
|
Algori::RemontErreur(lesMail);
|
|
|
|
}
|
|
|
|
else if ( (*ili) == sauveMaillagesEnCours )
|
|
|
|
{ cout << "\n================================================================="
|
|
|
|
<< "\n| ecriture des maillages en cours en .her et .lis |"
|
|
|
|
<< "\n================================================================="
|
|
|
|
<< endl;
|
|
|
|
|
|
|
|
// ----- sort les informations sur fichiers
|
|
|
|
// Affichage des donnees des maillages dans des fichiers dont le nom est construit
|
|
|
|
// à partir du nom de chaque maillage au format ".her" et ".lis"
|
|
|
|
lesMail->Affiche_maillage_dans_her_lis(TEMPS_tdt,*lesRef);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// cas ou le type principal n'est pas valide
|
|
|
|
// on ne fait que le calcul complémentaire
|
|
|
|
{ list <EnumSousTypeCalcul>::const_iterator ili,ili_fin = soustypeDeCalcul->end();
|
|
|
|
list <bool>::const_iterator ila;
|
|
|
|
for (ili = soustypeDeCalcul->begin(),ila = avec_soustypeDeCalcul->begin();
|
|
|
|
ili!=ili_fin;ili++,ila++)
|
|
|
|
if (*ila) // cas où le sous type est valide
|
|
|
|
{if (Remonte_in(*ili)) // on test la présence du calcul de remonté
|
|
|
|
{ // certaines initialisations sont nécessaires car c'est le premier calcul
|
|
|
|
Algori::InitRemontSigma(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
|
|
|
|
Algori::InitErreur(lesMail,lesRef,divStock,charge,lesCondLim,lesContacts,resultats);
|
|
|
|
Algori::RemontSigma(lesMail);
|
|
|
|
Algori::RemontErreur(lesMail);
|
|
|
|
}
|
|
|
|
else if ( (*ili) == sauveMaillagesEnCours )
|
|
|
|
{ cout << "\n================================================================="
|
|
|
|
<< "\n| ecriture des maillages en cours en .her et .lis |"
|
|
|
|
<< "\n================================================================="
|
|
|
|
<< endl;
|
|
|
|
|
|
|
|
// ----- sort les informations sur fichiers
|
|
|
|
// Affichage des donnees des maillages dans des fichiers dont le nom est construit
|
|
|
|
// à partir du nom de chaque maillage au format ".her" et ".lis"
|
|
|
|
// a priori ici on n'a pas fait de calcul donc on sort les grandeurs à t
|
|
|
|
lesMail->Affiche_maillage_dans_her_lis(TEMPS_0,*lesRef);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// si on a forcé la sortie des itérations et incréments, il faut réinitialiser l'indicateur
|
|
|
|
if (!(pa.EtatSortieEquilibreGlobal()))
|
|
|
|
pa.ChangeSortieEquilibreGlobal(false);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// lecture des paramètres du calcul
|
|
|
|
void AlgoriCombine::lecture_Parametres(UtilLecture& entreePrinc)
|
|
|
|
{ MotCle motCle; // ref aux mots cle
|
|
|
|
deja_lue_entete_parametre = 1; // a priori pas de lecture d'entête
|
|
|
|
// on se positionne sur le prochain mot clé
|
|
|
|
do
|
|
|
|
{ entreePrinc.NouvelleDonnee();
|
|
|
|
}
|
|
|
|
while ( !motCle.SimotCle(entreePrinc.tablcar)) ;
|
|
|
|
// si le mot clé est "PARA_TYPE_DE_CALCUL" cela signifie
|
|
|
|
// qu'il y a un paramètre à lire
|
2023-05-03 17:23:49 +02:00
|
|
|
// bool lecture_effective = false;
|
2021-09-26 14:31:23 +02:00
|
|
|
if (strstr(entreePrinc.tablcar,"PARA_TYPE_DE_CALCUL")!=NULL)
|
|
|
|
{ //cas de la définition de paramètres
|
|
|
|
// on signale à Algori qu'il y a eu déjà une lecture de paramètre
|
|
|
|
deja_lue_entete_parametre=2;
|
|
|
|
// lecture du premier paramètres de l'algorithme
|
|
|
|
entreePrinc.NouvelleDonnee(); // ligne suivante
|
|
|
|
|
|
|
|
// on initialise tous les paramètres par défaut
|
|
|
|
// non, car cela permettra éventuellement de garder les anciens paramètres
|
|
|
|
|
|
|
|
// on s'arrête lorsqu'il n'y a plus de mot clé spécifique à lire
|
|
|
|
while ( (strstr(entreePrinc.tablcar,"choix_algo_")!=NULL)
|
|
|
|
|| (strstr(entreePrinc.tablcar,"gestion_sauvegarde_")!=NULL)
|
|
|
|
|| (strstr(entreePrinc.tablcar,"gestion_sortie_a_convergence_")!=NULL)
|
|
|
|
)
|
|
|
|
|
|
|
|
{bool lecture_effective_interne = false;
|
|
|
|
string nom_class_methode("AlgoriCombine::lecture_Parametres(...");
|
|
|
|
|
|
|
|
//=== cas où on utilise un choix d'algo interne via une fct nD
|
|
|
|
if (strstr(entreePrinc.tablcar,"choix_algo_")!=NULL)
|
|
|
|
{ string mot_cle="choix_algo_";
|
|
|
|
{ bool lec_eff = entreePrinc.Lecture_mot_cle_et_string
|
|
|
|
(nom_class_methode,mot_cle,nom_choix_algo);
|
|
|
|
lecture_effective_interne = lecture_effective_interne || lec_eff;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
//=== cas où on utilise une gestion de la sauvegarde de chaque algo via une fct nD
|
|
|
|
if (strstr(entreePrinc.tablcar,"gestion_sauvegarde_")!=NULL)
|
|
|
|
{ string mot_cle="gestion_sauvegarde_";
|
|
|
|
// puis on lit
|
|
|
|
{ bool lec_eff = entreePrinc.Lecture_mot_cle_et_string
|
|
|
|
(nom_class_methode,mot_cle,nom_gestion_sauvegarde);
|
|
|
|
lecture_effective_interne = lecture_effective_interne || lec_eff;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
//=== cas où on utilise une gestion de la sauvegarde de chaque algo via une fct nD
|
|
|
|
if (strstr(entreePrinc.tablcar,"gestion_sortie_a_convergence_")!=NULL)
|
|
|
|
{ string mot_cle="gestion_sortie_a_convergence_";
|
|
|
|
// puis on lit
|
|
|
|
{ bool lec_eff = entreePrinc.Lecture_mot_cle_et_string
|
|
|
|
(nom_class_methode,mot_cle,nom_gestion_sortie_a_convergence);
|
|
|
|
lecture_effective_interne = lecture_effective_interne || lec_eff;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
if ((lecture_effective_interne) && ( !motCle.SimotCle(entreePrinc.tablcar)))
|
|
|
|
{
|
|
|
|
#ifdef ENLINUX
|
|
|
|
if ((entreePrinc.entree)->fail())
|
|
|
|
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
|
|
|
|
{ entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if ((entreePrinc.entree)->eof())
|
|
|
|
// la lecture est bonne mais on a atteind la fin de la ligne
|
|
|
|
{ entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// sinon ce n'est pas une ligne ad hoc, la lecture s'arrêtera
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// puis appel de la méthode de la classe mère
|
|
|
|
Algori::lecture_Parametres(entreePrinc);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// création de cst_0 et cst_1
|
|
|
|
void AlgoriCombine::Creation_fct_cst()
|
|
|
|
{ // on crée si les fct n'existent pas déjà
|
|
|
|
// 1) on crée les paramètres pour la création des fonctions
|
|
|
|
Tableau <string > nom_variables;// les variables non globales -> 0
|
|
|
|
Tableau <Enum_GrandeurGlobale > enu_variables_globale; // enu globaux -> 0
|
|
|
|
Tableau <string > nom_variables_globales; // idem sous forme de strings
|
|
|
|
|
|
|
|
// 2) maintenant on crée les fonctions
|
|
|
|
if (cst_0 == NULL)
|
|
|
|
{string nom_ref("_"); // nom de ref de la fonction
|
|
|
|
string expression_fonction("0"); // la valeur de la fonction
|
|
|
|
cst_0 = new Fonction_expression_litterale_nD
|
|
|
|
(nom_ref,nom_variables,enu_variables_globale,nom_variables_globales
|
|
|
|
,expression_fonction);
|
|
|
|
};
|
|
|
|
if (cst_1 == NULL)
|
|
|
|
{string nom_ref("_"); // nom de ref de la fonction
|
|
|
|
string expression_fonction("1"); // la valeur de la fonction
|
|
|
|
cst_1 = new Fonction_expression_litterale_nD
|
|
|
|
(nom_ref,nom_variables,enu_variables_globale,nom_variables_globales
|
|
|
|
,expression_fonction);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// -------------------- Méthodes protégées --------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// écriture des paramètres dans la base info
|
|
|
|
// = 1 : on écrit tout
|
|
|
|
// = 2 : on écrit uniquement les données variables (supposées comme telles)
|
|
|
|
void AlgoriCombine::Ecrit_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas)
|
|
|
|
{
|
|
|
|
ofstream& sort = *entreePrinc.Sort_BI();
|
|
|
|
if (cas == 1)
|
|
|
|
{//-- tout d'abord les fonctions de gestion d'algo
|
|
|
|
// choix des sous_algo
|
|
|
|
if (nom_choix_algo == "")
|
|
|
|
{sort << "\n fct_choix_algo_ "<< "aucune ";}
|
|
|
|
else
|
|
|
|
{sort << "\n fct_choix_algo_ "<< nom_choix_algo;};
|
|
|
|
// gestion de sauvegarde
|
|
|
|
if (nom_gestion_sauvegarde == "")
|
|
|
|
{sort << "\n fct_gestion_sauvegarde_ "<< "aucune ";}
|
|
|
|
else
|
|
|
|
{sort << "\n fct_gestion_sauvegarde_ "<< nom_gestion_sauvegarde;};
|
|
|
|
// gestion de sortie à convergence
|
|
|
|
if (nom_gestion_sortie_a_convergence == "")
|
|
|
|
{sort << "\n fct_gestion_sortie_a_convergence_ "<< "aucune ";}
|
|
|
|
else
|
|
|
|
{sort << "\n fct_gestion_sortie_a_convergence_ "<< nom_gestion_sortie_a_convergence;};
|
|
|
|
|
|
|
|
//--- puis on passe en revue les algos internes
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
{ sort << "\n ----->>parametres_sous_algo_specifiques_ "<< Nom_TypeCalcul(tab_algo(i)->TypeDeCalcul());
|
|
|
|
tab_algo(i)->Ecrit_Base_info_Parametre(entreePrinc,cas);
|
|
|
|
sort << "\n ----->>fin_parametres_sous_algo_specifiques_ "<< Nom_TypeCalcul(tab_algo(i)->TypeDeCalcul());
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// lecture des paramètres dans la base info
|
|
|
|
// = 1 : on récupère tout
|
|
|
|
// = 2 : on récupère uniquement les données variables (supposées comme telles)
|
|
|
|
// choix = true : fonctionnememt normal
|
|
|
|
// choix = false : la méthode ne doit pas lire mais initialiser les données à leurs valeurs par défaut
|
|
|
|
// car la lecture est impossible
|
|
|
|
void AlgoriCombine::Lecture_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas,bool choix)
|
|
|
|
{
|
|
|
|
// récup du flot
|
|
|
|
ifstream * ent = entreePrinc.Ent_BI();
|
|
|
|
if (cas == 1)
|
|
|
|
{// dimensionnement
|
|
|
|
if (choix)
|
|
|
|
{// cas d'une lecture normale
|
|
|
|
ifstream * ent = entreePrinc.Ent_BI();
|
|
|
|
string toto;
|
|
|
|
(*ent) >> toto; // on passe l'entête
|
|
|
|
//-- tout d'abord les fonctions de gestion d'algo
|
|
|
|
// choix des sous_algo
|
|
|
|
(*ent) >> toto; // on passe l'entête
|
|
|
|
if (toto == "aucune")
|
|
|
|
{nom_choix_algo = "";choix_algo=NULL;}
|
|
|
|
else
|
|
|
|
{nom_choix_algo = toto;};
|
|
|
|
// gestion de sauvegarde
|
|
|
|
(*ent) >> toto; // on passe l'entête
|
|
|
|
if (toto == "aucune")
|
|
|
|
{nom_gestion_sauvegarde = "";gestion_sauvegarde=NULL;}
|
|
|
|
else
|
|
|
|
{nom_gestion_sauvegarde = toto;};
|
|
|
|
// gestion de sortie à convergence
|
|
|
|
(*ent) >> toto; // on passe l'entête
|
|
|
|
if (toto == "aucune")
|
|
|
|
{nom_gestion_sortie_a_convergence = "";gestion_sortie_a_convergence=NULL;}
|
|
|
|
else
|
|
|
|
{nom_gestion_sortie_a_convergence = toto;};
|
|
|
|
};
|
|
|
|
//--- puis on passe en revue les algos internes
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
{// si on est arrivée ici, cela veut dire que l'on a lue sur le .BI qu'il s'agit de paramètre spécifiques
|
|
|
|
// de sous-algo donc il y a une première ligne qui indique de quel sous algo il s'agit
|
|
|
|
// on suit la même logique que celle de Algori::Ecriture_base_info
|
|
|
|
string nom1,nom2;
|
|
|
|
(*ent) >> nom1 ;
|
|
|
|
if (nom1 == "----->>parametres_sous_algo_specifiques_")
|
|
|
|
{ // lecture du nom de l'algo
|
|
|
|
(*ent) >> nom2;
|
|
|
|
if (Id_nom_TypeCalcul(nom2.c_str()) == tab_algo(i)->TypeDeCalcul())
|
|
|
|
{ // les données sauvegardées correspondent à l'algo en cours, on peut les récupérer
|
|
|
|
Lecture_Base_info_Parametre(entreePrinc,cas,true);
|
|
|
|
// on finit la lecture en passant les dernières lignes jusqu'au mot clé
|
|
|
|
(*ent) >> nom1;
|
|
|
|
while (nom1 != "----->>fin_parametres_sous_algo_specifiques_")
|
|
|
|
(*ent) >> nom1;
|
|
|
|
(*ent) >> nom1; // enfin on passe le nom de l'algo
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // l'algo ne correspond pas, on passe les informations correspondants
|
|
|
|
while (nom1 != "----->>fin_parametres_sous_algo_specifiques_:")
|
|
|
|
(*ent) >> nom1;
|
|
|
|
(*ent) >> nom1; // enfin on passe le nom de l'algo
|
|
|
|
// on demande à l'agorithme de faire une initialisation sans lecture
|
|
|
|
Lecture_Base_info_Parametre(entreePrinc,cas,false);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // erreur on est mal positionné dans le fichier
|
|
|
|
cout << "\n *** erreur en lecture des parametres specifiques de l'algorithme"
|
|
|
|
<< " on attendait le mot cle ----->>parametres_sous_algo_specifiques_ "
|
|
|
|
<< " et on a lue "<< nom1
|
|
|
|
<< "\n AlgoriCombine::Lecture_Base_info_Parametre(...";
|
|
|
|
// dans le cas où un comptage du calcul est en cours on l'arrête
|
|
|
|
if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
|
|
|
|
if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
|
|
|
|
tab_algo(i)->Lecture_Base_info_Parametre(entreePrinc,cas,choix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// création d'un fichier de commande: cas des paramètres spécifiques
|
|
|
|
void AlgoriCombine::Info_commande_parametres(UtilLecture& entreePrinc)
|
|
|
|
{ // écriture dans le fichier de commande
|
|
|
|
ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
|
|
|
|
|
|
|
|
sort << "\n# exemple partiel de declaration d'un algorithme qui integre "
|
|
|
|
<< " 2 sous algorithmes " ;
|
|
|
|
sort << "\n ";
|
|
|
|
sort << "\n combiner avec plus visualisation "
|
|
|
|
<< "\n# ++++++++++++ liste des sous algorithmes ++++++++++++ "
|
|
|
|
<< " liste_algorithmes_a_combiner_ # mot cle de debut de liste "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# ============ algo 1 ============ "
|
|
|
|
<< "\n# ----- Dynamic Relaxation "
|
|
|
|
<< "\n dynamique_relaxation_dynam "
|
|
|
|
<< "\n # puis les parametres particuliers de l'algorithme de relaxation ..."
|
|
|
|
<< "\n # ... a completer "
|
|
|
|
<< "\n "
|
|
|
|
<< "\n# ============ algo 2 ============ "
|
|
|
|
<< "\n# ----- newton statique "
|
|
|
|
<< "\n non_dynamique "
|
|
|
|
<< "\n PARA_TYPE_DE_CALCUL "
|
|
|
|
<< "\n mode_debug_= 1 # il s'agit ici du mode debug uniquement pour le non_dynamique "
|
|
|
|
<< "\n# ... "
|
|
|
|
<< "\n fin_liste_algorithmes_a_combiner_ # mot cle de fin de liste de sous algo "
|
|
|
|
<< "\n "
|
|
|
|
<< "\n# ++++++++++++ parametres de l'algorithme combiner ++++++++++++ "
|
|
|
|
<< "\n# ils sont facultatifs et ici commentes cf. doc pour + de prec "
|
|
|
|
<< "\n PARA_TYPE_DE_CALCUL "
|
|
|
|
<< "\n## --- gestion du choix de l'algo"
|
|
|
|
<< "\n# choix_algo_ fonc_choix_algo"
|
|
|
|
<< "\n# # --- gestion de la sauvegarde de chaque algo"
|
|
|
|
<< "\n# gestion_sauvegarde_ fonc_gestion_sauvegarde # idem sauvegarde"
|
|
|
|
<< "\n# # --- puis la sortie du sous algo si convergence"
|
|
|
|
<< "\n# gestion_sortie_a_convergence_ fonc_gestion_sortie_a_convergence"
|
|
|
|
<< "\n " << flush;
|
|
|
|
|
|
|
|
cout << "\n# description plus precise de l'algorithme combiner (rep o ou n defaut) ? ";
|
|
|
|
string rep("n");
|
|
|
|
// procédure de lecture avec prise en charge d'un retour chariot
|
|
|
|
rep = lect_return_defaut(true,"n");
|
|
|
|
// si la taille de rep == 0 cela veut dire que c'est un retour chariot
|
|
|
|
if (rep.size()==0)
|
|
|
|
{rep = "n";
|
|
|
|
};
|
|
|
|
if ((rep == "o") || (rep == "O") ||(rep == "0"))
|
|
|
|
{ sort << "\n --- AlgoriCombine --- "
|
|
|
|
<< "\n# l'algorithme combiner permets d'encapsuler et de controler "
|
|
|
|
<< "\n# plusieurs sous algorithmes a l'interieur d'un algorithme maitre. "
|
|
|
|
<< "\n# NB:"
|
|
|
|
<< "\n# - Il n'y a pas de limitation sur le nombre de sous algorithme "
|
|
|
|
<< "\n# - un meme type d'algorithme peut apparaitre plusieurs fois "
|
|
|
|
<< "\n# - les sous algorithmes sont reperes par leur numero d'apparition"
|
|
|
|
<< "\n# lors de la lecture (et non par leur type) "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# Par defaut le fonctionnement est le suivant: "
|
|
|
|
<< "\n# - pour chaque increment de charge, l'ensemble des sous algorithmes "
|
|
|
|
<< "\n# est execute dans l'ordre de leur lecture "
|
|
|
|
<< "\n# - le programme sort d'un sous algorithme lorsque typiquement la precision "
|
|
|
|
<< "\n# requise pour cet algorithme en fonction de la norme choisit, est "
|
|
|
|
<< "\n# satisfaite (a noter que chaque algorithme peut redefinir sa propre "
|
|
|
|
<< "\n# norme et sa propre precision via des fonctions nD et/ou des parametres"
|
|
|
|
<< "\n# de controle specifique) "
|
|
|
|
<< "\n# - seul le dernier algorithme valide (si convergence) le resultat final"
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# Il est possible d'etendre ce fonctionnement avec les parametres "
|
|
|
|
<< "\n# facultatifs propres a l'algo combiner definit par le mot cle: "
|
|
|
|
<< "\n# PARA_TYPE_DE_CALCUL "
|
|
|
|
<< "\n# positionne apres la definition de tous les sous algo (cf. mot cle "
|
|
|
|
<< "\n# fin_liste_algorithmes_a_combiner_ ) "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# - on peut definir une fonction nD, dependante de grandeurs globales "
|
|
|
|
<< "\n# qui doit retourner 1 scalaire. Ce scalaire indique le "
|
|
|
|
<< "\n# choix de l'algo voulu. Dans ce cas, a chaque increment "
|
|
|
|
<< "\n# de charge, la fonction est appelee et le nombre (entier) que retourne la"
|
|
|
|
<< "\n# fonction indique le numero du sous algo a utiliser. En sortie du sous algo "
|
|
|
|
<< "\n# on regarde s'il s'agissait d'un calcul avec validation ou non. "
|
|
|
|
<< "\n# Le sous algo ne rend la main que si le calcul s'est deroule correctement "
|
|
|
|
<< "\n# (cf. remarques si-dessous). Aussi si le calcul etait avec validation "
|
|
|
|
<< "\n# la charge est incremente sinon il n'y a pas d'incrementation de la charge. "
|
|
|
|
<< "\n# Puis la fonction de choix d'algo est appelee pour designer le nouveau "
|
|
|
|
<< "\n# sous algo a appeler."
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# . la definition de la fonction s'effectue avec le mot cle choix_algo_"
|
|
|
|
<< "\n# suivit du nom d'une fonction nD definit dans la suite de la mise"
|
|
|
|
<< "\n# en donnees. "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# exemple de definition : "
|
|
|
|
<< "\n# choix_algo_ fonc_choix_algo # gestion du choix de l'algo "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# - par defaut, c'est le dernier sous algo qui valide le calcul. On peut definir "
|
|
|
|
<< "\n# une fonction nD, dependante de grandeurs globales, qui redefinit quand le sous algo "
|
|
|
|
<< "\n# doit valider le calcul. Cette fonction est appelee a l'interieur du sous algo "
|
|
|
|
<< "\n# a la fin de chaque iteration (implicit) ou increment (explicit) "
|
|
|
|
<< "\n# et permet a l'utilisateur (par exemple en fonction de la precision obtenue) "
|
|
|
|
<< "\n# de valider le calcul. "
|
|
|
|
<< "\n# Conjointement avec la fonction de choix d'algo, la fonction de validation"
|
|
|
|
<< "\n# est egalement appelee apres le retour du sous algo, pour incrementer la charge"
|
|
|
|
<< "\n# ou non (cf. si-dessus)."
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# . la definition de la fonction s'effectue avec le mot cle gestion_sauvegarde_"
|
|
|
|
<< "\n# suivit du nom d'une fonction nD definit dans la suite de la mise"
|
|
|
|
<< "\n# en donnees. "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# exemple de definition : "
|
|
|
|
<< "\n# gestion_sauvegarde_ fonc_gestion_sauvegarde # gestion de la convergence de chaque algo "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# - Par defaut, le programme sort d'un sous algorithme lorsque typiquement la precision "
|
|
|
|
<< "\n# requise pour cette algorithme en fonction de la norme choisit, est "
|
|
|
|
<< "\n# satisfaite, ceci pour un increment de charge. "
|
|
|
|
<< "\n# Il est possible d'effectuer plusieurs increment de charge avec un meme sous algo."
|
|
|
|
<< "\n# A priori il faut dans ce cas utiliser conjointement les fonction de "
|
|
|
|
<< "\n# gestion de sauvegarde et de validation de calcul, et on utilise une troisieme"
|
|
|
|
<< "\n# fonction nD qui dit quand on sort du sous algo."
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# . la def de la fonction s'effectue avec le mot cle gestion_sortie_a_convergence_"
|
|
|
|
<< "\n# suivit du nom d'une fonction nD definit dans la suite de la mise"
|
|
|
|
<< "\n# en donnees. "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# exemple de definition : "
|
|
|
|
<< "\n# gestion_sortie_a_convergence_ fonc_gestion_sortie_a_convergence # gestion de la sortie de chaque algo "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# Autres remarques importantes: "
|
|
|
|
// << "\n# - dans le cas de l'utilisation des fct nD, l'incrementation du chargement peut "
|
|
|
|
// << "\n# s'effectuer a l'interieur d'un sous algo. Ainsi un certain sous algo peut "
|
|
|
|
// << "\n# (eventuellement) enchainer plusieurs increments de charge "
|
|
|
|
// << "\n# avant de rendre la main. "
|
|
|
|
<< "\n# - un sous algo ne rend la main que s'il a fonctionne correctement. Par exemple "
|
|
|
|
<< "\n# s'il ne converge pas, il suit sa logique propre (cf. ses propres parametres"
|
|
|
|
<< "\n# de controle) jusqu'a aboutir au resultat cible (increment, precision etc.)."
|
|
|
|
<< "\n# Aussi, tant que l'algo ne rend pas la main, un nouveau choix de sous algo"
|
|
|
|
<< "\n# n'est pas possible. Cependant, chaque test de convergence du sous algo"
|
|
|
|
<< "\n# peut se controler via une fonction nD qui prend en compte l'evolution du calcul."
|
|
|
|
<< "\n# On peut ainsi definir une strategie specifique, qui permet de sortir de l'algo."
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# - au cours de l'execution de l'algo combiner on peut consulter la variable"
|
|
|
|
<< "\n# globale : "
|
|
|
|
<< "\n# algo_global_actuel"
|
|
|
|
<< "\n# qui contient pendant l'execution, le numero de def du sous algo en cours "
|
|
|
|
<< "\n# (voir la doc pour l'equivalence numero <-> type d'algo, car ce n'est pas le "
|
|
|
|
<< "\n# numero de lecture !!)"
|
|
|
|
<< "\n# - au cours de la mise en donnees generale (= le .info) on definit un ensemble de "
|
|
|
|
<< "\n# parametres de controle (ex: pas de temps, increment, nombre d'iteration etc. )."
|
|
|
|
<< "\n# Ces parametres s'appliquent a l'algorithme principal c-a-d combiner ."
|
|
|
|
<< "\n# Par defaut, l'ensemble de ces parametres de controle, est re-attribue a chaque"
|
|
|
|
<< "\n# sous algorithme. Mais il est egalement possible de modifier specifiquement certains"
|
|
|
|
<< "\n# parametre pour un algorithme particulier. On se reportera a la documentation generale"
|
|
|
|
<< "\n# pour plus d'info : cf. les mots cle : "
|
|
|
|
<< "\n# ==PARA_SPECIFIQUE_SOUS_ALGO== "
|
|
|
|
<< "\n# et "
|
|
|
|
<< "\n# ==FIN_PARA_SPECIFIQUE_SOUS_ALGO_=="
|
|
|
|
<< "\n# Ces 2 mots cles permettent de definir des parametres de controle specifiques pour un "
|
|
|
|
<< "\n# sous algorithme. "
|
|
|
|
<< "\n# - Ils doivent etre utilises apres la definition des parametres de "
|
|
|
|
<< "\n# controle generaux (parametre par defaut de tous les sous algo)"
|
|
|
|
<< "\n# - le premier est suivi du numero d'algo auquel il s'applique "
|
|
|
|
<< "\n# - le second termine la definition specifique "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# exemple de mise en donnees : "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# para_affichage #------------ "
|
|
|
|
<< "\n#---------------------------"
|
|
|
|
<< "\n# PARAMETRE | VALEUR | "
|
|
|
|
<< "\n#--------------------------- "
|
|
|
|
<< "\n# FREQUENCE_AFFICHAGE_INCREMENT 1 "
|
|
|
|
<< "\n# FREQUENCE_AFFICHAGE_ITERATION 1 "
|
|
|
|
<< "\n# FREQUENCE_SORTIE_FIL_DU_CALCUL 1 "
|
|
|
|
<< "\n# ... fin des parametres generaux "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# ==PARA_SPECIFIQUE_SOUS_ALGO== 1 # para specifiques sous algo 1 "
|
|
|
|
<< "\n# controle #------------ "
|
|
|
|
<< "\n#-------------------- "
|
|
|
|
<< "\n# PARAMETER | VALUE | "
|
|
|
|
<< "\n#-------------------- "
|
|
|
|
<< "\n# NORME E_cinetique/E_statique_ET_ResSurReact "
|
|
|
|
<< "\n# PRECISION 5e-1 "
|
|
|
|
<< "\n# etc. "
|
|
|
|
<< "\n# ==FIN_PARA_SPECIFIQUE_SOUS_ALGO_== "
|
|
|
|
<< "\n# "
|
|
|
|
<< "\n# ==PARA_SPECIFIQUE_SOUS_ALGO== 2 # para specifiques sous algo 2 "
|
|
|
|
<< "\n# .... "
|
|
|
|
<< "\n# ==FIN_PARA_SPECIFIQUE_SOUS_ALGO_== "
|
|
|
|
;
|
|
|
|
};
|
|
|
|
// appel de la classe mère
|
|
|
|
Algori::Info_com_parametres(entreePrinc);
|
|
|
|
sort << "\n" << endl;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// sortie sur fichier des temps cpu
|
|
|
|
// idem la forme générique de la classe mère
|
|
|
|
// + des infos partielles pour chaque sous-algorithme
|
|
|
|
void AlgoriCombine::Sortie_temps_cpu(const LesCondLim& lesCondLim
|
|
|
|
, const Charge& charge,const LesContacts & contact)
|
|
|
|
{// -- on commence par appeler la méthode générique
|
|
|
|
// mais auparavant, il faut abonder la partie loi de comportement
|
|
|
|
// qui globalise automatiquement, donc qui n'est pas spécifique à chaque algo
|
|
|
|
|
|
|
|
Algori::Sortie_temps_cpu(lesCondLim,charge,contact);
|
|
|
|
|
|
|
|
// -- puis on complète pour chaque sous algo
|
|
|
|
// NB: concernant le contact, le chargement et les CL ou CLL, les temps étant
|
|
|
|
// stockés dans les objets concernés, il n'y a pas de séparation pour chaque
|
|
|
|
// algo, donc on ne sort pas ces temps qui ne sont que globaux (pas spécifiques à
|
|
|
|
// chaque algo)
|
|
|
|
// on récupère le fichier des temps cpu
|
|
|
|
entreePrinc->Ouverture_fichier_temps_cpu(); // ouverture au cas où
|
|
|
|
// récupération du fichier des temps cpu
|
|
|
|
ofstream & sort_cpu = entreePrinc->Sort_temps_cpu();
|
|
|
|
int nbdigit = 6; // pour le pourcentage
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
{ // la petite méthode qui sert au transfert et qui doit-être appelé avant les sorties
|
|
|
|
tab_algo(i)->Temps_CPU_HZpp_to_lesTempsCpu(lesCondLim,charge,contact);
|
|
|
|
// on concatène la totalité pour ensuite sortir également des pourcentage
|
|
|
|
double total_cpu = tab_algo(i)->tempsInitialisation.Temps_CPU_User();
|
|
|
|
total_cpu += tab_algo(i)->tempsMiseAjourAlgo.Temps_CPU_User();
|
|
|
|
total_cpu += tab_algo(i)->tempsCalEquilibre.Temps_CPU_User();
|
|
|
|
total_cpu += tab_algo(i)->tempsSauvegarde.Temps_CPU_User();
|
|
|
|
total_cpu += tab_algo(i)->tempsSortieFilCalcul.Temps_CPU_User();
|
|
|
|
sort_cpu << fixed;
|
|
|
|
sort_cpu.precision(2);
|
|
|
|
// pour éviter de faire une division par 0
|
|
|
|
total_cpu = MaX(ConstMath::trespetit, total_cpu);
|
|
|
|
|
|
|
|
sort_cpu << "\n ----->> specifiquement au sous_algo: "<< Nom_TypeCalcul(tab_algo(i)->TypeDeCalcul());
|
|
|
|
sort_cpu << "\n ---> tps_total_sous_algo "
|
|
|
|
<< "("<< std::setw(nbdigit) << total_cpu/1000. << " ) ";
|
|
|
|
|
|
|
|
sort_cpu << "\n tps_InitAlgo "
|
|
|
|
<< "("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsInitialisation.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsInitialisation.Temps_CPU_User_milli();
|
|
|
|
sort_cpu << "\n tps_MiseAJourAlgo "
|
|
|
|
<< "("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsMiseAjourAlgo.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsMiseAjourAlgo.Temps_CPU_User_milli();
|
|
|
|
sort_cpu << "\n tps_CalEquilibre "
|
|
|
|
<< "("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsCalEquilibre.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsCalEquilibre.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n tps_MatSmLoc "
|
|
|
|
<< ".("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsRaidSmEner.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsRaidSmEner.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n tps_SmLoc "
|
|
|
|
<< ".("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsSecondMembreEnerg.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsSecondMembreEnerg.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n tps_lois_comp "
|
|
|
|
<< "..("<< std::setw(nbdigit) << (100 * tab_algo(i)->temps_lois_comportement.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->temps_lois_comportement.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n tps_metrique_KSM "
|
|
|
|
<< "...("<< std::setw(nbdigit) << (100 * tab_algo(i)->temps_metrique_K_SM.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->temps_metrique_K_SM.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n tps_ResSystLineaire "
|
|
|
|
<< "("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsResolSystemLineaire.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsResolSystemLineaire.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n tps_Sauvegarde "
|
|
|
|
<< "("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsSauvegarde.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsSauvegarde.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n tps_SortieFilCalcul "
|
|
|
|
<< "("<< std::setw(nbdigit) << (100 * tab_algo(i)->tempsSortieFilCalcul.Temps_CPU_User()/total_cpu) << " % ) "
|
|
|
|
<< tab_algo(i)->tempsSortieFilCalcul.Temps_CPU_User_milli()
|
|
|
|
;
|
|
|
|
sort_cpu << "\n";
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// une méthode qui a pour objectif de terminer tous les comptages, utile
|
|
|
|
// dans le cas d'un arrêt impromptu
|
|
|
|
void AlgoriCombine::Arret_du_comptage_CPU()
|
|
|
|
{ // tout d'abord on appel la méthode générique qui concerne finalement
|
|
|
|
// que l'algo combiné
|
|
|
|
Algori::Arret_du_comptage_CPU();
|
|
|
|
|
|
|
|
// puis ici il s'agit de faire l'arrêt également de tous les sous algo
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
tab_algo(i)->Arret_du_comptage_CPU();
|
|
|
|
};
|
|
|
|
|
|
|
|
// ------- concernant les algo internes --------
|
|
|
|
// lecture des algorithmes internes
|
|
|
|
void AlgoriCombine::Lecture_algo_interne(const bool avec_typeDeCal
|
|
|
|
,const list <EnumSousTypeCalcul>& soustype
|
|
|
|
,const list <bool>& avec_soustypeDeCal
|
|
|
|
,UtilLecture& entreePrinc)
|
|
|
|
{ // les algos internes sont encadrés par les mots clés:
|
|
|
|
// liste_algorithmes_a_combiner_ et fin_liste_algorithmes_a_combiner_
|
|
|
|
// ces mots clés doivent exister et il doit y avoir au moins un algo interne
|
|
|
|
|
|
|
|
|
|
|
|
list_sousTypeCalcul.clear();
|
|
|
|
list_avec_sousCalcul.clear();
|
|
|
|
|
|
|
|
list <list<EnumSousTypeCalcul> >::const_iterator ili=list_sousTypeCalcul.begin();
|
|
|
|
list <list<bool> >::const_iterator ala=list_avec_sousCalcul.begin();
|
|
|
|
|
|
|
|
try
|
|
|
|
{ entreePrinc.NouvelleDonnee();// on passe la ligne de définition de l'algo combiner
|
|
|
|
string nom_class_methode("AlgoriCombine::Lecture_algo_interne(..."); // pour info lecture
|
|
|
|
// on passe le mot clé de début de liste
|
|
|
|
string mot_cle = "liste_algorithmes_a_combiner_";
|
2023-05-03 17:23:49 +02:00
|
|
|
// bool lec_eff = entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
|
|
|
|
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
|
2021-09-26 14:31:23 +02:00
|
|
|
list < Algori * > list_algori_inter; // une liste de travail pour la lecture
|
|
|
|
// maintenant on va lire chaque algorithme
|
|
|
|
entreePrinc.NouvelleDonnee();
|
|
|
|
do
|
|
|
|
{ // on lit les infos concernant le type de calcul interne
|
|
|
|
EnumTypeCalcul typeCalcul;bool avec_Calcul;
|
|
|
|
list<EnumSousTypeCalcul> sousTypeCalcul;
|
|
|
|
list<bool> avec_sousCalcul;
|
|
|
|
LectureTypeCalcul(entreePrinc,typeCalcul,avec_Calcul,sousTypeCalcul,avec_sousCalcul);
|
|
|
|
list_sousTypeCalcul.push_front(sousTypeCalcul);ili=list_sousTypeCalcul.begin();
|
|
|
|
list_avec_sousCalcul.push_front(avec_sousCalcul);ala=list_avec_sousCalcul.begin();
|
|
|
|
// du coup : les listes sont rangées : la première -> le dernier algo, etc.
|
|
|
|
// def de l'algorithme
|
|
|
|
Algori* algori = Algori::New_Agori
|
|
|
|
(typeCalcul,avec_Calcul, (*ili),(*ala),entreePrinc);
|
|
|
|
list_algori_inter.push_back(algori);
|
|
|
|
}
|
|
|
|
while (strstr(entreePrinc.tablcar,"fin_liste_algorithmes_a_combiner_")==NULL) ;
|
|
|
|
// entreePrinc.NouvelleDonnee(); // on passe le mot clé fin_liste_algorithmes_a_combiner_
|
|
|
|
// maintenant on stocke dans le tableau ceci pour un acces non séquentiel futur
|
|
|
|
int nb_algo = list_algori_inter.size();
|
|
|
|
tab_algo.Change_taille(nb_algo);
|
|
|
|
list < Algori * >::iterator il,ilfin= list_algori_inter.end();
|
|
|
|
int i=1;
|
|
|
|
for (il = list_algori_inter.begin();il != ilfin; il++,i++)
|
|
|
|
tab_algo(i)=(*il);
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
cout << "\n *** erreur en lecture algorithme(s) interne(s) "
|
|
|
|
<< "\n AlgoriCombine::Lecture_algo_interne(.."<<flush;
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
|
|
|
|
// on renseigne la variable: ptalgocombi de la classe Algori pour tous les sous-algo
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
tab_algo(i)->Change_ptalgocombi (this);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// sortie des temps cpu cumulées de tous les algos
|
|
|
|
void AlgoriCombine::AutreSortieTempsCPU(ofstream& sort,const int ) const
|
|
|
|
{ // on commence par cumuler tous les temps de calcul
|
|
|
|
Tableau <Temps_CPU_HZpp> lesTsCpu(10); // init
|
|
|
|
|
|
|
|
// on passe en revue tous les algorithmes et on cumule les temps cpu
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
tab_algo(i)->Ajout_Temps_CPU_HZpp_to_lesTempsCpu(lesTsCpu);
|
|
|
|
// on n'ajoute pas les temps de l'algo combiner, car sinon
|
|
|
|
// on va compter 2 fois certains temps
|
|
|
|
// en fait les temps de l'algo combiner ne sont pas très exploitable
|
|
|
|
// dans la forme actuelle, peut-être à améliorer si on veut les temps
|
|
|
|
// spécifique de l'algo combiner
|
|
|
|
|
|
|
|
// puis on affiche comme dans
|
|
|
|
//Algori::Ecriture_base_info(ofstream& sort,const int cas
|
|
|
|
/// ----> pour rappel:
|
|
|
|
// //------- temps cpu -----
|
|
|
|
// Temps_CPU_HZpp tempsInitialisation; // lesTempsCpu(1)
|
|
|
|
// Temps_CPU_HZpp tempsMiseAjourAlgo; // lesTempsCpu(2)
|
|
|
|
// Temps_CPU_HZpp tempsCalEquilibre; // lesTempsCpu(3)
|
|
|
|
// Temps_CPU_HZpp tempsRaidSmEner; // lesTempsCpu(4)
|
|
|
|
// Temps_CPU_HZpp tempsSecondMembreEnerg; // lesTempsCpu(5)
|
|
|
|
// Temps_CPU_HZpp tempsResolSystemLineaire; // lesTempsCpu(6)
|
|
|
|
// Temps_CPU_HZpp tempsSauvegarde; // lesTempsCpu(7)
|
|
|
|
// Temps_CPU_HZpp tempsSortieFilCalcul; // lesTempsCpu(8)
|
|
|
|
// Temps_CPU_HZpp tempsRaidSmEnerContact; // lesTempsCpu(9)
|
|
|
|
// Temps_CPU_HZpp tempsSecondMembreEnergContact; // lesTempsCpu(10)
|
|
|
|
// Temps_CPU_HZpp temps_CL; // lesTempsCpu(11)
|
|
|
|
// Temps_CPU_HZpp temps_CLL; // lesTempsCpu(12)
|
|
|
|
// Temps_CPU_HZpp temps_lois_comportement; // lesTempsCpu(13)
|
|
|
|
// Temps_CPU_HZpp temps_metrique_K_SM; // lesTempsCpu(14)
|
|
|
|
// Temps_CPU_HZpp temps_chargement; // lesTempsCpu(15)
|
|
|
|
// Temps_CPU_HZpp temps_rech_contact; // lesTempsCpu(16)
|
2023-05-03 17:23:49 +02:00
|
|
|
// cas d'un calcul parallèle: // passage des infos entre process
|
2023-09-03 10:10:17 +02:00
|
|
|
// Temps_CPU_HZpp temps_transfert_court ; // lesTempsCpu(17)
|
|
|
|
// Temps_CPU_HZpp temps_transfert_long ; // lesTempsCpu(18)
|
|
|
|
// Temps_CPU_HZpp temps_attente ; // lesTempsCpu(19)
|
|
|
|
// Temps_CPU_HZpp temps_transfert_court_charge ; // lesTempsCpu(20)
|
|
|
|
// Temps_CPU_HZpp temps_transfert_long_charge ; // lesTempsCpu(21)
|
|
|
|
// Temps_CPU_HZpp temps_attente_charge ; // lesTempsCpu(22)
|
|
|
|
// Temps_CPU_HZpp temps_transfert_court_contact ; // lesTempsCpu(23)
|
|
|
|
// Temps_CPU_HZpp temps_transfert_long_contact ; // lesTempsCpu(24)
|
|
|
|
// Temps_CPU_HZpp temps_attente_contact ; // lesTempsCpu(25)
|
2021-09-26 14:31:23 +02:00
|
|
|
sort << "\n tps_InitAlgo " << lesTsCpu(1);
|
|
|
|
sort << "\n tps_MiseAJourAlgo "<< lesTsCpu(2);
|
|
|
|
sort << "\n tps_CalEquilibre "<< lesTsCpu(3);
|
|
|
|
sort << "\n tps_MatSmLoc "<< lesTsCpu(4);
|
|
|
|
sort << "\n tps_SmLoc "<< lesTsCpu(5);
|
|
|
|
sort << "\n tps_ResSystLineaire "<< lesTsCpu(6);
|
|
|
|
sort << "\n tps_Sauvegarde "<< lesTsCpu(7);
|
|
|
|
sort << "\n tps_SortieFilCalcul "<< lesTsCpu(8);
|
|
|
|
sort << "\n tps_contactMatSmLoc "<< lesTsCpu(9);
|
|
|
|
sort << "\n tps_contactSmLoc "<< lesTsCpu(10);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// sortie pour info de la liste des énumérés de tous les sous-algo
|
|
|
|
list <EnumTypeCalcul> AlgoriCombine::List_Sous_Algo() const
|
|
|
|
{ list <EnumTypeCalcul> retour;
|
|
|
|
int nb_algo = tab_algo.Taille();
|
|
|
|
for (int i=1;i<=nb_algo;i++)
|
|
|
|
retour.push_back(tab_algo(i)->TypeDeCalcul());
|
|
|
|
// retour
|
|
|
|
return retour;
|
|
|
|
};
|