Arcane  4.1.11.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-2026 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/* Parallel consistency of node/face UIDs in the AMR case */
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 "INIT",
56 "COMPUTE",
57 "GATHERFACE",
58 "UPDATE",
59 "REHASH",
60 "ENDUPDATE"
61};
62#endif
63
64/*---------------------------------------------------------------------------*/
65/*---------------------------------------------------------------------------*/
66
70, m_mesh(mesh)
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)
76, m_is_updated(false)
77{
78 ;
79}
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84void ParallelAMRConsistency::
85init()
86{
87 CHECKPERF(m_perf_counter.start(PerfCounter::INIT))
88 // Marks nodes on the boundary
89 Integer nb_active_face = static_cast<Integer>(m_mesh->nbFace() * 0.2); // 20% of shared faces (estimated)
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();
94 Integer sid = m_mesh->parallelMng()->commRank();
95 ENUMERATE_FACE (iface, m_mesh->allFaces()) {
96 Face face = *iface;
97 ItemUniqueId face_uid = face.uniqueId();
98 int face_flags = face.itemBase().flags();
99 if (face.nbCell() == 2 && (face.cell(0).level() == 0 && face.cell(1).level() == 0)) {
100 if ((face.cell(0).owner() != sid || face.cell(1).owner() != sid) ||
101 (face_flags & ItemFlags::II_Shared) ||
102 (face_flags & ItemFlags::II_SubDomainBoundary)) {
103 m_shared_face_uids.add(face_uid);
104 }
105 else if (_hasSharedNodes(face)) {
106 m_connected_shared_face_uids.add(face_uid);
107 }
108 }
109 else if (face.nbCell() == 1 && face.cell(0).level() == 0) {
110 if (_hasSharedNodes(face)) {
111 m_connected_shared_face_uids.add(face_uid);
112 }
113 }
114 }
115 m_is_updated = true;
116
117 CHECKPERF(m_perf_counter.stop(PerfCounter::INIT))
118}
119/*---------------------------------------------------------------------------*/
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
124void ParallelAMRConsistency::
125_addFaceToList(Face face, FaceInfoMap& face_map)
126{
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;
135 }
136 center /= nb_node;
137 //info() << "ADD FACE uid=" << face.uniqueId() << " nb_node="
138 //<< nb_node << " center=" << center;
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);
142}
143
144/*---------------------------------------------------------------------------*/
145/*---------------------------------------------------------------------------*/
146
147bool ParallelAMRConsistency::
148_hasSharedNodes(Face face)
149{
150 //CHECK that one edge is connected to a ghost cell
151 for (Node node : face.nodes()) {
152 if (node.itemBase().flags() & ItemFlags::II_Shared)
153 return true;
154 }
155 return false;
156}
157
158/*---------------------------------------------------------------------------*/
159/*---------------------------------------------------------------------------*/
168{
169 CHECKPERF(m_perf_counter.start(PerfCounter::COMPUTE))
170 //UniqueArray<ItemInternal*> active_faces;
171 // Marks nodes on the boundary
172 Integer nb_active_face = static_cast<Integer>(m_mesh->nbFace() * 0.2); // 20% of shared faces (estimated)
173
174 m_nodes_info.resize((nb_active_face * 2) + 5);
175 m_nodes_info.clear();
176 ENUMERATE_NODE (i_item, m_mesh->allNodes()) {
177 Real3 node_coord = m_nodes_coord[i_item];
178 ItemUniqueId uid = i_item->uniqueId();
179 NodeInfo node_info(uid, i_item->owner());
180 node_info.setCoord(node_coord);
181 m_nodes_info.add(uid, node_info);
182 }
183
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);
189
190 FaceFamily* true_face_family = dynamic_cast<FaceFamily*>(m_mesh->faceFamily());
191 if (!true_face_family)
192 ARCANE_FATAL("can not obtain FaceFamily");
193
194 Int32 sid = m_mesh->parallelMng()->commRank();
195 //UniqueArray<ItemInternal*> active_faces;
196 ItemMap active_faces;
197 UniqueArray<ItemUniqueId> active_faces_to_send;
198 typedef std::set<ItemInternal*> Set;
199 Set active_nodes_set;
200 ItemMap active_nodes;
201 // Iterates over faces and marks active boundary nodes
202 DynamicMesh* mesh = dynamic_cast<DynamicMesh*>(m_mesh);
203 if (!mesh)
204 throw FatalErrorException(A_FUNCINFO, "can not obtain DynamicMesh");
205 ItemInternalMap& faces_map = mesh->facesMap();
206
207 for (Integer iface = 0; iface < m_shared_face_uids.size(); ++iface) {
208 Int64 face_uid = m_shared_face_uids[iface];
209 Face face = faces_map.findItem(face_uid);
210 {
212 true_face_family->allSubFaces(face, subfaces);
213 if (subfaces.size() != 1) {
214 for (Integer s = 0; s < subfaces.size(); s++) {
215 Face face2 = subfaces[s];
217 Int64 uid = face2.uniqueId();
218 bool face_to_send = face_finder.isNewUid(uid);
219 if (face_to_send) {
220 _addFaceToList(face2, m_active_faces);
221
222 //active_faces.add(face2);
223 active_faces.insert(ItemMapValue(uid, face2));
224 active_faces_to_send.add(ItemUniqueId(uid));
225 for (Node node : face2.nodes()) {
226 node.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
227 active_nodes.insert(ItemMapValue(node.uniqueId(), node));
228 }
229 for (Edge edge : face2.edges()) {
230 edge.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
231 }
232 }
233 }
234 }
235 }
236 }
237 for (Integer iface = 0; iface < m_connected_shared_face_uids.size(); ++iface) {
238 Int64 face_uid = m_connected_shared_face_uids[iface];
239 Face face(faces_map.findItem(face_uid));
240
241 {
242 Integer nb_node = face.nbNode();
243 typedef std::pair<Real3, Real3> Edge;
244 UniqueArray<Edge> edges;
245 edges.reserve(nb_node);
246 for (Integer i = 0; i < nb_node; ++i) {
247 Integer next = i == nb_node - 1 ? 0 : i + 1;
248 Node node1 = face.node(i);
249 Node node2 = face.node(next);
252 edges.add(Edge(m_nodes_coord[node1], m_nodes_coord[node2] - m_nodes_coord[node1]));
253 }
254 }
256 true_face_family->allSubFaces(face, subfaces);
257 for (Integer s = 0; s < subfaces.size(); s++) {
258 Face face2(subfaces[s]);
259 Int64 uid = face2.uniqueId();
260 bool face_to_send = face_finder.isNewUid(uid);
261 if (face_to_send) {
262 Integer nb_node2 = face2.nbNode();
263 for (Integer i = 0; i < nb_node2; ++i) {
264 Node node_i = face2.node(i);
265 Real3 Xi = m_nodes_coord[node_i];
266 for (Integer j = 0; j < edges.size(); ++j) {
267 Real3 n = Xi - edges[j].first;
268 Real sinteta = math::cross(edges[j].second, n).squareNormL2();
269 if (math::isZero(sinteta)) {
271 //active_nodes_set.insert(node_i);
272 active_nodes.insert(ItemMapValue(node_i.uniqueId(), node_i));
273 _addNodeToList(node_i, m_active_nodes);
274 }
275 }
276 }
277 }
278 }
279 }
280 }
281
282 UniqueArray<ItemUniqueId> active_nodes_to_send(arcaneCheckArraySize(active_nodes.size()));
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();
287 //active_nodes.insert(ItemMapValue(uid,node)) ;
288 }
289 CHECKPERF(m_perf_counter.stop(PerfCounter::COMPUTE))
290
291 //CHECKPERF( m_perf_counter.start(PerfCounter::GATHERFACE) )
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);
295 //CHECKPERF( m_perf_counter.stop(PerfCounter::GATHERFACE) )
296
297 CHECKPERF(m_perf_counter.start(PerfCounter::UPDATE))
298 //UPDATE FACES
299 //for (Integer index = 0; index < active_faces.size(); index++)
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];
303 //const Int64 current_uid = face->uniqueId();
304 FaceInfo& fi = m_active_faces[face.uniqueId()];
305 Int64 new_uid = fi.uniqueId();
306 faces_map.remove(face_uid);
307 //if (current_uid != fi.uniqueId())
308 ARCANE_ASSERT((face_uid != new_uid), ("AMR CONSISTENCY UPDATE FACE ERROR"));
309 face.mutableItemBase().setUniqueId(fi.uniqueId());
310 face.mutableItemBase().setOwner(fi.owner(), sid);
311 //debug() << "[\t ParallelAMRConsistency] NEW FACE BEFORE " << face->uniqueId()<<" new uid "<<fi.uniqueId() << " " << fi.owner();
312 faces_map.add(new_uid, ItemCompatibility::_itemInternal(face));
313 }
314
315 //UPDATE NODES
316 //ENUMERATE_NODE(i_item,m_mesh->allNodes())
317 ItemInternalMap& nodes_map = mesh->nodesMap();
318 for (ItemUidSet::iterator iter = update_node_uids.begin(); iter != update_node_uids.end(); ++iter) {
319 //ItemInternal* node = i_item->internal() ;
320 Int64 node_uid = *iter;
321 Item node = active_nodes[node_uid];
322 if (node.null())
323 ARCANE_FATAL("AMR CONSISTENCY NULL NODE ERROR");
324 //const Int64 node_uid = node->uniqueId();
325 NodeInfo ni = m_nodes_info[node.uniqueId()];
326 Int64 new_uid = ni.uniqueId();
327 //if (node_uid != ni.uniqueId())
328 ARCANE_ASSERT((node_uid != new_uid), ("AMR CONSISTENCY UPDATE NODE ERROR"));
329 //debug() << "[\t ParallelAMRConsistency] OLD NEW NODE " << node_uid << " " << ni.uniqueId()<<" owner "<<ni.owner();
330 nodes_map.remove(node_uid);
331 node.mutableItemBase().setUniqueId(ni.uniqueId());
332 node.mutableItemBase().setOwner(ni.owner(), sid);
334 nodes_map.add(new_uid, ItemCompatibility::_itemInternal(node));
335 }
336 CHECKPERF(m_perf_counter.stop(PerfCounter::UPDATE))
337
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))
342}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
347/*---------------------------------------------------------------------------*/
348/*---------------------------------------------------------------------------*/
358 ConstArrayView<ItemUniqueId> nodes_to_send,
359 FaceInfoMap& face_map,
360 MapCoordToUid& node_finder,
361 MapCoordToUid& face_finder,
362 ItemUidSet& updated_face_uids,
363 ItemUidSet& updated_node_uids)
364{
365 CHECKPERF(m_perf_counter.start(PerfCounter::GATHERFACE))
366
367 IParallelMng* pm = m_mesh->parallelMng();
368 Integer sub_domain_id = pm->commRank();
369 Integer nb_sub_domain = pm->commSize();
370
371 const Real tol = 10e-12;
372
373 SerializeBuffer sbuf;
374 sbuf.setMode(ISerializer::ModeReserve);
375 Integer nb_to_send = faces_to_send.size();
376 Integer nb_node_to_send = nodes_to_send.size();
377
378 Int64UniqueArray unique_ids(nb_to_send);
379 Int64UniqueArray cells_unique_ids(nb_to_send);
380 Int64UniqueArray nodes_unique_id;
381 nodes_unique_id.reserve(nb_node_to_send);
382 RealUniqueArray coords;
383 coords.reserve(3 * nb_to_send);
384 RealUniqueArray nodes_coords;
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);
393 }
394 debug() << "SEND NODE : " << nb_node_to_send;
395 for (Integer i = 0; i < nb_node_to_send; ++i) {
396 //debug()<<"SEND NODE : "<<nodes_to_send[i];
397 ItemUniqueId nuid(nodes_to_send[i]);
398 nodes_unique_id.add(nuid.asInt64());
399 NodeInfo ni = m_nodes_info[nuid];
400 Real3 c = ni.getCoord();
401 nodes_coords.add(c.x);
402 nodes_coords.add(c.y);
403 nodes_coords.add(c.z);
404 }
405 sbuf.reserveInteger(1); // for the number of faces
406 sbuf.reserveInteger(1); // for the sub-domain number
407 sbuf.reserveInteger(1); // for the number of nodes in the list
408 sbuf.reserveArray(unique_ids); // for the unique id of the faces
409 sbuf.reserveArray(cells_unique_ids); // for the unique id of the face meshes
410 sbuf.reserveArray(nodes_unique_id); // for the list of nodes
411 sbuf.reserveArray(coords); // for the center coordinates
412 sbuf.reserveArray(nodes_coords); // for the node coordinates
413
414 sbuf.allocateBuffer();
416
417 sbuf.putInteger(nb_to_send);
418 sbuf.putInteger(sub_domain_id);
419 sbuf.putInteger(nodes_unique_id.size());
420 sbuf.putArray(unique_ids);
421 sbuf.putArray(cells_unique_ids);
422 sbuf.putArray(nodes_unique_id);
423 sbuf.putArray(coords);
424 sbuf.putArray(nodes_coords);
425
426 SerializeBuffer recv_buf;
427 pm->allGather(&sbuf, &recv_buf);
429
430 for (Integer i = 0; i < nb_sub_domain; ++i) {
431 Integer nb_face = recv_buf.getInteger();
432 Integer sid = recv_buf.getInteger();
433 Integer nb_node_unique_id = recv_buf.getInteger();
434 info() << " [\t ParallelAMRConsistency::_gatherFaces] READ nface=" << nb_face << " FROM sid=" << sid << " " << m_face_info_mng.size();
435 recv_buf.getArray(unique_ids);
436 recv_buf.getArray(cells_unique_ids);
437 recv_buf.getArray(nodes_unique_id);
438 recv_buf.getArray(coords);
439 recv_buf.getArray(nodes_coords);
440
441 // Iterate through all received faces; if some are missing,
442 // they are ignored.
443 for (Integer z = 0; z < nb_face; ++z) {
444 ItemUniqueId new_uid(unique_ids[z]);
445 ItemUniqueId cell_uid(cells_unique_ids[z]);
446
447 Real3 center;
448 center.x = coords[z * 3];
449 center.y = coords[z * 3 + 1];
450 center.z = coords[z * 3 + 2];
451
452 const Int64 current_uid = face_finder.find(center, tol);
453 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)) {
454 if (!face_map.hasKey(ItemUniqueId(current_uid))) {
455 error() << "face uid not found \n";
456 }
457 //UPDATE FACE_FINDER
458 face_finder.insert(center, new_uid, tol);
459 updated_face_uids.insert(current_uid);
460
461 FaceInfo& fi_old = face_map[ItemUniqueId(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);
466 face_map[ItemUniqueId(current_uid)] = fi;
467 }
468 }
469
470 for (Integer z = 0; z < nb_node_unique_id; ++z) {
471 ItemUniqueId nuid(nodes_unique_id[z]);
472 Real3 node_coord;
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)) {
478 ItemUniqueId c_nuid(current_node_uid);
479 if (nuid < m_nodes_info[c_nuid].uniqueId()) {
480 NodeInfo ni(nuid, sid);
481 ni.setCoord(node_coord);
482 m_nodes_info[c_nuid] = ni;
483
484 // UPDATE NODE FINDER
485 updated_node_uids.insert(current_node_uid);
486 }
487 }
488 }
489 }
490 CHECKPERF(m_perf_counter.stop(PerfCounter::GATHERFACE))
491
492 CHECKPERF(m_perf_counter.start(PerfCounter::UPDATE))
493 //update node_finder
494 for (ItemUidSet::iterator iter = updated_node_uids.begin(); iter != updated_node_uids.end(); ++iter) {
495 ItemUniqueId uid(*iter);
496 NodeInfo& ni = m_nodes_info[uid];
497 node_finder.insert(ni.getCoord(), ni.uniqueId(), tol);
498 }
499
500 //update m_face_info_mng
501 _update(m_face_info_mng.m_nodes_unique_id, m_nodes_info);
502
503 CHECKPERF(m_perf_counter.stop(PerfCounter::UPDATE))
504
505 //pm->barrier();
506}
507
508/*---------------------------------------------------------------------------*/
509/*---------------------------------------------------------------------------*/
510
511void ParallelAMRConsistency::
512_update(Array<ItemUniqueId>& nodes_unique_id, NodeInfoList const& nodes_info)
513{
514 for (Integer i = 0, n = nodes_unique_id.size(); i < n; ++i) {
515 ItemUniqueId& uid = nodes_unique_id[i];
516 NodeInfoList::Data const* data = nodes_info.lookup(uid);
517 if (data)
518 nodes_unique_id[i] = data->value().uniqueId();
519 else
520 info() << "ERROR " << i << " " << uid << " not found";
521 }
522}
523
524/*---------------------------------------------------------------------------*/
525/*---------------------------------------------------------------------------*/
526
527void ParallelAMRConsistency::
528_addNodeToList(Node node, NodeInfoList& node_map)
529{
530 Real3 node_coord = m_nodes_coord[node];
531 ItemUniqueId uid = node.uniqueId();
532 NodeInfoList::Data* i = node_map.lookup(uid);
533 if (!i) {
534 NodeInfo node_info(uid, node.owner());
535 node_info.setCoord(node_coord);
536 node_map.add(uid, node_info);
537 }
538}
539
540/*---------------------------------------------------------------------------*/
541/*---------------------------------------------------------------------------*/
542
543void ParallelAMRConsistency::
544_addFaceToList2(Face face, FaceInfoMap2& face_map)
545{
546 Integer nb_node = face.nbNode();
547 ItemUniqueId uid = face.uniqueId();
548 FaceInfoMap2::Data* i = face_map.lookup(uid);
549 if (!i) {
550 Real3 center(0., 0., 0.);
551 for (Node node : face.nodes()) {
552 Real3 node_coord = m_nodes_coord[node];
553 center += node_coord;
554 }
555 center /= nb_node;
556 FaceInfo2 fi(face.uniqueId(), face.owner());
557 fi.setCenter(center);
558 face_map.add(uid, fi);
559 }
560}
561
562/*---------------------------------------------------------------------------*/
563/*---------------------------------------------------------------------------*/
571makeNewItemsConsistent2(MapCoordToUid& node_finder, MapCoordToUid& face_finder)
572{
573 // Marks nodes on the boundary
574 Integer nb_active_face = static_cast<Integer>(m_mesh->nbFace() * 0.2); // 20% of shared faces (estimated)
575 m_active_nodes.resize((nb_active_face * 2) + 5);
576 m_active_faces.resize((nb_active_face * 2) + 5);
577
578 FaceFamily* true_face_family = dynamic_cast<FaceFamily*>(m_mesh->itemFamily(IK_Face));
579 if (!true_face_family)
580 throw FatalErrorException(A_FUNCINFO, "can not obtain FaceFamily");
581
582 Int32 sid = m_mesh->parallelMng()->commRank();
583
584 typedef std::set<Item> Set;
585 Set active_nodes_set, active_faces_set;
586 // Iterate through faces and mark active boundary nodes
587 DynamicMesh* mesh = dynamic_cast<DynamicMesh*>(m_mesh);
588 if (!mesh)
589 throw FatalErrorException(A_FUNCINFO, "can not obtain DynamicMesh");
590 ItemInternalMap& faces_map = mesh->facesMap();
591
592 faces_map.eachItem([&](Face face) {
593 bool is_sub_domain_boundary_face = false;
595 is_sub_domain_boundary_face = true; // true is not needed
596 }
597 else {
598 if (face.cell(0).level() == 0 && face.cell(1).level() == 0) {
599 if ((face.cell(0).owner() != sid || face.cell(1).owner() != sid))
600 is_sub_domain_boundary_face = true;
601 }
602 }
603
604 if (is_sub_domain_boundary_face) {
606 true_face_family->allSubFaces(face, subfaces);
607 for (Integer s = 0; s < subfaces.size(); s++) {
608 Face face2 = subfaces[s];
610 _addFaceToList2(face2, m_active_faces2);
611 active_faces_set.insert(face2);
612 for (Node node : face2.nodes()) {
613 node.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
614 active_nodes_set.insert(node);
615 _addNodeToList(node, m_active_nodes);
616 }
617 for (Edge edge : face2.edges())
618 edge.mutableItemBase().addFlags(ItemFlags::II_Shared | ItemFlags::II_SubDomainBoundary);
619 }
620 }
621 });
622
623 UniqueArray<ItemUniqueId> active_faces_to_send(arcaneCheckArraySize(active_faces_set.size()));
624 UniqueArray<ItemUniqueId> active_nodes_to_send(arcaneCheckArraySize(active_nodes_set.size()));
625
626 UniqueArray<Item> active_faces(arcaneCheckArraySize(active_faces_set.size()));
627 UniqueArray<Item> active_nodes(arcaneCheckArraySize(active_nodes_set.size()));
628
629 Set::const_iterator fit(active_faces_set.begin()), fend(active_faces_set.end());
630 Integer i = 0;
631 for (; fit != fend; ++fit) {
632 Item face = *fit;
633 active_faces_to_send[i] = (face.uniqueId());
634 active_faces[i] = face;
635 i++;
636 }
637 Set::const_iterator nit(active_nodes_set.begin()), nend(active_nodes_set.end());
638 i = 0;
639 for (; nit != nend; ++nit) {
640 Item node = *nit;
641 active_nodes_to_send[i] = (node.uniqueId());
642 //debug() << "ACTIVE NODE TO SEND " << node->uniqueId() << " " << active_nodes_to_send[i];
643 active_nodes[i] = node;
644 i++;
645 }
646
647 _gatherItems(active_nodes_to_send, active_faces_to_send, m_active_nodes, m_active_faces2, node_finder, face_finder);
648
649 for (Integer index = 0; index < active_faces.size(); index++) {
650 Item face = active_faces[index];
651 const Int64 current_uid = face.uniqueId();
652 FaceInfo2& fi = m_active_faces2[face.uniqueId()];
653 if (current_uid != fi.uniqueId()) {
654 face.mutableItemBase().setUniqueId(fi.uniqueId());
655 face.mutableItemBase().setOwner(fi.owner(), sid);
656 //debug() << "[\t ParallelAMRConsistency] NEW FACE BEFORE " << fi.uniqueId() << " " << fi.owner();
657 }
658 }
659 for (Integer index = 0; index < active_nodes.size(); index++) {
660 Item node = active_nodes[index];
661 const Int64 current_uid = node.uniqueId();
662 NodeInfo& ni = m_active_nodes[node.uniqueId()];
663 if (current_uid != ni.uniqueId()) {
664 node.mutableItemBase().setUniqueId(ni.uniqueId());
665 node.mutableItemBase().setOwner(ni.owner(), sid);
666 //debug() << "[\t ParallelAMRConsistency] NEW FACE BEFORE " << fi.uniqueId() << " " << fi.owner();
667 }
668 }
669
670 // It is necessary to re-sort #m_faces_map because the uniqueId() of
671 // faces have been modified
672 faces_map.notifyUniqueIdsChanged();
673 // same for nodes
674 mesh->nodesMap().notifyUniqueIdsChanged();
675}
676
677/*---------------------------------------------------------------------------*/
678/*---------------------------------------------------------------------------*/
679
680/*---------------------------------------------------------------------------*/
681/*---------------------------------------------------------------------------*/
691 ConstArrayView<ItemUniqueId> faces_to_send,
692 NodeInfoList& node_map,
693 FaceInfoMap2& face_map,
694 MapCoordToUid& node_finder,
695 MapCoordToUid& face_finder)
696{
697 IParallelMng* pm = m_mesh->parallelMng();
698 Integer sub_domain_id = pm->commRank();
699 Integer nb_sub_domain = pm->commSize();
700
701 SerializeBuffer sbuf;
702 sbuf.setMode(ISerializer::ModeReserve);
703 Integer nb_to_send = faces_to_send.size();
704 Integer nb_node_to_send = nodes_to_send.size();
705 Int64UniqueArray unique_ids(nb_to_send);
706 Int64UniqueArray node_unique_ids(nb_node_to_send);
707 RealUniqueArray coords;
708 coords.reserve(3 * nb_to_send);
709 RealUniqueArray nodes_coords;
710 nodes_coords.reserve(3 * nb_node_to_send);
711
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);
719 }
720
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);
727 }
728
729 sbuf.reserveInteger(1); // for the number of faces
730 sbuf.reserveInteger(1); // for the sub-domain number
731 sbuf.reserveInteger(1); // for the number of nodes in the list
732 sbuf.reserveArray(unique_ids); // for the unique id of the faces
733 sbuf.reserveArray(node_unique_ids); // for the list of nodes
734 sbuf.reserveArray(coords); // for the center coordinates
735 sbuf.reserveArray(nodes_coords); // for the node coordinates
736
737 sbuf.allocateBuffer();
739
740 sbuf.putInteger(nb_to_send);
741 sbuf.putInteger(sub_domain_id);
742 sbuf.putInteger(node_unique_ids.size());
743 sbuf.putArray(unique_ids);
744 sbuf.putArray(node_unique_ids);
745 sbuf.putArray(coords);
746 sbuf.putArray(nodes_coords);
747
748 SerializeBuffer recv_buf;
749 pm->allGather(&sbuf, &recv_buf);
751
752 for (Integer i = 0; i < nb_sub_domain; ++i) {
753 Integer nb_face = recv_buf.getInteger();
754 Integer sid = recv_buf.getInteger();
755 Integer nb_node_unique_id = recv_buf.getInteger();
756 //info() << " [\t ParallelAMRConsistency::_gatherFaces] READ nface=" << nb_face << " FROM sid=" << sid;
757
758 recv_buf.getArray(unique_ids);
759 recv_buf.getArray(node_unique_ids);
760 recv_buf.getArray(coords);
761 recv_buf.getArray(nodes_coords);
762
763 // Iterate through all received faces; if some are missing,
764 // they are ignored.
765 const Real tol = 10e-6;
766 for (Integer z = 0; z < nb_face; ++z) {
767 ItemUniqueId new_uid(unique_ids[z]);
768
769 Real3 center;
770 center.x = coords[z * 3];
771 center.y = coords[z * 3 + 1];
772 center.z = coords[z * 3 + 2];
773
774 const Int64 current_uid = face_finder.find(center, tol);
775 if ((current_uid != NULL_ITEM_ID) && (new_uid < current_uid)) {
776 if (!face_map.hasKey(ItemUniqueId(current_uid))) {
777 error() << "face uid not found \n";
778 }
779 FaceInfo2 fi(new_uid, sid);
780 fi.setCenter(center);
781 face_map[ItemUniqueId(current_uid)] = fi;
782 }
783 }
784
785 for (Integer z = 0; z < nb_node_unique_id; ++z) {
786 ItemUniqueId nuid(node_unique_ids[z]);
787 Real3 node_coord;
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)) {
793 NodeInfo ni(nuid, sid);
794 ni.setCoord(node_coord);
795 ItemUniqueId c_nuid(current_node_uid);
796 node_map[c_nuid] = ni;
797 }
798 }
799 }
800 pm->barrier();
801}
802
803/*---------------------------------------------------------------------------*/
804/*---------------------------------------------------------------------------*/
805
806} // End namespace Arcane::mesh
807
808/*---------------------------------------------------------------------------*/
809/*---------------------------------------------------------------------------*/
#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.
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.
Int32 level() const
Definition Item.h:1368
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Arête d'une maille.
Definition Item.h:826
Face d'une maille.
Definition Item.h:964
Cell cell(Int32 i) const
i-ème maille de la face
Definition Item.h:1665
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2).
Definition Item.h:1042
EdgeConnectedListViewType edges() const
Liste des arêtes de la face.
Definition Item.h:1159
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().
Int32 flags() const
Flags de l'entité
@ II_Shared
L'entité est partagée par un autre sous-domaine.
Definition ItemFlags.h:58
@ II_SubDomainBoundary
L'entité est à la frontière de deux sous-domaines.
Definition ItemFlags.h:59
Identifiant unique d'une entité.
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:791
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Definition Item.h:794
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:788
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:380
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:238
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:369
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 Item.h:582
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
constexpr __host__ __device__ Real squareNormL2() const
Retourne la norme L2 au carré du triplet .
Definition Real3.h:429
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.
Definition DynamicMesh.h:98
Info on an active Face.
Info on an active Face.
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)
__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....
UniqueArray< Int64 > Int64UniqueArray
Tableau dynamique à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:339
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.
Definition UtilsTypes.h:349
@ 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
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