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"
31#include "arcane/core/internal/IMeshInternal.h"
33#include "arcane/mesh/DynamicMesh.h"
34#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
35#include "arcane/utils/ScopedPtr.h"
60 using ItemInternalMap = DynamicMeshKindInfos::ItemInternalMap;
74 IMesh* m_mesh =
nullptr;
77 bool m_is_verbose =
false;
78 bool m_is_allocate =
false;
80 bool m_use_optimized_node_layer =
true;
81 bool m_use_only_minimal_cell_uid =
true;
87 void _sendAndReceiveCells(SubDomainItemMap& cells_to_send);
101, m_mesh_internal(
mesh->_internalApi())
102, m_parallel_mng(m_mesh->parallelMng())
103, m_is_allocate(is_allocate)
107 Int32 vv = v.value();
108 m_use_optimized_node_layer = (vv == 1 || vv == 3);
109 m_use_only_minimal_cell_uid = (v == 2 || vv == 3);
112 m_is_verbose = (v.value() != 0);
119void GhostLayerBuilder2::
142 using BasicType =
Int64;
143 static constexpr Int64 nbBasicTypeSize() {
return 3; }
149 Int32 message_size = messageSize(values);
151 auto* ptr =
reinterpret_cast<const Int64*
>(fsi_base);
157 Int32 message_size = messageSize(values);
159 auto* ptr =
reinterpret_cast<Int64*
>(fsi_base);
166 Int64 message_size_i64 = values.
size() * nbBasicTypeSize();
167 Int32 message_size = CheckedConvert::toInteger(message_size_i64);
173 if ((message_size % nbBasicTypeSize()) != 0)
174 ARCANE_FATAL(
"Message size '{0}' is not a multiple of basic size '{1}'", message_size, nbBasicTypeSize());
175 Int32 nb_element = message_size / nbBasicTypeSize();
185 size_t h1 = std::hash<Int64>{}(a.node_uid);
186 size_t h2 = std::hash<Int64>{}(a.cell_uid);
187 size_t h3 = std::hash<Int32>{}(a.cell_owner);
193 return (a.node_uid == b.node_uid && a.cell_uid == b.cell_uid && a.cell_owner == b.cell_owner);
198 Int64 node_uid = NULL_ITEM_UNIQUE_ID;
199 Int64 cell_uid = NULL_ITEM_UNIQUE_ID;
200 Int32 cell_owner = -1;
215 Int64 k1_node_uid = k1.node_uid;
216 Int64 k2_node_uid = k2.node_uid;
217 if (k1_node_uid < k2_node_uid)
219 if (k1_node_uid > k2_node_uid)
222 Int64 k1_cell_uid = k1.cell_uid;
223 Int64 k2_cell_uid = k2.cell_uid;
224 if (k1_cell_uid < k2_cell_uid)
226 if (k1_cell_uid > k2_cell_uid)
229 return (k1.cell_owner < k2.cell_owner);
234 auto buf_view = BoundaryNodeInfo::asBasicBuffer(values);
235 return pm->send(buf_view, rank,
false);
240 auto buf_view = BoundaryNodeInfo::asBasicBuffer(values);
241 return pm->
recv(buf_view, rank,
false);
246 return BoundaryNodeInfo::messageSize(values);
252 bni.node_uid = INT64_MAX;
253 bni.cell_uid = INT64_MAX;
260 return bni.node_uid != INT64_MAX;
305 Integer nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
306 info() <<
"** GHOST LAYER BUILDER V" << m_version <<
" with sort (nb_ghost_layer=" << nb_ghost_layer <<
")";
315 if (nb_ghost_layer == 0)
319 const bool is_non_manifold = m_mesh->meshKind().isNonManifold();
320 if (is_non_manifold && (m_version != 3))
321 ARCANE_FATAL(
"Only version 3 of ghostlayer builder is supported for non manifold meshes");
323 ItemInternalMap& cells_map = m_mesh_internal->cellsMap();
324 ItemInternalMap& nodes_map = m_mesh_internal->nodesMap();
326 Integer boundary_nodes_uid_count = 0;
330 if (m_version == 3) {
337 warning() <<
"Invalid call to addGhostLayers() with version 3 because mesh "
338 <<
" already has '" << nb_ghost <<
"' ghost cells. The computed ghost cells"
339 <<
" may be wrong. Use version 4 of ghost layer builder if you want to handle this case";
345 if (m_version >= 4) {
348 if (node_layer[node.
localId()] == 1)
349 ++boundary_nodes_uid_count;
358 node_layer[node.
localId()] = 1;
359 ++boundary_nodes_uid_count;
364 info() <<
"NB BOUNDARY NODE=" << boundary_nodes_uid_count;
366 for (
Integer current_layer = 1; current_layer <= nb_ghost_layer; ++current_layer) {
368 info() <<
"Processing layer " << current_layer;
371 if (m_version >= 4 && cell.
owner() != my_rank)
375 if (cell_layer[cell_lid] != (-1))
377 bool is_current_layer =
false;
379 Integer layer = node_layer[inode_local_id];
381 if (layer == current_layer) {
382 is_current_layer =
true;
386 if (is_current_layer) {
387 cell_layer[cell_lid] = current_layer;
391 Integer layer = node_layer[inode_local_id];
394 node_layer[inode_local_id] = current_layer + 1;
406 if (m_use_optimized_node_layer) {
410 Int32 layer = node_layer[lid];
412 node_layer[lid] = nb_ghost_layer + 1;
416 info() <<
"Mark remaining nodes nb=" << nb_no_layer;
419 for (
Integer i = 1; i <= nb_ghost_layer; ++i)
420 _addGhostLayer(i, node_layer);
442 ItemInternalMap& faces_map = m_mesh_internal->facesMap();
455 inode.mutableItemBase().addFlags(shared_and_boundary_flags);
456 node_layer[inode.localId()] = 1;
459 iedge.mutableItemBase().addFlags(shared_and_boundary_flags);
462 _markBoundaryNodesFromEdges(node_layer);
468void GhostLayerBuilder2::
471 info() <<
"Processing ghost layer " << current_layer
472 <<
" node_layer_size=" << node_layer.
size();
481 bool is_verbose = m_is_verbose;
486 Int64 nb_added_for_different_rank = 0;
487 Int64 nb_added_for_in_layer = 0;
495 const bool do_only_minimal_uid = m_use_only_minimal_cell_uid;
506 Int32 node_lid = node.localId();
508 if (cell.
owner() != my_rank) {
510 ++nb_added_for_different_rank;
513 Integer layer = node_layer[node_lid];
514 do_it = layer <= current_layer;
516 ++nb_added_for_in_layer;
519 Int32 node_lid = node.localId();
520 if (do_only_minimal_uid) {
521 Int64 current_uid = node_cell_uids[node_lid];
522 if ((current_uid == NULL_ITEM_UNIQUE_ID) || cell_uid < current_uid) {
523 node_cell_uids[node_lid] = cell_uid;
525 info() <<
"AddNode node_uid=" << node.uniqueId() <<
" cell=" << cell_uid;
528 info() <<
"AddNode node_uid=" << node.uniqueId() <<
" cell=" << cell_uid <<
" not done current=" << current_uid;
531 Int64 node_uid = node.uniqueId();
533 nci.node_uid = node_uid;
534 nci.cell_uid = cell_uid;
535 nci.cell_owner = my_rank;
536 boundary_node_list.
add(nci);
538 info() <<
"AddNode node_uid=" << node.uniqueId() <<
" cell=" << cell_uid;
544 if (do_only_minimal_uid) {
546 Int32 lid = node.localId();
547 Int64 cell_uid = node_cell_uids[lid];
548 if (cell_uid != NULL_ITEM_UNIQUE_ID) {
549 Int64 node_uid = node.uniqueId();
551 nci.node_uid = node_uid;
552 nci.cell_uid = cell_uid;
553 nci.cell_owner = my_rank;
554 boundary_node_list.
add(nci);
559 info() <<
"NB BOUNDARY NODE LIST=" << boundary_node_list.
size()
560 <<
" nb_added_for_different_rank=" << nb_added_for_different_rank
561 <<
" nb_added_for_in_layer=" << nb_added_for_in_layer
562 <<
" do_only_minimal=" << do_only_minimal_uid;
565 SharedArray<BoundaryNodeInfo> all_boundary_node_info = boundary_node_list;
567 UniqueArray<BoundaryNodeToSendInfo> node_list_to_send;
569 ConstArrayView<BoundaryNodeInfo> all_bni = all_boundary_node_info;
571 for (
Integer i = 0; i < bi_n; ++i) {
575 Int64 node_uid = bni.node_uid;
577 for (; last_i < bi_n; ++last_i)
578 if (all_bni[last_i].node_uid != node_uid)
580 Integer nb_same_node = (last_i - i);
582 info() <<
"NB_SAME_NODE uid=" << node_uid <<
" n=" << nb_same_node <<
" last_i=" << last_i;
586 Int32 owner = bni.cell_owner;
587 bool has_ghost =
false;
588 for (
Integer z = 0; z < nb_same_node; ++z)
589 if (all_bni[i + z].cell_owner != owner) {
596 si.m_nb_cell = nb_same_node;
597 node_list_to_send.add(si);
599 info() <<
"Add ghost uid=" << node_uid <<
" index=" << i <<
" nb_same_node=" << nb_same_node;
607 ConstArrayView<BoundaryNodeInfo> all_bni = all_boundary_node_info;
608 Integer nb_node_to_send = node_list_to_send.size();
609 std::set<Int32> ranks_done;
610 for (
Integer i = 0; i < nb_node_to_send; ++i) {
611 Integer index = node_list_to_send[i].m_index;
612 Integer nb_cell = node_list_to_send[i].m_nb_cell;
616 for (
Integer kz = 0; kz < nb_cell; ++kz) {
617 Int32 krank = all_bni[index + kz].cell_owner;
618 if (ranks_done.find(krank) == ranks_done.end()) {
619 ranks_done.insert(krank);
625 nb_info_to_send[krank] += (nb_cell * 2) + 2;
632 for (
Integer i = 0; i < nb_rank; ++i) {
633 Integer nb_to_send = nb_info_to_send[i];
635 info() <<
"NB_TO_SEND rank=" << i <<
" n=" << nb_to_send;
641 for (
Integer i = 0; i < nb_rank; ++i) {
642 nb_info_to_send_indexes[i] = total_nb_to_send;
643 total_nb_to_send += nb_info_to_send[i];
645 info() <<
"TOTAL_NB_TO_SEND=" << total_nb_to_send;
647 UniqueArray<Int64> resend_infos(total_nb_to_send);
649 ConstArrayView<BoundaryNodeInfo> all_bni = all_boundary_node_info;
650 Integer nb_node_to_send = node_list_to_send.size();
651 std::set<Int32> ranks_done;
652 for (
Integer i = 0; i < nb_node_to_send; ++i) {
653 Integer node_index = node_list_to_send[i].m_index;
654 Integer nb_cell = node_list_to_send[i].m_nb_cell;
655 Int64 node_uid = all_bni[node_index].node_uid;
659 for (
Integer kz = 0; kz < nb_cell; ++kz) {
660 Int32 krank = all_bni[node_index + kz].cell_owner;
661 if (ranks_done.find(krank) == ranks_done.end()) {
662 ranks_done.insert(krank);
663 Integer send_index = nb_info_to_send_indexes[krank];
664 resend_infos[send_index] = node_uid;
666 resend_infos[send_index] = nb_cell;
668 for (
Integer zz = 0; zz < nb_cell; ++zz) {
669 resend_infos[send_index] = all_bni[node_index + zz].cell_uid;
671 resend_infos[send_index] = all_bni[node_index + zz].cell_owner;
674 nb_info_to_send_indexes[krank] = send_index;
682 Timer::SimplePrinter sp(
traceMng(),
"Sending size with AllToAll");
683 pm->allToAll(nb_info_to_send, nb_info_to_recv, 1);
687 for (
Integer i = 0; i < nb_rank; ++i)
688 info() <<
"NB_TO_RECV: I=" << i <<
" n=" << nb_info_to_recv[i];
691 for (
Integer i = 0; i < nb_rank; ++i)
692 total_nb_to_recv += nb_info_to_recv[i];
699 UniqueArray<Int64> recv_infos;
706 Int32 total_send = 0;
707 Int32 total_recv = 0;
708 for (
Integer i = 0; i < nb_rank; ++i) {
709 send_counts[i] = (
Int32)(nb_info_to_send[i] * vsize);
710 recv_counts[i] = (
Int32)(nb_info_to_recv[i] * vsize);
711 send_indexes[i] = total_send;
712 recv_indexes[i] = total_recv;
713 total_send += send_counts[i];
714 total_recv += recv_counts[i];
716 recv_infos.resize(total_nb_to_recv);
721 info() <<
"BUF_SIZES: send=" << send_buf.size() <<
" recv=" << recv_buf.size();
723 Timer::SimplePrinter sp(
traceMng(),
"Send values with AllToAll");
724 pm->allToAllVariable(send_buf, send_counts, send_indexes, recv_buf, recv_counts, recv_indexes);
728 SubDomainItemMap cells_to_send(50,
true);
737 UniqueArray<Int32> my_cells;
738 SharedArray<Int32> ranks_to_send;
739 std::set<Int32> ranks_done;
740 while (index < total_nb_to_recv) {
741 Int64 node_uid = recv_infos[index];
743 Int64 nb_cell = recv_infos[index];
745 Node current_node(nodes_map.
findItem(node_uid));
747 info() <<
"NODE uid=" << node_uid <<
" nb_cell=" << nb_cell <<
" idx=" << (index - 2);
749 ranks_to_send.clear();
751 for (
Integer kk = 0; kk < nb_cell; ++kk) {
752 Int64 cell_uid = recv_infos[index];
754 Int32 cell_owner = CheckedConvert::toInt32(recv_infos[index]);
756 if (kk == 0 && current_layer == 1 && m_is_allocate)
762 info() <<
" CELL=" << cell_uid <<
" owner=" << cell_owner;
763 if (cell_owner == my_rank) {
764 impl::ItemBase dcell = cells_map.
tryFind(cell_uid);
766 ARCANE_FATAL(
"Internal error: cell uid={0} is not in our mesh", cell_uid);
767 if (do_only_minimal_uid) {
769 for (CellLocalId c : current_node.cellIds())
773 my_cells.add(dcell.localId());
776 if (ranks_done.find(cell_owner) == ranks_done.end()) {
777 ranks_to_send.add(cell_owner);
778 ranks_done.insert(cell_owner);
784 info() <<
"CELLS TO SEND: node_uid=" << node_uid
785 <<
" nb_rank=" << ranks_to_send.size()
786 <<
" nb_cell=" << my_cells.size();
787 info(4) <<
"CELLS TO SEND: node_uid=" << node_uid
788 <<
" rank=" << ranks_to_send
789 <<
" cell=" << my_cells;
792 for (
Integer zrank = 0, zn = ranks_to_send.size(); zrank < zn; ++zrank) {
793 Int32 send_rank = ranks_to_send[zrank];
794 SubDomainItemMap::Data* d = cells_to_send.lookupAdd(send_rank);
796 for (
Integer zid = 0, zid_size = my_cells.size(); zid < zid_size; ++zid) {
798 c.add(my_cells[zid]);
804 info() <<
"GHOST V3 SERIALIZE CELLS";
805 _sendAndReceiveCells(cells_to_send);
823 bool is_verbose = m_is_verbose;
826 boundary_node_sorter.setNeedIndexAndRank(
false);
830 boundary_node_sorter.
sort(boundary_node_list);
836 for (
Integer i = 0; i < n; ++i) {
838 info() <<
"NODES_KEY i=" << i
839 <<
" node=" << bni.node_uid
840 <<
" cell=" << bni.cell_uid
841 <<
" rank=" << bni.cell_owner;
860 Integer begin_own_list_index = 0;
861 if (n != 0 && my_rank != 0) {
862 if (BoundaryNodeBitonicSortTraits::isValid(all_bni[0])) {
863 Int64 node_uid = all_bni[0].node_uid;
864 for (
Integer i = 0; i < n; ++i) {
865 if (all_bni[i].node_uid != node_uid) {
866 begin_own_list_index = i;
870 end_node_list.
add(all_bni[i]);
874 info() <<
"BEGIN_OWN_LIST_INDEX=" << begin_own_list_index <<
" end_node_list_size=" << end_node_list.
size();
876 for (
Integer k = 0, kn = end_node_list.
size(); k < kn; ++k)
877 info() <<
" SEND node_uid=" << end_node_list[k].node_uid
878 <<
" cell_uid=" << end_node_list[k].cell_uid;
885 Integer send_message_size = BoundaryNodeBitonicSortTraits::messageSize(end_node_list);
888 if (my_rank != (nb_rank - 1)) {
894 info() <<
"Send size=" << send_message_size <<
" Recv size=" << recv_message_size;
898 if (recv_message_size != 0) {
899 Int32 nb_element = BoundaryNodeInfo::nbElement(recv_message_size);
900 end_node_list_recv.
resize(nb_element);
901 requests.
add(BoundaryNodeBitonicSortTraits::recv(pm, my_rank + 1, end_node_list_recv));
903 if (send_message_size != 0)
904 requests.
add(BoundaryNodeBitonicSortTraits::send(pm, my_rank - 1, end_node_list));
908 boundary_node_list.
clear();
909 boundary_node_list.
addRange(all_bni.
subConstView(begin_own_list_index, n - begin_own_list_index));
910 boundary_node_list.
addRange(end_node_list_recv);
917void GhostLayerBuilder2::
918_sendAndReceiveCells(SubDomainItemMap& cells_to_send)
922 const bool is_verbose = m_is_verbose;
925 for (SubDomainItemMap::Enumerator i_map(cells_to_send); ++i_map;) {
926 Int32 sd = i_map.data()->key();
932 std::sort(std::begin(items), std::end(items));
933 auto new_end = std::unique(std::begin(items), std::end(items));
934 items.
resize(CheckedConvert::toInteger(new_end - std::begin(items)));
936 info(4) <<
"CELLS TO SEND SD=" << sd <<
" Items=" << items;
938 info(4) <<
"CELLS TO SEND SD=" << sd <<
" nb=" << items.size();
939 exchanger->addSender(sd);
941 exchanger->initializeCommunicationsMessages();
942 for (
Integer i = 0, ns = exchanger->nbSender(); i < ns; ++i) {
943 ISerializeMessage* sm = exchanger->messageToSend(i);
944 Int32 rank = sm->destination().value();
945 ISerializer* s = sm->serializer();
949 exchanger->processExchange();
950 info(4) <<
"END EXCHANGE CELLS";
951 for (
Integer i = 0, ns = exchanger->nbReceiver(); i < ns; ++i) {
952 ISerializeMessage* sm = exchanger->messageToReceive(i);
953 ISerializer* s = sm->serializer();
957 ScopedPtrT<IItemFamilySerializer> cell_serializer(m_mesh->cellFamily()->policyMng()->createSerializer());
958 cell_serializer->deserializeItems(s,
nullptr);
960 m_mesh_internal->printStats(TraceMessage::DEFAULT_LEVEL);
977 ItemInternalMap& faces_map = m_mesh_internal->facesMap();
983 bool is_sub_domain_boundary_face =
false;
985 is_sub_domain_boundary_face =
true;
989 is_sub_domain_boundary_face =
true;
991 if (is_sub_domain_boundary_face) {
994 inode.mutableItemBase().addFlags(shared_and_boundary_flags);
996 iedge.mutableItemBase().addFlags(shared_and_boundary_flags);
999 _markBoundaryNodesFromEdges(node_layer);
1005void GhostLayerBuilder2::
1009 if (!is_non_manifold)
1014 info() <<
"Mark boundary nodes from edges for non-manifold mesh";
1024 Int32 nb_dim2_cell = 0;
1025 Int32 nb_own_dim2_cell = 0;
1030 if (cell.
owner() == my_rank)
1034 if (nb_dim2_cell == nb_cell && nb_own_dim2_cell == 1) {
1036 for (Item inode : edge.
nodes()) {
1037 inode.mutableItemBase().addFlags(shared_and_boundary_flags);
1038 node_layer[inode.localId()] = 1;
1048_buildGhostLayerNewVersion(IMesh* mesh,
bool is_allocate,
Int32 version)
1051 glb.addGhostLayers();
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
constexpr const_pointer data() const noexcept
Pointer to the start of the view.
Base class for 1D data vectors.
void addRange(ConstReferenceType val, Int64 n)
Adds n elements of value val to the end of the array.
void resize(Int64 s)
Changes the number of elements in the array to s.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Constant view of an array of type T.
constexpr const_pointer data() const noexcept
Pointer to the allocated memory.
constexpr Integer size() const noexcept
Number of elements in the array.
constexpr ConstArrayView< T > subConstView(Integer abegin, Integer asize) const noexcept
Sub-view (constant) starting from element abegin and containing asize elements.
Template class for converting a type.
CellConnectedListViewType cells() const
List of edge cells.
Int32 nbCell() const
Number of cells connected to the edge.
Cell cell(Int32 i) const
i-th cell of the face
Int32 nbCell() const
Number of cells of the face (1 or 2).
EdgeConnectedListViewType edges() const
List of edges of the face.
Hash table for associative arrays.
virtual Int32 maxLocalId() const =0
virtual IItemFamily * nodeFamily()=0
Returns the node family.
virtual mesh::ItemInternalMap & nodesMap()=0
virtual IParallelMng * parallelMng()=0
Parallelism manager.
virtual ARCANE_DEPRECATED_240 void serializeCells(ISerializer *buffer, Int32ConstArrayView cells_local_id)=0
virtual const MeshKind meshKind() const =0
Mesh characteristics.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual void recv(ArrayView< char > values, Int32 rank)=0
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual void waitAllRequests(ArrayView< Request > rvalues)=0
Blocks while waiting for the rvalues requests to complete.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
@ ModeGet
The serializer expects get().
MutableItemBase toMutable()
Mutable interface of this entity.
Int32 flags() const
Flags of the entity.
@ II_Shared
The entity is shared by another subdomain.
@ II_SubDomainBoundary
The entity is at the boundary of two subdomains.
@ II_Boundary
The entity is on the boundary.
Internal structure of a mesh entity.
Utility class for printing information about an entity.
Int16 dimension() const
Dimension of the element (<0 if unknown).
NodeConnectedListViewType nodes() const
List of nodes of the entity.
NodeLocalIdView nodeIds() const
List of nodes of the entity.
Base class for a mesh element.
const ItemTypeInfo * typeInfo() const
Information about the entity type.
impl::MutableItemBase mutableItemBase() const
Mutable internal part of the entity.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Int32 owner() const
Owner subdomain number of the entity.
ItemUniqueId uniqueId() const
Unique identifier across all domains.
constexpr bool isOwn() const
true if the entity belongs to the subdomain
impl::ItemBase itemBase() const
Internal part of the entity.
bool isNonManifold() const
True if the mesh structure is eMeshCellDimensionKind::NonManifold.
void setOwner(Integer suid, Int32 current_sub_domain)
Sets the sub-domain number of the entity owner.
void addFlags(Int32 added_flags)
Adds the flags added_flags to those of the entity.
Parallel bitonic sort algorithm.
ConstArrayView< KeyType > keys() const override
After a sort, returns the list of elements on this rank.
void sort(ConstArrayView< KeyType > keys) override
Parallelly sorts the elements of keys on all ranks.
1D vector of data with reference semantics.
Displays the time elapsed between the call to the constructor and the destructor.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
TraceMessage warning() const
Flow for a warning message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Functor for sorting BoundaryNodeInfo via bitonic sort.
Structure containing boundary node information.
Construction of ghost layers.
void _sortBoundaryNodeList(Array< BoundaryNodeInfo > &boundary_node_list)
Parallel sorting of the list of boundary node information.
void _markBoundaryItems(ArrayView< Int32 > node_layer)
Marks the entities at the edge of the sub-domain.
void addGhostLayers()
Adds ghost cell layers.
GhostLayerBuilder2(IMesh *mesh, bool is_allocate, Int32 version)
Constructs an instance for the mesh mesh.
void _markBoundaryNodes(ArrayView< Int32 > node_layer)
Determines the boundary nodes.
Associative array of ItemInternal.
impl::ItemBase findItem(Int64 uid) const
Returns the unique ID entity uid.
void eachItem(const Lambda &lambda)
Template function to iterate over the instance's entities.
impl::ItemBase tryFind(Int64 key) const
Returns the entity associated with key if found, or the null entity otherwise.
Ref< IParallelExchanger > createExchangerRef(IParallelMng *pm)
Returns an interface to transfer messages between ranks.
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
ArrayView< Integer > IntegerArrayView
C equivalent of a 1D array of integers.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.
UniqueArray< Integer > IntegerUniqueArray
Dynamic 1D array of integers.
ConstArrayView< Integer > IntegerConstArrayView
C equivalent of a 1D array of integers.
std::int32_t Int32
Signed integer type of 32 bits.