Arcane  4.1.11.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
OneMeshItemAdder.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/* OneMeshItemAdder.cc (C) 2000-2025 */
9/* */
10/* Adding entities one by one. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/OneMeshItemAdder.h"
15
16#include "arcane/utils/NotSupportedException.h"
17#include "arcane/utils/ValueConvert.h"
18#include "arcane/utils/FixedArray.h"
19
21#include "arcane/core/MeshToMeshTransposer.h"
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/ItemPrinter.h"
24
25#include "arcane/mesh/DynamicMesh.h"
26#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
27#include "arcane/mesh/ItemTools.h"
28#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
29#include "arcane/mesh/GraphDoFs.h"
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane::mesh
35{
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
41{
42 public:
43
44 CellInfoProxy(ItemTypeInfo* type_info,
45 Int64 cell_uid,
46 Int32 sub_domain_id,
48 bool allow_build_face = false)
49 : m_type_info(type_info)
50 , m_cell_uid(cell_uid)
51 , m_info(info)
52 , m_owner(sub_domain_id)
53 , m_allow_build_face(allow_build_face)
54 {}
55
56 Int64 uniqueId() const { return m_cell_uid; }
57 ItemTypeInfo* typeInfo() const { return m_type_info; }
58 Int32 owner() const { return m_owner; }
59 Integer nbNode() const { return m_info.size(); }
60 Integer nbFace() const { return m_type_info->nbLocalFace(); }
61 Integer nbEdge() const { return m_type_info->nbLocalEdge(); }
62 Int64 nodeUniqueId(Integer i_node) const { return m_info[i_node]; }
63 Int32 nodeOwner(Integer) const { return m_owner; }
64 Int32 faceOwner(Integer) const { return m_owner; }
65 Int32 edgeOwner(Integer) const { return m_owner; }
66 ItemTypeInfo::LocalFace localFace(Integer i_face) const { return m_type_info->localFace(i_face); }
67 bool allowBuildFace() const { return m_allow_build_face; }
68 bool allowBuildEdge() const { return m_allow_build_face; }
69
70 private:
71
72 ItemTypeInfo* m_type_info = nullptr;
73 Int64 m_cell_uid = NULL_ITEM_UNIQUE_ID;
75 Int32 m_owner = A_NULL_RANK;
76 bool m_allow_build_face = false;
77};
78
79/*---------------------------------------------------------------------------*/
80/*---------------------------------------------------------------------------*/
81
82OneMeshItemAdder::
83OneMeshItemAdder(DynamicMeshIncrementalBuilder* mesh_builder)
84: TraceAccessor(mesh_builder->mesh()->traceMng())
85, m_mesh(mesh_builder->mesh())
86, m_mesh_builder(mesh_builder)
87, m_cell_family(m_mesh->trueCellFamily())
88, m_node_family(m_mesh->trueNodeFamily())
89, m_face_family(m_mesh->trueFaceFamily())
90, m_edge_family(m_mesh->trueEdgeFamily())
91, m_item_type_mng(m_mesh->itemTypeMng())
92, m_mesh_info(m_mesh->meshPartInfo().partRank())
93, m_face_reorderer(m_item_type_mng)
94{
95 //m_work_face_sorted_nodes.reserve(100);
96 m_work_face_orig_nodes_uid.reserve(100);
97}
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102ItemInternal* OneMeshItemAdder::
103addOneNode(Int64 node_uid, Int32 owner)
104{
105 bool is_add = false;
106 ItemInternal* node = m_node_family.findOrAllocOne(node_uid, is_add);
107 if (is_add) {
109 node->setOwner(owner, owner);
110 }
111 return node;
112}
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
125{
126 Int32 nb_node = nodes_uid.size();
127 // Checks that the number of nodes is the same
128 if (item.nbNode() != nb_node)
129 ARCANE_FATAL("Trying to add existing item (kind='{0}', uid={1}) with different number of node (existing={2} new={3})",
130 item.kind(), item.uniqueId(), item.nbNode(), nb_node);
131
132 // Checks that the nodes correspond to the existing ones
133 for (Int32 i = 0; i < nb_node; ++i) {
134 Int64 new_uid = nodes_uid[i];
135 Int64 current_uid = item.node(i).uniqueId();
136 if (new_uid != current_uid) {
137 std::ostringstream ostr;
138 for (Int32 k = 0; k < nb_node; ++k)
139 ostr << " " << item.node(k).uniqueId();
140 ARCANE_FATAL("Trying to add existing item (kind='{0}', uid={1}) with different nodes (index={2} existing='{3}' new='{4}')",
141 item.kind(), item.uniqueId(), i, ostr.str(), nodes_uid);
142 }
143 }
144}
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
155{
156 if (uid != NULL_ITEM_UNIQUE_ID)
157 return uid;
159 uid = MeshUtils::generateHashUniqueId(nodes_uid);
160 else
161 uid = m_next_face_uid++;
162 return uid;
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
180addOneFace(ItemTypeId type_id, Int64 face_uid, Int32 owner_rank, Int64ConstArrayView nodes_uid)
181{
182 const Integer face_nb_node = nodes_uid.size();
183
184 //m_work_face_sorted_nodes.resize(face_nb_node);
185 //m_work_face_orig_nodes_uid.resize(face_nb_node);
186 //for( Integer z=0; z<face_nb_node; ++z )
187 //m_work_face_orig_nodes_uid[z] = nodes_uid[z];
188 m_face_reorderer.reorder(type_id, nodes_uid);
189 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
190 // TODO: in the case where the face will be orphaned (not connected to a mesh),
191 // check if the face needs reorientation because this risks introducing
192 // an inconsistency if one later wishes to calculate a normal.
193 //MeshUtils::reorderNodesOfFace(m_work_face_orig_nodes_uid,m_work_face_sorted_nodes);
194 face_uid = _checkGenerateFaceUniqueId(face_uid, face_sorted_nodes);
195 bool is_add_face = false;
196 Face face = m_face_family.findOrAllocOne(face_uid, type_id, is_add_face);
197 // The face does not exist
198 if (is_add_face) {
199 ++m_mesh_info.nbFace();
200 face.mutableItemBase().setOwner(owner_rank, m_mesh_info.rank());
201 for (Integer i_node = 0; i_node < face_nb_node; ++i_node) {
202 Node node = addOneNode(face_sorted_nodes[i_node], m_mesh_info.rank());
203 m_face_family.replaceNode(face, i_node, node);
204 m_node_family.addFaceToNode(node, face);
205 }
206 }
207 else {
208 if (arcaneIsCheck())
209 _checkSameItemCoherency(face, face_sorted_nodes);
210 }
211
212 return ItemCompatibility::_itemInternal(face);
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
218ItemInternal* OneMeshItemAdder::
219addOneEdge(Int64 edge_uid, Int32 rank, Int64ConstArrayView nodes_uid)
220{
221 m_work_edge_sorted_nodes.resize(2);
222 m_work_edge_orig_nodes_uid.resize(2);
223
224 for (Integer z = 0; z < 2; ++z)
225 m_work_edge_orig_nodes_uid[z] = nodes_uid[z];
226 // reorderNodesOfFace behaves correctly here for edges == faces in 2D
227 MeshUtils::reorderNodesOfFace(m_work_edge_orig_nodes_uid, m_work_edge_sorted_nodes);
228
229 bool is_add_edge = false;
230 ItemInternal* edge = m_edge_family.findOrAllocOne(edge_uid, is_add_edge);
231
232 // The edge does not exist
233 if (is_add_edge) {
235 edge->setOwner(rank, m_mesh_info.rank());
236 for (Integer i_node = 0; i_node < 2; ++i_node) {
237 ItemInternal* current_node_internal = addOneNode(m_work_edge_sorted_nodes[i_node], m_mesh_info.rank());
238 m_edge_family.replaceNode(ItemLocalId(edge), i_node, ItemLocalId(current_node_internal));
239 m_node_family.addEdgeToNode(current_node_internal, edge);
240 }
241 }
242 return edge;
243}
244
245/*---------------------------------------------------------------------------*/
246/*---------------------------------------------------------------------------*/
247
248template <>
249Face OneMeshItemAdder::
250_findInternalFace(Integer i_face, const FullCellInfo& cell_info, bool& is_add)
251{
252 const Int64 face_unique_id = cell_info.faceUniqueId(i_face);
253 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
254 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
255 ItemTypeInfo* face_type_info = m_item_type_mng->typeFromId(lf.typeId());
256 return m_face_family.findOrAllocOne(face_unique_id, face_type_info, is_add);
257}
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
261
262template <>
263Face OneMeshItemAdder::
264_findInternalFace(Integer i_face, const CellInfoProxy& cell_info, bool& is_add)
265{
266 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
267 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
268 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
269 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
270 Int64 face_unique_id = NULL_ITEM_UNIQUE_ID;
271 Face face_internal;
272 const bool use_hash = m_use_hash_for_edge_and_face_unique_id;
273 // If calculating face uniqueIds from nodes,
274 // we can directly know if the face already exists. Otherwise, we
275 // call ItemTools::findFaceInNode2(), but this function is more
276 // costly because it searches for the face by traversing the faces connected
277 // to the first node of the face.
278 if (use_hash) {
279 face_unique_id = _checkGenerateFaceUniqueId(NULL_ITEM_UNIQUE_ID, face_sorted_nodes);
280 face_internal = m_face_family.itemsMap().tryFind(face_unique_id);
281 }
282 else {
283 // Retrieves the oriented nodes of the face
284 // (One must have called one of the face addition methods before)
285 Node nbi = nodes_map.findItem(face_sorted_nodes[0]);
286 face_internal = ItemTools::findFaceInNode2(nbi, lf.typeId(), face_sorted_nodes);
287 }
288 if (face_internal.null()) {
289 // The face was not found. It therefore does not exist in our sub-domain.
290 // If this is allowed, the new face is created.
291 if (!cell_info.allowBuildFace() && !m_use_hash_for_edge_and_face_unique_id) {
292 info() << "BadCell uid=" << cell_info.uniqueId();
293 for (Int32 i = 0; i < cell_info.nbNode(); ++i)
294 info() << "Cell node I=" << i << " uid=" << cell_info.nodeUniqueId(i);
295 ARCANE_FATAL("On the fly face allocation is not allowed here.\n"
296 " You need to add faces with IMeshModifier::addFaces().\n"
297 " CellUid={0} LocalFace={1} FaceNodes={2}",
298 cell_info.uniqueId(), i_face, face_sorted_nodes);
299 }
300 // Only recalculate the hash if it hasn't been done already.
301 if (!use_hash)
302 face_unique_id = _checkGenerateFaceUniqueId(NULL_ITEM_UNIQUE_ID, face_sorted_nodes);
303 is_add = true;
304 ItemTypeInfo* face_type = m_item_type_mng->typeFromId(lf.typeId());
305 return m_face_family.allocOne(face_unique_id, face_type);
306 }
307 else {
308 is_add = false;
309 return face_internal;
310 }
311}
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316template <>
317Edge OneMeshItemAdder::
318_findInternalEdge(Integer i_edge, const FullCellInfo& cell_info,
319 Int64 first_node, Int64 second_node, bool& is_add)
320{
321 ARCANE_UNUSED(first_node);
322 ARCANE_UNUSED(second_node);
323
324 const Int64 edge_unique_id = cell_info.edgeUniqueId(i_edge);
325 return m_edge_family.findOrAllocOne(edge_unique_id, is_add);
326}
327
328/*---------------------------------------------------------------------------*/
329/*---------------------------------------------------------------------------*/
330
331template <>
332Edge OneMeshItemAdder::
333_findInternalEdge(Integer i_edge, const CellInfoProxy& cell_info, Int64 first_node, Int64 second_node, bool& is_add)
334{
335 ARCANE_UNUSED(i_edge);
336
337 const bool use_hash = m_use_hash_for_edge_and_face_unique_id;
338 FixedArray<Int64, 2> nodes;
339 Int64 edge_unique_id = NULL_ITEM_UNIQUE_ID;
340 Edge edge_internal;
341 if (use_hash) {
342 nodes[0] = first_node;
343 nodes[1] = second_node;
344 edge_unique_id = MeshUtils::generateHashUniqueId(nodes.view());
345 edge_internal = m_edge_family.itemsMap().tryFind(edge_unique_id);
346 }
347 else {
348 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
349 Node nbi = nodes_map.findItem(first_node);
350 edge_internal = ItemTools::findEdgeInNode2(nbi, first_node, second_node);
351 }
352 if (edge_internal.null()) {
353 if (!cell_info.allowBuildEdge() && !use_hash)
354 ARCANE_FATAL("On the fly edge allocation is not allowed here."
355 " You need to add edges before with IMeshModifier::addEdges()");
356 if (!use_hash)
357 edge_unique_id = m_next_edge_uid++;
358 is_add = true;
359 return m_edge_family.allocOne(edge_unique_id);
360 }
361 else {
362 is_add = false;
363 return edge_internal;
364 }
365}
366
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
386addOneCell(ItemTypeId type_id,
387 Int64 cell_uid,
388 Int32 sub_domain_id,
389 Int64ConstArrayView nodes_uid,
390 bool allow_build_face)
391{
392 CellInfoProxy cell_info_proxy(m_item_type_mng->typeFromId(type_id), cell_uid, sub_domain_id, nodes_uid, allow_build_face);
393
394 return _addOneCell(cell_info_proxy);
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
405addOneCell(const FullCellInfo& cell_info)
406{
407 return _addOneCell(cell_info);
408}
409
410/*---------------------------------------------------------------------------*/
411/*---------------------------------------------------------------------------*/
412
413ItemInternal* OneMeshItemAdder::
414addOneItem(IItemFamily* family,
415 IItemFamilyModifier* family_modifier,
416 ItemTypeId type_id,
417 Int64 item_uid,
418 Integer item_owner,
419 Integer sub_domain_id,
420 Integer nb_connected_family,
421 Int64ConstArrayView connectivity_info)
422{
423 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(), ("ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
424 bool is_alloc = true;
425 Item item = family_modifier->findOrAllocOne(item_uid, type_id, m_mesh_info, is_alloc); // don't forget to add print in the class method
426 item.mutableItemBase().setOwner(item_owner, sub_domain_id);
427 // Add connectivities if needed
428 Integer info_index = 0;
429 for (Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
430 // get connected family
431 eItemKind family_kind = static_cast<eItemKind>(connectivity_info[info_index++]); // another way ?
432 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
433 IItemFamily* connected_family = m_mesh->itemFamily(family_kind);
434 // get connectivities family -> connected_family and reverse
435 String connectivity_name = mesh::connectivityName(family, connected_family);
436 String reverse_connectivity_name = mesh::connectivityName(connected_family, family);
437 bool is_dependency = false;
438 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getStoredConnectivity(family, connected_family, connectivity_name, is_dependency);
439 IIncrementalItemConnectivity* connected_family_to_family = m_mesh->itemFamilyNetwork()->getStoredConnectivity(connected_family, family, reverse_connectivity_name);
440 // Clear connectivities for already allocated items (except dependencies since replace is used)
441 if (!is_alloc) {
442 if (!is_dependency)
443 _clearConnectivity(ItemLocalId(item), family_to_connected_family);
444 if (connected_family_to_family)
445 _clearReverseConnectivity(ItemLocalId(item), family_to_connected_family, connected_family_to_family);
446 }
447 // get connected item lids
448 Int32UniqueArray connected_item_lids(nb_connected_item);
449 connected_family->itemsUniqueIdToLocalId(connected_item_lids, connectivity_info.subView(info_index, nb_connected_item), true);
450 for (Integer connected_item_index = 0; connected_item_index < nb_connected_item; ++connected_item_index) {
451 if (family_to_connected_family) {
452 // pre-alloc are done (=> use replace) when a dependency relation ("owning relation") while not when only a relation (use add)
453 if (!is_dependency)
454 family_to_connected_family->addConnectedItem(ItemLocalId(item), ItemLocalId(connected_item_lids[connected_item_index]));
455 else
456 family_to_connected_family->replaceConnectedItem(ItemLocalId(item), connected_item_index, ItemLocalId(connected_item_lids[connected_item_index])); // does not work with face to edges...
457 }
458 if (connected_family_to_family)
459 connected_family_to_family->addConnectedItem(ItemLocalId(connected_item_lids[connected_item_index]), ItemLocalId(item));
460 }
461 info_index += nb_connected_item;
462 }
463 // debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
464 debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
465 return ItemCompatibility::_itemInternal(item);
466}
467
468/*---------------------------------------------------------------------------*/
469
470ItemInternal* OneMeshItemAdder::
471addOneItem2(IItemFamily* family,
472 IItemFamilyModifier* family_modifier,
473 ItemTypeId type_id,
474 Int64 item_uid,
475 Integer item_owner,
476 Integer sub_domain_id,
477 Integer nb_connected_family,
478 Int64ConstArrayView connectivity_info)
479{
480 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(), ("ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
481 bool is_alloc = true;
482 Item item = family_modifier->findOrAllocOne(item_uid, type_id, m_mesh_info, is_alloc); // don't forget to add print in the class method
483 item.mutableItemBase().setOwner(item_owner, sub_domain_id);
484 // Add connectivities if needed
485 Integer info_index = 0;
486 for (Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
487 // Prepare connection
488 // get connected family
489 eItemKind family_kind = static_cast<eItemKind>(connectivity_info[info_index++]); // another way ?
490 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
491 if (nb_connected_item == 0)
492 continue;
493 IItemFamily* connected_family = nullptr;
494 switch (family_kind) {
495 case IK_Particle:
496 connected_family = m_mesh->findItemFamily(family_kind, ParticleFamily::defaultFamilyName(), false, false);
497 break;
498 case IK_DoF:
499 if (family->name() == GraphDoFs::dualNodeFamilyName())
500 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::linkFamilyName(), false, false);
501 else
502 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::dualNodeFamilyName(), false, false);
503 break;
504 default:
505 connected_family = m_mesh->itemFamily(family_kind);
506 break;
507 }
508 // get connectivities family -> connected_family and reverse
509 String connectivity_name = mesh::connectivityName(family, connected_family);
510 bool is_dependency = false;
511 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getConnectivity(family, connected_family, connectivity_name, is_dependency);
512 if (!family_to_connected_family)
513 ARCANE_FATAL("Cannot find connectivity name={0}", connectivity_name);
514 bool is_deep_connectivity = m_mesh->itemFamilyNetwork()->isDeep(family_to_connected_family);
515 bool is_relation = !(is_dependency && is_deep_connectivity);
516 // Build connection
517 // get connected item lids
518 Int32UniqueArray connected_item_lids(nb_connected_item);
519 bool do_fatal = is_relation ? false : true; // for relations, connected items may not be present and will be skipped.
520 connected_family->itemsUniqueIdToLocalId(connected_item_lids, connectivity_info.subView(info_index, nb_connected_item), do_fatal);
521 // if connection is relation, connected item not necessarily present: remove absent (ie null) items
522 Integer nb_connected_item_found = nb_connected_item;
523 if (is_relation) {
524 for (Integer index = 0; index < connected_item_lids.size();) {
525 if (connected_item_lids[index] == NULL_ITEM_LOCAL_ID) {
526 connected_item_lids.remove(index);
527 --nb_connected_item_found;
528 }
529 else
530 ++index;
531 }
532 }
533 for (Integer connected_item_index = 0; connected_item_index < nb_connected_item_found; ++connected_item_index) {
534 if (family_to_connected_family) {
535 // Only strategy : check and add
536 auto connected_item_lid = ItemLocalId{ connected_item_lids[connected_item_index] };
537 if (is_relation) {
538 if (!family_to_connected_family->hasConnectedItem(ItemLocalId(item), connected_item_lid)) {
539 family_to_connected_family->addConnectedItem(ItemLocalId(item), connected_item_lid);
540 }
541 }
542 else {
543 family_to_connected_family->replaceConnectedItem(ItemLocalId(item), connected_item_index, connected_item_lid);
544 }
545 }
546 }
547 info_index += nb_connected_item;
548 }
549 if (is_alloc)
550 debug(Trace::Highest) << "[addItems] ADD_ITEM " << ItemPrinter(item) << " in " << family->name();
551 // debug(Trace::Highest) << "[addItems] DEPENDENCIES for " << family->name() << FullItemPrinter(item) ; // debug info
552 // _printRelations(item); // debug info
553 return ItemCompatibility::_itemInternal(item);
554}
555
556/*---------------------------------------------------------------------------*/
557
558void OneMeshItemAdder::
559_printRelations(ItemInternal* item)
560{
561 debug(Trace::Highest) << "[addItems] RELATIONS for " << ItemPrinter(item) << " in " << item->family()->name();
562 for (const auto& relation : m_mesh->itemFamilyNetwork()->getChildRelations(item->family())) {
563 // debug(Trace::Highest) << " Relation " << relation->name();
564 // debug(Trace::Highest) << " Relation " << relation->nbConnectedItem(ItemLocalId(item));
565 ConnectivityItemVector connected_items(relation);
566 for (const auto& connected_item : connected_items.connectedItems(ItemLocalId(item))) {
567 debug(Trace::Highest) << ItemPrinter(connected_item);
568 }
569 }
570}
571
572/*---------------------------------------------------------------------------*/
573/*---------------------------------------------------------------------------*/
574
575void OneMeshItemAdder::
576_clearConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity)
577{
578
579 ConnectivityItemVector accessor(connectivity);
580 ENUMERATE_ITEM (connected_item, accessor.connectedItems(item)) {
581 connectivity->removeConnectedItem(item, connected_item);
582 }
583}
584
585/*---------------------------------------------------------------------------*/
586/*---------------------------------------------------------------------------*/
587
588void OneMeshItemAdder::
589_clearReverseConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity, IIncrementalItemConnectivity* reverse_connectivity)
590{
591 ConnectivityItemVector accessor(connectivity);
592 ENUMERATE_ITEM (connected_item, accessor.connectedItems(item)) {
593 reverse_connectivity->removeConnectedItem(connected_item, item);
594 }
595}
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
600template <> void OneMeshItemAdder::
601_AMR_Patch(Cell new_cell, const FullCellInfo& cell_info)
602{
604 if (m_mesh->isAmrActivated()) {
605 // FIXME doit-on traiter les mailles de niveau 0
606 //comme celles de niveau superieur
607 if (cell_info.level() != 0) {
608 Integer child_rank = cell_info.whichChildAmI();
609 Int64 hParent_uid = cell_info.hParentCellUniqueId();
610 ItemTypeId cell_type = ItemTypeId::fromInteger(cell_info.typeId());
611 bool is_add;
612 Cell hParent_cell = m_cell_family.findOrAllocOne(hParent_uid, cell_type, is_add);
613 m_cell_family._addParentCellToCell(new_cell, hParent_cell);
614 m_cell_family._addChildCellToCell(hParent_cell, child_rank, new_cell);
615 }
616 }
617}
618
619template <> void OneMeshItemAdder::
620_AMR_Patch(Cell cell, const CellInfoProxy& cell_info)
621{
622 ARCANE_UNUSED(cell);
623 ARCANE_UNUSED(cell_info);
624}
625
626/*---------------------------------------------------------------------------*/
627/*---------------------------------------------------------------------------*/
633template <typename CellInfo>
635_addOneCell(const CellInfo& cell_info)
636{
637 bool is_check = arcaneIsCheck();
638
639 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
640 ItemTypeId cell_type_id = cell_type_info->itemTypeId();
641 const bool is_verbose = false;
642 if (is_verbose)
643 info() << "AddNewCell type_id=" << cell_type_id << " nb_node=" << cell_info.nbNode()
644 << " type=" << cell_type_info->typeName();
645 // Checks if the cell already exists (in which case nothing is done).
646 Cell inew_cell;
647 {
648 bool is_add; // ce flag est toujours correctement positionné via les findOrAllocOne
649 inew_cell = m_cell_family.findOrAllocOne(cell_info.uniqueId(), cell_type_id, is_add);
650 if (!is_add) {
651 if (is_check) {
652 Cell cell2(inew_cell);
653 // Verifies that the nodes match those that exist.
654 for (Integer i = 0, is = cell_info.nbNode(); i < is; ++i)
655 if (cell_info.nodeUniqueId(i) != cell2.node(i).uniqueId())
656 ARCANE_FATAL("trying to add existing cell (uid={0}) with different nodes",
657 cell_info.uniqueId());
658 }
659 return ItemCompatibility::_itemInternal(inew_cell);
660 }
661 }
662
663 Cell new_cell(inew_cell);
664
665 ++m_mesh_info.nbCell();
666
667 const MeshKind& mesh_kind = m_mesh->meshKind();
668 const bool allow_multi_dim_cell = !mesh_kind.isMonoDimension();
669 const Int32 cell_nb_face = cell_info.nbFace();
670 MutableItemBase mut_cell = new_cell.mutableItemBase();
671 if (cell_type_info->dimension() == 2 && cell_type_info->nbLocalFace() == 0)
672 mut_cell.addFlags(ItemFlags::II_HasEdgeFor1DItems);
673 mut_cell.setOwner(cell_info.owner(), m_mesh_info.rank());
674 // Vérifie la cohérence entre le type local et la maille créée.
675 if (is_check) {
676 if (cell_info.nbNode() != inew_cell.nbNode())
677 ARCANE_FATAL("Incoherent number of nodes v={0} expected={1}", inew_cell.nbNode(), cell_info.nbNode());
678 if (cell_nb_face != inew_cell.nbFace())
679 ARCANE_FATAL("Incoherent number of faces v={0} expected={1}", inew_cell.nbFace(), cell_nb_face);
680 if (!cell_type_info->isValidForCell())
681 ARCANE_FATAL("Type '{0}' is not allowed for 'Cell' (cell_uid={1})",
682 cell_type_info->typeName(), cell_info.uniqueId());
683 if (!allow_multi_dim_cell) {
684 Int32 cell_dimension = cell_type_info->dimension();
685 Int32 mesh_dimension = m_mesh->dimension();
686 if (cell_dimension >= 0 && cell_dimension != mesh_dimension)
687 ARCANE_FATAL("Incoherent dimension for cell uid={0} cell_dim={1} mesh_dim={2} type={3}",
688 cell_info.uniqueId(), cell_dimension, mesh_dimension, cell_type_info->typeName());
689 }
690 }
691
693 ItemInternalMap& nodes_map = m_node_family.itemsMap();
694
695 _addNodesToCell(inew_cell, cell_info);
696
697 if (m_mesh_builder->hasEdge()) {
698 const Int32 cell_nb_edge = cell_info.nbEdge();
699 // Adds the necessary edges.
700 for (Integer i_edge = 0; i_edge < cell_nb_edge; ++i_edge) {
701 const ItemTypeInfo::LocalEdge& le = cell_type_info->localEdge(i_edge);
702 Int64 first_node = cell_info.nodeUniqueId(le.beginNode());
703 Int64 second_node = cell_info.nodeUniqueId(le.endNode());
704 if (first_node > second_node)
705 std::swap(first_node, second_node);
706
707 bool is_add = false;
708 Edge edge_internal = _findInternalEdge(i_edge, cell_info, first_node, second_node, is_add);
709 if (is_add) {
710 if (is_verbose)
711 info() << "Create edge " << edge_internal.uniqueId() << ' ' << edge_internal.localId();
712
713 edge_internal.mutableItemBase().setOwner(cell_info.edgeOwner(i_edge), m_mesh_info.rank());
714 {
715 Node current_node = nodes_map.findItem(first_node);
716 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
717 m_node_family.addEdgeToNode(current_node, edge_internal);
718 }
719 {
720 Node current_node = nodes_map.findItem(second_node);
721 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
722 m_node_family.addEdgeToNode(current_node, edge_internal);
723 }
724 ++m_mesh_info.nbEdge();
725 }
726
727 m_cell_family.replaceEdge(ItemLocalId(new_cell), i_edge, ItemLocalId(edge_internal));
728 m_edge_family.addCellToEdge(edge_internal, inew_cell);
729 }
730 }
731
732 // Adds the necessary faces.
733 for (Integer i_face = 0; i_face < cell_nb_face; ++i_face) {
734 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
735 const Integer face_nb_node = lf.nbNode();
736 // en effet de bord, _isReorder positionne m_face_reorderer.sortedNodes();
737 const bool is_reorder = _isReorder(i_face, lf, cell_info);
738 ConstArrayView<Int64> face_sorted_nodes = m_face_reorderer.sortedNodes();
739 bool is_add = false;
740 Face face = _findInternalFace(i_face, cell_info, is_add);
741 if (is_add) {
742 // For elements of order greater than 1, faces are added to the nodes
743 // corresponding to the associated order 1 (linear) element.
744 const ItemTypeInfo* face_type_info = m_item_type_mng->typeFromId(lf.typeId());
745 const Int32 face_nb_linear_node = face_type_info->linearTypeInfo()->nbLocalNode();
746 if (is_verbose) {
747 info() << "AddFaceToCell (cell_uid=" << new_cell.uniqueId() << ": Create face (index=" << i_face
748 << ") uid=" << face.uniqueId()
749 << " lid=" << face.localId()
750 << " type=" << face_type_info->typeName()
751 << " face_nb_linear_node=" << face_nb_linear_node
752 << " sorted_nodes=" << face_sorted_nodes;
753 }
754 face.mutableItemBase().setOwner(cell_info.faceOwner(i_face), m_mesh_info.rank());
755
756 for (Integer i_node = 0; i_node < face_nb_node; ++i_node) {
757 if (is_verbose)
758 info() << "AddNodeToFace i_node=" << i_node << " uid=" << face_sorted_nodes[i_node];
759 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
760 m_face_family.replaceNode(face, i_node, current_node);
761 if (i_node < face_nb_linear_node) {
762 m_node_family.addFaceToNode(current_node, face);
763 }
764 }
765
766 if (m_mesh_builder->hasEdge()) {
767 Integer face_nb_edge = lf.nbEdge();
768 for (Integer i_edge = 0; i_edge < face_nb_edge; ++i_edge) {
769 Edge current_edge = new_cell.edge(lf.edge(i_edge));
770 m_face_family.addEdgeToFace(face, current_edge);
771 m_edge_family.addFaceToEdge(current_edge, face);
772 }
773 }
774 ++m_mesh_info.nbFace();
775 }
776 m_cell_family.replaceFace(new_cell, i_face, face);
777
779 if (m_mesh->isAmrActivated()) {
780 if (is_reorder) {
781 if (face.nbCell() == 2)
782 m_face_family.replaceFrontCellToFace(face, new_cell);
783 else
784 m_face_family.addFrontCellToFace(face, inew_cell);
785 }
786 else {
787 if (face.nbCell() == 2)
788 m_face_family.replaceBackCellToFace(face, new_cell);
789 else
790 m_face_family.addBackCellToFace(face, inew_cell);
791 }
792 }
793 else {
794 if (is_reorder) {
795 m_face_family.addFrontCellToFace(face, inew_cell);
796 }
797 else {
798 m_face_family.addBackCellToFace(face, inew_cell);
799 }
800 }
801 }
802
803 _AMR_Patch(inew_cell, cell_info);
804 return ItemCompatibility::_itemInternal(inew_cell);
805}
806
807/*---------------------------------------------------------------------------*/
808/*---------------------------------------------------------------------------*/
825addOneParentItem(const Item& item, const eItemKind submesh_kind, const bool fatal_on_existing_item)
826{
827 //bool is_check = arcaneIsCheck();
828 ItemTypeMng* itm = m_mesh->itemTypeMng();
829 eItemKind kind = item.kind();
830 ItemTypeInfo* type = itm->typeFromId(item.type());
831
832 if (item.type() == IT_Line2 && submesh_kind == IK_Cell)
833 type = itm->typeFromId(IT_CellLine2);
834 if (item.type() == IT_Vertex && submesh_kind == IK_Face)
835 type = itm->typeFromId(IT_FaceVertex);
836 ItemTypeId type_id = type->itemTypeId();
837
838 if (MeshToMeshTransposer::kindTranspose(submesh_kind, m_mesh, m_mesh->parentMesh()) != kind)
839 ARCANE_FATAL("Incompatible kind/sub-kind");
840
841 // Checks if the mesh already exists
842 bool is_add; // this flag is always correctly set via findOrAllocOne
843 Item new_item;
844
845 switch (submesh_kind) {
846 case IK_Node:
847 new_item = m_node_family.findOrAllocOne(item.uniqueId(), is_add);
848 ++m_mesh_info.nbNode();
849 break;
850 case IK_Edge:
851 new_item = m_edge_family.findOrAllocOne(item.uniqueId(), is_add);
852 ++m_mesh_info.nbEdge();
853 break;
854 case IK_Face:
855 new_item = m_face_family.findOrAllocOne(item.uniqueId(), type, is_add);
856 ++m_mesh_info.nbFace();
857 break;
858 case IK_Cell:
859 if (kind == IK_Face && !(item.toFace().isSubDomainBoundary()))
860 ARCANE_FATAL("Bad boundary face");
861 new_item = m_cell_family.findOrAllocOne(item.uniqueId(), type_id, is_add);
862 ++m_mesh_info.nbCell();
863 break;
864 default:
865 throw NotSupportedException(A_FUNCINFO, String::format("Kind {0} not supported", submesh_kind));
866 }
867
868 if (!is_add) {
869 if (fatal_on_existing_item)
870 ARCANE_FATAL("Cannot add already existing parent item in submesh");
871 else
872 return ItemCompatibility::_itemInternal(new_item);
873 }
874
875 new_item.mutableItemBase().setParent(0, item.localId());
876 new_item.mutableItemBase().setOwner(item.owner(), m_mesh_info.rank());
877
878 // Localizes these sub-items relative to the item to be inserted
879 // By default everything is 0, which also corresponds to the submesh_kind==IK_Node case
880 Integer item_nb_node = 0;
881 Integer item_nb_face = 0;
882 Integer item_nb_edge = 0;
883
884 switch (submesh_kind) {
885 case IK_Cell:
886 item_nb_face = type->nbLocalFace();
887 item_nb_edge = type->nbLocalEdge();
888 item_nb_node = type->nbLocalNode();
889 break;
890 case IK_Face:
891 item_nb_edge = type->nbLocalEdge();
892 item_nb_node = type->nbLocalNode();
893 break;
894 case IK_Edge:
895 item_nb_node = type->nbLocalNode();
896 default: // les autres sont déjà filtrés avant
897 break;
898 }
899
900 // Handling the case of edge deactivation
901 if (!m_mesh_builder->hasEdge())
902 item_nb_edge = 0;
903
904#if OLD
905 // Ne fonctionne plus si on désactive les anciennes connectivités
906 if (is_check) {
907 for (Integer z = 0; z < item_nb_face; ++z)
908 new_item->_setFace(z, NULL_ITEM_ID);
909 for (Integer z = 0; z < item_nb_edge; ++z)
910 new_item->_setEdge(z, NULL_ITEM_ID);
911 for (Integer z = 0; z < item_nb_node; ++z)
912 new_item->_setNode(z, NULL_ITEM_ID);
913 }
914#endif
915
917 DynamicMeshKindInfos::ItemInternalMap& nodes_map = m_mesh->nodesMap();
918 auto* parent_mesh = ARCANE_CHECK_POINTER(dynamic_cast<DynamicMesh*>(m_mesh->parentMesh()));
919 DynamicMeshKindInfos::ItemInternalMap& parent_nodes_map = parent_mesh->nodesMap();
920
921 // Processing new nodes
922
923 // The vertices are used in the item order except for surface submeshes.
924 const bool direct_node_order =
925 !(submesh_kind == IK_Cell && kind == IK_Face && !(item.toFace().isSubDomainBoundaryOutside()));
926
927 Int64UniqueArray nodes_uid(item_nb_node, NULL_ITEM_UNIQUE_ID);
928 for (Integer i_node = 0; i_node < item_nb_node; ++i_node) {
929 Item parent_item;
930 if (type->typeId() == IT_FaceVertex)
931 parent_item = item;
932 else {
933 Int32 idx = ((direct_node_order) ? i_node : (item_nb_node - 1 - i_node));
934 parent_item = item.toItemWithNodes().node(idx);
935 }
936 Int64 new_node_uid = nodes_uid[i_node] = parent_item.uniqueId();
937 ItemInternal* node_internal = m_node_family.findOrAllocOne(new_node_uid, is_add);
938 if (is_add) {
939#ifdef ARCANE_DEBUG_DYNAMIC_MESH
940 info() << "Création node " << new_node_uid << ' '
941 << node_internal->uniqueId() << ' ' << node_internal->localId();
942#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
943 node_internal->setParent(0, parent_item.localId());
944 node_internal->setOwner(parent_item.owner(), m_mesh_info.rank());
945 ++m_mesh_info.nbNode();
946 }
947
948 // Connecting the item to the nodes
949 ItemLocalId node_lid(node_internal);
950 ItemLocalId new_item_lid(new_item);
951 switch (submesh_kind) {
952 case IK_Cell:
953 m_cell_family.replaceNode(new_item_lid, i_node, node_lid);
954 m_node_family.addCellToNode(node_internal, new_item.toCell());
955 break;
956 case IK_Face:
957 m_face_family.replaceNode(new_item_lid, i_node, node_lid);
958 m_node_family.addFaceToNode(node_internal, new_item.toFace());
959 break;
960 case IK_Edge:
961 m_edge_family.replaceNode(new_item_lid, i_node, node_lid);
962 m_node_family.addEdgeToNode(node_internal, new_item.toEdge());
963 break;
964 default: // les autres sont déjà filtrés avant
965 break;
966 }
967 }
968
969 // Processing new edges (the has_edge filter is already taken into account in item_nb_edge)
970 for (Integer i_edge = 0; i_edge < item_nb_edge; ++i_edge) {
971 const ItemTypeInfo::LocalEdge& le = type->localEdge(i_edge);
972
973 Int64 first_node = nodes_uid[le.beginNode()];
974 Int64 second_node = nodes_uid[le.endNode()];
975 if (first_node > second_node)
976 std::swap(first_node, second_node);
977
978 Edge parent_item = item.itemBase().edgeBase(i_edge);
979 if (parent_item.null())
980 ARCANE_FATAL("Cannot find parent edge");
981
982 Int64 new_edge_uid = parent_item.uniqueId();
983
984 ItemInternal* edge_internal = m_edge_family.findOrAllocOne(new_edge_uid, is_add);
985 if (is_add) {
986#ifdef ARCANE_DEBUG_DYNAMIC_MESH
987 info() << "Création edge " << new_edge_uid << ' '
988 << edge_internal->uniqueId() << ' ' << edge_internal->localId();
989#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
990 edge_internal->setParent(0, parent_item.localId());
991 edge_internal->setOwner(parent_item.owner(), m_mesh_info.rank());
992
993 {
994 Node current_node = nodes_map.findItem(first_node);
995 m_edge_family.replaceNode(ItemLocalId(edge_internal), 0, current_node);
996 m_node_family.addEdgeToNode(current_node, edge_internal);
997 }
998 {
999 Node current_node = nodes_map.findItem(second_node);
1000 m_edge_family.replaceNode(ItemLocalId(edge_internal), 1, current_node);
1001 m_node_family.addEdgeToNode(current_node, edge_internal);
1002 }
1003 ++m_mesh_info.nbEdge();
1004 }
1005
1006 // Connecting the item to the nodes
1007 switch (submesh_kind) {
1008 case IK_Cell: {
1009 m_cell_family.replaceEdge(ItemLocalId(new_item), i_edge, ItemLocalId(edge_internal));
1010 m_edge_family.addCellToEdge(edge_internal, new_item.toCell());
1011 } break;
1012 case IK_Face: {
1013 m_face_family.replaceEdge(ItemLocalId(new_item), i_edge, ItemLocalId(edge_internal));
1014 m_edge_family.addFaceToEdge(edge_internal, new_item.toFace());
1015 } break;
1016 default: // les autres sont déjà filtrés avant
1017 break;
1018 }
1019 }
1020
1021 // Processing new faces
1022 // item_nb_face already materializes that this context only occurs with submesh_kind==IK_Cell
1023 for (Integer i_face = 0; i_face < item_nb_face; ++i_face) {
1024 const ItemTypeInfo::LocalFace& lf = type->localFace(i_face);
1025 Integer face_nb_node = lf.nbNode();
1026
1027 m_work_face_orig_nodes_uid.resize(face_nb_node);
1028 for (Integer z = 0; z < face_nb_node; ++z)
1029 m_work_face_orig_nodes_uid[z] = nodes_uid[lf.node(z)];
1030 bool is_reorder = false;
1031 if (m_mesh->dimension() == 1) { // is 1d mesh
1032 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1033 }
1034 else {
1035 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1036 }
1037 ConstArrayView<Int64> face_sorted_nodes(m_face_reorderer.sortedNodes());
1038 // find parent item
1039 Item parent_item;
1040 if (kind == IK_Cell) {
1041 parent_item = item.toCell().face(i_face);
1042 }
1043 else if (kind == IK_Face) {
1044 if (m_mesh->dimension() == 1) { // is 1d mesh
1045 parent_item = parent_nodes_map.findItem(face_sorted_nodes[0]);
1046 }
1047 else {
1048 // Algo sans CT_FaceToEdge
1049 Int64 first_node = face_sorted_nodes[0];
1050 Int64 second_node = face_sorted_nodes[1];
1051 if (first_node > second_node)
1052 std::swap(first_node, second_node);
1053 Node nbi = parent_nodes_map.findItem(first_node);
1054 parent_item = ItemTools::findEdgeInNode2(nbi, first_node, second_node);
1055 }
1056 }
1057
1058 if (parent_item.null())
1059 ARCANE_FATAL("Cannot find parent face");
1060 Int64 new_face_uid = parent_item.uniqueId();
1061 ItemTypeInfo* face_type = itm->typeFromId(lf.typeId());
1062
1063 ItemInternal* face_internal = m_face_family.findOrAllocOne(new_face_uid, face_type, is_add);
1064 if (is_add) {
1065#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1066 info() << "Création face " << new_face_uid << ' '
1067 << face_internal->uniqueId() << ' ' << face_internal->localId();
1068#endif /* ARCANE_DEBUG_DYNAMIC_MESH */
1069 face_internal->setParent(0, parent_item.localId());
1070 face_internal->setOwner(parent_item.owner(), m_mesh_info.rank());
1071
1072 for (Integer i_node = 0; i_node < face_nb_node; ++i_node) {
1073 Node current_node = nodes_map.findItem(face_sorted_nodes[i_node]);
1074 m_face_family.replaceNode(ItemLocalId(face_internal), i_node, current_node);
1075 m_node_family.addFaceToNode(current_node, face_internal);
1076 }
1077
1078 if (m_mesh_builder->hasEdge()) {
1079 Integer face_nb_edge = lf.nbEdge();
1080 for (Integer i_edge = 0; i_edge < face_nb_edge; ++i_edge) {
1081 Int32 edge_idx = lf.edge(i_edge);
1082 Edge current_edge = new_item.itemBase().edgeBase(edge_idx);
1083 m_face_family.addEdgeToFace(face_internal, current_edge);
1084 m_edge_family.addFaceToEdge(current_edge, face_internal);
1085 }
1086 }
1087 ++m_mesh_info.nbFace();
1088 }
1089 m_cell_family.replaceFace(ItemLocalId(new_item), i_face, ItemLocalId(face_internal));
1090 if (is_reorder) {
1091 m_face_family.addFrontCellToFace(face_internal, new_item.toCell());
1092 }
1093 else {
1094 m_face_family.addBackCellToFace(face_internal, new_item.toCell());
1095 }
1096 }
1097
1098 return ItemCompatibility::_itemInternal(new_item);
1099}
1100
1101/*---------------------------------------------------------------------------*/
1102/*---------------------------------------------------------------------------*/
1106template <typename CellInfo>
1108_addNodesToCell(Cell cell, const CellInfo& cell_info)
1109{
1110 Integer cell_nb_node = cell_info.nbNode();
1111
1112 // Adds new nodes if necessary
1113 for (Integer i_node = 0; i_node < cell_nb_node; ++i_node) {
1114 Int64 node_unique_id = cell_info.nodeUniqueId(i_node);
1115 bool is_add = false;
1116 ItemInternal* node_internal = m_node_family.findOrAllocOne(node_unique_id, is_add);
1117 if (is_add) {
1118 ++m_mesh_info.nbNode();
1119 node_internal->setOwner(cell_info.nodeOwner(i_node), m_mesh_info.rank());
1120 }
1121 m_node_family.addCellToNode(node_internal, cell);
1122 m_cell_family.replaceNode(cell, i_node, ItemLocalId(node_internal));
1123 }
1124}
1125
1126/*---------------------------------------------------------------------------*/
1127/*---------------------------------------------------------------------------*/
1128
1129template <typename CellInfo>
1130bool OneMeshItemAdder::
1131_isReorder(Integer i_face, const ItemTypeInfo::LocalFace& lf, const CellInfo& cell_info)
1132{
1133 const Integer face_nb_node = lf.nbNode();
1134 m_work_face_orig_nodes_uid.resize(face_nb_node);
1135 for (Integer i_node = 0; i_node < face_nb_node; ++i_node)
1136 m_work_face_orig_nodes_uid[i_node] = cell_info.nodeUniqueId(lf.node(i_node));
1137 bool is_reorder = false;
1138 if (m_mesh->dimension() == 1) { // is 1d mesh
1139 is_reorder = m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1140 }
1141 else {
1142 is_reorder = m_face_reorderer.reorder(ItemTypeId::fromInteger(lf.typeId()), m_work_face_orig_nodes_uid);
1143 }
1144
1145 return is_reorder;
1146}
1147
1148/*---------------------------------------------------------------------------*/
1149/*---------------------------------------------------------------------------*/
1150
1154{
1155 m_next_face_uid = 0;
1156 m_next_edge_uid = 0;
1157 m_mesh_info.reset();
1158}
1159
1160/*---------------------------------------------------------------------------*/
1161/*---------------------------------------------------------------------------*/
1162
1165{
1166 if (m_next_face_uid != 0 || m_next_edge_uid != 0)
1167 ARCANE_FATAL("Can not call this method when edge or face are already created");
1169 info() << "Is Generate Edge and Face uniqueId() from Nodes=" << m_use_hash_for_edge_and_face_unique_id;
1170}
1171
1172/*---------------------------------------------------------------------------*/
1173/*---------------------------------------------------------------------------*/
1174
1175} // End namespace Arcane::mesh
1176
1177/*---------------------------------------------------------------------------*/
1178/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
Fonctions utilitaires sur le maillage.
bool reorderNodesOfFace(Int64ConstArrayView before_ids, Int64ArrayView after_ids)
Réordonne les noeuds d'une face.
Int64 generateHashUniqueId(SmallSpan< const Int64 > nodes_unique_id)
Génère un identifiant unique à partir d'une liste d'identifiants de noeuds.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
Maille d'un maillage.
Definition Item.h:1214
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1295
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1292
Edge edge(Int32 i) const
i-ème arête de la maille
Definition Item.h:1310
Vue constante d'un tableau de type T.
constexpr ConstArrayView< T > subView(Integer abegin, Integer asize) const noexcept
Sous-vue (constante) à partir de l'élément abegin et contenant asize éléments.
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
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2).
Definition Item.h:1042
bool isSubDomainBoundary() const
Indique si la face est au bord du sous-domaine (i.e nbCell()==1).
Definition Item.h:1061
Interface pour gérer une connectivité incrémentale.
virtual void replaceConnectedItem(ItemLocalId source_item, Integer index, ItemLocalId target_local_id)=0
Remplace l'entité d'index index de source_item par l'entité de localId() target_local_id.
virtual void addConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id)=0
Ajoute l'entité de localId() target_local_id à la connectivité de source_item.
Interface de modification d'une famille.
virtual IIncrementalItemConnectivity * getStoredConnectivity(IItemFamily *source_family, IItemFamily *target_family, const String &name)=0
Retourne, si elle est associée à un stockage, la connectivité entre les familles source_family et tar...
Interface d'une famille d'entités.
Definition IItemFamily.h:84
virtual String name() const =0
Nom de la famille.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converti un tableau de numéros uniques en numéros locaux.
ItemUniqueId uniqueId() const
Numéro unique de l'entité
ItemTypeInfo * typeInfo() const
Type de l'entité.
Int32 localId() const
Numéro local (au sous-domaine) de l'entité
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
Type d'une entité (Item).
Definition ItemTypeId.h:32
static ItemTypeId fromInteger(Int64 v)
Créé une instance à partir d'un entier.
Informations locales sur une arête d'une maille.
Integer endNode() const
Indice local à la maille du sommet extrémité de l'arête.
Integer beginNode() const
Indice local à la maille du sommet origine de l'arête.
Informations locales sur une face d'une maille.
Integer node(Integer i) const
Indice locale dans la maille du i-ème noeud de la face.
Integer nbEdge() const
Nombre d'arête de la face.
Integer typeId() const
Type de l'entité face.
Integer edge(Integer i) const
Arête de la face.
Integer nbNode() const
Nombre de noeuds de la face.
Infos sur un type d'entité du maillage.
LocalEdge localEdge(Integer id) const
Connectivité locale de la i-ème arête de la maille.
LocalFace localFace(Integer id) const
Connectivité locale de la i-ème face de la maille.
const ItemTypeInfo * linearTypeInfo() const
Type de l'élément linéaire correspondant.
Int16 dimension() const
Dimension de l'élément (<0 si inconnu).
Integer nbLocalNode() const
Nombre de noeuds de l'entité
String typeName() const
Nom du type.
Integer nbLocalFace() const
Nombre de faces de l'entité
bool isValidForCell() const
Indique si le type est valide pour créér une maille (Cell).
ItemTypeId itemTypeId() const
Numéro du type.
Gestionnaire des types d'entités d'un maillage.
Definition ItemTypeMng.h:65
ItemTypeInfo * typeFromId(Integer id) const
Type correspondant au numéro id.
Elément de maillage s'appuyant sur des noeuds (Edge,Face,Cell).
Definition Item.h:736
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:791
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
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
Edge toEdge() const
Converti l'entité en le genre Edge.
Definition Item.h:1688
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Definition Item.h:238
ItemWithNodes toItemWithNodes() const
Converti l'entité en le genre ItemWithNodes.
Definition Item.h:1674
Cell toCell() const
Converti l'entité en le genre Cell.
Definition Item.h:1702
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
Face toFace() const
Converti l'entité en le genre Edge.
Definition Item.h:1695
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:369
constexpr eItemKind kind() const
Genre de l'entité
Definition Item.h:250
Int16 type() const
Type de l'entité
Definition Item.h:241
Caractéristiques d'un maillage.
Definition MeshKind.h:111
bool isMonoDimension() const
Vrai si la structure du maillage est eMeshCellDimensionKind::MonoDimension.
Definition MeshKind.h:120
static eItemKind kindTranspose(eItemKind kindA, IMesh *meshA, IMesh *meshB)
Transpose le genre kindA du maillage meshA en le genre associé dans meshB.
Méthodes permettant de modifier ItemBase.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
void setParent(Int32 aindex, Int32 parent_local_id)
Positionne le i-ème parent (actuellement aindex doit valoir 0).
void addFlags(Int32 added_flags)
Ajoute les flags added_flags à ceux de l'entité
Noeud d'un maillage.
Definition Item.h:582
Exception lorsqu'une opération n'est pas supportée.
Chaîne de caractères unicode.
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.
ITraceMng * traceMng() const
Gestionnaire de trace.
Implementation of a mesh.
Definition DynamicMesh.h:98
IItemFamily * itemFamily(eItemKind ik) override
Retourne la famille d'entité de type ik.
Integer dimension() override
Dimension du maillage (1D, 2D ou 3D).
IItemFamilyNetwork * itemFamilyNetwork() override
Interface du réseau de familles (familles connectées).
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Retrieves or allocates a unique numbered edge uid and of type type.Generic item addition.
void replaceNode(ItemLocalId edge, Integer index, ItemLocalId node)
Replaces the node at index index of the edge edge with * that of localId() node_lid.
Info to create/serialize a mesh knowing the uniqueId() and owner() of all these sub-entities (cells,...
Integer level() const
AMR.
Associative array of ItemInternal.
impl::ItemBase findItem(Int64 uid) const
Returns the unique ID entity uid.
static Edge findEdgeInNode2(Node node, Int64 begin_node, Int64 end_node)
Definition ItemTools.cc:73
static Face findFaceInNode2(Node node, Integer face_type_id, Int64ConstArrayView face_nodes_uid)
Definition ItemTools.cc:44
Int32 rank() const
Number of this subdomain.
Definition MeshInfos.h:54
Integer & nbEdge()
Number of edges in the mesh.
Definition MeshInfos.h:61
Integer & nbNode()
Number of nodes in the mesh.
Definition MeshInfos.h:57
void _checkSameItemCoherency(ItemWithNodes item, ConstArrayView< Int64 > nodes_uid)
Checks the coherence of nodes for an already added item.
void _addNodesToCell(Cell cell, const CellInfo &cell_info)
Adds the nodes nodes_uid to the mesh cell.
NodesOfItemReorderer m_face_reorderer
Work arrays.
ItemInternal * _addOneCell(const CellInfo &cell_info)
Adds a cell.
ItemInternal * addOneCell(ItemTypeId type_id, Int64 cell_uid, Int32 sub_domain_id, Int64ConstArrayView nodes_uid, bool allow_build_face)
Adds a cell.
MeshInfos m_mesh_info
General information about the mesh (sub-domain number, number of items...).
Int64 _checkGenerateFaceUniqueId(Int64 uid, ConstArrayView< Int64 > nodes_uid)
Generates a uniqueId() for the face if uid is null.
Int64 m_next_edge_uid
Next uniqueId() number used for generating edges.
void setUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId(bool v)
Positions the uniqueId() numbering mechanism.
void resetAfterDeallocate()
Resets the structures to allow for re-allocation.
bool m_use_hash_for_edge_and_face_unique_id
If true, generates face uniqueIds from node uniqueIds.
Int64 m_next_face_uid
Next uniqueId() number used for generating faces.
ItemInternal * addOneParentItem(const Item &item, const eItemKind submesh_kind, const bool fatal_on_existing_item=true)
Adds a parent item.
ItemInternal * addOneFace(ItemTypeId type_id, Int64 face_uid, Int32 owner_rank, Int64ConstArrayView nodes_uid)
Adds a face.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
Definition Misc.cc:68
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.
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.
Definition UtilsTypes.h:480
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:341
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_DoF
Entité de maillage de genre degre de liberte.
@ IK_Edge
Entité de maillage de genre arête.
std::int32_t Int32
Type entier signé sur 32 bits.