Skip to content

Commit c48c5e1

Browse files
Merge pull request #1975 from arcaneframework/dev/gg-begin-add-constituents-in-vtkhdfv2
Begin support for post-processing constituents with format VtkHdf
2 parents 2472872 + 45cbb1a commit c48c5e1

File tree

3 files changed

+156
-16
lines changed

3 files changed

+156
-16
lines changed

arcane/ceapart/tests/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,10 @@ if (ARCANE_HAS_ACCELERATOR_API)
471471
"-We,ARCANE_MATERIAL_NEW_ITEM_INIT,2" "-We,ARCANE_USE_GENERIC_COPY_BETWEEN_PURE_AND_PARTIAL,2")
472472
arcane_add_test_sequential_host_and_accelerator(material_heat4_init3_accelerator "${ARCANE_TEST_PATH}/testMaterialHeat-4-opt15.arc" "-m 20"
473473
"-We,ARCANE_MATERIAL_NEW_ITEM_INIT,3" "-We,ARCANE_ALLENVCELL_FOR_RUNCOMMAND,1")
474+
if(HDF5_FOUND)
475+
arcane_add_test(material_heat2_vtkhdfv2 testMaterialHeat-2-vtkhdfv2.arc)
476+
endif()
477+
474478
endif()
475479

476480
###################
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0"?>
2+
<case codename="ArcaneTest" xml:lang="en" codeversion="1.0">
3+
<arcane>
4+
<title>Test MaterialHeat</title>
5+
<description>Test des Materiaux</description>
6+
<timeloop>MaterialHeatTestLoop</timeloop>
7+
</arcane>
8+
9+
<arcane-post-processing>
10+
<output-period>5</output-period>
11+
<format name="VtkHdfV2PostProcessor" />
12+
<output>
13+
<variable>Temperature</variable>
14+
</output>
15+
</arcane-post-processing>
16+
17+
<meshes>
18+
<mesh>
19+
<generator name="Cartesian2D">
20+
<nb-part-x>2</nb-part-x>
21+
<nb-part-y>2</nb-part-y>
22+
<origin>0.0 0.0</origin>
23+
<x><n>40</n><length>1.2</length><progression>1.0</progression></x>
24+
<y><n>60</n><length>1.5</length><progression>1.0</progression></y>
25+
</generator>
26+
</mesh>
27+
</meshes>
28+
29+
<material-heat-test>
30+
<nb-iteration>15</nb-iteration>
31+
<modification-flags>15</modification-flags>
32+
<check-numerical-result>false</check-numerical-result>
33+
<material>
34+
<name>MAT1</name>
35+
</material>
36+
<material>
37+
<name>MAT2</name>
38+
</material>
39+
<material>
40+
<name>MAT3</name>
41+
</material>
42+
43+
<environment>
44+
<name>ENV1</name>
45+
<material>MAT1</material>
46+
<material>MAT2</material>
47+
</environment>
48+
<environment>
49+
<name>ENV2</name>
50+
<material>MAT2</material>
51+
<material>MAT3</material>
52+
</environment>
53+
54+
<heat-object>
55+
<center>0.3 0.4 0.0</center>
56+
<velocity>0.02 0.04 0.0</velocity>
57+
<radius>0.18</radius>
58+
<material>ENV1_MAT1</material>
59+
<expected-final-temperature>3632937.10322508</expected-final-temperature>
60+
</heat-object>
61+
<heat-object>
62+
<center>0.8 0.4 0.0</center>
63+
<velocity>-0.02 0.04 0.0</velocity>
64+
<radius>0.25</radius>
65+
<material>ENV1_MAT2</material>
66+
<expected-final-temperature>7780818.83419631</expected-final-temperature>
67+
</heat-object>
68+
<heat-object>
69+
<center>0.2 1.2 0.0</center>
70+
<velocity>0.02 -0.05 0.0</velocity>
71+
<radius>0.2</radius>
72+
<material>ENV2_MAT2</material>
73+
<expected-final-temperature>4230364.18968662</expected-final-temperature>
74+
</heat-object>
75+
<heat-object>
76+
<center>0.9 0.9 0.0</center>
77+
<velocity>-0.02 -0.04 0.0</velocity>
78+
<radius>0.15</radius>
79+
<material>ENV2_MAT3</material>
80+
<expected-final-temperature>2259280.64283209</expected-final-temperature>
81+
</heat-object>
82+
83+
</material-heat-test>
84+
85+
</case>

