Arcane  v3.14.10.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/*---------------------------------------------------------------------------*/
65{
66 public:
67
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;
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
149 IMesh* mesh = subDomain()->defaultMesh();
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
305 info() << "Total time for post-processing analysis output (second): " << total_time;
307 if (nb_time!=0)
308 info() << "Average time per output (second): " << total_time / nb_time
309 << " (for " << nb_time << " outputs";
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
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){
377 post_processor->setBaseDirectoryName(m_output_directory.path());
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
Variables communes d'un cas.
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.
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
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
virtual CellGroup allActiveCells()=0
Interface d'un écrivain pour les informations de post-traitement.
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.
Interface du gestionnaire de variables.
Interface d'une variable.
Definition IVariable.h:54
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
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Informations pour construire un module.
Gère les sorties basées sur un temps physique, temps CPU ou un nombre d'itération.
bool check(Real old_time, Real current_time, Integer current_iteration, Integer current_cpu_time, const String &from_function=String())
Vérifie s'il faut effectuer une sortie.
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
Integer nbActivated() const
Retourne le nombre de fois que le timer a été activé
Definition Timer.h:222
@ TimerReal
Timer utilisant le temps réel.
Definition Timer.h:76
Real totalTime() const
Retourne le temps total (en secondes) passé dans le timer.
Definition Timer.h:216
Paramètres nécessaires à la construction d'une variable.
Collection de variables.
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.
Chaîne de caractères unicode.
TraceMessage warning() const
Flot pour un message d'avertissement.
TraceMessage info() const
Flot pour un message d'information.
constexpr ARCCORE_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 -*-
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.