Ignore:
Timestamp:
06/06/17 17:58:16 (7 years ago)
Author:
oabramkina
Message:

Two server levels: merging with trunk r1137.
There are bugs.

Location:
XIOS/dev/dev_olga/src/node
Files:
19 edited

Legend:

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

    r1144 r1158  
    2727      , hasBounds_(false), isCompressible_(false) 
    2828      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    29       , transformationMap_(), hasValue(false), doZoomByIndex_(false) 
     29      , transformationMap_(), hasValue(false), doZoomByIndex_(false), hasLabel(false) 
    3030      , computedWrittenIndex_(false) 
    3131   { 
     
    3838      , hasBounds_(false), isCompressible_(false) 
    3939      , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    40       , transformationMap_(), hasValue(false), doZoomByIndex_(false) 
     40      , transformationMap_(), hasValue(false), doZoomByIndex_(false), hasLabel(false) 
    4141      , computedWrittenIndex_(false) 
    4242   { 
     
    5858 
    5959   ///--------------------------------------------------------------- 
     60 
     61   const std::set<StdString> & CAxis::getRelFiles(void) const 
     62   { 
     63      return (this->relFiles); 
     64   } 
     65 
    6066   bool CAxis::IsWritten(const StdString & filename) const 
    6167   { 
     
    7076   bool CAxis::isDistributed(void) const 
    7177   { 
    72       return (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 
    73              (!this->n.isEmpty() && (this->n != this->n_glo));; 
     78      bool distributed = (!this->begin.isEmpty() && !this->n.isEmpty() && (this->begin + this->n < this->n_glo)) || 
     79             (!this->n.isEmpty() && (this->n != this->n_glo)); 
     80      // A same stupid condition to make sure that if there is only one client, axis 
     81      // should be considered to be distributed. This should be a temporary solution      
     82      distributed |= (1 == CContext::getCurrent()->client->clientSize); 
     83      return distributed; 
    7484   } 
    7585 
     
    132142   std::map<int, StdSize> CAxis::getAttributesBufferSize() 
    133143   { 
    134 //     CContextClient* client = CContext::getCurrent()->client; 
    135144     // For now the assumption is that secondary server pools consist of the same number of procs. 
    136145     // CHANGE the line below if the assumption changes. 
     
    172181         if (hasBounds_) 
    173182           sizeValEvent += CArray<double,2>::size(2 * it->second.size()); 
     183  
     184         if (hasLabel) 
     185           sizeValEvent += CArray<StdString,1>::size(it->second.size()); 
    174186 
    175187         size_t size = CEventClient::headerSize + getId().size() + sizeof(size_t) + std::max(sizeIndexEvent, sizeValEvent); 
     
    255267      this->checkZoom(); 
    256268      this->checkMask(); 
    257       this->checkBounds();       
     269      this->checkBounds(); 
     270      this->checkLabel(); 
    258271   } 
    259272 
     
    339352   } 
    340353 
    341    void CAxis::checkEligibilityForCompressedOutput() 
    342    { 
    343      // We don't check if the mask is valid here, just if a mask has been defined at this point. 
    344      isCompressible_ = !mask.isEmpty(); 
    345    } 
     354  void CAxis::checkLabel() 
     355  { 
     356    if (!label.isEmpty()) 
     357    { 
     358      if (label.extent(0) != n) 
     359        ERROR("CAxis::checkLabel(void)", 
     360              << "The label array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension of axis size." << std::endl 
     361              << "Axis size is " << n.getValue() << "." << std::endl 
     362              << "label size is "<< label.extent(0)<<  " ."); 
     363      hasLabel = true; 
     364    } 
     365    else hasLabel = false; 
     366  } 
     367  void CAxis::checkEligibilityForCompressedOutput() 
     368  { 
     369    // We don't check if the mask is valid here, just if a mask has been defined at this point. 
     370    isCompressible_ = !mask.isEmpty(); 
     371  } 
    346372 
    347373   bool CAxis::dispatchEvent(CEventServer& event) 
     
    437463    CContext* context = CContext::getCurrent(); 
    438464 
    439     // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
    440465    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    441466    for (int p = 0; p < nbSrvPools; ++p) 
     
    729754    CContext* context = CContext::getCurrent(); 
    730755 
    731     // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
    732756    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    733757    for (int p = 0; p < nbSrvPools; ++p) 
     
    10711095      } 
    10721096    } 
     1097 
     1098    if (hasLabel) 
     1099    { 
     1100      //label_srv(ind_srv) = labelVal( ind); 
     1101    } 
    10731102  } 
    10741103 
     
    11141143  } 
    11151144 
     1145  /*! 
     1146    Compare two axis objects.  
     1147    They are equal if only if they have identical attributes as well as their values. 
     1148    Moreover, they must have the same transformations. 
     1149  \param [in] axis Compared axis 
     1150  \return result of the comparison 
     1151  */ 
     1152  bool CAxis::isEqual(CAxis* obj) 
     1153  { 
     1154    vector<StdString> excludedAttr; 
     1155    excludedAttr.push_back("axis_ref"); 
     1156 
     1157    bool objEqual = SuperClass::isEqual(obj, excludedAttr);     
     1158    if (!objEqual) return objEqual; 
     1159 
     1160    TransMapTypes thisTrans = this->getAllTransformations(); 
     1161    TransMapTypes objTrans  = obj->getAllTransformations(); 
     1162 
     1163    TransMapTypes::const_iterator it, itb, ite; 
     1164    std::vector<ETranformationType> thisTransType, objTransType; 
     1165    for (it = thisTrans.begin(); it != thisTrans.end(); ++it) 
     1166      thisTransType.push_back(it->first); 
     1167    for (it = objTrans.begin(); it != objTrans.end(); ++it) 
     1168      objTransType.push_back(it->first); 
     1169 
     1170    if (thisTransType.size() != objTransType.size()) return false; 
     1171    for (int idx = 0; idx < thisTransType.size(); ++idx) 
     1172      objEqual &= (thisTransType[idx] == objTransType[idx]); 
     1173 
     1174    return objEqual; 
     1175  } 
    11161176 
    11171177  CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id) 
  • XIOS/dev/dev_olga/src/node/axis.hpp

    r1144 r1158  
    6868 
    6969         static CAxis* createAxis(); 
    70       
     70 
     71         /// Accesseurs /// 
     72         const std::set<StdString> & getRelFiles(void) const; 
     73 
    7174         int getNumberWrittenIndexes() const; 
    7275         int getTotalNumberWrittenIndexes() const; 
     
    115118         void duplicateTransformation(CAxis*); 
    116119         CTransformation<CAxis>* addTransformation(ETranformationType transType, const StdString& id=""); 
     120         bool isEqual(CAxis* axis); 
    117121 
    118122      public: 
     
    121125        CArray<double,1> value_srv; 
    122126        CArray<double,2> bound_srv; 
     127        CArray<StdString,1> label_srv; 
    123128        bool hasValue; 
    124129        CArray<int,1> globalDimGrid; 
     
    131136         void checkMask(); 
    132137         void checkZoom(); 
    133          void checkBounds();          
     138         void checkBounds(); 
     139         void checkLabel(); 
    134140         void sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
    135141                             CServerDistributionDescription::ServerDistributionType distType); 
     
    166172         std::map<int, CArray<int,1> > indiSrv_; 
    167173         bool hasBounds_; 
    168  
     174         bool hasLabel; 
    169175         bool doZoomByIndex_; 
    170176         bool computedWrittenIndex_; 
  • XIOS/dev/dev_olga/src/node/calendar_wrapper.cpp

    r983 r1158  
    8383  { 
    8484    // Create the calendar if possible 
    85     if (0 != calendar) 
     85    if (calendar) 
    8686    { 
    8787      ERROR("CCalendarWrapper::createCalendar(void)", 
  • XIOS/dev/dev_olga/src/node/context.cpp

    r1144 r1158  
    1414#include "type.hpp" 
    1515#include "xios_spl.hpp" 
     16#include "timer.hpp" 
     17#include "memtrack.hpp" 
    1618 
    1719#include "server.hpp" 
     
    372374       comms.push_back(interCommClient); 
    373375     } 
    374      client = new CContextClient(this,intraCommClient,interCommClient,cxtClient); 
     376     client = new CContextClient(this,intraCommClient,interCommClient, cxtClient); 
    375377   } 
    376378 
     
    615617   void CContext::closeDefinition(void) 
    616618   { 
     619    CTimer::get("Context : close definition").resume() ; 
    617620    postProcessingGlobalAttributes(); 
    618621 
     
    640643      if (!hasServer) startPrefetchingOfEnabledReadModeFiles(); 
    641644    } 
     645    CTimer::get("Context : close definition").suspend() ; 
    642646   } 
    643647 
     
    690694       this->enabledFiles[i]->generateNewTransformationGridDest(); 
    691695     } 
    692  
    693696   } 
    694697 
     
    783786   { 
    784787      const std::vector<CFile*> allFiles = CFile::getAll(); 
     788      const CDate& initDate = calendar->getInitDate(); 
    785789 
    786790      for (unsigned int i = 0; i < allFiles.size(); i++) 
     
    788792         { 
    789793            if (allFiles[i]->enabled.getValue()) // Si l'attribut 'enabled' est fixé à vrai. 
     794            { 
     795              if ((initDate + allFiles[i]->output_freq.getValue()) < (initDate + this->getCalendar()->getTimeStep())) 
     796              { 
     797                error(0)<<"WARNING: void CContext::findEnabledFiles()"<<endl 
     798                    << "Output frequency in file \""<<allFiles[i]->getFileOutputName() 
     799                    <<"\" is less than the time step. File will not be written."<<endl; 
     800              } 
     801              else 
    790802               enabledFiles.push_back(allFiles[i]); 
     803            } 
    791804         } 
    792          else enabledFiles.push_back(allFiles[i]); // otherwise true by default 
    793  
     805         else 
     806         { 
     807           if ( (initDate + allFiles[i]->output_freq.getValue()) < (initDate + this->getCalendar()->getTimeStep())) 
     808           { 
     809             error(0)<<"WARNING: void CContext::findEnabledFiles()"<<endl 
     810                 << "Output frequency in file \""<<allFiles[i]->getFileOutputName() 
     811                 <<"\" is less than the time step. File will not be written."<<endl; 
     812           } 
     813           else 
     814             enabledFiles.push_back(allFiles[i]); // otherwise true by default 
     815         } 
    794816 
    795817      if (enabledFiles.size() == 0) 
     
    12671289     StdString fileDefRoot("file_definition"); 
    12681290     CFileGroup* cfgrpPtr = CFileGroup::get(fileDefRoot); 
     1291 
    12691292     for (int i = 0; i < size; ++i) 
    12701293     { 
     
    13131336       CFile* file = allFiles[i]; 
    13141337 
     1338       std::vector<CVariable*> fileVars, fieldVars, vars = file->getAllVariables(); 
     1339       for (size_t k = 0; k < vars.size(); k++) 
     1340       { 
     1341         CVariable* var = vars[k]; 
     1342 
     1343         if (var->ts_target.isEmpty() 
     1344              || var->ts_target == CVariable::ts_target_attr::file || var->ts_target == CVariable::ts_target_attr::both) 
     1345           fileVars.push_back(var); 
     1346 
     1347         if (!var->ts_target.isEmpty() 
     1348              && (var->ts_target == CVariable::ts_target_attr::field || var->ts_target == CVariable::ts_target_attr::both)) 
     1349           fieldVars.push_back(var); 
     1350       } 
     1351 
    13151352       if (!file->timeseries.isEmpty() && file->timeseries != CFile::timeseries_attr::none) 
    13161353       { 
    1317          StdString tsPrefix = !file->ts_prefix.isEmpty() ? file->ts_prefix : file->getFileOutputName(); 
    1318  
     1354         StdString fileNameStr("%file_name%") ; 
     1355         StdString tsPrefix = !file->ts_prefix.isEmpty() ? file->ts_prefix : fileNameStr ; 
     1356          
     1357         StdString fileName=file->getFileOutputName(); 
     1358         size_t pos=tsPrefix.find(fileNameStr) ; 
     1359         while (pos!=std::string::npos) 
     1360         { 
     1361           tsPrefix=tsPrefix.replace(pos,fileNameStr.size(),fileName) ; 
     1362           pos=tsPrefix.find(fileNameStr) ; 
     1363         } 
     1364         
    13191365         const std::vector<CField*> allFields = file->getAllFields(); 
    13201366         for (size_t j = 0; j < allFields.size(); j++) 
     
    13261372             CFile* tsFile = CFile::create(); 
    13271373             tsFile->duplicateAttributes(file); 
    1328              tsFile->setVirtualVariableGroup(file->getVirtualVariableGroup()); 
    1329  
     1374 
     1375             // Add variables originating from file and targeted to timeserie file 
     1376             for (size_t k = 0; k < fileVars.size(); k++) 
     1377               tsFile->getVirtualVariableGroup()->addChild(fileVars[k]); 
     1378 
     1379             
    13301380             tsFile->name = tsPrefix + "_"; 
    13311381             if (!field->name.isEmpty()) 
     
    13411391             CField* tsField = tsFile->addField(); 
    13421392             tsField->field_ref = field->getId(); 
    1343              tsField->setVirtualVariableGroup(field->getVirtualVariableGroup()); 
     1393 
     1394             // Add variables originating from file and targeted to timeserie field 
     1395             for (size_t k = 0; k < fieldVars.size(); k++) 
     1396               tsField->getVirtualVariableGroup()->addChild(fieldVars[k]); 
     1397 
     1398             vars = field->getAllVariables(); 
     1399             for (size_t k = 0; k < vars.size(); k++) 
     1400             { 
     1401               CVariable* var = vars[k]; 
     1402 
     1403               // Add variables originating from field and targeted to timeserie field 
     1404               if (var->ts_target.isEmpty() 
     1405                    || var->ts_target == CVariable::ts_target_attr::field || var->ts_target == CVariable::ts_target_attr::both) 
     1406                 tsField->getVirtualVariableGroup()->addChild(var); 
     1407 
     1408               // Add variables originating from field and targeted to timeserie file 
     1409               if (!var->ts_target.isEmpty() 
     1410                    && (var->ts_target == CVariable::ts_target_attr::file || var->ts_target == CVariable::ts_target_attr::both)) 
     1411                 tsFile->getVirtualVariableGroup()->addChild(var); 
     1412             } 
    13441413 
    13451414             tsFile->solveFieldRefInheritance(true); 
     
    14561525   void CContext::updateCalendar(int step) 
    14571526   { 
    1458       info(50) <<"Context "<< this->getId() <<" updateCalendar : before : " << calendar->getCurrentDate() << endl; 
     1527      info(50) << "updateCalendar : before : " << calendar->getCurrentDate() << endl; 
    14591528      calendar->update(step); 
    1460       info(50) <<"Context "<< this->getId() << " updateCalendar : after : " << calendar->getCurrentDate() << endl; 
    1461  
     1529      info(50) << "updateCalendar : after : " << calendar->getCurrentDate() << endl; 
     1530#ifdef XIOS_MEMTRACK_LIGHT 
     1531      info(50) << " Current memory used by XIOS : "<<  MemTrack::getCurrentMemorySize()*1.0/(1024*1024)<<" Mbyte, at timestep "<<step<<" of context "<<this->getId()<<endl ; 
     1532#endif 
    14621533      if (hasClient) 
    14631534      { 
     
    15371608 
    15381609  void CContext::sendRegistry(void) 
    1539   {     
     1610  { 
    15401611    registryOut->hierarchicalGatherRegistry() ; 
    15411612 
  • XIOS/dev/dev_olga/src/node/domain.cpp

    r1144 r1158  
    2626namespace xios { 
    2727 
    28    /// ////////////////////// Dfinitions ////////////////////// /// 
     28   /// ////////////////////// Définitions ////////////////////// /// 
    2929 
    3030   CDomain::CDomain(void) 
     
    7979   } 
    8080 
     81   const std::set<StdString> & CDomain::getRelFiles(void) const 
     82   { 
     83      return (this->relFiles); 
     84   } 
     85 
     86 
    8187   /*! 
    8288     Returns the number of indexes written by each server. 
     
    170176   { 
    171177      return ((this->zoom_i_index.isEmpty()) || (0 == this->zoom_i_index.numElements())); 
    172       // return ((this->zoom_ni_srv == 0) || 
    173       //         (this->zoom_nj_srv == 0)); 
     178 
    174179   } 
    175180 
     
    190195   bool CDomain::isDistributed(void) const 
    191196   { 
    192       return !((!ni.isEmpty() && (ni == ni_glo) && !nj.isEmpty() && (nj == nj_glo)) || 
     197      bool distributed = !((!ni.isEmpty() && (ni == ni_glo) && !nj.isEmpty() && (nj == nj_glo)) || 
    193198              (!i_index.isEmpty() && i_index.numElements() == ni_glo*nj_glo)); 
     199      distributed |= (1 == CContext::getCurrent()->client->clientSize); 
     200 
     201      return distributed; 
    194202   } 
    195203 
     
    221229 
    222230   //---------------------------------------------------------------- 
     231 
     232   /*! 
     233      Verify if all distribution information of a domain are available 
     234      This checking verifies the definition of distribution attributes (ni, nj, ibegin, jbegin) 
     235   */ 
     236   bool CDomain::distributionAttributesHaveValue() const 
     237   { 
     238      bool hasValues = true; 
     239 
     240      if (ni.isEmpty() && ibegin.isEmpty() && i_index.isEmpty()) 
     241      { 
     242        hasValues = false; 
     243        return hasValues; 
     244      } 
     245 
     246      return hasValues; 
     247   } 
    223248 
    224249   /*! 
     
    331356            ni.setValue(ni_glo - ibeginVec[iIdx]); 
    332357          } 
    333         } 
    334  
    335         // Now fill other attributes 
    336         if (type_attr::rectilinear == type) fillInRectilinearLonLat(); 
     358        }  
    337359     } 
    338360     else  // unstructured domain 
     
    380402            nj.setValue(1); 
    381403          } 
     404 
     405          i_index.resize(ni);           
     406          for(int idx = 0; idx < ni; ++idx) i_index(idx)=ibegin+idx; 
    382407        } 
    383408        else 
     
    391416 
    392417     checkDomain(); 
     418   } 
     419 
     420   /*! 
     421     Fill in longitude and latitude whose values are read from file 
     422   */ 
     423   void CDomain::fillInLonLat() 
     424   { 
     425     switch (type) 
     426     { 
     427      case type_attr::rectilinear: 
     428        fillInRectilinearLonLat(); 
     429        break; 
     430      case type_attr::curvilinear: 
     431        fillInCurvilinearLonLat(); 
     432        break; 
     433      case type_attr::unstructured: 
     434        fillInUnstructuredLonLat(); 
     435        break; 
     436 
     437      default: 
     438      break; 
     439     } 
     440 
    393441   } 
    394442 
     
    468516   } 
    469517 
    470  
    471  
     518    /* 
     519      Fill in longitude and latitude of curvilinear domain read from a file 
     520      If there are already longitude and latitude defined by model. We just igonore reading value. 
     521    */ 
     522   void CDomain::fillInCurvilinearLonLat() 
     523   { 
     524     if (!lonvalue_curvilinear_read_from_file.isEmpty() && lonvalue_2d.isEmpty()) 
     525     { 
     526       lonvalue_2d.resize(ni,nj); 
     527       for (int jdx = 0; jdx < nj; ++jdx) 
     528        for (int idx = 0; idx < ni; ++idx) 
     529         lonvalue_2d(idx,jdx) = lonvalue_curvilinear_read_from_file(idx+ibegin, jdx+jbegin); 
     530 
     531       lonvalue_curvilinear_read_from_file.free(); 
     532     } 
     533 
     534     if (!latvalue_curvilinear_read_from_file.isEmpty() && latvalue_2d.isEmpty()) 
     535     { 
     536       latvalue_2d.resize(ni,nj); 
     537       for (int jdx = 0; jdx < nj; ++jdx) 
     538        for (int idx = 0; idx < ni; ++idx) 
     539         latvalue_2d(idx,jdx) = latvalue_curvilinear_read_from_file(idx+ibegin, jdx+jbegin); 
     540 
     541       latvalue_curvilinear_read_from_file.free(); 
     542     } 
     543 
     544     if (!bounds_lonvalue_curvilinear_read_from_file.isEmpty() && bounds_lon_2d.isEmpty()) 
     545     { 
     546       bounds_lon_2d.resize(nvertex,ni,nj); 
     547       for (int jdx = 0; jdx < nj; ++jdx) 
     548        for (int idx = 0; idx < ni; ++idx) 
     549          for (int ndx = 0; ndx < nvertex; ++ndx) 
     550         bounds_lon_2d(ndx,idx,jdx) = bounds_lonvalue_curvilinear_read_from_file(ndx,idx+ibegin, jdx+jbegin); 
     551 
     552       bounds_lonvalue_curvilinear_read_from_file.free(); 
     553     } 
     554 
     555     if (!bounds_latvalue_curvilinear_read_from_file.isEmpty() && bounds_lat_2d.isEmpty()) 
     556     { 
     557       bounds_lat_2d.resize(nvertex,ni,nj); 
     558       for (int jdx = 0; jdx < nj; ++jdx) 
     559        for (int idx = 0; idx < ni; ++idx) 
     560          for (int ndx = 0; ndx < nvertex; ++ndx) 
     561            bounds_lat_2d(ndx,idx,jdx) = bounds_latvalue_curvilinear_read_from_file(ndx,idx+ibegin, jdx+jbegin); 
     562 
     563       bounds_latvalue_curvilinear_read_from_file.free(); 
     564     } 
     565 
     566   } 
     567 
     568    /* 
     569      Fill in longitude and latitude of unstructured domain read from a file 
     570      If there are already longitude and latitude defined by model. We just igonore reading value. 
     571    */ 
     572   void CDomain::fillInUnstructuredLonLat() 
     573   { 
     574     if (i_index.isEmpty()) 
     575     { 
     576       i_index.resize(ni); 
     577       for(int idx = 0; idx < ni; ++idx) i_index(idx)=ibegin+idx; 
     578     } 
     579 
     580     if (!lonvalue_unstructured_read_from_file.isEmpty() && lonvalue_1d.isEmpty()) 
     581     { 
     582        lonvalue_1d.resize(ni); 
     583        for (int idx = 0; idx < ni; ++idx) 
     584          lonvalue_1d(idx) = lonvalue_unstructured_read_from_file(i_index(idx)); 
     585 
     586        // We dont need these values anymore, so just delete them 
     587        lonvalue_unstructured_read_from_file.free(); 
     588     }  
     589 
     590     if (!latvalue_unstructured_read_from_file.isEmpty() && latvalue_1d.isEmpty()) 
     591     { 
     592        latvalue_1d.resize(ni); 
     593        for (int idx = 0; idx < ni; ++idx) 
     594          latvalue_1d(idx) =  latvalue_unstructured_read_from_file(i_index(idx)); 
     595 
     596        // We dont need these values anymore, so just delete them 
     597        latvalue_unstructured_read_from_file.free(); 
     598     } 
     599 
     600     if (!bounds_lonvalue_unstructured_read_from_file.isEmpty() && bounds_lon_1d.isEmpty()) 
     601     { 
     602        int nbVertex = nvertex; 
     603        bounds_lon_1d.resize(nbVertex,ni); 
     604        for (int idx = 0; idx < ni; ++idx) 
     605          for (int jdx = 0; jdx < nbVertex; ++jdx) 
     606            bounds_lon_1d(jdx,idx) = bounds_lonvalue_unstructured_read_from_file(jdx, i_index(idx)); 
     607 
     608        // We dont need these values anymore, so just delete them 
     609        lonvalue_unstructured_read_from_file.free(); 
     610     } 
     611 
     612     if (!bounds_latvalue_unstructured_read_from_file.isEmpty() && bounds_lat_1d.isEmpty()) 
     613     { 
     614        int nbVertex = nvertex; 
     615        bounds_lat_1d.resize(nbVertex,ni); 
     616        for (int idx = 0; idx < ni; ++idx) 
     617          for (int jdx = 0; jdx < nbVertex; ++jdx) 
     618            bounds_lat_1d(jdx,idx) = bounds_latvalue_unstructured_read_from_file(jdx, i_index(idx)); 
     619 
     620        // We dont need these values anymore, so just delete them 
     621        lonvalue_unstructured_read_from_file.free(); 
     622     } 
     623   } 
     624 
     625  /* 
     626    Get global longitude and latitude of rectilinear domain. 
     627  */ 
    472628   void CDomain::AllgatherRectilinearLonLat(CArray<double,1>& lon, CArray<double,1>& lat, CArray<double,1>& lon_g, CArray<double,1>& lat_g) 
    473629   { 
     
    590746    else 
    591747    { 
    592       if (bounds_lat_start.isEmpty()) bounds_lon_start=-90. ; 
     748      if (bounds_lat_start.isEmpty()) bounds_lat_start=-90. ; 
    593749      if (bounds_lat_end.isEmpty()) bounds_lat_end=90 ; 
    594750    } 
     
    695851       for (int j = 0; j < nj; ++j) 
    696852         for (int i = 0; i < ni; ++i) j_index(i+j*ni) = j+jbegin; 
    697      }      
     853     } 
     854      
    698855     checkZoom(); 
    699856   } 
     
    14311588     if (context->hasClient) 
    14321589     { 
    1433        // this->checkMask(); 
    14341590      this->computeConnectedClients(); 
    1435        // if (hasLonLat || hasArea || isCompressible_) this->computeConnectedClients(); 
    14361591       if (hasLonLat) 
    14371592         if (!context->hasServer) 
     
    14821637     if (context->hasClient) 
    14831638     { 
    1484 //       this->completeLonLatClient(); 
    14851639       sendAttributes(); 
    14861640     } 
     
    26942848  } 
    26952849 
    2696  
    26972850  /*! 
    26982851    Receive area information from client(s) 
     
    27422895       
    27432896    } 
     2897  } 
     2898 
     2899  /*! 
     2900    Compare two domain objects.  
     2901    They are equal if only if they have identical attributes as well as their values. 
     2902    Moreover, they must have the same transformations. 
     2903  \param [in] domain Compared domain 
     2904  \return result of the comparison 
     2905  */ 
     2906  bool CDomain::isEqual(CDomain* obj) 
     2907  { 
     2908    vector<StdString> excludedAttr; 
     2909    excludedAttr.push_back("domain_ref"); 
     2910    bool objEqual = SuperClass::isEqual(obj, excludedAttr); 
     2911    if (!objEqual) return objEqual; 
     2912 
     2913    TransMapTypes thisTrans = this->getAllTransformations(); 
     2914    TransMapTypes objTrans  = obj->getAllTransformations(); 
     2915 
     2916    TransMapTypes::const_iterator it, itb, ite; 
     2917    std::vector<ETranformationType> thisTransType, objTransType; 
     2918    for (it = thisTrans.begin(); it != thisTrans.end(); ++it) 
     2919      thisTransType.push_back(it->first); 
     2920    for (it = objTrans.begin(); it != objTrans.end(); ++it) 
     2921      objTransType.push_back(it->first); 
     2922 
     2923    if (thisTransType.size() != objTransType.size()) return false; 
     2924    for (int idx = 0; idx < thisTransType.size(); ++idx) 
     2925      objEqual &= (thisTransType[idx] == objTransType[idx]); 
     2926 
     2927    return objEqual; 
    27442928  } 
    27452929 
  • XIOS/dev/dev_olga/src/node/domain.hpp

    r1144 r1158  
    4242      , public CDomainAttributes 
    4343   { 
    44                /// typedef /// 
    45          typedef CObjectTemplate<CDomain>   SuperClass; 
    46          typedef CDomainAttributes SuperClassAttribute; 
    47           
    48       public : 
     44     /// typedef /// 
     45     typedef CObjectTemplate<CDomain>   SuperClass; 
     46     typedef CDomainAttributes SuperClassAttribute; 
     47     public: 
    4948         enum EEventId 
    5049         { 
     
    9190         CTransformation<CDomain>* addTransformation(ETranformationType transType, const StdString& id=""); 
    9291 
    93       public:          
     92      public: 
     93         const std::set<StdString> & getRelFiles(void) const; 
    9494         bool IsWritten(const StdString & filename) const; 
    9595         bool isWrittenCompressed(const StdString& filename) const; 
     
    116116         vector< vector<int> > i_indSrv ; // for each server, i global index to send 
    117117         vector< vector<int> > j_indSrv ; // for each server, j global index to send 
    118  
     118         std::vector<int> getNbGlob(); 
     119         bool isEqual(CDomain* domain); 
    119120      public: 
    120121         /// Mutateur /// 
     
    130131         void fillInRectilinearBoundLonLat(CArray<double,1>& lon, CArray<double,1>& lat, 
    131132                                           CArray<double,2>& boundsLon, CArray<double,2>& boundsLat); 
    132          void fillInRectilinearLonLat(); 
     133          
     134         void fillInLonLat(); 
     135         bool distributionAttributesHaveValue() const; 
    133136 
    134137         static bool dispatchEvent(CEventServer& event); 
     
    157160         static StdString GetName(void); 
    158161         static StdString GetDefName(void); 
    159          static ENodeType GetType(void);    
    160  
     162 
     163         static ENodeType GetType(void); 
     164         const std::map<int, vector<size_t> >& getIndexServer() const; 
    161165         CArray<bool, 1> localMask; 
    162166         bool isCurvilinear ; 
     
    182186 
    183187         void setTransformations(const TransMapTypes&);          
    184  
     188         void computeNGlobDomain(); 
    185189         void sendAttributes(); 
    186190         void sendIndex(); 
     
    192196         void sendDataIndex(); 
    193197         void convertLonLatValue(); 
    194  
     198         void fillInRectilinearLonLat(); 
     199         void fillInCurvilinearLonLat(); 
     200         void fillInUnstructuredLonLat(); 
    195201       private:          
    196202         bool doZoomByIndex_; 
  • XIOS/dev/dev_olga/src/node/expand_domain.cpp

    r941 r1158  
    3838  void CExpandDomain::checkValid(CDomain* domainDst) 
    3939  { 
    40     if (CDomain::type_attr::unstructured != domainDst->type) 
    41     { 
    42       ERROR("CExpandDomain::checkValid(CDomain* domainDst)", 
    43             << "Domain extension is only supported for unstructured" << std::endl 
    44             << "Check type of domain destination, id = " << domainDst->getId()); 
    45     } 
     40    // if (CDomain::type_attr::unstructured != domainDst->type) 
     41    // { 
     42    //   ERROR("CExpandDomain::checkValid(CDomain* domainDst)", 
     43    //         << "Domain extension is only supported for unstructured" << std::endl 
     44    //         << "Check type of domain destination, id = " << domainDst->getId()); 
     45    // } 
    4646 
    4747    if (this->type.isEmpty()) this->type.setValue(CExpandDomain::type_attr::edge); 
  • XIOS/dev/dev_olga/src/node/field.cpp

    r1144 r1158  
    3838      , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false) 
    3939      , useCompressedOutput(false) 
     40      , hasTimeInstant(false) 
     41      , hasTimeCentered(false) 
    4042      , wasDataAlreadyReceivedFromServer(false) 
     43      , isEOF(false) 
    4144   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
    4245 
     
    5053      , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false) 
    5154      , useCompressedOutput(false) 
     55      , hasTimeInstant(false) 
     56      , hasTimeCentered(false) 
    5257      , wasDataAlreadyReceivedFromServer(false) 
     58      , isEOF(false) 
    5359   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
    5460 
     
    122128  void CField::sendUpdateData(const CArray<double,1>& data) 
    123129  { 
    124     CTimer::get("XIOS Send Data").resume(); 
     130    CTimer::get("Field : send data").resume(); 
    125131 
    126132    CContext* context = CContext::getCurrent(); 
     
    174180      }     
    175181 
    176     CTimer::get("XIOS Send Data").suspend(); 
     182    CTimer::get("Field : send data").suspend(); 
    177183  } 
    178184 
     
    183189    list<CEventServer::SSubEvent>::iterator it; 
    184190    string fieldId; 
    185  
     191    CTimer::get("Field : recv data").resume(); 
    186192    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    187193    { 
     
    192198    } 
    193199    get(fieldId)->recvUpdateData(rankBuffers); 
     200    CTimer::get("Field : recv data").suspend(); 
    194201  } 
    195202 
     
    252259    } 
    253260  } 
    254    
    255 //   void  CField::recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers) 
    256 //   { 
    257 //     CContext* context = CContext::getCurrent(); 
    258  
    259 //     if (data_srv.empty()) 
    260 //     { 
    261 //       for (map<int, CArray<size_t, 1> >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it) 
    262 //       { 
    263 //         int rank = it->first; 
    264 //         data_srv.insert(std::make_pair(rank, CArray<double,1>(it->second.numElements()))); 
    265 //         foperation_srv.insert(pair<int,boost::shared_ptr<func::CFunctor> >(rank,boost::shared_ptr<func::CFunctor>(new func::CInstant(data_srv[rank])))); 
    266 //       } 
    267 //     } 
    268  
    269 //     const CDate& currDate = context->getCalendar()->getCurrentDate(); 
    270 //     const CDate opeDate      = last_operation_srv +freq_op + freq_operation_srv - freq_op; 
    271 //     const CDate writeDate    = last_Write_srv     + freq_write_srv; 
    272  
    273 //     if (opeDate <= currDate) 
    274 //     { 
    275 //       for (int n = 0; n < ranks.size(); n++) 
    276 //       { 
    277 //         CArray<double,1> data_tmp; 
    278 //         *buffers[n] >> data_tmp; 
    279 //         (*foperation_srv[ranks[n]])(data_tmp); 
    280 //       } 
    281 //       last_operation_srv = currDate; 
    282 //     } 
    283  
    284 //     if (writeDate < (currDate + freq_operation_srv)) 
    285 //     { 
    286 //       for (int n = 0; n < ranks.size(); n++) 
    287 //       { 
    288 //         this->foperation_srv[ranks[n]]->final(); 
    289 //       } 
    290  
    291 //       last_Write_srv = writeDate; 
    292 //     } 
    293  
    294 //     if (context->hasClient && context->hasServer) 
    295 //     { 
    296 //       size_t writtenSize; 
    297 // //      if (field->getUseCompressedOutput()) 
    298 // //        writtenSize = grid->getNumberWrittenIndexes(); 
    299 // //      else 
    300 //         writtenSize = grid->getWrittenDataSize(); 
    301  
    302 //       CArray<double,1> fieldData(writtenSize); 
    303 // //      if (!field->default_value.isEmpty()) fieldData = field->default_value; 
    304  
    305 // //      if (field->getUseCompressedOutput()) 
    306 // //        field->outputCompressedField(fieldData); 
    307 // //      else 
    308 //         this->outputField(fieldData); 
    309 //       sendUpdateData(fieldData); 
    310 //     } 
    311 //     if (!context->hasClient && context->hasServer) 
    312 //     { 
    313 //       writeField(); 
    314 //     } 
    315  
    316 //     lastlast_Write_srv = last_Write_srv; 
    317  
    318 //   } 
    319261 
    320262  void CField::writeField(void) 
     
    331273  } 
    332274 
    333   void CField::sendReadDataRequest(const CDate& tsDataRequested) 
     275  bool CField::sendReadDataRequest(const CDate& tsDataRequested) 
    334276  { 
    335277    CContext* context = CContext::getCurrent(); 
     
    339281    lastDataRequestedFromServer = tsDataRequested; 
    340282 
    341     CEventClient event(getType(), EVENT_ID_READ_DATA); 
    342     if (client->isServerLeader()) 
     283    if (!isEOF) // No need to send the request if we already know we are at EOF 
    343284    { 
    344       CMessage msg; 
    345       msg << getId(); 
    346       const std::list<int>& ranks = client->getRanksServerLeader(); 
    347       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    348         event.push(*itRank, 1, msg); 
    349       client->sendEvent(event); 
    350     } 
    351     else client->sendEvent(event); 
     285      CEventClient event(getType(), EVENT_ID_READ_DATA); 
     286      if (client->isServerLeader()) 
     287      { 
     288        CMessage msg; 
     289        msg << getId(); 
     290        const std::list<int>& ranks = client->getRanksServerLeader(); 
     291        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     292          event.push(*itRank, 1, msg); 
     293        client->sendEvent(event); 
     294      } 
     295      else client->sendEvent(event); 
     296    } 
     297    else 
     298      serverSourceFilter->signalEndOfStream(tsDataRequested); 
     299 
     300    return !isEOF; 
    352301  } 
    353302 
     
    361310 
    362311    bool dataRequested = false; 
     312 
    363313    while (currentDate >= lastDataRequestedFromServer) 
    364314    { 
     
    368318      info(20) << "lastDataRequestedFromServer + file->output_freq.getValue() : " << lastDataRequestedFromServer + file->output_freq << endl ; 
    369319 
    370       sendReadDataRequest(lastDataRequestedFromServer + file->output_freq); 
    371  
    372       dataRequested = true; 
    373     } 
     320      dataRequested |= sendReadDataRequest(lastDataRequestedFromServer + file->output_freq); 
     321    } 
     322 
    374323    return dataRequested; 
    375324  } 
     
    386335  { 
    387336    CContext* context = CContext::getCurrent(); 
    388     CContextClient* client = context->client;     
     337    CContextClient* client = context->client; 
    389338 
    390339    CEventClient event(getType(), EVENT_ID_READ_DATA_READY); 
     
    393342    bool hasData = readField(); 
    394343 
    395      
     344    map<int, CArray<double,1> >::iterator it; 
    396345    if (!grid->doGridHaveDataDistributed()) 
    397346    { 
     
    413362            } 
    414363          } 
    415  
    416364          client->sendEvent(event); 
    417365       } 
     
    500448    std::map<int, CArray<double,1> > data; 
    501449 
    502     bool isEOF = false; 
    503  
    504450    for (int i = 0; i < ranks.size(); i++) 
    505451    { 
     
    585531   //---------------------------------------------------------------- 
    586532 
    587    bool CField::isActive(void) const 
    588    { 
    589       return (instantDataFilter != NULL); 
     533   bool CField::isActive(bool atCurrentTimestep /*= false*/) const 
     534   { 
     535      if (clientSourceFilter) 
     536        return atCurrentTimestep ? clientSourceFilter->isDataExpected(CContext::getCurrent()->getCalendar()->getCurrentDate()) : true; 
     537      else if (storeFilter) 
     538        return true; 
     539      else if (instantDataFilter) 
     540        ERROR("bool CField::isActive(bool atCurrentTimestep)", 
     541              << "Impossible to check if field [ id = " << getId() << " ] is active as it cannot be used to receive nor send data."); 
     542 
     543      return false; 
    590544   } 
    591545 
     
    815769          if (hasDirectFieldReference()) getDirectFieldReference()->solveAllReferenceEnabledField(false); 
    816770        } 
    817        else if (context->hasServer)         
     771        else if (context->hasServer) 
    818772          solveServerOperation(); 
    819773 
     
    940894       { 
    941895         // Check if we have an expression to parse 
    942        if (hasExpression()) 
     896         if (hasExpression()) 
    943897         { 
    944          boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0')); 
    945          boost::shared_ptr<COutputPin> filter = expr->reduce(gc, *this); 
    946  
    947          // Check if a spatial transformation is needed 
    948          if (!field_ref.isEmpty()) 
    949          { 
    950            CGrid* gridRef = CField::get(field_ref)->grid; 
    951  
    952            if (grid && grid != gridRef && grid->hasTransform()) 
     898           boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0')); 
     899           boost::shared_ptr<COutputPin> filter = expr->reduce(gc, *this); 
     900 
     901           // Check if a spatial transformation is needed 
     902           if (!field_ref.isEmpty()) 
    953903           { 
    954              double defaultValue = !default_value.isEmpty() ? default_value : 0.0; 
    955              std::pair<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, defaultValue); 
    956  
    957              filter->connectOutput(filters.first, 0); 
    958              filter = filters.second; 
     904             CGrid* gridRef = CField::get(field_ref)->grid; 
     905 
     906             if (grid && grid != gridRef && grid->hasTransform()) 
     907             { 
     908               bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
     909               double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
     910               std::pair<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, hasMissingValue, defaultValue); 
     911 
     912               filter->connectOutput(filters.first, 0); 
     913               filter = filters.second; 
     914             } 
    959915           } 
    960          } 
    961  
    962          instantDataFilter = filter; 
     916 
     917           instantDataFilter = filter; 
    963918         } 
    964919         // Check if we have a reference on another field 
     
    967922         // Check if the data is to be read from a file 
    968923         else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read) 
    969          instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, 
    970                                                                                                      freq_offset.isEmpty() ? NoneDu : freq_offset, 
    971                                                                                                      true)); 
     924           instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, 
     925                                                                                                       freq_offset.isEmpty() ? NoneDu : freq_offset, 
     926                                                                                                       true)); 
    972927         else // The data might be passed from the model 
    973          instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid)); 
    974        } 
    975  
    976        // If the field data is to be read by the client or/and written to a file 
    977        if (enableOutput && !storeFilter && !fileWriterFilter) 
    978        { 
    979          if (!read_access.isEmpty() && read_access) 
    980928         { 
    981            storeFilter = boost::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid)); 
    982            instantDataFilter->connectOutput(storeFilter, 0); 
     929            bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
     930            double defaultValue  = ignoreMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
     931            instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, NoneDu, false, 
     932                                                                                                        ignoreMissingValue, defaultValue)); 
    983933         } 
    984  
    985          if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write)) 
    986          { 
    987            fileWriterFilter = boost::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this)); 
    988            getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0); 
    989          } 
    990        } 
    991      } 
    992    } 
    993  
     934       } 
     935     } 
     936 
     937     // If the field data is to be read by the client or/and written to a file 
     938     if (enableOutput && !storeFilter && !fileWriterFilter) 
     939     { 
     940       if (!read_access.isEmpty() && read_access) 
     941       { 
     942         storeFilter = boost::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid)); 
     943         instantDataFilter->connectOutput(storeFilter, 0); 
     944       } 
     945 
     946       if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write)) 
     947       { 
     948         fileWriterFilter = boost::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this)); 
     949         getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0); 
     950       } 
     951     } 
     952   } 
    994953 
    995954   /*! 
     
    1000959    * \return the output pin corresponding to the field reference 
    1001960    */ 
    1002      boost::shared_ptr<COutputPin> CField::getFieldReference(CGarbageCollector& gc) 
    1003      { 
    1004        if (instantDataFilter || field_ref.isEmpty()) 
    1005          ERROR("COutputPin* CField::getFieldReference(CGarbageCollector& gc)", 
    1006                "Impossible to get the field reference for a field which has already been parsed or which does not have a field_ref."); 
    1007  
    1008        CField* fieldRef = CField::get(field_ref); 
    1009        fieldRef->buildFilterGraph(gc, false); 
    1010  
    1011        std::pair<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters; 
    1012        // Check if a spatial transformation is needed 
    1013        if (grid && grid != fieldRef->grid && grid->hasTransform()) 
    1014        { 
    1015          double defaultValue = !default_value.isEmpty() ? default_value : 0.0; 
    1016          filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, defaultValue); 
    1017        } 
    1018        else 
    1019          filters.first = filters.second = boost::shared_ptr<CFilter>(new CPassThroughFilter(gc)); 
    1020  
    1021        fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0); 
    1022  
    1023        return filters.second; 
    1024      } 
     961   boost::shared_ptr<COutputPin> CField::getFieldReference(CGarbageCollector& gc) 
     962   { 
     963     if (instantDataFilter || field_ref.isEmpty()) 
     964       ERROR("COutputPin* CField::getFieldReference(CGarbageCollector& gc)", 
     965             "Impossible to get the field reference for a field which has already been parsed or which does not have a field_ref."); 
     966 
     967     CField* fieldRef = CField::get(field_ref); 
     968     fieldRef->buildFilterGraph(gc, false); 
     969 
     970     std::pair<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters; 
     971     // Check if a spatial transformation is needed 
     972     if (grid && grid != fieldRef->grid && grid->hasTransform()) 
     973     {        
     974       bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
     975       double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);                                 
     976       filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue); 
     977     } 
     978     else 
     979       filters.first = filters.second = boost::shared_ptr<CFilter>(new CPassThroughFilter(gc)); 
     980 
     981     fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0); 
     982 
     983     return filters.second; 
     984   } 
    1025985 
    1026986   /*! 
     
    10581018       { 
    10591019         if (!clientSourceFilter) 
    1060            clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid)); 
     1020         { 
     1021           bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
     1022           double defaultValue  = ignoreMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);  
     1023           clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, NoneDu, false, 
     1024                                                                                   ignoreMissingValue, defaultValue)); 
     1025         } 
    10611026 
    10621027         selfReferenceFilter = clientSourceFilter; 
     
    11041069     return it->second; 
    11051070   } 
     1071 
     1072  /*! 
     1073    * Returns the temporal filter corresponding to the field's temporal operation 
     1074    * for the specified operation frequency. 
     1075    * 
     1076    * \param gc the garbage collector to use 
     1077    * \param outFreq the operation frequency, i.e. the frequency at which the output data will be computed 
     1078    * \return the output pin corresponding to the requested temporal filter 
     1079    */ 
     1080    
     1081   boost::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq) 
     1082   { 
     1083     if (instantDataFilter || !hasExpression()) 
     1084       ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)", 
     1085             "Impossible to add a self reference to a field which has already been parsed or which does not have an expression."); 
     1086 
     1087     if (!selfReferenceFilter) getSelfReference(gc) ; 
     1088 
     1089     if (serverSourceFilter || clientSourceFilter) 
     1090     { 
     1091       if (operation.isEmpty()) 
     1092         ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)", 
     1093               << "An operation must be defined for field \"" << getId() << "\"."); 
     1094 
     1095       if (freq_op.isEmpty()) freq_op.setValue(TimeStep); 
     1096       if (freq_offset.isEmpty()) freq_offset.setValue(NoneDu); 
     1097 
     1098       const bool ignoreMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
     1099 
     1100       boost::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 
     1101                                                                             CContext::getCurrent()->getCalendar()->getInitDate(), 
     1102                                                                             freq_op, freq_offset, outFreq, 
     1103                                                                             ignoreMissingValue, ignoreMissingValue ? default_value : 0.0)); 
     1104       selfReferenceFilter->connectOutput(temporalFilter, 0); 
     1105       return temporalFilter ; 
     1106     } 
     1107     else if (!field_ref.isEmpty()) 
     1108     { 
     1109       CField* fieldRef = CField::get(field_ref); 
     1110       fieldRef->buildFilterGraph(gc, false);  
     1111       return fieldRef->getTemporalDataFilter(gc, outFreq) ; 
     1112     } 
     1113  } 
    11061114 
    11071115   //---------------------------------------------------------------- 
  • XIOS/dev/dev_olga/src/node/field.hpp

    r1144 r1158  
    9999 
    100100       public: 
    101          bool isActive(void) const; 
     101         bool isActive(bool atCurrentTimestep = false) const; 
    102102         bool hasOutputFile; 
    103103 
     
    150150        void recvUpdateData(std::map<int,CBufferIn*>& rankBuffers); 
    151151        void writeField(void); 
    152         void sendReadDataRequest(const CDate& tsDataRequested); 
     152        bool sendReadDataRequest(const CDate& tsDataRequested); 
    153153        bool sendReadDataRequestIfNeeded(void); 
    154154        static void recvReadDataRequest(CEventServer& event); 
     
    157157        static void recvReadDataReady(CEventServer& event); 
    158158        void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers); 
     159        void outputField(CArray<double,3>& fieldOut); 
     160        void outputField(CArray<double,2>& fieldOut); 
    159161        void outputField(CArray<double,1>& fieldOut); 
     162        void inputField(CArray<double,3>& fieldOut); 
     163        void inputField(CArray<double,2>& fieldOut); 
    160164        void inputField(CArray<double,1>& fieldOut); 
    161165        void outputCompressedField(CArray<double, 1>& fieldOut); 
     
    240244         //! The terminal filter which stores the instant data 
    241245         boost::shared_ptr<CStoreFilter> storeFilter; 
    242          //! The terminal filter which sends the data to file 
     246         //! The terminal filter which writes the data to file 
    243247         boost::shared_ptr<CFileWriterFilter> fileWriterFilter; 
    244248         //! The terminal filter which writes data to file 
  • XIOS/dev/dev_olga/src/node/file.cpp

    r1144 r1158  
    1414#include "type.hpp" 
    1515#include "xios_spl.hpp" 
     16#include "context_client.hpp" 
    1617#include "mpi.hpp" 
     18#include "timer.hpp" 
    1719 
    1820namespace xios { 
     
    4951   //---------------------------------------------------------------- 
    5052 
    51    const StdString& CFile::getFileOutputName(void) const 
    52    { 
    53      return name.isEmpty() ? getId() : name; 
     53   const StdString CFile::getFileOutputName(void) const 
     54   { 
     55     return (name.isEmpty() ? getId() : name) + (name_suffix.isEmpty() ? StdString("") :  name_suffix.getValue()); 
    5456   } 
    5557 
     
    215217      if (!split_freq.isEmpty()) 
    216218      { 
    217         if (context->registryIn->foundKey("splitStart") && context->registryIn->foundKey("splitEnd")) 
     219        StdString keySuffix("CContext_"+CContext::getCurrent()->getId()+"::CFile_"+getFileOutputName()+"::") ;  
     220        if (context->registryIn->foundKey(keySuffix+"splitStart") && context->registryIn->foundKey(keySuffix+"splitEnd")) 
    218221        { 
    219222          CDate savedSplitStart(*context->getCalendar()), savedSplitEnd(*context->getCalendar()); 
    220           context->registryIn->getKey("splitStart", savedSplitStart); 
    221           context->registryIn->getKey("splitEnd",   savedSplitEnd); 
     223          context->registryIn->getKey(keySuffix+"splitStart", savedSplitStart); 
     224          context->registryIn->getKey(keySuffix+"splitEnd",   savedSplitEnd); 
    222225 
    223226          if (savedSplitStart <= lastSplit && lastSplit <= savedSplitEnd) 
     
    234237      const int recordOffset = record_offset.isEmpty() ? 0 : record_offset; 
    235238 
    236 //      set<CAxis*> setAxis; 
    237 //      set<CDomain*> setDomains; 
    238239      set<StdString> setAxis; 
    239240      set<StdString> setDomains; 
     
    263264      if (allDomainEmpty) MPI_Comm_free(&fileComm); 
    264265 
    265       if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); 
     266      // if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); 
    266267      if (time_counter_name.isEmpty()) time_counter_name = "time_counter"; 
    267268    } 
     
    281282        if (mode.isEmpty() || mode.getValue() == mode_attr::write) 
    282283        { 
     284          CTimer::get("Files : create headers").resume(); 
    283285          if (!isOpen) createHeader(); 
     286          CTimer::get("Files : create headers").suspend(); 
    284287          checkSync(); 
    285288        }         
     
    303306        if (!mode.isEmpty() && mode.getValue() == mode_attr::read) 
    304307        { 
     308          CTimer::get("Files : open headers").resume(); 
    305309          if (!isOpen) openInReadMode(&(context->server->intraComm)); 
     310          CTimer::get("Files : open headers").suspend(); 
    306311        } 
    307312        //checkSplit(); // Really need for reading? 
     
    374379      { 
    375380         StdString filename = getFileOutputName(); 
    376          if (!name_suffix.isEmpty()) filename+=name_suffix.getValue(); 
    377381 
    378382// determine splitting format in the file name  : firstPart%start_date%middlePart%end_date%lastPart 
     
    441445           oss << lastPart ; 
    442446 
    443            context->registryOut->setKey("splitStart", lastSplit); 
    444            context->registryOut->setKey("splitEnd",   splitEnd); 
     447           StdString keySuffix("CContext_"+CContext::getCurrent()->getId()+"::CFile_"+getFileOutputName()+"::") ;  
     448           context->registryOut->setKey(keySuffix+"splitStart", lastSplit); 
     449           context->registryOut->setKey(keySuffix+"splitEnd",   splitEnd); 
    445450         } 
    446451         else oss<<firstPart<<lastPart ; 
     
    489494         if (isOpen) data_out->closeFile(); 
    490495 
    491         data_out = shared_ptr<CDataOutput>(new CNc4DataOutput(oss.str(), append, useClassicFormat, useCFConvention, 
     496        data_out = shared_ptr<CDataOutput>(new CNc4DataOutput(this, oss.str(), append, useClassicFormat, useCFConvention, 
    492497                                                              fileComm, multifile, isCollective, time_counter_name)); 
    493498        isOpen = true; 
     
    509514          { 
    510515            CField* field = *it; 
     516            this->data_out->writeFieldTimeAxis(field); 
     517          } 
     518           
     519          for (it = this->enabledFields.begin(); it != end; it++) 
     520          { 
     521            CField* field = *it; 
    511522            this->data_out->writeField(field); 
    512523          } 
     
    517528 
    518529          this->data_out->definition_end(); 
     530        } 
     531        else 
     532        { 
     533          // check time axis even in append mode 
     534          std::vector<CField*>::iterator it, end = this->enabledFields.end(); 
     535          for (it = this->enabledFields.begin(); it != end; it++) 
     536          { 
     537            CField* field = *it; 
     538            this->data_out->writeFieldTimeAxis(field); 
     539          } 
    519540        } 
    520541      } 
     
    535556      StdOStringStream oss; 
    536557      oss << filename; 
    537       if (!name_suffix.isEmpty()) oss << name_suffix.getValue(); 
    538558 
    539559      if (!split_freq.isEmpty()) 
     
    872892   } 
    873893 
    874  
    875894   /*! 
    876895   \brief Send a message to create a field on server side 
  • XIOS/dev/dev_olga/src/node/file.hpp

    r1144 r1158  
    7070      public: 
    7171         /// Accesseurs /// 
    72          const StdString& getFileOutputName(void) const; 
     72         const StdString getFileOutputName(void) const; 
    7373         boost::shared_ptr<CDataOutput> getDataOutput(void) const; 
    7474         boost::shared_ptr<CDataInput> getDataInput(void) const; 
  • XIOS/dev/dev_olga/src/node/grid.cpp

    r1144 r1158  
    3131      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    3232      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    33       , globalDim_(), connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 
     33      , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 
    3434      , transformations_(0), isTransformed_(false) 
    35       , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false) 
     35      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    3636      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    3737      , computedWrittenIndex_(false) 
     
    5050      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    5151      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
    52       , globalDim_(), connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 
     52      , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false) 
    5353      , transformations_(0), isTransformed_(false) 
    54       , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false) 
     54      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    5555      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    5656      , computedWrittenIndex_(false) 
     
    7676 
    7777 
    78    StdSize CGrid::getDimension(void) const 
    79    { 
    80       return globalDim_.size(); 
     78   StdSize CGrid::getDimension(void) 
     79   { 
     80      return getGlobalDimension().size(); 
    8181   } 
    8282 
     
    196196        for (int i = 0; i < axisListP.size(); ++i) 
    197197        { 
    198           axisListP[i]->checkAttributesOnClientAfterTransformation(globalDim_,axisPositionInGrid_[i]); 
     198          axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(),axisPositionInGrid_[i]); 
    199199        } 
    200200      } 
     
    243243     this->solveScalarRef(areAttributesChecked); 
    244244     this->solveAxisRef(areAttributesChecked); 
    245      this->solveDomainRef(areAttributesChecked); 
    246      computeGridGlobalDimension(getDomains(), getAxis(), getScalars(), axis_domain_order); 
     245     this->solveDomainRef(areAttributesChecked);      
    247246     this->isDomainAxisChecked = areAttributesChecked; 
    248247   } 
     
    311310            {sendIndex(); this->isIndexSent = true;} 
    312311       } 
     312 
     313       // Not sure about this 
     314       //if (!(this->hasTransform() && !this->isTransformed())) 
     315       // this->isChecked = true; 
     316       //return; 
    313317     } 
    314318     
     
    409413      using namespace std; 
    410414      std::vector<CDomain*> domainP = this->getDomains(); 
    411       std::vector<CAxis*> axisP = this->getAxis();       
     415      std::vector<CAxis*> axisP = this->getAxis(); 
    412416      int dim = domainP.size() * 2 + axisP.size(); 
    413417 
     
    512516        { 
    513517          if (sendAtt) 
    514             axisListP[i]->sendCheckedAttributes(globalDim_,axisPositionInGrid_[i]); 
     518            axisListP[i]->sendCheckedAttributes(getGlobalDimension(),axisPositionInGrid_[i]); 
    515519          else 
    516520            axisListP[i]->checkAttributesOnClient(); 
     
    534538        } 
    535539      } 
     540   } 
     541   std::vector<int> CGrid::getAxisPositionInGrid() const 
     542   { 
     543     return axisPositionInGrid_; 
    536544   } 
    537545 
     
    652660              }               
    653661            } 
    654  
    655  
    656662          }           
    657663        } 
     
    695701       // Compute mapping between client and server 
    696702       std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
    697        CServerDistributionDescription serverDistributionDescription(globalDim_, client->serverSize); 
     703       CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
    698704       serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
    699705                                                                  client->clientRank, 
     
    933939        } 
    934940      } 
    935      } 
     941    } 
    936942   } 
    937943   //---------------------------------------------------------------- 
     
    11221128   } 
    11231129 
     1130/* 
     1131   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field) 
     1132   { 
     1133     const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 
     1134     StdSize numElements = stored.numElements(); 
     1135     for (StdSize n = 0; n < numElements; ++n) 
     1136     { 
     1137       field[out_i(n)] = stored(n); 
     1138     } 
     1139   } 
     1140 
     1141   void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored) 
     1142   { 
     1143     const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 
     1144     StdSize numElements = stored.numElements(); 
     1145     for (StdSize n = 0; n < numElements; ++n) 
     1146     { 
     1147       stored(n) = field[out_i(n)]; 
     1148     } 
     1149   } 
     1150 
     1151   void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field) 
     1152   { 
     1153     const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank]; 
     1154     StdSize numElements = stored.numElements(); 
     1155     for (StdSize n = 0; n < numElements; ++n) 
     1156     { 
     1157       field[out_i(n)] = stored(n); 
     1158     } 
     1159   } 
     1160*/ 
     1161   //---------------------------------------------------------------- 
     1162 
    11241163   void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const 
    11251164   { 
     
    11701209  { 
    11711210    CContext* context = CContext::getCurrent(); 
    1172     // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
    11731211    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 
    11741212    for (int p = 0; p < nbSrvPools; ++p) 
     
    15381576  } 
    15391577 
    1540   void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains, 
    1541                                          const std::vector<CAxis*>& axis, 
    1542                                          const std::vector<CScalar*>& scalars, 
    1543                                          const CArray<int,1>& axisDomainOrder) 
    1544   { 
    1545     globalDim_.resize(domains.size()*2+axis.size()+scalars.size()); 
     1578  /* 
     1579     Compute on the fly the global dimension of a grid with its elements 
     1580     \param[in/out] globalDim global dimension of grid 
     1581     \param[in] domains list of its domains 
     1582     \param[in] axiss list of its axis 
     1583     \param[in] scalars list of its scalars 
     1584     \param[in] axisDomainOrder the order of element in a grid (e.g: scalar then axis) 
     1585     \return The dimension of which we do distribution (often for server) 
     1586  */ 
     1587  int CGrid::computeGridGlobalDimension(std::vector<int>& globalDim, 
     1588                                        const std::vector<CDomain*> domains, 
     1589                                        const std::vector<CAxis*> axis, 
     1590                                        const std::vector<CScalar*> scalars, 
     1591                                        const CArray<int,1>& axisDomainOrder) 
     1592  { 
     1593    globalDim.resize(domains.size()*2+axis.size()+scalars.size()); 
     1594    int positionDimensionDistributed = 1; 
    15461595    int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0; 
    15471596    for (int i = 0; i < axisDomainOrder.numElements(); ++i) 
     
    15511600        if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured)) 
    15521601        { 
    1553           positionDimensionDistributed_ = idx; 
     1602          positionDimensionDistributed = idx; 
    15541603        } 
    15551604        else 
    15561605        { 
    1557           positionDimensionDistributed_ = idx +1; 
    1558         } 
    1559  
    1560         globalDim_[idx]   = domains[idxDomain]->ni_glo.getValue(); 
    1561         globalDim_[idx+1] = domains[idxDomain]->nj_glo.getValue(); 
     1606          positionDimensionDistributed = idx +1; 
     1607        } 
     1608 
     1609        globalDim[idx]   = domains[idxDomain]->ni_glo.getValue(); 
     1610        globalDim[idx+1] = domains[idxDomain]->nj_glo.getValue(); 
    15621611 
    15631612        ++idxDomain; 
     
    15661615      else if (1 == axisDomainOrder(i)) 
    15671616      { 
    1568         globalDim_[idx] = axis[idxAxis]->n_glo.getValue(); 
     1617        globalDim[idx] = axis[idxAxis]->n_glo.getValue(); 
    15691618        ++idxAxis; 
    15701619        ++idx; 
     
    15721621      else 
    15731622      { 
    1574         globalDim_[idx] = 1; 
     1623        globalDim[idx] = 1; 
    15751624        ++idxScalar; 
    15761625        ++idx; 
    15771626      } 
    15781627    } 
    1579   } 
    1580  
     1628 
     1629    return positionDimensionDistributed; 
     1630  } 
     1631 
     1632  // Retrieve the global dimension of grid 
    15811633  std::vector<int> CGrid::getGlobalDimension() 
    15821634  { 
    1583     return globalDim_; 
     1635    std::vector<int> globalDim; 
     1636    computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order); 
     1637 
     1638    return globalDim; 
     1639  } 
     1640 
     1641  // Retrieve dimension on which we do distribution (Very often, it should be 2nd dimension) 
     1642  int CGrid::getDistributedDimension() 
     1643  { 
     1644    std::vector<int> globalDim; 
     1645    return computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);     
    15841646  } 
    15851647 
  • XIOS/dev/dev_olga/src/node/grid.hpp

    r1144 r1158  
    8787 
    8888         /// Accesseurs /// 
    89          StdSize getDimension(void) const; 
     89         StdSize getDimension(void); 
    9090 
    9191         StdSize  getDataSize(void) const; 
     
    176176         std::vector<int> getGlobalDimension(); 
    177177         bool isScalarGrid() const; 
     178         std::vector<int> getAxisPositionInGrid() const; 
    178179 
    179180         bool doGridHaveDataToWrite(); 
     
    268269        void computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
    269270                                   CClientServerMapping::GlobalIndexMap& globalIndexOnServer); 
     271        int computeGridGlobalDimension(std::vector<int>& globalDim, 
     272                                       const std::vector<CDomain*> domains, 
     273                                       const std::vector<CAxis*> axis, 
     274                                       const std::vector<CScalar*> scalars, 
     275                                       const CArray<int,1>& axisDomainOrder); 
     276        int getDistributedDimension(); 
    270277 
    271278        void computeClientIndex(); 
     
    296303        std::vector<int> axisPositionInGrid_; 
    297304        CGridTransformation* transformations_; 
    298         bool hasDomainAxisBaseRef_; 
    299         std::vector<int> globalDim_; 
     305        bool hasDomainAxisBaseRef_;         
    300306        std::map<CGrid*, std::pair<bool,StdString> > gridSrc_; 
    301307        bool hasTransform_; 
  • XIOS/dev/dev_olga/src/node/interpolate_domain.cpp

    r1021 r1158  
    5555    { 
    5656      case mode_attr::read: 
    57         if (this->file.isEmpty()) 
     57        if (this->weight_filename.isEmpty()) 
    5858        { 
    5959          if (!this->write_weight) 
     
    6464        else 
    6565        { 
    66           weightFile = this->file; 
     66          weightFile = this->weight_filename; 
    6767          ifstream f(weightFile.c_str()); 
    6868          if (!f.good()) 
     
    7575        break; 
    7676      case mode_attr::read_or_compute: 
    77         if (!this->file.isEmpty() && !this->write_weight) 
     77        if (!this->weight_filename.isEmpty() && !this->write_weight) 
    7878        { 
    79           weightFile = this->file; 
     79          weightFile = this->weight_filename; 
    8080          ifstream f(weightFile.c_str()); 
    8181          if (!f.good()) 
  • XIOS/dev/dev_olga/src/node/mesh.cpp

    r946 r1158  
    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  
    11993    return seed ; 
    12094  } 
     
    141115    return seed ; 
    142116  } 
     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 
    143138 
    144139///---------------------------------------------------------------- 
     
    600595        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2Idx; 
    601596        CArray<size_t,1> nodeHashList(nbEdges_*nvertex*4); 
     597        int nbHash = 0; 
    602598        for (int ne = 0; ne < nbEdges_; ++ne) 
    603599        { 
     
    609605              if (nodeHash2Idx[hashValues[nh]].size() == 0) 
    610606              { 
    611                 nodeHash2Idx[hashValues[nh]].push_back(generateNodeIndex(hashValues, mpiRank)); 
     607                nodeHash2Idx[hashValues[nh]].push_back(generateNodeIndex(hashValues)); 
    612608                nodeHash2Idx[hashValues[nh]].push_back(mpiRank); 
     609                nodeHashList(nbHash) = hashValues[nh]; 
     610                ++nbHash; 
    613611              } 
    614               nodeHashList((ne*nvertex + nv)*4 + nh) = hashValues[nh]; 
    615             } 
    616           } 
    617         } 
     612            } 
     613          } 
     614        } 
     615        nodeHashList.resizeAndPreserve(nbHash); 
    618616 
    619617        // (2.2) Generating global node indexes 
    620         // The ownership criterion: priority of the process holding the smaller index 
     618        // The ownership criterion: priority of the process of smaller index 
    621619        // Maps generated in this step are: 
    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 
     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(); 
    669699 
    670700        // (2.3) Saving variables: node_lon, node_lat, edge_nodes 
    671701        // Creating map nodeHash2IdxGlo <hash, idxGlo> 
    672702        // Creating map edgeHash2IdxGlo <hash, idxGlo> 
    673         nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
    674         node_count = dhtNodeIdxGlo.getIndexCount(); 
    675         node_start = dhtNodeIdxGlo.getIndexStart(); 
     703//        nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
     704//        node_count = dhtNodeIdxGlo.getIndexCount(); 
     705//        node_start = dhtNodeIdxGlo.getIndexStart(); 
    676706        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeHash2IdxGlo; 
    677707        node_lon.resize(node_count); 
     
    685715          { 
    686716            hashValues = CMesh::createHashes(bounds_lon(nv, ne), bounds_lat(nv, ne)); 
    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]; 
     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            { 
    695723//              node_lon(idxGlo - node_start) = (bounds_lon(nv, ne) == 360.) ? (0.) : (bounds_lon(nv, ne)); 
    696724              node_lon(idxGlo - node_start) = bounds_lon(nv, ne); 
    697725              node_lat(idxGlo - node_start) = bounds_lat(nv, ne); 
    698726            } 
    699             else 
    700             { 
    701               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = nodeIdxMin2IdxGlo.find(ownerIdx); 
    702               idxGlo = (itIdxGlo->second)[0]; 
    703             } 
    704  
    705727            edge_nodes(nv,ne) = idxGlo; 
    706728            for (int nh = 0; nh < 4; ++nh) 
     
    793815        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHash2Rank; 
    794816        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdxGlo2Face; 
    795         CArray<size_t,1> edgeIdxGloList(nbFaces_*nvertex); 
     817        CArray<size_t,1> edgeIdxList(nbFaces_*nvertex); 
    796818        size_t iIdx = 0; 
    797819 
     
    824846              if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 
    825847              { 
    826                 edgeIdxGloList(iIdx) = edgeIdxGlo; 
     848                edgeIdxList(iIdx) = edgeIdxGlo; 
    827849                ++iIdx; 
    828850              } 
    829851              edgeIdxGlo2Face[edgeIdxGlo].push_back(faceIdxGlo); 
    830               edgeHash2Rank[edgeHash].push_back(itEdgeHash->first); 
    831852              edgeHash2Rank[edgeHash].push_back(mpiRank); 
     853              edgeHash2Rank[edgeHash].push_back(itEdgeHash->second[0]); 
    832854            } 
    833855            else 
     
    837859          } 
    838860        } 
    839         edgeIdxGloList.resizeAndPreserve(iIdx); 
     861        edgeIdxList.resizeAndPreserve(iIdx); 
    840862 
    841863        // (1.3) Saving remaining variables edge_faces and face_faces 
     
    846868        dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 
    847869        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 
    848         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeHashMin2IdxGlo; 
    849  
    850         // edgeHash2Info = <edgeHash, <idxGlo, rank1, idxGlo, rank2>> 
    851         // edgeHashMin2IdxGlo = <edgeHashMin, idxGlo> 
     870 
     871        // edgeHash2Info = <edgeHash, < rank1, idxGlo, rank2, idxGlo>> 
     872        int edgeCount = 0; 
    852873        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 
    853874        { 
    854875          vector <size_t> edgeInfo = it->second; 
    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(); 
     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); 
     914        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 
    865920 
    866921        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; 
    867950        face_faces.resize(nvertex, nbFaces_); 
    868  
    869         CClientClientDHTSizet dhtEdge2Face (edgeIdxGlo2Face, comm); 
    870         dhtEdge2Face.computeIndexInfoMapping(edgeIdxGloList); 
    871         CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 
    872         CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itFace1, itFace2; 
    873  
    874951        for (int nf = 0; nf < nbFaces_; ++nf) 
    875952        { 
     
    896973              size_t faceIdxGlo = nbFacesAccum + nf; 
    897974              size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 
    898               itEdgeHash = edgeHash2IdxGlo.find(edgeHash); 
    899               if (itEdgeHash != edgeHashMin2IdxGlo.end()) 
     975              itEdgeHash = edgeHash2Info.find(edgeHash); 
     976              int edgeIdxGlo = (itEdgeHash->second)[1]; 
     977 
     978              if ( (itEdgeHash->second)[0] == mpiRank) 
    900979              { 
    901                 int edgeIdxGlo = itEdgeHash->second[0]; 
    902                 itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
     980                itFace1 = edgeIdx2FaceIdx.find(edgeIdxGlo); 
    903981                int face1 = itFace1->second[0]; 
    904982                if (itFace1->second.size() == 1) 
    905983                { 
    906                   edge_faces(0, edgeIdxGlo - edge_start) = face1; 
    907                   edge_faces(1, edgeIdxGlo - edge_start) = -999; 
    908984                  face_faces(nv1, nf) = 999999; 
    909985                } 
     
    911987                { 
    912988                  int face2 = itFace1->second[1]; 
    913                   edge_faces(0, edgeIdxGlo - edge_start) = face1; 
    914                   edge_faces(1, edgeIdxGlo - edge_start) = face2; 
    915989                  face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 
    916990                } 
     
    918992              else 
    919993              { 
    920                 itEdgeHash = edgeHashMin2IdxGlo.find(edgeHash); 
    921                 size_t edgeIdxGlo = itEdgeHash->second[0]; 
    922                 itFace1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
     994                itFace1 = edgeIdx2FaceIdx.find(edgeIdxGlo); 
    923995                int face1 = itFace1->second[0]; 
    924996                int face2 = itFace1->second[1]; 
     
    9571029        CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it1, it2; 
    9581030        CArray<size_t,1> edgeHashList(nbFaces_*nvertex); 
     1031        int nEdgeHash = 0; 
    9591032        for (int nf = 0; nf < nbFaces_; ++nf) 
    9601033        { 
     
    9781051            face_nodes(nv1,nf) = it1->second[0]; 
    9791052            size_t edgeHash = hashPairOrdered(it1->second[0], it2->second[0]); 
    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 
     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 
    9881066        // Maps generated in this step are: 
    989         // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 
    990         // edgeIdx2IdxMin = = <idx, idxMin> 
    991         // edgeIdx2IdxGlo = <idxMin, idxGlo> 
     1067        // edgeIdx2Idx = = <idx, <rankOwner, idx>> 
     1068        // edgeIdx2IdxGlo = <idxMin, <rankOwner, idxGlo>> 
    9921069 
    9931070        CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); 
    9941071        dhtEdgeHash.computeIndexInfoMapping(edgeHashList); 
    9951072        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeHash2Info = dhtEdgeHash.getInfoIndexMap(); 
    996  
    997         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 
    998         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 
    999         CArray<size_t,1> edgeIdxMinList(nbFaces_*nvertex); 
    1000         size_t iIdxMin = 0; 
     1073        // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 
     1074 
     1075        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2Idx; 
    10011076 
    10021077        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 
    10031078        { 
    1004           size_t idxMin = (it->second)[0]; 
     1079          size_t rankMin = (it->second)[1]; 
    10051080          size_t idx = (it->second)[0]; 
     1081 
    10061082          for (int i = 2; i < (it->second).size();) 
    10071083          { 
    1008             if (mpiRank == (it->second)[i+1]) 
    1009             { 
     1084            if ((it->second)[i+1] < rankMin) 
     1085            { 
     1086              rankMin = (it->second)[i+1]; 
    10101087              idx = (it->second)[i]; 
    1011             } 
    1012             if ((it->second)[i] < idxMin) 
    1013             { 
    1014                 idxMin = (it->second)[i]; 
    1015                 (it->second)[i] = (it->second)[i-2]; 
     1088              (it->second)[i+1] = (it->second)[i-1]; 
    10161089            } 
    10171090            i += 2; 
    10181091          } 
    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; 
     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; 
    10491114 
    10501115        for (int nf = 0; nf < nbFaces_; ++nf) 
     
    10681133              it2 = nodeHash2IdxGlo.find(nodeHashList((nf*nvertex + nv1)*4 + nh2)); 
    10691134            } 
     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            } 
    10701189            // Getting edge global index 
    10711190            size_t nodeIdxGlo1 = it1->second[0]; 
    10721191            size_t nodeIdxGlo2 = it2->second[0]; 
    1073             size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 
     1192            size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    10741193            if (nodeIdxGlo1 != nodeIdxGlo2) 
    10751194            { 
    1076               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 
    1077               size_t ownerIdx = (itIdx->second)[0]; 
    1078               int edgeIdxGlo = 0; 
     1195              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 
     1196              int edgeIdxGlo = (itIdx->second)[1]; 
    10791197              size_t faceIdxGlo = nbFacesAccum + nf; 
    10801198 
    1081               if (myIdx == ownerIdx) 
     1199              if (mpiRank == (itIdx->second)[0]) 
    10821200              { 
    1083                 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
    1084                 edgeIdxGlo = (itIdxGlo->second)[0]; 
    10851201                double edgeLon; 
    10861202                double diffLon = abs(bounds_lon(nv1, nf) - bounds_lon(nv2, nf)); 
     
    10961212                edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 
    10971213              } 
    1098               else 
    1099               { 
    1100                 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
    1101                 edgeIdxGlo = (itIdxGlo->second)[0]; 
    1102               } 
    11031214              face_edges(nv1,nf) = edgeIdxGlo; 
    11041215              if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 
     
    11171228        edgeIdxGloList.resizeAndPreserve(iIdx); 
    11181229 
    1119         // (2.4) Saving remaining variables edge_faces and face_faces 
     1230        // (2.5) Saving remaining variables edge_faces and face_faces 
    11201231        edge_faces.resize(2, edge_count); 
    11211232        face_faces.resize(nvertex, nbFaces_); 
     
    11251236        CClientClientDHTSizet::Index2VectorInfoTypeMap& edgeIdxGlo2FaceIdx = dhtEdge2Face.getInfoIndexMap(); 
    11261237        CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itNodeIdxGlo1, itNodeIdxGlo2; 
     1238        CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx; 
    11271239 
    11281240        for (int nf = 0; nf < nbFaces_; ++nf) 
     
    11491261            size_t nodeIdxGlo2 = it2->second[0]; 
    11501262 
    1151             size_t myIdx = generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank); 
    1152             CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxMin.find(myIdx); 
    1153             size_t ownerIdx = (itIdx->second)[0]; 
     1263            size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
     1264            itIdx = edgeIdx2IdxGlo.find(myIdx); 
    11541265            size_t faceIdxGlo = nbFacesAccum + nf; 
    1155  
    1156             if (myIdx == ownerIdx) 
    1157             { 
    1158               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
    1159               int edgeIdxGlo = (itIdxGlo->second)[0]; 
     1266            int edgeIdxGlo = (itIdx->second)[1]; 
     1267 
     1268            if (mpiRank == (itIdx->second)[0]) 
     1269            { 
    11601270              it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    11611271              int face1 = it1->second[0]; 
     
    11761286            else 
    11771287            { 
    1178               CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
    1179               size_t edgeIdxGlo = (itIdxGlo->second)[0]; 
    11801288              it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    11811289              int face1 = it1->second[0]; 
     
    12001308          { 
    12011309            hashValues = CMesh::createHashes(bounds_lon(nv, nf), bounds_lat(nv, nf)); 
    1202             size_t nodeIndex = generateNodeIndex(hashValues, mpiRank); 
     1310//            size_t nodeIndex = generateNodeIndex(hashValues, mpiRank); 
     1311            size_t nodeIndex = generateNodeIndex(hashValues); 
    12031312            for (int nh = 0; nh < 4; ++nh) 
    12041313            { 
     
    12161325 
    12171326        // (3.2) Generating global node indexes 
    1218         // The ownership criterion: priority of the process holding the smaller index 
     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. 
    12191329        // Maps generated in this step are: 
    1220         // nodeHash2Info = <hash, [[idxMin, rankMin], [idx1, rank1], [idx3, rank3]..]> 
    1221         // nodeIdx2IdxMin = = <idx, idxMin> 
    1222         // nodeIdx2IdxGlo = <idxMin, idxGlo> 
     1330        // nodeHash2Info = <hash, [[idx, rankMin], [idx, rank1], [idx, rank3]..]> 
     1331        // nodeIdx2Idx = <idx, <rankOwner, idx>> 
    12231332 
    12241333        CClientClientDHTSizet dhtNodeHash(nodeHash2Idx, comm); 
     
    12261335        CClientClientDHTSizet::Index2VectorInfoTypeMap& nodeHash2Info = dhtNodeHash.getInfoIndexMap(); 
    12271336 
    1228         CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxMin; 
    1229         CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2IdxGlo; 
    1230         CArray<size_t,1> nodeIdxMinList(nbFaces_*nvertex*4); 
    1231         size_t iIdxMin = 0; 
     1337        CClientClientDHTSizet::Index2VectorInfoTypeMap nodeIdx2Idx; 
     1338        CArray<size_t,1> nodeIdxList(nbFaces_*nvertex*4); 
     1339        size_t nIdx = 0; 
    12321340 
    12331341        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = nodeHash2Info.begin(); it != nodeHash2Info.end(); ++it) 
    12341342        { 
    1235           size_t idxMin = (it->second)[0]; 
     1343          size_t rankMin = (it->second)[1]; 
    12361344          size_t idx = (it->second)[0]; 
    12371345          for (int i = 2; i < (it->second).size();) 
    12381346          { 
    1239             if (mpiRank == (it->second)[i+1]) 
     1347            if ( (it->second)[i+1] < rankMin) 
    12401348            { 
    12411349              idx = (it->second)[i]; 
    1242             } 
    1243             if ((it->second)[i] < idxMin) 
    1244             { 
    1245                 idxMin = (it->second)[i]; 
    1246                 (it->second)[i] = (it->second)[i-2]; 
     1350              rankMin = (it->second)[i+1]; 
     1351              (it->second)[i+1] = (it->second)[i-1]; 
    12471352            } 
    12481353            i += 2; 
    12491354          } 
    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(); 
     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(); 
    12661407 
    12671408        // (3.3) Saving node data: node_lon, node_lat, and face_nodes 
    12681409        // Generating edgeHash2Info = <hash, <idx, rank>> and edgeHashList 
    1269         nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
    1270         node_count = dhtNodeIdxGlo.getIndexCount(); 
    1271         node_start = dhtNodeIdxGlo.getIndexStart(); 
     1410//        nbNodesGlo = dhtNodeIdxGlo.getNbIndexesGlobal(); 
     1411//        node_count = dhtNodeIdxGlo.getIndexCount(); 
     1412//        node_start = dhtNodeIdxGlo.getIndexStart(); 
    12721413        node_lon.resize(node_count); 
    12731414        node_lat.resize(node_count); 
     
    12861427            vector<size_t> hashValues1 = CMesh::createHashes(bounds_lon(nv1, nf), bounds_lat(nv1, nf)); 
    12871428            vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 
    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]; 
     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            { 
    12981439              node_lon(nodeIdxGlo1 - node_start) = bounds_lon(nv1, nf); 
    12991440              node_lat(nodeIdxGlo1 - node_start) = bounds_lat(nv1, nf); 
    13001441            } 
    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]; 
    13081442            if (nodeIdxGlo1 != nodeIdxGlo2) 
    13091443            { 
    13101444              size_t edgeHash = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
    1311               edgeHash2Idx[edgeHash].push_back(generateEdgeIndex(nodeIdxGlo1, nodeIdxGlo2, mpiRank)); 
     1445              edgeHash2Idx[edgeHash].push_back(edgeHash); 
    13121446              edgeHash2Idx[edgeHash].push_back(mpiRank); 
    13131447              edgeHashList(nEdgeHash) = edgeHash; 
     
    13211455        // (3.4) Generating global edge indexes 
    13221456        // Maps generated in this step are: 
    1323         // edgeIdx2IdxMin = = <idx, idxMin> 
    1324         // edgeIdx2IdxGlo = <idxMin, idxGlo> 
     1457        // edgeIdx2Idx = = <idx, <rankOwner, idx>> 
     1458        // edgeIdx2IdxGlo = <idxMin, <rankOwner, idxGlo>> 
    13251459 
    13261460        CClientClientDHTSizet dhtEdgeHash(edgeHash2Idx, comm); 
     
    13291463        // edgeHash2Info = <hash, [[idx1, rank1], [idx2, rank2], [idx3, rank3]..]> 
    13301464 
    1331         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxMin; 
    1332         CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2IdxGlo; 
    1333         CArray<size_t,1> edgeIdxMinList(nbFaces_*nvertex); 
    1334         iIdxMin = 0; 
     1465        CClientClientDHTSizet::Index2VectorInfoTypeMap edgeIdx2Idx; 
    13351466 
    13361467        for (CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator it = edgeHash2Info.begin(); it != edgeHash2Info.end(); ++it) 
    13371468        { 
    1338           size_t idxMin = (it->second)[0]; 
     1469          size_t rankMin = (it->second)[1]; 
    13391470          size_t idx = (it->second)[0]; 
    13401471 
    13411472          for (int i = 2; i < (it->second).size();) 
    13421473          { 
    1343             if (mpiRank == (it->second)[i+1]) 
    1344             { 
     1474            if ((it->second)[i+1] < rankMin) 
     1475            { 
     1476              rankMin = (it->second)[i+1]; 
    13451477              idx = (it->second)[i]; 
    1346             } 
    1347             if ((it->second)[i] < idxMin) 
    1348             { 
    1349                 idxMin = (it->second)[i]; 
    1350                 (it->second)[i] = (it->second)[i-2]; 
     1478              (it->second)[i+1] = (it->second)[i-1]; 
    13511479            } 
    13521480            i += 2; 
    13531481          } 
    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(); 
     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(); 
    13691538 
    13701539        // (3.5) Saving variables: edge_lon, edge_lat, face_edges 
    13711540        // Creating map edgeIdxGlo2Face <idxGlo, face> 
    1372  
    1373         nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 
    1374         edge_count = dhtEdgeIdxGlo.getIndexCount(); 
    1375         edge_start = dhtEdgeIdxGlo.getIndexStart(); 
     1541//        nbEdgesGlo = dhtEdgeIdxGlo.getNbIndexesGlobal(); 
     1542//        edge_count = dhtEdgeIdxGlo.getIndexCount(); 
     1543//        edge_start = dhtEdgeIdxGlo.getIndexStart(); 
     1544 
    13761545        edge_lon.resize(edge_count); 
    13771546        edge_lat.resize(edge_count); 
     
    13931562            vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 
    13941563 
    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]; 
     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]; 
    14031570 
    14041571            if (nodeIdxGlo1 != nodeIdxGlo2) 
    14051572            { 
    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; 
     1573              size_t myIdx = hashPairOrdered(nodeIdxGlo1, nodeIdxGlo2); 
     1574              CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdx = edgeIdx2IdxGlo.find(myIdx); 
     1575              int edgeIdxGlo = (itIdx->second)[1]; 
    14101576              size_t faceIdxGlo = nbFacesAccum + nf; 
    14111577 
    1412               if (myIdx == ownerIdx) 
     1578              if (mpiRank == (itIdx->second)[0]) 
    14131579              { 
    1414                 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
    1415                 edgeIdxGlo = (itIdxGlo->second)[0]; 
    14161580                double edgeLon; 
    14171581                double diffLon = abs(bounds_lon(nv1, nf) - bounds_lon(nv2, nf)); 
     
    14271591                edge_nodes(1, edgeIdxGlo - edge_start) = nodeIdxGlo2; 
    14281592              } 
    1429               else 
    1430               { 
    1431                 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
    1432                 edgeIdxGlo = (itIdxGlo->second)[0]; 
    1433               } 
    14341593              face_edges(nv1,nf) = edgeIdxGlo; 
    14351594              if (edgeIdxGlo2Face.count(edgeIdxGlo) == 0) 
     
    14651624            vector<size_t> hashValues2 = CMesh::createHashes(bounds_lon(nv2, nf), bounds_lat(nv2, nf)); 
    14661625 
    1467             size_t myNodeIdx1 = generateNodeIndex(hashValues1, mpiRank); 
    1468             size_t myNodeIdx2 = generateNodeIndex(hashValues2, mpiRank); 
     1626            size_t myNodeIdx1 = generateNodeIndex(hashValues1); 
     1627            size_t myNodeIdx2 = generateNodeIndex(hashValues2); 
    14691628            if (myNodeIdx1 != myNodeIdx2) 
    14701629            { 
    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]; 
     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 
    14811638              size_t faceIdxGlo = nbFacesAccum + nf; 
    14821639 
    1483               if (myIdx == ownerIdx) 
     1640              if (mpiRank == (itIdx->second)[0]) 
    14841641              { 
    1485                 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdx2IdxGlo.find(myIdx); 
    1486                 int edgeIdxGlo = (itIdxGlo->second)[0]; 
    14871642                it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    14881643                int face1 = it1->second[0]; 
     
    15001655                  face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 
    15011656                } 
    1502               } // myIdx == ownerIdx 
     1657              } 
    15031658              else 
    15041659              { 
    1505                 CClientClientDHTSizet::Index2VectorInfoTypeMap::iterator itIdxGlo = edgeIdxMin2IdxGlo.find(ownerIdx); 
    1506                 size_t edgeIdxGlo = (itIdxGlo->second)[0]; 
    15071660                it1 = edgeIdxGlo2FaceIdx.find(edgeIdxGlo); 
    15081661                int face1 = it1->second[0]; 
    15091662                int face2 = it1->second[1]; 
    15101663                face_faces(nv1, nf) = (faceIdxGlo == face1 ? face2 : face1); 
    1511               } // myIdx != ownerIdx 
     1664              } 
    15121665            } // myNodeIdx1 != myNodeIdx2 
    15131666            else 
     
    15151668          } 
    15161669        } 
     1670 
    15171671      } 
    15181672      facesAreWritten = true; 
  • XIOS/dev/dev_olga/src/node/scalar.cpp

    r1144 r1158  
    6363  { 
    6464 
     65  } 
     66 
     67  /*! 
     68    Compare two scalar objects.  
     69    They are equal if only if they have identical attributes as well as their values. 
     70    Moreover, they must have the same transformations. 
     71  \param [in] scalar Compared scalar 
     72  \return result of the comparison 
     73  */ 
     74  bool CScalar::isEqual(CScalar* obj) 
     75  { 
     76    vector<StdString> excludedAttr; 
     77    excludedAttr.push_back("scalar_ref"); 
     78    bool objEqual = SuperClass::isEqual(obj, excludedAttr); 
     79    if (!objEqual) return objEqual; 
     80 
     81    TransMapTypes thisTrans = this->getAllTransformations(); 
     82    TransMapTypes objTrans  = obj->getAllTransformations(); 
     83 
     84    TransMapTypes::const_iterator it, itb, ite; 
     85    std::vector<ETranformationType> thisTransType, objTransType; 
     86    for (it = thisTrans.begin(); it != thisTrans.end(); ++it) 
     87      thisTransType.push_back(it->first); 
     88    for (it = objTrans.begin(); it != objTrans.end(); ++it) 
     89      objTransType.push_back(it->first); 
     90 
     91    if (thisTransType.size() != objTransType.size()) return false; 
     92    for (int idx = 0; idx < thisTransType.size(); ++idx) 
     93      objEqual &= (thisTransType[idx] == objTransType[idx]); 
     94 
     95    return objEqual; 
    6596  } 
    6697 
  • XIOS/dev/dev_olga/src/node/scalar.hpp

    r1144 r1158  
    7676           void duplicateTransformation(CScalar*); 
    7777           CTransformation<CScalar>* addTransformation(ETranformationType transType, const StdString& id=""); 
     78           bool isEqual(CScalar* scalar); 
    7879 
    7980         private: 
    8081           std::set<StdString> relFiles; 
     82           TransMapTypes transformationMap_; 
    8183 
    82          private: 
    83             TransMapTypes transformationMap_;             
    8484            void setTransformations(const TransMapTypes&); 
    8585 
  • XIOS/dev/dev_olga/src/node/variable.cpp

    r1071 r1158  
    4040      if (!node.getContent(this->content)) 
    4141      { 
     42        xml::THashAttributes attributes = node.getAttributes(); 
     43        StdString variableName = attributes["name"]; 
     44 
     45        node.goToParentElement(); 
     46        StdString parentName = node.getElementName(); 
     47        attributes = node.getAttributes(); 
     48        error << "The variable id = " << id << " and name = " << variableName << " does not have any content. Please define it!" << std::endl 
     49              << "This variable is inside another element whose attributes are :" << std::endl; 
     50 
     51        for (xml::THashAttributes::iterator it = attributes.begin(); it != attributes.end(); ++it) 
     52        { 
     53           error << it->first << "=\"" << it->second.c_str() << "\" "; 
     54        } 
     55        error << std::endl;  
     56 
    4257         ERROR("CVariable::parse(xml::CXMLNode & node)", 
    4358               << "[ variable id = " << id 
    44                << " ] variable is not defined !"); 
     59               << " ] variable is not defined !. It does not have any content. See error log for more details."); 
    4560      } 
    4661      content = boost::trim_copy(content) ; 
     
    108123      } 
    109124     } 
    110  
    111     //  if (!context->hasServer) 
    112     //  { 
    113     //    CContextClient* client=context->client ; 
    114  
    115     //    CEventClient event(this->getType(),EVENT_ID_VARIABLE_VALUE) ; 
    116     //    if (client->isServerLeader()) 
    117     //    { 
    118     //      CMessage msg ; 
    119     //      msg<<this->getId() ; 
    120     //      msg<<content ; 
    121     //      const std::list<int>& ranks = client->getRanksServerLeader(); 
    122     //      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    123     //        event.push(*itRank,1,msg); 
    124     //      client->sendEvent(event) ; 
    125     //    } 
    126     //    else client->sendEvent(event) ; 
    127     // } 
    128125   } 
    129126 
  • XIOS/dev/dev_olga/src/node/variable.hpp

    r1071 r1158  
    99#include "attribute_enum.hpp" 
    1010#include "attribute_enum_impl.hpp" 
     11#include "declare_attribute.hpp" 
    1112 
    1213namespace xios 
Note: See TracChangeset for help on using the changeset viewer.