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/ISubDomain.h"
25#include "arcane/IParallelMng.h"
26#include "arcane/ItemEnumerator.h"
27#include "arcane/IPrimaryMesh.h"
28#include "arcane/Properties.h"
29#include "arcane/ItemGroup.h"
30#include "arcane/Service.h"
31#include "arcane/Timer.h"
32#include "arcane/FactoryService.h"
33#include "arcane/ItemPrinter.h"
34#include "arcane/IItemFamily.h"
35#include "arcane/MeshVariable.h"
36#include "arcane/VariableBuildInfo.h"
37#include "arcane/std/MeshPartitionerBase.h"
41#include "arcane/cea/SplitSDMeshPartitioner.h"
51SplitSDMeshPartitioner::
52SplitSDMeshPartitioner(
const ServiceBuildInfo& sbi)
53: ArcaneSplitSDMeshPartitionerObject(sbi)
54, m_poids_aux_mailles(VariableBuildInfo(sbi.mesh(),
"MeshPartitionerCellsWeight",IVariable::PNoDump|IVariable::PNoRestore))
56 info() <<
"SplitSDMeshPartitioner::SplitSDMeshPartitioner(...)";
62void SplitSDMeshPartitioner::
63partitionMesh(
bool initial_partition)
65 info() <<
"Equilibrage de charge avec SplitSDMeshPartitioner";
71 _initArrayCellsWithConstraints();
72 if (haveConstraints())
73 throw FatalErrorException(
"SplitSDMeshPartitioner: On ne supporte pas les contraintes avec SplitSD");
82 init(initial_partition, InfoProc, Domaine, Maillage);
85 Equilibrage(InfoProc, Domaine, Maillage);
88 fin(InfoProc, Domaine, Maillage);
92void SplitSDMeshPartitioner::
95 info() <<
"SplitSDMeshPartitioner::init("<<initial_partition<<
",...)";
97 ISubDomain* sd = subDomain();
98 IParallelMng* pm = sd->parallelMng();
103 InfoProc->
me = sd->subDomainId();
107 InfoProc->
Split_Comm = *(MPI_Comm*)getCommunicator();
111 initPoids(initial_partition);
113 if (!initial_partition){
114 info() <<
"Initialize new owners";
116 IMesh* mesh = this->mesh();
120 cells_new_owner[icell] = cell.owner();
122 changeOwnersFromCells();
123 cells_new_owner.synchronize();
131 Domaine->
Intf = NULL;
145 Maillage->
Poids = 0.0;
148 MAJMaillageMaitre(InfoProc, Domaine, Maillage);
152void SplitSDMeshPartitioner::
153initPoids(
bool initial_partition)
155 ARCANE_UNUSED(initial_partition);
158 IMesh* mesh = this->mesh();
167 SharedArray<float> cell_weights = cellsWeightsWithConstraints(1,
true);
169 m_poids_aux_mailles[iitem] = cell_weights[iitem.index()];
174void SplitSDMeshPartitioner::
177 info() <<
"SplitSDMeshPartitioner::fin(...)";
178 LibereInfoProc(InfoProc);
179 LibereDomaine(Domaine);
180 LibereMaillage(Maillage);
192void SplitSDMeshPartitioner::
195 debug() <<
" ----------------------------------------";
196 debug() <<
"SplitSDMeshPartitioner::MAJDomaine(...)";
198 LibereDomaine(Domaine);
200 int me = subDomain()->subDomainId();
204 IMesh* mesh = this->mesh();
206 debug() <<
" all_faces.size() = =" <<all_faces.
size();
208 std::map<int, SharedArray<Face> > vois_faces;
211 const Face face = *i_item;
212 if (!face.isSubDomainBoundary()){
213 int id1 = face.backCell().owner();
214 int id2 = face.frontCell().owner();
227 SharedArray<Face> &v_face = vois_faces[idv];
234 UniqueArray<int> filtreNoeuds(mesh->nodeFamily()->maxLocalId());
235 filtreNoeuds.fill(0);
244 Domaine->
NbElements = mesh->ownCells().size();
251 Domaine->
PoidsDom += m_poids_aux_mailles[cell];
255 info() <<
"Domaine->NbIntf = "<<Domaine->
NbIntf;
256 info() <<
"Domaine->NbElements = "<<Domaine->
NbElements;
257 info() <<
"Domaine->PoidsDom = "<<Domaine->
PoidsDom;
261 unsigned int ind = 0;
262 for (std::map<
int, SharedArray<Face> >::iterator iter_vois = vois_faces.begin();
263 iter_vois!=vois_faces.end(); ++iter_vois) {
268 Array<Face> &v_face = (*iter_vois).second;
271 info() <<
"Domaine->Intf["<<ind<<
"].NoDomVois = "<<Domaine->
Intf[ind].
NoDomVois;
272 info() <<
" v_face.size() = "<<v_face.size();
275 for (
int i = 0; i<v_face.size(); i++){
276 const Face& face = v_face[i];
280 for( Integer z=0; z<face.nbNode(); ++z ){
281 const Node node = face.node(z);
282 Integer node_local_id = node.localId();
283 if (filtreNoeuds[node_local_id] != marque){
285 filtreNoeuds[node_local_id] = marque;
291 info() <<
" ListeNoeuds.size() = "<<Domaine->
Intf[ind].
ListeNoeuds.size();
298 info() <<
"MAJDomaine => ";
299 AfficheDomaine(1,Domaine);
300 info() <<
" ----------------------------------------";
305void SplitSDMeshPartitioner::
311 info() <<
"SplitSDMeshPartitioner::MAJMaillageMaitre(...)";
312 LibereMaillage(Maillage);
320 TailleTab = TailleDom(Domaine);
321 TabTMP = malloc ((
size_t) TailleTab);
323 PackDom(InfoProc, Domaine, TabTMP, TailleTab, InfoProc->
Split_Comm);
328 if (InfoProc->
me == 0){
330 info()<<
" ***************************";
331 info()<<
" * Avant MAJMaillageMaitre *";
332 AfficheMaillage (Maillage);
333 info()<<
" ***************************";
349 EnvoieMessage(InfoProc, 0, TAG_MAILLAGEMAITRE, TabTMP, TailleTab);
361 if (InfoProc->
me == 0){
364 Maillage->
Poids = 0.0;
368 for (iDom=InfoProc->
nbSubDomain-1; iDom>=0; iDom--){
372 TabTMP = RecoitMessage(InfoProc, iDom, TAG_MAILLAGEMAITRE, &TailleTab);
376 free ((
void*) TabTMP); TabTMP = NULL;
390 info()<<
" ***************************";
391 info()<<
" * Apres MAJMaillageMaitre *";
393 AfficheMaillage (Maillage);
395 info()<<
" ***************************";
396 verifMaillageMaitre(Maillage);
403void SplitSDMeshPartitioner::
407 info()<<
" on entre dans verifMaillageMaitre";
412 for (
int iDom=0; iDom<NbDomaines; iDom++){
413 for (
int j=0; j<ListeDomaines[iDom].
NbVoisins; j++){
422 if (k==ListeDomaines[iVois].NbVoisins){
423 printf(
"on ne trouve pas le numéro de voisin \n");
424 printf(
"pour info: iDom = %d, iVois = %d\n",iDom,iVois);
425 perror() <<
"verifMaillageMaitre en erreur sur le voisinage !!!";
428 if (ListeDomaines[iVois].ListeVoisins[k].NbNoeudsInterface != NbNoeudsInterface){
429 printf(
"on ne trouve pas le même nombre de noeuds entre les voisins \n");
430 printf(
"pour info: iDom = %d, iVois = %d, NbNoeudsInterface %d != %d\n"
431 ,iDom,iVois,NbNoeudsInterface,ListeDomaines[iVois].ListeVoisins[k].NbNoeudsInterface);
432 perror() <<
"verifMaillageMaitre en erreur sur le nombre de noeuds !!!";
437 info()<<
" on sort de verifMaillageMaitre";
439 ARCANE_UNUSED(Maillage);
444void SplitSDMeshPartitioner::
462 int* ListeNoeudsPrec;
466 int marqueDomNonVu = 0;
467 int marqueDomVide = -1;
472 info()<<
" ------------------------------------";
473 info()<<
" on entre dans MAJDeltaGlobal, tolerance = "<<tolerance;
474 info()<<
" ------------------------------------";
475 info()<<
" ......... Maillage Initial ...........";
476 AfficheListeDomaines(ListeDomaines,NbDomaines);
480 info()<<
" SplitSDMeshPartitioner::MAJDeltaGlobal : NbDomaines nul !";
485 info()<<
" \n = on sort de MAJDeltaGlobal sans rien faire (NbDomainesPleins = "<<Maillage->
NbDomainesPleins;
486 info()<<
" ------------------------------------";
491 FiltreDomaine = (
int*) malloc ((
size_t) NbDomaines*
sizeof(int));
492 CHECK_IF_NOT_NULL(FiltreDomaine);
495 for (i=0; i<NbDomaines; i++)
496 for (
int j=0; j<ListeDomaines[i].
NbVoisins; j++)
497 ListeDomaines[i].ListeVoisins[j].Delta = 0.0;
504 for (i=0; i<NbDomaines; i++){
505 if (ListeDomaines[i].NbElements != 0)
506 FiltreDomaine[i] = marqueDomNonVu;
508 FiltreDomaine[i] = marqueDomVide;
511 PoidsSave = (
double*) malloc ((
size_t) NbDomaines*
sizeof(double));
512 CHECK_IF_NOT_NULL(PoidsSave);
518 for (i=0; i<NbDomaines; i++){
520 PoidsSave[i] = ListeDomaines[i].
Poids;
522 if (FiltreDomaine[i] != marqueDomVide)
523 ListeDomaines[i].
Poids -= PoidsMoyen;
527 info()<<
" Après Poids -= PoidsMoyen";
528 AfficheListeDomaines(ListeDomaines,NbDomaines);
532 FrontPrec = (
int*) malloc ((
size_t) (NbDomaines-1)*
sizeof(
int));
533 CHECK_IF_NOT_NULL(FrontPrec);
534 FrontSuiv = (
int*) malloc ((
size_t) (NbDomaines-1)*
sizeof(
int));
535 CHECK_IF_NOT_NULL(FrontSuiv);
537 ListeNoeudsPrec = (
int*) malloc ((
size_t) (NbDomaines)*
sizeof(
int));
538 CHECK_IF_NOT_NULL(ListeNoeudsPrec);
540 for (iDomDep=0; iDomDep<NbDomaines; iDomDep++){
542 info()<<
" ListeDomaines[iDomDep = "<<iDomDep<<
"].Poids = "<<ListeDomaines[iDomDep].
Poids;
547 if (ListeDomaines[iDomDep].Poids > tolerance){
551 for (i=0; i<NbDomaines; i++)
552 if (FiltreDomaine[i] == marqueDomVu)
553 FiltreDomaine[i] = marqueDomNonVu;
556 FiltreDomaine[iDomDep] = marqueDomVu;
560 FrontSuiv[tailleFS-1] = iDomDep;
563 info()<<
" FrontSuiv[0] = "<<iDomDep;
567 ListeNoeudsPrec[FrontSuiv[tailleFS-1]] = -1;
570 while (ListeDomaines[iDomDep].Poids > tolerance){
572 info()<<
" while (ListeDomaines["<<iDomDep<<
"].Poids = "<<ListeDomaines[iDomDep].
Poids<<
" > "<<tolerance;
576 FrontTMP = FrontPrec;
577 FrontPrec = FrontSuiv;
578 FrontSuiv = FrontTMP;
585 fatal()<<
" partitionner/MAJDeltaGlobal: on ne trouve plus de domaine alors que l'on n'a pas terminé !!!";
593 for (
int iFP=0; iFP<tailleFP; iFP++){
594 int iDom = FrontPrec[iFP];
597 for (
int iVois=0; iVois<ListeDomaines[iDom].
NbVoisins; iVois++){
599 if (FiltreDomaine[iDomVois] == marqueDomNonVu){
601 FiltreDomaine[iDomVois] = marqueDomVu;
602 ListeNoeudsPrec[iDomVois] = iDom;
604 info()<<
" FrontSuiv["<<tailleFS<<
"] = "<<iDomVois;
606 FrontSuiv[tailleFS++] = iDomVois;
617 for (
int iFS=0; iFS<tailleFS; iFS++){
618 int iDom = FrontSuiv[iFS];
621 info()<<
" ListeDomaines["<<iDom<<
"].Poids = "<<ListeDomaines[iDom].
Poids;
625 if (ListeDomaines[iDom].Poids < 0.0){
627 double don = MIN(-ListeDomaines[iDom].Poids, ListeDomaines[iDomDep].Poids);
634 ListeDomaines[iDom].
Poids += don;
635 ListeDomaines[iDomDep].
Poids -= don;
642 iDomTmpPrec = ListeNoeudsPrec[iDomTmp];
643 while (iDomTmpPrec != -1){
645 MAJDelta(don,iDomTmpPrec,iDomTmp,ListeDomaines);
647 MAJDelta(-don,iDomTmp,iDomTmpPrec,ListeDomaines);
650 iDomTmp = iDomTmpPrec;
651 iDomTmpPrec = ListeNoeudsPrec[iDomTmp];
666 for (i=0; i<NbDomaines; i++)
667 ListeDomaines[i].Poids = PoidsSave[i];
669 free((
void*) FrontPrec); FrontPrec = NULL;
670 free((
void*) FrontSuiv); FrontSuiv = NULL;
671 free((
void*) ListeNoeudsPrec); ListeNoeudsPrec = NULL;
672 free((
void*) FiltreDomaine); FiltreDomaine = NULL;
673 free((
void*) PoidsSave); PoidsSave = NULL;
676 info()<<
" ......... Maillage Final ...........";
677 AfficheListeDomaines(ListeDomaines,NbDomaines);
678 info()<<
" = on sort de MAJDeltaGlobal =";
679 info()<<
" ------------------------------------";
684void SplitSDMeshPartitioner::
695 if (j == ListeDomaines[iDom].NbVoisins)
697 info()<<
"on ne trouve pas le numéro de voisin";
698 info()<<
"pour info: ajout = "<<ajout<<
", iDom = "<<iDom<<
", iVois = "<<iVois;
699 pfatal()<<
"Erreur dans Partitionner/MAJDelta, pas de voisin !";
708double SplitSDMeshPartitioner::
709CalculDeltaMin(
StrucMaillage* Maillage,
double deltaMin,
int iterEquilibrage,
int NbMaxIterEquil)
716 debug()<<
" on entre dans SplitSDMeshPartitioner::CalculDeltaMin, deltaMin = "<<deltaMin
717 <<
", iterEquilibrage = " <<iterEquilibrage
718 <<
", NbMaxIterEquil = " <<NbMaxIterEquil;
720 AfficheMaillage (Maillage);
722 double deltaAjuste = deltaMin;
725 double deltaMaxItf = 0.0;
727 double ratioDeltaMax = 0.0;
732 for (
int iDom=0; iDom<NbDomaines; iDom++){
733 double deltaTotalDom = 0.0;
734 for (
int j=0; j<ListeDomaines[iDom].
NbVoisins; j++){
736 deltaMaxItf = MAX(delta, deltaMaxItf);
737 if (delta > 0.0) deltaTotalDom += delta;
740 if (ListeDomaines[iDom].Poids>0.0)
741 ratio = deltaTotalDom/ ListeDomaines[iDom].
Poids;
742 ratioDeltaMax = MAX(ratio,ratioDeltaMax);
748 if (ratioDeltaMax>0.9)
749 deltaAjuste = poidsMoy/3.0;
750 else if (ratioDeltaMax>0.5)
751 deltaAjuste = deltaMaxItf/10.0;
754 deltaAjuste = MAX(deltaMin,deltaAjuste);
756#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
758 double proportion = deltaMaxItf/poidsMoy;
760 info()<<
" deltaMaxItf = "<<deltaMaxItf;
761 info()<<
" ratioDeltaMax = "<<ratioDeltaMax;
762 info()<<
" poidsMoy = "<<poidsMoy;
763 info()<<
" proportion = "<<proportion;
764 info()<<
" deltaAjuste = "<<deltaAjuste;
771void SplitSDMeshPartitioner::
775 int indDomCharge = -1;
786 int NbAppelsAEquil2Dom = -1;
788 int iterEquilibrage = 0;
789 int NbMaxIterEquil = 5;
791 double tolConnexite = 0.1;
795 info()<<
" -------------------------------------";
796 info()<<
" on entre dans SplitSDMeshPartitioner::Equilibrage, deltaMin = "<<deltaMin;
799 int TailleTMP = TailleEquil();
800 TabTMP = malloc((
size_t)TailleTMP);
801 CHECK_IF_NOT_NULL(TabTMP);
804 while (iterEquilibrage<NbMaxIterEquil && NbAppelsAEquil2Dom!=0){
807 int marqueDomNonVu = 0;
810 NbAppelsAEquil2Dom = 0;
815 int* MasqueDesNoeuds = GetMasqueDesNoeuds(InfoProc);
816 int* MasqueDesElements = GetMasqueDesElements(InfoProc);
820 IPrimaryMesh* mesh = this->mesh()->toPrimaryMesh();
823 if (InfoProc->
me == 0){
824 info()<<
" SplitSDMeshPartitioner::Equilibrage de la charge (iteration No "<<iterEquilibrage<<
")";
827 MAJDeltaGlobal(InfoProc, Maillage, deltaMin);
830 double deltaAjuste = CalculDeltaMin(Maillage, deltaMin, iterEquilibrage, NbMaxIterEquil);
833 FiltreDomaine = (
int*) calloc ((
size_t) Maillage->
NbDomainesMax,
sizeof(int));
834 CHECK_IF_NOT_NULL(FiltreDomaine);
839 FiltreDomaine[iDom] = marqueDomVu;
849 if (FiltreDomaine[iDom] == marqueDomNonVu && Maillage->
ListeDomaines[iDom].
Poids > poidsMax){
855 info()<<
"indDomCharge = "<<indDomCharge<<
"; poidsMax = "<<poidsMax;
858 if (indDomCharge != -1) {
860 FiltreDomaine[indDomCharge] = marqueDomVu;
872#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
873 info()<<
" Equilibrage ("<<iterEquilibrage<<
") pour le couple indDomCharge = "<<indDomCharge<<
"; indDomVois = "<<indDomVois
881 TabTMP = DiffuseMessage(InfoProc, 0, TabTMP, TailleTMP);
887 Equil2Dom(MasqueDesNoeuds, MasqueDesElements, marqueVu, marqueNonVu,
888 InfoProc, Domaine, Maillage, indDomCharge, indDomVois,
890 NbAppelsAEquil2Dom += 1;
896 }
while (indDomCharge != -1);
899 double DeltaNul = 0.0;
900 PackEquil(InfoProc, indDomCharge, indDomVois, DeltaNul, TabTMP, TailleTMP, InfoProc->
Split_Comm);
902 TabTMP = DiffuseMessage(InfoProc, 0, TabTMP, TailleTMP);
904 free((
void*) FiltreDomaine);
905 FiltreDomaine = NULL;
909 info()<<
" NbAppelsAEquil2Dom = "<<NbAppelsAEquil2Dom;
917 TabTMP = DiffuseMessage(InfoProc, 0, TabTMP, TailleTMP);
918 UnpackEquil(TabTMP, TailleTMP, InfoProc->
Split_Comm, &indDomCharge, &indDomVois, &Delta);
920 if (indDomCharge != -1){
925 Equil2Dom(MasqueDesNoeuds, MasqueDesElements, marqueVu, marqueNonVu,
926 InfoProc, Domaine, Maillage, indDomCharge, indDomVois, Delta);
927 NbAppelsAEquil2Dom += 1;
930 }
while(indDomCharge != -1);
935 if (NbAppelsAEquil2Dom){
937 LibereDomaine(Domaine);
940 info() <<
"cells_new_owner.synchronize() et changeOwnersFromCells()";
944 cells_new_owner.synchronize();
945 changeOwnersFromCells();
947 bool compact = mesh->properties()->getBool(
"compact");
948 mesh->properties()->setBool(
"compact",
false);
949 mesh->exchangeItems();
950 mesh->properties()->setBool(
"compact", compact);
956 MAJMaillageMaitre(InfoProc,Domaine,Maillage);
959 free((
void*)MasqueDesNoeuds);
960 MasqueDesNoeuds = NULL;
961 free((
void*)MasqueDesElements);
962 MasqueDesElements = NULL;
964 AfficheEquilMaillage(Maillage);
969 ConnexifieDomaine(InfoProc, Domaine, Maillage, tolConnexite);
971 AfficheEquilMaillage(Maillage);
978 debug()<<
" nombre d'iterations pour equilibrage = "<<iterEquilibrage<<
" / "<<NbMaxIterEquil<<
" max ";
979 debug()<<
" = on sort de SplitSDMeshPartitioner::Equilibrage";
980 debug()<<
" -------------------------------------";
986void SplitSDMeshPartitioner::
987Equil2Dom(
int* MasqueDesNoeuds,
int* MasqueDesElements,
int marqueVu,
int marqueNonVu,
989 int indDomCharge,
int indDomVois,
double Delta)
991 ARCANE_UNUSED(Maillage);
993 debug()<<
" on entre dans Equil2Dom (indDomCharge:"<<indDomCharge<<
", indDomVois:"<<indDomVois<<
", Delta:"<<Delta;
998 if (InfoProc->
me == indDomCharge){
1007 if (iIntf==Domaine->
NbIntf){
1008#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
1009 pinfo()<<
"### l'interface a disparu ### entre "<<indDomCharge<<
" et " <<indDomVois;
1014 SelectElements(MasqueDesNoeuds, MasqueDesElements,
1015 marqueVu, marqueNonVu,
1016 InfoProc, Domaine, Delta, indDomVois, ListeElements);
1021 IPrimaryMesh* mesh = this->mesh()->toPrimaryMesh();
1024 for (
int i=0; i<ListeElements.
size(); i++){
1025 const Cell item = ListeElements[i];
1026 cells_new_owner[item] = indDomVois;
1032 info() <<
"SelectElements et autres operations sur les processeurs "<<indDomCharge<<
" et " <<indDomVois;
1035 info()<<
" on sort de Equil2Dom";
1040void SplitSDMeshPartitioner::
1041SelectElements(
int* MasqueDesNoeuds,
int* MasqueDesElements,
int marqueVu,
int marqueNonVu,
1046 info()<<
"SplitSDMeshPartitioner::SelectElements(Domaine, Delta = "<<Delta<<
", indDomVois = "<<indDomVois<<
")";
1047 info()<<
" Domaine->NbElements = " << Domaine->
NbElements;
1048 info()<<
" Domaine->PoidsDom = " << Domaine->
PoidsDom;
1052 perror() <<
"Delta <= 0 !!!";
1055 IMesh* mesh = this->mesh();
1059 pinfo()<<
" Tout le domaine est sélectionné sur le domaine "<<subDomain()->subDomainId()
1060 <<
", avec SelectElements, PoidsDom = " << Domaine->
PoidsDom
1061 <<
", Delta = "<<Delta;
1067 const Cell item = *i_item;
1069 ListeElements.
add(item);
1077 int* IndFrontsNoeuds;
1078 int* IndFrontsElements;
1080 for (iIntf=0; iIntf<Domaine->
NbIntf && Domaine->
Intf[iIntf].
NoDomVois != indDomVois; iIntf++)
1083 if (iIntf==Domaine->
NbIntf) {
1084 pfatal()<<
" SelectElements ne trouve pas l'interface parmis les voisins !!!";
1095 IndFrontsNoeuds = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1096 CHECK_IF_NOT_NULL(IndFrontsNoeuds);
1098 IndFrontsElements = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1099 CHECK_IF_NOT_NULL(IndFrontsElements);
1108 IndFrontsNoeuds[0] = 0;
1110 IndFrontsElements[0] = 0;
1111 IndFrontsElements[1] = 0;
1114 int me = subDomain()->subDomainId();
1117 const Cell cell = *i_item;
1118 if (cell.owner() != me)
1119 MasqueDesElements[cell.localId()] = marqueVu;
1123 for (
int i=0; i<ListeElements.
size(); i++){
1124 const Cell cell = ListeElements[i];
1125 MasqueDesElements[cell.localId()] = marqueVu;
1131 retPF = ParcoursFrontalDelta (MasqueDesNoeuds, MasqueDesElements,
1132 marqueVu, marqueNonVu,
1134 &NbFronts, NbFrontsMax,
1135 FrontsNoeuds, IndFrontsNoeuds,
1136 FrontsElements,IndFrontsElements);
1140 IndFrontsNoeuds[NbFronts-1] = IndFrontsNoeuds[NbFronts];
1141 IndFrontsElements[NbFronts-1] = IndFrontsElements[NbFronts];
1148 LissageDuFront(MasqueDesNoeuds, MasqueDesElements,
1149 marqueVu, marqueNonVu,
1151 FrontsNoeuds, IndFrontsNoeuds,
1152 FrontsElements,IndFrontsElements);
1155 free((
void*)IndFrontsNoeuds); IndFrontsNoeuds = NULL;
1156 free((
void*)IndFrontsElements); IndFrontsElements = NULL;
1159 info()<<
" en sortie: ListeElements.size() = "<<ListeElements.
size();
1163int SplitSDMeshPartitioner::
1164ParcoursFrontalDelta (
int* MasqueDesNoeuds,
int* MasqueDesElements,
1165 int marqueVu,
int marqueNonVu,
1167 int *pNbFronts,
int NbFrontsMax,
1172 info()<<
" = on entre dans ParcoursFront : (NbFronts = "<<*pNbFronts<<
", NbFrontsMax = "<<NbFrontsMax<<
")";
1173 info()<<
" FrontsNoeuds.size() = "<<FrontsNoeuds.
size();
1174 info()<<
" FrontsElements.size() = "<<FrontsElements.
size();
1179 double PoidsActuel = 0.0;
1180 bool bloque =
false;
1183 for (IndFn=0; IndFn<IndFrontsNoeuds[*pNbFronts]; IndFn++){
1184 MasqueDesNoeuds[FrontsNoeuds[IndFn].localId()] = marqueVu;
1187 for (IndFe=0; IndFe<IndFrontsElements[*pNbFronts]; IndFe++){
1188 MasqueDesElements[FrontsElements[IndFe].localId()] = marqueVu;
1193 if (IndFrontsElements[*pNbFronts] > 0 && IndFrontsNoeuds[*pNbFronts] == 0){
1195 for (
int ielm=0; ielm<IndFrontsElements[*pNbFronts]; ielm++){
1196 const Cell cell = FrontsElements[ielm];
1197 PoidsActuel += m_poids_aux_mailles[cell];
1199 for (
int iepn = 0; iepn < cell.nbNode(); iepn++){
1200 const Node nodeVois = cell.node(iepn);
1203 if (MasqueDesNoeuds[nodeVois.localId()] == marqueNonVu){
1204 FrontsNoeuds.
add(nodeVois);
1206 MasqueDesNoeuds[nodeVois.localId()] = marqueVu;
1211 IndFrontsNoeuds[*pNbFronts] = IndFn;
1219 for (
int in = IndFrontsNoeuds[*pNbFronts-1];
1220 in < IndFrontsNoeuds[*pNbFronts] && PoidsActuel<Delta;
1222 const Node node = FrontsNoeuds[in];
1226 for (
int inpe = 0; inpe < node.nbCell(); inpe++){
1227 const Cell cell = node.cell(inpe);
1231 if (MasqueDesElements[cell.localId()] == marqueNonVu) {
1232 FrontsElements.
add(cell);
1234 MasqueDesElements[cell.localId()] = marqueVu;
1236 PoidsActuel += m_poids_aux_mailles[cell];
1238 for (
int iepn = 0; iepn < cell.nbNode(); iepn++){
1239 const Node nodeVois = cell.node(iepn);
1242 if (MasqueDesNoeuds[nodeVois.localId()] == marqueNonVu){
1243 FrontsNoeuds.
add(nodeVois);
1245 MasqueDesNoeuds[nodeVois.localId()] = marqueVu;
1253 if (IndFrontsNoeuds[*pNbFronts-1] == IndFrontsNoeuds[*pNbFronts]){
1258 IndFrontsNoeuds[*pNbFronts] = IndFn;
1259 IndFrontsElements[*pNbFronts] = IndFe;
1262 while (*pNbFronts<NbFrontsMax && PoidsActuel<Delta && !bloque);
1266 info()<<
" NbFronts = "<<*pNbFronts;
1267 info()<<
" Delta = "<<Delta;
1268 info()<<
" PoidsActuel = "<<PoidsActuel;
1269 info()<<
" NbNoeuds = "<<IndFrontsNoeuds[*pNbFronts];
1270 info()<<
" NbElements = "<<IndFrontsElements[*pNbFronts];
1271 info()<<
" bloque = "<<(bloque?
"VRAI":
"FAUX");
1273 if (!(*pNbFronts<NbFrontsMax)){
1274 info()<<
" = on arete apres avoir obtenu le nombre maximum de fronts "<<NbFrontsMax;
1276 else if (!(PoidsActuel<Delta)){
1277 info()<<
" = on arete apres avoir obtenu le poids desire "<<PoidsActuel;
1280 info()<<
" = on est bloque (non connexe ?) =";
1283 info()<<
" = on arete parce que l'on a tout vu =";
1285 info()<<
" = on sort de ParcoursFront . =";
1288 return ((bloque)?1:0);
1293void SplitSDMeshPartitioner::
1294LissageDuFront (
int* MasqueDesNoeuds,
int* MasqueDesElements,
1295 int marqueVu,
int marqueNonVu,
1300 ARCANE_UNUSED(IndFrontsElements);
1302 debug()<<
" on entre dans LissageDuFront : NbFronts = "<<NbFronts;
1304 int NbElementsAjoutes = 0;
1309 for (
int IndFn=IndFrontsNoeuds[NbFronts-1]; IndFn<IndFrontsNoeuds[NbFronts]; IndFn++){
1310 const Node node = FrontsNoeuds[IndFn];
1312 for (
int inpe = 0; inpe < node.nbCell(); inpe++){
1313 const Cell cell = node.cell(inpe);
1316 if (MasqueDesElements[cell.localId()] == marqueNonVu){
1319 for (iepn = 0; iepn < cell.nbNode() && MasqueDesNoeuds[cell.node(iepn).localId()] == marqueVu; iepn++)
1322 if (iepn == cell.nbNode()){
1325 FrontsElements.
add(cell);
1326 NbElementsAjoutes+=1;
1327 MasqueDesElements[cell.localId()] = marqueVu;
1331 MasqueDesElements[cell.localId()] = marqueVu;
1332 ElementsALiberer.
add(cell);
1340 for (
int i=0; i<ElementsALiberer.
size(); i++)
1341 MasqueDesElements[ElementsALiberer[i].localId()] = marqueNonVu;
1344 info()<<
" on sort de LissageDuFront ("<<NbElementsAjoutes<<
" elements ajoutes)";
1349void SplitSDMeshPartitioner::
1351 double tolConnexite)
1354 info()<<
" on entre dans ConnexifieDomaine, tolConnexite = "<<tolConnexite;
1357 int* MasqueDesNoeuds = GetMasqueDesNoeuds(InfoProc);
1358 int* MasqueDesElements = GetMasqueDesElements(InfoProc);
1360 int marqueNonVu = 0;
1364 double tailleMoy = (double)Domaine->
NbElements;
1367 int me = InfoProc->
me;
1368 IPrimaryMesh* mesh = this->mesh()->toPrimaryMesh();
1372 Cell cell = *i_item;
1373 if (cell.owner() != me)
1374 MasqueDesElements[cell.localId()] = marqueVu;
1377 int NbElementsVus = 0;
1380 info()<<
" NbElementsAVoir = "<<NbElementsAVoir;
1385 int* IndFrontsNoeuds;
1386 int* IndFrontsElements;
1396 IndFrontsNoeuds = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1397 CHECK_IF_NOT_NULL(IndFrontsNoeuds);
1399 IndFrontsElements = (
int*) malloc ((
size_t) (NbFrontsMax+1)*
sizeof(
int));
1400 CHECK_IF_NOT_NULL(IndFrontsElements);
1404 while (NbElementsVus < NbElementsAVoir){
1406 FrontsNoeuds.
clear();
1411 bool trouve =
false;
1413 const Cell cell = *i_item;
1414 if (!trouve && MasqueDesElements[cell.localId()] == marqueNonVu){
1415 FrontsElements.
add(cell);
1420 pfatal()<<
"ConnexifieDomaine est bloqué lors de la recherche d'un élément de départ";
1424 IndFrontsNoeuds[0] = 0;
1425 IndFrontsNoeuds[1] = 0;
1426 IndFrontsElements[0] = 0;
1427 IndFrontsElements[1] = 1;
1430 ParcoursFrontalDelta (MasqueDesNoeuds, MasqueDesElements,
1431 marqueVu, marqueNonVu,
1433 &NbFronts, NbFrontsMax,
1434 FrontsNoeuds, IndFrontsNoeuds,
1435 FrontsElements,IndFrontsElements);
1438 ListeFrontsElements.
add(FrontsElements);
1440 NbElementsVus+=FrontsElements.
size();
1442 info()<<
" NbElementsVus+="<<FrontsElements.
size();
1451 if (ListeFrontsElements.
size() > 1){
1454 info()<<
" NbComposantesConnexes = "<<ListeFrontsElements.
size();
1458 int nbDomEnDessous = 0;
1459 int plusGrosseCC = 0;
1461 int seuil = (int)(tailleMoy*tolConnexite);
1463 info()<<
" seuil = "<<seuil;
1466 for (
int i=0; i<ListeFrontsElements.
size(); i++){
1468 plusGrosseCC = MAX(plusGrosseCC,FrontsElements.
size());
1469 if (FrontsElements.
size()<seuil)
1474 info()<<
" nbDomEnDessous = "<<nbDomEnDessous;
1478 if (nbDomEnDessous == ListeFrontsElements.
size()){
1480 info() <<
" seuil abaissé à "<< plusGrosseCC;
1482 seuil = plusGrosseCC;
1487 for (
int i=0; i<ListeFrontsElements.
size(); i++){
1489 if (FrontsElements.
size()<seuil){
1493 int indDomVois = getDomVoisMaxFace(FrontsElements, me);
1496 for (
int j=0; j<FrontsElements.
size(); j++){
1497 const Cell item = FrontsElements[j];
1498 cells_new_owner[item] = indDomVois;
1504 info() <<
" Nombre de composantes transférées : "<<nbCCTransf;
1510 free((
void*) IndFrontsNoeuds);
1511 IndFrontsNoeuds = NULL;
1512 free((
void*) IndFrontsElements);
1513 IndFrontsElements = NULL;
1515 free((
void*)MasqueDesNoeuds);
1516 MasqueDesNoeuds = NULL;
1517 free((
void*)MasqueDesElements);
1518 MasqueDesElements = NULL;
1524 int nbCCTransfMin = 0;
1525 int nbCCTransfMax = 0;
1526 int nbCCTransfSum = 0;
1530 ISubDomain* sd = subDomain();
1531 IParallelMng* pm = sd->parallelMng();
1533 pm->computeMinMaxSum(nbCCTransf, nbCCTransfMin, nbCCTransfMax, nbCCTransfSum, procMin, procMax);
1535 bool synchroNecessaire = (nbCCTransfSum > 0);
1536#if defined(ARCANE_DEBUG) || defined(DEBUG_PARTITIONER)
1537 info()<<
" ConnexifieDomaine: nbCCTransfSum = "<<nbCCTransfSum;
1540 if (synchroNecessaire){
1542 info()<<
" on fait la synchronisation";
1546 cells_new_owner.synchronize();
1547 changeOwnersFromCells();
1549 bool compact = mesh->properties()->getBool(
"compact");
1550 mesh->properties()->setBool(
"compact",
false);
1551 mesh->exchangeItems();
1552 mesh->properties()->setBool(
"compact", compact);
1555 MAJDomaine(Domaine);
1558 MAJMaillageMaitre(InfoProc,Domaine,Maillage);
1561 info()<<
" on sort de ConnexifieDomaine";
1566int SplitSDMeshPartitioner::
1569 int indDomVois = -1;
1572 std::map<int,int> indVois_nbFace;
1574 for (
int i=0; i<ListeElements.
size(); i++){
1575 const Cell cell = ListeElements[i];
1577 for (
int j=0;j<cell.nbFace(); j++){
1578 const Face face = cell.face(j);
1580 if (!face.isSubDomainBoundary()){
1581 int id1 = face.backCell().owner();
1582 int id2 = face.frontCell().owner();
1584 if (id1 == me && id2 != me)
1585 indVois_nbFace[id2]+=1;
1586 else if (id1 != me && id2 == me)
1587 indVois_nbFace[id1]+=1;
1594 std::map<int,int>::iterator iter;
1595 for (iter = indVois_nbFace.begin();
1596 iter != indVois_nbFace.end();
1598 int nbFaces = (*iter).second;
1599 if (nbFaces>maxNbFaces){
1600 maxNbFaces = nbFaces;
1601 indDomVois = (*iter).first;
1605 if (indDomVois == -1)
1606 pfatal()<<
"indDomVois toujours à -1 !!!";
1609 pinfo()<<
" getDomVoisMaxFace, me = "<<me<<
", ListeElements.size() = "<<ListeElements.
size()
1610 <<
", indDomVois = "<<indDomVois<<
", maxNbFaces = "<<maxNbFaces;
1616int* SplitSDMeshPartitioner::
1619 int* MasqueDesNoeuds = NULL;
1621 IMesh* mesh = this->mesh();
1623 int maxNodeLocalId = 0;
1627 const Node node = *i_item;
1628 maxNodeLocalId = MAX(maxNodeLocalId,node.localId());
1631 info() <<
"SplitSDMeshPartitioner::GetMasqueDesNoeuds(), maxNodeLocalId = "<<maxNodeLocalId;
1635 MasqueDesNoeuds = (
int*) calloc ((
size_t)(maxNodeLocalId+1),
sizeof(
int));
1636 CHECK_IF_NOT_NULL(MasqueDesNoeuds);
1638 return MasqueDesNoeuds;
1642int* SplitSDMeshPartitioner::
1645 int* MasqueDesElements = NULL;
1647 IMesh* mesh = this->mesh();
1649 int maxCellLocalId = 0;
1653 const Cell cell = *i_item;
1654 maxCellLocalId = MAX(maxCellLocalId,cell.localId());
1658 info() <<
"SplitSDMeshPartitioner::GetMasqueDesElements(), maxCellLocalId = "<<maxCellLocalId;
1662 MasqueDesElements = (
int*) calloc ((
size_t)(maxCellLocalId+1),
sizeof(
int));
1663 CHECK_IF_NOT_NULL(MasqueDesElements);
1665 return MasqueDesElements;
1670void SplitSDMeshPartitioner::
1673 ARCANE_UNUSED(InfoProc);
1679void SplitSDMeshPartitioner::
1683 info()<<
"LibereDomaine(...)";
1686 if (Domaine->
NbIntf != 0){
1687 if (Domaine->
Intf != NULL){
1688 for (
int i=0; i<Domaine->
NbIntf; i++)
1690 delete [] Domaine->
Intf;
1691 Domaine->
Intf = NULL;
1701void SplitSDMeshPartitioner::
1705 info()<<
"LibereMaillage(...)";
1721 Maillage->
Poids = 0.0;
1727void SplitSDMeshPartitioner::
1733 for (idom=0; idom<NbDom; idom++) {
1734 info()<<
" --------------------";
1735 info()<<
" --- Domaine ("<<idom<<
") ---";
1736 info()<<
" --------------------";
1738 if (Domaine == NULL){
1739 info()<<
" Domaine vide ! (pointeur NULL)";
1741 else if (Domaine[idom].NbElements == 0) {
1742 info()<<
" Domaine vide ! (pas d'éléments)";
1745 info()<<
" NbElements = "<<Domaine[idom].
NbElements;
1746 info()<<
" PoidsDom = "<<Domaine[idom].
PoidsDom;
1747 info()<<
" Interfaces (NbIntf = "<<Domaine[idom].
NbIntf<<
") :";
1748 for (i=0; i<Domaine[idom].
NbIntf; i++) {
1749 info()<<
" ("<<i<<
") NoDomVois = "<<Domaine[idom].
Intf[i].
NoDomVois
1758void SplitSDMeshPartitioner::
1761 info()<<
" ----------------";
1762 info()<<
" --- Maillage ---";
1763 info()<<
" ----------------";
1764 if (Maillage==NULL){
1765 info()<<
" structure Maillage vide !";
1768 info()<<
" NbElements (total) = "<<Maillage->
NbElements;
1769 info()<<
" Poids (total) = "<<Maillage->
Poids;
1775 info()<<
" Maillage.ListeDomaines == NULL";
1785void SplitSDMeshPartitioner::
1788 info()<<
" ListeDomaines :";
1789 for (
int i=0; i<NbDomaines; i++) {
1790 info()<<
" ("<<i<<
") NbElements = "<<ListeDomaines[i].
NbElements<<
"; Poids = "<<ListeDomaines[i].
Poids;
1791 info()<<
" ("<<i<<
") NbVoisins = "<<ListeDomaines[i].
NbVoisins<<
"; ListeVoisins :";
1792 for (
int j=0; j<ListeDomaines[i].
NbVoisins; j++) {
1801void SplitSDMeshPartitioner::
1804 info()<<
" AfficheEquilMaillage(...)";
1806 double poidsMin = 0.0;
1807 double poidsMax = 0.0;
1816 if (poidsDom > poidsMax)
1817 poidsMax = poidsDom;
1818 if (poidsDom < poidsMin)
1819 poidsMin = poidsDom;
1822 info()<<
" INFO equilibrage / noeuds : max : "<<poidsMax<<
", min : "<<poidsMin
1826 info()<<
"AfficheEquilMaillage : Maillage->ListeDomaines == NULL";
1852void* SplitSDMeshPartitioner::RecoitMessage (
StrucInfoProc* InfoProc,
int FromProc,
int Tag,
int *pTailleTMP)
1859 if (*pTailleTMP <= 0)
1863 ierror = MPI_Probe (FromProc,
1868 if (ierror != MPI_SUCCESS)
1870 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication en provenance de "
1871 <<FromProc<<
", lors de MPI_Probe";
1875 ierror = MPI_Get_count (&status,
1879 if (ierror != MPI_SUCCESS) {
1880 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication en provenance de "
1881 <<FromProc<<
", lors de MPI_Get_count";
1886 if (*pTailleTMP > 0)
1888 TabTMP = malloc ((
size_t) *pTailleTMP);
1889 CHECK_IF_NOT_NULL(TabTMP);
1895 ierror = MPI_Recv (TabTMP,
1903 if (ierror != MPI_SUCCESS) {
1904 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication en provenance de "
1905 <<FromProc<<
", lors de MPI_Recv";
1929void SplitSDMeshPartitioner::EnvoieMessage(
StrucInfoProc* InfoProc,
int ToProc,
int Tag,
void* TabTMP,
int TailleTMP)
1933 ierror = MPI_Send ((
void *) TabTMP,
1940 if (ierror != MPI_SUCCESS) {
1941 InfoProc->
m_service->
pfatal()<<
"Problème sur "<<InfoProc->
me<<
" de communication vers "
1942 <<ToProc<<
", lors de MPI_Send";
2009void* SplitSDMeshPartitioner::DiffuseMessage(
StrucInfoProc* InfoProc,
int FromProc,
void* TabTMP,
int TailleTMP)
2014 InfoProc->
m_service->
pfatal()<<
"DiffuseMessage depuis "<<InfoProc->
me<<
", il est nécessaire que la taille du tableau soit connue !!!\n";
2018 if (InfoProc->
me != FromProc)
2022 TabTMP = malloc ((
size_t) TailleTMP);
2023 CHECK_IF_NOT_NULL(TabTMP);
2029 ierror = MPI_Bcast (TabTMP,
2035 if (ierror != MPI_SUCCESS) {
2037 <<FromProc<<
", lors de MPI_Bcast";
2055Integer SplitSDMeshPartitioner::
2058 size_t s = (2+2*Domaine->
NbIntf)*
sizeof(
int)+
sizeof(double);
2076void SplitSDMeshPartitioner::
2078 int TailleTMP, MPI_Comm comm)
2083 ier = MPI_Pack(&Domaine->
NbElements, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2084 CHECK_MPI_PACK_ERR(ier);
2086 ier = MPI_Pack(&Domaine->
PoidsDom, 1, MPI_DOUBLE, TabTMP, TailleTMP, &position, comm);
2087 CHECK_MPI_PACK_ERR(ier);
2089 ier = MPI_Pack(&Domaine->
NbIntf, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2090 CHECK_MPI_PACK_ERR(ier);
2092 for (
int i=0; i<Domaine->
NbIntf; i++){
2093 ier = MPI_Pack(&Domaine->
Intf[i].
NoDomVois, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2094 CHECK_MPI_PACK_ERR(ier);
2097 ier = MPI_Pack(&NbNoeuds, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2098 CHECK_MPI_PACK_ERR(ier);
2115void SplitSDMeshPartitioner::UnpackDom(
void* TabTMP,
int TailleTMP, MPI_Comm comm,
StrucListeDomMail* DomMail)
2119 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
NbElements, 1, MPI_INT, comm);
2120 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
Poids, 1, MPI_DOUBLE, comm);
2121 MPI_Unpack(TabTMP, TailleTMP, &position, &DomMail->
NbVoisins, 1, MPI_INT, comm);
2125 for (
int i=0; i<DomMail->
NbVoisins; i++){
2138int SplitSDMeshPartitioner::TailleEquil()
2140 return 2*
sizeof(int) +
sizeof(
double);
2147void SplitSDMeshPartitioner::PackEquil(
StrucInfoProc* InfoProc,
int indDomCharge,
int indDomVois,
double Delta,
void* TabTMP,
int TailleTMP, MPI_Comm comm)
2151 ier = MPI_Pack(&indDomCharge, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2152 CHECK_MPI_PACK_ERR(ier);
2154 ier = MPI_Pack(&indDomVois, 1, MPI_INT, TabTMP, TailleTMP, &position, comm);
2155 CHECK_MPI_PACK_ERR(ier);
2157 ier = MPI_Pack(&Delta, 1, MPI_DOUBLE, TabTMP, TailleTMP, &position, comm);
2158 CHECK_MPI_PACK_ERR(ier);
2165void SplitSDMeshPartitioner::UnpackEquil(
void* TabTMP,
int TailleTMP, MPI_Comm comm,
int* indDomCharge,
int* indDomVois,
double* Delta)
2168 MPI_Unpack(TabTMP, TailleTMP, &position, indDomCharge, 1, MPI_INT, comm);
2169 MPI_Unpack(TabTMP, TailleTMP, &position, indDomVois, 1, MPI_INT, comm);
2170 MPI_Unpack(TabTMP, TailleTMP, &position, Delta, 1, MPI_DOUBLE, comm);
2177 ServiceProperty(
"SplitSD",ST_SubDomain),
2181ARCANE_REGISTER_SERVICE_SPLITSDMESHPARTITIONER(SplitSD,SplitSDMeshPartitioner);
#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 groupe.
Integer size() const
Nombre d'éléments du vecteur.
Classe de base des vecteurs 1D de données.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
void clear()
Supprime les éléments du tableau.
Vecteur 1D de données avec sémantique par référence.
TraceMessage pfatal() const
Flot pour un message d'erreur fatale en parallèle.
Vecteur 1D de données avec sémantique par valeur (style STL).
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....
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
Int32 Integer
Type représentant un entier.
Arcane::AbstractService * m_service
Pour la gestion des traces (messages, erreurs, fatal ...)
StrucListeVoisMail * ListeVoisins
StrucListeDomMail * ListeDomaines
StructureInterface * Intf
Arcane::UniqueArray< Arcane::Node > ListeNoeuds