7#ifndef ARCANE_MESH_DUALUNIQUEIDMNG_H
8#define ARCANE_MESH_DUALUNIQUEIDMNG_H
13#include "arcane/utils/String.h"
14#include "arcane/utils/TraceAccessor.h"
103#include "arcane/Item.h"
104#include "arcane/utils/TraceAccessor.h"
105#include "arcane/utils/FatalErrorException.h"
116class ARCANE_MESH_EXPORT DualUniqueIdMng
125 static const Int64 node_code = 0;
126 static const Int64 face_code =
Int64(1) << 62;
127 static const Int64 cell_code =
Int64(1) << 61;
129 static const Int64 particle_code = (
Int64(1) << 61) + (
Int64(1) << 62);
131 bool m_use_dual_particle =
true;
133 DualUniqueIdMng(
ITraceMng* trace_mng,
bool use_dual_particle =
true)
135 , m_use_dual_particle(use_dual_particle)
138 ~DualUniqueIdMng() {}
146 template <
typename ItemT>
147 inline static Int64 uniqueIdOf(
const ItemT& item);
149 template <
typename ItemT>
150 inline Int64 debugUniqueIdOf(
const ItemT& item);
152 inline std::tuple<eItemKind, Int64> uniqueIdOfDualItem(
const DoF& item);
154 template <
typename ItemT>
155 inline static Int64 uniqueIdOf(
const ItemT& item,
const Integer rank);
157 template <
typename ItemT_1,
typename ItemT_2>
158 inline static Int64 uniqueIdOf(
const ItemT_1& item_1,
const ItemT_2& item_2);
160 inline std::pair<std::tuple<eItemKind, Int64>, std::tuple<eItemKind, Int64>> uniqueIdOfPairOfDualItems(
const DoF& item);
162 template <
typename ItemT_1,
typename ItemT_2>
163 inline static Int64 uniqueIdOf(
const ItemT_1& item_1,
const Integer item_1_rank,
164 const ItemT_2& item_2,
const Integer item_2_rank);
168 inline void info(
const DoF& node,
const Item& dual_item)
const;
169 inline void info(
const DoF& link,
const DoF& dual_node0,
const DoF& dual_node1,
const Item& dual_item0,
const Item& dual_item1)
const;
171 inline Int64 debugDualItemUniqueId(
DoF& node)
const;
175 template <
typename ItemT,
typename Type>
178 template <Integer Nbit,
typename Type>
179 inline static bool _onlyFirstBitUsed(
const Type id);
181 inline bool _checkDualNode(
const DoF& node,
const Item& dual_item)
const;
182 inline bool _checkLink(
const DoF& link,
const Item& dual_item0,
const Item& dual_item1)
const;
184 inline Int64 _extractFirstCode(
const Int64 id)
const;
185 inline Int64 _extractSecondCode(
const Int64 id)
const;
186 inline Int64 _extractFirstId(
const Int64 id)
const;
187 inline Int64 _extractSecondId(
const Int64 id)
const;
189 inline bool _codeIsValid(
const Item& item,
const Int64 code)
const;
190 inline bool _idIsValid(
const Item& item,
const Int64 id)
const;
200 static const Int64 code = 0;
240template <Integer Nbit,
typename Type>
243_onlyFirstBitUsed(
const Type id)
245 ARCANE_ASSERT((Nbit > 0), (
"Error template parameter Nbit <= 0"));
249 ARCANE_ASSERT((Nbit < nb_bit_max), (
"Error 8*sizeof(Type) <= Nbit"));
252 const Type Nbit_first_bits_nulls = ~((1 << Nbit) - 1);
255 return (Nbit_first_bits_nulls &
id) ==
Type(0);
261template <
typename ItemT>
264uniqueIdOf(
const ItemT& item)
266 ARCANE_ASSERT((8 *
sizeof(
Int64) == 64), (
"Int64 is not 64-bits"));
267 ARCANE_ASSERT((_onlyFirstBitUsed<29, Int64>(item.uniqueId())),
268 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
272 const Int64 unique_id = item.uniqueId();
274 return unique_id | traits_item_code<ItemT, Int64>::code;
277template <
typename ItemT>
280debugUniqueIdOf(
const ItemT& item)
282 ARCANE_ASSERT((8 *
sizeof(Int64) == 64), (
"Int64 is not 64-bits"));
283 ARCANE_ASSERT((_onlyFirstBitUsed<29, Int64>(item.uniqueId())),
284 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
288 const Int64 unique_id = item.uniqueId();
290 return unique_id | traits_item_code<ItemT, Int64>::code;
295uidToDualItemKind(
Int64 unique_id)
297 Int64 code = _extractSecondCode(unique_id);
299 if (code == face_code)
301 if (code == node_code)
303 if (code == cell_code)
305 if (m_use_dual_particle && code == particle_code)
307 else if (code == edge_code)
314codeToItemKind(
Int64 code)
316 if (code == face_code)
318 if (code == node_code)
320 if (code == cell_code)
322 if (m_use_dual_particle && code == particle_code)
324 else if (code == edge_code)
334 ARCANE_ASSERT((8 *
sizeof(
Int64) == 64), (
"Int64 is not 64-bits"));
335 ARCANE_ASSERT((_onlyFirstBitUsed<29, Int64>(item_uid)),
336 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
342 return item_uid | node_code;
344 return item_uid | face_code;
346 return item_uid | cell_code;
348 return item_uid | edge_code;
350 return item_uid | particle_code;
352 throw FatalErrorException(A_FUNCINFO,
"Item not defined in graph");
357inline std::tuple<eItemKind, Int64>
359uniqueIdOfDualItem(
const DoF& node)
361 ARCANE_ASSERT((8 *
sizeof(
Int64) == 64), (
"Int64 is not 64-bits"));
362 const Int64 node_id = node.uniqueId();
363 const Int64 dual_id = _extractFirstId(node_id);
364 eItemKind item_kind = uidToDualItemKind(node_id);
366 return std::make_tuple(item_kind, dual_id);
372template <
typename ItemT>
375uniqueIdOf(
const ItemT& item,
const Integer rank)
377 ARCANE_ASSERT((8 *
sizeof(
Int64) == 64), (
"Int64 is not 64-bits"));
378 ARCANE_ASSERT((_onlyFirstBitUsed<25, Int64>(item.uniqueId())),
379 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 25 bit)",
382 ARCANE_ASSERT((_onlyFirstBitUsed<4, Int64>(
Int64(rank))),
383 (String::format(
"rank={0} : invalid level (more than 4 bit)", rank).localstr()));
385 const Int64 unique_id = item.uniqueId();
393template <
typename ItemT_1,
typename ItemT_2>
396uniqueIdOf(
const ItemT_1& item_1,
const ItemT_2& item_2)
398 ARCANE_ASSERT((8 *
sizeof(
Int64) == 64), (
"Int64 is not 64-bits"));
399 ARCANE_ASSERT((_onlyFirstBitUsed<29, Int64>(item_1.uniqueId())),
400 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
403 ARCANE_ASSERT((_onlyFirstBitUsed<29, Int64>(item_2.uniqueId())),
404 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
408 const Int64 item_1_unique_id = item_1.uniqueId();
409 const Int64 item_2_unique_id = item_2.uniqueId();
411 return item_1_unique_id |
412 item_2_unique_id << 29 |
417inline std::pair<std::tuple<eItemKind, Int64>, std::tuple<eItemKind, Int64>>
419uniqueIdOfPairOfDualItems(
const DoF& link)
421 ARCANE_ASSERT((8 *
sizeof(
Int64) == 64), (
"Int64 is not 64-bits"));
423 const Int64 link_id = link.uniqueId();
425 const Int64 code_1 = _extractFirstCode(link_id);
426 const Int64 id_1 = _extractFirstId(link_id);
427 const eItemKind kind_1 = codeToItemKind(code_1);
429 const Int64 code_2 = _extractSecondCode(link_id);
430 const Int64 id_2 = _extractSecondId(link_id);
431 const eItemKind kind_2 = codeToItemKind(code_2);
433 return std::make_pair(std::make_tuple(kind_1, id_1), std::make_tuple(kind_2, id_2));
439template <
typename ItemT_1,
typename ItemT_2>
442uniqueIdOf(
const ItemT_1& item_1,
const Integer item_1_rank,
const ItemT_2& item_2,
const Integer item_2_rank)
444 ARCANE_ASSERT((8 *
sizeof(
Int64) == 64), (
"Int64 is not 64-bits"));
445 ARCANE_ASSERT((_onlyFirstBitUsed<25, Int64>(item_1.uniqueId())),
446 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 25 bit)",
449 ARCANE_ASSERT((_onlyFirstBitUsed<4, Int64>(
Int64(item_1_rank))),
450 (String::format(
"rank={0} : invalid level (more than 4 bit)", item_1_rank).localstr()));
451 ARCANE_ASSERT((_onlyFirstBitUsed<25, Int64>(item_2.uniqueId())),
452 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 25 bit)",
455 ARCANE_ASSERT((_onlyFirstBitUsed<4, Int64>(
Int64(item_2_rank))),
456 (String::format(
"rank={0} : invalid level (more than 4 bit)", item_2_rank).localstr()));
458 const Int64 item_1_unique_id = item_1.uniqueId();
459 const Int64 item_2_unique_id = item_2.uniqueId();
461 return item_1_unique_id |
462 Int64(item_1_rank) << 25 |
463 item_2_unique_id << 29 |
464 Int64(item_2_rank) << 54 |
473rankOf(
const DoF& node)
475 const Int64 id = node.uniqueId();
483_codeIsValid(
const Item& item,
const Int64 code)
const
513 throw FatalErrorException(A_FUNCINFO,
"Item not defined in graph");
523_idIsValid(
const Item& item,
const Int64 id)
const
525 return (
id != item.uniqueId()) ? false :
true;
533_extractSecondCode(
const Int64 id)
const
535 return ~((
Int64(1) << 61) - 1) &
id;
543_extractFirstId(
const Int64 id)
const
545 return ((
Int64(1) << 29) - 1) & id;
553_extractFirstCode(
const Int64 id)
const
555 return (~(((
Int64(1) << 59) - 1) | ~((
Int64(1) << 61) - 1)) &
id) << 2;
563_extractSecondId(
const Int64 id)
const
565 return (~(((
Int64(1) << 29) - 1) | ~((
Int64(1) << 59) - 1)) &
id) >> 29;
573_checkDualNode(
const DoF& node,
const Item& dual_item)
const
575 const Int64 node_id = node.uniqueId();
577 const Int64 code = _extractSecondCode(node_id);
578 const Int64 id = _extractFirstId(node_id);
580 return _codeIsValid(dual_item, code) && _idIsValid(dual_item,
id);
588_checkLink(
const DoF& link,
const Item& item_1,
const Item& item_2)
const
591 const Int64 link_id = link.uniqueId();
593 const Int64 code_1 = _extractFirstCode(link_id);
594 const Int64 id_1 = _extractFirstId(link_id);
596 const Int64 code_2 = _extractSecondCode(link_id);
597 const Int64 id_2 = _extractSecondId(link_id);
599 return _codeIsValid(item_1, code_1) && _idIsValid(item_1, id_1) && _codeIsValid(item_2, code_2) && _idIsValid(item_2, id_2);
609 ARCANE_ASSERT((_checkDualNode(node, dual_item) ==
true), (
"Error from dual node consistence. Do you use DualUniqueIdMng to generate unique id of graph item ?"));
611 info() <<
" -- Dual Node with unique id " << node.uniqueId()
612 <<
" of item of kind " << dual_item.kind()
613 <<
" and unique id " << dual_item.uniqueId();
621info(
const DoF& link,
const DoF& dual_node0,
const DoF& dual_node1,
const Item& dual_item0,
const Item& dual_item1)
const
623 ARCANE_ASSERT((_checkLink(link, dual_item0, dual_item1) ==
true), (
"Error from link consistence. Do you use DualUniqueIdMng to generate unique id of graph item ?"));
625 info() <<
"- Link with unique id " << link.uniqueId() <<
" of :";
627 info(dual_node0, dual_item0);
631 info(dual_node1, dual_item1);
Fichier de configuration d'Arcane.
TraceMessage info() const
Flot pour un message d'information.
Interface du gestionnaire de traces.
Classe de base d'un élément de maillage.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Unknown
Entité de maillage de genre inconnu ou non initialisé
@ IK_Face
Entité de maillage de genre face.
@ IK_Edge
Entité de maillage de genre arête.
const char * itemKindName(eItemKind kind)
Nom du genre d'entité.
static const Int64 code
Warning: incompatible with simultaneous use of dual nodes on edges and particles.