Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
GraphDoFs.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/* GraphDoFs.cc (C) 2000-2025 */
9/* */
10/*---------------------------------------------------------------------------*/
11
12#include "arcane/mesh/DualUniqueIdMng.h"
13#include "arcane/mesh/GraphDoFs.h"
14
15#include "arcane/utils/ArgumentException.h"
16
17#include "arcane/core/IMesh.h"
18#include "arcane/core/IItemConnectivity.h"
19#include "arcane/core/IIncrementalItemConnectivity.h"
21
22#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane::mesh
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33GraphIncrementalConnectivity::
34GraphIncrementalConnectivity(GraphDoFs* graph)
35: m_dualnode_family(graph->dualNodeFamily())
36, m_link_family(graph->linkFamily())
37, m_dualnode_connectivity(graph->m_dualnodes_incremental_connectivity)
38, m_link_connectivity(graph->m_links_incremental_connectivity)
39, m_dualitem_connectivities(graph->m_incremental_connectivities)
40, m_dualnode_to_connectivity_index(graph->m_dual_node_to_connectivity_index)
41{
42}
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46
47GraphDoFs::
48GraphDoFs(IMesh* mesh, String particle_family_name)
49: TraceAccessor(mesh->traceMng())
50, m_mesh(mesh)
51, m_dof_mng(mesh)
52, m_connectivity_mng(m_dof_mng.connectivityMng())
53, m_dual_node_family(m_dof_mng.getFamily(GraphDoFs::dualNodeFamilyName(), true))
54, m_link_family(m_dof_mng.getFamily(GraphDoFs::linkFamilyName(), true))
55, m_update_sync_info(false)
56, m_particle_family_name(particle_family_name)
57{
58}
59
60void GraphDoFs::
61_allocateGraph()
62{
63 if (m_graph_allocated)
64 return;
65
66 auto connectivity_index = 0;
67 m_connectivity_indexes_per_type.resize(NB_BASIC_ITEM_TYPE, -1);
68 m_connectivity_indexes_per_type[IT_DualNode] = connectivity_index++;
69 m_connectivity_indexes_per_type[IT_DualEdge] = connectivity_index++;
70 m_connectivity_indexes_per_type[IT_DualFace] = connectivity_index++;
71 m_connectivity_indexes_per_type[IT_DualCell] = connectivity_index++;
72 m_connectivity_indexes_per_type[IT_DualParticle] = connectivity_index++;
73
74 m_item_family_network = m_mesh->itemFamilyNetwork();
75 if (m_item_family_network == nullptr)
76 ARCANE_FATAL("ARCANE_GRAPH_CONNECTIVITY_POLICY need to be activated");
77
78 m_graph_id = m_item_family_network->registerConnectedGraph(this);
79
80 m_dualnodes_incremental_connectivity =
81 new IncrementalItemConnectivity(dualNodeFamily(),
82 linkFamily(),
83 mesh::connectivityName(dualNodeFamily(), linkFamily()));
84
85 m_connectivity_mng->registerConnectivity(m_dualnodes_incremental_connectivity);
86
87 if (m_item_family_network)
88 m_item_family_network->addRelation(dualNodeFamily(), linkFamily(), m_dualnodes_incremental_connectivity);
89
90 m_links_incremental_connectivity =
91 new IncrementalItemConnectivity(linkFamily(),
92 dualNodeFamily(),
93 mesh::connectivityName(linkFamily(), dualNodeFamily()));
94 m_connectivity_mng->registerConnectivity(m_links_incremental_connectivity);
95
96 if (m_item_family_network)
97 //m_item_family_network->addRelation(linkFamily(),dualNodeFamily(),m_links_incremental_connectivity);
98 m_item_family_network->addDependency(linkFamily(), dualNodeFamily(), m_links_incremental_connectivity, false);
99
100 m_incremental_connectivities.resize(NB_DUAL_ITEM_TYPE, nullptr);
101 std::array<int, NB_DUAL_ITEM_TYPE> dual_node_kinds = { IT_DualCell, IT_DualFace, IT_DualEdge, IT_DualNode, IT_DualParticle };
102 for (auto dual_node_kind : dual_node_kinds) {
103 IItemFamily* dual_item_family = _dualItemFamily(dualItemKind(dual_node_kind));
104 if (dual_item_family) {
105 auto dof2dual_incremental_connectivity =
106 new IncrementalItemConnectivity(dualNodeFamily(),
107 dual_item_family,
108 mesh::connectivityName(dualNodeFamily(), dual_item_family));
109
110 m_connectivity_mng->registerConnectivity(dof2dual_incremental_connectivity);
111 m_incremental_connectivities[_connectivityIndex(dual_node_kind)] = dof2dual_incremental_connectivity;
112 if (m_item_family_network)
113 m_item_family_network->addDependency(dualNodeFamily(), dual_item_family, dof2dual_incremental_connectivity, false);
114 }
115 }
116 m_graph_connectivity.reset(new GraphIncrementalConnectivity(dualNodeFamily(),
117 linkFamily(),
118 m_dualnodes_incremental_connectivity,
119 m_links_incremental_connectivity,
120 m_incremental_connectivities,
121 m_dual_node_to_connectivity_index));
122
123 for (auto& obs : m_connectivity_observer)
124 if (obs.get())
125 obs->notifyUpdateConnectivity();
126
127 m_update_sync_info = false;
128 m_graph_allocated = true;
129}
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133
134void GraphDoFs::
135addLinks(Integer nb_link,
136 Integer nb_dual_nodes_per_link,
137 Int64ConstArrayView links_infos)
138{
139 //info() << "GRAPHDOF : ADD LINKS";
140 Trace::Setter mci(traceMng(), _className());
141 if (!m_graph_allocated)
142 _allocateGraph();
143
144 IDoFFamily* link_family = m_dof_mng.getFamily(GraphDoFs::linkFamilyName());
145 IDoFFamily* dual_node_family = m_dof_mng.getFamily(GraphDoFs::dualNodeFamilyName());
146
147 // Extract link infos
148 Int64UniqueArray link_uids, connected_dual_node_uids;
149 link_uids.reserve(nb_link);
150 connected_dual_node_uids.reserve(nb_link * nb_dual_nodes_per_link);
151 for (auto links_infos_index = 0; links_infos_index < links_infos.size();) {
152 auto link_uid = links_infos[links_infos_index++];
153 link_uids.add(link_uid);
154 connected_dual_node_uids.addRange(
155 links_infos.subConstView(links_infos_index, nb_dual_nodes_per_link));
156 links_infos_index += nb_dual_nodes_per_link;
157 }
158
159 Int32UniqueArray link_lids(link_uids.size());
160 link_family->addDoFs(link_uids, link_lids);
161 link_family->endUpdate();
162
163 // resize connectivity
164 // fill connectivity
165 Int32UniqueArray connected_dual_nodes_lids(nb_link * nb_dual_nodes_per_link);
166 dual_node_family->itemFamily()->itemsUniqueIdToLocalId(
167 connected_dual_nodes_lids.view(), connected_dual_node_uids.constView(), true);
168
169 auto link_index = 0;
170 ENUMERATE_DOF (inewlink, link_family->itemFamily()->view(link_lids)) {
171 m_links_incremental_connectivity->notifySourceItemAdded(ItemLocalId(*inewlink));
172 for (auto lid : connected_dual_nodes_lids.subConstView(link_index, nb_dual_nodes_per_link)) {
173 m_links_incremental_connectivity->addConnectedItem(ItemLocalId(*inewlink), ItemLocalId(lid));
174 m_dualnodes_incremental_connectivity->addConnectedItem(ItemLocalId(lid), ItemLocalId(*inewlink));
175 }
176 link_index += nb_dual_nodes_per_link;
177 }
178 m_connectivity_mng->setUpToDate(m_links_incremental_connectivity);
179 m_connectivity_mng->setUpToDate(m_dualnodes_incremental_connectivity);
180
181 m_update_sync_info = false;
182}
183
184/*---------------------------------------------------------------------------*/
185/*---------------------------------------------------------------------------*/
186
187void GraphDoFs::
188addDualNodes(Integer graph_nb_dual_node,
189 Integer dual_node_kind,
190 Int64ConstArrayView dual_nodes_infos)
191{
192
193 Trace::Setter mci(traceMng(), _className());
194 if (!m_graph_allocated)
195 _allocateGraph();
196
197 // Size m_connecitivities if not yet done
198
199 Int64UniqueArray dual_node_uids, dual_item_uids;
200 dual_node_uids.reserve(graph_nb_dual_node);
201 dual_item_uids.reserve(graph_nb_dual_node);
202 for (auto infos_index = 0; infos_index < dual_nodes_infos.size();) {
203 dual_node_uids.add(dual_nodes_infos[infos_index++]);
204 dual_item_uids.add(dual_nodes_infos[infos_index++]);
205 }
206
207 Int32UniqueArray dual_node_lids(dual_node_uids.size());
208 auto* dual_node_family = m_dof_mng.getFamily(GraphDoFs::dualNodeFamilyName());
209 dual_node_family->addDoFs(dual_node_uids, dual_node_lids);
210 dual_node_family->endUpdate();
211
212 IItemFamily* dual_item_family = _dualItemFamily(dualItemKind(dual_node_kind));
213
214 auto incremental_dual_item_connectivity = m_incremental_connectivities[_connectivityIndex(dual_node_kind)];
215 if (incremental_dual_item_connectivity == nullptr) {
216 incremental_dual_item_connectivity =
217 new IncrementalItemConnectivity(dualNodeFamily(),
218 dual_item_family,
219 mesh::connectivityName(dualNodeFamily(), dual_item_family));
220
221 m_connectivity_mng->registerConnectivity(incremental_dual_item_connectivity);
222 m_incremental_connectivities[_connectivityIndex(dual_node_kind)] = incremental_dual_item_connectivity;
223 if (m_item_family_network)
224 m_item_family_network->addDependency(dualNodeFamily(), dual_item_family, incremental_dual_item_connectivity, false);
225 }
226 Int32UniqueArray dual_item_lids(dual_item_uids.size());
227 dual_item_family->itemsUniqueIdToLocalId(dual_item_lids, dual_item_uids);
228
229 ENUMERATE_DOF (idual_node, dual_node_family->itemFamily()->view(dual_node_lids)) {
230 incremental_dual_item_connectivity->notifySourceItemAdded(ItemLocalId(*idual_node));
231 incremental_dual_item_connectivity->addConnectedItem(ItemLocalId(*idual_node), ItemLocalId(dual_item_lids[idual_node.index()]));
232 }
233 m_connectivity_mng->setUpToDate(incremental_dual_item_connectivity);
234
235 m_update_sync_info = false;
236 //m_dual_node_to_connectivity_index.resize(&dual_node_family, _connectivityIndex(dual_node_kind));
237}
238
239void GraphDoFs::
240addDualNodes(Integer graph_nb_dual_node,
241 Int64ConstArrayView dual_nodes_infos)
242{
243
244 Trace::Setter mci(traceMng(), _className());
245 if (!m_graph_allocated)
246 _allocateGraph();
247
248 // Size m_connecitivities if not yet done
249 bool is_parallel = m_mesh->parallelMng()->isParallel();
250 Integer domain_rank = m_mesh->parallelMng()->commRank();
251
252 std::map<Int64, std::pair<Int64UniqueArray, Int64UniqueArray>> dual_info_per_kind;
253 for (auto infos_index = 0; infos_index < dual_nodes_infos.size();) {
254 Int64 dual_node_kind = dual_nodes_infos[infos_index++];
255 auto& info = dual_info_per_kind[dual_node_kind];
256 auto& dual_node_uids = info.first;
257 auto& dual_item_uids = info.second;
258 if (dual_node_uids.size() == 0) {
259 dual_node_uids.reserve(graph_nb_dual_node);
260 dual_item_uids.reserve(graph_nb_dual_node);
261 }
262 dual_node_uids.add(dual_nodes_infos[infos_index++]);
263 dual_item_uids.add(dual_nodes_infos[infos_index++]);
264 }
265
266 for (Integer index = 0; index < NB_DUAL_ITEM_TYPE; ++index) {
267 Integer dual_node_kind = m_dualnode_kinds[index];
268 auto& info = dual_info_per_kind[dual_node_kind];
269 auto& dual_node_uids = info.first;
270 auto& dual_item_uids = info.second;
271
272 auto* dual_node_family = m_dof_mng.getFamily(GraphDoFs::dualNodeFamilyName());
273 Int32UniqueArray dual_node_lids(dual_node_uids.size());
274 if (is_parallel) {
275 IItemFamily* dual_item_family = _dualItemFamily(dualItemKind(dual_node_kind));
276 if (dual_item_family) {
277 Int32UniqueArray dual_item_lids(dual_item_uids.size());
278 dual_item_family->itemsUniqueIdToLocalId(dual_item_lids, dual_item_uids);
279 auto dual_item_view = dual_item_family->view(dual_item_lids);
280
281 Int32UniqueArray local_dual_node_lids;
282 Int64UniqueArray local_dual_node_uids;
283
284 Integer local_size = 0;
285 for (auto const& item : dual_item_view)
286 if (item.owner() == domain_rank)
287 ++local_size;
288 local_dual_node_lids.resize(local_size);
289 local_dual_node_uids.reserve(local_size);
290
291 Integer ghost_size = dual_node_uids.size() - local_size;
292 Int64UniqueArray ghost_dual_node_uids;
293 Int32UniqueArray ghost_dual_node_lids;
294 Int32UniqueArray ghost_dual_node_owner;
295 ghost_dual_node_lids.resize(ghost_size);
296 ghost_dual_node_uids.reserve(ghost_size);
297 ghost_dual_node_owner.reserve(ghost_size);
298
299 Integer icount = 0;
300 for (auto const& item : dual_item_view) {
301 if (item.owner() == domain_rank) {
302 local_dual_node_uids.add(dual_node_uids[icount]);
303 }
304 else {
305 ghost_dual_node_uids.add(dual_node_uids[icount]);
306 ghost_dual_node_owner.add(item.owner());
307 }
308 ++icount;
309 }
310
311 dual_node_family->addDoFs(local_dual_node_uids, local_dual_node_lids);
312 dual_node_family->addGhostDoFs(ghost_dual_node_uids, ghost_dual_node_lids, ghost_dual_node_owner);
313 dual_node_family->endUpdate();
314
315 icount = 0;
316 Integer local_icount = 0;
317 Integer ghost_icount = 0;
318 for (auto const& item : dual_item_view) {
319 if (item.owner() == domain_rank)
320 dual_node_lids[icount] = local_dual_node_lids[local_icount++];
321 else
322 dual_node_lids[icount] = ghost_dual_node_lids[ghost_icount++];
323 ++icount;
324 }
325 }
326 }
327 else {
328 dual_node_family->addDoFs(dual_node_uids, dual_node_lids);
329 dual_node_family->endUpdate();
330 }
331
332 IItemFamily* dual_item_family = _dualItemFamily(dualItemKind(dual_node_kind));
333 if (dual_item_family) {
334
335 auto incremental_dual_item_connectivity = m_incremental_connectivities[index];
336 if (incremental_dual_item_connectivity == nullptr) {
337 incremental_dual_item_connectivity =
338 new IncrementalItemConnectivity(dualNodeFamily(),
339 dual_item_family,
340 mesh::connectivityName(dualNodeFamily(), dual_item_family));
341
342 m_connectivity_mng->registerConnectivity(incremental_dual_item_connectivity);
343 m_incremental_connectivities[index] = incremental_dual_item_connectivity;
344 if (m_item_family_network)
345 m_item_family_network->addDependency(dualNodeFamily(), dual_item_family, incremental_dual_item_connectivity, false);
346 }
347 Int32UniqueArray dual_item_lids(dual_item_uids.size());
348 dual_item_family->itemsUniqueIdToLocalId(dual_item_lids, dual_item_uids);
349
350 ENUMERATE_DOF (idual_node, dual_node_family->itemFamily()->view(dual_node_lids)) {
351 incremental_dual_item_connectivity->notifySourceItemAdded(ItemLocalId(*idual_node));
352 incremental_dual_item_connectivity->addConnectedItem(ItemLocalId(*idual_node), ItemLocalId(dual_item_lids[idual_node.index()]));
353 }
354
355 //m_dual_node_to_connectivity_index.resize(&dual_node_family, _connectivityIndex(dual_node_kind));
356
357 m_connectivity_mng->setUpToDate(incremental_dual_item_connectivity);
358 }
359 }
360
361 m_update_sync_info = false;
362}
363
364/*---------------------------------------------------------------------------*/
365/*---------------------------------------------------------------------------*/
366
367void GraphDoFs::
368removeDualNodes(Int32ConstArrayView dual_node_local_ids)
369{
370 Trace::Setter mci(traceMng(), _className());
371 //m_dual_node_family.removeItems(dual_node_local_ids);
372 m_dof_mng.getFamily(GraphDoFs::dualNodeFamilyName())->removeDoFs(dual_node_local_ids);
373 if (dual_node_local_ids.size() > 0)
374 m_update_sync_info = false;
375}
376
377/*---------------------------------------------------------------------------*/
378/*---------------------------------------------------------------------------*/
379
380void GraphDoFs::
381removeLinks(Int32ConstArrayView link_local_ids)
382{
383 Trace::Setter mci(traceMng(), _className());
384 //m_link_family.removeItems(link_local_ids);
385 m_dof_mng.getFamily(GraphDoFs::linkFamilyName())->removeDoFs(link_local_ids);
386 if (link_local_ids.size() > 0)
387 m_update_sync_info = false;
388}
389
390void GraphDoFs::
391removeConnectedItemsFromCells(Int32ConstArrayView cell_local_ids)
392{
393 std::set<Int32> cell_to_remove_set;
394 std::set<Int32> node_to_remove_set;
395 std::set<Int32> face_to_remove_set;
396 auto cell_family = m_mesh->cellFamily();
397 auto remove_cells = CellVectorView(cell_family, cell_local_ids);
398 ENUMERATE_CELL (icell, remove_cells) {
399 cell_to_remove_set.insert(icell->localId());
400 for (auto face : icell->faces()) {
401 if (face.itemBase().isSuppressed())
402 face_to_remove_set.insert(face.localId());
403 }
404 for (auto node : icell->nodes()) {
405 if (node.itemBase().isSuppressed())
406 node_to_remove_set.insert(node.localId());
407 }
408 }
409 {
410 std::set<Int32> link_to_remove_set;
411 ConnectivityItemVector dual_nodes(m_links_incremental_connectivity);
412 //ENUMERATE_DOF (ilink, linkFamily()->allItems())
413 for (auto ilink : linkFamily()->itemsInternal()) {
414 if (ilink->isSuppressed())
415 continue;
416 auto link_lid = ItemLocalId(ilink);
417 bool to_remove = false;
418 ENUMERATE_DOF (idual_node, dual_nodes.connectedItems(link_lid)) {
419 auto dual_item = m_graph_connectivity->dualItem(*idual_node);
420 switch (dual_item.kind()) {
421 case IK_Cell:
422 if (cell_to_remove_set.find(dual_item->localId()) != cell_to_remove_set.end())
423 to_remove = true;
424 break;
425 case IK_Face:
426 if (face_to_remove_set.find(dual_item->localId()) != face_to_remove_set.end())
427 to_remove = true;
428 break;
429 case IK_Node:
430 if (node_to_remove_set.find(dual_item->localId()) != node_to_remove_set.end())
431 to_remove = true;
432 break;
433 case IK_Particle:
434 if (dual_item.itemBase().isSuppressed())
435 to_remove = true;
436 break;
437 }
438 if (to_remove)
439 break;
440 }
441 if (to_remove) {
442 link_to_remove_set.insert(link_lid);
443 ENUMERATE_DOF (idual_node, dual_nodes.connectedItems(link_lid)) {
444 m_dualnodes_incremental_connectivity->removeConnectedItem(ItemLocalId(idual_node->localId()), link_lid);
445 }
446 }
447 }
448 m_detached_link_lids.resize(link_to_remove_set.size());
449 std::copy(std::begin(link_to_remove_set), std::end(link_to_remove_set), std::begin(m_detached_link_lids));
450
451 removeLinks(m_detached_link_lids);
452 //link_family->endUpdate() ;
453 m_detached_link_lids.clear();
454 }
455 {
456 auto incremental_dof2cell_connectivity = m_incremental_connectivities[m_connectivity_indexes_per_type[IT_DualCell]];
457 auto incremental_dof2face_connectivity = m_incremental_connectivities[m_connectivity_indexes_per_type[IT_DualFace]];
458 auto incremental_dof2node_connectivity = m_incremental_connectivities[m_connectivity_indexes_per_type[IT_DualNode]];
459 auto incremental_dof2part_connectivity = m_incremental_connectivities[m_connectivity_indexes_per_type[IT_DualParticle]];
460
461 //auto source_family = incremental_dof2cell_connectivity->sourceFamily() ;
462 //auto dof_family = dynamic_cast<DoFFamily*>(source_family) ;
463 //auto accessor = incremental_dof2cell_connectivity->connectivityAccessor() ;
464
465 //ENUMERATE_ITEM (idualnode, dualNodeFamily()->allItems())
466 for (auto idualnode : dualNodeFamily()->itemsInternal()) {
467 if (idualnode->isSuppressed())
468 continue;
469 auto dualnode_lid = ItemLocalId(idualnode);
470 //auto lid = idualnode->localId() ;
471 auto dual_item = m_graph_connectivity->dualItem(DoF(idualnode));
472 switch (dual_item.kind()) {
473 case IK_Cell:
474 if (cell_to_remove_set.find(dual_item.localId()) != cell_to_remove_set.end()) {
475 incremental_dof2cell_connectivity->replaceConnectedItem(dualnode_lid, 0, ItemLocalId(-1));
476 m_detached_dualnode_lids.add(dualnode_lid);
477 //info()<<" REMOVE DUALCELL : "<<idualnode->uniqueId();
478 }
479 break;
480 case IK_Face:
481 if (face_to_remove_set.find(dual_item.localId()) != face_to_remove_set.end()) {
482 incremental_dof2face_connectivity->replaceConnectedItem(dualnode_lid, 0, ItemLocalId(-1));
483 m_detached_dualnode_lids.add(dualnode_lid);
484 //info()<<" REMOVE DUALFACE : "<<idualnode->uniqueId();
485 }
486 break;
487 case IK_Node:
488 if (node_to_remove_set.find(dual_item.localId()) != node_to_remove_set.end()) {
489 incremental_dof2node_connectivity->replaceConnectedItem(dualnode_lid, 0, ItemLocalId(-1));
490 m_detached_dualnode_lids.add(dualnode_lid);
491 //info()<<" REMOVE DUALNODE : "<<idualnode->uniqueId();
492 }
493 break;
494 case IK_Particle:
495 if (dual_item.itemBase().isSuppressed()) {
496 incremental_dof2part_connectivity->replaceConnectedItem(dualnode_lid, 0, ItemLocalId(-1));
497 m_detached_dualnode_lids.add(dualnode_lid);
498 //info()<<" REMOVE DUALPART : "<<idualnode->uniqueId();
499 }
500 }
501 }
502
503 removeDualNodes(m_detached_dualnode_lids);
504 //dualNodeFamily()->endUpdate() ;
505 m_detached_dualnode_lids.clear();
506 }
507 m_update_sync_info = false;
508}
509/*---------------------------------------------------------------------------*/
510/*---------------------------------------------------------------------------*/
511
512bool GraphDoFs::
513isUpdated()
514{
515 if (!m_graph_allocated)
516 return true;
517
518 for (Integer index = 0; index < NB_DUAL_ITEM_TYPE; ++index) {
519 Integer dual_node_kind = m_dualnode_kinds[index];
520 auto dof2dual_incremental_connectivity = m_incremental_connectivities[_connectivityIndex(dual_node_kind)];
521
522 if (dof2dual_incremental_connectivity && !m_connectivity_mng->isUpToDate(dof2dual_incremental_connectivity))
523 m_update_sync_info = false;
524
525 if (!m_connectivity_mng->isUpToDate(m_dualnodes_incremental_connectivity))
526 m_update_sync_info = false;
527
528 if (!m_connectivity_mng->isUpToDate(m_links_incremental_connectivity))
529 m_update_sync_info = false;
530 }
531
532 Integer sync_info = (m_update_sync_info ? 0 : 1);
533 sync_info = m_mesh->parallelMng()->reduce(Parallel::ReduceSum, sync_info);
534 m_update_sync_info = sync_info == 0;
535
536 return m_update_sync_info;
537}
538
539void GraphDoFs::
540endUpdate()
541{
542 if (!m_graph_allocated)
543 return;
544
545 auto dualnode_family = dualNodeFamily();
546 auto link_family = linkFamily();
547
548 DualUniqueIdMng dual_uid_mng(traceMng());
549 for (Integer index = 0; index < NB_DUAL_ITEM_TYPE; ++index) {
550 Integer dual_node_kind = m_dualnode_kinds[index];
551 Arcane::eItemKind dual_item_kind = dualItemKind(dual_node_kind);
552 IItemFamily* dual_item_family = _dualItemFamily(dual_item_kind);
553
554 if (dual_item_family == nullptr || dual_item_family->nbItem() == 0)
555 continue;
556
557 auto dof2dual_incremental_connectivity = m_incremental_connectivities[_connectivityIndex(dual_node_kind)];
558 if (dof2dual_incremental_connectivity && !m_connectivity_mng->isUpToDate(dof2dual_incremental_connectivity)) {
559 //info() << "UPDATE DUALNODE CONNECTIVITY KIND " << index << " " << dual_node_kind << " " << dual_item_kind;
560 // Handle added nodes : create a dof for each own node added
561 Int32ArrayView source_family_added_items_lids;
562 Int32ArrayView source_family_removed_items_lids;
563 m_connectivity_mng->getSourceFamilyModifiedItems(dof2dual_incremental_connectivity, source_family_added_items_lids, source_family_removed_items_lids);
564
565 info() << " NUMBER OF REMOVE ITEMS : " << source_family_removed_items_lids.size();
566 info() << " NUMBER OF ADDED ITEMS : " << source_family_added_items_lids.size();
567 Int64UniqueArray dual_item_uids;
568 dual_item_uids.reserve(source_family_added_items_lids.size());
569 IntegerUniqueArray dual_node_lids;
570 dual_node_lids.reserve(source_family_added_items_lids.size());
571
572 ItemVector source_family_added_items(dualnode_family, source_family_added_items_lids);
573 ENUMERATE_DOF (idof, source_family_added_items) {
574 auto value = dual_uid_mng.uniqueIdOfDualItem(*idof);
575 if (std::get<0>(value) == dual_item_kind) {
576 dual_node_lids.add(idof->localId());
577 dual_item_uids.add(std::get<1>(value));
578 }
579 }
580
581 Int32SharedArray dual_item_lids(dual_item_uids.size());
582 dual_item_family->itemsUniqueIdToLocalId(dual_item_lids, dual_item_uids);
583
584 ENUMERATE_DOF (idual_node, dualnode_family->view(dual_node_lids)) {
585 dof2dual_incremental_connectivity->notifySourceItemAdded(ItemLocalId(*idual_node));
586 dof2dual_incremental_connectivity->addConnectedItem(ItemLocalId(*idual_node), ItemLocalId(dual_item_lids[idual_node.index()]));
587 //info()<<" ADD CONNECTED DUAL ITEM("<<idual_node->localId()<<" "<<idual_node->uniqueId()<<") "<<dual_item_lids[idual_node.index()]<<" "<<dual_item_uids[idual_node.index()] ;
588 }
589
590 // Update connectivity
591 //dof2dual_incremental_connectivity->updateConnectivity(source_family_added_items_lids,dual_lids);
592
593 // Update ghost
594 //synchronizer->synchronize();
595
596 // For test purpose only : try getSourceFamilyModifiedItem (must give back the new dofs created)
597 //Int32ArrayView target_family_added_item_lids, target_family_removed_item_lids;
598 //m_connectivity_mng->getTargetFamilyModifiedItems(dof2dual_incremental_connectivity,target_family_added_item_lids,target_family_removed_item_lids);
599 //_checkTargetFamilyInfo(dualnode_family.view(target_family_added_item_lids),lids);
600
601 //m_dual_node_to_connectivity_index.resize(dualnode_family, _connectivityIndex(dual_node_kind));
602
603 // Finalize connectivity update
604 m_connectivity_mng->setUpToDate(dof2dual_incremental_connectivity);
605 }
606 }
607
608 if (!m_connectivity_mng->isUpToDate(m_links_incremental_connectivity)) {
609
610 //info()<<"UPDATE LINK TO DUALNODE CONNECTIVITY" ;
611 // Handle added nodes : create a dof for each own node added
612 Int32ArrayView source_family_added_items_lids;
613 Int32ArrayView source_family_removed_items_lids;
614 m_connectivity_mng->getSourceFamilyModifiedItems(m_links_incremental_connectivity, source_family_added_items_lids, source_family_removed_items_lids);
615
616 info() << " NUMBER OF REMOVE ITEMS : " << source_family_removed_items_lids.size();
617 info() << " NUMBER OF ADDED ITEMS : " << source_family_added_items_lids.size();
618 ItemVector source_family_added_items(link_family, source_family_added_items_lids);
619
620 Int64UniqueArray link_uids;
621 link_uids.reserve(source_family_added_items_lids.size());
622 Int64UniqueArray dualnode_uids;
623 dualnode_uids.reserve(2 * source_family_added_items_lids.size());
624 ENUMERATE_DOF (ilink, source_family_added_items) {
625 link_uids.add(ilink->uniqueId());
626 auto value = dual_uid_mng.uniqueIdOfPairOfDualItems(*ilink);
627 eItemKind dualitem_kind_1 = std::get<0>(value.first);
628 Int64 dualitem_uid_1 = std::get<1>(value.first);
629 Int64 dof_uid_1 = dual_uid_mng.uniqueIdOf(dualitem_kind_1, dualitem_uid_1);
630 dualnode_uids.add(dof_uid_1);
631
632 eItemKind dualitem_kind_2 = std::get<0>(value.second);
633 Int64 dualitem_uid_2 = std::get<1>(value.second);
634 Int64 dof_uid_2 = dual_uid_mng.uniqueIdOf(dualitem_kind_2, dualitem_uid_2);
635 dualnode_uids.add(dof_uid_2);
636
637 //info()<<" ADDED DOF UID "<<ilink->uniqueId();
638 //info()<<" DUAL KIND 1="<<dualitem_kind_1<<" DUAL UID 1="<<dualitem_uid_1<<" DOF UID 1="<<dof_uid_1;
639 //info()<<" DUAL KIND 2="<<dualitem_kind_2<<" DUAL UID 2="<<dualitem_uid_2<<" DOF UID 2="<<dof_uid_2;
640 }
641
642 Integer nb_dual_nodes_per_link = 2;
643 Int32UniqueArray connected_dual_nodes_lids(dualnode_uids.size());
644
645 dualnode_family->itemsUniqueIdToLocalId(connected_dual_nodes_lids.view(), dualnode_uids);
646
647 Integer link_index = 0;
648 ENUMERATE_DOF (inewlink, source_family_added_items) {
649 m_links_incremental_connectivity->notifySourceItemAdded(ItemLocalId(*inewlink));
650 for (auto lid : connected_dual_nodes_lids.subConstView(link_index, nb_dual_nodes_per_link)) {
651 m_links_incremental_connectivity->addConnectedItem(ItemLocalId(*inewlink), ItemLocalId(lid));
652 m_dualnodes_incremental_connectivity->addConnectedItem(ItemLocalId(lid), ItemLocalId(*inewlink));
653 }
654 link_index += nb_dual_nodes_per_link;
655 }
656
657 // Finalize connectivity update
658 m_connectivity_mng->setUpToDate(m_links_incremental_connectivity);
659 m_connectivity_mng->setUpToDate(m_dualnodes_incremental_connectivity);
660 }
661
662 dualnode_family->computeSynchronizeInfos();
663 link_family->computeSynchronizeInfos();
664 m_update_sync_info = true;
665
666 updateAfterMeshChanged();
667
668 auto* x = new GraphIncrementalConnectivity(dualNodeFamily(),
669 linkFamily(),
670 m_dualnodes_incremental_connectivity,
671 m_links_incremental_connectivity,
672 m_incremental_connectivities,
673 m_dual_node_to_connectivity_index);
674 m_graph_connectivity.reset(x);
675
676 for (auto& obs : m_connectivity_observer) {
677 if (obs.get())
678 obs->notifyUpdateConnectivity();
679 }
680
681 for (auto& obs : m_graph_observer) {
682 if (obs.get())
683 obs->notifyUpdate();
684 }
685
686 //printDualNodes();
687 //printLinks();
688}
689
690/*---------------------------------------------------------------------------*/
691/*---------------------------------------------------------------------------*/
692
693void GraphDoFs::
694updateAfterMeshChanged()
695{
696 if (!m_graph_allocated)
697 return;
698
699 auto* dual_node_family = m_dof_mng.getFamily(GraphDoFs::dualNodeFamilyName());
700 m_dual_node_to_connectivity_index.resize(dual_node_family->itemFamily(), -1);
701 ENUMERATE_DOF (idof, dual_node_family->allItems()) {
702 for (Integer index = 0; index < m_incremental_connectivities.size(); ++index) {
703 auto connectivity = m_incremental_connectivities[index];
704 if (connectivity && (connectivity->maxNbConnectedItem() > 0)) {
705 ConnectivityItemVector accessor(connectivity);
706 if (accessor.connectedItems(*idof).size() > 0) {
707 m_dual_node_to_connectivity_index[*idof] = index;
708 }
709 }
710 }
711 }
712 //endUpdate();
713}
714
715/*---------------------------------------------------------------------------*/
716/*---------------------------------------------------------------------------*/
717
718void GraphDoFs::
719printDualNodes() const
720{
721 ENUMERATE_DOF (idualnode, dualNodeFamily()->allItems()) {
722 info() << "DualNode : lid = " << idualnode->localId();
723 info() << " uid = " << idualnode->uniqueId();
724 info() << " owner = " << idualnode->owner();
725 auto dual_item = m_graph_connectivity->dualItem(*idualnode);
726 info() << " DualItem : lid = " << dual_item.localId();
727 info() << " uid = " << dual_item.uniqueId();
728 info() << " kind = " << dual_item.kind();
729 info() << " owner = " << dual_item.owner();
730 auto links = m_graph_connectivity->links(*idualnode);
731 for (auto const& link : links) {
732 info() << " Connected link : lid = " << link.localId();
733 info() << " uid = " << link.uniqueId();
734 info() << " owner = " << link.owner();
735 }
736 }
737}
738
739/*---------------------------------------------------------------------------*/
740/*---------------------------------------------------------------------------*/
741
742void GraphDoFs::
743printLinks() const
744{
745 ENUMERATE_DOF (ilink, linkFamily()->allItems()) {
746 info() << "Link : LID = " << ilink.localId();
747 info() << " UID = " << ilink->uniqueId();
748 info() << " OWNER = " << ilink->owner();
749 ENUMERATE_DOF (idual_node, m_graph_connectivity->dualNodes(*ilink)) {
750 info() << " Dof : index = " << idual_node.index();
751 info() << " Dof : LID = " << idual_node->localId();
752 info() << " UID = " << idual_node->uniqueId();
753 info() << " OWNER = " << idual_node->owner();
754 auto dual_item = m_graph_connectivity->dualItem(*idual_node);
755 info() << " dual item UID = " << dual_item.uniqueId();
756 info() << " KIND = " << dual_item.kind();
757 info() << " OWNER = " << dual_item.owner();
758 }
759 }
760}
761
762/*---------------------------------------------------------------------------*/
763/*---------------------------------------------------------------------------*/
764
765} // namespace Arcane::mesh
766
767/*---------------------------------------------------------------------------*/
768/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_DOF(name, group)
Generic enumerator for a degree of freedom group.
#define ENUMERATE_CELL(name, group)
Generic enumerator for a cell group.
Various mathematical functions.
Integer size() const
Number of elements in the vector.
constexpr Integer size() const noexcept
Returns the size of the array.
void addRange(ConstReferenceType val, Int64 n)
Adds n elements of value val to the end of the array.
void resize(Int64 s)
Changes the number of elements in the array to s.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sub-view starting from element abegin and containing asize elements.
void add(ConstReferenceType val)
Adds element val to the end of the array.
ConstArrayView< T > constView() const
Constant view of this array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
ArrayView< T > view() const
Mutable view of this array.
Manages the retrieval of connectivity information.
ItemVectorView connectedItems(ItemLocalId item)
Returns the entities connected to item.
constexpr Integer size() const noexcept
Number of elements in the array.
constexpr ConstArrayView< T > subConstView(Integer abegin, Integer asize) const noexcept
Sub-view (constant) starting from element abegin and containing asize elements.
degree of freedom class.
Definition Item.h:1649
Interface of a DoF family.
Definition IDoFFamily.h:34
virtual DoFVectorView addDoFs(Int64ConstArrayView dof_uids, Int32ArrayView dof_lids)=0
Input is the DoF uids and we retrieve their lids.
virtual void endUpdate()=0
Interface of an entity family.
Definition IItemFamily.h:83
virtual ItemVectorView view(Int32ConstArrayView local_ids)=0
View on the entities.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converts an array of unique numbers to local numbers.
Index of an Item in a variable.
Definition ItemLocalId.h:42
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
void removeLinks(Int32ConstArrayView link_local_ids) override
Removes dual links from the graph.
Definition GraphDoFs.cc:381
void removeDualNodes(Int32ConstArrayView dual_node_local_ids) override
Removes dual nodes from the graph.
Definition GraphDoFs.cc:368
ItemVectorViewT< Cell > CellVectorView
View over a vector of cells.
Definition ItemTypes.h:305
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:339
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:480
SharedArray< Int32 > Int32SharedArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:381
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:341
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:453
eItemKind
Mesh entity type.
@ IK_Particle
Particle mesh entity.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.