Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArcanePostProcessingModule.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ArcanePostProcessingModule.cc (C) 2000-2022 */
9/* */
10/* Module de post-traitement. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Ptr.h"
15#include "arcane/utils/List.h"
16
17#include "arcane/EntryPoint.h"
18#include "arcane/ISubDomain.h"
19#include "arcane/IVariableMng.h"
20#include "arcane/IApplication.h"
21#include "arcane/IParallelMng.h"
22#include "arcane/ItemGroup.h"
23#include "arcane/Directory.h"
24#include "arcane/ITimeHistoryMng.h"
25#include "arcane/ServiceUtils.h"
26#include "arcane/IPostProcessorWriter.h"
27#include "arcane/SimpleProperty.h"
28#include "arcane/MeshAccessor.h"
29#include "arcane/IMesh.h"
30#include "arcane/VariableTypes.h"
31#include "arcane/CommonVariables.h"
32#include "arcane/MathUtils.h"
33#include "arcane/ITimeLoopMng.h"
34#include "arcane/ItemEnumerator.h"
35#include "arcane/ModuleFactory.h"
36#include "arcane/Timer.h"
37#include "arcane/IVariableAccessor.h"
38#include "arcane/VariableCollection.h"
39
40#include "arcane/OutputChecker.h"
41
42#include "arcane/std/ArcanePostProcessing_axl.h"
43
44#include <set>
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
49namespace Arcane
50{
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
63class ArcanePostProcessingModule
64: public ArcaneArcanePostProcessingObject
65{
66 public:
67
68 explicit ArcanePostProcessingModule(const ModuleBuilder& cb);
69 ~ArcanePostProcessingModule();
70
71 public:
72
73 virtual VersionInfo versionInfo() const { return VersionInfo(0,1,2); }
74
75 public:
76
77 virtual void exportData();
78 virtual void exportDataStart();
79
80 virtual void postProcessingStartInit();
81 virtual void postProcessingInit();
82 virtual void postProcessingExit();
83
84
85 private:
86
87 OutputChecker m_output_checker;
88 OutputChecker m_history_output_checker;
93 VariableList m_variables;
96
97 private:
98
99 void _readConfig();
100 void _saveAtTime(Real);
101
102 void _checkCreateOutputDir();
103};
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108ARCANE_REGISTER_MODULE_ARCANEPOSTPROCESSING(ArcanePostProcessingModule);
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
113ArcanePostProcessingModule::
114ArcanePostProcessingModule(const ModuleBuildInfo& mbi)
116, m_output_checker(mbi.subDomain(),"PostProcessing")
117, m_history_output_checker(mbi.subDomain(),"PostProcessingHistory")
118, m_times(VariableBuilder(this,"ExportTimes"))
119, m_do_output(true)
120, m_output_dir_created(false)
121, m_post_processor_timer(0)
122{
123 m_output_checker.assignIteration(&m_next_iteration,&options()->outputPeriod);
124 m_output_checker.assignGlobalTime(&m_next_global_time,&options()->outputFrequency);
125
126 m_history_output_checker.assignIteration(&m_history_next_iteration,&options()->outputHistoryPeriod);
127 m_post_processor_timer = new Timer(mbi.subDomain(),"PostProcessorTimer",Timer::TimerReal);
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
133ArcanePostProcessingModule::
134~ArcanePostProcessingModule()
135{
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
144{
145 Integer nb_var = options()->output().variable.size();
146 Integer nb_group = options()->output().group.size();
147
148 IVariableMng* var_mng = subDomain()->variableMng();
150
151 if (nb_var!=0){
152 std::set<String> used_variables; // Liste des variables déjà indiquées
153 m_variables.clear();
154 info() << " ";
155 info() << "-- List of output variables (" << nb_var << " variables):";
156 for( Integer i=0; i<nb_var; ++i ){
157 String varname(options()->output().variable[i]);
158 IVariable* var = var_mng->findMeshVariable(defaultMesh(),varname);
159 if (!var)
160 ARCANE_FATAL("PostTreatment: no variable with name '{0}' exists",varname);
161 eItemKind ik = var->itemKind();
162 if (ik!=IK_Node && ik!=IK_Edge && ik!=IK_Face && ik!=IK_Cell)
163 ARCANE_FATAL("PostTreatment: variable ({0}) must"
164 " be a mesh variable (node, edge, face or cell)",varname);
165
166 if (used_variables.find(varname)==used_variables.end()){
167 info() << "Variable <" << varname << ">";
168 m_variables.add(var);
169 used_variables.insert(varname);
170 var->addTag("PostProcessing","1");
171 }
172 else{
173 warning() << "Variable <" << varname << "> required twice during post-processing analysis";
174 }
175 }
176 }
177 else
178 m_do_output = false;
179
180 if (nb_group!=0){
181 std::set<String> used_groups; // Liste des groupes déjà indiquées
182 //m_group_list.resize(nb_group);
183 info() << " ";
184 info() << "-- List of output groups (" << nb_group << " groups):";
185 for( Integer i=0; i<nb_group; ++i ){
186 ItemGroup group = options()->output().group[i];
187 if (group.null())
188 continue;
189 String groupname = group.name();
190 if (used_groups.find(groupname)==used_groups.end()){
191 info() << "Group <" << groupname << ">";
192 used_groups.insert(groupname);
193 m_groups.add(group);
194 }
195 else
196 warning() << "Group <" << groupname << "> required twice during post-processing analysis";
197 }
198 //m_group_list.resize(index);
199 }
200 else{
201 // Si aucun groupe spécifié, sauve uniquement l'ensemble des mailles.
202 //m_groups.resize(1);
203
205 if(mesh->isAmrActivated())
206 m_groups.add(mesh->allActiveCells());
207 else
208 m_groups.add(mesh->allCells());
209 }
210}
211
212/*---------------------------------------------------------------------------*/
213/*---------------------------------------------------------------------------*/
214
215void ArcanePostProcessingModule::
216_checkCreateOutputDir()
217{
219 return;
220 m_output_directory = Directory(subDomain()->exportDirectory(),"depouillement");
223}
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
227
228void ArcanePostProcessingModule::
229postProcessingInit()
230{
231 info() << " -------------------------------------------";
232 info() << "| POST PROCESSING |";
233 info() << " -------------------------------------------";
234 info() << " ";
235
236 bool is_continue = subDomain()->isContinue();
237
238 info() << "Variables output:";
239 m_output_checker.initialize(is_continue);
240
241 info() << "History output:";
242 m_history_output_checker.initialize(is_continue);
243
244 _readConfig();
245
246 // Positionnement de l'option 'shrink' du timeHistoryMng depuis l'axl
247 if (options()->outputHistoryShrink==true){
248 //info()<< "\33[42;30m" << "postProcessingStartInit Setting History to be shrank!" << "\33[m";
249 subDomain()->timeHistoryMng()->setShrinkActive(options()->outputHistoryShrink);
250 }else{
251 //info()<< "\33[42;30m" << "postProcessingStartInit Plain History!" << "\33[m";
252 }
253
254 // initialize parameter with a dry call to checker
256 Real old_time = vc.globalOldTime();
257 Real current_time = vc.globalTime();
258 /* bool do_output = */ m_output_checker.check(old_time,current_time,
259 vc.globalIteration(),0);
260 /* bool do_output = */ m_history_output_checker.check(old_time,current_time,
261 vc.globalIteration(),0);
262 if (options()->saveInit()){
263 _saveAtTime(current_time);
264 }
265}
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
269
270void ArcanePostProcessingModule::
271postProcessingStartInit()
272{
273 m_next_global_time = 0.0;
275 m_curves_next_global_time = 0.0;
276 m_curves_next_iteration = 0;
277 m_history_next_iteration = 0;
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
292{
293 Real current_time = subDomain()->commonVariables().globalTime();
294 bool save_at_exit = false;
295 if (subDomain()->timeLoopMng()->finalTimeReached())
296 save_at_exit = options()->saveFinalTime();
297 if (!save_at_exit)
298 save_at_exit = options()->endExecutionOutput();
299 if (save_at_exit){
300 _saveAtTime(current_time);
301 }
302
303 // Affiche statistiques d'exécutions
304 Real total_time = m_post_processor_timer->totalTime();
305 info() << "Total time for post-processing analysis output (second): " << total_time;
306 Integer nb_time = m_post_processor_timer->nbActivated();
307 if (nb_time!=0)
308 info() << "Average time per output (second): " << total_time / nb_time
309 << " (for " << nb_time << " outputs";
310 IPostProcessorWriter* post_processor = options()->format();
311 if (post_processor)
312 post_processor->close();
313}
314
315/*---------------------------------------------------------------------------*/
316/*---------------------------------------------------------------------------*/
322{
324 Real old_time = vc.globalOldTime();
325 Real current_time = vc.globalTime();
326 bool do_output = m_output_checker.check(old_time,current_time,
327 vc.globalIteration(),0);
328 if (do_output)
329 _saveAtTime(current_time);
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
339{
340 // Ecrit les valeurs du dépouillement pour l'initialisation.
341 if (subDomain()->commonVariables().globalIteration()==0)
342 _saveAtTime(0.);
343
344 // Regarde s'il faut activer les historiques pour cette itération
346 Real old_time = vc.globalOldTime();
347 Real current_time = vc.globalTime();
348 bool do_history_output = m_history_output_checker.check(old_time,current_time,
349 vc.globalIteration(),0);
350
351 subDomain()->timeHistoryMng()->setActive(do_history_output);
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
356
357void ArcanePostProcessingModule::
358_saveAtTime(Real saved_time)
359{
360 Integer size = m_times.size();
361
363 //IParallelMng* pm = subDomain()->parallelMng();
364
365 // Ne sauvegarde pas si le temps actuel est le même que le précédent
366 // (Sinon ca fait planter Ensight...)
367 if (size!=0 && math::isEqual(m_times[size-1],saved_time))
368 return;
369
370 m_times.resize(size+1);
371 m_times[size] = saved_time;
372
373 _checkCreateOutputDir();
374
375 if (m_do_output){
376 IPostProcessorWriter* post_processor = options()->format();
378 post_processor->setTimes(m_times);
379 post_processor->setVariables(m_variables);
380 post_processor->setGroups(m_groups);
381 info() << " ";
382 info() << "**** Output in progress at time " << saved_time <<" ******";
383
384 {
386 vm->writePostProcessing(post_processor);
387 }
388 }
389}
390
391/*---------------------------------------------------------------------------*/
392/*---------------------------------------------------------------------------*/
393
394} // End namespace Arcane
395
396/*---------------------------------------------------------------------------*/
397/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Generation de la classe de base du Module.
CaseOptionsArcanePostProcessing * options() const
Options du jeu de données du module.
Arcane::VariableScalarInteger m_next_iteration
Variables du module.
ISubDomain * subDomain() const override
Sous-domaine associé au module.
IMesh * defaultMesh() const override
Maillage par défaut pour ce module.
Module de sortie pour le dépouillement.
Timer * m_post_processor_timer
Timer pour le temps passé à écrire.
bool m_output_dir_created
true si répertoire créé.
VariableArrayReal m_times
Instants de temps des sauvegardes.
virtual VersionInfo versionInfo() const
Version du module.
virtual void exportDataStart()
Point d'entrée en début d'itération.
VariableList m_variables
Liste des variables a exporter.
ItemGroupList m_groups
Liste des groupes à exporter.
virtual void exportData()
Vérifie et écrit les valeurs pour le dépouillement.
virtual void postProcessingExit()
Informations de dépouillement en sortie de la boucle de calcul.
Directory m_output_directory
Répertoire de sortie.
bool m_do_output
true si les sorties sont actives
constexpr Integer size() const noexcept
Retourne la taille du tableau.
Variables communes d'un cas.
Real globalTime() const
Temps courant.
Int32 globalIteration() const
Numéro de l'itération courante.
CommonVariables(IModule *c)
Construit les références des variables communes pour le module c.
Real globalOldTime() const
Temps courant précédent.
Classe gérant un répertoire.
Definition Directory.h:33
virtual bool createDirectory() const
Créé le répertoire.
Definition Directory.cc:120
virtual String path() const
Retourne le chemin du répertoire.
Definition Directory.cc:129
Interface d'un écrivain pour les informations de post-traitement.
virtual void setVariables(VariableCollection variables)=0
Positionne la liste des variables à sortir.
virtual void setTimes(RealConstArrayView times)=0
Positionne la liste des temps.
virtual void close()=0
Ferme l'écrivain. Après fermeture, il ne peut plus être utilisé
virtual void setGroups(ItemGroupCollection groups)=0
Positionne la liste des groupes à sortir.
virtual void setBaseDirectoryName(const String &dirname)=0
Positionne le nom du répertoire de sortie des fichiers. Ce répertoire doit exister.
virtual const CommonVariables & commonVariables() const =0
Informations sur les variables standards.
virtual IMesh * defaultMesh()=0
Maillage par défaut.
virtual bool isContinue() const =0
Vrai si on effectue une reprise, faux sinon.
virtual ITimeHistoryMng * timeHistoryMng()=0
Retourne le gestionnaire d'historique.
virtual IVariableMng * variableMng()=0
Retourne le gestionnaire de variables.
virtual void setShrinkActive(bool is_active)=0
Positionne le booléen indiquant si l'historique est compressé
virtual void setActive(bool is_active)=0
Positionne l'état d'activation.
Interface du gestionnaire de variables.
virtual IVariable * findMeshVariable(IMesh *mesh, const String &name)=0
Retourne la variable du maillage de nom name ou 0 si aucune de se nom existe.
virtual void writePostProcessing(IPostProcessorWriter *writer)=0
Ecrit les variables pour un post-traitement.
Interface d'une variable.
Definition IVariable.h:56
virtual void addTag(const String &tagname, const String &tagvalue)=0
Ajoute le tag tagname avev la valeur tagvalue.
virtual eItemKind itemKind() const =0
Type des entités du maillage sur lequel repose la variable.
Groupe d'entités de maillage.
Definition ItemGroup.h:49
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Informations pour construire un module.
ISubDomain * subDomain() const
Accès au sous-domaine associé
Gère les sorties basées sur un temps physique, temps CPU ou un nombre d'itération.
Chaîne de caractères unicode.
Sentinelle pour le timer. La sentinelle associée à un timer permet de déclancher celui-ci au moment d...
Definition Timer.h:89
Gestion d'un timer.
Definition Timer.h:62
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
virtual void resize(Integer new_size)
Redimensionne le tableau pour contenir new_size éléments.
Informations sur une version.
Definition VersionInfo.h:46
constexpr Integer size() const noexcept
Retourne la taille du tableau.
VariableRefArrayT< Real > VariableArrayReal
Variable tableau de type réels.
constexpr __host__ __device__ bool isEqual(const _Type &a, const _Type &b)
Teste l'égalité bit à bit entre deux valeurs.
Definition Numeric.h:253
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
List< ItemGroup > ItemGroupList
Tableau de groupes d'éléments du maillage.
eItemKind
Genre d'entité de maillage.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_Edge
Entité de maillage de genre arête.
double Real
Type représentant un réel.