Ignore:
Timestamp:
01/22/21 12:00:29 (3 years ago)
Author:
yushan
Message:

Graph intermedia commit to a tmp branch

Location:
XIOS/dev/dev_trunk_graph/src/node
Files:
5 added
60 edited

Legend:

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

    r1686 r2019  
    2020   CAxis::CAxis(void) 
    2121      : CObjectTemplate<CAxis>() 
    22       , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 
    23       , isClientAfterTransformationChecked(false) 
     22      , CAxisAttributes(), isChecked(false), relFiles() 
    2423      , hasBounds(false), isCompressible_(false) 
    25       , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_() 
    2624      , transformationMap_(), hasValue(false), hasLabel(false) 
    27       , computedWrittenIndex_(false) 
    28           , clients() 
     25      , clients() 
    2926   { 
    3027   } 
     
    3229   CAxis::CAxis(const StdString & id) 
    3330      : CObjectTemplate<CAxis>(id) 
    34       , CAxisAttributes(), isChecked(false), relFiles(), areClientAttributesChecked_(false) 
    35       , isClientAfterTransformationChecked(false) 
     31      , CAxisAttributes(), isChecked(false), relFiles() 
    3632      , hasBounds(false), isCompressible_(false) 
    37       , numberWrittenIndexes_(), totalNumberWrittenIndexes_(), offsetWrittenIndexes_() 
    3833      , transformationMap_(), hasValue(false), hasLabel(false) 
    39       , computedWrittenIndex_(false) 
    40           , clients() 
     34      , clients() 
    4135   { 
    4236   } 
     
    9387      // A condition to make sure that if there is only one client, axis 
    9488      // should be considered to be distributed. This should be a temporary solution      
    95       distributed |= (1 == CContext::getCurrent()->client->clientSize); 
     89      distributed |= (1 == CContext::getCurrent()->intraCommSize_); 
    9690      return distributed; 
    9791   } 
     
    9993 
    10094   /*! 
    101     * Test whether the data defined on the axis can be outputted in a compressed way. 
    102     * 
    103     * \return true if and only if a mask was defined for this axis 
     95    * Compute if the axis can be ouput in a compressed way. 
     96    * In this case the workflow view on server side must be the same 
     97    * than the full view for all context rank. The result is stored on 
     98    * internal isCompressible_ attribute. 
    10499    */ 
    105    bool CAxis::isCompressible(void) const 
    106    TRY 
    107    { 
    108       return isCompressible_; 
     100   void CAxis::computeIsCompressible(void) 
     101   TRY 
     102   { 
     103     // mesh is compressible contains some masked or indexed value, ie if full view is different of workflow view. 
     104     // But now assume that the size of the 2 view must be equal for everybody. True on server side 
     105     int isSameView = getLocalView(CElementView::FULL)->getSize() ==  getLocalView(CElementView::WORKFLOW)->getSize(); 
     106     MPI_Allreduce(MPI_IN_PLACE, &isSameView, 1, MPI_INT, MPI_LAND, CContext::getCurrent()->getIntraComm()) ; 
     107     if (isSameView) isCompressible_ = false ; 
     108     else isCompressible_ = true ; 
     109     isCompressibleComputed_=true ; 
    109110   } 
    110111   CATCH 
     
    124125   CATCH_DUMP_ATTR 
    125126 
    126    //---------------------------------------------------------------- 
    127  
    128    /*! 
    129      Returns the number of indexes written by each server. 
    130      \return the number of indexes written by each server 
    131    */ 
    132    int CAxis::getNumberWrittenIndexes(MPI_Comm writtenCom) 
    133    TRY 
    134    { 
    135      int writtenSize; 
    136      MPI_Comm_size(writtenCom, &writtenSize); 
    137      return numberWrittenIndexes_[writtenSize]; 
    138    } 
    139    CATCH_DUMP_ATTR 
    140  
    141    /*! 
    142      Returns the total number of indexes written by the servers. 
    143      \return the total number of indexes written by the servers 
    144    */ 
    145    int CAxis::getTotalNumberWrittenIndexes(MPI_Comm writtenCom) 
    146    TRY 
    147    { 
    148      int writtenSize; 
    149      MPI_Comm_size(writtenCom, &writtenSize); 
    150      return totalNumberWrittenIndexes_[writtenSize]; 
    151    } 
    152    CATCH_DUMP_ATTR 
    153  
    154    /*! 
    155      Returns the offset of indexes written by each server. 
    156      \return the offset of indexes written by each server 
    157    */ 
    158    int CAxis::getOffsetWrittenIndexes(MPI_Comm writtenCom) 
    159    TRY 
    160    { 
    161      int writtenSize; 
    162      MPI_Comm_size(writtenCom, &writtenSize); 
    163      return offsetWrittenIndexes_[writtenSize]; 
    164    } 
    165    CATCH_DUMP_ATTR 
    166  
    167    CArray<int, 1>& CAxis::getCompressedIndexToWriteOnServer(MPI_Comm writtenCom) 
    168    TRY 
    169    { 
    170      int writtenSize; 
    171      MPI_Comm_size(writtenCom, &writtenSize); 
    172      return compressedIndexToWriteOnServer[writtenSize]; 
    173    } 
    174    CATCH_DUMP_ATTR 
    175  
    176    //---------------------------------------------------------------- 
     127    //---------------------------------------------------------------- 
    177128 
    178129   /*! 
     
    274225   TRY 
    275226   { 
     227     if (checkAttributes_done_) return ; 
     228 
    276229     CContext* context=CContext::getCurrent(); 
    277230 
     
    318271      if (!this->value.isEmpty()) 
    319272      { 
    320         // Avoid this check at writing because it fails in case of a hole 
    321         if (context->hasClient) 
    322         { 
    323           StdSize true_size = value.numElements(); 
    324           if (this->n.getValue() != true_size) 
    325             ERROR("CAxis::checkAttributes(void)", 
    326                 << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 
    327                 << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size 
    328                 << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 
    329         } 
     273        StdSize true_size = value.numElements(); 
     274        if (this->n.getValue() != true_size) 
     275          ERROR("CAxis::checkAttributes(void)", 
     276              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] " 
     277              << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size 
     278              << ") than the one defined by the \'size\' attribute (" << n.getValue() << ")."); 
    330279        this->hasValue = true; 
    331280      } 
    332281 
    333282      this->checkBounds(); 
    334  
    335       if (context->hasClient) 
    336       { 
    337         this->checkMask(); 
    338         this->checkData(); 
    339         this->checkLabel(); 
    340       } 
     283      this->checkMask(); 
     284      this->checkData(); 
     285      this->checkLabel(); 
     286      initializeLocalElement() ; 
     287      addFullView() ; 
     288      addWorkflowView() ; 
     289      addModelView() ; 
     290 
     291      checkAttributes_done_ = true ; 
    341292   } 
    342293   CATCH_DUMP_ATTR 
     294 
     295 
    343296 
    344297   /*! 
     
    387340        for (int i = 0; i < data_n; ++i) 
    388341        { 
    389           if ((i+data_begin) >= 0 && (i+data_begin<n) && !mask(i+data_begin)) 
    390             data_index(i) = -1; 
     342           if (data_index(i) >= 0 && data_index(i)<n) 
     343             if (!mask(data_index(i))) data_index(i) = -1; 
    391344        } 
    392345      } 
     
    460413  CATCH_DUMP_ATTR 
    461414 
    462   /*! 
    463     Check whether we can do compressed output 
    464   */ 
    465   void CAxis::checkEligibilityForCompressedOutput() 
    466   TRY 
    467   { 
    468     // We don't check if the mask is valid here, just if a mask has been defined at this point. 
    469     isCompressible_ = !mask.isEmpty(); 
    470   } 
    471   CATCH_DUMP_ATTR 
    472  
     415  
    473416  /*! 
    474417    Dispatch event from the lower communication layer then process event according to its type 
     
    482425       switch(event.type) 
    483426       { 
    484           case EVENT_ID_DISTRIBUTION_ATTRIBUTE : 
    485             recvDistributionAttribute(event); 
    486             return true; 
    487             break; 
    488          case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES: 
    489            recvNonDistributedAttributes(event); 
     427         case EVENT_ID_AXIS_DISTRIBUTION: 
     428           recvAxisDistribution(event); 
    490429           return true; 
    491430           break; 
    492          case EVENT_ID_DISTRIBUTED_ATTRIBUTES: 
     431         case EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE: 
    493432           recvDistributedAttributes(event); 
    494433           return true; 
     
    503442  CATCH 
    504443 
    505    /*! 
    506      Check attributes on client side (This name is still adequate???) 
    507    */ 
    508    void CAxis::checkAttributesOnClient() 
    509    TRY 
    510    { 
    511      if (this->areClientAttributesChecked_) return; 
    512  
    513      CContext* context=CContext::getCurrent(); 
    514      if (context->hasClient && !context->hasServer) this->checkAttributes(); 
    515  
    516      this->areClientAttributesChecked_ = true; 
    517    } 
    518    CATCH_DUMP_ATTR 
    519  
    520    /* 
    521      The (spatial) transformation sometimes can change attributes of an axis (e.g zoom can change mask or generate can change whole attributes) 
    522      Therefore, we should recheck them. 
    523    */ 
    524    void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid, 
    525                                                           CServerDistributionDescription::ServerDistributionType distType) 
    526    TRY 
    527    { 
    528      CContext* context=CContext::getCurrent() ; 
    529  
    530      if (this->isClientAfterTransformationChecked) return; 
    531      if (context->hasClient) 
    532      {         
    533        if (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 
    534          computeConnectedClients(globalDim, orderPositionInGrid, distType); 
    535        else if (index.numElements() != n_glo) computeConnectedClients(globalDim, orderPositionInGrid,  CServerDistributionDescription::ROOT_DISTRIBUTION); 
    536      } 
    537  
    538      this->isClientAfterTransformationChecked = true; 
    539    } 
    540    CATCH_DUMP_ATTR 
    541  
    542    /* 
    543      Send all checked attributes to server? (We dont have notion of server any more so client==server) 
    544      \param [in] globalDim global dimension of grid containing this axis 
    545      \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
    546      \param [in] distType distribution type of the server. For now, we only have band distribution. 
    547  
    548    */ 
    549    void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
    550                                      CServerDistributionDescription::ServerDistributionType distType) 
    551    TRY 
    552    { 
    553      if (!this->areClientAttributesChecked_) checkAttributesOnClient(); 
    554      if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation(globalDim, orderPositionInGrid, distType); 
    555      CContext* context = CContext::getCurrent(); 
    556  
    557      if (this->isChecked) return; 
    558      if (context->hasClient) sendAttributes(globalDim, orderPositionInGrid, distType);     
    559  
    560      this->isChecked = true; 
    561    } 
    562    CATCH_DUMP_ATTR 
    563  
    564   /*! 
    565     Send attributes from one client to other clients 
    566     \param[in] globalDim global dimension of grid which contains this axis 
    567     \param[in] order 
    568   */ 
    569   void CAxis::sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
    570                              CServerDistributionDescription::ServerDistributionType distType) 
    571   TRY 
    572   { 
    573      sendDistributionAttribute(globalDim, orderPositionInGrid, distType); 
    574  
    575      // if (index.numElements() == n_glo.getValue()) 
    576      if ((orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType)) 
    577          || (index.numElements() != n_glo)) 
    578      { 
    579        sendDistributedAttributes();        
    580      } 
    581      else 
    582      { 
    583        sendNonDistributedAttributes();     
    584      }      
    585   } 
    586   CATCH_DUMP_ATTR 
    587  
    588   /* 
    589     Compute the connection between group of clients (or clients/servers). 
    590     (E.g: Suppose we have 2 group of clients in two model: A (client role) connect to B (server role), 
    591     this function calculate number of clients B connect to one client of A) 
    592      \param [in] globalDim global dimension of grid containing this axis 
    593      \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
    594      \param [in] distType distribution type of the server. For now, we only have band distribution. 
    595   */ 
    596   void CAxis::computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid, 
    597                                      CServerDistributionDescription::ServerDistributionType distType) 
    598   TRY 
    599   { 
    600     CContext* context = CContext::getCurrent(); 
    601  
    602     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    603  
    604     connectedServerRank_.clear(); 
    605     nbSenders.clear(); 
    606  
    607     for (int p = 0; p < nbSrvPools; ++p) 
    608     { 
    609       CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
    610       int nbServer = client->serverSize; 
    611       int range, clientSize = client->clientSize; 
    612       int rank = client->clientRank; 
    613  
    614       if (connectedServerRank_.find(nbServer) == connectedServerRank_.end()) 
    615       { 
    616         size_t ni = this->n.getValue(); 
    617         size_t ibegin = this->begin.getValue(); 
    618         size_t nbIndex = index.numElements(); 
    619  
    620         // First of all, we should compute the mapping of the global index and local index of the current client 
    621         if (globalLocalIndexMap_.empty()) 
    622         { 
    623           for (size_t idx = 0; idx < nbIndex; ++idx) 
    624           { 
    625             globalLocalIndexMap_[index(idx)] = idx; 
    626           } 
    627         } 
    628  
    629         // Calculate the compressed index if any 
    630 //        std::set<int> writtenInd; 
    631 //        if (isCompressible_) 
    632 //        { 
    633 //          for (int idx = 0; idx < data_index.numElements(); ++idx) 
    634 //          { 
    635 //            int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 
    636 // 
    637 //            if (ind >= 0 && ind < ni && mask(ind)) 
    638 //            { 
    639 //              ind += ibegin; 
    640 //              writtenInd.insert(ind); 
    641 //            } 
    642 //          } 
    643 //        } 
    644  
    645         // Compute the global index of the current client (process) hold 
    646         std::vector<int> nGlobAxis(1); 
    647         nGlobAxis[0] = n_glo.getValue(); 
    648  
    649         size_t globalSizeIndex = 1, indexBegin, indexEnd; 
    650         for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i]; 
    651         indexBegin = 0; 
    652         if (globalSizeIndex <= clientSize) 
    653         { 
    654           indexBegin = rank%globalSizeIndex; 
    655           indexEnd = indexBegin; 
    656         } 
    657         else 
    658         { 
    659           for (int i = 0; i < clientSize; ++i) 
    660           { 
    661             range = globalSizeIndex / clientSize; 
    662             if (i < (globalSizeIndex%clientSize)) ++range; 
    663             if (i == client->clientRank) break; 
    664             indexBegin += range; 
    665           } 
    666           indexEnd = indexBegin + range - 1; 
    667         } 
    668  
    669         CArray<size_t,1> globalIndex(index.numElements()); 
    670         for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    671           globalIndex(idx) = index(idx); 
    672  
    673         // Describe the distribution of server side 
    674  
    675         CServerDistributionDescription serverDescription(nGlobAxis, nbServer, distType); 
    676        
    677         std::vector<int> serverZeroIndex; 
    678         serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0); 
    679  
    680         std::list<int> serverZeroIndexLeader; 
    681         std::list<int> serverZeroIndexNotLeader;  
    682         CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
    683         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    684           *it = serverZeroIndex[*it]; 
    685  
    686         // Find out the connection between client and server side 
    687         CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 
    688         clientServerMap->computeServerIndexMapping(globalIndex, nbServer); 
    689         CClientServerMapping::GlobalIndexMap& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();       
    690  
    691         indSrv_[nbServer].swap(globalIndexAxisOnServer); 
    692  
    693         if (distType==CServerDistributionDescription::ROOT_DISTRIBUTION) 
    694         { 
    695           for(int i=1; i<nbServer; ++i) indSrv_[nbServer].insert(pair<int, vector<size_t> >(i,indSrv_[nbServer][0]) ) ; 
    696           serverZeroIndexLeader.clear() ; 
    697         } 
    698           
    699         CClientServerMapping::GlobalIndexMap::const_iterator it  = indSrv_[nbServer].begin(), 
    700                                                              ite = indSrv_[nbServer].end(); 
    701  
    702         for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first); 
    703  
    704         for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    705           connectedServerRank_[nbServer].push_back(*it); 
    706  
    707          // Even if a client has no index, it must connect to at least one server and  
    708          // send an "empty" data to this server 
    709          if (connectedServerRank_[nbServer].empty()) 
    710           connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 
    711  
    712         nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 
    713  
    714         delete clientServerMap; 
    715       } 
    716     } 
    717   } 
    718   CATCH_DUMP_ATTR 
    719  
    720   /* 
    721     Compute the index of data to write into file 
    722     (Different from the previous version, this version of XIOS allows data be written into file (classical role), 
    723     or transfered to another clients) 
    724   */ 
    725   void CAxis::computeWrittenIndex() 
    726   TRY 
    727   {   
    728     if (computedWrittenIndex_) return; 
    729     computedWrittenIndex_ = true; 
    730  
    731     CContext* context=CContext::getCurrent();       
    732     CContextServer* server = context->server;  
    733  
    734     // We describe the distribution of client (server) on which data are written 
    735     std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 
    736     nBegin[0]       = begin; 
    737     nSize[0]        = n; 
    738     nBeginGlobal[0] = 0;  
    739     nGlob[0]        = n_glo; 
    740     CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
    741     const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
    742  
    743     // Because all written data are local on a client,  
    744     // we need to compute the local index on the server from its corresponding global index 
    745     size_t nbWritten = 0, indGlo;       
    746     std::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
    747                                                         ite = globalLocalIndexMap_.end(), it;           
    748     CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
    749                                      itSrve = writtenGlobalIndex.end(), itSrv;   
    750  
    751     localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 
    752     nbWritten = 0; 
    753     for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    754     { 
    755       indGlo = *itSrv; 
    756       if (ite != globalLocalIndexMap_.find(indGlo)) 
    757       { 
    758         localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 
    759       } 
    760       else 
    761       { 
    762         localIndexToWriteOnServer(nbWritten) = -1; 
    763       } 
    764       ++nbWritten; 
    765     } 
    766  
    767   } 
    768   CATCH_DUMP_ATTR 
    769  
    770   void CAxis::computeWrittenCompressedIndex(MPI_Comm writtenComm) 
    771   TRY 
    772   { 
    773     int writtenCommSize; 
    774     MPI_Comm_size(writtenComm, &writtenCommSize); 
    775     if (compressedIndexToWriteOnServer.find(writtenCommSize) != compressedIndexToWriteOnServer.end()) 
    776       return; 
    777  
    778     if (isCompressible()) 
    779     { 
    780       size_t nbWritten = 0, indGlo; 
    781       CContext* context=CContext::getCurrent();       
    782       CContextServer* server = context->server;  
    783  
    784       // We describe the distribution of client (server) on which data are written 
    785       std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1); 
    786       nBegin[0]       = 0; 
    787       nSize[0]        = n; 
    788       nBeginGlobal[0] = 0;  
    789       nGlob[0]        = n_glo; 
    790       CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
    791       const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
    792       std::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
    793                                                           ite = globalLocalIndexMap_.end(), it;    
    794  
    795       CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
    796                                        itSrve = writtenGlobalIndex.end(), itSrv; 
    797       std::unordered_map<size_t,size_t> localGlobalIndexMap; 
    798       for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    799       { 
    800         indGlo = *itSrv; 
    801         if (ite != globalLocalIndexMap_.find(indGlo)) 
    802         { 
    803           localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 
    804           ++nbWritten; 
    805         }                  
    806       } 
    807 // 
    808 //      nbWritten = 0; 
    809 //      for (int idx = 0; idx < data_index.numElements(); ++idx) 
    810 //      { 
    811 //        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
    812 //        { 
    813 //          ++nbWritten; 
    814 //        } 
    815 //      } 
    816 // 
    817 //      compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 
    818 //      nbWritten = 0; 
    819 //      for (int idx = 0; idx < data_index.numElements(); ++idx) 
    820 //      { 
    821 //        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
    822 //        { 
    823 //          compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)]; 
    824 //          ++nbWritten; 
    825 //        } 
    826 //      } 
    827  
    828       nbWritten = 0; 
    829       for (int idx = 0; idx < data_index.numElements(); ++idx) 
    830       { 
    831         if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
    832         { 
    833           ++nbWritten; 
    834         } 
    835       } 
    836  
    837       compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 
    838       nbWritten = 0; 
    839       for (int idx = 0; idx < data_index.numElements(); ++idx) 
    840       { 
    841         if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx))) 
    842         { 
    843           compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)]; 
    844           ++nbWritten; 
    845         } 
    846       } 
    847  
    848       numberWrittenIndexes_[writtenCommSize] = nbWritten; 
    849  
    850       bool distributed_glo, distributed=isDistributed() ; 
    851       MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, writtenComm) ; 
    852       if (distributed_glo) 
    853       { 
    854               
    855         MPI_Allreduce(&numberWrittenIndexes_[writtenCommSize], &totalNumberWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 
    856         MPI_Scan(&numberWrittenIndexes_[writtenCommSize], &offsetWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 
    857         offsetWrittenIndexes_[writtenCommSize] -= numberWrittenIndexes_[writtenCommSize]; 
    858       } 
    859       else 
    860         totalNumberWrittenIndexes_[writtenCommSize] = numberWrittenIndexes_[writtenCommSize]; 
    861     } 
    862   } 
    863   CATCH_DUMP_ATTR 
    864  
    865   /*! 
    866     Send distribution information from a group of client (client role) to another group of client (server role) 
    867     The distribution of a group of client (server role) is imposed by the group of client (client role) 
    868     \param [in] globalDim global dimension of grid containing this axis 
    869     \param [in] orderPositionInGrid the relative order of this axis in the grid (e.g grid composed of domain+axis -> orderPositionInGrid is 2) 
    870     \param [in] distType distribution type of the server. For now, we only have band distribution. 
    871   */ 
    872   void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid, 
    873                                         CServerDistributionDescription::ServerDistributionType distType) 
    874   TRY 
    875   { 
    876     std::list<CContextClient*>::iterator it; 
    877     for (it=clients.begin(); it!=clients.end(); ++it) 
    878     { 
    879       CContextClient* client = *it; 
    880       int nbServer = client->serverSize; 
    881  
    882       CServerDistributionDescription serverDescription(globalDim, nbServer); 
    883       serverDescription.computeServerDistribution(); 
    884  
    885       std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin(); 
    886       std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes(); 
    887  
    888       CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE); 
    889       if (client->isServerLeader()) 
    890       { 
    891         std::list<CMessage> msgs; 
    892  
    893         const std::list<int>& ranks = client->getRanksServerLeader(); 
    894         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    895         { 
    896           // Use const int to ensure CMessage holds a copy of the value instead of just a reference 
    897           const int begin = serverIndexBegin[*itRank][orderPositionInGrid]; 
    898           const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid]; 
    899  
    900           msgs.push_back(CMessage()); 
    901           CMessage& msg = msgs.back(); 
    902           msg << this->getId(); 
    903           msg << ni << begin; 
    904           msg << isCompressible_;                     
    905  
    906           event.push(*itRank,1,msg); 
    907         } 
    908         client->sendEvent(event); 
    909       } 
    910       else client->sendEvent(event); 
    911     } 
    912   } 
    913   CATCH_DUMP_ATTR 
    914  
    915   /* 
    916     Receive distribution attribute from another client 
    917     \param [in] event event containing data of these attributes 
    918   */ 
    919   void CAxis::recvDistributionAttribute(CEventServer& event) 
    920   TRY 
    921   { 
    922     CBufferIn* buffer = event.subEvents.begin()->buffer; 
    923     string axisId; 
    924     *buffer >> axisId; 
    925     get(axisId)->recvDistributionAttribute(*buffer); 
    926   } 
    927   CATCH 
    928  
    929   /* 
    930     Receive distribution attribute from another client 
    931     \param [in] buffer buffer containing data of these attributes 
    932   */ 
    933   void CAxis::recvDistributionAttribute(CBufferIn& buffer) 
    934   TRY 
    935   { 
    936     int ni_srv, begin_srv; 
    937     buffer >> ni_srv >> begin_srv; 
    938     buffer >> isCompressible_;             
    939  
    940     // Set up new local size of axis on the receiving clients 
    941     n.setValue(ni_srv); 
    942     begin.setValue(begin_srv); 
    943   } 
    944   CATCH_DUMP_ATTR 
    945  
    946   /* 
    947     Send attributes of axis from a group of client to other group of clients/servers  
    948     on supposing that these attributes are not distributed among the sending group 
    949     In the future, if new attributes are added, they should also be processed in this function 
    950   */ 
    951   void CAxis::sendNonDistributedAttributes() 
    952   TRY 
    953   { 
    954     std::list<CContextClient*>::iterator it; 
    955     for (it=clients.begin(); it!=clients.end(); ++it) 
    956         { 
    957           CContextClient* client = *it; 
    958  
    959       CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES); 
    960       size_t nbIndex = index.numElements(); 
    961       size_t nbDataIndex = 0; 
    962  
    963       for (int idx = 0; idx < data_index.numElements(); ++idx) 
    964       { 
    965         int ind = data_index(idx); 
    966         if (ind >= 0 && ind < nbIndex) ++nbDataIndex; 
    967       } 
    968  
    969       CArray<int,1> dataIndex(nbDataIndex); 
    970       nbDataIndex = 0; 
    971       for (int idx = 0; idx < data_index.numElements(); ++idx) 
    972       { 
    973         int ind = data_index(idx); 
    974         if (ind >= 0 && ind < nbIndex) 
    975         { 
    976           dataIndex(nbDataIndex) = ind; 
    977           ++nbDataIndex; 
    978         } 
    979       } 
    980  
    981       if (client->isServerLeader()) 
    982       { 
    983         std::list<CMessage> msgs; 
    984  
    985         const std::list<int>& ranks = client->getRanksServerLeader(); 
    986         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    987         { 
    988           msgs.push_back(CMessage()); 
    989           CMessage& msg = msgs.back(); 
    990           msg << this->getId(); 
    991           msg << index.getValue() << dataIndex << mask.getValue(); 
    992           msg << hasValue; 
    993           if (hasValue) msg << value.getValue(); 
    994           msg << hasBounds; 
    995           if (hasBounds) msg << bounds.getValue(); 
    996           msg << hasLabel; 
    997           if (hasLabel) msg << label.getValue(); 
    998  
    999           event.push(*itRank, 1, msg); 
    1000         } 
    1001         client->sendEvent(event); 
    1002       } 
    1003       else client->sendEvent(event); 
    1004     } 
    1005   } 
    1006   CATCH_DUMP_ATTR 
    1007  
    1008   /* 
    1009     Receive the non-distributed attributes from another group of clients 
    1010     \param [in] event event containing data of these attributes 
    1011   */ 
    1012   void CAxis::recvNonDistributedAttributes(CEventServer& event) 
    1013   TRY 
    1014   { 
    1015     list<CEventServer::SSubEvent>::iterator it; 
    1016     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    1017     { 
    1018       CBufferIn* buffer = it->buffer; 
    1019       string axisId; 
    1020       *buffer >> axisId; 
    1021       get(axisId)->recvNonDistributedAttributes(it->rank, *buffer); 
    1022     } 
    1023   } 
    1024   CATCH 
    1025  
    1026   /* 
    1027     Receive the non-distributed attributes from another group of clients 
    1028     \param [in] rank rank of the sender 
    1029     \param [in] buffer buffer containing data sent from the sender 
    1030   */ 
    1031   void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer) 
    1032   TRY 
    1033   {  
    1034     CArray<int,1> tmp_index, tmp_data_index; 
    1035     CArray<bool,1> tmp_mask; 
    1036     CArray<double,1> tmp_val; 
    1037     CArray<double,2> tmp_bnds; 
    1038     CArray<string,1> tmp_label; 
    1039  
    1040     buffer >> tmp_index; 
    1041     index.reference(tmp_index); 
    1042     buffer >> tmp_data_index; 
    1043     data_index.reference(tmp_data_index); 
    1044     buffer >> tmp_mask; 
    1045     mask.reference(tmp_mask); 
    1046  
    1047     buffer >> hasValue; 
    1048     if (hasValue) 
    1049     { 
    1050       buffer >> tmp_val; 
    1051       value.reference(tmp_val); 
    1052     } 
    1053  
    1054     buffer >> hasBounds; 
    1055     if (hasBounds) 
    1056     { 
    1057       buffer >> tmp_bnds; 
    1058       bounds.reference(tmp_bnds); 
    1059     } 
    1060  
    1061     buffer >> hasLabel; 
    1062     if (hasLabel) 
    1063     { 
    1064       buffer >> tmp_label; 
    1065       label.reference(tmp_label); 
    1066     } 
    1067  
    1068     // Some value should be reset here 
    1069     data_begin.setValue(0); 
    1070     globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
    1071 //    for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx); 
    1072     for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[index(idx)] = idx; 
    1073   } 
    1074   CATCH_DUMP_ATTR 
    1075  
    1076   /* 
    1077     Send axis attributes from a group of clients to another group of clients/servers 
    1078     supposing that these attributes are distributed among the clients of the sending group 
    1079     In future, if new attributes are added, they should also be processed in this function 
    1080   */ 
    1081   void CAxis::sendDistributedAttributes(void) 
    1082   TRY 
    1083   { 
    1084     int ind, idx; 
    1085     std::list<CContextClient*>::iterator it; 
    1086  
    1087     for (it=clients.begin(); it!=clients.end(); ++it) 
    1088     { 
    1089       CContextClient* client = *it; 
    1090       int nbServer = client->serverSize; 
    1091  
    1092       CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES); 
    1093  
    1094       list<CMessage> listData; 
    1095       list<CArray<int,1> > list_indi, list_dataInd; 
    1096       list<CArray<double,1> > list_val; 
    1097       list<CArray<double,2> > list_bounds; 
    1098       list<CArray<string,1> > list_label; 
    1099  
    1100       // Cut off the ghost points 
    1101       int nbIndex = index.numElements(); 
    1102       CArray<int,1> dataIndex(nbIndex); 
    1103       dataIndex = -1; 
    1104       for (idx = 0; idx < data_index.numElements(); ++idx) 
    1105       { 
    1106         if (0 <= data_index(idx) && data_index(idx) < nbIndex) 
    1107           dataIndex(data_index(idx)) = 1; 
    1108       } 
    1109  
    1110       std::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap; 
    1111       iteMap = indSrv_[nbServer].end(); 
    1112       for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k) 
    1113       { 
    1114         int nbData = 0, nbDataCount = 0; 
    1115         int rank = connectedServerRank_[nbServer][k]; 
    1116         it = indSrv_[nbServer].find(rank); 
    1117         if (iteMap != it) 
    1118           nbData = it->second.size(); 
    1119  
    1120         list_indi.push_back(CArray<int,1>(nbData)); 
    1121         list_dataInd.push_back(CArray<int,1>(nbData)); 
    1122  
    1123         if (hasValue) 
    1124           list_val.push_back(CArray<double,1>(nbData)); 
    1125  
    1126         if (hasBounds)         
    1127           list_bounds.push_back(CArray<double,2>(2,nbData)); 
    1128  
    1129         if (hasLabel) 
    1130           list_label.push_back(CArray<string,1>(nbData)); 
    1131  
    1132         CArray<int,1>& indi = list_indi.back(); 
    1133         CArray<int,1>& dataIndi = list_dataInd.back(); 
    1134         dataIndi = -1; 
    1135  
    1136         for (int n = 0; n < nbData; ++n) 
    1137         { 
    1138           idx = static_cast<int>(it->second[n]); 
    1139           indi(n) = idx; 
    1140  
    1141           ind = globalLocalIndexMap_[idx]; 
    1142           dataIndi(n) = dataIndex(ind); 
    1143  
    1144           if (hasValue) 
    1145           { 
    1146             CArray<double,1>& val = list_val.back(); 
    1147             val(n) = value(ind); 
    1148           } 
    1149  
    1150           if (hasBounds) 
    1151           { 
    1152             CArray<double,2>& boundsVal = list_bounds.back(); 
    1153             boundsVal(0, n) = bounds(0,ind); 
    1154             boundsVal(1, n) = bounds(1,ind); 
    1155           } 
    1156  
    1157           if (hasLabel) 
    1158           { 
    1159             CArray<string,1>& labelVal = list_label.back(); 
    1160             labelVal(n) = label(ind);  
    1161           } 
    1162         } 
    1163  
    1164         listData.push_back(CMessage()); 
    1165         listData.back() << this->getId() 
    1166                         << list_indi.back() << list_dataInd.back(); 
    1167  
    1168         listData.back() << hasValue; 
    1169         if (hasValue) 
    1170           listData.back() << list_val.back(); 
    1171  
    1172         listData.back() << hasBounds; 
    1173         if (hasBounds) 
    1174           listData.back() << list_bounds.back(); 
    1175  
    1176         listData.back() << hasLabel; 
    1177         if (hasLabel) 
    1178           listData.back() << list_label.back(); 
    1179  
    1180         eventData.push(rank, nbSenders[nbServer][rank], listData.back()); 
    1181       } 
    1182  
    1183       client->sendEvent(eventData); 
    1184     } 
    1185   } 
    1186   CATCH_DUMP_ATTR 
    1187  
    1188   /* 
    1189     Receive the distributed attributes from another group of clients 
    1190     \param [in] event event containing data of these attributes 
    1191   */ 
    1192   void CAxis::recvDistributedAttributes(CEventServer& event) 
    1193   TRY 
    1194   { 
    1195     string axisId; 
    1196     vector<int> ranks; 
    1197     vector<CBufferIn*> buffers; 
    1198  
    1199     list<CEventServer::SSubEvent>::iterator it; 
    1200     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    1201     { 
    1202       ranks.push_back(it->rank); 
    1203       CBufferIn* buffer = it->buffer; 
    1204       *buffer >> axisId; 
    1205       buffers.push_back(buffer); 
    1206     } 
    1207     get(axisId)->recvDistributedAttributes(ranks, buffers); 
    1208   } 
    1209   CATCH 
    1210  
    1211   /* 
    1212     Receive the non-distributed attributes from another group of clients 
    1213     \param [in] ranks rank of the sender 
    1214     \param [in] buffers buffer containing data sent from the sender 
    1215   */ 
    1216   void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers) 
    1217   TRY 
    1218   { 
    1219     int nbReceived = ranks.size(), idx, ind, gloInd, locInd; 
    1220     vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived); 
    1221     vector<CArray<double,1> > vec_val(nbReceived); 
    1222     vector<CArray<double,2> > vec_bounds(nbReceived); 
    1223     vector<CArray<string,1> > vec_label(nbReceived); 
    1224      
    1225     for (idx = 0; idx < nbReceived; ++idx) 
    1226     {       
    1227       CBufferIn& buffer = *buffers[idx]; 
    1228       buffer >> vec_indi[idx]; 
    1229       buffer >> vec_dataInd[idx];       
    1230  
    1231       buffer >> hasValue; 
    1232       if (hasValue) 
    1233         buffer >> vec_val[idx]; 
    1234  
    1235       buffer >> hasBounds; 
    1236       if (hasBounds) 
    1237         buffer >> vec_bounds[idx]; 
    1238  
    1239       buffer >> hasLabel; 
    1240       if (hasLabel) 
    1241         buffer >> vec_label[idx];  
    1242     } 
    1243  
    1244     // Estimate size of index array 
    1245     int nbIndexGlob = 0; 
    1246     for (idx = 0; idx < nbReceived; ++idx) 
    1247     { 
    1248       nbIndexGlob += vec_indi[idx].numElements(); 
    1249     } 
    1250  
    1251     // Recompute global index 
    1252     // Take account of the overlapped index  
    1253     index.resize(nbIndexGlob); 
    1254     globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor())); 
    1255     nbIndexGlob = 0; 
    1256     int nbIndLoc = 0; 
    1257     for (idx = 0; idx < nbReceived; ++idx) 
    1258     { 
    1259       CArray<int,1>& tmp = vec_indi[idx]; 
    1260       for (ind = 0; ind < tmp.numElements(); ++ind) 
    1261       { 
    1262          gloInd = tmp(ind); 
    1263          nbIndLoc = (gloInd % n_glo)-begin; 
    1264          if (0 == globalLocalIndexMap_.count(gloInd)) 
    1265          { 
    1266            index(nbIndexGlob) = gloInd % n_glo; 
    1267            globalLocalIndexMap_[gloInd] = nbIndexGlob; 
    1268            ++nbIndexGlob; 
    1269          }  
    1270       }  
    1271     } 
    1272  
    1273     // Resize index to its real size 
    1274     if (nbIndexGlob==0) index.resize(nbIndexGlob) ; 
    1275     else index.resizeAndPreserve(nbIndexGlob); 
    1276  
    1277     int nbData = nbIndexGlob; 
    1278     CArray<int,1> nonCompressedData(nbData); 
    1279     nonCompressedData = -1;    
    1280     // Mask is incorporated into data_index and is not sent/received anymore 
    1281     mask.resize(0); 
    1282     if (hasValue) 
    1283       value.resize(nbData); 
    1284     if (hasBounds) 
    1285       bounds.resize(2,nbData); 
    1286     if (hasLabel) 
    1287       label.resize(nbData); 
    1288  
    1289     nbData = 0; 
    1290     for (idx = 0; idx < nbReceived; ++idx) 
    1291     { 
    1292       CArray<int,1>& indi = vec_indi[idx]; 
    1293       CArray<int,1>& dataIndi = vec_dataInd[idx]; 
    1294       int nb = indi.numElements(); 
    1295       for (int n = 0; n < nb; ++n) 
    1296       {  
    1297         locInd = globalLocalIndexMap_[size_t(indi(n))]; 
    1298  
    1299         nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd); 
    1300  
    1301         if (hasValue) 
    1302           value(locInd) = vec_val[idx](n); 
    1303  
    1304         if (hasBounds) 
    1305         { 
    1306           bounds(0,locInd) = vec_bounds[idx](0,n); 
    1307           bounds(1,locInd) = vec_bounds[idx](1,n); 
    1308         } 
    1309  
    1310         if (hasLabel) 
    1311           label(locInd) = vec_label[idx](n); 
    1312       } 
    1313     } 
    1314      
    1315     int nbCompressedData = 0; 
    1316     for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 
    1317     { 
    1318       if (0 <= nonCompressedData(idx)) 
    1319         ++nbCompressedData; 
    1320     } 
    1321  
    1322     data_index.resize(nbCompressedData); 
    1323     nbCompressedData = 0; 
    1324     for (idx = 0; idx < nonCompressedData.numElements(); ++idx) 
    1325     { 
    1326       if (0 <= nonCompressedData(idx)) 
    1327       { 
    1328         data_index(nbCompressedData) = idx % n; 
    1329         ++nbCompressedData; 
    1330       } 
    1331     } 
    1332  
    1333     data_begin.setValue(0); 
    1334     data_n.setValue(data_index.numElements()); 
    1335   } 
    1336   CATCH_DUMP_ATTR 
    1337  
     444   /* to remove later when reimplementing coupling */ 
     445   void CAxis::sendAxisToCouplerOut(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid, const string& fieldId, int posInGrid) 
     446   { 
     447     if (sendAxisToCouplerOut_done_.count(client)!=0) return ; 
     448     else sendAxisToCouplerOut_done_.insert(client) ; 
     449      
     450     string axisId="_axis["+std::to_string(posInGrid)+"]_of_"+fieldId ; 
     451 
     452    } 
     453 
     454  void CAxis::makeAliasForCoupling(const string& fieldId, int posInGrid) 
     455  { 
     456    const string axisId = "_axis["+std::to_string(posInGrid)+"]_of_"+fieldId ; 
     457    this->createAlias(axisId) ; 
     458  } 
     459 
     460   
    1338461  /*! 
    1339462    Compare two axis objects.  
     
    1432555   * Go through the hierarchy to find the axis from which the transformations must be inherited 
    1433556   */ 
    1434   void CAxis::solveInheritanceTransformation() 
     557  void CAxis::solveInheritanceTransformation_old() 
    1435558  TRY 
    1436559  { 
     
    1449572      for (size_t i = 0; i < refAxis.size(); ++i) 
    1450573        refAxis[i]->setTransformations(axis->getAllTransformations()); 
     574  } 
     575  CATCH_DUMP_ATTR 
     576 
     577  void CAxis::solveInheritanceTransformation() 
     578  TRY 
     579  { 
     580    if (solveInheritanceTransformation_done_) return; 
     581    else solveInheritanceTransformation_done_=true ; 
     582 
     583    CAxis* axis = this; 
     584    std::list<CAxis*> refAxis; 
     585    bool out=false ; 
     586    vector<StdString> excludedAttr; 
     587    excludedAttr.push_back("axis_ref"); 
     588     
     589    refAxis.push_front(axis) ; 
     590    while (axis->hasDirectAxisReference() && !out) 
     591    { 
     592      CAxis* lastAxis=axis ; 
     593      axis = axis->getDirectAxisReference(); 
     594      axis->solveRefInheritance() ; 
     595      if (!axis->SuperClass::isEqual(lastAxis,excludedAttr)) out=true ; 
     596      refAxis.push_front(axis) ; 
     597    } 
     598 
     599    CTransformationPaths::TPath path ; 
     600    auto& pathList = std::get<2>(path) ; 
     601    std::get<0>(path) = EElement::AXIS ; 
     602    std::get<1>(path) = refAxis.front()->getId() ; 
     603    for (auto& axis : refAxis) 
     604    { 
     605      CAxis::TransMapTypes transformations = axis->getAllTransformations(); 
     606      for(auto& transformation : transformations) pathList.push_back({transformation.second->getTransformationType(),  
     607                                                                      transformation.second->getId()}) ; 
     608    } 
     609    transformationPaths_.addPath(path) ; 
     610 
    1451611  } 
    1452612  CATCH_DUMP_ATTR 
     
    1497657  CATCH_DUMP_ATTR 
    1498658 
     659 
     660   ////////////////////////////////////////////////////////////////////////////////////// 
     661   //  this part is related to distribution, element definition, views and connectors  // 
     662   ////////////////////////////////////////////////////////////////////////////////////// 
     663 
     664   void CAxis::initializeLocalElement(void) 
     665   { 
     666      // after checkAttribute index of size n 
     667      int rank = CContext::getCurrent()->getIntraCommRank() ; 
     668       
     669      CArray<size_t,1> ind(n) ; 
     670      for (int i=0;i<n;i++) ind(i)=index(i) ; 
     671 
     672      localElement_ = new CLocalElement(rank, n_glo, ind) ; 
     673   } 
     674 
     675   void CAxis::addFullView(void) 
     676   { 
     677      CArray<int,1> index(n) ; 
     678      for(int i=0; i<n ; i++) index(i)=i ; 
     679      localElement_ -> addView(CElementView::FULL, index) ; 
     680   } 
     681 
     682   void CAxis::addWorkflowView(void) 
     683   { 
     684     // mask + data are included into data_index 
     685     int nk=data_index.numElements() ; 
     686     int nMask=0 ; 
     687     for(int k=0;k<nk;k++) if (data_index(k)>=0 && data_index(k)<n) nMask++ ; 
     688      
     689     CArray<int,1> index(nMask) ; 
     690     nMask=0 ; 
     691     for(int k=0;k<nk;k++)  
     692       if (data_index(k)>=0 && data_index(k)<n)  
     693       { 
     694         index(nMask) = data_index(k) ; 
     695         nMask++ ; 
     696       } 
     697     localElement_ -> addView(CElementView::WORKFLOW, index) ; 
     698   } 
     699 
     700   void CAxis::addModelView(void) 
     701   { 
     702     // information for model view is stored in data_index 
     703     localElement_->addView(CElementView::MODEL, data_index) ; 
     704   } 
     705 
     706   void CAxis::computeModelToWorkflowConnector(void) 
     707   {  
     708     CLocalView* srcView=getLocalView(CElementView::MODEL) ; 
     709     CLocalView* dstView=getLocalView(CElementView::WORKFLOW) ; 
     710     modelToWorkflowConnector_ = new CLocalConnector(srcView, dstView);  
     711     modelToWorkflowConnector_->computeConnector() ; 
     712   } 
     713 
     714 
     715   void CAxis::computeRemoteElement(CContextClient* client, EDistributionType type) 
     716  { 
     717    CContext* context = CContext::getCurrent(); 
     718    map<int, CArray<size_t,1>> globalIndex ; 
     719 
     720    if (type==EDistributionType::BANDS) // Bands distribution to send to file server 
     721    { 
     722      int nbServer = client->serverSize; 
     723      int nbClient = client->clientSize ; 
     724      int rankClient = client->clientRank ; 
     725      int size = nbServer / nbClient ; 
     726      int start ; 
     727      if (nbServer%nbClient > rankClient) 
     728      { 
     729       start = (size+1) * rankClient ; 
     730       size++ ; 
     731      } 
     732      else start = size*rankClient + nbServer%nbClient ; 
     733      
     734      for(int i=0; i<size; i++) 
     735      {  
     736        int rank=start+i ;  
     737        size_t indSize = n_glo/nbServer ; 
     738        size_t indStart ; 
     739        if (n_glo % nbServer > rank) 
     740        { 
     741          indStart = (indSize+1) * rank ; 
     742          indSize++ ; 
     743        } 
     744        else indStart = indSize*rank + n_glo%nbServer ; 
     745        
     746        auto& globalInd =  globalIndex[rank] ; 
     747        globalInd.resize(indSize) ; 
     748        for(size_t n = 0 ; n<indSize; n++) globalInd(n)=indStart+n ; 
     749      } 
     750    } 
     751    else if (type==EDistributionType::NONE) // domain is not distributed ie all servers get the same local domain 
     752    { 
     753      int nbServer = client->serverSize; 
     754      size_t nglo=n_glo ; 
     755      CArray<size_t,1> indGlo(nglo) ; 
     756      for(size_t i=0;i<nglo;i++) indGlo(i) = i ; 
     757      for (auto& rankServer : client->getRanksServerLeader()) globalIndex[rankServer].reference(indGlo.copy());  
     758    } 
     759    remoteElement_[client] = new CDistributedElement(n_glo, globalIndex) ; 
     760    remoteElement_[client]->addFullView() ; 
     761  } 
     762  
     763  void CAxis::distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex,  
     764                                 CScattererConnector* &scattererConnector, const string& axisId) 
     765  { 
     766    string serverAxisId = axisId.empty() ? this->getId() : axisId ; 
     767    CContext* context = CContext::getCurrent(); 
     768 
     769    this->sendAllAttributesToServer(client, serverAxisId)  ; 
     770 
     771    CDistributedElement scatteredElement(n_glo,globalIndex) ; 
     772    scatteredElement.addFullView() ; 
     773    scattererConnector = new CScattererConnector(localElement_->getView(CElementView::FULL), scatteredElement.getView(CElementView::FULL),  
     774                                                 context->getIntraComm(), client->getRemoteSize()) ; 
     775    scattererConnector->computeConnector() ; 
     776     
     777    // phase 0 
     778    // send remote element to construct the full view on server, ie without hole  
     779    CEventClient event0(getType(), EVENT_ID_AXIS_DISTRIBUTION); 
     780    CMessage message0 ; 
     781    message0<<serverAxisId<<0 ;  
     782    remoteElement_[client]->sendToServer(client,event0,message0) ;  
     783     
     784    // phase 1 
     785    // send the full view of element to construct the connector which connect distributed data coming from client to the full local view 
     786    CEventClient event1(getType(), EVENT_ID_AXIS_DISTRIBUTION); 
     787    CMessage message1 ; 
     788    message1<<serverAxisId<<1<<localElement_->getView(CElementView::FULL)->getGlobalSize() ;  
     789    scattererConnector->transfer(localElement_->getView(CElementView::FULL)->getGlobalIndex(),client,event1,message1) ; 
     790 
     791    sendDistributedAttributes(client, *scattererConnector, axisId) ; 
     792   
     793    // phase 2 send the mask : data index + mask2D 
     794    CArray<bool,1> maskIn(localElement_->getView(CElementView::WORKFLOW)->getSize()); 
     795    CArray<bool,1> maskOut ; 
     796    CLocalConnector workflowToFull(localElement_->getView(CElementView::WORKFLOW), localElement_->getView(CElementView::FULL)) ; 
     797    workflowToFull.computeConnector() ; 
     798    maskIn=true ; 
     799    workflowToFull.transfer(maskIn,maskOut,false) ; 
     800 
     801    // phase 3 : prepare grid scatterer connector to send data from client to server 
     802    map<int,CArray<size_t,1>> workflowGlobalIndex ; 
     803    map<int,CArray<bool,1>> maskOut2 ;  
     804    scattererConnector->transfer(maskOut, maskOut2) ; 
     805    scatteredElement.addView(CElementView::WORKFLOW, maskOut2) ; 
     806    scatteredElement.getView(CElementView::WORKFLOW)->getGlobalIndexView(workflowGlobalIndex) ; 
     807    // create new workflow view for scattered element 
     808    CDistributedElement clientToServerElement(scatteredElement.getGlobalSize(), workflowGlobalIndex) ; 
     809    clientToServerElement.addFullView() ; 
     810    CEventClient event2(getType(), EVENT_ID_AXIS_DISTRIBUTION); 
     811    CMessage message2 ; 
     812    message2<<serverAxisId<<2 ;  
     813    clientToServerElement.sendToServer(client, event2, message2) ;  
     814    clientToServerConnector_[client] = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW), clientToServerElement.getView(CElementView::FULL),  
     815                                                              context->getIntraComm(), client->getRemoteSize()) ; 
     816    clientToServerConnector_[client]->computeConnector() ; 
     817 
     818    clientFromServerConnector_[client] = new CGathererConnector(clientToServerElement.getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)); 
     819    clientFromServerConnector_[client]->computeConnector() ; 
     820 
     821 
     822  } 
     823 
     824  void CAxis::recvAxisDistribution(CEventServer& event) 
     825  TRY 
     826  { 
     827    string axisId; 
     828    int phasis ; 
     829    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> axisId >> phasis ; 
     830    get(axisId)->receivedAxisDistribution(event, phasis); 
     831  } 
     832  CATCH 
     833 
     834 
     835  void CAxis::receivedAxisDistribution(CEventServer& event, int phasis) 
     836  TRY 
     837  { 
     838    CContext* context = CContext::getCurrent(); 
     839    if (phasis==0) // receive the remote element to construct the full view 
     840    { 
     841      localElement_ = new  CLocalElement(context->getIntraCommRank(),event) ; 
     842      localElement_->addFullView() ; 
     843      // construct the local dimension and indexes 
     844      auto& globalIndex=localElement_->getGlobalIndex() ; 
     845      int nk=globalIndex.numElements() ; 
     846      int minK=n_glo,maxK=-1 ; 
     847      int nGlo=n_glo ; 
     848      int indGlo ; 
     849      for(int k=0;k<nk;k++) 
     850      { 
     851        indGlo=globalIndex(k) ; 
     852        if (indGlo<minK) minK=indGlo ; 
     853        if (indGlo>maxK) maxK=indGlo ; 
     854      }   
     855      if (maxK>=minK) { begin=minK ; n=maxK-minK+1 ; } 
     856      else {begin=0; n=0 ;} 
     857 
     858    } 
     859    else if (phasis==1) // receive the sent view from client to construct the full distributed full view on server 
     860    { 
     861      CContext* context = CContext::getCurrent(); 
     862      CDistributedElement* elementFrom = new  CDistributedElement(event) ; 
     863      elementFrom->addFullView() ; 
     864      gathererConnector_ = new CGathererConnector(elementFrom->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ; 
     865      gathererConnector_->computeConnector() ;  
     866    } 
     867    else if (phasis==2) 
     868    { 
     869//      delete gathererConnector_ ; 
     870      elementFrom_ = new  CDistributedElement(event) ; 
     871      elementFrom_->addFullView() ; 
     872//      gathererConnector_ =  new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ; 
     873//      gathererConnector_ -> computeConnector() ; 
     874    } 
     875   
     876  } 
     877  CATCH 
     878 
     879  void CAxis::setServerMask(CArray<bool,1>& serverMask, CContextClient* client) 
     880  TRY 
     881  { 
     882    CContext* context = CContext::getCurrent(); 
     883    localElement_->addView(CElementView::WORKFLOW, serverMask) ; 
     884    mask.reference(serverMask.copy()) ; 
     885  
     886    serverFromClientConnector_ = new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)) ; 
     887    serverFromClientConnector_->computeConnector() ; 
     888       
     889    serverToClientConnector_ = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW), elementFrom_->getView(CElementView::FULL), 
     890                                                         context->getIntraComm(), client->getRemoteSize()) ; 
     891    serverToClientConnector_->computeConnector() ; 
     892  } 
     893  CATCH_DUMP_ATTR 
     894 
     895  void CAxis::sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector, const string& axisId) 
     896  { 
     897    string serverAxisId = axisId.empty() ? this->getId() : axisId ; 
     898    CContext* context = CContext::getCurrent(); 
     899 
     900    if (hasValue) 
     901    { 
     902      { // send level value 
     903        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     904        CMessage message ; 
     905        message<<serverAxisId<<string("value") ;  
     906        scattererConnector.transfer(value, client, event,message) ; 
     907      } 
     908    } 
     909 
     910    if (hasBounds) 
     911    { 
     912      { // send bounds level value 
     913        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     914        CMessage message ; 
     915        message<<serverAxisId<<string("bounds") ;  
     916        scattererConnector.transfer(2, bounds, client, event,message) ; 
     917      } 
     918    } 
     919 
     920    if (hasLabel) 
     921    { 
     922      { // send label 
     923        // need to transform array of string (no fixed size for string) into array of array of char 
     924        // to use connector to transfer 
     925        // the strings must have fixed size which the maximum lenght over the string label.   
     926        int maxSize=0 ; 
     927        for(int i=0; i<label.numElements();i++)  
     928          if (maxSize < label(i).size()) maxSize=label(i).size() ; 
     929        MPI_Allreduce(MPI_IN_PLACE, &maxSize,1,MPI_INT,MPI_MAX, context->getIntraComm()) ; 
     930        maxSize=maxSize+1 ; 
     931        CArray<char,2> charArray(maxSize,label.numElements()) ; 
     932        for(int j=0; j<label.numElements();j++)  
     933        { 
     934          const char* str = label(j).c_str() ; 
     935          int strSize=label(j).size()+1 ; 
     936          for(int i=0; i<strSize; i++) charArray(i,j) = str[i] ; 
     937        } 
     938        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     939        CMessage message ; 
     940        message<<serverAxisId<<string("label")<<maxSize ; 
     941        scattererConnector.transfer(maxSize, charArray, client, event,message) ; 
     942      } 
     943    } 
     944  } 
     945 
     946  void CAxis::recvDistributedAttributes(CEventServer& event) 
     947  TRY 
     948  { 
     949    string axisId; 
     950    string type ; 
     951    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> axisId >> type ; 
     952    get(axisId)->recvDistributedAttributes(event, type); 
     953  } 
     954  CATCH 
     955 
     956  void CAxis::recvDistributedAttributes(CEventServer& event, const string& type) 
     957  TRY 
     958  { 
     959    if (type=="value")  
     960    { 
     961      gathererConnector_->transfer(event, value, 0.);  
     962    } 
     963    else if (type=="bounds") 
     964    { 
     965      CArray<double,1> value ; 
     966      gathererConnector_->transfer(event, 2, value, 0.);  
     967      bounds.resize(2,n) ; 
     968      if (bounds.numElements() > 0 ) bounds=CArray<double,2>(value.dataFirst(),shape(2,n),neverDeleteData) ;  
     969    } 
     970    else if (type=="label") 
     971    { 
     972      int maxSize ; 
     973      for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> maxSize ; 
     974      CArray<char,1> value ; 
     975      gathererConnector_->transfer(event, maxSize, value, '\0');  
     976      CArray<char,2> charArray(maxSize,n) ; 
     977      label.resize(n) ; 
     978      if (n>0) 
     979      { 
     980        charArray=CArray<char,2>(value.dataFirst(),shape(maxSize,n),neverDeleteData) ; 
     981        for(int j=0;j<n;j++) 
     982        { 
     983          int strSize ; 
     984          for(int i=0;i<maxSize;i++)  
     985            if (charArray(i,j)=='\0') { strSize=i ; break; } 
     986          string str(strSize,'\0') ; 
     987          for(int i=0;i<strSize;i++) str[i]=charArray(i,j) ;  
     988          label(j)=str ; 
     989        } 
     990      }  
     991    } 
     992  } 
     993  CATCH 
     994 
    1499995  DEFINE_REF_FUNC(Axis,axis) 
    1500996 
  • XIOS/dev/dev_trunk_graph/src/node/axis.hpp

    r1653 r2019  
    1616#include "transformation.hpp" 
    1717#include "transformation_enum.hpp" 
    18  
    19 namespace xios { 
     18#include "transformation_path.hpp" 
     19#include "element.hpp" 
     20#include "local_connector.hpp" 
     21#include "scatterer_connector.hpp" 
     22#include "gatherer_connector.hpp" 
     23#include "distribution_type.hpp" 
     24#include "generic_algorithm_transformation.hpp" 
     25 
     26 
     27namespace xios 
     28{ 
    2029   /// ////////////////////// Déclarations ////////////////////// /// 
    2130 
     
    4453         enum EEventId 
    4554         { 
    46            EVENT_ID_DISTRIBUTION_ATTRIBUTE,            
    47            EVENT_ID_DISTRIBUTED_VALUE, 
    48            EVENT_ID_NON_DISTRIBUTED_VALUE, 
    49            EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES, 
    50            EVENT_ID_DISTRIBUTED_ATTRIBUTES 
     55           EVENT_ID_AXIS_DISTRIBUTION, 
     56           EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE 
    5157         } ; 
    5258 
     
    5460         typedef CAxisAttributes RelAttributes; 
    5561         typedef CAxisGroup      RelGroup; 
    56          typedef CTransformation<CAxis>::TransformationMapTypes TransMapTypes; 
    5762 
    5863      public: 
     
    6772         /// Accesseurs /// 
    6873         const std::set<StdString> & getRelFiles(void) const; 
    69  
    70          int getNumberWrittenIndexes(MPI_Comm writtenCom); 
    71          int getTotalNumberWrittenIndexes(MPI_Comm writtenCom); 
    72          int getOffsetWrittenIndexes(MPI_Comm writtenCom); 
    73          CArray<int, 1>& getCompressedIndexToWriteOnServer(MPI_Comm writtenCom); 
    74  
     74  
    7575         std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid, 
    7676                                                        CServerDistributionDescription::ServerDistributionType disType = CServerDistributionDescription::BAND_DISTRIBUTION); 
     
    8080         bool isWrittenCompressed(const StdString& filename) const; 
    8181         bool isDistributed(void) const; 
    82          bool isCompressible(void) const; 
     82         
     83      public: 
     84        /*! 
     85            \brief return if the axis can be written or not in a compressed way. 
     86            ie if there are some masked or indexed point on the domain. Valid only on server side. 
     87            \return true if domain can be writtedn in a compressed way 
     88         */  
     89         bool isCompressible(void) { if (!isCompressibleComputed_) computeIsCompressible() ; return isCompressible_ ;}  
     90      private: 
     91         bool isCompressible_ ; /** specify if the domain can be written in a compressed way */  
     92         bool isCompressibleComputed_=false ; /** Indicate if compressability has been computed*/ 
     93         void computeIsCompressible() ; 
     94         
     95      public: 
    8396 
    8497         /// Mutateur /// 
     
    8699         void addRelFileCompressed(const StdString& filename); 
    87100 
    88          /// Vérifications /// 
    89          void checkAttributes(void); 
     101          
    90102 
    91103         /// Destructeur /// 
     
    102114 
    103115         static bool dispatchEvent(CEventServer& event);          
    104           
    105          void checkAttributesOnClient(); 
    106          void checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid, 
    107                                                          CServerDistributionDescription::ServerDistributionType distType = CServerDistributionDescription::BAND_DISTRIBUTION); 
    108          void sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
    109                                     CServerDistributionDescription::ServerDistributionType disType = CServerDistributionDescription::BAND_DISTRIBUTION); 
    110  
    111          void checkEligibilityForCompressedOutput(); 
     116         
     117         /// Vérifications /// 
     118         void checkAttributes(void); 
     119         bool checkAttributes_done_ = false ; 
     120 
    112121         size_t getGlobalWrittenSize(void) ; 
    113122 
    114          void computeWrittenIndex(); 
    115          void computeWrittenCompressedIndex(MPI_Comm); 
    116          bool hasTransformation(); 
    117          void solveInheritanceTransformation(); 
    118          TransMapTypes getAllTransformations();          
    119          void duplicateTransformation(CAxis*); 
    120          CTransformation<CAxis>* addTransformation(ETranformationType transType, const StdString& id=""); 
     123      ////////////////////////// 
     124      ///// transformations //// 
     125      ////////////////////////// 
     126      public: 
     127        typedef CTransformation<CAxis>::TransformationMapTypes TransMapTypes; 
     128      private: 
     129        static bool initializeTransformationMap(std::map<StdString, ETranformationType>& m); 
     130        static std::map<StdString, ETranformationType> transformationMapList_; 
     131        static bool dummyTransformationMapList_; 
     132        TransMapTypes transformationMap_;          
     133 
     134      public: 
     135        CTransformation<CAxis>* addTransformation(ETranformationType transType, const StdString& id=""); 
     136        CTransformation<CAxis>* addTransformation(ETranformationType transType, CTransformation<CAxis>* transformation) ; 
     137        void setTransformations(const TransMapTypes&);          
     138        void duplicateTransformation(CAxis*); 
     139        TransMapTypes getAllTransformations(); 
     140        bool hasTransformation(); 
     141        void solveInheritanceTransformation_old(); // to remove later 
     142        void solveInheritanceTransformation(); 
     143      private: 
     144        bool solveInheritanceTransformation_done_= false ; 
     145      private: 
     146        CGenericAlgorithmTransformation* transformationAlgorithm_ = nullptr ; 
     147      public: 
     148        void setTransformationAlgorithm(CGenericAlgorithmTransformation* transformationAlgorithm) { transformationAlgorithm_=transformationAlgorithm ;} 
     149        CGenericAlgorithmTransformation* getTransformationAlgorithm(void) { return transformationAlgorithm_ ;}    
     150      private: 
     151        CTransformationPaths transformationPaths_ ; 
     152      public: 
     153        CTransformationPaths getTransformationPaths(void) {return transformationPaths_;}  
     154        void setTransformationPaths(const CTransformationPaths& transformationPaths) { transformationPaths_=transformationPaths ;} 
     155 
     156      //////////////////////////// 
    121157         bool isEqual(CAxis* axis); 
    122158 
     
    126162        bool hasLabel; 
    127163 
    128         CArray<int,1> localIndexToWriteOnServer; 
    129  
    130164      private: 
    131165         void checkData(); 
     
    133167         void checkBounds(); 
    134168         void checkLabel(); 
    135          void sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid, 
    136                              CServerDistributionDescription::ServerDistributionType distType); 
    137          void sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid, 
    138                                         CServerDistributionDescription::ServerDistributionType distType); 
    139          void computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid, 
    140                                      CServerDistributionDescription::ServerDistributionType distType); 
    141  
    142          void sendNonDistributedAttributes(void); 
    143          void sendDistributedAttributes(void); 
    144  
    145          static void recvNonDistributedAttributes(CEventServer& event); 
    146          static void recvDistributedAttributes(CEventServer& event); 
    147          static void recvDistributionAttribute(CEventServer& event); 
    148          void recvNonDistributedAttributes(int rank, CBufferIn& buffer); 
    149          void recvDistributedAttributes(vector<int>& rank, vector<CBufferIn*> buffers); 
    150          void recvDistributionAttribute(CBufferIn& buffer); 
    151  
    152          void setTransformations(const TransMapTypes&); 
    153  
    154       private: 
    155  
    156 /** Clients that have to send a domain. There can be multiple clients in case of secondary server, otherwise only one client. */ 
     169       
     170      public: 
     171         void sendAxisToCouplerOut(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid, const string& fieldId, int posInGrid) ; 
     172      private: 
     173         std::set<CContextClient*> sendAxisToCouplerOut_done_ ; 
     174     
     175      public: 
     176         void makeAliasForCoupling(const string& fieldId, int posInGrid) ; 
     177 
     178 
     179      private: 
     180 
     181/** Clients that have to send a axis. There can be multiple clients in case of secondary server, otherwise only one client. */ 
    157182         std::list<CContextClient*> clients; 
    158183         std::set<CContextClient*> clientsSet; 
    159184 
     185      private: 
     186         /** define if the axis is completed or not ie all attributes have been received before in case  
     187             of grid reading from file or coupling */  
     188         bool isCompleted_=true ;   
     189      public:      
     190         /*! 
     191           \brief Check if a axis is completed 
     192           Before make any axis processing, we must be sure that all axis informations have 
     193           been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     194           other context (coupling). So all direct reference of the axis (axis_ref) must be also completed 
     195           \return true if axis and axis reference are completed 
     196          */ 
     197         bool isCompleted(void) 
     198         { 
     199           if (hasDirectAxisReference()) if (!getDirectAxisReference()->isCompleted()) return false; 
     200           else return isCompleted_ ; 
     201         } 
     202         void setCompleted(void) { isCompleted_=true ; } 
     203         void unsetCompleted(void) { isCompleted_=false ; } 
     204       
     205      private: 
    160206         bool isChecked; 
    161          bool areClientAttributesChecked_; 
    162          bool isClientAfterTransformationChecked; 
    163207         std::set<StdString> relFiles, relFilesCompressed; 
    164          TransMapTypes transformationMap_;          
    165          //! True if and only if the data defined on the axis can be outputted in a compressed way 
    166          bool isCompressible_; 
    167          std::map<int, map<int,int> > nbSenders; // Mapping of number of communicating client to a server 
    168          std::map<int, std::unordered_map<int, vector<size_t> > > indSrv_; // Global index of each client sent to server 
    169          // std::map<int, vector<int> > indWrittenSrv_; // Global written index of each client sent to server 
    170          std::unordered_map<size_t,size_t> globalLocalIndexMap_; 
    171          std::vector<int> indexesToWrite; 
    172          std::map<int,int> numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_; 
    173          std::map<int, CArray<int, 1> > compressedIndexToWriteOnServer; 
     208          std::map<int, std::unordered_map<int, vector<size_t> > > indSrv_; // Global index of each client sent to server 
    174209         std::map<int, std::vector<int> > connectedServerRank_; 
    175          bool computedWrittenIndex_;                   
    176  
    177        private: 
    178          static bool initializeTransformationMap(std::map<StdString, ETranformationType>& m); 
    179          static std::map<StdString, ETranformationType> transformationMapList_; 
    180          static bool dummyTransformationMapList_; 
     210 
     211       ////////////////////////////////////////////////////////////////////////////////////// 
     212       //  this part is related to distribution, element definition, views and connectors  // 
     213       ////////////////////////////////////////////////////////////////////////////////////// 
     214          
     215        private: 
     216         CLocalElement* localElement_ = nullptr ; 
     217         void initializeLocalElement(void) ; 
     218        public:  
     219         CLocalElement* getLocalElement(void) { if (localElement_==nullptr) initializeLocalElement() ; return localElement_ ; } 
     220         CLocalView* getLocalView(CElementView::type type) { return getLocalElement()->getView(type) ;} 
     221        private: 
     222         void addFullView(void) ; 
     223         void addWorkflowView(void) ; 
     224         void addModelView(void) ; 
     225 
     226        private: 
     227         CLocalConnector* modelToWorkflowConnector_ ; 
     228         void computeModelToWorkflowConnector(void)  ; 
     229        public: 
     230         CLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_ ;} 
     231        
     232       public: 
     233         void computeRemoteElement(CContextClient* client, EDistributionType) ; 
     234         void distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex, CScattererConnector* &scattererConnector, 
     235                                 const string& axisId="") ; 
     236 
     237         static void recvAxisDistribution(CEventServer& event) ; 
     238         void receivedAxisDistribution(CEventServer& event, int phasis) ; 
     239         void setServerMask(CArray<bool,1>& serverMask, CContextClient* client ) ; 
     240         void sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector, const string& axisId) ; 
     241         static void recvDistributedAttributes(CEventServer& event) ; 
     242         void recvDistributedAttributes(CEventServer& event, const string& type) ; 
     243       private: 
     244         map<CContextClient*, CDistributedElement*> remoteElement_ ; 
     245       public:  
     246         CDistributedElement* getRemoteElement(CContextClient* client) {return remoteElement_[client] ;} 
     247       private: 
     248         map<CContextClient*, CScattererConnector*> clientToServerConnector_ ; 
     249       public:  
     250         CScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;} 
     251       private: 
     252         CGathererConnector*  gathererConnector_ ; 
     253       public: 
     254         CGathererConnector* getGathererConnector(void) { return gathererConnector_ ;} 
     255       private: 
     256         CGathererConnector* serverFromClientConnector_ ; 
     257         CDistributedElement* elementFrom_ ; 
     258       public: 
     259        CGathererConnector* getServerFromClientConnector(void) { return serverFromClientConnector_ ;} 
     260 
     261       private: 
     262         CScattererConnector*  serverToClientConnector_ = nullptr ; 
     263       public:  
     264         CScattererConnector* getServerToClientConnector(void) { return serverToClientConnector_ ;}  
     265 
     266       private: 
     267          map<CContextClient*,CGathererConnector*>  clientFromServerConnector_  ; 
     268       public:  
     269         CGathererConnector* getClientFromServerConnector(CContextClient* client) { return clientFromServerConnector_[client] ;}  
    181270 
    182271         DECLARE_REF_FUNC(Axis,axis) 
  • XIOS/dev/dev_trunk_graph/src/node/compute_connectivity_domain.cpp

    r944 r2019  
    11#include "compute_connectivity_domain.hpp" 
     2#include "domain_algorithm_compute_connectivity.hpp" 
    23#include "type.hpp" 
    34 
     
    2728  bool CComputeConnectivityDomain::registerTrans() 
    2829  { 
    29     registerTransformation(TRANS_COMPUTE_CONNECTIVITY_DOMAIN, CComputeConnectivityDomain::create); 
     30    registerTransformation(TRANS_COMPUTE_CONNECTIVITY_DOMAIN, {create, getTransformation}); 
    3031  } 
    3132 
     
    5152  } 
    5253 
     54  CGenericAlgorithmTransformation* CComputeConnectivityDomain::createAlgorithm(bool isSource, 
     55                                                        CGrid* gridDst, CGrid* gridSrc, 
     56                                                        int elementPositionInGrid, 
     57                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     58                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     59                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     60                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     61                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     62                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     63  { 
     64    return CDomainAlgorithmComputeConnectivity::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     65                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     66                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition) ; 
     67  } 
    5368} 
  • XIOS/dev/dev_trunk_graph/src/node/compute_connectivity_domain.hpp

    r934 r2019  
    2020  class CComputeConnectivityDomain; 
    2121  class CDomain; 
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2224 
    2325  ///-------------------------------------------------------------- 
     
    4143      typedef CObjectTemplate<CComputeConnectivityDomain> SuperClass; 
    4244      typedef CComputeConnectivityDomainAttributes SuperClassAttribute; 
     45      typedef CComputeConnectivityDomain MyClass ; 
     46      typedef CTransformation<CDomain> SuperTransform ; 
    4347 
    4448    public : 
     
    5660      static StdString GetDefName(void); 
    5761      static ENodeType GetType(void); 
     62      const string& getId(void) { return this->SuperClass::getId();} 
     63      ETranformationType getTransformationType(void) { return TRANS_COMPUTE_CONNECTIVITY_DOMAIN ;} 
     64      static CTransformation<CDomain>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     65      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     66      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     67                                                               CGrid* gridDst, CGrid* gridSrc, 
     68                                                               int elementPositionInGrid, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     71                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     74                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5875    private: 
    5976      static bool registerTrans(); 
    6077      static CTransformation<CDomain>* create(const StdString& id, xml::CXMLNode* node); 
    6178      static bool _dummyRegistered; 
    62   }; // class CComputeConnectivityDomain 
     79    public: 
     80   }; // class CComputeConnectivityDomain 
    6381 
    6482  DECLARE_GROUP(CComputeConnectivityDomain); 
  • XIOS/dev/dev_trunk_graph/src/node/context.cpp

    r1612 r2019  
    2020#include "server.hpp" 
    2121#include "distribute_file_server2.hpp" 
     22#include "services_manager.hpp" 
     23#include "contexts_manager.hpp" 
     24#include "cxios.hpp" 
     25#include "client.hpp" 
     26#include "coupler_in.hpp" 
     27#include "coupler_out.hpp" 
    2228 
    2329namespace xios { 
     
    3137      , calendar(), hasClient(false), hasServer(false) 
    3238      , isPostProcessed(false), finalized(false) 
    33       , idServer_(), client(0), server(0) 
    34       , allProcessed(false), countChildCtx_(0) 
     39      , client(nullptr), server(nullptr) 
     40      , allProcessed(false), countChildContextFinalized_(0), isProcessingEvent_(false) 
    3541 
    3642   { /* Ne rien faire de plus */ } 
     
    4046      , calendar(), hasClient(false), hasServer(false) 
    4147      , isPostProcessed(false), finalized(false) 
    42       , idServer_(), client(0), server(0) 
    43       , allProcessed(false), countChildCtx_(0) 
     48      , client(nullptr), server(nullptr) 
     49      , allProcessed(false), countChildContextFinalized_(0), isProcessingEvent_(false) 
    4450   { /* Ne rien faire de plus */ } 
    4551 
     
    264270   ///--------------------------------------------------------------- 
    265271 
    266    //! Initialize client side 
    267    void CContext::initClient(MPI_Comm intraComm, MPI_Comm interComm, CContext* cxtServer /*= 0*/) 
    268    TRY 
    269    { 
    270  
    271      hasClient = true; 
    272      MPI_Comm intraCommServer, interCommServer; 
     272 
     273   void CContext::setClientServerBuffer(vector<CField*>& fields, bool bufferForWriting) 
     274   TRY 
     275   { 
     276      // Estimated minimum event size for small events (20 is an arbitrary constant just for safety) 
     277     const size_t minEventSize = CEventClient::headerSize + 20 * sizeof(int); 
     278      // Ensure there is at least some room for 20 of such events in the buffers 
     279     size_t minBufferSize = std::max(CXios::minBufferSize, 20 * minEventSize); 
     280 
     281#define DECLARE_NODE(Name_, name_)    \ 
     282     if (minBufferSize < sizeof(C##Name_##Definition)) minBufferSize = sizeof(C##Name_##Definition); 
     283#define DECLARE_NODE_PAR(Name_, name_) 
     284#include "node_type.conf" 
     285#undef DECLARE_NODE 
     286#undef DECLARE_NODE_PAR 
     287 
     288 
     289     map<CContextClient*,map<int,size_t>> dataSize ; 
     290     map<CContextClient*,map<int,size_t>> maxEventSize ; 
     291     map<CContextClient*,map<int,size_t>> attributesSize ;   
     292 
     293     for(auto field : fields) 
     294     { 
     295       field->setContextClientDataBufferSize(dataSize, maxEventSize, bufferForWriting) ; 
     296       field->setContextClientAttributesBufferSize(attributesSize, maxEventSize, bufferForWriting) ; 
     297     } 
    273298      
    274299 
    275      if (CServer::serverLevel != 1) 
    276       // initClient is called by client 
    277      { 
    278        client = new CContextClient(this, intraComm, interComm, cxtServer); 
    279        if (cxtServer) // Attached mode 
     300     for(auto& it : attributesSize) 
     301     { 
     302       auto contextClient = it.first ; 
     303       auto& contextDataSize =  dataSize[contextClient] ; 
     304       auto& contextAttributesSize =  attributesSize[contextClient] ; 
     305       auto& contextMaxEventSize =  maxEventSize[contextClient] ; 
     306    
     307       for (auto& it : contextAttributesSize) 
    280308       { 
    281          intraCommServer = intraComm; 
    282          interCommServer = interComm; 
     309         auto serverRank=it.first ; 
     310         auto& buffer = contextAttributesSize[serverRank] ; 
     311         if (contextDataSize[serverRank] > buffer) buffer=contextDataSize[serverRank] ; 
     312         buffer *= CXios::bufferSizeFactor; 
     313         if (buffer < minBufferSize) buffer = minBufferSize; 
     314         if (buffer > CXios::maxBufferSize ) buffer = CXios::maxBufferSize; 
    283315       } 
    284        else 
    285        { 
    286          MPI_Comm_dup(intraComm, &intraCommServer); 
    287          comms.push_back(intraCommServer); 
    288          MPI_Comm_dup(interComm, &interCommServer); 
    289          comms.push_back(interCommServer); 
    290        } 
    291 /* for registry take the id of client context */ 
    292 /* for servers, supress the _server_ from id  */ 
    293        string contextRegistryId=getId() ; 
    294        size_t pos=contextRegistryId.find("_server_") ; 
    295        if (pos!=std::string::npos)  contextRegistryId=contextRegistryId.substr(0,pos) ; 
    296  
    297        registryIn=new CRegistry(intraComm); 
    298        registryIn->setPath(contextRegistryId) ; 
    299        if (client->clientRank==0) registryIn->fromFile("xios_registry.bin") ; 
    300        registryIn->bcastRegistry() ; 
    301        registryOut=new CRegistry(intraComm) ; 
    302         
    303        registryOut->setPath(contextRegistryId) ; 
    304  
    305        server = new CContextServer(this, intraCommServer, interCommServer); 
    306      } 
    307      else 
    308      // initClient is called by primary server 
    309      { 
    310        clientPrimServer.push_back(new CContextClient(this, intraComm, interComm)); 
    311        MPI_Comm_dup(intraComm, &intraCommServer); 
    312        comms.push_back(intraCommServer); 
    313        MPI_Comm_dup(interComm, &interCommServer); 
    314        comms.push_back(interCommServer); 
    315        serverPrimServer.push_back(new CContextServer(this, intraCommServer, interCommServer)); 
    316      } 
    317    } 
    318    CATCH_DUMP_ATTR 
    319  
    320    /*! 
     316 
     317       // Leaders will have to send some control events so ensure there is some room for those in the buffers 
     318       if (contextClient->isServerLeader()) 
     319         for(auto& rank : contextClient->getRanksServerLeader()) 
     320           if (!contextAttributesSize.count(rank)) 
     321           { 
     322             contextAttributesSize[rank] = minBufferSize; 
     323             contextMaxEventSize[rank] = minEventSize; 
     324           } 
     325       
     326       contextClient->setBufferSize(contextAttributesSize, contextMaxEventSize);     
     327     } 
     328   } 
     329   CATCH_DUMP_ATTR 
     330 
     331 
     332    /*! 
    321333    Sets client buffers. 
    322334    \param [in] contextClient 
     
    324336    This flag is only true for client and server-1 for communication with server-2 
    325337  */ 
     338  // ym obsolete to be removed 
    326339   void CContext::setClientServerBuffer(CContextClient* contextClient, bool bufferForWriting) 
    327340   TRY 
    328341   { 
    329       // Estimated minimum event size for small events (10 is an arbitrary constant just for safety) 
    330      const size_t minEventSize = CEventClient::headerSize + getIdServer().size() + 10 * sizeof(int); 
     342      // Estimated minimum event size for small events (20 is an arbitrary constant just for safety) 
     343     const size_t minEventSize = CEventClient::headerSize + 20 * sizeof(int); 
    331344 
    332345      // Ensure there is at least some room for 20 of such events in the buffers 
     
    375388   CATCH_DUMP_ATTR 
    376389 
     390 /*! 
     391    * Compute the required buffer size to send the fields data. 
     392    * \param maxEventSize [in/out] the size of the bigger event for each connected server 
     393    * \param [in] contextClient 
     394    * \param [in] bufferForWriting True if buffers are used for sending data for writing 
     395      This flag is only true for client and server-1 for communication with server-2 
     396    */ 
     397   std::map<int, StdSize> CContext::getDataBufferSize(std::map<int, StdSize>& maxEventSize, 
     398                                                      CContextClient* contextClient, bool bufferForWriting /*= "false"*/) 
     399   TRY 
     400   { 
     401     std::map<int, StdSize> dataSize; 
     402 
     403     // Find all reference domain and axis of all active fields 
     404     std::vector<CFile*>& fileList = bufferForWriting ? this->enabledWriteModeFiles : this->enabledReadModeFiles; 
     405     size_t numEnabledFiles = fileList.size(); 
     406     for (size_t i = 0; i < numEnabledFiles; ++i) 
     407     { 
     408       CFile* file = fileList[i]; 
     409       if (file->getContextClient() == contextClient) 
     410       { 
     411         std::vector<CField*> enabledFields = file->getEnabledFields(); 
     412         size_t numEnabledFields = enabledFields.size(); 
     413         for (size_t j = 0; j < numEnabledFields; ++j) 
     414         { 
     415           // const std::vector<std::map<int, StdSize> > mapSize = enabledFields[j]->getGridDataBufferSize(contextClient); 
     416           const std::map<int, StdSize> mapSize = enabledFields[j]->getGridDataBufferSize(contextClient,bufferForWriting); 
     417           std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end(); 
     418           for (; it != itE; ++it) 
     419           { 
     420             // If dataSize[it->first] does not exist, it will be zero-initialized 
     421             // so we can use it safely without checking for its existance 
     422           if (CXios::isOptPerformance) 
     423               dataSize[it->first] += it->second; 
     424             else if (dataSize[it->first] < it->second) 
     425               dataSize[it->first] = it->second; 
     426 
     427           if (maxEventSize[it->first] < it->second) 
     428               maxEventSize[it->first] = it->second; 
     429           } 
     430         } 
     431       } 
     432     } 
     433     return dataSize; 
     434   } 
     435   CATCH_DUMP_ATTR 
     436 
     437/*! 
     438    * Compute the required buffer size to send the attributes (mostly those grid related). 
     439    * \param maxEventSize [in/out] the size of the bigger event for each connected server 
     440    * \param [in] contextClient 
     441    * \param [in] bufferForWriting True if buffers are used for sending data for writing 
     442      This flag is only true for client and server-1 for communication with server-2 
     443    */ 
     444   std::map<int, StdSize> CContext::getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, 
     445                                                           CContextClient* contextClient, bool bufferForWriting /*= "false"*/) 
     446   TRY 
     447   { 
     448   // As calendar attributes are sent even if there are no active files or fields, maps are initialized according the size of calendar attributes 
     449     std::map<int, StdSize> attributesSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient); 
     450     maxEventSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient); 
     451 
     452     std::vector<CFile*>& fileList = this->enabledFiles; 
     453     size_t numEnabledFiles = fileList.size(); 
     454     for (size_t i = 0; i < numEnabledFiles; ++i) 
     455     { 
     456//         CFile* file = this->enabledWriteModeFiles[i]; 
     457        CFile* file = fileList[i]; 
     458        std::vector<CField*> enabledFields = file->getEnabledFields(); 
     459        size_t numEnabledFields = enabledFields.size(); 
     460        for (size_t j = 0; j < numEnabledFields; ++j) 
     461        { 
     462          const std::map<int, StdSize> mapSize = enabledFields[j]->getGridAttributesBufferSize(contextClient, bufferForWriting); 
     463          std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end(); 
     464          for (; it != itE; ++it) 
     465          { 
     466         // If attributesSize[it->first] does not exist, it will be zero-initialized 
     467         // so we can use it safely without checking for its existence 
     468             if (attributesSize[it->first] < it->second) 
     469         attributesSize[it->first] = it->second; 
     470 
     471         if (maxEventSize[it->first] < it->second) 
     472         maxEventSize[it->first] = it->second; 
     473          } 
     474        } 
     475     } 
     476     return attributesSize; 
     477   } 
     478   CATCH_DUMP_ATTR 
     479 
     480 
     481 
    377482   //! Verify whether a context is initialized 
    378483   bool CContext::isInitialized(void) 
     
    383488   CATCH_DUMP_ATTR 
    384489 
    385    void CContext::initServer(MPI_Comm intraComm, MPI_Comm interComm, CContext* cxtClient /*= 0*/) 
     490 
     491   void CContext::init(CServerContext* parentServerContext, MPI_Comm intraComm, int serviceType) 
     492   TRY 
     493   { 
     494     parentServerContext_ = parentServerContext ; 
     495     if (serviceType==CServicesManager::CLIENT)  
     496       initClient(intraComm, serviceType) ; 
     497     else 
     498       initServer(intraComm, serviceType) ; 
     499    } 
     500    CATCH_DUMP_ATTR 
     501 
     502 
     503 
     504//! Initialize client side 
     505   void CContext::initClient(MPI_Comm intraComm, int serviceType) 
     506   TRY 
     507   { 
     508      intraComm_=intraComm ; 
     509      MPI_Comm_rank(intraComm_, &intraCommRank_) ; 
     510      MPI_Comm_size(intraComm_, &intraCommSize_) ; 
     511 
     512      serviceType_ = CServicesManager::CLIENT ; 
     513      if (serviceType_==CServicesManager::CLIENT) 
     514      { 
     515        hasClient=true ; 
     516        hasServer=false ; 
     517      } 
     518      contextId_ = getId() ; 
     519       
     520      attached_mode=true ; 
     521      if (!CXios::isUsingServer()) attached_mode=false ; 
     522 
     523 
     524      string contextRegistryId=getId() ; 
     525      registryIn=new CRegistry(intraComm); 
     526      registryIn->setPath(contextRegistryId) ; 
     527       
     528      int commRank ; 
     529      MPI_Comm_rank(intraComm_,&commRank) ; 
     530      if (commRank==0) registryIn->fromFile("xios_registry.bin") ; 
     531      registryIn->bcastRegistry() ; 
     532      registryOut=new CRegistry(intraComm_) ; 
     533      registryOut->setPath(contextRegistryId) ; 
     534      
     535   } 
     536   CATCH_DUMP_ATTR 
     537 
     538    
     539   void CContext::initServer(MPI_Comm intraComm, int serviceType) 
    386540   TRY 
    387541   { 
    388542     hasServer=true; 
    389      server = new CContextServer(this,intraComm,interComm); 
    390  
    391 /* for registry take the id of client context */ 
    392 /* for servers, supress the _server_ from id  */ 
    393      string contextRegistryId=getId() ; 
    394      size_t pos=contextRegistryId.find("_server_") ; 
    395      if (pos!=std::string::npos)  contextRegistryId=contextRegistryId.substr(0,pos) ; 
    396         
     543     intraComm_=intraComm ; 
     544     MPI_Comm_rank(intraComm_, &intraCommRank_) ; 
     545     MPI_Comm_size(intraComm_, &intraCommSize_) ; 
     546 
     547     serviceType_=serviceType ; 
     548 
     549     if (serviceType_==CServicesManager::GATHERER) 
     550     { 
     551       hasClient=true ; 
     552       hasServer=true ; 
     553     } 
     554     else if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::OUT_SERVER) 
     555     { 
     556       hasClient=false ; 
     557       hasServer=true ; 
     558     } 
     559 
     560     CXios::getContextsManager()->getContextId(getId(), contextId_, intraComm) ; 
     561      
    397562     registryIn=new CRegistry(intraComm); 
    398      registryIn->setPath(contextRegistryId) ; 
    399      if (server->intraCommRank==0) registryIn->fromFile("xios_registry.bin") ; 
     563     registryIn->setPath(contextId_) ; 
     564      
     565     int commRank ; 
     566     MPI_Comm_rank(intraComm_,&commRank) ; 
     567     if (commRank==0) registryIn->fromFile("xios_registry.bin") ; 
     568     
    400569     registryIn->bcastRegistry() ; 
    401570     registryOut=new CRegistry(intraComm) ; 
    402      registryOut->setPath(contextRegistryId) ; 
    403  
    404      MPI_Comm intraCommClient, interCommClient; 
    405      if (cxtClient) // Attached mode 
    406      { 
    407        intraCommClient = intraComm; 
    408        interCommClient = interComm; 
    409      } 
    410      else 
    411      { 
    412        MPI_Comm_dup(intraComm, &intraCommClient); 
    413        comms.push_back(intraCommClient); 
    414        MPI_Comm_dup(interComm, &interCommClient); 
    415        comms.push_back(interCommClient); 
    416      } 
    417      client = new CContextClient(this,intraCommClient,interCommClient, cxtClient); 
    418    } 
    419    CATCH_DUMP_ATTR 
    420  
    421    //! Try to send the buffers and receive possible answers 
    422   bool CContext::checkBuffersAndListen(bool enableEventsProcessing /*= true*/) 
     571     registryOut->setPath(contextId_) ; 
     572 
     573   } 
     574   CATCH_DUMP_ATTR 
     575 
     576 
     577  void CContext::createClientInterComm(MPI_Comm interCommClient, MPI_Comm interCommServer) // for servers 
    423578  TRY 
    424579  { 
    425     bool clientReady, serverFinished; 
    426  
    427     // Only classical servers are non-blocking 
    428     if (CServer::serverLevel == 0) 
    429     { 
    430       client->checkBuffers(); 
    431       bool hasTmpBufferedEvent = client->hasTemporarilyBufferedEvent(); 
    432       if (hasTmpBufferedEvent) 
    433         hasTmpBufferedEvent = !client->sendTemporarilyBufferedEvent(); 
    434       // Don't process events if there is a temporarily buffered event 
    435       return server->eventLoop(!hasTmpBufferedEvent || !enableEventsProcessing); 
    436     } 
    437     else if (CServer::serverLevel == 1) 
    438     { 
    439       if (!finalized) 
    440         client->checkBuffers(); 
    441       bool serverFinished = true; 
    442       if (!finalized) 
    443         serverFinished = server->eventLoop(enableEventsProcessing); 
    444       bool serverPrimFinished = true; 
    445       for (int i = 0; i < clientPrimServer.size(); ++i) 
    446       { 
    447         if (!finalized) 
    448           clientPrimServer[i]->checkBuffers(); 
    449         if (!finalized) 
    450           serverPrimFinished *= serverPrimServer[i]->eventLoop(enableEventsProcessing); 
    451       } 
    452       return ( serverFinished && serverPrimFinished); 
    453     } 
    454  
    455     else if (CServer::serverLevel == 2) 
    456     { 
    457       client->checkBuffers(); 
    458       return server->eventLoop(enableEventsProcessing); 
    459     } 
     580    MPI_Comm intraCommClient ; 
     581    MPI_Comm_dup(intraComm_, &intraCommClient); 
     582    comms.push_back(intraCommClient); 
     583    // attached_mode=parentServerContext_->isAttachedMode() ; //ym probably inherited from source context 
     584    server = new CContextServer(this,intraComm_, interCommServer); // check if we need to dupl. intraComm_ ? 
     585    client = new CContextClient(this,intraCommClient,interCommClient); 
     586    client->setAssociatedServer(server) ;   
     587    server->setAssociatedClient(client) ;   
     588 
    460589  } 
    461    CATCH_DUMP_ATTR 
    462  
    463    //! Terminate a context 
     590  CATCH_DUMP_ATTR 
     591 
     592  void CContext::createServerInterComm(void)  
     593  TRY 
     594  { 
     595    
     596    MPI_Comm interCommClient, interCommServer ; 
     597 
     598    if (serviceType_ == CServicesManager::CLIENT) 
     599    { 
     600 
     601      int commRank ; 
     602      MPI_Comm_rank(intraComm_,&commRank) ; 
     603      if (commRank==0) 
     604      { 
     605        if (attached_mode) CXios::getContextsManager()->createServerContext(CClient::getPoolRessource()->getId(), CXios::defaultServerId, 0, getContextId()) ; 
     606        else if (CXios::usingServer2) CXios::getContextsManager()->createServerContext(CXios::defaultPoolId, CXios::defaultGathererId, 0, getContextId()) ; 
     607        else  CXios::getContextsManager()->createServerContext(CXios::defaultPoolId, CXios::defaultServerId, 0, getContextId()) ; 
     608      } 
     609 
     610      MPI_Comm interComm ; 
     611       
     612      if (attached_mode) 
     613      { 
     614        parentServerContext_->createIntercomm(CClient::getPoolRessource()->getId(), CXios::defaultServerId, 0, getContextId(), intraComm_,  
     615                                              interCommClient, interCommServer) ; 
     616        int type ;  
     617        if (commRank==0) CXios::getServicesManager()->getServiceType(CClient::getPoolRessource()->getId(), CXios::defaultServerId, 0, type) ; 
     618        MPI_Bcast(&type,1,MPI_INT,0,intraComm_) ; 
     619        setCurrent(getId()) ; // getCurrent/setCurrent may be supress, it can cause a lot of trouble 
     620      } 
     621      else if (CXios::usingServer2) 
     622      {  
     623//      CXios::getContextsManager()->createServerContextIntercomm(CXios::defaultPoolId, CXios::defaultGathererId, 0, getContextId(), intraComm_, interComm) ; 
     624        parentServerContext_->createIntercomm(CXios::defaultPoolId, CXios::defaultGathererId, 0, getContextId(), intraComm_, 
     625                                              interCommClient, interCommServer) ; 
     626        int type ;  
     627        if (commRank==0) CXios::getServicesManager()->getServiceType(CXios::defaultPoolId, CXios::defaultGathererId, 0, type) ; 
     628        MPI_Bcast(&type,1,MPI_INT,0,intraComm_) ; 
     629      } 
     630      else 
     631      { 
     632        //CXios::getContextsManager()->createServerContextIntercomm(CXios::defaultPoolId, CXios::defaultServerId, 0, getContextId(), intraComm_, interComm) ; 
     633        parentServerContext_->createIntercomm(CXios::defaultPoolId, CXios::defaultServerId, 0, getContextId(), intraComm_, 
     634                                              interCommClient, interCommServer) ; 
     635        int type ;  
     636        if (commRank==0) CXios::getServicesManager()->getServiceType(CXios::defaultPoolId, CXios::defaultServerId, 0, type) ; 
     637        MPI_Bcast(&type,1,MPI_INT,0,intraComm_) ; 
     638      } 
     639 
     640        // intraComm client is not duplicated. In all the code we use client->intraComm for MPI 
     641        // in future better to replace it by intracommuncator associated to the context 
     642     
     643      MPI_Comm intraCommClient, intraCommServer ; 
     644      intraCommClient=intraComm_ ; 
     645      MPI_Comm_dup(intraComm_, &intraCommServer) ; 
     646      client = new CContextClient(this, intraCommClient, interCommClient); 
     647      server = new CContextServer(this, intraCommServer, interCommServer); 
     648      client->setAssociatedServer(server) ; 
     649      server->setAssociatedClient(client) ; 
     650    } 
     651     
     652    if (serviceType_ == CServicesManager::GATHERER) 
     653    { 
     654      int commRank ; 
     655      MPI_Comm_rank(intraComm_,&commRank) ; 
     656       
     657      int nbPartitions ; 
     658      if (commRank==0)  
     659      {  
     660        CXios::getServicesManager()->getServiceNbPartitions(CXios::defaultPoolId, CXios::defaultServerId, 0, nbPartitions) ; 
     661        for(int i=0 ; i<nbPartitions; i++) 
     662          CXios::getContextsManager()->createServerContext(CXios::defaultPoolId, CXios::defaultServerId, i, getContextId()) ; 
     663      }       
     664      MPI_Bcast(&nbPartitions, 1, MPI_INT, 0, intraComm_) ; 
     665       
     666      MPI_Comm interComm ; 
     667      for(int i=0 ; i<nbPartitions; i++) 
     668      { 
     669        parentServerContext_->createIntercomm(CXios::defaultPoolId, CXios::defaultServerId, i, getContextId(), intraComm_, interCommClient, interCommServer) ; 
     670        int type ;  
     671        if (commRank==0) CXios::getServicesManager()->getServiceType(CXios::defaultPoolId, CXios::defaultServerId, 0, type) ; 
     672        MPI_Bcast(&type,1,MPI_INT,0,intraComm_) ; 
     673        primServerId_.push_back(CXios::getContextsManager()->getServerContextName(CXios::defaultPoolId, CXios::defaultServerId, i, type, getContextId())) ; 
     674 
     675        // intraComm client is not duplicated. In all the code we use client->intraComm for MPI 
     676        // in future better to replace it by intracommuncator associated to the context 
     677       
     678        MPI_Comm intraCommClient, intraCommServer ; 
     679 
     680        intraCommClient=intraComm_ ; 
     681        MPI_Comm_dup(intraComm_, &intraCommServer) ; 
     682 
     683        CContextClient* client = new CContextClient(this, intraCommClient, interCommClient) ; 
     684        CContextServer* server = new CContextServer(this, intraCommServer, interCommServer) ; 
     685        client->setAssociatedServer(server) ; 
     686        server->setAssociatedClient(client) ; 
     687        clientPrimServer.push_back(client); 
     688        serverPrimServer.push_back(server);   
     689 
     690       
     691      } 
     692    } 
     693  } 
     694  CATCH_DUMP_ATTR 
     695 
     696    
     697 
     698  bool CContext::eventLoop(bool enableEventsProcessing) 
     699  { 
     700    bool finished=true;  
     701 
     702    if (client!=nullptr && !finalized) client->checkBuffers(); 
     703     
     704    for (int i = 0; i < clientPrimServer.size(); ++i) 
     705    { 
     706      if (!finalized) clientPrimServer[i]->checkBuffers(); 
     707      if (!finalized) finished &= serverPrimServer[i]->eventLoop(enableEventsProcessing); 
     708    } 
     709 
     710    for (auto couplerOut : couplerOutClient_) 
     711      if (!finalized) couplerOut.second->checkBuffers(); 
     712     
     713    for (auto couplerIn : couplerInClient_) 
     714      if (!finalized) couplerIn.second->checkBuffers(); 
     715     
     716    for (auto couplerOut : couplerOutServer_) 
     717      if (!finalized) couplerOut.second->eventLoop(enableEventsProcessing); 
     718 
     719    for (auto couplerIn : couplerInServer_) 
     720      if (!finalized) couplerIn.second->eventLoop(enableEventsProcessing); 
     721     
     722    if (server!=nullptr) if (!finalized) finished &= server->eventLoop(enableEventsProcessing); 
     723   
     724    return finalized && finished ; 
     725  } 
     726 
     727  void CContext::addCouplingChanel(const std::string& fullContextId, bool out) 
     728  { 
     729     int contextLeader ; 
     730      
     731     if (out) 
     732     {  
     733       if (couplerOutClient_.find(fullContextId)==couplerOutClient_.end())  
     734       { 
     735         bool ok=CXios::getContextsManager()->getContextLeader(fullContextId, contextLeader, getIntraComm()) ; 
     736      
     737         MPI_Comm interComm, interCommClient, interCommServer  ; 
     738         MPI_Comm intraCommClient, intraCommServer ; 
     739 
     740         if (ok) MPI_Intercomm_create(getIntraComm(), 0, CXios::getXiosComm(), contextLeader, 0, &interComm) ; 
     741 
     742        MPI_Comm_dup(intraComm_, &intraCommClient) ; 
     743        MPI_Comm_dup(intraComm_, &intraCommServer) ; 
     744        MPI_Comm_dup(interComm, &interCommClient) ; 
     745        MPI_Comm_dup(interComm, &interCommServer) ; 
     746        CContextClient* client = new CContextClient(this, intraCommClient, interCommClient); 
     747        CContextServer* server = new CContextServer(this, intraCommServer, interCommServer); 
     748        client->setAssociatedServer(server) ; 
     749        server->setAssociatedClient(client) ; 
     750        MPI_Comm_free(&interComm) ; 
     751        couplerOutClient_[fullContextId] = client ; 
     752        couplerOutServer_[fullContextId] = server ; 
     753 
     754/* 
     755      // for now, we don't now which beffer size must be used for client coupler 
     756      // It will be evaluated later. Fix a constant size for now... 
     757      // set to 10Mb for development 
     758       map<int,size_t> bufferSize, maxEventSize ; 
     759       for(int i=0;i<client->getRemoteSize();i++) 
     760       { 
     761         bufferSize[i]=10000000 ; 
     762         maxEventSize[i]=10000000 ; 
     763       } 
     764 
     765       client->setBufferSize(bufferSize, maxEventSize);     
     766*/ 
     767      } 
     768    } 
     769    else if (couplerInClient_.find(fullContextId)==couplerInClient_.end()) 
     770    { 
     771      bool ok=CXios::getContextsManager()->getContextLeader(fullContextId, contextLeader, getIntraComm()) ; 
     772      
     773       MPI_Comm interComm, interCommClient, interCommServer  ; 
     774       MPI_Comm intraCommClient, intraCommServer ; 
     775 
     776       if (ok) MPI_Intercomm_create(getIntraComm(), 0, CXios::getXiosComm(), contextLeader, 0, &interComm) ; 
     777 
     778       MPI_Comm_dup(intraComm_, &intraCommClient) ; 
     779       MPI_Comm_dup(intraComm_, &intraCommServer) ; 
     780       MPI_Comm_dup(interComm, &interCommServer) ; 
     781       MPI_Comm_dup(interComm, &interCommClient) ; 
     782       CContextServer* server = new CContextServer(this, intraCommServer, interCommServer); 
     783       CContextClient* client = new CContextClient(this, intraCommClient, interCommClient); 
     784       client->setAssociatedServer(server) ; 
     785       server->setAssociatedClient(client) ; 
     786       MPI_Comm_free(&interComm) ; 
     787 
     788       map<int,size_t> bufferSize, maxEventSize ; 
     789       for(int i=0;i<client->getRemoteSize();i++) 
     790       { 
     791         bufferSize[i]=10000000 ; 
     792         maxEventSize[i]=10000000 ; 
     793       } 
     794 
     795       client->setBufferSize(bufferSize, maxEventSize);     
     796       couplerInClient_[fullContextId] = client ; 
     797       couplerInServer_[fullContextId] = server ;         
     798    } 
     799  } 
     800   
     801  void CContext::globalEventLoop(void) 
     802  { 
     803    CXios::getDaemonsManager()->eventLoop() ; 
     804    setCurrent(getId()) ; 
     805  } 
     806 
     807 
    464808   void CContext::finalize(void) 
    465809   TRY 
    466810   { 
    467       if (hasClient && !hasServer) // For now we only use server level 1 to read data 
    468       { 
    469         doPreTimestepOperationsForEnabledReadModeFiles(); 
    470       } 
    471      // Send registry upon calling the function the first time 
    472      if (countChildCtx_ == 0) 
    473        if (hasClient) sendRegistry() ; 
    474  
    475      // Client: 
    476      // (1) blocking send context finalize to its server 
    477      // (2) blocking receive context finalize from its server 
    478      // (3) some memory deallocations 
    479      if (CXios::isClient) 
    480      { 
    481        // Make sure that client (model) enters the loop only once 
    482        if (countChildCtx_ < 1) 
    483        { 
    484          ++countChildCtx_; 
    485  
    486          client->finalize(); 
    487          while (client->havePendingRequests()) 
    488             client->checkBuffers(); 
    489  
    490          while (!server->hasFinished()) 
    491            server->eventLoop(); 
    492  
    493          if (hasServer) // Mode attache 
     811      registryOut->hierarchicalGatherRegistry() ; 
     812      if (server->intraCommRank==0) CXios::globalRegistry->mergeRegistry(*registryOut) ; 
     813 
     814      if (serviceType_==CServicesManager::CLIENT) 
     815      { 
     816//ym        doPreTimestepOperationsForEnabledReadModeFiles(); // For now we only use server level 1 to read data 
     817 
     818        triggerLateFields() ; 
     819 
     820        // inform couplerIn that I am finished 
     821        for(auto& couplerInClient : couplerInClient_) sendCouplerInContextFinalized(couplerInClient.second) ; 
     822 
     823        // wait until received message from couplerOut that they have finished 
     824        bool couplersInFinalized ; 
     825        do 
     826        { 
     827          couplersInFinalized=true ; 
     828          for(auto& couplerOutClient : couplerOutClient_) couplersInFinalized &= isCouplerInContextFinalized(couplerOutClient.second) ;  
     829          globalEventLoop() ; 
     830        } while (!couplersInFinalized) ; 
     831 
     832        info(100)<<"DEBUG: context "<<getId()<<" Send client finalize"<<endl ; 
     833        client->finalize(); 
     834        info(100)<<"DEBUG: context "<<getId()<<" Client finalize sent"<<endl ; 
     835        while (client->havePendingRequests()) client->checkBuffers(); 
     836        info(100)<<"DEBUG: context "<<getId()<<" no pending request ok"<<endl ; 
     837        bool notifiedFinalized=false ; 
     838        do 
     839        { 
     840          notifiedFinalized=client->isNotifiedFinalized() ; 
     841        } while (!notifiedFinalized) ; 
     842        client->releaseBuffers(); 
     843        info(100)<<"DEBUG: context "<<getId()<<" release client ok"<<endl ; 
     844      } 
     845      else if (serviceType_==CServicesManager::GATHERER) 
     846      { 
     847         for (int i = 0; i < clientPrimServer.size(); ++i) 
    494848         { 
    495            closeAllFile(); 
    496            registryOut->hierarchicalGatherRegistry() ; 
    497            if (server->intraCommRank==0) CXios::globalRegistry->mergeRegistry(*registryOut) ; 
     849           clientPrimServer[i]->finalize(); 
     850           bool bufferReleased; 
     851           do 
     852           { 
     853             clientPrimServer[i]->checkBuffers(); 
     854             bufferReleased = !clientPrimServer[i]->havePendingRequests(); 
     855           } while (!bufferReleased); 
     856            
     857           bool notifiedFinalized=false ; 
     858           do 
     859           { 
     860             notifiedFinalized=clientPrimServer[i]->isNotifiedFinalized() ; 
     861           } while (!notifiedFinalized) ; 
     862           clientPrimServer[i]->releaseBuffers(); 
    498863         } 
    499  
    500          //! Deallocate client buffers 
    501          client->releaseBuffers(); 
    502  
    503          //! Free internally allocated communicators 
    504          for (std::list<MPI_Comm>::iterator it = comms.begin(); it != comms.end(); ++it) 
    505            MPI_Comm_free(&(*it)); 
    506          comms.clear(); 
    507  
    508          info(20)<<"CContext: Context <"<<getId()<<"> is finalized."<<endl; 
    509        } 
    510      } 
    511      else if (CXios::isServer) 
    512      { 
    513        // First context finalize message received from a model 
    514        // Send context finalize to its child contexts (if any) 
    515        if (countChildCtx_ == 0) 
    516          for (int i = 0; i < clientPrimServer.size(); ++i) 
    517            clientPrimServer[i]->finalize(); 
    518  
    519        // (Last) context finalized message received 
    520        if (countChildCtx_ == clientPrimServer.size()) 
    521        { 
    522          // Blocking send of context finalize message to its client (e.g. primary server or model) 
    523          info(100)<<"DEBUG: context "<<getId()<<" Send client finalize<<"<<endl ; 
    524          client->finalize(); 
    525          bool bufferReleased; 
    526          do 
    527          { 
    528            client->checkBuffers(); 
    529            bufferReleased = !client->havePendingRequests(); 
    530          } while (!bufferReleased); 
    531          finalized = true; 
    532  
    533          closeAllFile(); // Just move to here to make sure that server-level 1 can close files 
    534          if (hasServer && !hasClient) 
    535          {            
    536            registryOut->hierarchicalGatherRegistry() ; 
    537            if (server->intraCommRank==0) CXios::globalRegistry->mergeRegistry(*registryOut) ; 
    538          } 
    539  
    540          //! Deallocate client buffers 
    541          client->releaseBuffers(); 
    542          for (int i = 0; i < clientPrimServer.size(); ++i) 
    543            clientPrimServer[i]->releaseBuffers(); 
    544  
    545          //! Free internally allocated communicators 
    546          for (std::list<MPI_Comm>::iterator it = comms.begin(); it != comms.end(); ++it) 
    547            MPI_Comm_free(&(*it)); 
    548          comms.clear(); 
    549  
    550          info(20)<<"CContext: Context <"<<getId()<<"> is finalized."<<endl; 
    551        } 
    552  
    553        ++countChildCtx_; 
    554      } 
     864         closeAllFile(); 
     865 
     866      } 
     867      else if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::OUT_SERVER) 
     868      { 
     869        closeAllFile(); 
     870      } 
     871 
     872      freeComms() ; 
     873         
     874      parentServerContext_->freeComm() ; 
     875      finalized = true; 
     876      info(20)<<"CContext: Context <"<<getId()<<"> is finalized."<<endl; 
    555877   } 
    556878   CATCH_DUMP_ATTR 
     
    576898   CATCH_DUMP_ATTR 
    577899 
    578    void CContext::postProcessingGlobalAttributes() 
    579    TRY 
    580    { 
    581      if (allProcessed) return;   
    582       
    583      // After xml is parsed, there are some more works with post processing 
    584      postProcessing(); 
    585  
    586      // Check grid and calculate its distribution 
    587      checkGridEnabledFields(); 
    588   
    589      // Distribute files between secondary servers according to the data size 
    590      distributeFiles(); 
    591  
    592      setClientServerBuffer(client, (hasClient && !hasServer)); 
    593      for (int i = 0; i < clientPrimServer.size(); ++i) 
    594          setClientServerBuffer(clientPrimServer[i], true); 
    595  
    596      if (hasClient) 
    597      { 
    598       // Send all attributes of current context to server 
    599       this->sendAllAttributesToServer(); 
    600  
    601       // Send all attributes of current calendar 
    602       CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(); 
    603  
    604       // We have enough information to send to server 
    605       // First of all, send all enabled files 
    606       sendEnabledFiles(this->enabledWriteModeFiles); 
    607       // We only use server-level 1 (for now) to read data 
    608       if (!hasServer) 
    609         sendEnabledFiles(this->enabledReadModeFiles); 
    610  
    611       // Then, send all enabled fields       
    612       sendEnabledFieldsInFiles(this->enabledWriteModeFiles); 
    613       if (!hasServer) 
    614         sendEnabledFieldsInFiles(this->enabledReadModeFiles); 
    615  
    616       // Then, check whether we have domain_ref, axis_ref or scalar_ref attached to the enabled fields 
    617       // If any, so send them to server 
    618        sendRefDomainsAxisScalars(this->enabledWriteModeFiles); 
    619       if (!hasServer) 
    620         sendRefDomainsAxisScalars(this->enabledReadModeFiles);         
    621  
    622        // Check whether enabled fields have grid_ref, if any, send this info to server 
    623       sendRefGrid(this->enabledFiles); 
    624       // This code may be useful in the future when we want to seperate completely read and write 
    625       // sendRefGrid(this->enabledWriteModeFiles); 
    626       // if (!hasServer) 
    627       //   sendRefGrid(this->enabledReadModeFiles); 
    628        
    629       // A grid of enabled fields composed of several components which must be checked then their 
    630       // checked attributes should be sent to server 
    631       sendGridComponentEnabledFieldsInFiles(this->enabledFiles); // This code can be seperated in two (one for reading, another for writing) 
    632  
    633        // We have a xml tree on the server side and now, it should be also processed 
    634       sendPostProcessing(); 
    635         
    636       // Finally, we send information of grid itself to server  
    637       sendGridEnabledFieldsInFiles(this->enabledWriteModeFiles);        
    638       if (!hasServer) 
    639         sendGridEnabledFieldsInFiles(this->enabledReadModeFiles);        
    640      } 
    641      allProcessed = true; 
    642    } 
    643    CATCH_DUMP_ATTR 
    644  
    645    void CContext::sendPostProcessingGlobalAttributes() 
    646    TRY 
    647    { 
    648       // Use correct context client to send message 
    649      // int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1; 
    650     int nbSrvPools = (this->hasServer) ? (this->hasClient ? this->clientPrimServer.size() : 0) : 1; 
    651      for (int i = 0; i < nbSrvPools; ++i) 
    652      { 
    653        CContextClient* contextClientTmp = (0 != clientPrimServer.size()) ? clientPrimServer[i] : client; 
    654        CEventClient event(getType(),EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES); 
    655  
    656        if (contextClientTmp->isServerLeader()) 
    657        { 
    658          CMessage msg; 
    659          if (hasServer) 
    660            msg<<this->getIdServer(i); 
    661          else 
    662            msg<<this->getIdServer(); 
    663          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    664          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    665            event.push(*itRank,1,msg); 
    666          contextClientTmp->sendEvent(event); 
    667        } 
    668        else contextClientTmp->sendEvent(event); 
    669      } 
    670    } 
    671    CATCH_DUMP_ATTR 
    672  
    673    void CContext::recvPostProcessingGlobalAttributes(CEventServer& event) 
    674    TRY 
    675    { 
    676       CBufferIn* buffer=event.subEvents.begin()->buffer; 
    677       string id; 
    678       *buffer>>id; 
    679       get(id)->recvPostProcessingGlobalAttributes(*buffer); 
    680    } 
    681    CATCH 
    682  
    683    void CContext::recvPostProcessingGlobalAttributes(CBufferIn& buffer) 
    684    TRY 
    685    {       
    686       postProcessingGlobalAttributes(); 
    687    } 
    688    CATCH_DUMP_ATTR 
    689  
     900    
    690901   /*! 
    691902   \brief Close all the context defintion and do processing data 
     
    697908   and the active fields (fields will be written onto active files) 
    698909   */ 
    699  
    700    void CContext::closeDefinition(void) 
    701    TRY 
    702    { 
    703     CTimer::get("Context : close definition").resume() ; 
    704     postProcessingGlobalAttributes(); 
    705  
    706     if (hasClient) sendPostProcessingGlobalAttributes(); 
    707  
    708     // There are some processings that should be done after all of above. For example: check mask or index 
    709     this->buildFilterGraphOfEnabledFields(); 
     910  void CContext::closeDefinition(void) 
     911   TRY 
     912   { 
     913     CTimer::get("Context : close definition").resume() ; 
     914      
     915     // create intercommunicator with servers.  
     916     // not sure it is the good place to be called here  
     917     createServerInterComm() ; 
     918 
     919 
     920     // After xml is parsed, there are some more works with post processing 
     921//     postProcessing(); 
     922 
    710923     
    711      if (hasClient && !hasServer) 
    712     { 
    713       buildFilterGraphOfFieldsWithReadAccess(); 
    714       postProcessFilterGraph(); 
    715     } 
     924    // Make sure the calendar was correctly created 
     925    if (serviceType_!=CServicesManager::CLIENT) CCalendarWrapper::get(CCalendarWrapper::GetDefName())->createCalendar(); 
     926    if (!calendar) 
     927      ERROR("CContext::postProcessing()", << "A calendar must be defined for the context \"" << getId() << "!\"") 
     928    else if (calendar->getTimeStep() == NoneDu) 
     929      ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"") 
     930    // Calendar first update to set the current date equals to the start date 
     931    calendar->update(0); 
     932 
     933    // Résolution des héritages descendants (càd des héritages de groupes) 
     934    // pour chacun des contextes. 
     935    solveDescInheritance(true); 
     936  
     937    // Solve inheritance for field to know if enabled or not. 
     938    for (auto field : CField::getAll()) field->solveRefInheritance(); 
     939 
     940    // Check if some axis, domains or grids are eligible to for compressed indexed output. 
     941    // Warning: This must be done after solving the inheritance and before the rest of post-processing 
     942    // --> later ????    checkAxisDomainsGridsEligibilityForCompressedOutput();       
     943 
     944      // Check if some automatic time series should be generated 
     945      // Warning: This must be done after solving the inheritance and before the rest of post-processing       
     946 
     947    // The timeseries should only be prepared in client 
     948    prepareTimeseries(); 
     949 
     950    //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir. 
     951    findEnabledFiles(); 
     952    findEnabledWriteModeFiles(); 
     953    findEnabledReadModeFiles(); 
     954    findEnabledCouplerIn(); 
     955    findEnabledCouplerOut(); 
     956    createCouplerInterCommunicator() ; 
     957 
     958    // Find all enabled fields of each file       
     959    vector<CField*>&& fileOutField = findAllEnabledFieldsInFileOut(this->enabledWriteModeFiles); 
     960    vector<CField*>&& fileInField = findAllEnabledFieldsInFileIn(this->enabledReadModeFiles); 
     961    vector<CField*>&& couplerOutField = findAllEnabledFieldsCouplerOut(this->enabledCouplerOut); 
     962    vector<CField*>&& couplerInField = findAllEnabledFieldsCouplerIn(this->enabledCouplerIn); 
     963    findFieldsWithReadAccess(); 
     964    vector<CField*>& fieldWithReadAccess = fieldsWithReadAccess_ ; 
     965    vector<CField*> fieldModelIn ; // fields potentially from model 
     966      
     967    // define if files are on clientSied or serverSide  
     968    if (serviceType_==CServicesManager::CLIENT) 
     969    { 
     970      for (auto& file : enabledWriteModeFiles) file->setClientSide() ; 
     971      for (auto& file : enabledReadModeFiles) file->setClientSide() ; 
     972    } 
     973    else 
     974    { 
     975      for (auto& file : enabledWriteModeFiles) file->setServerSide() ; 
     976      for (auto& file : enabledReadModeFiles) file->setServerSide() ; 
     977    } 
     978 
    716979     
    717     checkGridEnabledFields();    
    718  
    719     if (hasClient) this->sendProcessingGridOfEnabledFields(); 
    720     if (hasClient) this->sendCloseDefinition(); 
    721  
    722     // Nettoyage de l'arborescence 
    723     if (hasClient) CleanTree(); // Only on client side?? 
    724  
    725     if (hasClient) 
    726     { 
    727       sendCreateFileHeader(); 
    728       if (!hasServer) startPrefetchingOfEnabledReadModeFiles(); 
    729     } 
    730     CTimer::get("Context : close definition").suspend() ; 
    731    } 
    732    CATCH_DUMP_ATTR 
    733  
    734    void CContext::findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
    735    TRY 
    736    { 
    737      for (unsigned int i = 0; i < activeFiles.size(); i++) 
    738      (void)activeFiles[i]->getEnabledFields(); 
    739    } 
    740    CATCH_DUMP_ATTR 
    741  
     980    for (auto& field : couplerInField) 
     981    { 
     982      field->unsetGridCompleted() ; 
     983    } 
     984// find all field potentially at workflow end 
     985    vector<CField*> endWorkflowFields ; 
     986    endWorkflowFields.reserve(fileOutField.size()+couplerOutField.size()+fieldWithReadAccess.size()) ; 
     987    endWorkflowFields.insert(endWorkflowFields.end(),fileOutField.begin(), fileOutField.end()) ; 
     988    endWorkflowFields.insert(endWorkflowFields.end(),couplerOutField.begin(), couplerOutField.end()) ; 
     989    endWorkflowFields.insert(endWorkflowFields.end(),fieldWithReadAccess.begin(), fieldWithReadAccess.end()) ; 
     990 
     991    bool workflowGraphIsCompleted ; 
     992 
     993    bool first=true ; 
     994    do 
     995    { 
     996      workflowGraphIsCompleted=true;  
     997      for(auto endWorkflowField : endWorkflowFields)  
     998      { 
     999        workflowGraphIsCompleted &= endWorkflowField->buildWorkflowGraph(garbageCollector) ; 
     1000      } 
     1001 
     1002      for(auto couplerIn : enabledCouplerIn) couplerIn->assignContext() ; 
     1003      for(auto field : couplerInField) field->makeGridAliasForCoupling(); 
     1004      for(auto field : couplerInField) this->sendCouplerInReady(field->getContextClient()) ; 
     1005     
     1006 
     1007      // assign context to coupler out and related fields 
     1008      for(auto couplerOut : enabledCouplerOut) couplerOut->assignContext() ; 
     1009      // for now supose that all coupling out endpoint are succesfull. The difficultie is client/server buffer evaluation 
     1010      for(auto field : couplerOutField)  
     1011      { 
     1012        // connect to couplerOut -> to do 
     1013      } 
     1014      if (first) setClientServerBuffer(couplerOutField, true) ; // set buffer context --> to check 
     1015    
     1016      bool couplersReady ; 
     1017      do  
     1018      { 
     1019        couplersReady=true ; 
     1020        for(auto field : couplerOutField) 
     1021        { 
     1022          bool ready = isCouplerInReady(field->getContextClient()) ;  
     1023          if (ready) field->sendFieldToCouplerOut() ; 
     1024          couplersReady &= ready ; 
     1025        } 
     1026        if (!couplersReady) this->eventLoop() ; 
     1027      } while (!couplersReady) ; 
     1028 
     1029      first=false ; 
     1030      this->eventLoop() ; 
     1031    } while (!workflowGraphIsCompleted) ; 
     1032 
     1033    for( auto field : couplerInField) couplerInFields_.push_back(field) ; 
     1034 
     1035    // get all field coming potentially from model 
     1036    for (auto field : CField::getAll() ) if (field->getModelIn()) fieldModelIn.push_back(field) ; 
     1037 
     1038    // Distribute files between secondary servers according to the data size => assign a context to a file and then to fields 
     1039    if (serviceType_==CServicesManager::GATHERER) distributeFiles(this->enabledWriteModeFiles); 
     1040    else if (serviceType_==CServicesManager::CLIENT) for(auto file : this->enabledWriteModeFiles) file->setContextClient(client) ; 
     1041 
     1042    // client side, assign context for file reading 
     1043    if (serviceType_==CServicesManager::CLIENT) for(auto file : this->enabledReadModeFiles) file->setContextClient(client) ; 
     1044     
     1045    // server side, assign context where to send file data read 
     1046    if (serviceType_==CServicesManager::CServicesManager::GATHERER || serviceType_==CServicesManager::IO_SERVER)  
     1047      for(auto file : this->enabledReadModeFiles) file->setContextClient(client) ; 
     1048    
     1049    // workflow endpoint => sent to IO/SERVER 
     1050    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) 
     1051    { 
     1052      for(auto field : fileOutField)  
     1053      { 
     1054        field->connectToFileServer(garbageCollector) ; // connect the field to server filter 
     1055      } 
     1056      setClientServerBuffer(fileOutField, true) ; // set buffer context --> to review 
     1057      for(auto field : fileOutField) field->sendFieldToFileServer() ; 
     1058    } 
     1059 
     1060    // workflow endpoint => write to file 
     1061    if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::OUT_SERVER) 
     1062    { 
     1063      for(auto field : fileOutField)  
     1064      { 
     1065        field->connectToFileWriter(garbageCollector) ; // connect the field to server filter 
     1066      } 
     1067    } 
     1068     
     1069    // workflow endpoint => Send data from server to client 
     1070    if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::GATHERER) 
     1071    { 
     1072      for(auto field : fileInField)  
     1073      { 
     1074        field->connectToServerToClient(garbageCollector) ; 
     1075      } 
     1076    } 
     1077 
     1078    // workflow endpoint => sent to model on client side 
     1079    if (serviceType_==CServicesManager::CLIENT) 
     1080    { 
     1081      for(auto field : fieldWithReadAccess) field->connectToModelOutput(garbageCollector) ; 
     1082    } 
     1083 
     1084 
     1085    // workflow startpoint => data from model 
     1086    if (serviceType_==CServicesManager::CLIENT) 
     1087    { 
     1088      for(auto field : fieldModelIn)  
     1089      { 
     1090        field->connectToModelInput(garbageCollector) ; // connect the field to server filter 
     1091        // grid index will be computed on the fly 
     1092      } 
     1093    } 
     1094     
     1095    // workflow startpoint => data from client on server side 
     1096    if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::GATHERER || serviceType_==CServicesManager::OUT_SERVER) 
     1097    { 
     1098      for(auto field : fieldModelIn)  
     1099      { 
     1100        field->connectToClientInput(garbageCollector) ; // connect the field to server filter 
     1101      } 
     1102    } 
     1103 
     1104     
     1105    for(auto field : couplerInField)  
     1106    { 
     1107      field->connectToCouplerIn(garbageCollector) ; // connect the field to server filter 
     1108    } 
     1109     
     1110     
     1111    for(auto field : couplerOutField)  
     1112    { 
     1113      field->connectToCouplerOut(garbageCollector) ; // for now the same kind of filter that for file server 
     1114    } 
     1115 
     1116     // workflow startpoint => data from server on client side 
     1117    if (serviceType_==CServicesManager::CLIENT) 
     1118    { 
     1119      for(auto field : fileInField)  
     1120      { 
     1121        field->sendFieldToInputFileServer() ; 
     1122        field->connectToServerInput(garbageCollector) ; // connect the field to server filter 
     1123        fileInFields_.push_back(field) ; 
     1124      } 
     1125    } 
     1126 
     1127    // workflow startpoint => data read from file on server side 
     1128    if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::GATHERER) 
     1129    { 
     1130      for(auto field : fileInField)  
     1131      { 
     1132        field->connectToFileReader(garbageCollector) ; 
     1133      } 
     1134    } 
     1135     
     1136    // construct slave server list 
     1137    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER)  
     1138    { 
     1139      for(auto field : fileOutField) slaveServers_.insert(field->getContextClient()) ;  
     1140      for(auto field : fileInField)  slaveServers_.insert(field->getContextClient()) ;   
     1141    } 
     1142 
     1143    for(auto& slaveServer : slaveServers_) sendCloseDefinition(slaveServer) ; 
     1144 
     1145    if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::OUT_SERVER)   
     1146    { 
     1147      createFileHeader(); 
     1148    } 
     1149 
     1150    if (serviceType_==CServicesManager::CLIENT) startPrefetchingOfEnabledReadModeFiles(); 
     1151    
     1152    // send signal to couplerIn context that definition phasis is done 
     1153 
     1154    for(auto& couplerInClient : couplerInClient_) sendCouplerInCloseDefinition(couplerInClient.second) ; 
     1155 
     1156    // wait until all couplerIn signal that closeDefition is done. 
     1157    bool ok; 
     1158    do 
     1159    { 
     1160      ok = true ; 
     1161      for(auto& couplerOutClient : couplerOutClient_) ok &= isCouplerInCloseDefinition(couplerOutClient.second) ; 
     1162      this->eventLoop() ;  
     1163    } while (!ok) ; 
     1164 
     1165     CTimer::get("Context : close definition").suspend() ; 
     1166  } 
     1167  CATCH_DUMP_ATTR 
     1168 
     1169 
     1170  vector<CField*> CContext::findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles) 
     1171   TRY 
     1172   { 
     1173     vector<CField*> fields ; 
     1174     for(auto file : activeFiles) 
     1175     { 
     1176        const vector<CField*>&& fieldList=file->getEnabledFields() ; 
     1177        for(auto field : fieldList) field->setFileOut(file) ; 
     1178        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1179     } 
     1180     return fields ; 
     1181   } 
     1182   CATCH_DUMP_ATTR 
     1183 
     1184   vector<CField*> CContext::findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles) 
     1185   TRY 
     1186   { 
     1187     vector<CField*> fields ; 
     1188     for(auto file : activeFiles) 
     1189     { 
     1190        const vector<CField*>&& fieldList=file->getEnabledFields() ; 
     1191        for(auto field : fieldList) field->setFileIn(file) ; 
     1192        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1193     } 
     1194     return fields ; 
     1195   } 
     1196   CATCH_DUMP_ATTR 
     1197 
     1198   vector<CField*> CContext::findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut) 
     1199   TRY 
     1200   { 
     1201     vector<CField*> fields ; 
     1202     for (auto couplerOut :activeCouplerOut) 
     1203     { 
     1204        const vector<CField*>&& fieldList=couplerOut->getEnabledFields() ; 
     1205        for(auto field : fieldList) field->setCouplerOut(couplerOut) ; 
     1206        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1207     } 
     1208     return fields ; 
     1209   } 
     1210   CATCH_DUMP_ATTR 
     1211 
     1212   vector<CField*> CContext::findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn) 
     1213   TRY 
     1214   { 
     1215     vector<CField*> fields ; 
     1216     for (auto couplerIn :activeCouplerIn) 
     1217     { 
     1218        const vector<CField*>&& fieldList=couplerIn->getEnabledFields() ; 
     1219        for(auto field : fieldList) field->setCouplerIn(couplerIn) ; 
     1220        fields.insert(fields.end(),fieldList.begin(),fieldList.end()); 
     1221     } 
     1222     return fields ; 
     1223   } 
     1224   CATCH_DUMP_ATTR 
     1225 
     1226 /*! 
     1227  * Send context attribute and calendar to file server, it must be done once by context file server 
     1228  * \param[in] client : context client to send    
     1229  */   
     1230  void CContext::sendContextToFileServer(CContextClient* client) 
     1231  { 
     1232    if (sendToFileServer_done_.count(client)!=0) return ; 
     1233    else sendToFileServer_done_.insert(client) ; 
     1234     
     1235    this->sendAllAttributesToServer(client); // Send all attributes of current context to server 
     1236    CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(client); // Send all attributes of current cale 
     1237  } 
     1238 
     1239  
    7421240   void CContext::readAttributesOfEnabledFieldsInReadModeFiles() 
    7431241   TRY 
     
    7481246   CATCH_DUMP_ATTR 
    7491247 
    750    void CContext::sendGridComponentEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
    751    TRY 
    752    { 
    753      int size = activeFiles.size(); 
    754      for (int i = 0; i < size; ++i) 
    755      {        
    756        activeFiles[i]->sendGridComponentOfEnabledFields(); 
    757      } 
    758    } 
    759    CATCH_DUMP_ATTR 
    760  
    761    /*! 
    762       Send active (enabled) fields in file from a client to others 
    763       \param [in] activeFiles files contains enabled fields to send 
    764    */ 
    765    void CContext::sendGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
    766    TRY 
    767    { 
    768      int size = activeFiles.size(); 
    769      for (int i = 0; i < size; ++i) 
    770      {        
    771        activeFiles[i]->sendGridOfEnabledFields(); 
    772      } 
    773    } 
    774    CATCH_DUMP_ATTR 
    775  
    776    void CContext::checkGridEnabledFields() 
    777    TRY 
    778    { 
    779      int size = enabledFiles.size(); 
    780      for (int i = 0; i < size; ++i) 
    781      { 
    782        enabledFiles[i]->checkGridOfEnabledFields();        
    783      } 
    784    } 
    785    CATCH_DUMP_ATTR 
    786  
    787    /*! 
    788       Check grid of active (enabled) fields in file  
    789       \param [in] activeFiles files contains enabled fields whose grid needs checking 
    790    */ 
    791    void CContext::checkGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles) 
    792    TRY 
    793    { 
    794      int size = activeFiles.size(); 
    795      for (int i = 0; i < size; ++i) 
    796      { 
    797        activeFiles[i]->checkGridOfEnabledFields();        
    798      } 
    799    } 
    800    CATCH_DUMP_ATTR 
    801  
    802     /*! 
    803       Go up the hierachical tree via field_ref and do check of attributes of fields 
    804       This can be done in a client then all computed information will be sent from this client to others 
    805       \param [in] sendToServer Flag to indicate whether calculated information will be sent 
    806    */ 
    807    void CContext::solveOnlyRefOfEnabledFields(bool sendToServer) 
    808    TRY 
    809    { 
    810      int size = this->enabledFiles.size(); 
    811      for (int i = 0; i < size; ++i) 
    812      { 
    813        this->enabledFiles[i]->solveOnlyRefOfEnabledFields(sendToServer); 
    814      } 
    815  
    816      for (int i = 0; i < size; ++i) 
    817      { 
    818        this->enabledFiles[i]->generateNewTransformationGridDest(); 
    819      } 
    820    } 
    821    CATCH_DUMP_ATTR 
    822  
    823     /*! 
    824       Go up the hierachical tree via field_ref and do check of attributes of fields. 
    825       The transformation can be done in this step. 
    826       All computed information will be sent from this client to others. 
    827       \param [in] sendToServer Flag to indicate whether calculated information will be sent 
    828    */ 
    829    void CContext::solveAllRefOfEnabledFieldsAndTransform(bool sendToServer) 
    830    TRY 
    831    { 
    832      int size = this->enabledFiles.size(); 
    833      for (int i = 0; i < size; ++i) 
    834      { 
    835        this->enabledFiles[i]->solveAllRefOfEnabledFieldsAndTransform(sendToServer); 
    836      } 
    837    } 
    838    CATCH_DUMP_ATTR 
    839  
    840    void CContext::buildFilterGraphOfEnabledFields() 
    841    TRY 
    842    { 
    843      int size = this->enabledFiles.size(); 
    844      for (int i = 0; i < size; ++i) 
    845      { 
    846        this->enabledFiles[i]->buildFilterGraphOfEnabledFields(garbageCollector); 
    847      } 
    848    } 
    849    CATCH_DUMP_ATTR 
    8501248 
    8511249   void CContext::postProcessFilterGraph() 
     
    8961294  TRY 
    8971295  { 
    898     fieldsWithReadAccess.clear(); 
     1296    fieldsWithReadAccess_.clear(); 
    8991297    const vector<CField*> allFields = CField::getAll(); 
    9001298    for (size_t i = 0; i < allFields.size(); ++i) 
    9011299    { 
    9021300      CField* field = allFields[i]; 
    903  
    904       if (field->file && !field->file->mode.isEmpty() && field->file->mode == CFile::mode_attr::read) 
    905         field->read_access = true; 
    906       else if (!field->read_access.isEmpty() && field->read_access && (field->enabled.isEmpty() || field->enabled)) 
    907         fieldsWithReadAccess.push_back(field); 
     1301      if (!field->read_access.isEmpty() && field->read_access && (field->enabled.isEmpty() || field->enabled)) 
     1302      { 
     1303        fieldsWithReadAccess_.push_back(field); 
     1304        field->setModelOut() ; 
     1305      } 
    9081306    } 
    9091307  } 
    9101308  CATCH_DUMP_ATTR 
    9111309 
    912   void CContext::solveAllRefOfFieldsWithReadAccess() 
    913   TRY 
    914   { 
    915     for (size_t i = 0; i < fieldsWithReadAccess.size(); ++i) 
    916       fieldsWithReadAccess[i]->solveAllReferenceEnabledField(false); 
    917   } 
    918   CATCH_DUMP_ATTR 
    919  
    920   void CContext::buildFilterGraphOfFieldsWithReadAccess() 
    921   TRY 
    922   { 
    923     for (size_t i = 0; i < fieldsWithReadAccess.size(); ++i) 
    924       fieldsWithReadAccess[i]->buildFilterGraph(garbageCollector, true); 
    925   } 
    926   CATCH_DUMP_ATTR 
    927  
     1310   
    9281311   void CContext::solveAllInheritance(bool apply) 
    9291312   TRY 
     
    9351318     // Résolution des héritages par référence au niveau des fichiers. 
    9361319      const vector<CFile*> allFiles=CFile::getAll(); 
     1320      const vector<CCouplerIn*> allCouplerIn=CCouplerIn::getAll(); 
     1321      const vector<CCouplerOut*> allCouplerOut=CCouplerOut::getAll(); 
    9371322      const vector<CGrid*> allGrids= CGrid::getAll(); 
    9381323 
    939       if (hasClient && !hasServer) 
    940       //if (hasClient) 
     1324      if (serviceType_==CServicesManager::CLIENT) 
    9411325      { 
    9421326        for (unsigned int i = 0; i < allFiles.size(); i++) 
    9431327          allFiles[i]->solveFieldRefInheritance(apply); 
     1328 
     1329        for (unsigned int i = 0; i < allCouplerIn.size(); i++) 
     1330          allCouplerIn[i]->solveFieldRefInheritance(apply); 
     1331 
     1332        for (unsigned int i = 0; i < allCouplerOut.size(); i++) 
     1333          allCouplerOut[i]->solveFieldRefInheritance(apply); 
    9441334      } 
    9451335 
     
    9471337      unsigned int i = 0; 
    9481338      for (i = 0; i < vecSize; ++i) 
    949         allGrids[i]->solveDomainAxisRefInheritance(apply); 
     1339        allGrids[i]->solveElementsRefInheritance(apply); 
    9501340 
    9511341   } 
     
    10041394   CATCH_DUMP_ATTR 
    10051395 
    1006    void CContext::distributeFiles(void) 
     1396   void CContext::findEnabledCouplerIn(void) 
     1397   TRY 
     1398   { 
     1399      const std::vector<CCouplerIn*> allCouplerIn = CCouplerIn::getAll(); 
     1400      bool enabled ; 
     1401      for (size_t i = 0; i < allCouplerIn.size(); i++) 
     1402      { 
     1403        if (allCouplerIn[i]->enabled.isEmpty()) enabled=true ; 
     1404        else enabled=allCouplerIn[i]->enabled ; 
     1405        if (enabled) enabledCouplerIn.push_back(allCouplerIn[i]) ; 
     1406      } 
     1407   } 
     1408   CATCH_DUMP_ATTR 
     1409 
     1410   void CContext::findEnabledCouplerOut(void) 
     1411   TRY 
     1412   { 
     1413      const std::vector<CCouplerOut*> allCouplerOut = CCouplerOut::getAll(); 
     1414      bool enabled ; 
     1415      for (size_t i = 0; i < allCouplerOut.size(); i++) 
     1416      { 
     1417        if (allCouplerOut[i]->enabled.isEmpty()) enabled=true ; 
     1418        else enabled=allCouplerOut[i]->enabled ; 
     1419        if (enabled) enabledCouplerOut.push_back(allCouplerOut[i]) ; 
     1420      } 
     1421   } 
     1422   CATCH_DUMP_ATTR 
     1423 
     1424 
     1425 
     1426 
     1427   void CContext::distributeFiles(const vector<CFile*>& files) 
    10071428   TRY 
    10081429   { 
     
    10101431     distFileMemory=CXios::getin<bool>("server2_dist_file_memory", distFileMemory); 
    10111432 
    1012      if (distFileMemory) distributeFileOverMemoryBandwith() ; 
    1013      else distributeFileOverBandwith() ; 
    1014    } 
    1015    CATCH_DUMP_ATTR 
    1016  
    1017    void CContext::distributeFileOverBandwith(void) 
     1433     if (distFileMemory) distributeFileOverMemoryBandwith(files) ; 
     1434     else distributeFileOverBandwith(files) ; 
     1435   } 
     1436   CATCH_DUMP_ATTR 
     1437 
     1438   void CContext::distributeFileOverBandwith(const vector<CFile*>& files) 
    10181439   TRY 
    10191440   { 
    10201441     double eps=std::numeric_limits<double>::epsilon()*10 ; 
    10211442      
    1022      // If primary server 
    1023      if (hasServer && hasClient) 
    1024      { 
    1025        std::ofstream ofs(("distribute_file_"+getId()+".dat").c_str(), std::ofstream::out); 
    1026        int nbPools = clientPrimServer.size(); 
    1027  
    1028        // (1) Find all enabled files in write mode 
    1029        // for (int i = 0; i < this->enabledFiles.size(); ++i) 
    1030        // { 
    1031        //   if (enabledFiles[i]->mode.isEmpty() || (!enabledFiles[i]->mode.isEmpty() && enabledFiles[i]->mode.getValue() == CFile::mode_attr::write )) 
    1032        //    enabledWriteModeFiles.push_back(enabledFiles[i]); 
    1033        // } 
    1034  
    1035        // (2) Estimate the data volume for each file 
    1036        int size = this->enabledWriteModeFiles.size(); 
    1037        std::vector<std::pair<double, CFile*> > dataSizeMap; 
    1038        double dataPerPool = 0; 
    1039        int nfield=0 ; 
    1040        ofs<<size<<endl ; 
    1041        for (size_t i = 0; i < size; ++i) 
     1443     std::ofstream ofs(("distribute_file_"+getId()+".dat").c_str(), std::ofstream::out); 
     1444     int nbPools = clientPrimServer.size(); 
     1445 
     1446     // (1) Find all enabled files in write mode 
     1447     // for (int i = 0; i < this->enabledFiles.size(); ++i) 
     1448     // { 
     1449     //   if (enabledFiles[i]->mode.isEmpty() || (!enabledFiles[i]->mode.isEmpty() && enabledFiles[i]->mode.getValue() == CFile::mode_attr::write )) 
     1450     //    enabledWriteModeFiles.push_back(enabledFiles[i]); 
     1451     // } 
     1452 
     1453     // (2) Estimate the data volume for each file 
     1454     int size = files.size(); 
     1455     std::vector<std::pair<double, CFile*> > dataSizeMap; 
     1456     double dataPerPool = 0; 
     1457     int nfield=0 ; 
     1458     ofs<<size<<endl ; 
     1459     for (size_t i = 0; i < size; ++i) 
     1460     { 
     1461       CFile* file = files[i]; 
     1462       ofs<<file->getId()<<endl ; 
     1463       StdSize dataSize=0; 
     1464       std::vector<CField*> enabledFields = file->getEnabledFields(); 
     1465       size_t numEnabledFields = enabledFields.size(); 
     1466       ofs<<numEnabledFields<<endl ; 
     1467       for (size_t j = 0; j < numEnabledFields; ++j) 
    10421468       { 
    1043          CFile* file = this->enabledWriteModeFiles[i]; 
    1044          ofs<<file->getId()<<endl ; 
    1045          StdSize dataSize=0; 
    1046          std::vector<CField*> enabledFields = file->getEnabledFields(); 
    1047          size_t numEnabledFields = enabledFields.size(); 
    1048          ofs<<numEnabledFields<<endl ; 
    1049          for (size_t j = 0; j < numEnabledFields; ++j) 
     1469         dataSize += enabledFields[j]->getGlobalWrittenSize() ; 
     1470         ofs<<enabledFields[j]->getGrid()->getId()<<endl ; 
     1471         ofs<<enabledFields[j]->getGlobalWrittenSize()<<endl ; 
     1472       } 
     1473       double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ; 
     1474       double dataSizeSec= dataSize/ outFreqSec; 
     1475       ofs<<dataSizeSec<<endl ; 
     1476       nfield++ ; 
     1477// add epsilon*nField to dataSizeSec in order to  preserve reproductive ordering when sorting 
     1478       dataSizeMap.push_back(make_pair(dataSizeSec + dataSizeSec * eps * nfield , file)); 
     1479       dataPerPool += dataSizeSec; 
     1480     } 
     1481     dataPerPool /= nbPools; 
     1482     std::sort(dataSizeMap.begin(), dataSizeMap.end()); 
     1483 
     1484     // (3) Assign contextClient to each enabled file 
     1485 
     1486     std::multimap<double,int> poolDataSize ; 
     1487// multimap is not garanty to preserve stable sorting in c++98 but it seems it does for c++11 
     1488 
     1489     int j; 
     1490     double dataSize ; 
     1491     for (j = 0 ; j < nbPools ; ++j) poolDataSize.insert(std::pair<double,int>(0.,j)) ;   
     1492              
     1493     for (int i = dataSizeMap.size()-1; i >= 0; --i) 
     1494     { 
     1495       dataSize=(*poolDataSize.begin()).first ; 
     1496       j=(*poolDataSize.begin()).second ; 
     1497       dataSizeMap[i].second->setContextClient(clientPrimServer[j]); 
     1498       dataSize+=dataSizeMap[i].first; 
     1499       poolDataSize.erase(poolDataSize.begin()) ; 
     1500       poolDataSize.insert(std::pair<double,int>(dataSize,j)) ;  
     1501     } 
     1502 
     1503     for (std::multimap<double,int>:: iterator it=poolDataSize.begin() ; it!=poolDataSize.end(); ++it) info(30)<<"Load Balancing for servers (perfect=1) : "<<it->second<<" :  ratio "<<it->first*1./dataPerPool<<endl ; 
     1504   } 
     1505   CATCH_DUMP_ATTR 
     1506 
     1507   void CContext::distributeFileOverMemoryBandwith(const vector<CFile*>& filesList) 
     1508   TRY 
     1509   { 
     1510     int nbPools = clientPrimServer.size(); 
     1511     double ratio=0.5 ; 
     1512     ratio=CXios::getin<double>("server2_dist_file_memory_ratio", ratio); 
     1513 
     1514     int nFiles = filesList.size(); 
     1515     vector<SDistFile> files(nFiles); 
     1516     vector<SDistGrid> grids; 
     1517     map<string,int> gridMap ; 
     1518     string gridId;  
     1519     int gridIndex=0 ; 
     1520 
     1521     for (size_t i = 0; i < nFiles; ++i) 
     1522     { 
     1523       StdSize dataSize=0; 
     1524       CFile* file = filesList[i]; 
     1525       std::vector<CField*> enabledFields = file->getEnabledFields(); 
     1526       size_t numEnabledFields = enabledFields.size(); 
     1527 
     1528       files[i].id_=file->getId() ; 
     1529       files[i].nbGrids_=numEnabledFields; 
     1530       files[i].assignedGrid_ = new int[files[i].nbGrids_] ; 
     1531          
     1532       for (size_t j = 0; j < numEnabledFields; ++j) 
     1533       { 
     1534         gridId=enabledFields[j]->getGrid()->getId() ; 
     1535         if (gridMap.find(gridId)==gridMap.end()) 
    10501536         { 
    1051            dataSize += enabledFields[j]->getGlobalWrittenSize() ; 
    1052            ofs<<enabledFields[j]->grid->getId()<<endl ; 
    1053            ofs<<enabledFields[j]->getGlobalWrittenSize()<<endl ; 
     1537            gridMap[gridId]=gridIndex  ; 
     1538            SDistGrid newGrid;  
     1539            grids.push_back(newGrid) ; 
     1540            gridIndex++ ; 
    10541541         } 
    1055          double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ; 
    1056          double dataSizeSec= dataSize/ outFreqSec; 
    1057          ofs<<dataSizeSec<<endl ; 
    1058          nfield++ ; 
    1059 // add epsilon*nField to dataSizeSec in order to  preserve reproductive ordering when sorting 
    1060          dataSizeMap.push_back(make_pair(dataSizeSec + dataSizeSec * eps * nfield , file)); 
    1061          dataPerPool += dataSizeSec; 
     1542         files[i].assignedGrid_[j]=gridMap[gridId] ; 
     1543         grids[files[i].assignedGrid_[j]].size_=enabledFields[j]->getGlobalWrittenSize() ; 
     1544         dataSize += enabledFields[j]->getGlobalWrittenSize() ; // usefull 
    10621545       } 
    1063        dataPerPool /= nbPools; 
    1064        std::sort(dataSizeMap.begin(), dataSizeMap.end()); 
    1065  
    1066        // (3) Assign contextClient to each enabled file 
    1067  
    1068        std::multimap<double,int> poolDataSize ; 
    1069 // multimap is not garanty to preserve stable sorting in c++98 but it seems it does for c++11 
    1070  
    1071        int j; 
    1072        double dataSize ; 
    1073        for (j = 0 ; j < nbPools ; ++j) poolDataSize.insert(std::pair<double,int>(0.,j)) ;   
    1074                
    1075        for (int i = dataSizeMap.size()-1; i >= 0; --i) 
     1546       double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ; 
     1547       files[i].bandwith_= dataSize/ outFreqSec ; 
     1548     } 
     1549 
     1550     double bandwith=0 ; 
     1551     double memory=0 ; 
     1552    
     1553     for(int i=0; i<nFiles; i++)  bandwith+=files[i].bandwith_ ; 
     1554     for(int i=0; i<nFiles; i++)  files[i].bandwith_ = files[i].bandwith_/bandwith * ratio ; 
     1555 
     1556     for(int i=0; i<grids.size(); i++)  memory+=grids[i].size_ ; 
     1557     for(int i=0; i<grids.size(); i++)  grids[i].size_ = grids[i].size_ / memory * (1.0-ratio) ; 
     1558        
     1559     distributeFileOverServer2(nbPools, grids.size(), &grids[0], nFiles, &files[0]) ; 
     1560 
     1561     vector<double> memorySize(nbPools,0.) ; 
     1562     vector< set<int> > serverGrids(nbPools) ; 
     1563     vector<double> bandwithSize(nbPools,0.) ; 
     1564        
     1565     for (size_t i = 0; i < nFiles; ++i) 
     1566     { 
     1567       bandwithSize[files[i].assignedServer_] += files[i].bandwith_* bandwith /ratio ; 
     1568       for(int j=0 ; j<files[i].nbGrids_;j++) 
    10761569       { 
    1077          dataSize=(*poolDataSize.begin()).first ; 
    1078          j=(*poolDataSize.begin()).second ; 
    1079          dataSizeMap[i].second->setContextClient(clientPrimServer[j]); 
    1080          dataSize+=dataSizeMap[i].first; 
    1081          poolDataSize.erase(poolDataSize.begin()) ; 
    1082          poolDataSize.insert(std::pair<double,int>(dataSize,j)) ;  
     1570         if (serverGrids[files[i].assignedServer_].find(files[i].assignedGrid_[j]) == serverGrids[files[i].assignedServer_].end()) 
     1571         { 
     1572           memorySize[files[i].assignedServer_]+= grids[files[i].assignedGrid_[j]].size_ * memory / (1.0-ratio); 
     1573           serverGrids[files[i].assignedServer_].insert(files[i].assignedGrid_[j]) ; 
     1574         } 
    10831575       } 
    1084  
    1085        for (std::multimap<double,int>:: iterator it=poolDataSize.begin() ; it!=poolDataSize.end(); ++it) info(30)<<"Load Balancing for servers (perfect=1) : "<<it->second<<" :  ratio "<<it->first*1./dataPerPool<<endl ; 
    1086   
    1087        for (int i = 0; i < this->enabledReadModeFiles.size(); ++i) 
    1088        { 
    1089          enabledReadModeFiles[i]->setContextClient(client);           
    1090        } 
    1091      } 
    1092      else 
    1093      { 
    1094        for (int i = 0; i < this->enabledFiles.size(); ++i) 
    1095          enabledFiles[i]->setContextClient(client); 
    1096      } 
    1097    } 
    1098    CATCH_DUMP_ATTR 
    1099  
    1100    void CContext::distributeFileOverMemoryBandwith(void) 
    1101    TRY 
    1102    { 
    1103      // If primary server 
    1104      if (hasServer && hasClient) 
    1105      { 
    1106        int nbPools = clientPrimServer.size(); 
    1107        double ratio=0.5 ; 
    1108        ratio=CXios::getin<double>("server2_dist_file_memory_ratio", ratio); 
    1109  
    1110        int nFiles = this->enabledWriteModeFiles.size(); 
    1111        vector<SDistFile> files(nFiles); 
    1112        vector<SDistGrid> grids; 
    1113        map<string,int> gridMap ; 
    1114        string gridId;  
    1115        int gridIndex=0 ; 
    1116  
    1117        for (size_t i = 0; i < nFiles; ++i) 
    1118        { 
    1119          StdSize dataSize=0; 
    1120          CFile* file = this->enabledWriteModeFiles[i]; 
    1121          std::vector<CField*> enabledFields = file->getEnabledFields(); 
    1122          size_t numEnabledFields = enabledFields.size(); 
    1123  
    1124          files[i].id_=file->getId() ; 
    1125          files[i].nbGrids_=numEnabledFields; 
    1126          files[i].assignedGrid_ = new int[files[i].nbGrids_] ; 
    1127           
    1128          for (size_t j = 0; j < numEnabledFields; ++j) 
    1129          { 
    1130            gridId=enabledFields[j]->grid->getId() ; 
    1131            if (gridMap.find(gridId)==gridMap.end()) 
    1132            { 
    1133               gridMap[gridId]=gridIndex  ; 
    1134               SDistGrid newGrid;  
    1135               grids.push_back(newGrid) ; 
    1136               gridIndex++ ; 
    1137            } 
    1138            files[i].assignedGrid_[j]=gridMap[gridId] ; 
    1139            grids[files[i].assignedGrid_[j]].size_=enabledFields[j]->getGlobalWrittenSize() ; 
    1140            dataSize += enabledFields[j]->getGlobalWrittenSize() ; // usefull 
    1141          } 
    1142          double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ; 
    1143          files[i].bandwith_= dataSize/ outFreqSec ; 
    1144        } 
    1145  
    1146        double bandwith=0 ; 
    1147        double memory=0 ; 
    1148     
    1149        for(int i=0; i<nFiles; i++)  bandwith+=files[i].bandwith_ ; 
    1150        for(int i=0; i<nFiles; i++)  files[i].bandwith_ = files[i].bandwith_/bandwith * ratio ; 
    1151  
    1152        for(int i=0; i<grids.size(); i++)  memory+=grids[i].size_ ; 
    1153        for(int i=0; i<grids.size(); i++)  grids[i].size_ = grids[i].size_ / memory * (1.0-ratio) ; 
    1154         
    1155        distributeFileOverServer2(nbPools, grids.size(), &grids[0], nFiles, &files[0]) ; 
    1156  
    1157        vector<double> memorySize(nbPools,0.) ; 
    1158        vector< set<int> > serverGrids(nbPools) ; 
    1159        vector<double> bandwithSize(nbPools,0.) ; 
    1160         
    1161        for (size_t i = 0; i < nFiles; ++i) 
    1162        { 
    1163          bandwithSize[files[i].assignedServer_] += files[i].bandwith_* bandwith /ratio ; 
    1164          for(int j=0 ; j<files[i].nbGrids_;j++) 
    1165          { 
    1166            if (serverGrids[files[i].assignedServer_].find(files[i].assignedGrid_[j]) == serverGrids[files[i].assignedServer_].end()) 
    1167            { 
    1168              memorySize[files[i].assignedServer_]+= grids[files[i].assignedGrid_[j]].size_ * memory / (1.0-ratio); 
    1169              serverGrids[files[i].assignedServer_].insert(files[i].assignedGrid_[j]) ; 
    1170            } 
    1171          } 
    1172          enabledWriteModeFiles[i]->setContextClient(clientPrimServer[files[i].assignedServer_]) ; 
    1173          delete [] files[i].assignedGrid_ ; 
    1174        } 
    1175  
    1176        for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned file bandwith "<<bandwithSize[i]*86400.*4./1024/1024.<<" Mb / days"<<endl ; 
    1177        for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned grid memory "<<memorySize[i]*100/1024./1024.<<" Mb"<<endl ; 
    1178  
    1179  
    1180        for (int i = 0; i < this->enabledReadModeFiles.size(); ++i) 
    1181        { 
    1182          enabledReadModeFiles[i]->setContextClient(client);           
    1183        } 
    1184  
    1185    } 
    1186    else 
    1187    { 
    1188      for (int i = 0; i < this->enabledFiles.size(); ++i) 
    1189         enabledFiles[i]->setContextClient(client); 
    1190    } 
    1191 } 
     1576       filesList[i]->setContextClient(clientPrimServer[files[i].assignedServer_]) ; 
     1577       delete [] files[i].assignedGrid_ ; 
     1578     } 
     1579 
     1580     for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned file bandwith "<<bandwithSize[i]*86400.*4./1024/1024.<<" Mb / days"<<endl ; 
     1581     for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned grid memory "<<memorySize[i]*100/1024./1024.<<" Mb"<<endl ; 
     1582 
     1583   } 
    11921584   CATCH_DUMP_ATTR 
    11931585 
     
    12651657             return true; 
    12661658             break; 
    1267            case EVENT_ID_POST_PROCESS: 
    1268              recvPostProcessing(event); 
    1269              return true; 
    1270             case EVENT_ID_SEND_REGISTRY: 
     1659           case EVENT_ID_SEND_REGISTRY: 
    12711660             recvRegistry(event); 
    12721661             return true; 
    12731662             break; 
    1274             case EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES: 
    1275              recvPostProcessingGlobalAttributes(event); 
     1663           case EVENT_ID_COUPLER_IN_READY: 
     1664             recvCouplerInReady(event); 
    12761665             return true; 
    12771666             break; 
    1278             case EVENT_ID_PROCESS_GRID_ENABLED_FIELDS: 
    1279              recvProcessingGridOfEnabledFields(event); 
     1667           case EVENT_ID_COUPLER_IN_CLOSE_DEFINITION: 
     1668             recvCouplerInCloseDefinition(event); 
    12801669             return true; 
    12811670             break; 
     1671           case EVENT_ID_COUPLER_IN_CONTEXT_FINALIZED: 
     1672             recvCouplerInContextFinalized(event); 
     1673             return true; 
     1674             break;   
    12821675           default : 
    12831676             ERROR("bool CContext::dispatchEvent(CEventServer& event)", 
     
    12901683 
    12911684   //! Client side: Send a message to server to make it close 
     1685   // ym obsolete 
    12921686   void CContext::sendCloseDefinition(void) 
    12931687   TRY 
    12941688   { 
    1295      // Use correct context client to send message 
    1296      int nbSrvPools = (this->hasServer) ? (this->hasClient ? this->clientPrimServer.size() : 0) : 1; 
    1297      for (int i = 0; i < nbSrvPools; ++i) 
    1298      { 
    1299        CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client; 
     1689    int nbSrvPools ; 
     1690    if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ; 
     1691    else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ; 
     1692    else nbSrvPools = 0 ; 
     1693    CContextClient* contextClientTmp ; 
     1694 
     1695    for (int i = 0; i < nbSrvPools; ++i) 
     1696     { 
     1697       if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ; 
     1698       else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ; 
    13001699       CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION); 
    13011700       if (contextClientTmp->isServerLeader()) 
    13021701       { 
    13031702         CMessage msg; 
    1304          if (hasServer) 
    1305            msg<<this->getIdServer(i); 
    1306          else 
    1307            msg<<this->getIdServer(); 
    13081703         const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    13091704         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     
    13151710   } 
    13161711   CATCH_DUMP_ATTR 
     1712    
     1713   //  ! Client side: Send a message to server to make it close 
     1714   void CContext::sendCloseDefinition(CContextClient* client) 
     1715   TRY 
     1716   { 
     1717      if (sendCloseDefinition_done_.count(client)!=0) return ; 
     1718      else sendCloseDefinition_done_.insert(client) ; 
     1719 
     1720      CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION); 
     1721      if (client->isServerLeader()) 
     1722      { 
     1723        CMessage msg; 
     1724        for(auto rank : client->getRanksServerLeader()) event.push(rank,1,msg); 
     1725        client->sendEvent(event); 
     1726      } 
     1727     else client->sendEvent(event); 
     1728   } 
     1729   CATCH_DUMP_ATTR 
    13171730 
    13181731   //! Server side: Receive a message of client announcing a context close 
     
    13211734   { 
    13221735      CBufferIn* buffer=event.subEvents.begin()->buffer; 
    1323       string id; 
    1324       *buffer>>id; 
    1325       get(id)->closeDefinition(); 
     1736      getCurrent()->closeDefinition(); 
    13261737   } 
    13271738   CATCH 
     
    13311742   TRY 
    13321743   { 
    1333      // Use correct context client to send message 
    1334     int nbSrvPools = (this->hasServer) ? (this->hasClient ? this->clientPrimServer.size() : 0) : 1; 
    1335      for (int i = 0; i < nbSrvPools; ++i) 
    1336      { 
    1337        CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client; 
    1338        CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR); 
    1339  
    1340          if (contextClientTmp->isServerLeader()) 
    1341          { 
    1342            CMessage msg; 
    1343            if (hasServer) 
    1344              msg<<this->getIdServer(i)<<step; 
    1345            else 
    1346              msg<<this->getIdServer()<<step; 
    1347            const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    1348            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1349              event.push(*itRank,1,msg); 
    1350            contextClientTmp->sendEvent(event); 
    1351          } 
    1352          else contextClientTmp->sendEvent(event); 
     1744     CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR); 
     1745     for(auto client : slaveServers_)  
     1746     { 
     1747       if (client->isServerLeader()) 
     1748       { 
     1749         CMessage msg; 
     1750         msg<<step; 
     1751         for (auto& rank : client->getRanksServerLeader() ) event.push(rank,1,msg); 
     1752         client->sendEvent(event); 
     1753       } 
     1754       else client->sendEvent(event); 
    13531755     } 
    13541756   } 
     
    13601762   { 
    13611763      CBufferIn* buffer=event.subEvents.begin()->buffer; 
    1362       string id; 
    1363       *buffer>>id; 
    1364       get(id)->recvUpdateCalendar(*buffer); 
     1764      getCurrent()->recvUpdateCalendar(*buffer); 
    13651765   } 
    13661766   CATCH 
     
    13731773      buffer>>step; 
    13741774      updateCalendar(step); 
    1375       if (hasClient && hasServer) 
     1775      if (serviceType_==CServicesManager::GATHERER) 
    13761776      {         
    13771777        sendUpdateCalendar(step); 
     
    13841784   TRY 
    13851785   { 
    1386      // Use correct context client to send message 
    1387      // int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1; 
    1388      int nbSrvPools = (this->hasServer) ? (this->hasClient ? this->clientPrimServer.size() : 0) : 1; 
     1786     int nbSrvPools ; 
     1787     if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ; 
     1788     else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ; 
     1789     else nbSrvPools = 0 ; 
     1790     CContextClient* contextClientTmp ; 
     1791 
    13891792     for (int i = 0; i < nbSrvPools; ++i) 
    13901793     { 
    1391        CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client; 
     1794       if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ; 
     1795       else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ; 
    13921796       CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER); 
    13931797 
     
    13951799       { 
    13961800         CMessage msg; 
    1397          if (hasServer) 
    1398            msg<<this->getIdServer(i); 
    1399          else 
    1400            msg<<this->getIdServer(); 
    14011801         const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    14021802         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     
    14141814   { 
    14151815      CBufferIn* buffer=event.subEvents.begin()->buffer; 
    1416       string id; 
    1417       *buffer>>id; 
    1418       get(id)->recvCreateFileHeader(*buffer); 
     1816      getCurrent()->recvCreateFileHeader(*buffer); 
    14191817   } 
    14201818   CATCH 
     
    14241822   TRY 
    14251823   { 
    1426       if (!hasClient && hasServer)  
     1824      if (serviceType_==CServicesManager::IO_SERVER || serviceType_==CServicesManager::OUT_SERVER)  
    14271825        createFileHeader(); 
    14281826   } 
    14291827   CATCH_DUMP_ATTR 
    14301828 
    1431    //! Client side: Send a message to do some post processing on server 
    1432    void CContext::sendProcessingGridOfEnabledFields() 
    1433    TRY 
    1434    { 
    1435       // Use correct context client to send message 
    1436      int nbSrvPools = (this->hasServer) ? (this->hasClient ? this->clientPrimServer.size() : 0) : 1; 
    1437      for (int i = 0; i < nbSrvPools; ++i) 
    1438      { 
    1439        CContextClient* contextClientTmp = (0 != clientPrimServer.size()) ? clientPrimServer[i] : client; 
    1440        CEventClient event(getType(),EVENT_ID_PROCESS_GRID_ENABLED_FIELDS); 
    1441  
    1442        if (contextClientTmp->isServerLeader()) 
    1443        { 
    1444          CMessage msg; 
    1445          if (hasServer) 
    1446            msg<<this->getIdServer(i); 
    1447          else 
    1448            msg<<this->getIdServer(); 
    1449          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    1450          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1451            event.push(*itRank,1,msg); 
    1452          contextClientTmp->sendEvent(event); 
    1453        } 
    1454        else contextClientTmp->sendEvent(event); 
    1455      } 
    1456    } 
    1457    CATCH_DUMP_ATTR 
    1458  
    1459    //! Server side: Receive a message to do some post processing 
    1460    void CContext::recvProcessingGridOfEnabledFields(CEventServer& event) 
    1461    TRY 
    1462    { 
    1463       CBufferIn* buffer=event.subEvents.begin()->buffer; 
    1464       string id; 
    1465       *buffer>>id;       
    1466    } 
    1467    CATCH 
    1468  
    1469    //! Client side: Send a message to do some post processing on server 
    1470    void CContext::sendPostProcessing() 
    1471    TRY 
    1472    { 
    1473       // Use correct context client to send message 
    1474      // int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1; 
    1475      int nbSrvPools = (this->hasServer) ? (this->hasClient ? this->clientPrimServer.size() : 0) : 1; 
    1476      for (int i = 0; i < nbSrvPools; ++i) 
    1477      { 
    1478        CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client; 
    1479        CEventClient event(getType(),EVENT_ID_POST_PROCESS); 
    1480        if (contextClientTmp->isServerLeader()) 
    1481        { 
    1482          CMessage msg; 
    1483          if (hasServer) 
    1484            msg<<this->getIdServer(i); 
    1485          else 
    1486            msg<<this->getIdServer(); 
    1487          const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    1488          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1489          event.push(*itRank,1,msg); 
    1490          contextClientTmp->sendEvent(event); 
    1491        } 
    1492        else contextClientTmp->sendEvent(event); 
    1493      } 
    1494    } 
    1495    CATCH_DUMP_ATTR 
    1496  
    1497    //! Server side: Receive a message to do some post processing 
    1498    void CContext::recvPostProcessing(CEventServer& event) 
    1499    TRY 
    1500    { 
    1501       CBufferIn* buffer=event.subEvents.begin()->buffer; 
    1502       string id; 
    1503       *buffer>>id; 
    1504       get(id)->recvPostProcessing(*buffer); 
    1505    } 
    1506    CATCH 
    1507  
    1508    //! Server side: Receive a message to do some post processing 
    1509    void CContext::recvPostProcessing(CBufferIn& buffer) 
    1510    TRY 
    1511    { 
    1512       CCalendarWrapper::get(CCalendarWrapper::GetDefName())->createCalendar(); 
    1513       postProcessing(); 
    1514    } 
    1515    CATCH_DUMP_ATTR 
    1516  
    1517    const StdString& CContext::getIdServer() 
    1518    TRY 
    1519    { 
    1520       if (hasClient) 
    1521       { 
    1522         idServer_ = this->getId(); 
    1523         idServer_ += "_server"; 
    1524         return idServer_; 
    1525       } 
    1526       if (hasServer) return (this->getId()); 
    1527    } 
    1528    CATCH_DUMP_ATTR 
    1529  
    1530    const StdString& CContext::getIdServer(const int i) 
    1531    TRY 
    1532    { 
    1533      idServer_ = this->getId(); 
    1534      idServer_ += "_server_"; 
    1535      idServer_ += std::to_string(static_cast<unsigned long long>(i)); 
    1536      return idServer_; 
    1537    } 
    1538    CATCH_DUMP_ATTR 
    1539  
    1540    /*! 
    1541    \brief Do some simple post processings after parsing xml file 
    1542       After the xml file (iodef.xml) is parsed, it is necessary to build all relations among 
    1543    created object, e.g: inhertance among fields, domain, axis. After that, all fiels as well as their parents (reference fields), 
    1544    which will be written out into netcdf files, are processed 
    1545    */ 
    1546    void CContext::postProcessing() 
    1547    TRY 
    1548    { 
    1549      if (isPostProcessed) return; 
    1550  
    1551       // Make sure the calendar was correctly created 
    1552       if (!calendar) 
    1553         ERROR("CContext::postProcessing()", << "A calendar must be defined for the context \"" << getId() << "!\"") 
    1554       else if (calendar->getTimeStep() == NoneDu) 
    1555         ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"") 
    1556       // Calendar first update to set the current date equals to the start date 
    1557       calendar->update(0); 
    1558  
    1559       // Find all inheritance in xml structure 
    1560       this->solveAllInheritance(); 
    1561  
    1562 //      ShowTree(info(10)); 
    1563  
    1564       // Check if some axis, domains or grids are eligible to for compressed indexed output. 
    1565       // Warning: This must be done after solving the inheritance and before the rest of post-processing 
    1566       checkAxisDomainsGridsEligibilityForCompressedOutput();       
    1567  
    1568       // Check if some automatic time series should be generated 
    1569       // Warning: This must be done after solving the inheritance and before the rest of post-processing       
    1570  
    1571       // The timeseries should only be prepared in client 
    1572       if (hasClient && !hasServer) prepareTimeseries(); 
    1573  
    1574       //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers à sortir. 
    1575       findEnabledFiles(); 
    1576       findEnabledWriteModeFiles(); 
    1577       findEnabledReadModeFiles(); 
    1578  
    1579       // For now, only read files with client and only one level server 
    1580       // if (hasClient && !hasServer) findEnabledReadModeFiles();       
    1581  
    1582       // Find all enabled fields of each file       
    1583       findAllEnabledFieldsInFiles(this->enabledWriteModeFiles); 
    1584       findAllEnabledFieldsInFiles(this->enabledReadModeFiles); 
    1585  
    1586       // For now, only read files with client and only one level server 
    1587       // if (hasClient && !hasServer)  
    1588       //   findAllEnabledFieldsInFiles(this->enabledReadModeFiles);       
    1589  
    1590       if (hasClient && !hasServer) 
    1591       { 
    1592         initReadFiles(); 
    1593         // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis) 
    1594         this->readAttributesOfEnabledFieldsInReadModeFiles(); 
    1595       } 
    1596  
    1597       // Only search and rebuild all reference objects of enable fields, don't transform 
    1598       this->solveOnlyRefOfEnabledFields(false); 
    1599  
    1600       // Search and rebuild all reference object of enabled fields, and transform 
    1601       this->solveAllRefOfEnabledFieldsAndTransform(false); 
    1602  
    1603       // Find all fields with read access from the public API 
    1604       if (hasClient && !hasServer) findFieldsWithReadAccess(); 
    1605       // and solve the all reference for them 
    1606       if (hasClient && !hasServer) solveAllRefOfFieldsWithReadAccess(); 
    1607  
    1608       isPostProcessed = true; 
    1609    } 
    1610    CATCH_DUMP_ATTR 
    1611  
    1612    /*! 
    1613     * Compute the required buffer size to send the attributes (mostly those grid related). 
    1614     * \param maxEventSize [in/out] the size of the bigger event for each connected server 
    1615     * \param [in] contextClient 
    1616     * \param [in] bufferForWriting True if buffers are used for sending data for writing 
    1617       This flag is only true for client and server-1 for communication with server-2 
    1618     */ 
    1619    std::map<int, StdSize> CContext::getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, 
    1620                                                            CContextClient* contextClient, bool bufferForWriting /*= "false"*/) 
    1621    TRY 
    1622    { 
    1623          // As calendar attributes are sent even if there are no active files or fields, maps are initialized according the size of calendar attributes 
    1624      std::map<int, StdSize> attributesSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient); 
    1625      maxEventSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient); 
    1626  
    1627      std::vector<CFile*>& fileList = this->enabledFiles; 
    1628      size_t numEnabledFiles = fileList.size(); 
    1629      for (size_t i = 0; i < numEnabledFiles; ++i) 
    1630      { 
    1631 //         CFile* file = this->enabledWriteModeFiles[i]; 
    1632         CFile* file = fileList[i]; 
    1633         std::vector<CField*> enabledFields = file->getEnabledFields(); 
    1634         size_t numEnabledFields = enabledFields.size(); 
    1635         for (size_t j = 0; j < numEnabledFields; ++j) 
     1829   void CContext::createCouplerInterCommunicator(void) 
     1830   TRY 
     1831   { 
     1832      int rank=this->getIntraCommRank() ; 
     1833      map<string,list<CCouplerOut*>> listCouplerOut ;   
     1834      map<string,list<CCouplerIn*>> listCouplerIn ;   
     1835 
     1836      for(auto couplerOut : enabledCouplerOut) listCouplerOut[couplerOut->getCouplingContextId()].push_back(couplerOut) ; 
     1837      for(auto couplerIn : enabledCouplerIn) listCouplerIn[couplerIn->getCouplingContextId()].push_back(couplerIn) ; 
     1838 
     1839      CCouplerManager* couplerManager = CXios::getCouplerManager() ; 
     1840      if (rank==0) 
     1841      { 
     1842        for(auto couplerOut : listCouplerOut) couplerManager->registerCoupling(this->getContextId(),couplerOut.first) ; 
     1843        for(auto couplerIn : listCouplerIn) couplerManager->registerCoupling(couplerIn.first,this->getContextId()) ; 
     1844      } 
     1845 
     1846      do 
     1847      { 
     1848        for(auto couplerOut : listCouplerOut)  
    16361849        { 
    1637           const std::map<int, StdSize> mapSize = enabledFields[j]->getGridAttributesBufferSize(contextClient, bufferForWriting); 
    1638           std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end(); 
    1639           for (; it != itE; ++it) 
     1850          bool isNextCoupling ; 
     1851          if (rank==0) isNextCoupling = couplerManager->isNextCoupling(this->getContextId(),couplerOut.first) ; 
     1852          MPI_Bcast(&isNextCoupling,1,MPI_C_BOOL, 0, getIntraComm()) ;  
     1853          if (isNextCoupling)  
    16401854          { 
    1641                      // If attributesSize[it->first] does not exist, it will be zero-initialized 
    1642                      // so we can use it safely without checking for its existence 
    1643              if (attributesSize[it->first] < it->second) 
    1644                            attributesSize[it->first] = it->second; 
    1645  
    1646                      if (maxEventSize[it->first] < it->second) 
    1647                            maxEventSize[it->first] = it->second; 
    1648           } 
     1855            addCouplingChanel(couplerOut.first, true) ; 
     1856            listCouplerOut.erase(couplerOut.first) ; 
     1857            break ; 
     1858          }             
    16491859        } 
    1650      } 
    1651      return attributesSize; 
    1652    } 
    1653    CATCH_DUMP_ATTR 
    1654  
    1655    /*! 
    1656     * Compute the required buffer size to send the fields data. 
    1657     * \param maxEventSize [in/out] the size of the bigger event for each connected server 
    1658     * \param [in] contextClient 
    1659     * \param [in] bufferForWriting True if buffers are used for sending data for writing 
    1660       This flag is only true for client and server-1 for communication with server-2 
    1661     */ 
    1662    std::map<int, StdSize> CContext::getDataBufferSize(std::map<int, StdSize>& maxEventSize, 
    1663                                                       CContextClient* contextClient, bool bufferForWriting /*= "false"*/) 
    1664    TRY 
    1665    { 
    1666      std::map<int, StdSize> dataSize; 
    1667  
    1668      // Find all reference domain and axis of all active fields 
    1669      std::vector<CFile*>& fileList = bufferForWriting ? this->enabledWriteModeFiles : this->enabledReadModeFiles; 
    1670      size_t numEnabledFiles = fileList.size(); 
    1671      for (size_t i = 0; i < numEnabledFiles; ++i) 
    1672      { 
    1673        CFile* file = fileList[i]; 
    1674        if (file->getContextClient() == contextClient) 
    1675        { 
    1676          std::vector<CField*> enabledFields = file->getEnabledFields(); 
    1677          size_t numEnabledFields = enabledFields.size(); 
    1678          for (size_t j = 0; j < numEnabledFields; ++j) 
    1679          { 
    1680            // const std::vector<std::map<int, StdSize> > mapSize = enabledFields[j]->getGridDataBufferSize(contextClient); 
    1681            const std::map<int, StdSize> mapSize = enabledFields[j]->getGridDataBufferSize(contextClient,bufferForWriting); 
    1682            std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end(); 
    1683            for (; it != itE; ++it) 
    1684            { 
    1685              // If dataSize[it->first] does not exist, it will be zero-initialized 
    1686              // so we can use it safely without checking for its existance 
    1687                  if (CXios::isOptPerformance) 
    1688                dataSize[it->first] += it->second; 
    1689              else if (dataSize[it->first] < it->second) 
    1690                dataSize[it->first] = it->second; 
    1691  
    1692                  if (maxEventSize[it->first] < it->second) 
    1693                maxEventSize[it->first] = it->second; 
    1694            } 
    1695          } 
    1696        } 
    1697      } 
    1698      return dataSize; 
    1699    } 
    1700    CATCH_DUMP_ATTR 
    1701  
    1702    //! Client side: Send infomation of active files (files are enabled to write out) 
     1860        for(auto couplerIn : listCouplerIn)  
     1861        { 
     1862          bool isNextCoupling ; 
     1863          if (rank==0) isNextCoupling = couplerManager->isNextCoupling(couplerIn.first,this->getContextId()); 
     1864          MPI_Bcast(&isNextCoupling,1,MPI_C_BOOL, 0, getIntraComm()) ;  
     1865          if (isNextCoupling)  
     1866          { 
     1867            addCouplingChanel(couplerIn.first, false) ; 
     1868            listCouplerIn.erase(couplerIn.first) ; 
     1869            break ; 
     1870          }            
     1871        } 
     1872 
     1873      } while (!listCouplerOut.empty() || !listCouplerIn.empty()) ; 
     1874 
     1875   } 
     1876   CATCH_DUMP_ATTR 
     1877 
     1878   
     1879     //! Client side: Send infomation of active files (files are enabled to write out) 
    17031880   void CContext::sendEnabledFiles(const std::vector<CFile*>& activeFiles) 
    17041881   TRY 
     
    17341911   CATCH_DUMP_ATTR 
    17351912 
    1736    //! Client side: Check if the defined axis, domains and grids are eligible for compressed indexed output 
    1737    void CContext::checkAxisDomainsGridsEligibilityForCompressedOutput() 
    1738    TRY 
    1739    { 
    1740      if (!hasClient) return; 
    1741  
    1742      const vector<CAxis*> allAxis = CAxis::getAll(); 
    1743      for (vector<CAxis*>::const_iterator it = allAxis.begin(); it != allAxis.end(); it++) 
    1744        (*it)->checkEligibilityForCompressedOutput(); 
    1745  
    1746      const vector<CDomain*> allDomains = CDomain::getAll(); 
    1747      for (vector<CDomain*>::const_iterator it = allDomains.begin(); it != allDomains.end(); it++) 
    1748        (*it)->checkEligibilityForCompressedOutput(); 
    1749  
    1750      const vector<CGrid*> allGrids = CGrid::getAll(); 
    1751      for (vector<CGrid*>::const_iterator it = allGrids.begin(); it != allGrids.end(); it++) 
    1752        (*it)->checkEligibilityForCompressedOutput(); 
    1753    } 
    1754    CATCH_DUMP_ATTR 
    1755  
     1913   
    17561914   //! Client side: Prepare the timeseries by adding the necessary files 
    17571915   void CContext::prepareTimeseries() 
    17581916   TRY 
    17591917   { 
    1760      if (!hasClient) return; 
    1761  
    17621918     const std::vector<CFile*> allFiles = CFile::getAll(); 
    17631919     for (size_t i = 0; i < allFiles.size(); i++) 
     
    18562012   CATCH_DUMP_ATTR 
    18572013 
    1858    //! Client side: Send information of reference grid of active fields 
    1859    void CContext::sendRefGrid(const std::vector<CFile*>& activeFiles) 
    1860    TRY 
    1861    { 
    1862      std::set<StdString> gridIds; 
    1863      int sizeFile = activeFiles.size(); 
    1864      CFile* filePtr(NULL); 
    1865  
    1866      // Firstly, find all reference grids of all active fields 
    1867      for (int i = 0; i < sizeFile; ++i) 
    1868      { 
    1869        filePtr = activeFiles[i]; 
    1870        std::vector<CField*> enabledFields = filePtr->getEnabledFields(); 
    1871        int sizeField = enabledFields.size(); 
    1872        for (int numField = 0; numField < sizeField; ++numField) 
    1873        { 
    1874          if (0 != enabledFields[numField]->getRelGrid()) 
    1875            gridIds.insert(CGrid::get(enabledFields[numField]->getRelGrid())->getId()); 
    1876        } 
    1877      } 
    1878  
    1879      // Create all reference grids on server side 
    1880      StdString gridDefRoot("grid_definition"); 
    1881      CGridGroup* gridPtr = CGridGroup::get(gridDefRoot); 
    1882      std::set<StdString>::const_iterator it, itE = gridIds.end(); 
    1883      for (it = gridIds.begin(); it != itE; ++it) 
    1884      { 
    1885        gridPtr->sendCreateChild(*it); 
    1886        CGrid::get(*it)->sendAllAttributesToServer(); 
    1887        CGrid::get(*it)->sendAllDomains(); 
    1888        CGrid::get(*it)->sendAllAxis(); 
    1889        CGrid::get(*it)->sendAllScalars(); 
    1890      } 
    1891    } 
    1892    CATCH_DUMP_ATTR 
    1893  
     2014   
    18942015   //! Client side: Send information of reference domain, axis and scalar of active fields 
    18952016   void CContext::sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles) 
    18962017   TRY 
    18972018   { 
    1898      std::set<StdString> domainIds, axisIds, scalarIds; 
     2019     std::set<pair<StdString,CContextClient*>> domainIds, axisIds, scalarIds; 
    18992020 
    19002021     // Find all reference domain and axis of all active fields 
     
    19062027       for (int j = 0; j < numEnabledFields; ++j) 
    19072028       { 
     2029         CContextClient* contextClient=enabledFields[j]->getContextClient() ; 
    19082030         const std::vector<StdString>& prDomAxisScalarId = enabledFields[j]->getRefDomainAxisIds(); 
    1909          if ("" != prDomAxisScalarId[0]) domainIds.insert(prDomAxisScalarId[0]); 
    1910          if ("" != prDomAxisScalarId[1]) axisIds.insert(prDomAxisScalarId[1]); 
    1911          if ("" != prDomAxisScalarId[2]) scalarIds.insert(prDomAxisScalarId[2]); 
     2031         if ("" != prDomAxisScalarId[0]) domainIds.insert(make_pair(prDomAxisScalarId[0],contextClient)); 
     2032         if ("" != prDomAxisScalarId[1]) axisIds.insert(make_pair(prDomAxisScalarId[1],contextClient)); 
     2033         if ("" != prDomAxisScalarId[2]) scalarIds.insert(make_pair(prDomAxisScalarId[2],contextClient)); 
    19122034       } 
    19132035     } 
     
    19192041     StdString scalarDefRoot("scalar_definition"); 
    19202042     CScalarGroup* scalarPtr = CScalarGroup::get(scalarDefRoot); 
    1921      itE = scalarIds.end(); 
    1922      for (itScalar = scalarIds.begin(); itScalar != itE; ++itScalar) 
    1923      { 
    1924        if (!itScalar->empty()) 
     2043      
     2044     for (auto itScalar = scalarIds.begin(); itScalar != scalarIds.end(); ++itScalar) 
     2045     { 
     2046       if (!itScalar->first.empty()) 
    19252047       { 
    1926          scalarPtr->sendCreateChild(*itScalar); 
    1927          CScalar::get(*itScalar)->sendAllAttributesToServer(); 
     2048         scalarPtr->sendCreateChild(itScalar->first,itScalar->second); 
     2049         CScalar::get(itScalar->first)->sendAllAttributesToServer(itScalar->second); 
    19282050       } 
    19292051     } 
     
    19312053     StdString axiDefRoot("axis_definition"); 
    19322054     CAxisGroup* axisPtr = CAxisGroup::get(axiDefRoot); 
    1933      itE = axisIds.end(); 
    1934      for (itAxis = axisIds.begin(); itAxis != itE; ++itAxis) 
    1935      { 
    1936        if (!itAxis->empty()) 
     2055      
     2056     for (auto itAxis = axisIds.begin(); itAxis != axisIds.end(); ++itAxis) 
     2057     { 
     2058       if (!itAxis->first.empty()) 
    19372059       { 
    1938          axisPtr->sendCreateChild(*itAxis); 
    1939          CAxis::get(*itAxis)->sendAllAttributesToServer(); 
     2060         axisPtr->sendCreateChild(itAxis->first, itAxis->second); 
     2061         CAxis::get(itAxis->first)->sendAllAttributesToServer(itAxis->second); 
    19402062       } 
    19412063     } 
     
    19442066     StdString domDefRoot("domain_definition"); 
    19452067     CDomainGroup* domPtr = CDomainGroup::get(domDefRoot); 
    1946      itE = domainIds.end(); 
    1947      for (itDom = domainIds.begin(); itDom != itE; ++itDom) 
    1948      { 
    1949        if (!itDom->empty()) { 
    1950           domPtr->sendCreateChild(*itDom); 
    1951           CDomain::get(*itDom)->sendAllAttributesToServer(); 
     2068      
     2069     for (auto itDom = domainIds.begin(); itDom != domainIds.end(); ++itDom) 
     2070     { 
     2071       if (!itDom->first.empty()) { 
     2072          domPtr->sendCreateChild(itDom->first, itDom->second); 
     2073          CDomain::get(itDom->first)->sendAllAttributesToServer(itDom->second); 
    19522074       } 
    19532075     } 
     2076   } 
     2077   CATCH_DUMP_ATTR 
     2078 
     2079   void CContext::triggerLateFields(void) 
     2080   TRY 
     2081   { 
     2082    for(auto& field : fileInFields_) field->triggerLateField() ; 
     2083    for(auto& field : couplerInFields_) field->triggerLateField() ; 
    19542084   } 
    19552085   CATCH_DUMP_ATTR 
     
    19632093      if (prevStep < step) 
    19642094      { 
    1965         if (hasClient && !hasServer) // For now we only use server level 1 to read data 
     2095        if (serviceType_==CServicesManager::CLIENT) // For now we only use server level 1 to read data 
    19662096        { 
    1967           doPreTimestepOperationsForEnabledReadModeFiles(); 
     2097          triggerLateFields(); 
    19682098        } 
    19692099 
     
    19752105  #endif 
    19762106 
    1977         if (hasClient && !hasServer) // For now we only use server level 1 to read data 
     2107        if (serviceType_==CServicesManager::CLIENT) // For now we only use server level 1 to read data 
    19782108        { 
    19792109          doPostTimestepOperationsForEnabledReadModeFiles(); 
     
    20072137      vector<CFile*>::const_iterator it; 
    20082138 
    2009       for (it=enabledFiles.begin(); it != enabledFiles.end(); it++) 
    2010       // for (it=enabledWriteModeFiles.begin(); it != enabledWriteModeFiles.end(); it++) 
     2139      //for (it=enabledFiles.begin(); it != enabledFiles.end(); it++) 
     2140      for (it=enabledWriteModeFiles.begin(); it != enabledWriteModeFiles.end(); it++) 
    20112141      { 
    20122142         (*it)->initWrite(); 
     
    20642194  { 
    20652195    CBufferIn* buffer=event.subEvents.begin()->buffer; 
    2066     string id; 
    2067     *buffer>>id; 
    2068     get(id)->recvRegistry(*buffer); 
     2196    getCurrent()->recvRegistry(*buffer); 
    20692197  } 
    20702198  CATCH 
     
    20872215    registryOut->hierarchicalGatherRegistry() ; 
    20882216 
    2089     // Use correct context client to send message 
    2090     int nbSrvPools = (this->hasServer) ? (this->hasClient ? this->clientPrimServer.size() : 0) : 1; 
     2217    int nbSrvPools ; 
     2218    if (serviceType_==CServicesManager::CLIENT) nbSrvPools = 1 ; 
     2219    else if (serviceType_==CServicesManager::GATHERER) nbSrvPools = this->clientPrimServer.size() ; 
     2220    else nbSrvPools = 0 ; 
     2221    CContextClient* contextClientTmp ; 
     2222 
    20912223    for (int i = 0; i < nbSrvPools; ++i) 
    20922224    { 
    2093       CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client; 
     2225      if (serviceType_==CServicesManager::CLIENT) contextClientTmp = client ; 
     2226      else if (serviceType_==CServicesManager::GATHERER ) contextClientTmp = clientPrimServer[i] ; 
     2227 
    20942228      CEventClient event(CContext::GetType(), CContext::EVENT_ID_SEND_REGISTRY); 
    2095         if (contextClientTmp->isServerLeader()) 
    2096         { 
    2097            CMessage msg ; 
    2098            if (hasServer) 
    2099              msg<<this->getIdServer(i); 
    2100            else 
    2101              msg<<this->getIdServer(); 
    2102            if (contextClientTmp->clientRank==0) msg<<*registryOut ; 
    2103            const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    2104            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     2229      if (contextClientTmp->isServerLeader()) 
     2230      { 
     2231        CMessage msg ; 
     2232        if (contextClientTmp->clientRank==0) msg<<*registryOut ; 
     2233        const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
     2234        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    21052235             event.push(*itRank,1,msg); 
    2106            contextClientTmp->sendEvent(event); 
    2107          } 
    2108          else contextClientTmp->sendEvent(event); 
     2236        contextClientTmp->sendEvent(event); 
     2237      } 
     2238      else contextClientTmp->sendEvent(event); 
    21092239    } 
    21102240  } 
    21112241  CATCH_DUMP_ATTR 
     2242 
     2243   
     2244  void CContext::sendFinalizeClient(CContextClient* contextClient, const string& contextClientId) 
     2245  TRY 
     2246  { 
     2247    CEventClient event(getType(),EVENT_ID_CONTEXT_FINALIZE_CLIENT); 
     2248    if (contextClient->isServerLeader()) 
     2249    { 
     2250      CMessage msg; 
     2251      msg<<contextClientId ; 
     2252      const std::list<int>& ranks = contextClient->getRanksServerLeader(); 
     2253      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
     2254           event.push(*itRank,1,msg); 
     2255      contextClient->sendEvent(event); 
     2256    } 
     2257    else contextClient->sendEvent(event); 
     2258  } 
     2259  CATCH_DUMP_ATTR 
     2260 
     2261  
     2262  void CContext::recvFinalizeClient(CEventServer& event) 
     2263  TRY 
     2264  { 
     2265    CBufferIn* buffer=event.subEvents.begin()->buffer; 
     2266    string id; 
     2267    *buffer>>id; 
     2268    get(id)->recvFinalizeClient(*buffer); 
     2269  } 
     2270  CATCH 
     2271 
     2272  void CContext::recvFinalizeClient(CBufferIn& buffer) 
     2273  TRY 
     2274  { 
     2275    countChildContextFinalized_++ ; 
     2276  } 
     2277  CATCH_DUMP_ATTR 
     2278 
     2279 
     2280 
     2281 
     2282 //! Client side: Send a message  announcing that context can receive grid definition from coupling 
     2283   void CContext::sendCouplerInReady(CContextClient* client) 
     2284   TRY 
     2285   { 
     2286      if (sendCouplerInReady_done_.count(client)!=0) return ; 
     2287      else sendCouplerInReady_done_.insert(client) ; 
     2288 
     2289      CEventClient event(getType(),EVENT_ID_COUPLER_IN_READY); 
     2290 
     2291      if (client->isServerLeader()) 
     2292      { 
     2293        CMessage msg; 
     2294        msg<<this->getId(); 
     2295        for (auto& rank : client->getRanksServerLeader()) event.push(rank,1,msg); 
     2296        client->sendEvent(event); 
     2297      } 
     2298      else client->sendEvent(event); 
     2299   } 
     2300   CATCH_DUMP_ATTR 
     2301 
     2302   //! Server side: Receive a message announcing that context can send grid definition for context coupling 
     2303   void CContext::recvCouplerInReady(CEventServer& event) 
     2304   TRY 
     2305   { 
     2306      CBufferIn* buffer=event.subEvents.begin()->buffer; 
     2307      getCurrent()->recvCouplerInReady(*buffer); 
     2308   } 
     2309   CATCH 
     2310 
     2311   //! Server side: Receive a message announcing that context can send grid definition for context coupling 
     2312   void CContext::recvCouplerInReady(CBufferIn& buffer) 
     2313   TRY 
     2314   { 
     2315      string contextId ; 
     2316      buffer>>contextId; 
     2317      couplerInReady_.insert(getCouplerOutClient(contextId)) ; 
     2318   } 
     2319   CATCH_DUMP_ATTR 
     2320 
     2321 
     2322 
     2323 
     2324 
     2325 //! Client side: Send a message  announcing that a coupling context have done it closeDefinition, so data can be sent now. 
     2326   void CContext::sendCouplerInCloseDefinition(CContextClient* client) 
     2327   TRY 
     2328   { 
     2329      if (sendCouplerInCloseDefinition_done_.count(client)!=0) return ; 
     2330      else sendCouplerInCloseDefinition_done_.insert(client) ; 
     2331 
     2332      CEventClient event(getType(),EVENT_ID_COUPLER_IN_CLOSE_DEFINITION); 
     2333 
     2334      if (client->isServerLeader()) 
     2335      { 
     2336        CMessage msg; 
     2337        msg<<this->getId(); 
     2338        for (auto& rank : client->getRanksServerLeader()) event.push(rank,1,msg); 
     2339        client->sendEvent(event); 
     2340      } 
     2341      else client->sendEvent(event); 
     2342   } 
     2343   CATCH_DUMP_ATTR 
     2344 
     2345   //! Server side: Receive a message announcing that a coupling context have done it closeDefinition, so data can be sent now. 
     2346   void CContext::recvCouplerInCloseDefinition(CEventServer& event) 
     2347   TRY 
     2348   { 
     2349      CBufferIn* buffer=event.subEvents.begin()->buffer; 
     2350      getCurrent()->recvCouplerInCloseDefinition(*buffer); 
     2351   } 
     2352   CATCH 
     2353 
     2354   //! Server side: Receive a message announcing that a coupling context have done it closeDefinition, so data can be sent now. 
     2355   void CContext::recvCouplerInCloseDefinition(CBufferIn& buffer) 
     2356   TRY 
     2357   { 
     2358      string contextId ; 
     2359      buffer>>contextId; 
     2360      couplerInCloseDefinition_.insert(getCouplerOutClient(contextId)) ; 
     2361   } 
     2362   CATCH_DUMP_ATTR 
     2363 
     2364 
     2365 
     2366 
     2367//! Client side: Send a message  announcing that a coupling context have done it contextFinalize, so it can also close it own context. 
     2368   void CContext::sendCouplerInContextFinalized(CContextClient* client) 
     2369   TRY 
     2370   { 
     2371      if (sendCouplerInContextFinalized_done_.count(client)!=0) return ; 
     2372      else sendCouplerInContextFinalized_done_.insert(client) ; 
     2373 
     2374      CEventClient event(getType(),EVENT_ID_COUPLER_IN_CONTEXT_FINALIZED); 
     2375 
     2376      if (client->isServerLeader()) 
     2377      { 
     2378        CMessage msg; 
     2379        msg<<this->getId(); 
     2380        for (auto& rank : client->getRanksServerLeader()) event.push(rank,1,msg); 
     2381        client->sendEvent(event); 
     2382      } 
     2383      else client->sendEvent(event); 
     2384   } 
     2385   CATCH_DUMP_ATTR 
     2386 
     2387   //! Server side: Receive a message announcing that a coupling context have done it contextFinalize, so it can also close it own context. 
     2388   void CContext::recvCouplerInContextFinalized(CEventServer& event) 
     2389   TRY 
     2390   { 
     2391      CBufferIn* buffer=event.subEvents.begin()->buffer; 
     2392      getCurrent()->recvCouplerInContextFinalized(*buffer); 
     2393   } 
     2394   CATCH 
     2395 
     2396   //! Server side: Receive a message announcing that a coupling context have done it contextFinalize, so it can also close it own context. 
     2397   void CContext::recvCouplerInContextFinalized(CBufferIn& buffer) 
     2398   TRY 
     2399   { 
     2400      string contextId ; 
     2401      buffer>>contextId; 
     2402      couplerInContextFinalized_.insert(getCouplerOutClient(contextId)) ; 
     2403   } 
     2404   CATCH_DUMP_ATTR 
     2405 
     2406 
     2407 
    21122408 
    21132409  /*! 
  • XIOS/dev/dev_trunk_graph/src/node/context.hpp

    r1612 r2019  
    1212#include "registry.hpp" 
    1313#include "mpi.hpp" 
     14#include "services_manager.hpp" 
     15#include "server_context.hpp" 
    1416 
    1517 
     
    2426   class CContext; 
    2527   class CFile; 
     28   class CCouplerIn ; 
     29   class CCouplerOut ; 
    2630   ///-------------------------------------------------------------- 
    2731 
     
    4953           EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR, 
    5054           EVENT_ID_CREATE_FILE_HEADER,EVENT_ID_CONTEXT_FINALIZE, 
    51            EVENT_ID_POST_PROCESS, EVENT_ID_SEND_REGISTRY, 
    52            EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES, 
    53            EVENT_ID_PROCESS_GRID_ENABLED_FIELDS 
     55           EVENT_ID_SEND_REGISTRY, 
     56           EVENT_ID_CONTEXT_FINALIZE_CLIENT, 
     57           EVENT_ID_COUPLER_IN_READY, 
     58           EVENT_ID_COUPLER_IN_CLOSE_DEFINITION, 
     59           EVENT_ID_COUPLER_IN_CONTEXT_FINALIZED, 
    5460         }; 
    5561 
     
    8894      public : 
    8995         // Initialize server or client 
    90          void initClient(MPI_Comm intraComm, MPI_Comm interComm, CContext* cxtServer = 0); 
    91          void initServer(MPI_Comm intraComm, MPI_Comm interComm, CContext* cxtClient = 0); 
     96         void init(CServerContext* parentServerContext, MPI_Comm intraComm, int serviceType); 
     97         void initClient(MPI_Comm intraComm, int serviceType); 
     98          
     99         void initServer(MPI_Comm intraComm, int serviceType ); 
     100         void createClientInterComm(MPI_Comm interCommClient, MPI_Comm interCommServer)  ; 
     101         void createServerInterComm(void)  ; 
     102 
    92103         bool isInitialized(void); 
    93104 
     
    95106 
    96107         // Put sever or client into loop state 
    97          bool checkBuffersAndListen(bool enableEventsProcessing=true); 
     108         bool eventLoop(bool enableEventsProcessing=true); 
     109         void globalEventLoop(void); 
    98110 
    99111         // Finalize a context 
    100112         void finalize(void); 
     113 
    101114         bool isFinalized(void); 
    102115 
    103116         void closeDefinition(void); 
    104117 
     118         // to be removed      
     119         std::vector<CField*> findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles); 
    105120         // Some functions to process context 
    106          void findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles); 
     121         std::vector<CField*> findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles); 
     122         std::vector<CField*> findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles); 
     123         std::vector<CField*> findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut); 
     124         std::vector<CField*> findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn); 
    107125         // void findAllEnabledFields(void); 
    108126         // void findAllEnabledFieldsInReadModeFiles(void); 
     
    110128         void solveAllInheritance(bool apply=true); 
    111129         void findEnabledFiles(void); 
     130         void findEnabledCouplerIn(void); 
     131         void findEnabledCouplerOut(void); 
     132         void createCouplerInterCommunicator(void) ; 
    112133         void findEnabledWriteModeFiles(void); 
    113134         void findEnabledReadModeFiles(void); 
     
    116137         void createFileHeader(void); 
    117138         void initReadFiles(void); 
    118          void checkAxisDomainsGridsEligibilityForCompressedOutput(); 
    119139         void prepareTimeseries(void); 
    120          void solveOnlyRefOfEnabledFields(bool sendToServer);          
    121          void buildFilterGraphOfEnabledFields(); 
    122140         void postProcessFilterGraph(); 
    123141         void startPrefetchingOfEnabledReadModeFiles(); 
     
    125143         void doPostTimestepOperationsForEnabledReadModeFiles(); 
    126144         void findFieldsWithReadAccess(void); 
    127          void solveAllRefOfFieldsWithReadAccess(); 
    128          void buildFilterGraphOfFieldsWithReadAccess(); 
    129          void postProcessing(); 
    130          void postProcessingGlobalAttributes();          
    131  
    132          void solveAllRefOfEnabledFieldsAndTransform(bool sendToServer); 
    133          void checkGridEnabledFields(); 
    134          void checkGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles); 
    135          void sendGridEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);   
    136          void sendGridComponentEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles)       ; 
    137  
     145         void triggerLateFields(void) ; 
     146           
    138147         std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false); 
    139148         std::map<int, StdSize> getDataBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false); 
    140          void setClientServerBuffer(CContextClient* contextClient, bool bufferForWriting = false); 
     149         void setClientServerBuffer(CContextClient* contextClient, bool bufferForWriting = false); // old interface to be removed 
     150         void setClientServerBuffer(vector<CField*>& fields, bool bufferForWriting) ;  
    141151 
    142152         // Distribute files (in write mode) among secondary-server pools according to the estimated data flux 
    143          void distributeFiles(void); 
    144          void distributeFileOverBandwith() ; 
    145          void distributeFileOverMemoryBandwith() ; 
     153         void distributeFiles(const std::vector<CFile*>& files); 
     154         void distributeFileOverBandwith(const std::vector<CFile*>& files) ; 
     155         void distributeFileOverMemoryBandwith(const std::vector<CFile*>& files) ; 
    146156          
    147157         // Send context close definition 
    148158         void sendCloseDefinition(void); 
     159       public: 
     160         void sendCloseDefinition(CContextClient* client) ; 
     161       private: 
     162         set<CContextClient*> sendCloseDefinition_done_ ; 
     163       public: 
    149164         // There are something to send on closing context defintion 
    150165         void sendUpdateCalendar(int step); 
     
    153168         void sendEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles); 
    154169         void sendRefDomainsAxisScalars(const std::vector<CFile*>& activeFiles); 
    155          void sendRefGrid(const std::vector<CFile*>& activeFiles); 
    156          void sendPostProcessing(); 
    157          void sendPostProcessingGlobalAttributes(); 
    158          void sendProcessingGridOfEnabledFields(); 
    159170         //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers 
    160171         void sendRegistry(void) ; 
    161  
    162          const StdString& getIdServer(); 
    163          const StdString& getIdServer(const int srvPoolNb); 
     172         void sendFinalizeClient(CContextClient* contextClient, const string& contextClientId); 
     173          
     174         public: 
     175         void sendContextToFileServer(CContextClient* client) ; 
     176         private: 
     177         std::set<CContextClient*> sendToFileServer_done_ ; 
     178          
     179         public:  
     180         std::string getContextId() {return contextId_;} 
    164181 
    165182         // Client side: Receive and process messages 
     
    171188         static void recvSolveInheritanceContext(CEventServer& event); 
    172189         void recvSolveInheritanceContext(CBufferIn& buffer); 
    173          static void recvPostProcessing(CEventServer& event); 
    174          void recvPostProcessing(CBufferIn& buffer); 
    175          static void recvProcessingGridOfEnabledFields(CEventServer& event); 
    176          static void recvPostProcessingGlobalAttributes(CEventServer& event); 
    177          void recvPostProcessingGlobalAttributes(CBufferIn& buffer); 
    178190         static void recvRegistry(CEventServer& event) ; 
    179191         void recvRegistry(CBufferIn& buffer) ; //!< registry is received by the servers 
    180  
    181          void freeComms(void);                  //!< Free internally allcoated communicators 
    182          void releaseClientBuffers(void);       //! Deallocate buffers allocated by clientContexts 
     192         static void recvFinalizeClient(CEventServer& event) ; 
     193         void recvFinalizeClient(CBufferIn& buffer); 
     194         
     195       public: 
     196         void sendCouplerInReady(CContextClient* client); 
     197       private: 
     198         set<CContextClient*> sendCouplerInReady_done_; 
     199       public: 
     200         static void recvCouplerInReady(CEventServer& event) ; 
     201         void recvCouplerInReady(CBufferIn& buffer) ; //!< coupler is ready to receive grid definition. 
     202         set<CContextClient*> couplerInReady_; 
     203         bool isCouplerInReady(CContextClient* client) { return couplerInReady_.count(client)!=0 ;} 
     204 
     205       public: 
     206        void sendCouplerInCloseDefinition(CContextClient* client) ; 
     207        set<CContextClient*> sendCouplerInCloseDefinition_done_; 
     208        static void recvCouplerInCloseDefinition(CEventServer& event) ; 
     209        void recvCouplerInCloseDefinition(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent      
     210        set<CContextClient*> couplerInCloseDefinition_ ; 
     211        bool isCouplerInCloseDefinition(CContextClient* client) { return couplerInCloseDefinition_.count(client)!=0 ;} 
     212 
     213       public: 
     214        void sendCouplerInContextFinalized(CContextClient* client) ; 
     215        set<CContextClient*> sendCouplerInContextFinalized_done_; 
     216        static void recvCouplerInContextFinalized(CEventServer& event) ; 
     217        void recvCouplerInContextFinalized(CBufferIn& buffer) ; //!< coupler has finished it defintion, data can be sent      
     218        set<CContextClient*> couplerInContextFinalized_ ; 
     219        bool isCouplerInContextFinalized(CContextClient* client) { return couplerInContextFinalized_.count(client)!=0 ;} 
     220 
     221       public:   
     222        void freeComms(void);                  //!< Free internally allcoated communicators 
     223        void releaseClientBuffers(void);       //! Deallocate buffers allocated by clientContexts 
    183224 
    184225         // dispatch event 
     
    208249        static void ShowTree(StdOStream & out = std::clog); 
    209250        static void CleanTree(void); 
     251        int getServiceType(void) {return serviceType_;} 
    210252 
    211253      public : 
     
    223265         virtual bool hasChild(void) const; 
    224266 
     267         bool isProcessingEvent(void) {return isProcessingEvent_;} 
     268         bool setProcessingEvent(void) {isProcessingEvent_=true ;} 
     269         bool unsetProcessingEvent(void) {isProcessingEvent_=false ;} 
     270         MPI_Comm getIntraComm(void) {return intraComm_ ;} 
     271         int getIntraCommRank(void) {return intraCommRank_;} 
     272         int getIntraCommSize(void) {return intraCommSize_;} 
     273 
     274         void addCouplingChanel(const std::string& contextId, bool out) ; 
    225275 
    226276      public : 
     
    235285         std::vector<CFile*> enabledWriteModeFiles; 
    236286 
     287         std::vector<CCouplerIn*> enabledCouplerIn; 
     288         std::vector<CCouplerOut*> enabledCouplerOut; 
     289 
     290 
    237291         // List of all enabled fields whose instant data is accessible from the public API 
    238292         // but which are not part of a file 
    239          std::vector<CField*> fieldsWithReadAccess; 
     293         std::vector<CField*> fieldsWithReadAccess_; 
     294         std::vector<CField*> couplerInFields_; 
     295         std::vector<CField*> fileInFields_; 
     296 
    240297 
    241298         // Context root 
     
    253310         std::vector<CContextClient*> clientPrimServer; 
    254311 
     312         // list of slave servers (IO server or others) 
     313         set<CContextClient*> slaveServers_ ; 
     314      private: 
     315         // the map containing context client associated to it string id for coupling out ; 
     316         std::map<std::string, CContextClient*> couplerOutClient_ ; 
     317         // the map containing context server associated to it string id for coupling out ; 
     318         std::map<std::string, CContextServer*> couplerOutServer_ ; 
     319         // the map containing context client associated to it string id for coupling in ; 
     320         std::map<std::string, CContextClient*> couplerInClient_ ; 
     321         // the map containing context server associated to it string id for coupling in ; 
     322         std::map<std::string, CContextServer*> couplerInServer_ ; 
     323      public: 
     324         CContextClient* getCouplerInClient(const string& contextId) { return couplerInClient_[contextId] ;} 
     325         CContextServer* getCouplerInServer(const string& contextId) { return couplerInServer_[contextId] ;} 
     326         CContextClient* getCouplerOutClient(const string& contextId) { return couplerOutClient_[contextId] ;} 
     327         CContextServer* getCouplerOutServer(const string& contextId) { return couplerOutServer_[contextId] ;} 
     328       
     329   
     330         std::vector<std::string> primServerId_; 
     331 
    255332         CRegistry* registryIn ;    //!< input registry which is read from file 
    256333         CRegistry* registryOut ;   //!< output registry which will be written into file at the finalize 
    257334 
     335 
     336        MPI_Comm intraComm_ ; //! context intra communicator 
     337        int intraCommRank_ ; //! context intra communicator rank 
     338        int intraCommSize_ ; //! context intra communicator size 
     339         
    258340      private: 
    259341         bool isPostProcessed; 
    260342         bool allProcessed; 
    261343         bool finalized; 
    262          int countChildCtx_;        //!< Counter of child contexts (for now it is the number of secondary server pools) 
    263          StdString idServer_; 
     344         int countChildContextFinalized_;        //!< Counter of child contexts (for now it is the number of secondary server pools) 
    264345         CGarbageCollector garbageCollector; 
    265346         std::list<MPI_Comm> comms; //!< Communicators allocated internally 
     347 
     348         int serviceType_;  //!< service associated to the context 
     349         string contextId_ ; //!< context client id for the servers. For clients this is same as getId()  
     350         bool isProcessingEvent_ ; 
     351         CServerContext* parentServerContext_ ; 
    266352 
    267353      public: // Some function maybe removed in the near future 
  • XIOS/dev/dev_trunk_graph/src/node/domain.cpp

    r1686 r2019  
    11#include "domain.hpp" 
    2  
    32#include "attribute_template.hpp" 
    43#include "object_template.hpp" 
     
    1817#include "server_distribution_description.hpp" 
    1918#include "client_server_mapping_distributed.hpp" 
     19#include "local_connector.hpp" 
     20#include "grid_local_connector.hpp" 
     21#include "remote_connector.hpp" 
     22#include "gatherer_connector.hpp" 
     23#include "scatterer_connector.hpp" 
     24#include "grid_scatterer_connector.hpp" 
     25#include "grid_gatherer_connector.hpp" 
     26#include "transformation_path.hpp" 
     27 
     28 
     29 
    2030 
    2131#include <algorithm> 
     
    2737   CDomain::CDomain(void) 
    2838      : CObjectTemplate<CDomain>(), CDomainAttributes() 
    29       , isChecked(false), relFiles(), isClientChecked(false), nbSenders(), indSrv_(), connectedServerRank_() 
     39      , isChecked(false), relFiles(), indSrv_(), connectedServerRank_() 
    3040      , hasBounds(false), hasArea(false), isCompressible_(false), isUnstructed_(false) 
    31       , isClientAfterTransformationChecked(false), hasLonLat(false) 
     41      , hasLonLat(false) 
    3242      , isRedistributed_(false), hasPole(false) 
    3343      , lonvalue(), latvalue(), bounds_lonvalue(), bounds_latvalue() 
    34       , globalLocalIndexMap_(), computedWrittenIndex_(false) 
    3544      , clients(), hasLatInReadFile_(false), hasBoundsLatInReadFile_(false) 
    3645      , hasLonInReadFile_(false), hasBoundsLonInReadFile_(false) 
     
    4049   CDomain::CDomain(const StdString & id) 
    4150      : CObjectTemplate<CDomain>(id), CDomainAttributes() 
    42       , isChecked(false), relFiles(), isClientChecked(false), nbSenders(), indSrv_(), connectedServerRank_()  
     51      , isChecked(false), relFiles(), indSrv_(), connectedServerRank_()  
    4352      , hasBounds(false), hasArea(false), isCompressible_(false), isUnstructed_(false) 
    44       , isClientAfterTransformationChecked(false), hasLonLat(false) 
     53      , hasLonLat(false) 
    4554      , isRedistributed_(false), hasPole(false) 
    4655      , lonvalue(), latvalue(), bounds_lonvalue(), bounds_latvalue() 
    47       , globalLocalIndexMap_(), computedWrittenIndex_(false) 
    4856      , clients(), hasLatInReadFile_(false), hasBoundsLatInReadFile_(false) 
    4957      , hasLonInReadFile_(false), hasBoundsLonInReadFile_(false) 
     
    7280   CATCH 
    7381 
    74    std::map<StdString, ETranformationType> CDomain::transformationMapList_ = std::map<StdString, ETranformationType>(); 
    75    bool CDomain::_dummyTransformationMapList = CDomain::initializeTransformationMap(CDomain::transformationMapList_); 
    76  
    77    bool CDomain::initializeTransformationMap(std::map<StdString, ETranformationType>& m) 
    78    TRY 
    79    { 
    80      m["zoom_domain"] = TRANS_ZOOM_DOMAIN; 
    81      m["interpolate_domain"] = TRANS_INTERPOLATE_DOMAIN; 
    82      m["generate_rectilinear_domain"] = TRANS_GENERATE_RECTILINEAR_DOMAIN; 
    83      m["compute_connectivity_domain"] = TRANS_COMPUTE_CONNECTIVITY_DOMAIN; 
    84      m["expand_domain"] = TRANS_EXPAND_DOMAIN; 
    85      m["reorder_domain"] = TRANS_REORDER_DOMAIN; 
    86      m["extract_domain"] = TRANS_EXTRACT_DOMAIN; 
     82   const std::set<StdString> & CDomain::getRelFiles(void) const 
     83   TRY 
     84   { 
     85      return (this->relFiles); 
    8786   } 
    8887   CATCH 
    8988 
    90    const std::set<StdString> & CDomain::getRelFiles(void) const 
    91    TRY 
    92    { 
    93       return (this->relFiles); 
    94    } 
    95    CATCH 
    96  
    97    /*! 
    98      Returns the number of indexes written by each server. 
    99      \return the number of indexes written by each server 
    100    */ 
    101    int CDomain::getNumberWrittenIndexes(MPI_Comm writtenCom) 
    102    TRY 
    103    { 
    104      int writtenSize; 
    105      MPI_Comm_size(writtenCom, &writtenSize); 
    106      return numberWrittenIndexes_[writtenSize]; 
    107    } 
    108    CATCH_DUMP_ATTR 
    109  
    110    /*! 
    111      Returns the total number of indexes written by the servers. 
    112      \return the total number of indexes written by the servers 
    113    */ 
    114    int CDomain::getTotalNumberWrittenIndexes(MPI_Comm writtenCom) 
    115    TRY 
    116    { 
    117      int writtenSize; 
    118      MPI_Comm_size(writtenCom, &writtenSize); 
    119      return totalNumberWrittenIndexes_[writtenSize]; 
    120    } 
    121    CATCH_DUMP_ATTR 
    122  
    123    /*! 
    124      Returns the offset of indexes written by each server. 
    125      \return the offset of indexes written by each server 
    126    */ 
    127    int CDomain::getOffsetWrittenIndexes(MPI_Comm writtenCom) 
    128    TRY 
    129    { 
    130      int writtenSize; 
    131      MPI_Comm_size(writtenCom, &writtenSize); 
    132      return offsetWrittenIndexes_[writtenSize]; 
    133    } 
    134    CATCH_DUMP_ATTR 
    135  
    136    CArray<int, 1>& CDomain::getCompressedIndexToWriteOnServer(MPI_Comm writtenCom) 
    137    TRY 
    138    { 
    139      int writtenSize; 
    140      MPI_Comm_size(writtenCom, &writtenSize); 
    141      return compressedIndexToWriteOnServer[writtenSize]; 
    142    } 
    143    CATCH_DUMP_ATTR 
    144  
    145    //---------------------------------------------------------------- 
     89     //---------------------------------------------------------------- 
    14690 
    14791   /*! 
     
    227171              (!i_index.isEmpty() && i_index.numElements() == ni_glo*nj_glo)); 
    228172      bool distributed_glo ; 
    229       distributed |= (1 == CContext::getCurrent()->client->clientSize); 
     173      distributed |= (1 == CContext::getCurrent()->intraCommSize_); 
    230174 
    231175      return distributed; 
     
    236180 
    237181   /*! 
    238     * Test whether the data defined on the domain can be outputted in a compressed way. 
    239     * 
    240     * \return true if and only if a mask was defined for this domain 
     182    * Compute if the domain can be ouput in a compressed way. 
     183    * In this case the workflow view on server side must be the same 
     184    * than the full view for all context rank. The result is stored on 
     185    * internal isCompressible_ attribute. 
    241186    */ 
    242    bool CDomain::isCompressible(void) const 
    243    TRY 
    244    { 
    245       return isCompressible_; 
     187   void CDomain::computeIsCompressible(void) 
     188   TRY 
     189   { 
     190     // mesh is compressible contains some masked or indexed value, ie if full view is different of workflow view. 
     191     // But now assume that the size of the 2 view must be equal for everybody. True on server side 
     192     int isSameView = getLocalView(CElementView::FULL)->getSize() ==  getLocalView(CElementView::WORKFLOW)->getSize(); 
     193     MPI_Allreduce(MPI_IN_PLACE, &isSameView, 1, MPI_INT, MPI_LAND, CContext::getCurrent()->getIntraComm()) ; 
     194     if (isSameView) isCompressible_ = false ; 
     195     else isCompressible_ = true ; 
     196     isCompressibleComputed_=true ; 
    246197   } 
    247198   CATCH 
     
    302253     // For now the assumption is that secondary server pools consist of the same number of procs. 
    303254     // CHANGE the line below if the assumption changes. 
    304      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[0] : context->client; 
    305      int rankClient = client->clientRank; 
     255 
     256     int rankClient = context->intraCommRank_; 
    306257     int rankOnDomain = rankClient%nbLocalDomain; 
    307258 
     
    680631    // For now the assumption is that secondary server pools consist of the same number of procs. 
    681632    // CHANGE the line below if the assumption changes. 
    682     CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[0] : context->client; 
     633     int clientSize = context->intraCommSize_ ; 
    683634     lon_g.resize(ni_glo) ; 
    684635     lat_g.resize(nj_glo) ; 
    685636 
    686637 
    687      int* ibegin_g = new int[client->clientSize] ; 
    688      int* jbegin_g = new int[client->clientSize] ; 
    689      int* ni_g = new int[client->clientSize] ; 
    690      int* nj_g = new int[client->clientSize] ; 
     638     int* ibegin_g = new int[clientSize] ; 
     639     int* jbegin_g = new int[clientSize] ; 
     640     int* ni_g = new int[clientSize] ; 
     641     int* nj_g = new int[clientSize] ; 
    691642     int v ; 
    692643     v=ibegin ; 
    693      MPI_Allgather(&v,1,MPI_INT,ibegin_g,1,MPI_INT,client->intraComm) ; 
     644     MPI_Allgather(&v,1,MPI_INT,ibegin_g,1,MPI_INT,context->intraComm_) ; 
    694645     v=jbegin ; 
    695      MPI_Allgather(&v,1,MPI_INT,jbegin_g,1,MPI_INT,client->intraComm) ; 
     646     MPI_Allgather(&v,1,MPI_INT,jbegin_g,1,MPI_INT,context->intraComm_) ; 
    696647     v=ni ; 
    697      MPI_Allgather(&v,1,MPI_INT,ni_g,1,MPI_INT,client->intraComm) ; 
     648     MPI_Allgather(&v,1,MPI_INT,ni_g,1,MPI_INT,context->intraComm_) ; 
    698649     v=nj ; 
    699      MPI_Allgather(&v,1,MPI_INT,nj_g,1,MPI_INT,client->intraComm) ; 
    700  
    701      MPI_Allgatherv(lon.dataFirst(),ni,MPI_DOUBLE,lon_g.dataFirst(),ni_g, ibegin_g,MPI_DOUBLE,client->intraComm) ; 
    702      MPI_Allgatherv(lat.dataFirst(),nj,MPI_DOUBLE,lat_g.dataFirst(),nj_g, jbegin_g,MPI_DOUBLE,client->intraComm) ; 
     650     MPI_Allgather(&v,1,MPI_INT,nj_g,1,MPI_INT,context->intraComm_) ; 
     651 
     652     MPI_Allgatherv(lon.dataFirst(),ni,MPI_DOUBLE,lon_g.dataFirst(),ni_g, ibegin_g,MPI_DOUBLE,context->intraComm_) ; 
     653     MPI_Allgatherv(lat.dataFirst(),nj,MPI_DOUBLE,lat_g.dataFirst(),nj_g, jbegin_g,MPI_DOUBLE,context->intraComm_) ; 
    703654 
    704655      delete[] ibegin_g ; 
     
    12971248   CATCH_DUMP_ATTR 
    12981249 
    1299    void CDomain::checkEligibilityForCompressedOutput(void) 
    1300    TRY 
    1301    { 
    1302      // We don't check if the mask or the indexes are valid here, just if they have been defined at this point. 
    1303      isCompressible_ = !mask_1d.isEmpty() || !mask_2d.isEmpty() || !data_i_index.isEmpty(); 
    1304    } 
    1305    CATCH_DUMP_ATTR 
    13061250 
    13071251   //---------------------------------------------------------------- 
     
    17211665   CATCH_DUMP_ATTR 
    17221666 
    1723    void CDomain::checkAttributesOnClientAfterTransformation() 
    1724    TRY 
    1725    { 
    1726      CContext* context=CContext::getCurrent() ; 
    1727  
    1728      if (this->isClientAfterTransformationChecked) return; 
    1729      if (context->hasClient) 
    1730      { 
    1731       this->computeConnectedClients(); 
    1732        if (hasLonLat) 
    1733          if (!context->hasServer) 
    1734            this->completeLonLatClient(); 
    1735      } 
    1736  
    1737      this->isClientAfterTransformationChecked = true; 
    1738    } 
    1739    CATCH_DUMP_ATTR 
    1740  
    1741    //---------------------------------------------------------------- 
    1742    // Divide function checkAttributes into 2 seperate ones 
    1743    // This function only checks all attributes of current domain 
    1744    void CDomain::checkAttributesOnClient() 
    1745    TRY 
    1746    { 
    1747      if (this->isClientChecked) return; 
    1748      CContext* context=CContext::getCurrent(); 
    1749  
    1750       if (context->hasClient && !context->hasServer) 
    1751       { 
    1752         this->checkDomain(); 
    1753         this->checkBounds(); 
    1754         this->checkArea(); 
    1755         this->checkLonLat(); 
    1756       } 
    1757  
    1758       if (context->hasClient && !context->hasServer) 
    1759       { // Ct client uniquement 
    1760          this->checkMask(); 
    1761          this->checkDomainData(); 
    1762          this->checkCompression(); 
    1763          this->computeLocalMask() ; 
    1764       } 
    1765       else 
    1766       { // Ct serveur uniquement 
    1767       } 
    1768  
    1769       this->isClientChecked = true; 
    1770    } 
    1771    CATCH_DUMP_ATTR 
    1772  
    1773    // Send all checked attributes to server 
    1774    void CDomain::sendCheckedAttributes() 
    1775    TRY 
    1776    { 
    1777      if (!this->isClientChecked) checkAttributesOnClient(); 
    1778      if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation(); 
    1779      CContext* context=CContext::getCurrent() ; 
    1780  
    1781      if (this->isChecked) return; 
    1782      if (context->hasClient) 
    1783      { 
    1784        sendAttributes(); 
    1785      } 
    1786      this->isChecked = true; 
    1787    } 
    1788    CATCH_DUMP_ATTR 
    1789  
    17901667   void CDomain::checkAttributes(void) 
    17911668   TRY 
    17921669   { 
    1793       if (this->isChecked) return; 
    1794       CContext* context=CContext::getCurrent() ; 
    1795  
     1670      if (this->checkAttributes_done_) return; 
    17961671      this->checkDomain(); 
    17971672      this->checkLonLat(); 
    17981673      this->checkBounds(); 
    17991674      this->checkArea(); 
    1800  
    1801       if (context->hasClient) 
    1802       { // Ct client uniquement 
    1803          this->checkMask(); 
    1804          this->checkDomainData(); 
    1805          this->checkCompression(); 
    1806          this->computeLocalMask() ; 
    1807  
    1808       } 
    1809       else 
    1810       { // Ct serveur uniquement 
    1811       } 
    1812  
    1813       if (context->hasClient) 
    1814       { 
    1815         this->computeConnectedClients(); 
    1816         this->completeLonLatClient(); 
    1817       } 
    1818  
    1819       this->isChecked = true; 
     1675      this->checkMask(); 
     1676      this->checkDomainData(); 
     1677      this->checkCompression(); 
     1678      this->computeLocalMask() ; 
     1679      this->completeLonLatClient(); 
     1680      this->initializeLocalElement() ; 
     1681      this->addFullView() ; // probably do not automatically add View, but only if requested 
     1682      this->addWorkflowView() ; // probably do not automatically add View, but only if requested 
     1683      this->addModelView() ; // probably do not automatically add View, but only if requested 
     1684      // testing ? 
     1685     /* 
     1686      CLocalView* local = localElement_->getView(CElementView::WORKFLOW) ; 
     1687      CLocalView* model = localElement_->getView(CElementView::MODEL) ; 
     1688 
     1689      CLocalConnector test1(model, local) ; 
     1690      test1.computeConnector() ; 
     1691      CLocalConnector test2(local, model) ; 
     1692      test2.computeConnector() ; 
     1693      CGridLocalConnector gridTest1(vector<CLocalConnector*>{&test1}) ; 
     1694      CGridLocalConnector gridTest2(vector<CLocalConnector*>{&test2}) ; 
     1695       
     1696       
     1697      CArray<int,1> out1 ; 
     1698      CArray<int,1> out2 ; 
     1699      test1.transfer(data_i_index,out1,-111) ; 
     1700      test2.transfer(out1,out2,-111) ; 
     1701       
     1702      out1 = 0 ; 
     1703      out2 = 0 ; 
     1704      gridTest1.transfer(data_i_index,out1,-111) ; 
     1705      gridTest2.transfer(out1, out2,-111) ; 
     1706    */   
     1707      this->checkAttributes_done_ = true; 
    18201708   } 
    18211709   CATCH_DUMP_ATTR 
    18221710 
    1823   /*! 
    1824      Compute the connection of a client to other clients to determine which clients to send attributes to. 
    1825      The sending clients are supposed to already know the distribution of receiving clients (In simple cases, it's band) 
    1826      The connection among clients is calculated by using global index.  
    1827      A client connects to other clients which holds the same global index as it.      
    1828   */ 
    1829   void CDomain::computeConnectedClients() 
     1711 
     1712   void CDomain::initializeLocalElement(void) 
     1713   { 
     1714      // after checkDomain i_index and j_index of size (ni*nj)  
     1715      int nij = ni*nj ; 
     1716      CArray<size_t, 1> ij_index(ni*nj) ; 
     1717      for(int ij=0; ij<nij ; ij++) ij_index(ij) = i_index(ij)+j_index(ij)*ni_glo ; 
     1718      int rank = CContext::getCurrent()->getIntraCommRank() ; 
     1719      localElement_ = new CLocalElement(rank, ni_glo*nj_glo, ij_index) ; 
     1720   } 
     1721 
     1722   void CDomain::addFullView(void) 
     1723   { 
     1724      CArray<int,1> index(ni*nj) ; 
     1725      int nij=ni*nj ; 
     1726      for(int ij=0; ij<nij ; ij++) index(ij)=ij ; 
     1727      localElement_ -> addView(CElementView::FULL, index) ; 
     1728   } 
     1729 
     1730   void CDomain::addWorkflowView(void) 
     1731   { 
     1732     // information for workflow view is stored in localMask 
     1733     int nij=ni*nj ; 
     1734     int nMask=0 ; 
     1735     for(int ij=0; ij<nij ; ij++) if (localMask(ij)) nMask++ ; 
     1736     CArray<int,1> index(nMask) ; 
     1737 
     1738     nMask=0 ; 
     1739     for(int ij=0; ij<nij ; ij++)  
     1740      if (localMask(ij)) 
     1741      { 
     1742        index(nMask)=ij ; 
     1743        nMask++ ; 
     1744      } 
     1745      localElement_ -> addView(CElementView::WORKFLOW, index) ; 
     1746   } 
     1747 
     1748   void CDomain::addModelView(void) 
     1749   { 
     1750     // information for model view is stored in data_i_index/data_j_index 
     1751     // very weird, do not mix data_i_index and data_i_begin => in future only keep data_i_index 
     1752     int dataSize = data_i_index.numElements() ; 
     1753     CArray<int,1> index(dataSize) ; 
     1754     int i,j ; 
     1755     for(int k=0;k<dataSize;k++) 
     1756     { 
     1757        if (data_dim==2) 
     1758        { 
     1759          i=data_i_index(k)+data_ibegin ; // bad 
     1760          j=data_j_index(k)+data_jbegin ; // bad 
     1761          if (i>=0 && i<ni && j>=0 && j<nj) index(k)=i+j*ni ; 
     1762          else index(k)=-1 ; 
     1763        } 
     1764        else if (data_dim==1) 
     1765        { 
     1766          i=data_i_index(k)+data_ibegin ; // bad 
     1767          if (i>=0 && i<ni*nj) index(k)=i ; 
     1768          else index(k)=-1 ; 
     1769        } 
     1770     } 
     1771     localElement_->addView(CElementView::MODEL, index) ; 
     1772   } 
     1773         
     1774   void CDomain::computeModelToWorkflowConnector(void) 
     1775   {  
     1776     CLocalView* srcView=getLocalView(CElementView::MODEL) ; 
     1777     CLocalView* dstView=getLocalView(CElementView::WORKFLOW) ; 
     1778     modelToWorkflowConnector_ = new CLocalConnector(srcView, dstView);  
     1779     modelToWorkflowConnector_->computeConnector() ; 
     1780   } 
     1781 
     1782 
     1783    
     1784  /* to be removed later when coupling will be reimplemented, just to  not forget */ 
     1785  void CDomain::sendDomainToCouplerOut(CContextClient* client, const string& fieldId, int posInGrid) 
     1786  { 
     1787    if (sendDomainToFileServer_done_.count(client)!=0) return ; 
     1788    else sendDomainToFileServer_done_.insert(client) ; 
     1789     
     1790    const string domainId = "_domain["+std::to_string(posInGrid)+"]_of_"+fieldId ; 
     1791     
     1792    if (!domain_ref.isEmpty()) 
     1793    { 
     1794      auto domain_ref_tmp=domain_ref.getValue() ; 
     1795      domain_ref.reset() ; // remove the reference, find an other way to do that more cleanly 
     1796      this->sendAllAttributesToServer(client, domainId)  ; 
     1797      domain_ref = domain_ref_tmp ; 
     1798    } 
     1799    else this->sendAllAttributesToServer(client, domainId)  ; 
     1800  } 
     1801 
     1802 
     1803 
     1804 
     1805  void CDomain::makeAliasForCoupling(const string& fieldId, int posInGrid) 
     1806  { 
     1807    const string domainId = "_domain["+std::to_string(posInGrid)+"]_of_"+fieldId ; 
     1808    this->createAlias(domainId) ; 
     1809  } 
     1810 
     1811 
     1812  void CDomain::computeRemoteElement(CContextClient* client, EDistributionType type) 
    18301813  TRY 
    18311814  { 
    1832     CContext* context=CContext::getCurrent() ; 
    1833      
    1834     // This line should be changed soon. 
    1835     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 
    1836  
    1837     nbSenders.clear(); 
    1838     connectedServerRank_.clear(); 
    1839  
    1840     for (int p = 0; p < nbSrvPools; ++p) 
     1815    CContext* context = CContext::getCurrent(); 
     1816    map<int, CArray<size_t,1>> globalIndex ; 
     1817 
     1818    if (type==EDistributionType::BANDS) // Bands distribution to send to file server 
    18411819    { 
    1842       CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client; 
    1843       int nbServer = client->serverSize; 
    1844       int nbClient = client->clientSize; 
    1845       int rank     = client->clientRank; 
    1846       bool doComputeGlobalIndexServer = true; 
    1847  
    1848       if (connectedServerRank_.find(nbServer) == connectedServerRank_.end()) 
    1849       { 
    1850  
    1851         if (indSrv_.find(nbServer) == indSrv_.end()) 
    1852         { 
    1853           int i,j,i_ind,j_ind, nbIndex=i_index.numElements(); 
    1854           int globalIndexCount = i_index.numElements(); 
    1855           // Fill in index 
    1856           CArray<size_t,1> globalIndexDomain(nbIndex); 
    1857           size_t globalIndex; 
    1858  
    1859           for (i = 0; i < nbIndex; ++i) 
    1860           { 
    1861             i_ind=i_index(i); 
    1862             j_ind=j_index(i); 
    1863             globalIndex = i_ind + j_ind * ni_glo; 
    1864             globalIndexDomain(i) = globalIndex; 
    1865           } 
    1866  
    1867           if (globalLocalIndexMap_.empty()) 
    1868           { 
    1869             for (i = 0; i < nbIndex; ++i) 
    1870               globalLocalIndexMap_[globalIndexDomain(i)] = i; 
    1871           } 
    1872  
    1873           size_t globalSizeIndex = 1, indexBegin, indexEnd; 
    1874           int range, clientSize = client->clientSize; 
    1875           std::vector<int> nGlobDomain(2); 
    1876           nGlobDomain[0] = this->ni_glo; 
    1877           nGlobDomain[1] = this->nj_glo; 
    1878           for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i]; 
    1879           indexBegin = 0; 
    1880           if (globalSizeIndex <= clientSize) 
    1881           { 
    1882             indexBegin = rank%globalSizeIndex; 
    1883             indexEnd = indexBegin; 
    1884           } 
    1885           else 
    1886           { 
    1887             for (int i = 0; i < clientSize; ++i) 
    1888             { 
    1889               range = globalSizeIndex / clientSize; 
    1890               if (i < (globalSizeIndex%clientSize)) ++range; 
    1891               if (i == client->clientRank) break; 
    1892               indexBegin += range; 
    1893             } 
    1894             indexEnd = indexBegin + range - 1; 
    1895           } 
    1896  
    1897           // Even if servers have no index, they must received something from client 
    1898           // We only use several client to send "empty" message to these servers 
    1899           CServerDistributionDescription serverDescription(nGlobDomain, nbServer); 
    1900           std::vector<int> serverZeroIndex; 
    1901           if (isUnstructed_) serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0); 
    1902           else serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 1); 
    1903  
    1904           std::list<int> serverZeroIndexLeader; 
    1905           std::list<int> serverZeroIndexNotLeader; 
    1906           CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
    1907           for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    1908             *it = serverZeroIndex[*it]; 
    1909  
    1910           CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); 
    1911           clientServerMap->computeServerIndexMapping(globalIndexDomain, nbServer); 
    1912           CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer(); 
    1913  
    1914           CClientServerMapping::GlobalIndexMap::const_iterator it  = globalIndexDomainOnServer.begin(), 
    1915                  ite = globalIndexDomainOnServer.end(); 
    1916           indSrv_[nbServer].swap(globalIndexDomainOnServer); 
    1917           connectedServerRank_[nbServer].clear(); 
    1918           for (it = indSrv_[nbServer].begin(); it != ite; ++it) 
    1919             connectedServerRank_[nbServer].push_back(it->first); 
    1920  
    1921           for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    1922             connectedServerRank_[nbServer].push_back(*it); 
    1923  
    1924           // Even if a client has no index, it must connect to at least one server and 
    1925           // send an "empty" data to this server 
    1926           if (connectedServerRank_[nbServer].empty()) 
    1927             connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize); 
    1928  
    1929           // Now check if all servers have data to receive. If not, master client will send empty data. 
    1930           // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 
    1931           std::vector<int> counts (clientSize); 
    1932           std::vector<int> displs (clientSize); 
    1933           displs[0] = 0; 
    1934           int localCount = connectedServerRank_[nbServer].size() ; 
    1935           MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 
    1936           for (int i = 0; i < clientSize-1; ++i) 
    1937           { 
    1938             displs[i+1] = displs[i] + counts[i]; 
    1939           } 
    1940           std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]); 
    1941           MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 
    1942  
    1943           if ((allConnectedServers.size() != nbServer) && (rank == 0)) 
    1944           { 
    1945             std::vector<bool> isSrvConnected (nbServer, false); 
    1946             for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 
    1947             for (int i = 0; i < nbServer; ++i) 
    1948             { 
    1949               if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i); 
    1950             } 
    1951           } 
    1952           nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]); 
    1953           delete clientServerMap; 
    1954         } 
    1955       } 
    1956     } 
    1957   } 
    1958   CATCH_DUMP_ATTR 
    1959  
    1960    /*! 
    1961      Compute index to write data. We only write data on the zoomed region, therefore, there should 
    1962      be a map between the complete grid and the reduced grid where we write data. 
    1963      By using global index we can easily create this kind of mapping. 
    1964    */ 
    1965    void CDomain::computeWrittenIndex() 
    1966    TRY 
    1967    {   
    1968       if (computedWrittenIndex_) return; 
    1969       computedWrittenIndex_ = true; 
    1970  
    1971       CContext* context=CContext::getCurrent();       
    1972       CContextServer* server = context->server;   
    1973  
    1974       std::vector<int> nBegin(2), nSize(2), nBeginGlobal(2), nGlob(2); 
    1975       nBegin[0]       = ibegin;  nBegin[1] = jbegin; 
    1976       nSize[0]        = ni;      nSize[1]  = nj; 
    1977       nBeginGlobal[0] = 0; nBeginGlobal[1] = 0; 
    1978       nGlob[0]        = ni_glo;   nGlob[1] = nj_glo; 
    1979       CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
    1980       const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
    1981  
    1982       size_t nbWritten = 0, indGlo;       
    1983       std::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
    1984                                                           ite = globalLocalIndexMap_.end(), it;           
    1985       CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
    1986                                        itSrve = writtenGlobalIndex.end(), itSrv; 
    1987  
    1988       localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements()); 
    1989       nbWritten = 0; 
    1990       for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    1991       { 
    1992         indGlo = *itSrv; 
    1993         if (ite != globalLocalIndexMap_.find(indGlo)) 
    1994         { 
    1995           localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo]; 
    1996         } 
    1997         else 
    1998         { 
    1999           localIndexToWriteOnServer(nbWritten) = -1; 
    2000         } 
    2001         ++nbWritten; 
    2002       } 
    2003    } 
    2004    CATCH_DUMP_ATTR 
    2005  
    2006   void CDomain::computeWrittenCompressedIndex(MPI_Comm writtenComm) 
    2007   TRY 
    2008   { 
    2009     int writtenCommSize; 
    2010     MPI_Comm_size(writtenComm, &writtenCommSize); 
    2011     if (compressedIndexToWriteOnServer.find(writtenCommSize) != compressedIndexToWriteOnServer.end()) 
    2012       return; 
    2013  
    2014     if (isCompressible()) 
    2015     { 
    2016       size_t nbWritten = 0, indGlo; 
    2017       CContext* context=CContext::getCurrent();       
    2018       CContextServer* server = context->server;   
    2019  
    2020       std::vector<int> nBegin(2), nSize(2), nBeginGlobal(2), nGlob(2); 
    2021       nBegin[0]       = ibegin;  nBegin[1] = jbegin; 
    2022       nSize[0]        = ni;      nSize[1]  = nj; 
    2023       nBeginGlobal[0] = 0; nBeginGlobal[1] = 0; 
    2024       nGlob[0]        = ni_glo;   nGlob[1] = nj_glo; 
    2025       CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob);  
    2026       const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex(); 
    2027  
    2028       std::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(), 
    2029                                                           ite = globalLocalIndexMap_.end(), it;    
    2030       CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(), 
    2031                                        itSrve = writtenGlobalIndex.end(), itSrv; 
    2032       std::unordered_map<size_t,size_t> localGlobalIndexMap; 
    2033       for (itSrv = itSrvb; itSrv != itSrve; ++itSrv) 
    2034       { 
    2035         indGlo = *itSrv; 
    2036         if (ite != globalLocalIndexMap_.find(indGlo)) 
    2037         { 
    2038           localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo; 
    2039           ++nbWritten; 
    2040         }                  
    2041       } 
    2042  
    2043       nbWritten = 0; 
    2044       for (int idx = 0; idx < data_i_index.numElements(); ++idx) 
    2045       { 
    2046         if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 
    2047         { 
    2048           ++nbWritten; 
    2049         } 
    2050       } 
    2051  
    2052       compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten); 
    2053       nbWritten = 0; 
    2054       for (int idx = 0; idx < data_i_index.numElements(); ++idx) 
    2055       { 
    2056         if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx))) 
    2057         { 
    2058           compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_i_index(idx)]; 
    2059           ++nbWritten; 
    2060         } 
    2061       } 
    2062  
    2063       numberWrittenIndexes_[writtenCommSize] = nbWritten; 
    2064       bool distributed_glo, distributed=isDistributed() ; 
    2065       MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, writtenComm) ; 
    2066        
    2067       if (distributed_glo) 
    2068       { 
    2069               
    2070         MPI_Allreduce(&numberWrittenIndexes_[writtenCommSize], &totalNumberWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 
    2071         MPI_Scan(&numberWrittenIndexes_[writtenCommSize], &offsetWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm); 
    2072         offsetWrittenIndexes_[writtenCommSize] -= numberWrittenIndexes_[writtenCommSize]; 
    2073       } 
    2074       else 
    2075         totalNumberWrittenIndexes_[writtenCommSize] = numberWrittenIndexes_[writtenCommSize]; 
    2076       } 
    2077   } 
    2078   CATCH_DUMP_ATTR 
    2079  
    2080   /*! 
    2081     Send all attributes from client to connected clients 
    2082     The attributes will be rebuilt on receiving side 
    2083   */ 
    2084   void CDomain::sendAttributes() 
    2085   TRY 
    2086   { 
    2087     sendDistributionAttributes(); 
    2088     sendIndex();        
    2089     sendLonLat(); 
    2090     sendArea();     
    2091     sendDataIndex(); 
    2092   } 
    2093   CATCH 
    2094   /*! 
    2095     Send global index from client to connected client(s) 
    2096   */ 
    2097   void CDomain::sendIndex() 
    2098   TRY 
    2099   { 
    2100     int ns, n, i, j, ind, nv, idx; 
    2101     std::list<CContextClient*>::iterator it; 
    2102     for (it=clients.begin(); it!=clients.end(); ++it) 
    2103     { 
    2104       CContextClient* client = *it; 
    2105  
    2106       int serverSize = client->serverSize; 
    2107       CEventClient eventIndex(getType(), EVENT_ID_INDEX); 
    2108  
    2109       list<CMessage> list_msgsIndex; 
    2110       list<CArray<int,1> > list_indGlob; 
    2111  
    2112       std::unordered_map<int, vector<size_t> >::const_iterator itIndex, iteIndex; 
    2113       iteIndex = indSrv_[serverSize].end(); 
    2114       for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k) 
    2115       { 
    2116         int nbIndGlob = 0; 
    2117         int rank = connectedServerRank_[serverSize][k]; 
    2118         itIndex = indSrv_[serverSize].find(rank); 
    2119         if (iteIndex != itIndex) 
    2120           nbIndGlob = itIndex->second.size(); 
    2121  
    2122         list_indGlob.push_back(CArray<int,1>(nbIndGlob));         
    2123  
    2124         CArray<int,1>& indGlob = list_indGlob.back(); 
    2125         for (n = 0; n < nbIndGlob; ++n) 
    2126         { 
    2127           indGlob(n) = static_cast<int>(itIndex->second[n]); 
    2128         } 
    2129  
    2130         list_msgsIndex.push_back(CMessage()); 
    2131         list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix 
    2132         list_msgsIndex.back() << isCurvilinear; 
    2133         list_msgsIndex.back() << list_indGlob.back(); //list_indi.back() << list_indj.back(); 
    2134         
    2135         eventIndex.push(rank, nbSenders[serverSize][rank], list_msgsIndex.back()); 
    2136       } 
    2137  
    2138       client->sendEvent(eventIndex); 
    2139     } 
    2140   } 
    2141   CATCH_DUMP_ATTR 
    2142  
    2143   /*! 
    2144     Send distribution from client to other clients 
    2145     Because a client in a level knows correctly the grid distribution of client on the next level 
    2146     it calculates this distribution then sends it to the corresponding clients on the next level 
    2147   */ 
    2148   void CDomain::sendDistributionAttributes(void) 
    2149   TRY 
    2150   { 
    2151     std::list<CContextClient*>::iterator it; 
    2152     for (it=clients.begin(); it!=clients.end(); ++it) 
    2153     { 
    2154       CContextClient* client = *it; 
    21551820      int nbServer = client->serverSize; 
    21561821      std::vector<int> nGlobDomain(2); 
     
    21581823      nGlobDomain[1] = this->nj_glo; 
    21591824 
     1825      // to be changed in future, need to rewrite more simply domain distribution 
    21601826      CServerDistributionDescription serverDescription(nGlobDomain, nbServer); 
    2161       if (isUnstructed_) serverDescription.computeServerDistribution(false, 0); 
    2162       else serverDescription.computeServerDistribution(false, 1); 
    2163  
     1827      int distributedPosition ; 
     1828      if (isUnstructed_) distributedPosition = 0 ; 
     1829      else distributedPosition = 1 ; 
     1830       
    21641831      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin(); 
    21651832      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes(); 
    2166  
    2167       CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT); 
    2168       if (client->isServerLeader()) 
    2169       { 
    2170         std::list<CMessage> msgs; 
    2171  
    2172         const std::list<int>& ranks = client->getRanksServerLeader(); 
    2173         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    2174         { 
    2175           // Use const int to ensure CMessage holds a copy of the value instead of just a reference 
    2176           const int ibegin_srv = serverIndexBegin[*itRank][0]; 
    2177           const int jbegin_srv = serverIndexBegin[*itRank][1]; 
    2178           const int ni_srv = serverDimensionSizes[*itRank][0]; 
    2179           const int nj_srv = serverDimensionSizes[*itRank][1]; 
    2180  
    2181           msgs.push_back(CMessage()); 
    2182           CMessage& msg = msgs.back(); 
    2183           msg << this->getId() ; 
    2184           msg << isUnstructed_; 
    2185           msg << ni_srv << ibegin_srv << nj_srv << jbegin_srv; 
    2186           msg << ni_glo.getValue() << nj_glo.getValue(); 
    2187           msg << isCompressible_; 
    2188  
    2189           event.push(*itRank,1,msg); 
    2190         } 
    2191         client->sendEvent(event); 
    2192       } 
    2193       else client->sendEvent(event); 
     1833      vector<unordered_map<size_t,vector<int>>> indexServerOnElement ; 
     1834      CArray<int,1> axisDomainOrder(1) ; axisDomainOrder(0)=2 ; 
     1835      auto zeroIndex=serverDescription.computeServerGlobalByElement(indexServerOnElement, context->getIntraCommRank(), context->getIntraCommSize(), 
     1836                                                                  axisDomainOrder,distributedPosition) ; 
     1837      // distribution is very bad => to redo 
     1838      // convert indexServerOnElement => map<int,CArray<size_t,1>> - need to be changed later 
     1839      map<int, vector<size_t>> vectGlobalIndex ; 
     1840      for(auto& indexRanks : indexServerOnElement[0]) 
     1841      { 
     1842        size_t index=indexRanks.first ; 
     1843        auto& ranks=indexRanks.second ; 
     1844        for(int rank : ranks) vectGlobalIndex[rank].push_back(index) ; 
     1845      } 
     1846      for(auto& vect : vectGlobalIndex ) globalIndex.emplace(vect.first, CArray<size_t,1>(vect.second.data(), shape(vect.second.size()),duplicateData)) ; 
     1847    // some servers receves no index (zeroIndex array) => root process take them into account. 
     1848      if (context->getIntraCommRank()==0)  
     1849        for(auto& rank : zeroIndex) globalIndex[rank] = CArray<size_t,1>() ;  
    21941850    } 
     1851    else if (type==EDistributionType::NONE) // domain is not distributed ie all servers get the same local domain 
     1852    { 
     1853      int nbServer = client->serverSize; 
     1854      int nglo=ni_glo*nj_glo ; 
     1855      CArray<size_t,1> indGlo ; 
     1856      for(size_t i=0;i<nglo;i++) indGlo(i) = i ; 
     1857      for (auto& rankServer : client->getRanksServerLeader()) globalIndex[rankServer] = indGlo ;  
     1858    } 
     1859    remoteElement_[client] = new CDistributedElement(ni_glo*nj_glo, globalIndex) ; 
     1860    remoteElement_[client]->addFullView() ; 
    21951861  } 
    2196   CATCH_DUMP_ATTR 
    2197  
    2198   /*! 
    2199     Send area from client to connected client(s) 
    2200   */ 
    2201   void CDomain::sendArea() 
     1862  CATCH 
     1863 
     1864  
     1865 
     1866  void CDomain::distributeToServer(CContextClient* client, map<int, CArray<size_t,1>>& globalIndex, 
     1867                                   CScattererConnector* &scattererConnector, const string& domainId) 
    22021868  TRY 
    22031869  { 
    2204     if (!hasArea) return; 
    2205  
    2206     int ns, n, i, j, ind, nv, idx; 
    2207     std::list<CContextClient*>::iterator it; 
    2208  
    2209     for (it=clients.begin(); it!=clients.end(); ++it) 
    2210     { 
    2211       CContextClient* client = *it; 
    2212       int serverSize = client->serverSize; 
    2213  
    2214       // send area for each connected server 
    2215       CEventClient eventArea(getType(), EVENT_ID_AREA); 
    2216  
    2217       list<CMessage> list_msgsArea; 
    2218       list<CArray<double,1> > list_area; 
    2219  
    2220       std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap; 
    2221       iteMap = indSrv_[serverSize].end(); 
    2222       for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k) 
    2223       { 
    2224         int nbData = 0; 
    2225         int rank = connectedServerRank_[serverSize][k]; 
    2226         it = indSrv_[serverSize].find(rank); 
    2227         if (iteMap != it) 
    2228           nbData = it->second.size(); 
    2229         list_area.push_back(CArray<double,1>(nbData)); 
    2230  
    2231         const std::vector<size_t>& temp = it->second; 
    2232         for (n = 0; n < nbData; ++n) 
    2233         { 
    2234           idx = static_cast<int>(it->second[n]); 
    2235           list_area.back()(n) = areavalue(globalLocalIndexMap_[idx]); 
    2236         } 
    2237  
    2238         list_msgsArea.push_back(CMessage()); 
    2239         list_msgsArea.back() << this->getId() << hasArea; 
    2240         list_msgsArea.back() << list_area.back(); 
    2241         eventArea.push(rank, nbSenders[serverSize][rank], list_msgsArea.back()); 
    2242       } 
    2243       client->sendEvent(eventArea); 
    2244     } 
     1870    string serverDomainId = domainId.empty() ? this->getId() : domainId ; 
     1871    CContext* context = CContext::getCurrent(); 
     1872 
     1873    this->sendAllAttributesToServer(client, serverDomainId)  ; 
     1874 
     1875    CDistributedElement scatteredElement(ni_glo*nj_glo, globalIndex) ; 
     1876    scatteredElement.addFullView() ; 
     1877    scattererConnector = new CScattererConnector(localElement_->getView(CElementView::FULL), scatteredElement.getView(CElementView::FULL),  
     1878                                           context->getIntraComm(), client->getRemoteSize()) ; 
     1879    scattererConnector->computeConnector() ; 
     1880 
     1881    // phase 0 
     1882    // send remote element to construct the full view on server, ie without hole  
     1883    CEventClient event0(getType(), EVENT_ID_DOMAIN_DISTRIBUTION); 
     1884    CMessage message0 ; 
     1885    message0<<serverDomainId<<0 ;  
     1886    remoteElement_[client]->sendToServer(client,event0,message0) ;  
     1887     
     1888    // phase 1 
     1889    // send the full view of element to construct the connector which connect distributed data coming from client to the full local view 
     1890    CEventClient event1(getType(), EVENT_ID_DOMAIN_DISTRIBUTION); 
     1891    CMessage message1 ; 
     1892    message1<<serverDomainId<<1<<localElement_->getView(CElementView::FULL)->getGlobalSize() ;  
     1893    scattererConnector->transfer(localElement_->getView(CElementView::FULL)->getGlobalIndex(),client,event1,message1) ; 
     1894     
     1895    sendDistributedAttributes(client, *scattererConnector, domainId) ; 
     1896 
     1897   
     1898    // phase 2 send the mask : data index + mask2D 
     1899    CArray<bool,1> maskIn(localElement_->getView(CElementView::WORKFLOW)->getSize()); 
     1900    CArray<bool,1> maskOut ; 
     1901    CLocalConnector workflowToFull(localElement_->getView(CElementView::WORKFLOW), localElement_->getView(CElementView::FULL)) ; 
     1902    workflowToFull.computeConnector() ; 
     1903    maskIn=true ; 
     1904    workflowToFull.transfer(maskIn,maskOut,false) ; 
     1905 
     1906 
     1907    // phase 3 : prepare grid scatterer connector to send data from client to server 
     1908    map<int,CArray<size_t,1>> workflowGlobalIndex ; 
     1909    map<int,CArray<bool,1>> maskOut2 ;  
     1910    scattererConnector->transfer(maskOut, maskOut2, false) ; 
     1911    scatteredElement.addView(CElementView::WORKFLOW, maskOut2) ; 
     1912    scatteredElement.getView(CElementView::WORKFLOW)->getGlobalIndexView(workflowGlobalIndex) ; 
     1913    // create new workflow view for scattered element 
     1914    CDistributedElement clientToServerElement(scatteredElement.getGlobalSize(), workflowGlobalIndex) ; 
     1915    clientToServerElement.addFullView() ; 
     1916    CEventClient event2(getType(), EVENT_ID_DOMAIN_DISTRIBUTION); 
     1917    CMessage message2 ; 
     1918    message2<<serverDomainId<<2 ;  
     1919    clientToServerElement.sendToServer(client, event2, message2) ;  
     1920    clientToServerConnector_[client] = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW), clientToServerElement.getView(CElementView::FULL), 
     1921                                                               context->getIntraComm(), client->getRemoteSize()) ; 
     1922    clientToServerConnector_[client]->computeConnector() ; 
     1923 
     1924    clientFromServerConnector_[client] = new CGathererConnector(clientToServerElement.getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)); 
     1925    clientFromServerConnector_[client]->computeConnector() ; 
     1926 
    22451927  } 
    2246   CATCH_DUMP_ATTR 
    2247  
    2248   /*! 
    2249     Send longitude and latitude from client to servers 
    2250     Each client send long and lat information to corresponding connected clients(s). 
    2251     Because longitude and latitude are optional, this function only called if latitude and longitude exist 
    2252   */ 
    2253   void CDomain::sendLonLat() 
     1928  CATCH 
     1929  
     1930  void CDomain::recvDomainDistribution(CEventServer& event) 
    22541931  TRY 
    22551932  { 
    2256     if (!hasLonLat) return; 
    2257  
    2258     int ns, n, i, j, ind, nv, idx; 
    2259     std::list<CContextClient*>::iterator it; 
    2260     for (it=clients.begin(); it!=clients.end(); ++it) 
    2261     { 
    2262       CContextClient* client = *it; 
    2263       int serverSize = client->serverSize; 
    2264  
    2265       // send lon lat for each connected server 
    2266       CEventClient eventLon(getType(), EVENT_ID_LON); 
    2267       CEventClient eventLat(getType(), EVENT_ID_LAT); 
    2268  
    2269       list<CMessage> list_msgsLon, list_msgsLat; 
    2270       list<CArray<double,1> > list_lon, list_lat; 
    2271       list<CArray<double,2> > list_boundslon, list_boundslat; 
    2272  
    2273       std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap; 
    2274       iteMap = indSrv_[serverSize].end(); 
    2275       for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k) 
    2276       { 
    2277         int nbData = 0; 
    2278         int rank = connectedServerRank_[serverSize][k]; 
    2279         it = indSrv_[serverSize].find(rank); 
    2280         if (iteMap != it) 
    2281           nbData = it->second.size(); 
    2282  
    2283         list_lon.push_back(CArray<double,1>(nbData)); 
    2284         list_lat.push_back(CArray<double,1>(nbData)); 
    2285  
    2286         if (hasBounds) 
    2287         { 
    2288           list_boundslon.push_back(CArray<double,2>(nvertex, nbData)); 
    2289           list_boundslat.push_back(CArray<double,2>(nvertex, nbData)); 
    2290         } 
    2291  
    2292         CArray<double,1>& lon = list_lon.back(); 
    2293         CArray<double,1>& lat = list_lat.back(); 
    2294         const std::vector<size_t>& temp = it->second; 
    2295         for (n = 0; n < nbData; ++n) 
    2296         { 
    2297           idx = static_cast<int>(it->second[n]); 
    2298           int localInd = globalLocalIndexMap_[idx]; 
    2299           lon(n) = lonvalue(localInd); 
    2300           lat(n) = latvalue(localInd); 
    2301  
    2302           if (hasBounds) 
    2303           { 
    2304             CArray<double,2>& boundslon = list_boundslon.back(); 
    2305             CArray<double,2>& boundslat = list_boundslat.back(); 
    2306  
    2307             for (nv = 0; nv < nvertex; ++nv) 
    2308             { 
    2309               boundslon(nv, n) = bounds_lonvalue(nv, localInd); 
    2310               boundslat(nv, n) = bounds_latvalue(nv, localInd); 
    2311             } 
    2312           } 
    2313         } 
    2314  
    2315         list_msgsLon.push_back(CMessage()); 
    2316         list_msgsLat.push_back(CMessage()); 
    2317  
    2318         list_msgsLon.back() << this->getId() << hasLonLat; 
    2319         if (hasLonLat)  
    2320           list_msgsLon.back() << list_lon.back(); 
    2321         list_msgsLon.back()  << hasBounds; 
    2322         if (hasBounds) 
    2323         { 
    2324           list_msgsLon.back() << list_boundslon.back(); 
    2325         } 
    2326  
    2327         list_msgsLat.back() << this->getId() << hasLonLat; 
    2328         if (hasLonLat) 
    2329           list_msgsLat.back() << list_lat.back(); 
    2330         list_msgsLat.back() << hasBounds; 
    2331         if (hasBounds) 
    2332         {           
    2333           list_msgsLat.back() << list_boundslat.back(); 
    2334         } 
    2335  
    2336         eventLon.push(rank, nbSenders[serverSize][rank], list_msgsLon.back()); 
    2337         eventLat.push(rank, nbSenders[serverSize][rank], list_msgsLat.back()); 
    2338       } 
    2339       client->sendEvent(eventLon); 
    2340       client->sendEvent(eventLat); 
    2341     } 
     1933    string domainId; 
     1934    int phasis ; 
     1935    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> domainId >> phasis ; 
     1936    get(domainId)->receivedDomainDistribution(event, phasis); 
    23421937  } 
    2343   CATCH_DUMP_ATTR 
    2344  
    2345   /*! 
    2346     Send data index to corresponding connected clients. 
    2347     Data index can be compressed however, we always send decompressed data index 
    2348     and they will be compressed on receiving. 
    2349     The compressed index are represented with 1 and others are represented with -1 
    2350   */ 
    2351   void CDomain::sendDataIndex() 
     1938  CATCH 
     1939 
     1940  void CDomain::receivedDomainDistribution(CEventServer& event, int phasis) 
    23521941  TRY 
    23531942  { 
    2354     int ns, n, i, j, ind, nv, idx; 
    2355     std::list<CContextClient*>::iterator it; 
    2356     for (it=clients.begin(); it!=clients.end(); ++it) 
     1943    CContext* context = CContext::getCurrent(); 
     1944    if (phasis==0) // receive the remote element to construct the full view 
    23571945    { 
    2358       CContextClient* client = *it; 
    2359  
    2360       int serverSize = client->serverSize; 
    2361  
    2362       // send area for each connected server 
    2363       CEventClient eventDataIndex(getType(), EVENT_ID_DATA_INDEX); 
    2364  
    2365       list<CMessage> list_msgsDataIndex; 
    2366       list<CArray<int,1> > list_data_i_index, list_data_j_index; 
    2367  
    2368       int nbIndex = i_index.numElements(); 
    2369       int niByIndex = max(i_index) - min(i_index) + 1; 
    2370       int njByIndex = max(j_index) - min(j_index) + 1;  
    2371       int dataIindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : niByIndex; 
    2372       int dataJindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : njByIndex; 
    2373  
    2374        
    2375       CArray<int,1> dataIIndex(nbIndex), dataJIndex(nbIndex); 
    2376       dataIIndex = -1;  
    2377       dataJIndex = -1; 
    2378       ind = 0; 
    2379  
    2380       for (idx = 0; idx < data_i_index.numElements(); ++idx) 
    2381       { 
    2382         int dataIidx = data_i_index(idx) + data_ibegin; 
    2383         int dataJidx = data_j_index(idx) + data_jbegin; 
    2384         if ((0 <= dataIidx) && (dataIidx < dataIindexBound) && 
    2385             (0 <= dataJidx) && (dataJidx < dataJindexBound)) 
    2386         { 
    2387           dataIIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //i_index(dataIidx);//dataIidx; 
    2388           dataJIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //j_index(dataJidx);//           
    2389         } 
    2390       } 
    2391  
    2392       std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap; 
    2393       iteMap = indSrv_[serverSize].end(); 
    2394       for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k) 
    2395       { 
    2396         int nbData = 0; 
    2397         int rank = connectedServerRank_[serverSize][k]; 
    2398         it = indSrv_[serverSize].find(rank); 
    2399         if (iteMap != it) 
    2400           nbData = it->second.size(); 
    2401         list_data_i_index.push_back(CArray<int,1>(nbData)); 
    2402         list_data_j_index.push_back(CArray<int,1>(nbData)); 
    2403  
    2404         const std::vector<size_t>& temp = it->second; 
    2405         for (n = 0; n < nbData; ++n) 
    2406         { 
    2407           idx = static_cast<int>(it->second[n]); 
    2408           i = globalLocalIndexMap_[idx]; 
    2409           list_data_i_index.back()(n) = dataIIndex(i); 
    2410           list_data_j_index.back()(n) = dataJIndex(i); 
    2411         } 
    2412  
    2413         list_msgsDataIndex.push_back(CMessage()); 
    2414         list_msgsDataIndex.back() << this->getId(); 
    2415         list_msgsDataIndex.back() << list_data_i_index.back() << list_data_j_index.back(); 
    2416         eventDataIndex.push(rank, nbSenders[serverSize][rank], list_msgsDataIndex.back()); 
    2417       } 
    2418       client->sendEvent(eventDataIndex); 
     1946      localElement_ = new  CLocalElement(context->getIntraCommRank(),event) ; 
     1947      localElement_->addFullView() ; 
     1948      // construct the local dimension and indexes 
     1949      auto& globalIndex=localElement_->getGlobalIndex() ; 
     1950      int nij=globalIndex.numElements() ; 
     1951      int minI=ni_glo,maxI=-1,minJ=nj_glo,maxJ=-1 ; 
     1952      int i,j ; 
     1953      int niGlo=ni_glo, njGlo=njGlo ; 
     1954      for(int ij=0;ij<nij;ij++) 
     1955      { 
     1956        j=globalIndex(ij)/niGlo ; 
     1957        i=globalIndex(ij)%niGlo ; 
     1958        if (i<minI) minI=i ; 
     1959        if (i>maxI) maxI=i ; 
     1960        if (j<minJ) minJ=j ; 
     1961        if (j>maxJ) maxJ=j ; 
     1962      }   
     1963      if (maxI>=minI) { ibegin=minI ; ni=maxI-minI+1 ; } 
     1964      else {ibegin=0; ni=0 ;} 
     1965      if (maxJ>=minJ) { jbegin=minJ ; nj=maxJ-minJ+1 ; } 
     1966      else {jbegin=0; nj=0 ;} 
     1967 
     1968    } 
     1969    else if (phasis==1) // receive the sent view from client to construct the full distributed full view on server 
     1970    { 
     1971      CContext* context = CContext::getCurrent(); 
     1972      CDistributedElement* elementFrom = new  CDistributedElement(event) ; 
     1973      elementFrom->addFullView() ; 
     1974      gathererConnector_ = new CGathererConnector(elementFrom->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ; 
     1975      gathererConnector_->computeConnector() ;  
     1976    } 
     1977    else if (phasis==2) 
     1978    { 
     1979//      delete gathererConnector_ ; 
     1980      elementFrom_ = new  CDistributedElement(event) ; 
     1981      elementFrom_->addFullView() ; 
     1982//      gathererConnector_ =  new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ; 
     1983//      gathererConnector_ -> computeConnector() ; 
    24191984    } 
    24201985  } 
    24211986  CATCH 
    2422    
     1987 
     1988  void CDomain::setServerMask(CArray<bool,1>& serverMask, CContextClient* client) 
     1989  TRY 
     1990  { 
     1991    // nota : the client is needed to get the remote size for the scatterer connector. Maybe it is not the good place for this 
     1992    // Later, server to client connector can be computed on demand, with "client" as argument 
     1993    CContext* context = CContext::getCurrent(); 
     1994    localElement_->addView(CElementView::WORKFLOW, serverMask) ; 
     1995    mask_1d.reference(serverMask.copy()) ; 
     1996  
     1997    serverFromClientConnector_ = new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)) ; 
     1998    serverFromClientConnector_->computeConnector() ; 
     1999       
     2000    serverToClientConnector_ = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW), elementFrom_->getView(CElementView::FULL), 
     2001                                                       context->getIntraComm(), client->getRemoteSize()) ; 
     2002    serverToClientConnector_->computeConnector() ; 
     2003  } 
     2004  CATCH_DUMP_ATTR 
     2005 
     2006 
     2007  void CDomain::sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector,  const string& domainId) 
     2008  { 
     2009    string serverDomainId = domainId.empty() ? this->getId() : domainId ; 
     2010    CContext* context = CContext::getCurrent(); 
     2011 
     2012    if (hasLonLat) 
     2013    { 
     2014      { // send longitude 
     2015        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     2016        CMessage message ; 
     2017        message<<serverDomainId<<string("lon") ;  
     2018        scattererConnector.transfer(lonvalue, client, event,message) ; 
     2019      } 
     2020       
     2021      { // send latitude 
     2022        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     2023        CMessage message ; 
     2024        message<<serverDomainId<<string("lat") ;  
     2025        scattererConnector.transfer(latvalue, client, event, message) ; 
     2026      } 
     2027    } 
     2028 
     2029    if (hasBounds) 
     2030    {  
     2031      { // send longitude boudaries 
     2032        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     2033        CMessage message ; 
     2034        message<<serverDomainId<<string("boundslon") ;  
     2035        scattererConnector.transfer(nvertex, bounds_lonvalue, client, event, message ) ; 
     2036      } 
     2037 
     2038      { // send latitude boudaries 
     2039        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     2040        CMessage message ; 
     2041        message<<serverDomainId<<string("boundslat") ;  
     2042        scattererConnector.transfer(nvertex, bounds_latvalue, client, event, message ) ; 
     2043      } 
     2044    } 
     2045 
     2046    if (hasArea) 
     2047    {  // send area 
     2048      CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE); 
     2049      CMessage message ; 
     2050      message<<serverDomainId<<string("area") ;  
     2051      scattererConnector.transfer(areavalue, client, event,message) ; 
     2052    } 
     2053  } 
     2054 
     2055  void CDomain::recvDistributedAttributes(CEventServer& event) 
     2056  TRY 
     2057  { 
     2058    string domainId; 
     2059    string type ; 
     2060    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> domainId >> type ; 
     2061    get(domainId)->recvDistributedAttributes(event, type); 
     2062  } 
     2063  CATCH 
     2064 
     2065  void CDomain::recvDistributedAttributes(CEventServer& event, const string& type) 
     2066  TRY 
     2067  { 
     2068    if (type=="lon")  
     2069    { 
     2070      CArray<double,1> value ; 
     2071      gathererConnector_->transfer(event, value, 0.);  
     2072      lonvalue_2d.resize(ni,nj) ; 
     2073      if (lonvalue_2d.numElements()>0) lonvalue_2d=CArray<double,2>(value.dataFirst(),shape(ni,nj),neverDeleteData) ;  
     2074    } 
     2075    else if (type=="lat") 
     2076    { 
     2077      CArray<double,1> value ; 
     2078      gathererConnector_->transfer(event, value, 0.);  
     2079      latvalue_2d.resize(ni,nj) ; 
     2080      if (latvalue_2d.numElements()>0) latvalue_2d=CArray<double,2>(value.dataFirst(),shape(ni,nj),neverDeleteData) ;  
     2081    } 
     2082    else if (type=="boundslon") 
     2083    { 
     2084      CArray<double,1> value ; 
     2085      gathererConnector_->transfer(event, nvertex, value, 0.);  
     2086      bounds_lon_2d.resize(nvertex,ni,nj) ; 
     2087      if (bounds_lon_2d.numElements()>0) bounds_lon_2d=CArray<double,3>(value.dataFirst(),shape(nvertex,ni,nj),neverDeleteData) ;  
     2088    } 
     2089    else if (type=="boundslat") 
     2090    { 
     2091      CArray<double,1> value ; 
     2092      gathererConnector_->transfer(event, nvertex, value, 0.);  
     2093      bounds_lat_2d.resize(nvertex,ni,nj) ; 
     2094      if (bounds_lat_2d.numElements()>0) bounds_lat_2d=CArray<double,3>(value.dataFirst(),shape(nvertex,ni,nj),neverDeleteData) ;  
     2095    } 
     2096    else if (type=="area")  
     2097    { 
     2098      CArray<double,1> value ; 
     2099      gathererConnector_->transfer(event, value, 0.);  
     2100      area.resize(ni,nj) ; 
     2101      if (area.numElements()>0) area=CArray<double,2>(value.dataFirst(),shape(ni,nj),neverDeleteData) ;  
     2102    } 
     2103  } 
     2104  CATCH 
     2105     
    24232106  bool CDomain::dispatchEvent(CEventServer& event) 
    24242107  TRY 
     
    24292112      switch(event.type) 
    24302113      { 
    2431         case EVENT_ID_SERVER_ATTRIBUT: 
    2432           recvDistributionAttributes(event); 
     2114        case EVENT_ID_DOMAIN_DISTRIBUTION: 
     2115          recvDomainDistribution(event); 
    24332116          return true; 
    24342117          break; 
    2435         case EVENT_ID_INDEX: 
    2436           recvIndex(event); 
    2437           return true; 
    2438           break; 
    2439         case EVENT_ID_LON: 
    2440           recvLon(event); 
    2441           return true; 
    2442           break; 
    2443         case EVENT_ID_LAT: 
    2444           recvLat(event); 
    2445           return true; 
    2446           break; 
    2447         case EVENT_ID_AREA: 
    2448           recvArea(event); 
     2118        case EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE: 
     2119          recvDistributedAttributes(event); 
    24492120          return true; 
    24502121          break;   
    2451         case EVENT_ID_DATA_INDEX: 
    2452           recvDataIndex(event); 
    2453           return true; 
    2454           break; 
    24552122        default: 
    24562123          ERROR("bool CDomain::dispatchEvent(CEventServer& event)", 
     
    24622129  CATCH 
    24632130 
    2464   /*! 
    2465     Receive index event from clients(s) 
    2466     \param[in] event event contain info about rank and associated index 
    2467   */ 
    2468   void CDomain::recvIndex(CEventServer& event) 
    2469   TRY 
    2470   { 
    2471     string domainId; 
    2472     std::map<int, CBufferIn*> rankBuffers; 
    2473  
    2474     list<CEventServer::SSubEvent>::iterator it; 
    2475     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    2476     {       
    2477       CBufferIn* buffer = it->buffer; 
    2478       *buffer >> domainId; 
    2479       rankBuffers[it->rank] = buffer;         
    2480     } 
    2481     get(domainId)->recvIndex(rankBuffers); 
    2482   } 
    2483   CATCH 
    2484  
    2485   /*! 
    2486     Receive index information from client(s). We use the global index for mapping index between 
    2487     sending clients and receiving clients. 
    2488     \param[in] rankBuffers rank of sending client and the corresponding receive buffer   
    2489   */ 
    2490   void CDomain::recvIndex(std::map<int, CBufferIn*>& rankBuffers) 
    2491   TRY 
    2492   { 
    2493     int nbReceived = rankBuffers.size(), i, ind, index, type_int, iIndex, jIndex; 
    2494     recvClientRanks_.resize(nbReceived);         
    2495  
    2496     std::map<int, CBufferIn*>::iterator it = rankBuffers.begin(), ite = rankBuffers.end(); 
    2497     ind = 0; 
    2498     for (ind = 0; it != ite; ++it, ++ind) 
    2499     {        
    2500        recvClientRanks_[ind] = it->first; 
    2501        CBufferIn& buffer = *(it->second); 
    2502        buffer >> type_int >> isCurvilinear >> indGlob_[it->first];  
    2503        type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix 
    2504     } 
    2505     int nbIndGlob = 0; 
    2506     for (i = 0; i < nbReceived; ++i) 
    2507     { 
    2508       nbIndGlob += indGlob_[recvClientRanks_[i]].numElements(); 
    2509     } 
    2510      
    2511     globalLocalIndexMap_.rehash(std::ceil(nbIndGlob/globalLocalIndexMap_.max_load_factor())); 
    2512     i_index.resize(nbIndGlob); 
    2513     j_index.resize(nbIndGlob);    
    2514     int nbIndexGlobMax = nbIndGlob, nbIndLoc; 
    2515  
    2516     nbIndGlob = 0; 
    2517     for (i = 0; i < nbReceived; ++i) 
    2518     { 
    2519       CArray<int,1>& tmp = indGlob_[recvClientRanks_[i]]; 
    2520       for (ind = 0; ind < tmp.numElements(); ++ind) 
    2521       { 
    2522          index = tmp(ind); 
    2523          if (0 == globalLocalIndexMap_.count(index)) 
    2524          { 
    2525            iIndex = (index%ni_glo)-ibegin; 
    2526            iIndex = (iIndex < 0) ? 0 : iIndex; 
    2527            jIndex = (index/ni_glo)-jbegin; 
    2528            jIndex = (jIndex < 0) ? 0 : jIndex; 
    2529            nbIndLoc = iIndex + ni * jIndex; 
    2530            i_index(nbIndGlob) = index % ni_glo; 
    2531            j_index(nbIndGlob) = index / ni_glo; 
    2532            globalLocalIndexMap_[index] = nbIndGlob; 
    2533            ++nbIndGlob; 
    2534          }  
    2535       }  
    2536     }  
    2537  
    2538     if (nbIndGlob==0) 
    2539     { 
    2540       i_index.resize(nbIndGlob); 
    2541       j_index.resize(nbIndGlob); 
    2542     } 
    2543     else 
    2544     { 
    2545       i_index.resizeAndPreserve(nbIndGlob); 
    2546       j_index.resizeAndPreserve(nbIndGlob); 
    2547     } 
    2548  
    2549     domainMask.resize(0); // Mask is not defined anymore on servers 
    2550   } 
    2551   CATCH 
    2552  
    2553   /*! 
    2554     Receive attributes event from clients(s) 
    2555     \param[in] event event contain info about rank and associated attributes 
    2556   */ 
    2557   void CDomain::recvDistributionAttributes(CEventServer& event) 
    2558   TRY 
    2559   { 
    2560     CBufferIn* buffer=event.subEvents.begin()->buffer; 
    2561     string domainId ; 
    2562     *buffer>>domainId ; 
    2563     get(domainId)->recvDistributionAttributes(*buffer); 
    2564   } 
    2565   CATCH 
    2566  
    2567   /*! 
    2568     Receive attributes from client(s) 
    2569     \param[in] rank rank of client source 
    2570     \param[in] buffer message containing attributes info 
    2571   */ 
    2572   void CDomain::recvDistributionAttributes(CBufferIn& buffer) 
    2573   TRY 
    2574   { 
    2575     int ni_tmp, ibegin_tmp, nj_tmp, jbegin_tmp; 
    2576     int ni_glo_tmp, nj_glo_tmp; 
    2577     buffer >> isUnstructed_ >> ni_tmp >> ibegin_tmp >> nj_tmp >> jbegin_tmp 
    2578            >> ni_glo_tmp >> nj_glo_tmp 
    2579            >> isCompressible_; 
    2580  
    2581     ni.setValue(ni_tmp); 
    2582     ibegin.setValue(ibegin_tmp); 
    2583     nj.setValue(nj_tmp); 
    2584     jbegin.setValue(jbegin_tmp); 
    2585     ni_glo.setValue(ni_glo_tmp); 
    2586     nj_glo.setValue(nj_glo_tmp); 
    2587  
    2588   } 
    2589  CATCH_DUMP_ATTR 
    2590   /*! 
    2591     Receive longitude event from clients(s) 
    2592     \param[in] event event contain info about rank and associated longitude 
    2593   */ 
    2594   void CDomain::recvLon(CEventServer& event) 
    2595   TRY 
    2596   { 
    2597     string domainId; 
    2598     std::map<int, CBufferIn*> rankBuffers; 
    2599  
    2600     list<CEventServer::SSubEvent>::iterator it; 
    2601     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    2602     {       
    2603       CBufferIn* buffer = it->buffer; 
    2604       *buffer >> domainId; 
    2605       rankBuffers[it->rank] = buffer;         
    2606     } 
    2607     get(domainId)->recvLon(rankBuffers); 
    2608   } 
    2609   CATCH 
    2610  
    2611   /*! 
    2612     Receive longitude information from client(s) 
    2613     \param[in] rankBuffers rank of sending client and the corresponding receive buffer   
    2614   */ 
    2615   void CDomain::recvLon(std::map<int, CBufferIn*>& rankBuffers) 
    2616   TRY 
    2617   { 
    2618     int nbReceived = rankBuffers.size(), i, ind, index, iindex, jindex, lInd; 
    2619     if (nbReceived != recvClientRanks_.size()) 
    2620       ERROR("void CDomain::recvLon(std::map<int, CBufferIn*>& rankBuffers)", 
    2621            << "The number of sending clients is not correct." 
    2622            << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived); 
    2623  
    2624     vector<CArray<double,1> > recvLonValue(nbReceived); 
    2625     vector<CArray<double,2> > recvBoundsLonValue(nbReceived);     
    2626     for (i = 0; i < recvClientRanks_.size(); ++i) 
    2627     { 
    2628       int rank = recvClientRanks_[i]; 
    2629       CBufferIn& buffer = *(rankBuffers[rank]); 
    2630       buffer >> hasLonLat; 
    2631       if (hasLonLat) 
    2632         buffer >> recvLonValue[i]; 
    2633       buffer >> hasBounds; 
    2634       if (hasBounds) 
    2635         buffer >> recvBoundsLonValue[i]; 
    2636     } 
    2637  
    2638     if (hasLonLat) 
    2639     { 
    2640       int nbLonInd = 0; 
    2641       for (i = 0; i < nbReceived; ++i) 
    2642       { 
    2643         nbLonInd += recvLonValue[i].numElements(); 
    2644       } 
    2645      
    2646       if (nbLonInd != globalLocalIndexMap_.size()) 
    2647         info (0) << "If domain " << this->getDomainOutputName() <<" does not have overlapped regions between processes " 
    2648                  << "something must be wrong with longitude index "<< std::endl; 
    2649  
    2650       nbLonInd = globalLocalIndexMap_.size(); 
    2651       lonvalue.resize(nbLonInd); 
    2652       if (hasBounds) 
    2653       { 
    2654         bounds_lonvalue.resize(nvertex,nbLonInd); 
    2655         bounds_lonvalue = 0.; 
    2656       } 
    2657  
    2658       nbLonInd = 0; 
    2659       for (i = 0; i < nbReceived; ++i) 
    2660       { 
    2661         CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]]; 
    2662         CArray<double,1>& tmp = recvLonValue[i]; 
    2663         for (ind = 0; ind < tmp.numElements(); ++ind) 
    2664         { 
    2665           lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 
    2666           lonvalue(lInd) = tmp(ind);  
    2667            if (hasBounds) 
    2668            {           
    2669             for (int nv = 0; nv < nvertex; ++nv) 
    2670               bounds_lonvalue(nv, lInd) = recvBoundsLonValue[i](nv, ind); 
    2671            }                   
    2672         } 
    2673       }        
    2674     } 
    2675   } 
    2676   CATCH_DUMP_ATTR 
    2677  
    2678   /*! 
    2679     Receive latitude event from clients(s) 
    2680     \param[in] event event contain info about rank and associated latitude 
    2681   */ 
    2682   void CDomain::recvLat(CEventServer& event) 
    2683   TRY 
    2684   { 
    2685     string domainId; 
    2686     std::map<int, CBufferIn*> rankBuffers; 
    2687  
    2688     list<CEventServer::SSubEvent>::iterator it; 
    2689     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    2690     {       
    2691       CBufferIn* buffer = it->buffer; 
    2692       *buffer >> domainId; 
    2693       rankBuffers[it->rank] = buffer;     
    2694     } 
    2695     get(domainId)->recvLat(rankBuffers); 
    2696   } 
    2697   CATCH 
    2698  
    2699   /*! 
    2700     Receive latitude information from client(s) 
    2701     \param[in] rankBuffers rank of sending client and the corresponding receive buffer   
    2702   */ 
    2703   void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers) 
    2704   TRY 
    2705   { 
    2706     int nbReceived = rankBuffers.size(), i, ind, index, iindex, jindex, lInd; 
    2707     if (nbReceived != recvClientRanks_.size()) 
    2708       ERROR("void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)", 
    2709            << "The number of sending clients is not correct." 
    2710            << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived); 
    2711  
    2712     vector<CArray<double,1> > recvLatValue(nbReceived); 
    2713     vector<CArray<double,2> > recvBoundsLatValue(nbReceived);     
    2714     for (i = 0; i < recvClientRanks_.size(); ++i) 
    2715     { 
    2716       int rank = recvClientRanks_[i]; 
    2717       CBufferIn& buffer = *(rankBuffers[rank]); 
    2718       buffer >> hasLonLat; 
    2719       if (hasLonLat) 
    2720         buffer >> recvLatValue[i]; 
    2721       buffer >> hasBounds; 
    2722       if (hasBounds) 
    2723         buffer >> recvBoundsLatValue[i]; 
    2724     } 
    2725  
    2726     if (hasLonLat) 
    2727     { 
    2728       int nbLatInd = 0; 
    2729       for (i = 0; i < nbReceived; ++i) 
    2730       { 
    2731         nbLatInd += recvLatValue[i].numElements(); 
    2732       } 
    2733      
    2734       if (nbLatInd != globalLocalIndexMap_.size()) 
    2735         info (0) << "If domain " << this->getDomainOutputName() <<" does not have overlapped regions between processes " 
    2736                 << "something must be wrong with latitude index "<< std::endl; 
    2737  
    2738       nbLatInd = globalLocalIndexMap_.size(); 
    2739       latvalue.resize(nbLatInd); 
    2740       if (hasBounds) 
    2741       { 
    2742         bounds_latvalue.resize(nvertex,nbLatInd); 
    2743         bounds_latvalue = 0. ; 
    2744       } 
    2745  
    2746       nbLatInd = 0; 
    2747       for (i = 0; i < nbReceived; ++i) 
    2748       { 
    2749         CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]]; 
    2750         CArray<double,1>& tmp = recvLatValue[i]; 
    2751         for (ind = 0; ind < tmp.numElements(); ++ind) 
    2752         { 
    2753           lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 
    2754           latvalue(lInd) = tmp(ind);     
    2755            if (hasBounds) 
    2756            { 
    2757             CArray<double,2>& boundslat = recvBoundsLatValue[i]; 
    2758             for (int nv = 0; nv < nvertex; ++nv) 
    2759               bounds_latvalue(nv, lInd) = boundslat(nv, ind); 
    2760            }    
    2761           ++nbLatInd; 
    2762         } 
    2763       }        
    2764     } 
    2765   } 
    2766   CATCH_DUMP_ATTR 
    2767  
    2768   /*! 
    2769     Receive area event from clients(s) 
    2770     \param[in] event event contain info about rank and associated area 
    2771   */ 
    2772   void CDomain::recvArea(CEventServer& event) 
    2773   TRY 
    2774   { 
    2775     string domainId; 
    2776     std::map<int, CBufferIn*> rankBuffers; 
    2777  
    2778     list<CEventServer::SSubEvent>::iterator it; 
    2779     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    2780     {       
    2781       CBufferIn* buffer = it->buffer; 
    2782       *buffer >> domainId; 
    2783       rankBuffers[it->rank] = buffer;      
    2784     } 
    2785     get(domainId)->recvArea(rankBuffers); 
    2786   } 
    2787   CATCH 
    2788  
    2789   /*! 
    2790     Receive area information from client(s) 
    2791     \param[in] rankBuffers rank of sending client and the corresponding receive buffer      
    2792   */ 
    2793   void CDomain::recvArea(std::map<int, CBufferIn*>& rankBuffers) 
    2794   TRY 
    2795   { 
    2796     int nbReceived = rankBuffers.size(), i, ind, index, lInd; 
    2797     if (nbReceived != recvClientRanks_.size()) 
    2798       ERROR("void CDomain::recvArea(std::map<int, CBufferIn*>& rankBuffers)", 
    2799            << "The number of sending clients is not correct." 
    2800            << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived); 
    2801  
    2802     vector<CArray<double,1> > recvAreaValue(nbReceived);       
    2803     for (i = 0; i < recvClientRanks_.size(); ++i) 
    2804     { 
    2805       int rank = recvClientRanks_[i]; 
    2806       CBufferIn& buffer = *(rankBuffers[rank]);       
    2807       buffer >> hasArea; 
    2808       if (hasArea) 
    2809         buffer >> recvAreaValue[i]; 
    2810     } 
    2811  
    2812     if (hasArea) 
    2813     { 
    2814       int nbAreaInd = 0; 
    2815       for (i = 0; i < nbReceived; ++i) 
    2816       {       
    2817         nbAreaInd += recvAreaValue[i].numElements(); 
    2818       } 
    2819  
    2820       if (nbAreaInd != globalLocalIndexMap_.size()) 
    2821         info (0) << "If domain " << this->getDomainOutputName() <<" does not have overlapped regions between processes " 
    2822                  << "something must be wrong with area index "<< std::endl; 
    2823  
    2824       nbAreaInd = globalLocalIndexMap_.size(); 
    2825       areavalue.resize(nbAreaInd); 
    2826       nbAreaInd = 0;       
    2827       for (i = 0; i < nbReceived; ++i) 
    2828       { 
    2829         CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]]; 
    2830         CArray<double,1>& tmp = recvAreaValue[i]; 
    2831         for (ind = 0; ind < tmp.numElements(); ++ind) 
    2832         { 
    2833           lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 
    2834           areavalue(lInd) = tmp(ind);           
    2835         } 
    2836       } 
    2837        
    2838     } 
    2839   } 
    2840   CATCH_DUMP_ATTR 
    2841  
     2131   
    28422132  /*! 
    28432133    Compare two domain objects.  
     
    28732163  CATCH_DUMP_ATTR 
    28742164 
    2875   /*! 
    2876     Receive data index event from clients(s) 
    2877     \param[in] event event contain info about rank and associated index 
    2878   */ 
    2879   void CDomain::recvDataIndex(CEventServer& event) 
     2165///////////////////////////////////////////////////////////////////////// 
     2166///////////////             TRANSFORMATIONS                    ////////// 
     2167///////////////////////////////////////////////////////////////////////// 
     2168 
     2169  std::map<StdString, ETranformationType> CDomain::transformationMapList_ = std::map<StdString, ETranformationType>(); 
     2170  bool CDomain::dummyTransformationMapList_ = CDomain::initializeTransformationMap(CDomain::transformationMapList_); 
     2171 
     2172  bool CDomain::initializeTransformationMap(std::map<StdString, ETranformationType>& m) 
    28802173  TRY 
    28812174  { 
    2882     string domainId; 
    2883     std::map<int, CBufferIn*> rankBuffers; 
    2884  
    2885     list<CEventServer::SSubEvent>::iterator it; 
    2886     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    2887     {       
    2888       CBufferIn* buffer = it->buffer; 
    2889       *buffer >> domainId; 
    2890       rankBuffers[it->rank] = buffer;         
    2891     } 
    2892     get(domainId)->recvDataIndex(rankBuffers); 
     2175    m["zoom_domain"] = TRANS_ZOOM_DOMAIN; 
     2176    m["interpolate_domain"] = TRANS_INTERPOLATE_DOMAIN; 
     2177    m["generate_rectilinear_domain"] = TRANS_GENERATE_RECTILINEAR_DOMAIN; 
     2178    m["compute_connectivity_domain"] = TRANS_COMPUTE_CONNECTIVITY_DOMAIN; 
     2179    m["expand_domain"] = TRANS_EXPAND_DOMAIN; 
     2180    m["reorder_domain"] = TRANS_REORDER_DOMAIN; 
     2181    m["extract_domain"] = TRANS_EXTRACT_DOMAIN; 
    28932182  } 
    28942183  CATCH 
    28952184 
    2896   /*! 
    2897     Receive data index information from client(s) 
    2898     A client receives data index from different clients to rebuild its own data index. 
    2899     Because we use global index + mask info to calculate the sending data to client(s),  
    2900     this data index must be updated with mask info (maybe it will change in the future) 
    2901     Because the data index is local, to rebuild data index of received client, we should use global index along with.  
    2902  
    2903     \param[in] rankBuffers rank of sending client and the corresponding receive buffer      
    2904   */ 
    2905   void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers) 
    2906   TRY 
    2907   { 
    2908     int nbReceived = rankBuffers.size(), i, ind, index, indexI, indexJ, type_int, lInd;     
    2909     if (nbReceived != recvClientRanks_.size()) 
    2910       ERROR("void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)", 
    2911            << "The number of sending clients is not correct." 
    2912            << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived); 
    2913  
    2914     vector<CArray<int,1> > recvDataIIndex(nbReceived),recvDataJIndex(nbReceived);      
    2915     for (i = 0; i < recvClientRanks_.size(); ++i) 
    2916     { 
    2917       int rank = recvClientRanks_[i]; 
    2918       CBufferIn& buffer = *(rankBuffers[rank]); 
    2919       buffer >> recvDataIIndex[i]; 
    2920       buffer >> recvDataJIndex[i]; 
    2921     } 
    2922     
    2923     int nbIndex = i_index.numElements(); 
    2924     CArray<int,1> dataIIndex(nbIndex), dataJIndex(nbIndex); 
    2925     dataIIndex = -1; dataJIndex = -1; 
    2926       
    2927     nbIndex = 0; 
    2928     for (i = 0; i < nbReceived; ++i) 
    2929     {       
    2930       CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]]; 
    2931       CArray<int,1>& tmpI = recvDataIIndex[i];     
    2932       CArray<int,1>& tmpJ = recvDataJIndex[i];      
    2933       if ((tmpI.numElements() != tmpInd.numElements()) || (tmpJ.numElements() != tmpInd.numElements())) 
    2934           ERROR("void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)", 
    2935              << "The number of global received index is not coherent with the number of received data index." 
    2936              << "Expected number of global index: " << tmpI.numElements() << " but received " << tmpInd.numElements()); 
    2937  
    2938       for (ind = 0; ind < tmpI.numElements(); ++ind) 
    2939       { 
    2940          lInd = globalLocalIndexMap_[size_t(tmpInd(ind))]; 
    2941          dataIIndex(lInd) = (-1 == dataIIndex(lInd)) ? tmpI(ind) : dataIIndex(lInd); // Only fill in dataIndex if there is no data 
    2942          dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd);   
    2943       }  
    2944     } 
    2945  
    2946     int nbCompressedData = 0;   
    2947     for (ind = 0; ind < dataIIndex.numElements(); ++ind) 
    2948     { 
    2949        indexI = dataIIndex(ind); indexJ = dataJIndex(ind); 
    2950        if ((0 <= indexI) && (0 <= indexJ)) 
    2951          ++nbCompressedData; 
    2952     }         
    2953    
    2954     data_i_index.resize(nbCompressedData); 
    2955     data_j_index.resize(nbCompressedData); 
    2956  
    2957     nbCompressedData = 0;   
    2958     for (ind = 0; ind < dataIIndex.numElements(); ++ind) 
    2959     { 
    2960        indexI = dataIIndex(ind); indexJ = dataJIndex(ind); 
    2961        if ((0 <= indexI) && (0 <= indexJ)) 
    2962        { 
    2963           data_i_index(nbCompressedData) = (1 == data_dim) ? ind : ind % ni; 
    2964           data_j_index(nbCompressedData) = (1 == data_dim) ? 0   : ind / ni; 
    2965          ++nbCompressedData; 
    2966        } 
    2967     } 
    2968  
    2969     // Reset data_ibegin, data_jbegin 
    2970     data_ibegin.setValue(0); 
    2971     data_jbegin.setValue(0); 
    2972   } 
    2973   CATCH_DUMP_ATTR 
    29742185 
    29752186  CTransformation<CDomain>* CDomain::addTransformation(ETranformationType transType, const StdString& id) 
     
    29812192  CATCH_DUMP_ATTR 
    29822193 
     2194  CTransformation<CDomain>* CDomain::addTransformation(ETranformationType transType, CTransformation<CDomain>* transformation) 
     2195  TRY 
     2196  { 
     2197    transformationMap_.push_back(std::make_pair(transType, transformation)); 
     2198    return transformationMap_.back().second; 
     2199  } 
     2200  CATCH_DUMP_ATTR 
    29832201  /*! 
    29842202    Check whether a domain has transformation 
     
    30232241  } 
    30242242  CATCH_DUMP_ATTR 
    3025  
     2243     
    30262244  /*! 
    30272245   * Go through the hierarchy to find the domain from which the transformations must be inherited 
    30282246   */ 
    3029   void CDomain::solveInheritanceTransformation() 
     2247  void CDomain::solveInheritanceTransformation_old() 
    30302248  TRY 
    30312249  { 
     
    30462264  } 
    30472265  CATCH_DUMP_ATTR 
     2266 
     2267 
     2268  void CDomain::solveInheritanceTransformation() 
     2269  TRY 
     2270  { 
     2271    if (solveInheritanceTransformation_done_) return; 
     2272    else solveInheritanceTransformation_done_=true ; 
     2273 
     2274    CDomain* domain = this; 
     2275    CDomain* Lastdomain ; 
     2276    std::list<CDomain*> refDomains; 
     2277    bool out=false ; 
     2278    vector<StdString> excludedAttr; 
     2279    excludedAttr.push_back("domain_ref"); 
     2280     
     2281    refDomains.push_front(domain) ; 
     2282    while (domain->hasDirectDomainReference() && !out) 
     2283    { 
     2284      CDomain* lastDomain=domain ; 
     2285      domain = domain->getDirectDomainReference(); 
     2286      domain->solveRefInheritance() ; 
     2287      if (!domain->SuperClass::isEqual(lastDomain,excludedAttr)) out=true ; 
     2288      refDomains.push_front(domain) ; 
     2289    } 
     2290 
     2291    CTransformationPaths::TPath path ; 
     2292    auto& pathList = std::get<2>(path) ; 
     2293    std::get<0>(path) = EElement::DOMAIN ; 
     2294    std::get<1>(path) = refDomains.front()->getId() ; 
     2295    for (auto& domain : refDomains) 
     2296    { 
     2297      CDomain::TransMapTypes transformations = domain->getAllTransformations(); 
     2298      for(auto& transformation : transformations) pathList.push_back({transformation.second->getTransformationType(),  
     2299                                                                      transformation.second->getId()}) ; 
     2300    } 
     2301    transformationPaths_.addPath(path) ; 
     2302 
     2303  } 
     2304  CATCH_DUMP_ATTR 
     2305   
     2306///////////////////////////////////////////////////////////////////////////////////////////// 
     2307/////////////////////////////////////////////////////////////////////////////////////////////  
    30482308 
    30492309  void CDomain::setContextClient(CContextClient* contextClient) 
  • XIOS/dev/dev_trunk_graph/src/node/domain.hpp

    r1600 r2019  
    1616#include "transformation.hpp" 
    1717#include "transformation_enum.hpp" 
     18#include "transformation_path.hpp" 
    1819#include "server_distribution_description.hpp" 
    1920#include "mesh.hpp" 
    20  
    21 namespace xios { 
     21#include "element.hpp" 
     22#include "local_connector.hpp" 
     23#include "scatterer_connector.hpp" 
     24#include "gatherer_connector.hpp" 
     25#include "distribution_type.hpp" 
     26#include "generic_algorithm_transformation.hpp" 
     27 
     28 
     29namespace xios 
     30{ 
    2231 
    2332   /// ////////////////////// Déclarations ////////////////////// /// 
     
    4857         enum EEventId 
    4958         { 
    50            EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT,  
    51            EVENT_ID_AREA, 
    52            EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT 
     59           EVENT_ID_DOMAIN_DISTRIBUTION, EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE 
    5360         } ; 
    5461 
     
    5764         typedef CDomainAttributes RelAttributes; 
    5865         typedef CDomainGroup      RelGroup; 
    59          typedef CTransformation<CDomain>::TransformationMapTypes TransMapTypes; 
    60  
     66          
    6167         /// Constructeurs /// 
    6268         CDomain(void); 
     
    7682         /// Vérifications /// 
    7783         void checkAttributes(void); 
    78          void checkAttributesOnClient(); 
    79          void checkAttributesOnClientAfterTransformation(); 
    80          void checkEligibilityForCompressedOutput(void); 
    81  
    82          void sendCheckedAttributes(); 
    83  
    84          bool hasTransformation(); 
    85          void solveInheritanceTransformation(); 
    86          TransMapTypes getAllTransformations(); 
     84         bool checkAttributes_done_ = false ; 
     85 
     86          
     87      ////////////////////////// 
     88      ///// transformations //// 
     89      ////////////////////////// 
     90      public: 
     91        typedef CTransformation<CDomain>::TransformationMapTypes TransMapTypes; 
     92      private: 
     93        static bool initializeTransformationMap(std::map<StdString, ETranformationType>& m); 
     94        static std::map<StdString, ETranformationType> transformationMapList_; 
     95        static bool dummyTransformationMapList_; 
     96        TransMapTypes transformationMap_;          
     97 
     98      public: 
     99        CTransformation<CDomain>* addTransformation(ETranformationType transType, const StdString& id=""); 
     100        CTransformation<CDomain>* addTransformation(ETranformationType transType, CTransformation<CDomain>* transformation) ; 
     101        void setTransformations(const TransMapTypes&);          
     102        void duplicateTransformation(CDomain*); 
     103        TransMapTypes getAllTransformations(); 
     104        bool hasTransformation(); 
     105        void solveInheritanceTransformation_old(); // to remove later 
     106        void solveInheritanceTransformation(); 
     107      private: 
     108        bool solveInheritanceTransformation_done_= false ; 
     109      private: 
     110        CGenericAlgorithmTransformation* transformationAlgorithm_ = nullptr ; 
     111      public: 
     112        void setTransformationAlgorithm(CGenericAlgorithmTransformation* transformationAlgorithm) { transformationAlgorithm_=transformationAlgorithm ;} 
     113        CGenericAlgorithmTransformation* getTransformationAlgorithm(void) { return transformationAlgorithm_ ;}    
     114      private: 
     115        CTransformationPaths transformationPaths_ ; 
     116      public: 
     117        CTransformationPaths getTransformationPaths(void) {return transformationPaths_;}  
     118        void setTransformationPaths(const CTransformationPaths& transformationPaths) { transformationPaths_=transformationPaths ;} 
     119 
     120      //////////////////////////// 
     121 
    87122         void redistribute(int nbLocalDomain); 
    88          void duplicateTransformation(CDomain*); 
    89          CTransformation<CDomain>* addTransformation(ETranformationType transType, const StdString& id=""); 
    90123 
    91124      public: 
     
    94127         bool isWrittenCompressed(const StdString& filename) const; 
    95128          
    96          int getNumberWrittenIndexes(MPI_Comm writtenCom); 
    97          int getTotalNumberWrittenIndexes(MPI_Comm writtenCom); 
    98          int getOffsetWrittenIndexes(MPI_Comm writtenCom); 
    99          CArray<int,1>& getCompressedIndexToWriteOnServer(MPI_Comm writtenCom); 
    100  
    101129         std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, bool bufferForWriting = false); 
    102130 
    103131         bool isEmpty(void) const; 
    104132         bool isDistributed(void) const; 
    105          bool isCompressible(void) const;  
    106   
    107          std::vector<int> getNbGlob(); 
     133 
     134        public : 
     135         /*! 
     136            \brief return if the domain can be written or not in a compressed way. 
     137            ie if there are some masked or indexed point on the domain. Valid only on server side. 
     138            \return true if domain can be writtedn in a compressed way 
     139         */  
     140         bool isCompressible(void) { if (!isCompressibleComputed_) computeIsCompressible() ; return isCompressible_ ;}  
     141        private : 
     142         bool isCompressible_ ; /** specify if the domain can be written in a compressed way */  
     143         bool isCompressibleComputed_=false ; /** Indicate if compressability has been computed*/ 
     144         void computeIsCompressible() ; 
     145 
     146      public : 
    108147         bool isEqual(CDomain* domain); 
    109148 
    110149         static bool dispatchEvent(CEventServer& event); 
     150       
     151      private: 
     152         /** define if the domain is completed or not ie all attributes have been received before in case  
     153             of grid reading from file or coupling */  
     154         bool isCompleted_=true ;   
     155      public:      
     156        /*! 
     157           \brief Check if a domain is completed 
     158           Before make any domain processing, we must be sure that all domain informations have 
     159           been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     160           other context (coupling). So all direct reference of the domain (domain_ref) must be also completed 
     161           \return true if domain and domain reference are completed 
     162          */ 
     163         bool isCompleted(void) 
     164         { 
     165           if (hasDirectDomainReference()) if (!getDirectDomainReference()->isCompleted()) return false; 
     166           else return isCompleted_ ; 
     167         } 
     168         void setCompleted(void) { isCompleted_=true ; } 
     169         void unsetCompleted(void) { isCompleted_=false ; } 
    111170 
    112171      public: 
     
    115174         void addRelFileCompressed(const StdString& filename);             
    116175          
    117          void computeWrittenIndex(); 
    118          void computeWrittenCompressedIndex(MPI_Comm); 
    119  
    120176         void AllgatherRectilinearLonLat(CArray<double,1>& lon, CArray<double,1>& lat, 
    121177                                         CArray<double,1>& lon_g, CArray<double,1>& lat_g); 
     
    142198         CArray<double, 1> areavalue; 
    143199 
    144          CArray<int,1> localIndexToWriteOnServer; 
    145200 
    146201         CArray<bool, 1> domainMask; // mask_1d, mask_2d -> domainMask 
     
    157212 
    158213         void computeLocalMask(void) ; 
     214       
     215         /** The number of server of a context client. Avoid to re-compute indice computed in a previous computeConnectedClient */ 
     216         private: std::set<int> listNbServer_ ; 
     217          
    159218      private: 
    160219         void checkDomain(void); 
     
    169228         void checkArea(void); 
    170229         void checkLonLat(); 
    171  
    172          void setTransformations(const TransMapTypes&);          
    173          void computeNGlobDomain(); 
    174          void sendAttributes(); 
    175          void sendIndex(); 
    176          void sendDistributionAttributes(); 
    177          void sendArea(); 
    178          void sendLonLat();          
    179          void sendDataIndex(); 
     230          
     231       public: 
     232         void sendDomainToFileServer(CContextClient* client) ; 
     233       private: 
     234         std::set<CContextClient*> sendDomainToFileServer_done_ ; 
     235       public: 
     236         void sendDomainToCouplerOut(CContextClient* client, const string& fieldId, int posInGrid) ; 
     237       private: 
     238         std::set<CContextClient*> sendDomainToCouplerOut_done_ ; 
     239       
     240       public: 
     241        void makeAliasForCoupling(const string& fieldId, int posInGrid) ; 
     242 
     243       private: 
     244 
    180245         void convertLonLatValue(); 
    181246         void fillInRectilinearLonLat(); 
    182247         void fillInCurvilinearLonLat(); 
    183248         void fillInUnstructuredLonLat(); 
    184           
    185          static void recvDistributionAttributes(CEventServer& event); 
    186          static void recvIndex(CEventServer& event); 
    187          static void recvLon(CEventServer& event); 
    188          static void recvLat(CEventServer& event); 
    189          static void recvArea(CEventServer& event); 
    190          static void recvDataIndex(CEventServer& event); 
    191          void recvDistributionAttributes(CBufferIn& buffer);                   
    192          void recvIndex(std::map<int, CBufferIn*>& rankBuffers);          
    193          void recvLon(std::map<int, CBufferIn*>& rankBuffers); 
    194          void recvLat(std::map<int, CBufferIn*>& rankBuffers); 
    195          void recvArea(std::map<int, CBufferIn*>& rankBuffers);          
    196          void recvDataIndex(std::map<int, CBufferIn*>& rankBuffers); 
    197  
    198249         void completeLonLatClient(void);   
    199          void computeConnectedClients();     
    200  
     250          
     251          
    201252       private:          
    202253 
     
    205256         std::set<CContextClient*> clientsSet; 
    206257 
    207          bool isChecked, computedWrittenIndex_; 
     258         bool isChecked ; 
    208259         std::set<StdString> relFiles, relFilesCompressed; 
    209          bool isClientChecked; // Verify whether all attributes of domain on the client side are good 
    210          bool isClientAfterTransformationChecked; 
    211          std::map<int, CArray<int,1> > indGlob_; 
    212          std::map<int, map<int,int> > nbSenders; // Mapping of number of communicating client to a server 
    213  
    214 /** Global index of each client sent to server: map<serverSize, map<serverRank, indexes>> */ 
     260 
     261/** only on client side : Global index of each client sent to server: map<serverSize, map<serverRank, indexes>>  
     262    indSrv_[nbServers] -->  first map is related to the server distribution (ie associated with the contextClient) 
     263    indSrv_[nbServers][server_rank] -> array of global index sent to the server of rank "server_rank" 
     264    indSrv_[nbServers][server_rank](ind) --> global index on server of the local element "ind" sent (for lon, lat, mask, etc...)  
     265*/ 
    215266         std::map<int, std::unordered_map<int, vector<size_t> > > indSrv_; 
    216          // std::map<CContextClient*, std::map<int, vector<int> > > indWrittenSrv_; // Global written index of each client sent to server 
    217          std::vector<int> indexesToWrite; 
    218          std::vector<int> recvClientRanks_; 
    219          std::map<int,int> numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_; 
    220          std::map<int, CArray<int, 1> > compressedIndexToWriteOnServer;      
    221          std::map<int, std::map<int,size_t> > connectedDataSize_; 
     267 
    222268         std::map<int, std::vector<int> > connectedServerRank_; 
    223269 
    224          //! True if and only if the data defined on the domain can be outputted in a compressed way 
    225          bool isCompressible_; 
    226270         bool isRedistributed_; 
    227          TransMapTypes transformationMap_;          
    228271         bool isUnstructed_; 
    229          std::unordered_map<size_t,size_t> globalLocalIndexMap_; 
     272 
    230273        
    231        private: 
    232          static bool initializeTransformationMap(std::map<StdString, ETranformationType>& m); 
    233          static std::map<StdString, ETranformationType> transformationMapList_; 
    234          static bool _dummyTransformationMapList; 
     274       ////////////////////////////////////////////////////////////////////////////////////// 
     275       //  this part is related to distribution, element definition, views and connectors  // 
     276       ////////////////////////////////////////////////////////////////////////////////////// 
     277       private: 
     278         CLocalElement* localElement_ = nullptr ; 
     279         void initializeLocalElement(void) ; 
     280        
     281       public:   
     282         CLocalElement* getLocalElement(void) { if (localElement_==nullptr) initializeLocalElement() ; return localElement_ ; } 
     283         CLocalView* getLocalView(CElementView::type type) { return getLocalElement()->getView(type) ;} 
     284        
     285       private:   
     286         void addFullView(void) ; 
     287         void addWorkflowView(void) ; 
     288         void addModelView(void) ; 
     289         
     290       private: 
     291         CLocalConnector* modelToWorkflowConnector_ ; 
     292         void computeModelToWorkflowConnector(void)  ; 
     293       public: 
     294         CLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_ ;} 
     295 
     296       public: 
     297         void computeRemoteElement(CContextClient* client, EDistributionType) ; 
     298         void distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex, CScattererConnector* &scattererConnector, 
     299                                 const string& domainId="") ; 
     300 
     301         static void recvDomainDistribution(CEventServer& event) ; 
     302         void receivedDomainDistribution(CEventServer& event, int phasis) ; 
     303 
     304         void sendDistributedAttributes(CContextClient* client, CScattererConnector& scaterrerConnector, const string& domainId) ; 
     305         static void recvDistributedAttributes(CEventServer& event) ; 
     306         void recvDistributedAttributes(CEventServer& event, const string& type) ; 
     307         void setServerMask(CArray<bool,1>& serverMask, CContextClient* client) ; 
     308 
     309       private: 
     310         map<CContextClient*, CDistributedElement*> remoteElement_ ; 
     311       public:  
     312         CDistributedElement* getRemoteElement(CContextClient* client) {return remoteElement_[client] ;} 
     313       private: 
     314         map<CContextClient*, CScattererConnector*> clientToServerConnector_ ; 
     315       public:  
     316         CScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;} 
     317        
     318       private: 
     319         CGathererConnector*  gathererConnector_ ; 
     320       public: 
     321         CGathererConnector* getGathererConnector(void) { return gathererConnector_ ;} 
     322        private: 
     323         CGathererConnector* serverFromClientConnector_ ; 
     324         CDistributedElement* elementFrom_ ; 
     325       public: 
     326         CGathererConnector* getServerFromClientConnector(void) { return serverFromClientConnector_ ;} 
     327 
     328       private: 
     329         CScattererConnector*  serverToClientConnector_ = nullptr ; 
     330       public:  
     331         CScattererConnector* getServerToClientConnector(void) { return serverToClientConnector_ ;}  
     332 
     333       private: 
     334         map<CContextClient*,CGathererConnector*>  clientFromServerConnector_  ; 
     335       public:  
     336         CGathererConnector* getClientFromServerConnector(CContextClient* client) { return clientFromServerConnector_[client] ;}         
     337          
    235338 
    236339         DECLARE_REF_FUNC(Domain,domain) 
  • XIOS/dev/dev_trunk_graph/src/node/duplicate_scalar_to_axis.cpp

    r1314 r2019  
    11#include "duplicate_scalar_to_axis.hpp" 
     2#include "axis_algorithm_duplicate_scalar.hpp" 
    23#include "type.hpp" 
    34#include "axis.hpp" 
     
    2829  bool CDuplicateScalarToAxis::registerTrans() 
    2930  { 
    30     return registerTransformation(TRANS_DUPLICATE_SCALAR_TO_AXIS, CDuplicateScalarToAxis::create); 
     31    return registerTransformation(TRANS_DUPLICATE_SCALAR_TO_AXIS, {create, getTransformation}); 
    3132  } 
    3233 
     
    4344    
    4445  } 
    45  
     46   
     47  CGenericAlgorithmTransformation* CDuplicateScalarToAxis::createAlgorithm(bool isSource, 
     48                                                        CGrid* gridDst, CGrid* gridSrc, 
     49                                                        int elementPositionInGrid, 
     50                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     51                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     52                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     53                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     54                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     55                                                         std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     56  { 
     57    return CAxisAlgorithmDuplicateScalar::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid,  
     58                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     59                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition) ; 
     60  } 
    4661} 
  • XIOS/dev/dev_trunk_graph/src/node/duplicate_scalar_to_axis.hpp

    r1314 r2019  
    2020  class CAxis; 
    2121  class CScalar; 
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2224 
    2325  ///-------------------------------------------------------------- 
     
    4143      typedef CObjectTemplate<CDuplicateScalarToAxis> SuperClass; 
    4244      typedef CDuplicateScalarToAxisAttributes SuperClassAttribute; 
     45      typedef CDuplicateScalarToAxis MyClass ; 
     46      typedef CTransformation<CAxis> SuperTransform ; 
    4347 
    4448    public : 
     
    5660      static StdString GetDefName(void); 
    5761      static ENodeType GetType(void); 
     62      const string& getId(void) { return this->SuperClass::getId();} 
     63      ETranformationType getTransformationType(void) { return TRANS_DUPLICATE_SCALAR_TO_AXIS ;} 
     64      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     65      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     66      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     67                                                               CGrid* gridDst, CGrid* gridSrc, 
     68                                                               int elementPositionInGrid, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     71                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     74                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5875    private: 
    5976      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/expand_domain.cpp

    r1158 r2019  
    11#include "expand_domain.hpp" 
     2#include "domain_algorithm_expand.hpp" 
    23#include "type.hpp" 
    34 
     
    2728  bool CExpandDomain::registerTrans() 
    2829  { 
    29     registerTransformation(TRANS_EXPAND_DOMAIN, CExpandDomain::create); 
     30    registerTransformation(TRANS_EXPAND_DOMAIN, {create, getTransformation}); 
    3031  } 
    3132 
     
    4748    if (this->type.isEmpty()) this->type.setValue(CExpandDomain::type_attr::edge); 
    4849  } 
    49  
     50   
     51  CGenericAlgorithmTransformation* CExpandDomain::createAlgorithm(bool isSource, 
     52                                                        CGrid* gridDst, CGrid* gridSrc, 
     53                                                        int elementPositionInGrid, 
     54                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     55                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     56                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     57                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     58                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     59                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     60  { 
     61    return CDomainAlgorithmExpand::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     62                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     63                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition) ; 
     64  } 
    5065} 
  • XIOS/dev/dev_trunk_graph/src/node/expand_domain.hpp

    r935 r2019  
    2020  class CExpandDomain; 
    2121  class CDomain; 
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2224 
    2325  ///-------------------------------------------------------------- 
     
    4143      typedef CObjectTemplate<CExpandDomain> SuperClass; 
    4244      typedef CExpandDomainAttributes SuperClassAttribute; 
     45      typedef CExpandDomain MyClass ; 
     46      typedef CTransformation<CDomain> SuperTransform ; 
    4347 
    4448    public : 
     
    5660      static StdString GetDefName(void); 
    5761      static ENodeType GetType(void); 
     62      const string& getId(void) { return this->SuperClass::getId();} 
     63      ETranformationType getTransformationType(void) { return TRANS_EXPAND_DOMAIN ;} 
     64      static CTransformation<CDomain>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     65      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     66      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     67                                                               CGrid* gridDst, CGrid* gridSrc, 
     68                                                               int elementPositionInGrid, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     71                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     74                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5875    private: 
    5976      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/extract_axis.cpp

    r1558 r2019  
    11#include "extract_axis.hpp" 
     2#include "axis_algorithm_extract.hpp" 
    23#include "type.hpp" 
    34 
     
    2627  bool CExtractAxis::registerTrans() 
    2728  { 
    28     return registerTransformation(TRANS_EXTRACT_AXIS, CExtractAxis::create); 
     29    return registerTransformation(TRANS_EXTRACT_AXIS, {create, getTransformation}); 
    2930  } 
    3031 
     
    7778  } 
    7879 
     80  CGenericAlgorithmTransformation* CExtractAxis::createAlgorithm(bool isSource, 
     81                                                        CGrid* gridDst, CGrid* gridSrc, 
     82                                                        int elementPositionInGrid, 
     83                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     84                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     85                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     86                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     87                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     88                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     89  { 
     90    return CAxisAlgorithmExtract::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid,  
     91                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     92                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     93  } 
    7994} 
  • XIOS/dev/dev_trunk_graph/src/node/extract_axis.hpp

    r1558 r2019  
    2020  class CExtractAxis; 
    2121  class CAxis; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CExtractAxis> SuperClass; 
    4243      typedef CExtractAxisAttributes SuperClassAttribute; 
     44      typedef CExtractAxis MyClass ; 
     45      typedef CTransformation<CAxis> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_EXTRACT_AXIS ;} 
     63      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/extract_axis_to_scalar.cpp

    r960 r2019  
    11#include "extract_axis_to_scalar.hpp" 
     2#include "scalar_algorithm_extract_axis.hpp" 
     3 
    24#include "type.hpp" 
    35#include "axis.hpp" 
     
    2830  bool CExtractAxisToScalar::registerTrans() 
    2931  { 
    30     return registerTransformation(TRANS_EXTRACT_AXIS_TO_SCALAR, CExtractAxisToScalar::create); 
     32    return registerTransformation(TRANS_EXTRACT_AXIS_TO_SCALAR, {create, getTransformation}); 
    3133  } 
    3234 
     
    5759  } 
    5860 
     61  CGenericAlgorithmTransformation* CExtractAxisToScalar::createAlgorithm(bool isSource, 
     62                                                        CGrid* gridDst, CGrid* gridSrc, 
     63                                                        int elementPositionInGrid, 
     64                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     65                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     66                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     67                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     68                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     69                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     70  { 
     71    return CScalarAlgorithmExtractAxis::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     72                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     73                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition) ; 
     74  } 
    5975} 
  • XIOS/dev/dev_trunk_graph/src/node/extract_axis_to_scalar.hpp

    r960 r2019  
    2020  class CAxis; 
    2121  class CScalar; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CExtractAxisToScalar> SuperClass; 
    4243      typedef CExtractAxisToScalarAttributes SuperClassAttribute; 
     44      typedef CExtractAxisToScalar MyClass ; 
     45      typedef CTransformation<CScalar> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_EXTRACT_AXIS_TO_SCALAR ;} 
     63      static CTransformation<CScalar>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/extract_domain.cpp

    r1549 r2019  
    11#include "extract_domain.hpp" 
     2#include "domain_algorithm_extract.hpp" 
    23#include "type.hpp" 
    34 
     
    2728  bool CExtractDomain::registerTrans() 
    2829  { 
    29     registerTransformation(TRANS_EXTRACT_DOMAIN, CExtractDomain::create); 
     30    registerTransformation(TRANS_EXTRACT_DOMAIN, {create, getTransformation}); 
    3031  } 
    3132 
     
    7273  } 
    7374 
     75  CGenericAlgorithmTransformation* CExtractDomain::createAlgorithm(bool isSource, 
     76                                                        CGrid* gridDst, CGrid* gridSrc, 
     77                                                        int elementPositionInGrid, 
     78                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     79                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     80                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     81                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     82                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     83                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     84  { 
     85    return CDomainAlgorithmExtract::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     86                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     87                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     88  } 
    7489} 
  • XIOS/dev/dev_trunk_graph/src/node/extract_domain.hpp

    r1549 r2019  
    2020  class CExtractDomain; 
    2121  class CDomain; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CExtractDomain> SuperClass; 
    4243      typedef CExtractDomainAttributes SuperClassAttribute; 
     44      typedef CExtractDomain MyClass ; 
     45      typedef CTransformation<CDomain> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
    58     private: 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_EXTRACT_DOMAIN ;} 
     63      static CTransformation<CDomain>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
     74     private: 
    5975      static bool registerTrans(); 
    6076      static CTransformation<CDomain>* create(const StdString& id, xml::CXMLNode* node); 
    61       static bool _dummyRegistered; 
     77     static bool _dummyRegistered; 
    6278  }; // class CExtractDomain 
    6379 
  • XIOS/dev/dev_trunk_graph/src/node/extract_domain_to_axis.cpp

    r980 r2019  
    11#include "extract_domain_to_axis.hpp" 
     2#include "axis_algorithm_extract_domain.hpp" 
    23#include "type.hpp" 
    34#include "axis.hpp" 
     
    2829  bool CExtractDomainToAxis::registerTrans() 
    2930  { 
    30     return registerTransformation(TRANS_EXTRACT_DOMAIN_TO_AXIS, CExtractDomainToAxis::create); 
     31    return registerTransformation(TRANS_EXTRACT_DOMAIN_TO_AXIS, {create, getTransformation}); 
    3132  } 
    3233 
     
    9899  } 
    99100 
     101  CGenericAlgorithmTransformation* CExtractDomainToAxis::createAlgorithm(bool isSource, 
     102                                                        CGrid* gridDst, CGrid* gridSrc, 
     103                                                        int elementPositionInGrid, 
     104                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     105                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     106                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     107                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     108                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     109                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     110  { 
     111    return CAxisAlgorithmExtractDomain::create(isSource, gridDst, gridSrc, this, elementPositionInGrid,  
     112                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     113                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     114  } 
    100115} 
  • XIOS/dev/dev_trunk_graph/src/node/extract_domain_to_axis.hpp

    r895 r2019  
    2020  class CAxis; 
    2121  class CDomain; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CExtractDomainToAxis> SuperClass; 
    4243      typedef CExtractDomainToAxisAttributes SuperClassAttribute; 
    43  
     44      typedef CExtractDomainToAxis MyClass ; 
     45      typedef CTransformation<CAxis> SuperTransform ; 
     46  
    4447    public : 
    4548      /// Constructeurs /// 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_EXTRACT_DOMAIN_TO_AXIS ;} 
     63      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/field.cpp

    r1688 r2019  
    1515#include <set> 
    1616#include "garbage_collector.hpp" 
    17 #include "source_filter.hpp" 
    18 #include "store_filter.hpp" 
    19 #include "file_writer_filter.hpp" 
    2017#include "pass_through_filter.hpp" 
    2118#include "filter_expr_node.hpp" 
    2219#include "lex_parser.hpp" 
    2320#include "temporal_filter.hpp" 
    24 #include "spatial_transform_filter.hpp" 
    25 #include "file_server_writer_filter.hpp" 
    26 #include "workflow_graph.hpp" 
    27  
    28 namespace xios{ 
    29  
    30    /// ////////////////////// Définitions ////////////////////// /// 
    31  
    32    CField::CField(void) 
    33       : CObjectTemplate<CField>(), CFieldAttributes() 
    34       , grid(), file() 
    35       , written(false) 
    36       , nstep(0), nstepMax(0) 
    37       , hasOutputFile(false) 
    38       , domAxisScalarIds_(vector<StdString>(3,"")) 
    39       , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false) 
    40       , isGridChecked(false) 
    41       , useCompressedOutput(false) 
    42       , hasTimeInstant(false) 
    43       , hasTimeCentered(false) 
    44       , wasDataRequestedFromServer(false) 
    45       , wasDataAlreadyReceivedFromServer(false) 
    46       , mustAutoTrigger(false) 
    47       , isEOF(false), nstepMaxRead(false) 
    48    { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group"));  
    49      field_graph_start = -2; 
    50      field_graph_end = -2; 
    51    } 
    52  
    53    CField::CField(const StdString& id) 
    54       : CObjectTemplate<CField>(id), CFieldAttributes() 
    55       , grid(), file() 
    56       , written(false) 
    57       , nstep(0), nstepMax(0) 
    58       , hasOutputFile(false) 
    59       , domAxisScalarIds_(vector<StdString>(3,"")) 
    60       , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false) 
    61       , isGridChecked(false) 
    62       , useCompressedOutput(false) 
    63       , hasTimeInstant(false) 
    64       , hasTimeCentered(false) 
    65       , wasDataRequestedFromServer(false) 
    66       , wasDataAlreadyReceivedFromServer(false) 
    67       , mustAutoTrigger(false) 
    68       , isEOF(false), nstepMaxRead(false) 
    69    { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group"));  
    70      field_graph_start = -2; 
    71      field_graph_end = -2; 
    72    } 
    73  
    74  
    75    CField::~CField(void) 
    76    {} 
     21#include "server_from_client_source_filter.hpp" 
     22#include "file_reader_source_filter.hpp" 
     23#include "tracer.hpp" 
     24#include "graph_package.hpp" 
     25 
     26namespace xios 
     27{ 
     28 
     29  /// ////////////////////// Définitions ////////////////////// /// 
     30 
     31  CField::CField(void) 
     32    : CObjectTemplate<CField>(), CFieldAttributes() 
     33    , written(false) 
     34    , hasOutputFile(false) 
     35    , domAxisScalarIds_(vector<StdString>(3,"")) 
     36    , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false) 
     37    , isGridChecked(false) 
     38    , useCompressedOutput(false) 
     39    , hasTimeInstant(false) 
     40    , hasTimeCentered(false) 
     41    , mustAutoTrigger(false) 
     42  { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
     43 
     44  CField::CField(const StdString& id) 
     45    : CObjectTemplate<CField>(id), CFieldAttributes() 
     46    , written(false) 
     47    , hasOutputFile(false) 
     48    , domAxisScalarIds_(vector<StdString>(3,"")) 
     49    , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false) 
     50    , isGridChecked(false) 
     51    , useCompressedOutput(false) 
     52    , hasTimeInstant(false) 
     53    , hasTimeCentered(false) 
     54    , mustAutoTrigger(false) 
     55    { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); } 
     56 
     57  CField::~CField(void) 
     58  {} 
    7759 
    7860  //---------------------------------------------------------------- 
    7961 
    80    void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup) 
    81    TRY 
    82    { 
    83       this->vVariableGroup = newVVariableGroup; 
    84    } 
    85    CATCH 
    86  
    87    CVariableGroup* CField::getVirtualVariableGroup(void) const 
    88    TRY 
    89    { 
    90       return this->vVariableGroup; 
    91    } 
    92    CATCH 
    93  
    94    std::vector<CVariable*> CField::getAllVariables(void) const 
    95    TRY 
    96    { 
    97       return this->vVariableGroup->getAllChildren(); 
    98    } 
    99    CATCH 
    100  
    101    void CField::solveDescInheritance(bool apply, const CAttributeMap* const parent) 
    102    TRY 
    103    { 
    104       SuperClassAttribute::setAttributes(parent, apply); 
    105       this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL); 
    106    } 
    107    CATCH_DUMP_ATTR 
     62  void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup) 
     63  TRY 
     64  { 
     65    this->vVariableGroup = newVVariableGroup; 
     66  } 
     67  CATCH 
     68 
     69  CVariableGroup* CField::getVirtualVariableGroup(void) const 
     70  TRY 
     71  { 
     72     return this->vVariableGroup; 
     73  } 
     74  CATCH 
     75 
     76  std::vector<CVariable*> CField::getAllVariables(void) const 
     77  TRY 
     78  { 
     79    return this->vVariableGroup->getAllChildren(); 
     80  } 
     81  CATCH 
     82 
     83  void CField::solveDescInheritance(bool apply, const CAttributeMap* const parent) 
     84  TRY 
     85  { 
     86    SuperClassAttribute::setAttributes(parent, apply); 
     87    this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL); 
     88  } 
     89  CATCH_DUMP_ATTR 
    10890 
    10991  //---------------------------------------------------------------- 
     
    141123          return true; 
    142124          break; 
    143  
     125      
     126        case EVENT_ID_GRID_COMPLETED : 
     127          recvGridCompleted(event); 
     128          return true; 
     129          break; 
    144130        default : 
    145131          ERROR("bool CField::dispatchEvent(CEventServer& event)", << "Unknown Event"); 
     
    150136  CATCH 
    151137 
    152   void CField::sendUpdateData(const CArray<double,1>& data) 
    153   TRY 
    154   { 
    155     CTimer::get("Field : send data").resume(); 
    156  
    157     CContext* context = CContext::getCurrent(); 
    158     CContextClient* client = (!context->hasServer) ? context->client : this->file->getContextClient(); 
    159     int receiverSize = client->serverSize; 
    160  
    161     CEventClient event(getType(), EVENT_ID_UPDATE_DATA); 
    162  
    163     map<int, CArray<int,1> >::iterator it; 
    164     list<CMessage> list_msg; 
    165     list<CArray<double,1> > list_data; 
    166  
    167     if (!grid->doGridHaveDataDistributed(client)) 
    168     { 
    169        if (client->isServerLeader()) 
    170        { 
    171           for (it = grid->storeIndex_toSrv[client].begin(); it != grid->storeIndex_toSrv[client].end(); it++) 
    172           { 
    173             int rank = it->first; 
    174             CArray<int,1>& index = it->second; 
    175  
    176             list_msg.push_back(CMessage()); 
    177             list_data.push_back(CArray<double,1>(index.numElements())); 
    178  
    179             CArray<double,1>& data_tmp = list_data.back(); 
    180             for (int n = 0; n < data_tmp.numElements(); n++) data_tmp(n) = data(index(n)); 
    181  
    182             list_msg.back() << getId() << data_tmp; 
    183             event.push(rank, 1, list_msg.back()); 
    184           } 
    185           client->sendEvent(event); 
    186         } 
    187       else client->sendEvent(event); 
    188     } 
    189     else 
    190     { 
    191       for (it = grid->storeIndex_toSrv[client].begin(); it != grid->storeIndex_toSrv[client].end(); it++) 
    192       { 
    193         int rank = it->first; 
    194         CArray<int,1>& index = it->second; 
    195  
    196         list_msg.push_back(CMessage()); 
    197         list_data.push_back(CArray<double,1>(index.numElements())); 
    198  
    199         CArray<double,1>& data_tmp = list_data.back(); 
    200         for (int n = 0; n < data_tmp.numElements(); n++) data_tmp(n) = data(index(n)); 
    201  
    202         list_msg.back() << getId() << data_tmp; 
    203         event.push(rank, grid->nbSenders[receiverSize][rank], list_msg.back()); 
    204       } 
    205       client->sendEvent(event); 
    206     } 
    207  
    208     CTimer::get("Field : send data").suspend(); 
    209   } 
    210   CATCH_DUMP_ATTR 
    211138 
    212139  void CField::recvUpdateData(CEventServer& event) 
    213140  TRY 
    214141  { 
    215     std::map<int,CBufferIn*> rankBuffers; 
    216  
    217     list<CEventServer::SSubEvent>::iterator it; 
    218142    string fieldId; 
    219     CTimer::get("Field : recv data").resume(); 
    220     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    221     { 
    222       int rank = it->rank; 
    223       CBufferIn* buffer = it->buffer; 
    224       *buffer >> fieldId; 
    225       rankBuffers[rank] = buffer; 
    226     } 
    227     get(fieldId)->recvUpdateData(rankBuffers); 
    228     CTimer::get("Field : recv data").suspend(); 
    229   } 
    230   CATCH 
    231  
    232   void  CField::recvUpdateData(std::map<int,CBufferIn*>& rankBuffers) 
    233   TRY 
    234   { 
    235     CContext* context = CContext::getCurrent(); 
    236  
    237     size_t sizeData = 0; 
    238     if (0 == recvDataSrv.numElements()) 
    239     {             
    240       CArray<int,1>& storeClient = grid->storeIndex_client; 
    241  
    242       // Gather all data from different clients       
    243       recvDataSrv.resize(storeClient.numElements()); 
    244       recvFoperationSrv = std::shared_ptr<func::CFunctor>(new func::CInstant(recvDataSrv)); 
    245     } 
    246  
    247     CArray<double,1> recv_data_tmp(recvDataSrv.numElements());     
    248     const CDate& currDate = context->getCalendar()->getCurrentDate(); 
    249     CDuration offsetAllButMonth (freq_offset.getValue().year, 0 , freq_offset.getValue().day, 
    250                                    freq_offset.getValue().hour, freq_offset.getValue().minute, 
    251                                    freq_offset.getValue().second, freq_offset.getValue().timestep); 
    252     const CDate opeDate   = (last_operation_srv - offsetAllButMonth + context->getCalendar()->getTimeStep()) 
    253                               + freq_op + freq_operation_srv - freq_op - context->getCalendar()->getTimeStep() + offsetAllButMonth; 
    254  
    255     if (opeDate <= currDate) 
    256     { 
    257       for (map<int, CArray<size_t, 1> >::iterator it = grid->outLocalIndexStoreOnClient.begin(); it != grid->outLocalIndexStoreOnClient.end(); ++it) 
    258       { 
    259         CArray<double,1> tmp; 
    260         CArray<size_t,1>& indexTmp = it->second; 
    261         *(rankBuffers[it->first]) >> tmp; 
    262         for (int idx = 0; idx < indexTmp.numElements(); ++idx) 
    263         { 
    264           recv_data_tmp(indexTmp(idx)) = tmp(idx); 
    265         }       
    266       } 
    267     } 
    268  
    269     this->setData(recv_data_tmp); 
    270     // delete incomming flux for server only 
    271     recvFoperationSrv.reset() ; 
    272     recvDataSrv.reset() ; 
    273   } 
    274   CATCH_DUMP_ATTR 
    275  
    276   void CField::writeUpdateData(const CArray<double,1>& data) 
    277   TRY 
    278   { 
    279     CContext* context = CContext::getCurrent(); 
    280  
    281     const CDate& currDate = context->getCalendar()->getCurrentDate(); 
    282     CDuration offsetAllButMonth (freq_offset.getValue().year, 0 , freq_offset.getValue().day, 
    283                                    freq_offset.getValue().hour, freq_offset.getValue().minute, 
    284                                    freq_offset.getValue().second, freq_offset.getValue().timestep); 
    285     const CDate opeDate   = (last_operation_srv - offsetAllButMonth + context->getCalendar()->getTimeStep()) 
    286                               + freq_op + freq_operation_srv - freq_op - context->getCalendar()->getTimeStep() + offsetAllButMonth; 
    287     const CDate writeDate = last_Write_srv + freq_write_srv; 
    288  
    289     if (opeDate <= currDate) 
    290     { 
    291       (*recvFoperationSrv)(data); 
    292       last_operation_srv = currDate; 
    293     } 
    294  
    295     if (writeDate < (currDate + freq_operation_srv)) 
    296     { 
    297       recvFoperationSrv->final(); 
    298       last_Write_srv = writeDate; 
    299       grid->computeWrittenIndex(); 
    300       writeField(); 
    301       lastlast_Write_srv = last_Write_srv; 
    302     } 
    303   } 
    304   CATCH_DUMP_ATTR 
    305  
    306   void CField::writeField(void) 
    307   TRY 
    308   { 
    309     if (!getRelFile()->isEmptyZone()) 
    310     { 
    311       if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) 
    312       { 
    313         getRelFile()->checkWriteFile(); 
    314         this->incrementNStep(); 
    315         getRelFile()->getDataOutput()->writeFieldData(CField::get(this)); 
    316       } 
    317     } 
    318   } 
    319   CATCH_DUMP_ATTR 
     143    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> fieldId  ; 
     144    get(fieldId)->receiveUpdateData(event); 
     145  } 
     146  CATCH 
     147 
     148  void  CField::receiveUpdateData(CEventServer& event) 
     149  TRY 
     150  { 
     151    if (hasCouplerIn()) clientFromClientSourceFilter_->streamData(event) ; 
     152    else serverFromClientSourceFilter_->streamData(event) ; 
     153  } 
     154  CATCH 
    320155 
    321156  /* 
     
    329164  TRY 
    330165  { 
    331     CContext* context = CContext::getCurrent(); 
    332     // CContextClient* client = context->client; 
    333  
    334     // This code is for future: If we want to read file with level-2 servers 
    335     CContextClient* client = (!context->hasServer) ? context->client : this->file->getContextClient(); 
    336  
    337     lastDataRequestedFromServer = tsDataRequested; 
    338  
    339     // No need to send the request if we are sure that we are already at EOF 
    340     if (!isEOF || context->getCalendar()->getCurrentDate() <= dateEOF) 
    341     { 
    342       CEventClient event(getType(), EVENT_ID_READ_DATA); 
    343       if (client->isServerLeader()) 
    344       { 
    345         CMessage msg; 
    346         msg << getId(); 
    347         const std::list<int>& ranks = client->getRanksServerLeader(); 
    348         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    349           event.push(*itRank, 1, msg); 
    350         client->sendEvent(event); 
    351       } 
    352       else client->sendEvent(event); 
    353     } 
    354     else 
    355       serverSourceFilter->signalEndOfStream(tsDataRequested); 
    356  
    357     wasDataRequestedFromServer = true; 
    358  
    359     return !isEOF; 
    360   } 
    361   CATCH_DUMP_ATTR 
    362  
     166    return clientFromServerSourceFilter_->sendReadDataRequest(tsDataRequested) ; 
     167  } 
     168  CATCH_DUMP_ATTR 
     169  
     170   
    363171  /*! 
    364172  Send request new data read from file if need be, that is the current data is out-of-date. 
     
    368176  TRY 
    369177  { 
    370     const CDate& currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate(); 
    371  
    372     bool dataRequested = false; 
    373  
    374     while (currentDate >= lastDataRequestedFromServer) 
    375     { 
    376       info(20) << "currentDate : " << currentDate << endl ; 
    377       info(20) << "lastDataRequestedFromServer : " << lastDataRequestedFromServer << endl ; 
    378       info(20) << "file->output_freq.getValue() : " << file->output_freq.getValue() << endl ; 
    379       info(20) << "lastDataRequestedFromServer + file->output_freq.getValue() : " << lastDataRequestedFromServer + file->output_freq << endl ; 
    380  
    381       dataRequested |= sendReadDataRequest(lastDataRequestedFromServer + file->output_freq); 
    382     } 
    383  
    384     return dataRequested; 
    385   } 
    386   CATCH_DUMP_ATTR 
     178    return clientFromServerSourceFilter_->sendReadDataRequestIfNeeded() ; 
     179  } 
     180  CATCH_DUMP_ATTR 
     181 
    387182 
    388183  void CField::recvReadDataRequest(CEventServer& event) 
     
    395190  } 
    396191  CATCH 
    397  
     192   
    398193  /*! 
    399194    Receive data request sent from client and process it 
     
    405200  TRY 
    406201  { 
    407     CContext* context = CContext::getCurrent(); 
    408     CContextClient* client = context->client; 
    409  
    410     CEventClient event(getType(), EVENT_ID_READ_DATA_READY); 
    411     std::list<CMessage> msgs; 
    412  
    413     EReadField hasData = readField(); 
    414  
    415     map<int, CArray<double,1> >::iterator it; 
    416     if (!grid->doGridHaveDataDistributed(client)) 
    417     { 
    418        if (client->isServerLeader()) 
    419        { 
    420           if (0 != recvDataSrv.numElements()) 
    421           {             
    422             const std::list<int>& ranks = client->getRanksServerLeader(); 
    423             for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    424             { 
    425               msgs.push_back(CMessage()); 
    426               CMessage& msg = msgs.back(); 
    427               msg << getId(); 
    428               switch (hasData) 
    429               { 
    430                 case RF_DATA: 
    431                   msg << getNStep() - 1 << recvDataSrv; 
    432                   break; 
    433                 case RF_NODATA: 
    434                   msg << int(-2) << recvDataSrv; 
    435                   break; 
    436                 case RF_EOF:                   
    437                 default: 
    438                   msg << int(-1); 
    439                   break; 
    440               } 
    441  
    442               event.push(*itRank, 1, msg); 
    443             } 
    444           } 
    445           client->sendEvent(event); 
    446        } 
    447        else 
    448        { 
    449           client->sendEvent(event); 
    450        } 
    451     } 
    452     else 
    453     { 
    454       for (map<int, CArray<size_t, 1> >::iterator it = grid->outLocalIndexStoreOnClient.begin();  
    455                                                   it != grid->outLocalIndexStoreOnClient.end(); ++it) 
    456       { 
    457         CArray<size_t,1>& indexTmp = it->second; 
    458         CArray<double,1> tmp(indexTmp.numElements()); 
    459         for (int idx = 0; idx < indexTmp.numElements(); ++idx) 
    460         { 
    461           tmp(idx) = recvDataSrv(indexTmp(idx)); 
    462         }  
    463  
    464         msgs.push_back(CMessage()); 
    465         CMessage& msg = msgs.back(); 
    466         msg << getId(); 
    467         switch (hasData) 
    468         { 
    469           case RF_DATA: 
    470             msg << getNStep() - 1 << tmp; 
    471             break; 
    472           case RF_NODATA: 
    473             msg << int(-2) << tmp; 
    474             break; 
    475           case RF_EOF:                   
    476           default: 
    477             msg << int(-1); 
    478             break; 
    479         } 
    480  
    481         event.push(it->first, grid->nbReadSenders[client][it->first], msg); 
    482       } 
    483       client->sendEvent(event); 
    484     } 
    485   } 
    486   CATCH_DUMP_ATTR 
    487  
    488   /*! 
    489     Read field from a file. 
    490     A field is read with the distribution of data on the server side 
    491     \return State of field can be read from a file 
    492   */ 
    493   CField::EReadField CField::readField(void) 
    494   TRY 
    495   { 
    496     CContext* context = CContext::getCurrent(); 
    497     grid->computeWrittenIndex(); 
    498     getRelFile()->initRead(); 
    499     EReadField readState = RF_DATA; 
    500  
    501     if (!getRelFile()->isEmptyZone()) 
    502     {       
    503       if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)       
    504       { 
    505         if (0 == recvDataSrv.numElements()) 
    506         {             
    507           CArray<int,1>& storeClient = grid->storeIndex_client;           
    508           recvDataSrv.resize(storeClient.numElements());           
    509         } 
    510          
    511         getRelFile()->checkReadFile(); 
    512  
    513         if (!nstepMax) 
    514         { 
    515           nstepMax = getRelFile()->getDataInput()->getFieldNbRecords(CField::get(this)); 
    516         } 
    517  
    518         this->incrementNStep(); 
    519  
    520         if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) ) 
    521           readState = RF_EOF; 
    522  
    523         if (RF_EOF != readState) 
    524           getRelFile()->getDataInput()->readFieldData(CField::get(this)); 
    525       } 
    526     } 
    527     else 
    528     { 
    529       this->incrementNStep(); 
    530       if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) ) 
    531         readState = RF_EOF; 
    532       else 
    533         readState = RF_NODATA; 
    534  
    535       if (!nstepMaxRead) // This can be a bug if we try to read field from zero time record 
    536         readState = RF_NODATA; 
    537     } 
    538  
    539     if (!nstepMaxRead) 
    540     { 
    541        MPI_Allreduce(MPI_IN_PLACE, &nstepMax, 1, MPI_INT, MPI_MAX, context->server->intraComm); 
    542        nstepMaxRead = true; 
    543     } 
    544  
    545     return readState; 
    546   } 
    547   CATCH_DUMP_ATTR 
    548  
     202    fileReaderSourceFilter_->streamData() ; 
     203  } 
     204  CATCH_DUMP_ATTR   
     205 
     206   
    549207  /* 
    550208    Receive read data from server. 
     
    557215  { 
    558216    string fieldId; 
    559     vector<int> ranks; 
    560     vector<CBufferIn*> buffers; 
    561  
    562     list<CEventServer::SSubEvent>::iterator it; 
    563     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    564     { 
    565       ranks.push_back(it->rank); 
    566       CBufferIn* buffer = it->buffer; 
    567       *buffer >> fieldId; 
    568       buffers.push_back(buffer); 
    569     } 
    570     get(fieldId)->recvReadDataReady(ranks, buffers); 
    571   } 
    572   CATCH 
    573  
    574   /*! 
    575     Receive read data from server 
    576     \param [in] ranks Ranks of sending processes 
    577     \param [in] buffers buffers containing read data 
    578   */ 
    579   void CField::recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers) 
    580   TRY 
    581   { 
    582     CContext* context = CContext::getCurrent(); 
    583     std::map<int, CArray<double,1> > data; 
    584     const bool wasEOF = isEOF; 
    585  
    586     for (int i = 0; i < ranks.size(); i++) 
    587     { 
    588       int rank = ranks[i]; 
    589       int record; 
    590       *buffers[i] >> record; 
    591       isEOF = (record == int(-1)); 
    592  
    593       if (!isEOF) 
    594         *buffers[i] >> data[rank]; 
    595       else 
    596         break; 
    597     } 
    598  
    599     if (wasDataAlreadyReceivedFromServer) 
    600       lastDataReceivedFromServer = lastDataReceivedFromServer + file->output_freq; 
    601     else 
    602     { 
    603       lastDataReceivedFromServer = context->getCalendar()->getInitDate(); 
    604       wasDataAlreadyReceivedFromServer = true; 
    605     } 
    606  
    607     if (isEOF) 
    608     { 
    609       if (!wasEOF) 
    610         dateEOF = lastDataReceivedFromServer; 
    611  
    612       serverSourceFilter->signalEndOfStream(lastDataReceivedFromServer); 
    613     } 
    614     else 
    615       serverSourceFilter->streamDataFromServer(lastDataReceivedFromServer, data); 
    616   } 
    617   CATCH_DUMP_ATTR 
    618  
    619   void CField::checkForLateDataFromServer(void) 
     217    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> fieldId  ; 
     218    get(fieldId)->receiveReadDataReady(event); 
     219  } 
     220  CATCH 
     221 
     222  void CField::receiveReadDataReady(CEventServer& event) 
     223  TRY 
     224  { 
     225    clientFromServerSourceFilter_->streamData(event) ;     
     226  } 
     227  CATCH_DUMP_ATTR 
     228 
     229 
     230  void CField::checkForLateDataFromCoupler(void) 
    620231  TRY 
    621232  { 
     
    623234    const CDate& currentDate = context->getCalendar()->getCurrentDate(); 
    624235 
    625     // Check if data previously requested has been received as expected 
    626     if (wasDataRequestedFromServer && !isEOF) 
    627     { 
    628       CTimer timer("CField::checkForLateDataFromServer"); 
    629  
    630       bool isDataLate; 
    631       do 
    632       { 
    633         const CDate nextDataDue = wasDataAlreadyReceivedFromServer ? (lastDataReceivedFromServer + file->output_freq) : context->getCalendar()->getInitDate(); 
    634         isDataLate = (nextDataDue <= currentDate); 
    635  
    636         if (isDataLate) 
     236    CTimer timer("CField::checkForLateDataFromCoupler"); 
     237    timer.resume(); 
     238    traceOff() ; 
     239    timer.suspend(); 
     240     
     241    bool isDataLate;   
     242    do 
     243    { 
     244      isDataLate=clientFromClientSourceFilter_->isDataLate() ; 
     245      if (isDataLate) 
     246      { 
     247        timer.resume(); 
     248        context->globalEventLoop(); 
     249        timer.suspend(); 
     250      } 
     251    } while (isDataLate && timer.getCumulatedTime() < CXios::recvFieldTimeout); 
     252     
     253    timer.resume(); 
     254    traceOn() ; 
     255    timer.suspend() ; 
     256 
     257    if (isDataLate) ERROR("void CField::checkForLateDataFromCoupler(void)", 
     258                            << "Late data at timestep = " << currentDate); 
     259  } 
     260  CATCH_DUMP_ATTR 
     261 
     262  void CField::checkForLateDataFromServer(void) 
     263  TRY 
     264  { 
     265    clientFromServerSourceFilter_->checkForLateData() ; 
     266  } 
     267  CATCH_DUMP_ATTR  
     268   
     269   
     270  void CField::triggerLateField(void) 
     271  TRY 
     272  { 
     273    if (hasFileIn())  
     274    { 
     275      checkForLateDataFromServer() ; 
     276      clientFromServerSourceFilter_->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()) ; 
     277    }  
     278    else if (hasCouplerIn()) 
     279    { 
     280      checkForLateDataFromCoupler() ; 
     281      clientFromClientSourceFilter_->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()) ; 
     282    } 
     283  } 
     284  CATCH_DUMP_ATTR 
     285 
     286 
     287  void CField::checkIfMustAutoTrigger(void) 
     288  TRY 
     289  { 
     290    mustAutoTrigger = clientFromServerSourceFilter_ ? clientFromServerSourceFilter_->mustAutoTrigger() : false; 
     291  } 
     292  CATCH_DUMP_ATTR 
     293 
     294  void CField::autoTriggerIfNeeded(void) 
     295  TRY 
     296  { 
     297    if (mustAutoTrigger) 
     298      clientFromServerSourceFilter_->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()); 
     299  } 
     300  CATCH_DUMP_ATTR 
     301 
     302 
     303  //---------------------------------------------------------------- 
     304 
     305  StdString CField::GetName(void)    { return StdString("field"); } 
     306  StdString CField::GetDefName(void) { return CField::GetName(); } 
     307  ENodeType CField::GetType(void)    { return eField; } 
     308 
     309  //---------------------------------------------------------------- 
     310 
     311  CGrid* CField::getRelGrid(void) const 
     312  TRY 
     313  { 
     314    return this->grid_; 
     315  } 
     316  CATCH 
     317 
     318  //---------------------------------------------------------------- 
     319 
     320  CFile* CField::getRelFile(void) const 
     321  TRY 
     322  { 
     323    if (hasFileIn()) return this->fileIn_; 
     324    else if (hasFileOut()) return this->fileOut_ ; 
     325    else return nullptr ; 
     326  } 
     327  CATCH 
     328 
     329  func::CFunctor::ETimeType CField::getOperationTimeType() const 
     330  TRY 
     331  { 
     332    return operationTimeType; 
     333  } 
     334  CATCH 
     335 
     336 
     337  //---------------------------------------------------------------- 
     338 
     339  bool CField::isActive(bool atCurrentTimestep /*= false*/) const 
     340  TRY 
     341  { 
     342    if (modelToClientSourceFilter_)  
     343      return atCurrentTimestep ? modelToClientSourceFilter_->isDataExpected(CContext::getCurrent()->getCalendar()->getCurrentDate()) : true; 
     344    else if (clientToModelStoreFilter_)  return true; 
     345    else if (instantDataFilter) 
     346      ERROR("bool CField::isActive(bool atCurrentTimestep)", 
     347            << "Impossible to check if field [ id = " << getId() << " ] is active as it cannot be used to receive nor send data."); 
     348 
     349    return false; 
     350  } 
     351  CATCH 
     352 
     353  //---------------------------------------------------------------- 
     354 
     355  bool CField::wasWritten() const 
     356  TRY 
     357  { 
     358    return written; 
     359  } 
     360  CATCH 
     361 
     362  void CField::setWritten() 
     363  TRY 
     364  { 
     365    written = true; 
     366  } 
     367  CATCH_DUMP_ATTR 
     368 
     369  //---------------------------------------------------------------- 
     370 
     371  bool CField::getUseCompressedOutput() const 
     372  TRY 
     373  { 
     374    return useCompressedOutput; 
     375  } 
     376  CATCH 
     377 
     378  void CField::setUseCompressedOutput() 
     379  TRY 
     380  { 
     381    useCompressedOutput = true; 
     382  } 
     383  CATCH_DUMP_ATTR 
     384 
     385  //---------------------------------------------------------------- 
     386 
     387  void CField::updateRef(CGrid* grid) 
     388  TRY 
     389  { 
     390    if (!grid_ref.isEmpty()) grid_ref.setValue(grid->getId()); 
     391    else 
     392    { 
     393      std::vector<CAxis*> axisTmp = grid->getAxis(); 
     394      std::vector<CDomain*> domainTmp = grid->getDomains(); 
     395      if ((1<axisTmp.size()) || (1<domainTmp.size())) 
     396        ERROR("void CField::updateRef(CGrid* grid)", 
     397          << "More than one domain or axis is available for domain_ref/axis_ref of field " << this->getId()); 
     398 
     399      if ((!domain_ref.isEmpty()) && (domainTmp.empty())) 
     400        ERROR("void CField::updateRef(CGrid* grid)", 
     401          << "Incoherent between available domain and domain_ref of field " << this->getId()); 
     402      if ((!axis_ref.isEmpty()) && (axisTmp.empty())) 
     403        ERROR("void CField::updateRef(CGrid* grid)", 
     404          << "Incoherent between available axis and axis_ref of field " << this->getId()); 
     405 
     406      if (!domain_ref.isEmpty()) domain_ref.setValue(domainTmp[0]->getId()); 
     407      if (!axis_ref.isEmpty()) axis_ref.setValue(axisTmp[0]->getId()); 
     408    } 
     409  } 
     410  CATCH_DUMP_ATTR 
     411    
     412 
     413  void CField::checkGridOfEnabledFields() 
     414  TRY 
     415  { 
     416    if (!isGridChecked) 
     417    { 
     418      isGridChecked = true; 
     419      solveCheckMaskIndex(false); 
     420    } 
     421  } 
     422  CATCH_DUMP_ATTR 
     423 
     424  void CField::sendGridComponentOfEnabledFields() 
     425  TRY 
     426  { 
     427    solveGridDomainAxisRef(true); 
     428    // solveCheckMaskIndex(true); 
     429  } 
     430  CATCH_DUMP_ATTR 
     431 
     432  void CField::sendGridOfEnabledFields() 
     433  TRY 
     434  { 
     435    // solveGridDomainAxisRef(true); 
     436    solveCheckMaskIndex(true); 
     437  }    
     438  CATCH_DUMP_ATTR 
     439 
     440  /*! 
     441   * Compute the required buffer size to send the fields data. 
     442   * \param [in/out] bufferSize Modifying the bufferSize for the client context 
     443   * \param [in/out] maxEventSize Modifying the maximum event size for the client context  
     444   * \param [in] bufferForWriting True if buffers are used for sending data for writing 
     445   */   
     446  void CField::setContextClientDataBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize,  
     447                                              map<CContextClient*,map<int,size_t>>& maxEventSize,  
     448                                              bool bufferForWriting) 
     449  { 
     450    auto& contextBufferSize = bufferSize[client] ; 
     451    auto& contextMaxEventSize = maxEventSize[client] ; 
     452    const std::map<int, size_t> mapSize = grid_->getDataBufferSize(client, getId(), bufferForWriting); 
     453    for(auto& it : mapSize ) 
     454    { 
     455      // If contextBufferSize[it.first] does not exist, it will be zero-initialized 
     456      // so we can use it safely without checking for its existance 
     457      if (CXios::isOptPerformance) contextBufferSize[it.first] += it.second; 
     458      else if (contextBufferSize[it.first] < it.second) contextBufferSize[it.first] = it.second; 
     459 
     460      if (contextMaxEventSize[it.first] < it.second) contextMaxEventSize[it.first] = it.second; 
     461    } 
     462 
     463  } 
     464 
     465  void CField::setContextClientAttributesBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize,  
     466                                                   map<CContextClient*,map<int,size_t>>& maxEventSize,  
     467                                                   bool bufferForWriting) 
     468  { 
     469    auto& contextBufferSize = bufferSize[client] ; 
     470    auto& contextMaxEventSize = maxEventSize[client] ; 
     471    const std::map<int, size_t> mapSize = grid_->getAttributesBufferSize(client, bufferForWriting); 
     472    for(auto& it : mapSize ) 
     473    { 
     474      // If contextBufferSize[it.first] does not exist, it will be zero-initialized 
     475      // so we can use it safely without checking for its existance 
     476      if (contextBufferSize[it.first] < it.second) contextBufferSize[it.first] = it.second; 
     477      if (contextMaxEventSize[it.first] < it.second) contextMaxEventSize[it.first] = it.second; 
     478    } 
     479 
     480  } 
     481 
     482 
     483// ym obsolete to be removed  
     484  std::map<int, StdSize> CField::getGridAttributesBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/) 
     485  TRY 
     486  { 
     487    return grid_->getAttributesBufferSize(client, bufferForWriting); 
     488  } 
     489  CATCH_DUMP_ATTR 
     490 
     491// ym obsolete to be removed  
     492  std::map<int, StdSize> CField::getGridDataBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/) 
     493  TRY 
     494  { 
     495    return grid_->getDataBufferSize(client, getId(), bufferForWriting); 
     496  } 
     497  CATCH_DUMP_ATTR 
     498 
     499 
     500 
     501  size_t CField::getGlobalWrittenSize() 
     502  TRY 
     503  { 
     504    return grid_->getGlobalWrittenSize(); 
     505  } 
     506  CATCH_DUMP_ATTR 
     507 
     508  //---------------------------------------------------------------- 
     509 
     510  void CField::solveServerOperation(void) 
     511  TRY 
     512  { 
     513    CContext* context = CContext::getCurrent(); 
     514 
     515    if (freq_op.isEmpty()) freq_op.setValue(TimeStep); 
     516 
     517    if (freq_offset.isEmpty()) freq_offset.setValue(NoneDu); 
     518 
     519    if (operation.isEmpty()) 
     520      ERROR("void CField::solveServerOperation(void)", 
     521            << "An operation must be defined for field \"" << getId() << "\"."); 
     522 
     523    std::shared_ptr<func::CFunctor> functor; 
     524    CArray<double, 1> dummyData; 
     525 
     526#define DECLARE_FUNCTOR(MType, mtype) \ 
     527    if (operation.getValue().compare(#mtype) == 0) \ 
     528    { \ 
     529      functor.reset(new func::C##MType(dummyData)); \ 
     530    } 
     531 
     532#include "functor_type.conf" 
     533 
     534    if (!functor) 
     535      ERROR("void CField::solveServerOperation(void)", 
     536            << "\"" << operation << "\" is not a valid operation."); 
     537 
     538    operationTimeType = functor->timeType(); 
     539  } 
     540  CATCH_DUMP_ATTR 
     541 
     542 //---------------------------------------------------------------- 
     543 
     544  bool CField::buildWorkflowGraph(CGarbageCollector& gc) 
     545  { 
     546    if (buildWorkflowGraphDone_) return true ; 
     547     
     548    const bool detectMissingValues = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
     549    const double defaultValue = detectMissingValues ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
     550    bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     551    std::cout<<"field id="<<this->getId()<<" build_workflow_graph="<<buildGraph_<<std::endl; 
     552 
     553    if (!inputFilter)  
     554    { 
     555      inputFilter = std::shared_ptr<CPassThroughFilter>(new CPassThroughFilter(gc));  
     556      if(buildGraph_) 
     557      { 
     558        std::cout<<"============== field "<<this->getId()<<" calls a pass through filter ============== "<<inputFilter<<" ***** "<<CXios::isClient<<std::endl; 
     559        inputFilter->graphEnabled = true; 
     560        inputFilter->graphPackage = new CGraphPackage; 
     561        inputFilter->graphPackage->inFields.push_back(this); 
     562      } 
     563    } 
     564      
     565    if (hasDirectFieldReference()) 
     566    { 
     567       
     568      CField* fieldRef = getDirectFieldReference(); 
     569      if(buildGraph_) 
     570      { 
     571        (*fieldRef).build_workflow_graph.set(build_workflow_graph);   
     572      }     
     573      else 
     574      { 
     575        this->build_workflow_graph.set(fieldRef->build_workflow_graph); 
     576        buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     577      } 
     578 
     579       
     580      if(buildGraph_) this->build_workflow_graph.set(build_workflow_graph); 
     581      bool ret=fieldRef->buildWorkflowGraph(gc);  
     582      if (!ret) return false ; // workflow graph cannot be built at this stage 
     583    } 
     584 
     585    // now construct grid and check if element are enabled 
     586    solveGridReference() ; // grid_ is now defined 
     587    if (!isGridCompleted()) return false; 
     588 
     589    // Check if we have an expression to parse 
     590    std::shared_ptr<COutputPin> filterExpr ; 
     591    if (hasExpression()) 
     592    { 
     593      boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0')); 
     594      filterExpr = expr->reduce(gc, *this); 
     595      if (!filterExpr) return false ; // workflow graph cannot be built at this stage 
     596    } 
     597     
     598    // prepare transformation. Need to know before if workflow of auxillary field can be built 
     599    if (hasDirectFieldReference()) 
     600    { 
     601      auto gridPath=getGridPath() ; 
     602      gridPath.push_back(grid_) ; 
     603 
     604      CGrid* gridSrc=getDirectFieldReference()->getGrid() ; 
     605      std::shared_ptr<COutputPin> lastFilter ; 
     606      if (filterExpr) lastFilter=filterExpr ; 
     607      else lastFilter = inputFilter ; 
     608      CGrid* newGrid ;     
     609       
     610      for(auto grid : gridPath) 
     611      { 
     612        grid->solveElementsRefInheritance() ; 
     613        
     614        // new 
     615         
     616        std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = grid->buildTransformationGraph(gc, false,  gridSrc, detectMissingValues, defaultValue, newGrid, buildGraph_) ; 
     617        lastFilter->connectOutput(filters.first, 0); 
     618        if(buildGraph_) 
    637619        { 
    638           timer.resume(); 
    639  
    640           context->checkBuffersAndListen(); 
    641  
    642           timer.suspend(); 
     620          std::cout<<"============== field "<<this->getId()<<" calls a transformation filter 1 ============== "<<lastFilter<<" _ "<<filters.first<<" ***** "<<CXios::isClient<<std::endl; 
     621          filters.first->graphEnabled=true; 
     622          filters.first->graphPackage = new CGraphPackage; 
     623          filters.first->graphPackage->inFields.push_back(this); 
    643624        } 
    644       } 
    645       while (isDataLate && timer.getCumulatedTime() < CXios::recvFieldTimeout); 
    646  
    647       if (isDataLate) 
    648         ERROR("void CField::checkForLateDataFromServer(void)", 
    649               << "Late data at timestep = " << currentDate); 
    650     } 
    651   } 
    652   CATCH_DUMP_ATTR 
    653  
    654   void CField::checkIfMustAutoTrigger(void) 
    655   TRY 
    656   { 
    657     mustAutoTrigger = serverSourceFilter ? serverSourceFilter->mustAutoTrigger() : false; 
    658   } 
    659   CATCH_DUMP_ATTR 
    660  
    661   void CField::autoTriggerIfNeeded(void) 
    662   TRY 
    663   { 
    664     if (mustAutoTrigger) 
    665       serverSourceFilter->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()); 
    666   } 
    667   CATCH_DUMP_ATTR 
    668  
    669    //---------------------------------------------------------------- 
    670  
    671    void CField::setRelFile(CFile* _file) 
    672    TRY 
    673    { 
    674       this->file = _file; 
    675       hasOutputFile = true; 
    676    } 
    677    CATCH_DUMP_ATTR 
    678  
    679    //---------------------------------------------------------------- 
    680  
    681    StdString CField::GetName(void)    { return StdString("field"); } 
    682    StdString CField::GetDefName(void) { return CField::GetName(); } 
    683    ENodeType CField::GetType(void)    { return eField; } 
    684  
    685    //---------------------------------------------------------------- 
    686  
    687    CGrid* CField::getRelGrid(void) const 
    688    TRY 
    689    { 
    690       return this->grid; 
    691    } 
    692    CATCH 
    693  
    694    //---------------------------------------------------------------- 
    695  
    696    CFile* CField::getRelFile(void) const 
    697    TRY 
    698    { 
    699       return this->file; 
    700    } 
    701    CATCH 
    702  
    703    int CField::getNStep(void) const 
    704    TRY 
    705    { 
    706       return this->nstep; 
    707    } 
    708    CATCH 
    709  
    710    func::CFunctor::ETimeType CField::getOperationTimeType() const 
    711    TRY 
    712    { 
    713      return operationTimeType; 
    714    } 
    715    CATCH 
    716  
    717    //---------------------------------------------------------------- 
    718  
    719    void CField::incrementNStep(void) 
    720    TRY 
    721    { 
    722       this->nstep++; 
    723    } 
    724    CATCH_DUMP_ATTR 
    725  
    726    void CField::resetNStep(int nstep /*= 0*/) 
    727    TRY 
    728    { 
    729       this->nstep = nstep; 
    730    } 
    731    CATCH_DUMP_ATTR 
    732  
    733    void CField::resetNStepMax(void) 
    734    TRY 
    735    { 
    736       this->nstepMax = 0; 
    737       nstepMaxRead = false; 
    738    } 
    739    CATCH_DUMP_ATTR 
    740  
    741    //---------------------------------------------------------------- 
    742  
    743    bool CField::isActive(bool atCurrentTimestep /*= false*/) const 
    744    TRY 
    745    { 
    746       if (clientSourceFilter) 
    747         return atCurrentTimestep ? clientSourceFilter->isDataExpected(CContext::getCurrent()->getCalendar()->getCurrentDate()) : true; 
    748       else if (storeFilter) 
    749         return true; 
    750       else if (instantDataFilter) 
    751         ERROR("bool CField::isActive(bool atCurrentTimestep)", 
    752               << "Impossible to check if field [ id = " << getId() << " ] is active as it cannot be used to receive nor send data."); 
    753  
    754       return false; 
    755    } 
    756    CATCH 
    757  
    758    //---------------------------------------------------------------- 
    759  
    760    bool CField::wasWritten() const 
    761    TRY 
    762    { 
    763      return written; 
    764    } 
    765    CATCH 
    766  
    767    void CField::setWritten() 
    768    TRY 
    769    { 
    770      written = true; 
    771    } 
    772    CATCH_DUMP_ATTR 
    773  
    774    //---------------------------------------------------------------- 
    775  
    776    bool CField::getUseCompressedOutput() const 
    777    TRY 
    778    { 
    779      return useCompressedOutput; 
    780    } 
    781    CATCH 
    782  
    783    void CField::setUseCompressedOutput() 
    784    TRY 
    785    { 
    786      useCompressedOutput = true; 
    787    } 
    788    CATCH_DUMP_ATTR 
    789  
    790    //---------------------------------------------------------------- 
    791  
    792    std::shared_ptr<COutputPin> CField::getInstantDataFilter() 
    793    TRY 
    794    { 
    795      return instantDataFilter; 
    796    } 
    797    CATCH_DUMP_ATTR 
    798  
    799    //---------------------------------------------------------------- 
    800  
    801    /*! 
    802      Build up graph of grids which plays role of destination and source in grid transformation 
    803      This function should be called before \func solveGridReference() 
     625        lastFilter = filters.second; 
     626        gridSrc = newGrid ; 
     627 
     628        // end new 
     629      } 
     630 
     631      grid_=newGrid ; 
     632      grid_ref=grid_->getId() ; // for server  
     633      instantDataFilter = lastFilter ; 
     634       
     635      // connect the input Filter to the reference 
     636      getDirectFieldReference()->getInstantDataFilter()->connectOutput(inputFilter,0); 
     637      if(buildGraph_)  
     638      { 
     639        std::cout<<"============== field "<<this->getId()<<" calls a transformation filter 2 ============== "<<getDirectFieldReference()->getInstantDataFilter()<<" _ "<<inputFilter<<" ***** "<<CXios::isClient<<std::endl; 
     640        inputFilter->graphEnabled=true; 
     641        inputFilter->graphPackage = new CGraphPackage; 
     642        inputFilter->graphPackage->inFields.push_back(this); 
     643      } 
     644    } 
     645    else  
     646    { 
     647      if (hasFileIn()) // input file, attemp to read the grid from file 
     648      { 
     649         // must be checked 
     650         fileIn_->initRead() ; 
     651         fileIn_->checkReadFile(); 
     652         grid_->solveElementsRefInheritance() ; 
     653         if (fileIn_->isClientSide()) fileIn_->readFieldAttributesMetaData(this); 
     654         CGrid* newGrid ; 
     655         std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = grid_->buildTransformationGraph(gc, true, nullptr, detectMissingValues, defaultValue, newGrid, buildGraph_) ; 
     656         grid_ = newGrid ; 
     657         grid_ref=grid_->getId() ; // for server  
     658         if (fileIn_->isClientSide()) fileIn_->readFieldAttributesValues(this); 
     659         grid_->checkElementsAttributes() ; 
     660         // probably in future tag grid incomplete if coming from a reading 
     661         instantDataFilter=inputFilter ; 
     662      }   
     663      else if (hasCouplerIn()) 
     664      { 
     665        grid_->checkElementsAttributes() ; 
     666        instantDataFilter=inputFilter ; 
     667      } 
     668      else 
     669      { 
     670        setModelIn() ; // no reference, the field is potentially a source field from model 
     671 
     672        grid_->solveElementsRefInheritance() ; 
     673        CGrid* newGrid ; 
     674        std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = grid_->buildTransformationGraph(gc, true, nullptr, detectMissingValues, defaultValue, newGrid, buildGraph_) ; 
     675        newGrid->duplicateAttributes(grid_) ; // for grid attributes (mask) 
     676        grid_ = newGrid ; 
     677        grid_ref=grid_->getId() ; // for server  
     678        grid_->checkElementsAttributes() ; 
     679        instantDataFilter=inputFilter ; 
     680      } 
     681    } 
     682     
     683    if (hasFileOut()) 
     684    { 
     685      if (fileOut_->isServerSide()) 
     686      { 
     687        this->solveServerOperation() ; 
     688      } 
     689    } 
     690 
     691    buildWorkflowGraphDone_ = true ; 
     692    workflowEnabled_ = true ; 
     693    return true ; 
     694  } 
     695    
     696  /*! 
     697   * Connect field to filter to send data to server. A temporal filter is inserted before accordingly to the  
     698   * output frequency of the file 
     699   * \param gc the garbage collector to use when building the filter graph 
    804700   */ 
    805    void CField::buildGridTransformationGraph() 
    806    TRY 
    807    { 
    808      CContext* context = CContext::getCurrent(); 
    809      if (context->hasClient && !context->hasServer) 
    810      { 
    811        if (grid && !grid->isTransformed() && hasDirectFieldReference() && grid != getDirectFieldReference()->grid) 
    812        { 
    813          grid->addTransGridSource(getDirectFieldReference()->grid); 
    814        } 
    815      } 
    816    } 
    817    CATCH_DUMP_ATTR 
    818  
    819    /*! 
    820      Generate a new grid destination if there are more than one grid source pointing to a same grid destination 
     701  void CField::connectToFileServer(CGarbageCollector& gc) 
     702  { 
     703    // insert temporal filter before sending to files 
     704    clientToServerStoreFilter_ = std::shared_ptr<CClientToServerStoreFilter>(new CClientToServerStoreFilter(gc, this, client)); 
     705    // insert temporal filter before sending to files 
     706    getTemporalDataFilter(gc, fileOut_->output_freq)->connectOutput(clientToServerStoreFilter_, 0); 
     707    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     708    if(buildGraph_)  
     709    { 
     710      std::cout<<"============== field "<<this->getId()<<" calls a connectToFileServer  ============== "<<getTemporalDataFilter(gc, fileOut_->output_freq)<<" _ "<<clientToServerStoreFilter_<<" ***** "<<CXios::isClient<<std::endl; 
     711      clientToServerStoreFilter_->graphPackage = new CGraphPackage; 
     712      clientToServerStoreFilter_->graphEnabled = true; 
     713      clientToServerStoreFilter_->graphPackage->inFields.push_back(this); 
     714    } 
     715  }  
     716 
     717  void CField::connectToCouplerOut(CGarbageCollector& gc) 
     718  { 
     719    // insert temporal filter before sending to files 
     720    clientToServerStoreFilter_ = std::shared_ptr<CClientToServerStoreFilter>(new CClientToServerStoreFilter(gc, this, client)); 
     721    instantDataFilter->connectOutput(clientToServerStoreFilter_, 0); 
     722    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     723    if(buildGraph_)  
     724    { 
     725      std::cout<<"============== field "<<this->getId()<<" calls a connectToCouplerOut  ============== "<<instantDataFilter<<" _ "<<clientToServerStoreFilter_<<" ***** "<<CXios::isClient<<std::endl; 
     726      clientToServerStoreFilter_->graphPackage = new CGraphPackage; 
     727      clientToServerStoreFilter_->graphEnabled = true; 
     728      clientToServerStoreFilter_->graphPackage->inFields.push_back(this); 
     729    } 
     730  }  
     731 
     732  
     733  /*! 
     734   * Connect field to a source filter to receive data from model. 
    821735   */ 
    822    void CField::generateNewTransformationGridDest() 
    823    TRY 
    824    { 
    825      CContext* context = CContext::getCurrent(); 
    826      if (context->hasClient && !context->hasServer) 
    827      { 
    828        std::map<CGrid*,std::pair<bool,StdString> >& gridSrcMap = grid->getTransGridSource(); 
    829        if (1 < gridSrcMap.size()) 
    830        { 
    831          // Search for grid source 
    832          CGrid* gridSrc = grid; 
    833          CField* currField = this; 
    834          std::vector<CField*> hieraField; 
    835  
    836          while (currField->hasDirectFieldReference() && (gridSrc == grid)) 
    837          { 
    838            hieraField.push_back(currField); 
    839            CField* tmp = currField->getDirectFieldReference(); 
    840            currField = tmp; 
    841            gridSrc = currField->grid; 
    842          } 
    843  
    844          if (gridSrcMap.end() != gridSrcMap.find(gridSrc)) 
    845          { 
    846            CGrid* gridTmp; 
    847            std::pair<bool,StdString> newGridDest = gridSrcMap[gridSrc]; 
    848            if (newGridDest.first) 
    849            { 
    850              StdString newIdGridDest = newGridDest.second; 
    851              if (!CGrid::has(newIdGridDest)) 
    852              { 
    853                 ERROR("CGrid* CGrid::generateNewTransformationGridDest()", 
    854                   << " Something wrong happened! Grid whose id " << newIdGridDest 
    855                   << "should exist "); 
    856              } 
    857              gridTmp = CGrid::get(newIdGridDest); 
    858            } 
    859            else 
    860            { 
    861              StdString newIdGridDest = CGrid::generateId(gridSrc, grid); 
    862              gridTmp = CGrid::cloneGrid(newIdGridDest, grid); 
    863  
    864              (gridSrcMap[gridSrc]).first = true; 
    865              (gridSrcMap[gridSrc]).second = newIdGridDest; 
    866            } 
    867  
    868            // Update all descendants 
    869            for (std::vector<CField*>::iterator it = hieraField.begin(); it != hieraField.end(); ++it) 
    870            { 
    871              (*it)->grid = gridTmp; 
    872              (*it)->updateRef((*it)->grid); 
    873            } 
    874          } 
    875        } 
    876      } 
    877    } 
    878    CATCH_DUMP_ATTR 
    879  
    880    void CField::updateRef(CGrid* grid) 
    881    TRY 
    882    { 
    883      if (!grid_ref.isEmpty()) grid_ref.setValue(grid->getId()); 
    884      else 
    885      { 
    886        std::vector<CAxis*> axisTmp = grid->getAxis(); 
    887        std::vector<CDomain*> domainTmp = grid->getDomains(); 
    888        if ((1<axisTmp.size()) || (1<domainTmp.size())) 
    889          ERROR("void CField::updateRef(CGrid* grid)", 
    890            << "More than one domain or axis is available for domain_ref/axis_ref of field " << this->getId()); 
    891  
    892        if ((!domain_ref.isEmpty()) && (domainTmp.empty())) 
    893          ERROR("void CField::updateRef(CGrid* grid)", 
    894            << "Incoherent between available domain and domain_ref of field " << this->getId()); 
    895        if ((!axis_ref.isEmpty()) && (axisTmp.empty())) 
    896          ERROR("void CField::updateRef(CGrid* grid)", 
    897            << "Incoherent between available axis and axis_ref of field " << this->getId()); 
    898  
    899        if (!domain_ref.isEmpty()) domain_ref.setValue(domainTmp[0]->getId()); 
    900        if (!axis_ref.isEmpty()) axis_ref.setValue(axisTmp[0]->getId()); 
    901      } 
    902    } 
    903    CATCH_DUMP_ATTR 
    904     
    905    /*! 
    906      Solve reference of all enabled fields even the source fields . 
    907      In this step, we do transformations. 
     736  void CField::connectToModelInput(CGarbageCollector& gc) 
     737  { 
     738    const bool detectMissingValues = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
     739    const double defaultValue  = detectMissingValues ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
     740 
     741    if (check_if_active.isEmpty()) check_if_active = false;  
     742    modelToClientSourceFilter_ = std::shared_ptr<CModelToClientSourceFilter>(new CModelToClientSourceFilter(gc, grid_, detectMissingValues, defaultValue)); 
     743    modelToClientSourceFilter_ -> connectOutput(inputFilter,0) ; 
     744    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     745    if(buildGraph_ )  
     746    { 
     747      std::cout<<"============== field "<<this->getId()<<" calls a connectToModelInput  ============== "<<modelToClientSourceFilter_<<" _ "<<inputFilter<<" ***** "<<CXios::isClient<<std::endl; 
     748      modelToClientSourceFilter_->graphPackage = new CGraphPackage; 
     749      modelToClientSourceFilter_->graphEnabled = true; 
     750      modelToClientSourceFilter_->graphPackage->inFields.push_back(this); 
     751    } 
     752  }  
     753  
     754  /*! 
     755   * Connect field to a source filter to receive data from a client (on server side). 
    908756   */ 
    909    void CField::solveAllEnabledFieldsAndTransform() 
    910    TRY 
    911    { 
    912      CContext* context = CContext::getCurrent(); 
    913      bool hasClient = context->hasClient; 
    914      bool hasServer = context->hasServer; 
    915  
    916      if (!isReferenceSolvedAndTransformed) 
    917      { 
    918         isReferenceSolvedAndTransformed = true; 
    919  
    920         if (hasClient && !hasServer) 
     757  void CField::connectToClientInput(CGarbageCollector& gc) 
     758  { 
     759    serverFromClientSourceFilter_ = std::shared_ptr<CServerFromClientSourceFilter>(new CServerFromClientSourceFilter(gc,  grid_)); 
     760    serverFromClientSourceFilter_ -> connectOutput(inputFilter,0) ; 
     761    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     762    if(buildGraph_) 
     763    { 
     764      std::cout<<"============== field "<<this->getId()<<" calls a connectToClientInput  ============== "<<serverFromClientSourceFilter_ << " _ "<<inputFilter<<" ***** "<<CXios::isClient<<std::endl; 
     765      serverFromClientSourceFilter_->graphPackage = new CGraphPackage; 
     766      serverFromClientSourceFilter_->graphEnabled = true; 
     767      serverFromClientSourceFilter_->graphPackage->inFields.push_back(this); 
     768    } 
     769  }  
     770 
     771 
     772  /*! 
     773   * Connect field to a source filter to receive data from a server (on client side). 
     774   */ 
     775  void CField::connectToServerInput(CGarbageCollector& gc) 
     776  { 
     777    checkTimeAttributes(); 
     778    clientFromServerSourceFilter_ = std::shared_ptr<CClientFromServerSourceFilter>(new CClientFromServerSourceFilter(gc,this)) ; 
     779    clientFromServerSourceFilter_ -> connectOutput(inputFilter,0) ; 
     780    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     781    if(buildGraph_) 
     782    { 
     783      std::cout<<"============== field "<<this->getId()<<" calls a connectToServerInput  ============== "<<clientFromServerSourceFilter_ << " _ "<<inputFilter<<" ***** "<<CXios::isClient<<std::endl; 
     784      clientFromServerSourceFilter_->graphPackage = new CGraphPackage; 
     785      clientFromServerSourceFilter_->graphEnabled = true; 
     786      clientFromServerSourceFilter_->graphPackage->inFields.push_back(this); 
     787    } 
     788  }  
     789 
     790  /*! 
     791   * Connect field to a source filter to receive data from coupler (on client side). 
     792   */ 
     793   void CField::connectToCouplerIn(CGarbageCollector& gc) 
     794  { 
     795    CContext* context = CContext::getCurrent(); 
     796 
     797    if (freq_op.isEmpty()) freq_op.setValue(TimeStep); 
     798    if (freq_offset.isEmpty()) freq_offset.setValue(freq_op.getValue() - TimeStep); 
     799    clientFromClientSourceFilter_ = std::shared_ptr<CClientFromClientSourceFilter>(new CClientFromClientSourceFilter(gc, this)) ; 
     800    clientFromClientSourceFilter_ -> connectOutput(inputFilter,0) ; 
     801    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     802    if(buildGraph_) 
     803    { 
     804      std::cout<<"============== field "<<this->getId()<<" calls a connectToCouplerIn  ============== "<<clientFromClientSourceFilter_ << " _ "<<inputFilter<<" ***** "<<CXios::isClient<<std::endl; 
     805      clientFromClientSourceFilter_->graphPackage = new CGraphPackage; 
     806      clientFromClientSourceFilter_->graphEnabled = true; 
     807      clientFromClientSourceFilter_->graphPackage->inFields.push_back(this); 
     808    } 
     809  }  
     810 
     811  /*! 
     812   * Connect field to a file writer filter to write data in file (on server side). 
     813   */ 
     814  void CField::connectToFileWriter(CGarbageCollector& gc) 
     815  { 
     816    fileWriterStoreFilter_ = std::shared_ptr<CFileWriterStoreFilter>(new CFileWriterStoreFilter(gc, this)); 
     817    instantDataFilter->connectOutput(fileWriterStoreFilter_, 0); 
     818    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     819    if(buildGraph_) 
     820    { 
     821      std::cout<<"============== field "<<this->getId()<<" calls a connectToFileWriter  ============== "<<instantDataFilter << " _ "<<fileWriterStoreFilter_<<" ***** "<<CXios::isClient<<std::endl; 
     822      fileWriterStoreFilter_->graphPackage = new CGraphPackage; 
     823      fileWriterStoreFilter_->graphEnabled = true; 
     824      fileWriterStoreFilter_->graphPackage->inFields.push_back(this); 
     825    } 
     826  }  
     827 
     828  /*! 
     829   * Connect field to a file reader filter to read data from file (on server side). 
     830   */ 
     831  void CField::connectToFileReader(CGarbageCollector& gc) 
     832  { 
     833    fileReaderSourceFilter_ = std::shared_ptr<CFileReaderSourceFilter>(new CFileReaderSourceFilter(gc, this)); 
     834    fileReaderSourceFilter_->connectOutput(inputFilter, 0); 
     835    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     836    if(buildGraph_) 
     837    { 
     838      std::cout<<"============== field "<<this->getId()<<" calls a connectToFileReader  ============== "<<fileReaderSourceFilter_ << " _ "<<inputFilter<<" ***** "<<CXios::isClient<<std::endl; 
     839      fileReaderSourceFilter_->graphPackage = new CGraphPackage; 
     840      fileReaderSourceFilter_->graphEnabled = true; 
     841      fileReaderSourceFilter_->graphPackage->inFields.push_back(this); 
     842    } 
     843  } 
     844 
     845 
     846  /*! 
     847   * Connect field to a store filter to output data to model on client Side 
     848   */ 
     849  void CField::connectToModelOutput(CGarbageCollector& gc) 
     850  { 
     851    clientToModelStoreFilter_ = std::shared_ptr<CClientToModelStoreFilter>(new CClientToModelStoreFilter(gc, this)); 
     852    instantDataFilter->connectOutput(clientToModelStoreFilter_, 0); 
     853    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     854    if(buildGraph_) 
     855    { 
     856      std::cout<<"============== field "<<this->getId()<<" calls a connectToModelOutput  ============== "<<instantDataFilter << " _ "<<clientToModelStoreFilter_<<" ***** "<<CXios::isClient<<std::endl; 
     857      clientToModelStoreFilter_->graphPackage = new CGraphPackage; 
     858      clientToModelStoreFilter_->graphEnabled = true; 
     859      clientToModelStoreFilter_->graphPackage->inFields.push_back(this); 
     860    } 
     861  } 
     862 
     863 
     864  
     865  void CField::connectToServerToClient(CGarbageCollector& gc) 
     866  { 
     867    serverToClientStoreFilter_ = std::shared_ptr<CServerToClientStoreFilter>(new CServerToClientStoreFilter(gc, this, client)); 
     868    instantDataFilter->connectOutput(serverToClientStoreFilter_, 0); 
     869    const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     870    if(buildGraph_) 
     871    { 
     872      std::cout<<"============== field "<<this->getId()<<" calls a connectToServerToClient  ============== "<<instantDataFilter << " _ "<<serverToClientStoreFilter_<<" ***** "<<CXios::isClient<<std::endl; 
     873      serverToClientStoreFilter_->graphPackage = new CGraphPackage; 
     874      serverToClientStoreFilter_->graphEnabled = true; 
     875      serverToClientStoreFilter_->graphPackage->inFields.push_back(this); 
     876    } 
     877  } 
     878 
     879  /*! 
     880   * Transform the grid_path attribut into vector of grid. 
     881   * \return the vector CGrid* containing the list of grid path for tranformation 
     882   */  
     883  vector<CGrid*> CField::getGridPath(void) 
     884  { 
     885    std::vector<CGrid*> gridPath; 
     886 
     887    if (hasDirectFieldReference() && grid_ != getDirectFieldReference()->grid_) 
     888    { 
     889      if (!grid_path.isEmpty()) 
     890      { 
     891        std::string gridId; 
     892        size_t start = 0, end; 
     893 
     894        do 
    921895        { 
    922           solveRefInheritance(true); 
    923           if (hasDirectFieldReference()) getDirectFieldReference()->solveAllEnabledFieldsAndTransform(); 
     896          end = grid_path.getValue().find(',', start); 
     897          if (end != std::string::npos) 
     898          { 
     899            gridId = grid_path.getValue().substr(start, end - start); 
     900            start = end + 1; 
     901          } 
     902          else gridId = grid_path.getValue().substr(start); 
     903 
     904          if (!CGrid::has(gridId)) 
     905            ERROR("void CField::solveTransformedGrid()", 
     906               << "Invalid grid_path, the grid '" << gridId << "' does not exist."); 
     907 
     908          gridPath.push_back(CGrid::get(gridId)); 
    924909        } 
    925  
    926         if (hasServer) 
    927           solveServerOperation(); 
    928  
    929         solveGridReference(); 
    930  
    931         if (hasClient && !hasServer) 
    932        { 
    933          solveGenerateGrid(); 
    934          buildGridTransformationGraph(); 
    935        } 
    936  
    937        solveGridDomainAxisRef(false); 
    938  
    939        if (hasClient && !hasServer) 
    940        { 
    941          solveTransformedGrid(); 
    942        } 
    943  
    944        solveGridDomainAxisRef(false); 
    945      } 
    946    } 
    947    CATCH_DUMP_ATTR 
    948  
    949    void CField::checkGridOfEnabledFields() 
    950    TRY 
    951    { 
    952      if (!isGridChecked) 
    953      { 
    954        isGridChecked = true; 
    955        solveCheckMaskIndex(false); 
    956      } 
    957    } 
    958    CATCH_DUMP_ATTR 
    959  
    960    void CField::sendGridComponentOfEnabledFields() 
    961    TRY 
    962    { 
    963       solveGridDomainAxisRef(true); 
    964       // solveCheckMaskIndex(true); 
    965    } 
    966    CATCH_DUMP_ATTR 
    967  
    968    void CField::sendGridOfEnabledFields() 
    969    TRY 
    970    { 
    971       // solveGridDomainAxisRef(true); 
    972       solveCheckMaskIndex(true); 
    973    }    
    974    CATCH_DUMP_ATTR 
    975  
    976    void CField::solveOnlyReferenceEnabledField(bool doSending2Server) 
    977    TRY 
    978    { 
    979      CContext* context = CContext::getCurrent(); 
    980      if (!isReferenceSolved) 
    981      { 
    982         isReferenceSolved = true; 
    983  
    984         if (context->hasClient && !context->hasServer) 
    985         { 
    986           solveRefInheritance(true); 
    987           if (hasDirectFieldReference()) getDirectFieldReference()->solveOnlyReferenceEnabledField(false); 
    988         } 
    989  
    990         if (context->hasServer) 
    991           solveServerOperation(); 
    992  
    993         solveGridReference(); 
    994         grid->solveDomainAxisRefInheritance(true); // make it again to solve grid reading from file 
    995  
    996         if (context->hasClient && !context->hasServer) 
    997        { 
    998          solveGenerateGrid(); 
    999          buildGridTransformationGraph(); 
    1000        } 
    1001      } 
    1002    } 
    1003    CATCH_DUMP_ATTR 
    1004  
    1005    void CField::solveAllReferenceEnabledField(bool doSending2Server) 
    1006    TRY 
    1007    { 
    1008      CContext* context = CContext::getCurrent(); 
    1009      solveOnlyReferenceEnabledField(doSending2Server); 
    1010  
    1011      if (!areAllReferenceSolved) 
    1012      { 
    1013         areAllReferenceSolved = true; 
    1014         
    1015         if (context->hasClient && !context->hasServer) 
    1016         { 
    1017           solveRefInheritance(true); 
    1018           if (hasDirectFieldReference()) getDirectFieldReference()->solveAllReferenceEnabledField(false); 
    1019         } 
    1020         else if (context->hasServer) 
    1021           solveServerOperation(); 
    1022  
    1023         solveGridReference(); 
    1024      } 
    1025  
    1026      solveGridDomainAxisRef(doSending2Server); 
    1027  
    1028      if (context->hasClient && !context->hasServer) 
    1029      { 
    1030        solveTransformedGrid(); 
    1031      } 
    1032  
    1033      solveCheckMaskIndex(doSending2Server); 
    1034    } 
    1035    CATCH_DUMP_ATTR 
    1036  
    1037    std::map<int, StdSize> CField::getGridAttributesBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/) 
    1038    TRY 
    1039    { 
    1040      return grid->getAttributesBufferSize(client, bufferForWriting); 
    1041    } 
    1042    CATCH_DUMP_ATTR 
    1043  
    1044    std::map<int, StdSize> CField::getGridDataBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/) 
    1045    TRY 
    1046    { 
    1047      return grid->getDataBufferSize(client, getId(), bufferForWriting); 
    1048    } 
    1049    CATCH_DUMP_ATTR 
    1050  
    1051    size_t CField::getGlobalWrittenSize() 
    1052    TRY 
    1053    { 
    1054      return grid->getGlobalWrittenSize(); 
    1055    } 
    1056    CATCH_DUMP_ATTR 
    1057  
    1058    //---------------------------------------------------------------- 
    1059  
    1060    void CField::solveServerOperation(void) 
    1061    TRY 
    1062    { 
    1063       CContext* context = CContext::getCurrent(); 
    1064  
    1065       if (!context->hasServer || !hasOutputFile) return; 
    1066  
    1067       if (freq_op.isEmpty()) 
    1068         freq_op.setValue(TimeStep); 
    1069  
    1070       if (freq_offset.isEmpty()) 
    1071         freq_offset.setValue(NoneDu); 
    1072  
    1073       freq_operation_srv = file->output_freq.getValue(); 
    1074       freq_write_srv     = file->output_freq.getValue(); 
    1075  
    1076       lastlast_Write_srv = context->getCalendar()->getInitDate(); 
    1077       last_Write_srv     = context->getCalendar()->getInitDate(); 
    1078       last_operation_srv = context->getCalendar()->getInitDate(); 
    1079  
    1080       const CDuration toffset = freq_operation_srv - freq_offset.getValue() - context->getCalendar()->getTimeStep(); 
    1081       last_operation_srv     = last_operation_srv - toffset; 
    1082  
     910        while (end != std::string::npos); 
     911      } 
     912    } 
     913    return gridPath ; 
     914  } 
     915 
     916   
     917   
     918  /*! 
     919   * Returns the filter needed to handle a self reference in the field's expression. 
     920   * If the needed filter does not exist, it is created, otherwise it is reused. 
     921   * This method should only be called when building the filter graph corresponding 
     922   * to the field's expression. 
     923   * 
     924   * \param gc the garbage collector to use 
     925   * \return the output pin corresponding to a self reference 
     926   */ 
     927  std::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc) 
     928  TRY 
     929  { 
     930    return inputFilter ; 
     931  }  
     932  CATCH_DUMP_ATTR 
     933 
     934  /*! 
     935   * Returns the temporal filter corresponding to the field's temporal operation 
     936   * for the specified operation frequency. The filter is created if it does not 
     937   * exist, otherwise it is reused. 
     938   * 
     939   * \param gc the garbage collector to use 
     940   * \param outFreq the operation frequency, i.e. the frequency at which the output data will be computed 
     941   * \return the output pin corresponding to the requested temporal filter 
     942   */ 
     943  std::shared_ptr<COutputPin> CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq) 
     944  TRY 
     945  { 
     946    std::map<CDuration, std::shared_ptr<COutputPin> >::iterator it = temporalDataFilters.find(outFreq); 
     947 
     948    if (it == temporalDataFilters.end()) 
     949    { 
    1083950      if (operation.isEmpty()) 
    1084         ERROR("void CField::solveServerOperation(void)", 
     951        ERROR("void CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)", 
    1085952              << "An operation must be defined for field \"" << getId() << "\"."); 
    1086953 
    1087       std::shared_ptr<func::CFunctor> functor; 
    1088       CArray<double, 1> dummyData; 
    1089  
    1090 #define DECLARE_FUNCTOR(MType, mtype) \ 
    1091       if (operation.getValue().compare(#mtype) == 0) \ 
    1092       { \ 
    1093         functor.reset(new func::C##MType(dummyData)); \ 
    1094       } 
    1095  
    1096 #include "functor_type.conf" 
    1097  
    1098       if (!functor) 
    1099         ERROR("void CField::solveServerOperation(void)", 
    1100               << "\"" << operation << "\" is not a valid operation."); 
    1101  
    1102       operationTimeType = functor->timeType(); 
    1103    } 
    1104    CATCH_DUMP_ATTR 
    1105  
    1106    //---------------------------------------------------------------- 
    1107  
    1108    /*! 
    1109     * Constructs the graph filter for the field, enabling or not the data output. 
    1110     * This method should not be called more than once with enableOutput equal to true. 
    1111     * 
    1112     * \param gc the garbage collector to use when building the filter graph 
    1113     * \param enableOutput must be true when the field data is to be 
    1114     *                     read by the client or/and written to a file 
    1115     */ 
    1116    void CField::buildFilterGraph(CGarbageCollector& gc, bool enableOutput, Time start_graph, Time end_graph) 
    1117    TRY 
    1118    {      
    1119      if (!isReferenceSolvedAndTransformed) solveAllEnabledFieldsAndTransform(); 
    1120      if (!isGridChecked) checkGridOfEnabledFields(); 
    1121  
    1122      const bool detectMissingValues = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    1123       
    1124      const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 
    1125  
    1126       
    1127      const double defaultValue  = detectMissingValues ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
    1128  
    1129      CContext* context = CContext::getCurrent(); 
    1130       
    1131      Time filter_start; 
    1132      if(!build_workflow_graph_start.isEmpty() && buildWorkflowGraph) filter_start = context->calendar->getInitDate()+build_workflow_graph_start; 
    1133      else if(build_workflow_graph_start.isEmpty() && buildWorkflowGraph) filter_start = 0; 
    1134      else filter_start = -1; 
    1135  
    1136      Time filter_end; 
    1137      if(!build_workflow_graph_end.isEmpty() && buildWorkflowGraph) filter_end = context->calendar->getInitDate()+build_workflow_graph_end; 
    1138      else if(build_workflow_graph_end.isEmpty() && buildWorkflowGraph) filter_end = 9223372036854775807; 
    1139      else filter_end = -1; 
    1140  
    1141      if(this->field_graph_start==-2) this->field_graph_start = filter_start; 
    1142      if(this->field_graph_end==-2) this->field_graph_end = filter_end;         // init 
    1143  
    1144      // if(CXios::isClient) std::cout<<"****************** buildFilterGraph : field_id = "<<this->getId()<<" BEFORE: this->field_graph_start = "<<this->field_graph_start<<" this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1145  
    1146      if(start_graph == -1) 
    1147      { 
    1148        //nothing 
    1149        // if(CXios::isClient) std::cout<<"buildFilterGraph field_id = "<<this->getId()<<" case1: this->field_graph_start = "<<this->field_graph_start<<std::endl; 
    1150      } 
    1151      else //if(start_graph != -1) 
    1152      { 
    1153        if(this->field_graph_start == -1) this->field_graph_start = start_graph; 
    1154        else this->field_graph_start = min(this->field_graph_start, start_graph); 
    1155  
    1156        // if(CXios::isClient) std::cout<<"buildFilterGraph field_id = "<<this->getId()<<" case2: this->field_graph_start = "<<this->field_graph_start<<std::endl; 
    1157      } 
    1158  
    1159  
    1160      if(end_graph == -1) 
    1161      { 
    1162        //nothing 
    1163        // if(CXios::isClient) std::cout<<"buildFilterGraph field_id = "<<this->getId()<<" case1: this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1164      } 
    1165      else 
    1166      { 
    1167        if(this->field_graph_end == -1) this->field_graph_end = end_graph; 
    1168        else this->field_graph_end = max(this->field_graph_end, end_graph); 
    1169  
    1170        // if(CXios::isClient) std::cout<<"buildFilterGraph field_id = "<<this->getId()<<" case2: this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1171      } 
    1172      
    1173  
    1174      filter_start = this->field_graph_start; 
    1175      filter_end = this->field_graph_end; 
    1176  
    1177  
    1178      // if(CXios::isClient) std::cout<<"****************** buildFilterGraph : field_id = "<<this->getId()<<" AFTER: this->field_graph_start = "<<this->field_graph_start<<" this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1179       
    1180  
    1181       
    1182       
    1183  
    1184      bool hasWriterServer = context->hasServer && !context->hasClient; 
    1185      bool hasIntermediateServer = context->hasServer && context->hasClient; 
    1186  
    1187      if (hasWriterServer) 
    1188      { 
    1189         if (!instantDataFilter) 
    1190           instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false)); 
    1191  
    1192  
    1193        // If the field data is to be read by the client or/and written to a file 
    1194        if (enableOutput && !storeFilter && !fileWriterFilter) 
    1195        { 
    1196          if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write)) 
    1197          { 
    1198            fileServerWriterFilter = std::shared_ptr<CFileServerWriterFilter>(new CFileServerWriterFilter(gc, this)); 
    1199            instantDataFilter->connectOutput(fileServerWriterFilter, 0); 
    1200          } 
    1201        } 
    1202      } 
    1203      else if (hasIntermediateServer) 
    1204      { 
    1205        if (!instantDataFilter) 
    1206          instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, false)); 
    1207  
    1208              // If the field data is to be read by the client or/and written to a file 
    1209        if (enableOutput && !storeFilter && !fileWriterFilter) 
    1210        { 
    1211          if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write)) 
    1212          { 
    1213            fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this)); 
    1214            instantDataFilter->connectOutput(fileWriterFilter, 0); 
    1215          } 
    1216        } 
    1217      } 
    1218      else 
    1219      { 
    1220        // Start by building a filter which can provide the field's instant data 
    1221        if (!instantDataFilter) 
    1222        { 
    1223          // Check if we have an expression to parse 
    1224          if (hasExpression()) 
    1225          { 
    1226            boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0')); 
    1227            std::shared_ptr<COutputPin> filter = expr->reduce(gc, *this, filter_start, filter_end); 
    1228  
    1229            // Check if a spatial transformation is needed 
    1230            if (!field_ref.isEmpty()) 
    1231            { 
    1232              CGrid* gridRef = CField::get(field_ref)->grid; 
    1233  
    1234              if (grid && grid != gridRef && grid->hasTransform()) 
    1235              { 
    1236                std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, detectMissingValues, defaultValue); 
    1237  
    1238                filter->connectOutput(filters.first, 0); 
    1239                filter = filters.second; 
    1240              } 
    1241            } 
    1242  
    1243            instantDataFilter = filter; 
    1244            instantDataFilter->field = this; 
    1245            filter->tag = buildWorkflowGraph; 
    1246             
    1247            filter->start_graph = filter_start; 
    1248            filter->end_graph = filter_end; 
    1249  
    1250            for(int i=0; i<filter->parent_filters.size(); i++) 
    1251            { 
    1252              filter->tag = filter->tag || filter->parent_filters[i]->tag; 
    1253            } 
    1254          } 
    1255          // Check if we have a reference on another field 
    1256          else if (!field_ref.isEmpty()) 
    1257          { 
    1258            instantDataFilter = getFieldReference(gc, filter_start, filter_end); 
    1259            instantDataFilter->tag = buildWorkflowGraph; 
    1260            instantDataFilter->start_graph = filter_start; 
    1261            instantDataFilter->end_graph = filter_end; 
    1262          } 
    1263          // Check if the data is to be read from a file 
    1264          else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read) 
    1265          { 
    1266            checkTimeAttributes(); 
    1267            instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 
    1268                                                                                                        detectMissingValues, defaultValue)); 
    1269            instantDataFilter->tag = buildWorkflowGraph; 
    1270            instantDataFilter->start_graph = filter_start; 
    1271            instantDataFilter->end_graph = filter_end; 
    1272            instantDataFilter->field = this; 
    1273  
    1274          } 
    1275          else // The data might be passed from the model 
    1276          { 
    1277             if (check_if_active.isEmpty()) check_if_active = false;  
    1278             instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false, 
    1279                                                                                                       detectMissingValues, defaultValue));  
    1280             instantDataFilter->tag = buildWorkflowGraph; 
    1281             instantDataFilter->start_graph = filter_start; 
    1282             instantDataFilter->end_graph = filter_end; 
    1283             instantDataFilter->field = this; 
    1284             // if(CXios::isClient) std::cout<<"***********************buildFilterGraph init source filter : field_id = "<<this->getId()<<" sourcefilter->start_graph = "<<clientSourceFilter->start_graph<<" sourcefilter->end_graph = "<<clientSourceFilter->end_graph<<std::endl; 
    1285          } 
    1286        } 
    1287  
    1288        // If the field data is to be read by the client or/and written to a file 
    1289        if (enableOutput && !storeFilter && !fileWriterFilter) 
    1290        { 
    1291          if (!read_access.isEmpty() && read_access) 
    1292          { 
    1293            storeFilter = std::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid, 
    1294                                                                           detectMissingValues, defaultValue)); 
    1295            instantDataFilter->connectOutput(storeFilter, 0); 
    1296  
    1297            storeFilter->tag = (instantDataFilter->tag || buildWorkflowGraph); 
    1298            instantDataFilter->start_graph = filter_start; 
    1299            instantDataFilter->end_graph = filter_end; 
    1300  
    1301            instantDataFilter->setParentFiltersTag(); 
    1302            storeFilter->start_graph = filter_start; 
    1303            storeFilter->end_graph = filter_end; 
    1304            storeFilter->field = this; 
    1305            storeFilter->distance = instantDataFilter->distance+1; 
    1306          } 
    1307  
    1308          if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write)) 
    1309          { 
    1310            fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this)); 
    1311            getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0); 
    1312             
    1313            fileWriterFilter->tag = (getTemporalDataFilter(gc, file->output_freq)->tag || buildWorkflowGraph); 
    1314            getTemporalDataFilter(gc, file->output_freq)->start_graph = filter_start; 
    1315            getTemporalDataFilter(gc, file->output_freq)->end_graph = filter_end; 
    1316            getTemporalDataFilter(gc, file->output_freq)->tag = buildWorkflowGraph; 
    1317            getTemporalDataFilter(gc, file->output_freq)->setParentFiltersTag(); 
    1318            fileWriterFilter->start_graph = filter_start; 
    1319            fileWriterFilter->end_graph = filter_end; 
    1320            fileWriterFilter->distance = getTemporalDataFilter(gc, file->output_freq)->distance+1; 
    1321  
    1322            // std::cout<<"CFileWriterFilter filter start = "<<filter_start<<" end = "<<filter_end<<" field = "<<this->getId()<<std::endl; 
    1323  
    1324          } 
    1325        } 
    1326      } 
    1327    } 
    1328    CATCH_DUMP_ATTR 
    1329  
    1330    /*! 
    1331     * Returns the filter needed to handle the field reference. 
    1332     * This method should only be called when building the filter graph corresponding to the field. 
    1333     * 
    1334     * \param gc the garbage collector to use 
    1335     * \return the output pin corresponding to the field reference 
    1336     */ 
    1337    std::shared_ptr<COutputPin> CField::getFieldReference(CGarbageCollector& gc, Time start_graph, Time end_graph) 
    1338    TRY 
    1339    { 
    1340      if (instantDataFilter || field_ref.isEmpty()) 
    1341        ERROR("COutputPin* CField::getFieldReference(CGarbageCollector& gc)", 
    1342              "Impossible to get the field reference for a field which has already been parsed or which does not have a field_ref."); 
    1343  
    1344      CField* fieldRef = CField::get(field_ref); 
    1345      fieldRef->buildFilterGraph(gc, false, start_graph, end_graph); 
    1346      const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 
    1347  
    1348      CContext* context = CContext::getCurrent(); 
    1349  
    1350      Time filter_start; 
    1351      if(!build_workflow_graph_start.isEmpty() && buildWorkflowGraph) filter_start = context->calendar->getInitDate()+build_workflow_graph_start; 
    1352      else if(build_workflow_graph_start.isEmpty() && buildWorkflowGraph) filter_start = 0; 
    1353      else filter_start = -1; 
    1354  
    1355      Time filter_end; 
    1356      if(!build_workflow_graph_end.isEmpty() && buildWorkflowGraph) filter_end = context->calendar->getInitDate()+build_workflow_graph_end; 
    1357      else if(build_workflow_graph_end.isEmpty() && buildWorkflowGraph) filter_end = 9223372036854775807; 
    1358      else filter_end = -1; 
    1359  
    1360      if(this->field_graph_start==-2) this->field_graph_start = filter_start; 
    1361      if(this->field_graph_end==-2) this->field_graph_end = filter_end;         // init 
    1362  
    1363      // if(CXios::isClient) std::cout<<"getFieldReference field_id = "<<this->getId()<<" BEFORE: this->field_graph_start = "<<this->field_graph_start<<" this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1364  
    1365      if(start_graph == -1) 
    1366      { 
    1367        //nothing 
    1368        // if(CXios::isClient) std::cout<<"getFieldReference field_id = "<<this->getId()<<" case1: this->field_graph_start = "<<this->field_graph_start<<std::endl; 
    1369      } 
    1370      else //if(start_graph != -1) 
    1371      { 
    1372        if(this->field_graph_start == -1) this->field_graph_start = start_graph; 
    1373        else this->field_graph_start = min(this->field_graph_start, start_graph); 
    1374  
    1375        // if(CXios::isClient) std::cout<<"getFieldReference field_id = "<<this->getId()<<" case2: this->field_graph_start = "<<this->field_graph_start<<std::endl; 
    1376      } 
    1377  
    1378      if(end_graph == -1) 
    1379      { 
    1380        //nothing 
    1381        // if(CXios::isClient) std::cout<<"getFieldReference field_id = "<<this->getId()<<" case1: this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1382      } 
    1383      else 
    1384      { 
    1385        if(this->field_graph_end == -1) this->field_graph_end = end_graph; 
    1386        else this->field_graph_end = max(this->field_graph_end, end_graph); 
    1387  
    1388        // if(CXios::isClient) std::cout<<"getFieldReference field_id = "<<this->getId()<<" case2: this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1389      } 
    1390  
    1391      filter_start = this->field_graph_start; 
    1392      filter_end = this->field_graph_end; 
    1393  
    1394      // if(CXios::isClient) std::cout<<"getFieldReference field_id = "<<this->getId()<<" AFTER: this->field_graph_start = "<<this->field_graph_start<<" this->field_graph_end = "<<this->field_graph_end<<std::endl; 
    1395  
    1396  
    1397      std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters; 
    1398      // Check if a spatial transformation is needed 
    1399      if (grid && grid != fieldRef->grid && grid->hasTransform()) 
    1400      {        
    1401        bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    1402        double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);                                 
    1403        filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue); 
    1404  
    1405        fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0); 
    1406  
    1407       
    1408  
    1409        filters.second->parent_filters.resize(1); 
    1410        filters.second->parent_filters[0]= fieldRef->getInstantDataFilter(); 
    1411  
    1412        filters.second->tag = (buildWorkflowGraph || filters.second->parent_filters[0]->tag); 
    1413         
    1414        filters.second->start_graph = filter_start; 
    1415        filters.second->end_graph = filter_end; 
    1416        filters.second->field = this; 
    1417         
    1418      } 
    1419      else 
    1420      { 
    1421        filters.first = filters.second = std::shared_ptr<CFilter>(new CPassThroughFilter(gc)); 
    1422  
    1423        fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0); 
    1424       
    1425  
    1426        filters.second->parent_filters.resize(1); 
    1427        filters.second->parent_filters[0]= fieldRef->getInstantDataFilter(); 
    1428  
    1429        filters.second->tag = (buildWorkflowGraph || filters.second->parent_filters[0]->tag); 
    1430  
    1431        filters.second->start_graph = filter_start; 
    1432        filters.second->end_graph = filter_end; 
    1433        filters.second->field = this; 
    1434  
    1435      } 
    1436  
    1437      return filters.second; 
    1438    } 
    1439    CATCH_DUMP_ATTR 
    1440  
    1441    /*! 
    1442     * Returns the filter needed to handle a self reference in the field's expression. 
    1443     * If the needed filter does not exist, it is created, otherwise it is reused. 
    1444     * This method should only be called when building the filter graph corresponding 
    1445     * to the field's expression. 
    1446     * 
    1447     * \param gc the garbage collector to use 
    1448     * \return the output pin corresponding to a self reference 
    1449     */ 
    1450    std::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc, Time start_graph, Time end_graph) 
    1451    TRY 
    1452    { 
    1453      if(CXios::isClient) std::cout<<"getSelfReference field_id = "<<this->getId()<<" start_graph = "<<start_graph<<" end_graph = "<<end_graph<<std::endl; 
    1454  
    1455      if (instantDataFilter || !hasExpression()) 
    1456        ERROR("COutputPin* CField::getSelfReference(CGarbageCollector& gc)", 
    1457              "Impossible to add a self reference to a field which has already been parsed or which does not have an expression."); 
    1458       
    1459      bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 
    1460  
    1461      if (!selfReferenceFilter) 
    1462      { 
    1463        const bool detectMissingValues = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true); 
    1464        const double defaultValue  = detectMissingValues ? default_value : (!default_value.isEmpty() ? default_value : 0.0); 
    1465  
    1466        if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read) 
    1467        { 
    1468          if (!serverSourceFilter) 
    1469          { 
    1470            checkTimeAttributes(); 
    1471            serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true, 
    1472                                                                                    detectMissingValues, defaultValue)); 
    1473          } 
    1474  
    1475          selfReferenceFilter = serverSourceFilter; 
    1476        } 
    1477        else if (!field_ref.isEmpty()) 
    1478        { 
    1479          CField* fieldRef = CField::get(field_ref); 
    1480          fieldRef->buildFilterGraph(gc, false); 
    1481          selfReferenceFilter = fieldRef->getInstantDataFilter(); 
    1482        } 
    1483        else 
    1484        { 
    1485          if (!clientSourceFilter) 
    1486          { 
    1487            if (check_if_active.isEmpty()) check_if_active = false; 
    1488            clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, true, NoneDu, false, 
    1489                                                                                    detectMissingValues, defaultValue)); 
    1490          } 
    1491  
    1492          selfReferenceFilter = clientSourceFilter; 
    1493        } 
    1494      } 
    1495  
    1496      selfReferenceFilter->tag = buildWorkflowGraph; 
    1497      selfReferenceFilter->field = this; 
    1498      return selfReferenceFilter; 
    1499    } 
    1500    CATCH_DUMP_ATTR 
    1501  
    1502    /*! 
    1503     * Returns the temporal filter corresponding to the field's temporal operation 
    1504     * for the specified operation frequency. The filter is created if it does not 
    1505     * exist, otherwise it is reused. 
    1506     * 
    1507     * \param gc the garbage collector to use 
    1508     * \param outFreq the operation frequency, i.e. the frequency at which the output data will be computed 
    1509     * \return the output pin corresponding to the requested temporal filter 
    1510     */ 
    1511    std::shared_ptr<COutputPin> CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq) 
    1512    TRY 
    1513    { 
    1514      std::map<CDuration, std::shared_ptr<COutputPin> >::iterator it = temporalDataFilters.find(outFreq); 
    1515      const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 
    1516  
    1517      CContext* context = CContext::getCurrent(); 
    1518  
    1519  
    1520      if (it == temporalDataFilters.end()) 
    1521      { 
    1522        if (operation.isEmpty()) 
    1523          ERROR("void CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)", 
    1524                << "An operation must be defined for field \"" << getId() << "\"."); 
    1525  
    1526        checkTimeAttributes(&outFreq); 
    1527  
    1528        const bool detectMissingValues = (!detect_missing_value.isEmpty()  && detect_missing_value == true); 
    1529        std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 
     954      checkTimeAttributes(&outFreq); 
     955 
     956      const bool detectMissingValues = (!detect_missing_value.isEmpty()  && detect_missing_value == true); 
     957      std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 
    1530958                                                                             CContext::getCurrent()->getCalendar()->getInitDate(), 
    1531959                                                                             freq_op, freq_offset, outFreq, detectMissingValues)); 
    1532960 
    1533        instantDataFilter->connectOutput(temporalFilter, 0); 
    1534        // temporalFilter->tag = buildWorkflowGraph; 
    1535         
    1536        temporalFilter->parent_filters.resize(1); 
    1537        temporalFilter->parent_filters[0] = instantDataFilter; 
    1538         
    1539  
    1540        if(temporalFilter->parent_filters[0]->tag) temporalFilter->tag=true; 
    1541  
    1542        // temporalFilter->start_graph = filter_start; 
    1543        // temporalFilter->end_graph = filter_end; 
    1544        temporalFilter->field = this; 
    1545  
    1546        it = temporalDataFilters.insert(std::make_pair(outFreq, temporalFilter)).first; 
    1547      } 
    1548  
    1549      return it->second; 
    1550    } 
    1551    CATCH_DUMP_ATTR 
     961      instantDataFilter->connectOutput(temporalFilter, 0); 
     962      const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     963      if(buildGraph_)  
     964      { 
     965        std::cout<<"============== field "<<this->getId()<<" calls a getTemporalDataFilter  ============== "<<instantDataFilter << " _ "<<temporalFilter<<" ***** "<<CXios::isClient<<std::endl; 
     966        temporalFilter->graphPackage = new CGraphPackage; 
     967        temporalFilter->graphEnabled = true; 
     968        temporalFilter->graphPackage->inFields.push_back(this); 
     969      } 
     970 
     971      it = temporalDataFilters.insert(std::make_pair(outFreq, temporalFilter)).first; 
     972    } 
     973 
     974    return it->second; 
     975  } 
     976  CATCH_DUMP_ATTR 
    1552977 
    1553978  /*! 
     
    1559984    * \return the output pin corresponding to the requested temporal filter 
    1560985    */ 
    1561     
    1562    std::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq) 
    1563    TRY 
    1564    { 
    1565      if (instantDataFilter || !hasExpression()) 
    1566        ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)", 
    1567              "Impossible to add a self reference to a field which has already been parsed or which does not have an expression."); 
    1568  
    1569      if (!selfReferenceFilter) getSelfReference(gc) ; 
    1570  
    1571      if (serverSourceFilter || clientSourceFilter) 
    1572      { 
    1573        if (operation.isEmpty()) 
    1574          ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)", 
    1575                << "An operation must be defined for field \"" << getId() << "\"."); 
    1576  
    1577        checkTimeAttributes(&outFreq); 
    1578  
    1579        const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true); 
    1580        bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true); 
    1581        std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, 
    1582                                                                            CContext::getCurrent()->getCalendar()->getInitDate(), 
    1583                                                                            freq_op, freq_offset, outFreq, detectMissingValues)); 
    1584  
    1585        selfReferenceFilter->connectOutput(temporalFilter, 0); 
    1586        temporalFilter->tag = buildWorkflowGraph; 
    1587        temporalFilter->field = this; 
    1588  
    1589        return temporalFilter ; 
    1590      } 
    1591      else if (!field_ref.isEmpty()) 
    1592      { 
    1593        CField* fieldRef = CField::get(field_ref); 
    1594        fieldRef->buildFilterGraph(gc, false);  
    1595        return fieldRef->getTemporalDataFilter(gc, outFreq) ; 
    1596      } 
    1597   } 
    1598    CATCH_DUMP_ATTR 
    1599  
    1600    //---------------------------------------------------------------- 
     986 
     987  std::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq) 
     988  TRY 
     989  { 
     990    if (instantDataFilter || !hasExpression()) 
     991      ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)", 
     992            "Impossible to add a self reference to a field which has already been parsed or which does not have an expression."); 
     993     
     994    if (selfTemporalDataFilter) return selfTemporalDataFilter; 
     995 
     996    if (hasDirectFieldReference()) 
     997    { 
     998      CField* fieldRef=getDirectFieldReference(); 
     999      return fieldRef->getTemporalDataFilter(gc, outFreq) ; 
     1000    } 
     1001    else 
     1002    { 
     1003      if (selfTemporalDataFilter) return selfTemporalDataFilter ; 
     1004 
     1005      if (operation.isEmpty()) 
     1006        ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)", 
     1007              << "An operation must be defined for field \"" << getId() << "\"."); 
     1008 
     1009      checkTimeAttributes(&outFreq); //bof 
     1010 
     1011      const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true); 
     1012      selfTemporalDataFilter = std::shared_ptr<CTemporalFilter>(new CTemporalFilter(gc, operation, 
     1013                                                                CContext::getCurrent()->getCalendar()->getInitDate(), 
     1014                                                                freq_op, freq_offset, outFreq, detectMissingValues)); 
     1015 
     1016      inputFilter->connectOutput(selfTemporalDataFilter, 0); 
     1017      const bool buildGraph_ = !build_workflow_graph.isEmpty() && build_workflow_graph == true ; 
     1018      if(buildGraph_) 
     1019      { 
     1020        std::cout<<"============== field "<<this->getId()<<" calls a getSelfTemporalDataFilter  ============== "<<inputFilter << " _ "<<selfTemporalDataFilter<<" ***** "<<CXios::isClient<<std::endl; 
     1021        selfTemporalDataFilter->graphPackage = new CGraphPackage; 
     1022        selfTemporalDataFilter->graphEnabled = true; 
     1023        selfTemporalDataFilter->graphPackage->inFields.push_back(this); 
     1024      } 
     1025      return selfTemporalDataFilter ; 
     1026    } 
     1027  } 
     1028  CATCH_DUMP_ATTR 
     1029 
     1030 
     1031  //---------------------------------------------------------------- 
    16011032/* 
    16021033   void CField::fromBinary(StdIStream& is) 
     
    16141045   //---------------------------------------------------------------- 
    16151046 
    1616    void CField::solveGridReference(void) 
     1047  void CField::solveGridReference(void) 
     1048  TRY 
     1049  { 
     1050    if (grid_!=nullptr) return ; // already done 
     1051 
     1052    if (grid_ref.isEmpty() && domain_ref.isEmpty() && axis_ref.isEmpty() && scalar_ref.isEmpty()) 
     1053    { 
     1054      ERROR("CField::solveGridReference(void)", 
     1055            << "A grid must be defined for field '" << getFieldOutputName() << "' ."); 
     1056    } 
     1057    else if (!grid_ref.isEmpty() && (!domain_ref.isEmpty() || !axis_ref.isEmpty() || !scalar_ref.isEmpty())) 
     1058    { 
     1059      ERROR("CField::solveGridReference(void)", 
     1060            << "Field '" << getFieldOutputName() << "' has both a grid and a domain/axis/scalar." << std::endl 
     1061            << "Please define either 'grid_ref' or 'domain_ref'/'axis_ref'/'scalar_ref'."); 
     1062    } 
     1063 
     1064    if (grid_ref.isEmpty()) 
     1065    { 
     1066      std::vector<CDomain*> vecDom; 
     1067      std::vector<CAxis*> vecAxis; 
     1068      std::vector<CScalar*> vecScalar; 
     1069      std::vector<int> axisDomainOrderTmp; 
     1070 
     1071      std::vector<CDomain*> vecDomRef; 
     1072      std::vector<CAxis*> vecAxisRef; 
     1073      std::vector<CScalar*> vecScalarRef; 
     1074         
     1075      if (!domain_ref.isEmpty()) 
     1076      { 
     1077        StdString tmp = domain_ref.getValue(); 
     1078        if (CDomain::has(domain_ref)) 
     1079        { 
     1080          vecDom.push_back(CDomain::get(domain_ref)); 
     1081          vecDomRef.push_back(CDomain::createDomain()); 
     1082          vecDomRef.back()->domain_ref=domain_ref; 
     1083          axisDomainOrderTmp.push_back(2); 
     1084        } 
     1085        else  ERROR("CField::solveGridReference(void)", 
     1086                    << "Invalid reference to domain '" << domain_ref.getValue() << "'."); 
     1087      } 
     1088 
     1089      if (!axis_ref.isEmpty()) 
     1090      { 
     1091        if (CAxis::has(axis_ref)) 
     1092        { 
     1093          vecAxis.push_back(CAxis::get(axis_ref)); 
     1094          vecAxisRef.push_back(CAxis::createAxis()); 
     1095          vecAxisRef.back()->axis_ref=axis_ref; 
     1096          axisDomainOrderTmp.push_back(1); 
     1097        } 
     1098        else  ERROR("CField::solveGridReference(void)", 
     1099                    << "Invalid reference to axis '" << axis_ref.getValue() << "'."); 
     1100      } 
     1101 
     1102      if (!scalar_ref.isEmpty()) 
     1103      { 
     1104        if (CScalar::has(scalar_ref)) 
     1105        { 
     1106          vecScalar.push_back(CScalar::get(scalar_ref)); 
     1107          vecScalarRef.push_back(CScalar::createScalar()); 
     1108          vecScalarRef.back()->scalar_ref=scalar_ref; 
     1109          axisDomainOrderTmp.push_back(0); 
     1110        } 
     1111        else ERROR("CField::solveGridReference(void)", 
     1112                   << "Invalid reference to scalar '" << scalar_ref.getValue() << "'."); 
     1113      } 
     1114         
     1115      CArray<int,1> axisDomainOrder(axisDomainOrderTmp.size()); 
     1116      for (int idx = 0; idx < axisDomainOrderTmp.size(); ++idx) 
     1117      { 
     1118        axisDomainOrder(idx) = axisDomainOrderTmp[idx]; 
     1119      } 
     1120 
     1121      // Warning: the gridId shouldn't be set as the grid_ref since it could be inherited 
     1122      StdString gridId = CGrid::generateId(vecDom, vecAxis, vecScalar,axisDomainOrder); 
     1123      if (CGrid::has(gridId)) this->grid_ = CGrid::get(gridId); 
     1124      else  this->grid_ = CGrid::createGrid(gridId, vecDomRef, vecAxisRef, vecScalarRef,axisDomainOrder); 
     1125    } 
     1126    else 
     1127    { 
     1128      if (CGrid::has(grid_ref)) this->grid_ = CGrid::get(grid_ref); 
     1129      else  ERROR("CField::solveGridReference(void)", 
     1130                   << "Invalid reference to grid '" << grid_ref.getValue() << "'."); 
     1131    } 
     1132  } 
     1133  CATCH_DUMP_ATTR 
     1134 
     1135  void CField::solveGridDomainAxisRef(bool checkAtt) 
     1136  TRY 
     1137  { 
     1138    grid_->solveDomainAxisRef(checkAtt); 
     1139  } 
     1140  CATCH_DUMP_ATTR 
     1141 
     1142  void CField::solveCheckMaskIndex(bool doSendingIndex) 
     1143  TRY 
     1144  { 
     1145    grid_->checkMaskIndex(doSendingIndex); 
     1146  } 
     1147  CATCH_DUMP_ATTR 
     1148 
     1149   
     1150  void CField::solveGridDomainAxisBaseRef() 
     1151  TRY 
     1152  { 
     1153    grid_->solveDomainAxisRef(false); 
     1154    grid_->solveDomainAxisBaseRef(); 
     1155  } 
     1156  CATCH_DUMP_ATTR 
     1157 
     1158  ///------------------------------------------------------------------- 
     1159 
     1160  template <> 
     1161  void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void) 
     1162  TRY 
     1163  { 
     1164    if (this->group_ref.isEmpty()) return; 
     1165    StdString gref = this->group_ref.getValue(); 
     1166 
     1167    if (!CFieldGroup::has(gref)) 
     1168      ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)", 
     1169         << "[ gref = " << gref << "]" 
     1170         << " invalid group name !"); 
     1171 
     1172    CFieldGroup* group = CFieldGroup::get(gref); 
     1173    CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this)); 
     1174    owner->setAttributes(group); // inherite of attributes of group reference 
     1175       
     1176    std::vector<CField*> allChildren  = group->getAllChildren(); 
     1177    std::vector<CField*>::iterator it = allChildren.begin(), end = allChildren.end(); 
     1178 
     1179    for (; it != end; it++) 
     1180    { 
     1181      CField* child = *it; 
     1182     if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId()); 
     1183    } 
     1184  } 
     1185  CATCH_DUMP_ATTR 
     1186 
     1187  ///------------------------------------------------------------------- 
     1188 
     1189  void CField::parse(xml::CXMLNode& node) 
     1190  TRY 
     1191  { 
     1192    string newContent ; 
     1193    SuperClass::parse(node); 
     1194    if (node.goToChildElement()) 
     1195    { 
     1196      do 
     1197      { 
     1198        if (node.getElementName() == "variable" || node.getElementName() == "variable_group") this->getVirtualVariableGroup()->parseChild(node); 
     1199        else if (node.getElementName() == "expr") if (node.getContent(newContent)) content+=newContent ; 
     1200      } while (node.goToNextElement()); 
     1201      node.goToParentElement(); 
     1202    } 
     1203    if (node.getContent(newContent)) content=newContent ; 
     1204  } 
     1205  CATCH_DUMP_ATTR 
     1206 
     1207 /*! 
     1208   This function retrieves Id of corresponding domain_ref and axis_ref (if any) 
     1209   of a field. In some cases, only domain exists but axis doesn't 
     1210   \return pair of Domain and Axis id 
     1211  */ 
     1212  const std::vector<StdString>& CField::getRefDomainAxisIds() 
     1213  TRY 
     1214  { 
     1215    CGrid* cgPtr = getRelGrid(); 
     1216    if (NULL != cgPtr) 
     1217    { 
     1218      std::vector<StdString>::iterator it; 
     1219      if (!domain_ref.isEmpty()) 
     1220      { 
     1221        std::vector<StdString> domainList = cgPtr->getDomainList(); 
     1222        it = std::find(domainList.begin(), domainList.end(), domain_ref.getValue()); 
     1223        if (domainList.end() != it) domAxisScalarIds_[0] = *it; 
     1224      } 
     1225 
     1226      if (!axis_ref.isEmpty()) 
     1227      { 
     1228        std::vector<StdString> axisList = cgPtr->getAxisList(); 
     1229        it = std::find(axisList.begin(), axisList.end(), axis_ref.getValue()); 
     1230        if (axisList.end() != it) domAxisScalarIds_[1] = *it; 
     1231      } 
     1232 
     1233      if (!scalar_ref.isEmpty()) 
     1234      { 
     1235        std::vector<StdString> scalarList = cgPtr->getScalarList(); 
     1236        it = std::find(scalarList.begin(), scalarList.end(), scalar_ref.getValue()); 
     1237        if (scalarList.end() != it) domAxisScalarIds_[2] = *it; 
     1238      } 
     1239    } 
     1240    return (domAxisScalarIds_); 
     1241  } 
     1242  CATCH_DUMP_ATTR 
     1243 
     1244  CVariable* CField::addVariable(const string& id) 
     1245  TRY 
     1246  { 
     1247    return vVariableGroup->createChild(id); 
     1248  } 
     1249  CATCH 
     1250 
     1251  CVariableGroup* CField::addVariableGroup(const string& id) 
     1252  TRY 
     1253  { 
     1254    return vVariableGroup->createChildGroup(id); 
     1255  } 
     1256  CATCH 
     1257 
     1258  void CField::setContextClient(CContextClient* contextClient) 
     1259  TRY 
     1260  { 
     1261    CContext* context = CContext::getCurrent(); 
     1262    client = contextClient; 
     1263   
     1264    // A grid is sent by a client (both for read or write) or by primary server (write only) 
     1265    if (context->getServiceType()==CServicesManager::GATHERER) 
     1266    { 
     1267      if (getRelFile()->mode.isEmpty() || (!getRelFile()->mode.isEmpty() && getRelFile()->mode == CFile::mode_attr::write)) 
     1268        grid_->setContextClient(contextClient); 
     1269    } 
     1270    else if (context->getServiceType()==CServicesManager::CLIENT) 
     1271      grid_->setContextClient(contextClient); 
     1272  } 
     1273  CATCH_DUMP_ATTR 
     1274 
     1275  void CField::sendCloseDefinition(void) 
     1276  { 
     1277    CContext::getCurrent()->sendCloseDefinition(client) ; 
     1278  } 
     1279 
     1280  void CField::sendFieldToFileServer(void) 
     1281  { 
     1282    CContext::getCurrent()->sendContextToFileServer(client); 
     1283    getRelFile()->sendFileToFileServer(client); 
     1284    sentGrid_ = grid_-> duplicateSentGrid() ; 
     1285    sentGrid_->sendGridToFileServer(client); 
     1286    name = getFieldOutputName() ; 
     1287    this->sendAllAttributesToServer(client); 
     1288    this->sendAddAllVariables(client); 
     1289  } 
     1290 
     1291  void CField::sendFieldToInputFileServer(void) 
     1292  { 
     1293    CContext::getCurrent()->sendContextToFileServer(client); 
     1294    getRelFile()->sendFileToFileServer(client); 
     1295    sentGrid_ = grid_-> duplicateSentGrid() ; 
     1296    sentGrid_->sendGridToFileServer(client); 
     1297    read_access=true ; // not the best solution, but on server side, the field must be a starting point of the workflow 
     1298                       // must be replace by a better solution when implementing filters for reading and send to client 
     1299                       // on server side 
     1300    this->sendAllAttributesToServer(client); 
     1301    this->sendAddAllVariables(client); 
     1302  } 
     1303 
     1304  void CField::sendFieldToCouplerOut(void) 
     1305  { 
     1306    if (sendFieldToCouplerOut_done_) return ; 
     1307    else sendFieldToCouplerOut_done_=true ; 
     1308    grid_->sendGridToCouplerOut(client, this->getId()); 
     1309    this->sendGridCompleted(); 
     1310 
     1311  } 
     1312   
     1313  void CField::makeGridAliasForCoupling(void)  
     1314  {  
     1315    grid_->makeAliasForCoupling(this->getId());  
     1316  } 
     1317 
     1318 //! Client side: Send a message  announcing that the grid definition has been received from a coupling context 
     1319   void CField::sendGridCompleted(void) 
    16171320   TRY 
    16181321   { 
    1619       if (grid_ref.isEmpty() && domain_ref.isEmpty() && axis_ref.isEmpty() && scalar_ref.isEmpty()) 
    1620       { 
    1621         ERROR("CField::solveGridReference(void)", 
    1622               << "A grid must be defined for field '" << getFieldOutputName() << "' ."); 
    1623       } 
    1624       else if (!grid_ref.isEmpty() && (!domain_ref.isEmpty() || !axis_ref.isEmpty() || !scalar_ref.isEmpty())) 
    1625       { 
    1626         ERROR("CField::solveGridReference(void)", 
    1627               << "Field '" << getFieldOutputName() << "' has both a grid and a domain/axis/scalar." << std::endl 
    1628               << "Please define either 'grid_ref' or 'domain_ref'/'axis_ref'/'scalar_ref'."); 
    1629       } 
    1630  
    1631       if (grid_ref.isEmpty()) 
    1632       { 
    1633         std::vector<CDomain*> vecDom; 
    1634         std::vector<CAxis*> vecAxis; 
    1635         std::vector<CScalar*> vecScalar; 
    1636         std::vector<int> axisDomainOrderTmp; 
    1637  
    1638         std::vector<CDomain*> vecDomRef; 
    1639         std::vector<CAxis*> vecAxisRef; 
    1640         std::vector<CScalar*> vecScalarRef; 
    1641  
    1642          
    1643         if (!domain_ref.isEmpty()) 
    1644         { 
    1645           StdString tmp = domain_ref.getValue(); 
    1646           if (CDomain::has(domain_ref)) 
    1647           { 
    1648             vecDom.push_back(CDomain::get(domain_ref)); 
    1649             vecDomRef.push_back(CDomain::createDomain()); 
    1650             vecDomRef.back()->domain_ref=domain_ref; 
    1651             axisDomainOrderTmp.push_back(2); 
    1652           } 
    1653           else  ERROR("CField::solveGridReference(void)", 
    1654                       << "Invalid reference to domain '" << domain_ref.getValue() << "'."); 
    1655         } 
    1656  
    1657         if (!axis_ref.isEmpty()) 
    1658         { 
    1659           if (CAxis::has(axis_ref)) 
    1660           { 
    1661             vecAxis.push_back(CAxis::get(axis_ref)); 
    1662             vecAxisRef.push_back(CAxis::createAxis()); 
    1663             vecAxisRef.back()->axis_ref=axis_ref; 
    1664             axisDomainOrderTmp.push_back(1); 
    1665           } 
    1666           else  ERROR("CField::solveGridReference(void)", 
    1667                       << "Invalid reference to axis '" << axis_ref.getValue() << "'."); 
    1668         } 
    1669  
    1670         if (!scalar_ref.isEmpty()) 
    1671         { 
    1672           if (CScalar::has(scalar_ref)) 
    1673           { 
    1674             vecScalar.push_back(CScalar::get(scalar_ref)); 
    1675             vecScalarRef.push_back(CScalar::createScalar()); 
    1676             vecScalarRef.back()->scalar_ref=scalar_ref; 
    1677             axisDomainOrderTmp.push_back(0); 
    1678           } 
    1679           else ERROR("CField::solveGridReference(void)", 
    1680                      << "Invalid reference to scalar '" << scalar_ref.getValue() << "'."); 
    1681         } 
    1682          
    1683         CArray<int,1> axisDomainOrder(axisDomainOrderTmp.size()); 
    1684         for (int idx = 0; idx < axisDomainOrderTmp.size(); ++idx) 
    1685         { 
    1686           axisDomainOrder(idx) = axisDomainOrderTmp[idx]; 
    1687         } 
    1688  
    1689         // Warning: the gridId shouldn't be set as the grid_ref since it could be inherited 
    1690         StdString gridId = CGrid::generateId(vecDom, vecAxis, vecScalar,axisDomainOrder); 
    1691         if (CGrid::has(gridId)) this->grid = CGrid::get(gridId); 
    1692         else  this->grid = CGrid::createGrid(gridId, vecDomRef, vecAxisRef, vecScalarRef,axisDomainOrder); 
    1693       } 
    1694       else 
    1695       { 
    1696         if (CGrid::has(grid_ref)) this->grid = CGrid::get(grid_ref); 
    1697         else  ERROR("CField::solveGridReference(void)", 
    1698                      << "Invalid reference to grid '" << grid_ref.getValue() << "'."); 
    1699       } 
     1322      CEventClient event(getType(),EVENT_ID_GRID_COMPLETED); 
     1323 
     1324      if (client->isServerLeader()) 
     1325      { 
     1326        CMessage msg; 
     1327        msg<<this->getId(); 
     1328        for (auto& rank : client->getRanksServerLeader()) event.push(rank,1,msg); 
     1329        client->sendEvent(event); 
     1330      } 
     1331      else client->sendEvent(event); 
    17001332   } 
    17011333   CATCH_DUMP_ATTR 
    17021334 
    1703    void CField::solveGridDomainAxisRef(bool checkAtt) 
     1335   //! Server side: Receive a message announcing that the grid definition has been received from a coupling context 
     1336   void CField::recvGridCompleted(CEventServer& event) 
    17041337   TRY 
    17051338   { 
    1706      grid->solveDomainAxisRef(checkAtt); 
     1339      CBufferIn* buffer=event.subEvents.begin()->buffer; 
     1340      string id; 
     1341      *buffer>>id ; 
     1342      get(id)->recvGridCompleted(*buffer); 
     1343   } 
     1344   CATCH 
     1345 
     1346   //! Server side: Receive a message  message  announcing that the grid definition has been received from a coupling context 
     1347   void CField::recvGridCompleted(CBufferIn& buffer) 
     1348   TRY 
     1349   { 
     1350      setGridCompleted() ; 
    17071351   } 
    17081352   CATCH_DUMP_ATTR 
    17091353 
    1710    void CField::solveCheckMaskIndex(bool doSendingIndex) 
    1711    TRY 
    1712    { 
    1713      grid->checkMaskIndex(doSendingIndex); 
    1714    } 
    1715    CATCH_DUMP_ATTR 
    1716  
    1717    void CField::solveTransformedGrid() 
    1718    TRY 
    1719    { 
    1720      if (grid && !grid->isTransformed() && hasDirectFieldReference() && grid != getDirectFieldReference()->grid) 
    1721      { 
    1722        std::vector<CGrid*> grids; 
    1723        // Source grid 
    1724        grids.push_back(getDirectFieldReference()->grid); 
    1725        // Intermediate grids 
    1726        if (!grid_path.isEmpty()) 
    1727        { 
    1728          std::string gridId; 
    1729          size_t start = 0, end; 
    1730  
    1731          do 
    1732          { 
    1733            end = grid_path.getValue().find(',', start); 
    1734            if (end != std::string::npos) 
    1735            { 
    1736              gridId = grid_path.getValue().substr(start, end - start); 
    1737              start = end + 1; 
    1738            } 
    1739            else 
    1740              gridId = grid_path.getValue().substr(start); 
    1741  
    1742            if (!CGrid::has(gridId)) 
    1743              ERROR("void CField::solveTransformedGrid()", 
    1744                    << "Invalid grid_path, the grid '" << gridId << "' does not exist."); 
    1745  
    1746            grids.push_back(CGrid::get(gridId)); 
    1747          } 
    1748          while (end != std::string::npos); 
    1749        } 
    1750        // Destination grid 
    1751        grids.push_back(grid); 
    1752  
    1753        for (size_t i = 0, count = grids.size() - 1; i < count; ++i) 
    1754        { 
    1755          CGrid *gridSrc  = grids[i]; 
    1756          CGrid *gridDest = grids[i + 1]; 
    1757          if (!gridDest->isTransformed()) 
    1758            gridDest->transformGrid(gridSrc); 
    1759        } 
    1760      } 
    1761      else if (grid && grid->hasTransform() && !grid->isTransformed()) 
    1762      { 
    1763        // Temporarily deactivate the self-transformation of grid 
    1764        // grid->transformGrid(grid); 
    1765      } 
    1766    } 
    1767    CATCH_DUMP_ATTR 
    1768  
    1769    void CField::solveGenerateGrid() 
    1770    TRY 
    1771    { 
    1772      if (grid && !grid->isTransformed() && hasDirectFieldReference() && grid != getDirectFieldReference()->grid) 
    1773        grid->completeGrid(getDirectFieldReference()->grid); 
    1774      else 
    1775        grid->completeGrid(); 
    1776    } 
    1777    CATCH_DUMP_ATTR 
    1778  
    1779    void CField::solveGridDomainAxisBaseRef() 
    1780    TRY 
    1781    { 
    1782      grid->solveDomainAxisRef(false); 
    1783      grid->solveDomainAxisBaseRef(); 
    1784    } 
    1785    CATCH_DUMP_ATTR 
    1786  
    1787    ///------------------------------------------------------------------- 
    1788  
    1789    template <> 
    1790    void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void) 
    1791    TRY 
    1792    { 
    1793       if (this->group_ref.isEmpty()) return; 
    1794       StdString gref = this->group_ref.getValue(); 
    1795  
    1796       if (!CFieldGroup::has(gref)) 
    1797          ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)", 
    1798                << "[ gref = " << gref << "]" 
    1799                << " invalid group name !"); 
    1800  
    1801       CFieldGroup* group = CFieldGroup::get(gref); 
    1802       CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this)); 
    1803       owner->setAttributes(group); // inherite of attributes of group reference 
    1804        
    1805       std::vector<CField*> allChildren  = group->getAllChildren(); 
    1806       std::vector<CField*>::iterator it = allChildren.begin(), end = allChildren.end(); 
    1807  
    1808       for (; it != end; it++) 
    1809       { 
    1810          CField* child = *it; 
    1811          if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId()); 
    1812  
    1813       } 
    1814    } 
    1815    CATCH_DUMP_ATTR 
    1816  
    1817    void CField::scaleFactorAddOffset(double scaleFactor, double addOffset) 
    1818    TRY 
    1819    { 
    1820      recvDataSrv = (recvDataSrv - addOffset) / scaleFactor; 
    1821    } 
    1822    CATCH_DUMP_ATTR 
    1823  
    1824    void CField::invertScaleFactorAddOffset(double scaleFactor, double addOffset) 
    1825    TRY 
    1826    { 
    1827      recvDataSrv = recvDataSrv * scaleFactor + addOffset; 
    1828    } 
    1829    CATCH_DUMP_ATTR 
    1830  
    1831    void CField::outputField(CArray<double,1>& fieldOut) 
    1832    TRY 
    1833    {  
    1834       CArray<size_t,1>& outIndexClient = grid->localIndexToWriteOnClient; 
    1835       CArray<size_t,1>& outIndexServer = grid->localIndexToWriteOnServer; 
    1836       for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx) 
    1837       { 
    1838         fieldOut(outIndexServer(idx)) = recvDataSrv(outIndexClient(idx)); 
    1839       } 
    1840    } 
    1841    CATCH_DUMP_ATTR 
    1842  
    1843    void CField::inputField(CArray<double,1>& fieldIn) 
    1844    TRY 
    1845    { 
    1846       CArray<size_t,1>& outIndexClient = grid->localIndexToWriteOnClient; 
    1847       CArray<size_t,1>& outIndexServer = grid->localIndexToWriteOnServer; 
    1848       for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx) 
    1849       { 
    1850         recvDataSrv(outIndexClient(idx)) = fieldIn(outIndexServer(idx)); 
    1851       } 
    1852    } 
    1853    CATCH_DUMP_ATTR 
    1854  
    1855    void CField::outputCompressedField(CArray<double,1>& fieldOut) 
    1856    TRY 
    1857    { 
    1858       CArray<size_t,1>& outIndexClient = grid->localIndexToWriteOnClient; 
    1859       CArray<size_t,1>& outIndexServer = grid->localIndexToWriteOnServer; 
    1860       for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx) 
    1861       { 
    1862         fieldOut((idx)) = recvDataSrv(outIndexClient(idx)); 
    1863       } 
    1864    } 
    1865    CATCH_DUMP_ATTR 
    1866  
    1867    ///------------------------------------------------------------------- 
    1868  
    1869    void CField::parse(xml::CXMLNode& node) 
    1870    TRY 
    1871    { 
    1872       string newContent ; 
    1873       SuperClass::parse(node); 
    1874       if (node.goToChildElement()) 
    1875       { 
    1876         do 
    1877         { 
    1878           if (node.getElementName() == "variable" || node.getElementName() == "variable_group") this->getVirtualVariableGroup()->parseChild(node); 
    1879           else if (node.getElementName() == "expr") if (node.getContent(newContent)) content+=newContent ; 
    1880         } while (node.goToNextElement()); 
    1881         node.goToParentElement(); 
    1882       } 
    1883       if (node.getContent(newContent)) content=newContent ; 
    1884     } 
    1885    CATCH_DUMP_ATTR 
    1886  
    1887    /*! 
    1888      This function retrieves Id of corresponding domain_ref and axis_ref (if any) 
    1889    of a field. In some cases, only domain exists but axis doesn't 
    1890    \return pair of Domain and Axis id 
     1354 
     1355  void CField::sendAddAllVariables(CContextClient* client) 
     1356  TRY 
     1357  { 
     1358    std::vector<CVariable*> allVar = getAllVariables(); 
     1359    std::vector<CVariable*>::const_iterator it = allVar.begin(); 
     1360    std::vector<CVariable*>::const_iterator itE = allVar.end(); 
     1361 
     1362    for (; it != itE; ++it) 
     1363    { 
     1364      this->sendAddVariable((*it)->getId(), client); 
     1365      (*it)->sendAllAttributesToServer(client); 
     1366      (*it)->sendValue(client); 
     1367    } 
     1368  } 
     1369  CATCH_DUMP_ATTR 
     1370 
     1371  /*! 
     1372   * Send all Attributes to server. This method is overloaded, since only grid_ref attribute 
     1373   * must be sent to server and not domain_ref/axis_ref/scalar_ref.  
    18911374   */ 
    1892    const std::vector<StdString>& CField::getRefDomainAxisIds() 
    1893    TRY 
    1894    { 
    1895      CGrid* cgPtr = getRelGrid(); 
    1896      if (NULL != cgPtr) 
    1897      { 
    1898        std::vector<StdString>::iterator it; 
    1899        if (!domain_ref.isEmpty()) 
    1900        { 
    1901          std::vector<StdString> domainList = cgPtr->getDomainList(); 
    1902          it = std::find(domainList.begin(), domainList.end(), domain_ref.getValue()); 
    1903          if (domainList.end() != it) domAxisScalarIds_[0] = *it; 
    1904        } 
    1905  
    1906        if (!axis_ref.isEmpty()) 
    1907        { 
    1908          std::vector<StdString> axisList = cgPtr->getAxisList(); 
    1909          it = std::find(axisList.begin(), axisList.end(), axis_ref.getValue()); 
    1910          if (axisList.end() != it) domAxisScalarIds_[1] = *it; 
    1911        } 
    1912  
    1913        if (!scalar_ref.isEmpty()) 
    1914        { 
    1915          std::vector<StdString> scalarList = cgPtr->getScalarList(); 
    1916          it = std::find(scalarList.begin(), scalarList.end(), scalar_ref.getValue()); 
    1917          if (scalarList.end() != it) domAxisScalarIds_[2] = *it; 
    1918        } 
    1919      } 
    1920      return (domAxisScalarIds_); 
    1921    } 
    1922    CATCH_DUMP_ATTR 
    1923  
    1924    CVariable* CField::addVariable(const string& id) 
    1925    TRY 
    1926    { 
    1927      return vVariableGroup->createChild(id); 
    1928    } 
    1929    CATCH 
    1930  
    1931    CVariableGroup* CField::addVariableGroup(const string& id) 
    1932    TRY 
    1933    { 
    1934      return vVariableGroup->createChildGroup(id); 
    1935    } 
    1936    CATCH 
    1937  
    1938    void CField::setContextClient(CContextClient* contextClient) 
    1939    TRY 
    1940    { 
    1941      CContext* context = CContext::getCurrent(); 
    1942      client = contextClient; 
    1943      if (context->hasClient) 
    1944      { 
    1945        // A grid is sent by a client (both for read or write) or by primary server (write only) 
    1946        if (context->hasServer) 
    1947        { 
    1948          if (file->mode.isEmpty() || (!file->mode.isEmpty() && file->mode == CFile::mode_attr::write)) 
    1949            grid->setContextClient(contextClient); 
    1950        } 
    1951        else 
    1952            grid->setContextClient(contextClient); 
    1953      } 
    1954    } 
    1955    CATCH_DUMP_ATTR 
    1956  
    1957    CContextClient* CField::getContextClient() 
    1958    TRY 
    1959    { 
    1960      return client; 
    1961    } 
    1962    CATCH 
    1963  
    1964    void CField::sendAddAllVariables(CContextClient* client) 
    1965    TRY 
    1966    { 
    1967      std::vector<CVariable*> allVar = getAllVariables(); 
    1968      std::vector<CVariable*>::const_iterator it = allVar.begin(); 
    1969      std::vector<CVariable*>::const_iterator itE = allVar.end(); 
    1970  
    1971      for (; it != itE; ++it) 
    1972      { 
    1973        this->sendAddVariable((*it)->getId(), client); 
    1974        (*it)->sendAllAttributesToServer(client); 
    1975        (*it)->sendValue(client); 
    1976      } 
    1977    } 
    1978    CATCH_DUMP_ATTR 
    1979  
    1980    /*! 
    1981     * Send all Attributes to server. This method is overloaded, since only grid_ref attribute 
    1982     * must be sent to server and not domain_ref/axis_ref/scalar_ref.  
    1983     */ 
    19841375     
    1985    void CField::sendAllAttributesToServer(CContextClient* client) 
    1986    TRY 
    1987    { 
    1988      if (grid_ref.isEmpty()) 
    1989      { 
    1990        grid_ref=grid->getId() ; 
    1991        SuperClass::sendAllAttributesToServer(client) ; 
    1992        grid_ref.reset(); 
    1993      } 
    1994      else SuperClass::sendAllAttributesToServer(client) ; 
    1995    } 
    1996    CATCH_DUMP_ATTR 
     1376  void CField::sendAllAttributesToServer(CContextClient* client) 
     1377  TRY 
     1378  { 
     1379    if (grid_ref.isEmpty()) 
     1380    { 
     1381      grid_ref=sentGrid_->getId() ; 
     1382      SuperClass::sendAllAttributesToServer(client) ; 
     1383      domain_ref.reset() ; 
     1384      axis_ref.reset() ; 
     1385      scalar_ref.reset() ; 
     1386      grid_ref.reset(); 
     1387    } 
     1388    else  
     1389    { 
     1390      string tmp = grid_ref; 
     1391      grid_ref = sentGrid_->getId() ; 
     1392      SuperClass::sendAllAttributesToServer(client) ; 
     1393      grid_ref = tmp ; 
     1394    } 
     1395  } 
     1396  CATCH_DUMP_ATTR 
    19971397     
    1998    void CField::sendAddVariable(const string& id, CContextClient* client) 
    1999    TRY 
    2000    { 
    2001       sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE, client); 
    2002    } 
    2003    CATCH_DUMP_ATTR 
    2004  
    2005    void CField::sendAddVariableGroup(const string& id, CContextClient* client) 
    2006    TRY 
    2007    { 
    2008       sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE_GROUP, client); 
    2009    } 
    2010    CATCH_DUMP_ATTR 
    2011  
    2012    void CField::recvAddVariable(CEventServer& event) 
    2013    TRY 
    2014    { 
    2015  
    2016       CBufferIn* buffer = event.subEvents.begin()->buffer; 
    2017       string id; 
    2018       *buffer >> id; 
    2019       get(id)->recvAddVariable(*buffer); 
    2020    } 
    2021    CATCH 
    2022  
    2023    void CField::recvAddVariable(CBufferIn& buffer) 
    2024    TRY 
    2025    { 
    2026       string id; 
    2027       buffer >> id; 
    2028       addVariable(id); 
    2029    } 
    2030    CATCH_DUMP_ATTR 
    2031  
    2032    void CField::recvAddVariableGroup(CEventServer& event) 
    2033    TRY 
    2034    { 
    2035  
    2036       CBufferIn* buffer = event.subEvents.begin()->buffer; 
    2037       string id; 
    2038       *buffer >> id; 
    2039       get(id)->recvAddVariableGroup(*buffer); 
    2040    } 
    2041    CATCH 
    2042  
    2043    void CField::recvAddVariableGroup(CBufferIn& buffer) 
    2044    TRY 
    2045    { 
    2046       string id; 
    2047       buffer >> id; 
    2048       addVariableGroup(id); 
    2049    } 
    2050    CATCH_DUMP_ATTR 
    2051  
    2052    /*! 
    2053     * Check on freq_off and freq_op attributes. 
    2054     */ 
    2055    void CField::checkTimeAttributes(CDuration* freqOp) 
    2056    TRY 
    2057    { 
    2058      bool isFieldRead  = file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read; 
    2059      bool isFieldWrite = file && ( file->mode.isEmpty() ||  file->mode == CFile::mode_attr::write); 
    2060      if (isFieldRead && !(operation.getValue() == "instant" || operation.getValue() == "once") )      
    2061        ERROR("void CField::checkTimeAttributes(void)", 
    2062              << "Unsupported operation for field '" << getFieldOutputName() << "'." << std::endl 
    2063              << "Currently only \"instant\" is supported for fields read from file.") 
    2064  
    2065      if (freq_op.isEmpty()) 
    2066      { 
    2067        if (operation.getValue() == "instant") 
    2068        { 
    2069          if (isFieldRead || isFieldWrite) freq_op.setValue(file->output_freq.getValue()); 
    2070          else freq_op=*freqOp ; 
    2071        } 
    2072        else 
    2073          freq_op.setValue(TimeStep); 
    2074      } 
    2075      if (freq_offset.isEmpty()) 
    2076        freq_offset.setValue(isFieldRead ? NoneDu : (freq_op.getValue() - TimeStep)); 
    2077    } 
    2078    CATCH_DUMP_ATTR 
    2079  
    2080    /*! 
    2081     * Returns string arithmetic expression associated to the field. 
    2082     * \return if content is defined return content string, otherwise, if "expr" attribute is defined, return expr string. 
    2083     */ 
    2084    const string& CField::getExpression(void) 
    2085    TRY 
    2086    { 
    2087      if (!expr.isEmpty() && content.empty()) 
    2088      { 
    2089        content = expr; 
    2090        expr.reset(); 
    2091      } 
    2092  
    2093      return content; 
    2094    } 
    2095    CATCH_DUMP_ATTR 
    2096  
    2097    bool CField::hasExpression(void) const 
    2098    TRY 
    2099    { 
    2100      return (!expr.isEmpty() || !content.empty()); 
    2101    } 
    2102    CATCH 
    2103  
    2104    bool CField::hasGridMask(void) const 
    2105    TRY 
    2106    { 
    2107      return (this->grid->hasMask()); 
    2108    } 
    2109    CATCH 
    2110  
    2111    DEFINE_REF_FUNC(Field,field) 
     1398  void CField::sendAddVariable(const string& id, CContextClient* client) 
     1399  TRY 
     1400  { 
     1401    sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE, client); 
     1402  } 
     1403  CATCH_DUMP_ATTR 
     1404 
     1405  void CField::sendAddVariableGroup(const string& id, CContextClient* client) 
     1406  TRY 
     1407  { 
     1408    sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE_GROUP, client); 
     1409  } 
     1410  CATCH_DUMP_ATTR 
     1411 
     1412  void CField::recvAddVariable(CEventServer& event) 
     1413  TRY 
     1414  { 
     1415    CBufferIn* buffer = event.subEvents.begin()->buffer; 
     1416    string id; 
     1417    *buffer >> id; 
     1418    get(id)->recvAddVariable(*buffer); 
     1419  } 
     1420  CATCH 
     1421 
     1422  void CField::recvAddVariable(CBufferIn& buffer) 
     1423  TRY 
     1424  { 
     1425    string id; 
     1426    buffer >> id; 
     1427    addVariable(id); 
     1428  } 
     1429  CATCH_DUMP_ATTR 
     1430 
     1431  void CField::recvAddVariableGroup(CEventServer& event) 
     1432  TRY 
     1433  { 
     1434    CBufferIn* buffer = event.subEvents.begin()->buffer; 
     1435    string id; 
     1436    *buffer >> id; 
     1437    get(id)->recvAddVariableGroup(*buffer); 
     1438  } 
     1439  CATCH 
     1440 
     1441  void CField::recvAddVariableGroup(CBufferIn& buffer) 
     1442  TRY 
     1443  { 
     1444    string id; 
     1445    buffer >> id; 
     1446    addVariableGroup(id); 
     1447  } 
     1448  CATCH_DUMP_ATTR 
     1449 
     1450  /*! 
     1451   * Check on freq_off and freq_op attributes. 
     1452   */ 
     1453  void CField::checkTimeAttributes(CDuration* freqOp) 
     1454  TRY 
     1455  { 
     1456    if (hasFileIn() && !(operation.getValue() == "instant" || operation.getValue() == "once") )      
     1457      ERROR("void CField::checkTimeAttributes(void)", 
     1458         << "Unsupported operation for field '" << getFieldOutputName() << "'." << std::endl 
     1459         << "Currently only \"instant\" is supported for fields read from file.") 
     1460 
     1461    if (freq_op.isEmpty()) 
     1462    { 
     1463      if (operation.getValue() == "instant") 
     1464      { 
     1465        if (hasFileIn() || hasFileOut()) freq_op.setValue(getRelFile()->output_freq.getValue()); 
     1466        else freq_op=*freqOp ; 
     1467      } 
     1468      else freq_op.setValue(TimeStep); 
     1469    } 
     1470    if (freq_offset.isEmpty()) freq_offset.setValue(hasFileIn() ? NoneDu : (freq_op.getValue() - TimeStep)); 
     1471  } 
     1472  CATCH_DUMP_ATTR 
     1473 
     1474  /*! 
     1475   * Returns string arithmetic expression associated to the field. 
     1476   * \return if content is defined return content string, otherwise, if "expr" attribute is defined, return expr string. 
     1477   */ 
     1478  const string& CField::getExpression(void) 
     1479  TRY 
     1480  { 
     1481    if (!expr.isEmpty() && content.empty()) 
     1482    { 
     1483      content = expr; 
     1484      expr.reset(); 
     1485    } 
     1486 
     1487    return content; 
     1488  } 
     1489  CATCH_DUMP_ATTR 
     1490 
     1491  bool CField::hasExpression(void) const 
     1492  TRY 
     1493  { 
     1494    return (!expr.isEmpty() || !content.empty()); 
     1495  } 
     1496  CATCH 
     1497 
     1498  bool CField::hasGridMask(void) const 
     1499  TRY 
     1500  { 
     1501    return (this->grid_->hasMask()); 
     1502  } 
     1503  CATCH 
     1504 
     1505  DEFINE_REF_FUNC(Field,field) 
    21121506} // namespace xios 
  • XIOS/dev/dev_trunk_graph/src/node/field.hpp

    r1686 r2019  
    77#include "functor.hpp" 
    88#include "functor_type.hpp" 
    9 #include "filter.hpp" 
    109#include "duration.hpp" 
    1110#include "date.hpp" 
     
    1817#include "variable.hpp" 
    1918#include "context_client.hpp" 
    20  
    21  
    22 namespace xios { 
     19#include "pass_through_filter.hpp" 
     20#include "temporal_filter.hpp" 
     21#include "model_to_client_source_filter.hpp" 
     22#include "client_from_client_source_filter.hpp" 
     23#include "client_from_server_source_filter.hpp" 
     24#include "client_to_model_store_filter.hpp" 
     25#include "server_to_client_store_filter.hpp" 
     26#include "server_from_client_source_filter.hpp" 
     27#include "file_writer_store_filter.hpp" 
     28#include "client_to_server_store_filter.hpp" 
     29#include "file_reader_source_filter.hpp" 
     30 
     31 
     32 
     33 
     34 
     35namespace xios  
     36{ 
    2337 
    2438   /// ////////////////////// Déclarations ////////////////////// /// 
     
    2943 
    3044   class CFile; 
     45   class CCouplerIn ; 
     46   class CCouplerOut ; 
    3147   class CGrid; 
    3248   class CContext; 
     
    3652   class COutputPin; 
    3753   class CSourceFilter; 
    38    class CStoreFilter; 
    39    class CFileWriterFilter; 
    40    class CFileServerWriterFilter; 
    41  
     54   class CServerToClientFilter; 
    4255   ///-------------------------------------------------------------- 
    4356 
     
    4659#  include "field_attribute.conf" 
    4760   END_DECLARE_ATTRIBUTE_MAP(CField) 
     61 
     62   class CContextClient ; 
    4863 
    4964   ///-------------------------------------------------------------- 
     
    5974         typedef CFieldAttributes SuperClassAttribute; 
    6075 
     76      public :    
    6177         enum EReadField 
    6278         { 
     
    7288         { 
    7389           EVENT_ID_UPDATE_DATA, EVENT_ID_READ_DATA, EVENT_ID_READ_DATA_READY, 
    74            EVENT_ID_ADD_VARIABLE, EVENT_ID_ADD_VARIABLE_GROUP 
     90           EVENT_ID_ADD_VARIABLE, EVENT_ID_ADD_VARIABLE_GROUP, EVENT_ID_GRID_COMPLETED 
    7591         }; 
    7692 
     
    89105 
    90106      public: 
    91          int getNStep(void) const; 
    92  
    93107         template <int N> void getData(CArray<double, N>& _data) const; 
    94  
    95          std::shared_ptr<COutputPin> getInstantDataFilter(); 
    96  
    97          /// Mutateur /// 
    98          void setRelFile(CFile* _file); 
    99          void incrementNStep(void); 
    100          void resetNStep(int nstep = 0); 
    101          void resetNStepMax(); 
    102108 
    103109         std::map<int, StdSize> getGridAttributesBufferSize(CContextClient* client, bool bufferForWriting = false); 
     
    105111         std::map<int, StdSize> getGridDataBufferSize(CContextClient* client, bool bufferForWriting = false); 
    106112 
    107          void setContextClient(CContextClient* newContextClient); 
    108          CContextClient* getContextClient(); 
    109  
     113       public: 
     114          void makeGridAliasForCoupling(void) ; 
    110115       public: 
    111116         bool isActive(bool atCurrentTimestep = false) const; 
     
    122127         void solveServerOperation(void); 
    123128         void solveCheckMaskIndex(bool doSendingIndex); 
    124          void solveAllReferenceEnabledField(bool doSending2Server); 
    125          void solveOnlyReferenceEnabledField(bool doSending2Server); 
    126          void generateNewTransformationGridDest(); 
    127129         void updateRef(CGrid* grid); 
    128          void buildGridTransformationGraph(); 
    129130         void solveGridDomainAxisRef(bool checkAtt); 
    130          void solveTransformedGrid(); 
    131          void solveGenerateGrid(); 
    132131         void solveGridDomainAxisBaseRef(); 
    133132 
    134          void solveAllEnabledFieldsAndTransform(); 
    135133         void checkGridOfEnabledFields(); 
    136134         void sendGridOfEnabledFields(); 
    137135         void sendGridComponentOfEnabledFields(); 
    138136 
     137         void sendFieldToFileServer(void) ; 
     138         void sendCloseDefinition(void) ; 
     139       
     140      public: 
     141         void sendFieldToCouplerOut(void) ; 
     142      private: 
     143         bool sendFieldToCouplerOut_done_=false; 
     144      public: 
     145 
     146         void sendFieldToInputFileServer(void) ; 
     147 
    139148         /// Vérifications /// 
    140149         void checkTimeAttributes(CDuration* freqOp=NULL); 
    141150 
    142          void buildFilterGraph(CGarbageCollector& gc, bool enableOutput, Time start_graph=-1, Time end_graph=-1); 
     151         bool buildWorkflowGraph(CGarbageCollector& gc) ; 
     152         bool buildWorkflowGraphDone_ = false ; 
     153 
    143154         size_t getGlobalWrittenSize(void) ; 
    144155          
    145156          
    146          std::shared_ptr<COutputPin> getFieldReference(CGarbageCollector& gc, Time start_graph=-1, Time end_graph=-1); 
    147          std::shared_ptr<COutputPin> getSelfReference(CGarbageCollector& gc, Time start_graph=-1, Time end_graph=-1); 
     157         std::shared_ptr<COutputPin> getSelfReference(CGarbageCollector& gc); 
    148158         std::shared_ptr<COutputPin> getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq); 
    149159         std::shared_ptr<COutputPin> getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq); 
     
    163173        static bool dispatchEvent(CEventServer& event); 
    164174        void sendAllAttributesToServer(CContextClient* client) ;  
    165         void sendUpdateData(const CArray<double,1>& data); 
    166         void sendUpdateData(const CArray<double,1>& data, CContextClient* client); 
     175         
    167176        static void recvUpdateData(CEventServer& event); 
    168         void recvUpdateData(std::map<int,CBufferIn*>& rankBuffers); 
    169         void writeField(void); 
     177        void receiveUpdateData(CEventServer& event);   
     178 
    170179        bool sendReadDataRequest(const CDate& tsDataRequested); 
    171180        bool sendReadDataRequestIfNeeded(void); 
    172181        static void recvReadDataRequest(CEventServer& event); 
    173182        void recvReadDataRequest(void); 
    174         EReadField readField(void); 
    175183        static void recvReadDataReady(CEventServer& event); 
    176         void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers); 
     184        void receiveReadDataReady(CEventServer& event); 
     185        void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers); // old interface to remove 
     186        void recvDataFromCoupler(vector<int> ranks, vector<CBufferIn*> buffers) ; // old interface to remove 
    177187        void checkForLateDataFromServer(void); 
    178         void checkIfMustAutoTrigger(void); 
    179         void autoTriggerIfNeeded(void); 
    180         void outputField(CArray<double,3>& fieldOut); 
    181         void outputField(CArray<double,2>& fieldOut); 
    182         void outputField(CArray<double,1>& fieldOut); 
    183         void inputField(CArray<double,3>& fieldOut); 
    184         void inputField(CArray<double,2>& fieldOut); 
    185         void inputField(CArray<double,1>& fieldOut); 
    186         void outputCompressedField(CArray<double, 1>& fieldOut); 
    187         void scaleFactorAddOffset(double scaleFactor, double addOffset); 
    188         void invertScaleFactorAddOffset(double scaleFactor, double addOffset); 
     188        void checkForLateDataFromCoupler(void) ; 
     189 
     190        void checkIfMustAutoTrigger(void); // ym obsolete 
     191        void autoTriggerIfNeeded(void); //ym obsolete 
     192        void triggerLateField(void) ; 
     193 
    189194        void parse(xml::CXMLNode& node); 
    190195 
     
    203208        void recvAddVariableGroup(CBufferIn& buffer);         
    204209        void sendAddAllVariables(CContextClient* client); 
    205         void writeUpdateData(const CArray<double,1>& data); 
    206210 
    207211        const std::vector<StdString>& getRefDomainAxisIds(); 
     
    211215 
    212216        bool hasGridMask(void) const; 
     217         
     218        void connectToFileServer(CGarbageCollector& gc) ; 
     219        void connectToCouplerOut(CGarbageCollector& gc) ; 
     220        void connectToCouplerIn(CGarbageCollector& gc) ; 
     221        void connectToModelInput(CGarbageCollector& gc) ; 
     222        void connectToFileWriter(CGarbageCollector& gc) ; 
     223        void connectToClientInput(CGarbageCollector& gc) ; 
     224        void connectToServerInput(CGarbageCollector& gc) ; 
     225        void connectToModelOutput(CGarbageCollector& gc); 
     226        void connectToFileReader(CGarbageCollector& gc) ; 
     227        void connectToServerToClient(CGarbageCollector& gc) ; 
     228 
     229        void setContextClientDataBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize,  
     230                                        map<CContextClient*,map<int,size_t>>& maxEventSize,  
     231                                        bool bufferForWriting) ; 
     232        void setContextClientAttributesBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize,  
     233                                                 map<CContextClient*,map<int,size_t>>& maxEventSize,  
     234                                                 bool bufferForWriting) ; 
     235      private: 
     236          bool isGridCompleted_ = true ; 
     237      public: 
     238          bool isGridCompleted() { return isGridCompleted_ ;}  
     239          void setGridCompleted(void) { isGridCompleted_= true; } 
     240          void unsetGridCompleted(void) { isGridCompleted_ = false ;} 
     241       
     242      public:      
     243          void sendGridCompleted(void) ; 
     244      private:    
     245          static void recvGridCompleted(CEventServer& event); 
     246          void recvGridCompleted(CBufferIn& buffer); 
     247 
     248 
     249      private: 
     250        std::vector<CGrid*> getGridPath(void) ; 
    213251 
    214252      public: 
     
    216254         CVariableGroup* vVariableGroup; 
    217255 
    218          CGrid*  grid; 
    219          CFile*  file; 
    220  
    221          CDuration freq_operation_srv, freq_write_srv; 
    222  
     256         CGrid*  grid_=nullptr; 
     257         CGrid* getGrid(void) { return grid_; }  
     258       
     259      private: 
     260         CGrid* sentGrid_=nullptr ; 
     261      public: 
     262         CGrid* getSentGrid(void) { return sentGrid_; }     
     263 
     264      public: 
     265//         CFile*  file; 
     266          
     267         CFile* fileIn_ = nullptr ; //<! pointer to input related file 
     268         bool hasFileIn(void) const { return fileIn_==nullptr ? false : true ;}  
     269         CFile* getFileIn(void) {return fileIn_;} 
     270         void setFileIn(CFile* fileIn) { fileIn_ = fileIn ;} 
     271         void unsetFileIn(void) { fileIn_ = nullptr ;} 
     272 
     273         CFile* fileOut_ = nullptr ; //<! pointer to output related file 
     274         bool hasFileOut(void) const { return fileOut_==nullptr ? false : true ;}  
     275         CFile* getFileOut(void) {return fileOut_;} 
     276         void setFileOut(CFile* fileOut) { fileOut_ = fileOut ;} 
     277         void unsetFileOut(void) { fileOut_ = nullptr ;} 
     278 
     279         CCouplerIn* couplerIn_ = nullptr ; //<!pointer to input related coupler 
     280         bool hasCouplerIn(void) const { return couplerIn_==nullptr ? false : true ;} 
     281         CCouplerIn* getCouplerIn(void) {return couplerIn_;} 
     282         void setCouplerIn(CCouplerIn* couplerIn) { couplerIn_ = couplerIn ;} 
     283         void unsetCouplerIn(void) { couplerIn_ = nullptr ;} 
     284 
     285         CCouplerOut* couplerOut_ = nullptr ; //<!pointer to output related coupler 
     286         bool hasCouplerOut(void) const { return couplerOut_==nullptr ? false : true ;} 
     287         CCouplerOut* getCouplerOut(void) {return couplerOut_;} 
     288         void setCouplerOut(CCouplerOut* couplerOut) { couplerOut_ = couplerOut ;} 
     289         void unsetCouplerOut(void) { couplerOut_ = nullptr ;} 
     290 
     291         bool modelIn_ = false ; //<! field can be received from model == true  
     292         bool getModelIn(void) { return modelIn_ ;} 
     293         void setModelIn(void) { modelIn_ = true ;} 
     294         void unsetModelIn(void) { modelIn_ = false ;} 
     295          
     296         bool modelOut_ = false ; //<! field can be retrieve to model == true 
     297         bool getModelOut(void) { return modelOut_ ;} 
     298         void setModelOut(void) { modelOut_ = true ;} 
     299         void unsetModelOut(void) { modelOut_ = false ;} 
     300 
     301          
    223302         bool written; //<! Was the field written at least once 
    224          int nstep, nstepMax; 
    225          bool isEOF; 
    226          CDate lastlast_Write_srv, last_Write_srv, last_operation_srv; 
    227          CDate lastDataRequestedFromServer, lastDataReceivedFromServer, dateEOF; 
    228          bool wasDataRequestedFromServer, wasDataAlreadyReceivedFromServer; 
    229303         bool mustAutoTrigger; 
    230304 
    231          map<int,std::shared_ptr<func::CFunctor> > foperation_srv; 
    232  
    233          // map<int, CArray<double,1> > data_srv; 
    234          CArray<double,1> recvDataSrv; 
    235           
    236          std::shared_ptr<func::CFunctor> recvFoperationSrv; 
    237305         string content; 
    238306 
     
    244312         bool hasTimeCentered; 
    245313 
    246          Time field_graph_start; 
    247          Time field_graph_end; 
    248  
    249314 
    250315         DECLARE_REF_FUNC(Field,field) 
    251  
     316         
    252317      private: 
    253318         CContextClient* client; 
     319      public: 
     320         void setContextClient(CContextClient* newContextClient); 
     321         CContextClient* getContextClient(void) {return client;} 
     322 
     323      private: 
    254324 
    255325         bool areAllReferenceSolved; 
     
    257327         bool isReferenceSolvedAndTransformed; 
    258328         bool isGridChecked; 
    259          bool nstepMaxRead; 
    260  
    261       private: 
     329 
     330       private:  
     331         //! define if the field is part of the active workflow. It will be tagged to true when CField::buildWorkflowGraph is successfull  
     332         bool workflowEnabled_ = false ; 
     333       public:  
     334         /*! workflowEnabled_ public accessor 
     335          * \return Value of workflowEnabled_ */ 
     336         bool getWorkflowEnabled(void) { return  workflowEnabled_; } 
     337  
     338 
     339      private: 
     340      
    262341         //! The type of operation attached to the field 
    263342         func::CFunctor::ETimeType operationTimeType; 
    264343 
     344         //! The output pin of the input filter of the field 
     345         std::shared_ptr<CPassThroughFilter> inputFilter; 
     346 
     347         //! The self temporal data filter 
     348         std::shared_ptr<CTemporalFilter> selfTemporalDataFilter ; 
     349          
    265350         //! The output pin of the filter providing the instant data for the field 
    266351         std::shared_ptr<COutputPin> instantDataFilter; 
     352      public: 
     353          std::shared_ptr<COutputPin> getInstantDataFilter(void) { return instantDataFilter;} 
     354 
     355      private: 
     356 
    267357         //! The output pin of the filters providing the result of the field's temporal operation 
    268358         std::map<CDuration, std::shared_ptr<COutputPin>, DurationFakeLessComparator> temporalDataFilters; 
     359          
    269360         //! The output pin of the filter providing the instant data for self references 
    270          std::shared_ptr<COutputPin> selfReferenceFilter; 
     361         std::shared_ptr<COutputPin> selfReferenceFilter; // probably redondant with inputFilter 
     362 
    271363         //! The source filter for data provided by the client 
    272          std::shared_ptr<CSourceFilter> clientSourceFilter; 
     364//         std::shared_ptr<CSourceFilter> clientSourceFilter; // obsolete to remove 
     365  
     366         //! The source filter for data provided by the model to enter the client workflow 
     367         std::shared_ptr<CModelToClientSourceFilter> modelToClientSourceFilter_; 
     368 
     369         //! The source filter for data provided by the model to enter the client workflow 
     370         std::shared_ptr<CClientToModelStoreFilter> clientToModelStoreFilter_; 
     371 
     372         //! The source filter for data provided by the client that send data to server workflow 
     373         std::shared_ptr<CServerFromClientSourceFilter> serverFromClientSourceFilter_; 
     374 
     375         //! The source filter for data provided by an other to enter the current client workflow (coupling mode) 
     376         std::shared_ptr<CClientFromClientSourceFilter> clientFromClientSourceFilter_; 
     377 
     378         //! The source filter for data provided by server to enter the current client workflow (reading mode) 
     379         std::shared_ptr<CClientFromServerSourceFilter> clientFromServerSourceFilter_; 
     380          
     381         //! The source filter for data read from file on server side  
     382         std::shared_ptr<CFileReaderSourceFilter> fileReaderSourceFilter_; 
     383 
    273384         //! The source filter for data provided by the server 
    274          std::shared_ptr<CSourceFilter> serverSourceFilter; 
    275          //! The terminal filter which stores the instant data 
    276          std::shared_ptr<CStoreFilter> storeFilter; 
    277          //! The terminal filter which writes the data to file 
    278          std::shared_ptr<CFileWriterFilter> fileWriterFilter; 
     385//         std::shared_ptr<CSourceFilter> serverSourceFilter; // obsolete to remove 
     386         
     387         //! The terminal filter which send data to server for writing 
     388         std::shared_ptr<CClientToServerStoreFilter> clientToServerStoreFilter_; 
     389         
    279390         //! The terminal filter which writes data to file 
    280          std::shared_ptr<CFileServerWriterFilter> fileServerWriterFilter; 
     391         std::shared_ptr<CFileWriterStoreFilter> fileWriterStoreFilter_; 
     392 
     393         //! The terminal filter which send data from server to client 
     394         std::shared_ptr<CServerToClientStoreFilter> serverToClientStoreFilter_; 
     395 
     396 
    281397   }; // class CField 
    282398 
  • XIOS/dev/dev_trunk_graph/src/node/field_impl.hpp

    r1653 r2019  
    99#include "timer.hpp" 
    1010#include "array_new.hpp" 
    11 #include "source_filter.hpp" 
    12 #include "store_filter.hpp" 
    1311 
    1412 
     
    1917  TRY 
    2018  { 
    21     if (clientSourceFilter) 
     19    if (modelToClientSourceFilter_) 
    2220    { 
    2321      if (check_if_active.isEmpty() || (!check_if_active.isEmpty() && (!check_if_active) || isActive(true))) 
    24         clientSourceFilter->streamData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 
     22        modelToClientSourceFilter_->streamData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 
    2523    } 
    2624    else if (instantDataFilter) 
     
    3432  TRY 
    3533  { 
    36     if (storeFilter) 
     34    if (clientToModelStoreFilter_) 
    3735    { 
    38       CDataPacket::StatusCode status = storeFilter->getData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 
     36      CDataPacket::StatusCode status = clientToModelStoreFilter_->getData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data); 
    3937 
    4038      if (status == CDataPacket::END_OF_STREAM) 
  • XIOS/dev/dev_trunk_graph/src/node/file.cpp

    r1612 r2019  
    145145   TRY 
    146146   { 
    147       if (!this->enabledFields.empty()) 
    148          return (this->enabledFields); 
    149  
    150       const int _outputlevel = 
    151          (!output_level.isEmpty()) ? output_level.getValue() : default_outputlevel; 
     147      if (!this->enabledFields.empty()) return (this->enabledFields); 
     148 
     149      const int _outputlevel = (!output_level.isEmpty()) ? output_level.getValue() : default_outputlevel; 
    152150      std::vector<CField*>::iterator it; 
    153151      this->enabledFields = this->getAllFields(); 
     
    176174 
    177175         newEnabledFields.push_back(*it); 
    178          // Le champ est finalement actif, on y ajoute la rfrence au champ de base. 
    179          (*it)->setRelFile(CFile::get(this)); 
    180176      } 
    181177      enabledFields = newEnabledFields; 
     
    226222      CContext* context = CContext::getCurrent(); 
    227223      const CDate& currentDate = context->calendar->getCurrentDate(); 
    228       CContextServer* server = context->server; 
    229224 
    230225      lastSync  = currentDate; 
     
    245240      isOpen = false;       
    246241 
    247 //      if (!record_offset.isEmpty() && record_offset < 0) 
    248 //        ERROR("void CFile::initFile(void)", 
    249 //              "Invalid 'record_offset', this attribute cannot be negative."); 
    250       const int recordOffset = record_offset.isEmpty() ? 0 : record_offset; 
    251  
    252242      set<StdString> setAxis; 
    253243      set<StdString> setDomains; 
     
    257247      { 
    258248         CField* field = *it;          
    259          std::vector<CAxis*> vecAxis = field->grid->getAxis(); 
     249         std::vector<CAxis*> vecAxis = field->getGrid()->getAxis(); 
    260250         for (size_t i = 0; i < vecAxis.size(); ++i) 
    261251           setAxis.insert(vecAxis[i]->getAxisOutputName()); 
    262          std::vector<CDomain*> vecDomains = field->grid->getDomains(); 
     252         std::vector<CDomain*> vecDomains = field->getGrid()->getDomains(); 
    263253         for (size_t i = 0; i < vecDomains.size(); ++i) 
    264254           setDomains.insert(vecDomains[i]->getDomainOutputName()); 
    265  
    266          field->resetNStep(recordOffset); 
    267255      } 
    268256      nbAxis = setAxis.size(); 
     
    272260      createSubComFile(); 
    273261 
    274       // if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); 
    275262      if (time_counter_name.isEmpty()) time_counter_name = "time_counter"; 
    276263    } 
     
    281268    TRY 
    282269    { 
     270      CContext* context = CContext::getCurrent(); 
    283271      if (checkRead) return; 
    284       createSubComFile(); 
     272      //createSubComFile(); 
     273      allZoneEmpty = false;  
     274      MPI_Comm_dup(context->intraComm_, &fileComm) ; 
    285275      checkRead = true; 
    286276    } 
     
    294284    { 
    295285      CContext* context = CContext::getCurrent(); 
    296       CContextServer* server = context->server; 
    297286 
    298287      // create sub communicator for file 
     
    302291      { 
    303292         CField* field = *it; 
    304          bool nullGrid = (0 == field->grid); 
    305          allZoneEmpty &= nullGrid ? false : !field->grid->doGridHaveDataToWrite(); 
     293         bool nullGrid = (nullptr == field->getGrid()); 
     294         allZoneEmpty &= nullGrid ? false : !field->getGrid()->doGridHaveDataToWrite(); 
    306295      } 
    307296 
    308297      int color = allZoneEmpty ? 0 : 1; 
    309       MPI_Comm_split(server->intraComm, color, server->intraCommRank, &fileComm); 
     298      MPI_Comm_split(context->intraComm_, color, context->intraCommRank_, &fileComm); 
    310299      if (allZoneEmpty) MPI_Comm_free(&fileComm); 
    311300    } 
     
    321310    { 
    322311      CContext* context = CContext::getCurrent(); 
    323       // Done by classical server or secondary server 
    324       // This condition should be changed soon 
    325       if (CServer::serverLevel == 0 || CServer::serverLevel == 2) 
     312 
     313      if (mode.isEmpty() || mode.getValue() == mode_attr::write) 
    326314      { 
    327         if (mode.isEmpty() || mode.getValue() == mode_attr::write) 
    328         { 
    329           CTimer::get("Files : create headers").resume(); 
    330           if (!isOpen) createHeader(); 
    331           CTimer::get("Files : create headers").suspend(); 
    332           checkSync(); 
    333         }         
    334         checkSplit(); // REally need this? 
    335       } 
     315        CTimer::get("Files : create headers").resume(); 
     316        if (!isOpen) createHeader(); 
     317        CTimer::get("Files : create headers").suspend(); 
     318        checkSync(); 
     319      }         
     320      checkSplit();  
    336321    } 
    337322    CATCH_DUMP_ATTR 
     
    349334      // Done by classical server or secondary server 
    350335      // TODO: This condition should be changed soon. It only works with maximum number of level as 2 
    351       if (CServer::serverLevel == 0 || CServer::serverLevel == 1) 
    352       { 
     336 
     337//ym      if (CServer::serverLevel == 0 || CServer::serverLevel == 1)  
     338// ym client must doing it also 
     339//      if (context->getServiceType()==CServicesManager::IO_SERVER || context->getServiceType()==CServicesManager::GATHERER) 
     340//      { 
    353341        if (!mode.isEmpty() && mode.getValue() == mode_attr::read) 
    354342        { 
     
    360348        } 
    361349        //checkSplit(); // Really need for reading? 
    362       } 
     350 //     } 
    363351    } 
    364352    CATCH_DUMP_ATTR 
     
    416404          lastSplit = lastSplit + split_freq.getValue(); 
    417405          std::vector<CField*>::iterator it, end = this->enabledFields.end(); 
    418           for (it = this->enabledFields.begin(); it != end; it++) 
     406/*          for (it = this->enabledFields.begin(); it != end; it++) 
    419407          { 
    420408            (*it)->resetNStep(); 
    421409            (*it)->resetNStepMax(); 
    422           } 
     410          }*/ 
    423411          if (mode.isEmpty() || mode.getValue() == mode_attr::write) 
    424412            createHeader(); 
     
    432420    CATCH_DUMP_ATTR 
    433421 
     422 
    434423   /*! 
    435424   \brief Create header of netcdf file 
     
    440429   { 
    441430      CContext* context = CContext::getCurrent(); 
    442       CContextServer* server = context->server; 
    443  
     431       
    444432      if (!allZoneEmpty) 
    445433      { 
     
    557545            MPI_Comm_rank(fileComm, &commRank); 
    558546 
    559             if (server->intraCommSize > 1) 
     547            if (context->intraCommSize_ > 1) 
    560548            { 
    561549              oss << "_" ; 
     
    633621  { 
    634622    CContext* context = CContext::getCurrent(); 
    635     CContextServer* server = context->server; 
    636623    MPI_Comm readComm = this->fileComm; 
    637624 
     
    680667        MPI_Comm_rank(readComm, &commRank); 
    681668 
    682         if (server->intraCommSize > 1) 
     669        if (context->intraCommSize_ > 1) 
    683670        { 
    684671          oss << "_"; 
     
    696683      bool isCollective = par_access.isEmpty() || par_access == par_access_attr::collective; 
    697684      bool readMetaDataPar = true; 
    698       if (!context->hasServer) readMetaDataPar = (read_metadata_par.isEmpty()) ? false : read_metadata_par; 
     685      if (context->getServiceType()==CServicesManager::CLIENT) readMetaDataPar = (read_metadata_par.isEmpty()) ? false : read_metadata_par; 
    699686 
    700687      if (isOpen) data_out->closeFile(); 
     
    747734 
    748735        // Now complete domain and axis associated with this field 
    749         enabledFields[idx]->solveGenerateGrid(); 
     736        
     737       //ym => this a problem in wich order are done the grid generation. Probably metadata are read in file and after the grid is ditributed by the filter 
     738       // => must be checked in detail. But solveGenerated grid is not existing any more with new transformation framework 
     739       // enabledFields[idx]->solveGenerateGrid(); 
    750740 
    751741        // Read necessary value from file 
     
    761751   CATCH_DUMP_ATTR 
    762752 
     753   void CFile::readFieldAttributesMetaData(CField* field) 
     754   { 
     755     this->data_in->readFieldAttributesMetaData(field); 
     756   } 
     757 
     758   void CFile::readFieldAttributesValues(CField* field) 
     759   { 
     760     this->data_in->readFieldAttributesValues(field); 
     761   } 
    763762   /*! 
    764763   \brief Parse xml file and write information into file object 
     
    822821 
    823822   //---------------------------------------------------------------- 
    824  
    825    /*! 
    826    \brief Resolve all reference of active fields. 
    827       In order to know exactly which data each active field has, a search for all its 
    828    reference to find its parents or/and its base reference object must be done. Moreover 
    829    during this search, there are some information that can only be sent to server AFTER 
    830    all information of active fields are created on server side, e.g: checking mask or index 
    831    \param [in] sendToServer: Send all info to server (true) or only a part of it (false) 
    832    */ 
    833    void CFile::solveOnlyRefOfEnabledFields(bool sendToServer) 
    834    TRY 
    835    { 
    836      int size = this->enabledFields.size(); 
    837      for (int i = 0; i < size; ++i) 
    838      { 
    839        this->enabledFields[i]->solveOnlyReferenceEnabledField(sendToServer); 
    840      } 
    841    } 
    842    CATCH_DUMP_ATTR 
    843823 
    844824   void CFile::checkGridOfEnabledFields() 
     
    931911   CATCH_DUMP_ATTR 
    932912 
    933    void CFile::generateNewTransformationGridDest() 
    934    TRY 
    935    { 
    936      int size = this->enabledFields.size(); 
    937      for (int i = 0; i < size; ++i) 
    938      { 
    939        this->enabledFields[i]->generateNewTransformationGridDest(); 
    940      } 
    941    } 
    942    CATCH_DUMP_ATTR 
    943  
    944    /*! 
    945    \brief Resolve all reference of active fields. 
    946       In order to know exactly which data each active field has, a search for all its 
    947    reference to find its parents or/and its base reference object must be done. Moreover 
    948    during this search, there are some information that can only be sent to server AFTER 
    949    all information of active fields are created on server side, e.g: checking mask or index 
    950    \param [in] sendToServer: Send all info to server (true) or only a part of it (false) 
    951    */ 
    952    void CFile::solveAllRefOfEnabledFieldsAndTransform(bool sendToServer) 
    953    TRY 
    954    { 
    955      int size = this->enabledFields.size(); 
    956      for (int i = 0; i < size; ++i) 
    957      {        
    958       this->enabledFields[i]->solveAllEnabledFieldsAndTransform(); 
    959      } 
    960    } 
    961    CATCH_DUMP_ATTR 
    962  
    963    /*! 
    964     * Constructs the filter graph for each active field. 
    965     * 
    966     * \param gc the garbage collector to use when building the filter graph 
    967     */ 
    968    void CFile::buildFilterGraphOfEnabledFields(CGarbageCollector& gc) 
    969    TRY 
    970    { 
    971      int size = this->enabledFields.size(); 
    972      for (int i = 0; i < size; ++i) 
    973      { 
    974        this->enabledFields[i]->buildFilterGraph(gc, true); 
    975      } 
    976    } 
    977    CATCH_DUMP_ATTR 
    978913 
    979914   /*! 
     
    13501285   CATCH_DUMP_ATTR 
    13511286 
     1287 
     1288   
     1289   /*! 
     1290    * Send file attribute, related variable and chield field tree to a given file server. 
     1291    * \param[in] client : the context client where to send file 
     1292    */ 
     1293   void CFile::sendFileToFileServer(CContextClient* client) 
     1294   TRY 
     1295   { 
     1296     if (sendFileToFileServer_done_.count(client)!=0) return ; 
     1297     else sendFileToFileServer_done_.insert(client) ; 
     1298      
     1299     StdString fileDefRoot("file_definition"); 
     1300     CFileGroup* cfgrpPtr = CFileGroup::get(fileDefRoot); 
     1301     cfgrpPtr->sendCreateChild(this->getId(), client); 
     1302     this->sendAllAttributesToServer(client); 
     1303     this->sendAddAllVariables(client); 
     1304     for(auto field : enabledFields) this->sendAddField(field->getId(), client); 
     1305   } 
     1306   CATCH_DUMP_ATTR 
    13521307   /*! 
    13531308   \brief Dispatch event received from client 
  • XIOS/dev/dev_trunk_graph/src/node/file.hpp

    r1612 r2019  
    104104         void close(void); 
    105105         void readAttributesOfEnabledFieldsInReadMode(); 
    106  
     106         void readFieldAttributesMetaData(CField* field) ; 
     107         void readFieldAttributesValues(CField* field) ; 
    107108         // Some processing on file 
    108109         void solveFieldRefInheritance(bool apply); 
    109110         void processEnabledFile(void); 
    110          void solveOnlyRefOfEnabledFields(bool sendToServer); 
    111          void generateNewTransformationGridDest(); 
    112111          
    113          void buildFilterGraphOfEnabledFields(CGarbageCollector& gc); 
    114112         void postProcessFilterGraph(); 
    115113         void prefetchEnabledReadModeFields(); 
     
    117115         void doPostTimestepOperationsForEnabledReadModeFields(); 
    118116 
    119          void solveAllRefOfEnabledFieldsAndTransform(bool sendToServer); 
    120117         void checkGridOfEnabledFields(); 
    121118         void sendGridOfEnabledFields(); 
     
    142139         void sendAddVariableGroup(const string& id, CContextClient* client); 
    143140         void sendAddAllVariables(CContextClient* client); 
    144           
     141      public: 
     142         void sendFileToFileServer(CContextClient* client) ; 
     143      private: 
     144         std::set<CContextClient*> sendFileToFileServer_done_ ; 
     145 
     146      public: 
    145147         // Receive info from client 
    146148         static void recvAddField(CEventServer& event); 
     
    173175         CDate lastSync; 
    174176         CDate lastSplit; 
     177          
     178         const CDate& getLastSplit(void) { return lastSplit ; } 
     179         
    175180         int nbAxis, nbDomains; 
    176181         bool isOpen;          
     
    192197         std::vector<CField*> enabledFields; 
    193198 
     199       private:   
     200         bool isClientSide_ ; // the file is on client side or on server side ? 
     201       public: 
     202         bool isClientSide(void) { return isClientSide_ ;} 
     203         bool isServerSide(void) { return !isClientSide_ ;} 
     204         void setClientSide(void) { isClientSide_=true ;} 
     205         void setServerSide(void) { isClientSide_=false ;} 
     206        
     207       private: 
     208 
    194209 
    195210      public: 
  • XIOS/dev/dev_trunk_graph/src/node/generate_rectilinear_domain.cpp

    r838 r2019  
    11#include "generate_rectilinear_domain.hpp" 
     2#include "domain_algorithm_generate_rectilinear.hpp" 
    23#include "type.hpp" 
    34 
     
    2728  bool CGenerateRectilinearDomain::registerTrans() 
    2829  { 
    29     registerTransformation(TRANS_GENERATE_RECTILINEAR_DOMAIN, create); 
     30    registerTransformation(TRANS_GENERATE_RECTILINEAR_DOMAIN, {create, getTransformation}); 
    3031  } 
    3132 
     
    138139  } 
    139140 
     141  CGenericAlgorithmTransformation* CGenerateRectilinearDomain::createAlgorithm(bool isSource, 
     142                                                        CGrid* gridDst, CGrid* gridSrc, 
     143                                                        int elementPositionInGrid, 
     144                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     145                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     146                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     147                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     148                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     149                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     150  { 
     151    return CDomainAlgorithmGenerateRectilinear::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     152                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     153                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     154  } 
    140155} 
  • XIOS/dev/dev_trunk_graph/src/node/generate_rectilinear_domain.hpp

    r836 r2019  
    2020  class CGenerateRectilinearDomain; 
    2121  class CDomain; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CGenerateRectilinearDomain> SuperClass; 
    4243      typedef CGenerateRectilinearDomainAttributes SuperClassAttribute; 
     44      typedef CGenerateRectilinearDomain MyClass ; 
     45      typedef CTransformation<CDomain> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_GENERATE_RECTILINEAR_DOMAIN ;} 
     63      static CTransformation<CDomain>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/grid.cpp

    r1612 r2019  
    1616#include "client_server_mapping_distributed.hpp" 
    1717#include "distribution_client.hpp" 
    18 #include "grid_transformation.hpp" 
    19 #include "grid_generate.hpp" 
    2018#include "server.hpp" 
    21  
    22 namespace xios { 
     19#include "distribution_type.hpp" 
     20#include "grid_remote_connector.hpp" 
     21#include "grid_elements.hpp" 
     22#include "grid_local_view.hpp" 
     23#include "grid_mask_connector.hpp" 
     24#include "transformation_path.hpp" 
     25#include "grid_transformation_factory_impl.hpp" 
     26#include "transform_filter.hpp" 
     27#include "grid_algorithm.hpp" 
     28#include "grid_algorithm_generic.hpp" 
     29#include "generic_algorithm_transformation.hpp" 
     30#include "algo_types.hpp" 
     31 
     32 
     33namespace xios 
     34{ 
    2335 
    2436   /// ////////////////////// Dfinitions ////////////////////// /// 
     
    3042      , vAxisGroup_(), axisList_(), isAxisListSet(false) 
    3143      , vScalarGroup_(), scalarList_(), isScalarListSet(false) 
    32       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    33       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
     44      , clientDistribution_(0), isIndexSent(false) 
    3445      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
    35           , isDataDistributed_(true), isCompressible_(false) 
    36       , transformations_(0), isTransformed_(false) 
     46            , isCompressible_(false) 
    3747      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    38       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    39       , computedWrittenIndex_(false) 
     48      , gridSrc_(), order_() 
    4049      , clients() 
    4150   { 
     
    5160      , vAxisGroup_(), axisList_(), isAxisListSet(false) 
    5261      , vScalarGroup_(), scalarList_(), isScalarListSet(false) 
    53       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    54       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
     62      , clientDistribution_(0), isIndexSent(false) 
    5563      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
    56           , isDataDistributed_(true), isCompressible_(false) 
    57       , transformations_(0), isTransformed_(false) 
     64            , isCompressible_(false) 
    5865      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    59       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    60       , computedWrittenIndex_(false) 
     66      , gridSrc_(), order_() 
    6167      , clients() 
    6268   { 
     
    6975   { 
    7076    if (0 != clientDistribution_) delete clientDistribution_; 
    71     if (0 != serverDistribution_) delete serverDistribution_; 
    72     if (0 != clientServerMap_) delete clientServerMap_; 
    73     if (0 != transformations_) delete transformations_; 
    7477   } 
    7578 
     
    8184 
    8285 
     86  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     87  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     88  /////////              MEMBER FUNCTION RELATED TO GRID CONSTRUCTION by ELEMNTS AND MANAGEMENT                      ///// 
     89  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     90  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     91 
     92 
     93   CGrid* CGrid::createGrid(CDomain* domain) 
     94   TRY 
     95   { 
     96     std::vector<CDomain*> vecDom(1, domain); 
     97     std::vector<CAxis*> vecAxis; 
     98     return createGrid(vecDom, vecAxis); 
     99   } 
     100   CATCH 
     101 
     102   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis) 
     103   TRY 
     104  { 
     105      std::vector<CDomain*> vecDom(1, domain); 
     106      std::vector<CAxis*> vecAxis(1, axis); 
     107 
     108      return createGrid(vecDom, vecAxis); 
     109   } 
     110   CATCH 
     111 
     112   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
     113                            const CArray<int,1>& axisDomainOrder) 
     114   TRY 
     115   { 
     116     std::vector<CScalar*> vecScalar; 
     117     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder); 
     118   } 
     119   CATCH 
     120 
     121   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
     122                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
     123   TRY 
     124   { 
     125     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder); 
     126   } 
     127   CATCH 
     128 
     129   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
     130                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
     131   TRY 
     132   { 
     133      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size())) 
     134        ERROR("CGrid* CGrid::createGrid(...)", 
     135              << "The size of axisDomainOrder (" << axisDomainOrder.numElements() 
     136              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<")."); 
     137 
     138      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id); 
     139      grid->setDomainList(domains); 
     140      grid->setAxisList(axis); 
     141      grid->setScalarList(scalars); 
     142 
     143      // By default, domains are always the first elements of a grid 
     144      if (0 == axisDomainOrder.numElements()) 
     145      { 
     146        int size = domains.size() + axis.size() + scalars.size(); 
     147        int nb = 0; 
     148        grid->axis_domain_order.resize(size); 
     149        for (int i = 0; i < size; ++i) 
     150        { 
     151          if (i < domains.size()) 
     152          { 
     153            grid->axis_domain_order(i) = 2; 
     154            grid->order_.push_back(2) ; 
     155          } 
     156          else if ((scalars.size() < (size-nb)) < size) 
     157          { 
     158            grid->axis_domain_order(i) = 1; 
     159            grid->order_.push_back(1) ; 
     160          } 
     161          else 
     162          { 
     163            grid->axis_domain_order(i) = 0; 
     164            grid->order_.push_back(0) ; 
     165          } 
     166          ++nb; 
     167        } 
     168      } 
     169      else 
     170      { 
     171        grid->axis_domain_order.resize(axisDomainOrder.numElements()); 
     172        grid->axis_domain_order = axisDomainOrder; 
     173        grid->order_.clear() ; 
     174        for(int i=0; i<axisDomainOrder.numElements();i++) grid->order_.push_back(axisDomainOrder(i)) ; 
     175 
     176      } 
     177       
     178 //     grid->solveElementsRefInheritance(true); 
     179      grid->computeElements() ; 
     180      return grid; 
     181   } 
     182   CATCH 
     183 
     184   //---------------------------------------------------------------- 
     185 
     186   //! Change virtual field group to a new one 
     187   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup) 
     188   TRY 
     189   { 
     190      this->vDomainGroup_ = newVDomainGroup; 
     191   } 
     192   CATCH_DUMP_ATTR 
     193 
     194   //! Change virtual variable group to new one 
     195   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup) 
     196   TRY 
     197   { 
     198      this->vAxisGroup_ = newVAxisGroup; 
     199   } 
     200   CATCH_DUMP_ATTR 
     201 
     202   //! Change virtual variable group to new one 
     203   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup) 
     204   TRY 
     205   { 
     206      this->vScalarGroup_ = newVScalarGroup; 
     207   } 
     208   CATCH_DUMP_ATTR 
     209 
     210   //---------------------------------------------------------------- 
     211 
     212   CDomainGroup* CGrid::getVirtualDomainGroup() const 
     213   TRY 
     214   { 
     215     return this->vDomainGroup_; 
     216   } 
     217   CATCH 
     218 
     219   CAxisGroup* CGrid::getVirtualAxisGroup() const 
     220   TRY 
     221   { 
     222     return this->vAxisGroup_; 
     223   } 
     224   CATCH 
     225 
     226   CScalarGroup* CGrid::getVirtualScalarGroup() const 
     227   TRY 
     228   { 
     229     return this->vScalarGroup_; 
     230   } 
     231   CATCH 
     232 
     233  ///--------------------------------------------------------------- 
     234 
     235   CDomain* CGrid::addDomain(const std::string& id) 
     236   TRY 
     237   { 
     238     order_.push_back(2); 
     239     axis_domain_order.resize(order_.size()); 
     240     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
     241     CDomain* domain = vDomainGroup_->createChild(id); 
     242     isDomListSet=false ; 
     243     computeElements(); 
     244     return domain ; 
     245   } 
     246   CATCH_DUMP_ATTR 
     247 
     248   CAxis* CGrid::addAxis(const std::string& id) 
     249   TRY 
     250   { 
     251     order_.push_back(1); 
     252     axis_domain_order.resize(order_.size()); 
     253     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
     254     CAxis* axis=vAxisGroup_->createChild(id); 
     255     isAxisListSet=false ; 
     256     computeElements();  
     257     return axis ; 
     258   } 
     259   CATCH_DUMP_ATTR 
     260 
     261   CScalar* CGrid::addScalar(const std::string& id) 
     262   TRY 
     263   { 
     264     order_.push_back(0); 
     265     axis_domain_order.resize(order_.size()); 
     266     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
     267     CScalar* scalar =  vScalarGroup_->createChild(id); 
     268     isScalarListSet=false ; 
     269     computeElements(); 
     270     return scalar; 
     271   } 
     272   CATCH_DUMP_ATTR 
     273 
     274 
     275 
     276 
     277  /*! 
     278  \brief Get the list of domain pointers 
     279  \return list of domain pointers 
     280  */ 
     281  std::vector<CDomain*> CGrid::getDomains() 
     282  TRY 
     283  { 
     284    setDomainList(); 
     285    std::vector<CDomain*> domList; 
     286    if (!domList_.empty()) 
     287    { 
     288      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i])); 
     289    } 
     290    return domList; 
     291  } 
     292  CATCH_DUMP_ATTR 
     293 
     294  /*! 
     295  \brief Get the list of  axis pointers 
     296  \return list of axis pointers 
     297  */ 
     298  std::vector<CAxis*> CGrid::getAxis() 
     299  TRY 
     300  { 
     301    setAxisList(); 
     302    std::vector<CAxis*> aList; 
     303    if (!axisList_.empty()) 
     304      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i])); 
     305 
     306    return aList; 
     307  } 
     308  CATCH_DUMP_ATTR 
     309 
     310  /*! 
     311  \brief Get the list of  axis pointers 
     312  \return list of axis pointers 
     313  */ 
     314  std::vector<CScalar*> CGrid::getScalars() 
     315  TRY 
     316  { 
     317    setScalarList() ; 
     318    std::vector<CScalar*> sList; 
     319    if (!scalarList_.empty()) 
     320      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i])); 
     321 
     322    return sList; 
     323  } 
     324  CATCH_DUMP_ATTR 
     325 
     326  /*! 
     327  \brief Get domain pointer with index 
     328  \return domain pointer 
     329  */ 
     330  CDomain* CGrid::getDomain(int domainIndex) 
     331  TRY 
     332  { 
     333    std::vector<CDomain*> domainListP = this->getDomains(); 
     334    if (domainListP.empty()) 
     335    { 
     336      ERROR("CGrid::getDomain(int domainIndex)", 
     337            << "No domain associated to this grid. " << std::endl 
     338            << "Grid id = " << this->getId()); 
     339    } 
     340 
     341    if (domainIndex >= domainListP.size() || (domainIndex < 0)) 
     342      ERROR("CGrid::getDomain(int domainIndex)", 
     343            << "Domain with the index doesn't exist " << std::endl 
     344            << "Grid id = " << this->getId() << std::endl 
     345            << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl); 
     346 
     347    return domainListP[domainIndex]; 
     348  } 
     349  CATCH_DUMP_ATTR 
     350 
     351  /*! 
     352  \brief Get the axis pointer with index 
     353  \return axis pointer 
     354  */ 
     355  CAxis* CGrid::getAxis(int axisIndex) 
     356  TRY 
     357  { 
     358    std::vector<CAxis*> axisListP = this->getAxis(); 
     359    if (axisListP.empty()) 
     360    { 
     361      ERROR("CGrid::getDomain(int axisIndex)", 
     362            << "No axis associated to this grid. " << std::endl 
     363            << "Grid id = " << this->getId()); 
     364    } 
     365 
     366    if (axisIndex >= axisListP.size() || (axisIndex < 0)) 
     367      ERROR("CGrid::getDomain(int axisIndex)", 
     368            << "Domain with the index doesn't exist " << std::endl 
     369            << "Grid id = " << this->getId() << std::endl 
     370            << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl); 
     371 
     372    return axisListP[axisIndex]; 
     373  } 
     374  CATCH_DUMP_ATTR 
     375 
     376  /*! 
     377  \brief Get the a scalar pointer 
     378  \return scalar pointer 
     379  */ 
     380  CScalar* CGrid::getScalar(int scalarIndex) 
     381  TRY 
     382  { 
     383    std::vector<CScalar*> scalarListP = this->getScalars(); 
     384    if (scalarListP.empty()) 
     385    { 
     386      ERROR("CGrid::getScalar(int scalarIndex)", 
     387            << "No scalar associated to this grid. " << std::endl 
     388            << "Grid id = " << this->getId()); 
     389    } 
     390 
     391    if (scalarIndex >= scalarListP.size() || (scalarIndex < 0)) 
     392      ERROR("CGrid::getScalar(int scalarIndex)", 
     393            << "Scalar with the index doesn't exist " << std::endl 
     394            << "Grid id = " << this->getId() << std::endl 
     395            << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl); 
     396 
     397    return scalarListP[scalarIndex]; 
     398  } 
     399  CATCH_DUMP_ATTR 
     400 
     401  /*! 
     402  \brief Set domain(s) of a grid from a list 
     403  \param[in] domains list of domains 
     404  */ 
     405  void CGrid::setDomainList(const std::vector<CDomain*> domains) 
     406  TRY 
     407  { 
     408    if (isDomListSet) return; 
     409    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 
     410    if (!domains.empty() && domList.empty()) 
     411    { 
     412      for (int i = 0; i < domains.size(); ++i) 
     413        this->getVirtualDomainGroup()->addChild(domains[i]); 
     414      domList = this->getVirtualDomainGroup()->getAllChildren(); 
     415    } 
     416 
     417    if (!domList.empty()) 
     418    { 
     419      int sizeDom = domList.size(); 
     420      domList_.resize(sizeDom); 
     421      for (int i = 0; i < sizeDom; ++i) 
     422      { 
     423        domList_[i] = domList[i]->getId(); 
     424      } 
     425      isDomListSet = true; 
     426    } 
     427  } 
     428  CATCH_DUMP_ATTR 
     429 
     430  /*! 
     431  \brief Set axis(s) of a grid from a list 
     432  \param[in] axis list of axis 
     433  */ 
     434  void CGrid::setAxisList(const std::vector<CAxis*> axis) 
     435  TRY 
     436  { 
     437    if (isAxisListSet) return; 
     438    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 
     439    if (!axis.empty() && aList.empty()) 
     440    { 
     441      for (int i = 0; i < axis.size(); ++i) 
     442        this->getVirtualAxisGroup()->addChild(axis[i]); 
     443      aList = this->getVirtualAxisGroup()->getAllChildren(); 
     444    } 
     445 
     446    if (!aList.empty()) 
     447    { 
     448      int sizeAxis = aList.size(); 
     449      axisList_.resize(sizeAxis); 
     450      for (int i = 0; i < sizeAxis; ++i) 
     451      { 
     452        axisList_[i] = aList[i]->getId(); 
     453      } 
     454      isAxisListSet = true; 
     455    } 
     456  } 
     457  CATCH_DUMP_ATTR 
     458 
     459  /*! 
     460  \brief Set scalar(s) of a grid from a list 
     461  \param[in] scalars list of scalars 
     462  */ 
     463  void CGrid::setScalarList(const std::vector<CScalar*> scalars) 
     464  TRY 
     465  { 
     466    if (isScalarListSet) return; 
     467    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 
     468    if (!scalars.empty() && sList.empty()) 
     469    { 
     470      for (int i = 0; i < scalars.size(); ++i) 
     471        this->getVirtualScalarGroup()->addChild(scalars[i]); 
     472      sList = this->getVirtualScalarGroup()->getAllChildren(); 
     473    } 
     474 
     475    if (!sList.empty()) 
     476    { 
     477      int sizeScalar = sList.size(); 
     478      scalarList_.resize(sizeScalar); 
     479      for (int i = 0; i < sizeScalar; ++i) 
     480      { 
     481        scalarList_[i] = sList[i]->getId(); 
     482      } 
     483      isScalarListSet = true; 
     484    } 
     485  } 
     486  CATCH_DUMP_ATTR 
     487 
     488  /*! 
     489  \brief Get list of id of domains 
     490  \return id list of domains 
     491  */ 
     492  std::vector<StdString> CGrid::getDomainList() 
     493  TRY 
     494  { 
     495    setDomainList(); 
     496    return domList_; 
     497  } 
     498  CATCH 
     499 
     500  /*! 
     501  \brief Get list of id of axis 
     502  \return id list of axis 
     503  */ 
     504  std::vector<StdString> CGrid::getAxisList() 
     505  TRY 
     506  { 
     507    setAxisList(); 
     508    return axisList_; 
     509  } 
     510  CATCH 
     511 
     512  /*! 
     513  \brief Get list of id of scalar 
     514  \return id list of scalar 
     515  */ 
     516  std::vector<StdString> CGrid::getScalarList() 
     517  TRY 
     518  { 
     519    setScalarList(); 
     520    return scalarList_; 
     521  } 
     522  CATCH 
     523 
     524 
     525  void CGrid::computeElements(void) 
     526  { 
     527    const auto& domains = getDomains() ; 
     528    const auto& axis = getAxis() ; 
     529    const auto& scalars = getScalars() ; 
     530    int idxDomain = 0, idxAxis=0 , idxScalar=0 ;  
     531  
     532    elements_.clear() ; 
     533    for(auto type : order_) 
     534    { 
     535      if      (type == 0) { elements_.push_back({scalars[idxScalar], TYPE_SCALAR, scalars[idxScalar], nullptr, nullptr } ) ; idxScalar++;} 
     536      else if (type == 1) { elements_.push_back({axis[idxAxis], TYPE_AXIS, nullptr, axis[idxAxis], nullptr}) ; idxAxis++;} 
     537      else if (type == 2) { elements_.push_back({domains[idxDomain], TYPE_DOMAIN, nullptr, nullptr, domains[idxDomain] }) ; idxDomain++;}         
     538    } 
     539    elementsComputed_ = true ; 
     540  } 
     541   
     542   
     543 /*! 
     544    Parse a grid, for now, it contains only domain, axis and scalar 
     545  */ 
     546  void CGrid::parse(xml::CXMLNode& node) 
     547  TRY 
     548  { 
     549    SuperClass::parse(node); 
     550 
     551    if (node.goToChildElement()) 
     552    { 
     553      StdString domainName("domain"); 
     554      StdString axisName("axis"); 
     555      StdString scalarName("scalar"); 
     556      do 
     557      { 
     558        if (node.getElementName() == domainName) { 
     559          order_.push_back(2); 
     560          this->getVirtualDomainGroup()->parseChild(node); 
     561        } 
     562        if (node.getElementName() == axisName) { 
     563          order_.push_back(1); 
     564          this->getVirtualAxisGroup()->parseChild(node); 
     565        } 
     566        if (node.getElementName() == scalarName) { 
     567          order_.push_back(0); 
     568          this->getVirtualScalarGroup()->parseChild(node); 
     569        } 
     570      } while (node.goToNextElement()); 
     571      node.goToParentElement(); 
     572    } 
     573 
     574    if (!order_.empty()) 
     575    { 
     576      int sizeOrd = order_.size(); 
     577      axis_domain_order.resize(sizeOrd); 
     578      for (int i = 0; i < sizeOrd; ++i) 
     579      { 
     580        axis_domain_order(i) = order_[i]; 
     581      } 
     582    } 
     583 
     584    setDomainList(); 
     585    setAxisList(); 
     586    setScalarList(); 
     587    computeElements() ; 
     588   } 
     589   CATCH_DUMP_ATTR 
     590 
     591 
     592  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     593  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     594  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     595  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     596 
     597 
     598 
    83599   StdSize CGrid::getDimension(void) 
    84600   TRY 
     
    90606   //--------------------------------------------------------------- 
    91607 
    92    StdSize CGrid::getDataSize(void) const 
     608   StdSize CGrid::getDataSize(void)  
    93609   TRY 
    94610   { 
     
    96612     if (!isScalarGrid()) 
    97613     { 
    98        std::vector<int> dataNindex = clientDistribution_->getDataNIndex(); 
     614       std::vector<int> dataNindex = getClientDistribution()->getDataNIndex(); 
    99615       for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];        
    100616     } 
     
    102618   } 
    103619   CATCH 
     620    
     621   /*! 
     622    * Get the local data grid size, ie the size of the compressed grid (inside the workflow) 
     623    * \return The size od the compressed grid 
     624    */ 
     625    StdSize  CGrid::getLocalDataSize(void) { return getClientDistribution()->getLocalDataSize();} 
     626 
    104627 
    105628   /*! 
     
    128651     for (size_t i = 0; i < axisList.size(); ++i) 
    129652     { 
    130        std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),axisPositionInGrid_[i]); 
     653       std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),getAxisPositionInGrid()[i]); 
    131654       for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it) 
    132655       { 
     
    202725   CATCH_DUMP_ATTR 
    203726    
    204    void CGrid::checkAttributesAfterTransformation() 
    205    TRY 
    206    { 
    207       setAxisList(); 
    208       std::vector<CAxis*> axisListP = this->getAxis(); 
    209       if (!axisListP.empty()) 
    210       { 
    211         int idx = 0; 
    212         axisPositionInGrid_.resize(0); 
    213         for (int i = 0; i < axis_domain_order.numElements(); ++i) 
    214         { 
    215           int elementDimension = axis_domain_order(i); 
    216           if (1 == elementDimension) 
    217           { 
    218             axisPositionInGrid_.push_back(idx); 
    219             ++idx; 
    220           } 
    221           else if (2 == elementDimension) idx += 2; 
    222         } 
    223  
    224         for (int i = 0; i < axisListP.size(); ++i) 
    225         { 
    226           axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(),axisPositionInGrid_[i]); 
    227         } 
    228       } 
    229  
    230       setDomainList(); 
    231       std::vector<CDomain*> domListP = this->getDomains(); 
    232       if (!domListP.empty()) 
    233       { 
    234         for (int i = 0; i < domListP.size(); ++i) 
    235         { 
    236           domListP[i]->checkAttributesOnClientAfterTransformation(); 
    237         } 
    238       } 
    239    } 
    240    CATCH_DUMP_ATTR 
    241  
    242    //--------------------------------------------------------------- 
    243  
     727 
     728   void CGrid::computeAxisPositionInGrid(void) 
     729   { 
     730     axisPositionInGrid_.resize(0); 
     731     int idx = 0; 
     732     for (int i = 0; i < axis_domain_order.numElements(); ++i) 
     733     { 
     734       int elementDimension = axis_domain_order(i); 
     735       if (1 == elementDimension) 
     736       { 
     737         axisPositionInGrid_.push_back(idx); 
     738         ++idx; 
     739       } 
     740       else if (2 == elementDimension) idx += 2; 
     741     } 
     742   } 
     743 
     744   
    244745   /*! 
    245746    * Test whether the data defined on the grid can be outputted in a compressed way. 
     
    327828   CATCH_DUMP_ATTR 
    328829 
     830   //ym obsolete -> to be removed later 
    329831   void CGrid::checkMaskIndex(bool doSendingIndex) 
    330832   TRY 
    331833   { 
    332834     CContext* context = CContext::getCurrent(); 
    333      int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;    
    334      nbSrvPools = 1;   
    335      for (int p = 0; p < nbSrvPools; ++p) 
    336      {     
    337        if (context->hasClient && this->isChecked && doSendingIndex && !isIndexSent)  
    338        {  
    339          if (isScalarGrid()) 
    340            sendIndexScalarGrid(); 
    341          else 
    342            sendIndex(); 
    343          this->isIndexSent = true;  
    344        } 
    345  
    346        // Not sure about this 
    347        //if (!(this->hasTransform() && !this->isTransformed())) 
    348        // this->isChecked = true; 
    349        //return; 
    350      } 
    351      
     835      
    352836     if (this->isChecked) return; 
    353      this->checkAttributesAfterTransformation(); 
    354  
    355      // TODO: Transfer grid attributes 
    356      //if (!context->hasClient && context->hasServer) this->createMask(); 
    357      this->computeIndex(); 
    358  
    359      if (!(this->hasTransform() && !this->isTransformed())) 
    360       this->isChecked = true; 
    361  
    362      if (!(this->hasTransform() && (!this->isGenerated()))) 
    363       this->isChecked = true; 
    364    } 
    365    CATCH_DUMP_ATTR 
     837     this->checkElementsAttributes(); 
     838     this->isChecked = true; 
     839   } 
     840   CATCH_DUMP_ATTR 
     841 
     842 
    366843   bool CGrid::hasMask() const 
    367844   TRY 
     
    372849   CATCH 
    373850 
    374    /* 
    375      Create mask of grid from mask of its components 
    376    */ 
    377    void CGrid::createMask(void) 
    378    TRY 
    379    { 
    380       using namespace std; 
    381       std::vector<CDomain*> domainP = this->getDomains(); 
    382       std::vector<CAxis*> axisP = this->getAxis(); 
    383       int dim = domainP.size() * 2 + axisP.size(); 
    384  
    385       std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    386       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    387       std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    388       for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
    389  
    390       switch (dim) { 
    391         case 1: 
    392           checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order, true); 
    393           break; 
    394         case 2: 
    395           checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order, true); 
    396           break; 
    397         case 3: 
    398           checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order, true); 
    399           break; 
    400         case 4: 
    401           checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order, true); 
    402           break; 
    403         case 5: 
    404           checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order, true); 
    405           break; 
    406         case 6: 
    407           checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order, true); 
    408           break; 
    409         case 7: 
    410           checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order, true); 
    411           break; 
    412         default: 
    413           break; 
    414       } 
    415    } 
    416    CATCH_DUMP_ATTR 
    417  
    418    /* 
    419      Check validity of grid's mask by using the masks of its components 
    420    */ 
    421    void CGrid::checkMask(void) 
    422    TRY 
    423    { 
    424       using namespace std; 
    425       std::vector<CDomain*> domainP = this->getDomains(); 
    426       std::vector<CAxis*> axisP = this->getAxis(); 
    427       int dim = domainP.size() * 2 + axisP.size(); 
    428  
    429       std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    430       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    431       std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    432       for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
    433  
    434       switch (dim) { 
    435         case 1: 
    436           checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order); 
    437           break; 
    438         case 2: 
    439           checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order); 
    440           break; 
    441         case 3: 
    442           checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order); 
    443           break; 
    444         case 4: 
    445           checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order); 
    446           break; 
    447         case 5: 
    448           checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order); 
    449           break; 
    450         case 6: 
    451           checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order); 
    452           break; 
    453         case 7: 
    454           checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order); 
    455           break; 
    456         default: 
    457           break; 
    458       } 
    459    } 
    460    CATCH_DUMP_ATTR 
    461  
    462    /* 
    463      Modify value of mask in a certain index 
    464      This function can be used to correct the mask of grid after being constructed with createMask 
    465      \param [in] indexToModify 
    466      \param [in] modifyValue 
    467    */ 
    468    void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue) 
    469    TRY 
    470    { 
    471       using namespace std; 
    472       std::vector<CDomain*> domainP = this->getDomains(); 
    473       std::vector<CAxis*> axisP = this->getAxis(); 
    474       int dim = domainP.size() * 2 + axisP.size(); 
    475  
    476       switch (dim) { 
    477         case 0: 
    478           modifyGridMask(mask_0d, indexToModify, modifyValue); 
    479           break; 
    480         case 1: 
    481           modifyGridMask(mask_1d, indexToModify, modifyValue); 
    482           break; 
    483         case 2: 
    484           modifyGridMask(mask_2d, indexToModify, modifyValue); 
    485           break; 
    486         case 3: 
    487           modifyGridMask(mask_3d, indexToModify, modifyValue); 
    488           break; 
    489         case 4: 
    490           modifyGridMask(mask_4d, indexToModify, modifyValue); 
    491           break; 
    492         case 5: 
    493           modifyGridMask(mask_5d, indexToModify, modifyValue); 
    494           break; 
    495         case 6: 
    496           modifyGridMask(mask_6d, indexToModify, modifyValue); 
    497           break; 
    498         case 7: 
    499           modifyGridMask(mask_7d, indexToModify, modifyValue); 
    500           break; 
    501         default: 
    502           break; 
    503       } 
    504    } 
    505    CATCH_DUMP_ATTR 
    506  
    507    /* 
    508      Change the mask size. This function is used on reconstructing mask in server side 
    509      \param [in] newDimensionSize 
    510      \param [in] newValue  
    511    */ 
    512    void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue) 
    513    TRY 
    514    {       
    515       std::vector<CDomain*> domainP = this->getDomains(); 
    516       std::vector<CAxis*> axisP = this->getAxis();             
    517       int dim = domainP.size() * 2 + axisP.size(); 
    518  
    519       switch (dim) { 
    520         case 0: 
    521           modifyGridMaskSize(mask_0d, newDimensionSize, newValue); 
    522           break; 
    523         case 1: 
    524           modifyGridMaskSize(mask_1d, newDimensionSize, newValue); 
    525           break; 
    526         case 2: 
    527           modifyGridMaskSize(mask_2d, newDimensionSize, newValue); 
    528           break; 
    529         case 3: 
    530           modifyGridMaskSize(mask_3d, newDimensionSize, newValue); 
    531           break; 
    532         case 4: 
    533           modifyGridMaskSize(mask_4d, newDimensionSize, newValue); 
    534           break; 
    535         case 5: 
    536           modifyGridMaskSize(mask_5d, newDimensionSize, newValue); 
    537           break; 
    538         case 6: 
    539           modifyGridMaskSize(mask_6d, newDimensionSize, newValue); 
    540           break; 
    541         case 7: 
    542           modifyGridMaskSize(mask_7d, newDimensionSize, newValue); 
    543           break; 
    544         default: 
    545           break; 
    546       } 
    547    } 
    548    CATCH_DUMP_ATTR 
    549  
     851    
     852   CArray<bool,1>& CGrid::getMask(void) 
     853   { 
     854       
     855      if (mask_.isEmpty()) 
     856      {   
     857        if (!mask_0d.isEmpty()) mask_.reference(CArray<bool,1>(mask_0d.dataFirst(),shape(mask_0d.numElements()), neverDeleteData)) ; 
     858        if (!mask_1d.isEmpty()) mask_.reference(CArray<bool,1>(mask_1d.dataFirst(),shape(mask_1d.numElements()), neverDeleteData)) ; 
     859        if (!mask_2d.isEmpty()) mask_.reference(CArray<bool,1>(mask_2d.dataFirst(),shape(mask_2d.numElements()), neverDeleteData)) ; 
     860        if (!mask_3d.isEmpty()) mask_.reference(CArray<bool,1>(mask_3d.dataFirst(),shape(mask_3d.numElements()), neverDeleteData)) ; 
     861        if (!mask_4d.isEmpty()) mask_.reference(CArray<bool,1>(mask_4d.dataFirst(),shape(mask_4d.numElements()), neverDeleteData)) ; 
     862        if (!mask_5d.isEmpty()) mask_.reference(CArray<bool,1>(mask_5d.dataFirst(),shape(mask_5d.numElements()), neverDeleteData)) ; 
     863        if (!mask_6d.isEmpty()) mask_.reference(CArray<bool,1>(mask_6d.dataFirst(),shape(mask_6d.numElements()), neverDeleteData)) ; 
     864        if (!mask_7d.isEmpty()) mask_.reference(CArray<bool,1>(mask_7d.dataFirst(),shape(mask_7d.numElements()), neverDeleteData)) ; 
     865      } 
     866      return mask_ ; 
     867   } 
     868 
     869   
    550870   //--------------------------------------------------------------- 
    551871 
     
    556876      std::vector<CDomain*> domListP = this->getDomains(); 
    557877      if (!domListP.empty()) 
    558       { 
    559         for (int i = 0; i < domListP.size(); ++i) 
    560         { 
    561           if (sendAtt) domListP[i]->sendCheckedAttributes(); 
    562           else domListP[i]->checkAttributesOnClient(); 
    563         } 
    564       } 
     878        for (int i = 0; i < domListP.size(); ++i) domListP[i]->checkAttributes(); 
    565879   } 
    566880   CATCH_DUMP_ATTR 
     
    574888      std::vector<CAxis*> axisListP = this->getAxis(); 
    575889      if (!axisListP.empty()) 
    576       { 
    577         int idx = 0; 
    578         axisPositionInGrid_.resize(0); 
    579         for (int i = 0; i < axis_domain_order.numElements(); ++i) 
    580         { 
    581           int elementDimension = axis_domain_order(i); 
    582           if (1 == elementDimension) 
    583           { 
    584             axisPositionInGrid_.push_back(idx); 
    585             ++idx; 
    586           } 
    587           else if (2 == elementDimension) idx += 2; 
    588         } 
    589  
    590         for (int i = 0; i < axisListP.size(); ++i) 
    591         { 
    592           if (sendAtt) 
    593             axisListP[i]->sendCheckedAttributes(getGlobalDimension(),axisPositionInGrid_[i]); 
    594           else 
    595             axisListP[i]->checkAttributesOnClient(); 
    596         } 
    597       } 
     890        for (int i = 0; i < axisListP.size(); ++i)  axisListP[i]->checkAttributes(); 
    598891   } 
    599892   CATCH_DUMP_ATTR 
     
    607900      std::vector<CScalar*> scalarListP = this->getScalars(); 
    608901      if (!scalarListP.empty()) 
    609       { 
    610         for (int i = 0; i < scalarListP.size(); ++i) 
    611         { 
    612           /*Nothing to do for now */ 
    613 //          if (sendAtt) scalarListP[i]->sendCheckedAttributes(); 
    614 //          else scalarListP[i]->checkAttributesOnClient(); 
    615         } 
    616       } 
    617    } 
    618    CATCH_DUMP_ATTR 
    619  
    620    /*! 
    621       Compute the index to for write data into a file 
    622    */ 
    623    void CGrid::computeWrittenIndex() 
    624    TRY 
    625    {       
    626       if (computedWrittenIndex_) return; 
    627       computedWrittenIndex_ = true; 
    628  
    629       if (isScalarGrid()) 
    630       { 
    631         size_t nbWritten = 1; 
    632         int writtenIndex = 0; 
    633  
    634         localIndexToWriteOnClient.resize(nbWritten);   
    635         localIndexToWriteOnServer.resize(nbWritten); 
    636         localIndexToWriteOnServer(0) = writtenIndex; 
    637         localIndexToWriteOnClient(0) = writtenIndex; 
    638          
    639         return; 
    640       } 
    641  
    642       size_t nbWritten = 0, indGlo; 
    643       CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
    644       CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(), 
    645                                                               ite = globalDataIndex.end(), it;     
    646       const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex();                                                               
    647       CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(), 
    648                                                           itSrve = globalLocalIndex.end(), itSrv; 
    649       for (it = itb; it != ite; ++it) 
    650       { 
    651         indGlo = it->first; 
    652         if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten;                 
    653       } 
    654  
    655       localIndexToWriteOnClient.resize(nbWritten);   
    656       localIndexToWriteOnServer.resize(nbWritten); 
    657        
    658       { 
    659         numberWrittenIndexes_ = nbWritten; 
    660         if (isDataDistributed_) 
    661         { 
    662           CContextServer* server = CContext::getCurrent()->server;       
    663           MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    664           MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    665           offsetWrittenIndexes_ -= numberWrittenIndexes_; 
    666         } 
    667         else 
    668           totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
    669       } 
    670  
    671       nbWritten = 0;  
    672       for (it = itb; it != ite; ++it) 
    673       { 
    674         indGlo = it->first; 
    675         itSrv = globalLocalIndex.find(indGlo); 
    676         if (itSrve != itSrv) 
    677         { 
    678           localIndexToWriteOnServer(nbWritten) = itSrv->second; 
    679           localIndexToWriteOnClient(nbWritten) = it->second; 
    680           ++nbWritten;                 
    681         }  
    682       } 
    683    } 
    684    CATCH_DUMP_ATTR 
    685  
    686    //--------------------------------------------------------------- 
    687  
    688    /* 
    689      Compute the global index and its local index taking account mask and data index. 
    690      These global indexes will be used to compute the connection of this client (sender) to its servers (receivers) 
    691      (via function computeConnectedClient) 
    692      These global indexes also correspond to data sent to servers (if any) 
    693    */ 
    694    void CGrid::computeClientIndex() 
    695    TRY 
    696    { 
     902        for (int i = 0; i < scalarListP.size(); ++i) scalarListP[i]->checkAttributes() ; 
     903   } 
     904   CATCH_DUMP_ATTR 
     905 
     906 
     907    //--------------------------------------------------------------- 
     908   CDistributionClient* CGrid::getClientDistribution() 
     909   TRY 
     910   { 
     911     if (!computeClientDistribution_done_) computeClientDistribution() ; 
     912     return clientDistribution_; 
     913   } 
     914   CATCH_DUMP_ATTR 
     915    
     916   void CGrid::computeClientDistribution(void) 
     917   { 
     918     if (computeClientDistribution_done_) return ; 
     919     else computeClientDistribution_done_ = true ; 
     920 
    697921     CContext* context = CContext::getCurrent(); 
    698  
    699      CContextClient* client = context->client; 
    700      int rank = client->clientRank; 
    701  
     922     int rank = context-> getIntraCommRank(); 
    702923     clientDistribution_ = new CDistributionClient(rank, this); 
    703      // Get local data index on client 
    704      int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size(); 
    705      int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size(); 
    706      // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise 
    707      storeIndex_client.resize(nbStoreIndex); 
    708      storeMask_client.resize(nbStoreGridMask); 
    709      for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 
    710      for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client(idx) = (clientDistribution_->getLocalMaskIndexOnClient())[idx]; 
    711  
    712      if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 
    713      else 
    714      { 
    715         // Mapping global index received from clients to the storeIndex_client 
    716         CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
    717         CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 
    718         map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
    719                                                ite = outGlobalIndexFromClient.end(), it; 
    720  
    721         for (it = itb; it != ite; ++it) 
    722         { 
    723           int rank = it->first; 
    724           CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
    725           outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    726           CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
    727           size_t nbIndex = 0; 
    728  
    729           // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 
    730           for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    731           { 
    732             if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    733             { 
    734               ++nbIndex; 
    735             } 
    736           } 
    737  
    738           if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 
    739                ERROR("void CGrid::computeClientIndex()", 
    740                   << "Number of local index on client is different from number of received global index" 
    741                   << "Rank of sent client " << rank <<"." 
    742                   << "Number of local index " << nbIndex << ". " 
    743                   << "Number of received global index " << localIndex.numElements() << "."); 
    744  
    745           nbIndex = 0; 
    746           for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    747           { 
    748             if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    749             { 
    750               localIndex(idx) = globalDataIndex[globalIndex(idx)]; 
    751             } 
    752           } 
    753         } 
    754       } 
    755    } 
    756    CATCH_DUMP_ATTR 
    757  
    758    /*! 
    759      Compute connected receivers and indexes to be sent to these receivers. 
    760    */ 
    761    void CGrid::computeConnectedClients() 
    762    TRY 
    763    { 
    764      CContext* context = CContext::getCurrent(); 
    765      int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size(); 
    766      connectedServerRank_.clear(); 
    767      connectedDataSize_.clear(); 
    768      globalIndexOnServer_.clear(); 
    769      nbSenders.clear(); 
    770  
    771      for (int p = 0; p < nbSrvPools; ++p) 
    772      { 
    773        CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p]; 
    774        int receiverSize = client->serverSize; 
    775 //       connectedServerRank_[client].clear(); 
    776  
    777        if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end()) 
    778        { 
    779         if (!doGridHaveDataDistributed(client)) 
    780          { 
    781             if (client->isServerLeader()) 
    782             { 
    783               size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 
    784               const std::list<int>& ranks = client->getRanksServerLeader(); 
    785               for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    786               { 
    787                 connectedServerRank_[receiverSize].push_back(*itRank); 
    788                 connectedDataSize_[receiverSize][*itRank] = ssize; 
    789               } 
    790             } 
    791             return; 
    792          } 
    793  
    794          // Compute mapping between client and server 
    795          std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
    796          CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
    797          std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
    798                                                                                                     client->clientRank, 
    799                                                                                                     client->clientSize, 
    800                                                                                                     axis_domain_order, 
    801                                                                                                     getDistributedDimension()); 
    802  
    803          // Even if servers have no index, they must received something from client 
    804          // We only use several client to send "empty" message to these servers 
    805          std::list<int> serverZeroIndexLeader; 
    806          std::list<int> serverZeroIndexNotLeader; 
    807          CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
    808          for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    809            *it = serverZeroIndex[*it]; 
    810  
    811          if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 
    812            computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 
    813  
    814          const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    815          CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
    816          CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
    817          itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
    818          iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
    819  
    820          for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    821          { 
    822            int serverRank = itGlobalMap->first; 
    823            int indexSize = itGlobalMap->second.size(); 
    824            const std::vector<size_t>& indexVec = itGlobalMap->second; 
    825            for (int idx = 0; idx < indexSize; ++idx) 
    826            { 
    827               itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 
    828               if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 
    829               { 
    830                 if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 
    831                   connectedDataSize_[receiverSize][serverRank] = 1; 
    832                 else 
    833                   ++connectedDataSize_[receiverSize][serverRank]; 
    834               } 
    835            } 
    836          } 
    837  
    838          // Connected servers which really have index 
    839          for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 
    840            connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 
    841          } 
    842  
    843          // Connected servers which have no index at all 
    844          for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    845            connectedServerRank_[receiverSize].push_back(*it); 
    846  
    847          // Even if a client has no index, it must connect to at least one server and 
    848          // send an "empty" data to this server 
    849          if (connectedServerRank_[receiverSize].empty()) 
    850           connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 
    851  
    852          // Now check if all servers have data to receive. If not, master client will send empty data. 
    853          // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 
    854          std::vector<int> counts (client->clientSize); 
    855          std::vector<int> displs (client->clientSize); 
    856          displs[0] = 0; 
    857          int localCount = connectedServerRank_[receiverSize].size() ; 
    858          MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 
    859          for (int i = 0; i < client->clientSize-1; ++i) 
    860          { 
    861            displs[i+1] = displs[i] + counts[i]; 
    862          } 
    863          std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]); 
    864          MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 
    865  
    866          if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0)) 
    867          { 
    868            std::vector<bool> isSrvConnected (receiverSize, false); 
    869            for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 
    870            for (int i = 0; i < receiverSize; ++i) 
    871            { 
    872              if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i); 
    873            } 
    874          } 
    875  
    876          nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 
    877        } 
    878      } 
    879    } 
    880    CATCH_DUMP_ATTR 
    881  
    882    /*! 
    883      Compute the global index of grid to send to server as well as the connected server of the current client. 
    884      First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know 
    885      their global index. We can have a map of global index of grid and local index that each client holds 
    886      Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s) 
    887      of the current client. 
    888    */ 
    889    void CGrid::computeIndex(void) 
    890    TRY 
    891    { 
    892      CContext* context = CContext::getCurrent(); 
    893      if (isScalarGrid()) 
    894      { 
    895        computeClientIndexScalarGrid(); 
    896        if (context->hasClient) 
    897        { 
    898          computeConnectedClientsScalarGrid(); 
    899        } 
    900      } 
    901      else 
    902      { 
    903        computeClientIndex(); 
    904        if (context->hasClient) 
    905        { 
    906          computeConnectedClients(); 
    907        } 
    908      } 
    909      if (CServer::serverLevel==2) 
    910      { 
    911        computeWrittenIndex() ; 
    912        if (serverDistribution_!=0) serverDistribution_->partialClear() ; 
    913        if (clientDistribution_!=0) clientDistribution_->partialClear() ; 
    914        outGlobalIndexFromClient.clear() ; 
    915      } 
    916    } 
    917    CATCH_DUMP_ATTR 
    918  
    919    /*! 
    920       Compute the global of (client) grid to send to server with the global index of each element of grid 
    921       Each element of grid has its own global index associated to a groups of server. We only search for the global index of each element whose 
    922       server is the same, then calculate the global index of grid. This way can reduce so much the time for executing DHT, which only needs to run 
    923       on each element whose size is much smaller than one of whole grid. 
    924       \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 
    925       \param [in] client contextClient 
    926       \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 
    927    */ 
    928    void CGrid::computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
    929                                      const CContextClient* client, 
    930                                      CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 
    931    TRY 
    932    { 
    933      int serverSize = client->serverSize; 
    934  
    935      std::vector<CDomain*> domList = getDomains(); 
    936      std::vector<CAxis*> axisList = getAxis(); 
    937  
    938      // Some pre-calculations of global index on each element of current grid. 
    939      int nbElement = axis_domain_order.numElements(); 
    940      std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 
    941      int domainIdx = 0, axisIdx = 0, scalarIdx = 0; 
    942      std::vector<size_t> elementNGlobal(nbElement); 
    943      elementNGlobal[0] = 1; 
    944      size_t globalSize = 1; 
    945      for (int idx = 0; idx < nbElement; ++idx) 
    946      { 
    947        elementNGlobal[idx] = globalSize; 
    948        size_t elementSize; 
    949        size_t elementGlobalSize = 1; 
    950        if (2 == axis_domain_order(idx)) // This is domain 
    951        { 
    952          elementSize = domList[domainIdx]->i_index.numElements(); 
    953          globalIndexElement[idx].resize(elementSize); 
    954          for (int jdx = 0; jdx < elementSize; ++jdx) 
    955          { 
    956            globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 
    957          } 
    958          elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 
    959          ++domainIdx; 
    960        } 
    961        else if (1 == axis_domain_order(idx))  // This is axis 
    962        { 
    963          elementSize = axisList[axisIdx]->index.numElements(); 
    964          globalIndexElement[idx].resize(elementSize); 
    965          for (int jdx = 0; jdx < elementSize; ++jdx) 
    966          { 
    967            globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 
    968          } 
    969          elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 
    970          ++axisIdx; 
    971        } 
    972        else  // Of course, this is scalar 
    973        { 
    974          globalIndexElement[idx].resize(1); 
    975          globalIndexElement[idx](0) = 0; 
    976          elementGlobalSize = 1; 
    977        } 
    978        globalSize *= elementGlobalSize; 
    979      } 
    980  
    981      std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 
    982      std::vector<std::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 
    983      CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server 
    984      // Number of temporary distributed global index held by each client for each server 
    985      // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank 
    986      CArray<int,1> nbIndexOnServerTmp(serverSize); 
    987      for (int idx = 0; idx < nbElement; ++idx) 
    988      { 
    989        nbIndexOnServer = 0; 
    990        const std::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 
    991        const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 
    992        CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 
    993        clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 
    994        const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 
    995        CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 
    996                                                                     ite = globalIndexElementOnServerMap.end(), it; 
    997        for (it = itb; it != ite; ++it) 
    998        { 
    999          const std::vector<int>& tmp = it->second; 
    1000          nbIndexOnServerTmp = 0; 
    1001          for (int i = 0; i < tmp.size(); ++i) 
    1002          { 
    1003            if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]); 
    1004          } 
    1005          nbIndexOnServer += nbIndexOnServerTmp; 
    1006        } 
    1007  
    1008        for (int i = 0; i < serverSize; ++i) 
    1009        { 
    1010          if (0 != nbIndexOnServer(i)) 
    1011          { 
    1012            globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i)); 
    1013            elementOnServer[idx][i] = true; 
    1014          } 
    1015        } 
    1016  
    1017      nbIndexOnServer = 0; 
    1018      for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 
    1019      { 
    1020        it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 
    1021        if (it != ite) 
    1022        { 
    1023          const std::vector<int>& tmp = it->second; 
    1024          nbIndexOnServerTmp = 0; 
    1025          for (int i = 0; i < tmp.size(); ++i) 
    1026          { 
    1027            if (0 == nbIndexOnServerTmp(tmp[i])) 
    1028            { 
    1029              globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first; 
    1030              ++nbIndexOnServerTmp(tmp[i]); 
    1031            } 
    1032          } 
    1033          nbIndexOnServer += nbIndexOnServerTmp; 
    1034        } 
    1035      } 
    1036    } 
    1037  
    1038     // Determine server which contain global source index 
    1039     std::vector<bool> intersectedProc(serverSize, true); 
    1040     for (int idx = 0; idx < nbElement; ++idx) 
    1041     { 
    1042       std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 
    1043                      intersectedProc.begin(), intersectedProc.begin(), 
    1044                      std::logical_and<bool>()); 
    1045     } 
    1046  
    1047     std::vector<int> srcRank; 
    1048     for (int idx = 0; idx < serverSize; ++idx) 
    1049     { 
    1050       if (intersectedProc[idx]) srcRank.push_back(idx); 
    1051     } 
    1052  
    1053     // Compute the global index of grid from global index of each element. 
    1054     for (int i = 0; i < srcRank.size(); ++i) 
    1055     { 
    1056       size_t ssize = 1; 
    1057       int rankSrc = srcRank[i]; 
    1058       std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 
    1059       std::vector<size_t> currentIndex(nbElement,0); 
    1060       for (int idx = 0; idx < nbElement; ++idx) 
    1061       { 
    1062         ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 
    1063         globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 
    1064       } 
    1065       globalIndexOnServer[rankSrc].resize(ssize); 
    1066  
    1067       std::vector<int> idxLoop(nbElement,0); 
    1068       int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 
    1069       size_t idx = 0; 
    1070       while (idx < ssize) 
    1071       { 
    1072         for (int ind = 0; ind < nbElement; ++ind) 
    1073         { 
    1074           if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 
    1075           { 
    1076             idxLoop[ind] = 0; 
    1077             ++idxLoop[ind+1]; 
    1078           } 
    1079  
    1080           currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 
    1081         } 
    1082  
    1083         for (int ind = 0; ind < innnerLoopSize; ++ind) 
    1084         { 
    1085           currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 
    1086           size_t globalSrcIndex = 0; 
    1087           for (int idxElement = 0; idxElement < nbElement; ++idxElement) 
    1088           { 
    1089             globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 
    1090           } 
    1091           globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 
    1092           ++idx; 
    1093           ++idxLoop[0]; 
    1094         } 
    1095       } 
    1096     } 
    1097    } 
    1098    CATCH_DUMP_ATTR 
    1099 //---------------------------------------------------------------- 
    1100  
    1101    CGrid* CGrid::createGrid(CDomain* domain) 
    1102    TRY 
    1103    { 
    1104       std::vector<CDomain*> vecDom(1, domain); 
    1105       std::vector<CAxis*> vecAxis; 
    1106  
    1107       return createGrid(vecDom, vecAxis); 
    1108    } 
    1109    CATCH 
    1110  
    1111    CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis) 
    1112    TRY 
    1113   { 
    1114       std::vector<CDomain*> vecDom(1, domain); 
    1115       std::vector<CAxis*> vecAxis(1, axis); 
    1116  
    1117       return createGrid(vecDom, vecAxis); 
    1118    } 
    1119    CATCH 
    1120  
    1121    CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
    1122                             const CArray<int,1>& axisDomainOrder) 
    1123    TRY 
    1124    { 
    1125      std::vector<CScalar*> vecScalar; 
    1126      return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder); 
    1127    } 
    1128    CATCH 
    1129  
    1130    CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
    1131                             const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
    1132    TRY 
    1133    { 
    1134      return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder); 
    1135    } 
    1136    CATCH 
    1137  
    1138    CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
    1139                             const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
    1140    TRY 
    1141    { 
    1142       if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size())) 
    1143         ERROR("CGrid* CGrid::createGrid(...)", 
    1144               << "The size of axisDomainOrder (" << axisDomainOrder.numElements() 
    1145               << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<")."); 
    1146  
    1147       CGrid* grid = CGridGroup::get("grid_definition")->createChild(id); 
    1148       grid->setDomainList(domains); 
    1149       grid->setAxisList(axis); 
    1150       grid->setScalarList(scalars); 
    1151  
    1152       // By default, domains are always the first elements of a grid 
    1153       if (0 == axisDomainOrder.numElements()) 
    1154       { 
    1155         int size = domains.size() + axis.size() + scalars.size(); 
    1156         int nb = 0; 
    1157         grid->axis_domain_order.resize(size); 
    1158         for (int i = 0; i < size; ++i) 
    1159         { 
    1160           if (i < domains.size()) { 
    1161             grid->axis_domain_order(i) = 2; 
    1162  
    1163           } 
    1164           else if ((scalars.size() < (size-nb)) < size) { 
    1165             grid->axis_domain_order(i) = 1; 
    1166           } 
    1167           else 
    1168             grid->axis_domain_order(i) = 0; 
    1169           ++nb; 
    1170         } 
    1171       } 
    1172       else 
    1173       { 
    1174         grid->axis_domain_order.resize(axisDomainOrder.numElements()); 
    1175         grid->axis_domain_order = axisDomainOrder; 
    1176       } 
    1177  
    1178       grid->solveDomainAxisRefInheritance(true); 
    1179  
    1180       return grid; 
    1181    } 
    1182    CATCH 
     924   } 
     925 
     926 
     927  bool CGrid::isDataDistributed(void)  
     928  {  
     929    return getClientDistribution()->isDataDistributed() ; 
     930  } 
     931 
     932   
    1183933 
    1184934   CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc) 
     
    12831033   CATCH 
    12841034 
     1035 
    12851036   //---------------------------------------------------------------- 
    12861037 
    1287    CDomainGroup* CGrid::getVirtualDomainGroup() const 
    1288    TRY 
    1289    { 
    1290      return this->vDomainGroup_; 
    1291    } 
    1292    CATCH 
    1293  
    1294    CAxisGroup* CGrid::getVirtualAxisGroup() const 
    1295    TRY 
    1296    { 
    1297      return this->vAxisGroup_; 
    1298    } 
    1299    CATCH 
    1300  
    1301    CScalarGroup* CGrid::getVirtualScalarGroup() const 
    1302    TRY 
    1303    { 
    1304      return this->vScalarGroup_; 
    1305    } 
    1306    CATCH 
    1307  
    1308 /* 
    1309    void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field) 
    1310    { 
    1311      const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 
    1312      StdSize numElements = stored.numElements(); 
    1313      for (StdSize n = 0; n < numElements; ++n) 
    1314      { 
    1315        field[out_i(n)] = stored(n); 
    1316      } 
    1317    } 
    1318  
    1319    void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored) 
    1320    { 
    1321      const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 
    1322      StdSize numElements = stored.numElements(); 
    1323      for (StdSize n = 0; n < numElements; ++n) 
    1324      { 
    1325        stored(n) = field[out_i(n)]; 
    1326      } 
    1327    } 
    1328  
    1329    void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field) 
    1330    { 
    1331      const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank]; 
    1332      StdSize numElements = stored.numElements(); 
    1333      for (StdSize n = 0; n < numElements; ++n) 
    1334      { 
    1335        field[out_i(n)] = stored(n); 
    1336      } 
    1337    } 
    1338 */ 
    1339    //---------------------------------------------------------------- 
    1340  
    1341    void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const 
    1342    TRY 
    1343    { 
    1344       const StdSize size = storeIndex_client.numElements(); 
    1345  
    1346       stored.resize(size); 
    1347       for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 
    1348    } 
    1349    CATCH 
    1350  
    1351    void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const 
    1352    TRY 
    1353    { 
    1354       const StdSize size = storeIndex_client.numElements(); 
    1355  
    1356       for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i); 
    1357    } 
    1358    CATCH 
    1359  
    1360    void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const 
    1361    { 
    1362       const StdSize size = storeIndex_client.numElements(); 
    1363       stored.resize(size); 
    1364       const double nanValue = std::numeric_limits<double>::quiet_NaN(); 
    1365  
    1366       if (storeMask_client.numElements() != 0) 
    1367         for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue; 
    1368       else 
    1369         for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 
    1370    } 
    1371  
    1372    void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 
    1373    TRY 
    1374    { 
    1375       const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient(); 
    1376       const int size = localMaskedDataIndex.size(); 
    1377       for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i]; 
    1378    } 
    1379    CATCH 
    1380  
    1381   void CGrid::computeClientIndexScalarGrid() 
    1382   TRY 
    1383   { 
    1384     CContext* context = CContext::getCurrent();     
    1385     { 
    1386       CContextClient* client = context->client; 
    1387  
    1388       int rank = client->clientRank; 
    1389  
    1390       clientDistribution_ = new CDistributionClient(rank, this); 
    1391  
    1392       storeIndex_client.resize(1); 
    1393       storeIndex_client(0) = 0;       
    1394  
    1395       if (0 != serverDistribution_) 
    1396       { 
    1397         map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
    1398                                                ite = outGlobalIndexFromClient.end(), it; 
    1399         for (it = itb; it != ite; ++it) 
    1400         { 
    1401           int rank = it->first; 
    1402           CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
    1403           outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    1404           CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
    1405           if (1 != globalIndex.numElements()) 
    1406             ERROR("void CGrid::computeClientIndexScalarGrid()", 
    1407               << "Something wrong happened. " 
    1408               << "Number of received global index on scalar grid should equal to 1"  
    1409               << "Number of received global index " << globalIndex.numElements() << "."); 
    1410  
    1411           localIndex(0) = globalIndex(0); 
    1412         } 
    1413       } 
    1414     } 
    1415   } 
    1416   CATCH_DUMP_ATTR 
    1417  
    1418   void CGrid::computeConnectedClientsScalarGrid() 
    1419   TRY 
    1420   { 
    1421     CContext* context = CContext::getCurrent();     
    1422     int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size(); 
    1423     connectedServerRank_.clear(); 
    1424     connectedDataSize_.clear(); 
    1425     nbSenders.clear(); 
    1426  
    1427     for (int p = 0; p < nbSrvPools; ++p) 
    1428     { 
    1429       CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p]; 
    1430       int receiverSize = client->serverSize; 
    1431  
    1432 //      connectedServerRank_[client].clear(); 
    1433  
    1434       if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end()) 
    1435       { 
    1436         if (client->isServerLeader()) 
    1437         { 
    1438           const std::list<int>& ranks = client->getRanksServerLeader(); 
    1439           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1440           { 
    1441             int rank = *itRank; 
    1442             int nb = 1; 
    1443             connectedServerRank_[receiverSize].push_back(rank); 
    1444             connectedDataSize_[receiverSize][rank] = nb; 
    1445             nbSenders[receiverSize][rank] = nb; 
    1446           } 
    1447         } 
    1448         else 
    1449         { 
    1450           const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1451           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1452           { 
    1453             int rank = *itRank; 
    1454             int nb = 1; 
    1455             connectedServerRank_[receiverSize].push_back(rank); 
    1456             connectedDataSize_[receiverSize][rank] = nb; 
    1457             nbSenders[receiverSize][rank] = nb; 
    1458           } 
    1459         } 
    1460       } 
    1461       isDataDistributed_ = false; 
    1462     } 
    1463   } 
    1464   CATCH_DUMP_ATTR 
    1465  
    1466   void CGrid::sendIndexScalarGrid() 
    1467   TRY 
    1468   { 
    1469     CContext* context = CContext::getCurrent(); 
    1470     storeIndex_toSrv.clear(); 
    1471     std::list<CContextClient*>::iterator it; 
    1472  
    1473     for (it=clients.begin(); it!=clients.end(); ++it) 
    1474     { 
    1475       CContextClient* client = *it; 
    1476       int receiverSize = client->serverSize; 
    1477  
    1478       CEventClient event(getType(), EVENT_ID_INDEX); 
    1479       list<CMessage> listMsg; 
    1480       list<CArray<size_t,1> > listOutIndex; 
    1481  
    1482       if (client->isServerLeader()) 
    1483       { 
    1484         const std::list<int>& ranks = client->getRanksServerLeader(); 
    1485         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1486         { 
    1487           int rank = *itRank; 
    1488           int nb = 1; 
    1489           storeIndex_toSrv[client].insert(std::make_pair(rank, CArray<int,1>(nb))); 
    1490           listOutIndex.push_back(CArray<size_t,1>(nb)); 
    1491  
    1492           CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 
    1493           CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    1494  
    1495           for (int k = 0; k < nb; ++k) 
    1496           { 
    1497             outGlobalIndexOnServer(k) = 0; 
    1498             outLocalIndexToServer(k)  = 0; 
    1499           } 
    1500  
    1501           if (context->hasClient && !context->hasServer) 
    1502             storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1503  
    1504           listMsg.push_back(CMessage()); 
    1505           listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1506  
    1507           event.push(rank, 1, listMsg.back()); 
    1508         } 
    1509         client->sendEvent(event); 
    1510       } 
    1511       else 
    1512       { 
    1513         const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1514         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1515         { 
    1516           int rank = *itRank; 
    1517           int nb = 1;           
    1518           CArray<int, 1> outLocalIndexToServer(nb); 
    1519           for (int k = 0; k < nb; ++k) 
    1520           { 
    1521             outLocalIndexToServer(k)  = 0; 
    1522           } 
    1523  
    1524           if (context->hasClient && !context->hasServer) 
    1525             storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1526         } 
    1527         client->sendEvent(event); 
    1528       } 
    1529     } 
    1530   } 
    1531   CATCH_DUMP_ATTR 
    1532  
    1533   void CGrid::sendIndex(void) 
    1534   TRY 
    1535   { 
    1536     CContext* context = CContext::getCurrent(); 
    1537     storeIndex_toSrv.clear(); 
    1538     std::list<CContextClient*>::iterator it; 
    1539  
    1540     for (it=clients.begin(); it!=clients.end(); ++it) 
    1541     { 
    1542       CContextClient* client = *it; 
    1543       int receiverSize = client->serverSize; 
    1544  
    1545       CEventClient event(getType(), EVENT_ID_INDEX); 
    1546       int rank; 
    1547       list<CMessage> listMsg; 
    1548       list<CArray<size_t,1> > listOutIndex; 
    1549       const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    1550       CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex, 
    1551                                                               iteIndex = globalLocalIndexSendToServer.end(); 
    1552       itIndex = itbIndex;                                                               
    1553  
    1554       if (!doGridHaveDataDistributed(client)) 
    1555       { 
    1556         if (client->isServerLeader()) 
    1557         { 
    1558           int indexSize = globalLocalIndexSendToServer.size(); 
    1559           CArray<size_t,1> outGlobalIndexOnServer(indexSize); 
    1560           CArray<int,1> outLocalIndexToServer(indexSize); 
    1561           for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1562           { 
    1563             outGlobalIndexOnServer(idx) = itIndex->first; 
    1564             outLocalIndexToServer(idx) = itIndex->second; 
    1565           } 
    1566  
    1567           const std::list<int>& ranks = client->getRanksServerLeader(); 
    1568           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1569           { 
    1570             storeIndex_toSrv[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1571             if (context->hasClient && !context->hasServer) 
    1572               storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1573              
    1574             listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 
    1575  
    1576             listMsg.push_back(CMessage()); 
    1577             listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1578  
    1579             event.push(*itRank, 1, listMsg.back()); 
    1580           } 
    1581           client->sendEvent(event); 
    1582         } 
    1583         else 
    1584         { 
    1585            int indexSize = globalLocalIndexSendToServer.size(); 
    1586            CArray<int,1> outLocalIndexToServer(indexSize); 
    1587            for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1588            { 
    1589              outLocalIndexToServer(idx) = itIndex->second; 
    1590            } 
    1591  
    1592            const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1593            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1594            { 
    1595              storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1596            } 
    1597            client->sendEvent(event); 
    1598          } 
    1599       } 
    1600       else 
    1601       { 
    1602         CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 
    1603         itGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
    1604         iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
    1605  
    1606         std::map<int,std::vector<int> >localIndexTmp; 
    1607         std::map<int,std::vector<size_t> > globalIndexTmp; 
    1608         for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    1609         { 
    1610           int serverRank = itGlobalMap->first; 
    1611           int indexSize = itGlobalMap->second.size(); 
    1612           const std::vector<size_t>& indexVec = itGlobalMap->second; 
    1613           for (int idx = 0; idx < indexSize; ++idx) 
    1614           { 
    1615             itIndex = globalLocalIndexSendToServer.find(indexVec[idx]); 
    1616             if (iteIndex != itIndex) 
    1617             { 
    1618               globalIndexTmp[serverRank].push_back(itIndex->first); 
    1619               localIndexTmp[serverRank].push_back(itIndex->second); 
    1620             } 
    1621           } 
    1622         } 
    1623  
    1624         for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns) 
    1625         { 
    1626           rank = connectedServerRank_[receiverSize][ns]; 
    1627           int nb = 0; 
    1628           if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 
    1629             nb = globalIndexTmp[rank].size(); 
    1630  
    1631           storeIndex_toSrv[client].insert(make_pair(rank, CArray<int,1>(nb))); 
    1632           listOutIndex.push_back(CArray<size_t,1>(nb)); 
    1633  
    1634           CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 
    1635           CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    1636  
    1637           for (int k = 0; k < nb; ++k) 
    1638           { 
    1639             outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k); 
    1640             outLocalIndexToServer(k)  = localIndexTmp[rank].at(k); 
    1641           } 
    1642  
    1643           storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1644           listMsg.push_back(CMessage()); 
    1645           listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1646  
    1647           event.push(rank, nbSenders[receiverSize][rank], listMsg.back()); 
    1648         } 
    1649  
    1650         client->sendEvent(event); 
    1651       } 
    1652     } 
    1653   } 
    1654   CATCH_DUMP_ATTR 
    1655  
    1656   void CGrid::recvIndex(CEventServer& event) 
    1657   TRY 
    1658   { 
    1659     string gridId; 
    1660     vector<int> ranks; 
    1661     vector<CBufferIn*> buffers; 
    1662  
    1663     list<CEventServer::SSubEvent>::iterator it; 
    1664     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    1665     { 
    1666       ranks.push_back(it->rank); 
    1667       CBufferIn* buffer = it->buffer; 
    1668       *buffer >> gridId; 
    1669       buffers.push_back(buffer); 
    1670     } 
    1671     get(gridId)->recvIndex(ranks, buffers); 
    1672   } 
    1673   CATCH 
    1674  
    1675   void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers) 
    1676   TRY 
    1677   { 
    1678     CContext* context = CContext::getCurrent(); 
    1679     connectedServerRankRead_ = ranks; 
    1680  
    1681     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    1682     nbSrvPools = 1;     
    1683     nbReadSenders.clear(); 
    1684     for (int p = 0; p < nbSrvPools; ++p) 
    1685     { 
    1686       CContextServer* server = (!context->hasClient) ? context->server : context->serverPrimServer[p]; 
    1687       CContextClient* client = context->client;   //(!context->hasClient) ? context->client : context->clientPrimServer[p]; 
    1688        
    1689       int idx = 0, numElement = axis_domain_order.numElements(); 
    1690       int ssize = numElement; 
    1691       std::vector<int> indexMap(numElement); 
    1692       for (int i = 0; i < numElement; ++i) 
    1693       { 
    1694         indexMap[i] = idx; 
    1695         if (2 == axis_domain_order(i)) 
    1696         { 
    1697           ++ssize; 
    1698           idx += 2; 
    1699         } 
    1700         else 
    1701           ++idx; 
    1702       } 
    1703  
    1704       for (int n = 0; n < ranks.size(); n++) 
    1705       { 
    1706         int rank = ranks[n]; 
    1707         CBufferIn& buffer = *buffers[n]; 
    1708  
    1709         buffer >> isDataDistributed_ >> isCompressible_; 
    1710         size_t dataSize = 0; 
    1711  
    1712         if (0 == serverDistribution_) 
    1713         { 
    1714           int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    1715           std::vector<CDomain*> domainList = getDomains(); 
    1716           std::vector<CAxis*> axisList = getAxis(); 
    1717           std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement); 
    1718           std::vector<CArray<int,1> > globalIndex(numElement); 
    1719           for (int i = 0; i < numElement; ++i) 
    1720           { 
    1721             nGlobElement[i] = globalSize; 
    1722             if (2 == axis_domain_order(i)) //domain 
    1723             { 
    1724               nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
    1725               nSize[indexMap[i]]  = domainList[domainId]->ni; 
    1726               nBeginGlobal[indexMap[i]] = 0; 
    1727               nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    1728  
    1729               nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
    1730               nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
    1731               nBeginGlobal[indexMap[i] + 1] = 0; 
    1732               nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    1733  
    1734               { 
    1735                 int count = 0; 
    1736                 globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]); 
    1737                 for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx) 
    1738                   for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    1739                   { 
    1740                     globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 
    1741                     ++count; 
    1742                   } 
    1743               } 
    1744  
    1745               ++domainId; 
    1746             } 
    1747             else if (1 == axis_domain_order(i)) // axis 
    1748             { 
    1749               nBegin[indexMap[i]] = axisList[axisId]->begin; 
    1750               nSize[indexMap[i]]  = axisList[axisId]->n; 
    1751               nBeginGlobal[indexMap[i]] = 0; 
    1752               nGlob[indexMap[i]] = axisList[axisId]->n_glo;      
    1753               globalIndex[i].resize(nSize[indexMap[i]]); 
    1754               for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    1755                 globalIndex[i](idx) = nBegin[indexMap[i]] + idx; 
    1756  
    1757               ++axisId; 
    1758             } 
    1759             else // scalar 
    1760             {  
    1761               nBegin[indexMap[i]] = 0; 
    1762               nSize[indexMap[i]]  = 1; 
    1763               nBeginGlobal[indexMap[i]] = 0; 
    1764               nGlob[indexMap[i]] = 1; 
    1765               globalIndex[i].resize(1); 
    1766               globalIndex[i](0) = 0; 
    1767               ++scalarId; 
    1768             } 
    1769           } 
    1770           dataSize = 1; 
    1771  
    1772           for (int i = 0; i < nSize.size(); ++i) 
    1773             dataSize *= nSize[i]; 
    1774           serverDistribution_ = new CDistributionServer(server->intraCommRank,  
    1775                                                         globalIndex, axis_domain_order, 
    1776                                                         nBegin, nSize, nBeginGlobal, nGlob); 
    1777         } 
    1778  
    1779         CArray<size_t,1> outIndex; 
    1780         buffer >> outIndex; 
    1781         outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex)); 
    1782         connectedDataSizeRead_[rank] = outIndex.numElements(); 
    1783  
    1784         if (doGridHaveDataDistributed(client)) 
    1785         {} 
    1786         else 
    1787         { 
    1788           // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER 
    1789           // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar) 
    1790           dataSize = serverDistribution_->getGridSize(); 
    1791         } 
    1792         writtenDataSize_ += dataSize; 
    1793       } 
    1794  
    1795  
    1796       // Compute mask of the current grid 
    1797       { 
    1798         int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    1799         std::vector<CDomain*> domainList = getDomains(); 
    1800         std::vector<CAxis*> axisList = getAxis(); 
    1801         int dimSize = 2 * domainList.size() + axisList.size(); 
    1802         std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize);         
    1803         for (int i = 0; i < numElement; ++i) 
    1804         {           
    1805           if (2 == axis_domain_order(i)) //domain 
    1806           { 
    1807             nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
    1808             nSize[indexMap[i]]  = domainList[domainId]->ni; 
    1809             nBeginGlobal[indexMap[i]] = 0;               
    1810             nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    1811  
    1812             nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
    1813             nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
    1814             nBeginGlobal[indexMap[i] + 1] = 0;               
    1815             nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    1816  
    1817             ++domainId; 
    1818           } 
    1819           else if (1 == axis_domain_order(i)) // axis 
    1820           { 
    1821             nBegin[indexMap[i]] = axisList[axisId]->begin; 
    1822             nSize[indexMap[i]]  = axisList[axisId]->n; 
    1823             nBeginGlobal[indexMap[i]] = 0;               
    1824             nGlob[indexMap[i]] = axisList[axisId]->n_glo;               
    1825             ++axisId; 
    1826           } 
    1827           else // scalar 
    1828           {   
    1829           } 
    1830         } 
    1831          
    1832         if (nSize.empty()) // Scalar grid 
    1833         { 
    1834           nBegin.push_back(0); 
    1835           nSize.push_back(1); 
    1836           nBeginGlobal.push_back(0);               
    1837           nGlob.push_back(1);   
    1838         } 
    1839       } 
    1840  
    1841       if (isScalarGrid()) return; 
    1842  
    1843       nbReadSenders[client] = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks); 
    1844     } 
    1845   } 
    1846   CATCH_DUMP_ATTR 
    1847  
     1038     
     1039   
     1040   
    18481041  /* 
    18491042     Compute on the fly the global dimension of a grid with its elements 
     
    19381131  TRY 
    19391132  { 
    1940      return (0 != writtenDataSize_); 
     1133     return (0 != getGridLocalElements()->getView(CElementView::FULL)->getSize()); 
    19411134  } 
    19421135  CATCH_DUMP_ATTR 
    19431136 
    1944   /*! 
    1945     Return size of data which is written on each server 
    1946     Whatever dimension of a grid, data which are written on server must be presented as 
    1947     an one dimension array. 
    1948     \return size of data written on server 
    1949   */ 
    1950   size_t CGrid::getWrittenDataSize() const 
    1951   TRY 
    1952   { 
    1953     return writtenDataSize_; 
    1954   } 
    1955   CATCH 
    1956  
    1957   /*! 
    1958     Returns the number of indexes written by each server. 
    1959     \return the number of indexes written by each server 
    1960   */ 
    1961   int CGrid::getNumberWrittenIndexes() const 
    1962   TRY 
    1963   { 
    1964     return numberWrittenIndexes_; 
    1965   } 
    1966   CATCH 
    1967  
    1968   /*! 
    1969     Returns the total number of indexes written by the servers. 
    1970     \return the total number of indexes written by the servers 
    1971   */ 
    1972   int CGrid::getTotalNumberWrittenIndexes() const 
    1973   TRY 
    1974   { 
    1975     return totalNumberWrittenIndexes_; 
    1976   } 
    1977   CATCH 
    1978  
    1979   /*! 
    1980     Returns the offset of indexes written by each server. 
    1981     \return the offset of indexes written by each server 
    1982   */ 
    1983   int CGrid::getOffsetWrittenIndexes() const 
    1984   TRY 
    1985   { 
    1986     return offsetWrittenIndexes_; 
    1987   } 
    1988   CATCH 
    1989  
    1990   CDistributionServer* CGrid::getDistributionServer() 
    1991   TRY 
    1992   { 
    1993     return serverDistribution_; 
    1994   } 
    1995   CATCH_DUMP_ATTR 
    1996  
    1997   CDistributionClient* CGrid::getDistributionClient() 
    1998   TRY 
    1999   { 
    2000     return clientDistribution_; 
    2001   } 
    2002   CATCH_DUMP_ATTR 
    2003  
     1137  
    20041138  bool CGrid::doGridHaveDataDistributed(CContextClient* client) 
    20051139  TRY 
    20061140  { 
     1141    // This function is now useless because it will return false only if server and client size are equal to 1 
     1142    // to be seriously check in future  
     1143 
    20071144    if (isScalarGrid()) return false; 
    20081145    else if (0 != client) 
    20091146    { 
    2010       return  (isDataDistributed_ ||  (1 != client->clientSize) || (1 != client->serverSize)); 
     1147      return  (isDataDistributed() ||  (1 != client->clientSize) || (1 != client->serverSize)); 
    20111148    } 
    20121149    else 
    2013       return isDataDistributed_;     
     1150      return isDataDistributed();     
    20141151  } 
    20151152  CATCH_DUMP_ATTR 
     
    20311168      switch(event.type) 
    20321169      { 
    2033         case EVENT_ID_INDEX : 
    2034           recvIndex(event); 
    2035           return true; 
    2036           break; 
    2037  
    20381170         case EVENT_ID_ADD_DOMAIN : 
    20391171           recvAddDomain(event); 
     
    20501182           return true; 
    20511183           break; 
     1184 
     1185         case EVENT_ID_SEND_MASK : 
     1186           recvMask(event); 
     1187           return true; 
     1188           break; 
    20521189        default : 
    2053           ERROR("bool CDomain::dispatchEvent(CEventServer& event)", 
     1190          ERROR("bool CGrid::dispatchEvent(CEventServer& event)", 
    20541191                << "Unknown Event"); 
    20551192          return false; 
     
    20591196  CATCH 
    20601197 
    2061    ///--------------------------------------------------------------- 
    2062  
    2063    CDomain* CGrid::addDomain(const std::string& id) 
    2064    TRY 
    2065    { 
    2066      order_.push_back(2); 
    2067      axis_domain_order.resize(order_.size()); 
    2068      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
    2069      return vDomainGroup_->createChild(id); 
    2070    } 
    2071    CATCH_DUMP_ATTR 
    2072  
    2073    CAxis* CGrid::addAxis(const std::string& id) 
    2074    TRY 
    2075    { 
    2076      order_.push_back(1); 
    2077      axis_domain_order.resize(order_.size()); 
    2078      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
    2079      return vAxisGroup_->createChild(id); 
    2080    } 
    2081    CATCH_DUMP_ATTR 
    2082  
    2083    CScalar* CGrid::addScalar(const std::string& id) 
    2084    TRY 
    2085    { 
    2086      order_.push_back(0); 
    2087      axis_domain_order.resize(order_.size()); 
    2088      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
    2089      return vScalarGroup_->createChild(id); 
    2090    } 
    2091    CATCH_DUMP_ATTR 
    2092  
    2093    //! Change virtual field group to a new one 
    2094    void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup) 
    2095    TRY 
    2096    { 
    2097       this->vDomainGroup_ = newVDomainGroup; 
    2098    } 
    2099    CATCH_DUMP_ATTR 
    2100  
    2101    //! Change virtual variable group to new one 
    2102    void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup) 
    2103    TRY 
    2104    { 
    2105       this->vAxisGroup_ = newVAxisGroup; 
    2106    } 
    2107    CATCH_DUMP_ATTR 
    2108  
    2109    //! Change virtual variable group to new one 
    2110    void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup) 
    2111    TRY 
    2112    { 
    2113       this->vScalarGroup_ = newVScalarGroup; 
    2114    } 
    2115    CATCH_DUMP_ATTR 
     1198  
     1199 
     1200  void CGrid::sendGridToFileServer(CContextClient* client) 
     1201  { 
     1202    if (sendGridToFileServer_done_.count(client)!=0) return ; 
     1203    else sendGridToFileServer_done_.insert(client) ; 
     1204 
     1205    StdString gridDefRoot("grid_definition"); 
     1206    CGridGroup* gridPtr = CGridGroup::get(gridDefRoot); 
     1207    gridPtr->sendCreateChild(this->getId(),client); 
     1208    this->sendAllAttributesToServer(client); 
     1209    distributeGridToFileServer(client) ; 
     1210  } 
     1211 
     1212 
     1213  void CGrid::distributeGridToFileServer(CContextClient* client) 
     1214  { 
     1215    CContext* context = CContext::getCurrent(); 
     1216    // simple Distribution for now  
     1217    // distribute over the fisrt element except if it is a scalar 
     1218    auto& elements = getElements() ; 
     1219    int posDistributed = 0 ; 
     1220    for(auto& element : elements) 
     1221    { 
     1222      if (element.type==TYPE_DOMAIN) break ; 
     1223      else if (element.type==TYPE_AXIS) break ; 
     1224      else if (element.type==TYPE_SCALAR) posDistributed++ ; 
     1225    } 
     1226     
     1227    vector<CLocalView*> localViews ; 
     1228    vector<CDistributedView*> remoteViews ; 
     1229 
     1230    for(int i=0 ; i<elements.size() ; i++) 
     1231    { 
     1232      if (elements[i].type==TYPE_DOMAIN)  
     1233      {  
     1234         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1235         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1236         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1237         localViews.push_back(domain->getLocalView(CElementView::FULL)) ; 
     1238      } 
     1239      else if (elements[i].type==TYPE_AXIS) 
     1240      { 
     1241        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1242        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1243        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1244        localViews.push_back(axis->getLocalView(CElementView::FULL)) ; 
     1245      } 
     1246      else if (elements[i].type==TYPE_SCALAR) 
     1247      { 
     1248        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1249        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1250        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1251        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ; 
     1252      } 
     1253    } 
     1254    CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm(), client->getRemoteSize()) ; 
     1255    gridRemoteConnector.computeConnector() ; 
     1256     
     1257    vector<CScattererConnector*> scattererConnectors ; 
     1258    CScattererConnector* scattererConnector; 
     1259    for(int i=0 ; i<elements.size() ; i++) 
     1260    { 
     1261      if (elements[i].type==TYPE_DOMAIN)  
     1262      {  
     1263         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1264         sendAddDomain(domain->getId(),client) ; 
     1265         domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 
     1266         scattererConnectors.push_back(scattererConnector) ; 
     1267      } 
     1268      else if (elements[i].type==TYPE_AXIS) 
     1269      { 
     1270        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1271        sendAddAxis(axis->getId(),client) ; 
     1272        axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 
     1273        scattererConnectors.push_back(scattererConnector) ; 
     1274      } 
     1275      else if (elements[i].type==TYPE_SCALAR) 
     1276      { 
     1277        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1278        sendAddScalar(scalar->getId(),client) ; 
     1279        scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 
     1280        scattererConnectors.push_back(scattererConnector) ; 
     1281      } 
     1282    } 
     1283 
     1284    CGridScattererConnector gridScattererConnector(scattererConnectors) ; 
     1285    CGridLocalConnector* workflowToFull = getGridLocalElements()->getConnector(CElementView::WORKFLOW, CElementView::FULL) ; 
     1286    CArray<bool,1> maskIn(workflowToFull->getSrcSize()) ; 
     1287    CArray<bool,1> maskOut(workflowToFull->getDstSize()) ; 
     1288    maskIn = true ; 
     1289    workflowToFull->transfer(maskIn,maskOut,false) ; 
     1290 
     1291    CEventClient event(getType(), EVENT_ID_SEND_MASK); 
     1292    CMessage message ; 
     1293    message<<getId() ;  
     1294    gridScattererConnector.transfer(maskOut, client, event, message) ; 
     1295    for(auto& it : scattererConnectors) delete it ; 
     1296 
     1297    vector<CScattererConnector*> clientToServerConnectors ; 
     1298    vector<CGathererConnector*>  clientFromServerConnectors ; 
     1299    for(auto& element : elements) 
     1300    { 
     1301      if (element.type==TYPE_DOMAIN)  
     1302      {  
     1303         clientToServerConnectors.push_back(element.domain->getClientToServerConnector(client)) ; 
     1304         clientFromServerConnectors.push_back(element.domain->getClientFromServerConnector(client)) ; 
     1305      } 
     1306      else if (element.type==TYPE_AXIS) 
     1307      { 
     1308        clientToServerConnectors.push_back(element.axis->getClientToServerConnector(client)) ; 
     1309        clientFromServerConnectors.push_back(element.axis->getClientFromServerConnector(client)) ; 
     1310 
     1311      } 
     1312      else if (element.type==TYPE_SCALAR) 
     1313      { 
     1314        clientToServerConnectors.push_back(element.scalar->getClientToServerConnector(client)) ; 
     1315        clientFromServerConnectors.push_back(element.scalar->getClientFromServerConnector(client)) ; 
     1316      } 
     1317    } 
     1318     
     1319    // compute the grid clientToServerConnector to send flux from client to servers 
     1320    clientToServerConnector_[client] = new CGridScattererConnector(clientToServerConnectors) ; 
     1321    clientFromServerConnector_[client] = new CGridGathererConnector(clientFromServerConnectors) ; 
     1322 
     1323 
     1324  } 
     1325 
     1326  void CGrid::recvMask(CEventServer& event) 
     1327  { 
     1328    string gridId; 
     1329    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> gridId  ; 
     1330    get(gridId)->receiveMask(event); 
     1331  } 
     1332   
     1333  void CGrid::receiveMask(CEventServer& event) 
     1334  { 
     1335    vector<CGathererConnector*> gathererConnectors ; 
     1336    vector<CLocalView*> fullViews ; 
     1337 
     1338    for(auto& element : getElements()) 
     1339    { 
     1340      if (element.type==TYPE_DOMAIN)  
     1341      { 
     1342        gathererConnectors.push_back(element.domain->getGathererConnector()); 
     1343        fullViews.push_back(element.domain->getLocalElement()->getView(CElementView::FULL)); 
     1344         
     1345      } 
     1346      else if (element.type==TYPE_AXIS) 
     1347      { 
     1348       gathererConnectors.push_back(element.axis->getGathererConnector()); 
     1349       fullViews.push_back(element.axis->getLocalElement()->getView(CElementView::FULL)); 
     1350      } 
     1351      else if (element.type==TYPE_SCALAR)  
     1352      { 
     1353        gathererConnectors.push_back(element.scalar->getGathererConnector()); 
     1354        fullViews.push_back(element.scalar->getLocalElement()->getView(CElementView::FULL)); 
     1355      } 
     1356    } 
     1357    CGridGathererConnector gridGathererConnector(gathererConnectors) ; 
     1358    CGridMaskConnector gridMaskConnector(fullViews) ; 
     1359 
     1360    CArray<bool,1> maskOut ; 
     1361    gridGathererConnector.transfer_or(event,maskOut) ; 
     1362    gridMaskConnector.computeConnector(maskOut) ; 
     1363 
     1364    CContextClient* client = event.getContextServer()->getAssociatedClient() ; 
     1365    int i=0 ; 
     1366    for(auto& element : getElements()) 
     1367    { 
     1368      if (element.type==TYPE_DOMAIN) element.domain->setServerMask(gridMaskConnector.getElementMask(i),client); 
     1369      else if (element.type==TYPE_AXIS) element.axis->setServerMask(gridMaskConnector.getElementMask(i),client); 
     1370      else if (element.type==TYPE_SCALAR) element.scalar->setServerMask(gridMaskConnector.getElementMask(i),client); 
     1371      i++ ; 
     1372    } 
     1373  } 
     1374 
     1375 
     1376  void CGrid::sendGridToCouplerOut(CContextClient* client, const string& fieldId) 
     1377  { 
     1378/*    if (sendGridToCouplerOut_done_.count(client)!=0) return ; 
     1379    else sendGridToCouplerOut_done_.insert(client) ; 
     1380  
     1381    CContext* context = CContext::getCurrent(); 
     1382    // simple Distribution for now  
     1383    // distribute over the fisrt element except if it is a scalar 
     1384    auto& elements = getElements() ; 
     1385    int posDistributed = 0 ; 
     1386    for(auto& element : elements) 
     1387    { 
     1388      if (element.type==TYPE_DOMAIN) break ; 
     1389      else if (element.type==TYPE_AXIS) break ; 
     1390      else if (element.type==TYPE_SCALAR) posDistributed++ ; 
     1391    } 
     1392     
     1393    vector<CLocalView*> localViews ; 
     1394    vector<CDistributedView*> remoteViews ; 
     1395 
     1396    for(int i=0 ; i<elements.size() ; i++) 
     1397    { 
     1398      if (elements[i].type==TYPE_DOMAIN)  
     1399      {  
     1400         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1401         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1402         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1403         localViews.push_back(domain->getLocalView(CElementView::FULL)) ; 
     1404      } 
     1405      else if (elements[i].type==TYPE_AXIS) 
     1406      { 
     1407        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1408        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1409        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1410        localViews.push_back(axis->getLocalView(CElementView::FULL)) ; 
     1411      } 
     1412      else if (elements[i].type==TYPE_SCALAR) 
     1413      { 
     1414        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1415        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1416        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1417        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ; 
     1418      } 
     1419    } 
     1420    CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm(), client->getRemoteSize()) ; 
     1421    gridRemoteConnector.computeConnector() ; 
     1422     
     1423    vector<CScattererConnector*> clientToClientConnectors ; 
     1424    for(int i=0 ; i<elements.size() ; i++) 
     1425    { 
     1426      if (elements[i].type==TYPE_DOMAIN)  
     1427      {  
     1428         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1429         sendAddDomain(domain->getId(),client) ; 
     1430         domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 
     1431         clientToClientConnectors.push_back(domain->getClientToServerConnector(client)) ; 
     1432      } 
     1433      else if (elements[i].type==TYPE_AXIS) 
     1434      { 
     1435        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1436        sendAddAxis(axis->getId(),client) ; 
     1437        axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 
     1438        clientToClientConnectors.push_back(axis->getClientToServerConnector(client)) ; 
     1439      } 
     1440      else if (elements[i].type==TYPE_SCALAR) 
     1441      { 
     1442        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1443        sendAddScalar(scalar->getId(),client) ; 
     1444        scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 
     1445        clientToClientConnectors.push_back(scalar->getClientToServerConnector(client)) ; 
     1446      } 
     1447    } 
     1448     
     1449    // compute the grid clientToServerConnector to send flux from client to servers 
     1450    clientToClientConnector_[client] = new CGridScattererConnector(clientToClientConnectors) ;*/ 
     1451  } 
     1452 
     1453  void CGrid::makeAliasForCoupling(const string& fieldId) 
     1454  { 
     1455    string gridId="_grid_of_"+fieldId ; 
     1456    createAlias(gridId) ; 
     1457     
     1458    const auto& domVect = getDomains() ; 
     1459    for (int pos=0; pos<domVect.size();pos++) domVect[pos]->makeAliasForCoupling(fieldId, pos); 
     1460 
     1461    const auto& axisVect=getAxis() ; 
     1462    for (int pos=0; pos<axisVect.size();pos++) axisVect[pos]->makeAliasForCoupling(fieldId, pos); 
     1463 
     1464    const auto& scalVect=getScalars() ; 
     1465    for (int pos=0; pos<scalVect.size();pos++) scalVect[pos]->makeAliasForCoupling(fieldId, pos); 
     1466  } 
    21161467 
    21171468   /*! 
     
    21191470   \param[in] id String identity of domain that will be created on server 
    21201471   */ 
    2121    void CGrid::sendAddDomain(const string& id) 
    2122    TRY 
    2123   { 
    2124       sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN); 
     1472   void CGrid::sendAddDomain(const string& id, CContextClient* contextClient) 
     1473   TRY 
     1474  { 
     1475      sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN, contextClient); 
    21251476   } 
    21261477   CATCH_DUMP_ATTR 
     
    21301481   \param[in] id String identity of axis that will be created on server 
    21311482   */ 
    2132    void CGrid::sendAddAxis(const string& id) 
    2133    TRY 
    2134    { 
    2135       sendAddItem(id, (int)EVENT_ID_ADD_AXIS); 
     1483   void CGrid::sendAddAxis(const string& id, CContextClient* contextClient) 
     1484   TRY 
     1485   { 
     1486      sendAddItem(id, (int)EVENT_ID_ADD_AXIS, contextClient); 
    21361487   } 
    21371488   CATCH_DUMP_ATTR 
     
    21411492   \param[in] id String identity of scalar that will be created on server 
    21421493   */ 
    2143    void CGrid::sendAddScalar(const string& id) 
    2144    TRY 
    2145    { 
    2146       sendAddItem(id, (int)EVENT_ID_ADD_SCALAR); 
     1494   void CGrid::sendAddScalar(const string& id, CContextClient* contextClient) 
     1495   TRY 
     1496   { 
     1497      sendAddItem(id, (int)EVENT_ID_ADD_SCALAR, contextClient); 
    21471498   } 
    21481499   CATCH_DUMP_ATTR 
     
    22311582   } 
    22321583   CATCH_DUMP_ATTR 
     1584 
     1585  /*! 
     1586  \brief Check if all elements of the grid are complete 
     1587  Before make any grid processing, we must be sure that all grid information elements have 
     1588  been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     1589  other context (coupling) 
     1590  */ 
     1591  bool CGrid::isCompleted(void) 
     1592  { 
     1593    setDomainList(); 
     1594    for (auto domainId : domList_) if (!CDomain::get(domainId)->isCompleted()) return false ; 
     1595    setAxisList() ; 
     1596    for (auto axisId : axisList_) if (!CAxis::get(axisId)->isCompleted()) return false ; 
     1597    setScalarList() ; 
     1598    for (auto scalarId : scalarList_) if (!CScalar::get(scalarId)->isCompleted()) return false ; 
     1599    return true ; 
     1600  } 
     1601 
     1602  /*! 
     1603  \brief impose that all elements of the grid are complete 
     1604  Before make any grid processing, we must be sure that all grid information elements have 
     1605  been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     1606  other context (coupling) 
     1607  */ 
     1608  void CGrid::setCompleted(void) 
     1609  { 
     1610    setDomainList(); 
     1611    for (auto domainId : domList_) CDomain::get(domainId)->setCompleted() ; 
     1612    setAxisList() ; 
     1613    for (auto axisId : axisList_) CAxis::get(axisId)->setCompleted() ; 
     1614    setScalarList() ; 
     1615    for (auto scalarId : scalarList_) CScalar::get(scalarId)->setCompleted() ; 
     1616  } 
     1617 
     1618/*! 
     1619  \brief impose that all elements of the grid are incomplete 
     1620  Before make any grid processing, we must be sure that all grid information elements have 
     1621  been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     1622  other context (coupling) 
     1623  */ 
     1624  void CGrid::unsetCompleted(void) 
     1625  { 
     1626    setDomainList(); 
     1627    for (auto domainId : domList_) CDomain::get(domainId)->unsetCompleted() ; 
     1628    setAxisList() ; 
     1629    for (auto axisId : axisList_) CAxis::get(axisId)->unsetCompleted() ; 
     1630    setScalarList() ; 
     1631    for (auto scalarId : scalarList_) CScalar::get(scalarId)->unsetCompleted() ; 
     1632  } 
    22331633 
    22341634  /*! 
     
    22381638  \param[in] apply inherit all attributes of parents (true) 
    22391639  */ 
    2240   void CGrid::solveDomainAxisRefInheritance(bool apply) 
    2241   TRY 
    2242   { 
    2243     CContext* context = CContext::getCurrent(); 
    2244     unsigned int vecSize, i; 
    2245     std::vector<StdString>::iterator it, itE; 
     1640  void CGrid::solveElementsRefInheritance(bool apply) 
     1641  TRY 
     1642  { 
    22461643    setDomainList(); 
    2247     it = domList_.begin(); itE = domList_.end(); 
    2248     for (; it != itE; ++it) 
    2249     { 
    2250       CDomain* pDom = CDomain::get(*it); 
    2251       if (context->hasClient && !context->hasServer)       
    2252       { 
    2253         pDom->solveRefInheritance(apply); 
    2254         pDom->solveInheritanceTransformation(); 
    2255       } 
     1644    for (auto domainId : domList_) 
     1645    { 
     1646      CDomain* pDom = CDomain::get(domainId); 
     1647      pDom->solveRefInheritance(apply); 
     1648      pDom->solveInheritanceTransformation(); 
    22561649    } 
    22571650 
    22581651    setAxisList(); 
    2259     it = axisList_.begin(); itE = axisList_.end(); 
    2260     for (; it != itE; ++it) 
    2261     { 
    2262       CAxis* pAxis = CAxis::get(*it); 
    2263       if (context->hasClient && !context->hasServer) 
    2264       { 
    2265         pAxis->solveRefInheritance(apply); 
    2266         pAxis->solveInheritanceTransformation(); 
    2267       } 
     1652    for (auto axisId : axisList_) 
     1653    { 
     1654      CAxis* pAxis = CAxis::get(axisId); 
     1655      pAxis->solveRefInheritance(apply); 
     1656      pAxis->solveInheritanceTransformation(); 
    22681657    } 
    22691658 
    22701659    setScalarList(); 
    2271     it = scalarList_.begin(); itE = scalarList_.end(); 
    2272     for (; it != itE; ++it) 
    2273     { 
    2274       CScalar* pScalar = CScalar::get(*it); 
    2275       if (context->hasClient && !context->hasServer) 
    2276       { 
    2277         pScalar->solveRefInheritance(apply); 
    2278         pScalar->solveInheritanceTransformation(); 
    2279       } 
     1660    for (auto scalarId : scalarList_) 
     1661    { 
     1662      CScalar* pScalar = CScalar::get(scalarId); 
     1663      pScalar->solveRefInheritance(apply); 
     1664      pScalar->solveInheritanceTransformation(); 
    22801665    } 
    22811666  } 
    22821667  CATCH_DUMP_ATTR 
    22831668 
    2284   bool CGrid::isTransformed() 
    2285   TRY 
    2286   { 
    2287     return isTransformed_; 
     1669 /*! 
     1670  \brief check attributes of all elements of the grid 
     1671  */ 
     1672  void CGrid::checkElementsAttributes(void) 
     1673  TRY 
     1674  { 
     1675    setDomainList(); 
     1676    for (auto domainId : domList_) CDomain::get(domainId)->checkAttributes(); 
     1677 
     1678    setAxisList(); 
     1679    for (auto axisId : axisList_) CAxis::get(axisId)->checkAttributes(); 
     1680     
     1681    setScalarList(); 
     1682    for (auto scalarId : scalarList_) CScalar::get(scalarId)->checkAttributes(); 
    22881683  } 
    22891684  CATCH_DUMP_ATTR 
    22901685 
    2291   void CGrid::setTransformed() 
    2292   TRY 
    2293   { 
    2294     isTransformed_ = true; 
     1686 
     1687 
     1688//********************************************************** 
     1689//**************   New transformation method  ************** 
     1690//********************************************************** 
     1691 
     1692  std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> >  
     1693  CGrid::buildTransformationGraph(CGarbageCollector& gc, bool isSource, CGrid* gridSrc, double detectMissingValues, double defaultValue, CGrid*& newGrid, bool graphEnabled) 
     1694  TRY 
     1695  { 
     1696    registerAlgorithmTransformation() ; // needed to enable self-registration of the transformations 
     1697                                        // big mystery why it doesn't work witout that... 
     1698                                        // problem with the linker ??  
     1699 
     1700    std::shared_ptr<CFilter> inputFilter = std::shared_ptr<CPassThroughFilter>(new CPassThroughFilter(gc)); 
     1701    std::shared_ptr<CFilter> outputFilter = inputFilter ; 
     1702 
     1703 
     1704    string newId ; 
     1705    if (gridSrc!=nullptr) newId = gridSrc->getId() + " --> " + this->getId()  ; 
     1706    else newId = " --> " + this->getId()  ; 
     1707    bool isNewGrid ; 
     1708    if (CGrid::has(newId)) 
     1709    { 
     1710      cout<<"Retrive existing grid : "<<newId<<endl ; 
     1711      newGrid = CGrid::get(newId); 
     1712      isNewGrid = false ; 
     1713    } 
     1714    else   
     1715    { 
     1716      cout<<"Create new grid : "<<newId<<endl ; 
     1717      newGrid = CGrid::create(newId) ; 
     1718      isNewGrid = true ; 
     1719    } 
     1720 
     1721    bool hadTransform=false ; 
     1722    bool hasTransform=false ; 
     1723    bool hasRemainTransform=false ; 
     1724    CGenericAlgorithmTransformation* algo ; 
     1725    int pos ; 
     1726 
     1727    for(int i=0 ; i<elements_.size(); i++) 
     1728    { 
     1729      CTransformationPaths transformationPath ; 
     1730      auto dstElement = elements_[i] ; 
     1731 
     1732      if (dstElement.type==TYPE_DOMAIN)      transformationPath = dstElement.domain->getTransformationPaths() ; 
     1733      else if (dstElement.type==TYPE_AXIS)   transformationPath = dstElement.axis->getTransformationPaths() ; 
     1734      else if (dstElement.type==TYPE_SCALAR) transformationPath = dstElement.scalar->getTransformationPaths() ; 
     1735 
     1736      SElement srcElement  ; 
     1737      if (gridSrc==nullptr) srcElement = this->elements_[i] ; 
     1738      else srcElement = gridSrc->elements_[i] ; 
     1739 
     1740      if (gridSrc==nullptr) transformationPath.mergePaths() ; 
     1741      else 
     1742      {   
     1743        if (srcElement.type==TYPE_DOMAIN)      transformationPath.mergePaths(srcElement.domain->getTransformationPaths()) ; 
     1744        else if (srcElement.type==TYPE_AXIS)   transformationPath.mergePaths(srcElement.axis->getTransformationPaths()) ; 
     1745        else if (srcElement.type==TYPE_SCALAR) transformationPath.mergePaths(srcElement.scalar->getTransformationPaths()) ; 
     1746      } 
     1747 
     1748      hasTransform=transformationPath.hasTransform()  ; 
     1749       
     1750      if (hasTransform && !hadTransform) 
     1751      { 
     1752        pos=i ; 
     1753        EElement dstElementType=transformationPath.getNextElementType() ; 
     1754        string dstElementId=transformationPath.getNextElementId() ; 
     1755        string srcElementId=transformationPath.getNextElementSrcId() ; 
     1756        auto transType = transformationPath.getNextTransformationType() ; 
     1757        auto transId = transformationPath.getNextTransformationId() ; 
     1758 
     1759        CGrid* tmpGridSrc=CGrid::create(); // source grid  
     1760        if (srcElement.type==TYPE_DOMAIN)      tmpGridSrc->addDomain(srcElement.domain->getId()) ; 
     1761        else if (srcElement.type==TYPE_AXIS)   tmpGridSrc->addAxis(srcElement.axis->getId()) ; 
     1762        else if (srcElement.type==TYPE_SCALAR) tmpGridSrc->addScalar(srcElement.scalar->getId()) ; 
     1763        tmpGridSrc->checkElementsAttributes() ; 
     1764        CGrid* tmpGridDst=CGrid::create(); // destination Grid 
     1765        map<int,int> posInGrid={{0,0}} ; 
     1766                
     1767        cout<<"--> New transform from "<<srcElementId<<" to "<<dstElementId<<endl ; 
     1768        if (dstElementType==EElement::DOMAIN) 
     1769        { 
     1770          CDomain* dstDomain ; 
     1771          CDomain* lastDstDomain ; 
     1772          bool isGenerate=false ; 
     1773    
     1774          do  
     1775          { 
     1776 
     1777            if (CDomain::has(dstElementId))  
     1778            { 
     1779              dstDomain = CDomain::get(dstElementId) ; 
     1780              cout<<"Retrive existing domain : "<<dstElementId<<endl ; 
     1781            } 
     1782            else 
     1783            { 
     1784              dstDomain = CDomain::create() ; 
     1785              dstDomain->createAlias(dstElementId) ; 
     1786              cout<<"Create new domain : "<<dstDomain->getId()<<" with alias : "<<dstElementId<<endl ; 
     1787 
     1788              if (isGenerate) dstDomain->duplicateAttributes(lastDstDomain) ; 
     1789              else if (srcElementId=="" && srcElement.type==TYPE_DOMAIN)  dstDomain->duplicateAttributes(srcElement.domain) ; // make a copy 
     1790              else dstDomain->duplicateAttributes(dstElement.domain) ; // make a copy 
     1791              CTransformation<CDomain>* transformation = CTransformation<CDomain>::createTransformation(transType,"") ; 
     1792              auto srcTransform = CTransformation<CDomain>::getTransformation(transType, transId) ; 
     1793              transformation->inheritFrom(srcTransform) ; 
     1794              CGrid* tmpGridDst=CGrid::create(); // destination Grid 
     1795              tmpGridDst->addDomain(dstDomain->getId()) ; 
     1796 
     1797              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0,  
     1798                                                       posInGrid,posInGrid,posInGrid, 
     1799                                                       posInGrid,posInGrid,posInGrid ); 
     1800 
     1801 
     1802              dstDomain->setTransformationAlgorithm(algo) ; 
     1803              dstDomain->setTransformationPaths(transformationPath) ; 
     1804            } 
     1805            algo=dstDomain->getTransformationAlgorithm() ; 
     1806            isGenerate = algo->isGenerateTransformation() ; 
     1807            transformationPath.removeNextTransform() ; 
     1808            dstElementId=transformationPath.getNextElementId() ; 
     1809            srcElementId=transformationPath.getNextElementSrcId() ; 
     1810            transType = transformationPath.getNextTransformationType() ; 
     1811            transId = transformationPath.getNextTransformationId() ; 
     1812            lastDstDomain=dstDomain ; 
     1813            dstDomain->setTransformationPaths(transformationPath) ; 
     1814          } while(transformationPath.hasTransform() && isGenerate) ; 
     1815 
     1816          if (isNewGrid) newGrid->addDomain(dstDomain->getId()) ; 
     1817          algo = dstDomain->getTransformationAlgorithm() ; 
     1818        } 
     1819        else if (dstElementType==EElement::AXIS) 
     1820        { 
     1821          CAxis* dstAxis ; 
     1822          CAxis* lastDstAxis ; 
     1823          bool isGenerate=false ; 
     1824 
     1825          do  
     1826          { 
     1827            if (CAxis::has(dstElementId))  
     1828            { 
     1829              dstAxis = CAxis::get(dstElementId) ; 
     1830              cout<<"Retrive existing axis : "<<dstElementId<<endl ; 
     1831            } 
     1832            else 
     1833            { 
     1834              dstAxis = CAxis::create() ; 
     1835              dstAxis->createAlias(dstElementId) ; 
     1836              cout<<"Create new axis : "<<dstAxis->getId()<<" with alias : "<<dstElementId<<endl ; 
     1837               
     1838              if (isGenerate) dstAxis->duplicateAttributes(lastDstAxis) ; 
     1839              else if (srcElementId=="" && srcElement.type==TYPE_AXIS)  dstAxis->duplicateAttributes(srcElement.axis) ; // make a copy 
     1840              else dstAxis->duplicateAttributes(dstElement.axis) ; // make a copy 
     1841              CTransformation<CAxis>* transformation = CTransformation<CAxis>::createTransformation(transType,"") ; 
     1842              auto srcTransform = CTransformation<CAxis>::getTransformation(transType, transId) ; 
     1843              transformation->inheritFrom(srcTransform) ; 
     1844              tmpGridDst->addAxis(dstAxis->getId()) ; 
     1845 
     1846              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0,  
     1847                                                      posInGrid,posInGrid,posInGrid, 
     1848                                                      posInGrid,posInGrid,posInGrid ); 
     1849 
     1850              dstAxis->setTransformationAlgorithm(algo) ; 
     1851              dstAxis->setTransformationPaths(transformationPath) ; 
     1852            } 
     1853            
     1854            algo=dstAxis->getTransformationAlgorithm() ; 
     1855            isGenerate = algo->isGenerateTransformation() ; 
     1856            transformationPath.removeNextTransform() ; 
     1857            dstElementId=transformationPath.getNextElementId() ; 
     1858            srcElementId=transformationPath.getNextElementSrcId() ; 
     1859            transType = transformationPath.getNextTransformationType() ; 
     1860            transId = transformationPath.getNextTransformationId() ; 
     1861            lastDstAxis=dstAxis ; 
     1862            dstAxis->setTransformationPaths(transformationPath) ; 
     1863          } while(transformationPath.hasTransform() && isGenerate) ; 
     1864            
     1865          if (isNewGrid) newGrid->addAxis(dstAxis->getId()) ; 
     1866          algo = dstAxis->getTransformationAlgorithm() ; 
     1867        } 
     1868        else if (dstElementType==EElement::SCALAR) 
     1869        { 
     1870          CScalar* dstScalar ; 
     1871          CScalar* lastDstScalar ; 
     1872          bool isGenerate=false ; 
     1873 
     1874          do  
     1875          { 
     1876            if (CScalar::has(dstElementId))  
     1877            { 
     1878              dstScalar = CScalar::get(dstElementId) ; 
     1879              cout<<"Retrive existing scalar : "<<dstElementId<<endl ; 
     1880            } 
     1881            else 
     1882            { 
     1883              dstScalar = CScalar::create() ; 
     1884              dstScalar->createAlias(dstElementId) ; 
     1885              cout<<"Create new scalar : "<<dstScalar->getId()<<" with alias : "<<dstElementId<<endl ; 
     1886               
     1887              if (isGenerate) dstScalar->duplicateAttributes(lastDstScalar) ; 
     1888              else if (srcElementId=="" && srcElement.type==TYPE_SCALAR)  dstScalar->duplicateAttributes(srcElement.scalar) ; // make a copy 
     1889              else dstScalar->duplicateAttributes(dstElement.scalar) ; // make a copy 
     1890              CTransformation<CScalar>* transformation = CTransformation<CScalar>::createTransformation(transType,"") ; 
     1891              auto srcTransform = CTransformation<CScalar>::getTransformation(transType, transId) ; 
     1892              transformation->inheritFrom(srcTransform) ; 
     1893              tmpGridDst->addScalar(dstScalar->getId()) ; 
     1894 
     1895              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0,  
     1896                                                       posInGrid,posInGrid,posInGrid, 
     1897                                                       posInGrid,posInGrid,posInGrid ); 
     1898               
     1899              dstScalar->setTransformationAlgorithm(algo) ; 
     1900              dstScalar->setTransformationPaths(transformationPath) ; 
     1901            } 
     1902            algo=dstScalar->getTransformationAlgorithm() ; 
     1903            isGenerate = algo->isGenerateTransformation() ; 
     1904            transformationPath.removeNextTransform() ; 
     1905            dstElementId=transformationPath.getNextElementId() ; 
     1906            srcElementId=transformationPath.getNextElementSrcId() ; 
     1907            transType = transformationPath.getNextTransformationType() ; 
     1908            transId = transformationPath.getNextTransformationId() ; 
     1909            lastDstScalar=dstScalar ; 
     1910            dstScalar->setTransformationPaths(transformationPath) ; 
     1911          } while(transformationPath.hasTransform() && isGenerate) ; 
     1912 
     1913          if (isNewGrid) newGrid->addScalar(dstScalar->getId()) ; 
     1914          algo = dstScalar->getTransformationAlgorithm() ;           
     1915        } 
     1916        // here create a new spatial filter with algo 
     1917         
     1918        hadTransform=true ; 
     1919        hasTransform=false ;  
     1920      } 
     1921      else 
     1922      { 
     1923        string srcElementId=transformationPath.getNextElementSrcId() ; 
     1924 
     1925        if (srcElement.type==TYPE_DOMAIN)       
     1926        { 
     1927          CDomain* domain ; 
     1928          if (srcElementId=="") srcElementId=srcElement.domain->getId() ;  
     1929          if (!CDomain::has(srcElementId))  
     1930          { 
     1931            domain=srcElement.domain ; 
     1932            domain->createAlias(srcElementId) ; 
     1933          } 
     1934          else domain = CDomain::get(srcElementId) ; 
     1935          domain->checkAttributes() ; 
     1936          
     1937          if (isNewGrid) newGrid->addDomain(srcElementId) ; 
     1938        } 
     1939        else if (srcElement.type==TYPE_AXIS) 
     1940        {    
     1941          CAxis* axis ; 
     1942          if (srcElementId=="") srcElementId=srcElement.axis->getId() ;  
     1943          if (!CAxis::has(srcElementId))  
     1944          { 
     1945            axis=srcElement.axis ; 
     1946            axis->createAlias(srcElementId) ; 
     1947          } 
     1948          else axis = CAxis::get(srcElementId) ; 
     1949          axis->checkAttributes() ; 
     1950          
     1951          if (isNewGrid) newGrid->addAxis(srcElementId) ; 
     1952        } 
     1953        else if (srcElement.type==TYPE_SCALAR) 
     1954        { 
     1955          CScalar* scalar ; 
     1956          if (srcElementId=="") srcElementId=srcElement.scalar->getId() ;  
     1957          if (!CScalar::has(srcElementId))  
     1958          { 
     1959            scalar=srcElement.scalar ; 
     1960            scalar->createAlias(srcElementId) ; 
     1961          } 
     1962          else scalar = CScalar::get(srcElementId) ; 
     1963          scalar->checkAttributes() ; 
     1964          
     1965          if (isNewGrid) newGrid->addScalar(srcElementId) ; 
     1966        } 
     1967      } 
     1968       
     1969      if (transformationPath.hasTransform() && hadTransform) hasRemainTransform=true ; 
     1970    }   
     1971     
     1972 
     1973    if (hadTransform) 
     1974    { 
     1975       
     1976      if (!isSource) 
     1977      { 
     1978        CGridAlgorithm* gridAlgorithm  ; 
     1979        if (isNewGrid) 
     1980        {  
     1981          gridAlgorithm = algo->createGridAlgorithm(gridSrc, newGrid, pos) ; 
     1982          newGrid->setGridAlgorithm(gridAlgorithm); 
     1983        } 
     1984        else gridAlgorithm = newGrid->getGridAlgorithm() ; 
     1985 
     1986        shared_ptr<CTransformFilter> transformFilter = shared_ptr<CTransformFilter>(gridAlgorithm->createTransformFilter(gc, detectMissingValues, defaultValue)) ; 
     1987        outputFilter->connectOutput(transformFilter,0) ; 
     1988        vector<string> auxFieldId = algo->getAuxFieldId() ; // better to do that at transformation not algo ?? 
     1989        int i=1;  
     1990        for (auto& it : auxFieldId) 
     1991        { 
     1992          CField* auxField = CField::get(it) ; 
     1993          auxField->buildWorkflowGraph(gc) ; 
     1994          auxField->getInstantDataFilter()->connectOutput(transformFilter,i) ; 
     1995          i++ ; 
     1996        } 
     1997        outputFilter = transformFilter ; 
     1998      } 
     1999 
     2000      if (hasRemainTransform) 
     2001      { 
     2002        gridSrc=newGrid ; 
     2003        pair<shared_ptr<CFilter>, shared_ptr<CFilter> > filters = this->buildTransformationGraph(gc, isSource, gridSrc, detectMissingValues, defaultValue, newGrid) ; 
     2004        outputFilter->connectOutput(filters.first,0) ; 
     2005        outputFilter=filters.second ; 
     2006      } 
     2007    } 
     2008      
     2009    return {inputFilter,outputFilter} ; 
    22952010  } 
    22962011  CATCH_DUMP_ATTR 
    22972012 
    2298   CGridTransformation* CGrid::getTransformations() 
    2299   TRY 
    2300   { 
    2301     return transformations_; 
    2302   } 
    2303   CATCH_DUMP_ATTR 
    2304  
    2305   void CGrid::addTransGridSource(CGrid* gridSrc) 
    2306   TRY 
    2307   { 
    2308     if (gridSrc_.end() == gridSrc_.find(gridSrc)) 
    2309       gridSrc_.insert(make_pair(gridSrc,make_pair(false,""))); 
    2310   } 
    2311   CATCH_DUMP_ATTR 
    2312  
    2313   std::map<CGrid*,std::pair<bool,StdString> >& CGrid::getTransGridSource() 
    2314   TRY 
    2315   { 
    2316     return gridSrc_; 
    2317   } 
    2318   CATCH_DUMP_ATTR 
    2319  
    2320   /*! 
    2321      Complete all the necessary (and lacking) attributes of a grid 
    2322      This function is similar to gridTransformation but works only (till now) on generate_rectilinear_domain transformation 
    2323   */ 
    2324   void CGrid::completeGrid(CGrid* transformGridSrc) 
    2325   TRY 
    2326   { 
    2327     if (0 != transformGridSrc) 
    2328     { 
    2329       if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements()) 
    2330       { 
    2331         ERROR("CGrid::completeGrid(CGrid* transformGridSrc)", 
    2332              << "Two grids have different number of elements. " << std::endl 
    2333              << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl 
    2334              << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements()); 
    2335       } 
    2336     } 
    2337  
    2338     if (isGenerated()) return; 
    2339     setGenerated(); 
    2340  
    2341     CGridGenerate gridGenerate(this, transformGridSrc); 
    2342     gridGenerate.completeGrid(); 
    2343   } 
    2344   CATCH_DUMP_ATTR 
    2345  
    2346   bool CGrid::isGenerated() 
    2347   TRY 
    2348   { 
    2349     return isGenerated_; 
    2350   } 
    2351   CATCH 
    2352  
    2353   void CGrid::setGenerated() 
    2354   TRY 
    2355   { 
    2356     isGenerated_ = true; 
    2357   } 
    2358   CATCH_DUMP_ATTR 
    2359  
    2360   void CGrid::transformGrid(CGrid* transformGridSrc) 
    2361   TRY 
    2362   { 
    2363     if (!transformGridSrc) 
    2364       ERROR("CGrid::transformGrid(CGrid* transformGridSrc)", 
    2365             << "Impossible to transform grid '" << getId() << "', the source grid is null."); 
    2366  
    2367     if (isTransformed()) return; 
    2368     setTransformed(); 
    2369     if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements()) 
    2370     { 
    2371       ERROR("CGrid::transformGrid(CGrid* transformGridSrc)", 
    2372            << "Two grids have different number of elements. " << std::endl 
    2373            << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl 
    2374            << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements()); 
    2375     } 
     2013 
     2014//**************************************************************** 
     2015//**************************************************************** 
     2016 
     2017//---------------------------------------------------------------- 
     2018 
     2019  CGrid* CGrid::duplicateSentGrid(void) 
     2020  { 
     2021    CGrid* newGrid ; 
     2022    string sentGridId="sent__"+getId() ; 
     2023    if (has(sentGridId)) newGrid = get(sentGridId) ; 
    23762024    else 
    23772025    { 
    2378     } 
    2379  
    2380     transformations_ = new CGridTransformation(this, transformGridSrc); 
    2381     transformations_->computeAll(); 
    2382     if (0 < transformations_->getNbAlgo()) hasTransform_ = true; 
    2383  
    2384     // Ok, now need to compute index of grid source 
    2385     transformGridSrc->checkMaskIndex(false); 
    2386   } 
    2387   CATCH_DUMP_ATTR 
    2388  
    2389   bool CGrid::hasTransform() 
    2390   TRY 
    2391   { 
    2392     if (hasTransform_) return hasTransform_; 
    2393  
    2394     std::vector<CDomain*> domList = getDomains(); 
    2395     std::vector<CAxis*> axisList = getAxis(); 
    2396     std::vector<CScalar*> scalarList = getScalars(); 
    2397  
    2398     for (int idx = 0; idx < domList.size(); ++idx) hasTransform_ |= domList[idx]->hasTransformation(); 
    2399     for (int idx = 0; idx < axisList.size(); ++idx) hasTransform_ |= axisList[idx]->hasTransformation(); 
    2400     for (int idx = 0; idx < scalarList.size(); ++idx) hasTransform_ |= scalarList[idx]->hasTransformation(); 
    2401  
    2402     return hasTransform_; 
    2403   } 
    2404   CATCH_DUMP_ATTR 
    2405  
    2406   /*! 
    2407   \brief Get the list of domain pointers 
    2408   \return list of domain pointers 
    2409   */ 
    2410   std::vector<CDomain*> CGrid::getDomains() 
    2411   TRY 
    2412   { 
    2413     std::vector<CDomain*> domList; 
    2414     if (!domList_.empty()) 
    2415     { 
    2416       for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i])); 
    2417     } 
    2418     return domList; 
    2419   } 
    2420   CATCH_DUMP_ATTR 
    2421  
    2422   /*! 
    2423   \brief Get the list of  axis pointers 
    2424   \return list of axis pointers 
    2425   */ 
    2426   std::vector<CAxis*> CGrid::getAxis() 
    2427   TRY 
    2428   { 
    2429     std::vector<CAxis*> aList; 
    2430     if (!axisList_.empty()) 
    2431       for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i])); 
    2432  
    2433     return aList; 
    2434   } 
    2435   CATCH_DUMP_ATTR 
    2436  
    2437   /*! 
    2438   \brief Get the list of  axis pointers 
    2439   \return list of axis pointers 
    2440   */ 
    2441   std::vector<CScalar*> CGrid::getScalars() 
    2442   TRY 
    2443   { 
    2444     std::vector<CScalar*> sList; 
    2445     if (!scalarList_.empty()) 
    2446       for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i])); 
    2447  
    2448     return sList; 
    2449   } 
    2450   CATCH_DUMP_ATTR 
    2451  
    2452   /*! 
    2453   \brief Get domain pointer with index 
    2454   \return domain pointer 
    2455   */ 
    2456   CDomain* CGrid::getDomain(int domainIndex) 
    2457   TRY 
    2458   { 
    2459     std::vector<CDomain*> domainListP = this->getDomains(); 
    2460     if (domainListP.empty()) 
    2461     { 
    2462       ERROR("CGrid::getDomain(int domainIndex)", 
    2463             << "No domain associated to this grid. " << std::endl 
    2464             << "Grid id = " << this->getId()); 
    2465     } 
    2466  
    2467     if (domainIndex >= domainListP.size() || (domainIndex < 0)) 
    2468       ERROR("CGrid::getDomain(int domainIndex)", 
    2469             << "Domain with the index doesn't exist " << std::endl 
    2470             << "Grid id = " << this->getId() << std::endl 
    2471             << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl); 
    2472  
    2473     return domainListP[domainIndex]; 
    2474   } 
    2475   CATCH_DUMP_ATTR 
    2476  
    2477   /*! 
    2478   \brief Get the axis pointer with index 
    2479   \return axis pointer 
    2480   */ 
    2481   CAxis* CGrid::getAxis(int axisIndex) 
    2482   TRY 
    2483   { 
    2484     std::vector<CAxis*> axisListP = this->getAxis(); 
    2485     if (axisListP.empty()) 
    2486     { 
    2487       ERROR("CGrid::getDomain(int axisIndex)", 
    2488             << "No axis associated to this grid. " << std::endl 
    2489             << "Grid id = " << this->getId()); 
    2490     } 
    2491  
    2492     if (axisIndex >= axisListP.size() || (axisIndex < 0)) 
    2493       ERROR("CGrid::getDomain(int axisIndex)", 
    2494             << "Domain with the index doesn't exist " << std::endl 
    2495             << "Grid id = " << this->getId() << std::endl 
    2496             << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl); 
    2497  
    2498     return axisListP[axisIndex]; 
    2499   } 
    2500   CATCH_DUMP_ATTR 
    2501  
    2502   /*! 
    2503   \brief Get the a scalar pointer 
    2504   \return scalar pointer 
    2505   */ 
    2506   CScalar* CGrid::getScalar(int scalarIndex) 
    2507   TRY 
    2508   { 
    2509     std::vector<CScalar*> scalarListP = this->getScalars(); 
    2510     if (scalarListP.empty()) 
    2511     { 
    2512       ERROR("CGrid::getScalar(int scalarIndex)", 
    2513             << "No scalar associated to this grid. " << std::endl 
    2514             << "Grid id = " << this->getId()); 
    2515     } 
    2516  
    2517     if (scalarIndex >= scalarListP.size() || (scalarIndex < 0)) 
    2518       ERROR("CGrid::getScalar(int scalarIndex)", 
    2519             << "Scalar with the index doesn't exist " << std::endl 
    2520             << "Grid id = " << this->getId() << std::endl 
    2521             << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl); 
    2522  
    2523     return scalarListP[scalarIndex]; 
    2524   } 
    2525   CATCH_DUMP_ATTR 
    2526  
    2527   /*! 
    2528   \brief Set domain(s) of a grid from a list 
    2529   \param[in] domains list of domains 
    2530   */ 
    2531   void CGrid::setDomainList(const std::vector<CDomain*> domains) 
    2532   TRY 
    2533   { 
    2534     if (isDomListSet) return; 
    2535     std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 
    2536     if (!domains.empty() && domList.empty()) 
    2537     { 
    2538       for (int i = 0; i < domains.size(); ++i) 
    2539         this->getVirtualDomainGroup()->addChild(domains[i]); 
    2540       domList = this->getVirtualDomainGroup()->getAllChildren(); 
    2541     } 
    2542  
    2543     if (!domList.empty()) 
    2544     { 
    2545       int sizeDom = domList.size(); 
    2546       domList_.resize(sizeDom); 
    2547       for (int i = 0; i < sizeDom; ++i) 
    2548       { 
    2549         domList_[i] = domList[i]->getId(); 
    2550       } 
    2551       isDomListSet = true; 
    2552     } 
    2553   } 
    2554   CATCH_DUMP_ATTR 
    2555  
    2556   /*! 
    2557   \brief Set axis(s) of a grid from a list 
    2558   \param[in] axis list of axis 
    2559   */ 
    2560   void CGrid::setAxisList(const std::vector<CAxis*> axis) 
    2561   TRY 
    2562   { 
    2563     if (isAxisListSet) return; 
    2564     std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 
    2565     if (!axis.empty() && aList.empty()) 
    2566     { 
    2567       for (int i = 0; i < axis.size(); ++i) 
    2568         this->getVirtualAxisGroup()->addChild(axis[i]); 
    2569       aList = this->getVirtualAxisGroup()->getAllChildren(); 
    2570     } 
    2571  
    2572     if (!aList.empty()) 
    2573     { 
    2574       int sizeAxis = aList.size(); 
    2575       axisList_.resize(sizeAxis); 
    2576       for (int i = 0; i < sizeAxis; ++i) 
    2577       { 
    2578         axisList_[i] = aList[i]->getId(); 
    2579       } 
    2580       isAxisListSet = true; 
    2581     } 
    2582   } 
    2583   CATCH_DUMP_ATTR 
    2584  
    2585   /*! 
    2586   \brief Set scalar(s) of a grid from a list 
    2587   \param[in] scalars list of scalars 
    2588   */ 
    2589   void CGrid::setScalarList(const std::vector<CScalar*> scalars) 
    2590   TRY 
    2591   { 
    2592     if (isScalarListSet) return; 
    2593     std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 
    2594     if (!scalars.empty() && sList.empty()) 
    2595     { 
    2596       for (int i = 0; i < scalars.size(); ++i) 
    2597         this->getVirtualScalarGroup()->addChild(scalars[i]); 
    2598       sList = this->getVirtualScalarGroup()->getAllChildren(); 
    2599     } 
    2600  
    2601     if (!sList.empty()) 
    2602     { 
    2603       int sizeScalar = sList.size(); 
    2604       scalarList_.resize(sizeScalar); 
    2605       for (int i = 0; i < sizeScalar; ++i) 
    2606       { 
    2607         scalarList_[i] = sList[i]->getId(); 
    2608       } 
    2609       isScalarListSet = true; 
    2610     } 
    2611   } 
    2612   CATCH_DUMP_ATTR 
    2613  
    2614   /*! 
    2615   \brief Get list of id of domains 
    2616   \return id list of domains 
    2617   */ 
    2618   std::vector<StdString> CGrid::getDomainList() 
    2619   TRY 
    2620   { 
    2621     setDomainList(); 
    2622     return domList_; 
    2623   } 
    2624   CATCH 
    2625  
    2626   /*! 
    2627   \brief Get list of id of axis 
    2628   \return id list of axis 
    2629   */ 
    2630   std::vector<StdString> CGrid::getAxisList() 
    2631   TRY 
    2632   { 
    2633     setAxisList(); 
    2634     return axisList_; 
    2635   } 
    2636   CATCH 
    2637  
    2638   /*! 
    2639   \brief Get list of id of scalar 
    2640   \return id list of scalar 
    2641   */ 
    2642   std::vector<StdString> CGrid::getScalarList() 
    2643   TRY 
    2644   { 
    2645     setScalarList(); 
    2646     return scalarList_; 
    2647   } 
    2648   CATCH 
    2649  
    2650   /*! 
    2651     Send all attributes of domains from client to server 
    2652   */ 
    2653   void CGrid::sendAllDomains() 
    2654   TRY 
    2655   { 
    2656     std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 
    2657     int dSize = domList.size(); 
    2658     for (int i = 0; i < dSize; ++i) 
    2659     { 
    2660       sendAddDomain(domList[i]->getId()); 
    2661       domList[i]->sendAllAttributesToServer(); 
    2662     } 
    2663   } 
    2664   CATCH_DUMP_ATTR 
    2665  
    2666   /*! 
    2667     Send all attributes of axis from client to server 
    2668   */ 
    2669   void CGrid::sendAllAxis() 
    2670   TRY 
    2671   { 
    2672     std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 
    2673     int aSize = aList.size(); 
    2674  
    2675     for (int i = 0; i < aSize; ++i) 
    2676     { 
    2677       sendAddAxis(aList[i]->getId()); 
    2678       aList[i]->sendAllAttributesToServer(); 
    2679     } 
    2680   } 
    2681   CATCH_DUMP_ATTR 
    2682  
    2683   /*! 
    2684     Send all attributes of scalars from client to server 
    2685   */ 
    2686   void CGrid::sendAllScalars() 
    2687   TRY 
    2688   { 
    2689     std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 
    2690     int sSize = sList.size(); 
    2691  
    2692     for (int i = 0; i < sSize; ++i) 
    2693     { 
    2694       sendAddScalar(sList[i]->getId()); 
    2695       sList[i]->sendAllAttributesToServer(); 
    2696     } 
    2697   } 
    2698   CATCH_DUMP_ATTR 
     2026      newGrid = CGrid::create(sentGridId) ; 
     2027      for(auto element : elements_) 
     2028      { 
     2029        if (element.type==TYPE_DOMAIN)       
     2030        { 
     2031          CDomain* domain = CDomain::create(); 
     2032          domain->duplicateAttributes(element.domain) ; 
     2033          domain->name = element.domain->getId() ; 
     2034          newGrid->addDomain(domain->getId()) ; 
     2035        } 
     2036        else if (element.type==TYPE_AXIS)       
     2037        { 
     2038          CAxis* axis = CAxis::create(); 
     2039          axis->duplicateAttributes(element.axis) ; 
     2040          axis->name = element.axis->getId() ; 
     2041          newGrid->addAxis(axis->getId()) ; 
     2042        } 
     2043        else if (element.type==TYPE_SCALAR)       
     2044        { 
     2045          CScalar* scalar = CScalar::create(); 
     2046          scalar->duplicateAttributes(element.scalar) ; 
     2047          scalar->name = element.scalar->getId() ; 
     2048          newGrid->addScalar(scalar->getId()) ; 
     2049        } 
     2050      } 
     2051      newGrid->checkElementsAttributes() ; 
     2052    } 
     2053    return newGrid ; 
     2054  } 
     2055 
    26992056 
    27002057  void CGrid::setContextClient(CContextClient* contextClient) 
     
    27062063      clientsSet.insert(contextClient); 
    27072064    } 
    2708     for (int i=0; i<this->getDomains().size(); i++) 
    2709         this->getDomains()[i]->setContextClient(contextClient); 
    2710     for (int i=0; i<this->getAxis().size(); i++) 
    2711         this->getAxis()[i]->setContextClient(contextClient); 
     2065    for (auto domain : getDomains()) domain->setContextClient(contextClient); 
     2066    for (auto axis : getAxis()) axis->setContextClient(contextClient); 
     2067    for (auto scalar : getScalars()) scalar->setContextClient(contextClient); 
     2068    
    27122069  } 
    27132070  CATCH_DUMP_ATTR 
    27142071 
    2715   /*! 
    2716     Parse a grid, for now, it contains only domain, axis and scalar 
    2717   */ 
    2718   void CGrid::parse(xml::CXMLNode& node) 
    2719   TRY 
    2720   { 
    2721     SuperClass::parse(node); 
    2722  
    2723     if (node.goToChildElement()) 
    2724     { 
    2725       StdString domainName("domain"); 
    2726       StdString axisName("axis"); 
    2727       StdString scalarName("scalar"); 
    2728       do 
    2729       { 
    2730         if (node.getElementName() == domainName) { 
    2731           order_.push_back(2); 
    2732           this->getVirtualDomainGroup()->parseChild(node); 
    2733         } 
    2734         if (node.getElementName() == axisName) { 
    2735           order_.push_back(1); 
    2736           this->getVirtualAxisGroup()->parseChild(node); 
    2737         } 
    2738         if (node.getElementName() == scalarName) { 
    2739           order_.push_back(0); 
    2740           this->getVirtualScalarGroup()->parseChild(node); 
    2741         } 
    2742       } while (node.goToNextElement()); 
    2743       node.goToParentElement(); 
    2744     } 
    2745  
    2746     if (!order_.empty()) 
    2747     { 
    2748       int sizeOrd = order_.size(); 
    2749       axis_domain_order.resize(sizeOrd); 
    2750       for (int i = 0; i < sizeOrd; ++i) 
    2751       { 
    2752         axis_domain_order(i) = order_[i]; 
    2753       } 
    2754     } 
    2755  
    2756     setDomainList(); 
    2757     setAxisList(); 
    2758     setScalarList(); 
    2759    } 
    2760   CATCH_DUMP_ATTR 
    2761  
     2072  
     2073  void CGrid::computeGridLocalElements() 
     2074  { 
     2075    std::vector<CDomain*> domainList = this->getDomains(); 
     2076    std::vector<CAxis*> axisList = this->getAxis(); 
     2077    std::vector<CScalar*> scalarList = this->getScalars(); 
     2078    auto domain=domainList.begin() ; 
     2079    auto axis=axisList.begin() ; 
     2080    auto scalar=scalarList.begin() ; 
     2081    vector<CLocalElement*> elements; 
     2082    for(auto order : order_) 
     2083    { 
     2084      if (order==2)  
     2085      { 
     2086        elements.push_back((*domain)->getLocalElement()); 
     2087        domain++ ; 
     2088      } 
     2089      else if (order==1) 
     2090      { 
     2091        elements.push_back((*axis)->getLocalElement()); 
     2092        axis++ ; 
     2093      } 
     2094      else if (order==0) 
     2095      {  
     2096        elements.push_back((*scalar)->getLocalElement()); 
     2097        scalar++ ; 
     2098      } 
     2099    } 
     2100    if (hasMask())  
     2101    { 
     2102      vector<bool> mask(getMask().getVector()) ; 
     2103      gridLocalElements_ = new CGridLocalElements(elements, mask) ;   
     2104    } 
     2105    else gridLocalElements_ = new CGridLocalElements(elements) ;   
     2106  } 
     2107 
     2108  void CGrid::computeModelToWorkflowConnector(void) 
     2109  { 
     2110    modelToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::MODEL,CElementView::WORKFLOW,true) ; 
     2111  } 
     2112 
     2113  void CGrid::computeWorkflowToFullConnector(void) 
     2114  { 
     2115    workflowToFullConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::FULL) ; 
     2116  } 
     2117 
     2118  void CGrid::computeWorkflowToModelConnector(void) 
     2119  { 
     2120    workflowToModelConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::MODEL,true) ; 
     2121  } 
     2122 
     2123  void CGrid::computeFullToWorkflowConnector(void) 
     2124  { 
     2125    fullToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::FULL,CElementView::WORKFLOW) ; 
     2126  } 
     2127 
     2128  void CGrid::computeServerFromClientConnector(void) 
     2129  { 
     2130    vector<CGathererConnector*> connectors ; 
     2131    for(auto& element : getElements()) 
     2132    { 
     2133      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ; 
     2134      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ;  
     2135      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ;  
     2136    } 
     2137    serverFromClientConnector_ = new CGridGathererConnector(connectors) ; 
     2138  } 
     2139 
     2140  void CGrid::computeServerToClientConnector(void) 
     2141  { 
     2142    vector<CScattererConnector*> connectors ; 
     2143    for(auto& element : getElements()) 
     2144    { 
     2145      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerToClientConnector()) ; 
     2146      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerToClientConnector()) ;  
     2147      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerToClientConnector()) ;  
     2148    } 
     2149    serverToClientConnector_ = new CGridScattererConnector(connectors) ; 
     2150  } 
     2151 
     2152  void CGrid::computeClientFromClientConnector(void) 
     2153  { 
     2154    vector<CGathererConnector*> connectors ; 
     2155    for(auto& element : getElements()) 
     2156    { 
     2157      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ; 
     2158      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ;  
     2159      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ;  
     2160    } 
     2161    clientFromClientConnector_ = new CGridGathererConnector(connectors) ; 
     2162  } 
     2163 
     2164   
    27622165} // namespace xios 
  • XIOS/dev/dev_trunk_graph/src/node/grid.hpp

    r1653 r2019  
    1616#include "utils.hpp" 
    1717#include "transformation_enum.hpp" 
     18#include "grid_local_connector.hpp" 
     19#include "grid_elements.hpp" 
     20#include "grid_scatterer_connector.hpp" 
     21#include "grid_gatherer_connector.hpp" 
     22#include "transformation_path.hpp" 
     23#include "filter.hpp" 
     24#include "grid_algorithm.hpp" 
     25 
    1826 
    1927namespace xios { 
     
    3139   class CServerDistributionDescription; 
    3240   class CClientServerMapping; 
    33    class CGridTransformation; 
    34  
     41   
    3542   ///-------------------------------------------------------------- 
    3643 
     
    5057         typedef CGridAttributes SuperClassAttribute; 
    5158 
     59      private: 
     60         
     61        // define a structure to store elements (CDomain, CAxis, CScalar) using a void* and a type to cast the pointer 
     62         enum EElementType { TYPE_SCALAR, TYPE_AXIS, TYPE_DOMAIN } ; 
     63         struct SElement {void* ptr ; EElementType type ; CScalar* scalar ;  CAxis* axis ; CDomain* domain ; } ; 
     64         vector<SElement> elements_ ; 
     65         bool elementsComputed_ = false ;  
     66         /** retrieve the vector of elements as a structure containing a void* and the type of pointer */ 
     67         vector<SElement>& getElements(void) { if (!elementsComputed_) computeElements() ; return elements_ ; }  
     68         void computeElements(void) ; 
     69         /** List order of axis and domain in a grid, if there is a domain, it will take value 2, axis 1, scalar 0 */ 
     70         std::vector<int> order_; 
     71 
    5272      public: 
    5373 
     
    5777         enum EEventId 
    5878         { 
    59            EVENT_ID_INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR 
     79           EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR, 
     80           EVENT_ID_SEND_MASK, 
     81 
    6082         }; 
    6183 
     
    7092 
    7193         void checkEligibilityForCompressedOutput(); 
    72  
    73          void solveDomainAxisRef(bool areAttributesChecked); 
     94          
     95 
    7496 
    7597         void checkMaskIndex(bool doCalculateIndex); 
     
    89111         StdSize getDimension(void); 
    90112 
    91          StdSize  getDataSize(void) const; 
    92  
    93          /// Entrees-sorties de champs 
    94          template <int n> 
    95          void inputField(const CArray<double,n>& field, CArray<double,1>& stored) const; 
    96          template <int n> 
    97          void maskField(const CArray<double,n>& field, CArray<double,1>& stored) const; 
    98          template <int n> 
    99          void outputField(const CArray<double,1>& stored, CArray<double,n>& field) const;   
    100          template <int n> 
    101          void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) const;  
    102  
     113         StdSize  getDataSize(void) ; 
     114 
     115         /** 
     116          * Get the local data grid size, ie the size of the compressed grid (inside the workflow) 
     117          * \return The size od the compressed grid 
     118          */ 
     119         StdSize  getLocalDataSize(void) ; 
     120 
     121  
    103122         virtual void parse(xml::CXMLNode& node); 
    104123 
     
    129148 
    130149      public:             
    131          void computeIndexServer(void); 
    132          void computeIndex(void); 
    133          void computeIndexScalarGrid(); 
    134          void computeWrittenIndex(); 
     150         void solveDomainAxisRef(bool areAttributesChecked); 
     151         void checkElementsAttributes(void) ; 
    135152 
    136153         void solveDomainRef(bool checkAtt); 
    137154         void solveAxisRef(bool checkAtt); 
    138155         void solveScalarRef(bool checkAtt); 
    139          void solveDomainAxisRefInheritance(bool apply = true); 
    140         void solveTransformations(); 
     156         void solveElementsRefInheritance(bool apply = true); 
     157        // void solveTransformations(); 
    141158         void solveDomainAxisBaseRef(); 
    142159 
     
    144161         CAxis* addAxis(const std::string& id=StdString()); 
    145162         CScalar* addScalar(const std::string& id=StdString()); 
    146          void sendAddDomain(const std::string& id=""); 
    147          void sendAddAxis(const std::string& id=""); 
    148          void sendAddScalar(const std::string& id=""); 
    149          void sendAllDomains(); 
    150          void sendAllAxis(); 
    151          void sendAllScalars(); 
    152  
     163 
     164      public: 
     165         void sendGridToFileServer(CContextClient* client) ; 
     166      private: 
     167         std::set<CContextClient*> sendGridToFileServer_done_ ; 
     168      
     169      public: 
     170         void sendGridToCouplerOut(CContextClient* client, const string& fieldId) ; 
     171      private: 
     172         std::set<CContextClient*> sendGridToCouplerOut_done_ ; 
     173 
     174      public: 
     175         void makeAliasForCoupling(const string& fieldId) ; 
     176 
     177      public: 
     178         void sendAddDomain(const std::string& id,CContextClient* contextClient); 
     179         void sendAddAxis(const std::string& id,CContextClient* contextClient); 
     180         void sendAddScalar(const std::string& id,CContextClient* contextClient); 
     181         
    153182         static void recvAddDomain(CEventServer& event); 
    154183         void recvAddDomain(CBufferIn& buffer); 
     
    159188 
    160189         static bool dispatchEvent(CEventServer& event); 
    161          static void recvIndex(CEventServer& event); 
    162          void recvIndex(vector<int> ranks, vector<CBufferIn*> buffers); 
    163          void sendIndex(void); 
    164          void sendIndexScalarGrid(); 
    165  
     190        
     191       public: 
    166192         void setContextClient(CContextClient* contextClient); 
    167193 
    168          void computeDomConServer(); 
    169          std::map<int, int> getDomConServerSide(); 
    170194         std::map<int, StdSize> getAttributesBufferSize(CContextClient* client, bool bufferForWriting = false); 
    171195         std::map<int, StdSize> getDataBufferSize(CContextClient* client, const std::string& id = "", bool bufferForWriting = false); 
     
    185209         bool doGridHaveDataToWrite(); 
    186210         bool doGridHaveDataDistributed(CContextClient* client = 0); 
    187          size_t getWrittenDataSize() const; 
    188          int getNumberWrittenIndexes() const; 
    189          int getTotalNumberWrittenIndexes() const; 
    190          int getOffsetWrittenIndexes() const; 
    191  
    192          CDistributionServer* getDistributionServer(); 
    193          CDistributionClient* getDistributionClient(); 
    194          CGridTransformation* getTransformations(); 
    195  
    196          void transformGrid(CGrid* transformGridSrc); 
    197          void completeGrid(CGrid* transformGridSrc = 0); 
    198          void doAutoDistribution(CGrid* transformGridSrc); 
    199          bool isTransformed(); 
    200          void setTransformed(); 
    201          bool isGenerated(); 
    202          void setGenerated(); 
    203          void addTransGridSource(CGrid* gridSrc); 
    204          std::map<CGrid*, std::pair<bool,StdString> >& getTransGridSource(); 
    205          bool hasTransform(); 
    206          size_t getGlobalWrittenSize(void) ; 
    207       public: 
    208          CArray<int, 1> storeIndex_client; 
    209          CArray<bool, 1> storeMask_client; 
    210  
    211 /** Map containing indexes that will be sent in sendIndex(). */ 
    212          std::map<CContextClient*, map<int, CArray<int, 1> > > storeIndex_toSrv; 
    213  
    214 /** Map storing the number of senders. Key = size of receiver's intracomm */ 
    215          std::map<int, std::map<int,int> > nbSenders; 
    216  
    217          std::map<CContextClient*, std::map<int,int> > nbReadSenders; 
    218  
    219          map<int, CArray<int, 1> > storeIndex_fromSrv; // Support, for now, reading with level-1 server 
    220  
    221          map<int, CArray<size_t, 1> > outIndexFromClient;  // Deprecated 
    222  
    223          map<int, CArray<size_t, 1> > compressedOutIndexFromClient; 
    224  
    225 /** Map storing received indexes. Key = sender rank, value = index array. */ 
    226          map<int, CArray<size_t, 1> > outGlobalIndexFromClient; 
    227  
    228 // Manh Ha's comment: " A client receives global index from other clients (via recvIndex) 
    229 // then does mapping these index into local index of STORE_CLIENTINDEX 
    230 // In this way, store_clientIndex can be used as an input of a source filter 
    231 // Maybe we need a flag to determine whether a client wants to write. TODO " 
    232  
    233 /** Map storing received data. Key = sender rank, value = data array. 
    234  *  The map is created in CGrid::computeClientIndex and filled upon receiving data in CField::recvUpdateData() */ 
    235          map<int, CArray<size_t, 1> > outLocalIndexStoreOnClient;  
    236  
    237 /** Indexes calculated based on server-like distribution. 
    238  *  They are used for writing/reading data and only calculated for server level that does the writing/reading. 
    239  *  Along with localIndexToWriteOnClient, these indexes are used to correctly place incoming data. */ 
    240          CArray<size_t,1> localIndexToWriteOnServer; 
    241  
    242 /** Indexes calculated based on client-like distribution. 
    243  *  They are used for writing/reading data and only calculated for server level that does the writing/reading. 
    244  *  Along with localIndexToWriteOnServer, these indexes are used to correctly place incoming data. */ 
    245          CArray<size_t,1> localIndexToWriteOnClient; 
    246  
    247          CArray<size_t,1> indexFromClients; 
     211 
     212         /////////////////////////////////////////// 
     213         ////////    TRANSFORMATIONS           ///// 
     214         /////////////////////////////////////////// 
     215      public: 
     216         pair<shared_ptr<CFilter>, shared_ptr<CFilter> > buildTransformationGraph(CGarbageCollector& gc, bool isSource, CGrid* gridSrc, double detectMissingValues, 
     217                                                                                  double defaultValue, CGrid*& newGrid, bool graphEnabled=false) ; 
     218      private: 
     219        CGridAlgorithm* gridAlgorithm_ = nullptr ; 
     220      public: 
     221        void setGridAlgorithm(CGridAlgorithm* gridAlgorithm) {gridAlgorithm_ = gridAlgorithm;} 
     222        CGridAlgorithm* getGridAlgorithm(void) { return gridAlgorithm_ ;} 
     223        
     224        /////////////////////////////////////////// 
     225      public: 
     226 
     227        size_t getGlobalWrittenSize(void) ; 
     228          
     229         bool isCompleted(void) ; 
     230         void setCompleted(void) ; 
     231         void unsetCompleted(void) ; 
     232 
    248233 
    249234         bool hasMask(void) const; 
    250          void checkMask(void); 
    251          void createMask(void); 
    252          void modifyMask(const CArray<int,1>& indexToModify, bool valueToModify = false); 
    253          void modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue = false); 
    254  
    255          void computeGridGlobalDimension(const std::vector<CDomain*>& domains, 
    256                                          const std::vector<CAxis*>& axis, 
    257                                          const std::vector<CScalar*>& scalars, 
    258                                          const CArray<int,1>& axisDomainOrder); 
    259  
    260       private: 
    261        template<int N> 
    262        void checkGridMask(CArray<bool,N>& gridMask, 
    263                           const std::vector<CArray<bool,1>* >& domainMasks, 
    264                           const std::vector<CArray<bool,1>* >& axisMasks, 
    265                           const CArray<int,1>& axisDomainOrder, 
    266                           bool createMask = false); 
    267         template<int N> 
    268         void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify); 
    269  
    270         template<int N> 
    271         void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue); 
    272  
    273         void storeField_arr(const double* const data, CArray<double, 1>& stored) const; 
    274         void restoreField_arr(const CArray<double, 1>& stored, double* const data) const; 
    275         void uncompressField_arr(const double* const data, CArray<double, 1>& outData) const; 
    276         void maskField_arr(const double* const data, CArray<double, 1>& stored) const; 
    277  
     235        /** get mask pointer stored in mask_1d, or mask_2d, or..., or mask_7d */ 
     236         CArray<bool,1> mask_ ; 
     237         CArray<bool,1>& getMask(void) ; 
     238 
     239      private: 
     240        /** Client-like distribution calculated based on the knowledge of the entire grid */ 
     241       CDistributionClient* clientDistribution_; 
     242     public:  
     243       void computeClientDistribution(void) ; 
     244     private: 
     245       bool computeClientDistribution_done_ = false ; 
     246     public: 
     247       CDistributionClient* getClientDistribution(void);  
     248 
     249     private:    
    278250        void setVirtualDomainGroup(CDomainGroup* newVDomainGroup); 
    279251        void setVirtualAxisGroup(CAxisGroup* newVAxisGroup); 
     
    288260        CScalarGroup* getVirtualScalarGroup() const; 
    289261 
    290         void checkAttributesAfterTransformation(); 
    291         void setTransformationAlgorithms(); 
    292         void computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
    293                                    const CContextClient* client, 
    294                                    CClientServerMapping::GlobalIndexMap& globalIndexOnServer); 
    295262        int computeGridGlobalDimension(std::vector<int>& globalDim, 
    296263                                       const std::vector<CDomain*> domains, 
     
    299266                                       const CArray<int,1>& axisDomainOrder); 
    300267        int getDistributedDimension(); 
    301  
    302         void computeClientIndex(); 
    303         void computeConnectedClients(); 
    304         void computeClientIndexScalarGrid();  
    305         void computeConnectedClientsScalarGrid();  
    306  
     268      public: 
     269 
     270        bool isDataDistributed(void) ;  
    307271      private: 
    308272 
     
    311275        std::set<CContextClient*> clientsSet; 
    312276 
     277      private: 
    313278        bool isChecked; 
    314279        bool isDomainAxisChecked; 
     
    321286        bool isAxisListSet, isDomListSet, isScalarListSet; 
    322287 
    323 /** Client-like distribution calculated based on the knowledge of the entire grid */ 
    324         CDistributionClient* clientDistribution_; 
    325  
    326 /** Server-like distribution calculated upon receiving indexes */ 
    327         CDistributionServer* serverDistribution_; 
    328  
    329         CClientServerMapping* clientServerMap_; 
    330         size_t writtenDataSize_; 
    331         int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_; 
    332  
    333288/** Map storing local ranks of connected receivers. Key = size of receiver's intracomm. 
    334289  * It is calculated in computeConnectedClients(). */ 
     
    344299/** Size of data to be send in case of reading. It is calculated in recvIndex(). */ 
    345300        std::map<int,size_t> connectedDataSizeRead_; 
    346  
    347         bool isDataDistributed_;         
     301       
    348302         //! True if and only if the data defined on the grid can be outputted in a compressed way 
    349303        bool isCompressible_; 
    350304        std::set<std::string> relFilesCompressed; 
    351305 
    352         bool isTransformed_, isGenerated_; 
    353         bool computedWrittenIndex_; 
     306         
    354307        std::vector<int> axisPositionInGrid_; 
    355         CGridTransformation* transformations_; 
     308        void computeAxisPositionInGrid(void) ; 
     309        bool computeAxisPositionInGrid_done_ = false ; 
     310        std::vector<int>& getAxisPositionInGrid(void) { if (!computeAxisPositionInGrid_done_) computeAxisPositionInGrid() ; return axisPositionInGrid_ ;} 
     311 
    356312        bool hasDomainAxisBaseRef_;         
    357313        std::map<CGrid*, std::pair<bool,StdString> > gridSrc_; 
    358         bool hasTransform_; 
    359  
    360 /** Map storing global indexes of server-like (band-wise) distribution for sending to receivers. 
    361   * Key = size of receiver's intracomm. 
    362   */ 
    363 //        std::map<CContextClient*, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_; 
    364         std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_; 
    365  
    366  
    367 /** List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false) */ 
    368         std::vector<int> order_; 
     314 
     315     ////////////////////////////////////////////////////////////////////////////////////// 
     316     //  this part is related to distribution, element definition, views and connectors  // 
     317     ////////////////////////////////////////////////////////////////////////////////////// 
     318      public: 
     319       CGrid* duplicateSentGrid(void) ; 
     320      private: 
     321       static void recvMask(CEventServer& event) ; 
     322       void receiveMask(CEventServer& event) ; 
     323 
     324      private:   
     325        CGridLocalElements* gridLocalElements_= nullptr ; 
     326        void computeGridLocalElements(void) ; 
     327      public: 
     328        CGridLocalElements* getGridLocalElements(void) { if (gridLocalElements_==nullptr) computeGridLocalElements() ; return gridLocalElements_ ;} 
     329 
     330      private: 
     331        CGridLocalConnector* modelToWorkflowConnector_ = nullptr ; 
     332      public: 
     333        void computeModelToWorkflowConnector(void) ; 
     334        CGridLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_;} 
     335 
     336      private: 
     337        CGridLocalConnector* workflowToModelConnector_ ; 
     338      public: 
     339        void computeWorkflowToModelConnector(void) ; 
     340        CGridLocalConnector* getWorkflowToModelConnector(void) { if (workflowToModelConnector_==nullptr) computeWorkflowToModelConnector() ; return workflowToModelConnector_;} 
     341 
     342      public: //?  
     343        void distributeGridToFileServer(CContextClient* client); 
     344       
     345             
     346      private: 
     347        CGridLocalConnector* workflowToFullConnector_ = nullptr; 
     348      public: 
     349        void computeWorkflowToFullConnector(void) ; 
     350        CGridLocalConnector* getWorkflowToFullConnector(void) { if (workflowToFullConnector_==nullptr) computeWorkflowToFullConnector() ; return workflowToFullConnector_;} 
     351 
     352      private: 
     353        CGridLocalConnector* fullToWorkflowConnector_ = nullptr; 
     354      public: 
     355        void computeFullToWorkflowConnector(void) ; 
     356        CGridLocalConnector* getFullToWorkflowConnector(void) { if (fullToWorkflowConnector_==nullptr) computeFullToWorkflowConnector() ; return fullToWorkflowConnector_;} 
     357 
     358     
     359 
     360      private: 
     361         CGridGathererConnector* clientFromClientConnector_ = nullptr ; 
     362      public: 
     363         CGridGathererConnector* getClientFromClientConnector(void) { if (clientFromClientConnector_==nullptr) computeClientFromClientConnector() ; return clientFromClientConnector_;} 
     364         void computeClientFromClientConnector(void) ; 
     365 
     366      private: 
     367         map<CContextClient*, CGridScattererConnector*> clientToClientConnector_ ; 
     368      public: 
     369         CGridScattererConnector* getClientToClientConnector(CContextClient* client) { return clientToClientConnector_[client] ;} // make some test to see if connector exits for the given client 
     370   
     371 
     372      private: 
     373         map<CContextClient*,CGridGathererConnector*> clientFromServerConnector_  ; 
     374      public: 
     375         CGridGathererConnector* getClientFromServerConnector(CContextClient* client) { return clientFromServerConnector_[client];} 
     376         void computeClientFromServerConnector(void) ; 
     377 
     378      private: 
     379         CGridScattererConnector* serverToClientConnector_=nullptr ; 
     380      public: 
     381         CGridScattererConnector* getServerToClientConnector(void) { if (serverToClientConnector_==nullptr) computeServerToClientConnector() ; return serverToClientConnector_;} 
     382         void computeServerToClientConnector(void) ; 
     383      private: 
     384         map<CContextClient*, CGridScattererConnector*> clientToServerConnector_ ; 
     385      public: 
     386         CGridScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;} // make some test to see if connector exits for the given client 
     387          
     388      private: 
     389         CGridGathererConnector* serverFromClientConnector_ = nullptr ; 
     390      public: 
     391         CGridGathererConnector* getServerFromClientConnector(void) { if (serverFromClientConnector_==nullptr) computeServerFromClientConnector() ; return serverFromClientConnector_;} 
     392         void computeServerFromClientConnector(void) ; 
    369393 
    370394   }; // class CGrid 
    371  
    372    ///-------------------------------------------------------------- 
    373  
    374    template <int n> 
    375    void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const 
    376    TRY 
    377    { 
    378 //#ifdef __XIOS_DEBUG 
    379       if (this->getDataSize() != field.numElements()) 
    380          ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const", 
    381                 << "[ Awaiting data of size = " << this->getDataSize() << ", " 
    382                 << "Received data size = "      << field.numElements() << " ] " 
    383                 << "The data array does not have the right size! " 
    384                 << "Grid = " << this->getId()) 
    385 //#endif 
    386       this->storeField_arr(field.dataFirst(), stored); 
    387    } 
    388    CATCH 
    389  
    390    template <int n> 
    391    void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) const 
    392    { 
    393 //#ifdef __XIOS_DEBUG 
    394       if (this->getDataSize() != field.numElements()) 
    395          ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const", 
    396                 << "[ Awaiting data of size = " << this->getDataSize() << ", " 
    397                 << "Received data size = "      << field.numElements() << " ] " 
    398                 << "The data array does not have the right size! " 
    399                 << "Grid = " << this->getId()) 
    400 //#endif 
    401       this->maskField_arr(field.dataFirst(), stored); 
    402    } 
    403  
    404    template <int n> 
    405    void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const 
    406    TRY 
    407    { 
    408 //#ifdef __XIOS_DEBUG 
    409       if (this->getDataSize() != field.numElements()) 
    410          ERROR("void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const", 
    411                 << "[ Size of the data = " << this->getDataSize() << ", " 
    412                 << "Output data size = "   << field.numElements() << " ] " 
    413                 << "The ouput array does not have the right size! " 
    414                 << "Grid = " << this->getId()) 
    415 //#endif 
    416       this->restoreField_arr(stored, field.dataFirst()); 
    417    } 
    418    CATCH 
    419  
    420    /*! 
    421      This function removes the effect of mask on received data on the server. 
    422      This function only serve for the checking purpose. TODO: Something must be done to seperate mask and data_index from each other in received data 
    423      \data data received data with masking effect on the server 
    424      \outData data without masking effect 
    425    */ 
    426    template <int N> 
    427    void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData) const 
    428    TRY 
    429    {       
    430      uncompressField_arr(data.dataFirst(), outData); 
    431    } 
    432    CATCH 
    433  
    434    template<int N> 
    435    void CGrid::checkGridMask(CArray<bool,N>& gridMask, 
    436                              const std::vector<CArray<bool,1>* >& domainMasks, 
    437                              const std::vector<CArray<bool,1>* >& axisMasks, 
    438                              const CArray<int,1>& axisDomainOrder, 
    439                              bool createMask) 
    440    TRY 
    441    { 
    442      int idx = 0; 
    443      int numElement = axisDomainOrder.numElements(); 
    444      int dim = domainMasks.size() * 2 + axisMasks.size(); 
    445      std::vector<CDomain*> domainP = this->getDomains(); 
    446      std::vector<CAxis*> axisP = this->getAxis(); 
    447  
    448      std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim); 
    449      std::vector<int> currentIndex(dim); 
    450      int idxDomain = 0, idxAxis = 0; 
    451     for (int i = 0; i < numElement; ++i) 
    452     { 
    453       indexMap[i] = idx; 
    454       if (2 == axisDomainOrder(i)) { 
    455           eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni; 
    456           eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj; 
    457           idx += 2; ++idxDomain; 
    458       } 
    459       else if (1 == axisDomainOrder(i)) { 
    460 //        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements(); 
    461         eachDimSize[indexMap[i]] = axisP[idxAxis]->n; 
    462         ++idx; ++idxAxis; 
    463       } 
    464       else {}; 
    465     } 
    466  
    467     if (!gridMask.isEmpty() && !createMask) 
    468     { 
    469       for (int i = 0; i < dim; ++i) 
    470       { 
    471         if (gridMask.extent(i) != eachDimSize[i]) 
    472           ERROR("CGrid::checkMask(void)", 
    473                 << "The mask has one dimension whose size is different from the one of the local grid." << std::endl 
    474                 << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl 
    475                 << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl 
    476                 << "Grid = " << this->getId()) 
    477       } 
    478     } 
    479     else { 
    480         CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 
    481         gridMask = true; 
    482     } 
    483  
    484     int ssize = gridMask.numElements(); 
    485     idx = 0; 
    486     while (idx < ssize) 
    487     { 
    488       for (int i = 0; i < dim-1; ++i) 
    489       { 
    490         if (idxLoop[i] == eachDimSize[i]) 
    491         { 
    492           idxLoop[i] = 0; 
    493           ++idxLoop[i+1]; 
    494         } 
    495       } 
    496  
    497       // Find out outer index 
    498       idxDomain = idxAxis = 0; 
    499       bool maskValue = true; 
    500       for (int i = 0; i < numElement; ++i) 
    501       { 
    502         if (2 == axisDomainOrder(i)) 
    503         { 
    504           int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]; 
    505           if (idxTmp < (*domainMasks[idxDomain]).numElements()) 
    506             maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp); 
    507           else 
    508             maskValue = false; 
    509           ++idxDomain; 
    510         } 
    511         else if (1 == axisDomainOrder(i)) 
    512         { 
    513           int idxTmp = idxLoop[indexMap[i]]; 
    514           if (idxTmp < (*axisMasks[idxAxis]).numElements()) 
    515             maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp); 
    516           else 
    517             maskValue = false; 
    518  
    519           ++idxAxis; 
    520         } 
    521       } 
    522  
    523       int maskIndex = idxLoop[0]; 
    524       int mulDim = 1; 
    525       for (int k = 1; k < dim; ++k) 
    526       { 
    527         mulDim *= eachDimSize[k-1]; 
    528         maskIndex += idxLoop[k]*mulDim; 
    529       } 
    530       *(gridMask.dataFirst()+maskIndex) &= maskValue; 
    531  
    532       ++idxLoop[0]; 
    533       ++idx; 
    534     } 
    535    } 
    536    CATCH_DUMP_ATTR 
    537  
    538    template<int N> 
    539    void CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask, 
    540                                   const std::vector<int>& eachDimSize, 
    541                                   bool newValue) 
    542    TRY 
    543    { 
    544       if (N != eachDimSize.size()) 
    545       { 
    546         // ERROR("CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask, 
    547         //                                  const std::vector<int>& eachDimSize, 
    548         //                                  bool newValue)", 
    549         //       << "Dimension size of the mask is different from input dimension size." << std::endl 
    550         //       << "Mask dimension is " << N << "." << std::endl 
    551         //       << "Input dimension is " << eachDimSize.size() << "." << std::endl 
    552         //       << "Grid = " << this->getId()) 
    553       } 
    554       CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize); 
    555       gridMask = newValue; 
    556    } 
    557    CATCH_DUMP_ATTR 
    558                                   
    559  
    560    /*! 
    561      Modify the current mask of grid, the local index to be modified will take value false 
    562      \param [in/out] gridMask current mask of grid 
    563      \param [in] indexToModify local index to modify 
    564    */ 
    565    template<int N> 
    566    void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify) 
    567    TRY 
    568    {      
    569      int num = indexToModify.numElements(); 
    570      for (int idx = 0; idx < num; ++idx) 
    571      { 
    572        *(gridMask.dataFirst()+indexToModify(idx)) = valueToModify; 
    573      } 
    574    } 
    575    CATCH_DUMP_ATTR 
    576  
    577    ///-------------------------------------------------------------- 
    578  
    579  
    580395 
    581396   // Declare/Define CGridGroup and CGridDefinition 
  • XIOS/dev/dev_trunk_graph/src/node/interpolate_axis.cpp

    r937 r2019  
    11#include "interpolate_axis.hpp" 
     2#include "axis_algorithm_interpolate_coordinate.hpp" 
     3#include "axis_algorithm_interpolate.hpp" 
    24#include "type.hpp" 
    35#include "field.hpp" 
     
    2729  bool CInterpolateAxis::registerTrans() 
    2830  { 
    29     return registerTransformation(TRANS_INTERPOLATE_AXIS, CInterpolateAxis::create); 
     31    return registerTransformation(TRANS_INTERPOLATE_AXIS, {create, getTransformation}); 
    3032  } 
    3133 
     
    8486    return auxInputs; 
    8587  } 
     88 
     89  CGenericAlgorithmTransformation* CInterpolateAxis::createAlgorithm(bool isSource, 
     90                                                        CGrid* gridDst, CGrid* gridSrc, 
     91                                                        int elementPositionInGrid, 
     92                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     93                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     94                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     95                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     96                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     97                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     98  { 
     99    if (!coordinate.isEmpty())  return CAxisAlgorithmInterpolateCoordinate::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid,  
     100                                      elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     101                                      elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     102    else return CAxisAlgorithmInterpolate::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid,  
     103                elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     104                elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     105  } 
    86106} 
  • XIOS/dev/dev_trunk_graph/src/node/interpolate_axis.hpp

    r836 r2019  
    2020  class CInterpolateAxis; 
    2121  class CAxis; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CInterpolateAxis> SuperClass; 
    4243      typedef CInterpolateAxisAttributes SuperClassAttribute; 
     44      typedef CInterpolateAxis MyClass ; 
     45      typedef CTransformation<CAxis> SuperTransform ; 
    4346 
    4447    public : 
     
    5861      static StdString GetDefName(void); 
    5962      static ENodeType GetType(void); 
     63      const string& getId(void) { return this->SuperClass::getId();} 
     64      ETranformationType getTransformationType(void) { return TRANS_INTERPOLATE_AXIS ;} 
     65      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     66      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     67      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     68                                                               CGrid* gridDst, CGrid* gridSrc, 
     69                                                               int elementPositionInGrid, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     71                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     72                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     74                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     75                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    6076    private: 
    6177      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/interpolate_domain.cpp

    r1653 r2019  
    11#include "interpolate_domain.hpp" 
     2#include "domain_algorithm_interpolate.hpp" 
    23#include "type.hpp" 
    34 
     
    2728  bool CInterpolateDomain::registerTrans() 
    2829  { 
    29     registerTransformation(TRANS_INTERPOLATE_DOMAIN, create); 
     30    registerTransformation(TRANS_INTERPOLATE_DOMAIN, {create, getTransformation}); 
    3031  } 
    3132 
     
    6869  } 
    6970 
     71  CGenericAlgorithmTransformation* CInterpolateDomain::createAlgorithm(bool isSource, 
     72                                                        CGrid* gridDst, CGrid* gridSrc, 
     73                                                        int elementPositionInGrid, 
     74                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     75                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     76                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     77                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     78                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     79                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     80  { 
     81    return CDomainAlgorithmInterpolate::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     82                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     83                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     84  } 
    7085} 
  • XIOS/dev/dev_trunk_graph/src/node/interpolate_domain.hpp

    r1021 r2019  
    2020  class CInterpolateDomain; 
    2121  class CDomain; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CInterpolateDomain> SuperClass; 
    4243      typedef CInterpolateDomainAttributes SuperClassAttribute; 
     44      typedef CInterpolateDomain MyClass ; 
     45      typedef CTransformation<CDomain> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_INTERPOLATE_DOMAIN ;} 
     63      static CTransformation<CDomain>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/inverse_axis.cpp

    r836 r2019  
    11#include "inverse_axis.hpp" 
     2#include "axis_algorithm_inverse.hpp" 
    23#include "type.hpp" 
    34 
     
    2627  bool CInverseAxis::registerTrans() 
    2728  { 
    28     return registerTransformation(TRANS_INVERSE_AXIS, CInverseAxis::create); 
     29    return registerTransformation(TRANS_INVERSE_AXIS, {create, getTransformation}); 
    2930  } 
    3031 
     
    3940  {} 
    4041 
     42  CGenericAlgorithmTransformation* CInverseAxis::createAlgorithm(bool isSource, 
     43                                                        CGrid* gridDst, CGrid* gridSrc, 
     44                                                        int elementPositionInGrid, 
     45                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     46                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     47                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     48                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     49                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     50                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     51  { 
     52    return CAxisAlgorithmInverse::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     53                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     54                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition) ; 
     55  } 
    4156} 
  • XIOS/dev/dev_trunk_graph/src/node/inverse_axis.hpp

    r836 r2019  
    1919  class CInverseAxis; 
    2020  class CAxis; 
     21  class CGenericAlgorithmTransformation ; 
     22  class CGrid; 
    2123  ///-------------------------------------------------------------- 
    2224 
     
    3941      typedef CObjectTemplate<CInverseAxis> SuperClass; 
    4042      typedef CInverseAxisAttributes SuperClassAttribute; 
     43      typedef CInverseAxis MyClass ; 
     44      typedef CTransformation<CAxis> SuperTransform ; 
    4145 
    4246    public : 
     
    5458      static StdString GetDefName(void); 
    5559      static ENodeType GetType(void); 
    56  
     60      const string& getId(void) { return this->SuperClass::getId();} 
     61      ETranformationType getTransformationType(void) { return TRANS_INVERSE_AXIS ;} 
     62      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     63      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     64      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     65                                                               CGrid* gridDst, CGrid* gridSrc, 
     66                                                               int elementPositionInGrid, 
     67                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     70                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5773    private: 
    5874      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/mesh.cpp

    r1542 r2019  
    539539          } 
    540540        } 
    541         nodeHashList.resizeAndPreserve(nbHash); 
     541        if (nbHash==0) nodeHashList.resize(nbHash); 
     542        else nodeHashList.resizeAndPreserve(nbHash); 
    542543 
    543544        // (2.2) Generating global node indexes 
     
    986987          } 
    987988        } 
    988         edgeHashList.resizeAndPreserve(nEdgeHash); 
     989        if (nEdgeHash==0) edgeHashList.resize(nEdgeHash); 
     990        else edgeHashList.resizeAndPreserve(nEdgeHash); 
    989991 
    990992        // (2.3) Generating global edge indexes 
     
    13271329          } 
    13281330        } 
    1329         nodeIdxList.resizeAndPreserve(nIdx); 
     1331        if (nIdx==0) nodeIdxList.resize(nIdx); 
     1332        else nodeIdxList.resizeAndPreserve(nIdx); 
    13301333        CClientClientDHTSizet dhtNodeIdx(nodeIdx2Idx, comm); 
    13311334        dhtNodeIdx.computeIndexInfoMapping(nodeIdxList); 
     
    13771380          } 
    13781381        } 
    1379         edgeHashList.resizeAndPreserve(nEdgeHash); 
     1382        if (nEdgeHash==0) edgeHashList.resize(nEdgeHash); 
     1383        else edgeHashList.resizeAndPreserve(nEdgeHash); 
    13801384 
    13811385        // (3.4) Generating global edge indexes 
     
    17541758      } 
    17551759    } 
    1756     nghbFaces.resizeAndPreserve(2, nbNghb); 
     1760    if (nbNghb==0) nghbFaces.resize(2, nbNghb); 
     1761    else nghbFaces.resizeAndPreserve(2, nbNghb); 
    17571762  } // getGloNghbFacesNodeType 
    17581763 
     
    18061811      } 
    18071812    } 
    1808     nodeHashList.resizeAndPreserve(iIdx); 
     1813    if (iIdx==0) nodeHashList.resize(iIdx); 
     1814    else nodeHashList.resizeAndPreserve(iIdx); 
    18091815 
    18101816    // (1.2) Generating node indexes 
     
    19341940      } 
    19351941    } 
    1936     nghbFaces.resizeAndPreserve(2, nbNghb); 
     1942    if (nbNghb==0) nghbFaces.resize(2, nbNghb); 
     1943    else nghbFaces.resizeAndPreserve(2, nbNghb); 
    19371944  } // getGloNghbFacesEdgeType 
    19381945 
  • XIOS/dev/dev_trunk_graph/src/node/node_enum.hpp

    r1558 r2019  
    1515         eField,gField, 
    1616         eFile,gFile, 
     17         eCouplerIn,gCouplerIn, 
     18         eCouplerOut,gCouplerOut, 
    1719         eGrid,gGrid, 
    1820         eVariable,gVariable, 
  • XIOS/dev/dev_trunk_graph/src/node/node_type.hpp

    r1558 r2019  
    66#include "field.hpp" 
    77#include "file.hpp" 
     8#include "coupler_in.hpp" 
     9#include "coupler_out.hpp" 
    810#include "grid.hpp" 
    911#include "variable.hpp" 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_axis_to_axis.cpp

    r1314 r2019  
    11#include "reduce_axis_to_axis.hpp" 
     2#include "axis_algorithm_reduce_axis.hpp" 
    23#include "type.hpp" 
    34#include "axis.hpp" 
     
    2728  bool CReduceAxisToAxis::registerTrans() 
    2829  { 
    29     return registerTransformation(TRANS_REDUCE_AXIS_TO_AXIS, CReduceAxisToAxis::create); 
     30    return registerTransformation(TRANS_REDUCE_AXIS_TO_AXIS, {create, getTransformation}); 
    3031  } 
    3132 
     
    5657  } 
    5758 
     59  CGenericAlgorithmTransformation* CReduceAxisToAxis::createAlgorithm(bool isSource, 
     60                                                        CGrid* gridDst, CGrid* gridSrc, 
     61                                                        int elementPositionInGrid, 
     62                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     63                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     64                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     65                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     66                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     67                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     68  { 
     69    return CAxisAlgorithmReduceAxis::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     70                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     71                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     72  } 
    5873} 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_axis_to_axis.hpp

    r1301 r2019  
    1919  class CReduceAxisToAxis; 
    2020  class CAxis; 
    21  
     21  class CGenericAlgorithmTransformation ; 
     22  class CGrid; 
    2223  ///-------------------------------------------------------------- 
    2324 
     
    4041      typedef CObjectTemplate<CReduceAxisToAxis> SuperClass; 
    4142      typedef CReduceAxisToAxisAttributes SuperClassAttribute; 
     43      typedef CReduceAxisToAxis MyClass ; 
     44      typedef CTransformation<CAxis> SuperTransform ; 
    4245 
    4346    public : 
     
    5558      static StdString GetDefName(void); 
    5659      static ENodeType GetType(void); 
    57     private: 
     60      const string& getId(void) { return this->SuperClass::getId();} 
     61      ETranformationType getTransformationType(void) { return TRANS_REDUCE_AXIS_TO_AXIS ;} 
     62      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     63      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     64      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     65                                                               CGrid* gridDst, CGrid* gridSrc, 
     66                                                               int elementPositionInGrid, 
     67                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     70                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
     73   private: 
    5874      static bool registerTrans(); 
    5975      static CTransformation<CAxis>* create(const StdString& id, xml::CXMLNode* node); 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_axis_to_scalar.cpp

    r980 r2019  
    11#include "reduce_axis_to_scalar.hpp" 
     2#include "scalar_algorithm_reduce_axis.hpp" 
    23#include "type.hpp" 
    34 
     
    2627  bool CReduceAxisToScalar::registerTrans() 
    2728  { 
    28     return registerTransformation(TRANS_REDUCE_AXIS_TO_SCALAR, CReduceAxisToScalar::create); 
     29    return registerTransformation(TRANS_REDUCE_AXIS_TO_SCALAR, {create, getTransformation}); 
    2930  } 
    3031 
     
    4142  } 
    4243 
     44  CGenericAlgorithmTransformation* CReduceAxisToScalar::createAlgorithm(bool isSource, 
     45                                                        CGrid* gridDst, CGrid* gridSrc, 
     46                                                        int elementPositionInGrid, 
     47                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     48                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     49                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     50                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     51                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     52                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     53  { 
     54    return CScalarAlgorithmReduceAxis::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     55                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     56                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     57  } 
    4358} 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_axis_to_scalar.hpp

    r888 r2019  
    1919  class CReduceAxisToScalar; 
    2020  class CScalar; 
    21  
     21  class CGenericAlgorithmTransformation ; 
     22  class CGrid; 
    2223  ///-------------------------------------------------------------- 
    2324 
     
    4041      typedef CObjectTemplate<CReduceAxisToScalar> SuperClass; 
    4142      typedef CReduceAxisToScalarAttributes SuperClassAttribute; 
     43      typedef CReduceAxisToScalar MyClass ; 
     44      typedef CTransformation<CScalar> SuperTransform ; 
    4245 
    4346    public : 
     
    5558      static StdString GetDefName(void); 
    5659      static ENodeType GetType(void); 
     60      const string& getId(void) { return this->SuperClass::getId();} 
     61      ETranformationType getTransformationType(void) { return TRANS_REDUCE_AXIS_TO_SCALAR ;} 
     62      static CTransformation<CScalar>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     63      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     64      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     65                                                               CGrid* gridDst, CGrid* gridSrc, 
     66                                                               int elementPositionInGrid, 
     67                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     70                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5773    private: 
    5874      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_domain_to_axis.cpp

    r1299 r2019  
    11#include "reduce_domain_to_axis.hpp" 
     2#include "axis_algorithm_reduce_domain.hpp" 
    23#include "type.hpp" 
    34#include "axis.hpp" 
     
    2829  bool CReduceDomainToAxis::registerTrans() 
    2930  { 
    30     return registerTransformation(TRANS_REDUCE_DOMAIN_TO_AXIS, CReduceDomainToAxis::create); 
     31    return registerTransformation(TRANS_REDUCE_DOMAIN_TO_AXIS, {create, getTransformation}); 
    3132  } 
    3233 
     
    8788  } 
    8889 
     90  CGenericAlgorithmTransformation* CReduceDomainToAxis::createAlgorithm(bool isSource, 
     91                                                        CGrid* gridDst, CGrid* gridSrc, 
     92                                                        int elementPositionInGrid, 
     93                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     94                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     95                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     96                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     97                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     98                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     99  { 
     100    return CAxisAlgorithmReduceDomain::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     101                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     102                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition) ; 
     103  } 
    89104} 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_domain_to_axis.hpp

    r895 r2019  
    2020  class CAxis; 
    2121  class CDomain; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CReduceDomainToAxis> SuperClass; 
    4243      typedef CReduceDomainToAxisAttributes SuperClassAttribute; 
     44      typedef CReduceDomainToAxis MyClass ; 
     45     typedef CTransformation<CAxis> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
    58     private: 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_REDUCE_DOMAIN_TO_AXIS ;} 
     63      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
     74     private: 
    5975      static bool registerTrans(); 
    6076      static CTransformation<CAxis>* create(const StdString& id, xml::CXMLNode* node); 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_domain_to_scalar.cpp

    r1313 r2019  
    11#include "reduce_domain_to_scalar.hpp" 
     2#include "scalar_algorithm_reduce_domain.hpp" 
    23#include "type.hpp" 
    34 
     
    2627  bool CReduceDomainToScalar::registerTrans() 
    2728  { 
    28     return registerTransformation(TRANS_REDUCE_DOMAIN_TO_SCALAR, CReduceDomainToScalar::create); 
     29    return registerTransformation(TRANS_REDUCE_DOMAIN_TO_SCALAR, {create, getTransformation}); 
    2930  } 
    3031 
     
    4243  } 
    4344 
     45  CGenericAlgorithmTransformation* CReduceDomainToScalar::createAlgorithm(bool isSource, 
     46                                                        CGrid* gridDst, CGrid* gridSrc, 
     47                                                        int elementPositionInGrid, 
     48                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     49                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     50                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     51                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     52                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     53                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     54  { 
     55    return CScalarAlgorithmReduceDomain::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     56                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     57                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition) ; 
     58  } 
    4459} 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_domain_to_scalar.hpp

    r976 r2019  
    2020  class CDomain; 
    2121  class CScalar; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CReduceDomainToScalar> SuperClass; 
    4243      typedef CReduceDomainToScalarAttributes SuperClassAttribute; 
     44      typedef CReduceDomainToScalar MyClass ; 
     45      typedef CTransformation<CScalar> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_REDUCE_DOMAIN_TO_SCALAR ;} 
     63      static CTransformation<CScalar>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_scalar_to_scalar.cpp

    r1314 r2019  
    11#include "reduce_scalar_to_scalar.hpp" 
     2#include "scalar_algorithm_reduce_scalar.hpp" 
    23#include "type.hpp" 
    34 
     
    2627  bool CReduceScalarToScalar::registerTrans() 
    2728  { 
    28     return registerTransformation(TRANS_REDUCE_SCALAR_TO_SCALAR, CReduceScalarToScalar::create); 
     29    return registerTransformation(TRANS_REDUCE_SCALAR_TO_SCALAR, {create, getTransformation}); 
    2930  } 
    3031 
     
    4142  } 
    4243 
     44  CGenericAlgorithmTransformation* CReduceScalarToScalar::createAlgorithm(bool isSource, 
     45                                                        CGrid* gridDst, CGrid* gridSrc, 
     46                                                        int elementPositionInGrid, 
     47                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     48                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     49                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     50                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     51                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     52                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     53  { 
     54    return CScalarAlgorithmReduceScalar::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     55                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     56                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     57  } 
    4358} 
  • XIOS/dev/dev_trunk_graph/src/node/reduce_scalar_to_scalar.hpp

    r1314 r2019  
    1919  class CReduceScalarToScalar; 
    2020  class CScalar; 
    21  
     21  class CGenericAlgorithmTransformation ; 
     22  class CGrid; 
    2223  ///-------------------------------------------------------------- 
    2324 
     
    4041      typedef CObjectTemplate<CReduceScalarToScalar> SuperClass; 
    4142      typedef CReduceScalarToScalarAttributes SuperClassAttribute; 
     43      typedef CReduceScalarToScalar MyClass ; 
     44      typedef CTransformation<CScalar> SuperTransform ; 
    4245 
    4346    public : 
     
    5558      static StdString GetDefName(void); 
    5659      static ENodeType GetType(void); 
     60      const string& getId(void) { return this->SuperClass::getId();} 
     61      ETranformationType getTransformationType(void) { return TRANS_REDUCE_SCALAR_TO_SCALAR ;} 
     62      static CTransformation<CScalar>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     63      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     64      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     65                                                               CGrid* gridDst, CGrid* gridSrc, 
     66                                                               int elementPositionInGrid, 
     67                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     70                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5773    private: 
    5874      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/reorder_domain.cpp

    r1457 r2019  
    11#include "reorder_domain.hpp" 
     2#include "domain_algorithm_reorder.hpp" 
    23#include "type.hpp" 
    34 
     
    2728  bool CReorderDomain::registerTrans() 
    2829  { 
    29     registerTransformation(TRANS_REORDER_DOMAIN, CReorderDomain::create); 
     30    registerTransformation(TRANS_REORDER_DOMAIN, {create, getTransformation}); 
    3031  } 
    3132 
     
    4142  } 
    4243 
     44  CGenericAlgorithmTransformation* CReorderDomain::createAlgorithm(bool isSource, 
     45                                                        CGrid* gridDst, CGrid* gridSrc, 
     46                                                        int elementPositionInGrid, 
     47                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     48                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     49                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     50                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     51                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     52                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     53  { 
     54    return CDomainAlgorithmReorder::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     55                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     56                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     57  } 
    4358} 
  • XIOS/dev/dev_trunk_graph/src/node/reorder_domain.hpp

    r1457 r2019  
    2020  class CReorderDomain; 
    2121  class CDomain; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CReorderDomain> SuperClass; 
    4243      typedef CReorderDomainAttributes SuperClassAttribute; 
     44      typedef CReorderDomain MyClass ; 
     45      typedef CTransformation<CDomain> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
    58     private: 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_REORDER_DOMAIN ;} 
     63      static CTransformation<CDomain>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
     74     private: 
    5975      static bool registerTrans(); 
    6076      static CTransformation<CDomain>* create(const StdString& id, xml::CXMLNode* node); 
  • XIOS/dev/dev_trunk_graph/src/node/scalar.cpp

    r1314 r2019  
    77#include "xios_spl.hpp" 
    88#include "type.hpp" 
    9  
    10 namespace xios { 
    11  
    12    /// ////////////////////// Définitions ////////////////////// /// 
    13  
    14    CScalar::CScalar(void) 
    15       : CObjectTemplate<CScalar>() 
    16       , CScalarAttributes() 
    17       , relFiles() 
    18    { /* Ne rien faire de plus */ } 
    19  
    20    CScalar::CScalar(const StdString & id) 
    21       : CObjectTemplate<CScalar>(id) 
    22       , CScalarAttributes() 
    23       , relFiles() 
    24    { /* Ne rien faire de plus */ } 
    25  
    26    CScalar::~CScalar(void) 
    27    { /* Ne rien faire de plus */ } 
    28  
    29    std::map<StdString, ETranformationType> CScalar::transformationMapList_ = std::map<StdString, ETranformationType>(); 
    30    bool CScalar::dummyTransformationMapList_ = CScalar::initializeTransformationMap(CScalar::transformationMapList_); 
    31    bool CScalar::initializeTransformationMap(std::map<StdString, ETranformationType>& m) 
    32    { 
    33      m["reduce_axis"]   = TRANS_REDUCE_AXIS_TO_SCALAR; 
    34      m["extract_axis"]  = TRANS_EXTRACT_AXIS_TO_SCALAR; 
    35      m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_SCALAR; 
    36      m["reduce_scalar"] = TRANS_REDUCE_SCALAR_TO_SCALAR; 
    37    } 
    38  
    39    StdString CScalar::GetName(void)   { return (StdString("scalar")); } 
    40    StdString CScalar::GetDefName(void){ return (CScalar::GetName()); } 
    41    ENodeType CScalar::GetType(void)   { return (eScalar); } 
    42  
    43    CScalar* CScalar::createScalar() 
    44    { 
    45      CScalar* scalar = CScalarGroup::get("scalar_definition")->createChild(); 
    46      return scalar; 
    47    } 
    48  
    49    bool CScalar::IsWritten(const StdString & filename) const 
    50    { 
    51       return (this->relFiles.find(filename) != this->relFiles.end()); 
    52    } 
    53  
    54    void CScalar::addRelFile(const StdString& filename) 
    55    { 
     9#include "context.hpp" 
     10 
     11namespace xios  
     12{ 
     13 
     14  /// ////////////////////// Définitions ////////////////////// /// 
     15 
     16  CScalar::CScalar(void) 
     17     : CObjectTemplate<CScalar>() 
     18     , CScalarAttributes() 
     19     , relFiles() 
     20  { /* Ne rien faire de plus */ } 
     21 
     22  CScalar::CScalar(const StdString & id) 
     23     : CObjectTemplate<CScalar>(id) 
     24     , CScalarAttributes() 
     25     , relFiles() 
     26  { /* Ne rien faire de plus */ } 
     27 
     28  CScalar::~CScalar(void) 
     29  { /* Ne rien faire de plus */ } 
     30 
     31  std::map<StdString, ETranformationType> CScalar::transformationMapList_ = std::map<StdString, ETranformationType>(); 
     32  bool CScalar::dummyTransformationMapList_ = CScalar::initializeTransformationMap(CScalar::transformationMapList_); 
     33  bool CScalar::initializeTransformationMap(std::map<StdString, ETranformationType>& m) 
     34  { 
     35    m["reduce_axis"]   = TRANS_REDUCE_AXIS_TO_SCALAR; 
     36    m["extract_axis"]  = TRANS_EXTRACT_AXIS_TO_SCALAR; 
     37    m["reduce_domain"] = TRANS_REDUCE_DOMAIN_TO_SCALAR; 
     38    m["reduce_scalar"] = TRANS_REDUCE_SCALAR_TO_SCALAR; 
     39  } 
     40 
     41  StdString CScalar::GetName(void)   { return (StdString("scalar")); } 
     42  StdString CScalar::GetDefName(void){ return (CScalar::GetName()); } 
     43  ENodeType CScalar::GetType(void)   { return (eScalar); } 
     44 
     45  CScalar* CScalar::createScalar() 
     46  { 
     47    CScalar* scalar = CScalarGroup::get("scalar_definition")->createChild(); 
     48    return scalar; 
     49  } 
     50 
     51  bool CScalar::IsWritten(const StdString & filename) const 
     52  { 
     53    return (this->relFiles.find(filename) != this->relFiles.end()); 
     54  } 
     55 
     56  void CScalar::addRelFile(const StdString& filename) 
     57  { 
    5658      this->relFiles.insert(filename); 
    57    } 
    58  
    59    void CScalar::checkAttributes(void) 
    60    { 
    61    } 
    62  
    63   void CScalar::checkAttributesOnClient() 
    64   { 
    65  
     59  } 
     60 
     61  void CScalar::checkAttributes(void) 
     62  { 
     63    if (checkAttributes_done_) return ; 
     64    checkAttributes_done_ = true ;  
     65 
     66    if (mask.isEmpty()) mask=true ; 
     67 
     68    initializeLocalElement() ; 
     69    addFullView() ; 
     70    addWorkflowView() ; 
     71    addModelView() ; 
    6672  } 
    6773 
     
    129135   * Go through the hierarchy to find the scalar from which the transformations must be inherited 
    130136   */ 
    131   void CScalar::solveInheritanceTransformation() 
     137  void CScalar::solveInheritanceTransformation_old() 
    132138  { 
    133139    if (hasTransformation() || !hasDirectScalarReference()) 
     
    146152        refScalar[i]->setTransformations(scalar->getAllTransformations()); 
    147153  } 
    148  
     154  
     155  void CScalar::solveInheritanceTransformation() 
     156  TRY 
     157  { 
     158    if (solveInheritanceTransformation_done_) return; 
     159    else solveInheritanceTransformation_done_=true ; 
     160 
     161    CScalar* scalar = this; 
     162    CScalar* Lastscalar ; 
     163    std::list<CScalar*> refScalars; 
     164    bool out=false ; 
     165    vector<StdString> excludedAttr; 
     166    excludedAttr.push_back("scalar_ref"); 
     167     
     168    refScalars.push_front(scalar) ; 
     169    while (scalar->hasDirectScalarReference() && !out) 
     170    { 
     171      CScalar* lastScalar=scalar ; 
     172      scalar = scalar->getDirectScalarReference(); 
     173      scalar->solveRefInheritance() ; 
     174      if (!scalar->SuperClass::isEqual(lastScalar,excludedAttr)) out=true ; 
     175      refScalars.push_front(scalar) ; 
     176    } 
     177 
     178    CTransformationPaths::TPath path ; 
     179    auto& pathList = std::get<2>(path) ; 
     180    std::get<0>(path) = EElement::SCALAR ; 
     181    std::get<1>(path) = refScalars.front()->getId() ; 
     182    for (auto& scalar : refScalars) 
     183    { 
     184      CScalar::TransMapTypes transformations = scalar->getAllTransformations(); 
     185      for(auto& transformation : transformations) pathList.push_back({transformation.second->getTransformationType(),  
     186                                                                      transformation.second->getId()}) ; 
     187    } 
     188    transformationPaths_.addPath(path) ; 
     189 
     190  } 
     191  CATCH_DUMP_ATTR 
     192 
     193  /* obsolete, to remove after reimplementing coupling */ 
     194  void CScalar::sendScalarToCouplerOut(CContextClient* client, const string& fieldId, int posInGrid) 
     195  { 
     196    if (sendScalarToCouplerOut_done_.count(client)!=0) return ; 
     197    else sendScalarToCouplerOut_done_.insert(client) ; 
     198 
     199    string scalarId="_scalar["+std::to_string(posInGrid)+"]_of_"+fieldId ; 
     200 
     201    this->sendAllAttributesToServer(client, scalarId); 
     202  }   
     203 
     204  void CScalar::makeAliasForCoupling(const string& fieldId, int posInGrid) 
     205  { 
     206    const string scalarId = "_scalar["+std::to_string(posInGrid)+"]_of_"+fieldId ; 
     207    this->createAlias(scalarId) ; 
     208  } 
     209 
     210  void CScalar::setContextClient(CContextClient* contextClient) 
     211  TRY 
     212  { 
     213    if (clientsSet.find(contextClient)==clientsSet.end()) 
     214    { 
     215      clients.push_back(contextClient) ; 
     216      clientsSet.insert(contextClient); 
     217    } 
     218  } 
     219  CATCH_DUMP_ATTR 
    149220  /*! 
    150221    Parse children nodes of a scalar in xml file. 
     
    183254  } 
    184255 
     256   ////////////////////////////////////////////////////////////////////////////////////// 
     257   //  this part is related to distribution, element definition, views and connectors  // 
     258   ////////////////////////////////////////////////////////////////////////////////////// 
     259 
     260   void CScalar::initializeLocalElement(void) 
     261   { 
     262      // after checkAttribute index of size n 
     263      int rank = CContext::getCurrent()->getIntraCommRank() ; 
     264       
     265      CArray<size_t,1> ind(1) ; 
     266      ind(0)=0 ; 
     267      localElement_ = new CLocalElement(rank, 1, ind) ; 
     268   } 
     269 
     270   void CScalar::addFullView(void) 
     271   { 
     272      CArray<int,1> index(1) ; 
     273      for(int i=0; i<1 ; i++) index(0)=0 ; 
     274      localElement_ -> addView(CElementView::FULL, index) ; 
     275   } 
     276 
     277   void CScalar::addWorkflowView(void) 
     278   { 
     279      CArray<int,1> index ; 
     280      if (mask)  
     281      { 
     282        index.resize(1) ; 
     283        index(0)=0 ; 
     284      } 
     285      else index.resize(0) ; 
     286      localElement_ -> addView(CElementView::WORKFLOW, index) ; 
     287   } 
     288 
     289   void CScalar::addModelView(void) 
     290   { 
     291     CArray<int,1> index(1) ; 
     292     for(int i=0; i<1 ; i++) index(0)=0 ; 
     293     localElement_->addView(CElementView::MODEL, index) ; 
     294   } 
     295 
     296   void CScalar::computeModelToWorkflowConnector(void) 
     297   {  
     298     CLocalView* srcView=getLocalView(CElementView::MODEL) ; 
     299     CLocalView* dstView=getLocalView(CElementView::WORKFLOW) ; 
     300     modelToWorkflowConnector_ = new CLocalConnector(srcView, dstView);  
     301     modelToWorkflowConnector_->computeConnector() ; 
     302   } 
     303 
     304 
     305  void CScalar::computeRemoteElement(CContextClient* client, EDistributionType type) 
     306  { 
     307    CContext* context = CContext::getCurrent(); 
     308    map<int, CArray<size_t,1>> globalIndex ; 
     309 
     310    int nbServer = client->serverSize; 
     311    size_t nglo=1 ; 
     312    CArray<size_t,1> indGlo(nglo) ; 
     313    for(size_t i=0;i<nglo;i++) indGlo(i) = i ; 
     314    for (auto& rankServer : client->getRanksServerLeader()) globalIndex[rankServer].reference(indGlo.copy()) ;  
     315 
     316    remoteElement_[client] = new CDistributedElement(nglo, globalIndex) ; 
     317    remoteElement_[client]->addFullView() ; 
     318  } 
     319  
     320  void CScalar::distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex,  
     321                                   CScattererConnector* &scattererConnector, const string& scalarId) 
     322  { 
     323    string serverScalarId = scalarId.empty() ? this->getId() : scalarId ; 
     324    CContext* context = CContext::getCurrent(); 
     325 
     326    this->sendAllAttributesToServer(client, serverScalarId)  ; 
     327 
     328    CDistributedElement scatteredElement(1,globalIndex) ; 
     329    scatteredElement.addFullView() ; 
     330    scattererConnector = new CScattererConnector(localElement_->getView(CElementView::FULL), scatteredElement.getView(CElementView::FULL),  
     331                                                 context->getIntraComm(), client->getRemoteSize()) ; 
     332    scattererConnector->computeConnector() ; 
     333     
     334    // phase 0 
     335    // send remote element to construct the full view on server, ie without hole  
     336    CEventClient event0(getType(), EVENT_ID_SCALAR_DISTRIBUTION); 
     337    CMessage message0 ; 
     338    message0<<serverScalarId<<0 ;  
     339    remoteElement_[client]->sendToServer(client,event0,message0) ;  
     340     
     341    // phase 1 
     342    // send the full view of element to construct the connector which connect distributed data coming from client to the full local view 
     343    CEventClient event1(getType(), EVENT_ID_SCALAR_DISTRIBUTION); 
     344    CMessage message1 ; 
     345    message1<<serverScalarId<<1<<localElement_->getView(CElementView::FULL)->getGlobalSize() ;  
     346    scattererConnector->transfer(localElement_->getView(CElementView::FULL)->getGlobalIndex(),client,event1,message1) ; 
     347 
     348    sendDistributedAttributes(client, *scattererConnector, scalarId) ; 
     349   
     350    // phase 2 send the mask : data index + mask2D 
     351    CArray<bool,1> maskIn(localElement_->getView(CElementView::WORKFLOW)->getSize()); 
     352    CArray<bool,1> maskOut ; 
     353    CLocalConnector workflowToFull(localElement_->getView(CElementView::WORKFLOW), localElement_->getView(CElementView::FULL)) ; 
     354    workflowToFull.computeConnector() ; 
     355    maskIn=true ; 
     356    workflowToFull.transfer(maskIn,maskOut,false) ; 
     357 
     358    // phase 3 : prepare grid scatterer connector to send data from client to server 
     359    map<int,CArray<size_t,1>> workflowGlobalIndex ; 
     360    map<int,CArray<bool,1>> maskOut2 ;  
     361    scattererConnector->transfer(maskOut, maskOut2) ; 
     362    scatteredElement.addView(CElementView::WORKFLOW, maskOut2) ; 
     363    scatteredElement.getView(CElementView::WORKFLOW)->getGlobalIndexView(workflowGlobalIndex) ; 
     364    // create new workflow view for scattered element 
     365    CDistributedElement clientToServerElement(scatteredElement.getGlobalSize(), workflowGlobalIndex) ; 
     366    clientToServerElement.addFullView() ; 
     367    CEventClient event2(getType(), EVENT_ID_SCALAR_DISTRIBUTION); 
     368    CMessage message2 ; 
     369    message2<<serverScalarId<<2 ;  
     370    clientToServerElement.sendToServer(client, event2, message2) ;  
     371    clientToServerConnector_[client] = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW), clientToServerElement.getView(CElementView::FULL), 
     372                                                               context->getIntraComm(), client->getRemoteSize()) ; 
     373    clientToServerConnector_[client]->computeConnector() ; 
     374 
     375    clientFromServerConnector_[client] = new CGathererConnector(clientToServerElement.getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)); 
     376    clientFromServerConnector_[client]->computeConnector() ; 
     377 
     378  } 
     379   
     380  void CScalar::recvScalarDistribution(CEventServer& event) 
     381  TRY 
     382  { 
     383    string scalarId; 
     384    int phasis ; 
     385    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> scalarId >> phasis ; 
     386    get(scalarId)->receivedScalarDistribution(event, phasis); 
     387  } 
     388  CATCH 
     389   
     390  void CScalar::receivedScalarDistribution(CEventServer& event, int phasis) 
     391  TRY 
     392  { 
     393    CContext* context = CContext::getCurrent(); 
     394    if (phasis==0) // receive the remote element to construct the full view 
     395    { 
     396      localElement_ = new  CLocalElement(context->getIntraCommRank(),event) ; 
     397      localElement_->addFullView() ; 
     398      // construct the local dimension and indexes 
     399      auto& globalIndex=localElement_->getGlobalIndex() ; 
     400      int nk=globalIndex.numElements() ; 
     401      // no distribution for scalar => nk ==1 or maybe 0 ? 
     402    } 
     403    else if (phasis==1) // receive the sent view from client to construct the full distributed full view on server 
     404    { 
     405      CContext* context = CContext::getCurrent(); 
     406      CDistributedElement* elementFrom = new  CDistributedElement(event) ; 
     407      elementFrom->addFullView() ; 
     408      gathererConnector_ = new CGathererConnector(elementFrom->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ; 
     409      gathererConnector_->computeConnector() ;  
     410    } 
     411    else if (phasis==2) 
     412    { 
     413//      delete gathererConnector_ ; 
     414      elementFrom_ = new  CDistributedElement(event) ; 
     415      elementFrom_->addFullView() ; 
     416//      gathererConnector_ =  new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ; 
     417//      gathererConnector_ -> computeConnector() ; 
     418    } 
     419  } 
     420  CATCH 
     421 
     422  void CScalar::setServerMask(CArray<bool,1>& serverMask, CContextClient* client) 
     423  TRY 
     424  { 
     425    CContext* context = CContext::getCurrent(); 
     426    localElement_->addView(CElementView::WORKFLOW, serverMask) ; 
     427    mask = serverMask(0) ; 
     428  
     429    serverFromClientConnector_ = new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)) ; 
     430    serverFromClientConnector_->computeConnector() ; 
     431       
     432    serverToClientConnector_ = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW), elementFrom_->getView(CElementView::FULL), 
     433                                                         context->getIntraComm(), client->getRemoteSize()) ; 
     434    serverToClientConnector_->computeConnector() ; 
     435  } 
     436  CATCH_DUMP_ATTR 
     437 
     438  void CScalar::sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector, const string& scalarId) 
     439  { 
     440    string serverScalarId = scalarId.empty() ? this->getId() : scalarId ; 
     441    CContext* context = CContext::getCurrent(); 
     442 
     443    // nothing for now 
     444  } 
     445 
     446  void CScalar::recvDistributedAttributes(CEventServer& event) 
     447  TRY 
     448  { 
     449    string scalarId; 
     450    string type ; 
     451    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> scalarId >> type ; 
     452    get(scalarId)->recvDistributedAttributes(event, type); 
     453  } 
     454  CATCH 
     455 
     456  void CScalar::recvDistributedAttributes(CEventServer& event, const string& type) 
     457  TRY 
     458  { 
     459    // nothing for now 
     460  } 
     461  CATCH   
     462 
     463  bool CScalar::dispatchEvent(CEventServer& event) 
     464  TRY 
     465  { 
     466     if (SuperClass::dispatchEvent(event)) return true; 
     467     else 
     468     { 
     469       switch(event.type) 
     470       { 
     471          case EVENT_ID_SCALAR_DISTRIBUTION: 
     472            recvScalarDistribution(event); 
     473            return true; 
     474            break; 
     475          case EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE: 
     476            recvDistributedAttributes(event); 
     477            return true; 
     478            break; 
     479          default : 
     480            ERROR("bool CScalar::dispatchEvent(CEventServer& event)", 
     481                   << "Unknown Event"); 
     482          return false; 
     483        } 
     484     } 
     485  } 
     486  CATCH 
     487 
     488 
    185489  // Definition of some macros 
    186490  DEFINE_REF_FUNC(Scalar,scalar) 
  • XIOS/dev/dev_trunk_graph/src/node/scalar.hpp

    r1436 r2019  
    1313#include "transformation.hpp" 
    1414#include "transformation_enum.hpp" 
     15#include "transformation_path.hpp" 
     16#include "element.hpp" 
     17#include "local_connector.hpp" 
     18#include "scatterer_connector.hpp" 
     19#include "gatherer_connector.hpp" 
     20#include "distribution_type.hpp" 
     21#include "generic_algorithm_transformation.hpp" 
     22 
    1523 
    1624namespace xios 
    1725{ 
    18       /// ////////////////////// Déclarations ////////////////////// /// 
    19  
    20       class CScalarGroup; 
    21       class CScalarAttributes; 
    22       class CScalar; 
    23       ///-------------------------------------------------------------- 
    24  
    25       // Declare/Define CVarAttribute 
    26       BEGIN_DECLARE_ATTRIBUTE_MAP(CScalar) 
     26  /// ////////////////////// Déclarations ////////////////////// /// 
     27 
     28  class CScalarGroup; 
     29  class CScalarAttributes; 
     30  class CScalar; 
     31  ///-------------------------------------------------------------- 
     32 
     33  // Declare/Define CVarAttribute 
     34  BEGIN_DECLARE_ATTRIBUTE_MAP(CScalar) 
    2735#include "scalar_attribute.conf" 
    28       END_DECLARE_ATTRIBUTE_MAP(CScalar) 
    29  
    30       ///-------------------------------------------------------------- 
    31  
    32       class CScalar 
    33          : public CObjectTemplate<CScalar> 
    34          , public CScalarAttributes 
     36  END_DECLARE_ATTRIBUTE_MAP(CScalar) 
     37 
     38  ///-------------------------------------------------------------- 
     39 
     40  class CScalar: public CObjectTemplate<CScalar> 
     41               , public CScalarAttributes 
     42  { 
     43      friend class CScalarGroup; 
     44 
     45      /// typedef /// 
     46      typedef CObjectTemplate<CScalar>   SuperClass; 
     47      typedef CScalarAttributes SuperClassAttribute; 
     48 
     49    public: 
     50      enum EEventId 
    3551      { 
    36             /// typedef /// 
    37             typedef CObjectTemplate<CScalar>   SuperClass; 
    38             typedef CScalarAttributes SuperClassAttribute; 
    39  
    40             friend class CScalarGroup; 
    41  
    42          public : 
    43  
    44             typedef CScalarAttributes RelAttributes; 
    45             typedef CScalarGroup      RelGroup; 
    46             typedef CTransformation<CScalar>::TransformationMapTypes TransMapTypes; 
    47  
    48             /// Constructeurs /// 
    49             CScalar(void); 
    50             explicit CScalar(const StdString & id); 
    51             CScalar(const CScalar & var);       // Not implemented yet. 
    52             CScalar(const CScalar * const var); // Not implemented yet. 
    53  
    54             /// Destructeur /// 
    55             virtual ~CScalar(void); 
    56  
    57          public : 
    58             /// Accesseurs statiques /// 
    59             static StdString GetName(void); 
    60             static StdString GetDefName(void); 
    61             static ENodeType GetType(void); 
    62  
    63          public: 
    64             static CScalar* createScalar(); 
    65  
    66          public: 
    67             void checkAttributes(void); 
    68             void addRelFile(const StdString& filename); 
    69             bool IsWritten(const StdString& filename) const; 
    70             void checkAttributesOnClient(); 
    71             virtual void parse(xml::CXMLNode & node); 
    72  
    73          public: 
    74            bool hasTransformation(); 
    75            void solveInheritanceTransformation(); 
    76            TransMapTypes getAllTransformations(); 
    77            void duplicateTransformation(CScalar*); 
    78            CTransformation<CScalar>* addTransformation(ETranformationType transType, const StdString& id=""); 
    79            bool isEqual(CScalar* scalar); 
    80  
    81          private: 
    82            std::set<StdString> relFiles; 
    83            TransMapTypes transformationMap_; 
    84  
    85             void setTransformations(const TransMapTypes&); 
    86  
    87        private: 
    88            static bool initializeTransformationMap(std::map<StdString, ETranformationType>& m); 
    89            static std::map<StdString, ETranformationType> transformationMapList_; 
    90            static bool dummyTransformationMapList_; 
    91  
    92  
    93             DECLARE_REF_FUNC(Scalar,scalar) 
    94  
    95       }; // class CVar 
    96       ///-------------------------------------------------------------- 
    97  
    98       // Declare/Define CScalarGroup and CScalarDefinition 
    99       DECLARE_GROUP(CScalar); 
     52        EVENT_ID_SCALAR_DISTRIBUTION, 
     53        EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE, 
     54      } ; 
     55      static bool dispatchEvent(CEventServer& event);       
     56            
     57 
     58    public : 
     59 
     60      typedef CScalarAttributes RelAttributes; 
     61      typedef CScalarGroup      RelGroup; 
     62 
     63      /// Constructeurs /// 
     64      CScalar(void); 
     65      explicit CScalar(const StdString & id); 
     66      CScalar(const CScalar & var);       // Not implemented yet. 
     67      CScalar(const CScalar * const var); // Not implemented yet. 
     68 
     69      /// Destructeur /// 
     70      virtual ~CScalar(void); 
     71 
     72    public : 
     73      /// Accesseurs statiques /// 
     74      static StdString GetName(void); 
     75      static StdString GetDefName(void); 
     76      static ENodeType GetType(void); 
     77 
     78    public: 
     79      static CScalar* createScalar(); 
     80 
     81    public: 
     82      void checkAttributes(void); 
     83      bool checkAttributes_done_ = false ; 
     84             
     85      void addRelFile(const StdString& filename); 
     86      bool IsWritten(const StdString& filename) const; 
     87      virtual void parse(xml::CXMLNode & node); 
     88         
     89    public: 
     90      void sendScalarToCouplerOut(CContextClient* client, const string& fieldId, int posInGrid) ; 
     91    private: 
     92      std::set<CContextClient*> sendScalarToCouplerOut_done_ ; 
     93          
     94    public: 
     95      void makeAliasForCoupling(const string& fieldId, int posInGrid) ; 
     96 
     97      //////////////////////////////// 
     98      ////    TRANSFORMATIONS     //// 
     99      ////////////////////////////////  
     100    public: 
     101      typedef CTransformation<CScalar>::TransformationMapTypes TransMapTypes; 
     102    private: 
     103      static bool initializeTransformationMap(std::map<StdString, ETranformationType>& m); 
     104      static std::map<StdString, ETranformationType> transformationMapList_; 
     105      static bool dummyTransformationMapList_;      TransMapTypes transformationMap_; 
     106      void setTransformations(const TransMapTypes&); 
     107 
     108    public: 
     109      bool hasTransformation(); 
     110      TransMapTypes getAllTransformations(); 
     111      void duplicateTransformation(CScalar*); 
     112      CTransformation<CScalar>* addTransformation(ETranformationType transType, const StdString& id=""); 
     113     
     114       void solveInheritanceTransformation_old(); 
     115       void solveInheritanceTransformation(); 
     116      private: 
     117        bool solveInheritanceTransformation_done_= false ; 
     118      private: 
     119        CGenericAlgorithmTransformation* transformationAlgorithm_ = nullptr ; 
     120      public: 
     121        void setTransformationAlgorithm(CGenericAlgorithmTransformation* transformationAlgorithm) { transformationAlgorithm_=transformationAlgorithm ;} 
     122        CGenericAlgorithmTransformation* getTransformationAlgorithm(void) { return transformationAlgorithm_ ;}    
     123      private: 
     124        CTransformationPaths transformationPaths_ ; 
     125      public: 
     126        CTransformationPaths getTransformationPaths(void) {return transformationPaths_;}  
     127        void setTransformationPaths(const CTransformationPaths& transformationPaths) { transformationPaths_=transformationPaths ;} 
     128      //////////////////////////////// 
     129      //////////////////////////////// 
     130 
     131      bool isEqual(CScalar* scalar); 
     132    private:   
     133          /** Clients that have to send a scalar. There can be multiple clients in case of secondary server, otherwise only one client. */ 
     134      std::list<CContextClient*> clients; 
     135      std::set<CContextClient*> clientsSet; 
     136    public: 
     137      void setContextClient(CContextClient* contextClient) ; 
     138         
     139    private: 
     140      std::set<StdString> relFiles; 
     141 
     142    private: 
     143      /** define if the scalar is completed or not ie all attributes have been received before in case  
     144           of grid reading from file or coupling */  
     145      bool isCompleted_=true ;   
     146    public:      
     147      /*! 
     148        \brief Check if a scalar is completed 
     149        Before make any scalar processing, we must be sure that all scalar informations have 
     150        been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     151        other context (coupling). So all direct reference of the scalar (scalar_ref) must be also completed 
     152        \return true if scalar and scalar reference are completed 
     153      */ 
     154      bool isCompleted(void) 
     155      { 
     156        if (hasDirectScalarReference()) if (!getDirectScalarReference()->isCompleted()) return false; 
     157        else return isCompleted_ ; 
     158      } 
     159      void setCompleted(void) { isCompleted_=true ; } 
     160      void unsetCompleted(void) { isCompleted_=false ; } 
     161 
     162 
     163 
     164    ////////////////////////////////////////////////////////////////////////////////////// 
     165    //  this part is related to distribution, element definition, views and connectors  // 
     166    ////////////////////////////////////////////////////////////////////////////////////// 
     167    private: 
     168      CLocalElement* localElement_ = nullptr ; 
     169      void initializeLocalElement(void) ; 
     170        
     171    public:   
     172      CLocalElement* getLocalElement(void) { if (localElement_==nullptr) initializeLocalElement() ; return localElement_ ; } 
     173      CLocalView* getLocalView(CElementView::type type) { return getLocalElement()->getView(type) ;} 
     174        
     175    private:   
     176      void addFullView(void) ; 
     177      void addWorkflowView(void) ; 
     178      void addModelView(void) ; 
     179         
     180    private: 
     181      CLocalConnector* modelToWorkflowConnector_ ; 
     182      void computeModelToWorkflowConnector(void)  ; 
     183    public: 
     184      CLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_ ;} 
     185 
     186    public: 
     187      void computeRemoteElement(CContextClient* client, EDistributionType) ; 
     188      void distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex, CScattererConnector* &scattererConnector, 
     189                                 const string& scalarId="") ; 
     190 
     191      static void recvScalarDistribution(CEventServer& event) ; 
     192      void receivedScalarDistribution(CEventServer& event, int phasis) ; 
     193      void setServerMask(CArray<bool,1>& serverMask, CContextClient* client) ; 
     194      void sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector, const string& scalarId) ; 
     195      static void recvDistributedAttributes(CEventServer& event) ; 
     196      void recvDistributedAttributes(CEventServer& event, const string& type) ; 
     197 
     198    private: 
     199      map<CContextClient*, CDistributedElement*> remoteElement_ ; 
     200    public:  
     201      CDistributedElement* getRemoteElement(CContextClient* client) {return remoteElement_[client] ;} 
     202    private: 
     203      map<CContextClient*, CScattererConnector*> clientToServerConnector_ ; 
     204    public:  
     205      CScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;} 
     206 
     207    private: 
     208      CGathererConnector*  gathererConnector_ ; 
     209    public: 
     210      CGathererConnector* getGathererConnector(void) { return gathererConnector_ ;} 
     211    private: 
     212      CGathererConnector* serverFromClientConnector_ ; 
     213      CDistributedElement* elementFrom_ ; 
     214    public: 
     215      CGathererConnector* getServerFromClientConnector(void) { return serverFromClientConnector_ ;} 
     216 
     217    private: 
     218      CScattererConnector*  serverToClientConnector_ = nullptr ; 
     219    public:  
     220      CScattererConnector* getServerToClientConnector(void) { return serverToClientConnector_ ;}  
     221 
     222    private: 
     223      map<CContextClient*,CGathererConnector*>  clientFromServerConnector_  ; 
     224    public:  
     225      CGathererConnector* getClientFromServerConnector(CContextClient* client) { return clientFromServerConnector_[client] ;}  
     226 
     227    private: 
     228      DECLARE_REF_FUNC(Scalar,scalar) 
     229 
     230  }; // class CVar 
     231  ///-------------------------------------------------------------- 
     232 
     233  // Declare/Define CScalarGroup and CScalarDefinition 
     234  DECLARE_GROUP(CScalar); 
    100235} // namespace xios 
    101236 
  • XIOS/dev/dev_trunk_graph/src/node/temporal_splitting.cpp

    r1275 r2019  
    11#include "temporal_splitting.hpp" 
     2#include "axis_algorithm_temporal_splitting.hpp" 
    23#include "type.hpp" 
    34#include "axis.hpp" 
     
    2930  bool CTemporalSplitting::registerTrans() 
    3031  { 
    31     return registerTransformation(TRANS_TEMPORAL_SPLITTING, CTemporalSplitting::create); 
     32    return registerTransformation(TRANS_TEMPORAL_SPLITTING, {create, getTransformation}); 
    3233  } 
    3334 
     
    4546  } 
    4647 
     48  CGenericAlgorithmTransformation* CTemporalSplitting::createAlgorithm(bool isSource, 
     49                                                        CGrid* gridDst, CGrid* gridSrc, 
     50                                                        int elementPositionInGrid, 
     51                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     52                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     53                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     54                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     55                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     56                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     57  { 
     58    return CAxisAlgorithmTemporalSplitting::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     59                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     60                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     61  } 
    4762} 
  • XIOS/dev/dev_trunk_graph/src/node/temporal_splitting.hpp

    r1275 r2019  
    2020  class CAxis; 
    2121  class CScalar; 
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2224  ///-------------------------------------------------------------- 
    2325 
     
    4042      typedef CObjectTemplate<CTemporalSplitting> SuperClass; 
    4143      typedef CTemporalSplittingAttributes SuperClassAttribute; 
     44      typedef CTemporalSplitting MyClass ; 
     45      typedef CTransformation<CAxis> SuperTransform ; 
    4246 
    4347    public : 
     
    5559      static StdString GetDefName(void); 
    5660      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_TEMPORAL_SPLITTING ;} 
     63      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5774    private: 
    5875      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/variable.cpp

    r1158 r2019  
    9494   * 
    9595   */ 
    96    void CVariable::sendValue() 
    97    { 
    98      CContext* context=CContext::getCurrent() ; 
    99  
    100      if (context->hasClient) 
    101      { 
    102        // Use correct context client to send message 
    103        // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1; 
    104       int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1; 
    105        for (int i = 0; i < nbSrvPools; ++i) 
    106        { 
    107 //       CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer 
    108          CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] 
    109                                                                              : context->client; 
    110  
    111          CEventClient event(this->getType(),EVENT_ID_VARIABLE_VALUE) ; 
    112          if (contextClientTmp->isServerLeader()) 
    113          { 
    114            CMessage msg ; 
    115            msg<<this->getId() ; 
    116            msg<<content ; 
    117            const std::list<int>& ranks = contextClientTmp->getRanksServerLeader(); 
    118            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    119              event.push(*itRank,1,msg); 
    120            contextClientTmp->sendEvent(event) ; 
    121          } 
    122          else contextClientTmp->sendEvent(event) ; 
    123       } 
    124      } 
    125    } 
    126  
    127    void CVariable::sendValue(CContextClient* client, bool clientPrim /*= false*/) 
     96 
     97   void CVariable::sendValue(CContextClient* client) 
    12898   { 
    12999     CEventClient event(this->getType(),EVENT_ID_VARIABLE_VALUE) ; 
  • XIOS/dev/dev_trunk_graph/src/node/variable.hpp

    r1158 r2019  
    7979 
    8080            //! Sending a request to set up variable data 
    81             void sendValue(); 
    82             void sendValue(CContextClient* client, bool clientPrim = false); 
     81            void sendValue(CContextClient* client); 
    8382 
    8483            static void recvValue(CEventServer& event) ; 
  • XIOS/dev/dev_trunk_graph/src/node/zoom_axis.cpp

    r1201 r2019  
    11#include "zoom_axis.hpp" 
     2#include "axis_algorithm_zoom.hpp" 
    23#include "type.hpp" 
    34 
     
    2627  bool CZoomAxis::registerTrans() 
    2728  { 
    28     return registerTransformation(TRANS_ZOOM_AXIS, CZoomAxis::create); 
     29    return registerTransformation(TRANS_ZOOM_AXIS, {create, getTransformation}); 
    2930  } 
    3031 
     
    7778  } 
    7879 
     80  CGenericAlgorithmTransformation* CZoomAxis::createAlgorithm(bool isSource, 
     81                                                        CGrid* gridDst, CGrid* gridSrc, 
     82                                                        int elementPositionInGrid, 
     83                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     84                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     85                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     86                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     87                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     88                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     89  { 
     90    return CAxisAlgorithmZoom::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     91                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     92                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     93  } 
    7994} 
  • XIOS/dev/dev_trunk_graph/src/node/zoom_axis.hpp

    r836 r2019  
    2020  class CZoomAxis; 
    2121  class CAxis; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CZoomAxis> SuperClass; 
    4243      typedef CZoomAxisAttributes SuperClassAttribute; 
     44      typedef CZoomAxis MyClass ; 
     45      typedef CTransformation<CAxis> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_ZOOM_AXIS ;} 
     63      static CTransformation<CAxis>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     64      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
  • XIOS/dev/dev_trunk_graph/src/node/zoom_domain.cpp

    r836 r2019  
    11#include "zoom_domain.hpp" 
     2#include "domain_algorithm_zoom.hpp" 
    23#include "type.hpp" 
    34 
     
    2728  bool CZoomDomain::registerTrans() 
    2829  { 
    29     registerTransformation(TRANS_ZOOM_DOMAIN, CZoomDomain::create); 
     30    registerTransformation(TRANS_ZOOM_DOMAIN, {create, getTransformation}); 
    3031  } 
    3132 
     
    7273  } 
    7374 
     75  CGenericAlgorithmTransformation* CZoomDomain::createAlgorithm(bool isSource, 
     76                                                        CGrid* gridDst, CGrid* gridSrc, 
     77                                                        int elementPositionInGrid, 
     78                                                        std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     79                                                        std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     80                                                        std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     81                                                        std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     82                                                        std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     83                                                        std::map<int, int>& elementPositionInGridDst2DomainPosition) 
     84  { 
     85    return CDomainAlgorithmZoom::create(isSource, gridDst,  gridSrc, this, elementPositionInGrid, 
     86                       elementPositionInGridSrc2ScalarPosition, elementPositionInGridSrc2AxisPosition, elementPositionInGridSrc2DomainPosition, 
     87                       elementPositionInGridDst2ScalarPosition, elementPositionInGridDst2AxisPosition, elementPositionInGridDst2DomainPosition); 
     88  } 
    7489} 
  • XIOS/dev/dev_trunk_graph/src/node/zoom_domain.hpp

    r836 r2019  
    2020  class CZoomDomain; 
    2121  class CDomain; 
    22  
     22  class CGenericAlgorithmTransformation ; 
     23  class CGrid; 
    2324  ///-------------------------------------------------------------- 
    2425 
     
    4142      typedef CObjectTemplate<CZoomDomain> SuperClass; 
    4243      typedef CZoomDomainAttributes SuperClassAttribute; 
     44      typedef CZoomDomain MyClass ; 
     45      typedef CTransformation<CDomain> SuperTransform ; 
    4346 
    4447    public : 
     
    5659      static StdString GetDefName(void); 
    5760      static ENodeType GetType(void); 
     61      const string& getId(void) { return this->SuperClass::getId();} 
     62      ETranformationType getTransformationType(void) { return TRANS_ZOOM_DOMAIN ;} 
     63      virtual void inheritFrom(SuperTransform* srcTransform) { solveDescInheritance(true, this->SuperClass::get((MyClass*)srcTransform)) ;} 
     64      static CTransformation<CDomain>* getTransformation(const StdString& id) { return SuperClass::get(id);} 
     65      virtual CGenericAlgorithmTransformation* createAlgorithm(bool isSource, 
     66                                                               CGrid* gridDst, CGrid* gridSrc, 
     67                                                               int elementPositionInGrid, 
     68                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition, 
     69                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition, 
     70                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
     71                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition, 
     72                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition, 
     73                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)  ; 
    5874    private: 
    5975      static bool registerTrans(); 
    6076      static CTransformation<CDomain>* create(const StdString& id, xml::CXMLNode* node); 
     77      
    6178      static bool _dummyRegistered; 
    6279  }; // class CZoomDomain 
Note: See TracChangeset for help on using the changeset viewer.