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] =
72, m_nodes_coord(m_mesh->toPrimaryMesh()->nodesCoordinates())
73, m_nodes_info(1000, true)
74, m_active_nodes(1000, true)
75, m_active_faces(5000, true)
76, m_active_faces2(5000, true)
85void ParallelAMRConsistency::
88 CHECKPERF( m_perf_counter.start(PerfCounter::INIT) )
91 m_shared_face_uids.
reserve(nb_active_face) ;
92 m_shared_face_uids.
clear() ;
93 m_connected_shared_face_uids.
reserve(nb_active_face) ;
94 m_connected_shared_face_uids.
clear() ;
104 m_shared_face_uids.
add(face_uid);
106 else if (_hasSharedNodes(face)){
107 m_connected_shared_face_uids.
add(face_uid);
111 if (_hasSharedNodes(face)){
112 m_connected_shared_face_uids.add(face_uid);
116 m_is_updated = true ;
118 CHECKPERF( m_perf_counter.stop(PerfCounter::INIT) )
125void ParallelAMRConsistency::
126_addFaceToList(Face face, FaceInfoMap& face_map)
128 Integer nb_node = face.nbNode();
129 Real3 center(0., 0., 0.);
130 Integer data_index = m_face_info_mng.size();
131 for (Node node : face.nodes()){
132 Real3 node_coord = m_nodes_coord[node];
133 ItemUniqueId uid = node.uniqueId();
134 m_face_info_mng.add(uid);
135 center += node_coord;
140 FaceInfo fi(face.uniqueId(), face.cell(0).uniqueId(), nb_node, face.owner(), data_index, &m_face_info_mng);
141 fi.setCenter(center);
142 face_map.add(face.uniqueId(), fi);
148bool ParallelAMRConsistency::
149_hasSharedNodes(Face face)
152 for ( Node node : face.nodes() ){
170 CHECKPERF( m_perf_counter.start(PerfCounter::COMPUTE) )
173 Integer nb_active_face =
static_cast<Integer> (m_mesh->nbFace() * 0.2);
175 m_nodes_info.resize((nb_active_face * 2) + 5);
176 m_nodes_info.clear() ;
178 Real3 node_coord = m_nodes_coord[i_item];
180 NodeInfo node_info(uid, i_item->owner());
181 node_info.setCoord(node_coord);
182 m_nodes_info.add(uid, node_info);
186 m_active_faces.resize((nb_active_face * 2) + 5);
187 m_active_nodes.resize((nb_active_face * 2) + 5);
188 m_active_faces.clear() ;
189 m_face_info_mng.m_nodes_unique_id.clear() ;
190 m_face_info_mng.m_nodes_unique_id.reserve(nb_active_face) ;
194 if (!true_face_family)
197 Int32 sid = m_mesh->parallelMng()->commRank();
199 ItemMap active_faces ;
200 UniqueArray < ItemUniqueId > active_faces_to_send;
201 typedef std::set<ItemInternal*> Set;
202 Set active_nodes_set;
203 ItemMap active_nodes ;
210 for(
Integer iface=0;iface<m_shared_face_uids.size();++iface){
211 Int64 face_uid = m_shared_face_uids[iface];
215 true_face_family->allSubFaces(face, subfaces);
216 if (subfaces.
size() != 1){
218 Face face2 = subfaces[s];
221 bool face_to_send = face_finder.isNewUid(uid);
223 _addFaceToList(face2, m_active_faces);
226 active_faces.insert(ItemMapValue(uid,face2));
230 active_nodes.insert(ItemMapValue(node.uniqueId(),node));
240 for(
Integer iface=0;iface<m_connected_shared_face_uids.size();++iface){
241 Int64 face_uid = m_connected_shared_face_uids[iface];
246 typedef std::pair<Real3,Real3>
Edge ;
249 for(
Integer i=0;i<nb_node;++i){
250 Integer next = i==nb_node-1?0:i+1;
255 edges.
add(
Edge(m_nodes_coord[node1],m_nodes_coord[node2]-m_nodes_coord[node1])) ;
259 true_face_family->allSubFaces(face, subfaces);
261 Face face2(subfaces[s]);
263 bool face_to_send = face_finder.isNewUid(uid) ;
266 for(
Integer i=0;i<nb_node2;++i){
268 Real3 Xi = m_nodes_coord[node_i] ;
270 Real3 n = Xi-edges[j].first ;
275 active_nodes.insert(ItemMapValue(node_i.
uniqueId(),node_i));
276 _addNodeToList(node_i, m_active_nodes);
286 ItemMap::const_iterator nit(active_nodes.begin()), nend(active_nodes.end());
287 for (
int i=0; nit != nend; ++nit,++i){
288 Item node = nit->second;
289 active_nodes_to_send[i]= node.
uniqueId();
292 CHECKPERF( m_perf_counter.stop(PerfCounter::COMPUTE) )
295 ItemUidSet update_face_uids ;
296 ItemUidSet update_node_uids ;
297 _gatherFaces(active_faces_to_send,active_nodes_to_send, m_active_faces, node_finder, face_finder,update_face_uids,update_node_uids);
302 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATE) )
305 for(ItemUidSet::iterator iter = update_face_uids.begin();iter!=update_face_uids.end();++iter){
306 Int64 face_uid = *iter ;
307 Item face = active_faces[face_uid];
310 Int64 new_uid = fi.uniqueId() ;
311 faces_map.
remove(face_uid) ;
313 ARCANE_ASSERT((face_uid != new_uid),(
"AMR CONSISTENCY UPDATE FACE ERROR")) ;
317 faces_map.
add(new_uid,ItemCompatibility::_itemInternal(face));
323 for(ItemUidSet::iterator iter = update_node_uids.begin();iter!=update_node_uids.end();++iter){
325 Int64 node_uid = *iter ;
326 Item node = active_nodes[node_uid];
331 Int64 new_uid = ni.uniqueId() ;
333 ARCANE_ASSERT((node_uid != new_uid),(
"AMR CONSISTENCY UPDATE NODE ERROR")) ;
335 nodes_map.
remove(node_uid) ;
339 nodes_map.
add(new_uid,ItemCompatibility::_itemInternal(node));
341 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATE) )
343 CHECKPERF( m_perf_counter.start(PerfCounter::ENDUPDATE) )
344 m_mesh->nodeFamily()->partialEndUpdate();
345 m_mesh->faceFamily()->partialEndUpdate();
346 CHECKPERF( m_perf_counter.stop(PerfCounter::ENDUPDATE) )
364 FaceInfoMap& face_map,
367 ItemUidSet& updated_face_uids,
368 ItemUidSet& updated_node_uids)
370 CHECKPERF( m_perf_counter.start(PerfCounter::GATHERFACE) )
376 const Real tol = 10e-12;
379 sbuf.
setMode(ISerializer::ModeReserve);
386 nodes_unique_id.
reserve(nb_node_to_send);
388 coords.
reserve(3 * nb_to_send);
390 nodes_coords.
reserve(3 *nb_node_to_send );
391 for (
Integer i = 0; i < nb_to_send; ++i){
392 const FaceInfo& fi = face_map[faces_to_send[i]];
393 unique_ids[i] = fi.uniqueId().asInt64();
394 cells_unique_ids[i] = fi.cellUniqueId().asInt64();
395 coords.
add(fi.center().
x);
396 coords.
add(fi.center().
y);
397 coords.
add(fi.center().
z);
399 debug()<<
"SEND NODE : "<<nb_node_to_send;
400 for (
Integer i = 0; i < nb_node_to_send; ++i){
403 nodes_unique_id.
add(nuid.asInt64());
405 Real3 c = ni.getCoord();
406 nodes_coords.
add(c.
x);
407 nodes_coords.
add(c.
y);
408 nodes_coords.
add(c.
z);
410 sbuf.reserveInteger(1);
411 sbuf.reserveInteger(1);
412 sbuf.reserveInteger(1);
435 for (
Integer i = 0; i < nb_sub_domain; ++i){
439 info() <<
" [\t ParallelAMRConsistency::_gatherFaces] READ nface=" << nb_face <<
" FROM sid=" << sid<<
" "<<m_face_info_mng.size();
441 recv_buf.
getArray(cells_unique_ids);
448 for (
Integer z = 0; z < nb_face; ++z){
453 center.
x = coords[z * 3];
454 center.
y = coords[z * 3 + 1];
455 center.
z = coords[z * 3 + 2];
457 const Int64 current_uid = face_finder.find(center, tol);
458 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)){
460 error() <<
"face uid not found \n";
463 face_finder.insert(center,new_uid,tol) ;
464 updated_face_uids.insert(current_uid) ;
467 Integer data_index = fi_old.getDataIndex();
468 Integer nb_node = fi_old.nbNode() ;
469 FaceInfo fi(new_uid, cell_uid, nb_node, sid, data_index, &m_face_info_mng);
470 fi.setCenter(center);
475 for (
Integer z = 0; z < nb_node_unique_id; ++z){
478 node_coord.
x = nodes_coords[z * 3];
479 node_coord.
y = nodes_coords[z * 3 + 1];
480 node_coord.
z = nodes_coords[z * 3 + 2];
481 Int64 current_node_uid = node_finder.find(node_coord, tol);
482 if ((current_node_uid != NULL_ITEM_ID) && (nuid < current_node_uid)){
484 if(nuid<m_nodes_info[c_nuid].uniqueId()){
486 ni.setCoord(node_coord);
487 m_nodes_info[c_nuid] = ni;
490 updated_node_uids.insert(current_node_uid) ;
495 CHECKPERF( m_perf_counter.stop(PerfCounter::GATHERFACE) )
497 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATE) )
499 for(ItemUidSet::iterator iter = updated_node_uids.begin();iter!=updated_node_uids.end();++iter){
502 node_finder.insert(ni.getCoord(),ni.uniqueId(),tol) ;
506 _update(m_face_info_mng.m_nodes_unique_id,m_nodes_info) ;
508 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATE) )
516void ParallelAMRConsistency::
522 NodeInfoList::Data
const* data = nodes_info.lookup(uid);
524 nodes_unique_id[i] = data->value().uniqueId() ;
526 info()<<
"ERROR "<<i<<
" "<<uid<<
" not found";
533void ParallelAMRConsistency::
534_addNodeToList(Node node, NodeInfoList& node_map)
536 Real3 node_coord = m_nodes_coord[node];
537 ItemUniqueId uid = node.uniqueId();
538 NodeInfoList::Data* i = node_map.lookup(uid);
540 NodeInfo node_info(uid, node.owner());
541 node_info.setCoord(node_coord);
542 node_map.add(uid, node_info);
549void ParallelAMRConsistency::
550_addFaceToList2(Face face, FaceInfoMap2& face_map)
552 Integer nb_node = face.nbNode();
553 ItemUniqueId uid = face.uniqueId();
554 FaceInfoMap2::Data* i = face_map.lookup(uid);
556 Real3 center(0., 0., 0.);
557 for (Node node : face.nodes() ){
558 Real3 node_coord = m_nodes_coord[node];
559 center += node_coord;
562 FaceInfo2 fi(face.uniqueId(), face.owner());
563 fi.setCenter(center);
564 face_map.add(uid, fi);
580 Integer nb_active_face =
static_cast<Integer> (m_mesh->nbFace() * 0.2);
581 m_active_nodes.resize((nb_active_face * 2) + 5);
582 m_active_faces.resize((nb_active_face * 2) + 5);
585 if (!true_face_family)
588 Int32 sid = m_mesh->parallelMng()->commRank();
591 typedef std::set<Item> Set;
592 Set active_nodes_set, active_faces_set;
600 bool is_sub_domain_boundary_face =
false;
602 is_sub_domain_boundary_face =
true;
607 is_sub_domain_boundary_face =
true;
611 if (is_sub_domain_boundary_face){
613 true_face_family->allSubFaces(face, subfaces);
615 Face face2 = subfaces[s];
617 _addFaceToList2(face2, m_active_faces2);
618 active_faces_set.insert(face2);
621 active_nodes_set.insert(node);
622 _addNodeToList(node, m_active_nodes);
636 Set::const_iterator fit(active_faces_set.begin()), fend(active_faces_set.end());
638 for (; fit != fend; ++fit){
640 active_faces_to_send[i]=(face.
uniqueId());
641 active_faces[i]=face;
644 Set::const_iterator nit(active_nodes_set.begin()), nend(active_nodes_set.end());
646 for (; nit != nend; ++nit){
648 active_nodes_to_send[i]= (node.
uniqueId());
650 active_nodes[i]=node;
654 _gatherItems(active_nodes_to_send, active_faces_to_send, m_active_nodes, m_active_faces2, node_finder, face_finder);
656 for (
Integer index = 0; index < active_faces.
size(); index++){
657 Item face = active_faces[index];
660 if (current_uid != fi.uniqueId()){
666 for (
Integer index = 0; index < active_nodes.
size(); index++){
667 Item node = active_nodes[index];
670 if (current_uid != ni.uniqueId()){
681 mesh->nodesMap().notifyUniqueIdsChanged();
699 NodeInfoList& node_map,
700 FaceInfoMap2& face_map,
709 sbuf.
setMode(ISerializer::ModeReserve);
715 coords.
reserve(3 * nb_to_send);
717 nodes_coords.
reserve(3 * nb_node_to_send);
719 for (
Integer i = 0; i < nb_node_to_send; ++i){
720 const NodeInfo& ni = node_map[nodes_to_send[i]];
721 node_unique_ids[i] = ni.uniqueId().asInt64();
722 const Real3 c = ni.getCoord();
723 nodes_coords.
add(c.
x);
724 nodes_coords.
add(c.
y);
725 nodes_coords.
add(c.
z);
728 for (
Integer i = 0; i < nb_to_send; ++i){
729 const FaceInfo2& fi = face_map[faces_to_send[i]];
730 unique_ids[i] = fi.uniqueId().asInt64();
731 coords.
add(fi.center().
x);
732 coords.
add(fi.center().
y);
733 coords.
add(fi.center().
z);
736 sbuf.reserveInteger(1);
737 sbuf.reserveInteger(1);
738 sbuf.reserveInteger(1);
759 for (
Integer i = 0; i < nb_sub_domain; ++i){
772 const Real tol = 10e-6;
773 for (
Integer z = 0; z < nb_face; ++z){
777 center.
x = coords[z * 3];
778 center.
y = coords[z * 3 + 1];
779 center.
z = coords[z * 3 + 2];
781 const Int64 current_uid = face_finder.find(center, tol);
782 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)){
784 error() <<
"face uid not found \n";
787 fi.setCenter(center);
792 for (
Integer z = 0; z < nb_node_unique_id; ++z){
795 node_coord.
x = nodes_coords[z * 3];
796 node_coord.
y = nodes_coords[z * 3 + 1];
797 node_coord.
z = nodes_coords[z * 3 + 2];
798 Int64 current_node_uid = node_finder.find(node_coord, tol);
799 if ((current_node_uid != NULL_ITEM_ID) && (nuid < current_node_uid)){
801 ni.setCoord(node_coord);
803 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).
Implémentation d'un maillage.
Infos sur une Face active.
Infos sur une Face active.
Tableau associatif de ItemInternal.
void remove(Int64 key)
Supprime la valeur associée à la clé key.
impl::ItemBase findItem(Int64 uid) const
Retourne l'entité de numéro unique uid.
void notifyUniqueIdsChanged()
Notifie que les numéros uniques des entités ont changés.
void eachItem(const Lambda &lambda)
Fonction template pour itérer sur les entités de l'instance.
bool add(Int64 key, ItemInternal *v)
Ajoute la valeur v correspondant à la clé key.
structure de recherche d'un noeud à partir de ses coords La clef de hashage est la position geometriq...
void makeNewItemsConsistent2(MapCoordToUid &node_finder, MapCoordToUid &face_finder)
Détermine les faces à envoyer aux voisins.
void makeNewItemsConsistent(NodeMapCoordToUid &node_finder, FaceMapCoordToUid &face_finder)
Détermine les faces à envoyer aux voisins.
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