arcane/src/arcane/hdf5/VtkHdfV2PostProcessor.cc

+67-16
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
22
//-----------------------------------------------------------------------------
3-
// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
3+
// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
44
// See the top-level COPYRIGHT file for details.
55
// SPDX-License-Identifier: Apache-2.0
66
//-----------------------------------------------------------------------------
77
/*---------------------------------------------------------------------------*/
8-
/* VtkHdfV2PostProcessor.cc (C) 2000-2024 */
8+
/* VtkHdfV2PostProcessor.cc (C) 2000-2025 */
99
/* */
1010
/* Pos-traitement au format VTK HDF. */
1111
/*---------------------------------------------------------------------------*/
@@ -30,6 +30,9 @@
3030
#include "arcane/core/IMesh.h"
3131
#include "arcane/core/internal/VtkCellTypes.h"
3232

33+
#include "arcane/core/materials/IMeshMaterialMng.h"
34+
#include "arcane/core/materials/IMeshEnvironment.h"
35+
3336
#include "arcane/hdf5/Hdf5Utils.h"
3437
#include "arcane/hdf5/VtkHdfV2PostProcessor_axl.h"
3538

@@ -66,6 +69,7 @@
6669
namespace Arcane
6770
{
6871
using namespace Hdf5Utils;
72+
using namespace Materials;
6973

7074
namespace
7175
{
@@ -93,6 +97,15 @@ class VtkHdfV2DataWriter
9397
*/
9498
struct DatasetGroupAndName
9599
{
100+
public:
101+
102+
DatasetGroupAndName(HGroup& group_, const String& name_)
103+
: group(group_)
104+
, name(name_)
105+
{}
106+
107+
public:
108+
96109
HGroup& group;
97110
String name;
98111
};
@@ -215,7 +228,7 @@ class VtkHdfV2DataWriter
215228

216229
public:
217230

218-
VtkHdfV2DataWriter(IMesh* mesh, const ItemGroupCollection& groups, bool use_collective_io);
231+
VtkHdfV2DataWriter(IMesh* mesh, const ItemGroupCollection& groups, bool is_collective_io);
219232

220233
public:
221234

@@ -232,8 +245,12 @@ class VtkHdfV2DataWriter
232245

233246
private:
234247

248+
//! Maillage associé
235249
IMesh* m_mesh = nullptr;
236250

251+
//! Gestionnaire de matériaux associé (peut-être nul)
252+
IMeshMaterialMng* m_material_mng = nullptr;
253+
237254
//! Liste des groupes à sauver
238255
ItemGroupCollection m_groups;
239256

@@ -276,6 +293,7 @@ class VtkHdfV2DataWriter
276293

277294
ItemGroupCollectiveInfo m_all_cells_info;
278295
ItemGroupCollectiveInfo m_all_nodes_info;
296+
UniqueArray<Ref<ItemGroupCollectiveInfo>> m_materials_groups;
279297

280298
/*!
281299
* \brief Taille maximale (en kilo-octet) pour une écriture.
@@ -328,6 +346,7 @@ class VtkHdfV2DataWriter
328346
void _initializeOffsets();
329347
void _initializeItemGroupCollectiveInfos(ItemGroupCollectiveInfo& group_info);
330348
WritePartInfo _computeWritePartInfo(Int64 local_size);
349+
void _writeConstituentsGroups();
331350
};
332351

333352
/*---------------------------------------------------------------------------*/
@@ -352,6 +371,9 @@ beginWrite(const VariableCollection& vars)
352371
{
353372
ARCANE_UNUSED(vars);
354373

374+
// Récupère le gestionnaire de matériaux s'il existe
375+
m_material_mng = IMeshMaterialMng::getReference(m_mesh, false);
376+
355377
IParallelMng* pm = m_mesh->parallelMng();
356378
const Int32 nb_rank = pm->commSize();
357379
m_is_parallel = nb_rank > 1;
@@ -361,7 +383,7 @@ beginWrite(const VariableCollection& vars)
361383
const bool is_first_call = (time_index < 2);
362384
m_is_first_call = is_first_call;
363385
if (is_first_call)
364-
pwarning() << "L'implémentation au format 'VtkHdfV2' est expérimentale";
386+
info() << "WARNING: L'implémentation au format 'VtkHdfV2' est expérimentale";
365387

366388
String filename = _getFileName();
367389

@@ -372,17 +394,19 @@ beginWrite(const VariableCollection& vars)
372394

373395
HInit();
374396

375-
// Il est possible d'utiliser le mode collectif de HDF5 via MPI-IO dans les cas suivants:
376-
// - Hdf5 a été compilé avec MPI
377-
// - on est en mode MPI pure (ni mode mémoire partagé, ni mode hybride)
397+
// Il est possible d'utiliser le mode collectif de HDF5 via MPI-IO dans les cas suivants :
398+
// * Hdf5 a été compilé avec MPI,
399+
// * on est en mode MPI pure (ni mode mémoire partagé, ni mode hybride).
378400
m_is_collective_io = m_is_collective_io && (pm->isParallel() && HInit::hasParallelHdf5());
379401
if (pm->isHybridImplementation() || pm->isThreadImplementation())
380402
m_is_collective_io = false;
381403

382404
if (is_first_call) {
383405
info() << "VtkHdfV2DataWriter: using collective MPI/IO ?=" << m_is_collective_io;
384406
info() << "VtkHdfV2DataWriter: max_write_size (kB) =" << m_max_write_size;
407+
info() << "VtkHdfV2DataWriter: has_material?=" << (m_material_mng != nullptr);
385408
}
409+
386410
// Vrai si on doit participer aux écritures
387411
// Si on utilise MPI/IO avec HDF5, il faut tout de même que tous
388412
// les rangs fassent toutes les opérations d'écriture pour garantir
@@ -511,10 +535,10 @@ beginWrite(const VariableCollection& vars)
511535
points[index][2] = pos.z;
512536
}
513537

514-
// Sauve l'uniqueId de chaque noeud dans le dataset "GlobalNodeId".
538+
// Sauve l'uniqueId de chaque nœud dans le dataset "GlobalNodeId".
515539
_writeDataSet1DCollective<Int64>({ { m_node_data_group, "GlobalNodeId" }, m_cell_offset_info }, nodes_uid);
516540

517-
// Sauve les informations sur le type de noeud (réel ou fantôme).
541+
// Sauve les informations sur le type de nœud (réel ou fantôme).
518542
_writeDataSet1DCollective<unsigned char>({ { m_node_data_group, "vtkGhostType" }, m_cell_offset_info }, nodes_ghost_type);
519543

520544
// Sauve les coordonnées des noeuds.
@@ -529,7 +553,6 @@ beginWrite(const VariableCollection& vars)
529553
_writeDataSet1DCollective<Int64>({ { m_cell_data_group, "GlobalCellId" }, m_cell_offset_info }, cells_uid);
530554

531555
if (m_is_writer) {
532-
533556
// Liste des temps.
534557
Real current_time = m_times[time_index - 1];
535558
_writeDataSet1D<Real>({ { m_steps_group, "Values" }, m_time_offset_info }, asConstSpan(&current_time));
@@ -541,6 +564,33 @@ beginWrite(const VariableCollection& vars)
541564
// Nombre de temps
542565
_addInt64Attribute(m_steps_group, "NSteps", time_index);
543566
}
567+
568+
_writeConstituentsGroups();
569+
}
570+
571+
/*---------------------------------------------------------------------------*/
572+
/*---------------------------------------------------------------------------*/
573+
574+
void VtkHdfV2DataWriter::
575+
_writeConstituentsGroups()
576+
{
577+
if (!m_material_mng)
578+
return;
579+
580+
// Remplit les informations des groupes liés aux constituents
581+
// NOTE : Pour l'instant, on ne traite que les milieux.
582+
for (IMeshEnvironment* env : m_material_mng->environments()) {
583+
CellGroup cells = env->cells();
584+
Ref<ItemGroupCollectiveInfo> group_info_ref = createRef<ItemGroupCollectiveInfo>(cells);
585+
m_materials_groups.add(group_info_ref);
586+
ItemGroupCollectiveInfo& group_info = *group_info_ref.get();
587+
_initializeItemGroupCollectiveInfos(group_info);
588+
ConstArrayView<Int32> groups_ids = cells.view().localIds();
589+
DatasetGroupAndName dataset_group_name(m_top_group, String("Constituent_") + cells.name());
590+
if (m_is_first_call)
591+
info() << "Writing infos for group '" << cells.name() << "'";
592+
_writeDataSet1DCollective<Int32>({ dataset_group_name, m_cell_offset_info }, groups_ids);
593+
}
544594
}
545595

546596
/*---------------------------------------------------------------------------*/
@@ -1140,21 +1190,22 @@ _readAndSetOffset(DatasetInfo& offset_info, Int32 wanted_step)
11401190
void VtkHdfV2DataWriter::
11411191
_initializeOffsets()
11421192
{
1143-
// Il y a 5 valeurs d'offset utilisées:
1193+
// Il y a 5 valeurs d'offset utilisées :
1194+
//
11441195
// - offset sur le nombre de mailles (CellOffsets). Cet offset a pour nombre d'éléments
11451196
// le nombre de temps sauvés et est augmenté à chaque sortie du nombre de mailles. Cet offset
1146-
// est aussi utiliser pour les variables aux mailles
1147-
// - offset sur le nombre de noeuds (PointOffsets). Il équivalent à 'CellOffsets' mais
1197+
// est aussi utilisé pour les variables aux mailles
1198+
// - offset sur le nombre de noeuds (PointOffsets). Il est équivalent à 'CellOffsets' mais
11481199
// pour les noeuds.
11491200
// - offset pour "NumberOfCells", "NumberOfPoints" et "NumberOfConnectivityIds". Pour chacun
11501201
// de ces champs il y a NbPart valeurs par temps, avec 'NbPart' le nombre de parties (donc
1151-
// le nombre de sous-domaines si on ne fait pas de regroupement). Il y a donc au total
1202+
// le nombre de sous-domaines si on ne fait pas de regroupement). Il y a ainsi au total
11521203
// NbPart * NbTimeStep dans ce champ d'offset.
11531204
// - offset pour le champ "Connectivity" qui s'appelle "ConnectivityIdOffsets".
11541205
// Cet offset a pour nombre d'éléments le nombre de temps sauvés.
11551206
// - offset pour le champ "Offsets". "Offset" contient pour chaque maille l'offset dans
1156-
// "Connectivity" de la connectivité des noeuds de la maille. Cet offset n'est pas sauvés
1157-
// mais comme ce champ à un nombre de valeur égale au nombre de mailles plus 1 il est possible
1207+
// "Connectivity" de la connectivité des noeuds de la maille. Cet offset n'est pas sauvés,
1208+
// mais comme ce champ à un nombre de valeurs égal au nombre de mailles plus un il est possible
11581209
// de le déduire de "CellOffsets" (il vaut "CellOffsets" plus l'index du temps courant).
11591210

11601211
m_cell_offset_info = DatasetInfo(m_steps_group, "CellOffsets");

0 commit comments

Comments
 (0)