Index: XIOS/trunk/src/node/axis.cpp
===================================================================
--- XIOS/trunk/src/node/axis.cpp	(revision 566)
+++ XIOS/trunk/src/node/axis.cpp	(revision 567)
@@ -6,4 +6,6 @@
 #include "message.hpp"
 #include "type.hpp"
+#include "context.hpp"
+#include "context_client.hpp"
 #include "xmlioserver_spl.hpp"
 
@@ -14,10 +16,10 @@
    CAxis::CAxis(void)
       : CObjectTemplate<CAxis>()
-      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject()
+      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
    { /* Ne rien faire de plus */ }
 
    CAxis::CAxis(const StdString & id)
       : CObjectTemplate<CAxis>(id)
-      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject()
+      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject(), areClientAttributesChecked_(false)
    { /* Ne rien faire de plus */ }
 
@@ -52,5 +54,4 @@
    void CAxis::checkAttributes(void)
    {
-      if (this->isChecked) return;
       if (this->size.isEmpty())
          ERROR("CAxis::checkAttributes(void)",
@@ -76,23 +77,5 @@
       else this->ni.setValue(size);
 
-      StdSize zoom_begin,zoom_end, zoom_size;
-
-      // Maybe index begins at 0 (zero)
-      zoom_begin = (this->zoom_begin.isEmpty()) ?  0 : this->zoom_begin.getValue();
-      zoom_end = (this->zoom_end.isEmpty()) ?  size-1 : this->zoom_end.getValue();
-      zoom_size = (this->zoom_size.isEmpty()) ?  size : this->zoom_size.getValue();
-
-      if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1;
-      if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1;
-      if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1;
-
-      if ( (zoom_begin < 0) || (zoom_begin > size-1) || (zoom_end<0) || (zoom_end>size-1) || (zoom_size<1) || (zoom_size>size) || (zoom_begin>zoom_end))
-        ERROR("CAxis::checkAttributes(void)",
               << "One or more attributes among <zoom_begin>, <zoom_end>, <zoom_size> of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
-
-      this->zoom_begin.setValue(zoom_begin);
-      this->zoom_end.setValue(zoom_end);
-      this->zoom_size.setValue(zoom_size);
-
       StdSize true_size = value.numElements();
       if (size != true_size)
@@ -102,5 +85,5 @@
       this->checkData();
       this->checkMask();
-      this->isChecked = true;
+      this->checkZoom();
    }
 
@@ -122,4 +105,30 @@
         for (int i = 0; i < dn; ++i) data_index(i) = (i+1);
       }
+   }
+
+   void CAxis::checkZoom(void)
+   {
+      StdSize zoom_begin,zoom_end, zoom_size;
+
+      zoom_begin = (this->zoom_begin.isEmpty()) ?  0 : this->zoom_begin.getValue() ;
+      zoom_size  = (this->zoom_size.isEmpty()) ?  size.getValue() : this->zoom_size.getValue() ;
+      zoom_end   = (this->zoom_end.isEmpty()) ?  (size.getValue() - 1) : this->zoom_end.getValue() ;
+
+      if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1 ;
+      if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1 ;
+      if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1 ;
+
+      if ( (zoom_begin < 0) || (zoom_begin > size-1) || (zoom_end<0) || (zoom_end>size-1) || (zoom_size<1) || (zoom_size>size) || (zoom_begin>zoom_end))
+        ERROR("CAxis::checkAttributes(void)",<< "One or more attribut of <zoom_begin>, <zoom_end>, <zoom_size>, are not well specified") ;
+
+      this->zoom_begin.setValue(zoom_begin) ;
+      this->zoom_end.setValue(zoom_end) ;
+      this->zoom_size.setValue(zoom_size) ;
+
+      // compute client zoom indices
+//      zoom_begin_client = ibegin_client > zoom_begin ? begin_client : zoom_begin ;
+//      zoom_end_client   = iend_client < zoom_end ? iend_client : zoom_end ;
+//      zoom_size_client  = zoom_end_client-zoom_begin_client+1 ;
+//      if (zoom_ni_client<0) zoom_ni_client=0 ;
    }
 
@@ -166,4 +175,116 @@
    }
 
+  bool CAxis::dispatchEvent(CEventServer& event)
+   {
+      if (SuperClass::dispatchEvent(event)) return true ;
+      else
+      {
+        switch(event.type)
+        {
+           case EVENT_ID_SERVER_ATTRIBUT :
+             recvServerAttribut(event) ;
+             return true ;
+             break ;
+           default :
+             ERROR("bool CContext::dispatchEvent(CEventServer& event)",
+                    <<"Unknown Event") ;
+           return false ;
+         }
+      }
+   }
+
+   void CAxis::checkAttributesOnClient(const std::vector<int>& globalDim, int orderPositionInGrid,
+                                       CServerDistributionDescription::ServerDistributionType distType)
+   {
+     if (this->areClientAttributesChecked_) return;
+     this->checkAttributes();
+
+     CContext* context=CContext::getCurrent() ;
+     if (context->hasClient)
+     {
+       computeServerIndex(globalDim, orderPositionInGrid, distType);
+     }
+
+     this->areClientAttributesChecked_ = true;
+   }
+
+   void CAxis::computeServerIndex(const std::vector<int>& globalDim, int orderPositionInGrid,
+                                  CServerDistributionDescription::ServerDistributionType distType)
+   {
+     CServerDistributionDescription serverDescription(globalDim);
+
+     CContext* context=CContext::getCurrent() ;
+     CContextClient* client=context->client ;
+     int nbServer=client->serverSize ;
+     int serverRank=client->getServerLeader() ;
+
+     serverDescription.computeServerDistribution(nbServer, false, distType);
+     std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
+     std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
+     begin_srv = (serverIndexBegin[serverRank])[orderPositionInGrid];
+     ni_srv = serverDimensionSizes[serverRank][orderPositionInGrid];
+     end_srv = begin_srv+ni_srv-1;
+   }
+
+   // Send all checked attributes to server
+   void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
+                                     CServerDistributionDescription::ServerDistributionType distType)
+   {
+     if (!this->areClientAttributesChecked_) checkAttributesOnClient(globalDim,
+                                                                     orderPositionInGrid,
+                                                                     distType);
+     CContext* context=CContext::getCurrent() ;
+
+     if (this->isChecked) return;
+     if (context->hasClient)
+     {
+       sendServerAttribut() ;
+     }
+
+     this->isChecked = true;
+   }
+
+  void CAxis::sendServerAttribut(void)
+  {
+    CContext* context=CContext::getCurrent();
+    CContextClient* client=context->client;
+
+    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT) ;
+    if (client->isServerLeader())
+    {
+      CMessage msg ;
+      msg<<this->getId() ;
+      msg<<ni_srv<<begin_srv<<end_srv;
+      event.push(client->getServerLeader(),1,msg) ;
+      client->sendEvent(event) ;
+    }
+    else client->sendEvent(event) ;
+  }
+
+  void CAxis::recvServerAttribut(CEventServer& event)
+  {
+    CBufferIn* buffer=event.subEvents.begin()->buffer;
+    string axisId ;
+    *buffer>>axisId ;
+    get(axisId)->recvServerAttribut(*buffer) ;
+  }
+
+  void CAxis::recvServerAttribut(CBufferIn& buffer)
+  {
+    int zoom_end = zoom_begin.getValue()+zoom_size.getValue()-1;
+    int ni_srv, begin_srv, end_srv;
+
+    buffer>>ni_srv>>begin_srv>>end_srv;
+
+    zoom_begin_srv = zoom_begin.getValue() > begin_srv ? zoom_begin.getValue() : begin_srv ;
+    zoom_end_srv   = zoom_end < end_srv ? zoom_end : end_srv ;
+    zoom_size_srv  = zoom_end_srv-zoom_begin_srv+1 ;
+
+    if (zoom_size_srv<=0)
+    {
+      zoom_begin_srv=0 ; zoom_end_srv=0 ; zoom_size_srv=0 ;
+    }
+  }
+
    DEFINE_REF_FUNC(Axis,axis)
 
Index: XIOS/trunk/src/node/axis.hpp
===================================================================
--- XIOS/trunk/src/node/axis.hpp	(revision 566)
+++ XIOS/trunk/src/node/axis.hpp	(revision 567)
@@ -11,4 +11,5 @@
 #include "attribute_enum.hpp"
 #include "attribute_enum_impl.hpp"
+#include "server_distribution_description.hpp"
 
 namespace xios {
@@ -33,4 +34,9 @@
       , public CAxisAttributes
    {
+         enum EEventId
+         {
+           EVENT_ID_SERVER_ATTRIBUT
+         } ;
+
          /// typedef ///
          typedef CObjectTemplate<CAxis>   SuperClass;
@@ -66,11 +72,27 @@
          static StdString GetName(void);
          static StdString GetDefName(void);
-
          static ENodeType GetType(void);
 
+         void sendServerAttribut(void);
+         static bool dispatchEvent(CEventServer& event);
+         static void recvServerAttribut(CEventServer& event);
+         void recvServerAttribut(CBufferIn& buffer) ;
+         void checkAttributesOnClient(const std::vector<int>& globalDim, int orderPositionInGrid,
+                                      CServerDistributionDescription::ServerDistributionType disType = CServerDistributionDescription::BAND_DISTRIBUTION);
+         void sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
+                                    CServerDistributionDescription::ServerDistributionType disType = CServerDistributionDescription::BAND_DISTRIBUTION);
+      public:
+        int zoom_begin_srv, zoom_end_srv, zoom_size_srv;
+        int ni_srv, begin_srv, end_srv;
       private :
          void checkData();
          void checkMask();
+         void checkZoom();
+         void computeServerIndex(const std::vector<int>& globalDim, int orderPositionInGrid,
+                                 CServerDistributionDescription::ServerDistributionType disType);
+      private:
+
          bool isChecked;
+         bool areClientAttributesChecked_;
          std::set<StdString> relFiles;
 
Index: XIOS/trunk/src/node/context.cpp
===================================================================
--- XIOS/trunk/src/node/context.cpp	(revision 566)
+++ XIOS/trunk/src/node/context.cpp	(revision 567)
@@ -308,5 +308,4 @@
      if (hasClient)
      {
-//       std::cout << "Current context " << *this << std::endl;
        // After xml is parsed, there are some more works with post processing
        postProcessing();
@@ -317,9 +316,4 @@
      if (hasClient && !hasServer)
      {
-       // After xml is parsed, there are some more works with post processing
-//       postProcessing();
-
-//       setClientServerBuffer();
-
       // Send all attributes of current context to server
       this->sendAllAttributesToServer();
@@ -336,10 +330,8 @@
 
       // At last, we have all info of domain and axis, then send them
-       sendRefDomainsAxis();
+//       sendRefDomainsAxis();
 
       // After that, send all grid (if any)
        sendRefGrid();
-
-
     }
 
@@ -416,11 +408,4 @@
    }
 
-//    void CContext::processEnabledFiles(void)
-//   {
-//     for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-//     this->enabledFiles[i]->processEnabledFile();
-//   }
-
-
    void CContext::solveAllRefOfEnabledFields(bool sendToServer)
    {
@@ -440,22 +425,4 @@
      }
    }
