Arcane  v3.14.10.0
Documentation utilisateur
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:
60 Hdf5VariableWriterHelper(IMesh* mesh,const String& xml_filename)
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;
74 HFile m_file_id; //!< Identifiant HDF du fichier
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");
96 for( XmlNode elem : variables_elem ){
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/*---------------------------------------------------------------------------*/
132/*!
133 * \brief Ecriture de variables au format HDF5.
134 */
136: public ArcaneHdf5VariableWriterObject
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);
155 Hdf5VariableWriterHelper* sd = new Hdf5VariableWriterHelper(mesh_handle.mesh(),file_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:
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:
211 ManualHdf5DataWriter(IParallelMng* pm,Integer index,const String& directory_name,
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;
246 StringBuilder path = index_path;
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/*---------------------------------------------------------------------------*/
284/*!
285 * \brief Ecriture de variables au format HDF5.
286 */
289{
290 public:
291
294
295 public:
296
297 virtual void build()
298 {
299 }
300
301 //! Retourne l'écrivain associé à ce post-processeur
302 virtual IDataWriter* dataWriter() { return m_writer; }
303
304 //! Notifie qu'une sortie va être effectuée avec les paramètres courants.
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
314 //! Notifie qu'une sortie vient d'être effectuée.
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();
322 XmlNode doc = info_doc->documentNode();
323 XmlElement root_element = XmlElement(doc,"hdf5");
324 root_element.setAttrValue("file-name",m_file_name);
326 RealConstArrayView my_times = times();
327 for( VariableCollection::Enumerator ivar(variables); ++ivar; ){
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 }
342 ByteUniqueArray xml_bytes;
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
353 //! Ferme l'écrivain. Après fermeture, il ne peut plus être utilisé
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 {
365 String base_file_name = baseFileName();
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.
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
Encapsule un hid_t pour un fichier.
Definition Hdf5Utils.h:210
Encapsule un dataset simple d'un fichier HDF5 qui représente un tableau.
Definition Hdf5Utils.h:777
Définition des types standards Arcane pour hdf5.
Definition Hdf5Utils.h:562
void setPath(const String &path)
Positionne le chemin dans le fichier Hdf5 contenant la valeur de la variable.
Ecriture de variables au format HDF5.
Interface de l'application.
virtual IIOMng * ioMng()=0
Gestionnaire des entrées/sorties.
virtual IRessourceMng * ressourceMng() const =0
Gestionnaire de ressources.
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 bool writeXmlFile(IXmlDocumentHolder *doc, const String &filename, const bool indented=false)=0
Ecrit l'arbre XML du document doc dans le fichier filename.
virtual IXmlDocumentHolder * parseXmlFile(const String &filename, const String &schemaname=String())=0
Lit et analyse le fichier XML filename.
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
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 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.
virtual IXmlDocumentHolder * createXmlDocument()=0
Créé un noeud document XML. Crée et retourne un document XML utilisant une implémentation par défaut....
virtual IApplication * application()=0
Application.
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
virtual String itemFamilyName() const =0
Nom de la famille associée (nul si aucune).
virtual String fullName() const =0
Nom complet de la variable (avec le préfixe de la famille)
virtual eItemKind itemKind() const =0
Type des entités du maillage sur lequel repose la variable.
virtual ItemGroup itemGroup() const =0
Groupe du maillage associé.
virtual String name() const =0
Nom de la variable.
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
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
IMesh * mesh() const
Maillage associé.
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.
T * get() const
Retourne l'objet référé par l'instance.
Definition Ptr.h:121
Encapsulation d'un pointeur qui se détruit automatiquement.
Definition ScopedPtr.h:44
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
XmlNode documentElement() const
Retourne le noeud élément du document.
Definition XmlNode.cc:556
String attrValue(const String &name, bool throw_exception=false) const
Valeur de l'attribut name.
Definition XmlNode.cc:225
XmlNodeList children(const String &name) const
Ensemble des noeuds fils de ce noeud ayant pour nom name.
Definition XmlNode.cc:93
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.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Constructeur de chaîne de caractère unicode.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
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é