Ignore:
Timestamp:
01/25/17 16:25:17 (7 years ago)
Author:
yushan
Message:

initialize the branch

Location:
XIOS/dev/branch_yushan/src/node
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/branch_yushan/src/node/axis.cpp

    r995 r1037  
    264264      isDistributed_ = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 
    265265                       (!this->n.isEmpty() && (this->n != this->n_glo)); 
    266  
    267       // A same stupid condition to make sure that if there is only one client, axis 
    268       // should be considered to be distributed. This should be a temporary solution      
    269       isDistributed_ |= (1 == CContext::getCurrent()->client->clientSize); 
    270266   } 
    271267 
  • XIOS/dev/branch_yushan/src/node/context.cpp

    r1033 r1037  
    339339   } 
    340340 
     341   //! Server side: Put server into a loop in order to listen message from client 
     342   bool CContext::eventLoop(void) 
     343   { 
     344     return server->eventLoop(); 
     345   } 
     346 
    341347   //! Try to send the buffers and receive possible answers 
    342348   bool CContext::checkBuffersAndListen(void) 
    343349   { 
    344350     client->checkBuffers(); 
    345  
    346      bool hasTmpBufferedEvent = client->hasTemporarilyBufferedEvent(); 
    347      if (hasTmpBufferedEvent) 
    348        hasTmpBufferedEvent = !client->sendTemporarilyBufferedEvent(); 
    349  
    350      // Don't process events if there is a temporarily buffered event 
    351      return server->eventLoop(!hasTmpBufferedEvent); 
     351     return server->eventLoop(); 
    352352   } 
    353353 
     
    389389   void CContext::closeDefinition(void) 
    390390   { 
     391     int myRank; 
     392     MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 
     393 
     394     //printf("myRank = %d, hasClient = %d, hasServer = %d\n", myRank, hasClient, hasServer); 
     395 
    391396     // There is nothing client need to send to server 
    392397     if (hasClient) 
    393398     { 
    394399       // After xml is parsed, there are some more works with post processing 
    395        postProcessing(); 
    396      } 
    397      setClientServerBuffer(); 
     400       postProcessing();  
     401       //printf("myRank = %d,                postProcessing OK\n", myRank); 
     402     } 
     403     setClientServerBuffer(); //printf("myRank = %d, setClientServerBuffer OK\n", myRank); 
    398404 
    399405     if (hasClient && !hasServer) 
    400406     { 
    401407      // Send all attributes of current context to server 
    402       this->sendAllAttributesToServer(); 
     408      this->sendAllAttributesToServer(); //printf("myRank = %d, this->sendAllAttributesToServer OK\n", myRank); 
    403409 
    404410      // Send all attributes of current calendar 
    405411      CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(); 
     412      //printf("myRank = %d, CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer OK\n", myRank); 
    406413 
    407414      // We have enough information to send to server 
    408415      // First of all, send all enabled files 
    409        sendEnabledFiles(); 
     416       sendEnabledFiles();  //printf("myRank = %d, sendEnabledFiles OK\n", myRank); 
    410417 
    411418      // Then, send all enabled fields 
    412        sendEnabledFields(); 
     419       sendEnabledFields();  //printf("myRank = %d, sendEnabledFields OK\n", myRank); 
    413420 
    414421      // At last, we have all info of domain and axis, then send them 
    415        sendRefDomainsAxis(); 
     422       sendRefDomainsAxis();  //printf("myRank = %d, sendRefDomainsAxis OK\n", myRank); 
    416423 
    417424      // After that, send all grid (if any) 
    418        sendRefGrid(); 
     425       sendRefGrid(); //printf("myRank = %d, sendRefGrid OK\n", myRank); 
    419426    } 
    420427 
    421428    // We have a xml tree on the server side and now, it should be also processed 
    422     if (hasClient && !hasServer) sendPostProcessing(); 
     429    if (hasClient && !hasServer) sendPostProcessing();   
    423430 
    424431    // There are some processings that should be done after all of above. For example: check mask or index 
    425432    if (hasClient) 
    426433    { 
    427       this->buildFilterGraphOfEnabledFields(); 
    428       buildFilterGraphOfFieldsWithReadAccess(); 
    429       this->solveAllRefOfEnabledFields(true); 
     434      this->buildFilterGraphOfEnabledFields();  //printf("myRank = %d, buildFilterGraphOfEnabledFields OK\n", myRank); 
     435      buildFilterGraphOfFieldsWithReadAccess();  //printf("myRank = %d, buildFilterGraphOfFieldsWithReadAccess OK\n", myRank); 
     436      this->solveAllRefOfEnabledFields(true);  //printf("myRank = %d, solveAllRefOfEnabledFields OK\n", myRank); 
    430437    } 
    431438 
     
    434441 
    435442    // Nettoyage de l'arborescence 
    436     if (hasClient && !hasServer) CleanTree(); // Only on client side?? 
     443    if (hasClient && !hasServer) CleanTree(); 
    437444 
    438445    if (hasClient) 
    439446    { 
    440       sendCreateFileHeader(); 
    441  
    442       startPrefetchingOfEnabledReadModeFiles(); 
     447      sendCreateFileHeader();  //printf("myRank = %d, sendCreateFileHeader OK\n", myRank); 
     448 
     449      startPrefetchingOfEnabledReadModeFiles();  //printf("myRank = %d, startPrefetchingOfEnabledReadModeFiles OK\n", myRank); 
    443450    } 
    444451   } 
     
    479486   { 
    480487     int size = this->enabledFiles.size(); 
     488      
    481489     for (int i = 0; i < size; ++i) 
    482490     { 
     
    566574   { 
    567575      const std::vector<CFile*> allFiles = CFile::getAll(); 
    568       const CDate& initDate = calendar->getInitDate(); 
    569576 
    570577      for (unsigned int i = 0; i < allFiles.size(); i++) 
     
    572579         { 
    573580            if (allFiles[i]->enabled.getValue()) // Si l'attribut 'enabled' est fixé à vrai. 
    574             { 
    575               if ((initDate + allFiles[i]->output_freq.getValue()) < (initDate + this->getCalendar()->getTimeStep())) 
    576               { 
    577                 error(0)<<"WARNING: void CContext::findEnabledFiles()"<<endl 
    578                     << "Output frequency in file \""<<allFiles[i]->getFileOutputName() 
    579                     <<"\" is less than the time step. File will not be written."<<endl; 
    580               } 
    581               else 
    582581               enabledFiles.push_back(allFiles[i]); 
    583             } 
    584582         } 
    585          else 
    586          { 
    587            if ( (initDate + allFiles[i]->output_freq.getValue()) < (initDate + this->getCalendar()->getTimeStep())) 
    588            { 
    589              error(0)<<"WARNING: void CContext::findEnabledFiles()"<<endl 
    590                  << "Output frequency in file \""<<allFiles[i]->getFileOutputName() 
    591                  <<"\" is less than the time step. File will not be written."<<endl; 
    592            } 
    593            else 
    594              enabledFiles.push_back(allFiles[i]); // otherwise true by default 
    595          } 
     583         else enabledFiles.push_back(allFiles[i]); // otherwise true by default 
     584 
    596585 
    597586      if (enabledFiles.size() == 0) 
     
    812801   void CContext::postProcessing() 
    813802   { 
     803     int myRank; 
     804     MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 
     805 
     806     //printf("myRank = %d, in postProcessing, isPostProcessed = %d\n", myRank, isPostProcessed); 
    814807     if (isPostProcessed) return; 
    815808 
     
    820813        ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"") 
    821814      // Calendar first update to set the current date equals to the start date 
    822       calendar->update(0); 
     815      calendar->update(0);  //printf("myRank = %d, calendar->update(0) OK\n", myRank); 
    823816 
    824817      // Find all inheritance in xml structure 
    825       this->solveAllInheritance(); 
     818      this->solveAllInheritance();  //printf("myRank = %d, this->solveAllInheritance OK\n", myRank); 
    826819 
    827820      // Check if some axis, domains or grids are eligible to for compressed indexed output. 
    828821      // Warning: This must be done after solving the inheritance and before the rest of post-processing 
    829       checkAxisDomainsGridsEligibilityForCompressedOutput(); 
     822      checkAxisDomainsGridsEligibilityForCompressedOutput();  //printf("myRank = %d, checkAxisDomainsGridsEligibilityForCompressedOutput OK\n", myRank); 
    830823 
    831824      // Check if some automatic time series should be generated 
    832825      // Warning: This must be done after solving the inheritance and before the rest of post-processing 
    833       prepareTimeseries(); 
     826      prepareTimeseries();  //printf("myRank = %d, prepareTimeseries OK\n", myRank); 
    834827 
    835828      //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir. 
    836       this->findEnabledFiles(); 
    837       this->findEnabledReadModeFiles(); 
     829      this->findEnabledFiles();  //printf("myRank = %d, this->findEnabledFiles OK\n", myRank); 
     830      this->findEnabledReadModeFiles();  //printf("myRank = %d, this->findEnabledReadModeFiles OK\n", myRank); 
    838831 
    839832      // Find all enabled fields of each file 
    840       this->findAllEnabledFields(); 
    841       this->findAllEnabledFieldsInReadModeFiles(); 
     833      this->findAllEnabledFields();  //printf("myRank = %d, this->findAllEnabledFields OK\n", myRank); 
     834      this->findAllEnabledFieldsInReadModeFiles();  //printf("myRank = %d, this->findAllEnabledFieldsInReadModeFiles OK\n", myRank); 
    842835 
    843836     if (hasClient && !hasServer) 
    844837     { 
    845838      // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 
    846       this->readAttributesOfEnabledFieldsInReadModeFiles(); 
     839      this->readAttributesOfEnabledFieldsInReadModeFiles();  //printf("myRank = %d, this->readAttributesOfEnabledFieldsInReadModeFiles OK\n", myRank); 
    847840     } 
    848841 
    849842      // Only search and rebuild all reference objects of enable fields, don't transform 
    850       this->solveOnlyRefOfEnabledFields(false); 
     843      this->solveOnlyRefOfEnabledFields(false);  //printf("myRank = %d, this->solveOnlyRefOfEnabledFields(false) OK\n", myRank); 
    851844 
    852845      // Search and rebuild all reference object of enabled fields 
    853       this->solveAllRefOfEnabledFields(false); 
     846      this->solveAllRefOfEnabledFields(false);  //printf("myRank = %d, this->solveAllRefOfEnabledFields(false) OK\n", myRank); 
    854847 
    855848      // Find all fields with read access from the public API 
    856       findFieldsWithReadAccess(); 
     849      findFieldsWithReadAccess();  //printf("myRank = %d, findFieldsWithReadAccess OK\n", myRank); 
    857850      // and solve the all reference for them 
    858       solveAllRefOfFieldsWithReadAccess(); 
     851      solveAllRefOfFieldsWithReadAccess();  //printf("myRank = %d, solveAllRefOfFieldsWithReadAccess OK\n", myRank); 
    859852 
    860853      isPostProcessed = true; 
     
    12401233         event.push(*itRank,1,msg); 
    12411234       client->sendEvent(event); 
    1242      } 
    1243      else client->sendEvent(event); 
     1235    } 
     1236    else client->sendEvent(event); 
    12441237  } 
    12451238 
  • XIOS/dev/branch_yushan/src/node/context.hpp

    r1033 r1037  
    9393 
    9494         // Put sever or client into loop state 
     95         bool eventLoop(void); 
     96 
    9597         bool checkBuffersAndListen(void); 
    9698 
  • XIOS/dev/branch_yushan/src/node/domain.cpp

    r995 r1037  
    698698     computeNGlobDomain(); 
    699699     checkZoom(); 
    700       
     700 
    701701     isDistributed_ = !((!ni.isEmpty() && (ni == ni_glo) && !nj.isEmpty() && (nj == nj_glo)) || 
    702702                        (!i_index.isEmpty() && i_index.numElements() == ni_glo*nj_glo)); 
    703  
    704      // A stupid condition to make sure that if there is only one client, domain 
    705      // should be considered to be distributed. This should be a temporary solution      
    706      isDistributed_ |= (1 == CContext::getCurrent()->client->clientSize); 
    707703   } 
    708704 
     
    13071303   void CDomain::checkAttributesOnClientAfterTransformation() 
    13081304   { 
    1309      CContext* context=CContext::getCurrent() ; 
    1310  
     1305     int myRank; 
     1306     MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 
     1307 
     1308     CContext* context=CContext::getCurrent() ;  //printf("myRank = %d, CContext::getCurrent OK\n", myRank); 
     1309 
     1310     //printf("myRank = %d, this->isClientAfterTransformationChecked = %d\n", myRank, this->isClientAfterTransformationChecked); 
    13111311     if (this->isClientAfterTransformationChecked) return; 
     1312     //printf("myRank = %d, context->hasClient = %d\n", myRank, context->hasClient); 
    13121313     if (context->hasClient) 
    13131314     { 
    1314        this->checkMask(); 
    1315        if (hasLonLat || hasArea || isCompressible_) this->computeConnectedServer(); 
    1316        if (hasLonLat) this->completeLonLatClient(); 
     1315       this->checkMask();  //printf("myRank = %d, this->checkMask OK\n", myRank); 
     1316       //printf("myRank = %d, hasLonLat = %d, hasArea = %d, isCompressible_ = %d\n", myRank, hasLonLat, hasArea, isCompressible_); 
     1317       if (hasLonLat || hasArea || isCompressible_)  
     1318        { 
     1319          //printf("myRank = %d, start this->computeConnectedServer\n", myRank); 
     1320          this->computeConnectedServer(); 
     1321          //printf("myRank = %d, this->computeConnectedServer OK\n", myRank); 
     1322        } 
     1323       //printf("myRank = %d, hasLonLat = %d\n", myRank, hasLonLat); 
     1324       if (hasLonLat)  
     1325        { 
     1326          this->completeLonLatClient(); 
     1327          //printf("myRank = %d, this->completeLonLatClient OK\n", myRank); 
     1328        } 
    13171329     } 
    13181330 
     
    14481460  void CDomain::computeConnectedServer(void) 
    14491461  { 
     1462    int myRank; 
     1463    MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 
     1464 
    14501465    CContext* context=CContext::getCurrent() ; 
    14511466    CContextClient* client=context->client ; 
     
    15341549      } 
    15351550    } 
     1551     
    15361552 
    15371553    size_t globalSizeIndex = 1, indexBegin, indexEnd; 
     
    15551571      indexEnd = indexBegin + range - 1; 
    15561572    } 
    1557  
     1573     
    15581574    CServerDistributionDescription serverDescription(nGlobDomain_, nbServer); 
    15591575    if (isUnstructed_) serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0); 
    15601576    else serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 1); 
    15611577 
     1578    //printf("myRank = %d, check 7 OK\n", myRank); 
     1579 
    15621580    CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), 
    15631581                                                                                client->intraComm); 
    1564     clientServerMap->computeServerIndexMapping(globalIndexDomain); 
     1582    //printf("myRank = %d new OK\n", myRank); 
     1583 
     1584    clientServerMap->computeServerIndexMapping(globalIndexDomain);   
     1585    //printf("myRank = %d, clientServerMap->computeServerIndexMapping(globalIndexDomain) OK\n", myRank); 
     1586     
    15651587    const CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer(); 
     1588    //printf("myRank = %d, clientServerMap->getGlobalIndexOnServer OK\n", myRank); 
     1589     
     1590    //printf("myRank = %d, check 8 OK\n", myRank); 
    15661591 
    15671592    CClientServerMapping::GlobalIndexMap::const_iterator it  = globalIndexDomainOnServer.begin(), 
     
    15971622    } 
    15981623 
     1624    //printf("myRank = %d, check 9 OK\n", myRank); 
     1625 
    15991626    connectedServerRank_.clear(); 
    16001627    for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) { 
     
    16051632 
    16061633    delete clientServerMap; 
     1634    //printf("myRank = %d, check 10 OK\n", myRank); 
    16071635  } 
    16081636 
  • XIOS/dev/branch_yushan/src/node/field.cpp

    r1018 r1037  
    3636      , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false) 
    3737      , useCompressedOutput(false) 
    38       , hasTimeInstant(false) 
    39       , hasTimeCentered(false) 
    40       , wasDataAlreadyReceivedFromServer(false) 
    41       , isEOF(false) 
     38      , isReadDataRequestPending(false) 
    4239   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
    4340 
     
    5047      , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false) 
    5148      , useCompressedOutput(false) 
    52       , hasTimeInstant(false) 
    53       , hasTimeCentered(false) 
    54       , wasDataAlreadyReceivedFromServer(false) 
    55       , isEOF(false) 
     49      , isReadDataRequestPending(false) 
    5650   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
    5751 
     
    253247  } 
    254248 
    255   bool CField::sendReadDataRequest(const CDate& tsDataRequested) 
     249  void CField::sendReadDataRequest(void) 
    256250  { 
    257251    CContext* context = CContext::getCurrent(); 
    258252    CContextClient* client = context->client; 
    259253 
    260     lastDataRequestedFromServer = tsDataRequested; 
    261  
    262     if (!isEOF) // No need to send the request if we already know we are at EOF 
    263     { 
    264       CEventClient event(getType(), EVENT_ID_READ_DATA); 
    265       if (client->isServerLeader()) 
    266       { 
    267         CMessage msg; 
    268         msg << getId(); 
    269         const std::list<int>& ranks = client->getRanksServerLeader(); 
    270         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    271           event.push(*itRank, 1, msg); 
    272         client->sendEvent(event); 
    273       } 
    274       else client->sendEvent(event); 
    275     } 
    276     else 
    277       serverSourceFilter->signalEndOfStream(tsDataRequested); 
    278  
    279     return !isEOF; 
     254    lastDataRequestedFromServer = context->getCalendar()->getCurrentDate(); 
     255    isReadDataRequestPending = true; 
     256 
     257    CEventClient event(getType(), EVENT_ID_READ_DATA); 
     258    if (client->isServerLeader()) 
     259    { 
     260      CMessage msg; 
     261      msg << getId(); 
     262      const std::list<int>& ranks = client->getRanksServerLeader(); 
     263      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     264        event.push(*itRank, 1, msg); 
     265      client->sendEvent(event); 
     266    } 
     267    else client->sendEvent(event); 
    280268  } 
    281269 
     
    288276    const CDate& currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate(); 
    289277 
    290     bool dataRequested = false; 
    291  
    292     while (currentDate >= lastDataRequestedFromServer) 
    293     { 
    294       info(20) << "currentDate : " << currentDate << endl ; 
    295       info(20) << "lastDataRequestedFromServer : " << lastDataRequestedFromServer << endl ; 
    296       info(20) << "file->output_freq.getValue() : " << file->output_freq.getValue() << endl ; 
    297       info(20) << "lastDataRequestedFromServer + file->output_freq.getValue() : " << lastDataRequestedFromServer + file->output_freq << endl ; 
    298  
    299       dataRequested |= sendReadDataRequest(lastDataRequestedFromServer + file->output_freq); 
    300     } 
    301  
    302     return dataRequested; 
     278    bool requestData = (currentDate >= lastDataRequestedFromServer + file->output_freq.getValue()); 
     279 
     280    if (requestData) 
     281    { 
     282      cout<<"currentDate : "<<currentDate<<endl ; 
     283      cout<<"lastDataRequestedFromServer : "<<lastDataRequestedFromServer<<endl ; 
     284      cout<<"file->output_freq.getValue() : "<<file->output_freq.getValue()<<endl ; 
     285      cout<<"lastDataRequestedFromServer + file->output_freq.getValue() : "<<lastDataRequestedFromServer + file->output_freq.getValue()<<endl ; 
     286 
     287      sendReadDataRequest(); 
     288    } 
     289 
     290    return requestData; 
    303291  } 
    304292 
     
    322310 
    323311    map<int, CArray<double,1> >::iterator it; 
    324     if (!grid->doGridHaveDataDistributed()) 
    325     { 
    326        if (client->isServerLeader()) 
    327        { 
    328           if (!data_srv.empty()) 
    329           { 
    330             it = data_srv.begin(); 
    331             const std::list<int>& ranks = client->getRanksServerLeader(); 
    332             for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    333             { 
    334               msgs.push_back(CMessage()); 
    335               CMessage& msg = msgs.back(); 
    336               msg << getId(); 
    337               if (hasData) 
    338                 msg << getNStep() - 1 << it->second; 
    339               else 
    340                 msg << int(-1); 
    341               event.push(*itRank, 1, msg); 
    342             } 
    343           } 
    344           client->sendEvent(event); 
    345        }  
    346        else  
    347        { 
    348           // if (!data_srv.empty()) 
    349           // { 
    350           //   it = data_srv.begin(); 
    351           //   const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    352           //   for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    353           //   { 
    354           //     msgs.push_back(CMessage()); 
    355           //     CMessage& msg = msgs.back(); 
    356           //     msg << getId(); 
    357           //     if (hasData) 
    358           //       msg << getNStep() - 1 << it->second; 
    359           //     else 
    360           //       msg << int(-1); 
    361           //     event.push(*itRank, 1, msg); 
    362           //   } 
    363           // } 
    364           client->sendEvent(event); 
    365        } 
    366     } 
    367     else 
    368     { 
    369       for (it = data_srv.begin(); it != data_srv.end(); it++) 
    370       { 
    371         msgs.push_back(CMessage()); 
    372         CMessage& msg = msgs.back(); 
    373         msg << getId(); 
    374         if (hasData) 
    375           msg << getNStep() - 1 << it->second; 
    376         else 
    377           msg << int(-1); 
    378         event.push(it->first, grid->nbSenders[it->first], msg); 
    379       } 
    380       client->sendEvent(event); 
    381     } 
     312    for (it = data_srv.begin(); it != data_srv.end(); it++) 
     313    { 
     314      msgs.push_back(CMessage()); 
     315      CMessage& msg = msgs.back(); 
     316      msg << getId(); 
     317      if (hasData) 
     318        msg << getNStep() - 1 << it->second; 
     319      else 
     320        msg << int(-1); 
     321      event.push(it->first, grid->nbSenders[it->first], msg); 
     322    } 
     323    client->sendEvent(event); 
    382324  } 
    383325 
     
    402344        this->incrementNStep(); 
    403345 
     346 
     347 
    404348        if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) ) 
    405349          return false; 
     
    435379    std::map<int, CArray<double,1> > data; 
    436380 
     381    bool isEOF = false; 
     382 
    437383    for (int i = 0; i < ranks.size(); i++) 
    438384    { 
     
    447393    } 
    448394 
    449     if (wasDataAlreadyReceivedFromServer) 
    450       lastDataReceivedFromServer = lastDataReceivedFromServer + file->output_freq; 
     395    if (isEOF) 
     396      serverSourceFilter->signalEndOfStream(lastDataRequestedFromServer); 
    451397    else 
    452     { 
    453       lastDataReceivedFromServer = context->getCalendar()->getInitDate(); 
    454       wasDataAlreadyReceivedFromServer = true; 
    455     } 
    456  
    457     if (isEOF) 
    458       serverSourceFilter->signalEndOfStream(lastDataReceivedFromServer); 
    459     else 
    460       serverSourceFilter->streamDataFromServer(lastDataReceivedFromServer, data); 
     398      serverSourceFilter->streamDataFromServer(lastDataRequestedFromServer, data); 
     399 
     400    isReadDataRequestPending = false; 
    461401  } 
    462402 
     
    681621   void CField::solveAllReferenceEnabledField(bool doSending2Server) 
    682622   { 
    683      CContext* context = CContext::getCurrent(); 
    684      solveOnlyReferenceEnabledField(doSending2Server); 
     623     int myRank; 
     624     MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 
     625 
     626     CContext* context = CContext::getCurrent();  //printf("my_Rank = %d, CContext* context = CContext::getCurrent OK\n", myRank); 
     627     solveOnlyReferenceEnabledField(doSending2Server);  //printf("my_Rank = %d, solveOnlyReferenceEnabledField(doSending2Server) OK\n", myRank); 
    685628 
    686629     if (!areAllReferenceSolved) 
     
    690633        if (context->hasClient) 
    691634        { 
    692           solveRefInheritance(true); 
    693           if (hasDirectFieldReference()) getDirectFieldReference()->solveAllReferenceEnabledField(false); 
     635          solveRefInheritance(true);  //printf("my_Rank = %d, solveRefInheritance(true) OK\n", myRank); 
     636          if (hasDirectFieldReference())  
     637          { 
     638            getDirectFieldReference()->solveAllReferenceEnabledField(false);  
     639            //printf("my_Rank = %d, getDirectFieldReference()->solveAllReferenceEnabledField(false) OK\n", myRank); 
     640          } 
    694641        } 
    695642        else if (context->hasServer) 
     643        { 
    696644          solveServerOperation(); 
    697  
    698         solveGridReference(); 
    699      } 
    700  
    701      solveGridDomainAxisRef(doSending2Server); 
     645          //printf("my_Rank = %d, solveServerOperation OK\n", myRank); 
     646        } 
     647 
     648        solveGridReference();  //printf("my_Rank = %d, solveGridReference OK\n", myRank); 
     649     } 
     650 
     651     solveGridDomainAxisRef(doSending2Server);  //printf("my_Rank = %d, solveGridDomainAxisRef(doSending2Server) OK\n", myRank); 
    702652 
    703653     if (context->hasClient) 
    704654     { 
    705        solveTransformedGrid(); 
    706      } 
    707  
    708      solveCheckMaskIndex(doSending2Server); 
     655       solveTransformedGrid();  //printf("my_Rank = %d, solveTransformedGrid OK\n", myRank); 
     656     } 
     657 
     658     solveCheckMaskIndex(doSending2Server);  //printf("FIELD.CPP: my_Rank = %d, solveCheckMaskIndex(doSending2Server) OK\n", myRank); 
    709659   } 
    710660 
     
    783733     { 
    784734       // Check if we have an expression to parse 
    785        if (hasExpression()) 
    786        { 
    787          boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0')); 
    788          boost::shared_ptr<COutputPin> filter = expr->reduce(gc, *this); 
    789  
    790          // Check if a spatial transformation is needed 
    791          if (!field_ref.isEmpty()) 
    792          { 
    793            CGrid* gridRef = CField::get(field_ref)->grid; 
    794  
    795            if (grid && grid != gridRef && grid->hasTransform()) 
    796            { 
    797              bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    798              double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
    799              std::pair<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, hasMissingValue, defaultValue); 
    800  
    801              filter->connectOutput(filters.first, 0); 
    802              filter = filters.second; 
    803            } 
    804          } 
    805  
    806          instantDataFilter = filter; 
     735       if (!content.empty()) 
     736       { 
     737         boost::scoped_ptr<IFilterExprNode> expr(parseExpr(content + '\0')); 
     738         instantDataFilter = expr->reduce(gc, *this); 
    807739       } 
    808740       // Check if we have a reference on another field 
     
    811743       // Check if the data is to be read from a file 
    812744       else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read) 
    813          instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, 
    814                                                                                                      freq_offset.isEmpty() ? NoneDu : freq_offset, 
    815                                                                                                      true)); 
     745         instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid, 
     746                                                                                                     freq_offset.isEmpty() ? NoneDu : freq_offset)); 
    816747       else // The data might be passed from the model 
    817        { 
    818           bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    819           double defaultValue  = ignoreMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
    820           instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, NoneDu, false, 
    821                                                                                                       ignoreMissingValue, defaultValue));       } 
     748         instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid)); 
    822749     } 
    823750 
     
    858785     // Check if a spatial transformation is needed 
    859786     if (grid && grid != fieldRef->grid && grid->hasTransform()) 
    860      {        
    861        bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    862        double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);                                 
    863        filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue); 
    864      } 
     787     { 
     788       double defaultValue = 0.0; 
     789       if (!default_value.isEmpty()) defaultValue = this->default_value; 
     790       filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, defaultValue); 
     791     } 
     792 
    865793     else 
    866794       filters.first = filters.second = boost::shared_ptr<CFilter>(new CPassThroughFilter(gc)); 
     
    882810   boost::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc) 
    883811   { 
    884      if (instantDataFilter || !hasExpression()) 
     812     if (instantDataFilter || content.empty()) 
    885813       ERROR("COutputPin* CField::getSelfReference(CGarbageCollector& gc)", 
    886814             "Impossible to add a self reference to a field which has already been parsed or which does not have an expression."); 
     
    891819       { 
    892820         if (!serverSourceFilter) 
    893            serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, 
    894                                                                                    freq_offset.isEmpty() ? NoneDu : freq_offset, 
    895                                                                                    true)); 
     821           serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid, 
     822                                                                                   freq_offset.isEmpty() ? NoneDu : freq_offset)); 
    896823 
    897824         selfReferenceFilter = serverSourceFilter; 
    898825       } 
    899826       else if (!field_ref.isEmpty()) 
    900        { 
    901          CField* fieldRef = CField::get(field_ref); 
    902          fieldRef->buildFilterGraph(gc, false);  
    903          selfReferenceFilter = fieldRef->getInstantDataFilter(); 
    904        } 
     827         selfReferenceFilter = getFieldReference(gc); 
    905828       else 
    906829       { 
    907830         if (!clientSourceFilter) 
    908          { 
    909            bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    910            double defaultValue  = ignoreMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);  
    911            clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, NoneDu, false, 
    912                                                                                    ignoreMissingValue, defaultValue)); 
    913          } 
     831           clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid)); 
    914832 
    915833         selfReferenceFilter = clientSourceFilter; 
     
    945863 
    946864       const bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    947         
     865 
    948866       boost::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 
    949867                                                                             CContext::getCurrent()->getCalendar()->getInitDate(), 
     
    957875     return it->second; 
    958876   } 
    959  
    960   /*! 
    961     * Returns the temporal filter corresponding to the field's temporal operation 
    962     * for the specified operation frequency. 
    963     * 
    964     * \param gc the garbage collector to use 
    965     * \param outFreq the operation frequency, i.e. the frequency at which the output data will be computed 
    966     * \return the output pin corresponding to the requested temporal filter 
    967     */ 
    968     
    969    boost::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq) 
    970    { 
    971      if (instantDataFilter || !hasExpression()) 
    972        ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)", 
    973              "Impossible to add a self reference to a field which has already been parsed or which does not have an expression."); 
    974  
    975      if (!selfReferenceFilter) getSelfReference(gc) ; 
    976  
    977      if (serverSourceFilter || clientSourceFilter) 
    978      { 
    979        if (operation.isEmpty()) 
    980          ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)", 
    981                << "An operation must be defined for field \"" << getId() << "\"."); 
    982  
    983        if (freq_op.isEmpty()) freq_op.setValue(TimeStep); 
    984        if (freq_offset.isEmpty()) freq_offset.setValue(NoneDu); 
    985  
    986        const bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    987  
    988        boost::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 
    989                                                                              CContext::getCurrent()->getCalendar()->getInitDate(), 
    990                                                                              freq_op, freq_offset, outFreq, 
    991                                                                              ignoreMissingValue, ignoreMissingValue ? default_value : 0.0)); 
    992        selfReferenceFilter->connectOutput(temporalFilter, 0); 
    993        return temporalFilter ; 
    994      } 
    995      else if (!field_ref.isEmpty()) 
    996      { 
    997        CField* fieldRef = CField::get(field_ref); 
    998        fieldRef->buildFilterGraph(gc, false);  
    999        return fieldRef->getTemporalDataFilter(gc, outFreq) ; 
    1000      } 
    1001   } 
    1002877 
    1003878   //---------------------------------------------------------------- 
     
    11531028     else if (grid && grid->hasTransform() && !grid->isTransformed()) 
    11541029     { 
    1155        // Temporarily deactivate the self-transformation of grid 
    1156        //grid->transformGrid(grid); 
     1030       grid->transformGrid(grid); 
    11571031     } 
    11581032   } 
     
    14301304   } 
    14311305 
    1432    /*! 
    1433     * Returns string arithmetic expression associated to the field. 
    1434     * \return if content is defined return content string, otherwise, if "expr" attribute is defined, return expr string. 
    1435     */ 
    1436    const string& CField::getExpression(void) 
    1437    { 
    1438      if (!expr.isEmpty() && content.empty()) 
    1439      { 
    1440        content = expr; 
    1441        expr.reset(); 
    1442      } 
    1443  
    1444      return content; 
    1445    } 
    1446  
    1447    bool CField::hasExpression(void) const 
    1448    { 
    1449      return (!expr.isEmpty() || !content.empty()); 
    1450    } 
    1451  
    14521306   DEFINE_REF_FUNC(Field,field) 
    14531307} // namespace xios 
  • XIOS/dev/branch_yushan/src/node/field.hpp

    r1017 r1037  
    124124         boost::shared_ptr<COutputPin> getSelfReference(CGarbageCollector& gc); 
    125125         boost::shared_ptr<COutputPin> getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq); 
    126          boost::shared_ptr<COutputPin> getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq); 
    127126 
    128127//         virtual void fromBinary(StdIStream& is); 
     
    143142        void recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers); 
    144143        void writeField(void); 
    145         bool sendReadDataRequest(const CDate& tsDataRequested); 
     144        void sendReadDataRequest(void); 
    146145        bool sendReadDataRequestIfNeeded(void); 
    147146        static void recvReadDataRequest(CEventServer& event); 
     
    179178        const std::vector<StdString>& getRefDomainAxisIds(); 
    180179 
    181         const string& getExpression(void); 
    182         bool hasExpression(void) const; 
    183  
    184180      public: 
    185181         /// Propriétés privées /// 
     
    195191         bool isEOF; 
    196192         CDate lastlast_Write_srv, last_Write_srv, last_operation_srv; 
    197          CDate lastDataRequestedFromServer, lastDataReceivedFromServer; 
    198          bool wasDataAlreadyReceivedFromServer; 
     193         CDate lastDataRequestedFromServer; 
    199194 
    200195         map<int,boost::shared_ptr<func::CFunctor> > foperation_srv; 
     
    206201         bool isReferenceSolved; 
    207202         std::vector<StdString> domAxisScalarIds_; 
     203         bool isReadDataRequestPending; 
    208204         bool useCompressedOutput; 
    209  
    210          // Two variable to identify the time_counter meta data written in file, which has no time_counter 
    211          bool hasTimeInstant; 
    212          bool hasTimeCentered; 
    213205 
    214206         DECLARE_REF_FUNC(Field,field) 
  • XIOS/dev/branch_yushan/src/node/field_impl.hpp

    r1007 r1037  
    1919  { 
    2020    if (clientSourceFilter) 
     21    { 
    2122      clientSourceFilter->streamData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 
    22     else if (instantDataFilter) 
     23    } 
     24    else if (!field_ref.isEmpty() || !content.empty()) 
    2325      ERROR("void CField::setData(const CArray<double, N>& _data)", 
    2426            << "Impossible to receive data from the model for a field [ id = " << getId() << " ] with a reference or an arithmetic operation."); 
  • XIOS/dev/branch_yushan/src/node/file.cpp

    r1013 r1037  
    1717#include "mpi.hpp" 
    1818 
     19 
    1920namespace xios { 
    2021 
     
    2930     setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); 
    3031   } 
     32    
     33 
    3134 
    3235   CFile::CFile(const StdString & id) 
     
    3841      setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); 
    3942    } 
     43    
    4044 
    4145   CFile::~CFile(void) 
     
    235239      const int recordOffset = record_offset.isEmpty() ? 0 : record_offset; 
    236240 
    237       // set<CAxis*> setAxis; 
    238       // set<CDomain*> setDomains; 
    239       set<StdString> setAxis; 
    240       set<StdString> setDomains; 
    241        
     241      set<CAxis*> setAxis; 
     242      set<CDomain*> setDomains; 
     243 
    242244      std::vector<CField*>::iterator it, end = this->enabledFields.end(); 
    243245      for (it = this->enabledFields.begin(); it != end; it++) 
     
    247249         std::vector<CAxis*> vecAxis = field->grid->getAxis(); 
    248250         for (size_t i = 0; i < vecAxis.size(); ++i) 
    249             setAxis.insert(vecAxis[i]->getAxisOutputName()); 
    250             // setAxis.insert(vecAxis[i]); 
     251            setAxis.insert(vecAxis[i]); 
    251252         std::vector<CDomain*> vecDomains = field->grid->getDomains(); 
    252253         for (size_t i = 0; i < vecDomains.size(); ++i) 
    253             setDomains.insert(vecDomains[i]->getDomainOutputName()); 
    254             // setDomains.insert(vecDomains[i]); 
     254            setDomains.insert(vecDomains[i]); 
    255255 
    256256         field->resetNStep(recordOffset); 
     
    264264      if (allDomainEmpty) MPI_Comm_free(&fileComm); 
    265265 
    266       // if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); 
     266      if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); 
    267267      if (time_counter_name.isEmpty()) time_counter_name = "time_counter"; 
    268268    } 
     
    375375         if (pos2!=std::string::npos) 
    376376         { 
    377            middlePart=filename.substr(pos1,pos2-pos1) ;            
     377           middlePart=filename.substr(pos1,pos2-pos1) ; 
     378           cout<<pos2<<endl ; 
    378379           pos2+=strEndDate.size() ; 
    379380           lastPart=filename.substr(pos2,filename.size()-pos2) ; 
     
    580581          this->data_in->closeFile(); 
    581582       } 
     583 
    582584      if (fileComm != MPI_COMM_NULL) MPI_Comm_free(&fileComm); 
     585 
    583586   } 
    584587   //---------------------------------------------------------------- 
     
    715718   { 
    716719     int size = this->enabledFields.size(); 
     720      
    717721     for (int i = 0; i < size; ++i) 
    718722     { 
     
    745749     int size = this->enabledFields.size(); 
    746750     for (int i = 0; i < size; ++i) 
    747        this->enabledFields[i]->sendReadDataRequest(CContext::getCurrent()->getCalendar()->getCurrentDate()); 
     751       this->enabledFields[i]->sendReadDataRequest(); 
    748752   } 
    749753 
  • XIOS/dev/branch_yushan/src/node/file.hpp

    r957 r1037  
    1212#include "attribute_enum_impl.hpp" 
    1313#include "mpi.hpp" 
     14#ifdef _usingEP 
     15#include "ep_declaration.hpp" 
     16#endif 
    1417 
    1518namespace xios { 
  • XIOS/dev/branch_yushan/src/node/grid.cpp

    r1008 r1037  
    166166   void CGrid::checkAttributesAfterTransformation() 
    167167   { 
    168       setAxisList(); 
    169       std::vector<CAxis*> axisListP = this->getAxis(); 
     168      int myRank; 
     169      MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 
     170 
     171      setAxisList();  //printf("myRank = %d, setAxisList OK\n", myRank); 
     172      std::vector<CAxis*> axisListP = this->getAxis();  //printf("myRank = %d, this->getAxis OK\n", myRank); 
    170173      if (!axisListP.empty()) 
    171174      { 
    172175        int idx = 0; 
    173176        axisPositionInGrid_.resize(0); 
     177         
    174178        for (int i = 0; i < axis_domain_order.numElements(); ++i) 
    175179        { 
     
    179183            axisPositionInGrid_.push_back(idx); 
    180184            ++idx; 
     185            //printf("myRank = %d, axisPositionInGrid_.push_back OK\n", myRank); 
    181186          } 
    182187          else if (2 == elementDimension) idx += 2; 
     
    186191        { 
    187192          axisListP[i]->checkAttributesOnClientAfterTransformation(globalDim_,axisPositionInGrid_[i]); 
    188         } 
    189       } 
    190  
    191       setDomainList(); 
    192       std::vector<CDomain*> domListP = this->getDomains(); 
     193          //printf("myRank = %d, axisListP[%d/%d]->checkAttributesOnClientAfterTransformation OK\n", myRank, i, axisListP.size()); 
     194        } 
     195      } 
     196 
     197      setDomainList(); //printf("myRank = %d, setDomainList OK\n", myRank); 
     198      std::vector<CDomain*> domListP = this->getDomains(); //printf("myRank = %d, this->getDomains OK\n", myRank); 
    193199      if (!domListP.empty()) 
    194200      { 
    195201        for (int i = 0; i < domListP.size(); ++i) 
    196202        { 
     203          //printf("myRank = %d, start domListP[%d]->checkAttributesOnClientAfterTransformation\n", myRank, i); 
    197204          domListP[i]->checkAttributesOnClientAfterTransformation(); 
     205          //printf("myRank = %d, domListP[%d]->checkAttributesOnClientAfterTransformation OK\n", myRank, i); 
    198206        } 
    199207      } 
     
    272280   void CGrid::checkMaskIndex(bool doSendingIndex) 
    273281   { 
    274      CContext* context = CContext::getCurrent(); 
     282     int myRank; 
     283     MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 
     284 
     285     CContext* context = CContext::getCurrent();  
    275286     CContextClient* client=context->client; 
    276287 
     
    278289     { 
    279290       if (context->hasClient) 
    280           if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; } 
     291          if (this->isChecked && doSendingIndex && !isIndexSent)  
     292            {  
     293              sendIndexScalarGrid();  
     294              this->isIndexSent = true;  
     295            } 
    281296 
    282297       if (this->isChecked) return; 
    283  
    284298       if (context->hasClient) 
    285299       { 
     
    287301       } 
    288302 
    289        if (!(this->hasTransform() && !this->isTransformed())) 
    290         this->isChecked = true; 
     303       this->isChecked = true; 
    291304       return; 
    292305     } 
    293  
     306      
    294307     if (context->hasClient) 
    295       if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; } 
     308      if (this->isChecked && doSendingIndex && !isIndexSent)  
     309        { 
     310          sendIndex();  
     311          this->isIndexSent = true; 
     312        } 
    296313 
    297314     if (this->isChecked) return; 
     
    299316     if (context->hasClient) 
    300317     { 
    301         this->checkAttributesAfterTransformation(); 
    302         this->checkMask(); 
    303         this->computeIndex(); 
     318        this->checkAttributesAfterTransformation();  
     319        this->checkMask();   
     320        this->computeIndex();   
    304321     } 
    305  
    306      if (!(this->hasTransform() && !this->isTransformed()))  
    307       this->isChecked = true; 
    308  
    309      if (!(this->hasTransform() && (!this->isGenerated()))) 
    310       this->isChecked = true;  
     322     this->isChecked = true; 
    311323   } 
    312324 
     
    10511063        int rank = *itRank; 
    10521064        int nb = 1; 
    1053         storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));         
     1065        storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb))); 
    10541066        listOutIndex.push_back(CArray<size_t,1>(nb)); 
    10551067 
     
    10631075        } 
    10641076 
    1065         storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    10661077        listMsg.push_back(CMessage()); 
    10671078        listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
     
    10721083    } 
    10731084    else 
    1074     { 
    1075       const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1076       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1077       { 
    1078         int rank = *itRank; 
    1079         int nb = 1;         
    1080         storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(nb))); 
    1081         CArray<int, 1>& outLocalIndexToServer = storeIndex_fromSrv[rank]; 
    1082         for (int k = 0; k < nb; ++k) 
    1083         {           
    1084           outLocalIndexToServer(k)  = 0; 
    1085         } 
    1086       } 
    10871085      client->sendEvent(event); 
    1088     } 
    10891086  } 
    10901087 
     
    11141111          outLocalIndexToServer(idx) = itIndex->second; 
    11151112        } 
    1116          
     1113 
     1114        //int nbClient = client->clientSize; // This stupid variable signals the servers the number of client connect to them 
    11171115        const std::list<int>& ranks = client->getRanksServerLeader(); 
    11181116        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    11191117        { 
    11201118          storeIndex_toSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1121           storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    11221119          listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 
    11231120 
     
    11291126        client->sendEvent(event); 
    11301127      } 
    1131       else  
    1132       { 
    1133         int indexSize = globalLocalIndexSendToServer.size();         
    1134         CArray<int,1> outLocalIndexToServer(indexSize); 
    1135         for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1136         {           
    1137           outLocalIndexToServer(idx) = itIndex->second; 
    1138         } 
    1139          
    1140         const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1141         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1142         {           
    1143           storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1144         } 
     1128      else 
    11451129        client->sendEvent(event); 
    1146       } 
    11471130    } 
    11481131    else 
     
    11771160          nb = globalIndexTmp[rank].size(); 
    11781161 
    1179         storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));         
     1162        storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb))); 
    11801163        listOutIndex.push_back(CArray<size_t,1>(nb)); 
    11811164 
     
    11891172        } 
    11901173 
    1191         storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    11921174        listMsg.push_back(CMessage()); 
    11931175        listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
  • XIOS/dev/branch_yushan/src/node/grid.hpp

    r988 r1037  
    221221 
    222222         map<int, CArray<int, 1> > storeIndex_toSrv; 
    223          map<int, CArray<int, 1> > storeIndex_fromSrv; 
    224223         map<int,int> nbSenders; 
    225224 
  • XIOS/dev/branch_yushan/src/node/interpolate_domain.cpp

    r1014 r1037  
    4848    } 
    4949 
    50     if (this->mode.isEmpty()) this->mode.setValue(mode_attr::compute); 
    51     if (this->write_weight.isEmpty()) this->write_weight.setValue(false); 
     50    StdString weightFile = "interpolation_weights_" + domainSrc->getDomainOutputName(); 
    5251 
    53     StdString weightFile; 
    54     switch (this->mode) 
    55     { 
    56       case mode_attr::read: 
    57         if (this->weight_filename.isEmpty()) 
    58         { 
    59           if (!this->write_weight) 
     52    if (!this->mode.isEmpty()) 
     53    {  
     54      if (mode_attr::read == this->mode) 
     55      { 
     56         if (this->file.isEmpty()) 
     57         { 
    6058            ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 
    6159                 << "Read mode is activated but there is no file specified." << std::endl 
    6260                 << "Please define a correct file containing interpolation weights with option 'file'. "); 
    63         } 
    64         else 
    65         { 
    66           weightFile = this->weight_filename; 
    67           ifstream f(weightFile.c_str()); 
    68           if (!f.good()) 
    69             ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 
    70                   << "Read mode is activated but file "  << weightFile << " doesn't exist." << std::endl 
    71                   << "Please check this file "); 
    72         } 
    73         break; 
    74       case mode_attr::compute: 
    75         break; 
    76       case mode_attr::read_or_compute: 
    77         if (!this->weight_filename.isEmpty() && !this->write_weight) 
    78         { 
    79           weightFile = this->weight_filename; 
    80           ifstream f(weightFile.c_str()); 
    81           if (!f.good()) 
    82             ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 
    83                   << "read_or_compute mode is activated but file "  << weightFile << " doesn't exist." << std::endl 
    84                   << "Please check this file "); 
    85         } 
    86         break; 
    87       default: 
    88         break; 
     61         } 
     62         else 
     63         { 
     64           weightFile = this->file; 
     65           ifstream f(weightFile.c_str()); 
     66           if (!f.good()) 
     67             ERROR("void CInterpolateDomain::checkValid(CDomain* domainSrc)", 
     68                   << "Read mode is activated but file "  << weightFile << " doesn't exist." << std::endl 
     69                   << "Please check this file "); 
     70         } 
     71      } 
     72      else 
     73      { 
     74        if (file.isEmpty()) 
     75          this->file.setValue(weightFile); 
     76      }    
     77    } 
     78    else 
     79    { 
     80      if (!file.isEmpty()) // set mode read 
     81      { 
     82         weightFile = this->file; 
     83         ifstream f(weightFile.c_str()); 
     84         if (!f.good()) // file doesn't exist 
     85           this->mode.setValue(mode_attr::write); 
     86         else 
     87           this->mode.setValue(mode_attr::read); 
     88      } 
     89      else // only calculate weights() Mode set write but there is no file) 
     90      { 
     91        this->mode.setValue(mode_attr::write); 
     92      } 
    8993    } 
    9094 
  • XIOS/dev/branch_yushan/src/node/interpolate_domain.hpp

    r1004 r1037  
    5050      virtual ~CInterpolateDomain(void); 
    5151 
    52       virtual void checkValid(CDomain* domainSource); 
     52      virtual void checkValid(CDomain* axisDest); 
    5353 
    5454      /// Accesseurs statiques /// 
  • XIOS/dev/branch_yushan/src/node/mesh.cpp

    r1002 r1037  
    1111/// ////////////////////// Définitions ////////////////////// /// 
    1212 
    13   CMesh::CMesh(void) :  nbNodesGlo(0), nbEdgesGlo(0) 
    14             ,  node_start(0), node_count(0) 
    15             ,  edge_start(0), edge_count(0) 
    16             ,  nbFaces_(0), nbNodes_(0), nbEdges_(0) 
    17             ,  nodesAreWritten(false), edgesAreWritten(false), facesAreWritten(false) 
     13  CMesh::CMesh(void) :  nbNodesGlo{0}, nbEdgesGlo{0} 
     14            ,  node_start{0}, node_count{0} 
     15            ,  edge_start{0}, edge_count{0} 
     16            ,  nbFaces_{0}, nbNodes_{0}, nbEdges_{0} 
     17            ,  nodesAreWritten{false}, edgesAreWritten{false}, facesAreWritten{false} 
    1818            ,  node_lon(), node_lat() 
    1919            ,  edge_lon(), edge_lat(), edge_nodes() 
    2020            ,  face_lon(), face_lat() 
    2121            ,  face_nodes() 
    22             ,  pNodeGlobalIndex(NULL), pEdgeGlobalIndex(NULL) 
     22            ,  pNodeGlobalIndex{NULL}, pEdgeGlobalIndex{NULL} 
    2323  { 
    2424  } 
     
    9191      seed ^= sizetHash(first) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 
    9292    } 
     93    return seed ; 
     94  } 
     95 
     96///---------------------------------------------------------------- 
     97/*! 
     98 * \fn size_t generateEdgeIndex(size_t first, size_t second, int rank) 
     99 * Generates an edge index. 
     100 * If the same edge is generated by two processes, each process will have its own edge index. 
     101 * \param [in] first Edge node. 
     102 * \param [in] second Edge node. 
     103 * \param [in] rank MPI process rank. 
     104 */ 
     105  size_t generateEdgeIndex(size_t first, size_t second, int rank) 
     106  { 
     107    size_t seed = rank ; 
     108    if (first < second) 
     109    { 
     110      seed = hashPair(seed, first); 
     111      seed = hashPair(seed, second); 
     112    } 
     113    else 
     114    { 
     115      seed = hashPair(seed, second); 
     116      seed = hashPair(seed, first); 
     117    } 
     118 
    93119    return seed ; 
    94120  } 
     
    115141    return seed ; 
    116142  } 
    117  
    118   ///---------------------------------------------------------------- 
    119   /*! 
    120    * \fn size_t generateNodeIndex(vector<size_t>& valList) 
    121    * Generates a node index unique for all processes. 
    122    * \param [in] valList Vector storing four node hashes. 
    123    */ 
    124     size_t generateNodeIndex(vector<size_t>& valList) 
    125     { 
    126       // Sort is needed to avoid problems for nodes with lon = 0 generated by faces in east and west semisphere 
    127       vector<size_t> vec = valList; 
    128       sort (vec.begin(), vec.end()); 
    129       size_t seed = vec[0] ; 
    130       int it = 1; 
    131       for(; it != vec.size(); ++it) 
    132       { 
    133          seed = hashPair(seed, vec[it]); 
    134       } 
    135       return seed ; 
    136     } 
    137  
    138143 
    139144///---------------------------------------------------------------- 
     
    595600        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2Idx; 
    596601        CArray<size_t,1> nodeHashList(nbEdges_*nvertex*4); 
    597         int nbHash = 0; 
    598602        for (int ne = 0; ne < nbEdges_; ++ne) 
    599603        { 
     
    605609              if (nodeHash2Idx[hashValues[nh]].size() == 0) 
    606610              { 
    607                 nodeHash2Idx[hashValues[nh]].push_back(generateNodeIndex(hashValues)); 
     611                nodeHash2Idx[hashValues[nh]].push_back(generateNodeIndex(hashValues, mpiRank)); 
    608612                nodeHash2Idx[hashValues[nh]].push_back(mpiRank); 
    609                 nodeHashList(nbHash) = hashValues[nh]; 
    610                 ++nbHash; 
    611613              } 
    612             } 
    613           } 
    614         } 
    615         nodeHashList.resizeAndPreserve(nbHash); 
     614              nodeHashList((ne*nvertex + nv)*4 + nh) = hashValues[nh]; 
     615            } 
     616          } 
     617        } 
    616618 
    617619        // (2.2) Generating global node indexes 
    618         // The ownership criterion: priority of the process of smaller index 
     620        // The ownership criterion: priority of the process holding the smaller index 
    619621        // Maps generated in this step are: 
    620         // Maps generated in this step are: 
    621          // nodeHash2Info = <hash, [[idx, rankMin], [idx, rank1], [idx, rank3]..]> 
    622          // nodeIdx2Idx = <idx, <rankOwner, idx>> 
    623  
    624          CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 
    625          dhtNodeHash.computeIndexInfoMapping(nodeHashList); 
    626          CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 
    627  
    628  
    629          CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2Idx; 
    630          CArray<size_t,1> nodeIdxList(nbEdges_*nvertex*4); 
    631          size_t nIdx = 0; 
    632  
    633          for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 
    634          { 
    635            size_t rankMin = (it->second)[1]; 
    636            size_t idx = (it->second)[0]; 
    637            for (int i = 2; i < (it->second).size();) 
    638            { 
    639              if ( (it->second)[i+1] < rankMin) 
    640              { 
    641                idx = (it->second)[i]; 
    642                rankMin = (it->second)[i+1]; 
    643                (it->second)[i+1] = (it->second)[i-1]; 
    644              } 
    645              i += 2; 
    646            } 
    647            if (nodeIdx2Idx.count(idx) == 0) 
    648            { 
    649              if (mpiRank == rankMin) 
    650              { 
    651                nodeIdx2Idx[idx].push_back(rankMin); 
    652                nodeIdx2Idx[idx].push_back(idx); 
    653              } 
    654              nodeIdxList(nIdx) = idx; 
    655              ++nIdx; 
    656            } 
    657          } 
    658          nodeIdxList.resizeAndPreserve(nIdx); 
    659  
    660          // CDHTAutoIndexing will not give consistent node numbering for varying number of procs. => 
    661          // Solution: global node indexing by hand. 
    662          // Maps modified in this step: 
    663          // nodeIdx2Idx = <idx, idxGlo> 
    664          int nodeCount = nodeIdx2Idx.size(); 
    665          int nodeStart, nbNodes; 
    666          MPI_Scan(&nodeCount, &nodeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 
    667          int nNodes = nodeStart; 
    668          MPI_Bcast(&nNodes, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 
    669          nbNodesGlo = nNodes; 
    670  
    671          nodeStart -= nodeCount; 
    672          node_start = nodeStart; 
    673          node_count = nodeCount; 
    674          CClientClientDHTSizet::Index2VectorInfoTypeMap dummyMap; // just a dummy map used to ensure that each node is numbered only once 
    675          size_t count = 0; 
    676  
    677          for (int ne = 0; ne < nbEdges_; ++ne) 
    678          { 
    679            for (int nv = 0; nv < nvertex; ++nv) 
    680            { 
    681              vector<size_t> hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 
    682              size_t nodeIdx = generateNodeIndex(hashValues); 
    683              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeIdx2Idx.find(nodeIdx); 
    684              if (it != nodeIdx2Idx.end()) 
    685              { 
    686                if (dummyMap.count(nodeIdx) == 0) 
    687                { 
    688                  dummyMap[nodeIdx].push_back(nodeIdx); 
    689                  (it->second)[1] = node_start + count; 
    690                  ++count; 
    691                } 
    692              } 
    693            } 
    694          } 
    695  
    696          CClientClientDHTSizet dhtNodeIdx(nodeIdx2Idx, comm); 
    697          dhtNodeIdx.computeIndexInfoMapping(nodeIdxList); 
    698          CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdx2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 
     622        // nodeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 
     623        // nodeIdx2IdxMin = <idx, idxMin> 
     624        // nodeIdx2IdxGlo = <idxMin, idxMin> 
     625 
     626        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxMin; 
     627        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxGlo; 
     628        CArray<size_t,1> nodeIdxMinList(nbEdges_*nvertex); 
     629 
     630        CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 
     631        dhtNodeHash.computeIndexInfoMapping(nodeHashList); 
     632        CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 
     633        size_t iIdxMin = 0; 
     634 
     635        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 
     636        { 
     637          size_t idx = (it->second)[0]; 
     638          size_t idxMin = (it->second)[0]; 
     639          for (int i = 2; i < (it->second).size();) 
     640          { 
     641            if (mpiRank == (it->second)[i+1]) 
     642            { 
     643              idx = (it->second)[i]; 
     644            } 
     645            if ((it->second)[i] < idxMin) 
     646            { 
     647                idxMin = (it->second)[i]; 
     648                (it->second)[i] = (it->second)[i-2]; 
     649            } 
     650            i += 2; 
     651          } 
     652          (it->second)[0] = idxMin; 
     653          if (nodeIdx2IdxMin.count(idx) == 0) 
     654          { 
     655            nodeIdx2IdxMin[idx].push_back(idxMin); 
     656            if (idx == idxMin) 
     657              nodeIdx2IdxGlo[idxMin].push_back(idxMin); 
     658            nodeIdxMinList(iIdxMin) = idxMin; 
     659            ++iIdxMin; 
     660          } 
     661        } 
     662        nodeIdxMinList.resizeAndPreserve(iIdxMin); 
     663        CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2IdxGlo, comm); 
     664        CClientClientDHTSizet dhtNodeIdx(nodeIdx2IdxGlo, comm); 
     665        dhtNodeIdx.computeIndexInfoMapping(nodeIdxMinList); 
     666        CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdxMin2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 
     667        // nodeIdx2IdxGlo holds global indexes only for nodes owned by a process 
     668        // nodeIdxMin2IdxGlo holds global indexes for all nodes generated by a process 
    699669 
    700670        // (2.3) Saving variables: node_lon, node_lat, edge_nodes 
    701671        // Creating map nodeHash2IdxGlo <hash, idxGlo> 
    702672        // Creating map edgeHash2IdxGlo <hash, idxGlo> 
    703 //        nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
    704 //        node_count = dhtNodeIdxGlo.getIndexCount(); 
    705 //        node_start = dhtNodeIdxGlo.getIndexStart(); 
     673        nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
     674        node_count = dhtNodeIdxGlo.getIndexCount(); 
     675        node_start = dhtNodeIdxGlo.getIndexStart(); 
    706676        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2IdxGlo; 
    707677        node_lon.resize(node_count); 
     
    715685          { 
    716686            hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 
    717             size_t myIdx = generateNodeIndex(hashValues); 
    718             CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = nodeIdx2IdxGlo.find(myIdx); 
    719             idxGlo = (itIdx->second)[1]; 
    720  
    721             if (mpiRank == (itIdx->second)[0]) 
    722             { 
     687            size_t myIdx = generateNodeIndex(hashValues, mpiRank); 
     688            CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = nodeIdx2IdxMin.find(myIdx); 
     689            size_t ownerIdx = (itIdx->second)[0]; 
     690 
     691            if (myIdx == ownerIdx) 
     692            { 
     693              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = nodeIdx2IdxGlo.find(myIdx); 
     694              idxGlo = (itIdxGlo->second)[0]; 
    723695//              node_lon(idxGlo - node_start) = (bounds_lon(nv, ne) == 360.) ? (0.) : (bounds_lon(nv, ne)); 
    724696              node_lon(idxGlo - node_start) = bounds_lon(nv, ne); 
    725697              node_lat(idxGlo - node_start) = bounds_lat(nv, ne); 
    726698            } 
     699            else 
     700            { 
     701              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = nodeIdxMin2IdxGlo.find(ownerIdx); 
     702              idxGlo = (itIdxGlo->second)[0]; 
     703            } 
     704 
    727705            edge_nodes(nv,ne) = idxGlo; 
    728706            for (int nh = 0; nh < 4; ++nh) 
     
    815793        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2Rank; 
    816794        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 
    817         CArray<size_t,1> edgeIdxList(nbFaces_*nvertex); 
     795        CArray<size_t,1> edgeIdxGloList(nbFaces_*nvertex); 
    818796        size_t iIdx = 0; 
    819797 
     
    846824              if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 
    847825              { 
    848                 edgeIdxList(iIdx) = edgeIdxGlo; 
     826                edgeIdxGloList(iIdx) = edgeIdxGlo; 
    849827                ++iIdx; 
    850828              } 
    851829              edgeIdxGlo2Face[edgeIdxGlo].push_back(faceIdxGlo); 
     830              edgeHash2Rank[edgeHash].push_back(itEdgeHash->first); 
    852831              edgeHash2Rank[edgeHash].push_back(mpiRank); 
    853               edgeHash2Rank[edgeHash].push_back(itEdgeHash->second[0]); 
    854832            } 
    855833            else 
     
    859837          } 
    860838        } 
    861         edgeIdxList.resizeAndPreserve(iIdx); 
     839        edgeIdxGloList.resizeAndPreserve(iIdx); 
    862840 
    863841        // (1.3) Saving remaining variables edge_faces and face_faces 
     
    868846        dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 
    869847        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 
    870  
    871         // edgeHash2Info = <edgeHash, < rank1, idxGlo, rank2, idxGlo>> 
    872         int edgeCount = 0; 
     848        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHashMin2IdxGlo; 
     849 
     850        // edgeHash2Info = <edgeHash, <idxGlo, rank1, idxGlo, rank2>> 
     851        // edgeHashMin2IdxGlo = <edgeHashMin, idxGlo> 
    873852        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 
    874853        { 
    875854          vector <size_t> edgeInfo = it->second; 
    876           if (edgeInfo[0] == mpiRank) 
    877           { 
    878             ++edgeCount; 
    879           } 
    880         } 
    881  
    882         int edgeStart, nbEdges; 
    883         MPI_Scan(&edgeCount, &edgeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 
    884         int nEdges = edgeStart; 
    885         MPI_Bcast(&nEdges, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 
    886         nbEdgesGlo = nEdges; 
    887  
    888         // edges to be splitted equally between procs 
    889         if ( (nbEdgesGlo % mpiSize) == 0) 
    890         { 
    891           edge_count = nbEdgesGlo/mpiSize; 
    892           edge_start = mpiRank*edge_count; 
    893         } 
    894         else 
    895         { 
    896           if (mpiRank == (mpiSize - 1) ) 
    897           { 
    898             edge_count = nbEdgesGlo/mpiSize; 
    899             edge_start = mpiRank*(nbEdgesGlo/mpiSize + 1); 
    900           } 
    901           else 
    902           { 
    903             edge_count = nbEdgesGlo/mpiSize + 1; 
    904             edge_start = mpiRank*edge_count; 
    905           } 
    906         } 
    907         CArray<size_t,1> edgeIdxGloList(edge_count); 
    908         for (int i = 0; i < edge_count; ++i) 
    909         { 
    910           edgeIdxGloList(i) = i + edge_start; 
    911         } 
    912  
    913         CClientClientDHTSizet dhtEdgeIdxGlo2Face (edgeIdxGlo2Face, comm); 
     855          if (edgeInfo.size() == 4)                       // two processes generate the same edge 
     856            if (edgeInfo[1] > edgeInfo[3]) 
     857              edgeInfo[1] = edgeInfo[3]; 
     858          if (edgeInfo[1] == mpiRank) 
     859            edgeHashMin2IdxGlo[it->first].push_back(edgeInfo[0]); 
     860        } 
     861 
     862        CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeHashMin2IdxGlo, comm); 
     863        edge_count = dhtEdgeIdxGlo.getIndexCount(); 
     864        edge_start = dhtEdgeIdxGlo.getIndexStart(); 
     865 
     866        edge_faces.resize(2, edge_count); 
     867        face_faces.resize(nvertex, nbFaces_); 
     868 
    914869        CClientClientDHTSizet dhtEdge2Face (edgeIdxGlo2Face, comm); 
    915         dhtEdgeIdxGlo2Face.computeIndexInfoMapping(edgeIdxGloList); 
    916         CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdgeIdxGlo2Face.getInfoIndexMap(); 
    917         dhtEdge2Face.computeIndexInfoMapping(edgeIdxList); 
    918         CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdx2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 
    919  
    920  
    921         edge_faces.resize(2, edge_count); 
    922         for (int i = 0; i < edge_count; ++i) 
    923         { 
    924           CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdxGlo2FaceIdx.find(i + edge_start); 
    925           int indexGlo = it->first; 
    926           vector<size_t> faces = it->second; 
    927           int face1 = faces[0]; 
    928           edge_faces(0, indexGlo - edge_start) = face1; 
    929           if (faces.size() == 2) 
    930           { 
    931             int face2 = faces[1]; 
    932             edge_faces(1, indexGlo - edge_start) = face2; 
    933           } 
    934           else 
    935           { 
    936             edge_faces(1, indexGlo - edge_start) = -999; 
    937           } 
    938         } 
    939  
    940         size_t tmp; 
    941         vector<size_t> tmpVec; 
    942         for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdx2FaceIdx.begin(); it != edgeIdx2FaceIdx.end(); it++) 
    943         { 
    944           tmp = it->first; 
    945           tmpVec = it->second; 
    946           tmp++; 
    947         } 
    948  
    949         CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itFace1, itFace2, itIndex; 
    950         face_faces.resize(nvertex, nbFaces_); 
     870        dhtEdge2Face.computeIndexInfoMapping(edgeIdxGloList); 
     871        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 
     872        CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itFace1, itFace2; 
     873 
    951874        for (int nf = 0; nf < nbFaces_; ++nf) 
    952875        { 
     
    973896              size_t faceIdxGlo = nbFacesAccum + nf; 
    974897              size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 
    975               itEdgeHash = edgeHash2Info.find(edgeHash); 
    976               int edgeIdxGlo = (itEdgeHash->second)[1]; 
    977  
    978               if ( (itEdgeHash->second)[0] == mpiRank) 
     898              itEdgeHash = edgeHash2IdxGlo.find(edgeHash); 
     899              if (itEdgeHash != edgeHashMin2IdxGlo.end()) 
    979900              { 
    980                 itFace1 = edgeIdx2FaceIdx.find(edgeIdxGlo); 
     901                int edgeIdxGlo = itEdgeHash->second[0]; 
     902                itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    981903                int face1 = itFace1->second[0]; 
    982904                if (itFace1->second.size() == 1) 
    983905                { 
     906                  edge_faces(0, edgeIdxGlo - edge_start) = face1; 
     907                  edge_faces(1, edgeIdxGlo - edge_start) = -999; 
    984908                  face_faces(nv1, nf) = 999999; 
    985909                } 
     
    987911                { 
    988912                  int face2 = itFace1->second[1]; 
     913                  edge_faces(0, edgeIdxGlo - edge_start) = face1; 
     914                  edge_faces(1, edgeIdxGlo - edge_start) = face2; 
    989915                  face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 
    990916                } 
     
    992918              else 
    993919              { 
    994                 itFace1 = edgeIdx2FaceIdx.find(edgeIdxGlo); 
     920                itEdgeHash = edgeHashMin2IdxGlo.find(edgeHash); 
     921                size_t edgeIdxGlo = itEdgeHash->second[0]; 
     922                itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    995923                int face1 = itFace1->second[0]; 
    996924                int face2 = itFace1->second[1]; 
     
    1029957        CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it1, it2; 
    1030958        CArray<size_t,1> edgeHashList(nbFaces_*nvertex); 
    1031         int nEdgeHash = 0; 
    1032959        for (int nf = 0; nf < nbFaces_; ++nf) 
    1033960        { 
     
    1051978            face_nodes(nv1,nf) = it1->second[0]; 
    1052979            size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 
    1053             if (edgeHash2Idx.count(edgeHash) == 0) 
    1054             { 
    1055               edgeHash2Idx[edgeHash].push_back(edgeHash); 
    1056               edgeHash2Idx[edgeHash].push_back(mpiRank); 
    1057               edgeHashList(nEdgeHash) = edgeHash; 
    1058               ++nEdgeHash; 
    1059             } 
    1060           } 
    1061         } 
    1062         edgeHashList.resizeAndPreserve(nEdgeHash); 
    1063  
    1064         // (2.3) Generating global edge indexes 
    1065         // The ownership criterion: priority of the process with smaller rank 
     980            edgeHash2Idx[edgeHash].push_back(generateEdgeIndex(it1->second[0], it2->second[0], mpiRank)); 
     981            edgeHash2Idx[edgeHash].push_back(mpiRank); 
     982            edgeHashList(nf*nvertex + nv1) = edgeHash; 
     983          } 
     984        } 
     985 
     986        // (2.2) Generating global edge indexes 
     987        // The ownership criterion: priority of the process holding the smaller index 
    1066988        // Maps generated in this step are: 
    1067         // edgeIdx2Idx = = <idx, <rankOwner, idx>> 
    1068         // edgeIdx2IdxGlo = <idxMin, <rankOwner, idxGlo>> 
     989        // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 
     990        // edgeIdx2IdxMin = = <idx, idxMin> 
     991        // edgeIdx2IdxGlo = <idxMin, idxGlo> 
    1069992 
    1070993        CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); 
    1071994        dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 
    1072995        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 
    1073         // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 
    1074  
    1075         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2Idx; 
     996 
     997        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 
     998        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 
     999        CArray<size_t,1> edgeIdxMinList(nbFaces_*nvertex); 
     1000        size_t iIdxMin = 0; 
    10761001 
    10771002        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 
    10781003        { 
    1079           size_t rankMin = (it->second)[1]; 
     1004          size_t idxMin = (it->second)[0]; 
    10801005          size_t idx = (it->second)[0]; 
    1081  
    10821006          for (int i = 2; i < (it->second).size();) 
    10831007          { 
    1084             if ((it->second)[i+1] < rankMin) 
    1085             { 
    1086               rankMin = (it->second)[i+1]; 
     1008            if (mpiRank == (it->second)[i+1]) 
     1009            { 
    10871010              idx = (it->second)[i]; 
    1088               (it->second)[i+1] = (it->second)[i-1]; 
     1011            } 
     1012            if ((it->second)[i] < idxMin) 
     1013            { 
     1014                idxMin = (it->second)[i]; 
     1015                (it->second)[i] = (it->second)[i-2]; 
    10891016            } 
    10901017            i += 2; 
    10911018          } 
    1092           if (edgeIdx2Idx.count(idx) == 0) 
    1093           { 
    1094             if (mpiRank == rankMin) 
    1095             { 
    1096               edgeIdx2Idx[idx].push_back(rankMin); 
    1097               edgeIdx2Idx[idx].push_back(idx); 
    1098             } 
    1099           } 
    1100         } 
    1101  
    1102         int edgeCount = edgeIdx2Idx.size(); 
    1103         int edgeStart, nbEdges; 
    1104         MPI_Scan(&edgeCount, &edgeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 
    1105         int nEdges = edgeStart; 
    1106         MPI_Bcast(&nEdges, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 
    1107         nbEdgesGlo = nEdges; 
    1108  
    1109         edgeStart -= edgeCount; 
    1110         edge_start = edgeStart; 
    1111         edge_count = edgeCount; 
    1112         CClientClientDHTSizet::Index2VectorInfoTypeMap dummyEdgeMap; 
    1113         int count = 0; 
     1019          (it->second)[0] = idxMin; 
     1020          if (edgeIdx2IdxMin.count(idx) == 0) 
     1021          { 
     1022            edgeIdx2IdxMin[idx].push_back(idxMin); 
     1023            if (idx == idxMin) 
     1024              edgeIdx2IdxGlo[idxMin].push_back(idxMin); 
     1025            edgeIdxMinList(iIdxMin) = idxMin; 
     1026            ++iIdxMin; 
     1027          } 
     1028        } 
     1029        edgeIdxMinList.resizeAndPreserve(iIdxMin); 
     1030        CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeIdx2IdxGlo, comm); 
     1031        CClientClientDHTSizet dhtEdgeIdx(edgeIdx2IdxGlo, comm); 
     1032        dhtEdgeIdx.computeIndexInfoMapping(edgeIdxMinList); 
     1033        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxMin2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 
     1034        // edgeIdx2IdxGlo holds global indexes only for edges owned by a process 
     1035        // edgeIdxMin2IdxGlo holds global indexes for all edges generated by a process 
     1036 
     1037        // (2.3) Saving variables: edge_lon, edge_lat, face_edges 
     1038        nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 
     1039        edge_count = dhtEdgeIdxGlo.getIndexCount(); 
     1040        edge_start = dhtEdgeIdxGlo.getIndexStart(); 
     1041        edge_lon.resize(edge_count); 
     1042        edge_lat.resize(edge_count); 
     1043        edge_nodes.resize(2, edge_count); 
     1044        face_edges.resize(nvertex, nbFaces_); 
     1045 
     1046        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 
     1047        CArray<size_t,1> edgeIdxGloList(nbFaces_*nvertex); 
     1048        size_t iIdx = 0; 
    11141049 
    11151050        for (int nf = 0; nf < nbFaces_; ++nf) 
     
    11331068              it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 
    11341069            } 
    1135             size_t nodeIdxGlo1 = it1->second[0]; 
    1136             size_t nodeIdxGlo2 = it2->second[0]; 
    1137  
    1138             if (nodeIdxGlo1 != nodeIdxGlo2) 
    1139             { 
    1140               size_t edgeIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    1141               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdx2Idx.find(edgeIdx); 
    1142               if (it != edgeIdx2Idx.end()) 
    1143               { 
    1144                 if (dummyEdgeMap.count(edgeIdx) == 0) 
    1145                 { 
    1146                   dummyEdgeMap[edgeIdx].push_back(edgeIdx); 
    1147                   (it->second)[1] = edge_start + count; 
    1148                   ++count; 
    1149                 } 
    1150               } 
    1151             } 
    1152           } 
    1153         } 
    1154  
    1155         CClientClientDHTSizet dhtEdgeIdx(edgeIdx2Idx, comm); 
    1156         dhtEdgeIdx.computeIndexInfoMapping(edgeHashList); 
    1157         CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdx2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 
    1158  
    1159         // (2.4) Saving variables: edge_lon, edge_lat, face_edges 
    1160         edge_lon.resize(edge_count); 
    1161         edge_lat.resize(edge_count); 
    1162         edge_nodes.resize(2, edge_count); 
    1163         face_edges.resize(nvertex, nbFaces_); 
    1164  
    1165         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 
    1166         CArray<size_t,1> edgeIdxGloList(nbFaces_*nvertex); 
    1167         size_t iIdx = 0; 
    1168  
    1169         for (int nf = 0; nf < nbFaces_; ++nf) 
    1170         { 
    1171           for (int nv1 = 0; nv1 < nvertex; ++nv1) 
    1172           { 
    1173             // Getting global indexes of edge's nodes 
    1174             int nh1 = 0; 
    1175             int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 
    1176             it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 
    1177             while (it1 == nodeHash2IdxGlo.end()) 
    1178             { 
    1179               ++nh1; 
    1180               it1 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh1)); 
    1181             } 
    1182             int nh2 = 0; 
    1183             it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv2)*4 + nh2)); 
    1184             while (it2 == nodeHash2IdxGlo.end()) 
    1185             { 
    1186               ++nh2; 
    1187               it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 
    1188             } 
    11891070            // Getting edge global index 
    11901071            size_t nodeIdxGlo1 = it1->second[0]; 
    11911072            size_t nodeIdxGlo2 = it2->second[0]; 
    1192             size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
     1073            size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 
    11931074            if (nodeIdxGlo1 != nodeIdxGlo2) 
    11941075            { 
    1195               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 
    1196               int edgeIdxGlo = (itIdx->second)[1]; 
     1076              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 
     1077              size_t ownerIdx = (itIdx->second)[0]; 
     1078              int edgeIdxGlo = 0; 
    11971079              size_t faceIdxGlo = nbFacesAccum + nf; 
    11981080 
    1199               if (mpiRank == (itIdx->second)[0]) 
     1081              if (myIdx == ownerIdx) 
    12001082              { 
     1083                CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
     1084                edgeIdxGlo = (itIdxGlo->second)[0]; 
    12011085                double edgeLon; 
    12021086                double diffLon = abs(bounds_lon(nv1, nf) - bounds_lon(nv2, nf)); 
     
    12121096                edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 
    12131097              } 
     1098              else 
     1099              { 
     1100                CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
     1101                edgeIdxGlo = (itIdxGlo->second)[0]; 
     1102              } 
    12141103              face_edges(nv1,nf) = edgeIdxGlo; 
    12151104              if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 
     
    12281117        edgeIdxGloList.resizeAndPreserve(iIdx); 
    12291118 
    1230         // (2.5) Saving remaining variables edge_faces and face_faces 
     1119        // (2.4) Saving remaining variables edge_faces and face_faces 
    12311120        edge_faces.resize(2, edge_count); 
    12321121        face_faces.resize(nvertex, nbFaces_); 
     
    12361125        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 
    12371126        CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdxGlo1, itNodeIdxGlo2; 
    1238         CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx; 
    12391127 
    12401128        for (int nf = 0; nf < nbFaces_; ++nf) 
     
    12611149            size_t nodeIdxGlo2 = it2->second[0]; 
    12621150 
    1263             size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    1264             itIdx = edgeIdx2IdxGlo.find(myIdx); 
     1151            size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 
     1152            CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 
     1153            size_t ownerIdx = (itIdx->second)[0]; 
    12651154            size_t faceIdxGlo = nbFacesAccum + nf; 
    1266             int edgeIdxGlo = (itIdx->second)[1]; 
    1267  
    1268             if (mpiRank == (itIdx->second)[0]) 
    1269             { 
     1155 
     1156            if (myIdx == ownerIdx) 
     1157            { 
     1158              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
     1159              int edgeIdxGlo = (itIdxGlo->second)[0]; 
    12701160              it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    12711161              int face1 = it1->second[0]; 
     
    12861176            else 
    12871177            { 
     1178              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
     1179              size_t edgeIdxGlo = (itIdxGlo->second)[0]; 
    12881180              it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    12891181              int face1 = it1->second[0]; 
     
    13081200          { 
    13091201            hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 
    1310 //            size_t nodeIndex = generateNodeIndex(hashValues, mpiRank); 
    1311             size_t nodeIndex = generateNodeIndex(hashValues); 
     1202            size_t nodeIndex = generateNodeIndex(hashValues, mpiRank); 
    13121203            for (int nh = 0; nh < 4; ++nh) 
    13131204            { 
     
    13251216 
    13261217        // (3.2) Generating global node indexes 
    1327         // The ownership criterion: priority of the process with smaller rank. 
    1328         // With any other criterion it is not possible to have consistent node indexing for different number of procs. 
     1218        // The ownership criterion: priority of the process holding the smaller index 
    13291219        // Maps generated in this step are: 
    1330         // nodeHash2Info = <hash, [[idx, rankMin], [idx, rank1], [idx, rank3]..]> 
    1331         // nodeIdx2Idx = <idx, <rankOwner, idx>> 
     1220        // nodeHash2Info = <hash, [[idxMin, rankMin], [idx1, rank1], [idx3, rank3]..]> 
     1221        // nodeIdx2IdxMin = = <idx, idxMin> 
     1222        // nodeIdx2IdxGlo = <idxMin, idxGlo> 
    13321223 
    13331224        CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 
     
    13351226        CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 
    13361227 
    1337         CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2Idx; 
    1338         CArray<size_t,1> nodeIdxList(nbFaces_*nvertex*4); 
    1339         size_t nIdx = 0; 
     1228        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxMin; 
     1229        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxGlo; 
     1230        CArray<size_t,1> nodeIdxMinList(nbFaces_*nvertex*4); 
     1231        size_t iIdxMin = 0; 
    13401232 
    13411233        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 
    13421234        { 
    1343           size_t rankMin = (it->second)[1]; 
     1235          size_t idxMin = (it->second)[0]; 
    13441236          size_t idx = (it->second)[0]; 
    13451237          for (int i = 2; i < (it->second).size();) 
    13461238          { 
    1347             if ( (it->second)[i+1] < rankMin) 
     1239            if (mpiRank == (it->second)[i+1]) 
    13481240            { 
    13491241              idx = (it->second)[i]; 
    1350               rankMin = (it->second)[i+1]; 
    1351               (it->second)[i+1] = (it->second)[i-1]; 
     1242            } 
     1243            if ((it->second)[i] < idxMin) 
     1244            { 
     1245                idxMin = (it->second)[i]; 
     1246                (it->second)[i] = (it->second)[i-2]; 
    13521247            } 
    13531248            i += 2; 
    13541249          } 
    1355           if (nodeIdx2Idx.count(idx) == 0) 
    1356           { 
    1357             if (mpiRank == rankMin) 
    1358             { 
    1359               nodeIdx2Idx[idx].push_back(rankMin); 
    1360               nodeIdx2Idx[idx].push_back(idx); 
    1361             } 
    1362             nodeIdxList(nIdx) = idx; 
    1363             ++nIdx; 
    1364           } 
    1365         } 
    1366  
    1367 //        CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2Idx, comm); 
    1368         // CDHTAutoIndexing will not give consistent node numbering for varying number of procs. => 
    1369         // Solution: global node indexing by hand. 
    1370         // Maps modified in this step: 
    1371         // nodeIdx2Idx = <idx, idxGlo> 
    1372         int nodeCount = nodeIdx2Idx.size(); 
    1373         int nodeStart, nbNodes; 
    1374         MPI_Scan(&nodeCount, &nodeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 
    1375         int nNodes = nodeStart; 
    1376         MPI_Bcast(&nNodes, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 
    1377         nbNodesGlo = nNodes; 
    1378  
    1379         nodeStart -= nodeCount; 
    1380         node_start = nodeStart; 
    1381         node_count = nodeCount; 
    1382         CClientClientDHTSizet::Index2VectorInfoTypeMap dummyMap; // just a dummy map used to ensure that each node is numbered only once 
    1383         size_t count = 0; 
    1384  
    1385         for (int nf = 0; nf < nbFaces_; ++nf) 
    1386         { 
    1387           for (int nv = 0; nv < nvertex; ++nv) 
    1388           { 
    1389             vector<size_t> hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 
    1390             size_t nodeIdx = generateNodeIndex(hashValues); 
    1391             CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeIdx2Idx.find(nodeIdx); 
    1392             if (it != nodeIdx2Idx.end()) 
    1393             { 
    1394               if (dummyMap.count(nodeIdx) == 0) 
    1395               { 
    1396                 dummyMap[nodeIdx].push_back(nodeIdx); 
    1397                 (it->second)[1] = node_start + count; 
    1398                 ++count; 
    1399               } 
    1400             } 
    1401           } 
    1402         } 
    1403         nodeIdxList.resizeAndPreserve(nIdx); 
    1404         CClientClientDHTSizet dhtNodeIdx(nodeIdx2Idx, comm); 
    1405         dhtNodeIdx.computeIndexInfoMapping(nodeIdxList); 
    1406         CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdx2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 
     1250          (it->second)[0] = idxMin; 
     1251          if (nodeIdx2IdxMin.count(idx) == 0) 
     1252          { 
     1253            nodeIdx2IdxMin[idx].push_back(idxMin); 
     1254            if (idx == idxMin) 
     1255              nodeIdx2IdxGlo[idxMin].push_back(idxMin); 
     1256            nodeIdxMinList(iIdxMin) = idxMin; 
     1257            ++iIdxMin; 
     1258          } 
     1259        } 
     1260 
     1261        nodeIdxMinList.resizeAndPreserve(iIdxMin); 
     1262        CDHTAutoIndexing dhtNodeIdxGlo = CDHTAutoIndexing(nodeIdx2IdxGlo, comm); 
     1263        CClientClientDHTSizet dhtNodeIdx(nodeIdx2IdxGlo, comm); 
     1264        dhtNodeIdx.computeIndexInfoMapping(nodeIdxMinList); 
     1265        CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeIdxMin2IdxGlo = dhtNodeIdx.getInfoIndexMap(); 
    14071266 
    14081267        // (3.3) Saving node data: node_lon, node_lat, and face_nodes 
    14091268        // Generating edgeHash2Info = <hash, <idx, rank>> and edgeHashList 
    1410 //        nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
    1411 //        node_count = dhtNodeIdxGlo.getIndexCount(); 
    1412 //        node_start = dhtNodeIdxGlo.getIndexStart(); 
     1269        nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
     1270        node_count = dhtNodeIdxGlo.getIndexCount(); 
     1271        node_start = dhtNodeIdxGlo.getIndexStart(); 
    14131272        node_lon.resize(node_count); 
    14141273        node_lat.resize(node_count); 
     
    14271286            vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 
    14281287            vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 
    1429             size_t nodeIdx1 = generateNodeIndex(hashValues1); 
    1430             size_t nodeIdx2 = generateNodeIndex(hashValues2); 
    1431             CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx1 = nodeIdx2IdxGlo.find(nodeIdx1); 
    1432             CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx2 = nodeIdx2IdxGlo.find(nodeIdx2); 
    1433             size_t ownerRank = (itNodeIdx1->second)[0]; 
    1434             nodeIdxGlo1 = (itNodeIdx1->second)[1]; 
    1435             nodeIdxGlo2 = (itNodeIdx2->second)[1]; 
    1436  
    1437             if (mpiRank == ownerRank) 
    1438             { 
     1288            size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 
     1289            size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 
     1290            CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx1 = nodeIdx2IdxMin.find(myNodeIdx1); 
     1291            CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx2 = nodeIdx2IdxMin.find(myNodeIdx2); 
     1292            size_t ownerNodeIdx = (itNodeIdx1->second)[0]; 
     1293 
     1294            if (myNodeIdx1 == ownerNodeIdx) 
     1295            { 
     1296              itNodeIdxGlo1 = nodeIdx2IdxGlo.find(myNodeIdx1); 
     1297              nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 
    14391298              node_lon(nodeIdxGlo1 - node_start) = bounds_lon(nv1, nf); 
    14401299              node_lat(nodeIdxGlo1 - node_start) = bounds_lat(nv1, nf); 
    14411300            } 
     1301            else 
     1302            { 
     1303              itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find(ownerNodeIdx); 
     1304              nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 
     1305            } 
     1306            itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((itNodeIdx2->second)[0]); 
     1307            nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 
    14421308            if (nodeIdxGlo1 != nodeIdxGlo2) 
    14431309            { 
    14441310              size_t edgeHash = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    1445               edgeHash2Idx[edgeHash].push_back(edgeHash); 
     1311              edgeHash2Idx[edgeHash].push_back(generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank)); 
    14461312              edgeHash2Idx[edgeHash].push_back(mpiRank); 
    14471313              edgeHashList(nEdgeHash) = edgeHash; 
     
    14551321        // (3.4) Generating global edge indexes 
    14561322        // Maps generated in this step are: 
    1457         // edgeIdx2Idx = = <idx, <rankOwner, idx>> 
    1458         // edgeIdx2IdxGlo = <idxMin, <rankOwner, idxGlo>> 
     1323        // edgeIdx2IdxMin = = <idx, idxMin> 
     1324        // edgeIdx2IdxGlo = <idxMin, idxGlo> 
    14591325 
    14601326        CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); 
     
    14631329        // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 
    14641330 
    1465         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2Idx; 
     1331        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 
     1332        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 
     1333        CArray<size_t,1> edgeIdxMinList(nbFaces_*nvertex); 
     1334        iIdxMin = 0; 
    14661335 
    14671336        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 
    14681337        { 
    1469           size_t rankMin = (it->second)[1]; 
     1338          size_t idxMin = (it->second)[0]; 
    14701339          size_t idx = (it->second)[0]; 
    14711340 
    14721341          for (int i = 2; i < (it->second).size();) 
    14731342          { 
    1474             if ((it->second)[i+1] < rankMin) 
    1475             { 
    1476               rankMin = (it->second)[i+1]; 
     1343            if (mpiRank == (it->second)[i+1]) 
     1344            { 
    14771345              idx = (it->second)[i]; 
    1478               (it->second)[i+1] = (it->second)[i-1]; 
     1346            } 
     1347            if ((it->second)[i] < idxMin) 
     1348            { 
     1349                idxMin = (it->second)[i]; 
     1350                (it->second)[i] = (it->second)[i-2]; 
    14791351            } 
    14801352            i += 2; 
    14811353          } 
    1482           if (edgeIdx2Idx.count(idx) == 0) 
    1483           { 
    1484             if (mpiRank == rankMin) 
    1485             { 
    1486               edgeIdx2Idx[idx].push_back(rankMin); 
    1487               edgeIdx2Idx[idx].push_back(idx); 
    1488             } 
    1489           } 
    1490         } 
    1491  
    1492         int edgeCount = edgeIdx2Idx.size(); 
    1493         int edgeStart, nbEdges; 
    1494         MPI_Scan(&edgeCount, &edgeStart, 1, MPI_UNSIGNED_LONG, MPI_SUM, comm); 
    1495         int nEdges = edgeStart; 
    1496         MPI_Bcast(&nEdges, 1, MPI_UNSIGNED_LONG, mpiSize-1, comm); 
    1497         nbEdgesGlo = nEdges; 
    1498  
    1499         edgeStart -= edgeCount; 
    1500         edge_start = edgeStart; 
    1501         edge_count = edgeCount; 
    1502         CClientClientDHTSizet::Index2VectorInfoTypeMap dummyEdgeMap; 
    1503         count = 0; 
    1504  
    1505         for (int nf = 0; nf < nbFaces_; ++nf) 
    1506         { 
    1507           for (int nv1 = 0; nv1 < nvertex; ++nv1) 
    1508           { 
    1509             int nv2 = (nv1 < nvertex -1 ) ? (nv1 + 1) : (nv1 + 1 - nvertex); // cyclic rotation 
    1510             vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 
    1511             vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 
    1512             size_t nodeIdx1 = generateNodeIndex(hashValues1); 
    1513             size_t nodeIdx2 = generateNodeIndex(hashValues2); 
    1514             CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx1 = nodeIdx2IdxGlo.find(nodeIdx1); 
    1515             CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdx2 = nodeIdx2IdxGlo.find(nodeIdx2); 
    1516             nodeIdxGlo1 = (itNodeIdx1->second)[1]; 
    1517             nodeIdxGlo2 = (itNodeIdx2->second)[1]; 
    1518  
    1519             if (nodeIdxGlo1 != nodeIdxGlo2) 
    1520             { 
    1521               size_t edgeIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    1522               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeIdx2Idx.find(edgeIdx); 
    1523               if (it != edgeIdx2Idx.end()) 
    1524               { 
    1525                 if (dummyEdgeMap.count(edgeIdx) == 0) 
    1526                 { 
    1527                   dummyEdgeMap[edgeIdx].push_back(edgeIdx); 
    1528                   (it->second)[1] = edge_start + count; 
    1529                   ++count; 
    1530                 } 
    1531               } 
    1532             } 
    1533           } 
    1534         } 
    1535         CClientClientDHTSizet dhtEdgeIdx(edgeIdx2Idx, comm); 
    1536         dhtEdgeIdx.computeIndexInfoMapping(edgeHashList); 
    1537         CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdx2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 
     1354          (it->second)[0] = idxMin; 
     1355          if (edgeIdx2IdxMin.count(idx) == 0) 
     1356          { 
     1357            edgeIdx2IdxMin[idx].push_back(idxMin); 
     1358            if (idx == idxMin) 
     1359              edgeIdx2IdxGlo[idxMin].push_back(idxMin); 
     1360            edgeIdxMinList(iIdxMin) = idxMin; 
     1361            ++iIdxMin; 
     1362          } 
     1363        } 
     1364        edgeIdxMinList.resizeAndPreserve(iIdxMin); 
     1365        CDHTAutoIndexing dhtEdgeIdxGlo = CDHTAutoIndexing(edgeIdx2IdxGlo, comm); 
     1366        CClientClientDHTSizet dhtEdgeIdx(edgeIdx2IdxGlo, comm); 
     1367        dhtEdgeIdx.computeIndexInfoMapping(edgeIdxMinList); 
     1368        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxMin2IdxGlo = dhtEdgeIdx.getInfoIndexMap(); 
    15381369 
    15391370        // (3.5) Saving variables: edge_lon, edge_lat, face_edges 
    15401371        // Creating map edgeIdxGlo2Face <idxGlo, face> 
    1541 //        nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 
    1542 //        edge_count = dhtEdgeIdxGlo.getIndexCount(); 
    1543 //        edge_start = dhtEdgeIdxGlo.getIndexStart(); 
    1544  
     1372 
     1373        nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 
     1374        edge_count = dhtEdgeIdxGlo.getIndexCount(); 
     1375        edge_start = dhtEdgeIdxGlo.getIndexStart(); 
    15451376        edge_lon.resize(edge_count); 
    15461377        edge_lat.resize(edge_count); 
     
    15621393            vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 
    15631394 
    1564             size_t nodeIdx1 = generateNodeIndex(hashValues1); 
    1565             size_t nodeIdx2 = generateNodeIndex(hashValues2); 
    1566             it1 = nodeIdx2IdxGlo.find(nodeIdx1); 
    1567             it2 = nodeIdx2IdxGlo.find(nodeIdx2); 
    1568             size_t nodeIdxGlo1 = (it1->second)[1]; 
    1569             size_t nodeIdxGlo2 = (it2->second)[1]; 
     1395            size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 
     1396            size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 
     1397            it1 = nodeIdx2IdxMin.find(myNodeIdx1); 
     1398            it2 = nodeIdx2IdxMin.find(myNodeIdx2); 
     1399            itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find((it1->second)[0]); 
     1400            itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((it2->second)[0]); 
     1401            size_t nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 
     1402            size_t nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 
    15701403 
    15711404            if (nodeIdxGlo1 != nodeIdxGlo2) 
    15721405            { 
    1573               size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    1574               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 
    1575               int edgeIdxGlo = (itIdx->second)[1]; 
     1406              size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 
     1407              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 
     1408              size_t ownerIdx = (itIdx->second)[0]; 
     1409              int edgeIdxGlo; 
    15761410              size_t faceIdxGlo = nbFacesAccum + nf; 
    15771411 
    1578               if (mpiRank == (itIdx->second)[0]) 
     1412              if (myIdx == ownerIdx) 
    15791413              { 
     1414                CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
     1415                edgeIdxGlo = (itIdxGlo->second)[0]; 
    15801416                double edgeLon; 
    15811417                double diffLon = abs(bounds_lon(nv1, nf) - bounds_lon(nv2, nf)); 
     
    15911427                edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 
    15921428              } 
     1429              else 
     1430              { 
     1431                CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
     1432                edgeIdxGlo = (itIdxGlo->second)[0]; 
     1433              } 
    15931434              face_edges(nv1,nf) = edgeIdxGlo; 
    15941435              if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 
     
    16241465            vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 
    16251466 
    1626             size_t myNodeIdx1 = generateNodeIndex(hashValues1); 
    1627             size_t myNodeIdx2 = generateNodeIndex(hashValues2); 
     1467            size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 
     1468            size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 
    16281469            if (myNodeIdx1 != myNodeIdx2) 
    16291470            { 
    1630               it1 = nodeIdx2IdxGlo.find(myNodeIdx1); 
    1631               it2 = nodeIdx2IdxGlo.find(myNodeIdx2); 
    1632               size_t nodeIdxGlo1 = (it1->second)[1]; 
    1633               size_t nodeIdxGlo2 = (it2->second)[1]; 
    1634               size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    1635               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 
    1636               int edgeIdxGlo = (itIdx->second)[1]; 
    1637  
     1471              it1 = nodeIdx2IdxMin.find(myNodeIdx1); 
     1472              it2 = nodeIdx2IdxMin.find(myNodeIdx2); 
     1473              itNodeIdxGlo1 = nodeIdxMin2IdxGlo.find((it1->second)[0]); 
     1474              itNodeIdxGlo2 = nodeIdxMin2IdxGlo.find((it2->second)[0]); 
     1475              size_t nodeIdxGlo1 = (itNodeIdxGlo1->second)[0]; 
     1476              size_t nodeIdxGlo2 = (itNodeIdxGlo2->second)[0]; 
     1477 
     1478              size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 
     1479              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 
     1480              size_t ownerIdx = (itIdx->second)[0]; 
    16381481              size_t faceIdxGlo = nbFacesAccum + nf; 
    16391482 
    1640               if (mpiRank == (itIdx->second)[0]) 
     1483              if (myIdx == ownerIdx) 
    16411484              { 
     1485                CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
     1486                int edgeIdxGlo = (itIdxGlo->second)[0]; 
    16421487                it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    16431488                int face1 = it1->second[0]; 
     
    16551500                  face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 
    16561501                } 
    1657               } 
     1502              } // myIdx == ownerIdx 
    16581503              else 
    16591504              { 
     1505                CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
     1506                size_t edgeIdxGlo = (itIdxGlo->second)[0]; 
    16601507                it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    16611508                int face1 = it1->second[0]; 
    16621509                int face2 = it1->second[1]; 
    16631510                face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 
    1664               } 
     1511              } // myIdx != ownerIdx 
    16651512            } // myNodeIdx1 != myNodeIdx2 
    16661513            else 
     
    16681515          } 
    16691516        } 
    1670  
    16711517      } 
    16721518      facesAreWritten = true; 
Note: See TracChangeset for help on using the changeset viewer.