Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
TimeHistoryMng2.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* TimeHistoryMng2.cc (C) 2000-2025 */
9/* */
10/* Module managing a history of values (Version 2). */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/ApplicationInfo.h"
16#include "arcane/utils/ScopedPtr.h"
17#include "arcane/utils/ITraceMng.h"
18#include "arcane/utils/PlatformUtils.h"
19
20#include "arcane/core/ITimeHistoryMng.h"
21#include "arcane/core/IIOMng.h"
22#include "arcane/core/CommonVariables.h"
23#include "arcane/core/ISubDomain.h"
24#include "arcane/core/Directory.h"
25#include "arcane/core/AbstractModule.h"
26#include "arcane/core/EntryPoint.h"
27#include "arcane/core/ObserverPool.h"
28#include "arcane/core/IVariableMng.h"
29#include "arcane/core/CaseOptionsMain.h"
30#include "arcane/core/IParallelMng.h"
31#include "arcane/core/ITimeHistoryCurveWriter2.h"
32#include "arcane/core/ITimeHistoryTransformer.h"
33#include "arcane/core/XmlNode.h"
34#include "arcane/core/XmlNodeList.h"
35#include "arcane/core/IXmlDocumentHolder.h"
36#include "arcane/core/ServiceFinder2.h"
37#include "arcane/core/ServiceBuilder.h"
38#include "arcane/core/IMeshMng.h"
39
40#include "arcane/datatype/DataTypeTraits.h"
41
42#include "arcane/impl/internal/TimeHistoryMngInternal.h"
43#include "arcane/core/GlobalTimeHistoryAdder.h"
44
45#include <variant>
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
50namespace Arcane
51{
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
59class GnuplotTimeHistoryCurveWriter2
60: public TraceAccessor
62{
63 public:
64
65 GnuplotTimeHistoryCurveWriter2(ITraceMng* tm)
66 : TraceAccessor(tm)
67 {
68 }
69
70 public:
71
72 void build() override {}
73 void beginWrite(const TimeHistoryCurveWriterInfo& infos) override
74 {
75 m_times = infos.times();
76 String path = infos.path();
77 // m_output_path overrides the infos argument if not empty.
78 if (m_output_path.empty())
79 m_output_path = path;
80
81 m_gnuplot_path = Directory(Directory(m_output_path), "gnuplot");
82 // Create the output directory.
83 if (m_gnuplot_path.createDirectory()) {
84 warning() << "Can not create gnuplot curve directory '"
85 << m_gnuplot_path.path() << "'";
86 }
87 }
88 void writeCurve(const TimeHistoryCurveInfo& infos) override
89 {
90 String name(infos.name().clone());
91
92 if (infos.subDomain() != NULL_SUB_DOMAIN_ID) {
93 name = "SD" + String::fromNumber(infos.subDomain()) + "_" + name;
94 }
95 if (infos.hasSupport()) {
96 name = infos.support() + "_" + name;
97 }
98
99 String sname(m_gnuplot_path.file(name));
100 FILE* ofile = fopen(sname.localstr(), "w");
101 if (!ofile) {
102 warning() << "Can not open gnuplot curve file '" << sname << "'";
103 return;
104 }
105 RealConstArrayView values = infos.values();
106 Int32ConstArrayView iterations = infos.iterations();
107 Integer nb_val = iterations.size();
108 Integer sub_size = infos.subSize();
109 for (Integer i = 0; i < nb_val; ++i) {
110 fprintf(ofile, "%.16E", Convert::toDouble(m_times[iterations[i]]));
111 for (Integer z = 0; z < sub_size; ++z)
112 fprintf(ofile, " %.16E", Convert::toDouble(values[(i * sub_size) + z]));
113 fprintf(ofile, "\n");
114 }
115 fclose(ofile);
116 }
117
118 void endWrite() override {}
119
120 String name() const override { return "gnuplot"; }
121
122 void setOutputPath(const String& path) override
123 {
124 m_output_path = path;
125 }
126 String outputPath() const override
127 {
128 return m_output_path;
129 }
130
131 private:
132
133 String m_output_path;
134 UniqueArray<Real> m_times;
135 Directory m_gnuplot_path;
136};
137
138/*---------------------------------------------------------------------------*/
139/*---------------------------------------------------------------------------*/
140
148class TimeHistoryMng2
149: public AbstractModule
150, public CommonVariables
151, public ITimeHistoryMng
152{
153
154 public:
155
156 TimeHistoryMng2(const ModuleBuildInfo& cb, bool add_entry_points = true);
157 ~TimeHistoryMng2() override = default;
158
159 public:
160
161 VersionInfo versionInfo() const override { return VersionInfo(1, 0, 0); }
162
163 public:
164
165 void addValue(const String& name, Real value, bool end_time, bool is_local) override
166 {
167 m_internal->addValue(TimeHistoryAddValueArgInternal(name, end_time, (is_local ? parallelMng()->commRank() : NULL_SUB_DOMAIN_ID)), value);
168 }
169 void addValue(const String& name, Int64 value, bool end_time, bool is_local) override
170 {
171 m_internal->addValue(TimeHistoryAddValueArgInternal(name, end_time, (is_local ? parallelMng()->commRank() : NULL_SUB_DOMAIN_ID)), value);
172 }
173 void addValue(const String& name, Int32 value, bool end_time, bool is_local) override
174 {
175 m_internal->addValue(TimeHistoryAddValueArgInternal(name, end_time, (is_local ? parallelMng()->commRank() : NULL_SUB_DOMAIN_ID)), value);
176 }
177 void addValue(const String& name, RealConstArrayView values, bool end_time, bool is_local) override
178 {
179 m_internal->addValue(TimeHistoryAddValueArgInternal(name, end_time, (is_local ? parallelMng()->commRank() : NULL_SUB_DOMAIN_ID)), values);
180 }
181 void addValue(const String& name, Int32ConstArrayView values, bool end_time, bool is_local) override
182 {
183 m_internal->addValue(TimeHistoryAddValueArgInternal(name, end_time, (is_local ? parallelMng()->commRank() : NULL_SUB_DOMAIN_ID)), values);
184 }
185 void addValue(const String& name, Int64ConstArrayView values, bool end_time, bool is_local) override
186 {
187 m_internal->addValue(TimeHistoryAddValueArgInternal(name, end_time, (is_local ? parallelMng()->commRank() : NULL_SUB_DOMAIN_ID)), values);
188 }
189
190 public:
191
192 void timeHistoryBegin() override;
193 void timeHistoryEnd() override;
194 void timeHistoryInit() override;
195 void timeHistoryStartInit() override;
196 void timeHistoryContinueInit() override;
197 void timeHistoryRestore() override;
198 void timeHistoryStartInitEnd();
199
200 public:
201
202 void addCurveWriter(ITimeHistoryCurveWriter2* writer) override;
204 {
205 ARCANE_CHECK_POINTER(writer);
206 removeCurveWriter(writer->name());
207 }
208 void removeCurveWriter(const String& name) override;
209
210 public:
211
212 void dumpHistory(bool is_verbose) override;
213 void dumpCurves(ITimeHistoryCurveWriter2* writer) override;
214
215 bool active() const override { return m_internal->active(); }
216 void setActive(bool is_active) override { m_internal->setActive(is_active); }
217
218 bool isDumpActive() const override { return m_internal->isDumpActive(); }
219 void setDumpActive(bool is_active) override { m_internal->setDumpActive(is_active); }
220
221 bool isShrinkActive() const override { return m_internal->isShrinkActive(); }
222 void setShrinkActive(bool is_active) override { m_internal->setShrinkActive(is_active); }
223
225
226 ITimeHistoryMngInternal* _internalApi() override { return m_internal.get(); }
227
228 private:
229
231 // Ref<ITimeHistoryAdder> m_adder;
232};
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
237TimeHistoryMng2::
238TimeHistoryMng2(const ModuleBuildInfo& mb, bool add_entry_points)
239: AbstractModule(mb)
240, CommonVariables(this)
241, m_internal(makeRef(new TimeHistoryMngInternal(subDomain()->variableMng(),
242 makeRef(new Properties(subDomain()->propertyMng(), "ArcaneTimeHistoryProperties")))))
243// , m_adder(makeRef(new GlobalTimeHistoryAdder(this)))
244{
245 if (add_entry_points) {
246 addEntryPoint(this, "ArcaneTimeHistoryBegin", &TimeHistoryMng2::timeHistoryBegin,
248 addEntryPoint(this, "ArcaneTimeHistoryEnd", &TimeHistoryMng2::timeHistoryEnd,
250 addEntryPoint(this, "ArcaneTimeHistoryInit", &TimeHistoryMng2::timeHistoryInit,
252 addEntryPoint(this, "ArcaneTimeHistoryStartInit", &TimeHistoryMng2::timeHistoryStartInit,
254 addEntryPoint(this, "ArcaneTimeHistoryContinueInit", &TimeHistoryMng2::timeHistoryContinueInit,
256 addEntryPoint(this, "ArcaneTimeHistoryStartInitEnd", &TimeHistoryMng2::timeHistoryStartInitEnd,
258 addEntryPoint(this, "ArcaneTimeHistoryRestore", &TimeHistoryMng2::timeHistoryRestore,
260 }
261}
262
263/*---------------------------------------------------------------------------*/
264/*---------------------------------------------------------------------------*/
265
266void TimeHistoryMng2::
267timeHistoryStartInit()
268{
269 m_internal->addNowInGlobalTime();
270}
271
272/*---------------------------------------------------------------------------*/
273
274void TimeHistoryMng2::
275timeHistoryStartInitEnd()
276{
277 m_internal->updateGlobalTimeCurve();
278}
279
280/*---------------------------------------------------------------------------*/
281/*---------------------------------------------------------------------------*/
282
283void TimeHistoryMng2::
284timeHistoryBegin()
285{
286 // If not active, do not unnecessarily enlarge m_global_times
287 // which will be copied into the backed-up variable 'm_th_global_time'
288 if (isShrinkActive() && !active()) {
289 // Do nothing
290 }
291 else {
292 //warning() << "timeHistoryBegin " << m_global_time() << " " << m_global_times.size();
293 m_internal->addNowInGlobalTime();
294 }
295
296 // Check if temporal outputs should be printed
297 {
298 bool force_print_thm = false;
299 int th_step = subDomain()->caseOptionsMain()->writeHistoryPeriod();
300 if (th_step != 0) {
301 if ((globalIteration() % th_step) == 0)
302 if (parallelMng()->isMasterIO() || (m_internal->isNonIOMasterCurvesEnabled() && m_internal->isMasterIOOfSubDomain()))
303 force_print_thm = true;
304 }
305 if (subDomain()->applicationInfo().isDebug())
306 force_print_thm = true;
307 if (force_print_thm)
308 m_internal->dumpHistory();
309 }
310}
311
312/*---------------------------------------------------------------------------*/
313/*---------------------------------------------------------------------------*/
314
315void TimeHistoryMng2::
316timeHistoryEnd()
317{
318 m_internal->updateGlobalTimeCurve();
319}
320
321/*---------------------------------------------------------------------------*/
322/*---------------------------------------------------------------------------*/
323
324void TimeHistoryMng2::
325timeHistoryInit()
326{
327 //warning() << "timeHistoryInit " << m_global_time() << " " << m_global_times.size();
328
329 info(4) << "TimeHistory is MasterIO ? " << m_internal->isMasterIO();
330 if (!m_internal->isMasterIO() && (!m_internal->isNonIOMasterCurvesEnabled() || !m_internal->isMasterIOOfSubDomain()))
331 return;
332
333 m_internal->editOutputPath(Directory(subDomain()->exportDirectory(), "courbes"));
334 m_internal->addObservers(subDomain()->propertyMng());
335
336 if (platform::getEnvironmentVariable("ARCANE_DISABLE_GNUPLOT_CURVES").null()) {
337 ITimeHistoryCurveWriter2* gnuplot_curve_writer = new GnuplotTimeHistoryCurveWriter2(traceMng());
338 m_internal->addCurveWriter(makeRef(gnuplot_curve_writer));
339 }
340
341 ServiceBuilder<ITimeHistoryCurveWriter2> builder(subDomain());
342 auto writers = builder.createAllInstances();
343 for (auto& wr_ref : writers) {
344 ITimeHistoryCurveWriter2* cw = wr_ref.get();
345 if (cw) {
346 info() << "FOUND CURVE SERVICE (V2)!";
347 m_internal->addCurveWriter(wr_ref);
348 }
349 }
350}
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
354
357{
358 m_internal->addCurveWriter(makeRef(writer));
359}
360
361/*---------------------------------------------------------------------------*/
362/*---------------------------------------------------------------------------*/
363
364void TimeHistoryMng2::
365timeHistoryContinueInit()
366{
367 if (m_internal->isMasterIO() || (m_internal->isNonIOMasterCurvesEnabled() && m_internal->isMasterIOOfSubDomain()))
368 m_internal->readVariables(subDomain()->meshMng(), subDomain()->defaultMesh());
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
373
374void TimeHistoryMng2::
375timeHistoryRestore()
376{
377 m_internal->resizeArrayAfterRestore();
378}
379
380/*---------------------------------------------------------------------------*/
381/*---------------------------------------------------------------------------*/
382
384dumpHistory(bool is_verbose)
385{
386 ARCANE_UNUSED(is_verbose);
387 m_internal->dumpHistory();
388}
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
395{
396 m_internal->dumpCurves(writer);
397}
398
399/*---------------------------------------------------------------------------*/
400/*---------------------------------------------------------------------------*/
401
404{
405 m_internal->applyTransformation(v);
406}
407
408/*---------------------------------------------------------------------------*/
409/*---------------------------------------------------------------------------*/
410
413{
414 m_internal->removeCurveWriter(name);
415}
416
417/*---------------------------------------------------------------------------*/
418/*---------------------------------------------------------------------------*/
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
423extern "C++" ARCANE_IMPL_EXPORT ITimeHistoryMng*
424arcaneCreateTimeHistoryMng2(ISubDomain* mng)
425{
426 return new TimeHistoryMng2(ModuleBuildInfo(mng, "TimeHistoryMng"));
427}
428extern "C++" ARCANE_IMPL_EXPORT ITimeHistoryMng*
429arcaneCreateTimeHistoryMng2(ISubDomain* mng, bool add_entry_points)
430{
431 return new TimeHistoryMng2(ModuleBuildInfo(mng, "TimeHistoryMng"), add_entry_points);
432}
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
437} // End namespace Arcane
438
439/*---------------------------------------------------------------------------*/
440/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
String name() const override
Module name.
ITraceMng * traceMng() const override
Trace manager.
ISubDomain * subDomain() const override
Sub-domain associated with the module.
IMesh * defaultMesh() const override
Default mesh for this module.
AbstractModule(const ModuleBuildInfo &)
Constructor from a ModuleBuildInfo.
IParallelMng * parallelMng() const override
Message passing parallelism manager.
Int32 globalIteration() const
Current iteration number.
CommonVariables(IModule *c)
Constructs the references of the common variables for the module c.
constexpr Integer size() const noexcept
Number of elements in the array.
Class managing a directory.
Definition Directory.h:36
void beginWrite(const TimeHistoryCurveWriterInfo &infos) override
Notify the start of writing.
void setOutputPath(const String &path) override
Base directory where curves will be written.
String outputPath() const override
Base directory where curves will be written.
void writeCurve(const TimeHistoryCurveInfo &infos) override
Write a curve.
void endWrite() override
Notify the end of writing.
String name() const override
Writer name.
static const char *const WComputeLoop
called during the calculation loop
Definition IEntryPoint.h:43
static const char *const WStartInit
called during new case initialization
Definition IEntryPoint.h:51
static const char *const WRestore
called to restore variables during a rollback
Definition IEntryPoint.h:53
@ PAutoLoadEnd
Automatically loaded at the end. This means that a module possessing an entry point with this propert...
Definition IEntryPoint.h:81
@ PAutoLoadBegin
Automatically loaded at the beginning. This means that a module possessing an entry point with this p...
Definition IEntryPoint.h:74
static const char *const WContinueInit
called during continuation initialization
Definition IEntryPoint.h:49
static const char *const WInit
called during initialization
Definition IEntryPoint.h:47
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual const CaseOptionsMain * caseOptionsMain() const =0
General dataset options.
virtual String name() const =0
Writer name.
Interface for the internal part of a value history manager.
Class managing a history of values.
Interface of an object transforming history curves.
Information for building a module.
Reference to an instance.
String clone() const
Clones this string.
Definition String.cc:414
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
Class extending the arguments when adding a value to a value history.
Information for writing a curve.
Int32ConstArrayView iterations() const
List of iterations.
const String & name() const
Curve name.
RealConstArrayView values() const
List of curve values.
Integer subSize() const
Number of values per time step.
Information about writing curves.
String path() const
Path to write the data (unless specifically overridden by the service via ITimeHistoryCurveWriter2::s...
RealConstArrayView times() const
List of times.
Manager of a history of values.
void applyTransformation(ITimeHistoryTransformer *v) override
Applies the transformation v to all curves.
void setDumpActive(bool is_active) override
Sets the output activation status.
void dumpCurves(ITimeHistoryCurveWriter2 *writer) override
Uses the writer writer to output all curves.
ITimeHistoryMngInternal * _internalApi() override
Internal Arcane API.
void removeCurveWriter(ITimeHistoryCurveWriter2 *writer) override
Removes a writer.
void addValue(const String &name, Real value, bool end_time, bool is_local) override
Adds the value value to the history name.
void setActive(bool is_active) override
Sets the activation status.
void addValue(const String &name, Int64 value, bool end_time, bool is_local) override
void dumpHistory(bool is_verbose) override
Saves the history.
bool active() const override
Indicates the activation status.
void addValue(const String &name, Int64ConstArrayView values, bool end_time, bool is_local) override
void setShrinkActive(bool is_active) override
Sets the boolean indicating if the history is compressed.
void addValue(const String &name, RealConstArrayView values, bool end_time, bool is_local) override
Adds the value value to the history name.
VersionInfo versionInfo() const override
Module version.
void addValue(const String &name, Int32 value, bool end_time, bool is_local) override
Adds the value value to the history name.
bool isDumpActive() const override
Indicates the output activation status.
void addValue(const String &name, Int32ConstArrayView values, bool end_time, bool is_local) override
Adds the value value to the history name.
void addCurveWriter(ITimeHistoryCurveWriter2 *writer) override
Adds a writer.
bool isShrinkActive() const override
Returns a boolean indicating if the history is compressed.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
TraceMessage warning() const
Flow for a warning message.
1D data vector with value semantics (STL style).
Information about a version.
Definition VersionInfo.h:47
double toDouble(Real r)
Converts a Real to double.
String getEnvironmentVariable(const String &name)
Environment variable named name.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:480
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
void addEntryPoint(ModuleType *module, const char *name, void(ModuleType::*func)(), const String &where=IEntryPoint::WComputeLoop, int property=IEntryPoint::PNone)
Template routine allowing an entry point to be referenced in a module.
Definition EntryPoint.h:174
std::int32_t Int32
Signed integer type of 32 bits.
ConstArrayView< Real > RealConstArrayView
C equivalent of a 1D array of reals.
Definition UtilsTypes.h:488