-
-//   void CContext::solveAllGridRef(void)
-//   {
-//     for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-//     this->enabledFiles[i]->solveEFGridRef();
-//   }
-//
-//   void CContext::solveAllOperation(void)
-//   {
-//      for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-//      this->enabledFiles[i]->solveEFOperation();
-//   }
-//
-//   void CContext::solveAllExpression(void)
-//   {
-//      for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-//      this->enabledFiles[i]->solveEFExpression();
-//   }
 
    void CContext::solveAllInheritance(bool apply)
@@ -671,5 +638,4 @@
       CCalendarWrapper::get(CCalendarWrapper::GetDefName())->createCalendar();
       postProcessing();
-//      std::cout << "server context " << *this << std::endl;
    }
 
@@ -719,5 +685,6 @@
    std::map<int, StdSize>& CContext::getDataSize()
    {
-     std::set<StdString> domainIds;
+     // Set of grid used by enabled fields
+     std::set<StdString> usedGrid;
 
      // Find all reference domain and axis of all active fields
@@ -729,15 +696,17 @@
        for (int j = 0; j < numEnabledFields; ++j)
        {
-         const std::pair<StdString, StdString>& prDomAxisId = enabledFields[j]->getDomainAxisIds();
+//         const std::pair<StdString, StdString>& prDomAxisId = enabledFields[j]->getDomainAxisIds();
+         StdString currentGrid = enabledFields[j]->grid->getId();
          const std::map<int, StdSize> mapSize = enabledFields[j]->getGridDataSize();
          if (dataSize_.empty())
          {
            dataSize_ = mapSize;
-           domainIds.insert(prDomAxisId.first);
+           usedGrid.insert(currentGrid);
+//           domainIds.insert(prDomAxisId.first);
          }
          else
          {
            std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end();
-           if (domainIds.find(prDomAxisId.first) == domainIds.end())
+           if (usedGrid.find(currentGrid) == usedGrid.end())
            {
              for (; it != itE; ++it)
@@ -830,51 +799,51 @@
 
    //! Client side: Send information of reference domain and axis of active fields
-   void CContext::sendRefDomainsAxis()
-   {
-     std::set<StdString> domainIds;
-     std::set<StdString> axisIds;
-
-     // Find all reference domain and axis of all active fields
-     int numEnabledFiles = this->enabledFiles.size();
-     for (int i = 0; i < numEnabledFiles; ++i)
-     {
-       std::vector<CField*> enabledFields = this->enabledFiles[i]->getEnabledFields();
-       int numEnabledFields = enabledFields.size();
-       for (int j = 0; j < numEnabledFields; ++j)
-       {
-         const std::pair<StdString, StdString>& prDomAxisId = enabledFields[j]->getDomainAxisIds();
-         domainIds.insert(prDomAxisId.first);
-         axisIds.insert(prDomAxisId.second);
-       }
-     }
-
-     // Create all reference axis on server side
-     std::set<StdString>::iterator itDom, itAxis;
-     std::set<StdString>::const_iterator itE;
-
-     StdString axiDefRoot("axis_definition");
-     CAxisGroup* axisPtr = CAxisGroup::get(axiDefRoot);
-     itE = axisIds.end();
-     for (itAxis = axisIds.begin(); itAxis != itE; ++itAxis)
-     {
-       if (!itAxis->empty())
-       {
-         axisPtr->sendCreateChild(*itAxis);
-         CAxis::get(*itAxis)->sendAllAttributesToServer();
-       }
-     }
-
-     // Create all reference domains on server side
-     StdString domDefRoot("domain_definition");
-     CDomainGroup* domPtr = CDomainGroup::get(domDefRoot);
-     itE = domainIds.end();
-     for (itDom = domainIds.begin(); itDom != itE; ++itDom)
-     {
-       if (!itDom->empty()) {
-          domPtr->sendCreateChild(*itDom);
-          CDomain::get(*itDom)->sendAllAttributesToServer();
-       }
-     }
-   }
+//   void CContext::sendRefDomainsAxis()
+//   {
+//     std::set<StdString> domainIds;
+//     std::set<StdString> axisIds;
+//
+//     // Find all reference domain and axis of all active fields
+//     int numEnabledFiles = this->enabledFiles.size();
+//     for (int i = 0; i < numEnabledFiles; ++i)
+//     {
+//       std::vector<CField*> enabledFields = this->enabledFiles[i]->getEnabledFields();
+//       int numEnabledFields = enabledFields.size();
+//       for (int j = 0; j < numEnabledFields; ++j)
+//       {
+//         const std::pair<StdString, StdString>& prDomAxisId = enabledFields[j]->getDomainAxisIds();
+//         domainIds.insert(prDomAxisId.first);
+//         axisIds.insert(prDomAxisId.second);
+//       }
+//     }
+//
+//     // Create all reference axis on server side
+//     std::set<StdString>::iterator itDom, itAxis;
+//     std::set<StdString>::const_iterator itE;
+//
+//     StdString axiDefRoot("axis_definition");
+//     CAxisGroup* axisPtr = CAxisGroup::get(axiDefRoot);
+//     itE = axisIds.end();
+//     for (itAxis = axisIds.begin(); itAxis != itE; ++itAxis)
+//     {
+//       if (!itAxis->empty())
+//       {
+//         axisPtr->sendCreateChild(*itAxis);
+//         CAxis::get(*itAxis)->sendAllAttributesToServer();
+//       }
+//     }
+//
+//     // Create all reference domains on server side
+//     StdString domDefRoot("domain_definition");
+//     CDomainGroup* domPtr = CDomainGroup::get(domDefRoot);
+//     itE = domainIds.end();
+//     for (itDom = domainIds.begin(); itDom != itE; ++itDom)
+//     {
+//       if (!itDom->empty()) {
+//          domPtr->sendCreateChild(*itDom);
+//          CDomain::get(*itDom)->sendAllAttributesToServer();
+//       }
+//     }
+//   }
 
    //! Update calendar in each time step
Index: XIOS/trunk/src/node/distribution_client.cpp
===================================================================
--- XIOS/trunk/src/node/distribution_client.cpp	(revision 566)
+++ XIOS/trunk/src/node/distribution_client.cpp	(revision 567)
@@ -16,5 +16,6 @@
    nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_(),nZoomBegin_(), nZoomEnd_(),
    dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_(),
-   gridMask_(), localDomainIndex_(), localAxisIndex_(), indexMap_(), indexDomainData_(), indexAxisData_()
+   gridMask_(), localDomainIndex_(), localAxisIndex_(), indexMap_(), indexDomainData_(), indexAxisData_(),
+   isDataDistributed_(true), axisNum_(0), domainNum_(0), localDataIndexSendToServer_(0)
 {
 }
@@ -25,5 +26,6 @@
    nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_(),nZoomBegin_(), nZoomEnd_(),
    dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_(),
-   gridMask_(), localDomainIndex_(), localAxisIndex_(), indexMap_(), indexDomainData_(), indexAxisData_()
+   gridMask_(), localDomainIndex_(), localAxisIndex_(), indexMap_(), indexDomainData_(), indexAxisData_(),
+   isDataDistributed_(true), axisNum_(0), domainNum_(0), localDataIndexSendToServer_(0)
 {
   readDistributionInfo(grid);
@@ -34,4 +36,5 @@
 {
   if (0 != localDataIndex_) delete localDataIndex_;
+  if (0 != localDataIndexSendToServer_) delete localDataIndexSendToServer_;
 }
 
@@ -46,5 +49,5 @@
   std::vector<CDomain*> domList = grid->getDomains();
   std::vector<CAxis*> axisList = grid->getAxis();
-  CArray<bool,1>& axisDomainOrder = grid->axisDomainOrder;
+  CArray<bool,1> axisDomainOrder = grid->axisDomainOrder;
 
   std::vector<CDomain*>::iterator itbDom, iteDom, itDom;
@@ -55,34 +58,25 @@
 
   // First of all, every attribute of domain and axis should be checked
-  for (;itDom != iteDom; ++itDom) (*itDom)->checkAttributesOnClient();
-  for (;itAxis != iteAxis; ++itAxis) (*itAxis)->checkAttributes();
+//  for (;itDom != iteDom; ++itDom) (*itDom)->checkAttributesOnClient();
+//  for (;itAxis != iteAxis; ++itAxis) (*itAxis)->checkAttributesOnClient();
+
+  readDistributionInfo(domList, axisList, axisDomainOrder);
 
   // Then check mask of grid
+  int gridDim = domList.size()*2 + axisList.size();
   grid->checkMask();
-  CArray<bool,3>& gridMask = grid->mask;
-
-  ////////////////////////////////////////////////////////
-
-  int gridDim = domList.size()*2 + axisList.size();
-
-  // For now, just suppose that gridMask is all true, but we need to cope with this problem
-  //  std::vector<std::vector<bool> > gridMask(gridDim);
-//  int idxDomain = 0, idxAxis = 0;
-//  for (int i = 0; i < axisDomainOrder.size(); ++i)
-//  {
-//    if (axisDomainOrder(i))
-//    {
-//      gridMask[idxDomain*2+i].resize(domList[idxDomain]->ni);
-//      gridMask[idxDomain*2+i+1].resize(domList[idxDomain]->nj);
-//      ++idxDomain;
-//    }
-//    else
-//    {
-//      gridMask[i].resize(axisList[idxAxis]->ni);
-//      ++idxAxis;
-//    }
-//  }
-
-  readDistributionInfo(domList, axisList, axisDomainOrder, gridMask);
+  switch (gridDim) {
+    case 1:
+      readGridMaskInfo(grid->mask1);
+      break;
+    case 2:
+      readGridMaskInfo(grid->mask2);
+      break;
+    case 3:
+      readGridMaskInfo(grid->mask3);
+      break;
+    default:
+      break;
+  }
 }
 
@@ -96,11 +90,12 @@
   \param [in] axisList List of axis of grid
   \param [in] axisDomainOrder order of axis and domain inside a grid. True if domain, false if axis
-  \param [in] gridMask Mask of grid, for now, keep it 3 dimension, but it needs changing
+//  \param [in] gridMask Mask of grid, for now, keep it 3 dimension, but it needs changing
 */
 void CDistributionClient::readDistributionInfo(const std::vector<CDomain*>& domList,
                                                const std::vector<CAxis*>& axisList,
-                                               const CArray<bool,1>& axisDomainOrder,
-                                               const CArray<bool,3>& gridMask)
-{
+                                               const CArray<bool,1>& axisDomainOrder)
+{
+  domainNum_ = domList.size();
+  axisNum_   = axisList.size();
   numElement_ = axisDomainOrder.numElements(); // Number of element, e.x: Axis, Domain
 
@@ -109,6 +104,6 @@
 
   // Each domain or axis has its mask, of course
-  domainMasks_.resize(domList.size());
-  for (int i = 0; i < domainMasks_.size();++i)
+  domainMasks_.resize(domainNum_);
+  for (int i = 0; i < domainNum_;++i)
   {
     domainMasks_[i].resize(domList[i]->mask.extent(0), domList[i]->mask.extent(1));
@@ -116,13 +111,10 @@
   }
 
-  axisMasks_.resize(axisList.size());
-  for (int i = 0; i < axisMasks_.size(); ++i)
+  axisMasks_.resize(axisNum_);
+  for (int i = 0; i < axisNum_; ++i)
   {
     axisMasks_[i].resize(axisList[i]->mask.numElements());
     axisMasks_[i] = axisList[i]->mask;
   }
-
-  gridMask_.resize(gridMask.extent(0), gridMask.extent(1), gridMask.extent(2));
-  gridMask_ = gridMask;
 
   // Because domain and axis can be in any order (axis1, domain1, axis2, axis3, )
@@ -139,4 +131,5 @@
       idx += 2;
     }
+    else ++idx;
   }
 
@@ -215,4 +208,10 @@
     ++idx;
   }
+
+  // Grid has only one axis and it is not distributed
+  bool isDataNotDistributed = true;
+  for (int i = 0; i < this->dims_; ++i)
+    isDataNotDistributed &= (nLocal_[i] == nGlob_[i]);
+  isDataDistributed_ = !isDataNotDistributed;
 }
 
@@ -343,5 +342,9 @@
 
     // Find out outer index
+    // Depending the inner-most element is axis or domain,
+    // The outer loop index begins correspondingly at one (1) or zero (0)
     idxDomain = idxAxis = 0;
+    if (axisDomainOrder_(0)) ++idxDomain;
+    else ++idxAxis;
     for (int i = 1; i < numElement_; ++i)
     {
@@ -359,4 +362,7 @@
     }
 
+    int maskIndex = currentIndex[0];
+    for (int j = 0; j < this->dims_; ++j)
+
     // Inner most index
     idxDomain = idxAxis = 0;
@@ -370,5 +376,13 @@
       else currentIndex[0]   = localAxisIndex_[idxAxis][i];
 
-      if (gridMask_(currentIndex[0], currentIndex[1], currentIndex[2]))
+      int gridMaskIndex = currentIndex[0];
+      int mulDimMask = 1;
+      for (int k = 1; k < this->dims_; ++k)
+      {
+        mulDimMask *= nLocal_[k-1];
+        gridMaskIndex += (currentIndex[k])*mulDimMask;
+      }
+
+      if (gridMask_(gridMaskIndex)) //(gridMask_(currentIndex[0], currentIndex[1], currentIndex[2]))
       {
         ++indexLocalDataOnClientCount;
@@ -389,11 +403,13 @@
   this->globalIndex_ = new CArray<size_t,1>(indexSend2ServerCount);
   localDataIndex_ = new CArray<int,1>(indexLocalDataOnClientCount);
+  localDataIndexSendToServer_ = new CArray<int,1>(indexSend2ServerCount);
 
   // We need to loop with data index
-  innerLoopSize = dataNIndex_[0];
-  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
   idxLoop.assign(numElement_,0);
   idx = indexLocalDataOnClientCount = indexSend2ServerCount = 0;
-  int count = 0, correctOuterIndexDomain = 0, correctOuterIndexAxis = 0;
+  ssize = 1; for (int i = 0; i < numElement_; ++i) ssize *= dataNIndex_[i];
+  innerLoopSize = dataNIndex_[0];
+  int countLocalData = 0;
+  std::vector<int> correctOuterIndex(numElement_,0);
   while (idx < ssize)
   {
@@ -403,12 +419,17 @@
       {
         idxLoop[i] = 0;
+        correctOuterIndex[i] = 0;
         ++idxLoop[i+1];
-      }
-    }
-
-    // Outer index
+        ++correctOuterIndex[i+1];
+      }
+    }
+
+    // Depending the inner-most element axis or domain,
+    // The outer loop index begins correspondingly at one (1) or zero (0)
     idxDomain = idxAxis = 0;
