Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
Hdf5VariableWriter.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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/* Hdf5VariableWriter.cc (C) 2000-2023 */
9/* */
10/* Ecriture de variables au format HDF5. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/ScopedPtr.h"
17#include "arcane/utils/Array.h"
18#include "arcane/utils/StringBuilder.h"
19#include "arcane/utils/NotImplementedException.h"
20#include "arcane/utils/StringBuilder.h"
21
22#include "arcane/AbstractService.h"
23#include "arcane/IRessourceMng.h"
24#include "arcane/BasicTimeLoopService.h"
25#include "arcane/IVariableWriter.h"
26#include "arcane/IXmlDocumentHolder.h"
27#include "arcane/IIOMng.h"
28#include "arcane/IMesh.h"
29#include "arcane/PostProcessorWriterBase.h"
30#include "arcane/IDataWriter.h"
31#include "arcane/IParallelMng.h"
32#include "arcane/Directory.h"
33#include "arcane/VariableCollection.h"
34#include "arcane/IMeshMng.h"
35
36#include "arcane/utils/Collection.h"
37
38#include "arcane/hdf5/Hdf5VariableWriter_axl.h"
39#include "arcane/hdf5/Hdf5VariableInfoBase.h"
40
41#include <set>
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46ARCANE_BEGIN_NAMESPACE
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
51using namespace Hdf5Utils;
52
53/*---------------------------------------------------------------------------*/
54/*---------------------------------------------------------------------------*/
55
57: public TraceAccessor
58{
59 public:
61 : TraceAccessor(mesh->traceMng()), m_mesh(mesh), m_xml_file_name(xml_filename)
62 {
63 }
65 public:
66 virtual void open();
67 virtual void notifyRestore(){}
68 virtual void writeOnExit();
69 private:
70 IMesh* m_mesh;
71 String m_xml_file_name;
72 String m_hdf5_file_name;
75 ScopedPtrT<IXmlDocumentHolder> m_xml_document_holder;
77};
78
79/*---------------------------------------------------------------------------*/
80/*---------------------------------------------------------------------------*/
81
82void Hdf5VariableWriterHelper::
83open()
84{
85 IIOMng* io_mng = m_mesh->parallelMng()->ioMng();
86 m_xml_document_holder = io_mng->parseXmlFile(m_xml_file_name);
87 if (!m_xml_document_holder.get())
88 fatal() << "Can not read file '" << m_xml_file_name << "'";
89
90 XmlNode root_element = m_xml_document_holder->documentNode().documentElement();
91 m_hdf5_file_name = root_element.attrValue("file-name",true);
92
93 // Lecture des variables pour les sorties finales
94 {
95 XmlNodeList variables_elem = root_element.children("exit-variable");
97 String var_name = elem.attrValue("name",true);
98 String var_family = elem.attrValue("family",true);
99 String var_path = elem.attrValue("path",true);
100 info() << "VARIABLE: name=" << var_name << " path=" << var_path
101 << " family=" << var_family;
102 Hdf5VariableInfoBase* var_info = Hdf5VariableInfoBase::create(m_mesh,var_name,var_family);
103 var_info->setPath(var_path);
104 m_exit_variables.add(var_info);
105 }
106 }
107}
108
109/*---------------------------------------------------------------------------*/
110/*---------------------------------------------------------------------------*/
111
112void Hdf5VariableWriterHelper::
113writeOnExit()
114{
115 //TODO lancer exception en cas d'erreur.
116 HFile hfile;
117
118 if (m_mesh->parallelMng()->isMasterIO()){
119 hfile.openTruncate(m_hdf5_file_name);
120 }
121
122 std::set<ItemGroup> groups_to_write;
123 for( Integer iz=0, izs=m_exit_variables.size(); iz<izs; ++iz ){
124 Hdf5VariableInfoBase* vi = m_exit_variables[iz];
125 groups_to_write.insert(vi->variable()->itemGroup());
126 vi->writeVariable(hfile,m_types);
127 }
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
137{
138 public:
139
142
143 public:
144
145 void build() override {}
146 void onTimeLoopStartInit() override
147 {
148 IMeshMng* mm = subDomain()->meshMng();
149 for( Integer i=0, is=options()->write.size(); i<is; ++i ){
150 String file_name = options()->write[i]->fileName();
151 String mesh_name = options()->write[i]->meshName();
152 info() << "Hdf5VariableWriter: FILE_INFO: mesh=" << mesh_name << " file_name=" << file_name;
153 {
154 MeshHandle mesh_handle = mm->findMeshHandle(mesh_name);
156 m_writers.add(sd);
157 }
158 }
159 info() << "Hdf5VariableWriter: Nb writer =" << m_writers.size();
160 for( Integer i=0, is=m_writers.size(); i<is; ++i ){
161 m_writers[i]->open();
162 }
163 }
164 void onTimeLoopExit() override
165 {
166 info() << "Hdf5VariableWriter: End loop";
167 for( Integer i=0, is=m_writers.size(); i<is; ++i ){
168 m_writers[i]->writeOnExit();
169 }
170 }
171 void onTimeLoopRestore() override
172 {
173 for( Integer i=0, is=m_writers.size(); i<is; ++i ){
174 m_writers[i]->notifyRestore();
175 }
176 }
177 void onTimeLoopBeginLoop() override {}
178 private:
179 UniqueArray<Hdf5VariableWriterHelper*> m_writers;
180};
181
182/*---------------------------------------------------------------------------*/
183/*---------------------------------------------------------------------------*/
184
185Hdf5VariableWriter::
186Hdf5VariableWriter(const ServiceBuildInfo& sbi)
187: ArcaneHdf5VariableWriterObject(sbi)
188{
189}
190
191/*---------------------------------------------------------------------------*/
192/*---------------------------------------------------------------------------*/
193
194Hdf5VariableWriter::
195~Hdf5VariableWriter()
196{
197 for( Integer i=0, is=m_writers.size(); i<is; ++i )
198 delete m_writers[i];
199 m_writers.clear();
200}
201
202/*---------------------------------------------------------------------------*/
203/*---------------------------------------------------------------------------*/
204
206: public TraceAccessor
207, public IDataWriter
208{
209 typedef std::set<ItemGroup> ItemGroupSet;
210 public:
212 const String& file_name)
213 : TraceAccessor(pm->traceMng()), m_parallel_mng(pm), m_index(index),
214 m_directory_name(directory_name), m_file_name(file_name)
215 {
216 }
217 public:
218
219 virtual void beginWrite(const VariableCollection& vars)
220 {
221 info(4) << "BEGIN WRITE N=" << vars.count() << " INDEX=" << m_index << " directory=" << m_directory_name;
222 Directory out_dir(m_directory_name);
223 String full_filename = out_dir.file(m_file_name);
224 info(4) << "OUT FILE_NAME=" << full_filename;
225 if (m_parallel_mng->isMasterIO()){
226 if (m_index<=1){
227 m_hdf_file.openTruncate(full_filename);
228 }
229 else
230 m_hdf_file.openAppend(full_filename);
231 }
232 m_saved_groups.clear();
233 }
234 virtual void endWrite()
235 {
236 }
237 virtual void setMetaData(const String& meta_data)
238 {
239 ARCANE_UNUSED(meta_data);
240 }
241 virtual void write(IVariable* var,IData* data)
242 {
243 ARCANE_UNUSED(data);
244 info(4) << "WRITE VAR name=" << var->fullName();
245 String index_path = String("Index") + m_index;
247 path += "/Variables/";
248 path += var->fullName();
249
250 ScopedPtrT<Hdf5VariableInfoBase> var_info(Hdf5VariableInfoBase::create(var));
251 var_info->setPath(path);
252 var_info->writeVariable(m_hdf_file,m_hdf5_types);
253 if (m_index==1){
254 // HACK: pour l'instant, sauve uniquement les infos de groupe lors de la premiere protection
255 // Normalement, cela devrait etre specifié par l'API.
256 ItemGroup group = var->itemGroup();
257 if (!group.null() && m_saved_groups.find(group)==m_saved_groups.end()){
258 Integer save_type = Hdf5VariableInfoBase::SAVE_IDS + Hdf5VariableInfoBase::SAVE_COORDS;
259 String group_path = index_path + "/Groups/" + group.name();
260 var_info->writeGroup(m_hdf_file,m_hdf5_types,group_path,save_type);
261 }
262 m_saved_groups.insert(group);
263 }
264 }
265
266 void writeInfos(ByteConstArrayView bytes)
267 {
268 Hdf5Utils::StandardArrayT<Byte> v(m_hdf_file.id(),"Infos");
269 v.write(m_hdf5_types,bytes);
270 }
271
272 private:
273 Hdf5Utils::StandardTypes m_hdf5_types;
274 IParallelMng* m_parallel_mng;
275 Integer m_index;
276 String m_directory_name;
277 String m_file_name;
278 HFile m_hdf_file;
279 std::set<ItemGroup> m_saved_groups;
280};
281
282/*---------------------------------------------------------------------------*/
283/*---------------------------------------------------------------------------*/
289{
290 public:
291
294
295 public:
296
297 virtual void build()
298 {
299 }
300
302 virtual IDataWriter* dataWriter() { return m_writer; }
303
305 virtual void notifyBeginWrite()
306 {
307 _setFileName();
309 Integer index = times().size();
310 info() << "Hdf5VariableWriter: nb_vars=" << variables.count() << " index=" << index;
311 m_writer = new ManualHdf5DataWriter(subDomain()->parallelMng(),index,baseDirectoryName(),m_file_name);
312 }
313
315 virtual void notifyEndWrite()
316 {
317 // Ecrit le fichier XML contenant les infos des temps et des variables
318 bool is_master = subDomain()->parallelMng()->isMasterIO();
319 if (is_master){
320 IApplication* app = subDomain()->application();
321 ScopedPtrT<IXmlDocumentHolder> info_doc(app->ressourceMng()->createXmlDocument());
322 XmlNode doc = info_doc->documentNode();
324 root_element.setAttrValue("file-name",m_file_name);
328 IVariable* var = *ivar;
329 // Ne gère que les variables sur des entités du maillage.
330 if (var->itemKind()==IK_Unknown)
331 continue;
332 XmlNode x = root_element.createAndAppendElement("time-variable");
333 x.setAttrValue("name",var->name());
334 x.setAttrValue("family",var->itemFamilyName());
335 for( Integer i=0, n=my_times.size(); i<n; ++i ){
336 XmlNode tx = x.createAndAppendElement("time-value");
337 String index_path = String::format("Index{0}/Variables/{1}",i+1,var->fullName());
338 tx.setAttrValue("path",index_path);
339 tx.setAttrValue("global-time",String::fromNumber(my_times[i]));
340 }
341 }
343 info_doc->save(xml_bytes);
344 if (m_writer)
345 m_writer->writeInfos(xml_bytes);
346 app->ioMng()->writeXmlFile(info_doc.get(),"toto.xml");
347 // Il faut écrire le fichier XML dans le fichier hdf5.
348 }
349 delete m_writer;
350 m_writer = 0;
351 }
352
354 virtual void close() {}
355
356 private:
357
358 ManualHdf5DataWriter* m_writer;
359 String m_file_name;
360
361 private:
362
363 void _setFileName()
364 {
366 if (base_file_name.null())
367 base_file_name = "data";
368 m_file_name = base_file_name + ".h5";
369 }
370};
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374
375ManualHdf5VariableWriter::
376ManualHdf5VariableWriter(const ServiceBuildInfo& sbi)
377: PostProcessorWriterBase(sbi)
378, m_writer(0)
379{
380}
381
382/*---------------------------------------------------------------------------*/
383/*---------------------------------------------------------------------------*/
384
385ManualHdf5VariableWriter::
386~ManualHdf5VariableWriter()
387{
388 delete m_writer;
389}
390
391/*---------------------------------------------------------------------------*/
392/*---------------------------------------------------------------------------*/
393
394ARCANE_REGISTER_SERVICE_HDF5VARIABLEWRITER(Hdf5VariableWriter,
395 Hdf5VariableWriter);
396
397ARCANE_REGISTER_SUB_DOMAIN_FACTORY(ManualHdf5VariableWriter,
398 IPostProcessorWriter,
399 Hdf5VariableWriter);
400
401/*---------------------------------------------------------------------------*/
402/*---------------------------------------------------------------------------*/
403
404ARCANE_END_NAMESPACE
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
#define ARCANE_REGISTER_SUB_DOMAIN_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Generation de la classe de base du Service.
Classe gérant un répertoire.
Definition Directory.h:33
Encapsule un hid_t pour un fichier.
Encapsule un dataset simple d'un fichier HDF5 qui représente un tableau.
Définition des types standards Arcane pour hdf5.
Classe de base pour lire ou écrire une variables.
HFile m_file_id
Identifiant HDF du fichier.
Ecriture de variables au format HDF5.
void build() override
Construction de niveau build du service.
Interface de l'application.
Interface d'écriture des données d'une variable.
Definition IDataWriter.h:49
Interface d'une donnée.
Definition IData.h:33
Interface du gestionnaire des entrées sorties.
Definition IIOMng.h:42
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
Interface du gestionnaire des maillages.
Definition IMeshMng.h:40
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
virtual bool isMasterIO() const =0
true si l'instance est un gestionnaire maître des entrées/sorties.
Interface d'une variable.
Definition IVariable.h:54
Groupe d'entités de maillage.
Definition ItemGroup.h:49
const String & name() const
Nom du groupe.
Definition ItemGroup.h:76
bool null() const
true is le groupe est le groupe nul
Definition ItemGroup.h:70
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
virtual void setMetaData(const String &meta_data)
Positionne les infos des méta-données.
virtual void write(IVariable *var, IData *data)
Ecrit les données data de la variable var.
Ecriture de variables au format HDF5.
virtual void notifyEndWrite()
Notifie qu'une sortie vient d'être effectuée.
virtual void close()
Ferme l'écrivain. Après fermeture, il ne peut plus être utilisé
virtual void notifyBeginWrite()
Notifie qu'une sortie va être effectuée avec les paramètres courants.
virtual void build()
Construction de niveau build du service.
virtual IDataWriter * dataWriter()
Retourne l'écrivain associé à ce post-processeur.
Handle sur un maillage.
Definition MeshHandle.h:47
Classe de base d'un écrivain pour les informations de post-traitement.
virtual const String & baseFileName()
Nom du fichier contenant les sorties.
virtual RealConstArrayView times()
Liste des temps sauvés.
virtual const String & baseDirectoryName()
Nom du répertoire de sortie des fichiers.
virtual VariableCollection variables()
Liste des variables à sauver.
Structure contenant les informations pour créer un service.
Collection de variables.
Elément d'un arbre DOM.
Definition XmlNode.h:396
Liste de noeuds d'un arbre DOM.
Definition XmlNodeList.h:33
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
Vue constante d'un tableau de type T.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé