diff --git a/arcane/ceapart/tests/CMakeLists.txt b/arcane/ceapart/tests/CMakeLists.txt
index d7372d42c..319792ab5 100644
--- a/arcane/ceapart/tests/CMakeLists.txt
+++ b/arcane/ceapart/tests/CMakeLists.txt
@@ -471,6 +471,10 @@ if (ARCANE_HAS_ACCELERATOR_API)
"-We,ARCANE_MATERIAL_NEW_ITEM_INIT,2" "-We,ARCANE_USE_GENERIC_COPY_BETWEEN_PURE_AND_PARTIAL,2")
arcane_add_test_sequential_host_and_accelerator(material_heat4_init3_accelerator "${ARCANE_TEST_PATH}/testMaterialHeat-4-opt15.arc" "-m 20"
"-We,ARCANE_MATERIAL_NEW_ITEM_INIT,3" "-We,ARCANE_ALLENVCELL_FOR_RUNCOMMAND,1")
+ if(HDF5_FOUND)
+ arcane_add_test(material_heat2_vtkhdfv2 testMaterialHeat-2-vtkhdfv2.arc)
+ endif()
+
endif()
###################
diff --git a/arcane/ceapart/tests/testMaterialHeat-2-vtkhdfv2.arc b/arcane/ceapart/tests/testMaterialHeat-2-vtkhdfv2.arc
new file mode 100644
index 000000000..1eb9b0458
--- /dev/null
+++ b/arcane/ceapart/tests/testMaterialHeat-2-vtkhdfv2.arc
@@ -0,0 +1,85 @@
+
+
+
+ Test MaterialHeat
+ Test des Materiaux
+ MaterialHeatTestLoop
+
+
+
+ 5
+
+
+
+
+
+
+
+ 2
+ 2
+ 0.0 0.0
+ 401.21.0
+ 601.51.0
+
+
+
+
+
+ 15
+ 15
+ false
+
+ MAT1
+
+
+ MAT2
+
+
+ MAT3
+
+
+
+ ENV1
+ MAT1
+ MAT2
+
+
+ ENV2
+ MAT2
+ MAT3
+
+
+
+ 0.3 0.4 0.0
+ 0.02 0.04 0.0
+ 0.18
+ ENV1_MAT1
+ 3632937.10322508
+
+
+ 0.8 0.4 0.0
+ -0.02 0.04 0.0
+ 0.25
+ ENV1_MAT2
+ 7780818.83419631
+
+
+ 0.2 1.2 0.0
+ 0.02 -0.05 0.0
+ 0.2
+ ENV2_MAT2
+ 4230364.18968662
+
+
+ 0.9 0.9 0.0
+ -0.02 -0.04 0.0
+ 0.15
+ ENV2_MAT3
+ 2259280.64283209
+
+
+
+
+
diff --git a/arcane/src/arcane/hdf5/VtkHdfV2PostProcessor.cc b/arcane/src/arcane/hdf5/VtkHdfV2PostProcessor.cc
index 1ab458918..05599173f 100644
--- a/arcane/src/arcane/hdf5/VtkHdfV2PostProcessor.cc
+++ b/arcane/src/arcane/hdf5/VtkHdfV2PostProcessor.cc
@@ -1,11 +1,11 @@
// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
//-----------------------------------------------------------------------------
-// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
+// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: Apache-2.0
//-----------------------------------------------------------------------------
/*---------------------------------------------------------------------------*/
-/* VtkHdfV2PostProcessor.cc (C) 2000-2024 */
+/* VtkHdfV2PostProcessor.cc (C) 2000-2025 */
/* */
/* Pos-traitement au format VTK HDF. */
/*---------------------------------------------------------------------------*/
@@ -30,6 +30,9 @@
#include "arcane/core/IMesh.h"
#include "arcane/core/internal/VtkCellTypes.h"
+#include "arcane/core/materials/IMeshMaterialMng.h"
+#include "arcane/core/materials/IMeshEnvironment.h"
+
#include "arcane/hdf5/Hdf5Utils.h"
#include "arcane/hdf5/VtkHdfV2PostProcessor_axl.h"
@@ -66,6 +69,7 @@
namespace Arcane
{
using namespace Hdf5Utils;
+using namespace Materials;
namespace
{
@@ -93,6 +97,15 @@ class VtkHdfV2DataWriter
*/
struct DatasetGroupAndName
{
+ public:
+
+ DatasetGroupAndName(HGroup& group_, const String& name_)
+ : group(group_)
+ , name(name_)
+ {}
+
+ public:
+
HGroup& group;
String name;
};
@@ -215,7 +228,7 @@ class VtkHdfV2DataWriter
public:
- VtkHdfV2DataWriter(IMesh* mesh, const ItemGroupCollection& groups, bool use_collective_io);
+ VtkHdfV2DataWriter(IMesh* mesh, const ItemGroupCollection& groups, bool is_collective_io);
public:
@@ -232,8 +245,12 @@ class VtkHdfV2DataWriter
private:
+ //! Maillage associé
IMesh* m_mesh = nullptr;
+ //! Gestionnaire de matériaux associé (peut-être nul)
+ IMeshMaterialMng* m_material_mng = nullptr;
+
//! Liste des groupes à sauver
ItemGroupCollection m_groups;
@@ -276,6 +293,7 @@ class VtkHdfV2DataWriter
ItemGroupCollectiveInfo m_all_cells_info;
ItemGroupCollectiveInfo m_all_nodes_info;
+ UniqueArray[> m_materials_groups;
/*!
* \brief Taille maximale (en kilo-octet) pour une écriture.
@@ -328,6 +346,7 @@ class VtkHdfV2DataWriter
void _initializeOffsets();
void _initializeItemGroupCollectiveInfos(ItemGroupCollectiveInfo& group_info);
WritePartInfo _computeWritePartInfo(Int64 local_size);
+ void _writeConstituentsGroups();
};
/*---------------------------------------------------------------------------*/
@@ -352,6 +371,9 @@ beginWrite(const VariableCollection& vars)
{
ARCANE_UNUSED(vars);
+ // Récupère le gestionnaire de matériaux s'il existe
+ m_material_mng = IMeshMaterialMng::getReference(m_mesh, false);
+
IParallelMng* pm = m_mesh->parallelMng();
const Int32 nb_rank = pm->commSize();
m_is_parallel = nb_rank > 1;
@@ -361,7 +383,7 @@ beginWrite(const VariableCollection& vars)
const bool is_first_call = (time_index < 2);
m_is_first_call = is_first_call;
if (is_first_call)
- pwarning() << "L'implémentation au format 'VtkHdfV2' est expérimentale";
+ info() << "WARNING: L'implémentation au format 'VtkHdfV2' est expérimentale";
String filename = _getFileName();
@@ -372,9 +394,9 @@ beginWrite(const VariableCollection& vars)
HInit();
- // Il est possible d'utiliser le mode collectif de HDF5 via MPI-IO dans les cas suivants:
- // - Hdf5 a été compilé avec MPI
- // - on est en mode MPI pure (ni mode mémoire partagé, ni mode hybride)
+ // Il est possible d'utiliser le mode collectif de HDF5 via MPI-IO dans les cas suivants :
+ // * Hdf5 a été compilé avec MPI,
+ // * on est en mode MPI pure (ni mode mémoire partagé, ni mode hybride).
m_is_collective_io = m_is_collective_io && (pm->isParallel() && HInit::hasParallelHdf5());
if (pm->isHybridImplementation() || pm->isThreadImplementation())
m_is_collective_io = false;
@@ -382,7 +404,9 @@ beginWrite(const VariableCollection& vars)
if (is_first_call) {
info() << "VtkHdfV2DataWriter: using collective MPI/IO ?=" << m_is_collective_io;
info() << "VtkHdfV2DataWriter: max_write_size (kB) =" << m_max_write_size;
+ info() << "VtkHdfV2DataWriter: has_material?=" << (m_material_mng != nullptr);
}
+
// Vrai si on doit participer aux écritures
// Si on utilise MPI/IO avec HDF5, il faut tout de même que tous
// les rangs fassent toutes les opérations d'écriture pour garantir
@@ -511,10 +535,10 @@ beginWrite(const VariableCollection& vars)
points[index][2] = pos.z;
}
- // Sauve l'uniqueId de chaque noeud dans le dataset "GlobalNodeId".
+ // Sauve l'uniqueId de chaque nœud dans le dataset "GlobalNodeId".
_writeDataSet1DCollective({ { m_node_data_group, "GlobalNodeId" }, m_cell_offset_info }, nodes_uid);
- // Sauve les informations sur le type de noeud (réel ou fantôme).
+ // Sauve les informations sur le type de nœud (réel ou fantôme).
_writeDataSet1DCollective({ { m_node_data_group, "vtkGhostType" }, m_cell_offset_info }, nodes_ghost_type);
// Sauve les coordonnées des noeuds.
@@ -529,7 +553,6 @@ beginWrite(const VariableCollection& vars)
_writeDataSet1DCollective({ { m_cell_data_group, "GlobalCellId" }, m_cell_offset_info }, cells_uid);
if (m_is_writer) {
-
// Liste des temps.
Real current_time = m_times[time_index - 1];
_writeDataSet1D({ { m_steps_group, "Values" }, m_time_offset_info }, asConstSpan(¤t_time));
@@ -541,6 +564,33 @@ beginWrite(const VariableCollection& vars)
// Nombre de temps
_addInt64Attribute(m_steps_group, "NSteps", time_index);
}
+
+ _writeConstituentsGroups();
+}
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+void VtkHdfV2DataWriter::
+_writeConstituentsGroups()
+{
+ if (!m_material_mng)
+ return;
+
+ // Remplit les informations des groupes liés aux constituents
+ // NOTE : Pour l'instant, on ne traite que les milieux.
+ for (IMeshEnvironment* env : m_material_mng->environments()) {
+ CellGroup cells = env->cells();
+ Ref group_info_ref = createRef(cells);
+ m_materials_groups.add(group_info_ref);
+ ItemGroupCollectiveInfo& group_info = *group_info_ref.get();
+ _initializeItemGroupCollectiveInfos(group_info);
+ ConstArrayView groups_ids = cells.view().localIds();
+ DatasetGroupAndName dataset_group_name(m_top_group, String("Constituent_") + cells.name());
+ if (m_is_first_call)
+ info() << "Writing infos for group '" << cells.name() << "'";
+ _writeDataSet1DCollective({ dataset_group_name, m_cell_offset_info }, groups_ids);
+ }
}
/*---------------------------------------------------------------------------*/
@@ -1140,21 +1190,22 @@ _readAndSetOffset(DatasetInfo& offset_info, Int32 wanted_step)
void VtkHdfV2DataWriter::
_initializeOffsets()
{
- // Il y a 5 valeurs d'offset utilisées:
+ // Il y a 5 valeurs d'offset utilisées :
+ //
// - offset sur le nombre de mailles (CellOffsets). Cet offset a pour nombre d'éléments
// le nombre de temps sauvés et est augmenté à chaque sortie du nombre de mailles. Cet offset
- // est aussi utiliser pour les variables aux mailles
- // - offset sur le nombre de noeuds (PointOffsets). Il équivalent à 'CellOffsets' mais
+ // est aussi utilisé pour les variables aux mailles
+ // - offset sur le nombre de noeuds (PointOffsets). Il est équivalent à 'CellOffsets' mais
// pour les noeuds.
// - offset pour "NumberOfCells", "NumberOfPoints" et "NumberOfConnectivityIds". Pour chacun
// de ces champs il y a NbPart valeurs par temps, avec 'NbPart' le nombre de parties (donc
- // le nombre de sous-domaines si on ne fait pas de regroupement). Il y a donc au total
+ // le nombre de sous-domaines si on ne fait pas de regroupement). Il y a ainsi au total
// NbPart * NbTimeStep dans ce champ d'offset.
// - offset pour le champ "Connectivity" qui s'appelle "ConnectivityIdOffsets".
// Cet offset a pour nombre d'éléments le nombre de temps sauvés.
// - offset pour le champ "Offsets". "Offset" contient pour chaque maille l'offset dans
- // "Connectivity" de la connectivité des noeuds de la maille. Cet offset n'est pas sauvés
- // mais comme ce champ à un nombre de valeur égale au nombre de mailles plus 1 il est possible
+ // "Connectivity" de la connectivité des noeuds de la maille. Cet offset n'est pas sauvés,
+ // mais comme ce champ à un nombre de valeurs égal au nombre de mailles plus un il est possible
// de le déduire de "CellOffsets" (il vaut "CellOffsets" plus l'index du temps courant).
m_cell_offset_info = DatasetInfo(m_steps_group, "CellOffsets");
]