Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MeshToMeshTransposer.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/* MeshToMeshTransposer.cc (C) 2000-2009 */
9/* */
10/* Operator for transposition between sub-meshes. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Array.h"
15#include "arcane/utils/FatalErrorException.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/TraceInfo.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/Item.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/MeshToMeshTransposer.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
37kindTranspose(eItemKind kindA, IMesh* meshA, IMesh* meshB)
38{
39 // Case of nodes which are always of fixed dimension
40 if (kindA == IK_Node)
41 return IK_Node;
42
43 // We keep the hierarchy Node <= Edge <= Face <= Cell
44 // even if sometimes in low dimensions certain notions collapse.
45 Integer dimA = meshA->dimension();
46 Integer dimB = meshB->dimension();
47
48 Integer iKind;
49 switch (kindA) {
50 case IK_Node:
51 iKind = 0;
52 break;
53 case IK_Edge:
54 iKind = 1;
55 break;
56 case IK_Face:
57 iKind = 2;
58 break;
59 case IK_Cell:
60 iKind = 3;
61 break;
62 default:
63 throw FatalErrorException(A_FUNCINFO, "Cannot transpose unknown kind");
64 }
65
66 iKind = iKind - dimB + dimA; // numerical transposition (kindA+dimA==kindB+dimB)
67
68 eItemKind i2k_mapper[4] = { IK_Node, IK_Edge, IK_Face, IK_Cell };
69 if (iKind < 0 || iKind > 3)
70 throw FatalErrorException(A_FUNCINFO, "Cannot transpose unknown dimension");
71 eItemKind kindB = i2k_mapper[iKind];
72
73 // Handling of dimension condensation
74 if (kindB == IK_Edge && dimB < 3)
75 kindB = IK_Node;
76 else if (kindB == IK_Face && dimB < 2)
77 kindB = IK_Node;
78
79 return kindB;
80}
81
82/*---------------------------------------------------------------------------*/
83/*---------------------------------------------------------------------------*/
84
86transpose(IMesh* meshA, IMesh* meshB, ItemVectorView itemsA, bool do_fatal)
87{
88 ARCANE_ASSERT((meshA != NULL && meshB != NULL), ("Bad NULL mesh"));
89
90 // Empty itemsA => empty return
91 if (itemsA.size() == 0)
92 return ItemVector();
93
94 // We must calculate the transition on the kind
95 eItemKind kindA = itemsA[0].kind(); // since itemsA is not empty
96 eItemKind kindB = kindTranspose(kindA, meshA, meshB);
97 IItemFamily* familyA = meshA->itemFamily(kindA);
98 IItemFamily* familyB = meshB->itemFamily(kindB);
99 return _transpose(familyA, familyB, itemsA, do_fatal);
100}
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
106transpose(IItemFamily* familyA, IItemFamily* familyB, ItemVectorView itemsA, bool do_fatal)
107{
108 ARCANE_ASSERT((familyA != NULL && familyB != NULL), ("Bad NULL mesh"));
109
110 // Empty itemsA => empty return
111 if (itemsA.size() == 0)
112 return ItemVector();
113
114 return _transpose(familyA, familyB, itemsA, do_fatal);
115}
116
117/*---------------------------------------------------------------------------*/
118/*---------------------------------------------------------------------------*/
119
120ItemVector MeshToMeshTransposer::
121_transpose(IItemFamily* familyA, IItemFamily* familyB, const ItemVectorView& itemsA, bool do_fatal)
122{
123 eItemKind kindB = familyB->itemKind();
124 IItemFamily* parent_familyA = familyA->parentFamily();
125 IItemFamily* parent_familyB = familyB->parentFamily();
126
127 // Only processes transposition on a single level
128 if (parent_familyA == familyB) {
129 // meshA is a sub-mesh of meshB
130 UniqueArray<Int32> lidsB(itemsA.size(), NULL_ITEM_LOCAL_ID);
131 ENUMERATE_ITEM (iitem, itemsA) {
132 const Item& item = *iitem;
133 lidsB[iitem.index()] = item.parent().localId();
134 }
135 return ItemVector(familyB, lidsB);
136 }
137 else if (parent_familyB == familyA) {
138 // meshB is a sub-mesh of meshA
139 if (kindB == IK_Node || kindB == IK_Face || kindB == IK_Edge || kindB == IK_Cell) {
140 // Currently the uids are the same between sub-meshes and parent mesh
141 // By transitivity, this comes down to searching for the uids of itemsA in meshB
142 UniqueArray<Int64> uidsA(itemsA.size());
143 ENUMERATE_ITEM (iitem, itemsA) {
144 uidsA[iitem.index()] = iitem->uniqueId();
145 }
146 UniqueArray<Int32> lidsB(uidsA.size());
147 familyB->itemsUniqueIdToLocalId(lidsB, uidsA, do_fatal);
148 return ItemVector(familyB, lidsB);
149 }
150 else {
151 throw NotImplementedException(A_FUNCINFO, "Cannot only transpose item to cell or node");
152 }
153 }
154 else if (familyA == familyB) {
155 // same mesh
156 return ItemVector(familyB, itemsA.localIds());
157 }
158 else {
159 throw NotImplementedException(A_FUNCINFO, String::format("Cannot transpose between families {0}::{1} and {2}::{3}", familyA->mesh()->name(), familyA->name(), familyA->mesh()->name(), familyB->name()));
160 }
161
162 // // The implementation assumes and verifies that meshA and meshB have the same parent mesh
163 // {
164 // IMesh * masterSupportA = meshA;
165 // while (masterSupportA->parentMesh()) {
166 // masterSupportA = masterSupportA->parentMesh();
167 // }
168 // IMesh * masterSupportB = meshB;
169 // while (masterSupportB->parentMesh()) {
170 // masterSupportB = masterSupportB->parentMesh();
171 // }
172 // if (masterSupportA != masterSupportB)
173 // throw FatalErrorException(A_FUNCINFO,"Non common parent for transposition between meshes");
174 // }
175}
176
177/*---------------------------------------------------------------------------*/
178/*---------------------------------------------------------------------------*/
179
180} // namespace Arcane
181
182/*---------------------------------------------------------------------------*/
183/*---------------------------------------------------------------------------*/
Types and macros for iterating over mesh entities.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
Declarations of types on entities.
Interface of an entity family.
Definition IItemFamily.h:83
virtual String name() const =0
Family name.
virtual IItemFamily * parentFamily() const =0
IItemFamily parent.
virtual eItemKind itemKind() const =0
Entity kind.
virtual IMesh * mesh() const =0
Associated mesh.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converts an array of unique numbers to local numbers.
virtual String name() const =0
Mesh name.
virtual IItemFamily * itemFamily(eItemKind ik)=0
Returns the entity family of type ik.
virtual Integer dimension()=0
Mesh dimension (1D, 2D, or 3D).
View on a vector of entities.
Int32 size() const
Number of elements in the vector.
Int32ConstArrayView localIds() const
Array of local IDs of entities.
Entity vector.
Definition ItemVector.h:60
Base class for a mesh element.
Definition Item.h:84
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Definition Item.h:233
Item parent(Int32 i) const
i-th parent for submeshes
Definition Item.h:300
static eItemKind kindTranspose(eItemKind kindA, IMesh *meshA, IMesh *meshB)
Transpose the kind kindA of mesh meshA to the associated kind in meshB.
static ItemVector transpose(IMesh *meshA, IMesh *meshB, ItemVectorView itemsA, bool do_fatal=false)
Transpose itemsA from meshB to items on meshB.
1D data vector with value semantics (STL style).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
eItemKind
Mesh entity type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.
@ IK_Edge
Edge mesh entity.