-    bool isIndexDomainDataCorrect = false;
-    bool isIndexAxisDataCorrect = false;
+    if (axisDomainOrder_(0)) ++idxDomain;
+    else ++idxAxis;
+    bool isIndexDomainDataCorrect = true;
+    bool isIndexAxisDataCorrect = true;
 
     for (int i = 1; i < numElement_; ++i)
@@ -418,9 +439,8 @@
         if (indexDomainData_[idxDomain][idxLoop[i]])
         {
-          currentIndex[indexMap_[i]]   = localDomainIndex_[idxDomain][correctOuterIndexDomain];
-          currentIndex[indexMap_[i]+1] = localDomainIndex_[idxDomain*2+1][correctOuterIndexDomain];
-          isIndexDomainDataCorrect = true;
-          ++correctOuterIndexDomain;
-        }
+          currentIndex[indexMap_[i]]   = localDomainIndex_[idxDomain][correctOuterIndex[i]];
+          currentIndex[indexMap_[i]+1] = localDomainIndex_[idxDomain*2+1][correctOuterIndex[i]];
+        }
+        else isIndexDomainDataCorrect = false;
         ++idxDomain;
       }
@@ -429,8 +449,7 @@
         if (indexAxisData_[idxAxis][idxLoop[i]])
         {
-          currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][correctOuterIndexAxis];
-          isIndexAxisDataCorrect = true;
-          ++correctOuterIndexAxis;
-        }
+          currentIndex[indexMap_[i]]   = localAxisIndex_[idxAxis][correctOuterIndex[i]];
+        }
+        else isIndexAxisDataCorrect = false;
         ++idxAxis;
       }
@@ -464,10 +483,17 @@
       }
 
+      int gridMaskIndex = currentIndex[0];
+      int mulDimMask = 1;
+      for (int k = 1; k < this->dims_; ++k)
+      {
+        mulDimMask *= nLocal_[k-1];
+        gridMaskIndex += (currentIndex[k])*mulDimMask;
+      }
+
       if (isIndexDomainDataCorrect &&
           isIndexAxisDataCorrect &&
-          gridMask_(currentIndex[0], currentIndex[1], currentIndex[2]))
-      {
-        (*localDataIndex_)(indexLocalDataOnClientCount) = count;
-        ++indexLocalDataOnClientCount;
+          gridMask_(gridMaskIndex))
+      {
+        (*localDataIndex_)(indexLocalDataOnClientCount) = countLocalData;
 
         bool isIndexOnServer = true;
@@ -486,8 +512,10 @@
           }
           (*this->globalIndex_)(indexSend2ServerCount) = globalIndex;
+          (*localDataIndexSendToServer_)(indexSend2ServerCount) = indexLocalDataOnClientCount;
           ++indexSend2ServerCount;
         }
-      }
-      ++count;
+        ++indexLocalDataOnClientCount;
+      }
+      ++countLocalData;
     }
     idxLoop[0] += innerLoopSize;
@@ -546,3 +574,8 @@
 }
 
+const CArray<int,1>& CDistributionClient::getLocalDataIndexSendToServerOnClient() const
+{
+  return (*localDataIndexSendToServer_);
+}
+
 } // namespace xios
Index: XIOS/trunk/src/node/distribution_client.hpp
===================================================================
--- XIOS/trunk/src/node/distribution_client.hpp	(revision 566)
+++ XIOS/trunk/src/node/distribution_client.hpp	(revision 567)
@@ -37,5 +37,9 @@
 
     virtual const CArray<int,1>& getLocalDataIndexOnClient() const;
+    virtual const CArray<int,1>& getLocalDataIndexSendToServerOnClient() const;
+
     std::vector<int> getNGlob() { return nGlob_; }
+    std::vector<int> getDataNIndex() { return dataNIndex_; }
+    bool isDataDistributed() { return isDataDistributed_; }
 
   protected:
@@ -44,7 +48,5 @@
     void readDistributionInfo(const std::vector<CDomain*>& domList,
                               const std::vector<CAxis*>& axisList,
-                              const CArray<bool,1>& axisDomainOrder,
-                              const CArray<bool,3>& gridMask);
-
+                              const CArray<bool,1>& axisDomainOrder);
   private:
     //! Create local index of a domain
@@ -59,7 +61,11 @@
     inline int getAxisIndex(const int& dataIndex, const int& dataBegin, const int& ni);
 
+    template<int N>
+    void readGridMaskInfo(const CArray<bool,N>& gridMask);
+
   private:
     //!< LocalData index on client
     CArray<int,1>* localDataIndex_;
+    CArray<int,1>* localDataIndexSendToServer_;
 
   private:
@@ -85,7 +91,4 @@
     std::vector<CArray<bool,1> > axisMasks_; //!< Axis mask
 
-    // Just suppose that grid mask has 3 dimension. Need change
-    CArray<bool,3> gridMask_; // TODO: more general grid mask
-
     std::vector<std::vector<int> > localDomainIndex_;
     std::vector<std::vector<int> > localAxisIndex_;
@@ -96,8 +99,53 @@
     std::vector<std::vector<bool> > indexAxisData_;
 
+    //!< (Only for grid with one axis or scalar)Flag to determine whether data is distributed or not
+    bool isDataDistributed_;
+    int axisNum_;
+    int domainNum_;
+
+  private:
+    // Just suppose that grid mask has 3 dimension. Need change
+    CArray<bool,1> gridMask_; //!< Mask of grid
+
   private:
     CDistributionClient(const CDistributionClient& distClient); //! Not implement
 };
 
+template<int N>
+void CDistributionClient::readGridMaskInfo(const CArray<bool,N>& gridMask)
+{
+  int dim = gridMask.dimensions();
+  std::vector<int> dimensionSizes(dim);
+  for (int i = 0; i < dim; ++i) dimensionSizes[i] = gridMask.extent(i);
+
+  std::vector<int> idxLoop(dim,0);
+  int ssize = gridMask.numElements(), idx = 0;
+  gridMask_.resize(ssize);
+  while (idx < ssize)
+  {
+    for (int i = 0; i < dim-1; ++i)
+    {
+      if (idxLoop[i] == dimensionSizes[i])
+      {
+        idxLoop[i] = 0;
+        ++idxLoop[i+1];
+      }
+    }
+
+    int maskIndex = idxLoop[0];
+    int mulDim = 1;
+    for (int k = 1; k < dim; ++k)
+    {
+      mulDim *= dimensionSizes[k-1];
+      maskIndex += idxLoop[k]*mulDim;
+    }
+    gridMask_(maskIndex) = *(gridMask.dataFirst()+maskIndex);
+
+    ++idxLoop[0];
+    ++idx;
+  }
+}
+
+
 } // namespace xios
 #endif // __XIOS_DISTRIBUTIONCLIENT_HPP__
