Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MeshUtils.h
Go to the documentation of this file.
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/* MeshUtils.h (C) 2000-2025 */
9/* */
10/* Various utility functions for the mesh. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_MESHUTILS_H
13#define ARCANE_CORE_MESHUTILS_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/FunctorUtils.h"
19
20#include "arcane/core/Item.h"
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25/*!
26 * \file MeshUtils.h
27 *
28 * \brief Utility functions for the mesh.
29 */
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34namespace Arcane
35{
36class XmlNode;
38} // namespace Arcane
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43namespace Arcane::MeshUtils
44{
45extern "C++" ARCANE_CORE_EXPORT void
46writeMeshItemInfo(ISubDomain*, Cell cell, bool depend_info = true);
47extern "C++" ARCANE_CORE_EXPORT void
48writeMeshItemInfo(ISubDomain*, Node node, bool depend_info = true);
49extern "C++" ARCANE_CORE_EXPORT void
50writeMeshItemInfo(ISubDomain*, Edge edge, bool depend_info = true);
51extern "C++" ARCANE_CORE_EXPORT void
52writeMeshItemInfo(ISubDomain*, Face face, bool depend_info = true);
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
57/*!
58 * \brief Reorders the nodes of a face.
59 *
60 * This method reorders the list of nodes of a face so that the following
61 * properties are respected:
62 * - the first node of the face is the one with the smallest global number.
63 * - the second node of the face is the one with the second smallest global number.
64 *
65 * This allows faces to be oriented identically in parallel.
66 *
67 * \a before_ids and \a to must have the same number of elements
68 *
69 * \param before_ids global numbers of the face nodes before renumbering.
70 * \param after_ids (output), global numbers of the face nodes after renumbering
71 *
72 * \retval true if the face changes orientation during renumbering
73 * \retval false otherwise.
74 */
75extern "C++" ARCANE_CORE_EXPORT bool
77
78extern "C++" ARCANE_CORE_EXPORT bool
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84/*!
85 * \brief Reorders the nodes of a face.
86 *
87 * This method reorders the list of nodes of a face so that the following
88 * properties are respected:
89 * - the first node of the face is the one with the smallest global number.
90 * - the second node of the face is the one with the second smallest global number.
91 *
92 * This allows faces to be oriented identically in parallel.
93 *
94 * \a nodes_unique_id and \a new_index must have the same number of elements
95 *
96 * \param nodes_unique_id unique numbers of the face nodes.
97 * \param new_index (output), position of the node numbers after reorientation.
98 *
99 * For example, if a face has 4 nodes with unique numbers 7 3 2 5,
100 * the reorientation will yield the quadruplet (2 3 7 5), which is the following index array
101 * (2,1,0,3).
102 *
103 * \retval true if the face changes orientation during renumbering
104 * \retval false otherwise.
105 */
106extern "C++" ARCANE_CORE_EXPORT bool
108
109/*---------------------------------------------------------------------------*/
110/*---------------------------------------------------------------------------*/
111/*!
112 * \brief Searches for a face entity using the local numbers of these nodes.
113 *
114 * Searches for the face given by the sorted list of <b>local</b> numbers of
115 * these nodes \a face_nodes_local_id. \a node must be the first node of
116 * the face. The nodes of the face must be correctly oriented, as
117 * after calling reorderNodesOfFace().
118 *
119 * \return the corresponding face or a null face if it is not found.
120 */
121extern "C++" ARCANE_CORE_EXPORT Face
122getFaceFromNodesLocalId(Node node, Int32ConstArrayView face_nodes_local_id);
123
124ARCANE_DEPRECATED_REASON("Y2025: Use getFaceFromNodesLocalId() instead")
125inline Face
126getFaceFromNodesLocal(Node node, Int32ConstArrayView face_nodes_local_id)
127{
128 return getFaceFromNodesLocalId(node, face_nodes_local_id);
129}
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
133/*!
134 * \brief Searches for a face entity using the unique numbers of these nodes.
135 *
136 * Searches for the face given by the sorted list of <b>unique</b> numbers of
137 * these nodes \a face_nodes_unique_id. \a node must be the first node of
138 * the face. The nodes of the face must be correctly oriented, as
139 * after calling reorderNodesOfFace().
140 *
141 * \return the corresponding face or a null face if it is not found.
142 */
143extern "C++" ARCANE_CORE_EXPORT Face
144getFaceFromNodesUniqueId(Node node, Int64ConstArrayView face_nodes_unique_id);
145
146ARCANE_DEPRECATED_REASON("Y2025: Use getFaceFromNodesUniqueId() instead")
147inline Face
148getFaceFromNodesUnique(Node node, Int64ConstArrayView face_nodes_unique_id)
149{
150 return getFaceFromNodesUniqueId(node, face_nodes_unique_id);
151}
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
155
156/*!
157 * \brief Generates a unique identifier from a list of node identifiers.
158 */
159extern "C++" ARCANE_CORE_EXPORT Int64
160generateHashUniqueId(SmallSpan<const Int64> nodes_unique_id);
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
165/*!
166 * \brief Removes an entity while preserving order.
167 *
168 * Removes the entity with local number \a local_id from the list \a items.
169 * Entities located after the removed entity are shifted to fill the gap.
170 * If no value in \a items equals \a local_id, an exception is raised.
171 */
172extern "C++" ARCANE_CORE_EXPORT void
173removeItemAndKeepOrder(Int32ArrayView items, Int32 local_id);
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177
178/*!
179 * \brief Checks if the mesh has certain properties.
180 *
181 * If \a is_sorted, checks that the mesh entities are sorted by
182 * ascending order of their uniqueId().
183 * If \a has_no_hole is true, checks that if the mesh has \a n
184 * entities of a certain type, their local number ranges from \a 0 to \a n-1.
185 * If \a check_faces is true, it checks the faces. This option
186 * is only usable for older generation meshes (MeshV1) and
187 * will be removed as soon as this option is no longer used.
188 */
189extern "C++" ARCANE_CORE_EXPORT void
190checkMeshProperties(IMesh* mesh, bool is_sorted, bool has_no_hole, bool check_faces);
191
192/*!
193 * \brief Writes the mesh info \a mesh to the file \a file_name
194 *
195 * Entity identifiers are sorted so that the mesh is identical regardless of the initial numbering.
196 */
197extern "C++" ARCANE_CORE_EXPORT void
198writeMeshInfosSorted(IMesh* mesh, const String& file_name);
199
200extern "C++" ARCANE_CORE_EXPORT void
201writeMeshInfos(IMesh* mesh, const String& file_name);
202
203/*!
204 * \brief Writes the connectivity of the mesh \a mesh to the file \a file_name
205 *
206 * The connectivity of each edge, face, and cell entity is saved.
207 */
208extern "C++" ARCANE_CORE_EXPORT void
209writeMeshConnectivity(IMesh* mesh, const String& file_name);
210
211extern "C++" ARCANE_CORE_EXPORT void
212checkMeshConnectivity(IMesh* mesh, const XmlNode& root_node, bool check_sub_domain);
213
214extern "C++" ARCANE_CORE_EXPORT void
215checkMeshConnectivity(IMesh* mesh, const String& file_name, bool check_sub_domain);
216
217/*!
218 * \brief Writes the description of items in group \a item_group to the stream \a ostr
219 *
220 * For display, a name \a name is associated.
221 */
222extern "C++" ARCANE_CORE_EXPORT void
223printItems(std::ostream& ostr, const String& name, ItemGroup item_group);
224
225/*!
226 * \brief Displays the memory usage of the mesh groups.
227 *
228 * If \a print_level is 0, only the total memory usage is displayed.
229 * If \a print_level is 1 or more, the usage for each group is displayed.
230 *
231 * Returns the memory consumed in bytes.
232 */
233extern "C++" ARCANE_CORE_EXPORT Int64
234printMeshGroupsMemoryUsage(IMesh* mesh, Int32 print_level);
235
236//! Optimizes the memory usage of the groups.
237extern "C++" ARCANE_CORE_EXPORT void
238shrinkMeshGroups(IMesh* mesh);
239
240/*!
241 * \brief Writes the topology information of a synchronizer to a file
242 *
243 * Writes the topology information of \a var_syncer to the file \a filename.
244 * This method is collective. Only rank 0 writes the topology information.
245 */
246extern "C++" ARCANE_CORE_EXPORT void
247dumpSynchronizerTopologyJSON(IVariableSynchronizer* var_syncer, const String& filename);
248
249/*!
250 * \internal
251 * \brief Calculates and displays common patterns in the connectivities.
252 */
253extern "C++" ARCANE_CORE_EXPORT void
254computeConnectivityPatternOccurence(IMesh* mesh);
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
259/*!
260 * \brief Indicates that the mesh connectivities will not be regularly modified.
261 *
262 * This function allows indicating that the connectivities associated with
263 * mesh entities (Node, Edge, Face, and Cell) are mostly read-only. Note that
264 * this does not concern particles.
265 *
266 * When used on an accelerator, this allows duplicating information between
267 * the accelerator and the host to avoid multiple round trips
268 * if the connectivities are used on both simultaneously.
269 *
270 * If \a q is non-null and \a do_prefetch is true, then
271 * VariableUtils::prefetchVariableAsync() is called for each variable
272 * managing the connectivity.
273 */
274extern "C++" ARCANE_CORE_EXPORT void
275markMeshConnectivitiesAsMostlyReadOnly(IMesh* mesh, RunQueue* q = nullptr,
276 bool do_prefetch = false);
277
278/*---------------------------------------------------------------------------*/
279/*---------------------------------------------------------------------------*/
280
281/*
282 * \brief Returns the entity of the family \a family with unique ID \a unique_id.
283 *
284 * If no entity with this \a unique_id is found, returns the null entity.
285 *
286 * \pre family->hasUniqueIdMap() == true
287 */
288extern "C++" ARCANE_CORE_EXPORT ItemBase
289findOneItem(IItemFamily* family, Int64 unique_id);
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294/*
295 * \brief Returns the entity of the family \a family with unique ID \a unique_id.
296 *
297 * If no entity with this \a unique_id is found, returns the null entity.
298 *
299 * \pre family->hasUniqueIdMap() == true
300 */
301extern "C++" ARCANE_CORE_EXPORT ItemBase
302findOneItem(IItemFamily* family, ItemUniqueId unique_id);
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
306
307/*!
308 * \brief Visits all groups of \a family using the functor \a functor.
309 */
310extern "C++" ARCANE_CORE_EXPORT void
311visitGroups(IItemFamily* family, IFunctorWithArgumentT<ItemGroup&>* functor);
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316/*!
317 * \brief Visits all groups of \a mesh using the functor \a functor.
318 */
319extern "C++" ARCANE_CORE_EXPORT void
320visitGroups(IMesh* mesh, IFunctorWithArgumentT<ItemGroup&>* functor);
321
322/*---------------------------------------------------------------------------*/
323/*---------------------------------------------------------------------------*/
324
325/*!
326 * \brief Visits all groups of \a family using the lambda \a f.
327 *
328 * This function allows applying a visitor to all groups of the family \a family.
329 *
330 * For example:
331 *
332 * \code
333 * IMesh* mesh = ...;
334 * auto xx = [](const ItemGroup& x) { std::cout << "name=" << x.name(); };
335 * MeshUtils::visitGroups(mesh,xx);
336 * \endcode
337 */
338template <typename LambdaType> inline void
339visitGroups(IItemFamily* family, const LambdaType& f)
340{
342 // It must be cast to the correct type so that the compiler uses the correct overload.
344 visitGroups(family, sf_addr);
345}
346
347/*---------------------------------------------------------------------------*/
348/*---------------------------------------------------------------------------*/
349
350/*!
351 * \brief Visits all groups of \a mesh using the lambda \a f.
352 *
353 * This function allows applying a visitor to all groups of the families in
354 * the mesh \a mesh
355 *
356 * It is used as follows:
357 *
358 * \code
359 * IMesh* mesh = ...;
360 * auto xx = [](const ItemGroup& x) { std::cout << "name=" << x.name(); };
361 * MeshVisitor::visitGroups(mesh,xx);
362 * \endcode
363 */
364template <typename LambdaType> inline void
365visitGroups(IMesh* mesh, const LambdaType& f)
366{
368 // It must be cast to the correct type so that the compiler uses the correct overload.
370 visitGroups(mesh, sf_addr);
371}
372
373namespace impl
374{
375 inline Int64 computeCapacity(Int64 size)
376 {
378 }
379} // namespace impl
380
381/*---------------------------------------------------------------------------*/
382/*---------------------------------------------------------------------------*/
383
384/*!
385 * \brief Resizes an array that is indexed by 'ItemLocalId'.
386 *
387 * The array \a array is resized only if \a new_size is greater than the
388 * current size of the array or if \a force_resize is true.
389 *
390 * If the array is resized, additional capacity is reserved to avoid
391 * reallocating every time.
392 *
393 * This function is generally called for arrays indexed by an ItemLocalId,
394 * and therefore this function can be called every time an entity is added
395 * to the mesh.
396 *
397 * \retval true if a resize occurred
398 * \retval false otherwise
399 */
400template <typename DataType> inline bool
401checkResizeArray(Array<DataType>& array, Int64 new_size, bool force_resize)
402{
403 return Arcane::MemoryUtils::checkResizeArrayWithCapacity(array, new_size, force_resize);
404}
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
408
409/*!
410 * \brief Returns the maximum of the uniqueId() of the standard entities of the mesh.
411 *
412 * Standard entities are nodes, cells, faces, and edges.
413 * The operation is collective on mesh->parallelMng().
414 */
415extern "C++" ARCANE_CORE_EXPORT ItemUniqueId
416getMaxItemUniqueIdCollective(IMesh* mesh);
417
418/*---------------------------------------------------------------------------*/
419/*---------------------------------------------------------------------------*/
420
421/*!
422 * \brief Checks the hash of the uniqueId() of entities in a family.
423 *
424 * Calculates a hash of the uniqueId() of entities in a family using the
425 * \a hash_algo algorithm. For this calculation, rank 0 retrieves the set of
426 * uniqueIds() of the local entities of each subdomain, sorts them, and
427 * calculates the hash on the sorted array.
428 *
429 * Since most of the work is performed by rank 0, this method is not very
430 * extensible and should therefore only be used for testing purposes.
431 *
432 * \a expected_hash is the expected hash value in hexadecimal characters
433 * (obtained via Convert::toHexaString()). If \a expected_hash is not null,
434 * it compares the result with this value and, if different, throws a
435 * FatalErrorException.
436 *
437 * This operation is collective.
438 */
439extern "C++" ARCANE_CORE_EXPORT void
440checkUniqueIdsHashCollective(IItemFamily* family, IHashAlgorithm* hash_algo,
441 const String& expected_hash, bool print_hash_value,
442 bool include_ghost);
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
446
447/*!
448 * \brief Fills \a uids with the uniqueId() of the entities in \a view.
449 */
450extern "C++" ARCANE_CORE_EXPORT void
451fillUniqueIds(ItemVectorView items, Array<Int64>& uids);
452
453/*---------------------------------------------------------------------------*/
454/*---------------------------------------------------------------------------*/
455
456/*!
457 * \brief Creates or recreates a node-node connectivity via edges.
458 *
459 * The connectivity will be named \a connectivity_name.
460 */
461extern "C++" ARCANE_CORE_EXPORT Ref<IIndexedIncrementalItemConnectivity>
462computeNodeNodeViaEdgeConnectivity(IMesh* mesh, const String& connectivity_name);
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467/*!
468 * \brief Creates or recreates a node-node connectivity via edges for nodes
469 * on the boundary faces of the mesh.
470 *
471 * The connectivity will be named \a connectivity_name.
472 */
473extern "C++" ARCANE_CORE_EXPORT Ref<IIndexedIncrementalItemConnectivity>
474computeBoundaryNodeNodeViaEdgeConnectivity(IMesh* mesh, const String& connectivity_name);
475
476/*---------------------------------------------------------------------------*/
477/*---------------------------------------------------------------------------*/
478
479/*!
480 * \brief Determines the owners of the nodes.
481 *
482 * The determination is based on the owners of the cells.
483 * There should be no layers of ghost cells.
484 *
485 * This operation is collective.
486 */
487extern "C++" ARCANE_CORE_EXPORT void
488computeAndSetOwnerForNodes(IMesh* mesh);
489
490/*---------------------------------------------------------------------------*/
491/*---------------------------------------------------------------------------*/
492
493/*!
494 * \brief Determines the owners of the edges.
495 *
496 * The determination is based on the owners of the cells.
497 * There should be no layers of ghost cells.
498 *
499 * This operation is collective.
500 */
501extern "C++" ARCANE_CORE_EXPORT void
502computeAndSetOwnerForEdges(IMesh* mesh);
503
504/*---------------------------------------------------------------------------*/
505/*---------------------------------------------------------------------------*/
506
507/*!
508 * \brief Determines the owners of the faces.
509 *
510 * The determination is based on the owners of the cells.
511 * There should be no layers of ghost cells.
512 *
513 * This operation is collective.
514 */
515extern "C++" ARCANE_CORE_EXPORT void
516computeAndSetOwnerForFaces(IMesh* mesh);
517
518/*---------------------------------------------------------------------------*/
519/*---------------------------------------------------------------------------*/
520
521} // namespace Arcane::MeshUtils
522
523/*---------------------------------------------------------------------------*/
524/*---------------------------------------------------------------------------*/
525
526namespace Arcane::mesh_utils
527{
528// Used for compatibility with existing code.
529// These usings were added for Arcane version 3.10 (June 2023).
530// They can be deprecated starting in early 2024.
531using MeshUtils::checkMeshConnectivity;
532using MeshUtils::checkMeshProperties;
533using MeshUtils::computeConnectivityPatternOccurence;
534using MeshUtils::dumpSynchronizerTopologyJSON;
535using MeshUtils::getFaceFromNodesLocal;
536using MeshUtils::getFaceFromNodesUnique;
537using MeshUtils::printItems;
538using MeshUtils::printMeshGroupsMemoryUsage;
539using MeshUtils::removeItemAndKeepOrder;
540using MeshUtils::reorderNodesOfFace;
541using MeshUtils::reorderNodesOfFace2;
542using MeshUtils::shrinkMeshGroups;
543using MeshUtils::writeMeshConnectivity;
544using MeshUtils::writeMeshInfos;
545using MeshUtils::writeMeshInfosSorted;
546using MeshUtils::writeMeshItemInfo;
547
548/*---------------------------------------------------------------------------*/
549/*---------------------------------------------------------------------------*/
550
551} // namespace Arcane::mesh_utils
552
553/*---------------------------------------------------------------------------*/
554/*---------------------------------------------------------------------------*/
555
556#endif
bool checkResizeArray(Array< DataType > &array, Int64 new_size, bool force_resize)
Resizes an array that is indexed by 'ItemLocalId'.
Definition MeshUtils.h:401
bool reorderNodesOfFace(Int64ConstArrayView before_ids, Int64ArrayView after_ids)
Reorders the nodes of a face.
void visitGroups(IItemFamily *family, IFunctorWithArgumentT< ItemGroup & > *functor)
Visits all groups of family using the functor functor.
bool reorderNodesOfFace2(Int64ConstArrayView nodes_unique_id, Int32ArrayView new_index)
Reorders the nodes of a face.
Face getFaceFromNodesLocalId(Node node, Int32ConstArrayView face_nodes_local_id)
Searches for a face entity using the local numbers of these nodes.
Memory and allocator management functions.
Int64 computeCapacity(Int64 size)
Calculates an appropriate capacity for a size size.
Base class for 1D data vectors.
Face of a cell.
Definition Item.h:1032
Interface of a functor with an argument but without a return value.
Interface of a hashing algorithm.
Interface of an entity family.
Definition IItemFamily.h:83
Interface of a variable synchronization service.
Unique identifier of an entity.
View on a vector of entities.
Node of a mesh.
Definition Item.h:598
Reference to an instance.
Node of a DOM tree.
Definition XmlNode.h:51
Int32 checkResizeArrayWithCapacity(Array< DataType > &array, Int64 new_size, bool force_resize)
Resizes an array by adding a memory reserve.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:451
std::int64_t Int64
Signed integer type of 64 bits.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:480
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:453
@ Cell
The mesh is AMR by cell.
Definition MeshKind.h:53