Index: XIOS/dev/XIOS_DEV_CMIP6/src/node/domain.cpp
===================================================================
--- XIOS/dev/XIOS_DEV_CMIP6/src/node/domain.cpp	(revision 1236)
+++ XIOS/dev/XIOS_DEV_CMIP6/src/node/domain.cpp	(revision 1249)
@@ -86,7 +86,9 @@
      \return the number of indexes written by each server
    */
-   int CDomain::getNumberWrittenIndexes() const
-   {
-     return numberWrittenIndexes_;
+   int CDomain::getNumberWrittenIndexes(MPI_Comm writtenCom)
+   {
+     int writtenSize;
+     MPI_Comm_size(writtenCom, &writtenSize);
+     return numberWrittenIndexes_[writtenSize];
    }
 
@@ -95,7 +97,9 @@
      \return the total number of indexes written by the servers
    */
-   int CDomain::getTotalNumberWrittenIndexes() const
-   {
-     return totalNumberWrittenIndexes_;
+   int CDomain::getTotalNumberWrittenIndexes(MPI_Comm writtenCom)
+   {
+     int writtenSize;
+     MPI_Comm_size(writtenCom, &writtenSize);
+     return totalNumberWrittenIndexes_[writtenSize];
    }
 
@@ -104,7 +108,16 @@
      \return the offset of indexes written by each server
    */
-   int CDomain::getOffsetWrittenIndexes() const
-   {
-     return offsetWrittenIndexes_;
+   int CDomain::getOffsetWrittenIndexes(MPI_Comm writtenCom)
+   {
+     int writtenSize;
+     MPI_Comm_size(writtenCom, &writtenSize);
+     return offsetWrittenIndexes_[writtenSize];
+   }
+
+   CArray<int, 1>& CDomain::getCompressedIndexToWriteOnServer(MPI_Comm writtenCom)
+   {
+     int writtenSize;
+     MPI_Comm_size(writtenCom, &writtenSize);
+     return compressedIndexToWriteOnServer[writtenSize];
    }
 
@@ -1497,7 +1510,7 @@
    void CDomain::checkArea(void)
    {
-     bool hasAreaValue = (0 != areavalue.numElements());
-     hasArea = !area.isEmpty() || !areavalue.isEmpty();
-     if (hasArea)
+     bool hasAreaValue = (!areavalue.isEmpty() && 0 != areavalue.numElements());
+     hasArea = !area.isEmpty();
+     if (hasArea && !hasAreaValue)
      {
        if (area.extent(0) != ni || area.extent(1) != nj)
@@ -1902,49 +1915,118 @@
       }
       
-      if (isCompressible())
-      {
-        nbWritten = 0;
-        boost::unordered_map<size_t,size_t> localGlobalIndexMap;
-        for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
-        {
-          indGlo = *itSrv;
-          if (ite != globalLocalIndexMap_.find(indGlo))
-          {
-            localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo;
-            ++nbWritten;
-          }                 
-        }
-
-        nbWritten = 0;
-        for (int idx = 0; idx < data_i_index.numElements(); ++idx)
-        {
-          if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
-          {
-            ++nbWritten;
-          }
-        }
-
-        compressedIndexToWriteOnServer.resize(nbWritten);
-        nbWritten = 0;
-        for (int idx = 0; idx < data_i_index.numElements(); ++idx)
-        {
-          if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
-          {
-            compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_i_index(idx)];
-            ++nbWritten;
-          }
-        }
-
-        numberWrittenIndexes_ = nbWritten;
-        if (isDistributed())
-        {            
-          MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-          MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-          offsetWrittenIndexes_ -= numberWrittenIndexes_;
-        }
-        else
-          totalNumberWrittenIndexes_ = numberWrittenIndexes_;
-      }      
-   }
+      // if (isCompressible())
+      // {
+      //   nbWritten = 0;
+      //   boost::unordered_map<size_t,size_t> localGlobalIndexMap;
+      //   for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
+      //   {
+      //     indGlo = *itSrv;
+      //     if (ite != globalLocalIndexMap_.find(indGlo))
+      //     {
+      //       localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo;
+      //       ++nbWritten;
+      //     }                 
+      //   }
+
+      //   nbWritten = 0;
+      //   for (int idx = 0; idx < data_i_index.numElements(); ++idx)
+      //   {
+      //     if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
+      //     {
+      //       ++nbWritten;
+      //     }
+      //   }
+
+      //   compressedIndexToWriteOnServer.resize(nbWritten);
+      //   nbWritten = 0;
+      //   for (int idx = 0; idx < data_i_index.numElements(); ++idx)
+      //   {
+      //     if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
+      //     {
+      //       compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_i_index(idx)];
+      //       ++nbWritten;
+      //     }
+      //   }
+
+      //   numberWrittenIndexes_ = nbWritten;
+      //   if (isDistributed())
+      //   {            
+      //     MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
+      //     MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
+      //     offsetWrittenIndexes_ -= numberWrittenIndexes_;
+      //   }
+      //   else
+      //     totalNumberWrittenIndexes_ = numberWrittenIndexes_;
+      // }      
+   }
+
+  void CDomain::computeWrittenCompressedIndex(MPI_Comm writtenComm)
+  {
+    int writtenCommSize;
+    MPI_Comm_size(writtenComm, &writtenCommSize);
+    if (compressedIndexToWriteOnServer.find(writtenCommSize) != compressedIndexToWriteOnServer.end())
+      return;
+
+    if (isCompressible())
+    {
+      size_t nbWritten = 0, indGlo;
+      CContext* context=CContext::getCurrent();      
+      CContextServer* server = context->server;  
+
+      std::vector<int> nBegin(2), nSize(2), nBeginGlobal(2), nGlob(2);
+      nBegin[0]       = zoom_ibegin;  nBegin[1] = zoom_jbegin;
+      nSize[0]        = zoom_ni;      nSize[1]  = zoom_nj;
+      nBeginGlobal[0] = 0; nBeginGlobal[1] = 0;
+      nGlob[0]        = ni_glo;   nGlob[1] = nj_glo;
+      CDistributionServer srvDist(server->intraCommSize, nBegin, nSize, nBeginGlobal, nGlob); 
+      const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex();
+
+      boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(),
+                                                          ite = globalLocalIndexMap_.end(), it;   
+      CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(),
+                                       itSrve = writtenGlobalIndex.end(), itSrv;
+      boost::unordered_map<size_t,size_t> localGlobalIndexMap;
+      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
+      {
+        indGlo = *itSrv;
+        if (ite != globalLocalIndexMap_.find(indGlo))
+        {
+          localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo;
+          ++nbWritten;
+        }                 
+      }
+
+      nbWritten = 0;
+      for (int idx = 0; idx < data_i_index.numElements(); ++idx)
+      {
+        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
+        {
+          ++nbWritten;
+        }
+      }
+
+      compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten);
+      nbWritten = 0;
+      for (int idx = 0; idx < data_i_index.numElements(); ++idx)
+      {
+        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
+        {
+          compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_i_index(idx)];
+          ++nbWritten;
+        }
+      }
+
+      numberWrittenIndexes_[writtenCommSize] = nbWritten;
+      if (isDistributed())
+      {
+             
+        MPI_Allreduce(&numberWrittenIndexes_[writtenCommSize], &totalNumberWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm);
+        MPI_Scan(&numberWrittenIndexes_[writtenCommSize], &offsetWrittenIndexes_[writtenCommSize], 1, MPI_INT, MPI_SUM, writtenComm);
+        offsetWrittenIndexes_[writtenCommSize] -= numberWrittenIndexes_[writtenCommSize];
+      }
+      else
+        totalNumberWrittenIndexes_[writtenCommSize] = numberWrittenIndexes_[writtenCommSize];
+      }
+  }
 
   /*!
@@ -2406,5 +2488,5 @@
   void CDomain::recvIndex(std::map<int, CBufferIn*>& rankBuffers)
   {
-    int nbReceived = rankBuffers.size(), i, ind, index, type_int;
+    int nbReceived = rankBuffers.size(), i, ind, index, type_int, iIndex, jIndex;
     recvClientRanks_.resize(nbReceived);        
 
@@ -2426,5 +2508,7 @@
     globalLocalIndexMap_.rehash(std::ceil(nbIndGlob/globalLocalIndexMap_.max_load_factor()));
     i_index.resize(nbIndGlob);
-    j_index.resize(nbIndGlob);    
+    j_index.resize(nbIndGlob);   
+    int nbIndexGlobMax = nbIndGlob, nbIndLoc;
+
     nbIndGlob = 0;
     for (i = 0; i < nbReceived; ++i)
@@ -2436,8 +2520,20 @@
          if (0 == globalLocalIndexMap_.count(index))
          {
-           i_index(nbIndGlob) = index % ni_glo;
-           j_index(nbIndGlob) = index / ni_glo;
-           globalLocalIndexMap_[index] = nbIndGlob;  
-           ++nbIndGlob;
+           iIndex = (index%ni_glo)-ibegin;
+           iIndex = (iIndex < 0) ? 0 : iIndex;
+           jIndex = (index/ni_glo)-jbegin;
+           jIndex = (jIndex < 0) ? 0 : jIndex;
+           nbIndLoc = iIndex + ni * jIndex;
+           if (nbIndLoc < nbIndexGlobMax)
+           {
+             i_index(nbIndLoc) = index % ni_glo;
+             j_index(nbIndLoc) = index / ni_glo;
+             globalLocalIndexMap_[index] = nbIndLoc;  
+             ++nbIndGlob;
+           }
+           // i_index(nbIndGlob) = index % ni_glo;
+           // j_index(nbIndGlob) = index / ni_glo;
+           // globalLocalIndexMap_[index] = nbIndGlob;  
+           // ++nbIndGlob;
          } 
       } 
@@ -2497,6 +2593,6 @@
     if (zoom_ni<=0 || zoom_nj<=0)
     {
-      zoom_ibegin=0 ; zoom_iend=0 ; zoom_ni=0 ;
-      zoom_jbegin=0 ; zoom_jend=0 ; zoom_nj=0 ;
+      zoom_ni=0 ; zoom_ibegin=global_zoom_ibegin ; //=0; zoom_iend=0 ; 
+      zoom_nj=0 ; zoom_jbegin=global_zoom_jbegin ; //=0; zoom_jend=0 ;
     }
 
@@ -2555,4 +2651,5 @@
     nbMaskInd = globalLocalIndexMap_.size();
     mask_1d.resize(nbMaskInd);
+    mask_1d = false;
     
     for (i = 0; i < nbReceived; ++i)
@@ -2862,5 +2959,8 @@
     Receive data index information from client(s)
     A client receives data index from different clients to rebuild its own data index.
+    Because we use global index + mask info to calculate the sending data to client(s), 
+    this data index must be updated with mask info (maybe it will change in the future)
     Because the data index is local, to rebuild data index of received client, we should use global index along with. 
+
     \param[in] rankBuffers rank of sending client and the corresponding receive buffer     
   */
@@ -2901,5 +3001,10 @@
          lInd = globalLocalIndexMap_[size_t(tmpInd(ind))];
          dataIIndex(lInd) = (-1 == dataIIndex(lInd)) ? tmpI(ind) : dataIIndex(lInd); // Only fill in dataIndex if there is no data
-         dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd);         
+         dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd);  
+
+         if (!mask_1d(lInd))   // Include mask info into data index on the RECEIVE getServerDimensionSizes    
+         {
+           dataIIndex(lInd) = dataJIndex(lInd) = -1;
+         }
       } 
     }