Index: XIOS/trunk/src/node/distribution_server.cpp
===================================================================
--- XIOS/trunk/src/node/distribution_server.cpp	(revision 566)
+++ XIOS/trunk/src/node/distribution_server.cpp	(revision 567)
@@ -19,4 +19,14 @@
                                          const std::vector<int>& nZoomSize, const std::vector<int>& nGlobal)
   : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin)
+{
+  createGlobalIndex();
+}
+
+CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
+                                         const std::vector<int>& nZoomSize,
+                                         const std::vector<int>& nZoomBeginGlobal,
+                                         const std::vector<int>& nGlobal)
+  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal),
+    nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin)
 {
   createGlobalIndex();
@@ -89,5 +99,6 @@
   for (int i = 0; i < ssize; ++i)
   {
-    it = std::lower_bound(it, itEnd, globalIndex(i));
+    it = std::find(itBegin, itEnd, globalIndex(i));
+//    it = std::lower_bound(it, itEnd, globalIndex(i));
     if (itEnd != it)
     {
@@ -114,5 +125,6 @@
   for (int i = 0; i < ssize; ++i)
   {
-    it = std::lower_bound(it, itEnd, globalIndex(i));
+    it = std::find(itBegin, itEnd, globalIndex(i));
+//    it = std::lower_bound(it, itEnd, globalIndex(i));
     if (itEnd != it)
     {
@@ -125,3 +137,18 @@
 }
 
+
+std::vector<int> CDistributionServer::getZoomBeginGlobal() const
+{
+  return nZoomBeginGlobal_;
+}
+
+std::vector<int> CDistributionServer::getZoomBeginServer() const
+{
+  return nZoomBegin_;
+}
+
+std::vector<int> CDistributionServer::getZoomSizeServer() const
+{
+  return nZoomSize_;
+}
 } // namespace xios
Index: XIOS/trunk/src/node/distribution_server.hpp
===================================================================
--- XIOS/trunk/src/node/distribution_server.hpp	(revision 566)
+++ XIOS/trunk/src/node/distribution_server.hpp	(revision 567)
@@ -24,9 +24,17 @@
     /** Default constructor */
     CDistributionServer(int rank, int dims, CArray<size_t,1>* globalIndex = 0);
-    CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
-                        const std::vector<int>& nZoomSize, const std::vector<int>& nGlobal);
+    CDistributionServer(int rank, const std::vector<int>& nZoomBeginServer,
+                        const std::vector<int>& nZoomSizeServer, const std::vector<int>& nGlobal);
+    CDistributionServer(int rank, const std::vector<int>& nZoomBeginServer,
+                        const std::vector<int>& nZoomSizeServer,
+                        const std::vector<int>& nZoomBeginGlobal,
+                        const std::vector<int>& nGlobal);
 
     /** Default destructor */
     virtual ~CDistributionServer();
+
+    std::vector<int> getZoomBeginGlobal() const;
+    std::vector<int> getZoomBeginServer() const;
+    std::vector<int> getZoomSizeServer() const;
 
     virtual CArray<size_t,1> computeLocalIndex(const CArray<size_t,1>& globalIndex);
@@ -37,6 +45,8 @@
   private:
     std::vector<int> nGlobal_;
+    std::vector<int> nZoomBeginGlobal_;
     std::vector<int> nZoomSize_;
     std::vector<int> nZoomBegin_;
+
 };
 
Index: XIOS/trunk/src/node/field.cpp
===================================================================
--- XIOS/trunk/src/node/field.cpp	(revision 566)
+++ XIOS/trunk/src/node/field.cpp	(revision 567)
@@ -152,16 +152,38 @@
     list< CArray<double,1>* > list_data;
 
-     for (it = grid->storeIndex_toSrv.begin(); it != grid->storeIndex_toSrv.end(); it++)
-    {
-      int rank = (*it).first;
-      CArray<int,1>& index = *(it->second);
-      CArray<double,1> data_tmp(index.numElements());
-      for (int n = 0; n < data_tmp.numElements(); n++) data_tmp(n) = data(index(n));
-      list_msg.push_back(shared_ptr<CMessage>(new CMessage));
-      list_data.push_back(new CArray<double,1>(data_tmp));
-      *list_msg.back() << getId() << *list_data.back();
-      event.push(rank,grid->nbSenders[rank],*list_msg.back());
-    }
-    client->sendEvent(event);
+    if (!grid->doGridHaveDataDistributed())
+    {
+       if (0 == client->getClientRank())
+       {
+          for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++)
+          {
+            int rank=(*it).first ;
+            CArray<int,1>& index = *(it->second) ;
+            CArray<double,1> data_tmp(index.numElements()) ;
+            for(int n=0;n<data_tmp.numElements();n++) data_tmp(n)=data(index(n)) ;
+
+            list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
+            list_data.push_back(new CArray<double,1>(data_tmp)) ;
+            *list_msg.back()<<getId()<<*list_data.back() ;
+            event.push(rank,1,*list_msg.back()) ;
+          }
+          client->sendEvent(event) ;
+       } else client->sendEvent(event);
+    }
+    else
+    {
+      for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++)
+      {
+        int rank=(*it).first ;
+        CArray<int,1>& index = *(it->second) ;
+        CArray<double,1> data_tmp(index.numElements()) ;
+        for(int n=0;n<data_tmp.numElements();n++) data_tmp(n)=data(index(n)) ;
+        list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
+        list_data.push_back(new CArray<double,1>(data_tmp)) ;
+        *list_msg.back()<<getId()<<*list_data.back() ;
+        event.push(rank,grid->nbSenders[rank],*list_msg.back()) ;
+      }
+      client->sendEvent(event) ;
+    }
 
     for (list< CArray<double,1>* >::iterator it = list_data.begin(); it != list_data.end(); it++) delete *it;
@@ -189,8 +211,6 @@
   void  CField::recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers)
   {
-
     if (data_srv.empty())
     {
-//      for (map<int, CArray<int, 1>* >::iterator it = grid->out_i_fromClient.begin(); it != grid->out_i_fromClient.end(); it++)
       for (map<int, CArray<size_t, 1>* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
       {
@@ -234,5 +254,5 @@
   {
     if (!getRelFile()->allDomainEmpty)
-      if (!grid->domain->isEmpty() || getRelFile()->type == CFile::type_attr::one_file)
+      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) //      if (! grid->domain->isEmpty() || getRelFile()->type == CFile::type_attr::one_file)
       {
         getRelFile()->checkFile();
@@ -553,22 +573,4 @@
       }
 
-//     if (!grid_ref.isEmpty())
-//     {
-//       domain = grid->domain;
-//       axis = grid->axis;
-//     }
-
-//     CType<string> goodDomain;
-//     CType<string> goodAxis;
-//     if (!grid_ref.isEmpty())
-//     {
-//       if (!grid->domain_ref.isEmpty()) goodDomain = grid->domain_ref;
-//       if (!grid->axis_ref.isEmpty()) goodAxis = grid->axis_ref;
-//     }
-//     if (!domain_ref.isEmpty()) goodDomain = domain_ref;
-//     if (!axis_ref.isEmpty()) goodAxis = axis_ref;
-
-//     CArray<std::string,1> domListTmp = grid->domainList.getValue();
-//     CArray<std::string,1> axisListTmp = grid->axisList.getValue();
 
      if (domList.empty() && axisList.empty())
@@ -576,58 +578,4 @@
        this->grid = CGrid::createGrid(vecDom, vecAxis);
      }
-
-//     std::string goodDomain = domListTmp[0];
-//     std::string goodAxis = axisListTmp[0];
-
-//     if (goodDomain.isEmpty())
-//     if (goodDomain.empty())
-//     {
-//       ERROR("CField::solveGridReference(void)", << "The horizontal domain for this field is not defined");
-//     }
-//     else
-//     {
-//       if (CDomain::has(goodDomain)) domain = CDomain::get(goodDomain);
-//       else ERROR("CField::solveGridReference(void)",<< "Reference to the domain \'"
-//                  << goodDomain << "\' is wrong");
-////                << goodDomain.get() << "\' is wrong");
-//     }
-//
-////     if (!goodAxis.isEmpty())
-//     if (!goodAxis.empty())
-//     {
-//       if (CAxis::has(goodAxis))  axis = CAxis::get(goodAxis);
-//       else  ERROR("CField::solveGridReference(void)", << "Reference to the axis \'"
-//                   << goodAxis <<"\' is wrong");
-//                   << goodAxis.get() <<"\' is wrong");
-//     }
-
-//     bool nothingToDo = false;
-//
-//     if (!grid_ref.isEmpty())
-//     {
-//       if (!grid->domain_ref.isEmpty() && goodDomain.get() == grid->domain_ref.get())
-//         if (goodAxis.isEmpty()) nothingToDo = true;
-//         else if (!grid->axis_ref.isEmpty())
-//                 if (grid->axis_ref.get() == goodAxis.get()) nothingToDo = true;
-//     }
-//
-//     nothingToDo = true;
-//     if (!nothingToDo)
-//     {
-//       if (!goodAxis.isEmpty())
-//       {
-//         this->grid = CGrid::createGrid(domain, axis);
-//         this->grid_ref.setValue(this->grid->getId());
-//       }
-//       else
-//       {
-//         this->grid = CGrid::createGrid(domain);
-//         this->grid_ref.setValue(this->grid->getId());
-//       }
-//     }
-
-//     grid->solveReference();
-//     grid->solveDomainAxisRef();
-//     grid->checkMaskIndex();
    }
 
@@ -682,6 +630,4 @@
         grid->outputField(it->first,*it->second, fieldOut.dataFirst());
       }
-
-//         grid->outputField(it->first,*it->second, fieldOut.);
    }
 
@@ -689,8 +635,17 @@
    {
       map<int, CArray<double,1>* >::iterator it;
+      for(it=data_srv.begin();it!=data_srv.end();it++)
+      {
+         grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ;
+      }
+   }
+
+   void CField::outputField(CArray<double,1>& fieldOut)
+   {
+      map<int, CArray<double,1>* >::iterator it;
 
       for (it = data_srv.begin(); it != data_srv.end(); it++)
       {
-         grid->outputField(it->first, *it->second, fieldOut);
+         grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ;
       }
    }
@@ -844,15 +799,15 @@
    \return pair of Domain and Axis id
    */
