Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
SplitSDMeshPartitioner.h
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/* SplitSDMeshPartitioner.h (C) 2000-2024 */
9/* */
10/* Mesh partitioner replicating the functionality of SplitSD. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_FILES_SPLITSDMESHPARTITIONER_H
13#define ARCANE_FILES_SPLITSDMESHPARTITIONER_H
14
15// #define DEBUG_PARTITIONER
16
17/*---------------------------------------------------------------------------*/
18/*---------------------------------------------------------------------------*/
19#include "arcane/std/MeshPartitionerBase.h"
20
21#include "arcane/std/SplitSDMeshPartitioner_axl.h"
22
23#define MPICH_SKIP_MPICXX
24#define OMPI_SKIP_MPICXX
25#include <mpi.h>
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35#define TAG_MAILLAGEMAITRE 1
36
37#define CHECK_MPI_PACK_ERR(ier) \
38 if (ier != MPI_SUCCESS) { \
39 switch (ier) { \
40 case MPI_ERR_COMM: \
41 InfoProc->m_service->pfatal() << "error on MPI_Pack of type MPI_ERR_COMM"; \
42 break; \
43 case MPI_ERR_TYPE: \
44 InfoProc->m_service->pfatal() << "error on MPI_Pack of type MPI_ERR_TYPE"; \
45 break; \
46 case MPI_ERR_COUNT: \
47 InfoProc->m_service->pfatal() << "error on MPI_Pack of type MPI_ERR_COUNT"; \
48 break; \
49 case MPI_ERR_ARG: \
50 InfoProc->m_service->pfatal() << "error on MPI_Pack of type MPI_ERR_ARG"; \
51 break; \
52 default: \
53 InfoProc->m_service->pfatal() << "error on MPI_Pack of unknown type !"; \
54 } \
55 }
56
57#ifndef CHECK_IF_NOT_NULL
71#define CHECK_IF_NOT_NULL(Ptr) \
72 if (Ptr == NULL) { \
73 InfoProc->m_service->pfatal() << "Pointer is null, (Perhaps we lack memory !!! )"; \
74 }
75#endif
76
77#ifndef MAX
78#define MAX(a, b) ((a) < (b) ? (b) : (a))
79#endif
80#ifndef MIN
81#define MIN(a, b) ((a) > (b) ? (b) : (a))
82#endif
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
88typedef struct T_InfoProc
89{
92 int me;
97 // /** Master processor number,
98 // this is the processor on which aggregation,
99 // insertion and repartitioning are performed.*/
100 // int NoMaitre;
104 MPI_Comm Split_Comm;
105
108
111/*---------------------------------------------------------------------------*/
112/*---------------------------------------------------------------------------*/
118
119typedef struct T_INTERFACE
120{
124
129
131
132typedef struct T_BLOC_ETENDU
133{
137
139 Integer NbElements;
140
142 double PoidsDom;
143
145 Integer NbIntf;
146
149
151/*---------------------------------------------------------------------------*/
152/*---------------------------------------------------------------------------*/
157typedef struct T_ListeVoisMail
158{
165 double Delta;
167 // int PoidsInterface; no meaning here
170
175typedef struct T_ListeDomMail
176{
181 double Poids;
188
199typedef struct T_Maillage
200{
205 double Poids;
206
213
216 // /** List of processors without a subdomain */
217 // int* ListeNoProcsVides;
218
221/*---------------------------------------------------------------------------*/
222/*---------------------------------------------------------------------------*/
227class SplitSDMeshPartitioner
229//: public MeshPartitionerBase
230{
231 public:
232
233 SplitSDMeshPartitioner(const ServiceBuildInfo& sbi);
234
235 public:
236
237 virtual void build() {}
238
239 public:
240
241 virtual void partitionMesh(bool initial_partition);
242 virtual void partitionMesh(bool initial_partition, Int32 nb_part)
243 {
244 ARCANE_UNUSED(initial_partition);
245 ARCANE_UNUSED(nb_part);
246 throw NotImplementedException(A_FUNCINFO);
247 }
248
249 private:
250
252 void init(bool initial_partition, StrucInfoProc*& InfoProc, StructureBlocEtendu*& Domaine, StrucMaillage*& Maillage);
253
255 void initPoids(bool initial_partition);
256
258 void fin(StrucInfoProc*& InfoProc, StructureBlocEtendu*& Domaine, StrucMaillage*& Maillage);
259
261 void MAJDomaine(StructureBlocEtendu* Domaine);
262
264 void MAJMaillageMaitre(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage);
265
267 void verifMaillageMaitre(StrucMaillage* Maillage);
268
270 void MAJDeltaGlobal(StrucInfoProc* InfoProc, StrucMaillage* Maillage, double tolerance);
272 void MAJDelta(double don, int iDOmTmpPrec, int iDomTmp, StrucListeDomMail* ListeDomaines);
273
275 double CalculDeltaMin(StrucMaillage* Maillage, double deltaMin, int iterEquilibrage, int NbMaxIterEquil);
276
278 void Equilibrage(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage);
279
281 void Equil2Dom(int* MasqueDesNoeuds, int* MasqueDesElements, int marqueVu, int marqueNonVu,
282 StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage,
283 int indDomCharge, int indDomVois, double Delta);
284
286 void SelectElements(int* MasqueDesNoeuds, int* MasqueDesElements, int marqueVu, int marqueNonVu,
287 StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine,
288 double Delta, int indDomVois, Arcane::Array<Arcane::Cell>& ListeElements);
289
291 int ParcoursFrontalDelta(int* MasqueDesNoeuds, int* MasqueDesElements,
292 int marqueVu, int marqueNonVu,
293 double Delta,
294 int* pNbFronts, int NbFrontsMax,
295 Arcane::Array<Arcane::Node>& FrontsNoeuds, int* IndFrontsNoeuds,
296 Arcane::Array<Arcane::Cell>& FrontsElements, int* IndFrontsElements);
297
302 void LissageDuFront(int* MasqueDesNoeuds, int* MasqueDesElements,
303 int marqueVu, int marqueNonVu,
304 int NbFronts,
305 Arcane::Array<Arcane::Node>& FrontsNoeuds, int* IndFrontsNoeuds,
306 Arcane::Array<Arcane::Cell>& FrontsElements, int* IndFrontsElements);
307
309 void ConnexifieDomaine(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage, double tolConnexite);
310
312 int getDomVoisMaxFace(Arcane::Array<Arcane::Cell>& ListeElements, int me);
313
315 int* GetMasqueDesNoeuds(StrucInfoProc* InfoProc);
317 int* GetMasqueDesElements(StrucInfoProc* InfoProc);
318
319 void LibereInfoProc(StrucInfoProc*& InfoProc);
320 void LibereDomaine(StructureBlocEtendu*& Domaine);
321 void LibereMaillage(StrucMaillage*& Maillage);
322
323 void AfficheDomaine(int NbDom, StructureBlocEtendu* Domaine);
324 void AfficheMaillage(StrucMaillage* Maillage);
325 void AfficheListeDomaines(StrucListeDomMail* ListeDomaines, int NbDomaines);
326 void AfficheEquilMaillage(StrucMaillage* Maillage);
327
328 void* RecoitMessage(StrucInfoProc* InfoProc, int FromProc, int Tag, int* pTailleTMP);
329 void EnvoieMessage(StrucInfoProc* InfoProc, int ToProc, int Tag, void* TabTMP, int TailleTMP);
330 // MPI_Request* EnvoieIMessage(StrucInfoProc* InfoProc, int ToProc, int Tag, void* TabTMP, int TailleTMP);
331 void* DiffuseMessage(StrucInfoProc* InfoProc, int FromProc, void* TabTMP, int TailleTMP);
332
333 // size for transfer without nodes, only the size of ListeNoeuds
334 int TailleDom(StructureBlocEtendu* Domaine);
335 // the data is put into an array
336 void PackDom(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, void* TabTMP, int TailleTMP, MPI_Comm comm);
337 // the data is extracted from an array
338 void UnpackDom(void* TabTMP, int TailleTMP, MPI_Comm comm, StrucListeDomMail* DomMail);
339
340 // size for domain transfer for Balancing, and for Delta
341 int TailleEquil();
342 // the data is put into an array
343 void PackEquil(StrucInfoProc* InfoProc, int indDomCharge, int indDomVois, double Delta, void* TabTMP, int TailleTMP, MPI_Comm comm);
344 // the data is extracted from an array
345 void UnpackEquil(void* TabTMP, int TailleTMP, MPI_Comm comm, int* indDomCharge, int* indDomVois, double* Delta);
346
347 private:
348
349 VariableCellReal m_poids_aux_mailles; // weight calculated once per rebalancing call and follows the cells
350};
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
354
355} // namespace Arcane
356
357/*---------------------------------------------------------------------------*/
358/*---------------------------------------------------------------------------*/
359
360#endif
Base class of a service.
ArcaneSplitSDMeshPartitionerObject(const Arcane::ServiceBuildInfo &sbi)
Constructeur.
Base class for 1D data vectors.
Structure containing the information to create a service.
void Equil2Dom(int *MasqueDesNoeuds, int *MasqueDesElements, int marqueVu, int marqueNonVu, StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage, int indDomCharge, int indDomVois, double Delta)
transfer phase between 2 domains, MAJ of domains
void ConnexifieDomaine(StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage, double tolConnexite)
makes the domain connected when parts are too small and not connected
double CalculDeltaMin(StrucMaillage *Maillage, double deltaMin, int iterEquilibrage, int NbMaxIterEquil)
calculates a deltaMin based on local transfers
void PackEquil(StrucInfoProc *InfoProc, int indDomCharge, int indDomVois, double Delta, void *TabTMP, int TailleTMP, MPI_Comm comm)
int * GetMasqueDesElements(StrucInfoProc *InfoProc)
creation of an array that serves as a mask on the LocalId of elements
int getDomVoisMaxFace(Arcane::Array< Arcane::Cell > &ListeElements, int me)
searches for the neighboring domain having the max number of shared Faces with the set of cells
void UnpackDom(void *TabTMP, int TailleTMP, MPI_Comm comm, StrucListeDomMail *DomMail)
void MAJDelta(double don, int iDOmTmpPrec, int iDomTmp, StrucListeDomMail *ListeDomaines)
function to shift the Delta associated with a searched interface for a pair, domain,...
int ParcoursFrontalDelta(int *MasqueDesNoeuds, int *MasqueDesElements, int marqueVu, int marqueNonVu, double Delta, int *pNbFronts, int NbFrontsMax, Arcane::Array< Arcane::Node > &FrontsNoeuds, int *IndFrontsNoeuds, Arcane::Array< Arcane::Cell > &FrontsElements, int *IndFrontsElements)
limited front-tracking following the Delta (cumulative weight of elements taken in the fronts),...
void initPoids(bool initial_partition)
initialization of weights (m_cells_weight => m_poids_aux_mailles)
void * RecoitMessage(StrucInfoProc *InfoProc, int FromProc, int Tag, int *pTailleTMP)
void MAJDomaine(StructureBlocEtendu *Domaine)
update of the local structure (nodes on interfaces with neighboring subdomains)
void EnvoieMessage(StrucInfoProc *InfoProc, int ToProc, int Tag, void *TabTMP, int TailleTMP)
void PackDom(StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, void *TabTMP, int TailleTMP, MPI_Comm comm)
void SelectElements(int *MasqueDesNoeuds, int *MasqueDesElements, int marqueVu, int marqueNonVu, StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, double Delta, int indDomVois, Arcane::Array< Arcane::Cell > &ListeElements)
selection of elements in a domain for balancing between 2 domains, by performing a front-tracking fro...
void * DiffuseMessage(StrucInfoProc *InfoProc, int FromProc, void *TabTMP, int TailleTMP)
int TailleDom(StructureBlocEtendu *Domaine)
Gives the size in bytes required for the memory storage of a domain (without the list of interface no...
void verifMaillageMaitre(StrucMaillage *Maillage)
consistency check (reciprocity) of the interfaces
void UnpackEquil(void *TabTMP, int TailleTMP, MPI_Comm comm, int *indDomCharge, int *indDomVois, double *Delta)
void LissageDuFront(int *MasqueDesNoeuds, int *MasqueDesElements, int marqueVu, int marqueNonVu, int NbFronts, Arcane::Array< Arcane::Node > &FrontsNoeuds, int *IndFrontsNoeuds, Arcane::Array< Arcane::Cell > &FrontsElements, int *IndFrontsElements)
void fin(StrucInfoProc *&InfoProc, StructureBlocEtendu *&Domaine, StrucMaillage *&Maillage)
memory freeing of structures
void MAJMaillageMaitre(StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage)
update of the structure on processor 0
virtual void partitionMesh(bool initial_partition)
void MAJDeltaGlobal(StrucInfoProc *InfoProc, StrucMaillage *Maillage, double tolerance)
We use a front-tracking method to go from an overloaded node to other nodes by memorizing the path to...
int * GetMasqueDesNoeuds(StrucInfoProc *InfoProc)
creation of an array that serves as a mask on the LocalId of nodes
void Equilibrage(StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage)
iterative phase to balance the load
void init(bool initial_partition, StrucInfoProc *&InfoProc, StructureBlocEtendu *&Domaine, StrucMaillage *&Maillage)
initialization of structures
virtual void build()
Build-level construction of the service.
1D data vector with value semantics (STL style).
MeshVariableScalarRefT< Cell, Real > VariableCellReal
Real type quantity at cell center.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int32_t Int32
Signed integer type of 32 bits.
Arcane::AbstractService * m_service
For trace management (messages, errors, fatal ...).
StrucListeVoisMail * ListeVoisins
StrucListeDomMail * ListeDomaines
StructureInterface * Intf
Arcane::UniqueArray< Arcane::Node > ListeNoeuds