Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
ParallelAMRConsistency.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ParallelAMRConsistency.cc (C) 2000-2024 */
9/* */
10/* Consistence parallèle des uid des noeuds/faces dans le cas AMR */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
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"
20
21#include "arcane/mesh/DynamicMesh.h"
22#include "arcane/mesh/FaceFamily.h"
23#include "arcane/mesh/MapCoordToUid.h"
24#include "arcane/mesh/ParallelAMRConsistency.h"
25
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"
40
41#include <set>
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46namespace Arcane::mesh
47{
48
49/*---------------------------------------------------------------------------*/
50/*---------------------------------------------------------------------------*/
52
53#ifdef ACTIVATE_PERF_COUNTER
54const std::string ParallelAMRConsistency::PerfCounter::m_names[ParallelAMRConsistency::PerfCounter::NbCounters] =
55 {
56 "INIT",
57 "COMPUTE",
58 "GATHERFACE",
59 "UPDATE",
60 "REHASH",
61 "ENDUPDATE"
62 };
63#endif
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
70: TraceAccessor(mesh->traceMng())
71, m_mesh(mesh)
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)
77, m_is_updated(false)
78{
79 ;
80}
81
82/*---------------------------------------------------------------------------*/
83/*---------------------------------------------------------------------------*/
84
85void ParallelAMRConsistency::
86init()
87{
88 CHECKPERF( m_perf_counter.start(PerfCounter::INIT) )
89 // Marque les noeuds sur la frontière
90 Integer nb_active_face = static_cast<Integer> (m_mesh->nbFace() * 0.2); // 20% de faces shared (sur estimé)
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() ;
95 Integer sid = m_mesh->parallelMng()->commRank();
96 ENUMERATE_FACE(iface,m_mesh->allFaces()){
97 Face face = *iface;
99 int face_flags = face.itemBase().flags();
100 if (face.nbCell()==2 && (face.cell(0).level()==0 && face.cell(1).level()==0)){
101 if ( (face.cell(0).owner()!=sid || face.cell(1).owner()!= sid) ||
104 m_shared_face_uids.add(face_uid);
105 }
106 else if (_hasSharedNodes(face)){
107 m_connected_shared_face_uids.add(face_uid);
108 }
109 }
110 else if (face.nbCell()==1 && face.cell(0).level() == 0){
111 if (_hasSharedNodes(face)){
112 m_connected_shared_face_uids.add(face_uid);
113 }
114 }
115 }
116 m_is_updated = true ;
117
118 CHECKPERF( m_perf_counter.stop(PerfCounter::INIT) )
119}
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123/*---------------------------------------------------------------------------*/
124
125void ParallelAMRConsistency::
126_addFaceToList(Face face, FaceInfoMap& face_map)
127{
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;
136 }
137 center /= nb_node;
138 //info() << "ADD FACE uid=" << face.uniqueId() << " nb_node="
139 //<< nb_node << " center=" << center;
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);
143}
144
145/*---------------------------------------------------------------------------*/
146/*---------------------------------------------------------------------------*/
147
148bool ParallelAMRConsistency::
149_hasSharedNodes(Face face)
150{
151 //CHECK that one edge is connected to a ghost cell
152 for ( Node node : face.nodes() ){
153 if (node.itemBase().flags() & ItemFlags::II_Shared)
154 return true;
155 }
156 return false;
157}
158
159/*---------------------------------------------------------------------------*/
160/*---------------------------------------------------------------------------*/
169{
170 CHECKPERF( m_perf_counter.start(PerfCounter::COMPUTE) )
171 //Integer nb_sub_domain_boundary_face = 0;
172 // Marque les noeuds sur la frontière
173 Integer nb_active_face = static_cast<Integer> (m_mesh->nbFace() * 0.2); // 20% de faces shared (sur estimé)
174
175 m_nodes_info.resize((nb_active_face * 2) + 5);
176 m_nodes_info.clear() ;
177 ENUMERATE_NODE(i_item,m_mesh->allNodes()){
178 Real3 node_coord = m_nodes_coord[i_item];
179 ItemUniqueId uid = i_item->uniqueId();
180 NodeInfo node_info(uid, i_item->owner());
181 node_info.setCoord(node_coord);
182 m_nodes_info.add(uid, node_info);
183 }
184
185
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) ;
191
192
193 FaceFamily* true_face_family = dynamic_cast<FaceFamily*> (m_mesh->faceFamily());
194 if (!true_face_family)
195 ARCANE_FATAL("can not obtain FaceFamily");
196
197 Int32 sid = m_mesh->parallelMng()->commRank();
198 //UniqueArray<ItemInternal*> active_faces;
199 ItemMap active_faces ;
201 typedef std::set<ItemInternal*> Set;
203 ItemMap active_nodes ;
204 // Parcours les faces et marque les noeuds frontieres actives
205 DynamicMesh* mesh = dynamic_cast<DynamicMesh*> (m_mesh);
206 if (!mesh)
207 throw FatalErrorException(A_FUNCINFO, "can not obtain DynamicMesh");
208 ItemInternalMap& faces_map = mesh->facesMap();
209
210 for(Integer iface=0;iface<m_shared_face_uids.size();++iface){
211 Int64 face_uid = m_shared_face_uids[iface];
212 Face face = faces_map.findItem(face_uid);
213 {
215 true_face_family->allSubFaces(face, subfaces);
216 if (subfaces.size() != 1){
217 for (Integer s = 0; s < subfaces.size(); s++){
218 Face face2 = subfaces[s];
219 face2.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
220 Int64 uid = face2.uniqueId() ;
221 bool face_to_send = face_finder.isNewUid(uid);
222 if(face_to_send){
223 _addFaceToList(face2, m_active_faces);
224
225 //active_faces.add(face2);
226 active_faces.insert(ItemMapValue(uid,face2));
228 for ( Node node : face2.nodes() ){
229 node.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
230 active_nodes.insert(ItemMapValue(node.uniqueId(),node));
231 }
232 for ( Edge edge : face2.edges() ){
233 edge.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
234 }
235 }
236 }
237 }
238 }
239 }
240 for(Integer iface=0;iface<m_connected_shared_face_uids.size();++iface){
241 Int64 face_uid = m_connected_shared_face_uids[iface];
242 Face face(faces_map.findItem(face_uid));
243
244 {
245 Integer nb_node = face.nbNode() ;
246 typedef std::pair<Real3,Real3> Edge ;
247 UniqueArray<Edge> edges ;
248 edges.reserve(nb_node) ;
249 for(Integer i=0;i<nb_node;++i){
250 Integer next = i==nb_node-1?0:i+1;
251 Node node1 = face.node(i) ;
252 Node node2 = face.node(next) ;
253 if( (node1.itemBase().flags() & (ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary)) &&
254 (node2.itemBase().flags() & (ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary) ) ){
255 edges.add(Edge(m_nodes_coord[node1],m_nodes_coord[node2]-m_nodes_coord[node1])) ;
256 }
257 }
259 true_face_family->allSubFaces(face, subfaces);
260 for (Integer s = 0; s < subfaces.size(); s++){
261 Face face2(subfaces[s]);
262 Int64 uid = face2.uniqueId() ;
263 bool face_to_send = face_finder.isNewUid(uid) ;
264 if (face_to_send){
265 Integer nb_node2 = face2.nbNode() ;
266 for(Integer i=0;i<nb_node2;++i){
267 Node node_i = face2.node(i) ;
268 Real3 Xi = m_nodes_coord[node_i] ;
269 for(Integer j=0;j<edges.size();++j){
270 Real3 n = Xi-edges[j].first ;
271 Real sinteta = math::cross(edges[j].second,n).squareNormL2() ;
272 if (math::isZero(sinteta)){
273 node_i.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
274 //active_nodes_set.insert(node_i);
275 active_nodes.insert(ItemMapValue(node_i.uniqueId(),node_i));
276 _addNodeToList(node_i, m_active_nodes);
277 }
278 }
279 }
280 }
281 }
282 }
283 }
284
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;
290 //active_nodes.insert(ItemMapValue(uid,node)) ;
291 }
292 CHECKPERF( m_perf_counter.stop(PerfCounter::COMPUTE) )
293
294 //CHECKPERF( m_perf_counter.start(PerfCounter::GATHERFACE) )
295 ItemUidSet update_face_uids ;
296 ItemUidSet update_node_uids ;
298 //CHECKPERF( m_perf_counter.stop(PerfCounter::GATHERFACE) )
299
300
301
302 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATE) )
303 //UPDATE FACES
304 //for (Integer index = 0; index < active_faces.size(); index++)
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];
308 //const Int64 current_uid = face->uniqueId();
309 FaceInfo& fi = m_active_faces[face.uniqueId()];
310 Int64 new_uid = fi.uniqueId() ;
311 faces_map.remove(face_uid) ;
312 //if (current_uid != fi.uniqueId())
313 ARCANE_ASSERT((face_uid != new_uid),("AMR CONSISTENCY UPDATE FACE ERROR")) ;
314 face.mutableItemBase().setUniqueId(fi.uniqueId());
315 face.mutableItemBase().setOwner(fi.owner(), sid);
316 //debug() << "[\t ParallelAMRConsistency] NEW FACE BEFORE " << face->uniqueId()<<" new uid "<<fi.uniqueId() << " " << fi.owner();
317 faces_map.add(new_uid,ItemCompatibility::_itemInternal(face));
318 }
319
320 //UPDATE NODES
321 //ENUMERATE_NODE(i_item,m_mesh->allNodes())
322 ItemInternalMap& nodes_map = mesh->nodesMap();
323 for(ItemUidSet::iterator iter = update_node_uids.begin();iter!=update_node_uids.end();++iter){
324 //ItemInternal* node = i_item->internal() ;
325 Int64 node_uid = *iter ;
326 Item node = active_nodes[node_uid];
327 if (node.null())
328 ARCANE_FATAL("AMR CONSISTENCY NULL NODE ERROR");
329 //const Int64 node_uid = node->uniqueId();
330 NodeInfo ni = m_nodes_info[node.uniqueId()];
331 Int64 new_uid = ni.uniqueId() ;
332 //if (node_uid != ni.uniqueId())
333 ARCANE_ASSERT((node_uid != new_uid),("AMR CONSISTENCY UPDATE NODE ERROR")) ;
334 //debug() << "[\t ParallelAMRConsistency] OLD NEW NODE " << node_uid << " " << ni.uniqueId()<<" owner "<<ni.owner();
335 nodes_map.remove(node_uid) ;
336 node.mutableItemBase().setUniqueId(ni.uniqueId());
337 node.mutableItemBase().setOwner(ni.owner(), sid);
339 nodes_map.add(new_uid,ItemCompatibility::_itemInternal(node));
340 }
341 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATE) )
342
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) )
347}
348
349/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
367 ItemUidSet& updated_face_uids,
368 ItemUidSet& updated_node_uids)
369{
370 CHECKPERF( m_perf_counter.start(PerfCounter::GATHERFACE) )
371
372 IParallelMng* pm = m_mesh->parallelMng();
373 Integer sub_domain_id = pm->commRank();
374 Integer nb_sub_domain = pm->commSize();
375
376 const Real tol = 10e-12;
377
379 sbuf.setMode(ISerializer::ModeReserve);
380 Integer nb_to_send = faces_to_send.size();
381 Integer nb_node_to_send = nodes_to_send.size();
382
385 Int64UniqueArray nodes_unique_id;
386 nodes_unique_id.reserve(nb_node_to_send);
387 RealUniqueArray coords;
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);
398 }
399 debug()<<"SEND NODE : "<<nb_node_to_send;
400 for (Integer i = 0; i < nb_node_to_send; ++i){
401 //debug()<<"SEND NODE : "<<nodes_to_send[i];
403 nodes_unique_id.add(nuid.asInt64());
404 NodeInfo ni = m_nodes_info[nuid];
405 Real3 c = ni.getCoord();
406 nodes_coords.add(c.x);
407 nodes_coords.add(c.y);
408 nodes_coords.add(c.z);
409 }
410 sbuf.reserveInteger(1); // pour le nombre de faces
411 sbuf.reserveInteger(1); // pour le numéro du sous-domaine
412 sbuf.reserveInteger(1); // pour le nombre de noeuds dans la liste
413 sbuf.reserveArray(unique_ids); // pour le unique id des faces
414 sbuf.reserveArray(cells_unique_ids); // pour le unique id des mailles des faces
415 sbuf.reserveArray(nodes_unique_id); // pour la liste des noeuds
416 sbuf.reserveArray(coords); // pour les coordonnées du centre
417 sbuf.reserveArray(nodes_coords); // pour les coordonnées des noeuds
418
419 sbuf.allocateBuffer();
420 sbuf.setMode(ISerializer::ModePut);
421
422 sbuf.putInteger(nb_to_send);
423 sbuf.putInteger(sub_domain_id);
424 sbuf.putInteger(nodes_unique_id.size());
425 sbuf.putArray(unique_ids);
426 sbuf.putArray(cells_unique_ids);
427 sbuf.putArray(nodes_unique_id);
428 sbuf.putArray(coords);
429 sbuf.putArray(nodes_coords);
430
431 SerializeBuffer recv_buf;
432 pm->allGather(&sbuf, &recv_buf);
434
435 for (Integer i = 0; i < nb_sub_domain; ++i){
436 Integer nb_face = recv_buf.getInteger();
437 Integer sid = recv_buf.getInteger();
438 Integer nb_node_unique_id = recv_buf.getInteger();
439 info() << " [\t ParallelAMRConsistency::_gatherFaces] READ nface=" << nb_face << " FROM sid=" << sid<<" "<<m_face_info_mng.size();
440 recv_buf.getArray(unique_ids);
441 recv_buf.getArray(cells_unique_ids);
442 recv_buf.getArray(nodes_unique_id);
443 recv_buf.getArray(coords);
444 recv_buf.getArray(nodes_coords);
445
446 // Parcours toutes les faces reçues si certaines sont absentes,
447 // on les ignore.
448 for (Integer z = 0; z < nb_face; ++z){
450 ItemUniqueId cell_uid(cells_unique_ids[z]);
451
452 Real3 center;
453 center.x = coords[z * 3];
454 center.y = coords[z * 3 + 1];
455 center.z = coords[z * 3 + 2];
456
457 const Int64 current_uid = face_finder.find(center, tol);
458 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)){
459 if (!face_map.hasKey(ItemUniqueId(current_uid))){
460 error() << "face uid not found \n";
461 }
462 //UPDATE FACE_FINDER
463 face_finder.insert(center,new_uid,tol) ;
465
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);
472 }
473 }
474
475 for (Integer z = 0; z < nb_node_unique_id; ++z){
476 ItemUniqueId nuid(nodes_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];
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;
488
489 // UPDATE NODE FINDER
491 }
492 }
493 }
494 }
495 CHECKPERF( m_perf_counter.stop(PerfCounter::GATHERFACE) )
496
497 CHECKPERF( m_perf_counter.start(PerfCounter::UPDATE) )
498 //update node_finder
499 for(ItemUidSet::iterator iter = updated_node_uids.begin();iter!=updated_node_uids.end();++iter){
500 ItemUniqueId uid(*iter);
501 NodeInfo& ni = m_nodes_info[uid] ;
502 node_finder.insert(ni.getCoord(),ni.uniqueId(),tol) ;
503 }
504
505 //update m_face_info_mng
506 _update(m_face_info_mng.m_nodes_unique_id,m_nodes_info) ;
507
508 CHECKPERF( m_perf_counter.stop(PerfCounter::UPDATE) )
509
510 //pm->barrier();
511}
512
513/*---------------------------------------------------------------------------*/
514/*---------------------------------------------------------------------------*/
515
516void ParallelAMRConsistency::
517_update(Array<ItemUniqueId>& nodes_unique_id, NodeInfoList const& nodes_info)
518{
519 for(Integer i=0, n=nodes_unique_id.size();i<n;++i)
520 {
521 ItemUniqueId& uid = nodes_unique_id[i] ;
522 NodeInfoList::Data const* data = nodes_info.lookup(uid);
523 if (data)
524 nodes_unique_id[i] = data->value().uniqueId() ;
525 else
526 info()<<"ERROR "<<i<<" "<<uid<<" not found";
527 }
528}
529
530/*---------------------------------------------------------------------------*/
531/*---------------------------------------------------------------------------*/
532
533void ParallelAMRConsistency::
534_addNodeToList(Node node, NodeInfoList& node_map)
535{
536 Real3 node_coord = m_nodes_coord[node];
537 ItemUniqueId uid = node.uniqueId();
538 NodeInfoList::Data* i = node_map.lookup(uid);
539 if (!i){
540 NodeInfo node_info(uid, node.owner());
541 node_info.setCoord(node_coord);
542 node_map.add(uid, node_info);
543 }
544}
545
546/*---------------------------------------------------------------------------*/
547/*---------------------------------------------------------------------------*/
548
549void ParallelAMRConsistency::
550_addFaceToList2(Face face, FaceInfoMap2& face_map)
551{
552 Integer nb_node = face.nbNode();
553 ItemUniqueId uid = face.uniqueId();
554 FaceInfoMap2::Data* i = face_map.lookup(uid);
555 if (!i){
556 Real3 center(0., 0., 0.);
557 for (Node node : face.nodes() ){
558 Real3 node_coord = m_nodes_coord[node];
559 center += node_coord;
560 }
561 center /= nb_node;
562 FaceInfo2 fi(face.uniqueId(), face.owner());
563 fi.setCenter(center);
564 face_map.add(uid, fi);
565 }
566}
567
568/*---------------------------------------------------------------------------*/
569/*---------------------------------------------------------------------------*/
578{
579 // Marque les noeuds sur la frontière
580 Integer nb_active_face = static_cast<Integer> (m_mesh->nbFace() * 0.2); // 20% de faces shared (sur estimé)
581 m_active_nodes.resize((nb_active_face * 2) + 5);
582 m_active_faces.resize((nb_active_face * 2) + 5);
583
584 FaceFamily* true_face_family = dynamic_cast<FaceFamily*> (m_mesh->itemFamily(IK_Face));
585 if (!true_face_family)
586 throw FatalErrorException(A_FUNCINFO, "can not obtain FaceFamily");
587
588 Int32 sid = m_mesh->parallelMng()->commRank();
589
590
591 typedef std::set<Item> Set;
593 // Parcours les faces et marque les noeuds frontieres actives
594 DynamicMesh* mesh = dynamic_cast<DynamicMesh*> (m_mesh);
595 if (!mesh)
596 throw FatalErrorException(A_FUNCINFO, "can not obtain DynamicMesh");
597 ItemInternalMap& faces_map = mesh->facesMap();
598
599 faces_map.eachItem([&](Face face) {
600 bool is_sub_domain_boundary_face = false;
602 is_sub_domain_boundary_face = true; // true is not needed
603 }
604 else{
605 if (face.cell(0).level() == 0 && face.cell(1).level() == 0){
606 if ((face.cell(0).owner() != sid || face.cell(1).owner() != sid))
607 is_sub_domain_boundary_face = true;
608 }
609 }
610
613 true_face_family->allSubFaces(face, subfaces);
614 for (Integer s = 0; s < subfaces.size(); s++){
615 Face face2 = subfaces[s];
616 face2.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
617 _addFaceToList2(face2, m_active_faces2);
618 active_faces_set.insert(face2);
619 for ( Node node : face2.nodes() ){
620 node.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
621 active_nodes_set.insert(node);
622 _addNodeToList(node, m_active_nodes);
623 }
624 for ( Edge edge : face2.edges() )
625 edge.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
626 }
627 }
628 });
629
632
635
636 Set::const_iterator fit(active_faces_set.begin()), fend(active_faces_set.end());
637 Integer i=0;
638 for (; fit != fend; ++fit){
639 Item face = *fit;
640 active_faces_to_send[i]=(face.uniqueId());
641 active_faces[i]=face;
642 i++;
643 }
644 Set::const_iterator nit(active_nodes_set.begin()), nend(active_nodes_set.end());
645 i=0;
646 for (; nit != nend; ++nit){
647 Item node = *nit;
648 active_nodes_to_send[i]= (node.uniqueId());
649 //debug() << "ACTIVE NODE TO SEND " << node->uniqueId() << " " << active_nodes_to_send[i];
650 active_nodes[i]=node;
651 i++;
652 }
653
654 _gatherItems(active_nodes_to_send, active_faces_to_send, m_active_nodes, m_active_faces2, node_finder, face_finder);
655
656 for (Integer index = 0; index < active_faces.size(); index++){
657 Item face = active_faces[index];
658 const Int64 current_uid = face.uniqueId();
659 FaceInfo2& fi = m_active_faces2[face.uniqueId()];
660 if (current_uid != fi.uniqueId()){
661 face.mutableItemBase().setUniqueId(fi.uniqueId());
662 face.mutableItemBase().setOwner(fi.owner(), sid);
663 //debug() << "[\t ParallelAMRConsistency] NEW FACE BEFORE " << fi.uniqueId() << " " << fi.owner();
664 }
665 }
666 for (Integer index = 0; index < active_nodes.size(); index++){
667 Item node = active_nodes[index];
668 const Int64 current_uid = node.uniqueId();
669 NodeInfo& ni = m_active_nodes[node.uniqueId()];
670 if (current_uid != ni.uniqueId()){
671 node.mutableItemBase().setUniqueId(ni.uniqueId());
672 node.mutableItemBase().setOwner(ni.owner(), sid);
673 //debug() << "[\t ParallelAMRConsistency] NEW FACE BEFORE " << fi.uniqueId() << " " << fi.owner();
674 }
675 }
676
677 // Il faut ranger à nouveau #m_faces_map car les uniqueId() des
678 // faces ont été modifiés
679 faces_map.notifyUniqueIdsChanged();
680 // idem pour les noeuds
681 mesh->nodesMap().notifyUniqueIdsChanged();
682}
683
684/*---------------------------------------------------------------------------*/
685/*---------------------------------------------------------------------------*/
686
687/*---------------------------------------------------------------------------*/
688/*---------------------------------------------------------------------------*/
696void ParallelAMRConsistency::
703{
704 IParallelMng* pm = m_mesh->parallelMng();
705 Integer sub_domain_id = pm->commRank();
706 Integer nb_sub_domain = pm->commSize();
707
709 sbuf.setMode(ISerializer::ModeReserve);
710 Integer nb_to_send = faces_to_send.size();
711 Integer nb_node_to_send = nodes_to_send.size();
714 RealUniqueArray coords;
715 coords.reserve(3 * nb_to_send);
717 nodes_coords.reserve(3 * nb_node_to_send);
718
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);
726 }
727
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);
734 }
735
736 sbuf.reserveInteger(1); // pour le nombre de faces
737 sbuf.reserveInteger(1); // pour le numéro du sous-domaine
738 sbuf.reserveInteger(1); // pour le nombre de noeuds dans la liste
739 sbuf.reserveArray(unique_ids); // pour le unique id des faces
740 sbuf.reserveArray(node_unique_ids); // pour la liste des noeuds
741 sbuf.reserveArray(coords); // pour les coordonnées du centre
742 sbuf.reserveArray(nodes_coords); // pour les coordonnées des noeuds
743
744 sbuf.allocateBuffer();
745 sbuf.setMode(ISerializer::ModePut);
746
747 sbuf.putInteger(nb_to_send);
748 sbuf.putInteger(sub_domain_id);
749 sbuf.putInteger(node_unique_ids.size());
750 sbuf.putArray(unique_ids);
751 sbuf.putArray(node_unique_ids);
752 sbuf.putArray(coords);
753 sbuf.putArray(nodes_coords);
754
755 SerializeBuffer recv_buf;
756 pm->allGather(&sbuf, &recv_buf);
758
759 for (Integer i = 0; i < nb_sub_domain; ++i){
760 Integer nb_face = recv_buf.getInteger();
761 Integer sid = recv_buf.getInteger();
762 Integer nb_node_unique_id = recv_buf.getInteger();
763 //info() << " [\t ParallelAMRConsistency::_gatherFaces] READ nface=" << nb_face << " FROM sid=" << sid;
764
765 recv_buf.getArray(unique_ids);
766 recv_buf.getArray(node_unique_ids);
767 recv_buf.getArray(coords);
768 recv_buf.getArray(nodes_coords);
769
770 // Parcours toutes les faces reçues si certaines sont absentes,
771 // on les ignore.
772 const Real tol = 10e-6;
773 for (Integer z = 0; z < nb_face; ++z){
775
776 Real3 center;
777 center.x = coords[z * 3];
778 center.y = coords[z * 3 + 1];
779 center.z = coords[z * 3 + 2];
780
781 const Int64 current_uid = face_finder.find(center, tol);
782 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)){
783 if (!face_map.hasKey(ItemUniqueId(current_uid))){
784 error() << "face uid not found \n";
785 }
787 fi.setCenter(center);
789 }
790 }
791
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];
799 if ((current_node_uid != NULL_ITEM_ID) && (nuid < current_node_uid)){
801 ni.setCoord(node_coord);
803 node_map[c_nuid] = ni;
804 }
805 }
806 }
807 pm->barrier();
808}
809
810/*---------------------------------------------------------------------------*/
811/*---------------------------------------------------------------------------*/
812
813} // End namespace Arcane::mesh
814
815/*---------------------------------------------------------------------------*/
816/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour itérer sur les entités du maillage.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Int32 level() const
Definition Item.h:1328
Arête d'une maille.
Definition Item.h:798
Face d'une maille.
Definition Item.h:932
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1617
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1006
void resize(Integer new_size, bool use_prime=false)
Redimensionne la table de hachage.
bool add(KeyTypeConstRef id, const ValueType &value)
Ajoute la valeur value correspondant à la clé id.
void clear()
Supprime tous les éléments de la table.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual FaceGroup allFaces()=0
Groupe de toutes les faces.
virtual IItemFamily * itemFamily(eItemKind ik)=0
Retourne la famille d'entité de type ik.
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
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.
Int32 flags() const
Flags de l'entité
@ II_Shared
L'entité est partagée par un autre sous-domaine.
Definition ItemFlags.h:51
@ II_SubDomainBoundary
L'entité est à la frontière de deux sous-domaines.
Definition ItemFlags.h:52
Identifiant unique d'une entité.
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:768
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
Classe de base d'un élément de maillage.
Definition Item.h:83
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:365
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:229
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:207
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:354
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
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é
Noeud d'un maillage.
Definition Dom.h:204
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
constexpr ARCCORE_HOST_DEVICE Real squareNormL2() const
Retourne la norme L2 au carré du triplet .
Definition Real3.h:230
Implémentation d'un tampon pour la sérialisation.
Implémentation d'un maillage.
Definition DynamicMesh.h:97
Famille de faces.
Definition FaceFamily.h:53
Infos sur une Face active.
Infos sur une Face active.
Tableau associatif de ItemInternal.
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)
Integer size() const
Nombre d'éléments du vecteur.
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 clear()
Supprime les éléments du tableau.
void getArray(Array< Real > &values) override
Redimensionne et remplit values.
Integer getInteger() override
Récupère une taille.
void setMode(eMode new_mode) override
Positionne le fonctionnement actuel.
Exception lorsqu'une erreur fatale est survenue.
TraceMessage error() const
Flot pour un message d'erreur.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
ARCCORE_HOST_DEVICE Real3 cross(Real3 v1, Real3 v2)
Produit vectoriel de deux vecteurs à 3 composantes.
Definition MathUtils.h:723
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....
@ IK_Face
Entité de maillage de genre face.
Int32 Integer
Type représentant un entier.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35