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
120 using TraceAccessor::info;
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;
127 static const Int64 edge_code = (
Int64(1) << 61) + (
Int64(1) << 62);
128 static const Int64 particle_code = (
Int64(1) << 61) + (
Int64(1) << 62);
130 bool m_use_dual_particle =
true ;
140 inline eItemKind codeToItemKind(Int64 code) ;
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>
158 inline std::pair< std::tuple<eItemKind,Int64>,std::tuple<eItemKind,Int64> > uniqueIdOfPairOfDualItems(
const DoF& item);
160 template<
typename ItemT_1,
typename ItemT_2>
164 inline static Integer rankOf(
const DoF& );
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);
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;
204 static const Int64 code =
Int64(1) << 62;
208struct ARCANE_MESH_EXPORT DualUniqueIdMng::traits_item_code<Cell,Int64>
214struct ARCANE_MESH_EXPORT DualUniqueIdMng::traits_item_code<Edge,Int64>
220struct ARCANE_MESH_EXPORT DualUniqueIdMng::traits_item_code<Particle,Int64>
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.
Classe de base d'un élément de maillage.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Interface du gestionnaire de traces.
Classe d'accès aux traces.
TraceMessage info() const
Flot pour un message d'information.
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é.
Int32 Integer
Type représentant un entier.
std::int64_t Int64
Type entier signé sur 64 bits.