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