Arcane  4.2.3.0
Developer documentation
Loading...
Searching...
No Matches
FaceFamily.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/* FaceFamily.cc (C) 2000-2025 */
9/* */
10/* Face family. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/FaceFamily.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/NotImplementedException.h"
18#include "arcane/utils/String.h"
19#include "arcane/utils/OStringStream.h"
20
21#include "arcane/mesh/NodeFamily.h"
22#include "arcane/mesh/EdgeFamily.h"
23#include "arcane/mesh/IncrementalItemConnectivity.h"
24#include "arcane/mesh/CompactIncrementalItemConnectivity.h"
25#include "arcane/mesh/ItemConnectivitySelector.h"
26#include "arcane/mesh/AbstractItemFamilyTopologyModifier.h"
27#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
28#include "arcane/mesh/NewWithLegacyConnectivity.h"
29#include "arcane/mesh/FaceReorienter.h"
30
31#include "arcane/core/IMesh.h"
32#include "arcane/core/ITiedInterface.h"
33#include "arcane/core/TiedFace.h"
35#include "arcane/core/ItemPrinter.h"
36#include "arcane/core/Connectivity.h"
37
39#include "arcane/core/GeometricUtilities.h"
40#include "arcane/core/SharedVariable.h"
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45namespace Arcane::mesh
46{
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
52: public AbstractItemFamilyTopologyModifier
53{
54 public:
55
56 explicit TopologyModifier(FaceFamily* f)
57 : AbstractItemFamilyTopologyModifier(f)
58 , m_true_family(f)
59 {}
60 void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
61 {
62 m_true_family->replaceNode(item_lid, index, new_lid);
63 }
64 void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
65 {
66 m_true_family->replaceEdge(item_lid, index, new_lid);
67 }
68 void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
69 {
70 m_true_family->replaceFace(item_lid, index, new_lid);
71 }
72 void replaceCell(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
73 {
74 m_true_family->replaceCell(item_lid, index, new_lid);
75 }
76 void setBackAndFrontCells(FaceLocalId face_lid, CellLocalId back_cell_lid,
77 CellLocalId front_cell_lid) override
78 {
79 Face face(m_true_family->_itemInternal(face_lid));
80 m_true_family->setBackAndFrontCells(face, back_cell_lid, front_cell_lid);
81 }
82
83 private:
84
85 FaceFamily* m_true_family = nullptr;
86};
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91FaceFamily::
92FaceFamily(IMesh* mesh, const String& name)
93: ItemFamily(mesh, IK_Face, name)
94{
95 _setTopologyModifier(new TopologyModifier(this));
96}
97
98/*---------------------------------------------------------------------------*/
99/*---------------------------------------------------------------------------*/
100
101FaceFamily::
102~FaceFamily()
103{
104}
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108
109void FaceFamily::
110build()
111{
112 ItemFamily::build();
113
114 m_node_family = ARCANE_CHECK_POINTER(dynamic_cast<NodeFamily*>(m_mesh->nodeFamily()));
115 m_edge_family = ARCANE_CHECK_POINTER(dynamic_cast<EdgeFamily*>(m_mesh->edgeFamily()));
116
117 if (m_mesh->useMeshItemFamilyDependencies()) // temporary to fill legacy, even with family dependencies
118 {
119 m_node_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, NodeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this, mesh()->nodeFamily(), connectivityName(this, mesh()->nodeFamily())));
120 m_edge_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, EdgeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this, mesh()->edgeFamily(), connectivityName(this, mesh()->edgeFamily())));
121 m_face_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, FaceFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this, mesh()->faceFamily(), connectivityName(this, mesh()->faceFamily())));
122 m_cell_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, CellFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this, mesh()->cellFamily(), connectivityName(this, mesh()->cellFamily())));
123 }
124 else {
125 m_node_connectivity = new NodeConnectivity(this, mesh()->nodeFamily(), "FaceNode");
126 m_edge_connectivity = new EdgeConnectivity(this, mesh()->edgeFamily(), "FaceEdge");
127 m_face_connectivity = new FaceConnectivity(this, mesh()->faceFamily(), "FaceFace");
128 m_cell_connectivity = new CellConnectivity(this, mesh()->cellFamily(), "FaceCell");
129 }
130 m_hparent_connectivity = new HParentConnectivity(this, this, "HParentFace");
131 m_hchild_connectivity = new HChildConnectivity(this, this, "HChildFace");
132
133 _addConnectivitySelector(m_node_connectivity);
134 _addConnectivitySelector(m_edge_connectivity);
135 _addConnectivitySelector(m_face_connectivity);
136 _addConnectivitySelector(m_cell_connectivity);
137 _addConnectivitySelector(m_hparent_connectivity);
138 _addConnectivitySelector(m_hchild_connectivity);
139
140 _buildConnectivitySelectors();
141}
142
143/*---------------------------------------------------------------------------*/
144/*---------------------------------------------------------------------------*/
145
146inline void FaceFamily::
147_createOne(ItemInternal* item, Int64 uid, ItemTypeInfo* type)
148{
149 m_item_internal_list->faces = _itemsInternal();
150 _allocateInfos(item, uid, type);
151 auto nc = m_node_connectivity->trueCustomConnectivity();
152 if (nc)
153 nc->addConnectedItems(ItemLocalId(item), type->nbLocalNode());
154}
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158
159inline void FaceFamily::
160_createOne(ItemInternal* item, Int64 uid, ItemTypeId type_id)
161{
162 _createOne(item, uid, _itemTypeMng()->typeFromId(type_id));
163}
164
165/*---------------------------------------------------------------------------*/
166/*---------------------------------------------------------------------------*/
175allocOne(Int64 uid, ItemTypeId type_id, MeshInfos& mesh_info)
176{
177 ++mesh_info.nbFace();
178 return allocOne(uid, type_id);
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
188{
189 ItemInternal* item = _allocOne(uid);
190 _createOne(item, uid, type);
191 return item;
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
207findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos& mesh_info, bool& is_alloc)
208{
209 auto face = findOrAllocOne(uid, type_id, is_alloc);
210 if (is_alloc)
211 ++mesh_info.nbFace();
212 return face;
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
224findOrAllocOne(Int64 uid, ItemTypeInfo* type, bool& is_alloc)
225{
226 ItemInternal* item = _findOrAllocOne(uid, is_alloc);
227 if (is_alloc) {
228 _createOne(item, uid, type);
229 }
230 return item;
231}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
237allocOne(Int64 uid, ItemTypeId type_id)
238{
239 ItemInternal* item = _allocOne(uid);
240 _createOne(item, uid, type_id);
241 return item;
242}
243
244/*---------------------------------------------------------------------------*/
245/*---------------------------------------------------------------------------*/
246
248findOrAllocOne(Int64 uid, ItemTypeId type_id, bool& is_alloc)
249{
250 ItemInternal* item = _findOrAllocOne(uid, is_alloc);
251 if (is_alloc) {
252 _createOne(item, uid, type_id);
253 }
254 return item;
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
261nodeConnectivity() const
262{
263 return m_node_connectivity->trueCustomConnectivity();
264}
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
269IncrementalItemConnectivity* FaceFamily::
270edgeConnectivity() const
271{
272 return m_edge_connectivity->trueCustomConnectivity();
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
278IncrementalItemConnectivity* FaceFamily::
279cellConnectivity() const
280{
281 return m_cell_connectivity->trueCustomConnectivity();
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
289{
290 const Int32 nb_face = back_cells.size();
291 IncrementalItemConnectivity* c = m_cell_connectivity->trueCustomConnectivity();
292 const Int32 prealloc = c->preAllocatedSize();
293 const Int32 block = (prealloc > 0) ? prealloc : 2;
294 UniqueArray<Int32> index(nb_face);
295 UniqueArray<Int32> nb_item(nb_face);
297 list.reserve(static_cast<Int64>(nb_face + 1) * block);
298 list.resize(block);
299 list.fill(NULL_ITEM_LOCAL_ID);
300 ItemInternalArrayView faces = itemsInternal();
301 for (Int32 i = 0; i < nb_face; ++i) {
302 const Int32 back = back_cells[i];
303 const Int32 front = front_cells[i];
304 // The back cell is always the first.
305 Int32 n = 0;
306 const Int32 pos = list.size();
307 if (back != NULL_ITEM_LOCAL_ID) {
308 list.add(back);
309 ++n;
310 }
311 if (front != NULL_ITEM_LOCAL_ID) {
312 list.add(front);
313 ++n;
314 }
315 if (n == 0) {
316 index[i] = 0;
317 nb_item[i] = 0;
318 }
319 else {
320 const Int32 alloc = block * ((n + block - 1) / block);
321 for (Int32 z = n; z < alloc; ++z)
322 list.add(NULL_ITEM_LOCAL_ID);
323 index[i] = pos;
324 nb_item[i] = n;
325 }
326 faces[i]->_setFaceBackAndFrontCells(back, front);
327 }
328 c->setBulkConnectivity(nb_item, index, list);
329}
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
333
336{
337 m_item_internal_list->faces = _itemsInternal();
338 _allocateInfosBulk(uids, type, owner, lids);
339 m_item_internal_list->faces = _itemsInternal();
340}
341
342/*---------------------------------------------------------------------------*/
343/*---------------------------------------------------------------------------*/
344
345void FaceFamily::
346preAllocate(Integer nb_item)
347{
348 if (!m_has_face)
349 return;
350 // We do not pre-allocate by default because we do not want to pre-allocate
351 // for face->face connectivity because it is only used
352 // if there are TiedInterfaces and this is not frequent.
353 // So we explicitly pre-allocate the connectivities we want.
354 this->_preAllocate(nb_item, false);
355 m_node_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item, true);
356 if (Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_HasEdge))
357 m_edge_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item, true);
358 m_cell_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item, true);
359}
360
361/*---------------------------------------------------------------------------*/
362/*---------------------------------------------------------------------------*/
363
366{
367 debug() << "Creating the list of ghosts faces";
369}
370
371/*---------------------------------------------------------------------------*/
372/*---------------------------------------------------------------------------*/
379{
380 m_node_connectivity->replaceItem(face, index, node);
381}
382
383/*---------------------------------------------------------------------------*/
384/*---------------------------------------------------------------------------*/
391{
392 m_edge_connectivity->replaceItem(face, index, edge);
393}
394
395/*---------------------------------------------------------------------------*/
396/*---------------------------------------------------------------------------*/
402replaceFace(ItemLocalId face, Integer index, ItemLocalId face2)
403{
404 m_face_connectivity->replaceItem(face, index, face2);
405}
406
407/*---------------------------------------------------------------------------*/
408/*---------------------------------------------------------------------------*/
415{
416 m_cell_connectivity->replaceItem(face, index, cell);
417}
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
430setBackAndFrontCells(Face face, Int32 iback_cell_lid, Int32 ifront_cell_lid)
431{
432 face.mutableItemBase()._setFaceBackAndFrontCells(iback_cell_lid, ifront_cell_lid);
433 ItemLocalId back_cell_lid(iback_cell_lid);
434 ItemLocalId front_cell_lid(ifront_cell_lid);
435 auto c = m_cell_connectivity->trueCustomConnectivity();
436 if (c) {
437 ItemLocalId face_lid(face.localId());
438 // Removes all connected cells.
439 // TODO: optimize by not deleting if it is not necessary to avoid
440 // reallocations.
441 c->removeConnectedItems(face_lid);
442 if (front_cell_lid == NULL_ITEM_LOCAL_ID) {
443 if (back_cell_lid != NULL_ITEM_LOCAL_ID) {
444 // Only the back_cell or no cell remains.
445 c->IncrementalItemConnectivity::addConnectedItem(face_lid, back_cell_lid); // add the class name for the case of Face to Cell connectivity. The class is overridden to handle family dependencies but the base method must be called here.
446 }
447 // Here no cell remains, but since we deleted everything there is nothing
448 // to do.
449 }
450 else if (back_cell_lid == NULL_ITEM_LOCAL_ID) {
451 // Only the front cell remains
452 c->IncrementalItemConnectivity::addConnectedItem(face_lid, front_cell_lid);
453 }
454 else {
455 // There are two connected cells. The back_cell is always the first.
456 c->IncrementalItemConnectivity::addConnectedItem(face_lid, back_cell_lid);
457 c->IncrementalItemConnectivity::addConnectedItem(face_lid, front_cell_lid);
458 }
459 }
460}
461
462/*---------------------------------------------------------------------------*/
463/*---------------------------------------------------------------------------*/
464
466addBackCellToFace(Face face, Cell new_cell)
467{
468 _checkValidSourceTargetItems(face, new_cell);
469
470 Integer nb_cell = face.nbCell();
471
472 // SDP: the following tests are incompatible with refinement
473 // by layers
475 Cell current_cell = face.backCell();
477 ARCANE_FATAL("Face already having a back cell."
478 " This is most probably due to the fact that the face"
479 " is connected to a reverse cell with a negative volume."
480 " Face={0}. new_cell={1} current_cell={2}",
481 FullItemPrinter(face),
482 FullItemPrinter(new_cell), FullItemPrinter(current_cell));
483 }
484 }
485
486 if (nb_cell >= 2)
487 ARCANE_FATAL("face '{0}' already has two cells", FullItemPrinter(face));
488
489 _updateSharedInfo();
490
491 // If we already have a cell, it is the front cell.
492 Int32 front_cell_lid = (nb_cell == 1) ? face.cellId(0) : NULL_ITEM_LOCAL_ID;
493 setBackAndFrontCells(face, new_cell.localId(), front_cell_lid);
494}
495
496/*---------------------------------------------------------------------------*/
497/*---------------------------------------------------------------------------*/
498
500addFrontCellToFace(Face face, Cell new_cell)
501{
502 _checkValidSourceTargetItems(face, new_cell);
503
504 Integer nb_cell = face.nbCell();
505
506 // SDP: the following tests are incompatible with refinement
507 // by layers
509 Cell current_cell = face.frontCell();
511 ARCANE_FATAL("Face already having a front cell."
512 " This is most probably due to the fact that the face"
513 " is connected to a reverse cell with a negative volume."
514 " Face={0}. new_cell={1} current_cell={2}",
515 FullItemPrinter(face),
516 FullItemPrinter(new_cell), FullItemPrinter(current_cell));
517 }
518 }
519
520 if (nb_cell >= 2)
521 ARCANE_FATAL("face '{0}' already has two cells", FullItemPrinter(face));
522
523 _updateSharedInfo();
524
525 // If we already have a cell, it is the back cell.
526 Int32 back_cell_lid = (nb_cell == 1) ? face.cellId(0) : NULL_ITEM_LOCAL_ID;
527 setBackAndFrontCells(face, back_cell_lid, new_cell.localId());
528}
529
530/*---------------------------------------------------------------------------*/
531/*---------------------------------------------------------------------------*/
532
535{
536 ARCANE_ASSERT((face.nbCell() == 2), ("Face should have back and front cells"));
537
538 Cell current_cell = face.backCell();
539 _topologyModifier()->findAndReplaceCell(face, current_cell, new_cell);
540}
541
542/*---------------------------------------------------------------------------*/
543/*---------------------------------------------------------------------------*/
544
545void FaceFamily::
546replaceFrontCellToFace(Face face, ItemLocalId new_cell)
547{
548 ARCANE_ASSERT((face.nbCell() == 2), ("Face should have back and front cells"));
549
550 Cell current_cell = face.frontCell();
551 _topologyModifier()->findAndReplaceCell(face, current_cell, new_cell);
552}
553
554/*---------------------------------------------------------------------------*/
555/*---------------------------------------------------------------------------*/
556
557void FaceFamily::
558addBackFrontCellsFromParentFace(Face subface, Face face)
559{
560 Cell fcell = face.frontCell();
561 Cell bcell = face.backCell();
562
563 if (subface.hasFlags(ItemFlags::II_HasBackCell)) {
564 if (fcell.isActive())
565 addFrontCellToFace(subface, face.frontCell());
566 else if (bcell.isActive())
567 addFrontCellToFace(subface, face.backCell());
568 }
569 else if (subface.hasFlags(ItemFlags::II_HasFrontCell)) {
570 if (bcell.isActive())
571 addBackCellToFace(subface, face.backCell());
572 else if (fcell.isActive())
573 addBackCellToFace(subface, face.frontCell());
574 }
575 ARCANE_ASSERT((subface.backCell() != subface.frontCell()), ("back front cells error"));
576}
577
578/*---------------------------------------------------------------------------*/
579/*---------------------------------------------------------------------------*/
580
581void FaceFamily::
582replaceBackFrontCellsFromParentFace(Cell subcell, Face subface,
583 Cell cell, Face face)
584{
585 Cell fscell = subface.frontCell();
586 Cell bscell = subface.backCell();
587 Cell fcell = face.frontCell();
588 Cell bcell = face.backCell();
589 if (fscell.localId() == subcell.localId()) {
590 if (fcell.localId() == cell.localId()) {
591 if (bcell.level() > bscell.level()) {
592 replaceBackCellToFace(subface, bcell);
593 }
594 }
595 else {
596 if (fcell.level() > bscell.level()) {
597 replaceBackCellToFace(subface, fcell);
598 }
599 }
600 }
601 else {
602 if (fcell.localId() == cell.localId()) {
603 if (bcell.level() > fscell.level()) {
604 replaceFrontCellToFace(subface, bcell);
605 }
606 }
607 else {
608 if (fcell.level() > fscell.level()) {
609 replaceFrontCellToFace(subface, fcell);
610 }
611 }
612 }
613}
614
615/*---------------------------------------------------------------------------*/
616/*---------------------------------------------------------------------------*/
617
618bool FaceFamily::
619isSubFaceInFace(Face subface, Face face) const
620{
621 const Real tol = 1e-02;
622 bool is_true = false;
623
624 //TODO: a std::binary_search to speed up the search
625 for (Node inode : subface.nodes()) {
626 for (Node inode2 : face.nodes()) {
627 if (inode.uniqueId() == inode2.uniqueId()) { // it is enough that a single node coincides
628 is_true = true;
629 break;
630 }
631 }
632 }
633 if (!is_true)
634 return false;
635
636 SharedVariableNodeReal3 orig_nodes_coords(mesh()->sharedNodesCoordinates());
637 Real3 normal_face = _computeFaceNormal(face, orig_nodes_coords);
638 Real3 normal_subface = _computeFaceNormal(subface, orig_nodes_coords);
639 Real ps = math::dot(normal_face, normal_subface);
640 Real residual = math::abs(ps) - 1.;
641 return math::abs(residual) < tol ? true : false;
642}
643
644/*---------------------------------------------------------------------------*/
645/*---------------------------------------------------------------------------*/
646
647bool FaceFamily::
648isChildOnFace(ItemWithNodes child, Face face) const
649{
650 //TODO: a std::binary_search to speed up the search
651 for (Node inode : face.nodes()) {
652 for (Node inode2 : child.nodes()) {
653 if (inode.uniqueId() == inode2.uniqueId()) // it is enough that a single node coincides
654 return true;
655 }
656 }
657 return false;
658}
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
662
663void FaceFamily::
664subFaces(Face face, Array<ItemInternal*>& subfaces)
665{
666 Cell cell;
667 const Integer nb_cell = face.nbCell();
668
669 if (nb_cell == 2) {
670 Cell fcell = face.frontCell();
671 cell = (fcell.hasHChildren()) ? face.frontCell() : face.backCell();
672 }
673 else
674 cell = face.cell(0);
675
676 for (Integer c = 0; c < cell.nbHChildren(); c++) {
677 Cell child = cell.hChild(c);
678 if (isChildOnFace(child, face)) {
679 //debug() << "current FACE:" << FullItemPrinter(face)
680 //<< "\n current child CELL:" << FullItemPrinter(child)
681 //<< "\n";
682 for (Face subface : child.faces()) {
683 if (isSubFaceInFace(subface, face)) {
684 subfaces.add(ItemCompatibility::_itemInternal(subface));
685 }
686 }
687 }
688 }
689 //info() << "\n SUBFACE NB= " << subfaces.size();
690}
691
692/*---------------------------------------------------------------------------*/
693/*---------------------------------------------------------------------------*/
694
695void FaceFamily::
696allSubFaces(Face face, Array<ItemInternal*>& subfaces)
697{
698 subfaces.add(ItemCompatibility::_itemInternal(face));
699
700 Cell cell;
701 const Integer nb_cell = face.nbCell();
702 if (nb_cell == 2) {
703 Cell fcell = face.frontCell();
704 if (fcell.hasHChildren() && fcell.isOwn())
705 cell = face.frontCell();
706 else
707 cell = face.backCell();
708 }
709 else {
710 cell = face.cell(0);
711 }
712
713 for (Integer c = 0; c < cell.nbHChildren(); c++) {
714 Cell child = cell.hChild(c);
715 if (isChildOnFace(child, face)) {
716 for (Face subface : child.faces()) {
717 if (isSubFaceInFace(subface, face)) {
718 allSubFaces(subface, subfaces);
719 }
720 }
721 }
722 }
723}
724
725/*---------------------------------------------------------------------------*/
726/*---------------------------------------------------------------------------*/
727
728void FaceFamily::
729activeSubFaces(Face face, Array<ItemInternal*>& subfaces)
730{
731 Cell cell;
732 const Integer nb_cell = face.nbCell();
733
734 if (nb_cell == 2) {
735 Cell fcell = face.frontCell();
736 Cell bcell = face.backCell();
737 if (fcell.level() > bcell.level())
738 cell = face.frontCell();
739 else {
740 if (bcell.isOwn())
741 cell = face.backCell();
742 else
743 cell = face.frontCell();
744 }
745 }
746 else {
747 cell = face.cell(0);
748 }
749 Cell pcell = cell.topHParent();
750
751 UniqueArray<ItemInternal*> cell_family;
752 activeFamilyTree(cell_family, pcell);
753 for (Integer c = 0; c < cell_family.size(); c++) {
754 Cell child = cell_family[c];
755 if (isChildOnFace(child, face)) {
756 //debug() << "current FACE:" << FullItemPrinter(face)
757 //<< "\n current child CELL:" << FullItemPrinter(child)
758 //<< "\n";
759 for (Face subface : child.faces()) {
760 if (isSubFaceInFace(subface, face)) {
761 subfaces.add(ItemCompatibility::_itemInternal(subface));
762 }
763 }
764 }
765 }
766 //info() << "\n SUBFACE NB= " << subfaces.size();
767}
768
769/*---------------------------------------------------------------------------*/
770/*---------------------------------------------------------------------------*/
771
772void FaceFamily::
773familyTree(Array<ItemInternal*>& family, Cell item,
774 const bool reset) const
775{
776 ARCANE_ASSERT((!item.isSubactive()), ("The family tree doesn't include subactive items"));
777 // Clear the array if the flag reset tells us to.
778 if (reset)
779 family.clear();
780 // Add this item to the family tree.
781 family.add(ItemCompatibility::_itemInternal(item));
782 // Recurse into the items children, if it has them.
783 // Do not clear the array any more.
784 if (!item.isActive())
785 for (Integer c = 0, cs = item.nbHChildren(); c < cs; c++) {
786 Cell ichild = item.hChild(c);
787 familyTree(family, ichild, false);
788 }
789}
790
791/*---------------------------------------------------------------------------*/
792/*---------------------------------------------------------------------------*/
793
794void FaceFamily::
795activeFamilyTree(Array<ItemInternal*>& family, Cell item, const bool reset) const
796{
797 ARCANE_ASSERT((!item.isSubactive()), ("The family tree doesn't include subactive items"));
798 // Clear the array if the flag reset tells us to.
799 if (reset)
800 family.clear();
801 // Add this item to the family tree.
802 if (item.isActive())
803 family.add(ItemCompatibility::_itemInternal(item));
804 else
805 for (Integer c = 0, cs = item.nbHChildren(); c < cs; c++) {
806 Cell ichild = item.hChild(c);
807 if (ichild.isOwn())
808 activeFamilyTree(family, ichild, false);
809 }
810}
811
812/*---------------------------------------------------------------------------*/
813/*---------------------------------------------------------------------------*/
814
815void FaceFamily::
816_addParentFaceToFace(Face parent_face, Face child_face)
817{
818 m_hparent_connectivity->addConnectedItem(ItemLocalId(child_face), ItemLocalId(parent_face));
819}
820
821/*---------------------------------------------------------------------------*/
822/*---------------------------------------------------------------------------*/
823
824void FaceFamily::
825_addChildFaceToFace(Face parent_face, Face child_face)
826{
827 m_hchild_connectivity->addConnectedItem(ItemLocalId(parent_face), ItemLocalId(child_face));
828}
829
830// OFF AMR
831
832/*---------------------------------------------------------------------------*/
833/*---------------------------------------------------------------------------*/
834
836addEdgeToFace(Face face, Edge new_edge)
837{
838 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_FaceToEdge))
839 return;
840
841 _checkValidSourceTargetItems(face, new_edge);
842 m_edge_connectivity->addConnectedItem(ItemLocalId(face), ItemLocalId(new_edge));
843 ;
844}
845
846/*---------------------------------------------------------------------------*/
847/*---------------------------------------------------------------------------*/
848
850removeEdgeFromFace(Face face, Edge edge_to_remove)
851{
852 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_FaceToEdge))
853 return;
854
855 _checkValidSourceTargetItems(face, edge_to_remove);
856 m_edge_connectivity->removeConnectedItem(ItemLocalId(face), ItemLocalId(edge_to_remove));
857}
858
859/*---------------------------------------------------------------------------*/
860/*---------------------------------------------------------------------------*/
861
862inline void FaceFamily::
863_removeFace(Face face)
864{
865 ItemLocalId face_lid = face;
866 for (Int32 edge : face.edgeIds())
868 Int32 nb_linear_node = face.nbLinearNode();
869 for (Int32 i = 0; i < nb_linear_node; ++i) {
870 m_node_family->removeFaceFromNode(face.nodeId(i), face_lid);
871 }
872
873 _removeOne(face);
874 // We do not delete other relations here (none here)
875 // Because the other deletion must always be cell, face, edge, node
876 // so node is last and everything is already done
877 // Furthermore, this avoids recursion problems
878}
879
880/*---------------------------------------------------------------------------*/
881/*---------------------------------------------------------------------------*/
882
883Real3 FaceFamily::
884_computeFaceNormal(Face face, const SharedVariableNodeReal3& nodes_coord) const
885{
886 Real3 normal_face = Real3::zero();
887 Integer nb_node = face.nbNode();
888 Real3UniqueArray cord_face(nb_node);
889 for (Integer i = 0; i < nb_node; ++i) {
890 cord_face[i] = nodes_coord[face.node(i)];
891 }
892 switch (nb_node) {
893 case (4): {
894 GeometricUtilities::QuadMapping face_mapping;
895 face_mapping.m_pos[0] = cord_face[0];
896 face_mapping.m_pos[1] = cord_face[1];
897 face_mapping.m_pos[2] = cord_face[2];
898 face_mapping.m_pos[3] = cord_face[3];
899 normal_face = face_mapping.normal();
900 } break;
901 case (3): {
902 Real3 v1 = cord_face[1] - cord_face[0];
903 Real3 v2 = cord_face[2] - cord_face[0];
904 normal_face = math::vecMul(v1, v2).normalize();
905 } break;
906 case (2): {
907 normal_face = cord_face[0] - cord_face[1];
908 normal_face.normalize();
909 } break;
910 default:
911 ARCANE_FATAL("This kind of face is not handled");
912 }
913 return normal_face;
914}
915
916/*---------------------------------------------------------------------------*/
917/*---------------------------------------------------------------------------*/
918
920removeCellFromFace(Face face, ItemLocalId cell_to_remove_lid)
921{
922 _checkValidItem(face);
923
924 Integer nb_cell = face.nbCell();
925
926#ifdef ARCANE_CHECK
927 if (face.itemBase().isSuppressed())
928 ARCANE_FATAL("Can not remove cell from destroyed face={0}", ItemPrinter(face));
929 if (nb_cell == 0)
930 ARCANE_FATAL("Can not remove cell lid={0} from face uid={1} with no cell connected",
931 cell_to_remove_lid, face.uniqueId());
932#endif /* ARCANE_CHECK */
933
934 Integer nb_cell_after = nb_cell - 1;
935 const Int32 null_cell_lid = NULL_ITEM_LOCAL_ID;
937 // force the deletion of a face between two cells of different levels
938 // because this face is not topologically attached to the lower level cell
939 if (nb_cell == 2) {
940 if (face.backCell().level() != face.frontCell().level())
941 nb_cell_after = 0;
942 else if (!(face.backCell().isActive() && face.frontCell().isActive())) {
943 // TODO: GG: for performance reasons, it is better to avoid
944 // allocations in this method because it is called very often.
946 subFaces(face, subfaces);
947 for (Integer s = 0, ss = subfaces.size(); s < ss; s++) {
948 ItemInternal* face2 = subfaces[s];
949 Int32 cell0 = face2->cellId(0);
950 Int32 cell1 = face2->cellId(1);
951 // We previously had two connected cells,
952 // so the back_cell is cell 0, the front cell is cell 1
953 if (cell0 == cell_to_remove_lid) {
954 // The front cell remains
955 setBackAndFrontCells(face, null_cell_lid, cell1);
956 }
957 else {
958 // The back cell remains
959 setBackAndFrontCells(face, cell0, null_cell_lid);
960 }
961 _updateSharedInfo();
962 }
963 }
964 }
965 // OFF AMR
966 if (nb_cell_after != 0) {
967 Int32 cell0 = face.cellId(0);
968 Int32 cell1 = face.cellId(1);
969 // We previously had two connected cells,
970 // so the back_cell is cell 0, the front cell is cell 1
971 if (cell0 == cell_to_remove_lid) {
972 // The front cell remains
973 setBackAndFrontCells(face, null_cell_lid, cell1);
974 }
975 else {
976 // The back cell remains
977 setBackAndFrontCells(face, cell0, null_cell_lid);
978 }
979 }
980 else {
981 setBackAndFrontCells(face, null_cell_lid, null_cell_lid);
982 }
983
984 _updateSharedInfo();
985}
986
987/*---------------------------------------------------------------------------*/
988/*---------------------------------------------------------------------------*/
989
992{
993 _checkValidItem(face);
994
995 if (!face.itemBase().isSuppressed() && face.nbCell() == 0) {
996 _removeFace(face);
997 }
998}
999
1000/*---------------------------------------------------------------------------*/
1001/*---------------------------------------------------------------------------*/
1002
1003void FaceFamily::
1004_addMasterFaceToFace(Face face, Face master_face)
1005{
1006 m_face_connectivity->addConnectedItem(face, master_face);
1008}
1009
1010/*---------------------------------------------------------------------------*/
1011/*---------------------------------------------------------------------------*/
1012
1013void FaceFamily::
1014_addSlaveFacesToFace(Face master_face, Int32ConstArrayView slave_faces_lid)
1015{
1016 Integer nb_slave = slave_faces_lid.size();
1017 for (Integer i = 0; i < nb_slave; ++i)
1018 m_face_connectivity->addConnectedItem(master_face, ItemLocalId(slave_faces_lid[i]));
1020}
1021
1022/*---------------------------------------------------------------------------*/
1023/*---------------------------------------------------------------------------*/
1024
1025void FaceFamily::
1026_removeMasterFaceToFace(Face face)
1027{
1028 m_face_connectivity->removeConnectedItems(face);
1029 face.mutableItemBase().removeFlags(ItemFlags::II_SlaveFace);
1030}
1031
1032/*---------------------------------------------------------------------------*/
1033/*---------------------------------------------------------------------------*/
1034
1035void FaceFamily::
1036_removeSlaveFacesToFace(Face master_face)
1037{
1038 m_face_connectivity->removeConnectedItems(master_face);
1039 master_face.mutableItemBase().removeFlags(ItemFlags::II_MasterFace);
1040}
1041
1042/*---------------------------------------------------------------------------*/
1043/*---------------------------------------------------------------------------*/
1044
1047{
1048 TiedInterfaceFaceList tied_faces(interface->tiedFaces());
1049 Int32UniqueArray slave_faces;
1050
1051 ENUMERATE_FACE (imaster_face, interface->masterInterface()) {
1052 Face master_face = *imaster_face;
1053 Integer index = imaster_face.index();
1054 ConstArrayView<TiedFace> slave_tied_faces(tied_faces[index]);
1055 Integer nb_slave = slave_tied_faces.size();
1056 slave_faces.clear();
1057 for (Integer zz = 0; zz < nb_slave; ++zz) {
1058 TiedFace tn = tied_faces[index][zz];
1059 Face slave_face = tn.face();
1060 slave_faces.add(slave_face.localId());
1061 _addMasterFaceToFace(slave_face, master_face);
1062 }
1063 _addSlaveFacesToFace(master_face, slave_faces);
1064 }
1065}
1066
1067/*---------------------------------------------------------------------------*/
1068/*---------------------------------------------------------------------------*/
1069
1072{
1073 TiedInterfaceFaceList tied_faces(interface->tiedFaces());
1074
1075 ENUMERATE_FACE (imaster_face, interface->masterInterface()) {
1076 Face master_face = *imaster_face;
1077 Integer index = imaster_face.index();
1078 ConstArrayView<TiedFace> slave_tied_faces(tied_faces[index]);
1079 Integer nb_slave = slave_tied_faces.size();
1080 for (Integer zz = 0; zz < nb_slave; ++zz) {
1081 TiedFace tn = tied_faces[index][zz];
1082 Face slave_face = tn.face();
1083 _removeMasterFaceToFace(slave_face);
1084 }
1085 _removeSlaveFacesToFace(master_face);
1086 }
1087}
1088
1089/*---------------------------------------------------------------------------*/
1090/*---------------------------------------------------------------------------*/
1091
1092void FaceFamily::
1093setConnectivity(const Integer c)
1094{
1095 m_mesh_connectivity = c;
1096 m_has_face = Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_HasFace);
1097 if (m_has_face) {
1098 m_node_prealloc = Connectivity::getPrealloc(m_mesh_connectivity, IK_Face, IK_Node);
1099 if (Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_HasEdge))
1100 m_edge_prealloc = Connectivity::getPrealloc(m_mesh_connectivity, IK_Face, IK_Edge);
1101 m_face_connectivity->setPreAllocatedSize(4);
1102 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity, IK_Face, IK_Cell);
1103 m_node_connectivity->setPreAllocatedSize(m_node_prealloc);
1104 m_cell_connectivity->setPreAllocatedSize(m_cell_prealloc);
1105 debug() << "Family " << name() << " prealloc "
1106 << m_node_prealloc << " by node, "
1107 << m_edge_prealloc << " by edge, "
1108 << m_cell_prealloc << " by cell.";
1109 }
1110}
1111
1112/*---------------------------------------------------------------------------*/
1113/*---------------------------------------------------------------------------*/
1114
1115void FaceFamily::
1116reorientFacesIfNeeded()
1117{
1118 // Reorients the faces if necessary. This is the case, for example, if we
1119 // have changed the uniqueId() numbering of the nodes.
1120 mesh::FaceReorienter face_reorienter(mesh());
1121 ENUMERATE_ (Face, iface, allItems()) {
1122 face_reorienter.checkAndChangeOrientationAMR(*iface);
1123 }
1124}
1125
1126/*---------------------------------------------------------------------------*/
1127/*---------------------------------------------------------------------------*/
1128
1129} // End namespace Arcane::mesh
1130
1131/*---------------------------------------------------------------------------*/
1132/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Types and macros for iterating over mesh entities.
#define ENUMERATE_FACE(name, group)
Generic enumerator for a face group.
#define ENUMERATE_(type, name, group)
Generic enumerator for an entity group.
Integer size() const
Number of elements in the vector.
void fill(ConstReferenceType value)
Fills the array with the value value.
void resize(Int64 s)
Changes the number of elements in the array to s.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
Cell of a mesh.
Definition Item.h:1300
bool isActive() const
Definition Item.h:1451
Int32 level() const
Definition Item.h:1473
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Edge of a cell.
Definition Item.h:875
Face of a cell.
Definition Item.h:1032
Cell frontCell() const
Cell in front of the face (null cell if none).
Definition Item.h:1780
CellLocalId cellId(Int32 i) const
i-th cell of the face
Definition Item.h:1138
EdgeLocalIdView edgeIds() const
List of edges of the face.
Definition Item.h:1252
Int32 nbCell() const
Number of cells of the face (1 or 2).
Definition Item.h:1129
Cell backCell() const
Cell behind the face (null cell if none).
Definition Item.h:1774
virtual void findAndReplaceCell(ItemLocalId item_lid, ItemLocalId old_cell_lid, ItemLocalId new_cell_lid)=0
Finds and replaces a cell of an entity.
virtual IItemFamily * nodeFamily()=0
Returns the node family.
virtual IItemFamily * edgeFamily()=0
Returns the edge family.
virtual bool useMeshItemFamilyDependencies() const =0
check if the network itemFamily dependencies is activated
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Family network interface (connected families).
Interface of a class managing semi-conforming mesh.
virtual TiedInterfaceFaceList tiedFaces() const =0
List of information about the slave faces of a master face.
virtual FaceGroup masterInterface() const =0
Group containing the master faces.
bool isSuppressed() const
True if the entity is suppressed.
@ II_MasterFace
The entity is a master face of an interface.
Definition ItemFlags.h:65
@ II_HasBackCell
The entity has a back cell.
Definition ItemFlags.h:53
@ II_SlaveFace
The entity is a slave face of an interface.
Definition ItemFlags.h:64
@ II_HasFrontCell
The entity has a front cell.
Definition ItemFlags.h:52
Internal structure of a mesh entity.
Index of an Item in a variable.
Definition ItemLocalId.h:42
Utility class for printing information about an entity.
Definition ItemPrinter.h:35
Type of an entity (Item).
Definition ItemTypeId.h:33
Info on a mesh entity type.
NodeLocalId nodeId(Int32 index) const
i-th node of the entity.
Definition Item.h:849
Int32 nbLinearNode() const
Number of nodes of the associated linear entity (if entity order 2 or more).
Definition Item.h:852
Base class for a mesh element.
Definition Item.h:84
impl::MutableItemBase mutableItemBase() const
Mutable internal part of the entity.
Definition Item.h:394
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
constexpr bool hasFlags(Int32 flags) const
Returns if the flags are set for the entity.
Definition Item.h:352
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
impl::ItemBase itemBase() const
Internal part of the entity.
Definition Item.h:383
void _setFaceBackAndFrontCells(Int32 back_cell_lid, Int32 front_cell_lid)
For a face, positions both the back cell and the front cell.
void addFlags(Int32 added_flags)
Adds the flags added_flags to those of the entity.
Semi-conforming mesh face.
Definition TiedFace.h:35
Face face() const
Welded face.
Definition TiedFace.h:52
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
1D data vector with value semantics (STL style).
void removeFaceFromEdge(ItemLocalId edge, ItemLocalId face_to_remove)
Removes a face from an edge.
void replaceCell(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces a cell of an entity.
Definition FaceFamily.cc:72
void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces an edge of an entity.
Definition FaceFamily.cc:64
void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces a node of an entity.
Definition FaceFamily.cc:60
void setBackAndFrontCells(FaceLocalId face_lid, CellLocalId back_cell_lid, CellLocalId front_cell_lid) override
Positions a cell in front and behind a face.
Definition FaceFamily.cc:76
void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces a face of an entity.
Definition FaceFamily.cc:68
IncrementalItemConnectivity * nodeConnectivity() const
The true connectivity behind the selector, for a bulk fill.
void replaceNode(ItemLocalId face, Integer index, ItemLocalId node)
Replaces the node at index index of the face face with that of localId() node_lid.
void setBulkBackAndFrontCells(Int32ConstArrayView back_cells, Int32ConstArrayView front_cells)
Sets the cells of every face at once.
void setBackAndFrontCells(Face face, Int32 back_cell_lid, Int32 front_cell_lid)
Positions the cell behind and in front of the face.
NodeFamily * m_node_family
Node family associated with this family.
Definition FaceFamily.h:175
void removeEdgeFromFace(Face face, Edge edge_to_remove)
Removes an edge from the face.
void replaceEdge(ItemLocalId face, Integer index, ItemLocalId edge)
Replaces the edge at index index of the face face with that of localId() edge_lid.
Item allocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info) override
Allocates a face with unique number uid and type type. Generic item addition.
void applyTiedInterface(ITiedInterface *interface)
Sets the information related to the tied interface interface.
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Retrieves or allocates a face with unique number uid and type type.
EdgeFamily * m_edge_family
Edge family associated with this family.
Definition FaceFamily.h:178
void removeCellFromFace(Face face, ItemLocalId cell_to_remove_lid)
Removes a cell from the face.
void replaceCell(ItemLocalId face, Integer index, ItemLocalId cell)
Replaces the cell at index index of the face face with that of localId() cell_lid.
void allocateItemsBulk(Int64ConstArrayView uids, ItemTypeInfo *type, Int32 owner, Int32ArrayView lids)
Allocates every item of uids at once, in one pass per family array.
void addFrontCellToFace(Face face, Cell new_cell)
Adds a front cell to the face.
bool m_check_orientation
Indicates whether to check the orientation.
Definition FaceFamily.h:181
virtual void computeSynchronizeInfos() override
Constructs the structures necessary for synchronization.
void addEdgeToFace(Face face, Edge new_edge)
Adds an edge to the face.
void removeFaceIfNotConnected(Face face)
Removes the face if it is no longer connected.
void removeTiedInterface(ITiedInterface *interface)
Removes the information related to the tied interface interface.
void replaceBackCellToFace(Face face, ItemLocalId new_cell)
AMR.
void addBackCellToFace(Face face, Cell new_cell)
Adds a back cell to the face.
void replaceFace(ItemLocalId face, Integer index, ItemLocalId face2)
Replaces the face at index index of the face face with that of localId() face_lid.
void reserveMemoryForNbSourceItems(Int32 n, bool pre_alloc_connectivity) override
Reserves memory for n source entities.
void setBulkConnectivity(Int32ConstArrayView nb_items, Int32ConstArrayView indexes, Int32ConstArrayView list)
Replaces the whole connectivity with one the caller already knows.
Integer preAllocatedSize() const final
Number of entities pre-allocated for the connectivity of each entity.
IMesh * mesh() const override
Associated mesh.
IItemFamilyTopologyModifier * _topologyModifier() override
Topology modifier interface.
Definition ItemFamily.h:412
ItemGroup allItems() const override
Group of all entities.
ItemInternalList itemsInternal() override
Internal array of entities.
void computeSynchronizeInfos() override
Constructs the structures necessary for synchronization.
void _allocateInfosBulk(Int64ConstArrayView uids, ItemTypeInfo *type, Int32 owner, Int32ArrayView lids)
Allocates every item of uids at once.
String name() const override
Family name.
Definition ItemFamily.h:140
Class containing mesh information.
Definition MeshInfos.h:36
Integer & nbFace()
Number of faces in the mesh.
Definition MeshInfos.h:65
__host__ __device__ Real dot(Real2 u, Real2 v)
Dot product of u by v in .
Definition MathUtils.h:94
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Vector cross product of u by v in .
Definition MathUtils.h:48
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
UniqueArray< Real3 > Real3UniqueArray
Dynamic 1D array of rank 3 vectors.
Definition UtilsTypes.h:357
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:476
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:474
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:335
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:447
SharedMeshVariableScalarRefT< Node, Real3 > SharedVariableNodeReal3
Quantity at the node of coordinate type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.
@ IK_Edge
Edge mesh entity.
double Real
Type representing a real number.
@ Cell
The mesh is AMR by cell.
Definition MeshKind.h:53
std::int32_t Int32
Signed integer type of 32 bits.