Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
TimeHistoryMngInternal.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/* TimeHistoryMngInternal.cc (C) 2000-2025 */
9/* */
10/* Internal class managing a history of values. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/impl/internal/TimeHistoryMngInternal.h"
15
16#include "arcane/core/IMeshMng.h"
17#include "arcane/core/IPropertyMng.h"
18
19#include "arcane/utils/JSONWriter.h"
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24namespace Arcane
25{
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
32{
33 m_trace_mng->info() << "Add CurveWriter2 name=" << writer->name();
35 m_curve_writers2.insert(writer);
36}
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
40
42removeCurveWriter(const String& name)
43{
44 for (auto& cw : m_curve_writers2)
45 if (cw->name() == name) {
47 return;
48 }
49}
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
56{
57 OStringStream meta_data_str;
58
59 meta_data_str() << "<?xml version='1.0' ?>\n";
60 meta_data_str() << "<curves>\n";
61 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
62 TimeHistoryValue* val = i->second;
63 meta_data_str() << "<curve "
64 << " name='" << val->name() << "'"
65 << " index='" << val->index() << "'"
66 << " data-type='" << dataTypeName(val->dataType()) << "'"
67 << " sub-size='" << val->subSize() << "'";
68
69 if (!val->meshHandle().isNull()) {
70 meta_data_str() << " support='" << val->meshHandle().meshName() << "'";
71 }
72 if (val->isLocal()) {
73 meta_data_str() << " sub-domain='" << val->localSubDomainId() << "'";
74 }
75
76 meta_data_str() << "/>\n";
77 }
78 meta_data_str() << "</curves>\n";
79
80 {
81 String ss = meta_data_str.str();
82 m_th_meta_data = ss;
83 //warning() << "TimeHistoryMng MetaData: size=" << ss.len() << " v=" << ss;
84 }
85
87}
88
89/*---------------------------------------------------------------------------*/
90/*---------------------------------------------------------------------------*/
91
94{
95 m_observer_pool.addObserver(this,
97 prop_mng->writeObservable());
98
99 m_observer_pool.addObserver(this,
101 m_variable_mng->writeObservable());
102}
103
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106
109{
110 auto p = m_properties;
111 p->setInt32("version", m_version);
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
119{
120 m_global_times.add(m_common_variables.globalTime());
121 TimeHistoryAddValueArgInternal thpi(m_common_variables.m_global_time.name(), true, NULL_SUB_DOMAIN_ID);
122 addValue(thpi, m_common_variables.globalTime());
123}
124
125/*---------------------------------------------------------------------------*/
126/*---------------------------------------------------------------------------*/
127
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
140{
142 return;
143
145 TimeHistoryCurveWriterInfo infos(m_output_path, m_global_times.constView());
146 writer->beginWrite(infos);
147 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
148 const TimeHistoryValue& th = *(i->second);
149 th.dumpValues(m_trace_mng, writer, infos);
150 }
151 writer->endWrite();
152 }
153
154 else {
155
156#ifdef ARCANE_CHECK
158 bool all_need_comm = m_parallel_mng->reduce(MessagePassing::ReduceMin, m_need_comm);
159 if (all_need_comm != m_need_comm) {
160 ARCANE_FATAL("Internal error: m_need_comm not sync");
161 }
162 }
163#endif
164
165 if (m_is_master_io) {
166 TimeHistoryCurveWriterInfo infos(m_output_path, m_global_times.constView());
167 writer->beginWrite(infos);
168 // No curves
169 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
170 const TimeHistoryValue& th = *(i->second);
171 th.dumpValues(m_trace_mng, writer, infos);
172 }
173
174 // Received curves.
176 Integer master_io_rank = m_parallel_mng->masterIORank();
177 UniqueArray<Int32> length(5);
178
179 for (Integer i = 0; i < m_parallel_mng->commSize(); ++i) {
180 if (i != master_io_rank) {
181 Integer nb_curve = 0;
182 m_parallel_mng->recv(ArrayView<Integer>(1, &nb_curve), i);
183 for (Integer icurve = 0; icurve < nb_curve; ++icurve) {
184 m_parallel_mng->recv(length, i);
185
186 UniqueArray<char> buf(length[0]);
187 UniqueArray<Int32> iterations_to_write(length[1]);
188 UniqueArray<Real> values_to_write(length[2]);
189
190 m_parallel_mng->recv(buf, i);
191 m_parallel_mng->recv(iterations_to_write, i);
192 m_parallel_mng->recv(values_to_write, i);
193
194 String name = String(buf.unguardedBasePointer());
195
196 if (length[4] != 0) {
197 UniqueArray<char> buf2(length[4]);
198 m_parallel_mng->recv(buf2, i);
199 String name_mesh = String(buf2.unguardedBasePointer());
200
201 TimeHistoryCurveInfo curve_info(name, name_mesh, iterations_to_write, values_to_write, length[3], i);
202 writer->writeCurve(curve_info);
203 }
204 else {
205 TimeHistoryCurveInfo curve_info(name, iterations_to_write, values_to_write, length[3], i);
206 writer->writeCurve(curve_info);
207 }
208 }
209 }
210 }
211 }
212
213 writer->endWrite();
214 }
215 else if (m_need_comm) {
216 TimeHistoryCurveWriterInfo infos(m_output_path, m_global_times.constView());
217 Integer master_io_rank = m_parallel_mng->masterIORank();
219 UniqueArray<Int32> length(5);
220 m_parallel_mng->send(ArrayView<Integer>(1, &nb_curve), master_io_rank);
221 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
222 const TimeHistoryValue& th = *(i->second);
223 String name = th.name();
224 UniqueArray<Int32> iterations_to_write;
225 UniqueArray<Real> values_to_write;
226 th.arrayToWrite(iterations_to_write, values_to_write, infos);
227
228 length[0] = arcaneCheckArraySize(name.length() + 1);
229 length[1] = iterations_to_write.size();
230 length[2] = values_to_write.size();
231 length[3] = th.subSize();
232 if (!th.meshHandle().isNull()) {
233 length[4] = arcaneCheckArraySize(th.meshHandle().meshName().length() + 1);
234 }
235 else {
236 length[4] = 0;
237 }
238
239 m_parallel_mng->send(length, master_io_rank);
240 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
241 m_parallel_mng->send(iterations_to_write, master_io_rank);
242 m_parallel_mng->send(values_to_write, master_io_rank);
243 if (!th.meshHandle().isNull()) {
244 m_parallel_mng->send(ConstArrayView<char>(length[4], static_cast<const char*>(th.meshHandle().meshName().localstr())), master_io_rank);
245 }
246 }
247 }
248 }
249}
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
253
256{
258 return;
259 if (!m_is_dump_active)
260 return;
261
265
266 m_trace_mng->info() << "History output finished: " << platform::getCurrentDateTime();
267}
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
271
274{
276 return;
277 for (IterT<HistoryList> i(m_history_list); i(); ++i) {
278 TimeHistoryValue& th = *(i->second);
279 th.applyTransformation(m_trace_mng, v);
280 }
281}
282
283/*---------------------------------------------------------------------------*/
284/*---------------------------------------------------------------------------*/
285
287readVariables(IMeshMng* mesh_mng, IMesh* default_mesh)
288{
289 bool need_update = false;
290
291 auto p = m_properties;
292
293 Int32 version = 0;
294 if (!p->get("version", version)) {
295 version = 1;
296 m_trace_mng->info() << "The checkpoint contains legacy format of TimeHistory variables, updating...";
297 _fromLegacyFormat(default_mesh);
298 need_update = true;
299 }
300 else if (version == 2) {
301 m_trace_mng->info() << "TimeHistory Variables version 2";
302 }
303 else {
304 ARCANE_FATAL("Unknown TimeHistory Variables format -- Found version: {0}", version);
305 }
306
307 m_trace_mng->info(4) << "readVariables resizes m_global_time to " << m_th_global_time.size();
308 m_global_times.resize(m_th_global_time.size());
310
311 m_trace_mng->info() << "Reading the values history";
312
313 IIOMng* io_mng = m_parallel_mng->ioMng();
315 if (!doc.get()) {
316 m_trace_mng->error() << " METADATA len=" << m_th_meta_data().length()
317 << " str='" << m_th_meta_data() << "'";
318 ARCANE_FATAL("The meta-data of TimeHistoryMng2 are invalid.");
319 }
320 XmlNode root_node = doc->documentNode();
321 XmlNode curves_node = root_node.child(String("curves"));
322 XmlNodeList curves = curves_node.children(String("curve"));
323
324 // v1
325 String ustr_name("name");
326 String ustr_index("index");
327 String ustr_sub_size("sub-size");
328 String ustr_data_type("data-type");
329
330 // v2
331 String ustr_support("support");
332 String ustr_sub_domain("sub-domain");
333
334 for (XmlNode curve : curves) {
335 String name = curve.attrValue(ustr_name);
336 Integer index = curve.attr(ustr_index).valueAsInteger();
337 Integer sub_size = curve.attr(ustr_sub_size).valueAsInteger();
338 String data_type_str = curve.attrValue(ustr_data_type);
339 eDataType dt = dataTypeFromName(data_type_str.localstr());
340 String support_str = curve.attrValue(ustr_support, false);
341
342 XmlNode sub_domain_node = curve.attr(ustr_sub_domain);
343 Integer sub_domain = NULL_SUB_DOMAIN_ID;
344 if (!sub_domain_node.null()) {
345 sub_domain = sub_domain_node.valueAsInteger();
346 m_need_comm = true;
347 }
348
349 if (sub_domain != NULL_SUB_DOMAIN_ID && m_parallel_mng->commRank() != sub_domain) {
350 continue;
351 }
352
353 if (name.null())
354 ARCANE_FATAL("null name for curve");
355 if (index < 0)
356 ARCANE_FATAL("Invalid index '{0}' for curve", index);
357
358 TimeHistoryValue* val = nullptr;
359 if (support_str.null()) {
360 TimeHistoryAddValueArgInternal thpi(name, true, sub_domain);
361 switch (dt) {
362 case DT_Real:
363 val = new TimeHistoryValueT<Real>(m_variable_mng, thpi, index, sub_size, isShrinkActive());
364 break;
365 case DT_Int32:
366 val = new TimeHistoryValueT<Int32>(m_variable_mng, thpi, index, sub_size, isShrinkActive());
367 break;
368 case DT_Int64:
369 val = new TimeHistoryValueT<Int64>(m_variable_mng, thpi, index, sub_size, isShrinkActive());
370 break;
371 default:
372 ARCANE_FATAL("Unsupported type");
373 }
374 if (need_update) {
375 val->fromOldToNewVariables(m_variable_mng, default_mesh);
376 }
377 }
378 else {
379 MeshHandle mh = mesh_mng->findMeshHandle(support_str);
380 TimeHistoryAddValueArgInternal thpi(TimeHistoryAddValueArg(name, true, sub_domain), mh);
381 switch (dt) {
382 case DT_Real:
383 val = new TimeHistoryValueT<Real>(thpi, index, sub_size, isShrinkActive());
384 break;
385 case DT_Int32:
386 val = new TimeHistoryValueT<Int32>(thpi, index, sub_size, isShrinkActive());
387 break;
388 case DT_Int64:
389 val = new TimeHistoryValueT<Int64>(thpi, index, sub_size, isShrinkActive());
390 break;
391 default:
392 ARCANE_FATAL("Unsupported type");
393 }
394 // Important in the case where we have two histories of the same name for two different meshes,
395 // or the same name as a "global" history.
396 name = name + "_" + mh.meshName();
397 }
398 if (sub_domain != NULL_SUB_DOMAIN_ID) {
399 name = name + "_Local";
400 }
401 m_history_list.insert(HistoryValueType(name, val));
402 }
403}
404
405/*---------------------------------------------------------------------------*/
406/*---------------------------------------------------------------------------*/
407
410{
411 Integer current_iteration = m_common_variables.globalIteration();
412 {
413 // Check that we do not have more elements than iterations
414 // in 'm_th_global_time'. Normally this can only happen
415 // during a time rollback if the variables were saved
416 // during the time step.
417 // TODO: this test does not work if isShrinkActive() is true.
418 Integer n = m_th_global_time.size();
419 if (n > current_iteration) {
420 n = current_iteration;
421 m_th_global_time.resize(n);
422 m_trace_mng->info() << "TimeHistoryRestore: truncating TimeHistoryGlobalTime array to size n=" << n << "\n";
423 }
424 }
425 m_global_times.resize(m_th_global_time.size());
427
428 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
429 i->second->removeAfterIteration(current_iteration);
430 }
431}
432
433/*---------------------------------------------------------------------------*/
434/*---------------------------------------------------------------------------*/
435
437editOutputPath(const Directory& directory)
438{
439 m_directory = directory;
440 if (m_output_path.empty()) {
441 m_output_path = m_directory.path();
442 if (m_directory.createDirectory()) {
443 m_trace_mng->warning() << "Can't create the output directory '" << m_output_path << "'";
444 }
445 }
446}
447
448/*---------------------------------------------------------------------------*/
449/*---------------------------------------------------------------------------*/
450
453{
454 if (!m_is_master_io && (!thpi.timeHistoryAddValueArg().isLocal() || !m_enable_non_io_master_curves || !m_is_master_io_of_sd)) {
455 return;
456 }
457
458 if (thpi.timeHistoryAddValueArg().isLocal() && thpi.timeHistoryAddValueArg().localSubDomainId() != m_parallel_mng->commRank()) {
459 return;
460 }
461
462 if (!m_is_active) {
463 return;
464 }
465
466 String name_to_find = thpi.timeHistoryAddValueArg().name().clone();
467 if (!thpi.meshHandle().isNull()) {
468 // Important in the case where we have two histories with the same name for two different meshes,
469 // or the same name as a "global" history.
470 name_to_find = name_to_find + "_" + thpi.meshHandle().meshName();
471 }
472 if (thpi.timeHistoryAddValueArg().isLocal()) {
473 name_to_find = name_to_find + "_Local";
474 }
475
476 auto hl = m_history_list.find(name_to_find);
477
478 if (hl != m_history_list.end()) {
479 TimeHistoryCurveWriterInfo infos(m_output_path, m_global_times.constView());
480 hl->second->arrayToWrite(iterations, values, infos);
481 }
482 else {
483 iterations.clear();
484 values.clear();
485 }
486}
487
488/*---------------------------------------------------------------------------*/
489/*---------------------------------------------------------------------------*/
490
493{
494 m_trace_mng->debug() << "Writing of the history of values path=" << m_output_path;
495
497 m_trace_mng->info() << "Begin output history: " << platform::getCurrentDateTime();
498
499 // Writing via version 2 of the curve writers
500 for (auto& cw_ref : m_curve_writers2) {
501 ITimeHistoryCurveWriter2* writer = cw_ref.get();
502 m_trace_mng->debug() << "Writing curves with '" << writer->name()
503 << "' date=" << platform::getCurrentDateTime();
504 dumpCurves(writer);
505 }
506 }
507}
508
509/*---------------------------------------------------------------------------*/
510/*---------------------------------------------------------------------------*/
511
514{
515 // Only the master process writes.
516 Integer master_io_rank = m_parallel_mng->masterIORank();
517 if (m_is_master_io) {
518 std::ofstream ofile(m_directory.file("time_history.xml").localstr());
519 ofile << "<?xml version='1.0' ?>\n";
520 ofile << "<curves>\n";
521
522 // We first write the names of our curves.
523 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
524 const TimeHistoryValue& th = *(i->second);
525 ofile << "<curve name='";
526 if (!th.meshHandle().isNull()) {
527 ofile << th.meshHandle().meshName() << "_";
528 }
529 if (th.isLocal()) {
530 ofile << "SD" << master_io_rank << "_";
531 }
532 ofile << th.name() << "'/>\n";
533 }
534 // Then, if other processes can also have curves, we
535 // also write their names.
536 // Even if "m_io_master_write_only" is equal to false, this file is
537 // necessarily written by a single process.
539 for (Integer i = 0; i < m_parallel_mng->commSize(); ++i)
540 if (i != master_io_rank) {
541 Integer nb_curve = 0;
542 m_parallel_mng->recv(ArrayView<Integer>(1, &nb_curve), i);
543 for (Integer icurve = 0; icurve < nb_curve; ++icurve) {
544 UniqueArray<Int32> length(2);
545 m_parallel_mng->recv(length, i);
546
547 UniqueArray<char> buf(length[0]);
548 m_parallel_mng->recv(buf, i);
549 ofile << "<curve name='";
550
551 if (length[1] != 0) {
552 UniqueArray<char> buf2(length[1]);
553 m_parallel_mng->recv(buf2, i);
554 ofile << buf2.unguardedBasePointer() << "_";
555 }
556 ofile << "SD" << i << "_";
557 ofile << buf.unguardedBasePointer() << "'/>\n";
558 }
559 }
560 }
561 ofile << "</curves>\n";
562 }
563
564 // If we are not a writing process but it is possible that we possess curves.
567 m_parallel_mng->send(ArrayView<Integer>(1, &nb_curve), master_io_rank);
568 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
569 const TimeHistoryValue& th = *(i->second);
570 String name = th.name();
571 UniqueArray<Int32> length(2);
572 length[0] = arcaneCheckArraySize(name.length() + 1);
573 if (th.meshHandle().isNull()) {
574 length[1] = 0;
575 m_parallel_mng->send(length, master_io_rank);
576 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
577 }
578 else {
579 String mesh_name = th.meshHandle().meshName();
580 length[1] = arcaneCheckArraySize(mesh_name.length() + 1);
581 m_parallel_mng->send(length, master_io_rank);
582 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
583 m_parallel_mng->send(ConstArrayView<char>(length[1], static_cast<const char*>(mesh_name.localstr())), master_io_rank);
584 }
585 }
586 }
587}
588
589/*---------------------------------------------------------------------------*/
590/*---------------------------------------------------------------------------*/
591
594{
595 // Only the master process writes.
596 if (m_is_master_io) {
597
598 JSONWriter json_writer(JSONWriter::FormatFlags::None);
599 {
600 JSONWriter::Object o1(json_writer);
601 {
602 JSONWriter::Object o2(json_writer, "arcane-curves");
603 json_writer.write("version", 1);
604 {
605 Integer master_io_rank = m_parallel_mng->masterIORank();
606 json_writer.writeKey("curves");
607 json_writer.beginArray();
608
609 // We first write the names of our curves.
610 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
611 JSONWriter::Object o4(json_writer);
612 const TimeHistoryValue& th = *(i->second);
613 json_writer.write("name", th.name());
614
615 String name("");
616
617 if (!th.meshHandle().isNull()) {
618 json_writer.write("support", th.meshHandle().meshName());
619 name = name + th.meshHandle().meshName() + "_";
620 }
621
622 if (th.isLocal()) {
623 json_writer.write("sub-domain", master_io_rank);
624 name = name + "SD" + String::fromNumber(master_io_rank) + "_";
625 }
626
627 json_writer.write("unique-name", name + th.name());
628 }
629
630 // Then, if other processes can also have curves, we
631 // also write their names.
632 // Even if "m_io_master_write_only" is equal to false, this file is
633 // necessarily written by a single process.
635 for (Integer i = 0; i < m_parallel_mng->commSize(); ++i) {
636 if (i != master_io_rank) {
637 Integer nb_curve = 0;
638 m_parallel_mng->recv(ArrayView<Integer>(1, &nb_curve), i);
639 for (Integer icurve = 0; icurve < nb_curve; ++icurve) {
640 JSONWriter::Object o4(json_writer);
641 UniqueArray<Int32> length(2);
642 m_parallel_mng->recv(length, i);
643
644 UniqueArray<char> buf(length[0]);
645 m_parallel_mng->recv(buf, i);
646 json_writer.write("name", buf.unguardedBasePointer());
647
648 String name("");
649
650 if (length[1] != 0) {
651 UniqueArray<char> buf2(length[1]);
652 m_parallel_mng->recv(buf2, i);
653 json_writer.write("support", buf2.unguardedBasePointer());
654 name = name + buf2.unguardedBasePointer() + "_";
655 }
656
657 name = name + "SD" + String::fromNumber(i) + "_";
658
659 json_writer.write("sub-domain", i);
660 json_writer.write("unique-name", name + buf.unguardedBasePointer());
661 }
662 }
663 }
664 }
665 json_writer.endArray();
666 }
667 }
668 }
669
670 Directory out_dir(m_output_path);
671 std::ofstream ofile(out_dir.file("time_history.json").localstr());
672 ofile << json_writer.getBuffer();
673 ofile.close();
674 }
675
676 // If we are not a writing process but it is possible that we possess curves.
678
679 Integer master_io_rank = m_parallel_mng->masterIORank();
680
682 m_parallel_mng->send(ArrayView<Integer>(1, &nb_curve), master_io_rank);
683 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
684 const TimeHistoryValue& th = *(i->second);
685 String name = th.name();
686 UniqueArray<Int32> length(2);
687 length[0] = arcaneCheckArraySize(name.length() + 1);
688 if (th.meshHandle().isNull()) {
689 length[1] = 0;
690 m_parallel_mng->send(length, master_io_rank);
691 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
692 }
693 else {
694 String mesh_name = th.meshHandle().meshName();
695 length[1] = arcaneCheckArraySize(mesh_name.length() + 1);
696 m_parallel_mng->send(length, master_io_rank);
697 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
698 m_parallel_mng->send(ConstArrayView<char>(length[1], static_cast<const char*>(mesh_name.localstr())), master_io_rank);
699 }
700 }
701 }
702}
703
704/*---------------------------------------------------------------------------*/
705/*---------------------------------------------------------------------------*/
706
707template <class DataType>
710{
711 if (!m_is_active) {
712 return;
713 }
714
715 if (thpi.timeHistoryAddValueArg().isLocal()) {
716 m_need_comm = true;
717 }
718
719 if (!m_is_master_io && (!thpi.timeHistoryAddValueArg().isLocal() || !m_enable_non_io_master_curves || !m_is_master_io_of_sd)) {
720 return;
721 }
722
723 if (thpi.timeHistoryAddValueArg().isLocal() && thpi.timeHistoryAddValueArg().localSubDomainId() != m_parallel_mng->commRank()) {
724 return;
725 }
726
727 String name_to_find = thpi.timeHistoryAddValueArg().name().clone();
728 if (!thpi.meshHandle().isNull()) {
729 // Important in the case where we have two histories with the same name for two different meshes,
730 // or the same name as a "global" history.
731 name_to_find = name_to_find + "_" + thpi.meshHandle().meshName();
732 }
733 if (thpi.timeHistoryAddValueArg().isLocal()) {
734 name_to_find = name_to_find + "_Local";
735 }
736
737 Integer iteration = m_common_variables.globalIteration();
738
739 if (!thpi.timeHistoryAddValueArg().endTime() && iteration != 0)
740 --iteration;
741
742 auto hl = m_history_list.find(name_to_find);
743 TimeHistoryValueT<DataType>* th = nullptr;
744 // Found, we return it.
745 if (hl != m_history_list.end())
746 th = dynamic_cast<TimeHistoryValueT<DataType>*>(hl->second);
747 else {
748 if (!thpi.meshHandle().isNull()) {
749 th = new TimeHistoryValueT<DataType>(thpi, (Integer)m_history_list.size(), values.size(), isShrinkActive());
750 }
751 else {
752 th = new TimeHistoryValueT<DataType>(m_variable_mng, thpi, (Integer)m_history_list.size(), values.size(), isShrinkActive());
753 }
754 m_history_list.insert(HistoryValueType(name_to_find, th));
755 }
756 if (!th)
757 return;
758 if (values.size() != th->subSize()) {
759 ARCANE_FATAL("Bad subsize for curve '{0}' current={1} old={2}",
760 name_to_find, values.size(), th->subSize());
761 }
762 th->addValue(values, iteration);
763}
764
765/*---------------------------------------------------------------------------*/
766/*---------------------------------------------------------------------------*/
767
770{
771 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
772 TimeHistoryValue* v = i->second;
773 delete v;
774 }
775}
776
777/*---------------------------------------------------------------------------*/
778/*---------------------------------------------------------------------------*/
779
781_fromLegacyFormat(IMesh* default_mesh)
782{
783 IVariable* ptr_old_global_time = m_variable_mng->findMeshVariable(default_mesh, "TimeHistoryGlobalTime");
784 IVariable* ptr_old_meta_data = m_variable_mng->findMeshVariable(default_mesh, "TimeHistoryMetaData");
785 if (ptr_old_global_time == nullptr || ptr_old_meta_data == nullptr)
786 ARCANE_FATAL("TimeHistoryGlobalTime or TimeHistoryMetaData is not found.");
787
788 VariableArrayReal old_global_time(ptr_old_global_time);
789 VariableScalarString old_meta_data(ptr_old_meta_data);
790
791 m_th_global_time.resize(old_global_time.size());
792 m_th_global_time.copy(old_global_time);
793 m_th_meta_data.swapValues(old_meta_data);
794
795 old_global_time.resize(0);
796 old_meta_data.reset();
797}
798
799/*---------------------------------------------------------------------------*/
800/*---------------------------------------------------------------------------*/
801
804{
805 m_curve_writers2.erase(writer);
806}
807
808/*---------------------------------------------------------------------------*/
809/*---------------------------------------------------------------------------*/
810
811template void TimeHistoryMngInternal::
813
814template void TimeHistoryMngInternal::
816
817template void TimeHistoryMngInternal::
819
820/*---------------------------------------------------------------------------*/
821/*---------------------------------------------------------------------------*/
822
823} // End namespace Arcane
824
825/*---------------------------------------------------------------------------*/
826/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
constexpr Integer size() const noexcept
Returns the size of the array.
void clear()
Removes the elements from the array.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Class managing a directory.
Definition Directory.h:36
String file(const String &file_name) const override
Returns the full path of the file file_name in the directory.
Definition Directory.cc:120
Interface of the input/output manager.
Definition IIOMng.h:37
virtual IXmlDocumentHolder * parseXmlString(const String &str, const String &name)=0
Reads and parses the XML file contained in the string str.
Mesh manager interface.
Definition IMeshMng.h:41
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Searches for the mesh with name name.
Interface of the property manager.
virtual IObservable * writeObservable()=0
Observable for writing.
virtual String name() const =0
Writer name.
virtual void endWrite()=0
Notify the end of writing.
virtual void beginWrite(const TimeHistoryCurveWriterInfo &infos)=0
Notify the start of writing.
virtual void writeCurve(const TimeHistoryCurveInfo &infos)=0
Write a curve.
Interface of an object transforming history curves.
Interface of a variable.
Definition IVariable.h:40
Iterator intervalThis class manages an iterator pair allowing modification of the elements of the con...
Handle on a mesh.
Definition MeshHandle.h:48
bool isNull() const
Indicates if the handle is null (it does not reference any existing mesh or not).
Definition MeshHandle.h:163
Output stream linked to a String.
T * get() const
Returns the object referenced by the instance.
Definition Ptr.h:122
Reference to an instance.
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
bool null() const
Returns true if the string is null.
Definition String.cc:306
Int64 length() const
Returns the length of the string.
Definition String.cc:340
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.
Information about writing curves.
bool isShrinkActive() const override
Returns a boolean indicating if the history is compressed.
void updateMetaData() override
Method allowing the curve metadata to be updated.
bool m_is_master_io
True if I am the IO manager.
void addNowInGlobalTime() override
Method allowing the current GlobalTime to be added to the GlobalTimes array.
void addValue(const TimeHistoryAddValueArgInternal &thpi, Real value) override
Method allowing a value to be added to a history.
void _dumpSummaryOfCurves()
Method allowing a JSON file to be dumped with the name of each curve output in GNUPLOT format as well...
bool m_is_master_io_of_sd
True if I am the IO manager for my subdomain.
void _removeCurveWriter(const Ref< ITimeHistoryCurveWriter2 > &writer)
Method allowing removal of a writer.
void updateGlobalTimeCurve() override
Method allowing the GlobalTime array to be copied into the global GlobalTime variable.
void resizeArrayAfterRestore() override
Method allowing the value arrays to be resized after a restart.
void addObservers(IPropertyMng *prop_mng) override
Method allowing observers saving the history before a checkpoint to be added.
bool m_is_dump_active
Indicates if dumps are active.
void removeCurveWriter(const String &name) override
Method allowing a writer to be removed.
void readVariables(IMeshMng *mesh_mng, IMesh *default_mesh) override
Method allowing previously written curves to be retrieved during a restart.
void dumpHistory() override
Method allowing all curves to be written using all registered writers.
void _dumpSummaryOfCurvesLegacy()
Method allowing an XML file to be dumped with the name of each curve output in GNUPLOT format.
HistoryList m_history_list
List of histories.
void _addHistoryValue(const TimeHistoryAddValueArgInternal &thpi, ConstArrayView< DataType > values)
Method allowing values to be added to a value history.
VariableArrayReal m_th_global_time
Array of time instants.
bool m_enable_non_io_master_curves
Indicates if curve writing by non-io_master procs is possible.
void _dumpCurvesAllWriters()
Method allowing all curves to be dumped with all writers.
void applyTransformation(ITimeHistoryTransformer *v) override
Applies the transformation v to all curves.
void iterationsAndValues(const TimeHistoryAddValueArgInternal &thpi, UniqueArray< Int32 > &iterations, UniqueArray< Real > &values) override
Method allowing the iterations and values of a history to be outputted.
void dumpCurves(ITimeHistoryCurveWriter2 *writer) override
Method allowing curves to be written using the provided writer.
bool m_io_master_write_only
Indicates if writers must be called by all processes.
void _saveProperties()
Method allowing saving the properties of the metadata.
VariableScalarString m_th_meta_data
History info.
void _fromLegacyFormat(IMesh *default_mesh)
Method allowing conversion from the old format to the new.
void editOutputPath(const Directory &directory) override
Method allowing the curve output directory to be changed.
RealUniqueArray m_global_times
List of global times.
bool m_need_comm
Indicates if at least one curve is non-local (thus requiring communications).
bool m_is_active
Indicates if the service is active.
void addCurveWriter(Ref< ITimeHistoryCurveWriter2 > writer) override
Method allowing a writer to be added for curve output.
void addValue(ConstArrayView< DataType > values, Integer iteration)
Method allowing the addition of values to an iteration.
Base class for a value history.
Integer index() const
History index in the list.
const MeshHandle & meshHandle() const
Method allowing the retrieval of the registered MeshHandle.
const String & name() const
History name.
eDataType dataType() const
History data type.
virtual void applyTransformation(ITraceMng *msg, ITimeHistoryTransformer *v)=0
Method allowing the application of a transformation on the values of the value history.
virtual void fromOldToNewVariables(IVariableMng *vm, IMesh *default_mesh)=0
Method allowing the conversion of variables from old saves to the new format.
Integer localSubDomainId() const
Method allowing the retrieval of the subdomain ID to which this history belongs.
virtual void arrayToWrite(UniqueArray< Int32 > &iterations, UniqueArray< Real > &values, const TimeHistoryCurveWriterInfo &infos) const =0
Method allowing the retrieval of iterations and values from a value history.
bool isLocal() const
Method allowing determination if it is a global history or local to a subdomain.
virtual void dumpValues(ITraceMng *msg, ITimeHistoryCurveWriter2 *writer, const TimeHistoryCurveWriterInfo &infos) const =0
Prints the history values using the writer writer.
1D data vector with value semantics (STL style).
virtual void resize(Integer new_size)
Resizes the array to contain new_size elements.
void reset()
Resets the variable to its default value.
List of nodes of a DOM tree.
Definition XmlNodeList.h:36
Node of a DOM tree.
Definition XmlNode.h:51
XmlNode attr(const String &name, bool throw_exception=false) const
Returns the attribute of name name.
Definition XmlNode.cc:257
XmlNode child(const String &name) const
Child node of this node with name name.
Definition XmlNode.cc:73
XmlNodeList children(const String &name) const
Set of child nodes of this node having the name name.
Definition XmlNode.cc:102
bool null() const
True if the node is null.
Definition XmlNode.h:303
Integer valueAsInteger(bool throw_exception=false) const
Node value converted to integer.
Definition XmlNode.cc:441
VariableRefArrayT< Real > VariableArrayReal
Array variable of real type.
VariableRefScalarT< String > VariableScalarString
Scalar variable of character string type.
@ ReduceMin
Minimum of values.
String getCurrentDateTime()
Current date and time in ISO 8601 format.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Integer arcaneCheckArraySize(unsigned long long size)
Checks that size can be converted into an 'Integer' to serve as the size of an array....
Int32 Integer
Type representing an integer.
eDataType
Data type.
Definition DataTypes.h:41
@ DT_Int32
32-bit integer data type
Definition DataTypes.h:45
@ DT_Int64
64-bit integer data type
Definition DataTypes.h:46
@ DT_Real
Real data type.
Definition DataTypes.h:43
ARCANE_DATATYPE_EXPORT eDataType dataTypeFromName(const char *name, bool &has_error)
Finds the type associated with name.
Definition DataTypes.cc:94
const char * dataTypeName(eDataType type)
Data type name.
Definition DataTypes.cc:72
std::int32_t Int32
Signed integer type of 32 bits.