Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
ConstituentItem.h
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/* ConstituentItem.h (C) 2000-2025 */
9/* */
10/* Entity representing a constituent of a multi-material cell. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_MATERIALS_CONSTITUENTITEM_H
13#define ARCANE_CORE_MATERIALS_CONSTITUENTITEM_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/core/materials/ComponentItemInternal.h"
18
19#include "arcane/core/Item.h"
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24namespace Arcane::Materials
25{
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30/*!
31 * \ingroup ArcaneMaterials
32 * \brief Represents a component of a multi-material cell.
33 *
34 * This object represents a component of a multi-material cell. By
35 * component, we mean a material (MatCell), an environment (EnvCell), or
36 * an allenvcell (AllEnvCell).
37 *
38 * There is a notion of hierarchy between these components, and it is
39 * possible to retrieve the higher-level ConstituentItem via
40 * superCell(). To iterate over lower-level elements, it is possible to
41 * use the macro ENUMERATE_CELL_COMPONENTCELL()
42 *
43 * There is a special cell, called the null cell, for which
44 * null() is true and which represents an invalid cell. In the case of
45 * the invalid cell, no other methods of the class should be called
46 * under penalty of causing a crash.
47 *
48 * \warning These meshes are invalidated as soon as the list of cells of
49 * a material or an environment changes. Therefore, a cell of this type
50 * should not be kept between two changes to this list.
51 */
52class ARCANE_CORE_EXPORT ConstituentItem
53{
54 // For accessing _internal()
55 friend CellComponentCellEnumerator;
56 friend EnvCellVector;
57 friend MatCellVector;
58 friend MeshMaterialMng;
59 friend AllEnvCell;
60 friend EnvCell;
61 friend MatCell;
62 friend ConstituentItemVectorImpl;
63
64 public:
65
66 ARCCORE_HOST_DEVICE ConstituentItem(const matimpl::ConstituentItemBase& mii)
67 : m_constituent_item_index(mii.m_constituent_item_index)
68 , m_shared_info(mii.m_shared_info)
69 {}
70
71 ARCCORE_HOST_DEVICE ConstituentItem()
72 {
73#ifndef ARCCORE_DEVICE_CODE
74 m_shared_info = ComponentItemSharedInfo::_nullInstance();
75#endif
76 }
77
78 public:
79
80 //! Conversion operator to a ComponentItemLocalId
81 ARCCORE_HOST_DEVICE operator ComponentItemLocalId() const { return ComponentItemLocalId{ _varIndex() }; }
82
83 public:
84
85 //! \internal
86 ARCCORE_HOST_DEVICE MatVarIndex _varIndex() const { return m_shared_info->_varIndex(m_constituent_item_index); }
87
88 ARCCORE_HOST_DEVICE matimpl::ConstituentItemBase constituentItemBase() const { return { m_shared_info, m_constituent_item_index }; }
89
90 /*!
91 * \brief Associated constituent.
92 * \pre null()==false
93 */
94 IMeshComponent* component() const { return m_shared_info->_component(m_constituent_item_index); }
95
96 //! Component identifier in the list of components of this type.
97 ARCCORE_HOST_DEVICE Int32 componentId() const { return m_shared_info->_componentId(m_constituent_item_index); }
98
99 //! Indicates if it is the null cell
100 ARCCORE_HOST_DEVICE bool null() const { return m_constituent_item_index.isNull(); }
101
102 //! Higher-level cell in the hierarchy
103 ARCCORE_HOST_DEVICE ComponentCell superCell() const { return ComponentCell(_superItemBase()); }
104
105 //! Hierarchical level of the entity
106 ARCCORE_HOST_DEVICE Int32 level() const { return m_shared_info->m_level; }
107
108 //! Number of sub-elements
109 ARCCORE_HOST_DEVICE Int32 nbSubItem() const { return m_shared_info->_nbSubConstituent(m_constituent_item_index); }
110
111 //! Global cell
113 {
114 return Cell(m_shared_info->_globalItemBase(m_constituent_item_index));
115 }
116
117 //! localId() of the global cell
118 ARCCORE_HOST_DEVICE CellLocalId globalCellId() const
119 {
120 return CellLocalId(m_shared_info->_globalItemId(m_constituent_item_index));
121 }
122
123 /*!
124 * \brief Unique number of the constituent entity.
125 *
126 * This number is unique for each constituent of each cell.
127 *
128 * \warning This unique number is not the same as that of the associated global cell.
129 */
130 Int64 componentUniqueId() const { return m_shared_info->_componentUniqueId(m_constituent_item_index); }
131
132 //! List of sub-constituents of this entity
133 ARCCORE_HOST_DEVICE inline CellComponentCellEnumerator subItems() const;
134
135 //! Output operator
136 ARCANE_CORE_EXPORT friend std::ostream&
137 operator<<(std::ostream& o, const ComponentCell& mvi);
138
139 protected:
140
141 static ARCCORE_HOST_DEVICE void _checkLevel([[maybe_unused]] matimpl::ConstituentItemBase item_base,
142 [[maybe_unused]] Int32 expected_level)
143 {
144#if !defined(ARCCORE_DEVICE_CODE)
145 if (item_base.null())
146 return;
147 Int32 lvl = item_base.level();
148 if (lvl != expected_level)
149 _badConversion(item_base, lvl, expected_level);
150#endif
151 }
152 static void _badConversion(matimpl::ConstituentItemBase item_base, Int32 level, Int32 expected_level);
153
154 ARCCORE_HOST_DEVICE matimpl::ConstituentItemBase _subItemBase(Int32 index) const
155 {
156 return m_shared_info->_subItemBase(m_constituent_item_index, index);
157 }
158 ARCCORE_HOST_DEVICE matimpl::ConstituentItemBase _superItemBase() const
159 {
160 return m_shared_info->_superItemBase(m_constituent_item_index);
161 }
162 ARCCORE_HOST_DEVICE ConstituentItemIndex _firstSubConstituentLocalId() const
163 {
164 return m_shared_info->_firstSubConstituentLocalId(m_constituent_item_index);
165 }
166
167 protected:
168
169 ConstituentItemIndex m_constituent_item_index;
170 ComponentItemSharedInfo* m_shared_info = nullptr;
171
172 private:
173
174 //! \internal
175 ARCCORE_HOST_DEVICE ConstituentItemIndex _constituentItemIndex() const
176 {
177 return m_constituent_item_index;
178 }
179};
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
184/*!
185 * \brief Enumerator over the constituents of a cell.
186 */
187class ARCANE_CORE_EXPORT CellComponentCellEnumerator
188{
189 friend class EnumeratorTracer;
190
191 public:
192
194 {};
195 class Iterator
196 {
197 friend class CellComponentCellEnumerator;
198
199 public:
200
201 using iterator_category = std::forward_iterator_tag;
202 using value_type = ComponentCell;
203
204 private:
205
206 ARCCORE_HOST_DEVICE explicit Iterator(CellComponentCellEnumerator enumerator)
207 : m_index(enumerator.m_index)
208 , m_size(enumerator.m_size)
209 , m_first_sub_index(enumerator.m_first_sub_index)
210 , m_sub_constituent_shared_info(enumerator.m_sub_constituent_shared_info)
211 {}
212
213 public:
214
215 ARCCORE_HOST_DEVICE void operator++() { ++m_index; }
216 ARCCORE_HOST_DEVICE ComponentCell operator*() const
217 {
218 ARCANE_CHECK_AT(m_index, m_size);
219 return ComponentCell(_currentSubItemBase());
220 }
221 ARCCORE_HOST_DEVICE operator ComponentItemLocalId() const
222 {
223 return ComponentItemLocalId(_varIndex());
224 }
225 friend ARCCORE_HOST_DEVICE bool operator==(const Iterator& x, const Sentinel&)
226 {
227 return x.m_index == x.m_size;
228 }
229
230 private:
231
232 Int32 m_index = 0;
233 Int32 m_size = 0;
234 Int32 m_first_sub_index = -1;
235 ComponentItemSharedInfo* m_sub_constituent_shared_info = nullptr;
236
237 private:
238
239 ARCCORE_HOST_DEVICE matimpl::ConstituentItemBase _currentSubItemBase() const
240 {
241 return m_sub_constituent_shared_info->_item(ConstituentItemIndex(m_first_sub_index + m_index));
242 }
243 ARCCORE_HOST_DEVICE MatVarIndex _varIndex() const
244 {
245 return m_sub_constituent_shared_info->_varIndex(ConstituentItemIndex(m_first_sub_index + m_index));
246 }
247 };
248
249 template <typename ConstituentItemType>
250 class IteratorT : public Iterator
251 {
252 public:
253
254 using value_type = ConstituentItemType;
255 friend class CellComponentCellEnumeratorT<ConstituentItemType>;
256
257 private:
258
259 ARCCORE_HOST_DEVICE explicit IteratorT(CellComponentCellEnumeratorT<ConstituentItemType> enumerator)
260 : Iterator(enumerator)
261 {}
262
263 public:
264
265 ARCCORE_HOST_DEVICE ConstituentItemType operator*() const
266 {
267 ARCANE_CHECK_AT(m_index, m_size);
268 return ConstituentItemType(_currentSubItemBase());
269 }
270 };
271
272 public:
273
274 ARCCORE_HOST_DEVICE explicit CellComponentCellEnumerator(ComponentCell super_item)
275 : m_size(super_item.nbSubItem())
276 , m_first_sub_index(super_item._firstSubConstituentLocalId().localId())
277 , m_sub_constituent_shared_info(super_item.m_shared_info->m_sub_component_item_shared_info)
278 {
279 }
280
281 public:
282
283 ARCCORE_HOST_DEVICE void operator++() { ++m_index; }
284 ARCCORE_HOST_DEVICE bool hasNext() const { return m_index < m_size; }
285
286 ARCCORE_HOST_DEVICE ComponentCell operator*() const
287 {
288 ARCANE_CHECK_AT(m_index, m_size);
289 return ComponentCell(_currentSubItemBase());
290 }
291 ARCCORE_HOST_DEVICE MatVarIndex _varIndex() const
292 {
293 return m_sub_constituent_shared_info->_varIndex(ConstituentItemIndex(m_first_sub_index + m_index));
294 }
295 ARCCORE_HOST_DEVICE Int32 index() const { return m_index; }
296 ARCCORE_HOST_DEVICE operator ComponentItemLocalId() const
297 {
298 return ComponentItemLocalId(_varIndex());
299 }
300 ARCCORE_HOST_DEVICE Iterator begin() const { return Iterator(*this); }
301 ARCCORE_HOST_DEVICE Sentinel end() const { return {}; }
302
303 protected:
304
305 Int32 m_index = 0;
306 Int32 m_size = 0;
307 Int32 m_first_sub_index = -1;
308 ComponentItemSharedInfo* m_sub_constituent_shared_info = nullptr;
309
310 protected:
311
312 ARCCORE_HOST_DEVICE matimpl::ConstituentItemBase _currentSubItemBase() const
313 {
314 return m_sub_constituent_shared_info->_item(ConstituentItemIndex(m_first_sub_index + m_index));
315 }
316};
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321/*!
322 * \brief Typed enumerator over the component cells of a cell.
323 */
324template <typename ComponentCellType> class CellComponentCellEnumeratorT
325: public CellComponentCellEnumerator
326{
327 public:
328
330
331 public:
332
333 explicit ARCCORE_HOST_DEVICE CellComponentCellEnumeratorT(ComponentCell super_item)
334 : CellComponentCellEnumerator(super_item)
335 {}
336
337 public:
338
339 ARCCORE_HOST_DEVICE ComponentCellType operator*() const
340 {
341 ARCANE_CHECK_AT(m_index, m_size);
342 return ComponentCellType(_currentSubItemBase());
343 }
344 ARCCORE_HOST_DEVICE IteratorType begin() const { return IteratorType(*this); }
345 ARCCORE_HOST_DEVICE Sentinel end() const { return {}; }
346};
347
348/*---------------------------------------------------------------------------*/
349/*---------------------------------------------------------------------------*/
350
351ARCCORE_HOST_DEVICE CellComponentCellEnumerator ComponentCell::
352subItems() const
353{
354 return CellComponentCellEnumerator(*this);
355}
356
357/*---------------------------------------------------------------------------*/
358/*---------------------------------------------------------------------------*/
359
360} // End namespace Arcane::Materials
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365#endif
Cell of a mesh.
Definition Item.h:1300
Typed enumerator over the component cells of a cell.
Enumerator over the constituents of a cell.
__host__ __device__ CellLocalId globalCellId() const
localId() of the global cell
__host__ __device__ bool null() const
Indicates if it is the null cell.
__host__ __device__ Int32 componentId() const
Component identifier in the list of components of this type.
Int64 componentUniqueId() const
Unique number of the constituent entity.
__host__ __device__ Int32 nbSubItem() const
Number of sub-elements.
__host__ __device__ CellComponentCellEnumerator subItems() const
List of sub-constituents of this entity.
Cell globalCell() const
Global cell.
__host__ __device__ ComponentCell superCell() const
Higher-level cell in the hierarchy.
IMeshComponent * component() const
Associated constituent.
__host__ __device__ Int32 level() const
Hierarchical level of the entity.
Interface of a component (material or environment) of a mesh.
Represents an index on material and environment variables.
Always enables tracing in Arcane parts concerning materials.
std::int64_t Int64
Signed integer type of 64 bits.
std::int32_t Int32
Signed integer type of 32 bits.