-   const std::pair<StdString,StdString>& CField::getDomainAxisIds()
-   {
-     CGrid* cgPtr = getRelGrid();
-     if (NULL != cgPtr)
-     {
-       if (NULL != cgPtr->getRelDomain()) domAxisIds_.first = cgPtr->getRelDomain()->getId();
-       if (NULL != cgPtr->getRelAxis()) domAxisIds_.second = cgPtr->getRelAxis()->getId();
-     }
-
-     return domAxisIds_;
-   }
+//   const std::pair<StdString,StdString>& CField::getDomainAxisIds()
+//   {
+//     CGrid* cgPtr = getRelGrid();
+//     if (NULL != cgPtr)
+//     {
+//       if (NULL != cgPtr->getRelDomain()) domAxisIds_.first = cgPtr->getRelDomain()->getId();
+//       if (NULL != cgPtr->getRelAxis()) domAxisIds_.second = cgPtr->getRelAxis()->getId();
+//     }
+//
+//     return (domAxisIds_);
+//   }
 
    CVariable* CField::addVariable(const string& id)
Index: XIOS/trunk/src/node/field.hpp
===================================================================
--- XIOS/trunk/src/node/field.hpp	(revision 566)
+++ XIOS/trunk/src/node/field.hpp	(revision 567)
@@ -135,4 +135,5 @@
         void outputField(CArray<double,3>& fieldOut) ;
         void outputField(CArray<double,2>& fieldOut) ;
+        void outputField(CArray<double,1>& fieldOut) ;
         void scaleFactorAddOffset(double scaleFactor, double addOffset) ;
         void parse(xml::CXMLNode & node) ;
@@ -156,5 +157,5 @@
 
 
-        const std::pair<StdString, StdString>& getDomainAxisIds();
+//        const std::pair<StdString, StdString>& getDomainAxisIds();
       public :
          /// PropriÃ©tÃ©s privÃ©es ///
Index: XIOS/trunk/src/node/file.cpp
===================================================================
--- XIOS/trunk/src/node/file.cpp	(revision 566)
+++ XIOS/trunk/src/node/file.cpp	(revision 567)
@@ -212,4 +212,5 @@
 
       allDomainEmpty=true ;
+
       set<CDomain*> setDomain ;
 
@@ -218,6 +219,10 @@
       {
          CField* field = *it;
-         allDomainEmpty&=field->grid->domain->isEmpty() ;
-         setDomain.insert(field->grid->domain) ;
+//         allDomainEmpty&=field->grid->domain->isEmpty() ;
+         allDomainEmpty&=(!field->grid->doGridHaveDataToWrite());
+         std::vector<CDomain*> vecDomain = field->grid->getDomains();
+         for (int i = 0; i < vecDomain.size(); ++i)
+            setDomain.insert(vecDomain[i]);
+//            setDomain.insert(field->grid->domain) ;
       }
       nbDomain=setDomain.size() ;
@@ -320,5 +325,5 @@
 
         bool append = !this->append.isEmpty() && this->append.getValue();
-        
+
          bool useClassicFormat = !format.isEmpty() && format == format_attr::netcdf4_classic;
 
Index: XIOS/trunk/src/node/grid.cpp
===================================================================
--- XIOS/trunk/src/node/grid.cpp	(revision 566)
+++ XIOS/trunk/src/node/grid.cpp	(revision 567)
@@ -20,8 +20,7 @@
    CGrid::CGrid(void)
       : CObjectTemplate<CGrid>(), CGridAttributes()
-      , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
-      , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
+      , isChecked(false), isDomainAxisChecked(false), storeIndex(1)
       , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
-      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_()
+      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_(), writtenDataSize_(0), globalDim_()
    {
      setVirtualDomainGroup();
@@ -31,8 +30,7 @@
    CGrid::CGrid(const StdString & id)
       : CObjectTemplate<CGrid>(id), CGridAttributes()
-      , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
-      , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
+      , isChecked(false), isDomainAxisChecked(false), storeIndex(1)
       , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
-      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_()
+      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_(), writtenDataSize_(0), globalDim_()
    {
      setVirtualDomainGroup();
@@ -42,17 +40,7 @@
    CGrid::~CGrid(void)
    {
- //     this->axis.reset() ;
-//      this->domain.reset() ;
     deque< CArray<int, 1>* >::iterator it ;
 
     for(deque< CArray<int,1>* >::iterator it=storeIndex.begin(); it!=storeIndex.end();it++)  delete *it ;
-    for(deque< CArray<int,1>* >::iterator it=out_i_index.begin();it!=out_i_index.end();it++) delete *it ;
-    for(deque< CArray<int,1>* >::iterator it=out_j_index.begin();it!=out_j_index.end();it++) delete *it ;
-    for(deque< CArray<int,1>* >::iterator it=out_l_index.begin();it!=out_l_index.end();it++) delete *it ;
-
-    for(map<int,CArray<int,1>* >::iterator it=out_i_fromClient.begin();it!=out_i_fromClient.end();it++) delete it->second ;
-    for(map<int,CArray<int,1>* >::iterator it=out_j_fromClient.begin();it!=out_j_fromClient.end();it++) delete it->second ;
-    for(map<int,CArray<int,1>* >::iterator it=out_l_fromClient.begin();it!=out_l_fromClient.end();it++) delete it->second ;
-
     for(map<int,CArray<size_t,1>* >::iterator it=outIndexFromClient.begin();it!=outIndexFromClient.end();++it) delete (it->second);
 
@@ -60,5 +48,4 @@
     if (0 != serverDistribution_) delete serverDistribution_;
     if (0 != serverDistributionDescription_) delete serverDistributionDescription_;
-
    }
 
@@ -77,50 +64,50 @@
 
    //---------------------------------------------------------------
-
-   const std::deque< CArray<int,1>* > & CGrid::getOutIIndex(void)  const
-   {
-      return (this->out_i_index );
-   }
+//
+//   const std::deque< CArray<int,1>* > & CGrid::getOutIIndex(void)  const
+//   {
+//      return (this->out_i_index );
+//   }
+//
+//   //---------------------------------------------------------------
+//
+//   const std::deque< CArray<int,1>* > & CGrid::getOutJIndex(void)  const
+//   {
+//      return (this->out_j_index );
+//   }
+//
+//   //---------------------------------------------------------------
+//
+//   const std::deque< CArray<int,1>* > & CGrid::getOutLIndex(void)  const
+//   {
+//      return (this->out_l_index );
+//   }
+//
+//   //---------------------------------------------------------------
+//
+//   const CAxis*   CGrid::getRelAxis  (void) const
+//   {
+//      return (this->axis );
+//   }
+
+//   //---------------------------------------------------------------
+//
+//   const CDomain* CGrid::getRelDomain(void) const
+//   {
+//      return (this->domain );
+//   }
 
    //---------------------------------------------------------------
 
-   const std::deque< CArray<int,1>* > & CGrid::getOutJIndex(void)  const
-   {
-      return (this->out_j_index );
-   }
+//   bool CGrid::hasAxis(void) const
+//   {
+//      return (this->withAxis);
+//   }
 
    //---------------------------------------------------------------
 
-   const std::deque< CArray<int,1>* > & CGrid::getOutLIndex(void)  const
-   {
-      return (this->out_l_index );
-   }
-
-   //---------------------------------------------------------------
-
-   const CAxis*   CGrid::getRelAxis  (void) const
-   {
-      return (this->axis );
-   }
-
-   //---------------------------------------------------------------
-
-   const CDomain* CGrid::getRelDomain(void) const
-   {
-      return (this->domain );
-   }
-
-   //---------------------------------------------------------------
-
-   bool CGrid::hasAxis(void) const
-   {
-      return (this->withAxis);
-   }
-
-   //---------------------------------------------------------------
-
    StdSize CGrid::getDimension(void) const
    {
-      return ((this->withAxis)?3:2);
+      return (globalDim_.size());
    }
 
@@ -176,8 +163,7 @@
    StdSize CGrid::getDataSize(void) const
    {
-      StdSize retvalue=domain->data_ni.getValue() ;
-      if (domain->data_dim.getValue()==2) retvalue*=domain->data_nj.getValue() ;
-      if (this->withAxis) retvalue*=this->axis->size.getValue() ;
-
+      std::vector<int> dataNindex = clientDistribution_->getDataNIndex();
+      StdSize retvalue = 1;
+      for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];
       return (retvalue);
    }
@@ -201,29 +187,4 @@
 
 
-   //---------------------------------------------------------------
-
-//   void CGrid::solveReference(void)
-//   {
-//      if (this->isChecked) return;
-//      CContext* context = CContext::getCurrent() ;
-//      CContextClient* client=context->client ;
-//
-//      this->solveDomainRef() ;
-//      this->solveAxisRef() ;
-//
-//      if (context->hasClient)
-//      {
-//         checkMask() ;
-//         this->computeIndex() ;
-//
-//         this->storeIndex.push_front(new CArray<int,1>() );
-//         this->out_i_index.push_front(new CArray<int,1>());
-//         this->out_j_index.push_front(new CArray<int,1>());
-//         this->out_l_index.push_front(new CArray<int,1>());
-//      }
-////      this->computeIndexServer();
-//      this->isChecked = true;
-//   }
-
    void CGrid::solveDomainAxisRef(bool areAttributesChecked)
    {
@@ -250,152 +211,85 @@
         checkMask() ;
         this->computeIndex() ;
-
         this->storeIndex.push_front(new CArray<int,1>() );
-        this->out_i_index.push_front(new CArray<int,1>());
-        this->out_j_index.push_front(new CArray<int,1>());
-        this->out_l_index.push_front(new CArray<int,1>());
      }
-//      this->computeIndexServer();
      this->isChecked = true;
    }
 
-
    void CGrid::checkMask(void)
    {
       using namespace std;
-
-      unsigned int niu = domain->ni, nju = domain->nj;
-      unsigned int nlu = 1 ;
-      if (hasAxis()) nlu=axis->size ;
-
-      if (!mask.isEmpty())
-      {
-         if ((mask.extent(0) != niu) ||
-             (mask.extent(1) != nju) ||
-             (mask.extent(2) != nlu))
-             ERROR("CGrid::checkAttributes(void)",
-                  <<"The mask has not the same size than the local grid"<<endl
-                  <<"Local size is "<<niu<<"x"<<nju<<"x"<<nlu<<endl
-                  <<"Mask size is "<<mask.extent(0)<<"x"<<mask.extent(1)<<"x"<<mask.extent(2));
-      }
-      else
-      {
-        mask.resize(niu,nju,nlu) ;
-        mask=true  ;
-      }
-
-      CArray<bool,2>& domainMask = domain->mask ;
-      for (int l=0; l < nlu ; l++)
-        for (int j=0; j < nju ; j++)
-          for(int i=0; i<niu ; i++) mask(i,j,l) = mask(i,j,l) && domainMask(i,j) ;
-
-
-   }
-
+      std::vector<CDomain*> domainP = this->getDomains();
+      std::vector<CAxis*> axisP = this->getAxis();
+      int dim = domainP.size() * 2 + axisP.size();
+
+      std::vector<CArray<bool,2>* > domainMasks(domainP.size());
+      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask);
+      std::vector<CArray<bool,1>* > axisMasks(axisP.size());
+      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
+
+      switch (dim) {
+        case 1:
+          checkGridMask(mask1, domainMasks, axisMasks, axisDomainOrder);
+          break;
+        case 2:
+          checkGridMask(mask2, domainMasks, axisMasks, axisDomainOrder);
+          break;
+        case 3:
+          checkGridMask(mask3, domainMasks, axisMasks, axisDomainOrder);
+          break;
+//        case 4:
+//          checkGridMask(mask4, domainMasks, axisMasks, axisDomainOrder);
+//          break;
+//        case 5:
+//          checkGridMask(mask5, domainMasks, axisMasks, axisDomainOrder);
+//          break;
+//        case 6:
+//          checkGridMask(mask6, domainMasks, axisMasks, axisDomainOrder);
+//          break;
+//        case 7:
+//          checkGridMask(mask7, domainMasks, axisMasks, axisDomainOrder);
+//          break;
+        default:
+          break;
+      }
+   }
    //---------------------------------------------------------------
 
