Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
TiedInterfaceExchanger.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/* TiedInterfaceExchanger.cc (C) 2000-2016 */
9/* */
10/* Exchanger between sub-domains of tied interfaces. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ArcanePrecomp.h"
15
16#include "arcane/utils/NotSupportedException.h"
17#include "arcane/utils/ArgumentException.h"
18
19#include "arcane/mesh/TiedInterfaceExchanger.h"
20#include "arcane/mesh/DynamicMesh.h"
21#include "arcane/mesh/TiedInterface.h"
22#include "arcane/mesh/FaceFamily.h"
23
24#include "arcane/core/SerializeBuffer.h"
25#include "arcane/core/IParallelMng.h"
26#include "arcane/core/ItemPrinter.h"
27#include "arcane/core/ItemFamilySerializeArgs.h"
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32namespace Arcane::mesh
33{
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
39: public TraceAccessor
40{
41 public:
42
43 OneSubDomainInfo(ITraceMng* tm, Int32 rank)
44 : TraceAccessor(tm)
45 , m_rank(rank)
46 {}
47
48 public:
49
50 void addOne(Face face, ConstArrayView<TiedNode> tied_nodes,
51 ConstArrayView<TiedFace> tied_faces)
52 {
53 //info() << "ADD_ONE_TIED_FACE face=" << ItemPrinter(face) << " rank=" << m_rank;
54 uids.add(face.uniqueId());
55 Integer nb_tied_node = tied_nodes.size();
56 Integer nb_tied_face = tied_faces.size();
57 nb_items.add(nb_tied_node);
58 nb_items.add(nb_tied_face);
59 for (Integer z = 0; z < nb_tied_node; ++z) {
60 const TiedNode& tn = tied_nodes[z];
61 slaves_node_uid.add(tn.node().uniqueId());
62 Real2 iso = tn.isoCoordinates();
63 //info() << "ADD NODE node=" << ItemPrinter(tn.node()) << " iso=" << iso;
64 isos.add(iso.x);
65 isos.add(iso.y);
66 }
67 for (Integer z = 0; z < nb_tied_face; ++z) {
68 const TiedFace& tf = tied_faces[z];
69 slaves_face_uid.add(tf.face().uniqueId());
70 //info() << "ADD FACE face=" << ItemPrinter(tf.face());
71 }
72 }
73 void serializeReserve(ISerializer* buf)
74 {
75 buf->reserveArray(nb_items);
76 buf->reserveArray(isos);
77 buf->reserveArray(uids);
78 buf->reserveArray(slaves_node_uid);
79 buf->reserveArray(slaves_face_uid);
80 }
81
82 void serializePut(ISerializer* buf)
83 {
84 buf->putArray(uids);
85 buf->putArray(nb_items);
86 buf->putArray(isos);
87 buf->putArray(slaves_node_uid);
88 buf->putArray(slaves_face_uid);
89 }
90
91 void deserialize(ISerializer* buf)
92 {
93 buf->getArray(uids);
94 info() << "DESERIALIZE_INFO rank=" << m_rank << " nb_face=" << uids.largeSize();
95 buf->getArray(nb_items);
96 buf->getArray(isos);
97 buf->getArray(slaves_node_uid);
98 info() << "NODES: " << slaves_node_uid;
99 buf->getArray(slaves_face_uid);
100 info() << "FACES: " << slaves_face_uid;
101 }
102
103 public:
104
105 Int32 m_rank;
106 Int64UniqueArray uids;
107 Int64UniqueArray slaves_node_uid;
108 Int64UniqueArray slaves_face_uid;
109 IntegerUniqueArray nb_items;
110 RealUniqueArray isos;
115};
116
117/*---------------------------------------------------------------------------*/
118/*---------------------------------------------------------------------------*/
119
120/*---------------------------------------------------------------------------*/
121/*---------------------------------------------------------------------------*/
122
124: public TraceAccessor
126{
127 public:
128
129 DeserializedInfo(IMesh* mesh, ITraceMng* tm)
130 : TraceAccessor(tm)
131 , m_face_family(mesh->faceFamily())
132 , m_node_family(mesh->nodeFamily())
133 {}
134
135 public:
136
137 struct FaceInfo
138 {
147
148 FaceInfo(OneSubDomainInfo* _sd_info,
149 Integer _face_index,
150 Integer _slave_face_index,
151 Integer _slave_node_index)
152 {
153 sd_info = _sd_info;
154 face_index = _face_index;
155 slave_face_index = _slave_face_index;
156 slave_node_index = _slave_node_index;
157 }
158 };
159
164 {
165 Integer nb_uid = sdi->uids.size();
166 Integer face_index = 0;
167 Integer node_index = 0;
168 info(4) << "BUILD_AFTER_DESERIALIZE_INFO rank=" << sdi->m_rank << " nb_face=" << nb_uid;
169 for (Integer i = 0; i < nb_uid; ++i) {
170 Int64 uid = sdi->uids[i];
171 Integer nb_slave_node = sdi->nb_items[i * 2];
172 Integer nb_slave_face = sdi->nb_items[(i * 2) + 1];
173 //info() << "ADD_FACE uid=" << uid << " nb_node=" << nb_slave_node << " nb_face=" << nb_slave_face;
174 m_index_map.insert(std::make_pair(uid, FaceInfo(sdi, i, face_index, node_index)));
175 face_index += nb_slave_face;
176 node_index += nb_slave_node;
177 }
178 m_sdi_array.add(sdi);
179 }
180
181 void convertUniqueIds()
182 {
183 for (Integer z = 0, n = m_sdi_array.size(); z < n; ++z) {
184 OneSubDomainInfo* sdi = m_sdi_array[z];
185
186 Integer nb_total_slave_face = sdi->slaves_face_uid.size();
187 info(4) << "CONVERT_UID nb_slave_face=" << nb_total_slave_face;
188 sdi->slaves_face_local_id.resize(sdi->slaves_face_uid.size());
189 m_face_family->itemsUniqueIdToLocalId(sdi->slaves_face_local_id, sdi->slaves_face_uid);
190
191 Integer nb_total_slave_node = sdi->slaves_node_uid.size();
192 info(4) << "CONVERT_UID nb_slave_node=" << nb_total_slave_node;
193 sdi->slaves_node_local_id.resize(sdi->slaves_node_uid.size());
194 m_node_family->itemsUniqueIdToLocalId(sdi->slaves_node_local_id, sdi->slaves_node_uid);
195 }
196 }
197
198 const FaceInfo& _getInfo(Int64 uid)
199 {
200 std::map<Int64, FaceInfo>::const_iterator iter = m_index_map.find(uid);
201 if (iter == m_index_map.end())
202 throw ArgumentException(A_FUNCINFO, String::format("Can not find uid '{0}'", uid));
203 return iter->second;
204 }
205
206 void getNbSlave(Int64 uid, Integer* nb_node, Integer* nb_face)
207 {
208 const FaceInfo& fi = _getInfo(uid);
209 Integer face_index = fi.face_index;
210 *nb_node = fi.sd_info->nb_items[face_index * 2];
211 *nb_face = fi.sd_info->nb_items[(face_index * 2) + 1];
212 }
213
214 virtual void fillTiedInfos(Face face,
215 Int32ArrayView tied_nodes_lid,
216 Real2ArrayView tied_nodes_isos,
217 Int32ArrayView tied_faces_lid)
218 {
219 const FaceInfo& fi = _getInfo(face.uniqueId());
220 OneSubDomainInfo* sdi = fi.sd_info;
221 Int32ConstArrayView slaves_face_local_id = sdi->slaves_face_local_id.constView();
222 Int32ConstArrayView slaves_node_local_id = sdi->slaves_node_local_id.constView();
223 Integer face_index = fi.face_index;
224 Integer nb_node = sdi->nb_items[face_index * 2];
225 Integer nb_face = sdi->nb_items[(face_index * 2) + 1];
226 RealConstArrayView isos = sdi->isos.subConstView(fi.slave_node_index * 2, nb_node * 2);
227 Int32ConstArrayView nodes_lid = slaves_node_local_id.subView(fi.slave_node_index, nb_node);
228 Int32ConstArrayView faces_lid = slaves_face_local_id.subView(fi.slave_face_index, nb_face);
229 tied_nodes_lid.copy(nodes_lid);
230 tied_faces_lid.copy(faces_lid);
231 for (Integer z = 0; z < nb_node; ++z)
232 tied_nodes_isos[z] = Real2(isos[(z * 2)], isos[(z * 2) + 1]);
233 }
234
235 private:
236
237 IItemFamily* m_face_family;
238 IItemFamily* m_node_family;
239 std::map<Int64, FaceInfo> m_index_map;
240 UniqueArray<OneSubDomainInfo*> m_sdi_array;
241};
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
246/*---------------------------------------------------------------------------*/
247/*---------------------------------------------------------------------------*/
248
249TiedInterfaceExchanger::
250TiedInterfaceExchanger(DynamicMesh* mesh)
251: TraceAccessor(mesh->traceMng())
252, m_mesh(mesh)
253, m_sub_domain(mesh->subDomain())
254, m_deserialized_info(new DeserializedInfo(mesh, traceMng()))
255, m_my_rank(mesh->parallelMng()->commRank())
256{
257}
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
261
262TiedInterfaceExchanger::
263~TiedInterfaceExchanger()
264{
265 for (SubDomainInfoMap::const_iterator iter(m_infos.begin()); iter != m_infos.end(); ++iter)
266 delete iter->second;
267 delete m_deserialized_info;
268}
269
270/*---------------------------------------------------------------------------*/
271/*---------------------------------------------------------------------------*/
272
273inline TiedInterfaceExchanger::OneSubDomainInfo* TiedInterfaceExchanger::
274_getInfo(Int32 rank)
275{
276 SubDomainInfoMap::const_iterator iter = m_infos.find(rank);
277 if (iter != m_infos.end())
278 return iter->second;
279 OneSubDomainInfo* sdi = new OneSubDomainInfo(traceMng(), rank);
280 m_infos.insert(std::make_pair(rank, sdi));
281 return sdi;
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
289{
290 // precond:
291 // - this call must be made before face.owner() new contains
292 // the new owners because in this case ENUMERATE_FACE
293 // will not work correctly since it is a group
294 // of own cells and it is updated when owners
295 // change.
296 // - slave faces and their master face must have the same owner
297
298 // Iterates through all tied interfaces and:
299 // 1- saves the information about the tied faces that will be kept
300 // 2- prepares the information for each sub-domain.
301 // Each tied face contains either the associated master face (if it is
302 // a slave face), or the list of slave faces (if it is
303 // a master face).
304 // 3- Deletes the connectivity information for each face.
305
306 ConstArrayView<TiedInterface*> tied_interfaces(m_mesh->trueTiedInterfaces());
307 FaceFamily& face_family = m_mesh->trueFaceFamily();
308 VariableItemInt32& new_owners(face_family.itemsNewOwner());
309 for (Integer i = 0, n = tied_interfaces.size(); i < n; ++i) {
310 TiedInterface* ti = tied_interfaces[i];
311 FaceGroup master_group = ti->masterInterface();
312 TiedInterfaceNodeList tied_nodes = ti->tiedNodes();
313 TiedInterfaceFaceList tied_faces = ti->tiedFaces();
314 Integer index = 0;
315 ENUMERATE_FACE (iface, master_group) {
316 Face face = *iface;
317 Int32 owner = new_owners[iface];
318 OneSubDomainInfo* sdi = _getInfo(owner);
319 ConstArrayView<TiedNode> face_tied_nodes = tied_nodes[index];
320 ConstArrayView<TiedFace> face_tied_faces = tied_faces[index];
321 //info() << "ADD_TIED_INFOS: face=" << ItemPrinter(face) << " n1=" << face_tied_nodes.size() << " n2=" << face_tied_faces.size();
322 sdi->addOne(face, face_tied_nodes, face_tied_faces);
323 ++index;
324 }
325 face_family.removeTiedInterface(ti);
326 }
327}
328
329/*---------------------------------------------------------------------------*/
330/*---------------------------------------------------------------------------*/
342{
343 ISerializer* buf = args.serializer();
344 Int32 rank = args.rank();
345 OneSubDomainInfo* sdi = _getInfo(rank);
346 switch (buf->mode()) {
347 case ISerializer::ModeReserve:
348 sdi->serializeReserve(buf);
349 break;
351 sdi->serializePut(buf);
352 break;
354 sdi->deserialize(buf);
355 m_deserialized_info->buildAfterDeserializeInfo(sdi);
356 break;
357 }
358}
359
360/*---------------------------------------------------------------------------*/
361/*---------------------------------------------------------------------------*/
362
364finalize()
365{
366 // NOTE: it must be certain that this method is called
367 // once the localId() of the entities no longer changes
368 // (i.e., after compaction and sorting)
369
370 // It may be necessary to rebuild the info after deserialization
371 // of our own sub-domain because it was not deserialized.
372 OneSubDomainInfo* sdi = _getInfo(m_my_rank);
373 m_deserialized_info->buildAfterDeserializeInfo(sdi);
374
375 // It is necessary to convert the uniqueId to localId.
376 // It must absolutely not be done before reaching here because the
377 // localId() can change during a partitioning.
378 m_deserialized_info->convertUniqueIds();
379
380 // All new entities and groups
381 // have been updated. Now it remains to retrieve the
382 // information for each tied face, namely the list of nodes
383 // and slave faces as well as the iso coordinates.
384 ConstArrayView<TiedInterface*> tied_interfaces(m_mesh->trueTiedInterfaces());
385 IntegerUniqueArray nb_slave_nodes;
386 IntegerUniqueArray nb_slave_faces;
387 FaceFamily& face_family = m_mesh->trueFaceFamily();
388 for (Integer i = 0, n = tied_interfaces.size(); i < n; ++i) {
389 TiedInterface* ti = tied_interfaces[i];
390 FaceGroup master_group = ti->masterInterface();
391 Integer nb_master_face = master_group.size();
392 nb_slave_nodes.resize(nb_master_face);
393 nb_slave_faces.resize(nb_master_face);
394 Integer index = 0;
395 ENUMERATE_FACE (iface, master_group) {
396 Face face = *iface;
397 Integer nb_node = 0;
398 Integer nb_face = 0;
399 //info() << "TRY GET INFO face=" << ItemPrinter(face) << " owner=" << face.owner()
400 m_deserialized_info->getNbSlave(face.uniqueId(), &nb_node, &nb_face);
401 nb_slave_nodes[index] = nb_node;
402 nb_slave_faces[index] = nb_face;
403 ++index;
404 }
405 ti->rebuild(m_deserialized_info, nb_slave_nodes, nb_slave_faces);
406 face_family.applyTiedInterface(ti);
407 ti->checkValid();
408 }
409}
410
411/*---------------------------------------------------------------------------*/
412/*---------------------------------------------------------------------------*/
413
415family() const
416{
417 return m_mesh->faceFamily();
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
423} // namespace Arcane::mesh
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
#define ENUMERATE_FACE(name, group)
Generic enumerator for a face group.
Integer size() const
Number of elements in the vector.
void resize(Int64 s)
Changes the number of elements in the array to s.
Constant view of an array of type T.
constexpr ConstArrayView< T > subView(Integer abegin, Integer asize) const noexcept
Sub-view (constant) starting from element abegin and containing asize elements.
constexpr Integer size() const noexcept
Number of elements in the array.
constexpr ConstArrayView< T > subConstView(Integer abegin, Integer asize) const noexcept
Sub-view (constant) starting from element abegin and containing asize elements.
Face of a cell.
Definition Item.h:1032
Interface of an entity family.
Definition IItemFamily.h:83
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 void putArray(Span< const Real > values)=0
Save the number of elements and the values elements.
virtual void reserveArray(Span< const Real > values)=0
Reserve to save the number of elements and the values elements.
virtual void getArray(Array< Real > &values)=0
Resize and fill values.
virtual eMode mode() const =0
Current operating mode.
Arguments for the serialization callbacks of entity families.
Int32 rank() const
Rank of the source or destination.
ISerializer * serializer() const
Associated serializer.
Integer size() const
Number of elements in the group.
Definition ItemGroup.h:93
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
Class managing a 2-dimensional real vector.
Definition Real2.h:122
constexpr __host__ __device__ Real2 & add(Real2 b)
Adds b to the pair.
Definition Real2.h:236
Semi-conforming mesh face.
Definition TiedFace.h:35
Face face() const
Welded face.
Definition TiedFace.h:52
Semi-conformal mesh node.
Definition TiedNode.h:40
Node node() const
Tied node.
Definition TiedNode.h:59
Real2 isoCoordinates() const
Iso-barycentric coordinates of the node.
Definition TiedNode.h:62
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
Implementation of a mesh.
Definition DynamicMesh.h:98
void applyTiedInterface(ITiedInterface *interface)
Sets the information related to the tied interface interface.
void removeTiedInterface(ITiedInterface *interface)
Removes the information related to the tied interface interface.
VariableItemInt32 & itemsNewOwner() override
Variable containing the number of the new subdomain owning the entity.
void buildAfterDeserializeInfo(OneSubDomainInfo *sdi)
Constructs the info after deserialization.
Int32UniqueArray slaves_node_local_id
Only after deserialization, contains the localId() of each entity in slaves_node_uid.
Int32UniqueArray slaves_face_local_id
Only after deserialization, contains the localId() of each entity in slaves_face_uid.
IItemFamily * family() const override
Associated family.
void initialize() override
Initializes the instance before the start of exchanges.
void serialize(const ItemFamilySerializeArgs &args) override
Serializes the faces into the buffer buf.
void finalize() override
Performs end-of-exchange processing.
Information on mesh semi-conformities.
virtual TiedInterfaceFaceList tiedFaces() const
List of information about the slave faces of a master face.
virtual FaceGroup masterInterface() const
Group containing the master faces.
virtual TiedInterfaceNodeList tiedNodes() const
List of information about the slave nodes of a master face.
ItemGroupT< Face > FaceGroup
Group of faces.
Definition ItemTypes.h:179
ItemVariableScalarRefT< Int32 > VariableItemInt32
32-bit integer type quantity
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:339
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:341
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:453
UniqueArray< Real > RealUniqueArray
Dynamic 1D array of reals.
Definition UtilsTypes.h:349
ArrayView< Real2 > Real2ArrayView
C equivalent of a 1D array of Real2.
Definition UtilsTypes.h:465
UniqueArray< Integer > IntegerUniqueArray
Dynamic 1D array of integers.
Definition UtilsTypes.h:347
std::int32_t Int32
Signed integer type of 32 bits.
ConstArrayView< Real > RealConstArrayView
C equivalent of a 1D array of reals.
Definition UtilsTypes.h:488
Real y
second component of the pair
Definition Real2.h:35
Real x
first component of the pair
Definition Real2.h:34
Integer slave_node_index
Index in isos and slaves_node_uid of the first slave node.
Integer slave_face_index
Index in slaves_face_uid of the first slave face.