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"
110ARCANE_BEGIN_NAMESPACE
115class ARCANE_MESH_EXPORT DualUniqueIdMng
124 static const Int64 node_code = 0;
125 static const Int64 face_code =
Int64(1) << 62;
126 static const Int64 cell_code =
Int64(1) << 61;
128 static const Int64 particle_code = (
Int64(1) << 61) + (
Int64(1) << 62);
130 bool m_use_dual_particle = true ;
132 DualUniqueIdMng(
ITraceMng * trace_mng,
bool use_dual_particle=
true)
134 , m_use_dual_particle(use_dual_particle)
137 ~DualUniqueIdMng() {}
144 template<
typename ItemT>
145 inline static Int64 uniqueIdOf(
const ItemT& item);
147 template<
typename ItemT>
148 inline Int64 debugUniqueIdOf(
const ItemT& item);
150 inline std::tuple<eItemKind,Int64> uniqueIdOfDualItem(
const DoF& item);
152 template<
typename ItemT>
153 inline static Int64 uniqueIdOf(
const ItemT& item,
const Integer rank);
155 template<
typename ItemT_1,
typename ItemT_2>
156 inline static Int64 uniqueIdOf(
const ItemT_1& item_1,
const ItemT_2& item_2);
158 inline std::pair< std::tuple<eItemKind,Int64>,std::tuple<eItemKind,Int64> > uniqueIdOfPairOfDualItems(
const DoF& item);
160 template<
typename ItemT_1,
typename ItemT_2>
161 inline static Int64 uniqueIdOf(
const ItemT_1& item_1,
const Integer item_1_rank,
162 const ItemT_2& item_2,
const Integer item_2_rank);
166 inline void info(
const DoF& node,
const Item& dual_item)
const;
167 inline void info(
const DoF& link,
const DoF& dual_node0,
const DoF& dual_node1,
const Item& dual_item0,
const Item& dual_item1)
const;
169 inline Int64 debugDualItemUniqueId(
DoF& node)
const;
173 template<
typename ItemT,
typename Type>
176 template<Integer Nbit,
typename Type>
177 inline static bool _onlyFirstBitUsed(
const Type id);
179 inline bool _checkDualNode(
const DoF& node,
const Item& dual_item)
const;
180 inline bool _checkLink (
const DoF& link,
const Item& dual_item0,
const Item& dual_item1)
const;
182 inline Int64 _extractFirstCode (
const Int64 id)
const;
183 inline Int64 _extractSecondCode(
const Int64 id)
const;
184 inline Int64 _extractFirstId (
const Int64 id)
const;
185 inline Int64 _extractSecondId(
const Int64 id)
const;
187 inline bool _codeIsValid(
const Item& item,
const Int64 code)
const;
188 inline bool _idIsValid(
const Item& item,
const Int64 id )
const;
198 static const Int64 code = 0;
239template<Integer Nbit,
typename Type>
242_onlyFirstBitUsed(
const Type id)
244 ARCANE_ASSERT((Nbit > 0),(
"Error template parameter Nbit <= 0"));
248 ARCANE_ASSERT((Nbit < nb_bit_max),(
"Error 8*sizeof(Type) <= Nbit"));
251 const Type Nbit_first_bits_nulls = ~ ( (1 << Nbit) - 1 );
254 return (Nbit_first_bits_nulls &
id) ==
Type(0);
260template<
typename ItemT>
263uniqueIdOf(
const ItemT& item)
265 ARCANE_ASSERT((8*
sizeof(
Int64) == 64),(
"Int64 is not 64-bits"));
266 ARCANE_ASSERT((_onlyFirstBitUsed<29,Int64>(item.uniqueId())),
267 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
268 itemKindName(item.kind()),item.uniqueId()).localstr()));
270 const Int64 unique_id = item.uniqueId();
272 return unique_id | traits_item_code<ItemT,Int64>::code;
276template<
typename ItemT>
279debugUniqueIdOf(
const ItemT& item)
281 ARCANE_ASSERT((8*
sizeof(Int64) == 64),(
"Int64 is not 64-bits"));
282 ARCANE_ASSERT((_onlyFirstBitUsed<29,Int64>(item.uniqueId())),
283 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
284 itemKindName(item.kind()),item.uniqueId()).localstr()));
286 const Int64 unique_id = item.uniqueId();
288 return unique_id | traits_item_code<ItemT,Int64>::code;
293uidToDualItemKind(Int64 unique_id)
295 Int64 code = _extractSecondCode(unique_id) ;
303 if(m_use_dual_particle && code==particle_code)
305 else if(code==edge_code)
313codeToItemKind(Int64 code)
321 if(m_use_dual_particle && code==particle_code)
323 else if(code==edge_code)
331uniqueIdOf(eItemKind item_kind, Int64 item_uid)
333 ARCANE_ASSERT((8*
sizeof(Int64) == 64),(
"Int64 is not 64-bits"));
334 ARCANE_ASSERT((_onlyFirstBitUsed<29,Int64>(item_uid)),
335 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
341 return item_uid | node_code ;
343 return item_uid | face_code ;
345 return item_uid | cell_code ;
347 return item_uid | edge_code ;
349 return item_uid | particle_code ;
351 throw FatalErrorException(A_FUNCINFO,
"Item not defined in graph");
356inline std::tuple<eItemKind,Int64>
358uniqueIdOfDualItem(
const DoF& node)
360 ARCANE_ASSERT((8*
sizeof(Int64) == 64),(
"Int64 is not 64-bits"));
361 const Int64 node_id = node.uniqueId();
362 const Int64 dual_id = _extractFirstId(node_id);
363 eItemKind item_kind = uidToDualItemKind(node_id) ;
365 return std::make_tuple(item_kind,dual_id) ;
373template<
typename ItemT>
376uniqueIdOf(
const ItemT& item,
const Integer rank)
378 ARCANE_ASSERT((8*
sizeof(Int64) == 64),(
"Int64 is not 64-bits"));
379 ARCANE_ASSERT((_onlyFirstBitUsed<25,Int64>(item.uniqueId())),
380 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 25 bit)",
381 itemKindName(item.kind()),item.uniqueId()).localstr()));
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();
387 return unique_id | Int64(rank) << 25 | traits_item_code<ItemT,Int64>::code;
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)",
401 itemKindName(item_1.kind()),item_1.uniqueId()).localstr()));
402 ARCANE_ASSERT((_onlyFirstBitUsed<29,Int64>(item_2.uniqueId())),
403 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 29 bit)",
404 itemKindName(item_2.kind()),item_2.uniqueId()).localstr()));
406 const Int64 item_1_unique_id = item_1.uniqueId();
407 const Int64 item_2_unique_id = item_2.uniqueId();
409 return item_1_unique_id |
410 item_2_unique_id << 29 |
411 traits_item_code<ItemT_1,Int64>::code >> 2 |
412 traits_item_code<ItemT_2,Int64>::code;
416inline std::pair<std::tuple<eItemKind,Int64>,std::tuple<eItemKind,Int64> >
418uniqueIdOfPairOfDualItems(
const DoF& link)
420 ARCANE_ASSERT((8*
sizeof(Int64) == 64),(
"Int64 is not 64-bits"));
422 const Int64 link_id = link.uniqueId();
424 const Int64 code_1 = _extractFirstCode(link_id);
425 const Int64 id_1 = _extractFirstId(link_id);
426 const eItemKind kind_1 = codeToItemKind(code_1) ;
428 const Int64 code_2 = _extractSecondCode(link_id);
429 const Int64 id_2 = _extractSecondId(link_id);
430 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)) ;
440template<
typename ItemT_1,
typename ItemT_2>
443uniqueIdOf(
const ItemT_1& item_1,
const Integer item_1_rank,
const ItemT_2& item_2,
const Integer item_2_rank)
445 ARCANE_ASSERT((8*
sizeof(Int64) == 64),(
"Int64 is not 64-bits"));
446 ARCANE_ASSERT((_onlyFirstBitUsed<25,Int64>(item_1.uniqueId())),
447 (String::format(
"Item kind={0} uid={1} : invalid uid (more than 25 bit)",
448 itemKindName(item_1.kind()),item_1.uniqueId()).localstr()));
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)",
453 itemKindName(item_2.kind()),item_2.uniqueId()).localstr()));
454 ARCANE_ASSERT((_onlyFirstBitUsed<4,Int64>(Int64(item_2_rank))),
455 (String::format(
"rank={0} : invalid level (more than 4 bit)", item_2_rank).localstr()));
457 const Int64 item_1_unique_id = item_1.uniqueId();
458 const Int64 item_2_unique_id = item_2.uniqueId();
460 return item_1_unique_id |
461 Int64(item_1_rank) << 25 |
462 item_2_unique_id << 29 |
463 Int64(item_2_rank) << 54 |
464 traits_item_code<ItemT_1,Int64>::code >> 2 |
465 traits_item_code<ItemT_2,Int64>::code;
472rankOf(
const DoF& node)
474 const Int64
id = node.uniqueId();
475 return Integer(( ~( (Int64(1) << 25) - 1) &
id ) >> 25);
482_codeIsValid(
const Item& item,
const Int64 code)
const
488 if(code != traits_item_code<Face,Int64>::code) {
493 if(code != traits_item_code<Node,Int64>::code) {
498 if(code != traits_item_code<Cell,Int64>::code) {
503 if(code != traits_item_code<Edge,Int64>::code) {
508 if(code != traits_item_code<Particle,Int64>::code) {
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);
581 return _codeIsValid(dual_item,code) && _idIsValid(dual_item,
id);
589_checkLink(
const DoF& link,
const Item& item_1,
const Item& item_2)
const
592 const Int64 link_id = link.uniqueId();
594 const Int64 code_1 = _extractFirstCode(link_id);
595 const Int64 id_1 = _extractFirstId(link_id);
597 const Int64 code_2 = _extractSecondCode(link_id);
598 const Int64 id_2 = _extractSecondId(link_id);
601 return _codeIsValid(item_1,code_1) && _idIsValid(item_1,id_1)
602 && _codeIsValid(item_2,code_2) && _idIsValid(item_2,id_2);
610info(
const DoF& node,
const Item& dual_item)
const
612 ARCANE_ASSERT((_checkDualNode(node,dual_item) ==
true),(
"Error from dual node consistence. Do you use DualUniqueIdMng to generate unique id of graph item ?"));
615 info() <<
" -- Dual Node with unique id " << node.uniqueId()
616 <<
" of item of kind " << dual_item.kind()
617 <<
" and unique id " << dual_item.uniqueId();
625info(
const DoF& link,
const DoF& dual_node0,
const DoF& dual_node1,
const Item& dual_item0,
const Item& dual_item1)
const
627 ARCANE_ASSERT((_checkLink(link,dual_item0,dual_item1) ==
true),(
"Error from link consistence. Do you use DualUniqueIdMng to generate unique id of graph item ?"));
629 info() <<
"- Link with unique id " << link.uniqueId() <<
" of :";
631 info(dual_node0,dual_item0);
635 info(dual_node1,dual_item1);
Fichier de configuration d'Arcane.
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.
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
attention incompatible avec une utilisation silmutanée de dual node sur des arêtes et des particules