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 envoyant une exception FatalErrorException.
Integer size() const
Nombre d'éléments du vecteur.
Tableau d'items de types quelconques.
void clear()
Supprime les éléments du tableau.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void getArray(Array< Real > &values) override
Redimensionne et remplit values.
void allocateBuffer() override
Alloue la mémoire du sérialiseur.
void reserveArray(Span< const Real > values) override
Réserve pour sauver le nombre d'éléments et les values éléments.
void putArray(Span< const Real > values) override
Sauve le nombre d'éléments et les values éléments.
Integer getInteger() override
Récupère une taille.
void setMode(eMode new_mode) override
Positionne le fonctionnement actuel.
void putInteger(Integer value) override
Ajoute l'entier value.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
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.
Exception lorsqu'une erreur fatale est survenue.
bool hasKey(KeyTypeConstRef id)
true si une valeur avec la clé id est présente
virtual FaceGroup allFaces()=0
Groupe de toutes les faces.
virtual Integer nbFace()=0
Nombre de faces du maillage.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
virtual void allGather(ConstArrayView< char > send_buf, ArrayView< char > recv_buf)=0
Effectue un regroupement sur tous les processeurs. Il s'agit d'une opération collective....
virtual void barrier()=0
Effectue une barière.
@ ModePut
Le sérialiseur attend des reserve().
@ ModeGet
Le sérialiseur attend des get().
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.
Identifiant unique d'une entité.
Node node(Int32 i) const
i-ème noeud de l'entité
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
Classe de base d'un élément de maillage.
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
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é
Classe gérant un vecteur de réel de dimension 3.
constexpr __host__ __device__ Real squareNormL2() const
Retourne la norme L2 au carré du triplet .
Implémentation d'un tampon pour la sérialisation.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage error() const
Flot pour un message d'erreur.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
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)
Produit vectoriel de deux vecteurs à 3 composantes.
bool isZero(const BuiltInProxy< _Type > &a)
Teste si une valeur est exactement égale à zéro.
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Real > RealUniqueArray
Tableau dynamique à une dimension de réels.
@ IK_Face
Entité de maillage de genre face.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet