Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
SplitSDMeshPartitioner.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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) 2008 */
9/* */
10/* Partitioneur de maillage reprenant le fonctionnement (simplifié) de SplitSD
11 utilisé à Dassault Aviation et développé à l'ONERA par EB en 1996-99
12*/
13/*---------------------------------------------------------------------------*/
14#ifndef ARCANE_FILES_SPLITSDMESHPARTITIONER_H
15#define ARCANE_FILES_SPLITSDMESHPARTITIONER_H
16
17// #define DEBUG_PARTITIONER
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21#include "arcane/std/MeshPartitionerBase.h"
22
23#include "arcane/cea/SplitSDMeshPartitioner_axl.h"
24
25
26#define MPICH_SKIP_MPICXX
27#define OMPI_SKIP_MPICXX
28#include <mpi.h>
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33ARCANE_BEGIN_NAMESPACE
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37#define TAG_MAILLAGEMAITRE 1
38
39#define CHECK_MPI_PACK_ERR(ier) \
40 if (ier != MPI_SUCCESS) { \
41 switch (ier) { \
42 case MPI_ERR_COMM:InfoProc->m_service->pfatal()<<"erreur sur MPI_Pack de type MPI_ERR_COMM"; break; \
43 case MPI_ERR_TYPE: InfoProc->m_service->pfatal()<<"erreur sur MPI_Pack de type MPI_ERR_TYPE"; break; \
44 case MPI_ERR_COUNT: InfoProc->m_service->pfatal()<<"erreur sur MPI_Pack de type MPI_ERR_COUNT"; break; \
45 case MPI_ERR_ARG: InfoProc->m_service->pfatal()<<"erreur sur MPI_Pack de type MPI_ERR_ARG"; break; \
46 default: InfoProc->m_service->pfatal()<<"erreur sur MPI_Pack de type inconnu !"; \
47 } \
48 }
49
50#ifndef CHECK_IF_NOT_NULL
51/**
52 Macros qui fait le test comme quoi le pointeur en argument n'est pas nul
53 et qui fait appel à pfatal() si ce pointeur s'avère nul.
54 Cette macro est à utiliser après tout appel à l'une des fonctions utilisant la mémoire
55 (malloc, calloc, realloc ...).
56
57 @memo Teste si un pointeur n'est pas nul.
58
59 @param Ptr un pointeur
60
61 @author Eric Brière de l'Isle, ONERA, DRIS/SRL
62
63*/
64#define CHECK_IF_NOT_NULL(Ptr) \
65 if (Ptr==NULL) { \
66 InfoProc->m_service->pfatal()<<"Pointeur vaut nil, (On manque peut-etre de place memoire !!! )"; \
67 }
68#endif
69
70#ifndef MAX
71#define MAX(a,b) ((a)<(b)?(b):(a))
72#endif
73#ifndef MIN
74#define MIN(a,b) ((a)>(b)?(b):(a))
75#endif
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78/** Structure décrivant un processeur.
79 @name StrucInfoProc
80*/
81typedef struct T_InfoProc
82{
83/*@{*/
84 /** Numéro du processeur, ce numéro est compris entre 0 et le nombre de processeurs moins un.*/
85 int me;
86 /** Nombre total de processeurs,
87 c'est le nombre maximum de processeurs que cette application
88 peut utiliser lors d'une exécution.*/
90// /** Numéro du processeur maître,
91// c'est sur ce processeur que sont faites l'agglomération,
92// l'insertion et le redécoupage.*/
93// int NoMaitre;
94 /** Groupe de travail sous MPI
95 (la définition d'un nouveau groupe permet de limiter la porté
96 des messages utilisés).*/
97 MPI_Comm Split_Comm;
98
99 /// Pour la gestion des traces (messages, erreurs, fatal ...)
101
102/*@}*/
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106/**
107 Structure pour le stockage des informations locales, pour éviter de les recalculer plusieurs fois.
108 Il s'agit essentiellement des noeuds sur les interfaces avec les différents domaines voisins.
109 EB, 2007. Simplification de StructureBlocEtendu
110*/
111
112
113typedef struct T_INTERFACE
114{
115 /** Elément permettant de décrire une interface avec un seul bloc voisin
116 @name StructureInterface
117 */
118
119 /** Numero du domaine voisin commence a 0 */
121 /** Liste Des Noeuds interface */
123
125
126
127typedef struct T_BLOC_ETENDU
128{
129 /** Elément permettant de décrire un bloc étendu et son environnement
130 @name StructureBlocEtendu
131 */
132
133 /** Nombre de mailles */
134 Integer NbElements;
135
136 /** Poids total du domaine */
137 double PoidsDom;
138
139 /** Nombre d'interfaces */
140 Integer NbIntf;
141
142 /** Tableau de structures d'interfaces, une pour chacun des voisins du bloc en question */
144
145
147/*---------------------------------------------------------------------------*/
148/*---------------------------------------------------------------------------*/
149/** Elément permettant de décrire une interface entre deux blocs.
150 @name StrucListeVoisMail
151 @see StrucListeDomMail
152*/
153typedef struct T_ListeVoisMail
154{
155/*@{*/
156 /** Numéro du domaine voisin (de 0 au nombre de processeurs moins un) */
158 /** Nombre de noeuds dans l'interface commune */
160 /** Quantité à transférer par cette interface */
161 double Delta;
162 /** Poids pour l'interface */
163// int PoidsInterface; pas de signification ici
164/*@}*/
166
167/** Elément pour décrire un bloc dans la description globale du maillage.
168 @name StrucListeDomMail
169 @see StrucMaillage
170*/
171typedef struct T_ListeDomMail
172{
173/*@{*/
174 /** Nombre d'éléments dans le domaine */
176 /** Poids pour le domaine */
177 double Poids;
178 /** Nombre de blocs voisins */
180 /** Liste de descripteurs pour les voisins */
182/*@}*/
184
185/** Structure permettant la description globale du maillage.\\
186
187 {\em Remarque:} le stockage des numéros globaux inutilisés
188 est effectué sur le processeur maître,
189 le maître peut changer aussi est-ce transmis au nouveau
190 maître lors de la mise à jour du maillage maître (\Ref{MAJMaillageMaitre}).
191
192 @name StrucMaillage
193 @see main, MAJMaillageMaitre
194*/
195typedef struct T_Maillage
196{
197/*@{*/
198 /** Nombre d'éléments dans le maillage global */
200 /** Nombre d'éléments dans le maillage global */
201 double Poids;
202
203 /** Nombre de blocs non vides */
205 /** Nombre de domaines total, c'est le nombre de processeurs attribués à cette session */
207 /** Liste (de taille NbDomainesMax) de descripteurs de blocs */
209
210 /** Nombre de processeurs dont le sous-domaine est vide */
212// /** Liste des processeurs sans sous-domaine */
213// int* ListeNoProcsVides;
214
215/*@}*/
217/*---------------------------------------------------------------------------*/
218/*---------------------------------------------------------------------------*/
219/*!
220 * \brief Partitioneur de maillage inspiré de la bibliothèque SplitSD, développé
221 * initialement à l'ONERA pour Dassault Aviation.
222 */
224: public ArcaneSplitSDMeshPartitionerObject
225 //: public MeshPartitionerBase
226{
227 public:
228
230
231 public:
232
233 virtual void build() {}
234
235 public:
236
237 virtual void partitionMesh(bool initial_partition);
238 virtual void partitionMesh(bool initial_partition,Int32 nb_part)
239 {
240 ARCANE_UNUSED(initial_partition);
241 ARCANE_UNUSED(nb_part);
242 throw NotImplementedException(A_FUNCINFO);
243 }
244
245 private:
246 /// initialisation des structures
247 void init(bool initial_partition, StrucInfoProc* &InfoProc, StructureBlocEtendu* &Domaine, StrucMaillage* &Maillage);
248
249 /// initialisation des poids (m_cells_weight => m_poids_aux_mailles)
250 void initPoids(bool initial_partition);
251
252 /// libération mémoire des structures
253 void fin (StrucInfoProc* &InfoProc, StructureBlocEtendu* &Domaine, StrucMaillage* &Maillage);
254
255 /// mise à jour de la structure locale (noeuds sur les interfaces avec sous-domaines voisins)
256 void MAJDomaine(StructureBlocEtendu* Domaine);
257
258 /// mise à jour de la structure sur le processeur 0
259 void MAJMaillageMaitre(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage);
260
261 /// fonction de vérification de la cohérence (réciprocité) des interfaces
262 void verifMaillageMaitre(StrucMaillage* Maillage);
263
264 /// On utilise une méthode de parcours frontal pour aller d'un noeud surchargé vers les autres noeuds en mémorisant le chemin pour mettre à jour les Delta sur les interfaces.
265 void MAJDeltaGlobal(StrucInfoProc* InfoProc, StrucMaillage* Maillage, double tolerance);
266 /// fonction de décalage du Delta associé à une interface recherchée pour un couple, domaine et numéro de voisin, spécifié
267 void MAJDelta(double don, int iDOmTmpPrec,int iDomTmp, StrucListeDomMail* ListeDomaines);
268
269 /// calcul un deltaMin en fonction des transferts locaux
270 double CalculDeltaMin(StrucMaillage* Maillage, double deltaMin, int iterEquilibrage, int NbMaxIterEquil);
271
272 /// phase itérative pour équilibrer la charge
273 void Equilibrage(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage);
274
275 /// phase de transfert entre 2 domaines, MAJ des domaines
276 void Equil2Dom(int* MasqueDesNoeuds, int* MasqueDesElements, int marqueVu, int marqueNonVu,
277 StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage,
278 int indDomCharge, int indDomVois, double Delta);
279
280 /// sélection d'éléments dans un domaine pour équilibrage entre 2 dom, en faisant un parcour frontal depuis l'interface
281 void SelectElements(int* MasqueDesNoeuds, int* MasqueDesElements, int marqueVu, int marqueNonVu,
282 StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine,
283 double Delta, int indDomVois, Arcane::Array<Arcane::Cell>& ListeElements);
284
285 /// parcours frontal limité suivant le Delta (poids cumulés des éléments pris dans les fronts), retourne un en cas de blocage
286 int ParcoursFrontalDelta (int* MasqueDesNoeuds, int* MasqueDesElements,
287 int marqueVu, int marqueNonVu,
288 double Delta,
289 int *pNbFronts, int NbFrontsMax,
290 Arcane::Array<Arcane::Node>& FrontsNoeuds, int* IndFrontsNoeuds,
291 Arcane::Array<Arcane::Cell>& FrontsElements,int* IndFrontsElements);
292
293 /** lissage du dernier front obtenu par parcours frontal,
294 de manière à intégrer dans ce front les éléments dont tous les noeuds
295 sont déjà pris dans les fronts précédents
296 */
297 void LissageDuFront (int* MasqueDesNoeuds, int* MasqueDesElements,
298 int marqueVu, int marqueNonVu,
299 int NbFronts,
300 Arcane::Array<Arcane::Node>& FrontsNoeuds, int* IndFrontsNoeuds,
301 Arcane::Array<Arcane::Cell>& FrontsElements,int* IndFrontsElements);
302
303 /// déplace des parties du sous-domaine lorsqu'elles sont trop petites et non connexes
304 void ConnexifieDomaine(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, StrucMaillage* Maillage, double tolConnexite);
305
306 /// recherche le domaine voisin ayant le max de Faces en commun avec le groupe de mailles
307 int getDomVoisMaxFace(Arcane::Array<Arcane::Cell>& ListeElements, int me);
308
309 /// création d'un tableau qui sert de masque sur les LocalId des noeuds
310 int* GetMasqueDesNoeuds(StrucInfoProc* InfoProc);
311 /// création d'un tableau qui sert de masque sur les LocalId des éléments
312 int* GetMasqueDesElements(StrucInfoProc* InfoProc);
313
314 void LibereInfoProc(StrucInfoProc* &InfoProc);
315 void LibereDomaine(StructureBlocEtendu* &Domaine);
316 void LibereMaillage(StrucMaillage* &Maillage);
317
318 void AfficheDomaine (int NbDom, StructureBlocEtendu* Domaine);
319 void AfficheMaillage (StrucMaillage* Maillage);
320 void AfficheListeDomaines(StrucListeDomMail* ListeDomaines, int NbDomaines);
321 void AfficheEquilMaillage(StrucMaillage* Maillage);
322
323
324 void* RecoitMessage (StrucInfoProc* InfoProc, int FromProc, int Tag, int *pTailleTMP);
325 void EnvoieMessage (StrucInfoProc* InfoProc, int ToProc, int Tag, void* TabTMP, int TailleTMP);
326// MPI_Request* EnvoieIMessage(StrucInfoProc* InfoProc, int ToProc, int Tag, void* TabTMP, int TailleTMP);
327 void* DiffuseMessage(StrucInfoProc* InfoProc, int FromProc, void* TabTMP, int TailleTMP);
328
329 // taille pour le transfert sans les noeuds, seulement la taille de ListeNoeuds
330 int TailleDom(StructureBlocEtendu* Domaine);
331 // les données sont mise dans un tableau
332 void PackDom(StrucInfoProc* InfoProc, StructureBlocEtendu* Domaine, void* TabTMP, int TailleTMP, MPI_Comm comm);
333 // les données sont extraite d'un tableau
334 void UnpackDom(void* TabTMP, int TailleTMP, MPI_Comm comm, StrucListeDomMail* DomMail);
335
336 // taille pour le transfert des numéros de domaine pour Equilibrage, et du Delta
337 int TailleEquil();
338 // les données sont mise dans un tableau
339 void PackEquil(StrucInfoProc* InfoProc, int indDomCharge, int indDomVois, double Delta, void* TabTMP, int TailleTMP, MPI_Comm comm);
340 // les données sont extraite d'un tableau
341 void UnpackEquil(void* TabTMP, int TailleTMP, MPI_Comm comm, int* indDomCharge, int* indDomVois, double* Delta);
342
343
344private:
345 VariableCellReal m_poids_aux_mailles; // poids que l'on calcul une fois par appel au rééquilibrage et qui suit les cellules
346};
347/*---------------------------------------------------------------------------*/
348/*---------------------------------------------------------------------------*/
349
350ARCANE_END_NAMESPACE
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
354
355#endif
Classe de base d'un service.
Structure contenant les informations pour créer un service.
Partitioneur de maillage inspiré de la bibliothèque SplitSD, développé initialement à l'ONERA pour Da...
Classe de base des vecteurs 1D de données.
Vecteur 1D de données avec sémantique par valeur (style STL).
Arcane::AbstractService * m_service
Pour la gestion des traces (messages, erreurs, fatal ...)
StrucListeVoisMail * ListeVoisins
StrucListeDomMail * ListeDomaines
StructureInterface * Intf
Arcane::UniqueArray< Arcane::Node > ListeNoeuds