Arcane  v3.16.0.0
Documentation développeur
Tout Classes Espaces de nommage Fichiers Fonctions Variables Définitions de type Énumérations Valeurs énumérées Amis Macros Groupes Pages Concepts
TimeHistoryMngInternal.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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-2024 */
9/* */
10/* Classe interne gérant un historique de valeurs. */
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->localProcId() << "'";
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 else {
154 if (m_is_master_io) {
155 TimeHistoryCurveWriterInfo infos(m_output_path, m_global_times.constView());
156 writer->beginWrite(infos);
157 // Nos courbes
158 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
159 const TimeHistoryValue& th = *(i->second);
160 th.dumpValues(m_trace_mng, writer, infos);
161 }
162
163 // Les courbes reçues.
165 Integer master_io_rank = m_parallel_mng->masterIORank();
166 UniqueArray<Int32> length(5);
167
168 for (Integer i = 0; i < m_parallel_mng->commSize(); ++i) {
169 if (i != master_io_rank) {
170 Integer nb_curve = 0;
171 m_parallel_mng->recv(ArrayView<Integer>(1, &nb_curve), i);
172 for (Integer icurve = 0; icurve < nb_curve; ++icurve) {
173 m_parallel_mng->recv(length, i);
174
175 UniqueArray<char> buf(length[0]);
176 UniqueArray<Int32> iterations_to_write(length[1]);
177 UniqueArray<Real> values_to_write(length[2]);
178
179 m_parallel_mng->recv(buf, i);
180 m_parallel_mng->recv(iterations_to_write, i);
181 m_parallel_mng->recv(values_to_write, i);
182
183 String name = String(buf.unguardedBasePointer());
184
185 if (length[4] != 0) {
186 UniqueArray<char> buf2(length[4]);
187 m_parallel_mng->recv(buf2, i);
188 String name_mesh = String(buf2.unguardedBasePointer());
189
190 TimeHistoryCurveInfo curve_info(name, name_mesh, iterations_to_write, values_to_write, length[3], i);
191 writer->writeCurve(curve_info);
192 }
193 else {
194 TimeHistoryCurveInfo curve_info(name, iterations_to_write, values_to_write, length[3], i);
195 writer->writeCurve(curve_info);
196 }
197 }
198 }
199 }
200 }
201
202 writer->endWrite();
203 }
205 TimeHistoryCurveWriterInfo infos(m_output_path, m_global_times.constView());
206 Integer master_io_rank = m_parallel_mng->masterIORank();
208 UniqueArray<Int32> length(5);
209 m_parallel_mng->send(ArrayView<Integer>(1, &nb_curve), master_io_rank);
210 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
211 const TimeHistoryValue& th = *(i->second);
212 String name = th.name();
213 UniqueArray<Int32> iterations_to_write;
214 UniqueArray<Real> values_to_write;
215 th.arrayToWrite(iterations_to_write, values_to_write, infos);
216
217 length[0] = arcaneCheckArraySize(name.length() + 1);
218 length[1] = iterations_to_write.size();
219 length[2] = values_to_write.size();
220 length[3] = th.subSize();
221 if (!th.meshHandle().isNull()) {
222 length[4] = arcaneCheckArraySize(th.meshHandle().meshName().length() + 1);
223 }
224 else {
225 length[4] = 0;
226 }
227
228 m_parallel_mng->send(length, master_io_rank);
229 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
230 m_parallel_mng->send(iterations_to_write, master_io_rank);
231 m_parallel_mng->send(values_to_write, master_io_rank);
232 if (!th.meshHandle().isNull()) {
233 m_parallel_mng->send(ConstArrayView<char>(length[4], static_cast<const char*>(th.meshHandle().meshName().localstr())), master_io_rank);
234 }
235 }
236 }
237 }
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
245{
247 return;
248 if (!m_is_dump_active)
249 return;
250
254
255 m_trace_mng->info() << "Fin sortie historique: " << platform::getCurrentDateTime();
256}
257
258/*---------------------------------------------------------------------------*/
259/*---------------------------------------------------------------------------*/
260
263{
265 return;
266 for (IterT<HistoryList> i(m_history_list); i(); ++i) {
267 TimeHistoryValue& th = *(i->second);
268 th.applyTransformation(m_trace_mng, v);
269 }
270}
271
272/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
274
276readVariables(IMeshMng* mesh_mng, IMesh* default_mesh)
277{
278 bool need_update = false;
279
280 auto p = m_properties;
281
282 Int32 version = 0;
283 if (!p->get("version", version)) {
284 version = 1;
285 m_trace_mng->info() << "The checkpoint contains legacy format of TimeHistory variables, updating...";
286 _fromLegacyFormat(default_mesh);
287 need_update = true;
288 }
289 else if (version == 2) {
290 m_trace_mng->info() << "TimeHistory Variables version 2";
291 }
292 else {
293 ARCANE_FATAL("Unknown TimeHistory Variables format -- Found version: {0}", version);
294 }
295
296 m_trace_mng->info(4) << "readVariables resizes m_global_time to " << m_th_global_time.size();
297 m_global_times.resize(m_th_global_time.size());
299
300 m_trace_mng->info() << "Reading the values history";
301
302 IIOMng* io_mng = m_parallel_mng->ioMng();
304 if (!doc.get()) {
305 m_trace_mng->error() << " METADATA len=" << m_th_meta_data().length()
306 << " str='" << m_th_meta_data() << "'";
307 ARCANE_FATAL("The meta-data of TimeHistoryMng2 are invalid.");
308 }
309 XmlNode root_node = doc->documentNode();
310 XmlNode curves_node = root_node.child(String("curves"));
311 XmlNodeList curves = curves_node.children(String("curve"));
312
313 // v1
314 String ustr_name("name");
315 String ustr_index("index");
316 String ustr_sub_size("sub-size");
317 String ustr_data_type("data-type");
318
319 // v2
320 String ustr_support("support");
321 String ustr_sub_domain("sub-domain");
322
323 for (XmlNode curve : curves) {
324 String name = curve.attrValue(ustr_name);
325 Integer index = curve.attr(ustr_index).valueAsInteger();
326 Integer sub_size = curve.attr(ustr_sub_size).valueAsInteger();
327 String data_type_str = curve.attrValue(ustr_data_type);
328 eDataType dt = dataTypeFromName(data_type_str.localstr());
329 String support_str = curve.attrValue(ustr_support, false);
330
331 XmlNode sub_domain_node = curve.attr(ustr_sub_domain);
332 Integer sub_domain = NULL_SUB_DOMAIN_ID;
333 if (!sub_domain_node.null()) {
334 sub_domain = sub_domain_node.valueAsInteger();
335 }
336
337 if (sub_domain != NULL_SUB_DOMAIN_ID && m_parallel_mng->commRank() != sub_domain) {
338 continue;
339 }
340
341 if (name.null())
342 ARCANE_FATAL("null name for curve");
343 if (index < 0)
344 ARCANE_FATAL("Invalid index '{0}' for curve", index);
345
346 TimeHistoryValue* val = nullptr;
347 if (support_str.null()) {
348 TimeHistoryAddValueArgInternal thpi(name, true, sub_domain);
349 switch (dt) {
350 case DT_Real:
351 val = new TimeHistoryValueT<Real>(m_variable_mng, thpi, index, sub_size, isShrinkActive());
352 break;
353 case DT_Int32:
354 val = new TimeHistoryValueT<Int32>(m_variable_mng, thpi, index, sub_size, isShrinkActive());
355 break;
356 case DT_Int64:
357 val = new TimeHistoryValueT<Int64>(m_variable_mng, thpi, index, sub_size, isShrinkActive());
358 break;
359 default:
360 ARCANE_FATAL("Unsupported type");
361 }
362 if (need_update) {
363 val->fromOldToNewVariables(m_variable_mng, default_mesh);
364 }
365 }
366 else {
367 MeshHandle mh = mesh_mng->findMeshHandle(support_str);
368 TimeHistoryAddValueArgInternal thpi(TimeHistoryAddValueArg(name, true, sub_domain), mh);
369 switch (dt) {
370 case DT_Real:
371 val = new TimeHistoryValueT<Real>(thpi, index, sub_size, isShrinkActive());
372 break;
373 case DT_Int32:
374 val = new TimeHistoryValueT<Int32>(thpi, index, sub_size, isShrinkActive());
375 break;
376 case DT_Int64:
377 val = new TimeHistoryValueT<Int64>(thpi, index, sub_size, isShrinkActive());
378 break;
379 default:
380 ARCANE_FATAL("Unsupported type");
381 }
382 // Important dans le cas où on a deux historiques de même nom pour deux maillages différents,
383 // ou le même nom qu'un historique "globale".
384 name = name + "_" + mh.meshName();
385 }
386 if (sub_domain != NULL_SUB_DOMAIN_ID) {
387 name = name + "_Local";
388 }
389 m_history_list.insert(HistoryValueType(name, val));
390 }
391}
392
393/*---------------------------------------------------------------------------*/
394/*---------------------------------------------------------------------------*/
395
398{
399 Integer current_iteration = m_common_variables.globalIteration();
400 {
401 // Vérifie qu'on n'a pas plus d'éléments que d'itérations
402 // dans 'm_th_global_time'. Normalement cela ne peut arriver
403 // que lors d'un retour-arrière si les variables ont été sauvegardées
404 // au cours du pas de temps.
405 // TODO: ce test ne fonctionne pas si isShrinkActive() est vrai.
406 Integer n = m_th_global_time.size();
407 if (n > current_iteration) {
408 n = current_iteration;
409 m_th_global_time.resize(n);
410 m_trace_mng->info() << "TimeHistoryRestore: truncating TimeHistoryGlobalTime array to size n=" << n << "\n";
411 }
412 }
413 m_global_times.resize(m_th_global_time.size());
415
416 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
417 i->second->removeAfterIteration(current_iteration);
418 }
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
425editOutputPath(const Directory& directory)
426{
427 m_directory = directory;
428 if (m_output_path.empty()) {
429 m_output_path = m_directory.path();
430 if (m_directory.createDirectory()) {
431 m_trace_mng->warning() << "Can't create the output directory '" << m_output_path << "'";
432 }
433 }
434}
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
438
441{
442 if (!m_is_master_io && (!thpi.timeHistoryAddValueArg().isLocal() || !m_enable_non_io_master_curves)) {
443 return;
444 }
445
446 if (thpi.timeHistoryAddValueArg().isLocal() && thpi.timeHistoryAddValueArg().localProcId() != m_parallel_mng->commRank()) {
447 return;
448 }
449
450 if (!m_is_active) {
451 return;
452 }
453
454 String name_to_find = thpi.timeHistoryAddValueArg().name().clone();
455 if (!thpi.meshHandle().isNull()) {
456 // Important dans le cas où on a deux historiques de même nom pour deux maillages différents,
457 // ou le même nom qu'un historique "globale".
458 name_to_find = name_to_find + "_" + thpi.meshHandle().meshName();
459 }
460 if (thpi.timeHistoryAddValueArg().isLocal()) {
461 name_to_find = name_to_find + "_Local";
462 }
463
464 auto hl = m_history_list.find(name_to_find);
465
466 if (hl != m_history_list.end()) {
467 TimeHistoryCurveWriterInfo infos(m_output_path, m_global_times.constView());
468 hl->second->arrayToWrite(iterations, values, infos);
469 }
470 else {
471 iterations.clear();
472 values.clear();
473 }
474}
475
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
478
481{
482 m_trace_mng->debug() << "Writing of the history of values path=" << m_output_path;
483
485 m_trace_mng->info() << "Begin output history: " << platform::getCurrentDateTime();
486
487 // Ecriture via version 2 des curve writers
488 for (auto& cw_ref : m_curve_writers2) {
489 ITimeHistoryCurveWriter2* writer = cw_ref.get();
490 m_trace_mng->debug() << "Writing curves with '" << writer->name()
491 << "' date=" << platform::getCurrentDateTime();
492 dumpCurves(writer);
493 }
494 }
495}
496
497/*---------------------------------------------------------------------------*/
498/*---------------------------------------------------------------------------*/
499
502{
503 // Seul le processus master écrit.
504 Integer master_io_rank = m_parallel_mng->masterIORank();
505 if (m_is_master_io) {
506 std::ofstream ofile(m_directory.file("time_history.xml").localstr());
507 ofile << "<?xml version='1.0' ?>\n";
508 ofile << "<curves>\n";
509
510 // On écrit d'abord le nom de nos courbes.
511 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
512 const TimeHistoryValue& th = *(i->second);
513 ofile << "<curve name='";
514 if (!th.meshHandle().isNull()) {
515 ofile << th.meshHandle().meshName() << "_";
516 }
517 if (th.isLocal()) {
518 ofile << "SD" << master_io_rank << "_";
519 }
520 ofile << th.name() << "'/>\n";
521 }
522 // Puis, si les autres processus peuvent aussi avoir des courbes, on
523 // écrit aussi leurs noms.
525 for (Integer i = 0; i < m_parallel_mng->commSize(); ++i)
526 if (i != master_io_rank) {
527 Integer nb_curve = 0;
528 m_parallel_mng->recv(ArrayView<Integer>(1, &nb_curve), i);
529 for (Integer icurve = 0; icurve < nb_curve; ++icurve) {
530 UniqueArray<Int32> length(2);
531 m_parallel_mng->recv(length, i);
532
533 UniqueArray<char> buf(length[0]);
534 m_parallel_mng->recv(buf, i);
535 ofile << "<curve name='";
536
537 if (length[1] != 0) {
538 UniqueArray<char> buf2(length[1]);
539 m_parallel_mng->recv(buf2, i);
540 ofile << buf2.unguardedBasePointer() << "_";
541 }
542 ofile << "SD" << i << "_";
543 ofile << buf.unguardedBasePointer() << "'/>\n";
544 }
545 }
546 }
547 ofile << "</curves>\n";
548 }
549
550 // Si l'on n'est pas un processus écrivain mais qu'il est possible que l'on possède des courbes.
553 m_parallel_mng->send(ArrayView<Integer>(1, &nb_curve), master_io_rank);
554 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
555 const TimeHistoryValue& th = *(i->second);
556 String name = th.name();
557 UniqueArray<Int32> length(2);
558 length[0] = arcaneCheckArraySize(name.length() + 1);
559 if (th.meshHandle().isNull()) {
560 length[1] = 0;
561 m_parallel_mng->send(length, master_io_rank);
562 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
563 }
564 else {
565 String mesh_name = th.meshHandle().meshName();
566 length[1] = arcaneCheckArraySize(mesh_name.length() + 1);
567 m_parallel_mng->send(length, master_io_rank);
568 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
569 m_parallel_mng->send(ConstArrayView<char>(length[1], static_cast<const char*>(mesh_name.localstr())), master_io_rank);
570 }
571 }
572 }
573}
574
575/*---------------------------------------------------------------------------*/
576/*---------------------------------------------------------------------------*/
577
580{
581 // Seul le processus master écrit.
582 if (m_is_master_io) {
583
584 JSONWriter json_writer(JSONWriter::FormatFlags::None);
585 {
586 JSONWriter::Object o1(json_writer);
587 {
588 JSONWriter::Object o2(json_writer, "arcane-curves");
589 json_writer.write("version", 1);
590 {
591 Integer master_io_rank = m_parallel_mng->masterIORank();
592 json_writer.writeKey("curves");
593 json_writer.beginArray();
594
595 // On écrit d'abord le nom de nos courbes.
596 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
597 JSONWriter::Object o4(json_writer);
598 const TimeHistoryValue& th = *(i->second);
599 json_writer.write("name", th.name());
600
601 String name("");
602
603 if (!th.meshHandle().isNull()) {
604 json_writer.write("support", th.meshHandle().meshName());
605 name = name + th.meshHandle().meshName() + "_";
606 }
607
608 if (th.isLocal()) {
609 json_writer.write("sub-domain", master_io_rank);
610 name = name + "SD" + String::fromNumber(master_io_rank) + "_";
611 }
612
613 json_writer.write("unique-name", name + th.name());
614 }
615
616 // Puis, si les autres processus peuvent aussi avoir des courbes, on
617 // écrit aussi leurs noms.
619 for (Integer i = 0; i < m_parallel_mng->commSize(); ++i) {
620 if (i != master_io_rank) {
621 Integer nb_curve = 0;
622 m_parallel_mng->recv(ArrayView<Integer>(1, &nb_curve), i);
623 for (Integer icurve = 0; icurve < nb_curve; ++icurve) {
624 JSONWriter::Object o4(json_writer);
625 UniqueArray<Int32> length(2);
626 m_parallel_mng->recv(length, i);
627
628 UniqueArray<char> buf(length[0]);
629 m_parallel_mng->recv(buf, i);
630 json_writer.write("name", buf.unguardedBasePointer());
631
632 String name("");
633
634 if (length[1] != 0) {
635 UniqueArray<char> buf2(length[1]);
636 m_parallel_mng->recv(buf2, i);
637 json_writer.write("support", buf2.unguardedBasePointer());
638 name = name + buf2.unguardedBasePointer() + "_";
639 }
640
641 name = name + "SD" + String::fromNumber(i) + "_";
642
643 json_writer.write("sub-domain", i);
644 json_writer.write("unique-name", name + buf.unguardedBasePointer());
645 }
646 }
647 }
648 }
649 json_writer.endArray();
650 }
651 }
652 }
653
654 Directory out_dir(m_output_path);
655 std::ofstream ofile(out_dir.file("time_history.json").localstr());
656 ofile << json_writer.getBuffer();
657 ofile.close();
658 }
659
660 // Si l'on n'est pas un processus écrivain mais qu'il est possible que l'on possède des courbes.
662
663 Integer master_io_rank = m_parallel_mng->masterIORank();
664
666 m_parallel_mng->send(ArrayView<Integer>(1, &nb_curve), master_io_rank);
667 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
668 const TimeHistoryValue& th = *(i->second);
669 String name = th.name();
670 UniqueArray<Int32> length(2);
671 length[0] = arcaneCheckArraySize(name.length() + 1);
672 if (th.meshHandle().isNull()) {
673 length[1] = 0;
674 m_parallel_mng->send(length, master_io_rank);
675 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
676 }
677 else {
678 String mesh_name = th.meshHandle().meshName();
679 length[1] = arcaneCheckArraySize(mesh_name.length() + 1);
680 m_parallel_mng->send(length, master_io_rank);
681 m_parallel_mng->send(ConstArrayView<char>(length[0], static_cast<const char*>(name.localstr())), master_io_rank);
682 m_parallel_mng->send(ConstArrayView<char>(length[1], static_cast<const char*>(mesh_name.localstr())), master_io_rank);
683 }
684 }
685 }
686}
687
688/*---------------------------------------------------------------------------*/
689/*---------------------------------------------------------------------------*/
690
691template <class DataType>
694{
695 if (!m_is_active) {
696 return;
697 }
698
699 if (!m_is_master_io && (!thpi.timeHistoryAddValueArg().isLocal() || !m_enable_non_io_master_curves)) {
700 return;
701 }
702
703 if (thpi.timeHistoryAddValueArg().isLocal() && thpi.timeHistoryAddValueArg().localProcId() != m_parallel_mng->commRank()) {
704 return;
705 }
706
707 String name_to_find = thpi.timeHistoryAddValueArg().name().clone();
708 if (!thpi.meshHandle().isNull()) {
709 // Important dans le cas où on a deux historiques de même nom pour deux maillages différents,
710 // ou le même nom qu'un historique "globale".
711 name_to_find = name_to_find + "_" + thpi.meshHandle().meshName();
712 }
713 if (thpi.timeHistoryAddValueArg().isLocal()) {
714 name_to_find = name_to_find + "_Local";
715 }
716
717 Integer iteration = m_common_variables.globalIteration();
718
719 if (!thpi.timeHistoryAddValueArg().endTime() && iteration != 0)
720 --iteration;
721
722 auto hl = m_history_list.find(name_to_find);
723 TimeHistoryValueT<DataType>* th = nullptr;
724 // Trouvé, on le retourne.
725 if (hl != m_history_list.end())
726 th = dynamic_cast<TimeHistoryValueT<DataType>*>(hl->second);
727 else {
728 if (!thpi.meshHandle().isNull()) {
729 th = new TimeHistoryValueT<DataType>(thpi, (Integer)m_history_list.size(), values.size(), isShrinkActive());
730 }
731 else {
732 th = new TimeHistoryValueT<DataType>(m_variable_mng, thpi, (Integer)m_history_list.size(), values.size(), isShrinkActive());
733 }
734 m_history_list.insert(HistoryValueType(name_to_find, th));
735 }
736 if (!th)
737 return;
738 if (values.size() != th->subSize()) {
739 ARCANE_FATAL("Bad subsize for curve '{0}' current={1} old={2}",
740 name_to_find, values.size(), th->subSize());
741 }
742 th->addValue(values, iteration);
743}
744
745/*---------------------------------------------------------------------------*/
746/*---------------------------------------------------------------------------*/
747
750{
751 for (ConstIterT<HistoryList> i(m_history_list); i(); ++i) {
752 TimeHistoryValue* v = i->second;
753 delete v;
754 }
755}
756
757/*---------------------------------------------------------------------------*/
758/*---------------------------------------------------------------------------*/
759
761_fromLegacyFormat(IMesh* default_mesh)
762{
763 IVariable* ptr_old_global_time = m_variable_mng->findMeshVariable(default_mesh, "TimeHistoryGlobalTime");
764 IVariable* ptr_old_meta_data = m_variable_mng->findMeshVariable(default_mesh, "TimeHistoryMetaData");
765 if (ptr_old_global_time == nullptr || ptr_old_meta_data == nullptr)
766 ARCANE_FATAL("TimeHistoryGlobalTime or TimeHistoryMetaData is not found.");
767
768 VariableArrayReal old_global_time(ptr_old_global_time);
769 VariableScalarString old_meta_data(ptr_old_meta_data);
770
771 m_th_global_time.resize(old_global_time.size());
772 m_th_global_time.copy(old_global_time);
773 m_th_meta_data.swapValues(old_meta_data);
774
775 old_global_time.resize(0);
776 old_meta_data.reset();
777}
778
779/*---------------------------------------------------------------------------*/
780/*---------------------------------------------------------------------------*/
781
784{
785 m_curve_writers2.erase(writer);
786}
787
788/*---------------------------------------------------------------------------*/
789/*---------------------------------------------------------------------------*/
790
791template void TimeHistoryMngInternal::
793
794template void TimeHistoryMngInternal::
796
797template void TimeHistoryMngInternal::
799
800/*---------------------------------------------------------------------------*/
801/*---------------------------------------------------------------------------*/
802
803} // End namespace Arcane
804
805/*---------------------------------------------------------------------------*/
806/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
constexpr Integer size() const noexcept
Retourne la taille du tableau.
void clear()
Supprime les éléments du tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
interval d'itérateurs constant
Classe gérant un répertoire.
Definition Directory.h:33
virtual String file(const String &file_name) const
Retourne le chemin complet du fichier file_name dans le répertoire.
Definition Directory.cc:138
Interface du gestionnaire des entrées sorties.
Definition IIOMng.h:42
virtual IXmlDocumentHolder * parseXmlString(const String &str, const String &name)=0
Lit et analyse le fichier XML contenu dans la chaîne str.
Interface du gestionnaire des maillages.
Definition IMeshMng.h:40
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Recherche le maillage de nom name.
Interface du gestionnaire des propriétés.
virtual IObservable * writeObservable()=0
Observable pour l'écriture.
Interface d'un écrivain d'une courbe.
virtual String name() const =0
Nom de l'écrivain.
virtual void endWrite()=0
Notifie la fin de l'écriture.
virtual void beginWrite(const TimeHistoryCurveWriterInfo &infos)=0
Notifie un début d'écriture.
virtual void writeCurve(const TimeHistoryCurveInfo &infos)=0
Ecrit une courbe.
Interface d'un objet transformant les courbes d'historiques.
Interface d'une variable.
Definition IVariable.h:56
interval d'itérateursCette classe gère un couple d'itérateurs autorisant la modification des éléments...
Ecrivain au format JSON.
Definition JSONWriter.h:33
Handle sur un maillage.
Definition MeshHandle.h:47
bool isNull() const
Indique si le handle est nul (il ne référence aucun maillage existant ou non)
Definition MeshHandle.h:162
Flot de sortie lié à une String.
T * get() const
Retourne l'objet référé par l'instance.
Definition Ptr.h:121
Référence à une instance.
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
Int64 length() const
Retourne la longueur de la chaîne.
Definition String.cc:338
String clone() const
Clone cette chaîne.
Definition String.cc:412
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:227
Classe étendant les arguments lors d'un ajout de valeur dans un historique de valeur.
Informations pour l'écriture d'une courbe.
Informations sur l'écriture des courbes.
bool isShrinkActive() const override
Retourne un booléen indiquant si l'historique est compressé
void updateMetaData() override
Méthode permettant de mettre à jour les méta-données des courbes.
bool m_is_master_io
True si je suis le gestionnaire actif.
void addNowInGlobalTime() override
Méthode permettant d'ajouter le GlobalTime actuel au tableau des GlobalTimes.
void addValue(const TimeHistoryAddValueArgInternal &thpi, Real value) override
Méthode permettant d'ajouter une valeur à un historique.
void _dumpSummaryOfCurves()
Méthode permettant de sortir un fichier JSON avec le nom de chaque courbe sortie en format GNUPLOT ai...
void _removeCurveWriter(const Ref< ITimeHistoryCurveWriter2 > &writer)
Méthode permettant de retirer un écrivain.
void updateGlobalTimeCurve() override
Méthode permettant de copier le tableau de GlobalTime dans la variable globale GlobalTime.
void resizeArrayAfterRestore() override
Méthode permettant de redimensionner les tableaux de valeurs après une reprise.
void addObservers(IPropertyMng *prop_mng) override
Méthode permettant de rajouter les observers sauvegardant l'historique avant une protection.
bool m_is_dump_active
Indique si les dump sont actifs.
void removeCurveWriter(const String &name) override
Méthode permettant de retirer un écrivain.
void readVariables(IMeshMng *mesh_mng, IMesh *default_mesh) override
Méthode permettant de récupérer les courbes précédemment écrites lors d'une reprise.
void dumpHistory() override
Méthode permettant d'écrire toutes les courbes à l'aide de tous les writers enregistrés.
void _dumpSummaryOfCurvesLegacy()
Méthode permettant de sortir un fichier XML avec le nom de chaque courbe sortie en format GNUPLOT.
HistoryList m_history_list
Liste des historiques.
void _addHistoryValue(const TimeHistoryAddValueArgInternal &thpi, ConstArrayView< DataType > values)
Méthode permettant d'ajouter des valeurs à un historique de valeurs.
VariableArrayReal m_th_global_time
Tableau des instants de temps.
bool m_enable_non_io_master_curves
Indique si l'ecriture de courbes par des procs non io_master est possible.
void _dumpCurvesAllWriters()
Méthode permettant de sortir toutes les courbes avec tous les writers.
void applyTransformation(ITimeHistoryTransformer *v) override
Applique la transformation v à l'ensemble des courbes.
void iterationsAndValues(const TimeHistoryAddValueArgInternal &thpi, UniqueArray< Int32 > &iterations, UniqueArray< Real > &values) override
Méthode permettant de sortir les itérations et les valeurs d'un historique.
void dumpCurves(ITimeHistoryCurveWriter2 *writer) override
Méthode permettant d"écrire les courbes à l'aide du writer fourni.
bool m_io_master_write_only
Indique si les writers doivent être appelé par tous les processus.
void _saveProperties()
Méthode permettant de sauver les propriétés des metadatas.
VariableScalarString m_th_meta_data
Infos des historiques.
void _fromLegacyFormat(IMesh *default_mesh)
Méthode permettant de convertir l'ancien format vers le nouveau.
void editOutputPath(const Directory &directory) override
Méthode permettant de changer le répertoire de sortie des courbes.
RealUniqueArray m_global_times
Liste des temps globaux.
bool m_is_active
Indique si le service est actif.
void addCurveWriter(Ref< ITimeHistoryCurveWriter2 > writer) override
Méthode permettant d'ajouter un écrivain pour la sortie des courbes.
Historique de valeurs du type T.
void addValue(ConstArrayView< DataType > values, Integer iteration)
Méthode permettant d'ajouter des valeurs à une itération.
Classe de base d'un historique de valeurs.
Integer index() const
Index de l'historique dans la liste.
const MeshHandle & meshHandle() const
Méthode permettant de récupérer le MeshHandle enregistré.
const String & name() const
Nom de l'historique.
eDataType dataType() const
Type de données de l'historique.
virtual void applyTransformation(ITraceMng *msg, ITimeHistoryTransformer *v)=0
Méthode permettant d'appliquer une transformation sur les valeurs de l'historique de valeur.
virtual void fromOldToNewVariables(IVariableMng *vm, IMesh *default_mesh)=0
Méthode permettant de convertir les variables d'anciennes sauvegardes vers le nouveau format.
Integer localProcId() const
Méthode permettant de récupérer l'id du sous-domaine à qui appartient cet historique.
virtual void arrayToWrite(UniqueArray< Int32 > &iterations, UniqueArray< Real > &values, const TimeHistoryCurveWriterInfo &infos) const =0
Méthode permettant de récupérer les itérations et les valeurs d'un historique de valeur.
bool isLocal() const
Méthode permettant de savoir si c'est un historique global ou local à un sous-domaine.
virtual void dumpValues(ITraceMng *msg, ITimeHistoryCurveWriter2 *writer, const TimeHistoryCurveWriterInfo &infos) const =0
Imprime les valeurs de l'historique avec l'écrivain writer.
Vecteur 1D de données avec sémantique par valeur (style STL).
virtual void resize(Integer new_size)
Redimensionne le tableau pour contenir new_size éléments.
void reset()
Réinitialise la variable avec sa valeur par défaut.
Liste de noeuds d'un arbre DOM.
Definition XmlNodeList.h:33
Noeud d'un arbre DOM.
Definition XmlNode.h:51
XmlNode attr(const String &name, bool throw_exception=false) const
Retourne l'attribut de nom name.
Definition XmlNode.cc:248
XmlNode child(const String &name) const
Noeud fils de celui-ci de nom name.
Definition XmlNode.cc:64
XmlNodeList children(const String &name) const
Ensemble des noeuds fils de ce noeud ayant pour nom name.
Definition XmlNode.cc:93
bool null() const
Vrai si le noeud est nul.
Definition XmlNode.h:294
Integer valueAsInteger(bool throw_exception=false) const
Valeur du noeud convertie en entier.
Definition XmlNode.cc:432
VariableRefArrayT< Real > VariableArrayReal
Variable tableau de type réels.
VariableRefScalarT< String > VariableScalarString
Variable scalaire de type chaine de caractère.
ARCCORE_BASE_EXPORT String getCurrentDateTime()
Date et l'heure courante sous la forme ISO 8601.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
Int32 Integer
Type représentant un entier.
eDataType
Type d'une donnée.
Definition DataTypes.h:39
@ DT_Int32
Donnée de type entier 32 bits.
Definition DataTypes.h:43
@ DT_Int64
Donnée de type entier 64 bits.
Definition DataTypes.h:44
@ DT_Real
Donnée de type réel.
Definition DataTypes.h:41
ARCANE_DATATYPE_EXPORT eDataType dataTypeFromName(const char *name, bool &has_error)
Trouve le type associé à name.
Definition DataTypes.cc:92
const char * dataTypeName(eDataType type)
Nom du type de donnée.
Definition DataTypes.cc:70
std::int32_t Int32
Type entier signé sur 32 bits.