17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/ArcanePrecomp.h"
19#include "arcane/utils/Convert.h"
20#include "arcane/utils/Array.h"
22#include "arcane/core/ISubDomain.h"
23#include "arcane/core/IParallelMng.h"
25#include "arcane/core/IPrimaryMesh.h"
26#include "arcane/core/Properties.h"
27#include "arcane/core/ItemGroup.h"
28#include "arcane/core/Service.h"
29#include "arcane/core/Timer.h"
30#include "arcane/core/FactoryService.h"
31#include "arcane/core/ItemPrinter.h"
32#include "arcane/core/IItemFamily.h"
33#include "arcane/core/MeshVariable.h"
34#include "arcane/core/VariableBuildInfo.h"
35#include "arcane/std/MeshPartitionerBase.h"
36#include "arcane/std/SplitSDMeshPartitioner.h"
48SplitSDMeshPartitioner::
53 info() <<
"SplitSDMeshPartitioner::SplitSDMeshPartitioner(...)";
59void SplitSDMeshPartitioner::
60partitionMesh(
bool initial_partition)
62 info() <<
"Load balancing with SplitSDMeshPartitioner";
68 _initArrayCellsWithConstraints();
69 if (haveConstraints())
70 throw FatalErrorException(
"SplitSDMeshPartitioner: Constraints are not supported with SplitSD");
79 init(initial_partition, InfoProc, Domaine, Maillage);
85 fin(InfoProc, Domaine, Maillage);
89void SplitSDMeshPartitioner::
92 info() <<
"SplitSDMeshPartitioner::init(" << initial_partition <<
",...)";
104 InfoProc->
Split_Comm = *(MPI_Comm*)getCommunicator();
110 if (!initial_partition){
111 info() <<
"Initialize new owners";
117 cells_new_owner[icell] = cell.
owner();
120 cells_new_owner.synchronize();
128 Domaine->
Intf = NULL;
142 Maillage->
Poids = 0.0;
149void SplitSDMeshPartitioner::
150initPoids(
bool initial_partition)
152 ARCANE_UNUSED(initial_partition);
166 m_poids_aux_mailles[iitem] = cell_weights[iitem.index()];
171void SplitSDMeshPartitioner::
174 info() <<
"SplitSDMeshPartitioner::fin(...)";
175 LibereInfoProc(InfoProc);
176 LibereDomaine(Domaine);
177 LibereMaillage(Maillage);
189void SplitSDMeshPartitioner::
192 debug() <<
" ----------------------------------------";
193 debug() <<
"SplitSDMeshPartitioner::MAJDomaine(...)";
195 LibereDomaine(Domaine);
197 int me = subDomain()->subDomainId();
203 debug() <<
" all_faces.size() = =" << all_faces.
size();
205 std::map<int, SharedArray<Face>> vois_faces;
208 const Face face = *i_item;
232 filtreNoeuds.
fill(0);
248 Domaine->
PoidsDom += m_poids_aux_mailles[cell];
252 info() <<
"Domaine->NbIntf = " << Domaine->
NbIntf;
258 unsigned int ind = 0;
260 iter_vois != vois_faces.end(); ++iter_vois) {
268 info() <<
"Domaine->Intf[" << ind <<
"].NoDomVois = " << Domaine->
Intf[ind].
NoDomVois;
269 info() <<
" v_face.size() = " << v_face.
size();
272 for (
int i = 0; i < v_face.
size(); i++) {
273 const Face& face = v_face[i];
280 if (filtreNoeuds[node_local_id] != marque) {
282 filtreNoeuds[node_local_id] = marque;
295 info() <<
"MAJDomaine => ";
296 AfficheDomaine(1, Domaine);
297 info() <<
" ----------------------------------------";
302void SplitSDMeshPartitioner::
308 info() <<
"SplitSDMeshPartitioner::MAJMaillageMaitre(...)";
309 LibereMaillage(Maillage);
318 TabTMP = malloc((
size_t)TailleTab);
324 if (InfoProc->
me == 0) {
326 info() <<
" ***************************";
327 info() <<
" * Before MAJMaillageMaitre *";
328 AfficheMaillage(Maillage);
329 info() <<
" ***************************";
334 for (iDom = 0; iDom < InfoProc->
nbSubDomain; iDom++) {
345 EnvoieMessage(InfoProc, 0, TAG_MAILLAGEMAITRE, TabTMP, TailleTab);
357 if (InfoProc->
me == 0) {
360 Maillage->
Poids = 0.0;
364 for (iDom = InfoProc->
nbSubDomain - 1; iDom >= 0; iDom--) {
368 TabTMP =
RecoitMessage(InfoProc, iDom, TAG_MAILLAGEMAITRE, &TailleTab);
387 info() <<
" ***************************";
388 info() <<
" * After MAJMaillageMaitre *";
390 AfficheMaillage(Maillage);
392 info() <<
" ***************************";
399void SplitSDMeshPartitioner::
403 info() <<
" entering verifMaillageMaitre";
408 for (
int iDom = 0; iDom < NbDomaines; iDom++) {
409 for (
int j = 0; j < ListeDomaines[iDom].
NbVoisins; j++) {
418 if (k == ListeDomaines[iVois].NbVoisins) {
419 printf(
"we cannot find the neighbor number \n");
420 printf(
"for info: iDom = %d, iVois = %d\n", iDom, iVois);
421 perror() <<
"verifMaillageMaitre error on neighborhood !!!";
424 if (ListeDomaines[iVois].ListeVoisins[k].NbNoeudsInterface != NbNoeudsInterface) {
425 printf(
"we do not find the same number of nodes between neighbors \n");
426 printf(
"for info: iDom = %d, iVois = %d, NbNoeudsInterface %d != %d\n", iDom, iVois, NbNoeudsInterface, ListeDomaines[iVois].ListeVoisins[k].NbNoeudsInterface);
427 perror() <<
"verifMaillageMaitre error on number of nodes !!!";
432 info() <<
" leaving verifMaillageMaitre";
434 ARCANE_UNUSED(Maillage);
439void SplitSDMeshPartitioner::
457 int* ListeNoeudsPrec;
461 int marqueDomNonVu = 0;
462 int marqueDomVide = -1;
467 info() <<
" ------------------------------------";
468 info() <<
" entering MAJDeltaGlobal, tolerance = " << tolerance;
469 info() <<
" ------------------------------------";
470 info() <<
" ......... Initial Mesh ...........";
471 AfficheListeDomaines(ListeDomaines, NbDomaines);
474 if (NbDomaines == 0) {
475 info() <<
" SplitSDMeshPartitioner::MAJDeltaGlobal: NbDomaines is null!";
480 info() <<
" \n = exiting MAJDeltaGlobal without doing anything (NbDomainesPleins = " << Maillage->
NbDomainesPleins;
481 info() <<
" ------------------------------------";
486 FiltreDomaine = (
int*)malloc((
size_t)NbDomaines *
sizeof(
int));
487 CHECK_IF_NOT_NULL(FiltreDomaine);
490 for (i = 0; i < NbDomaines; i++)
491 for (
int j = 0; j < ListeDomaines[i].
NbVoisins; j++)
492 ListeDomaines[i].ListeVoisins[j].Delta = 0.0;
498 for (i = 0; i < NbDomaines; i++) {
499 if (ListeDomaines[i].NbElements != 0)
500 FiltreDomaine[i] = marqueDomNonVu;
502 FiltreDomaine[i] = marqueDomVide;
505 PoidsSave = (
double*)malloc((
size_t)NbDomaines *
sizeof(
double));
506 CHECK_IF_NOT_NULL(PoidsSave);
512 for (i = 0; i < NbDomaines; i++) {
514 PoidsSave[i] = ListeDomaines[i].
Poids;
516 if (FiltreDomaine[i] != marqueDomVide)
517 ListeDomaines[i].
Poids -= PoidsMoyen;
521 info() <<
" After Poids -= PoidsMoyen";
522 AfficheListeDomaines(ListeDomaines, NbDomaines);
526 FrontPrec = (
int*)malloc((
size_t)(NbDomaines - 1) *
sizeof(
int));
527 CHECK_IF_NOT_NULL(FrontPrec);
528 FrontSuiv = (
int*)malloc((
size_t)(NbDomaines - 1) *
sizeof(
int));
529 CHECK_IF_NOT_NULL(FrontSuiv);
531 ListeNoeudsPrec = (
int*)malloc((
size_t)(NbDomaines) *
sizeof(
int));
532 CHECK_IF_NOT_NULL(ListeNoeudsPrec);
534 for (iDomDep = 0; iDomDep < NbDomaines; iDomDep++) {
536 info() <<
" ListeDomaines[iDomDep = " << iDomDep <<
"].Poids = " << ListeDomaines[iDomDep].
Poids;
540 if (ListeDomaines[iDomDep].Poids > tolerance) {
544 for (i = 0; i < NbDomaines; i++)
545 if (FiltreDomaine[i] == marqueDomVu)
546 FiltreDomaine[i] = marqueDomNonVu;
549 FiltreDomaine[iDomDep] = marqueDomVu;
553 FrontSuiv[tailleFS - 1] = iDomDep;
556 info() <<
" FrontSuiv[0] = " << iDomDep;
560 ListeNoeudsPrec[FrontSuiv[tailleFS - 1]] = -1;
563 while (ListeDomaines[iDomDep].Poids > tolerance) {
565 info() <<
" while (ListeDomaines[" << iDomDep <<
"].Poids = " << ListeDomaines[iDomDep].
Poids <<
" > " << tolerance;
569 FrontTMP = FrontPrec;
570 FrontPrec = FrontSuiv;
571 FrontSuiv = FrontTMP;
577 fatal() <<
" partitionner/MAJDeltaGlobal: no more domains found while not finished!!!";
585 for (
int iFP = 0; iFP < tailleFP; iFP++) {
586 int iDom = FrontPrec[iFP];
589 for (
int iVois = 0; iVois < ListeDomaines[iDom].
NbVoisins; iVois++) {
591 if (FiltreDomaine[iDomVois] == marqueDomNonVu) {
593 FiltreDomaine[iDomVois] = marqueDomVu;
594 ListeNoeudsPrec[iDomVois] = iDom;
596 info() <<
" FrontSuiv[" << tailleFS <<
"] = " << iDomVois;
598 FrontSuiv[tailleFS++] = iDomVois;
608 for (
int iFS = 0; iFS < tailleFS; iFS++) {
609 int iDom = FrontSuiv[iFS];
612 info() <<
" ListeDomaines[" << iDom <<
"].Poids = " << ListeDomaines[iDom].
Poids;
616 if (ListeDomaines[iDom].Poids < 0.0) {
618 double don = MIN(-ListeDomaines[iDom].Poids, ListeDomaines[iDomDep].Poids);
625 ListeDomaines[iDom].
Poids += don;
626 ListeDomaines[iDomDep].
Poids -= don;
633 iDomTmpPrec = ListeNoeudsPrec[iDomTmp];
634 while (iDomTmpPrec != -1) {
636 MAJDelta(don, iDomTmpPrec, iDomTmp, ListeDomaines);
638 MAJDelta(-don, iDomTmp, iDomTmpPrec, ListeDomaines);
641 iDomTmp = iDomTmpPrec;
642 iDomTmpPrec = ListeNoeudsPrec[iDomTmp];
656 for (i = 0; i < NbDomaines; i++)
657 ListeDomaines[i].Poids = PoidsSave[i];
659 free((
void*)FrontPrec);
661 free((
void*)FrontSuiv);
663 free((
void*)ListeNoeudsPrec);
664 ListeNoeudsPrec = NULL;
665 free((
void*)FiltreDomaine);
666 FiltreDomaine = NULL;
667 free((
void*)PoidsSave);
671 info() <<
" ......... Final Mesh ...........";
672 AfficheListeDomaines(ListeDomaines, NbDomaines);
673 info() <<
" = exiting MAJDeltaGlobal =";
674 info() <<
" ------------------------------------";
679void SplitSDMeshPartitioner::
689 if (j == ListeDomaines[iDom].NbVoisins) {
690 info() <<
"could not find the neighbor number";
691 info() <<
"for info: addition = " << ajout <<
", iDom = " << iDom <<
", iVois = " << iVois;
692 pfatal() <<
"Error in Partitionner/MAJDelta, no neighbor found!";
701double SplitSDMeshPartitioner::
702CalculDeltaMin(
StrucMaillage* Maillage,
double deltaMin,
int iterEquilibrage,
int NbMaxIterEquil)
707 debug() <<
" entering SplitSDMeshPartitioner::CalculDeltaMin, deltaMin = " << deltaMin
708 <<
", iterEquilibrage = " << iterEquilibrage
709 <<
", NbMaxIterEquil = " << NbMaxIterEquil;
711 AfficheMaillage(Maillage);
713 double deltaAjuste = deltaMin;
716 double deltaMaxItf = 0.0;
718 double ratioDeltaMax = 0.0;
723 for (
int iDom = 0; iDom < NbDomaines; iDom++) {
724 double deltaTotalDom = 0.0;
725 for (
int j = 0; j < ListeDomaines[iDom].
NbVoisins; j++) {
727 deltaMaxItf = MAX(delta, deltaMaxItf);
729 deltaTotalDom += delta;
732 if (ListeDomaines[iDom].Poids > 0.0)
733 ratio = deltaTotalDom / ListeDomaines[iDom].
Poids;
734 ratioDeltaMax = MAX(ratio, ratioDeltaMax);
740 if (ratioDeltaMax > 0.9)
741 deltaAjuste = poidsMoy / 3.0;
742 else if (ratioDeltaMax > 0.5)
743 deltaAjuste = deltaMaxItf / 10.0;
746 deltaAjuste = MAX(deltaMin, deltaAjuste);
748#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
750 double proportion = deltaMaxItf / poidsMoy;
752 info() <<
" deltaMaxItf = " << deltaMaxItf;
753 info() <<
" ratioDeltaMax = " << ratioDeltaMax;
754 info() <<
" poidsMoy = " << poidsMoy;
755 info() <<
" proportion = " << proportion;
756 info() <<
" deltaAjuste = " << deltaAjuste;
763void SplitSDMeshPartitioner::
767 int indDomCharge = -1;
778 int NbAppelsAEquil2Dom = -1;
780 int iterEquilibrage = 0;
781 int NbMaxIterEquil = 5;
783 double tolConnexite = 0.1;
786 info() <<
" -------------------------------------";
787 info() <<
" entering SplitSDMeshPartitioner::Equilibrage, deltaMin = " << deltaMin;
791 TabTMP = malloc((
size_t)TailleTMP);
792 CHECK_IF_NOT_NULL(TabTMP);
795 while (iterEquilibrage < NbMaxIterEquil && NbAppelsAEquil2Dom != 0) {
798 int marqueDomNonVu = 0;
800 iterEquilibrage += 1;
801 NbAppelsAEquil2Dom = 0;
813 if (InfoProc->
me == 0) {
814 info() <<
" SplitSDMeshPartitioner::Equilibrage of the load (iteration No " << iterEquilibrage <<
")";
820 double deltaAjuste =
CalculDeltaMin(Maillage, deltaMin, iterEquilibrage, NbMaxIterEquil);
823 FiltreDomaine = (
int*)calloc((
size_t)Maillage->
NbDomainesMax,
sizeof(
int));
824 CHECK_IF_NOT_NULL(FiltreDomaine);
829 FiltreDomaine[iDom] = marqueDomVu;
839 if (FiltreDomaine[iDom] == marqueDomNonVu && Maillage->
ListeDomaines[iDom].
Poids > poidsMax) {
845 info() <<
"indDomCharge = " << indDomCharge <<
"; poidsMax = " << poidsMax;
848 if (indDomCharge != -1) {
850 FiltreDomaine[indDomCharge] = marqueDomVu;
860#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
861 info() <<
" Balancing (" << iterEquilibrage <<
") for the pair indDomCharge = " << indDomCharge <<
"; indDomVois = " << indDomVois
875 Equil2Dom(MasqueDesNoeuds, MasqueDesElements, marqueVu, marqueNonVu,
876 InfoProc, Domaine, Maillage, indDomCharge, indDomVois,
878 NbAppelsAEquil2Dom += 1;
884 }
while (indDomCharge != -1);
887 double DeltaNul = 0.0;
888 PackEquil(InfoProc, indDomCharge, indDomVois, DeltaNul, TabTMP, TailleTMP, InfoProc->
Split_Comm);
892 free((
void*)FiltreDomaine);
893 FiltreDomaine = NULL;
896 info() <<
" NbAppelsAEquil2Dom = " << NbAppelsAEquil2Dom;
907 if (indDomCharge != -1) {
912 Equil2Dom(MasqueDesNoeuds, MasqueDesElements, marqueVu, marqueNonVu,
913 InfoProc, Domaine, Maillage, indDomCharge, indDomVois, Delta);
914 NbAppelsAEquil2Dom += 1;
917 }
while (indDomCharge != -1);
922 if (NbAppelsAEquil2Dom) {
924 LibereDomaine(Domaine);
927 info() <<
"cells_new_owner.synchronize() et changeOwnersFromCells()";
931 cells_new_owner.synchronize();
934 bool compact =
mesh->properties()->getBool(
"compact");
935 mesh->properties()->setBool(
"compact",
false);
936 mesh->exchangeItems();
937 mesh->properties()->setBool(
"compact", compact);
946 free((
void*)MasqueDesNoeuds);
947 MasqueDesNoeuds = NULL;
948 free((
void*)MasqueDesElements);
949 MasqueDesElements = NULL;
951 AfficheEquilMaillage(Maillage);
958 AfficheEquilMaillage(Maillage);
965 debug() <<
" number of iterations for balancing = " << iterEquilibrage <<
" / " << NbMaxIterEquil <<
" max ";
966 debug() <<
" = we are exiting SplitSDMeshPartitioner::Equilibrage";
967 debug() <<
" -------------------------------------";
973void SplitSDMeshPartitioner::
974Equil2Dom(
int* MasqueDesNoeuds,
int* MasqueDesElements,
int marqueVu,
int marqueNonVu,
976 int indDomCharge,
int indDomVois,
double Delta)
978 ARCANE_UNUSED(Maillage);
980 debug() <<
" we are entering Equil2Dom (indDomCharge:" << indDomCharge <<
", indDomVois:" << indDomVois <<
", Delta:" << Delta;
985 if (InfoProc->
me == indDomCharge) {
993 if (iIntf == Domaine->
NbIntf) {
994#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
995 pinfo() <<
"### the interface has disappeared ### between " << indDomCharge <<
" and " << indDomVois;
1001 marqueVu, marqueNonVu,
1002 InfoProc, Domaine, Delta, indDomVois, ListeElements);
1009 for (
int i = 0; i < ListeElements.
size(); i++) {
1010 const Cell item = ListeElements[i];
1011 cells_new_owner[item] = indDomVois;
1017 info() <<
"SelectElements and other operations on processors " << indDomCharge <<
" and " << indDomVois;
1020 info() <<
" we are exiting Equil2Dom";
1025void SplitSDMeshPartitioner::
1026SelectElements(
int* MasqueDesNoeuds,
int* MasqueDesElements,
int marqueVu,
int marqueNonVu,
1031 info() <<
"SplitSDMeshPartitioner::SelectElements(Domaine, Delta = " << Delta <<
", indDomVois = " << indDomVois <<
")";
1033 info() <<
" Domaine->PoidsDom = " << Domaine->
PoidsDom;
1037 perror() <<
"Delta <= 0 !!!";
1044 pinfo() <<
" All the domain is selected on domain " << subDomain()->subDomainId()
1045 <<
", with SelectElements, PoidsDom = " << Domaine->
PoidsDom
1046 <<
", Delta = " << Delta;
1052 const Cell item = *i_item;
1054 ListeElements.
add(item);
1063 int* IndFrontsNoeuds;
1064 int* IndFrontsElements;
1066 for (iIntf = 0; iIntf < Domaine->
NbIntf && Domaine->
Intf[iIntf].
NoDomVois != indDomVois; iIntf++) {
1069 if (iIntf == Domaine->
NbIntf) {
1070 pfatal() <<
" SelectElements cannot find the interface among the neighbors !!!";
1081 IndFrontsNoeuds = (
int*)malloc((
size_t)(NbFrontsMax + 1) *
sizeof(
int));
1082 CHECK_IF_NOT_NULL(IndFrontsNoeuds);
1084 IndFrontsElements = (
int*)malloc((
size_t)(NbFrontsMax + 1) *
sizeof(
int));
1085 CHECK_IF_NOT_NULL(IndFrontsElements);
1094 IndFrontsNoeuds[0] = 0;
1096 IndFrontsElements[0] = 0;
1097 IndFrontsElements[1] = 0;
1100 int me = subDomain()->subDomainId();
1103 const Cell cell = *i_item;
1104 if (cell.
owner() != me)
1105 MasqueDesElements[cell.
localId()] = marqueVu;
1109 for (
int i = 0; i < ListeElements.
size(); i++) {
1110 const Cell cell = ListeElements[i];
1111 MasqueDesElements[cell.
localId()] = marqueVu;
1117 marqueVu, marqueNonVu,
1119 &NbFronts, NbFrontsMax,
1120 FrontsNoeuds, IndFrontsNoeuds,
1121 FrontsElements, IndFrontsElements);
1125 IndFrontsNoeuds[NbFronts - 1] = IndFrontsNoeuds[NbFronts];
1126 IndFrontsElements[NbFronts - 1] = IndFrontsElements[NbFronts];
1134 marqueVu, marqueNonVu,
1136 FrontsNoeuds, IndFrontsNoeuds,
1137 FrontsElements, IndFrontsElements);
1139 free((
void*)IndFrontsNoeuds);
1140 IndFrontsNoeuds = NULL;
1141 free((
void*)IndFrontsElements);
1142 IndFrontsElements = NULL;
1145 info() <<
" exiting: ListeElements.size() = " << ListeElements.
size();
1149int SplitSDMeshPartitioner::
1150ParcoursFrontalDelta(
int* MasqueDesNoeuds,
int* MasqueDesElements,
1151 int marqueVu,
int marqueNonVu,
1153 int* pNbFronts,
int NbFrontsMax,
1158 info() <<
" = we are entering FrontalTraversal : (NbFronts = " << *pNbFronts <<
", NbFrontsMax = " << NbFrontsMax <<
")";
1159 info() <<
" FrontsNoeuds.size() = " << FrontsNoeuds.
size();
1160 info() <<
" FrontsElements.size() = " << FrontsElements.
size();
1165 double PoidsActuel = 0.0;
1166 bool bloque =
false;
1169 for (IndFn = 0; IndFn < IndFrontsNoeuds[*pNbFronts]; IndFn++) {
1170 MasqueDesNoeuds[FrontsNoeuds[IndFn].localId()] = marqueVu;
1173 for (IndFe = 0; IndFe < IndFrontsElements[*pNbFronts]; IndFe++) {
1174 MasqueDesElements[FrontsElements[IndFe].localId()] = marqueVu;
1179 if (IndFrontsElements[*pNbFronts] > 0 && IndFrontsNoeuds[*pNbFronts] == 0) {
1181 for (
int ielm = 0; ielm < IndFrontsElements[*pNbFronts]; ielm++) {
1182 const Cell cell = FrontsElements[ielm];
1183 PoidsActuel += m_poids_aux_mailles[cell];
1185 for (
int iepn = 0; iepn < cell.
nbNode(); iepn++) {
1186 const Node nodeVois = cell.
node(iepn);
1189 if (MasqueDesNoeuds[nodeVois.
localId()] == marqueNonVu) {
1190 FrontsNoeuds.
add(nodeVois);
1192 MasqueDesNoeuds[nodeVois.
localId()] = marqueVu;
1197 IndFrontsNoeuds[*pNbFronts] = IndFn;
1205 for (
int in = IndFrontsNoeuds[*pNbFronts - 1];
1206 in < IndFrontsNoeuds[*pNbFronts] && PoidsActuel < Delta;
1208 const Node node = FrontsNoeuds[in];
1212 for (
int inpe = 0; inpe < node.
nbCell(); inpe++) {
1217 if (MasqueDesElements[cell.
localId()] == marqueNonVu) {
1218 FrontsElements.
add(cell);
1220 MasqueDesElements[cell.
localId()] = marqueVu;
1222 PoidsActuel += m_poids_aux_mailles[cell];
1224 for (
int iepn = 0; iepn < cell.
nbNode(); iepn++) {
1225 const Node nodeVois = cell.
node(iepn);
1228 if (MasqueDesNoeuds[nodeVois.
localId()] == marqueNonVu) {
1229 FrontsNoeuds.
add(nodeVois);
1231 MasqueDesNoeuds[nodeVois.
localId()] = marqueVu;
1239 if (IndFrontsNoeuds[*pNbFronts - 1] == IndFrontsNoeuds[*pNbFronts]) {
1244 IndFrontsNoeuds[*pNbFronts] = IndFn;
1245 IndFrontsElements[*pNbFronts] = IndFe;
1247 }
while (*pNbFronts < NbFrontsMax && PoidsActuel < Delta && !bloque);
1250 info() <<
" NbFronts = " << *pNbFronts;
1251 info() <<
" Delta = " << Delta;
1252 info() <<
" PoidsActuel = " << PoidsActuel;
1253 info() <<
" NbNoeuds = " << IndFrontsNoeuds[*pNbFronts];
1254 info() <<
" NbElements = " << IndFrontsElements[*pNbFronts];
1255 info() <<
" blocked = " << (bloque ?
"TRUE" :
"FALSE");
1257 if (!(*pNbFronts < NbFrontsMax)) {
1258 info() <<
" = we stop after obtaining the maximum number of fronts " << NbFrontsMax;
1260 else if (!(PoidsActuel < Delta)) {
1261 info() <<
" = we stop after obtaining the desired weight " << PoidsActuel;
1264 info() <<
" = we are blocked (not connected ?) =";
1267 info() <<
" = we stop because we have seen everything =";
1269 info() <<
" = we are exiting FrontalTraversal . =";
1272 return ((bloque) ? 1 : 0);
1277void SplitSDMeshPartitioner::
1278LissageDuFront(
int* MasqueDesNoeuds,
int* MasqueDesElements,
1279 int marqueVu,
int marqueNonVu,
1284 ARCANE_UNUSED(IndFrontsElements);
1286 debug() <<
" we are entering LissageDuFront : NbFronts = " << NbFronts;
1288 int NbElementsAjoutes = 0;
1293 for (
int IndFn = IndFrontsNoeuds[NbFronts - 1]; IndFn < IndFrontsNoeuds[NbFronts]; IndFn++) {
1294 const Node node = FrontsNoeuds[IndFn];
1296 for (
int inpe = 0; inpe < node.
nbCell(); inpe++) {
1300 if (MasqueDesElements[cell.
localId()] == marqueNonVu) {
1303 for (iepn = 0; iepn < cell.
nbNode() && MasqueDesNoeuds[cell.
node(iepn).
localId()] == marqueVu; iepn++) {
1306 if (iepn == cell.
nbNode()) {
1309 FrontsElements.
add(cell);
1310 NbElementsAjoutes += 1;
1311 MasqueDesElements[cell.
localId()] = marqueVu;
1315 MasqueDesElements[cell.
localId()] = marqueVu;
1316 ElementsALiberer.
add(cell);
1324 for (
int i = 0; i < ElementsALiberer.
size(); i++)
1325 MasqueDesElements[ElementsALiberer[i].localId()] = marqueNonVu;
1328 info() <<
" we exit LissageDuFront (" << NbElementsAjoutes <<
" elements added)";
1333void SplitSDMeshPartitioner::
1335 double tolConnexite)
1338 info() <<
" entering ConnexifieDomaine, tolConnexite = " << tolConnexite;
1344 int marqueNonVu = 0;
1348 double tailleMoy = (double)Domaine->
NbElements;
1351 int me = InfoProc->
me;
1356 Cell cell = *i_item;
1357 if (cell.
owner() != me)
1358 MasqueDesElements[cell.
localId()] = marqueVu;
1361 int NbElementsVus = 0;
1364 info() <<
" NbElementsAVoir = " << NbElementsAVoir;
1369 int* IndFrontsNoeuds;
1370 int* IndFrontsElements;
1380 IndFrontsNoeuds = (
int*)malloc((
size_t)(NbFrontsMax + 1) *
sizeof(
int));
1381 CHECK_IF_NOT_NULL(IndFrontsNoeuds);
1383 IndFrontsElements = (
int*)malloc((
size_t)(NbFrontsMax + 1) *
sizeof(
int));
1384 CHECK_IF_NOT_NULL(IndFrontsElements);
1387 while (NbElementsVus < NbElementsAVoir) {
1389 FrontsNoeuds.
clear();
1394 bool trouve =
false;
1396 const Cell cell = *i_item;
1397 if (!trouve && MasqueDesElements[cell.
localId()] == marqueNonVu) {
1398 FrontsElements.
add(cell);
1403 pfatal() <<
"ConnexifieDomaine is blocked while searching for a starting element";
1407 IndFrontsNoeuds[0] = 0;
1408 IndFrontsNoeuds[1] = 0;
1409 IndFrontsElements[0] = 0;
1410 IndFrontsElements[1] = 1;
1414 marqueVu, marqueNonVu,
1416 &NbFronts, NbFrontsMax,
1417 FrontsNoeuds, IndFrontsNoeuds,
1418 FrontsElements, IndFrontsElements);
1421 ListeFrontsElements.
add(FrontsElements);
1423 NbElementsVus += FrontsElements.
size();
1425 info() <<
" NbElementsVus+=" << FrontsElements.
size();
1434 if (ListeFrontsElements.
size() > 1) {
1437 info() <<
" NbComposantesConnexes = " << ListeFrontsElements.
size();
1441 int nbDomEnDessous = 0;
1442 int plusGrosseCC = 0;
1444 int seuil = (int)(tailleMoy * tolConnexite);
1446 info() <<
" threshold = " << seuil;
1449 for (
int i = 0; i < ListeFrontsElements.
size(); i++) {
1451 plusGrosseCC = MAX(plusGrosseCC, FrontsElements.
size());
1452 if (FrontsElements.
size() < seuil)
1453 nbDomEnDessous += 1;
1457 info() <<
" nbDomEnDessous = " << nbDomEnDessous;
1461 if (nbDomEnDessous == ListeFrontsElements.
size()) {
1463 info() <<
" threshold lowered to " << plusGrosseCC;
1465 seuil = plusGrosseCC;
1470 for (
int i = 0; i < ListeFrontsElements.
size(); i++) {
1472 if (FrontsElements.
size() < seuil) {
1479 for (
int j = 0; j < FrontsElements.
size(); j++) {
1480 const Cell item = FrontsElements[j];
1481 cells_new_owner[item] = indDomVois;
1487 info() <<
" Number of transferred components: " << nbCCTransf;
1493 free((
void*)IndFrontsNoeuds);
1494 IndFrontsNoeuds = NULL;
1495 free((
void*)IndFrontsElements);
1496 IndFrontsElements = NULL;
1498 free((
void*)MasqueDesNoeuds);
1499 MasqueDesNoeuds = NULL;
1500 free((
void*)MasqueDesElements);
1501 MasqueDesElements = NULL;
1506 int nbCCTransfMin = 0;
1507 int nbCCTransfMax = 0;
1508 int nbCCTransfSum = 0;
1515 pm->
computeMinMaxSum(nbCCTransf, nbCCTransfMin, nbCCTransfMax, nbCCTransfSum, procMin, procMax);
1517 bool synchroNecessaire = (nbCCTransfSum > 0);
1518#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
1519 info() <<
" ConnexifieDomaine: nbCCTransfSum = " << nbCCTransfSum;
1522 if (synchroNecessaire) {
1524 info() <<
" we perform the synchronization";
1528 cells_new_owner.synchronize();
1531 bool compact =
mesh->properties()->getBool(
"compact");
1532 mesh->properties()->setBool(
"compact",
false);
1533 mesh->exchangeItems();
1534 mesh->properties()->setBool(
"compact", compact);
1543 info() <<
" we exit ConnexifieDomaine";
1548int SplitSDMeshPartitioner::
1551 int indDomVois = -1;
1554 std::map<int, int> indVois_nbFace;
1556 for (
int i = 0; i < ListeElements.
size(); i++) {
1557 const Cell cell = ListeElements[i];
1559 for (
int j = 0; j < cell.
nbFace(); j++) {
1566 if (id1 == me && id2 != me)
1567 indVois_nbFace[id2] += 1;
1568 else if (id1 != me && id2 == me)
1569 indVois_nbFace[id1] += 1;
1576 std::map<int, int>::iterator iter;
1577 for (iter = indVois_nbFace.begin();
1578 iter != indVois_nbFace.end();
1580 int nbFaces = (*iter).second;
1581 if (nbFaces > maxNbFaces) {
1582 maxNbFaces = nbFaces;
1583 indDomVois = (*iter).first;
1587 if (indDomVois == -1)
1588 pfatal() <<
"indDomVois always at -1 !!!";
1591 pinfo() <<
" getDomVoisMaxFace, me = " << me <<
", ListeElements.size() = " << ListeElements.
size()
1592 <<
", indDomVois = " << indDomVois <<
", maxNbFaces = " << maxNbFaces;
1598int* SplitSDMeshPartitioner::
1601 int* MasqueDesNoeuds = NULL;
1605 int maxNodeLocalId = 0;
1609 const Node node = *i_item;
1610 maxNodeLocalId = MAX(maxNodeLocalId, node.
localId());
1613 info() <<
"SplitSDMeshPartitioner::GetMasqueDesNoeuds(), maxNodeLocalId = " << maxNodeLocalId;
1617 MasqueDesNoeuds = (
int*)calloc((
size_t)(maxNodeLocalId + 1),
sizeof(
int));
1618 CHECK_IF_NOT_NULL(MasqueDesNoeuds);
1620 return MasqueDesNoeuds;
1624int* SplitSDMeshPartitioner::
1627 int* MasqueDesElements = NULL;
1631 int maxCellLocalId = 0;
1635 const Cell cell = *i_item;
1636 maxCellLocalId = MAX(maxCellLocalId, cell.
localId());
1640 info() <<
"SplitSDMeshPartitioner::GetMasqueDesElements(), maxCellLocalId = " << maxCellLocalId;
1644 MasqueDesElements = (
int*)calloc((
size_t)(maxCellLocalId + 1),
sizeof(
int));
1645 CHECK_IF_NOT_NULL(MasqueDesElements);
1647 return MasqueDesElements;
1652void SplitSDMeshPartitioner::
1655 ARCANE_UNUSED(InfoProc);
1661void SplitSDMeshPartitioner::
1665 info() <<
"LibereDomaine(...)";
1668 if (Domaine->
NbIntf != 0) {
1669 if (Domaine->
Intf != NULL) {
1670 for (
int i = 0; i < Domaine->
NbIntf; i++)
1672 delete[] Domaine->
Intf;
1673 Domaine->
Intf = NULL;
1683void SplitSDMeshPartitioner::
1687 info() <<
"LibereMaillage(...)";
1703 Maillage->
Poids = 0.0;
1709void SplitSDMeshPartitioner::
1715 for (idom = 0; idom < NbDom; idom++) {
1716 info() <<
" --------------------";
1717 info() <<
" --- Domaine (" << idom <<
") ---";
1718 info() <<
" --------------------";
1720 if (Domaine == NULL) {
1721 info() <<
" Domaine vide ! (pointeur NULL)";
1723 else if (Domaine[idom].NbElements == 0) {
1724 info() <<
" Domaine vide ! (pas d'éléments)";
1727 info() <<
" NbElements = " << Domaine[idom].
NbElements;
1728 info() <<
" PoidsDom = " << Domaine[idom].
PoidsDom;
1729 info() <<
" Interfaces (NbIntf = " << Domaine[idom].
NbIntf <<
") :";
1730 for (i = 0; i < Domaine[idom].
NbIntf; i++) {
1731 info() <<
" (" << i <<
") NoDomVois = " << Domaine[idom].
Intf[i].
NoDomVois
1740void SplitSDMeshPartitioner::
1743 info() <<
" ----------------";
1744 info() <<
" ----- Mesh -----";
1745 info() <<
" ----------------";
1746 if (Maillage == NULL) {
1747 info() <<
" Mesh structure is empty!";
1750 info() <<
" NbElements (total) = " << Maillage->
NbElements;
1751 info() <<
" Poids (total) = " << Maillage->
Poids;
1754 info() <<
" NbProcsVides = " << Maillage->
NbProcsVides;
1757 info() <<
" Maillage.ListeDomaines == NULL";
1767void SplitSDMeshPartitioner::
1770 info() <<
" ListeDomaines :";
1771 for (
int i = 0; i < NbDomaines; i++) {
1772 info() <<
" (" << i <<
") NbElements = " << ListeDomaines[i].
NbElements <<
"; Weight = " << ListeDomaines[i].
Poids;
1773 info() <<
" (" << i <<
") NbVoisins = " << ListeDomaines[i].
NbVoisins <<
"; ListeVoisins :";
1774 for (
int j = 0; j < ListeDomaines[i].
NbVoisins; j++) {
1783void SplitSDMeshPartitioner::
1786 info() <<
" AfficheEquilMaillage(...)";
1788 double poidsMin = 0.0;
1789 double poidsMax = 0.0;
1798 if (poidsDom > poidsMax)
1799 poidsMax = poidsDom;
1800 if (poidsDom < poidsMin)
1801 poidsMin = poidsDom;
1804 info() <<
" INFO balancing / nodes : max : " << poidsMax <<
", min : " << poidsMin
1808 info() <<
"AfficheEquilMaillage : Maillage->ListeDomaines == NULL";
1839 if (*pTailleTMP <= 0) {
1842 ierror = MPI_Probe(FromProc,
1847 if (ierror != MPI_SUCCESS) {
1848 InfoProc->
m_service->
pfatal() <<
"Problem on " << InfoProc->
me <<
" communication from "
1849 << FromProc <<
", during MPI_Probe";
1853 ierror = MPI_Get_count(&status,
1857 if (ierror != MPI_SUCCESS) {
1858 InfoProc->
m_service->
pfatal() <<
"Problem on " << InfoProc->
me <<
" communication from "
1859 << FromProc <<
", during MPI_Get_count";
1864 if (*pTailleTMP > 0) {
1865 TabTMP = malloc((
size_t)*pTailleTMP);
1866 CHECK_IF_NOT_NULL(TabTMP);
1872 ierror = MPI_Recv(TabTMP,
1880 if (ierror != MPI_SUCCESS) {
1881 InfoProc->
m_service->
pfatal() <<
"Problem on " << InfoProc->
me <<
" communication from "
1882 << FromProc <<
", during MPI_Recv";
1910 ierror = MPI_Send((
void*)TabTMP,
1917 if (ierror != MPI_SUCCESS) {
1918 InfoProc->
m_service->
pfatal() <<
"Problem on " << InfoProc->
me <<
" communication to "
1919 << ToProc <<
", during MPI_Send";
1988 if (TailleTMP <= 0) {
1989 InfoProc->
m_service->
pfatal() <<
"DiffuseMessage from " << InfoProc->
me <<
", it is necessary that the array size is known !!!\n";
1992 if (InfoProc->
me != FromProc) {
1993 if (TabTMP == NULL) {
1994 TabTMP = malloc((
size_t)TailleTMP);
1995 CHECK_IF_NOT_NULL(TabTMP);
2000 ierror = MPI_Bcast(TabTMP,
2006 if (ierror != MPI_SUCCESS) {
2008 << FromProc <<
", during MPI_Bcast";
2028 size_t s = (2 + 2 * Domaine->
NbIntf) *
sizeof(
int) +
sizeof(double);
2046void SplitSDMeshPartitioner::
2048 int TailleTMP, MPI_Comm comm)
2053 ier = MPI_Pack(&Domaine->
NbElements, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2054 CHECK_MPI_PACK_ERR(ier);
2056 ier = MPI_Pack(&Domaine->
PoidsDom, 1, MPI_DOUBLE, TabTMP, TailleTMP, &position, comm);
2057 CHECK_MPI_PACK_ERR(ier);
2059 ier = MPI_Pack(&Domaine->
NbIntf, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2060 CHECK_MPI_PACK_ERR(ier);
2062 for (
int i = 0; i < Domaine->
NbIntf; i++) {
2063 ier = MPI_Pack(&Domaine->
Intf[i].
NoDomVois, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2064 CHECK_MPI_PACK_ERR(ier);
2067 ier = MPI_Pack(&NbNoeuds, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2068 CHECK_MPI_PACK_ERR(ier);
2089 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
NbElements, 1, MPI_INT, comm);
2090 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
Poids, 1, MPI_DOUBLE, comm);
2091 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
NbVoisins, 1, MPI_INT, comm);
2095 for (
int i = 0; i < DomMail->
NbVoisins; i++) {
2110 return 2 *
sizeof(int) +
sizeof(
double);
2121 ier = MPI_Pack(&indDomCharge, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2122 CHECK_MPI_PACK_ERR(ier);
2124 ier = MPI_Pack(&indDomVois, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2125 CHECK_MPI_PACK_ERR(ier);
2127 ier = MPI_Pack(&Delta, 1, MPI_DOUBLE, TabTMP, TailleTMP, &position, comm);
2128 CHECK_MPI_PACK_ERR(ier);
2138 MPI_Unpack(TabTMP, TailleTMP, &position, indDomCharge, 1, MPI_INT, comm);
2139 MPI_Unpack(TabTMP, TailleTMP, &position, indDomVois, 1, MPI_INT, comm);
2140 MPI_Unpack(TabTMP, TailleTMP, &position, Delta, 1, MPI_DOUBLE, comm);
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
Integer size() const
Number of elements in the vector.
Generation de la classe de base du Service.
Base class for 1D data vectors.
void fill(ConstReferenceType value)
Fills the array with the value value.
void clear()
Removes the elements from the array.
iterator begin()
Iterator over the first element of the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Face face(Int32 i) const
i-th face of the cell
Int32 nbFace() const
Number of faces of the cell.
Cell frontCell() const
Cell in front of the face (null cell if none).
bool isSubDomainBoundary() const
Indicates if the face is on the subdomain boundary (i.e nbCell()==1).
Cell backCell() const
Cell behind the face (null cell if none).
Exception when a fatal error has occurred.
Interface of a mesh partitioner.
Interface of a mesh partitioner.
virtual IPrimaryMesh * toPrimaryMesh()=0
Returns the instance in the form of an IPrimaryMesh.
Interface of the parallelism manager for a subdomain.
virtual void computeMinMaxSum(char val, char &min_val, char &max_val, char &sum_val, Int32 &min_rank, Int32 &max_rank)=0
Calculates the sum, min, and max of a value in one operation.
virtual Int32 commSize() const =0
Number of instances in the communicator.
Interface of the subdomain manager.
virtual Int32 subDomainId() const =0
Subdomain ID associated with this manager.
virtual IParallelMng * parallelMng()=0
Returns the parallelism manager.
Integer size() const
Number of elements in the group.
Node node(Int32 i) const
i-th node of the entity
Int32 nbNode() const
Number of nodes of the entity.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
Int32 owner() const
Owner subdomain number of the entity.
Real maxImbalance() const override
Maximum allowed imbalance.
virtual void changeOwnersFromCells()
Positions the new owners of nodes, edges and faces based on the cells.
Cell cell(Int32 i) const
i-th cell of the node
Int32 nbCell() const
Number of cells connected to the node.
Structure containing the information to create a service.
Service creation properties.
1D vector of data with reference semantics.
Mesh partitioner inspired by the SplitSD library, developed initially at ONERA for Dassault Aviation.
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
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
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage pinfo() const
Flow for a parallel information message.
TraceMessage fatal() const
Flow for a fatal error message.
TraceMessage pfatal() const
Flow for a parallel fatal error message.
TraceMessage info() const
Flow for an information message.
TraceMessage perror() const
1D data vector with value semantics (STL style).
Parameters necessary for building a variable.
Integer size() const
Number of elements in the vector.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
ItemGroupT< Cell > CellGroup
Group of cells.
ItemGroupT< Face > FaceGroup
Group of faces.
ItemGroupT< Node > NodeGroup
Group of nodes.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
ItemVariableScalarRefT< Integer > VariableItemInteger
Integer type quantity.
ItemVariableScalarRefT< Int32 > VariableItemInt32
32-bit integer type quantity
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Integer arcaneCheckArraySize(unsigned long long size)
Checks that size can be converted into an 'Integer' to serve as the size of an array....
Int32 Integer
Type representing an integer.
@ ST_SubDomain
The service is used at the subdomain level.
bool arcaneIsDebug()
True if the ARCANE_DEBUG macro is defined.
@ IK_Cell
Cell mesh entity.
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