19#include "arcane/utils/PlatformUtils.h"
20#include "arcane/utils/ArcanePrecomp.h"
21#include "arcane/utils/Convert.h"
22#include "arcane/utils/Array.h"
24#include "arcane/core/ISubDomain.h"
25#include "arcane/core/IParallelMng.h"
27#include "arcane/core/IPrimaryMesh.h"
28#include "arcane/core/Properties.h"
29#include "arcane/core/ItemGroup.h"
30#include "arcane/core/Service.h"
31#include "arcane/core/Timer.h"
32#include "arcane/core/FactoryService.h"
33#include "arcane/core/ItemPrinter.h"
34#include "arcane/core/IItemFamily.h"
35#include "arcane/core/MeshVariable.h"
36#include "arcane/core/VariableBuildInfo.h"
37#include "arcane/std/MeshPartitionerBase.h"
38#include "arcane/std/SplitSDMeshPartitioner.h"
50SplitSDMeshPartitioner::
55 info() <<
"SplitSDMeshPartitioner::SplitSDMeshPartitioner(...)";
61void SplitSDMeshPartitioner::
62partitionMesh(
bool initial_partition)
64 info() <<
"Equilibrage de charge avec SplitSDMeshPartitioner";
70 _initArrayCellsWithConstraints();
71 if (haveConstraints())
72 throw FatalErrorException(
"SplitSDMeshPartitioner: On ne supporte pas les contraintes avec SplitSD");
81 init(initial_partition, InfoProc, Domaine, Maillage);
87 fin(InfoProc, Domaine, Maillage);
91void SplitSDMeshPartitioner::
94 info() <<
"SplitSDMeshPartitioner::init("<<initial_partition<<
",...)";
106 InfoProc->
Split_Comm = *(MPI_Comm*)getCommunicator();
112 if (!initial_partition){
113 info() <<
"Initialize new owners";
119 cells_new_owner[icell] = cell.
owner();
122 cells_new_owner.synchronize();
130 Domaine->
Intf = NULL;
144 Maillage->
Poids = 0.0;
151void SplitSDMeshPartitioner::
152initPoids(
bool initial_partition)
154 ARCANE_UNUSED(initial_partition);
168 m_poids_aux_mailles[iitem] = cell_weights[iitem.index()];
173void SplitSDMeshPartitioner::
176 info() <<
"SplitSDMeshPartitioner::fin(...)";
177 LibereInfoProc(InfoProc);
178 LibereDomaine(Domaine);
179 LibereMaillage(Maillage);
191void SplitSDMeshPartitioner::
194 debug() <<
" ----------------------------------------";
195 debug() <<
"SplitSDMeshPartitioner::MAJDomaine(...)";
197 LibereDomaine(Domaine);
199 int me = subDomain()->subDomainId();
205 debug() <<
" all_faces.size() = =" <<all_faces.
size();
207 std::map<int, SharedArray<Face> > vois_faces;
210 const Face face = *i_item;
234 filtreNoeuds.
fill(0);
250 Domaine->
PoidsDom += m_poids_aux_mailles[cell];
254 info() <<
"Domaine->NbIntf = "<<Domaine->
NbIntf;
260 unsigned int ind = 0;
262 iter_vois!=vois_faces.end(); ++iter_vois) {
271 info() <<
" v_face.size() = "<<v_face.
size();
274 for (
int i = 0; i<v_face.
size(); i++){
275 const Face& face = v_face[i];
282 if (filtreNoeuds[node_local_id] != marque){
284 filtreNoeuds[node_local_id] = marque;
297 info() <<
"MAJDomaine => ";
298 AfficheDomaine(1,Domaine);
299 info() <<
" ----------------------------------------";
304void SplitSDMeshPartitioner::
310 info() <<
"SplitSDMeshPartitioner::MAJMaillageMaitre(...)";
311 LibereMaillage(Maillage);
320 TabTMP = malloc ((
size_t) TailleTab);
327 if (InfoProc->
me == 0){
329 info()<<
" ***************************";
330 info()<<
" * Avant MAJMaillageMaitre *";
331 AfficheMaillage (Maillage);
332 info()<<
" ***************************";
348 EnvoieMessage(InfoProc, 0, TAG_MAILLAGEMAITRE, TabTMP, TailleTab);
360 if (InfoProc->
me == 0){
363 Maillage->
Poids = 0.0;
367 for (iDom=InfoProc->
nbSubDomain-1; iDom>=0; iDom--){
371 TabTMP =
RecoitMessage(InfoProc, iDom, TAG_MAILLAGEMAITRE, &TailleTab);
375 free ((
void*) TabTMP); TabTMP = NULL;
389 info()<<
" ***************************";
390 info()<<
" * Apres MAJMaillageMaitre *";
392 AfficheMaillage (Maillage);
394 info()<<
" ***************************";
402void SplitSDMeshPartitioner::
406 info()<<
" on entre dans verifMaillageMaitre";
411 for (
int iDom=0; iDom<NbDomaines; iDom++){
412 for (
int j=0; j<ListeDomaines[iDom].
NbVoisins; j++){
421 if (k==ListeDomaines[iVois].NbVoisins){
422 printf(
"on ne trouve pas le numéro de voisin \n");
423 printf(
"pour info: iDom = %d, iVois = %d\n",iDom,iVois);
424 perror() <<
"verifMaillageMaitre en erreur sur le voisinage !!!";
427 if (ListeDomaines[iVois].ListeVoisins[k].NbNoeudsInterface != NbNoeudsInterface){
428 printf(
"on ne trouve pas le même nombre de noeuds entre les voisins \n");
429 printf(
"pour info: iDom = %d, iVois = %d, NbNoeudsInterface %d != %d\n"
430 ,iDom,iVois,NbNoeudsInterface,ListeDomaines[iVois].ListeVoisins[k].NbNoeudsInterface);
431 perror() <<
"verifMaillageMaitre en erreur sur le nombre de noeuds !!!";
436 info()<<
" on sort de verifMaillageMaitre";
438 ARCANE_UNUSED(Maillage);
443void SplitSDMeshPartitioner::
461 int* ListeNoeudsPrec;
465 int marqueDomNonVu = 0;
466 int marqueDomVide = -1;
471 info()<<
" ------------------------------------";
472 info()<<
" on entre dans MAJDeltaGlobal, tolerance = "<<tolerance;
473 info()<<
" ------------------------------------";
474 info()<<
" ......... Maillage Initial ...........";
475 AfficheListeDomaines(ListeDomaines,NbDomaines);
479 info()<<
" SplitSDMeshPartitioner::MAJDeltaGlobal : NbDomaines nul !";
484 info()<<
" \n = on sort de MAJDeltaGlobal sans rien faire (NbDomainesPleins = "<<Maillage->
NbDomainesPleins;
485 info()<<
" ------------------------------------";
490 FiltreDomaine = (
int*) malloc ((
size_t) NbDomaines*
sizeof(
int));
491 CHECK_IF_NOT_NULL(FiltreDomaine);
494 for (i=0; i<NbDomaines; i++)
495 for (
int j=0; j<ListeDomaines[i].
NbVoisins; j++)
496 ListeDomaines[i].ListeVoisins[j].Delta = 0.0;
503 for (i=0; i<NbDomaines; i++){
504 if (ListeDomaines[i].NbElements != 0)
505 FiltreDomaine[i] = marqueDomNonVu;
507 FiltreDomaine[i] = marqueDomVide;
510 PoidsSave = (
double*) malloc ((
size_t) NbDomaines*
sizeof(
double));
511 CHECK_IF_NOT_NULL(PoidsSave);
517 for (i=0; i<NbDomaines; i++){
519 PoidsSave[i] = ListeDomaines[i].
Poids;
521 if (FiltreDomaine[i] != marqueDomVide)
522 ListeDomaines[i].
Poids -= PoidsMoyen;
526 info()<<
" Après Poids -= PoidsMoyen";
527 AfficheListeDomaines(ListeDomaines,NbDomaines);
531 FrontPrec = (
int*) malloc ((
size_t) (NbDomaines-1)*
sizeof(
int));
532 CHECK_IF_NOT_NULL(FrontPrec);
533 FrontSuiv = (
int*) malloc ((
size_t) (NbDomaines-1)*
sizeof(
int));
534 CHECK_IF_NOT_NULL(FrontSuiv);
536 ListeNoeudsPrec = (
int*) malloc ((
size_t) (NbDomaines)*
sizeof(
int));
537 CHECK_IF_NOT_NULL(ListeNoeudsPrec);
539 for (iDomDep=0; iDomDep<NbDomaines; iDomDep++){
541 info()<<
" ListeDomaines[iDomDep = "<<iDomDep<<
"].Poids = "<<ListeDomaines[iDomDep].
Poids;
546 if (ListeDomaines[iDomDep].Poids > tolerance){
550 for (i=0; i<NbDomaines; i++)
551 if (FiltreDomaine[i] == marqueDomVu)
552 FiltreDomaine[i] = marqueDomNonVu;
555 FiltreDomaine[iDomDep] = marqueDomVu;
559 FrontSuiv[tailleFS-1] = iDomDep;
562 info()<<
" FrontSuiv[0] = "<<iDomDep;
566 ListeNoeudsPrec[FrontSuiv[tailleFS-1]] = -1;
569 while (ListeDomaines[iDomDep].Poids > tolerance){
571 info()<<
" while (ListeDomaines["<<iDomDep<<
"].Poids = "<<ListeDomaines[iDomDep].
Poids<<
" > "<<tolerance;
575 FrontTMP = FrontPrec;
576 FrontPrec = FrontSuiv;
577 FrontSuiv = FrontTMP;
584 fatal()<<
" partitionner/MAJDeltaGlobal: on ne trouve plus de domaine alors que l'on n'a pas terminé !!!";
592 for (
int iFP=0; iFP<tailleFP; iFP++){
593 int iDom = FrontPrec[iFP];
596 for (
int iVois=0; iVois<ListeDomaines[iDom].
NbVoisins; iVois++){
598 if (FiltreDomaine[iDomVois] == marqueDomNonVu){
600 FiltreDomaine[iDomVois] = marqueDomVu;
601 ListeNoeudsPrec[iDomVois] = iDom;
603 info()<<
" FrontSuiv["<<tailleFS<<
"] = "<<iDomVois;
605 FrontSuiv[tailleFS++] = iDomVois;
616 for (
int iFS=0; iFS<tailleFS; iFS++){
617 int iDom = FrontSuiv[iFS];
620 info()<<
" ListeDomaines["<<iDom<<
"].Poids = "<<ListeDomaines[iDom].
Poids;
624 if (ListeDomaines[iDom].Poids < 0.0){
626 double don = MIN(-ListeDomaines[iDom].Poids, ListeDomaines[iDomDep].Poids);
633 ListeDomaines[iDom].
Poids += don;
634 ListeDomaines[iDomDep].
Poids -= don;
641 iDomTmpPrec = ListeNoeudsPrec[iDomTmp];
642 while (iDomTmpPrec != -1){
644 MAJDelta(don,iDomTmpPrec,iDomTmp,ListeDomaines);
646 MAJDelta(-don,iDomTmp,iDomTmpPrec,ListeDomaines);
649 iDomTmp = iDomTmpPrec;
650 iDomTmpPrec = ListeNoeudsPrec[iDomTmp];
665 for (i=0; i<NbDomaines; i++)
666 ListeDomaines[i].Poids = PoidsSave[i];
668 free((
void*) FrontPrec); FrontPrec = NULL;
669 free((
void*) FrontSuiv); FrontSuiv = NULL;
670 free((
void*) ListeNoeudsPrec); ListeNoeudsPrec = NULL;
671 free((
void*) FiltreDomaine); FiltreDomaine = NULL;
672 free((
void*) PoidsSave); PoidsSave = NULL;
675 info()<<
" ......... Maillage Final ...........";
676 AfficheListeDomaines(ListeDomaines,NbDomaines);
677 info()<<
" = on sort de MAJDeltaGlobal =";
678 info()<<
" ------------------------------------";
683void SplitSDMeshPartitioner::
694 if (j == ListeDomaines[iDom].NbVoisins)
696 info()<<
"on ne trouve pas le numéro de voisin";
697 info()<<
"pour info: ajout = "<<ajout<<
", iDom = "<<iDom<<
", iVois = "<<iVois;
698 pfatal()<<
"Erreur dans Partitionner/MAJDelta, pas de voisin !";
707double SplitSDMeshPartitioner::
708CalculDeltaMin(
StrucMaillage* Maillage,
double deltaMin,
int iterEquilibrage,
int NbMaxIterEquil)
715 debug()<<
" on entre dans SplitSDMeshPartitioner::CalculDeltaMin, deltaMin = "<<deltaMin
716 <<
", iterEquilibrage = " <<iterEquilibrage
717 <<
", NbMaxIterEquil = " <<NbMaxIterEquil;
719 AfficheMaillage (Maillage);
721 double deltaAjuste = deltaMin;
724 double deltaMaxItf = 0.0;
726 double ratioDeltaMax = 0.0;
731 for (
int iDom=0; iDom<NbDomaines; iDom++){
732 double deltaTotalDom = 0.0;
733 for (
int j=0; j<ListeDomaines[iDom].
NbVoisins; j++){
735 deltaMaxItf = MAX(delta, deltaMaxItf);
736 if (delta > 0.0) deltaTotalDom += delta;
739 if (ListeDomaines[iDom].Poids>0.0)
740 ratio = deltaTotalDom/ ListeDomaines[iDom].
Poids;
741 ratioDeltaMax = MAX(ratio,ratioDeltaMax);
747 if (ratioDeltaMax>0.9)
748 deltaAjuste = poidsMoy/3.0;
749 else if (ratioDeltaMax>0.5)
750 deltaAjuste = deltaMaxItf/10.0;
753 deltaAjuste = MAX(deltaMin,deltaAjuste);
755#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
757 double proportion = deltaMaxItf/poidsMoy;
759 info()<<
" deltaMaxItf = "<<deltaMaxItf;
760 info()<<
" ratioDeltaMax = "<<ratioDeltaMax;
761 info()<<
" poidsMoy = "<<poidsMoy;
762 info()<<
" proportion = "<<proportion;
763 info()<<
" deltaAjuste = "<<deltaAjuste;
770void SplitSDMeshPartitioner::
774 int indDomCharge = -1;
785 int NbAppelsAEquil2Dom = -1;
787 int iterEquilibrage = 0;
788 int NbMaxIterEquil = 5;
790 double tolConnexite = 0.1;
794 info()<<
" -------------------------------------";
795 info()<<
" on entre dans SplitSDMeshPartitioner::Equilibrage, deltaMin = "<<deltaMin;
799 TabTMP = malloc((
size_t)TailleTMP);
800 CHECK_IF_NOT_NULL(TabTMP);
803 while (iterEquilibrage<NbMaxIterEquil && NbAppelsAEquil2Dom!=0){
806 int marqueDomNonVu = 0;
809 NbAppelsAEquil2Dom = 0;
822 if (InfoProc->
me == 0){
823 info()<<
" SplitSDMeshPartitioner::Equilibrage de la charge (iteration No "<<iterEquilibrage<<
")";
829 double deltaAjuste =
CalculDeltaMin(Maillage, deltaMin, iterEquilibrage, NbMaxIterEquil);
832 FiltreDomaine = (
int*) calloc ((
size_t) Maillage->
NbDomainesMax,
sizeof(
int));
833 CHECK_IF_NOT_NULL(FiltreDomaine);
838 FiltreDomaine[iDom] = marqueDomVu;
848 if (FiltreDomaine[iDom] == marqueDomNonVu && Maillage->
ListeDomaines[iDom].
Poids > poidsMax){
854 info()<<
"indDomCharge = "<<indDomCharge<<
"; poidsMax = "<<poidsMax;
857 if (indDomCharge != -1) {
859 FiltreDomaine[indDomCharge] = marqueDomVu;
871#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
872 info()<<
" Equilibrage ("<<iterEquilibrage<<
") pour le couple indDomCharge = "<<indDomCharge<<
"; indDomVois = "<<indDomVois
886 Equil2Dom(MasqueDesNoeuds, MasqueDesElements, marqueVu, marqueNonVu,
887 InfoProc, Domaine, Maillage, indDomCharge, indDomVois,
889 NbAppelsAEquil2Dom += 1;
895 }
while (indDomCharge != -1);
898 double DeltaNul = 0.0;
899 PackEquil(InfoProc, indDomCharge, indDomVois, DeltaNul, TabTMP, TailleTMP, InfoProc->
Split_Comm);
903 free((
void*) FiltreDomaine);
904 FiltreDomaine = NULL;
908 info()<<
" NbAppelsAEquil2Dom = "<<NbAppelsAEquil2Dom;
919 if (indDomCharge != -1){
924 Equil2Dom(MasqueDesNoeuds, MasqueDesElements, marqueVu, marqueNonVu,
925 InfoProc, Domaine, Maillage, indDomCharge, indDomVois, Delta);
926 NbAppelsAEquil2Dom += 1;
929 }
while(indDomCharge != -1);
934 if (NbAppelsAEquil2Dom){
936 LibereDomaine(Domaine);
939 info() <<
"cells_new_owner.synchronize() et changeOwnersFromCells()";
943 cells_new_owner.synchronize();
946 bool compact =
mesh->properties()->getBool(
"compact");
947 mesh->properties()->setBool(
"compact",
false);
948 mesh->exchangeItems();
949 mesh->properties()->setBool(
"compact", compact);
958 free((
void*)MasqueDesNoeuds);
959 MasqueDesNoeuds = NULL;
960 free((
void*)MasqueDesElements);
961 MasqueDesElements = NULL;
963 AfficheEquilMaillage(Maillage);
970 AfficheEquilMaillage(Maillage);
977 debug()<<
" nombre d'iterations pour equilibrage = "<<iterEquilibrage<<
" / "<<NbMaxIterEquil<<
" max ";
978 debug()<<
" = on sort de SplitSDMeshPartitioner::Equilibrage";
979 debug()<<
" -------------------------------------";
985void SplitSDMeshPartitioner::
986Equil2Dom(
int* MasqueDesNoeuds,
int* MasqueDesElements,
int marqueVu,
int marqueNonVu,
988 int indDomCharge,
int indDomVois,
double Delta)
990 ARCANE_UNUSED(Maillage);
992 debug()<<
" on entre dans Equil2Dom (indDomCharge:"<<indDomCharge<<
", indDomVois:"<<indDomVois<<
", Delta:"<<Delta;
997 if (InfoProc->
me == indDomCharge){
1006 if (iIntf==Domaine->
NbIntf){
1007#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
1008 pinfo()<<
"### l'interface a disparu ### entre "<<indDomCharge<<
" et " <<indDomVois;
1014 marqueVu, marqueNonVu,
1015 InfoProc, Domaine, Delta, indDomVois, ListeElements);
1023 for (
int i=0; i<ListeElements.
size(); i++){
1024 const Cell item = ListeElements[i];
1025 cells_new_owner[item] = indDomVois;
1031 info() <<
"SelectElements et autres operations sur les processeurs "<<indDomCharge<<
" et " <<indDomVois;
1034 info()<<
" on sort de Equil2Dom";
1039void SplitSDMeshPartitioner::
1040SelectElements(
int* MasqueDesNoeuds,
int* MasqueDesElements,
int marqueVu,
int marqueNonVu,
1045 info()<<
"SplitSDMeshPartitioner::SelectElements(Domaine, Delta = "<<Delta<<
", indDomVois = "<<indDomVois<<
")";
1051 perror() <<
"Delta <= 0 !!!";
1058 pinfo()<<
" Tout le domaine est sélectionné sur le domaine "<<subDomain()->subDomainId()
1059 <<
", avec SelectElements, PoidsDom = " << Domaine->
PoidsDom
1060 <<
", Delta = "<<Delta;
1066 const Cell item = *i_item;
1068 ListeElements.
add(item);
1076 int* IndFrontsNoeuds;
1077 int* IndFrontsElements;
1079 for (iIntf=0; iIntf<Domaine->
NbIntf && Domaine->
Intf[iIntf].
NoDomVois != indDomVois; iIntf++)
1082 if (iIntf==Domaine->
NbIntf) {
1083 pfatal()<<
" SelectElements ne trouve pas l'interface parmis les voisins !!!";
1094 IndFrontsNoeuds = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1095 CHECK_IF_NOT_NULL(IndFrontsNoeuds);
1097 IndFrontsElements = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1098 CHECK_IF_NOT_NULL(IndFrontsElements);
1107 IndFrontsNoeuds[0] = 0;
1109 IndFrontsElements[0] = 0;
1110 IndFrontsElements[1] = 0;
1113 int me = subDomain()->subDomainId();
1116 const Cell cell = *i_item;
1117 if (cell.
owner() != me)
1118 MasqueDesElements[cell.
localId()] = marqueVu;
1122 for (
int i=0; i<ListeElements.
size(); i++){
1123 const Cell cell = ListeElements[i];
1124 MasqueDesElements[cell.
localId()] = marqueVu;
1131 marqueVu, marqueNonVu,
1133 &NbFronts, NbFrontsMax,
1134 FrontsNoeuds, IndFrontsNoeuds,
1135 FrontsElements,IndFrontsElements);
1139 IndFrontsNoeuds[NbFronts-1] = IndFrontsNoeuds[NbFronts];
1140 IndFrontsElements[NbFronts-1] = IndFrontsElements[NbFronts];
1148 marqueVu, marqueNonVu,
1150 FrontsNoeuds, IndFrontsNoeuds,
1151 FrontsElements,IndFrontsElements);
1154 free((
void*)IndFrontsNoeuds); IndFrontsNoeuds = NULL;
1155 free((
void*)IndFrontsElements); IndFrontsElements = NULL;
1158 info()<<
" en sortie: ListeElements.size() = "<<ListeElements.
size();
1162int SplitSDMeshPartitioner::
1163ParcoursFrontalDelta (
int* MasqueDesNoeuds,
int* MasqueDesElements,
1164 int marqueVu,
int marqueNonVu,
1166 int *pNbFronts,
int NbFrontsMax,
1171 info()<<
" = on entre dans ParcoursFront : (NbFronts = "<<*pNbFronts<<
", NbFrontsMax = "<<NbFrontsMax<<
")";
1172 info()<<
" FrontsNoeuds.size() = "<<FrontsNoeuds.
size();
1173 info()<<
" FrontsElements.size() = "<<FrontsElements.
size();
1178 double PoidsActuel = 0.0;
1179 bool bloque =
false;
1182 for (IndFn=0; IndFn<IndFrontsNoeuds[*pNbFronts]; IndFn++){
1183 MasqueDesNoeuds[FrontsNoeuds[IndFn].localId()] = marqueVu;
1186 for (IndFe=0; IndFe<IndFrontsElements[*pNbFronts]; IndFe++){
1187 MasqueDesElements[FrontsElements[IndFe].localId()] = marqueVu;
1192 if (IndFrontsElements[*pNbFronts] > 0 && IndFrontsNoeuds[*pNbFronts] == 0){
1194 for (
int ielm=0; ielm<IndFrontsElements[*pNbFronts]; ielm++){
1195 const Cell cell = FrontsElements[ielm];
1196 PoidsActuel += m_poids_aux_mailles[cell];
1198 for (
int iepn = 0; iepn < cell.
nbNode(); iepn++){
1199 const Node nodeVois = cell.
node(iepn);
1202 if (MasqueDesNoeuds[nodeVois.
localId()] == marqueNonVu){
1203 FrontsNoeuds.
add(nodeVois);
1205 MasqueDesNoeuds[nodeVois.
localId()] = marqueVu;
1210 IndFrontsNoeuds[*pNbFronts] = IndFn;
1218 for (
int in = IndFrontsNoeuds[*pNbFronts-1];
1219 in < IndFrontsNoeuds[*pNbFronts] && PoidsActuel<Delta;
1221 const Node node = FrontsNoeuds[in];
1225 for (
int inpe = 0; inpe < node.
nbCell(); inpe++){
1230 if (MasqueDesElements[cell.
localId()] == marqueNonVu) {
1231 FrontsElements.
add(cell);
1233 MasqueDesElements[cell.
localId()] = marqueVu;
1235 PoidsActuel += m_poids_aux_mailles[cell];
1237 for (
int iepn = 0; iepn < cell.
nbNode(); iepn++){
1238 const Node nodeVois = cell.
node(iepn);
1241 if (MasqueDesNoeuds[nodeVois.
localId()] == marqueNonVu){
1242 FrontsNoeuds.
add(nodeVois);
1244 MasqueDesNoeuds[nodeVois.
localId()] = marqueVu;
1252 if (IndFrontsNoeuds[*pNbFronts-1] == IndFrontsNoeuds[*pNbFronts]){
1257 IndFrontsNoeuds[*pNbFronts] = IndFn;
1258 IndFrontsElements[*pNbFronts] = IndFe;
1261 while (*pNbFronts<NbFrontsMax && PoidsActuel<Delta && !bloque);
1265 info()<<
" NbFronts = "<<*pNbFronts;
1266 info()<<
" Delta = "<<Delta;
1267 info()<<
" PoidsActuel = "<<PoidsActuel;
1268 info()<<
" NbNoeuds = "<<IndFrontsNoeuds[*pNbFronts];
1269 info()<<
" NbElements = "<<IndFrontsElements[*pNbFronts];
1270 info()<<
" bloque = "<<(bloque?
"VRAI":
"FAUX");
1272 if (!(*pNbFronts<NbFrontsMax)){
1273 info()<<
" = on arete apres avoir obtenu le nombre maximum de fronts "<<NbFrontsMax;
1275 else if (!(PoidsActuel<Delta)){
1276 info()<<
" = on arete apres avoir obtenu le poids desire "<<PoidsActuel;
1279 info()<<
" = on est bloque (non connexe ?) =";
1282 info()<<
" = on arete parce que l'on a tout vu =";
1284 info()<<
" = on sort de ParcoursFront . =";
1287 return ((bloque)?1:0);
1292void SplitSDMeshPartitioner::
1293LissageDuFront (
int* MasqueDesNoeuds,
int* MasqueDesElements,
1294 int marqueVu,
int marqueNonVu,
1299 ARCANE_UNUSED(IndFrontsElements);
1301 debug()<<
" on entre dans LissageDuFront : NbFronts = "<<NbFronts;
1303 int NbElementsAjoutes = 0;
1308 for (
int IndFn=IndFrontsNoeuds[NbFronts-1]; IndFn<IndFrontsNoeuds[NbFronts]; IndFn++){
1309 const Node node = FrontsNoeuds[IndFn];
1311 for (
int inpe = 0; inpe < node.
nbCell(); inpe++){
1315 if (MasqueDesElements[cell.
localId()] == marqueNonVu){
1318 for (iepn = 0; iepn < cell.
nbNode() && MasqueDesNoeuds[cell.
node(iepn).
localId()] == marqueVu; iepn++)
1321 if (iepn == cell.
nbNode()){
1324 FrontsElements.
add(cell);
1325 NbElementsAjoutes+=1;
1326 MasqueDesElements[cell.
localId()] = marqueVu;
1330 MasqueDesElements[cell.
localId()] = marqueVu;
1331 ElementsALiberer.
add(cell);
1339 for (
int i=0; i<ElementsALiberer.
size(); i++)
1340 MasqueDesElements[ElementsALiberer[i].localId()] = marqueNonVu;
1343 info()<<
" on sort de LissageDuFront ("<<NbElementsAjoutes<<
" elements ajoutes)";
1348void SplitSDMeshPartitioner::
1350 double tolConnexite)
1353 info()<<
" on entre dans ConnexifieDomaine, tolConnexite = "<<tolConnexite;
1359 int marqueNonVu = 0;
1363 double tailleMoy = (double)Domaine->
NbElements;
1366 int me = InfoProc->
me;
1371 Cell cell = *i_item;
1372 if (cell.
owner() != me)
1373 MasqueDesElements[cell.
localId()] = marqueVu;
1376 int NbElementsVus = 0;
1379 info()<<
" NbElementsAVoir = "<<NbElementsAVoir;
1384 int* IndFrontsNoeuds;
1385 int* IndFrontsElements;
1395 IndFrontsNoeuds = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1396 CHECK_IF_NOT_NULL(IndFrontsNoeuds);
1398 IndFrontsElements = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1399 CHECK_IF_NOT_NULL(IndFrontsElements);
1403 while (NbElementsVus < NbElementsAVoir){
1405 FrontsNoeuds.
clear();
1410 bool trouve =
false;
1412 const Cell cell = *i_item;
1413 if (!trouve && MasqueDesElements[cell.
localId()] == marqueNonVu){
1414 FrontsElements.
add(cell);
1419 pfatal()<<
"ConnexifieDomaine est bloqué lors de la recherche d'un élément de départ";
1423 IndFrontsNoeuds[0] = 0;
1424 IndFrontsNoeuds[1] = 0;
1425 IndFrontsElements[0] = 0;
1426 IndFrontsElements[1] = 1;
1430 marqueVu, marqueNonVu,
1432 &NbFronts, NbFrontsMax,
1433 FrontsNoeuds, IndFrontsNoeuds,
1434 FrontsElements,IndFrontsElements);
1437 ListeFrontsElements.
add(FrontsElements);
1439 NbElementsVus+=FrontsElements.
size();
1441 info()<<
" NbElementsVus+="<<FrontsElements.
size();
1450 if (ListeFrontsElements.
size() > 1){
1453 info()<<
" NbComposantesConnexes = "<<ListeFrontsElements.
size();
1457 int nbDomEnDessous = 0;
1458 int plusGrosseCC = 0;
1460 int seuil = (int)(tailleMoy*tolConnexite);
1462 info()<<
" seuil = "<<seuil;
1465 for (
int i=0; i<ListeFrontsElements.
size(); i++){
1467 plusGrosseCC = MAX(plusGrosseCC,FrontsElements.
size());
1468 if (FrontsElements.
size()<seuil)
1473 info()<<
" nbDomEnDessous = "<<nbDomEnDessous;
1477 if (nbDomEnDessous == ListeFrontsElements.
size()){
1479 info() <<
" seuil abaissé à "<< plusGrosseCC;
1481 seuil = plusGrosseCC;
1486 for (
int i=0; i<ListeFrontsElements.
size(); i++){
1488 if (FrontsElements.
size()<seuil){
1495 for (
int j=0; j<FrontsElements.
size(); j++){
1496 const Cell item = FrontsElements[j];
1497 cells_new_owner[item] = indDomVois;
1503 info() <<
" Nombre de composantes transférées : "<<nbCCTransf;
1509 free((
void*) IndFrontsNoeuds);
1510 IndFrontsNoeuds = NULL;
1511 free((
void*) IndFrontsElements);
1512 IndFrontsElements = NULL;
1514 free((
void*)MasqueDesNoeuds);
1515 MasqueDesNoeuds = NULL;
1516 free((
void*)MasqueDesElements);
1517 MasqueDesElements = NULL;
1523 int nbCCTransfMin = 0;
1524 int nbCCTransfMax = 0;
1525 int nbCCTransfSum = 0;
1532 pm->
computeMinMaxSum(nbCCTransf, nbCCTransfMin, nbCCTransfMax, nbCCTransfSum, procMin, procMax);
1534 bool synchroNecessaire = (nbCCTransfSum > 0);
1535#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
1536 info()<<
" ConnexifieDomaine: nbCCTransfSum = "<<nbCCTransfSum;
1539 if (synchroNecessaire){
1541 info()<<
" on fait la synchronisation";
1545 cells_new_owner.synchronize();
1548 bool compact =
mesh->properties()->getBool(
"compact");
1549 mesh->properties()->setBool(
"compact",
false);
1550 mesh->exchangeItems();
1551 mesh->properties()->setBool(
"compact", compact);
1560 info()<<
" on sort de ConnexifieDomaine";
1565int SplitSDMeshPartitioner::
1568 int indDomVois = -1;
1571 std::map<int,int> indVois_nbFace;
1573 for (
int i=0; i<ListeElements.
size(); i++){
1574 const Cell cell = ListeElements[i];
1576 for (
int j=0;j<cell.
nbFace(); j++){
1583 if (id1 == me && id2 != me)
1584 indVois_nbFace[id2]+=1;
1585 else if (id1 != me && id2 == me)
1586 indVois_nbFace[id1]+=1;
1593 std::map<int,int>::iterator iter;
1594 for (iter = indVois_nbFace.begin();
1595 iter != indVois_nbFace.end();
1597 int nbFaces = (*iter).second;
1598 if (nbFaces>maxNbFaces){
1599 maxNbFaces = nbFaces;
1600 indDomVois = (*iter).first;
1604 if (indDomVois == -1)
1605 pfatal()<<
"indDomVois toujours à -1 !!!";
1608 pinfo()<<
" getDomVoisMaxFace, me = "<<me<<
", ListeElements.size() = "<<ListeElements.
size()
1609 <<
", indDomVois = "<<indDomVois<<
", maxNbFaces = "<<maxNbFaces;
1615int* SplitSDMeshPartitioner::
1618 int* MasqueDesNoeuds = NULL;
1622 int maxNodeLocalId = 0;
1626 const Node node = *i_item;
1627 maxNodeLocalId = MAX(maxNodeLocalId,node.
localId());
1630 info() <<
"SplitSDMeshPartitioner::GetMasqueDesNoeuds(), maxNodeLocalId = "<<maxNodeLocalId;
1634 MasqueDesNoeuds = (
int*) calloc ((
size_t)(maxNodeLocalId+1),
sizeof(
int));
1635 CHECK_IF_NOT_NULL(MasqueDesNoeuds);
1637 return MasqueDesNoeuds;
1641int* SplitSDMeshPartitioner::
1644 int* MasqueDesElements = NULL;
1648 int maxCellLocalId = 0;
1652 const Cell cell = *i_item;
1653 maxCellLocalId = MAX(maxCellLocalId,cell.
localId());
1657 info() <<
"SplitSDMeshPartitioner::GetMasqueDesElements(), maxCellLocalId = "<<maxCellLocalId;
1661 MasqueDesElements = (
int*) calloc ((
size_t)(maxCellLocalId+1),
sizeof(
int));
1662 CHECK_IF_NOT_NULL(MasqueDesElements);
1664 return MasqueDesElements;
1669void SplitSDMeshPartitioner::
1672 ARCANE_UNUSED(InfoProc);
1678void SplitSDMeshPartitioner::
1682 info()<<
"LibereDomaine(...)";
1685 if (Domaine->
NbIntf != 0){
1686 if (Domaine->
Intf != NULL){
1687 for (
int i=0; i<Domaine->
NbIntf; i++)
1689 delete [] Domaine->
Intf;
1690 Domaine->
Intf = NULL;
1700void SplitSDMeshPartitioner::
1704 info()<<
"LibereMaillage(...)";
1720 Maillage->
Poids = 0.0;
1726void SplitSDMeshPartitioner::
1732 for (idom=0; idom<NbDom; idom++) {
1733 info()<<
" --------------------";
1734 info()<<
" --- Domaine ("<<idom<<
") ---";
1735 info()<<
" --------------------";
1737 if (Domaine == NULL){
1738 info()<<
" Domaine vide ! (pointeur NULL)";
1740 else if (Domaine[idom].NbElements == 0) {
1741 info()<<
" Domaine vide ! (pas d'éléments)";
1744 info()<<
" NbElements = "<<Domaine[idom].
NbElements;
1745 info()<<
" PoidsDom = "<<Domaine[idom].
PoidsDom;
1746 info()<<
" Interfaces (NbIntf = "<<Domaine[idom].
NbIntf<<
") :";
1747 for (i=0; i<Domaine[idom].
NbIntf; i++) {
1748 info()<<
" ("<<i<<
") NoDomVois = "<<Domaine[idom].
Intf[i].
NoDomVois
1757void SplitSDMeshPartitioner::
1760 info()<<
" ----------------";
1761 info()<<
" --- Maillage ---";
1762 info()<<
" ----------------";
1763 if (Maillage==NULL){
1764 info()<<
" structure Maillage vide !";
1767 info()<<
" NbElements (total) = "<<Maillage->
NbElements;
1768 info()<<
" Poids (total) = "<<Maillage->
Poids;
1774 info()<<
" Maillage.ListeDomaines == NULL";
1784void SplitSDMeshPartitioner::
1787 info()<<
" ListeDomaines :";
1788 for (
int i=0; i<NbDomaines; i++) {
1789 info()<<
" ("<<i<<
") NbElements = "<<ListeDomaines[i].
NbElements<<
"; Poids = "<<ListeDomaines[i].
Poids;
1790 info()<<
" ("<<i<<
") NbVoisins = "<<ListeDomaines[i].
NbVoisins<<
"; ListeVoisins :";
1791 for (
int j=0; j<ListeDomaines[i].
NbVoisins; j++) {
1800void SplitSDMeshPartitioner::
1803 info()<<
" AfficheEquilMaillage(...)";
1805 double poidsMin = 0.0;
1806 double poidsMax = 0.0;
1815 if (poidsDom > poidsMax)
1816 poidsMax = poidsDom;
1817 if (poidsDom < poidsMin)
1818 poidsMin = poidsDom;
1821 info()<<
" INFO equilibrage / noeuds : max : "<<poidsMax<<
", min : "<<poidsMin
1825 info()<<
"AfficheEquilMaillage : Maillage->ListeDomaines == NULL";
1858 if (*pTailleTMP <= 0)
1862 ierror = MPI_Probe (FromProc,
1867 if (ierror != MPI_SUCCESS)
1869 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication en provenance de "
1870 <<FromProc<<
", lors de MPI_Probe";
1874 ierror = MPI_Get_count (&status,
1878 if (ierror != MPI_SUCCESS) {
1879 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication en provenance de "
1880 <<FromProc<<
", lors de MPI_Get_count";
1885 if (*pTailleTMP > 0)
1887 TabTMP = malloc ((
size_t) *pTailleTMP);
1888 CHECK_IF_NOT_NULL(TabTMP);
1894 ierror = MPI_Recv (TabTMP,
1902 if (ierror != MPI_SUCCESS) {
1903 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication en provenance de "
1904 <<FromProc<<
", lors de MPI_Recv";
1932 ierror = MPI_Send ((
void *) TabTMP,
1939 if (ierror != MPI_SUCCESS) {
1940 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication vers "
1941 <<ToProc<<
", lors de MPI_Send";
2013 InfoProc->
m_service->
pfatal()<<
"DiffuseMessage depuis "<<InfoProc->
me<<
", il est nécessaire que la taille du tableau soit connue !!!\n";
2017 if (InfoProc->
me != FromProc)
2021 TabTMP = malloc ((
size_t) TailleTMP);
2022 CHECK_IF_NOT_NULL(TabTMP);
2028 ierror = MPI_Bcast (TabTMP,
2034 if (ierror != MPI_SUCCESS) {
2036 <<FromProc<<
", lors de MPI_Bcast";
2057 size_t s = (2+2*Domaine->
NbIntf)*
sizeof(
int)+
sizeof(double);
2075void SplitSDMeshPartitioner::
2077 int TailleTMP, MPI_Comm comm)
2082 ier = MPI_Pack(&Domaine->
NbElements, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2083 CHECK_MPI_PACK_ERR(ier);
2085 ier = MPI_Pack(&Domaine->
PoidsDom, 1, MPI_DOUBLE, TabTMP, TailleTMP, &position, comm);
2086 CHECK_MPI_PACK_ERR(ier);
2088 ier = MPI_Pack(&Domaine->
NbIntf, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2089 CHECK_MPI_PACK_ERR(ier);
2091 for (
int i=0; i<Domaine->
NbIntf; i++){
2092 ier = MPI_Pack(&Domaine->
Intf[i].
NoDomVois, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2093 CHECK_MPI_PACK_ERR(ier);
2096 ier = MPI_Pack(&NbNoeuds, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2097 CHECK_MPI_PACK_ERR(ier);
2118 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
NbElements, 1, MPI_INT, comm);
2119 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
Poids, 1, MPI_DOUBLE, comm);
2120 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
NbVoisins, 1, MPI_INT, comm);
2124 for (
int i=0; i<DomMail->
NbVoisins; i++){
2139 return 2*
sizeof(int) +
sizeof(
double);
2150 ier = MPI_Pack(&indDomCharge, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2151 CHECK_MPI_PACK_ERR(ier);
2153 ier = MPI_Pack(&indDomVois, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2154 CHECK_MPI_PACK_ERR(ier);
2156 ier = MPI_Pack(&Delta, 1, MPI_DOUBLE, TabTMP, TailleTMP, &position, comm);
2157 CHECK_MPI_PACK_ERR(ier);
2167 MPI_Unpack(TabTMP, TailleTMP, &position, indDomCharge, 1, MPI_INT, comm);
2168 MPI_Unpack(TabTMP, TailleTMP, &position, indDomVois, 1, MPI_INT, comm);
2169 MPI_Unpack(TabTMP, TailleTMP, &position, Delta, 1, MPI_DOUBLE, comm);
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro pour déclarer une interface lors de l'enregistrement d'un service.
Integer size() const
Nombre d'éléments du vecteur.
Generation de la classe de base du Service.
Tableau d'items de types quelconques.
void fill(const DataType &data)
Remplissage du tableau.
void clear()
Supprime les éléments du tableau.
iterator begin()
Itérateur sur le premier élément du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Face face(Int32 i) const
i-ème face de la maille
Int32 nbFace() const
Nombre de faces de la maille.
Cell frontCell() const
Maille devant la face (maille nulle si aucune)
bool isSubDomainBoundary() const
Indique si la face est au bord du sous-domaine (i.e nbCell()==1)
Cell backCell() const
Maille derrière la face (maille nulle si aucune)
Exception lorsqu'une erreur fatale est survenue.
Interface d'un partitionneur de maillage.
Interface d'un partitionneur de maillage.
virtual IPrimaryMesh * toPrimaryMesh()=0
Retourne l'instance sous la forme d'un IPrimaryMesh.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual void computeMinMaxSum(char val, char &min_val, char &max_val, char &sum_val, Int32 &min_rank, Int32 &max_rank)=0
Calcule en une opération la somme, le min, le max d'une valeur.
virtual Int32 commSize() const =0
Nombre d'instance dans le communicateur.
Interface du gestionnaire d'un sous-domaine.
virtual Int32 subDomainId() const =0
Numéro du sous-domaine associé à ce gestionnaire.
virtual IParallelMng * parallelMng()=0
Retourne le gestionnaire de parallélisme.
Interface d'une variable.
Integer size() const
Nombre d'éléments du groupe.
Node node(Int32 i) const
i-ème noeud de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
Real maxImbalance() const override
Déséquilibre maximal autorisé
virtual void changeOwnersFromCells()
Positionne les nouveaux propriétaires des noeuds, arêtes et faces à partir des mailles.
Cell cell(Int32 i) const
i-ème maille du noeud
Int32 nbCell() const
Nombre de mailles connectées au noeud.
Structure contenant les informations pour créer un service.
Propriétés de création d'un service.
Vecteur 1D de données avec sémantique par référence.
Partitioneur de maillage inspiré de la bibliothèque SplitSD, développé initialement à l'ONERA pour Da...
void Equil2Dom(int *MasqueDesNoeuds, int *MasqueDesElements, int marqueVu, int marqueNonVu, StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage, int indDomCharge, int indDomVois, double Delta)
phase de transfert entre 2 domaines, MAJ des domaines
void ConnexifieDomaine(StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage, double tolConnexite)
déplace des parties du sous-domaine lorsqu'elles sont trop petites et non connexes
double CalculDeltaMin(StrucMaillage *Maillage, double deltaMin, int iterEquilibrage, int NbMaxIterEquil)
calcul un deltaMin en fonction des transferts locaux
void PackEquil(StrucInfoProc *InfoProc, int indDomCharge, int indDomVois, double Delta, void *TabTMP, int TailleTMP, MPI_Comm comm)
int * GetMasqueDesElements(StrucInfoProc *InfoProc)
création d'un tableau qui sert de masque sur les LocalId des éléments
int getDomVoisMaxFace(Arcane::Array< Arcane::Cell > &ListeElements, int me)
recherche le domaine voisin ayant le max de Faces en commun avec le groupe de mailles
void UnpackDom(void *TabTMP, int TailleTMP, MPI_Comm comm, StrucListeDomMail *DomMail)
void MAJDelta(double don, int iDOmTmpPrec, int iDomTmp, StrucListeDomMail *ListeDomaines)
fonction de décalage du Delta associé à une interface recherchée pour un couple, domaine et numéro de...
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)
parcours frontal limité suivant le Delta (poids cumulés des éléments pris dans les fronts),...
void initPoids(bool initial_partition)
initialisation des poids (m_cells_weight => m_poids_aux_mailles)
void * RecoitMessage(StrucInfoProc *InfoProc, int FromProc, int Tag, int *pTailleTMP)
void MAJDomaine(StructureBlocEtendu *Domaine)
mise à jour de la structure locale (noeuds sur les interfaces avec sous-domaines voisins)
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)
sélection d'éléments dans un domaine pour équilibrage entre 2 dom, en faisant un parcour frontal depu...
void * DiffuseMessage(StrucInfoProc *InfoProc, int FromProc, void *TabTMP, int TailleTMP)
int TailleDom(StructureBlocEtendu *Domaine)
Donne la taille en octets nécessaire pour le stockage mémoire d'un domaine (sans la liste des noeuds ...
void verifMaillageMaitre(StrucMaillage *Maillage)
fonction de vérification de la cohérence (réciprocité) des 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)
libération mémoire des structures
void MAJMaillageMaitre(StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage)
mise à jour de la structure sur le processeur 0
void MAJDeltaGlobal(StrucInfoProc *InfoProc, StrucMaillage *Maillage, double tolerance)
On utilise une méthode de parcours frontal pour aller d'un noeud surchargé vers les autres noeuds en ...
int * GetMasqueDesNoeuds(StrucInfoProc *InfoProc)
création d'un tableau qui sert de masque sur les LocalId des noeuds
void Equilibrage(StrucInfoProc *InfoProc, StructureBlocEtendu *Domaine, StrucMaillage *Maillage)
phase itérative pour équilibrer la charge
void init(bool initial_partition, StrucInfoProc *&InfoProc, StructureBlocEtendu *&Domaine, StrucMaillage *&Maillage)
initialisation des structures
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage pinfo() const
Flot pour un message d'information en parallèle.
TraceMessage fatal() const
Flot pour un message d'erreur fatale.
TraceMessage pfatal() const
Flot pour un message d'erreur fatale en parallèle.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage perror() const
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
void clear()
Supprime les éléments du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
ItemGroupT< Face > FaceGroup
Groupe de faces.
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro pour enregistrer un service.
ItemVariableScalarRefT< Integer > VariableItemInteger
Grandeur de type entier.
ItemVariableScalarRefT< Int32 > VariableItemInt32
Grandeur de type entier 32 bits.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
Int32 Integer
Type représentant un entier.
@ ST_SubDomain
Le service s'utilise au niveau du sous-domaine.
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
@ IK_Cell
Entité de maillage de genre maille.
std::int32_t Int32
Type entier signé sur 32 bits.
Arcane::AbstractService * m_service
Pour la gestion des traces (messages, erreurs, fatal ...)
StrucListeVoisMail * ListeVoisins
StrucListeDomMail * ListeDomaines
StructureInterface * Intf
Arcane::UniqueArray< Arcane::Node > ListeNoeuds