Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
LegacyMeshMaterialSynchronizerImpl.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/* MeshMaterialSynchronizerImpl.cc (C) 2000-2024 */
9/* */
10/* Synchronization of material entities. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/materials/internal/LegacyMeshMaterialSynchronizerImpl.h"
15
16#include "arcane/core/VariableTypes.h"
17#include "arcane/core/IParallelMng.h"
18#include "arcane/core/ItemPrinter.h"
19#include "arcane/core/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 The algorithm used is as follows:
92
93 We use a cell variable that uses a bit for each material to indicate its
94 presence: if this bit is set, the material is present; otherwise, it is
95 absent. The variable used is therefore of type ArrayByte per cell. The
96 _hasBit() and _setBit() methods allow positioning the bit for a given
97 material.
98
99 1. The subdomain fills this variable for these cells.
100 2. The variable is synchronized.
101 3. The subdomain compares this material presence table for each of its
102 ghost cells and adds/removes materials based on this table.
103 */
104 IMesh* mesh = m_material_mng->mesh();
105 if (!mesh->parallelMng()->isParallel())
106 return false;
107
108 ConstArrayView<IMeshMaterial*> materials = m_material_mng->materials();
109 Integer nb_mat = materials.size();
110 VariableCellArrayByte mat_presence(VariableBuildInfo(mesh, "ArcaneMaterialSyncPresence"));
111 Integer dim2_size = nb_mat / 8;
112 if ((nb_mat % 8) != 0)
113 ++dim2_size;
114 mat_presence.resize(dim2_size);
115 info(4) << "Resize presence variable nb_mat=" << nb_mat << " dim2=" << dim2_size;
116 CellToAllEnvCellConverter cell_converter = m_material_mng->cellToAllEnvCellConverter();
117 ENUMERATE_CELL (icell, mesh->ownCells()) {
118 ByteArrayView presence = mat_presence[icell];
119 presence.fill(0);
120 AllEnvCell all_env_cell = cell_converter[*icell];
121 _fillPresence(all_env_cell, presence);
122 }
123
124 bool has_changed = false;
125
126 mat_presence.synchronize();
127 {
128 ByteUniqueArray before_presence(dim2_size);
129 UniqueArray<UniqueArray<Int32>> to_add(nb_mat);
130 UniqueArray<UniqueArray<Int32>> to_remove(nb_mat);
131 ENUMERATE_CELL (icell, mesh->allCells()) {
132 Cell cell = *icell;
133 // Only processes ghost cells.
134 if (cell.isOwn())
135 continue;
136 Int32 cell_lid = cell.localId();
137 AllEnvCell all_env_cell = cell_converter[cell];
138 before_presence.fill(0);
139 _fillPresence(all_env_cell, before_presence);
140 ByteConstArrayView after_presence = mat_presence[cell];
141 // Adds/Removes this cell from materials if necessary.
142 for (Integer imat = 0; imat < nb_mat; ++imat) {
143 bool has_before = _hasBit(before_presence, imat);
144 bool has_after = _hasBit(after_presence, imat);
145 if (has_before && !has_after) {
146 to_remove[imat].add(cell_lid);
147 }
148 else if (has_after && !has_before)
149 to_add[imat].add(cell_lid);
150 }
151 }
152
153 MeshMaterialModifier modifier(m_material_mng);
154 for (Integer i = 0; i < nb_mat; ++i) {
155 if (!to_add[i].empty()) {
156 modifier.addCells(materials[i], to_add[i]);
157 has_changed = true;
158 }
159 if (!to_remove[i].empty()) {
160 modifier.removeCells(materials[i], to_remove[i]);
161 has_changed = true;
162 }
163 }
164 }
165 return has_changed;
166}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
171} // End namespace Arcane::Materials
172
173/*---------------------------------------------------------------------------*/
174/*---------------------------------------------------------------------------*/
#define ENUMERATE_CELL(name, group)
Generic enumerator for a cell group.
void fill(const T &o) noexcept
Fills the array with the value o.
Interface for the material and environment manager of a mesh.
#define ENUMERATE_CELL_MATCELL(iname, env_cell)
Macro to iterate over all MatCell cells of a cell.
#define ENUMERATE_CELL_ENVCELL(iname, all_env_cell)
Macro to iterate over all EnvCell cells of a cell.
MeshVariableArrayRefT< Cell, Byte > VariableCellArrayByte
Quantity at cell centers of byte array type.
Always enables tracing in Arcane parts concerning materials.
ArrayView< Byte > ByteArrayView
C equivalent of a 1D array of characters.
Definition UtilsTypes.h:447
Int32 Integer
Type representing an integer.
UniqueArray< Byte > ByteUniqueArray
Dynamic 1D array of characters.
Definition UtilsTypes.h:335
ConstArrayView< Byte > ByteConstArrayView
C equivalent of a 1D array of characters.
Definition UtilsTypes.h:476
unsigned char Byte
Type of a byte.
Definition BaseTypes.h:43
@ Cell
The mesh is AMR by cell.
Definition MeshKind.h:53