Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
LegacyMeshMaterialSynchronizerImpl.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 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/* MeshMaterialSynchronizerImpl.cc (C) 2000-2024 */
9/* */
10/* Synchronisation des entités des matériaux. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/LegacyMeshMaterialSynchronizerImpl.h"
15
16#include "arcane/VariableTypes.h"
17#include "arcane/IParallelMng.h"
18#include "arcane/ItemPrinter.h"
19#include "arcane/IMesh.h"
20
21#include "arcane/materials/CellToAllEnvCellConverter.h"
22#include "arcane/materials/MatItemEnumerator.h"
23#include "arcane/materials/MeshMaterialModifier.h"
24
25#include "arcane/core/ItemGenericInfoListView.h"
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane::Materials
31{
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35LegacyMeshMaterialSynchronizerImpl::
36LegacyMeshMaterialSynchronizerImpl(IMeshMaterialMng* material_mng)
37: TraceAccessor(material_mng->traceMng())
38, m_material_mng(material_mng)
39{
40}
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45LegacyMeshMaterialSynchronizerImpl::
46~LegacyMeshMaterialSynchronizerImpl()
47{
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53inline void LegacyMeshMaterialSynchronizerImpl::
54_setBit(ByteArrayView bytes, Integer position)
55{
56 Integer offset = position / 8;
57 Integer bit = position % 8;
58 bytes[offset] |= (Byte)(1 << bit);
59}
60
61inline bool LegacyMeshMaterialSynchronizerImpl::
62_hasBit(ByteConstArrayView bytes, Integer position)
63{
64 Integer offset = position / 8;
65 Integer bit = position % 8;
66 return bytes[offset] & (1 << bit);
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72void LegacyMeshMaterialSynchronizerImpl::
73_fillPresence(AllEnvCell all_env_cell, ByteArrayView presence)
74{
75 ENUMERATE_CELL_ENVCELL (ienvcell, all_env_cell) {
76 ENUMERATE_CELL_MATCELL (imatcell, (*ienvcell)) {
77 MatCell mc = *imatcell;
78 Integer mat_index = mc.materialId();
79 _setBit(presence, mat_index);
80 }
81 }
82}
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87bool LegacyMeshMaterialSynchronizerImpl::
88synchronizeMaterialsInCells()
89{
90 /*
91 L'algorithme utilisé est le suivant:
92
93 On utilise une variable aux mailles qui utilise un bit pour chaque
94 matériau pour indiquer sa présence: si ce bit est positionné, le matériau
95 est présent, sinon il est absent. La variable utilisée est donc de type
96 ArrayByte aux mailles. Les méthodes _hasBit() et _setBit() permettent
97 de positionner le bit d'un matériau donné.
98
99 1. Le sous-domaine remplit cette variables pour ces mailles.
100 2. La variable est synchronisée.
101 3. Le sous-domaine compare pour chacune de ses mailles fantômes
102 ce tableau de présence des matériaux et ajoute/supprime les matériaux en fonction
103 de ce tableau.
104 */
105 IMesh* mesh = m_material_mng->mesh();
106 if (!mesh->parallelMng()->isParallel())
107 return false;
108
109 ConstArrayView<IMeshMaterial*> materials = m_material_mng->materials();
110 Integer nb_mat = materials.size();
111 VariableCellArrayByte mat_presence(VariableBuildInfo(mesh, "ArcaneMaterialSyncPresence"));
112 Integer dim2_size = nb_mat / 8;
113 if ((nb_mat % 8) != 0)
114 ++dim2_size;
115 mat_presence.resize(dim2_size);
116 info(4) << "Resize presence variable nb_mat=" << nb_mat << " dim2=" << dim2_size;
117 CellToAllEnvCellConverter cell_converter = m_material_mng->cellToAllEnvCellConverter();
118 ENUMERATE_CELL (icell, mesh->ownCells()) {
119 ByteArrayView presence = mat_presence[icell];
120 presence.fill(0);
121 AllEnvCell all_env_cell = cell_converter[*icell];
122 _fillPresence(all_env_cell, presence);
123 }
124
125 bool has_changed = false;
126
127 mat_presence.synchronize();
128 {
129 ByteUniqueArray before_presence(dim2_size);
130 UniqueArray<UniqueArray<Int32>> to_add(nb_mat);
131 UniqueArray<UniqueArray<Int32>> to_remove(nb_mat);
132 ENUMERATE_CELL (icell, mesh->allCells()) {
133 Cell cell = *icell;
134 // Ne traite que les mailles fantomes.
135 if (cell.isOwn())
136 continue;
137 Int32 cell_lid = cell.localId();
138 AllEnvCell all_env_cell = cell_converter[cell];
139 before_presence.fill(0);
140 _fillPresence(all_env_cell, before_presence);
141 ByteConstArrayView after_presence = mat_presence[cell];
142 // Ajoute/Supprime cette maille des matériaux si besoin.
143 for (Integer imat = 0; imat < nb_mat; ++imat) {
144 bool has_before = _hasBit(before_presence, imat);
145 bool has_after = _hasBit(after_presence, imat);
146 if (has_before && !has_after) {
147 to_remove[imat].add(cell_lid);
148 }
149 else if (has_after && !has_before)
150 to_add[imat].add(cell_lid);
151 }
152 }
153
154 MeshMaterialModifier modifier(m_material_mng);
155 for (Integer i = 0; i < nb_mat; ++i) {
156 if (!to_add[i].empty()) {
157 modifier.addCells(materials[i], to_add[i]);
158 has_changed = true;
159 }
160 if (!to_remove[i].empty()) {
161 modifier.removeCells(materials[i], to_remove[i]);
162 has_changed = true;
163 }
164 }
165 }
166 return has_changed;
167}
168
169} // End namespace Arcane::Materials
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
void fill(const T &o) noexcept
Remplit le tableau avec la valeur o.
#define ENUMERATE_CELL_MATCELL(iname, env_cell)
Macro pour itérer sur tous les matériaux d'une maille.
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro pour itérer sur tous les milieux d'une maille.
MeshVariableArrayRefT< Cell, Byte > VariableCellArrayByte
Grandeur au centre des mailles de type tableau d'octet.
Active toujours les traces dans les parties Arcane concernant les matériaux.
UniqueArray< Byte > ByteUniqueArray
Tableau dynamique à une dimension de caractères.
Definition UtilsTypes.h:509
ConstArrayView< Byte > ByteConstArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:634
ArrayView< Byte > ByteArrayView
Equivalent C d'un tableau à une dimension de caractères.
Definition UtilsTypes.h:605
unsigned char Byte
Type d'un octet.
Definition UtilsTypes.h:142
Int32 Integer
Type représentant un entier.