14#include "arcane/utils/HashTableMap.h"
15#include "arcane/utils/Real3.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/Collection.h"
21#include "arcane/mesh/DynamicMesh.h"
22#include "arcane/mesh/FaceFamily.h"
23#include "arcane/mesh/MapCoordToUid.h"
24#include "arcane/mesh/ParallelAMRConsistency.h"
26#include "arcane/core/IMesh.h"
27#include "arcane/core/IMeshSubMeshTransition.h"
29#include "arcane/core/ItemGroup.h"
30#include "arcane/core/Item.h"
31#include "arcane/core/ISubDomain.h"
32#include "arcane/core/VariableTypes.h"
33#include "arcane/core/IItemFamily.h"
34#include "arcane/core/ItemCompare.h"
35#include "arcane/core/IParallelMng.h"
36#include "arcane/core/GeometricUtilities.h"
37#include "arcane/core/SerializeBuffer.h"
38#include "arcane/core/ItemPrinter.h"
39#include "arcane/core/IMeshUtilities.h"
53#ifdef ACTIVATE_PERF_COUNTER
54const std::string ParallelAMRConsistency::PerfCounter::m_names[ParallelAMRConsistency::PerfCounter::NbCounters] = {
71, m_nodes_coord(m_mesh->toPrimaryMesh()->nodesCoordinates())
72, m_nodes_info(1000, true)
73, m_active_nodes(1000, true)
74, m_active_faces(5000, true)
75, m_active_faces2(5000, true)
84void ParallelAMRConsistency::
87 CHECKPERF(m_perf_counter.start(PerfCounter::INIT))
90 m_shared_face_uids.
reserve(nb_active_face);
91 m_shared_face_uids.
clear();
92 m_connected_shared_face_uids.
reserve(nb_active_face);
93 m_connected_shared_face_uids.
clear();
103 m_shared_face_uids.
add(face_uid);
105 else if (_hasSharedNodes(face)) {
106 m_connected_shared_face_uids.
add(face_uid);
110 if (_hasSharedNodes(face)) {
111 m_connected_shared_face_uids.add(face_uid);
117 CHECKPERF(m_perf_counter.stop(PerfCounter::INIT))
124void ParallelAMRConsistency::
125_addFaceToList(Face face, FaceInfoMap& face_map)
127 Integer nb_node = face.nbNode();
128 Real3 center(0., 0., 0.);
129 Integer data_index = m_face_info_mng.size();
130 for (Node node : face.nodes()) {
131 Real3 node_coord = m_nodes_coord[node];
132 ItemUniqueId uid = node.uniqueId();
133 m_face_info_mng.add(uid);
134 center += node_coord;
139 FaceInfo fi(face.uniqueId(), face.cell(0).uniqueId(), nb_node, face.owner(), data_index, &m_face_info_mng);
140 fi.setCenter(center);
141 face_map.add(face.uniqueId(), fi);
147bool ParallelAMRConsistency::
148_hasSharedNodes(Face face)
151 for (Node node : face.nodes()) {
169 CHECKPERF(m_perf_counter.start(PerfCounter::COMPUTE))
172 Integer nb_active_face =
static_cast<Integer>(m_mesh->nbFace() * 0.2);
174 m_nodes_info.resize((nb_active_face * 2) + 5);
175 m_nodes_info.clear();
177 Real3 node_coord = m_nodes_coord[i_item];
179 NodeInfo node_info(uid, i_item->owner());
180 node_info.setCoord(node_coord);
181 m_nodes_info.add(uid, node_info);
184 m_active_faces.resize((nb_active_face * 2) + 5);
185 m_active_nodes.resize((nb_active_face * 2) + 5);
186 m_active_faces.clear();
187 m_face_info_mng.m_nodes_unique_id.clear();
188 m_face_info_mng.m_nodes_unique_id.reserve(nb_active_face);
191 if (!true_face_family)
194 Int32 sid = m_mesh->parallelMng()->commRank();
196 ItemMap active_faces;
198 typedef std::set<ItemInternal*> Set;
199 Set active_nodes_set;
200 ItemMap active_nodes;
207 for (
Integer iface = 0; iface < m_shared_face_uids.size(); ++iface) {
208 Int64 face_uid = m_shared_face_uids[iface];
212 true_face_family->allSubFaces(face, subfaces);
213 if (subfaces.
size() != 1) {
215 Face face2 = subfaces[s];
218 bool face_to_send = face_finder.isNewUid(uid);
220 _addFaceToList(face2, m_active_faces);
223 active_faces.insert(ItemMapValue(uid, face2));
227 active_nodes.insert(ItemMapValue(node.uniqueId(), node));
237 for (
Integer iface = 0; iface < m_connected_shared_face_uids.size(); ++iface) {
238 Int64 face_uid = m_connected_shared_face_uids[iface];
243 typedef std::pair<Real3, Real3>
Edge;
246 for (
Integer i = 0; i < nb_node; ++i) {
247 Integer next = i == nb_node - 1 ? 0 : i + 1;
252 edges.
add(
Edge(m_nodes_coord[node1], m_nodes_coord[node2] - m_nodes_coord[node1]));
256 true_face_family->allSubFaces(face, subfaces);
258 Face face2(subfaces[s]);
260 bool face_to_send = face_finder.isNewUid(uid);
263 for (
Integer i = 0; i < nb_node2; ++i) {
265 Real3 Xi = m_nodes_coord[node_i];
267 Real3 n = Xi - edges[j].first;
272 active_nodes.insert(ItemMapValue(node_i.
uniqueId(), node_i));
273 _addNodeToList(node_i, m_active_nodes);
283 ItemMap::const_iterator nit(active_nodes.begin()), nend(active_nodes.end());
284 for (
int i = 0; nit != nend; ++nit, ++i) {
285 Item node = nit->second;
286 active_nodes_to_send[i] = node.
uniqueId();
289 CHECKPERF(m_perf_counter.stop(PerfCounter::COMPUTE))
292 ItemUidSet update_face_uids;
293 ItemUidSet update_node_uids;
294 _gatherFaces(active_faces_to_send, active_nodes_to_send, m_active_faces, node_finder, face_finder, update_face_uids, update_node_uids);
297 CHECKPERF(m_perf_counter.start(PerfCounter::UPDATE))
300 for (ItemUidSet::iterator iter = update_face_uids.begin(); iter != update_face_uids.end(); ++iter) {
301 Int64 face_uid = *iter;
302 Item face = active_faces[face_uid];
305 Int64 new_uid = fi.uniqueId();
306 faces_map.
remove(face_uid);
308 ARCANE_ASSERT((face_uid != new_uid), (
"AMR CONSISTENCY UPDATE FACE ERROR"));
312 faces_map.
add(new_uid, ItemCompatibility::_itemInternal(face));
318 for (ItemUidSet::iterator iter = update_node_uids.begin(); iter != update_node_uids.end(); ++iter) {
320 Int64 node_uid = *iter;
321 Item node = active_nodes[node_uid];
326 Int64 new_uid = ni.uniqueId();
328 ARCANE_ASSERT((node_uid != new_uid), (
"AMR CONSISTENCY UPDATE NODE ERROR"));
330 nodes_map.
remove(node_uid);
334 nodes_map.
add(new_uid, ItemCompatibility::_itemInternal(node));
336 CHECKPERF(m_perf_counter.stop(PerfCounter::UPDATE))
338 CHECKPERF(m_perf_counter.start(PerfCounter::ENDUPDATE))
339 m_mesh->nodeFamily()->partialEndUpdate();
340 m_mesh->faceFamily()->partialEndUpdate();
341 CHECKPERF(m_perf_counter.stop(PerfCounter::ENDUPDATE))
359 FaceInfoMap& face_map,
362 ItemUidSet& updated_face_uids,
363 ItemUidSet& updated_node_uids)
365 CHECKPERF(m_perf_counter.start(PerfCounter::GATHERFACE))
371 const Real tol = 10e-12;
374 sbuf.
setMode(ISerializer::ModeReserve);
381 nodes_unique_id.
reserve(nb_node_to_send);
383 coords.
reserve(3 * nb_to_send);
385 nodes_coords.
reserve(3 * nb_node_to_send);
386 for (
Integer i = 0; i < nb_to_send; ++i) {
387 const FaceInfo& fi = face_map[faces_to_send[i]];
388 unique_ids[i] = fi.uniqueId().asInt64();
389 cells_unique_ids[i] = fi.cellUniqueId().asInt64();
390 coords.
add(fi.center().
x);
391 coords.
add(fi.center().
y);
392 coords.
add(fi.center().
z);
394 debug() <<
"SEND NODE : " << nb_node_to_send;
395 for (
Integer i = 0; i < nb_node_to_send; ++i) {
398 nodes_unique_id.
add(nuid.asInt64());
400 Real3 c = ni.getCoord();
401 nodes_coords.
add(c.
x);
402 nodes_coords.
add(c.
y);
403 nodes_coords.
add(c.
z);
405 sbuf.reserveInteger(1);
406 sbuf.reserveInteger(1);
407 sbuf.reserveInteger(1);
430 for (
Integer i = 0; i < nb_sub_domain; ++i) {
434 info() <<
" [\t ParallelAMRConsistency::_gatherFaces] READ nface=" << nb_face <<
" FROM sid=" << sid <<
" " << m_face_info_mng.size();
436 recv_buf.
getArray(cells_unique_ids);
443 for (
Integer z = 0; z < nb_face; ++z) {
448 center.
x = coords[z * 3];
449 center.
y = coords[z * 3 + 1];
450 center.
z = coords[z * 3 + 2];
452 const Int64 current_uid = face_finder.find(center, tol);
453 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)) {
455 error() <<
"face uid not found \n";
458 face_finder.insert(center, new_uid, tol);
459 updated_face_uids.insert(current_uid);
462 Integer data_index = fi_old.getDataIndex();
463 Integer nb_node = fi_old.nbNode();
464 FaceInfo fi(new_uid, cell_uid, nb_node, sid, data_index, &m_face_info_mng);
465 fi.setCenter(center);
470 for (
Integer z = 0; z < nb_node_unique_id; ++z) {
473 node_coord.
x = nodes_coords[z * 3];
474 node_coord.
y = nodes_coords[z * 3 + 1];
475 node_coord.
z = nodes_coords[z * 3 + 2];
476 Int64 current_node_uid = node_finder.find(node_coord, tol);
477 if ((current_node_uid != NULL_ITEM_ID) && (nuid < current_node_uid)) {
479 if (nuid < m_nodes_info[c_nuid].uniqueId()) {
481 ni.setCoord(node_coord);
482 m_nodes_info[c_nuid] = ni;
485 updated_node_uids.insert(current_node_uid);
490 CHECKPERF(m_perf_counter.stop(PerfCounter::GATHERFACE))
492 CHECKPERF(m_perf_counter.start(PerfCounter::UPDATE))
494 for (ItemUidSet::iterator iter = updated_node_uids.begin(); iter != updated_node_uids.end(); ++iter) {
497 node_finder.insert(ni.getCoord(), ni.uniqueId(), tol);
501 _update(m_face_info_mng.m_nodes_unique_id, m_nodes_info);
503 CHECKPERF(m_perf_counter.stop(PerfCounter::UPDATE))
511void ParallelAMRConsistency::
514 for (
Integer i = 0, n = nodes_unique_id.
size(); i < n; ++i) {
516 NodeInfoList::Data
const* data = nodes_info.lookup(uid);
518 nodes_unique_id[i] = data->value().uniqueId();
520 info() <<
"ERROR " << i <<
" " << uid <<
" not found";
527void ParallelAMRConsistency::
528_addNodeToList(Node node, NodeInfoList& node_map)
530 Real3 node_coord = m_nodes_coord[node];
531 ItemUniqueId uid = node.uniqueId();
532 NodeInfoList::Data* i = node_map.lookup(uid);
534 NodeInfo node_info(uid, node.owner());
535 node_info.setCoord(node_coord);
536 node_map.add(uid, node_info);
543void ParallelAMRConsistency::
544_addFaceToList2(Face face, FaceInfoMap2& face_map)
546 Integer nb_node = face.nbNode();
547 ItemUniqueId uid = face.uniqueId();
548 FaceInfoMap2::Data* i = face_map.lookup(uid);
550 Real3 center(0., 0., 0.);
551 for (Node node : face.nodes()) {
552 Real3 node_coord = m_nodes_coord[node];
553 center += node_coord;
556 FaceInfo2 fi(face.uniqueId(), face.owner());
557 fi.setCenter(center);
558 face_map.add(uid, fi);
574 Integer nb_active_face =
static_cast<Integer>(m_mesh->nbFace() * 0.2);
575 m_active_nodes.resize((nb_active_face * 2) + 5);
576 m_active_faces.resize((nb_active_face * 2) + 5);
579 if (!true_face_family)
582 Int32 sid = m_mesh->parallelMng()->commRank();
584 typedef std::set<Item> Set;
585 Set active_nodes_set, active_faces_set;
593 bool is_sub_domain_boundary_face =
false;
595 is_sub_domain_boundary_face =
true;
600 is_sub_domain_boundary_face =
true;
604 if (is_sub_domain_boundary_face) {
606 true_face_family->allSubFaces(face, subfaces);
608 Face face2 = subfaces[s];
610 _addFaceToList2(face2, m_active_faces2);
611 active_faces_set.insert(face2);
614 active_nodes_set.insert(node);
615 _addNodeToList(node, m_active_nodes);
629 Set::const_iterator fit(active_faces_set.begin()), fend(active_faces_set.end());
631 for (; fit != fend; ++fit) {
633 active_faces_to_send[i] = (face.
uniqueId());
634 active_faces[i] = face;
637 Set::const_iterator nit(active_nodes_set.begin()), nend(active_nodes_set.end());
639 for (; nit != nend; ++nit) {
641 active_nodes_to_send[i] = (node.
uniqueId());
643 active_nodes[i] = node;
647 _gatherItems(active_nodes_to_send, active_faces_to_send, m_active_nodes, m_active_faces2, node_finder, face_finder);
649 for (
Integer index = 0; index < active_faces.
size(); index++) {
650 Item face = active_faces[index];
653 if (current_uid != fi.uniqueId()) {
659 for (
Integer index = 0; index < active_nodes.
size(); index++) {
660 Item node = active_nodes[index];
663 if (current_uid != ni.uniqueId()) {
674 mesh->nodesMap().notifyUniqueIdsChanged();
692 NodeInfoList& node_map,
693 FaceInfoMap2& face_map,
702 sbuf.
setMode(ISerializer::ModeReserve);
708 coords.
reserve(3 * nb_to_send);
710 nodes_coords.
reserve(3 * nb_node_to_send);
712 for (
Integer i = 0; i < nb_node_to_send; ++i) {
713 const NodeInfo& ni = node_map[nodes_to_send[i]];
714 node_unique_ids[i] = ni.uniqueId().asInt64();
715 const Real3 c = ni.getCoord();
716 nodes_coords.
add(c.
x);
717 nodes_coords.
add(c.
y);
718 nodes_coords.
add(c.
z);
721 for (
Integer i = 0; i < nb_to_send; ++i) {
722 const FaceInfo2& fi = face_map[faces_to_send[i]];
723 unique_ids[i] = fi.uniqueId().asInt64();
724 coords.
add(fi.center().
x);
725 coords.
add(fi.center().
y);
726 coords.
add(fi.center().
z);
729 sbuf.reserveInteger(1);
730 sbuf.reserveInteger(1);
731 sbuf.reserveInteger(1);
752 for (
Integer i = 0; i < nb_sub_domain; ++i) {
765 const Real tol = 10e-6;
766 for (
Integer z = 0; z < nb_face; ++z) {
770 center.
x = coords[z * 3];
771 center.
y = coords[z * 3 + 1];
772 center.
z = coords[z * 3 + 2];
774 const Int64 current_uid = face_finder.find(center, tol);
775 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)) {
777 error() <<
"face uid not found \n";
780 fi.setCenter(center);
785 for (
Integer z = 0; z < nb_node_unique_id; ++z) {
788 node_coord.
x = nodes_coords[z * 3];
789 node_coord.
y = nodes_coords[z * 3 + 1];
790 node_coord.
z = nodes_coords[z * 3 + 2];
791 Int64 current_node_uid = node_finder.find(node_coord, tol);
792 if ((current_node_uid != NULL_ITEM_ID) && (nuid < current_node_uid)) {
794 ni.setCoord(node_coord);
796 node_map[c_nuid] = ni;
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
Base class for 1D data vectors.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
void getArray(Array< Real > &values) override
Resize and fill values.
void allocateBuffer() override
Allocates the serializer memory.
void reserveArray(Span< const Real > values) override
Reserve to save the number of elements and the values elements.
void putArray(Span< const Real > values) override
Save the number of elements and the values elements.
Integer getInteger() override
Retrieve a size.
void setMode(eMode new_mode) override
Sets the current mode.
void putInteger(Integer value) override
Add the integer value.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
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.
Exception when a fatal error has occurred.
bool hasKey(KeyTypeConstRef id)
true if a value with key id is present
virtual FaceGroup allFaces()=0
Group of all faces.
virtual Integer nbFace()=0
Number of mesh faces.
virtual IParallelMng * parallelMng()=0
Parallelism manager.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual Int32 commSize() const =0
Number of instances in the communicator.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Performs an all-gather operation across all processors. This is a collective operation....
virtual void barrier()=0
Performs a barrier.
@ ModePut
The serializer expects reserve().
@ ModeGet
The serializer expects get().
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.
Unique identifier of an entity.
Node node(Int32 i) const
i-th node of the entity
NodeConnectedListViewType nodes() const
List of nodes of the entity.
Int32 nbNode() const
Number of nodes of the entity.
Base class for a mesh element.
impl::MutableItemBase mutableItemBase() const
Mutable internal part of the entity.
Int32 owner() const
Owner subdomain number of the entity.
ItemUniqueId uniqueId() const
Unique identifier across all domains.
constexpr bool null() const
true if the entity is null (i.e. not connected to the mesh)
impl::ItemBase itemBase() const
Internal part of the entity.
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.
Class managing a 3-dimensional real vector.
constexpr __host__ __device__ Real squareNormL2() const
Returns the square of the L2 norm of the triplet $ .
Implementation of a buffer for serialization.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
TraceMessage error() const
Flow for an error message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Implementation of a mesh.
Associative array of ItemInternal.
void remove(Int64 key)
Removes the value associated with the key key.
impl::ItemBase findItem(Int64 uid) const
Returns the unique ID entity uid.
void notifyUniqueIdsChanged()
Notifies that the unique IDs of the entities have changed.
void eachItem(const Lambda &lambda)
Template function to iterate over the instance's entities.
bool add(Int64 key, ItemInternal *v)
Adds the value v corresponding to the key key.
structure for searching for a node based on its coordinates The hashing key is the geometric position...
void makeNewItemsConsistent2(MapCoordToUid &node_finder, MapCoordToUid &face_finder)
Determines the faces to send to neighbors.
void makeNewItemsConsistent(NodeMapCoordToUid &node_finder, FaceMapCoordToUid &face_finder)
Determines the faces to send to neighbors.
void _gatherFaces(ConstArrayView< ItemUniqueId > faces_to_send, ConstArrayView< ItemUniqueId > nodes_to_send, FaceInfoMap &face_map, MapCoordToUid &node_finder, MapCoordToUid &face_finder, ItemUidSet &updated_face_uids, ItemUidSet &updated_node_uids)
void _gatherItems(ConstArrayView< ItemUniqueId > nodes_to_send, ConstArrayView< ItemUniqueId > faces_to_send, NodeInfoList &node_map, FaceInfoMap2 &face_map, MapCoordToUid &node_finder, MapCoordToUid &face_finder)
ParallelAMRConsistency(IMesh *mesh)
AMR.
__host__ __device__ Real3 cross(Real3 v1, Real3 v2)
Cross product of two 3-component vectors.
bool isZero(const BuiltInProxy< _Type > &a)
Tests if a value is exactly equal to zero.
Integer arcaneCheckArraySize(unsigned long long size)
Checks that size can be converted into an 'Integer' to serve as the size of an array....
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
UniqueArray< Real > RealUniqueArray
Dynamic 1D array of reals.
@ IK_Face
Face mesh entity.
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.
Real y
second component of the triplet
Real z
third component of the triplet
Real x
first component of the triplet