Arcane  v3.14.10.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-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/* ArcaneCurveWriter.cc (C) 2000-2024 */
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/ITimeHistoryCurveWriter2.h"
19#include "arcane/BasicService.h"
20#include "arcane/FactoryService.h"
21#include "arcane/IApplication.h"
22#include "arcane/IRessourceMng.h"
23#include "arcane/IXmlDocumentHolder.h"
24#include "arcane/XmlNode.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
40: public BasicService
42{
43 public:
44
46 {
47 public:
48
49 Impl(IApplication* app, ITraceMng* tm, const String& path);
50
51 public:
52
53 String m_file_name;
54 std::ofstream m_stream;
56 XmlNode m_root_element;
57 };
58
59 public:
60
63 , m_version(2)
64 {}
66
67 public:
68
69 virtual void build() {}
70 virtual void beginWrite(const TimeHistoryCurveWriterInfo& infos);
71 virtual void endWrite();
72 virtual void writeCurve(const TimeHistoryCurveInfo& infos);
73 virtual String name() const { return "ArcaneCurveWriter"; }
74 virtual void setOutputPath(const String& path) { m_output_path = path; }
75 virtual String outputPath() const { return m_output_path; }
76
77 private:
78
80 Int32 m_version;
81 String m_output_path;
82
83 private:
84
85 void _writeHeader();
86 template <typename T>
87 Int64 _write(ConstArrayView<T> values)
88 {
89 Int64 offset = m_p->m_stream.tellp();
90 m_p->m_stream.write((const char*)values.data(), values.size() * sizeof(T));
91 //info() << "OFFSET offset=" << offset;
92 return offset;
93 }
94};
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
99ArcaneCurveWriter::Impl::
100Impl(IApplication* app, ITraceMng* tm, const String& path)
101: TraceAccessor(tm)
102, m_file_name("curves")
103{
104 String full_path = path + "/" + m_file_name + ".acv";
105 info() << "Begin write curves full_path=" << full_path;
106 m_stream.open(full_path.localstr(), std::ios::trunc);
107 if (!m_stream)
108 warning() << "Can not open file '" << full_path << "' for writing curves";
109 m_curves_doc = app->ressourceMng()->createXmlDocument();
110 XmlNode doc = m_curves_doc->documentNode();
111 m_root_element = XmlElement(doc, "curves");
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
117/*---------------------------------------------------------------------------*/
118/*---------------------------------------------------------------------------*/
119
122{
123 String path = infos.path();
124 // m_output_path surcharge les infos en argument si non vide.
125 // TODO: regarder s'il faut créer le répertoire
126 if (!m_output_path.empty())
127 m_output_path = path;
128
129 info() << A_FUNCNAME << "Begin write curves path=" << path;
130 m_p = new Impl(subDomain()->application(), traceMng(), path);
131
132 _writeHeader();
133 Int64 time_offset = _write(infos.times());
134 m_p->m_root_element.setAttrValue("times-offset", String::fromNumber(time_offset));
135 m_p->m_root_element.setAttrValue("times-size", String::fromNumber(infos.times().size()));
136 m_p->m_root_element.setAttrValue("x", "iteration");
137}
138
139/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
142void ArcaneCurveWriter::
143_writeHeader()
144{
145 Byte header[12];
146 // 4 premiers octets pour indiquer qu'il s'agit d'un fichier de courbes
147 // arcane
148 header[0] = 'A';
149 header[1] = 'C';
150 header[2] = 'V';
151 header[3] = (Byte)122;
152 // 4 octets suivant pour la version
153 // Actuellement version 1 ou 2. La version 1 ne supporte que les fichiers
154 // de taille sur 32 bits. La seule différence de la version 2 est que
155 // les offsets et longueurs stoquées à la fin du fichier sont sur
156 // 64bit au lieu de 32.
157 header[4] = (Byte)m_version;
158 header[5] = 0;
159 header[6] = 0;
160 header[7] = 0;
161 // 4 octets suivant pour indiquer l'indianness.
162 Int32 v = 0x01020304;
163 Byte* ptr = (Byte*)(&v);
164 for (Integer i = 0; i < 4; ++i)
165 header[8 + i] = ptr[i];
166 m_p->m_stream.write((const char*)header, 12);
167}
168
169/*---------------------------------------------------------------------------*/
170/*---------------------------------------------------------------------------*/
171
173endWrite()
174{
175 ByteUniqueArray bytes;
176 m_p->m_curves_doc->save(bytes);
177 if (m_version == 2) {
178 Int64 write_info[2];
179 write_info[0] = _write(bytes.constView());
180 write_info[1] = bytes.largeSize();
181 // Doit toujours être la dernière écriture du fichier
183 }
184 else if (m_version == 1) {
185 Int32 write_info[2];
186 write_info[0] = CheckedConvert::toInt32(_write(bytes.constView()));
187 write_info[1] = bytes.size();
188 // Doit toujours être la dernière écriture du fichier
190 }
191 else
192 ARCANE_FATAL("Invalid version {0} (valid values are '1' or '2')", m_version);
193
194 info(4) << "End writing curves";
195
196 // Libère le pointeur
197 m_p = 0;
198}
199
200/*---------------------------------------------------------------------------*/
201/*---------------------------------------------------------------------------*/
202
205{
206 //info() << "Writing curve name=" << infos.m_name;
207 Int64 values_offset = _write(infos.values());
208
209 Int32ConstArrayView iterations(infos.iterations());
210 Integer nb_val = iterations.size();
211 Int32 range_iterations[2];
212 // Regarde si les itérations sont contigues auquel cas
213 // on ne sauvegarde que la première et la dernière pour
214 // gagner de la place.
215 if (nb_val > 3) {
216 Int32 first_iter = iterations[0];
217 Int32 last_iter = iterations[nb_val - 1];
218 Int32 diff = 1 + last_iter - first_iter;
219 //info() << "NB_VAL=" << nb_val << " first=" << first_iter
220 // << " last=" << last_iter << " diff=" << diff << " IS_CONTIGOUS=" << (diff==nb_val);
221 if (diff == nb_val) {
224 iterations = Int32ConstArrayView(2, range_iterations);
225 }
226 }
227 Int64 iteration_offset = _write(iterations);
228
229 XmlNode node = m_p->m_root_element.createAndAppendElement("curve");
230
231 String name(infos.name().clone());
232
233 if (infos.subDomain() != NULL_SUB_DOMAIN_ID) {
234 name = "SD" + String::fromNumber(infos.subDomain()) + "_" + name;
235 }
236 if (infos.hasSupport()) {
237 name = infos.support() + "_" + name;
238 }
239
240 node.setAttrValue("name", name);
241 node.setAttrValue("iterations-offset", String::fromNumber(iteration_offset));
242 node.setAttrValue("iterations-size", String::fromNumber(iterations.size()));
243 node.setAttrValue("values-offset", String::fromNumber(values_offset));
244 node.setAttrValue("values-size", String::fromNumber(infos.values().size()));
245 node.setAttrValue("sub-size", String::fromNumber(infos.subSize()));
246 node.setAttrValue("base-name", infos.name());
247 if (infos.hasSupport()) {
248 node.setAttrValue("support", infos.support());
249 }
250 if (infos.subDomain() != NULL_SUB_DOMAIN_ID) {
251 node.setAttrValue("sub-domain", String::fromNumber(infos.subDomain()));
252 }
253}
254
255/*---------------------------------------------------------------------------*/
256/*---------------------------------------------------------------------------*/
257
261
262/*---------------------------------------------------------------------------*/
263/*---------------------------------------------------------------------------*/
264
265} // End namespace Arcane
266
267/*---------------------------------------------------------------------------*/
268/*---------------------------------------------------------------------------*/
#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.
Classe de base de service lié à un sous-domaine.
Interface de l'application.
Interface d'un écrivain d'une courbe.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
Structure contenant les informations pour créer un service.
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.
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
Integer size() const
Nombre d'éléments du vecteur.
Int64 largeSize() const
Nombre d'éléments du vecteur (en 64 bits)
ConstArrayView< T > constView() const
Vue constante sur ce tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Interface du gestionnaire de traces.
Chaîne de caractères unicode.
bool empty() const
Vrai si la chaîne est vide (nulle ou "")
Definition String.cc:315
String clone() const
Clone cette chaîne.
Definition String.cc:412
ITraceMng * traceMng() const
Gestionnaire de trace.
TraceMessage warning() const
Flot pour un message d'avertissement.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
unsigned char Byte
Type d'un octet.
Definition UtilsTypes.h:142
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:638