Arcane  4.2.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ArcaneCurveWriter.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/* ArcaneCurveWriter.cc (C) 2000-2026 */
9/* */
10/* Ecriture des courbes au format Arcane. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArrayView.h"
15#include "arcane/utils/ScopedPtr.h"
16#include "arcane/utils/CheckedConvert.h"
17
18#include "arcane/core/ITimeHistoryCurveWriter2.h"
19#include "arcane/core/BasicService.h"
20#include "arcane/core/FactoryService.h"
21#include "arcane/core/IApplication.h"
22#include "arcane/core/IRessourceMng.h"
23#include "arcane/core/IXmlDocumentHolder.h"
24#include "arcane/core/XmlNode.h"
25
26#include <fstream>
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31namespace Arcane
32{
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
41class ArcaneCurveWriter
42: public BasicService
44{
45 public:
46
47 class Impl : TraceAccessor
48 {
49 public:
50
51 Impl(IApplication* app, ITraceMng* tm, const String& path);
52
53 public:
54
55 String m_file_name;
56 std::ofstream m_stream;
58 XmlNode m_root_element;
59 };
60
61 public:
62
63 ArcaneCurveWriter(const ServiceBuildInfo& sbi)
64 : BasicService(sbi)
65 , m_version(2)
66 {}
68
69 public:
70
71 virtual void build() {}
72 virtual void beginWrite(const TimeHistoryCurveWriterInfo& infos);
73 virtual void endWrite();
74 virtual void writeCurve(const TimeHistoryCurveInfo& infos);
75 virtual String name() const { return "ArcaneCurveWriter"; }
76 virtual void setOutputPath(const String& path) { m_output_path = path; }
77 virtual String outputPath() const { return m_output_path; }
78
79 private:
80
82 Int32 m_version;
83 String m_output_path;
84
85 private:
86
87 void _writeHeader();
88 template <typename T>
89 Int64 _write(ConstArrayView<T> values)
90 {
91 Int64 offset = m_p->m_stream.tellp();
92 m_p->m_stream.write((const char*)values.data(), values.size() * sizeof(T));
93 //info() << "OFFSET offset=" << offset;
94 return offset;
95 }
96};
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101ArcaneCurveWriter::Impl::
102Impl(IApplication* app, ITraceMng* tm, const String& path)
103: TraceAccessor(tm)
104, m_file_name("curves")
105{
106 String full_path = path + "/" + m_file_name + ".acv";
107 info() << "Begin write curves full_path=" << full_path;
108 m_stream.open(full_path.localstr(), std::ios::trunc);
109 if (!m_stream)
110 warning() << "Impossible d'ouvrir le fichier '" << full_path << "' pour écrire les courbes";
111 m_curves_doc = app->ressourceMng()->createXmlDocument();
112 XmlNode doc = m_curves_doc->documentNode();
113 m_root_element = XmlElement(doc, "curves");
114}
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
118
119/*---------------------------------------------------------------------------*/
120/*---------------------------------------------------------------------------*/
121
124{
125 String path = infos.path();
126 // m_output_path surcharge les infos en argument si non vide.
127 // TODO: regarder s'il faut créer le répertoire
128 if (!m_output_path.empty())
129 m_output_path = path;
130
131 info() << A_FUNCNAME << "Début de l'écriture des courbes chemin=" << path;
132 m_p = new Impl(subDomain()->application(), traceMng(), path);
133
134 _writeHeader();
135 Int64 time_offset = _write(infos.times());
136 m_p->m_root_element.setAttrValue("times-offset", String::fromNumber(time_offset));
137 m_p->m_root_element.setAttrValue("times-size", String::fromNumber(infos.times().size()));
138 m_p->m_root_element.setAttrValue("x", "iteration");
139}
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143
144void ArcaneCurveWriter::
145_writeHeader()
146{
147 Byte header[12];
148 // 4 premiers octets pour indiquer qu'il s'agit d'un fichier de courbes
149 // arcane
150 header[0] = 'A';
151 header[1] = 'C';
152 header[2] = 'V';
153 header[3] = (Byte)122;
154 // 4 octets suivant pour la version
155 // Actuellement version 1 ou 2. La version 1 ne supporte que les fichiers
156 // de taille sur 32 bits. La seule différence de la version 2 est que
157 // les offsets et longueurs stoquées à la fin du fichier sont sur
158 // 64bit au lieu de 32.
159 header[4] = (Byte)m_version;
160 header[5] = 0;
161 header[6] = 0;
162 header[7] = 0;
163 // 4 octets suivant pour indiquer l'indianness.
164 Int32 v = 0x01020304;
165 Byte* ptr = (Byte*)(&v);
166 for (Integer i = 0; i < 4; ++i)
167 header[8 + i] = ptr[i];
168 m_p->m_stream.write((const char*)header, 12);
169}
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
173
175endWrite()
176{
177 ByteUniqueArray bytes;
178 m_p->m_curves_doc->save(bytes);
179 if (m_version == 2) {
180 Int64 write_info[2];
181 write_info[0] = _write(bytes.constView());
182 write_info[1] = bytes.largeSize();
183 // Doit toujours être la dernière écriture du fichier
184 _write(Int64ConstArrayView(2, write_info));
185 }
186 else if (m_version == 1) {
187 Int32 write_info[2];
188 write_info[0] = CheckedConvert::toInt32(_write(bytes.constView()));
189 write_info[1] = bytes.size();
190 // Doit toujours être la dernière écriture du fichier
191 _write(Int32ConstArrayView(2, write_info));
192 }
193 else
194 ARCANE_FATAL("Version invalide {0} (valeurs valides sont '1' ou '2')", m_version);
195
196 info(4) << "Fin de l'écriture des courbes";
197
198 // Libère le pointeur
199 m_p = 0;
200}
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
207{
208 //info() << "Écriture du nom de courbe=" << infos.m_name;
209 Int64 values_offset = _write(infos.values());
210
211 Int32ConstArrayView iterations(infos.iterations());
212 Integer nb_val = iterations.size();
213 Int32 range_iterations[2];
214 // Regarde si les itérations sont contigues auquel cas
215 // on ne sauvegarde que la première et la dernière pour
216 // gagner de la place.
217 if (nb_val > 3) {
218 Int32 first_iter = iterations[0];
219 Int32 last_iter = iterations[nb_val - 1];
220 Int32 diff = 1 + last_iter - first_iter;
221 //info() << "NB_VAL=" << nb_val << " first=" << first_iter
222 // << " last=" << last_iter << " diff=" << diff << " IS_CONTIGOUS=" << (diff==nb_val);
223 if (diff == nb_val) {
224 range_iterations[0] = first_iter;
225 range_iterations[1] = last_iter;
226 iterations = Int32ConstArrayView(2, range_iterations);
227 }
228 }
229 Int64 iteration_offset = _write(iterations);
230
231 XmlNode node = m_p->m_root_element.createAndAppendElement("curve");
232
233 String name(infos.name().clone());
234
235 if (infos.subDomain() != NULL_SUB_DOMAIN_ID) {
236 name = "SD" + String::fromNumber(infos.subDomain()) + "_" + name;
237 }
238 if (infos.hasSupport()) {
239 name = infos.support() + "_" + name;
240 }
241
242 node.setAttrValue("name", name);
243 node.setAttrValue("iterations-offset", String::fromNumber(iteration_offset));
244 node.setAttrValue("iterations-size", String::fromNumber(iterations.size()));
245 node.setAttrValue("values-offset", String::fromNumber(values_offset));
246 node.setAttrValue("values-size", String::fromNumber(infos.values().size()));
247 node.setAttrValue("sub-size", String::fromNumber(infos.subSize()));
248 node.setAttrValue("base-name", infos.name());
249 if (infos.hasSupport()) {
250 node.setAttrValue("support", infos.support());
251 }
252 if (infos.subDomain() != NULL_SUB_DOMAIN_ID) {
253 node.setAttrValue("sub-domain", String::fromNumber(infos.subDomain()));
254 }
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
263
264/*---------------------------------------------------------------------------*/
265/*---------------------------------------------------------------------------*/
266
267} // End namespace Arcane
268
269/*---------------------------------------------------------------------------*/
270/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Ecriture des courbes au format spécifique Arcane.
virtual void setOutputPath(const String &path)
Répertoire de base où seront écrites les courbes.
virtual String name() const
Nom de l'écrivain.
virtual String outputPath() const
Répertoire de base où seront écrites les courbes.
virtual void endWrite()
Notifie la fin de l'écriture.
virtual void build()
Construction de niveau build du service.
virtual void beginWrite(const TimeHistoryCurveWriterInfo &infos)
Notifie un début d'écriture.
virtual void writeCurve(const TimeHistoryCurveInfo &infos)
Ecrit une courbe.
Vue constante d'un tableau de type T.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface de l'application.
Interface d'un écrivain d'une courbe.
Interface du gestionnaire de traces.
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
Structure contenant les informations pour créer un service.
Chaîne de caractères unicode.
String clone() const
Clone cette chaîne.
Definition String.cc:413
Informations pour l'écriture d'une courbe.
Int32ConstArrayView iterations() const
Liste des itérations.
const String & name() const
Nom de la courbe.
RealConstArrayView values() const
Liste des valeurs de la courbe.
Integer subSize() const
Nombre de valeur par temps.
Informations sur l'écriture des courbes.
String path() const
Chemin ou écrire les données (sauf si surchargé spécifiquement par le service via ITimeHistoryCurveWr...
RealConstArrayView times() const
Liste des temps.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
ITraceMng * traceMng() const
Gestionnaire de trace.
Noeud d'un arbre DOM.
Definition XmlNode.h:51
void setAttrValue(const String &name, const String &value)
Positionne l'attribut name à la valeur value.
Definition XmlNode.cc:239
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:480
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:478
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:333
unsigned char Byte
Type d'un octet.
Definition BaseTypes.h:42
std::int32_t Int32
Type entier signé sur 32 bits.