-//   void CGrid::solveDomainRef(void)
-//   {
-//      if (!domain_ref.isEmpty())
-//      {
-//         if (CDomain::has(domain_ref.getValue()))
-//         {
-//            this->domain = CDomain::get(domain_ref.getValue()) ;
-//            domain->checkAttributes() ;
-//         }
-//         else ERROR("CGrid::solveDomainRef(void)",
-//                     << "Wrong domain reference") ;
-//      }
-//      else ERROR("CGrid::solveDomainRef(void)",
-//                  << "Domain reference is not defined") ;
-//   }
-//
-//   //---------------------------------------------------------------
-//
-//   void CGrid::solveAxisRef(void)
-//   {
-//      if (!axis_ref.isEmpty())
-//      {
-//         this->withAxis = true ;
-//         if (CAxis::get(axis_ref.getValue()))
-//         {
-//            this->axis = CAxis::get(axis_ref.getValue()) ;
-//            axis->checkAttributes() ;
-//         }
-//         else ERROR("CGrid::solveAxisRef(void)",
-//                    << "Wrong axis reference") ;
-//      }
-//      else withAxis = false ;
-//   }
-
-
    void CGrid::solveDomainRef(bool sendAtt)
    {
-//      if (!domain_ref.isEmpty())
-//      {
-//         if (CDomain::has(domain_ref.getValue()))
-//         {
-//            this->domain = CDomain::get(domain_ref.getValue()) ;
-//            if (sendAtt) domain->sendCheckedAttributes();
-//            else domain->checkAttributesOnClient() ;
-//         }
-//         else ERROR("CGrid::solveDomainRef(void)",
-//                     << "Wrong domain reference") ;
-//      }
-//      else ERROR("CGrid::solveDomainRef(void)",
-//                  << "Domain reference is not defined") ;
       setDomainList();
-      this->domain = CDomain::get(domList_.at(0));
-      if (0 != this->domain)
-      {
-//        this->domain = this->getDomain();
-        if (sendAtt) domain->sendCheckedAttributes();
-        else domain->checkAttributesOnClient() ;
-      }
-      else ERROR("CGrid::solveDomainRef(void)",
-                  << "Domain reference is not defined") ;
+      std::vector<CDomain*> domListP = this->getDomains();
+      if (!domListP.empty())
+      {
+        computeGridGlobalDimension(getDomains(), getAxis(), axisDomainOrder);
+        for (int i = 0; i < domListP.size(); ++i)
+        {
+          if (sendAtt) domListP[i]->sendCheckedAttributes();
+          else domListP[i]->checkAttributesOnClient();
+        }
+      }
    }
 
    //---------------------------------------------------------------
 
-   void CGrid::solveAxisRef(bool checkAtt)
-   {
-//      if (!axis_ref.isEmpty())
-//      {
-//         this->withAxis = true ;
-//         if (CAxis::get(axis_ref.getValue()))
-//         {
-//            this->axis = CAxis::get(axis_ref.getValue()) ;
-//            axis->checkAttributes() ;
-//         }
-//         else ERROR("CGrid::solveAxisRef(void)",
-//                    << "Wrong axis reference") ;
-//      }
-//      else withAxis = false ;
-//      getAllAxis();
+   void CGrid::solveAxisRef(bool sendAtt)
+   {
       setAxisList();
-      if (!axisList_.empty())
-      {
-        int sizeList = axisList_.size();
-        for (int i = 0; i < sizeList; ++i)
+      std::vector<CAxis*> axisListP = this->getAxis();
+      if (!axisListP.empty())
+      {
+        int idx = 0;
+        computeGridGlobalDimension(getDomains(), getAxis(), axisDomainOrder);
+        for (int i = 0; i < axisListP.size(); ++i)
         {
-          CAxis::get(axisList_.at(i))->checkAttributes();
-          this->axis = CAxis::get(axisList_.at(i));
+          while (this->axisDomainOrder(idx)) idx += 2;
+          if (sendAtt)
+            axisListP[i]->sendCheckedAttributes(globalDim_,idx);
+          else
+            axisListP[i]->checkAttributesOnClient(globalDim_,idx);
+          ++idx;
         }
-        withAxis = true;
-
-      }
-//      if (!axis_ref.isEmpty())
-//      {
-//         this->withAxis = true ;
-//         if (CAxis::get(axis_ref.getValue()))
-//         {
-//            this->axis = CAxis::get(axis_ref.getValue()) ;
-//            axis->checkAttributes() ;
-//         }
-//         else ERROR("CGrid::solveAxisRef(void)",
-//                    << "Wrong axis reference") ;
-//      }
-      else withAxis = false ;
+
+      }
    }
 
@@ -415,5 +309,7 @@
 
      // Finally, compute index mapping between client(s) and server(s)
-     clientServerMap_.computeServerIndexMapping(clientDistribution_->getGlobalIndex(),serverDistributionDescription_->getGlobalIndex());
+     clientServerMap_.computeServerIndexMapping(clientDistribution_->getGlobalIndex(),
+                                                clientDistribution_->getLocalDataIndexSendToServerOnClient(),
+                                                serverDistributionDescription_->getGlobalIndex());
      const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_.getGlobalIndexOnServer();
      std::vector<int> connectedServerRank;
@@ -427,88 +323,4 @@
      storeIndex_client = (clientDistribution_->getLocalDataIndexOnClient());
 
-/*
-      const int ni   = domain->ni.getValue() ,
-                nj   = domain->nj.getValue() ,
-                size = (this->hasAxis()) ? axis->size.getValue() : 1 ,
-                lbegin = (this->hasAxis()) ? axis->zoom_begin.getValue()-1 : 0 ,
-                lend = (this->hasAxis()) ? axis->zoom_end.getValue()-1 : 0 ;
-
-
-      const int data_dim     = domain->data_dim.getValue() ,
-                data_n_index = domain->data_n_index.getValue() ,
-                data_ibegin  = domain->data_ibegin.getValue() ,
-                data_jbegin  = (data_dim == 2)
-                             ? domain->data_jbegin.getValue() : -1;
-
-      CArray<int,1> data_i_index = domain->data_i_index ;
-      CArray<int,1> data_j_index = domain->data_j_index ;
-
-
-      int indexCount = 0;
-
-      for(int l = 0; l < size ; l++)
-      {
-         for(int n = 0, i = 0, j = 0; n < data_n_index; n++)
-         {
-            int temp_i = data_i_index(n) + data_ibegin,
-                temp_j = (data_dim == 1) ? -1
-                       : data_j_index(n) + data_jbegin;
-            i = (data_dim == 1) ? (temp_i - 1) % ni
-                                : (temp_i - 1) ;
-            j = (data_dim == 1) ? (temp_i - 1) / ni
-                                : (temp_j - 1) ;
-
-            if ((l >=lbegin && l<= lend) &&
-                (i >= 0 && i < ni) &&
-                (j >= 0 && j < nj) && mask(i,j,l))
-               indexCount++ ;
-         }
-      }
-
-      storeIndex[0]  = new CArray<int,1>(indexCount) ;
-      out_i_index[0] = new CArray<int,1>(indexCount) ;
-      out_j_index[0] = new CArray<int,1>(indexCount) ;
-      out_l_index[0] = new CArray<int,1>(indexCount) ;
-
-      storeIndex_client.resize(indexCount) ;
-      out_i_client.resize(indexCount) ;
-      out_j_client.resize(indexCount) ;
-      out_l_client.resize(indexCount) ;
-
-
-      for(int count = 0, indexCount = 0,  l = 0; l < size; l++)
-      {
-         for(int n = 0, i = 0, j = 0; n < data_n_index; n++, count++)
-         {
-            int temp_i = data_i_index(n) + data_ibegin,
-                temp_j = (data_dim == 1) ? -1
-                       : data_j_index(n) + data_jbegin;
-            i = (data_dim == 1) ? (temp_i - 1) % ni
-                                : (temp_i - 1) ;
-            j = (data_dim == 1) ? (temp_i - 1) / ni
-                                : (temp_j - 1) ;
-
-            if ((l >= lbegin && l <= lend) &&
-                (i >= 0 && i < ni) &&
-                (j >= 0 && j < nj) && mask(i,j,l))
-            {
-               (*storeIndex[0])(indexCount) = count ;
-               (*out_l_index[0])(indexCount) = l ;
-               (*out_i_index[0])(indexCount) = i ;
-               (*out_j_index[0])(indexCount) = j ;
-
-               storeIndex_client(indexCount) = count ;
-               out_i_client(indexCount)=i+domain->ibegin_client-1 ;
-               out_j_client(indexCount)=j+domain->jbegin_client-1 ;
-               out_l_client(indexCount)=l-lbegin ;
-               indexCount++ ;
-            }
-         }
-      }
-*/
-//      computeDomConServer();
-//      sendIndex() ;
-
-
    }
 
@@ -517,10 +329,9 @@
    CGrid* CGrid::createGrid(CDomain* domain)
    {
-      StdString new_id = StdString("__") + domain->getId() + StdString("__") ;
-      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
-
       std::vector<CDomain*> vecDom(1,domain);
-      grid->setDomainList(vecDom);
-//      grid->domain_ref.setValue(domain->getId());
+      std::vector<CAxis*> vecAxis;
+
+      CGrid* grid = createGrid(vecDom, vecAxis);
+
       return (grid);
    }
@@ -528,14 +339,8 @@
    CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
    {
-      StdString new_id = StdString("__") + domain->getId() +
-                         StdString("_") + axis->getId() + StdString("__") ;
-      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
-
       std::vector<CDomain*> vecDom(1,domain);
       std::vector<CAxis*> vecAxis(1,axis);
-      grid->setDomainList(vecDom);
-      grid->setAxisList(vecAxis);
-//      grid->domain_ref.setValue(domain->getId());
-//      grid->axis_ref.setValue(axis->getId());
+      CGrid* grid = createGrid(vecDom, vecAxis);
+
       return (grid);
    }
@@ -564,4 +369,6 @@
       }
 
