Arcane  v3.15.3.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MeshMaterialSynchronizer.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* Synchronisation des entités des matériaux. */
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
36MeshMaterialSynchronizer::
37MeshMaterialSynchronizer(IMeshMaterialMng* material_mng)
38: TraceAccessor(material_mng->traceMng())
39, m_material_mng(material_mng)
40{
41 if (Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ACC_MAT_SYNCHRONIZER", true)) {
42 m_synchronizer = new AcceleratorMeshMaterialSynchronizerImpl(material_mng);
43 info() << "using ACC material synchronizer";
44 }
45 else {
46 m_synchronizer = new LegacyMeshMaterialSynchronizerImpl(material_mng);
47 info() << "using DEFAULT material synchronizer";
48 }
49}
50
51/*---------------------------------------------------------------------------*/
52/*---------------------------------------------------------------------------*/
53
54MeshMaterialSynchronizer::
55~MeshMaterialSynchronizer()
56{
57 delete m_synchronizer;
58}
59
60/*---------------------------------------------------------------------------*/
61/*---------------------------------------------------------------------------*/
62
63bool MeshMaterialSynchronizer::
64synchronizeMaterialsInCells()
65{
66 return m_synchronizer->synchronizeMaterialsInCells();
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71/*!
72 * \brief Vérifie que les mailles des matériaux sont bien cohérentes entre les
73 * sous-domaines.
74 * Cette méthode est collective
75 */
76void MeshMaterialSynchronizer::
77checkMaterialsInCells(Integer max_print)
78{
79 /*
80 Pour cela, on utilise une variable aux mailles et on applique
81 l'algorithme suivant pour chaque matériau:
82 - le sous-domaine propriétaire remplit cette variable
83 avec l'indice du matériau
84 - la variable est synchronisée.
85 - chaque sous-domaine vérifie ensuite pour chaque maille
86 que si la variable a pour valeur l'indice du matériau, alors
87 ce matériau est présent.
88 */
89
90 IMesh* mesh = m_material_mng->mesh();
91 if (!mesh->parallelMng()->isParallel())
92 return;
93 m_material_mng->checkValid();
94
95 info(4) << "CheckMaterialsInCells";
96
97 VariableCellInt32 indexes(VariableBuildInfo(mesh,"ArcaneMaterialPresenceIndexes"));
98 _checkComponents(indexes, m_material_mng->materialsAsComponents(), max_print);
99 _checkComponents(indexes, m_material_mng->environmentsAsComponents(), max_print);
100
101 VariableCellInt64 hashes(VariableBuildInfo(mesh, "ArcaneMaterialCheckHashes"));
102 _checkComponentsInGhostCells(hashes, max_print);
103}
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108void MeshMaterialSynchronizer::
109_checkComponents(VariableCellInt32& indexes,
110 ConstArrayView<IMeshComponent*> components,
111 Integer max_print)
112{
113 IMesh* mesh = m_material_mng->mesh();
114 Integer nb_component = components.size();
115 Integer nb_error = 0;
116
117 info() << "Checking components nb=" << nb_component;
118
119 CellToAllEnvCellConverter all_env_cell_converter(m_material_mng);
120
121 for( Integer i=0; i<nb_component; ++i ){
122 indexes.fill(-1);
123 IMeshComponent* c = components[i];
124 ENUMERATE_COMPONENTCELL(iccell,c){
125 ComponentCell cc = *iccell;
126 indexes[cc.globalCell()] = i;
127 }
128
129 indexes.synchronize();
130
131 ENUMERATE_ALLENVCELL(iallenvcell,m_material_mng,mesh->allCells()){
132 AllEnvCell all_env_cell = *iallenvcell;
133 Cell cell = all_env_cell.globalCell();
134 bool has_sync_mat = (indexes[cell]==i);
135 ComponentCell cc = c->findComponentCell(all_env_cell);
136 bool has_component = !cc.null();
137 if (has_sync_mat!=has_component){
138 ++nb_error;
139 if (max_print<0 || nb_error<max_print)
140 error() << "Bad component synchronisation for i=" << i
141 << " name=" << c->name()
142 << " cell_uid=" << cell.uniqueId()
143 << " sync_mat=" << has_sync_mat
144 << " has_component=" << has_component;
145 }
146 }
147 }
148 if (nb_error!=0)
149 ARCANE_FATAL("Bad synchronisation");
150}
151
152void MeshMaterialSynchronizer::
153_checkComponentsInGhostCells(VariableCellInt64& hashes, Integer max_print)
154{
155 IMesh* mesh = m_material_mng->mesh();
156 Integer nb_error = 0;
157
158 ENUMERATE_ALLENVCELL (iallenvcell, m_material_mng, mesh->ownCells()) {
159 AllEnvCell all_env_cell = *iallenvcell;
160 Cell cell = all_env_cell.globalCell();
161
162 IntegerHashSuite hash_suite;
163
164 Int32 nb_env = all_env_cell.nbEnvironment();
165 hash_suite.add(nb_env);
166
167 for (Integer i = 0; i < nb_env; ++i) {
168 EnvCell env_cell = all_env_cell.cell(i);
169 Int32 nb_matt = env_cell.nbMaterial();
170 hash_suite.add(nb_matt);
171
172 for (Integer j = 0; j < nb_matt; ++j) {
173 MatCell mat = env_cell.cell(j);
174 Int32 id = mat.materialId();
175 hash_suite.add(id);
176 }
177 }
178
179 hashes[cell] = hash_suite.hash();
180 }
181
182 hashes.synchronize();
183
184 ENUMERATE_ALLENVCELL (iallenvcell, m_material_mng, mesh->allCells()) {
185 AllEnvCell all_env_cell = *iallenvcell;
186 Cell cell = all_env_cell.globalCell();
187 if (cell.isOwn())
188 continue;
189
190 IntegerHashSuite hash_suite;
191
192 Int32 nb_env = all_env_cell.nbEnvironment();
193 hash_suite.add(nb_env);
194
195 for (Integer i = 0; i < nb_env; ++i) {
196 EnvCell env_cell = all_env_cell.cell(i);
197 Int32 nb_matt = env_cell.nbMaterial();
198 hash_suite.add(nb_matt);
199
200 for (Integer j = 0; j < nb_matt; ++j) {
201 MatCell mat = env_cell.cell(j);
202 Int32 id = mat.materialId();
203 hash_suite.add(id);
204 }
205 }
206 if (hashes[cell] != hash_suite.hash()) {
207 nb_error++;
208 if (max_print < 0 || nb_error < max_print) {
209 error() << "Bad components synchronization -- Cell : " << cell << " -- Hash : " << hash_suite.hash();
210 }
211 }
212 }
213 if (nb_error != 0)
214 ARCANE_FATAL("Bad components synchronization -- Nb error : {0}", nb_error);
215}
216
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219
220} // End namespace Arcane::Materials
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
__host__ __device__ bool null() const
Indique s'il s'agit de la maille nulle.
Référence à une instance.
#define ENUMERATE_ALLENVCELL(iname,...)
Macro pour itérer sur toutes les mailles AllEnvCell d'un groupe.
#define ENUMERATE_COMPONENTCELL(iname, component)
Macro pour itérer sur toutes les mailles d'un composant.
MeshVariableScalarRefT< Cell, Int64 > VariableCellInt64
Grandeur au centre des mailles de type entier 64 bits.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Grandeur au centre des mailles de type entier 32 bits.
Active toujours les traces dans les parties Arcane concernant les matériaux.
Int32 Integer
Type représentant un entier.