14#include "arcane/utils/HashTableMap.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/CheckedConvert.h"
17#include "arcane/utils/ValueConvert.h"
19#include "arcane/core/parallel/BitonicSortT.H"
21#include "arcane/core/IParallelExchanger.h"
22#include "arcane/core/ISerializeMessage.h"
23#include "arcane/core/SerializeBuffer.h"
24#include "arcane/core/ISerializer.h"
25#include "arcane/core/ItemPrinter.h"
26#include "arcane/core/Timer.h"
27#include "arcane/core/IGhostLayerMng.h"
28#include "arcane/core/IItemFamilyPolicyMng.h"
29#include "arcane/core/IItemFamilySerializer.h"
30#include "arcane/core/ParallelMngUtils.h"
32#include "arcane/mesh/DynamicMesh.h"
33#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
58 using ItemInternalMap = DynamicMeshKindInfos::ItemInternalMap;
75 bool m_is_verbose =
false;
76 bool m_is_allocate =
false;
78 bool m_use_optimized_node_layer =
true;
79 bool m_use_only_minimal_cell_uid =
true;
85 void _sendAndReceiveCells(SubDomainItemMap& cells_to_send);
98, m_mesh(mesh_builder->
mesh())
99, m_mesh_builder(mesh_builder)
100, m_parallel_mng(m_mesh->parallelMng())
101, m_is_allocate(is_allocate)
105 Int32 vv = v.value();
106 m_use_optimized_node_layer = (vv == 1 || vv == 3);
107 m_use_only_minimal_cell_uid = (v == 2 || vv == 3);
110 m_is_verbose = (v.value()!=0);
117void GhostLayerBuilder2::
140 using BasicType =
Int64;
141 static constexpr Int64 nbBasicTypeSize() {
return 3; }
147 Int32 message_size = messageSize(values);
149 auto* ptr =
reinterpret_cast<const Int64*
>(fsi_base);
155 Int32 message_size = messageSize(values);
157 auto* ptr =
reinterpret_cast<Int64*
>(fsi_base);
164 Int64 message_size_i64 = values.
size() * nbBasicTypeSize();
171 if ((message_size % nbBasicTypeSize()) != 0)
172 ARCANE_FATAL(
"Message size '{0}' is not a multiple of basic size '{1}'", message_size, nbBasicTypeSize());
173 Int32 nb_element = message_size / nbBasicTypeSize();
183 size_t h1 = std::hash<Int64>{}(a.node_uid);
184 size_t h2 = std::hash<Int64>{}(a.cell_uid);
185 size_t h3 = std::hash<Int32>{}(a.cell_owner);
191 return (a.node_uid == b.node_uid && a.cell_uid == b.cell_uid && a.cell_owner == b.cell_owner);
196 Int64 node_uid = NULL_ITEM_UNIQUE_ID;
197 Int64 cell_uid = NULL_ITEM_UNIQUE_ID;
198 Int32 cell_owner = -1;
212 Int64 k1_node_uid = k1.node_uid;
213 Int64 k2_node_uid = k2.node_uid;
214 if (k1_node_uid<k2_node_uid)
216 if (k1_node_uid>k2_node_uid)
219 Int64 k1_cell_uid = k1.cell_uid;
220 Int64 k2_cell_uid = k2.cell_uid;
221 if (k1_cell_uid<k2_cell_uid)
223 if (k1_cell_uid>k2_cell_uid)
226 return (k1.cell_owner<k2.cell_owner);
231 auto buf_view = BoundaryNodeInfo::asBasicBuffer(values);
232 return pm->send(buf_view, rank,
false);
237 auto buf_view = BoundaryNodeInfo::asBasicBuffer(values);
238 return pm->
recv(buf_view, rank,
false);
243 return BoundaryNodeInfo::messageSize(values);
249 bni.node_uid = INT64_MAX;
250 bni.cell_uid = INT64_MAX;
257 return bni.node_uid!=INT64_MAX;
301 Integer nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
302 info() <<
"** GHOST LAYER BUILDER V" << m_version <<
" with sort (nb_ghost_layer=" << nb_ghost_layer <<
")";
311 if (nb_ghost_layer == 0)
315 const bool is_non_manifold = m_mesh->meshKind().isNonManifold();
316 if (is_non_manifold && (m_version != 3))
317 ARCANE_FATAL(
"Only version 3 of ghostlayer builder is supported for non manifold meshes");
319 ItemInternalMap& cells_map = m_mesh->cellsMap();
320 ItemInternalMap& nodes_map = m_mesh->nodesMap();
322 Integer boundary_nodes_uid_count = 0;
326 if (m_version == 3) {
333 warning() <<
"Invalid call to addGhostLayers() with version 3 because mesh "
334 <<
" already has '" << nb_ghost <<
"' ghost cells. The computed ghost cells"
335 <<
" may be wrong. Use version 4 of ghost layer builder if you want to handle this case";
341 if (m_version >= 4) {
344 if (node_layer[node.
localId()] == 1)
345 ++boundary_nodes_uid_count;
354 node_layer[node.
localId()] = 1;
355 ++boundary_nodes_uid_count;
360 info() <<
"NB BOUNDARY NODE=" << boundary_nodes_uid_count;
362 for (
Integer current_layer = 1; current_layer <= nb_ghost_layer; ++current_layer) {
364 info() <<
"Processing layer " << current_layer;
367 if (m_version >= 4 && cell.
owner() != my_rank)
371 if (cell_layer[cell_lid] != (-1))
373 bool is_current_layer =
false;
375 Integer layer = node_layer[inode_local_id];
377 if (layer == current_layer) {
378 is_current_layer =
true;
382 if (is_current_layer) {
383 cell_layer[cell_lid] = current_layer;
387 Integer layer = node_layer[inode_local_id];
390 node_layer[inode_local_id] = current_layer + 1;
402 if (m_use_optimized_node_layer) {
406 Int32 layer = node_layer[lid];
408 node_layer[lid] = nb_ghost_layer + 1;
412 info() <<
"Mark remaining nodes nb=" << nb_no_layer;
415 for (
Integer i = 1; i <= nb_ghost_layer; ++i)
416 _addGhostLayer(i, node_layer);
438 ItemInternalMap& faces_map = m_mesh->facesMap();
451 inode.mutableItemBase().addFlags(shared_and_boundary_flags);
452 node_layer[inode.localId()] = 1;
455 iedge.mutableItemBase().addFlags(shared_and_boundary_flags);
458 _markBoundaryNodesFromEdges(node_layer);
464void GhostLayerBuilder2::
467 info() <<
"Processing ghost layer " << current_layer;
476 bool is_verbose = m_is_verbose;
481 Int64 nb_added_for_different_rank = 0;
482 Int64 nb_added_for_in_layer = 0;
490 const bool do_only_minimal_uid = m_use_only_minimal_cell_uid;
495 if (m_version >= 4 && cell.
owner() != my_rank)
499 Int32 node_lid = node.localId();
501 if (cell.
owner() != my_rank) {
503 ++nb_added_for_different_rank;
506 Integer layer = node_layer[node_lid];
507 do_it = layer <= current_layer;
509 ++nb_added_for_in_layer;
512 Int32 node_lid = node.localId();
513 if (do_only_minimal_uid) {
514 Int64 current_uid = node_cell_uids[node_lid];
515 if ((current_uid == NULL_ITEM_UNIQUE_ID) || cell_uid < current_uid) {
516 node_cell_uids[node_lid] = cell_uid;
518 info() <<
"AddNode node_uid=" << node.uniqueId() <<
" cell=" << cell_uid;
521 info() <<
"AddNode node_uid=" << node.uniqueId() <<
" cell=" << cell_uid <<
" not done current=" << current_uid;
524 Int64 node_uid = node.uniqueId();
526 nci.node_uid = node_uid;
527 nci.cell_uid = cell_uid;
528 nci.cell_owner = my_rank;
529 boundary_node_list.
add(nci);
531 info() <<
"AddNode node_uid=" << node.uniqueId() <<
" cell=" << cell_uid;
537 if (do_only_minimal_uid) {
539 Int32 lid = node.localId();
540 Int64 cell_uid = node_cell_uids[lid];
541 if (cell_uid != NULL_ITEM_UNIQUE_ID) {
542 Int64 node_uid = node.uniqueId();
544 nci.node_uid = node_uid;
545 nci.cell_uid = cell_uid;
546 nci.cell_owner = my_rank;
547 boundary_node_list.
add(nci);
552 info() <<
"NB BOUNDARY NODE LIST=" << boundary_node_list.
size()
553 <<
" nb_added_for_different_rank=" << nb_added_for_different_rank
554 <<
" nb_added_for_in_layer=" << nb_added_for_in_layer
555 <<
" do_only_minimal=" << do_only_minimal_uid;
558 SharedArray<BoundaryNodeInfo> all_boundary_node_info = boundary_node_list;
560 UniqueArray<BoundaryNodeToSendInfo> node_list_to_send;
562 ConstArrayView<BoundaryNodeInfo> all_bni = all_boundary_node_info;
564 for (
Integer i = 0; i < bi_n; ++i) {
568 Int64 node_uid = bni.node_uid;
570 for (; last_i < bi_n; ++last_i)
571 if (all_bni[last_i].node_uid != node_uid)
573 Integer nb_same_node = (last_i - i);
575 info() <<
"NB_SAME_NODE uid=" << node_uid <<
" n=" << nb_same_node <<
" last_i=" << last_i;
579 Int32 owner = bni.cell_owner;
580 bool has_ghost =
false;
581 for (
Integer z = 0; z < nb_same_node; ++z)
582 if (all_bni[i + z].cell_owner != owner) {
589 si.m_nb_cell = nb_same_node;
590 node_list_to_send.add(si);
592 info() <<
"Add ghost uid=" << node_uid <<
" index=" << i <<
" nb_same_node=" << nb_same_node;
600 ConstArrayView<BoundaryNodeInfo> all_bni = all_boundary_node_info;
601 Integer nb_node_to_send = node_list_to_send.size();
602 std::set<Int32> ranks_done;
603 for (
Integer i = 0; i < nb_node_to_send; ++i) {
604 Integer index = node_list_to_send[i].m_index;
605 Integer nb_cell = node_list_to_send[i].m_nb_cell;
609 for (
Integer kz = 0; kz < nb_cell; ++kz) {
610 Int32 krank = all_bni[index + kz].cell_owner;
611 if (ranks_done.find(krank) == ranks_done.end()) {
612 ranks_done.insert(krank);
618 nb_info_to_send[krank] += (nb_cell * 2) + 2;
625 for (
Integer i = 0; i < nb_rank; ++i) {
626 Integer nb_to_send = nb_info_to_send[i];
628 info() <<
"NB_TO_SEND rank=" << i <<
" n=" << nb_to_send;
634 for (
Integer i = 0; i < nb_rank; ++i) {
635 nb_info_to_send_indexes[i] = total_nb_to_send;
636 total_nb_to_send += nb_info_to_send[i];
638 info() <<
"TOTAL_NB_TO_SEND=" << total_nb_to_send;
640 UniqueArray<Int64> resend_infos(total_nb_to_send);
642 ConstArrayView<BoundaryNodeInfo> all_bni = all_boundary_node_info;
643 Integer nb_node_to_send = node_list_to_send.size();
644 std::set<Int32> ranks_done;
645 for (
Integer i = 0; i < nb_node_to_send; ++i) {
646 Integer node_index = node_list_to_send[i].m_index;
647 Integer nb_cell = node_list_to_send[i].m_nb_cell;
648 Int64 node_uid = all_bni[node_index].node_uid;
652 for (
Integer kz = 0; kz < nb_cell; ++kz) {
653 Int32 krank = all_bni[node_index + kz].cell_owner;
654 if (ranks_done.find(krank) == ranks_done.end()) {
655 ranks_done.insert(krank);
656 Integer send_index = nb_info_to_send_indexes[krank];
657 resend_infos[send_index] = node_uid;
659 resend_infos[send_index] = nb_cell;
661 for (
Integer zz = 0; zz < nb_cell; ++zz) {
662 resend_infos[send_index] = all_bni[node_index + zz].cell_uid;
664 resend_infos[send_index] = all_bni[node_index + zz].cell_owner;
667 nb_info_to_send_indexes[krank] = send_index;
675 Timer::SimplePrinter sp(
traceMng(),
"Sending size with AllToAll");
676 pm->allToAll(nb_info_to_send, nb_info_to_recv, 1);
680 for (
Integer i = 0; i < nb_rank; ++i)
681 info() <<
"NB_TO_RECV: I=" << i <<
" n=" << nb_info_to_recv[i];
684 for (
Integer i = 0; i < nb_rank; ++i)
685 total_nb_to_recv += nb_info_to_recv[i];
692 UniqueArray<Int64> recv_infos;
699 Int32 total_send = 0;
700 Int32 total_recv = 0;
701 for (
Integer i = 0; i < nb_rank; ++i) {
702 send_counts[i] = (
Int32)(nb_info_to_send[i] * vsize);
703 recv_counts[i] = (
Int32)(nb_info_to_recv[i] * vsize);
704 send_indexes[i] = total_send;
705 recv_indexes[i] = total_recv;
706 total_send += send_counts[i];
707 total_recv += recv_counts[i];
709 recv_infos.resize(total_nb_to_recv);
714 info() <<
"BUF_SIZES: send=" << send_buf.size() <<
" recv=" << recv_buf.size();
716 Timer::SimplePrinter sp(
traceMng(),
"Send values with AllToAll");
717 pm->allToAllVariable(send_buf, send_counts, send_indexes, recv_buf, recv_counts, recv_indexes);
721 SubDomainItemMap cells_to_send(50,
true);
730 UniqueArray<Int32> my_cells;
731 SharedArray<Int32> ranks_to_send;
732 std::set<Int32> ranks_done;
733 while (index < total_nb_to_recv) {
734 Int64 node_uid = recv_infos[index];
736 Int64 nb_cell = recv_infos[index];
738 Node current_node(nodes_map.
findItem(node_uid));
740 info() <<
"NODE uid=" << node_uid <<
" nb_cell=" << nb_cell <<
" idx=" << (index - 2);
742 ranks_to_send.clear();
744 for (
Integer kk = 0; kk < nb_cell; ++kk) {
745 Int64 cell_uid = recv_infos[index];
749 if (kk == 0 && current_layer == 1 && m_is_allocate)
755 info() <<
" CELL=" << cell_uid <<
" owner=" << cell_owner;
756 if (cell_owner == my_rank) {
757 impl::ItemBase dcell = cells_map.
tryFind(cell_uid);
759 ARCANE_FATAL(
"Internal error: cell uid={0} is not in our mesh", cell_uid);
760 if (do_only_minimal_uid) {
762 for (CellLocalId c : current_node.cellIds())
766 my_cells.add(dcell.localId());
769 if (ranks_done.find(cell_owner) == ranks_done.end()) {
770 ranks_to_send.add(cell_owner);
771 ranks_done.insert(cell_owner);
777 info() <<
"CELLS TO SEND: node_uid=" << node_uid
778 <<
" nb_rank=" << ranks_to_send.size()
779 <<
" nb_cell=" << my_cells.size();
780 info(4) <<
"CELLS TO SEND: node_uid=" << node_uid
781 <<
" rank=" << ranks_to_send
782 <<
" cell=" << my_cells;
785 for (
Integer zrank = 0, zn = ranks_to_send.size(); zrank < zn; ++zrank) {
786 Int32 send_rank = ranks_to_send[zrank];
787 SubDomainItemMap::Data* d = cells_to_send.lookupAdd(send_rank);
789 for (
Integer zid = 0, zid_size = my_cells.size(); zid < zid_size; ++zid) {
791 c.add(my_cells[zid]);
797 info() <<
"GHOST V3 SERIALIZE CELLS";
798 _sendAndReceiveCells(cells_to_send);
816 bool is_verbose = m_is_verbose;
819 boundary_node_sorter.setNeedIndexAndRank(
false);
823 boundary_node_sorter.
sort(boundary_node_list);
829 for (
Integer i = 0; i < n; ++i) {
831 info() <<
"NODES_KEY i=" << i
832 <<
" node=" << bni.node_uid
833 <<
" cell=" << bni.cell_uid
834 <<
" rank=" << bni.cell_owner;
853 Integer begin_own_list_index = 0;
854 if (n != 0 && my_rank != 0) {
855 if (BoundaryNodeBitonicSortTraits::isValid(all_bni[0])) {
856 Int64 node_uid = all_bni[0].node_uid;
857 for (
Integer i = 0; i < n; ++i) {
858 if (all_bni[i].node_uid != node_uid) {
859 begin_own_list_index = i;
863 end_node_list.
add(all_bni[i]);
867 info() <<
"BEGIN_OWN_LIST_INDEX=" << begin_own_list_index <<
" end_node_list_size=" << end_node_list.
size();
869 for (
Integer k = 0, kn = end_node_list.
size(); k < kn; ++k)
870 info() <<
" SEND node_uid=" << end_node_list[k].node_uid
871 <<
" cell_uid=" << end_node_list[k].cell_uid;
878 Integer send_message_size = BoundaryNodeBitonicSortTraits::messageSize(end_node_list);
881 if (my_rank != (nb_rank - 1)) {
887 info() <<
"Send size=" << send_message_size <<
" Recv size=" << recv_message_size;
891 if (recv_message_size != 0) {
892 Int32 nb_element = BoundaryNodeInfo::nbElement(recv_message_size);
893 end_node_list_recv.
resize(nb_element);
894 requests.
add(BoundaryNodeBitonicSortTraits::recv(pm, my_rank + 1, end_node_list_recv));
896 if (send_message_size != 0)
897 requests.
add(BoundaryNodeBitonicSortTraits::send(pm, my_rank - 1, end_node_list));
901 boundary_node_list.
clear();
902 boundary_node_list.
addRange(all_bni.
subConstView(begin_own_list_index, n - begin_own_list_index));
903 boundary_node_list.
addRange(end_node_list_recv);
910void GhostLayerBuilder2::
911_sendAndReceiveCells(SubDomainItemMap& cells_to_send)
915 const bool is_verbose = m_is_verbose;
918 for (SubDomainItemMap::Enumerator i_map(cells_to_send); ++i_map;) {
919 Int32 sd = i_map.data()->key();
925 std::sort(std::begin(items), std::end(items));
926 auto new_end = std::unique(std::begin(items), std::end(items));
929 info(4) <<
"CELLS TO SEND SD=" << sd <<
" Items=" << items;
931 info(4) <<
"CELLS TO SEND SD=" << sd <<
" nb=" << items.size();
932 exchanger->addSender(sd);
934 exchanger->initializeCommunicationsMessages();
935 for (
Integer i = 0, ns = exchanger->nbSender(); i < ns; ++i) {
936 ISerializeMessage* sm = exchanger->messageToSend(i);
937 Int32 rank = sm->destination().value();
938 ISerializer* s = sm->serializer();
942 exchanger->processExchange();
943 info(4) <<
"END EXCHANGE CELLS";
944 for (
Integer i = 0, ns = exchanger->nbReceiver(); i < ns; ++i) {
945 ISerializeMessage* sm = exchanger->messageToReceive(i);
946 ISerializer* s = sm->serializer();
949 m_mesh_builder->printStats();
966 ItemInternalMap& faces_map = m_mesh->facesMap();
972 bool is_sub_domain_boundary_face =
false;
974 is_sub_domain_boundary_face =
true;
978 is_sub_domain_boundary_face =
true;
980 if (is_sub_domain_boundary_face) {
983 inode.mutableItemBase().addFlags(shared_and_boundary_flags);
985 iedge.mutableItemBase().addFlags(shared_and_boundary_flags);
988 _markBoundaryNodesFromEdges(node_layer);
994void GhostLayerBuilder2::
997 const bool is_non_manifold = m_mesh->
meshKind().isNonManifold();
998 if (!is_non_manifold)
1003 info() <<
"Mark boundary nodes from edges for non-manifold mesh";
1013 Int32 nb_dim2_cell = 0;
1014 Int32 nb_own_dim2_cell = 0;
1019 if (cell.
owner() == my_rank)
1023 if (nb_dim2_cell == nb_cell && nb_own_dim2_cell == 1) {
1025 for (Item inode : edge.
nodes()) {
1026 inode.mutableItemBase().addFlags(shared_and_boundary_flags);
1027 node_layer[inode.localId()] = 1;
1037_buildGhostLayerNewVersion(
DynamicMesh* mesh,
bool is_allocate,
Int32 version)
1040 glb.addGhostLayers();
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Integer size() const
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
constexpr const_pointer data() const noexcept
Pointeur sur le début de la vue.
Tableau d'items de types quelconques.
void clear()
Supprime les éléments du tableau.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
constexpr const_pointer data() const noexcept
Pointeur sur la mémoire allouée.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
constexpr ConstArrayView< T > subConstView(Integer abegin, Integer asize) const noexcept
Sous-vue (constante) à partir de l'élément abegin et contenant asize éléments.
CellConnectedListViewType cells() const
Liste des mailles de l'arête.
Int32 nbCell() const
Nombre de mailles connectées à l'arête.
Cell cell(Int32 i) const
i-ème maille de la face
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
EdgeConnectedListViewType edges() const
Liste des arêtes de la face.
Table de hachage pour tableaux associatifs.
virtual Int32 maxLocalId() const =0
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void waitAllRequests(ArrayView< Request > rvalues)=0
Bloque en attendant que les requêtes rvalues soient terminées.
virtual bool isParallel() const =0
Retourne true si l'exécution est parallèle.
MutableItemBase toMutable()
Interface modifiable de cette entité
Int32 flags() const
Flags de l'entité
@ II_Shared
L'entité est partagée par un autre sous-domaine.
@ II_SubDomainBoundary
L'entité est à la frontière de deux sous-domaines.
@ II_Boundary
L'entité est sur la frontière.
Structure interne d'une entité de maillage.
Classe utilitaire pour imprimer les infos sur une entité.
Int16 dimension() const
Dimension de l'élément (<0 si inconnu)
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
Classe de base d'un élément de maillage.
const ItemTypeInfo * typeInfo() const
Infos sur le type de l'entité.
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
bool isOwn() const
true si l'entité est appartient au sous-domaine
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
impl::ItemBase itemBase() const
Partie interne de l'entité.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
void addFlags(Int32 added_flags)
Ajoute les flags added_flags à ceux de l'entité
Algorithme de tri bitonique parallèle.
ConstArrayView< KeyType > keys() const override
Après un tri, retourne la liste des éléments de ce rang.
void sort(ConstArrayView< KeyType > keys) override
Trie en parallèle les éléments de keys sur tous les rangs.
Vecteur 1D de données avec sémantique par référence.
Affiche le temps passé entre l'appel au constructeur et le destructeur.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Construction d'un maillage de manière incrémentale.
Implémentation d'un maillage.
IItemFamily * nodeFamily() override
Retourne la famille des noeuds.
IParallelMng * parallelMng() override
Gestionnaire de parallèlisme.
void serializeCells(ISerializer *buffer, Int32ConstArrayView cells_local_id) override
const MeshKind meshKind() const override
Caractéristiques du maillage.
Fonctor pour trier les BoundaryNodeInfo via le tri bitonic.
Structure contenant les informations des noeuds frontières.
Construction des couches fantômes.
void _sortBoundaryNodeList(Array< BoundaryNodeInfo > &boundary_node_list)
Trie parallèle de la liste des infos sur les noeuds frontières.
void _markBoundaryItems(ArrayView< Int32 > node_layer)
Marque les entitées au bord du sous-domaine.
GhostLayerBuilder2(DynamicMeshIncrementalBuilder *mesh_builder, bool is_allocate, Int32 version)
Construit une instance pour le maillage mesh.
void addGhostLayers()
Ajoute les couches de mailles fantomes.
void _markBoundaryNodes(ArrayView< Int32 > node_layer)
Détermine les noeuds frontières.
Tableau associatif de ItemInternal.
impl::ItemBase findItem(Int64 uid) const
Retourne l'entité de numéro unique uid.
void eachItem(const Lambda &lambda)
Fonction template pour itérer sur les entités de l'instance.
impl::ItemBase tryFind(Int64 key) const
Retourne l'entité associée à key si trouvé ou l'entité nulle sinon.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Int32 toInt32(Int64 v)
Converti un Int64 en un Int32.
Ref< IParallelExchanger > createExchangerRef(IParallelMng *pm)
Retourne une interface pour transférer des messages entre rangs.
ArrayView< Int64 > Int64ArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Array< Int32 > Int32Array
Tableau dynamique à une dimension d'entiers 32 bits.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
ConstArrayView< Integer > IntegerConstArrayView
Equivalent C d'un tableau à une dimension d'entiers.
std::int32_t Int32
Type entier signé sur 32 bits.