+      grid->computeGridGlobalDimension(domains, axis, grid->axisDomainOrder);
+
       return (grid);
    }
@@ -575,34 +382,4 @@
    {
      return (this->vAxisGroup_);
-   }
-
-   //----------------------------------------------------------------
-
-   void CGrid::outputField(int rank, const CArray<double, 1>& stored,  CArray<double, 3>& field)
-   {
-      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
-      CArray<int,1>& out_j=*out_j_fromClient[rank] ;
-      CArray<int,1>& out_l=*out_l_fromClient[rank] ;
-
-      for(StdSize n = 0; n < stored.numElements(); n++)
-         field(out_i(n), out_j(n), out_l(n)) = stored(n) ;
-   }
-
-   void CGrid::outputField(int rank, const CArray<double, 1>& stored,  CArray<double, 2>& field)
-   {
-      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
-      CArray<int,1>& out_j=*out_j_fromClient[rank] ;
-
-      for(StdSize n = 0; n < stored.numElements(); n++)
-         field(out_i(n), out_j(n)) = stored(n) ;   }
-
-   //---------------------------------------------------------------
-
-   void CGrid::outputField(int rank,const CArray<double, 1>& stored,  CArray<double, 1>& field)
-   {
-      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
-
-      for(StdSize n = 0; n < stored.numElements(); n++)
-         field(out_i(n)) = stored(n) ;
    }
 
@@ -629,96 +406,4 @@
    }
 
-   //---------------------------------------------------------------
-
-//  void CGrid::sendIndex(void)
-//  {
-//    CContext* context = CContext::getCurrent() ;
-//    CContextClient* client=context->client ;
-//
-//    CEventClient event(getType(),EVENT_ID_INDEX) ;
-//    int rank ;
-//    list<shared_ptr<CMessage> > list_msg ;
-//    list< CArray<int,1>* > list_out_i,list_out_j,list_out_l ;
-//
-//    for(int ns=0;ns<domain->connectedServer.size();ns++)
-//    {
-//       rank=domain->connectedServer[ns] ;
-//
-//       int i,j ;
-//       int nb=0 ;
-//       for(int k=0;k<storeIndex_client.numElements();k++)
-//       {
-//         i=out_i_client(k)- domain->ibegin +1;
-//         j=out_j_client(k)- domain->jbegin +1;
-//         if (domain->mapConnectedServer(i,j)==ns)  nb++ ;
-//       }
-//       CArray<int,1> storeIndex(nb) ;
-//       CArray<int,1> out_i(nb) ;
-//       CArray<int,1> out_j(nb) ;
-//       CArray<int,1> out_l(nb) ;
-//
-//
-//       nb=0 ;
-//       for(int k=0;k<storeIndex_client.numElements();k++)
-//       {
-//         i=out_i_client(k)- domain->ibegin +1 ;
-//         j=out_j_client(k)- domain->jbegin +1 ;
-//         if (domain->mapConnectedServer(i,j)==ns)
-//         {
-//            storeIndex(nb)=k ;
-//            out_i(nb)=domain->i_index(i,j) + domain->ibegin-1;
-//            out_j(nb)=domain->j_index(i,j) + domain->jbegin-1;
-//            out_l(nb)=out_l_client(k) ;
-//            nb++ ;
-//         }
-//       }
-//
-//       storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(storeIndex) )) ;
-//       nbSenders.insert(pair<int,int>(rank,domain->nbSenders[ns])) ;
-//       list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
-//       list_out_i.push_back(new CArray<int,1>(out_i)) ;
-//       list_out_j.push_back(new CArray<int,1>(out_j)) ;
-//       list_out_l.push_back(new CArray<int,1>(out_l)) ;
-//
-//       *list_msg.back()<<getId()<<*list_out_i.back()<<*list_out_j.back()<<*list_out_l.back() ;
-//       event.push(rank,domain->nbSenders[ns],*list_msg.back()) ;
-//    }
-//    client->sendEvent(event) ;
-//
-//    for(list<CArray<int,1>* >::iterator it=list_out_i.begin();it!=list_out_i.end();it++) delete *it ;
-//    for(list<CArray<int,1>* >::iterator it=list_out_j.begin();it!=list_out_j.end();it++) delete *it ;
-//    for(list<CArray<int,1>* >::iterator it=list_out_l.begin();it!=list_out_l.end();it++) delete *it ;
-//
-//  }
-
-  void CGrid::computeDomConServer()
-  {
-    if (!isDomConServerComputed_)
-    {
-      for(int ns=0;ns<domain->connectedServer.size(); ++ns)
-      {
-         int rank=domain->connectedServer[ns] ;
-
-         int i,j ;
-         int nb=0 ;
-         for(int k=0;k<storeIndex_client.numElements();++k)
-         {
-           i=out_i_client(k)- domain->ibegin +1;
-           j=out_j_client(k)- domain->jbegin +1;
-           if (domain->mapConnectedServer(i,j)==ns)  ++nb ;
-         }
-
-         domConnectedServerSide_.insert(std::make_pair(rank, nb));
-      }
-      isDomConServerComputed_ = true;
-    }
-  }
-
-
-  std::map<int, int> CGrid::getDomConServerSide()
-  {
-    return domConnectedServerSide_;
-  }
-
   void CGrid::sendIndex(void)
   {
@@ -739,72 +424,57 @@
     itLocal = localIndexSendToServer.begin();
 
-    for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
-    {
-      rank = itGlobal->first;
-      int nb = (itGlobal->second).size();
-
-      CArray<size_t, 1> outGlobalIndexOnServer(nb);
-      CArray<int, 1> outLocalIndexToServer(nb);
-      for (int k = 0; k < nb; ++k)
-      {
-        outGlobalIndexOnServer(k) = itGlobal->second.at(k);
-        outLocalIndexToServer(k)  = itLocal->second.at(k);
-      }
-
-      storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
-      listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
-
-      list_msg.push_back(shared_ptr<CMessage>(new CMessage));
-      *list_msg.back()<<getId()<<*listOutIndex.back();
-      event.push(rank, nbSenders[rank], *list_msg.back());
-    }
-    client->sendEvent(event);
+    if (!doGridHaveDataDistributed())
+    {
+      if (0 == client->getClientRank())
+      {
+       for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
+        {
+          rank = itGlobal->first;
+          int nb = (itGlobal->second).size();
+
+          CArray<size_t, 1> outGlobalIndexOnServer(nb);
+          CArray<int, 1> outLocalIndexToServer(nb);
+          for (int k = 0; k < nb; ++k)
+          {
+            outGlobalIndexOnServer(k) = itGlobal->second.at(k);
+            outLocalIndexToServer(k)  = itLocal->second.at(k);
+          }
+
+          storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
+          listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
+
+          list_msg.push_back(shared_ptr<CMessage>(new CMessage));
+          *list_msg.back()<<getId()<<*listOutIndex.back();
+          event.push(rank, 1, *list_msg.back());
+        }
+        client->sendEvent(event);
+      } else client->sendEvent(event);
+    }
+    else
+    {
+      for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
+      {
+        rank = itGlobal->first;
+        int nb = (itGlobal->second).size();
+
+        CArray<size_t, 1> outGlobalIndexOnServer(nb);
+        CArray<int, 1> outLocalIndexToServer(nb);
+        for (int k = 0; k < nb; ++k)
+        {
+          outGlobalIndexOnServer(k) = itGlobal->second.at(k);
+          outLocalIndexToServer(k)  = itLocal->second.at(k);
+        }
+
+        storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
+        listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
+
+        list_msg.push_back(shared_ptr<CMessage>(new CMessage));
+        *list_msg.back()<<getId()<<*listOutIndex.back();
+        event.push(rank, nbSenders[rank], *list_msg.back());
+      }
+      client->sendEvent(event);
+    }
+
     for(list<CArray<size_t,1>* >::iterator it=listOutIndex.begin();it!=listOutIndex.end();++it) delete *it ;
-
-/*
-    if (!isDomConServerComputed_) computeDomConServer();
-
-    for(int ns=0;ns<domain->connectedServer.size();ns++)
-    {
-       rank=domain->connectedServer[ns] ;
-
-       int nb = domConnectedServerSide_.find(rank)->second;
-       CArray<int,1> storeIndex(nb) ;
-       CArray<int,1> out_i(nb) ;
-       CArray<int,1> out_j(nb) ;
-       CArray<int,1> out_l(nb) ;
-
-       int i, j;
-       nb=0 ;
-       for(int k=0;k<storeIndex_client.numElements();k++)
-       {
-         i=out_i_client(k)- domain->ibegin +1 ;
-         j=out_j_client(k)- domain->jbegin +1 ;
-         if (domain->mapConnectedServer(i,j)==ns)
-         {
-            storeIndex(nb)=k ;
-            out_i(nb)=domain->i_index(i,j) + domain->ibegin-1;
-            out_j(nb)=domain->j_index(i,j) + domain->jbegin-1;
-            out_l(nb)=out_l_client(k) ;
-            nb++ ;
-         }
-       }
-
-       storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(storeIndex) )) ;
-       nbSenders.insert(pair<int,int>(rank,domain->nbSenders[ns])) ;
-       list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
-       list_out_i.push_back(new CArray<int,1>(out_i)) ;
-       list_out_j.push_back(new CArray<int,1>(out_j)) ;
-       list_out_l.push_back(new CArray<int,1>(out_l)) ;
-
-       *list_msg.back()<<getId()<<*list_out_i.back()<<*list_out_j.back()<<*list_out_l.back() ;
-       event.push(rank,domain->nbSenders[ns],*list_msg.back()) ;
-    }
-    client->sendEvent(event) ;
-
-    for(list<CArray<int,1>* >::iterator it=list_out_i.begin();it!=list_out_i.end();it++) delete *it ;
-    for(list<CArray<int,1>* >::iterator it=list_out_j.begin();it!=list_out_j.end();it++) delete *it ;
-    for(list<CArray<int,1>* >::iterator it=list_out_l.begin();it!=list_out_l.end();it++) delete *it ;
-*/
   }
 
@@ -820,4 +490,65 @@
       get(gridId)->recvIndex(rank,*buffer) ;
     }
