Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MeshMaterialSynchronizer.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* MeshMaterialSynchronizer.cc (C) 2000-2025 */
9/* */
10/* Material entity synchronization. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/MeshMaterialSynchronizer.h"
15
16#include "arcane/materials/CellToAllEnvCellConverter.h"
17#include "arcane/materials/MatItemEnumerator.h"
18#include "arcane/materials/MeshMaterialModifier.h"
19
20#include "arcane/utils/HashSuite.h"
21
22#include "arcane/core/VariableTypes.h"
23#include "arcane/core/IParallelMng.h"
24#include "arcane/core/ItemPrinter.h"
25#include "arcane/core/IMesh.h"
26#include "arcane/core/ItemGenericInfoListView.h"
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31namespace Arcane::Materials
32{
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37MeshMaterialSynchronizer::
38MeshMaterialSynchronizer(IMeshMaterialMng* material_mng)
39: TraceAccessor(material_mng->traceMng())
40, m_material_mng(material_mng)
41{
42 if (Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACC_MAT_SYNCHRONIZER", true)) {
43 m_synchronizer = new AcceleratorMeshMaterialSynchronizerImpl(material_mng);
44 info() << "using ACC material synchronizer";
45 }
46 else {
47 m_synchronizer = new LegacyMeshMaterialSynchronizerImpl(material_mng);
48 info() << "using DEFAULT material synchronizer";
49 }
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55MeshMaterialSynchronizer::
56~MeshMaterialSynchronizer()
57{
58 delete m_synchronizer;
59}
60
61/*---------------------------------------------------------------------------*/
62/*---------------------------------------------------------------------------*/
63
64bool MeshMaterialSynchronizer::
65synchronizeMaterialsInCells()
66{
67 return m_synchronizer->synchronizeMaterialsInCells();
68}
69
70/*---------------------------------------------------------------------------*/
71/*---------------------------------------------------------------------------*/
72
73/*!
74 * \brief Checks that material cells are consistent between subdomains.
75 * This method is collective
76 */
77void MeshMaterialSynchronizer::
78checkMaterialsInCells(Integer max_print)
79{
80 /*
81 To do this, we use a cell variable and apply
82 the following algorithm for each material:
83 - the owning subdomain fills this variable
84 with the material index
85 - the variable is synchronized.
86 - each subdomain then checks for every cell
87 that if the variable has the material index, then
88 this material is present.
89 */
90
91 IMesh* mesh = m_material_mng->mesh();
92 if (!mesh->parallelMng()->isParallel())
93 return;
94 m_material_mng->checkValid();
95
96 info(4) << "CheckMaterialsInCells";
97
98 VariableCellInt32 indexes(VariableBuildInfo(mesh, "ArcaneMaterialPresenceIndexes"));
99 _checkComponents(indexes, m_material_mng->materialsAsComponents(), max_print);
100 _checkComponents(indexes, m_material_mng->environmentsAsComponents(), max_print);
101
102 VariableCellInt64 hashes(VariableBuildInfo(mesh, "ArcaneMaterialCheckHashes"));
103 _checkComponentsInGhostCells(hashes, max_print);
104}
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108
109void MeshMaterialSynchronizer::
110_checkComponents(VariableCellInt32& indexes,
111 ConstArrayView<IMeshComponent*> components,
112 Integer max_print)
113{
114 IMesh* mesh = m_material_mng->mesh();
115 Integer nb_component = components.size();
116 Integer nb_error = 0;
117
118 info() << "Checking components nb=" << nb_component;
119
120 CellToAllEnvCellConverter all_env_cell_converter(m_material_mng);
121
122 for (Integer i = 0; i < nb_component; ++i) {
123 indexes.fill(-1);
124 IMeshComponent* c = components[i];
125 ENUMERATE_COMPONENTCELL (iccell, c) {
126 ComponentCell cc = *iccell;
127 indexes[cc.globalCell()] = i;
128 }
129
130 indexes.synchronize();
131
132 ENUMERATE_ALLENVCELL (iallenvcell, m_material_mng, mesh->allCells()) {
133 AllEnvCell all_env_cell = *iallenvcell;
134 Cell cell = all_env_cell.globalCell();
135 bool has_sync_mat = (indexes[cell] == i);
136 ComponentCell cc = c->findComponentCell(all_env_cell);
137 bool has_component = !cc.null();
138 if (has_sync_mat != has_component) {
139 ++nb_error;
140 if (max_print < 0 || nb_error < max_print)
141 error() << "Bad component synchronisation for i=" << i
142 << " name=" << c->name()
143 << " cell_uid=" << cell.uniqueId()
144 << " sync_mat=" << has_sync_mat
145 << " has_component=" << has_component;
146 }
147 }
148 }
149 if (nb_error != 0)
150 ARCANE_FATAL("Bad synchronisation");
151}
152
153void MeshMaterialSynchronizer::
154_checkComponentsInGhostCells(VariableCellInt64& hashes, Integer max_print)
155{
156 IMesh* mesh = m_material_mng->mesh();
157 Integer nb_error = 0;
158
159 ENUMERATE_ALLENVCELL (iallenvcell, m_material_mng, mesh->ownCells()) {
160 AllEnvCell all_env_cell = *iallenvcell;
161 Cell cell = all_env_cell.globalCell();
162
163 IntegerHashSuite hash_suite;
164
165 Int32 nb_env = all_env_cell.nbEnvironment();
166 hash_suite.add(nb_env);
167
168 for (Integer i = 0; i < nb_env; ++i) {
169 EnvCell env_cell = all_env_cell.cell(i);
170 Int32 nb_matt = env_cell.nbMaterial();
171 hash_suite.add(nb_matt);
172
173 for (Integer j = 0; j < nb_matt; ++j) {
174 MatCell mat = env_cell.cell(j);
175 Int32 id = mat.materialId();
176 hash_suite.add(id);
177 }
178 }
179
180 hashes[cell] = hash_suite.hash();
181 }
182
183 hashes.synchronize();
184
185 ENUMERATE_ALLENVCELL (iallenvcell, m_material_mng, mesh->allCells()) {
186 AllEnvCell all_env_cell = *iallenvcell;
187 Cell cell = all_env_cell.globalCell();
188 if (cell.isOwn())
189 continue;
190
191 IntegerHashSuite hash_suite;
192
193 Int32 nb_env = all_env_cell.nbEnvironment();
194 hash_suite.add(nb_env);
195
196 for (Integer i = 0; i < nb_env; ++i) {
197 EnvCell env_cell = all_env_cell.cell(i);
198 Int32 nb_matt = env_cell.nbMaterial();
199 hash_suite.add(nb_matt);
200
201 for (Integer j = 0; j < nb_matt; ++j) {
202 MatCell mat = env_cell.cell(j);
203 Int32 id = mat.materialId();
204 hash_suite.add(id);
205 }
206 }
207 if (hashes[cell] != hash_suite.hash()) {
208 nb_error++;
209 if (max_print < 0 || nb_error < max_print) {
210 error() << "Bad components synchronization -- Cell : " << cell << " -- Hash : " << hash_suite.hash();
211 }
212 }
213 }
214 if (nb_error != 0)
215 ARCANE_FATAL("Bad components synchronization -- Nb error : {0}", nb_error);
216}
217
218/*---------------------------------------------------------------------------*/
219/*---------------------------------------------------------------------------*/
220
221} // End namespace Arcane::Materials
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
__host__ __device__ bool null() const
Indicates if it is the null cell.
Interface for the material and environment manager of a mesh.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro to iterate over all AllEnvCell cells of a group.
#define ENUMERATE_COMPONENTCELL(iname, component)
Macro to iterate over all ComponentCell cells of a component.
MeshVariableScalarRefT< Cell, Int64 > VariableCellInt64
Quantity at the cell center of 64-bit integer type.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Quantity at the cell center of 32-bit integer type.
Always enables tracing in Arcane parts concerning materials.
Int32 Integer
Type representing an integer.
@ Cell
The mesh is AMR by cell.
Definition MeshKind.h:53