+  }
+
+  void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains,
+                                         const std::vector<CAxis*>& axis,
+                                         const CArray<bool,1>& axisDomainOrder)
+  {
+    globalDim_.resize(domains.size()*2+axis.size());
+    int idx = 0, idxDomain = 0, idxAxis = 0;
+    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
+    {
+      if (axisDomainOrder(i))
+      {
+        globalDim_[idx]   = domains[idxDomain]->ni_glo.getValue();
+        globalDim_[idx+1] = domains[idxDomain]->nj_glo.getValue();
+        ++idxDomain;
+        idx += 2;
+      }
+      else
+      {
+        globalDim_[idx] = axis[idxAxis]->size.getValue();
+        ++idxAxis;
+        ++idx;
+      }
+    }
+  }
+
+  std::vector<int> CGrid::getGlobalDimension()
+  {
+    return globalDim_;
+  }
+
+  /*!
+    Verify whether one server need to write data
+    There are some cases on which one server has nodata to write. For example, when we
+  just only want to zoom on a domain.
+  */
+  bool CGrid::doGridHaveDataToWrite()
+  {
+    return (0 != serverDistribution_);
+  }
+
+  /*!
+    Return size of data which is written on each server
+    Whatever dimension of a grid, data which are written on server must be presented as
+  an one dimension array.
+  \return size of data written on server
+  */
+  size_t CGrid::getWrittenDataSize() const
+  {
+    return writtenDataSize_;
+  }
+
+
+  const CDistributionServer* CGrid::getDistributionServer() const
+  {
+    return serverDistribution_;
+  }
+
+  bool CGrid::doGridHaveDataDistributed()
+  {
+    return clientDistribution_->isDataDistributed();
   }
 
@@ -835,8 +566,10 @@
          indexMap[i] = idx;
          if (true == axisDomainOrder(i))
-        {
-          ++ssize;
-          idx += 2;
-        }
+         {
+            ++ssize;
+            idx += 2;
+         }
+         else
+          ++idx;
        }
 
@@ -844,5 +577,5 @@
        std::vector<CDomain*> domainList = getDomains();
        std::vector<CAxis*> axisList = getAxis();
-       std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize);
+       std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);
        for (int i = 0; i < numElement; ++i)
        {
@@ -851,8 +584,10 @@
             nZoomBegin[indexMap[i]]   = domainList[domainId]->zoom_ibegin_srv;
             nZoomSize[indexMap[i]]    = domainList[domainId]->zoom_ni_srv;
+            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->zoom_ibegin;
             nGlob[indexMap[i]]    = domainList[domainId]->ni_glo;
 
             nZoomBegin[indexMap[i]+1] = domainList[domainId]->zoom_jbegin_srv;
             nZoomSize[indexMap[i]+1]  = domainList[domainId]->zoom_nj_srv;
+            nZoomBeginGlobal[indexMap[i]+1] = domainList[domainId]->zoom_jbegin;
             nGlob[indexMap[i]+1]    = domainList[domainId]->nj_glo;
             ++domainId;
@@ -860,11 +595,17 @@
          else
          {
-            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin;
-            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size;
+            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
+            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
+            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->zoom_begin;
             nGlob[indexMap[i]]      = axisList[axisId]->size;
             ++axisId;
          }
        }
-       serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize, nGlob);
+       writtenDataSize_ = 1;
+       for (int i = 0; i < nZoomSize.size(); ++i)
+        writtenDataSize_ *= nZoomSize[i];
+
+       serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
+                                                     nZoomBeginGlobal, nGlob);
      }
 
@@ -873,19 +614,4 @@
      serverDistribution_->computeLocalIndex(outIndex);
      outIndexFromClient.insert(std::pair<int, CArray<size_t,1>* >(rank, new CArray<size_t,1>(outIndex)));
-
-    /*
-    CArray<int,1> out_i ;
-    CArray<int,1> out_j ;
-    CArray<int,1> out_l ;
-
-    buffer>>out_i>>out_j>>out_l ;
-
-    out_i -= domain->zoom_ibegin_srv-1 ;
-    out_j -= domain->zoom_jbegin_srv-1 ;
-
-    out_i_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_i) )) ;
-    out_j_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_j) )) ;
-    out_l_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_l) )) ;
-    */
   }
 
@@ -1240,6 +966,6 @@
   {
     SuperClass::parse(node);
+
     // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
-//    std::vector<int> axisOrder;
     std::vector<bool> order;
 
Index: XIOS/trunk/src/node/grid.hpp
===================================================================
--- XIOS/trunk/src/node/grid.hpp	(revision 566)
+++ XIOS/trunk/src/node/grid.hpp	(revision 567)
@@ -15,4 +15,5 @@
 #include "server_distribution_description.hpp"
 #include "client_server_mapping.hpp"
+#include "utils.hpp"
 
 namespace xios {
@@ -133,6 +134,4 @@
          void computeIndexServer(void);
          void computeIndex(void);
-//         void solveDomainRef(void);  //TODO temporarily comment
-//         void solveAxisRef(void);   // TODO: temporarily comment
 
          void solveDomainRef(bool checkAtt);
@@ -164,51 +163,46 @@
          std::vector<CAxis*> getAxis();
          std::vector<int> getAxisOrder();
+         std::vector<int> getGlobalDimension();
+
+         bool doGridHaveDataToWrite();
+         bool doGridHaveDataDistributed();
+         size_t getWrittenDataSize() const;
+
+         const CDistributionServer* getDistributionServer() const;
 
       public:
 
          /// PropriÃ©tÃ©s privÃ©es ///
-         bool withAxis ;
          bool isChecked;
          bool isDomainAxisChecked;
          bool isIndexSent;
 
-         CAxis*   axis ;
-         CDomain* domain ;
-
          std::deque< CArray<int, 1>* > storeIndex ;
-         std::deque< CArray<int, 1>* > out_i_index ;
-         std::deque< CArray<int, 1>* > out_j_index ;
-         std::deque< CArray<int, 1>* > out_l_index ;
-
         CArray<int, 1>  storeIndex_client ;
-        CArray<int, 1>  out_i_client ;
-        CArray<int, 1>  out_j_client ;
-        CArray<int, 1>  out_l_client ;
+
 
          map<int, CArray<int, 1>* >  storeIndex_toSrv ;
          map<int,int> nbSenders ;
-//         std::deque<ARRAY(int, 1)> out_i_toSrv ;
-//         std::deque<ARRAY(int, 1)> out_j_toSrv ;
-//         std::deque<ARRAY(int, 1)> out_l_toSrv ;
-
-         map<int, CArray<int, 1>* > out_i_fromClient ;
-         map<int, CArray<int, 1>* > out_j_fromClient ;
-         map<int, CArray<int, 1>* > out_l_fromClient ;
 
          map<int, CArray<size_t, 1>* > outIndexFromClient;
          void checkMask(void) ;
 
-         std::map<int, int> domConnectedServerSide_;
-         bool isDomConServerComputed_;
-
       private:
+       template<int N>
+       void checkGridMask(CArray<bool,N>& gridMask,
+                          const std::vector<CArray<bool,2>* >& domainMasks,
+                          const std::vector<CArray<bool,1>* >& axisMasks,
+                          const CArray<bool,1>& axisDomainOrder);
         void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
         void setVirtualDomainGroup();
         void setVirtualAxisGroup(CAxisGroup* newVAxisGroup);
         void setVirtualAxisGroup();
-//        void setAxisList();
+
         void setAxisList(const std::vector<CAxis*> axis = std::vector<CAxis*>());
-//        void setDomainList();
         void setDomainList(const std::vector<CDomain*> domains = std::vector<CDomain*>());
+
+        void computeGridGlobalDimension(const std::vector<CDomain*>& domains,
+                                        const std::vector<CAxis*>& axis,
+                                        const CArray<bool,1>& axisDomainOrder);
 
         CDomain* addDomain(const std::string& id);
@@ -217,4 +211,5 @@
         CAxisGroup* getVirtualAxisGroup() const;
         CDomainGroup* getVirtualDomainGroup() const;
+        std::vector<int> globalDim_;
       private:
         CDomainGroup* vDomainGroup_;
@@ -222,8 +217,10 @@
         std::vector<std::string> axisList_, domList_;
         bool isAxisListSet, isDomListSet;
+
         CDistributionClient* clientDistribution_;
         CDistributionServer* serverDistribution_;
         CServerDistributionDescription* serverDistributionDescription_;
         CClientServerMapping clientServerMap_;
+        size_t writtenDataSize_;
    }; // class CGrid
 
@@ -231,5 +228,5 @@
 
    template <int n>
-      void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const
+   void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const
    {
       if (this->getDataSize() != field.numElements())
@@ -241,4 +238,93 @@
    }
 
+   template<int N>
+   void CGrid::checkGridMask(CArray<bool,N>& gridMask,
+                             const std::vector<CArray<bool,2>* >& domainMasks,
+                             const std::vector<CArray<bool,1>* >& axisMasks,
+                             const CArray<bool,1>& axisDomainOrder)
+   {
+     int idx = 0;
+     int numElement = axisDomainOrder.numElements();
+     int dim = domainMasks.size()*2 + axisMasks.size();
+
+     std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim);
+     std::vector<int> currentIndex(dim);
+     int idxDomain = 0, idxAxis = 0;
+    for (int i = 0; i < numElement; ++i)
+    {
+      indexMap[i] = idx;
+      if (true == axisDomainOrder(i)) {
+          eachDimSize[indexMap[i]]   = domainMasks[idxDomain]->extent(0);
+          eachDimSize[indexMap[i]+1] = domainMasks[idxDomain]->extent(1);
+          idx += 2; ++idxDomain;
+      }
+      else {
+        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements();
+        ++idx; ++idxAxis;
+      }
+    }
+
+    if (!gridMask.isEmpty())
+    {
+      for (int i = 0; i < dim; ++i)
+      {
+        if (gridMask.extent(i) != eachDimSize[i])
+           ERROR("CGrid::checkMask(void)",
+                <<"The mask has one dimension whose size is different from the one of the local grid"<<endl
+                <<"Local size is "<< i << " " << eachDimSize[i]<<endl
+                <<"Mask dimension size is "<<gridMask.extent(i));
+      }
+    }
+    else {
+        CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
+        gridMask = true;
+    }
+
+    int ssize = gridMask.numElements();
+    idx = 0;
+    while (idx < ssize)
+    {
+      for (int i = 0; i < dim-1; ++i)
+      {
+        if (idxLoop[i] == eachDimSize[i])
+        {
+          idxLoop[i] = 0;
+          ++idxLoop[i+1];
+        }
+      }
+
+      // Find out outer index
+      idxDomain = idxAxis = 0;
+      bool maskValue = true;
+      for (int i = 0; i < numElement; ++i)
+      {
+        if (axisDomainOrder(i))
+        {
+          maskValue = maskValue && (*domainMasks[idxDomain])(idxLoop[indexMap[i]],
+                                                          idxLoop[indexMap[i]+1]);
+          ++idxDomain;
+        }
+        else
+        {
+          maskValue = maskValue && (*axisMasks[idxAxis])(idxLoop[indexMap[i]]);
+          ++idxAxis;
+        }
+      }
+
+      int maskIndex = idxLoop[0];
+      int mulDim = 1;
+      for (int k = 1; k < dim; ++k)
+      {
+        mulDim *= eachDimSize[k-1];
+        maskIndex += idxLoop[k]*mulDim;
+      }
+      *(gridMask.dataFirst()+maskIndex) = maskValue;
+
+      ++idxLoop[0];
+      ++idx;
+    }
+
+   }
+
    ///--------------------------------------------------------------
 
