Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/config/axis_attribute.conf
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/config/axis_attribute.conf	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/config/axis_attribute.conf	(revision 1930)
@@ -22,21 +22,21 @@
 
 /* LOCAL */
-DECLARE_ARRAY(double , 1   , value)
-DECLARE_ATTRIBUTE(StdString, axis_ref)
+DECLARE_ARRAY(double , 1   , value, false)
+DECLARE_ATTRIBUTE(StdString, axis_ref, false)
 
-DECLARE_ARRAY(int    ,1    , index)
+DECLARE_ARRAY(int    ,1    , index, false)
 
 /* LOCAL */
-DECLARE_ATTRIBUTE(int,       data_n)
-DECLARE_ATTRIBUTE(int,       data_begin)
-DECLARE_ARRAY(int    ,   1 , data_index)
+DECLARE_ATTRIBUTE(int,       data_n, false)
+DECLARE_ATTRIBUTE(int,       data_begin, false)
+DECLARE_ARRAY(int    ,   1 , data_index, false)
 
 /*LOCAL */
-DECLARE_ATTRIBUTE(int,       begin)
-DECLARE_ATTRIBUTE(int,       n)
+DECLARE_ATTRIBUTE(int,       begin, false)
+DECLARE_ATTRIBUTE(int,       n, false)
 
 /* LOCAL */
-DECLARE_ARRAY(bool, 1 , mask)
-DECLARE_ARRAY(double, 2 , bounds)
+DECLARE_ARRAY(bool, 1 , mask, false)
+DECLARE_ARRAY(double, 2 , bounds, false)
 DECLARE_ATTRIBUTE(int,       prec)
-DECLARE_ARRAY(StdString    ,1    , label)
+DECLARE_ARRAY(StdString    ,1    , label, false)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/config/domain_attribute.conf
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/config/domain_attribute.conf	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/config/domain_attribute.conf	(revision 1930)
@@ -57,8 +57,8 @@
 DECLARE_ARRAY(double, 3, bounds_lat_2d, false)
 
-DECLARE_ARRAY(double, 2, area)
+DECLARE_ARRAY(double, 2, area, false)
 DECLARE_ATTRIBUTE(double, radius)
 
 DECLARE_ENUM4(type,rectilinear,curvilinear,unstructured, gaussian)
-DECLARE_ATTRIBUTE(StdString, domain_ref)
+DECLARE_ATTRIBUTE(StdString, domain_ref, false)
 DECLARE_ATTRIBUTE(int,       prec)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/data_input.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/data_input.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/data_input.cpp	(revision 1930)
@@ -19,7 +19,7 @@
   //----------------------------------------------------------------
 
-  void CDataInput::readFieldData(CField* field, CArray<double,1>& data)
+  void CDataInput::readFieldData(CField* field, int record, CArray<double,1>& data)
   {
-    this->readFieldData_(field,data);
+    this->readFieldData_(field, record, data);
   }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/data_input.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/data_input.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/data_input.hpp	(revision 1930)
@@ -18,5 +18,5 @@
       /// Read methods ///
       StdSize getFieldNbRecords(CField* field);
-      void readFieldData(CField* field, CArray<double,1>& data);
+      void readFieldData(CField* field, int record, CArray<double,1>& data);
       void readFieldAttributesMetaData(CField* field);
       void readFieldAttributesValues(CField* field);
@@ -27,5 +27,5 @@
     protected:
       virtual StdSize getFieldNbRecords_(CField* field) = 0;
-      virtual void readFieldData_(CField* field, CArray<double,1>& data) = 0;
+      virtual void readFieldData_(CField* field, int record, CArray<double,1>& data) = 0;
       virtual void readFieldAttributes_(CField* field, bool readAttributeValues) = 0;
       virtual void closeFile_(void) = 0;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distributed_view.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distributed_view.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distributed_view.cpp	(revision 1930)
@@ -9,5 +9,5 @@
                                     : globalIndex_(parent->globalIndex_), globalSize_(parent->globalSize_), localSize_(parent->localSize_) 
   {
-    for(auto index : indexView) 
+    for(auto& index : indexView) 
     {
       index_[index.first].reference(index.second.copy()) ;
@@ -16,4 +16,20 @@
   }
 
-
-} 
+  CDistributedView::CDistributedView(CDistributedElement* parent, CElementView::type, const std::map<int,CArray<bool,1>>& maskView) 
+                                    : globalIndex_(parent->globalIndex_), globalSize_(parent->globalSize_), localSize_(parent->localSize_) 
+  {
+    for(auto& it : maskView) 
+    {
+      int rank = it.first ;
+      auto& mask = it.second ;
+      int size = mask.numElements() ;
+      auto& index = index_[rank] ; 
+      index.resize(size) ;
+      int pos=0 ;
+      for(int i=0 ; i < size ; i++)
+        if (mask(i)) { index(pos) = i ; pos++ ; }
+      index.resizeAndPreserve(pos) ;
+      size_[rank] = pos ;
+    }
+  } 
+}
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distributed_view.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distributed_view.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distributed_view.hpp	(revision 1930)
@@ -15,4 +15,5 @@
 
       CDistributedView(CDistributedElement* parent, CElementView::type type, const std::map<int,CArray<int,1>>& indexView) ;
+      CDistributedView(CDistributedElement* parent, CElementView::type type, const std::map<int,CArray<bool,1>>& maskView) ;
       
       std::map<int,CArray<int,1>>&  getIndex(void) { return index_ ;}
@@ -21,4 +22,28 @@
       std::map<int, int>& getLocalSize(void) { return localSize_ ;}
       size_t getGlobalSize(void) { return globalSize_ ;}
+
+      void getGlobalIndexView(map<int,CArray<size_t,1>>& globalIndexView)
+      {
+        for(auto& it : globalIndex_)
+        {
+          int rank=it.first ;
+          auto& globalIndex = it.second;
+          auto& globalIndView = globalIndexView[rank] ;
+          auto& index = index_[rank] ;
+          auto& size = size_[rank] ;
+          auto& localSize = localSize_[rank] ;
+          globalIndView.resize(size) ;
+          int pos=0 ;
+          for(int i=0 ; i<size ; i++)
+          {
+            if (index(i)>=0 && index(i)<localSize) 
+            {
+              globalIndView(i) = globalIndex(index(i)) ;
+              pos++ ;
+            }
+          }
+          globalIndView.resizeAndPreserve(pos) ;
+      }
+    }   
 
       void getGlobalIndex(int rank, vector<size_t>& globalIndex, size_t sliceIndex, size_t* sliceSize, CDistributedView** view, int pos)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distribution_type.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distribution_type.hpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/distribution_type.hpp	(revision 1930)
@@ -0,0 +1,9 @@
+#ifndef __DISTRIBUTION_TYPE_HPP__
+#define __DISTRIBUTION_TYPE_HPP__
+
+namespace xios
+{
+  enum class EDistributionType  { NONE=0, ROOT, BANDS, BLOCKS} ;
+}
+
+#endif
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.cpp	(revision 1930)
@@ -29,4 +29,9 @@
   {
     views_[type] = new CDistributedView(this, type, indexView) ;
+  } 
+
+  void CDistributedElement::addView(CElementView::type type, std::map<int, CArray<bool,1>>& maskView)
+  {
+    views_[type] = new CDistributedView(this, type, maskView) ;
   } 
 
@@ -118,4 +123,9 @@
   } 
 
+  void CLocalElement::addView(CElementView::type type, CArray<bool,1>& maskView)
+  {
+    views_[type] = new CLocalView(this, type, maskView) ;
+  } 
+
   void CLocalElement::addFullView(void)
   {
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.hpp	(revision 1930)
@@ -40,4 +40,5 @@
 
     void addView(CElementView::type type, std::map<int, CArray<int,1>>& indexView) ;
+    void addView(CElementView::type type, std::map<int, CArray<bool,1>>& maskView) ;
     void sendToServer(CEventClient& event, const CMessage& messageHeader) ;
 
@@ -55,6 +56,7 @@
       CLocalElement(int localRank, CEventServer& event) ;
       void recvFromClient(int localRank, CEventServer& event) ;
-      
+      const CArray<size_t,1>& getGlobalIndex(void) { return globalIndex_ ;}
       void addView(CElementView::type type, CArray<int,1>& indexView) ;
+      void addView(CElementView::type type, CArray<bool,1>& maskView) ;
       void addFullView(void) ;
       CLocalView* getView(CElementView::type type) 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.cpp	(revision 1930)
@@ -15,5 +15,7 @@
     unordered_map<size_t,int> mapGlobalLocalIndex ;
     int globalIndexSize=dstGlobalIndex.size() ;
-    for(auto& ind : dstIndex) mapGlobalLocalIndex[dstGlobalIndex(ind)] = ind ;
+    //for(auto& ind : dstIndex) mapGlobalLocalIndex[dstGlobalIndex(ind)] = ind ;
+    for(int i=0; i<dstSize_ ; i++) if (dstIndex(i)>=0 && dstIndex(i)<globalIndexSize) mapGlobalLocalIndex[dstGlobalIndex(dstIndex(i))] = i ;
+
     for(auto& rankIndex : srcIndex)
     {
@@ -27,7 +29,7 @@
       for(int ind=0; ind<indexSize ; ind++)
       {
-        if (ind>=0 && ind<globalIndexSize)
+        if (index(ind)>=0 && index(ind)<globalIndexSize)
         {
-           auto it=mapGlobalLocalIndex.find(globalIndex(ind)) ;
+           auto it=mapGlobalLocalIndex.find(globalIndex(index(ind))) ;
            if (it != mapGlobalLocalIndex.end()) 
            {
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.hpp	(revision 1930)
@@ -29,7 +29,8 @@
       
       template<typename T>
-      void transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut)
+      void transfer(int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut)
       {
-        dataOut.resize(dstSize_) ;
+        // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
+        dataOut.resize(dstSize_*sizeT) ;  
         T* output = dataOut.dataFirst() ;
         for(auto& data : dataIn)
@@ -39,5 +40,5 @@
           auto& connector=connector_[rank] ;
           auto& mask=mask_[rank] ;
-          int size=data.second.numElements() ;
+          int size=mask.size() ;
 
           for(int i=0, j=0 ;i<size;i++)
@@ -45,5 +46,7 @@
             if (mask[i]) 
             {
-              output[connector[j]] = input[i] ;
+              int cj = connector[j]*sizeT ;
+              int ci = i*sizeT ;
+              for (int k=0;k<sizeT;k++) output[cj+k] = input[ci+k] ;
               j++ ;
             }
@@ -52,4 +55,9 @@
       }
     
+      template<typename T>
+      void transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut)
+      {
+        transfer(1,dataIn,dataOut) ;
+      }
 
       template<typename T>
@@ -93,11 +101,17 @@
       void transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue)
       {
-        dataOut.resize(dstSize_) ;
-        dataOut=missingValue ;
-        transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut) ;
+        transfer(1, dataIn, dataout, missingValue)
       }
       
       template<typename T>
-      void transfer(CEventServer& event, CArray<T,1>& dataOut)
+      void transfer(int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue)
+      {
+        dataOut.resize(dstSize_*sizeT) ;
+        dataOut=missingValue ;
+        transfer(sizeT, dataIn, dataOut) ;
+      }
+
+      template<typename T>
+      void transfer(CEventServer& event, int sizeT, CArray<T,1>& dataOut)
       {
         map<int, CArray<T,1>> dataIn ;
@@ -107,5 +121,23 @@
           (*subEvent.buffer) >> data ;
         }
-        transfer(dataIn, dataOut) ;
+        transfer(sizeT, dataIn, dataOut) ;
+      }
+      
+      template<typename T>
+      void transfer(CEventServer& event, CArray<T,1>& dataOut)
+      {
+        transfer(event, 1, dataOut) ;
+      }
+
+      template<typename T>
+      void transfer(CEventServer& event, int sizeT, CArray<T,1>& dataOut, T missingValue)
+      {
+        map<int, CArray<T,1>> dataIn ;
+        for (auto& subEvent : event.subEvents) 
+        {
+          auto& data = dataIn[subEvent.rank]; 
+          (*subEvent.buffer) >> data ;
+        }
+        transfer(sizeT, dataIn, dataOut, missingValue) ;
       }
 
@@ -119,5 +151,5 @@
           (*subEvent.buffer) >> data ;
         }
-        transfer(dataIn, dataOut, missingValue) ;
+        transfer(1, dataIn, dataOut, missingValue) ;
       }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.cpp	(revision 1930)
@@ -6,5 +6,11 @@
   CGridLocalView::CGridLocalView(CGridLocalElements* parent, CElementView::type type) : localMask_(parent->getLocalMask())
   {
-    for(auto element : parent->getElements()) views_.push_back(element->getView(type)) ;
+    size_ = 1 ;
+    for(auto element : parent->getElements()) 
+    {
+      views_.push_back(element->getView(type)) ;
+      size_ *= element->getView(type)->getSize() ;
+    }
+
   }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.hpp	(revision 1930)
@@ -14,8 +14,10 @@
       std::vector<CLocalView*> views_ ;
       std::vector<bool>& localMask_ ;
+      int size_ ;
     
     public:
       CGridLocalView(CGridLocalElements* parent, CElementView::type type) ;
       std::vector<CLocalView*>& getViews(void) {return views_ ;}
+      int getSize() { return size_ ;}
   } ;
 }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.cpp	(revision 1930)
@@ -19,4 +19,60 @@
   {
     // generic method, every element can be distributed
+    int nDst = dstView_.size() ;
+    vector<size_t> dstSliceSize(nDst) ;
+    dstSliceSize[0] = 1 ;  
+    for(int i=1; i<nDst; i++)  dstSliceSize[i] = dstView_[i-1]->getGlobalSize()*dstSliceSize[i-1] ;
+  
+    CClientClientDHTTemplate<int>::Index2VectorInfoTypeMap dataInfo ;
+
+    CClientClientDHTTemplate<size_t>::Index2VectorInfoTypeMap info ; // info map
+    for(int pos=0; pos<nDst; pos++)
+    {
+      size_t sliceSize=dstSliceSize[pos] ;
+      map<int,CArray<size_t,1>> globalIndexView ;
+      dstView_[pos]->getGlobalIndexView(globalIndexView) ;
+      
+      CClientClientDHTTemplate<size_t>::Index2VectorInfoTypeMap lastInfo(info) ;
+
+      if (pos>0)
+      {
+        CArray<size_t,1> ranks(globalIndexView.size()) ;
+        auto it=globalIndexView.begin() ;
+        for(int i=0 ; i<ranks.numElements();i++,it++) ranks(i)=it->first ;
+        CClientClientDHTTemplate<size_t> dataRanks(info, localComm_) ;
+        dataRanks.computeIndexInfoMapping(ranks) ;
+        lastInfo = dataRanks.getInfoIndexMap() ;
+      }
+      
+      info.clear() ;
+      for(auto& it : globalIndexView)
+      {
+        int rank = it.first ;
+        auto& globalIndex = it.second ;
+        auto& inf = info[rank] ;
+        if (pos==0) for(int i=0;i<globalIndex.numElements();i++) inf.push_back(globalIndex(i)) ;
+        else
+        {
+          auto& lastGlobalIndex = lastInfo[rank] ;
+          for(size_t lastGlobalInd : lastGlobalIndex)
+          {
+            for(int i=0;i<globalIndex.numElements();i++) inf.push_back(globalIndex(i)*sliceSize+lastGlobalInd) ;
+          }
+        } 
+      }
+
+      if (pos==nDst-1)
+      {
+         for(auto& it : info)
+         {
+           int rank=it.first ;
+           auto& globalIndex = it.second ;
+           for(auto globalInd : globalIndex) dataInfo[globalInd].push_back(rank) ;
+         }
+      } 
+    }
+
+    CClientClientDHTTemplate<int> dataRanks(dataInfo, localComm_) ;
+/*
     CClientClientDHTTemplate<int>::Index2VectorInfoTypeMap info ; // info map
         
@@ -37,11 +93,14 @@
     
     CClientClientDHTTemplate<int> dataRanks(info, localComm_) ;
-    
+*/    
     // generate list of global index for src view
     int nSrc = srcView_.size() ;
     vector<size_t> srcSliceSize(nSrc) ;
-    srcSliceSize[nSrc-1] = 1 ;
-    for(int i=nSrc-2; i>=0; i--)  srcSliceSize[i] = srcView_[i+1]->getGlobalSize()*srcSliceSize[i+1] ;
-    
+//    srcSliceSize[nSrc-1] = 1 ;
+//    for(int i=nSrc-2; i>=0; i--)  srcSliceSize[i] = srcView_[i+1]->getGlobalSize()*srcSliceSize[i+1] ;
+   
+    srcSliceSize[0] = 1 ;  
+    for(int i=1; i<nSrc; i++)  srcSliceSize[i] = srcView_[i-1]->getGlobalSize()*srcSliceSize[i-1] ;
+
     vector<size_t> srcGlobalIndex ;
     size_t sliceIndex=0 ;
@@ -54,6 +113,6 @@
     vector<map<int, set<size_t>>> elements(nSrc) ; // internal representation of elements composing the grid
 
-    srcSliceSize[nSrc-1] = srcView_[nSrc-1]->getGlobalSize() ;
-    for(int i=nSrc-2 ; i>=0 ; i--) srcSliceSize[i] = srcView_[i]->getGlobalSize()*srcSliceSize[i+1] ;
+//    srcSliceSize[nSrc-1] = srcView_[nSrc-1]->getGlobalSize() ;
+//    for(int i=nSrc-2 ; i>=0 ; i--) srcSliceSize[i] = srcView_[i]->getGlobalSize()*srcSliceSize[i+1] ;
 
     for(auto& indRanks : returnInfo)
@@ -61,8 +120,9 @@
       size_t gridIndexGlo=indRanks.first ;
       auto& ranks = indRanks.second ;
-      for(int i=0;i<nSrc;i++)
+      for(int i=nSrc-1; i>=0; i--)
       {
         auto& element = elements[i] ;
-        size_t localIndGlo = gridIndexGlo % srcSliceSize[i] ;
+        size_t localIndGlo = gridIndexGlo / srcSliceSize[i] ;
+        gridIndexGlo = gridIndexGlo % srcSliceSize[i] ;
         for(int rank : ranks) element[rank].insert(localIndGlo) ;
       }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/local_view.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/local_view.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/local_view.cpp	(revision 1930)
@@ -15,4 +15,12 @@
   }
 
+  CLocalView::CLocalView(CLocalElement* parent, CElementView::type type, const CArray<bool,1>& maskView) 
+                        : CDistributedView( parent, type, {{  parent->localRank_,  maskView }} ),
+                          localRank_(parent->localRank_),
+                          globalIndex_(parent->globalIndex_), size_(CDistributedView::size_[parent->localRank_]),
+                          index_(CDistributedView::index_[parent->localRank_]), localSize_(CDistributedView::localSize_[parent->localRank_]) 
+  {
+
+  }
 
   void CLocalView::sendRemoteElement(CRemoteConnector& connector, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/local_view.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/local_view.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/local_view.hpp	(revision 1930)
@@ -17,6 +17,23 @@
     public:
     CLocalView(CLocalElement* parent, CElementView::type type, const CArray<int,1>& indexView) ;
+    CLocalView(CLocalElement* parent, CElementView::type type, const CArray<bool,1>& maskView) ;
+
     const CArray<int,1>& getIndex(void) { return index_ ;}
     const CArray<size_t,1>& getGlobalIndex(void) { return globalIndex_ ;}
+    
+    void getGlobalIndexView(CArray<size_t,1>& globalIndexView)
+    {
+      globalIndexView.resize(size_) ;
+      int pos=0 ;
+      for(int i=0 ; i<size_ ; i++)
+      {
+        if (index_(i)>=0 && index_(i)<localSize_) 
+        {
+          globalIndexView(i) = globalIndex_(index_(i)) ;
+          pos++ ;
+        }
+      }
+      globalIndexView.resizeAndPreserve(pos) ;
+    }    
 
     void getGlobalIndex(vector<size_t>& globalIndex, size_t sliceIndex, size_t* sliceSize, CLocalView** localView, int pos)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/scatterer_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/scatterer_connector.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/scatterer_connector.hpp	(revision 1930)
@@ -34,7 +34,20 @@
     void computeConnector(void) ;
     
-    template<typename T>
-    void transfer(const CArray<T,1>& dataIn, map<int, CArray<T,1>>& dataOut)
+    template<typename T, int n>
+    void transfer(const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut)
     {
+      transfer(1, dataIn, dataOut) ;
+    }
+
+    template<typename T, int n>
+    void transfer(const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut, T missingValue)
+    {
+      transfer(1, dataIn, dataOut, missingValue) ;
+    }
+
+    template<typename T, int n>
+    void transfer(int sizeT, const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut)
+    {
+      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
       for(auto& rankConnector : connector_)
       {
@@ -44,5 +57,5 @@
         int dstSize = mask.size() ;
         auto& data = dataOut[rank] ;
-        data.resize(dstSize) ;
+        data.resize(dstSize * sizeT) ;
         T* dstData = data.dataFirst() ;
         const T* srcData = dataIn.dataFirst() ;
@@ -50,5 +63,33 @@
           if (mask[i]) 
           {
-            dstData[i] = srcData[connector[j]] ;
+            for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = srcData[connector[j]*sizeT+k] ;
+            j++ ;
+          }
+      }
+    }
+
+    template<typename T, int n>
+    void transfer(int sizeT, const CArray<T,n>& dataIn, map<int, CArray<T,1>>& dataOut, T missingValue)
+    {
+      // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
+      for(auto& rankConnector : connector_)
+      {
+        int rank = rankConnector.first ;
+        auto& connector = rankConnector.second ;
+        auto& mask = mask_[rank] ;
+        int dstSize = mask.size() ;
+        auto& data = dataOut[rank] ;
+        data.resize(dstSize * sizeT) ;
+        T* dstData = data.dataFirst() ;
+        const T* srcData = dataIn.dataFirst() ;
+        for(int i=0, j=0; i<dstSize; i++)
+          if (mask[i]) 
+          {
+            for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = srcData[connector[j]*sizeT+k] ;
+            j++ ;
+          }
+          else 
+          {
+            for(int k=0;k<sizeT;k++) dstData[i*sizeT+k] = missingValue ;
             j++ ;
           }
@@ -56,9 +97,29 @@
     }
     
-    template<typename T>
-    void transfer(const CArray<T,1>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
+    template<typename T,int n>
+    void transfer(const CArray<T,n>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
+    {
+      transfer(1, dataIn, client, event, messageHeader) ;
+    }
+
+    template<typename T,int n>
+    void transfer(const CArray<T,n>& dataIn, T missingValue, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
+    {
+      transfer(1, dataIn, missingValue, client, event, messageHeader) ;
+    }
+
+    template<typename T, int n>
+    void transfer(int sizeT, const CArray<T,n>& dataIn, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
     {
       map<int, CArray<T,1>> dataOut ;
-      transfer(dataIn, dataOut) ;
+      transfer(sizeT, dataIn, dataOut) ;
+      sendToServer(dataOut, client, event, messageHeader) ;
+    }
+
+    template<typename T, int n>
+    void transfer(int sizeT, const CArray<T,n>& dataIn, T missingValue, CContextClient* client, CEventClient& event, const CMessage& messageHeader)
+    {
+      map<int, CArray<T,1>> dataOut ;
+      transfer(sizeT, dataIn, dataOut, missingValue) ;
       sendToServer(dataOut, client, event, messageHeader) ;
     }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.cpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.cpp	(revision 1930)
@@ -0,0 +1,51 @@
+#include "source_filter.hpp"
+#include "grid.hpp"
+#include "exception.hpp"
+#include "calendar_util.hpp"
+#include "field.hpp"
+#include "context.hpp"
+#include "grid.hpp"
+#include <limits> 
+
+namespace xios
+{
+    CClientFromClientSourceFilter::CClientFromClientSourceFilter(CGarbageCollector& gc, CField* field)
+     : COutputPin(gc, true)
+    {
+      CContext* context = CContext::getCurrent();
+      grid_= field-> getGrid();
+
+      freqOp_ = field->freq_op ;
+      lastDateReceived_ = context->getCalendar()->getInitDate();
+      offset_ = field->freq_offset ;
+    }
+
+  void CClientFromClientSourceFilter::streamData(CEventServer& event)
+  {
+    // unlikely to input from file server where data are received at ts=0
+    // for coupling, it would be after the first freq_op, because for now we don't have
+    // restart mecanism to send the value at ts=0. It must be changed in future
+  
+    if (wasDataAlreadyReceived_) lastDateReceived_ = lastDateReceived_ + freqOp_;
+    else wasDataAlreadyReceived_ = true ;
+
+    CDate date = lastDateReceived_ + offset_; // not sure is usefull check it for all filters
+
+    CDataPacketPtr packet(new CDataPacket);
+    packet->date = date;
+    packet->timestamp = date;
+    packet->status = CDataPacket::NO_ERROR;
+
+    grid_->getClientFromClientConnector()->transfer(event,packet->data) ;
+    onOutputReady(packet);
+  }
+
+  bool CClientFromClientSourceFilter::isDataLate(void)
+  {
+    bool isDataLate ;
+    CDate currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate() ;
+    if (wasDataAlreadyReceived_) isDataLate = lastDateReceived_ + offset_ + freqOp_ <= currentDate ;
+    else isDataLate = CContext::getCurrent()->getCalendar()->getInitDate()+ offset_ <= currentDate ;
+  }
+
+} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.hpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_client_source_filter.hpp	(revision 1930)
@@ -0,0 +1,48 @@
+#ifndef __XIOS_CLIENT_FROM_CLIENT_SOURCE_FILTER__
+#define __XIOS_CLIENT_FROM_CLIENT_SOURCE_FILTER__
+
+#include "output_pin.hpp"
+#include "event_server.hpp"
+#include "calendar_util.hpp"
+
+namespace xios
+{
+  class CField;
+  class CGrid ;
+
+
+  /*!
+   * A source filter is the entry point of the data in the graph of filters.
+   */
+  class CClientFromClientSourceFilter : public COutputPin
+  {
+    public:
+      /*!
+       * Constructs a source filter accepting data attached to the specified grid.
+       *
+       * \param gc the garbage collector associated with this filter
+       * \param field the field which the filter aply
+       */
+      CClientFromClientSourceFilter(CGarbageCollector& gc, CField* field) ;
+                    
+      /*!
+       * Transforms the data received from the model into a packet and send it
+       * in the filter graph. The array containing the data can safely be reused
+       * immediately after this method returns.
+       *
+       * \param event the event associated to data reception
+       */
+      void streamData(CEventServer& event);
+      bool isDataLate(void) ;
+
+    private:
+      CGrid* grid_;             //!< The grid attached to the data the filter can accept
+      CDuration freqOp_ ;
+      CDuration offset_ ;
+
+      bool wasDataAlreadyReceived_= false ;
+      CDate lastDateReceived_ ;
+  }; // class CSourceFilter
+} // namespace xios
+
+#endif //__XIOS_CLIENT_FROM_CLIENT_SOURCE_FILTER__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_server_source_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_server_source_filter.cpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_server_source_filter.cpp	(revision 1930)
@@ -0,0 +1,62 @@
+#include "client_from_server_source_filter.hpp"
+#include "grid.hpp"
+#include "field.hpp"
+#include "file.hpp"
+#include "exception.hpp"
+#include "calendar_util.hpp"
+#include "context.hpp"
+#include <limits> 
+
+namespace xios
+{
+  CClientFromServerSourceFilter::CClientFromServerSourceFilter(CGarbageCollector& gc, CField* field)
+    : COutputPin(gc, true)
+  {
+    CContext* context = CContext::getCurrent();
+    grid_= field->getGrid();
+    freqOp_ = field->fileIn_->output_freq ;
+    lastDateReceived_ = context->getCalendar()->getInitDate();
+    offset_ = field->freq_offset ;
+  }
+
+  void CClientFromServerSourceFilter::streamData(CEventServer& event)
+  {
+    const bool wasEOF = isEOF_;
+    int record ;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> record  ;
+    isEOF_ = (record == int(-1));
+
+    
+    if (wasDataAlreadyReceived_) lastDateReceived_ = lastDateReceived_ + freqOp_ ;
+    else wasDataAlreadyReceived_ = true;
+    
+    CDataPacketPtr packet(new CDataPacket);
+    packet->date = lastDateReceived_ + offset_;
+    packet->timestamp = packet->date ;
+
+    if (isEOF_) 
+    {
+      if (!wasEOF) dateEOF_ = lastDateReceived_;
+      packet->status = CDataPacket::END_OF_STREAM;
+    }
+    else 
+    {
+      grid_->getServerFromClientConnector()->transfer(event, packet->data) ;
+      packet->status = CDataPacket::NO_ERROR;
+    }
+    onOutputReady(packet);
+
+  }
+ 
+  bool CClientFromServerSourceFilter::isDataLate(void)
+  {
+    bool isDataLate ;
+    CDate currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate() ;
+
+    const CDate nextDataDue = wasDataAlreadyReceived_ ? (lastDateReceived_ + freqOp_) : CContext::getCurrent()->getCalendar()->getInitDate();
+    isDataLate = (nextDataDue <= currentDate);
+    
+    return isDataLate ; 
+    
+  }
+} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_server_source_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_server_source_filter.hpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_from_server_source_filter.hpp	(revision 1930)
@@ -0,0 +1,53 @@
+#ifndef __XIOS_CLIENT_FROM_SERVER_SOURCE_FILTER__
+#define __XIOS_CLIENT_FROM_SERVER_SOURCE_FILTER__
+
+#include <map>
+
+#include "output_pin.hpp"
+#include "event_server.hpp"
+#include "calendar_util.hpp"
+
+
+namespace xios
+{
+  class CGrid;
+  class CField;
+
+  /*!
+   * A source filter is the entry point of the data in the graph of filters.
+   */
+  class CClientFromServerSourceFilter : public COutputPin
+  {
+    public:
+      /*!
+       * Constructs a source filter accepting data attached to the specified grid.
+       *
+       * \param gc the garbage collector associated with this filter
+       * \param field associated to the filter
+       */
+      CClientFromServerSourceFilter(CGarbageCollector& gc, CField* field);
+
+      /*!
+       * Transforms the data received from the model into a packet and send it
+       * in the filter graph. The array containing the data can safely be reused
+       * immediately after this method returns.
+       *
+       * \param event the event coming from server with the associated data
+       */
+      void streamData(CEventServer& event);
+      bool isDataLate(void) ;
+      bool isEOF() {return isEOF_ ;}
+
+     private:
+      CGrid* grid_;             //!< The grid attached to the data the filter can accept
+      CDuration freqOp_ ;
+      CDuration offset_ ;
+
+      bool wasDataAlreadyReceived_= false ;
+      CDate lastDateReceived_ ;
+      bool isEOF_ = false ;
+      CDate dateEOF_ ;
+  }; // class CClientFromServerSourceFilter
+} // namespace xios
+
+#endif //__XIOS_CLIENT_FROM_SERVER_SOURCE_FILTER__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.cpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.cpp	(revision 1930)
@@ -0,0 +1,131 @@
+#include "client_to_model_store_filter.hpp"
+#include "context.hpp"
+#include "grid.hpp"
+#include "timer.hpp"
+#include "tracer.hpp"
+
+namespace xios
+{
+  CClientToModelStoreFilter::CClientToModelStoreFilter(CGarbageCollector& gc, CField* field)
+    : CInputPin(gc, 1)
+    , gc_(gc)
+  {
+    context_ = CContext::getCurrent() ;
+    grid_ = field->getGrid() ;
+
+    detectMissingValues_ = (!field->detect_missing_value.isEmpty() && !field->default_value.isEmpty() && field->detect_missing_value == true);
+    hasMissingValue_ = !field->default_value.isEmpty() ;
+    if (hasMissingValue_) missingValue_  = field->default_value ;
+    detectMissingValues_ = (!field->detect_missing_value.isEmpty() && hasMissingValue_);
+  }
+
+  CConstDataPacketPtr CClientToModelStoreFilter::getPacket(Time timestamp)
+  {
+    CTimer timer("CStoreFilter::getPacket");
+//    timer.resume(); 
+    info(0)<<"ENTERING CStoreFilter::getPacket"<<std::endl ;
+    traceOff() ;
+//    timer.suspend();
+    CConstDataPacketPtr packet;
+    const double timeout = CXios::recvFieldTimeout;
+
+    do
+    {
+      if (canBeTriggered()) trigger(timestamp);
+
+      timer.resume();
+
+      std::map<Time, CDataPacketPtr>::const_iterator it = packets_.find(timestamp);
+      if (it != packets_.end()) packet = it->second;
+      else  context_->eventLoop(); // if the packet is not available yet, check if it can be received
+
+      timer.suspend();
+    } while (!packet && timer.getCumulatedTime() < timeout);
+//    timer.resume();
+    traceOn() ;
+//    timer.suspend();
+
+    if (!packet)
+    {
+      std::map<Time, CDataPacketPtr>::const_iterator it ;
+      info(0)<<"Impossible to get the packet with timestamp = " << timestamp<<std::endl<<"Available timestamp are : "<<std::endl ;
+      for(it=packets_.begin();it!=packets_.end();++it) info(0)<<it->first<<"  ";
+      info(0)<<std::endl ;
+      ERROR("CConstDataPacketPtr CStoreFilter::getPacket(Time timestamp) const",
+            << "Impossible to get the packet with timestamp = " << timestamp);
+    }
+    return packet;
+  }
+
+  template <int N>
+  CDataPacket::StatusCode CClientToModelStoreFilter::getData(Time timestamp, CArray<double, N>& data)
+  {
+    CConstDataPacketPtr packet = getPacket(timestamp);
+
+    if (packet->status == CDataPacket::NO_ERROR)
+    {
+      if (hasMissingValue_) grid_->getWorkflowToModelConnector()->transfer(packet->data, data, missingValue_);
+      else grid_->getWorkflowToModelConnector()->transfer(packet->data, data);
+    }
+    return packet->status;
+  }
+
+  template CDataPacket::StatusCode CClientToModelStoreFilter::getData<1>(Time timestamp, CArray<double, 1>& data);
+  template CDataPacket::StatusCode CClientToModelStoreFilter::getData<2>(Time timestamp, CArray<double, 2>& data);
+  template CDataPacket::StatusCode CClientToModelStoreFilter::getData<3>(Time timestamp, CArray<double, 3>& data);
+  template CDataPacket::StatusCode CClientToModelStoreFilter::getData<4>(Time timestamp, CArray<double, 4>& data);
+  template CDataPacket::StatusCode CClientToModelStoreFilter::getData<5>(Time timestamp, CArray<double, 5>& data);
+  template CDataPacket::StatusCode CClientToModelStoreFilter::getData<6>(Time timestamp, CArray<double, 6>& data);
+  template CDataPacket::StatusCode CClientToModelStoreFilter::getData<7>(Time timestamp, CArray<double, 7>& data);
+
+  void CClientToModelStoreFilter::onInputReady(std::vector<CDataPacketPtr> data)
+  {
+
+    CDataPacketPtr packet;
+    if (detectMissingValues_)
+    {
+      const size_t nbData = data[0]->data.numElements();
+
+      packet = CDataPacketPtr(new CDataPacket);
+      packet->date = data[0]->date;
+      packet->timestamp = data[0]->timestamp;
+      packet->status = data[0]->status;
+      packet->data.resize(nbData);
+      packet->data = data[0]->data;
+
+      for (size_t idx = 0; idx < nbData; ++idx)
+      {
+        if (NumTraits<double>::isNan(packet->data(idx)))
+          packet->data(idx) = missingValue_;
+      }
+
+    }
+
+    else
+    {
+      packet = data[0];
+    }
+
+    packets_.insert(std::make_pair(packet->timestamp, packet));
+    // The packet is always destroyed by the garbage collector
+    // so we register but never unregister
+    gc_.registerObject(this, packet->timestamp);
+
+  }
+
+  bool CClientToModelStoreFilter::mustAutoTrigger() const
+  {
+    return false;
+  }
+
+  bool CClientToModelStoreFilter::isDataExpected(const CDate& date) const
+  {
+    return true;
+  }
+
+  void CClientToModelStoreFilter::invalidate(Time timestamp)
+  {
+    CInputPin::invalidate(timestamp);
+    packets_.erase(packets_.begin(), packets_.lower_bound(timestamp));
+  }
+} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.hpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/client_to_model_store_filter.hpp	(revision 1930)
@@ -0,0 +1,94 @@
+#ifndef __XIOS_CStoreFilter__
+#define __XIOS_CStoreFilter__
+
+#include "input_pin.hpp"
+
+namespace xios
+{
+  class CContext;
+  class CGrid;
+  class CField ;
+
+  /*!
+   * A terminal filter which stores all the packets it receives.
+   */
+  class CClientToModelStoreFilter : public CInputPin
+  {
+    public:
+      /*!
+       * Constructs the filter with one input slot and an associated
+       * garbage collector for the specified grid and context.
+       *
+       * \param gc the garbage collector associated with this input pin
+       * \param context the context to which the data belongs
+       * \param grid the grid to which the data is attached
+       * \param detectMissingValues whether missing values should be detected
+       * \param missingValue the value to use to replace missing values
+       */
+      CClientToModelStoreFilter(CGarbageCollector& gc, CField* field);
+
+      /*!
+       * Accesses the filter storage and retuns the packet corresponding
+       * to the specified timestamp. If there is no packet available for
+       * the specified timestamp, the function waits until the data is
+       * received or a timeout occurs.
+       *
+       * \param timestamp the timestamp of the requested packet
+       * \return a pointer to a read-only packet
+       */
+      CConstDataPacketPtr getPacket(Time timestamp);
+
+      /*!
+       * Accesses the filter storage and retuns the data corresponding
+       * to the specified timestamp. If there is no data available for
+       * the specified timestamp, the function waits until the data is
+       * received or a timeout occurs.
+       *
+       * \param timestamp the timestamp of the requested data
+       * \param data the array where the data is to be copied
+       * \return the status code associated with the data
+       */
+      template <int N>
+      CDataPacket::StatusCode getData(Time timestamp, CArray<double, N>& data);
+
+      /*!
+       * Tests if the filter must auto-trigger.
+       *
+       * \return true if the filter must auto-trigger
+       */
+      bool virtual mustAutoTrigger() const;
+
+      /*!
+       * Tests whether data is expected for the specified date.
+       *
+       * \param date the date associated to the data
+       */
+      bool virtual isDataExpected(const CDate& date) const;
+
+      /*!
+       * Removes all pending packets which are older than the specified timestamp.
+       *
+       * \param timestamp the timestamp used for invalidation
+       */
+      void virtual invalidate(Time timestamp);
+
+    protected:
+      /*!
+       * Stores the packet for later access.
+       *
+       * \param data a vector of packets corresponding to each slot
+       */
+      void virtual onInputReady(std::vector<CDataPacketPtr> data);
+
+    private:
+      CGarbageCollector& gc_; //!< The garbage collector associated to the filter
+      CContext* context_; //!< The context to which the data belongs
+      CGrid* grid_; //!< The grid attached to the data the filter can accept
+      bool detectMissingValues_; //!< Whether missing values should be detected
+      double missingValue_; //!< The value to use to replace missing values
+      bool hasMissingValue_ ;
+      std::map<Time, CDataPacketPtr> packets_; //<! The stored packets
+  }; // class CClientToModelStoreFilter
+} // namespace xios
+
+#endif //__XIOS_CStoreFilter__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/data_packet.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/data_packet.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/data_packet.hpp	(revision 1930)
@@ -32,5 +32,6 @@
      * \return a deep copy of the packet
      */
-    CDataPacket* copy() const {
+    CDataPacket* copy() const 
+    {
       CDataPacket* p = new CDataPacket;
       p->data.resize(data.shape());
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_reader_source_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_reader_source_filter.cpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_reader_source_filter.cpp	(revision 1930)
@@ -0,0 +1,75 @@
+#include "file_reader_source_filter.hpp"
+#include "grid.hpp"
+#include "exception.hpp"
+#include "calendar_util.hpp"
+#include "context.hpp"
+#include "field.hpp"
+#include "file.hpp"
+#include "context.hpp"
+
+
+namespace xios
+{
+  CFileReaderSourceFilter::CFileReaderSourceFilter(CGarbageCollector& gc, CField* field)
+    : COutputPin(gc)
+  {
+    field_ = field ;
+    grid_ = field->getGrid() ;
+    file_ = field->getFileIn() ;
+    if (!file_->cyclic.isEmpty()) isCyclic_ = file_->cyclic ;
+    if (!field_->scale_factor.isEmpty()) { hasScaleFactor_=true ; scaleFactor_ = field_->scale_factor ; }
+    if (!field_->add_offset.isEmpty()) { hasAddOffset_=true ; addOffset_ = field_->add_offset ; }
+  }
+
+  void CFileReaderSourceFilter::streamData()
+  {
+    Time timeStamp ;
+    CDataPacketPtr packet(new CDataPacket);
+    packet->date = CContext::getCurrent()->getCalendar()->getCurrentDate();
+    packet->timestamp = timeStamp;
+    packet->status = CDataPacket::NO_ERROR;
+
+    CArray<double,1> data ;
+    if (!isInitialized_)  initialize() ;
+    CField::EReadField readState = CField::RF_DATA;
+
+    if ( nStepMax_==0 || (nStep_ >= nStepMax_ && !isCyclic_)) readState = CField::RF_EOF;
+  
+    if (CField::RF_EOF != readState)
+    {
+      if (file_->isEmptyZone()) readData(data) ;
+      else readState = CField::RF_NODATA;
+    }
+    nStep_++ ;
+    
+    if (readState == CField::RF_DATA) packet->status = CDataPacket::NO_ERROR;
+    else packet->status = CDataPacket::END_OF_STREAM;
+            
+    onOutputReady(packet);
+  }
+
+  void CFileReaderSourceFilter::initialize()
+  {
+    CContext* context = CContext::getCurrent();
+    file_->initRead();
+    if (file_->isEmptyZone())
+    {      
+      file_->checkReadFile();
+      nStepMax_ = file_->getDataInput()->getFieldNbRecords(field_);
+      nStep_ = 0 ;
+    }
+    MPI_Allreduce(MPI_IN_PLACE, &nStepMax_, 1, MPI_INT, MPI_MAX, context->getIntraComm());
+  }
+
+  void CFileReaderSourceFilter::readData(CArray<double,1>& data)
+  {
+    CGridLocalConnector*  connector = grid_->getFullToWorkflowConnector() ;
+    CArray<double,1> dataIn(connector->getDstSize()) ;
+    file_->getDataInput()->readFieldData(field_, nStep_%nStepMax_, dataIn);
+    connector->transfer(dataIn, data) ; 
+
+    if (hasScaleFactor_ || hasAddOffset_) data = data * scaleFactor_ + addOffset_; // possibility of optimization
+  }
+ 
+  
+} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_reader_source_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_reader_source_filter.hpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_reader_source_filter.hpp	(revision 1930)
@@ -0,0 +1,54 @@
+#ifndef __XIOS_FILE_READER_SOURCE_FILTER__
+#define __XIOS_FILE_READER_SOURCE_FILTER__
+
+#include "output_pin.hpp"
+
+namespace xios
+{
+  class CField;
+  class CFile ;
+  class CGrid ;
+
+  /*!
+   * A source filter is the entry point of the data in the graph of filters.
+   */
+  class CFileReaderSourceFilter : public COutputPin
+  {
+    public:
+      /*!
+       * Constructs a source filter accepting data attached to the specified grid.
+       *
+       * \param gc the garbage collector associated with this filter
+       * \param field the field to which the data is related
+       */
+      CFileReaderSourceFilter(CGarbageCollector& gc, CField* field);
+
+      /*!
+       * Transforms the data received from the model into a packet and send it
+       * in the filter graph. The array containing the data can safely be reused
+       * immediately after this method returns.
+       *
+       * \param date the date associated to the data
+       * \param data an array containing the data
+       */
+      void streamData(void);
+      void initialize(void) ;
+      void readData(CArray<double,1>& data) ;
+
+    private:
+      CGrid* grid_;             //!< The grid attached to the data the filter can accept
+      CField* field_ ;
+      CFile* file_ ;
+      bool hasScaleFactor_ = false;
+      bool hasAddOffset_ = false ;
+      bool isInitialized_ = false ;
+      bool isCyclic_ = false ;
+      double scaleFactor_= 1.0 ;
+      double addOffset_= 0. ;
+      int nStepMax_ ;
+      int nStep_ ;
+
+  }; // class CFileReaderSourceFilter
+} // namespace xios
+
+#endif // __XIOS_FILE_READER_SOURCE_FILTER__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_server_reader_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_server_reader_filter.cpp	(revision 1929)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#include "file_server_reader_filter.hpp"
-#include "grid.hpp"
-#include "field.hpp"
-#include "exception.hpp"
-#include "calendar_util.hpp"
-#include <limits> 
-
-namespace xios
-{
-  CFileServerReaderFilter::CFileServerReaderFilter(CGarbageCollector& gc, CField* field) : COutputPin(gc), field_(field)
-  {
- 
-  }
-
-  void CFileServerReaderFilter::streamData(CDate date, const CArray<double, 1>& data)
-  {
-    CDataPacketPtr packet(new CDataPacket);
-    packet->date = date;
-    packet->timestamp = date;
-    packet->status = CDataPacket::NO_ERROR;
-    packet->data.reference(data.copy()) ;
-    onOutputReady(packet);
-  }
-
-  void CFileServerReaderFilter::signalEndOfStream(CDate date)
-  {
-    CDataPacketPtr packet(new CDataPacket);
-    packet->date = date;
-    packet->timestamp = date;
-    packet->status = CDataPacket::END_OF_STREAM;
-    onOutputReady(packet);
-  }
-} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_server_reader_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/file_server_reader_filter.hpp	(revision 1929)
+++ 	(revision )
@@ -1,52 +1,0 @@
-#ifndef __XIOS_FILE_SERVER_READER_HPP__
-#define __XIOS_FILE_SERVER_READER_HPP__
-
-#include <map>
-
-#include "output_pin.hpp"
-
-namespace xios
-{
-  class CGrid;
-  class CField;
-
-  /*!
-   * A source filter is the entry point of the data in the graph of filters. It is in charge to read data in a file on server side and
-   * injecting it into the workflow
-   */
-  class CFileServerReaderFilter : public COutputPin
-  {
-    public:
-      /*!
-       * Constructs a source filter accepting data attached to the specified grid.
-       *
-       * \param gc the garbage collector associated with this filter
-       * \param associatedField Field associated to the filter
-       */
-       CFileServerReaderFilter(CGarbageCollector& gc, CField* associatedField) ;
-
-      /*!
-       * Transforms the data received from the model into a packet and send it
-       * in the filter graph. The array containing the data can safely be reused
-       * immediately after this method returns.
-       *
-       * \param date the date associated to the data
-       * \param data an array containing the data
-       */
-      void streamData(CDate date, const CArray<double, 1>& data);
-
-      /*!
-       * Signals the filter graph that the end of stream was reached.
-       *
-       * \param date the date at which the end of stream occurred
-       */
-      void signalEndOfStream(CDate date);
-
-    private:
-      CField* field_;             //!< The field attached to the data the filter can accept
-//      const bool hasMissingValue;
-//      const double defaultValue;
-  }; // class CFileServerReaderFilter
-} // namespace xios
-
-#endif //__XIOS_FILE_SERVER_READER__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.cpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.cpp	(revision 1930)
@@ -0,0 +1,58 @@
+#include "model_to_client_source_filter.hpp"
+#include "grid.hpp"
+#include "exception.hpp"
+#include "calendar_util.hpp"
+#include <limits> 
+
+namespace xios
+{
+  CModelToClientSourceFilter::CModelToClientSourceFilter(CGarbageCollector& gc, CGrid* grid, bool hasMissingValue, double defaultValue)
+    : COutputPin(gc)
+    , grid_(grid)
+    , hasMissingValue_(hasMissingValue), defaultValue_(defaultValue)
+  {
+    if (!grid)
+      ERROR("CSourceFilter::CSourceFilter(CGrid* grid)",
+            "Impossible to construct a source filter without providing a grid.");
+  }
+
+  template <int N>
+  void CModelToClientSourceFilter::streamData(CDate date, const CArray<double, N>& data)
+  {
+    CDataPacketPtr packet(new CDataPacket);
+    packet->date = date;
+    packet->timestamp = date;
+    packet->status = CDataPacket::NO_ERROR;
+    
+    auto connector = grid_->getModelToWorkflowConnector() ;
+
+    if (connector->getSrcSize() != data.numElements())
+      ERROR("void CModelToClientSourceFilter::streamData(CDate date, const CArray<double, N>& data)",
+            << "[ Awaiting data of size = " <<connector->getSrcSize() << ", "
+            << "Received data size = "      << data.numElements() << " ] "
+            << "The data array does not have the right size! "
+            << "grid = " << grid_->getId())
+    const double nanValue = std::numeric_limits<double>::quiet_NaN();
+    packet->data.resize(connector->getDstSize()) ;
+    connector->transfer(data, packet->data, nanValue) ;
+
+    if (hasMissingValue_)
+    {
+        const double nanValue = std::numeric_limits<double>::quiet_NaN();
+        const size_t nbData = packet->data.numElements();
+        for (size_t idx = 0; idx < nbData; ++idx)
+          if (defaultValue_ == packet->data(idx))   packet->data(idx) = nanValue;
+    }
+    
+    onOutputReady(packet);
+  }
+
+  template void CModelToClientSourceFilter::streamData<1>(CDate date, const CArray<double, 1>& data);
+  template void CModelToClientSourceFilter::streamData<2>(CDate date, const CArray<double, 2>& data);
+  template void CModelToClientSourceFilter::streamData<3>(CDate date, const CArray<double, 3>& data);
+  template void CModelToClientSourceFilter::streamData<4>(CDate date, const CArray<double, 4>& data);
+  template void CModelToClientSourceFilter::streamData<5>(CDate date, const CArray<double, 5>& data);
+  template void CModelToClientSourceFilter::streamData<6>(CDate date, const CArray<double, 6>& data);
+  template void CModelToClientSourceFilter::streamData<7>(CDate date, const CArray<double, 7>& data);
+
+} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.hpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/model_to_client_source_filter.hpp	(revision 1930)
@@ -0,0 +1,55 @@
+#ifndef __XIOS_MODEL_TO_CLIENT_SOURCE_FILTER_HPP__
+#define __XIOS_MODEL_TO_CLIENT_SOURCE_FILTER_HPP__
+
+#include <map>
+
+#include "output_pin.hpp"
+
+namespace xios
+{
+  class CGrid;
+
+  /*!
+   * A source filter is the entry point of the data in the graph of filters.
+   */
+  class CModelToClientSourceFilter : public COutputPin
+  {
+    public:
+      /*!
+       * Constructs a source filter accepting data attached to the specified grid.
+       *
+       * \param gc the garbage collector associated with this filter
+       * \param grid the grid to which the data is attached
+       * \param hasMissingValue whether data has missing value
+       * \param defaultValue missing value to detect
+       */
+      CModelToClientSourceFilter(CGarbageCollector& gc, CGrid* grid, bool hasMissingValue = false, double defaultValue = 0.0);
+
+      /*!
+       * Transforms the data received from the model into a packet and send it
+       * in the filter graph. The array containing the data can safely be reused
+       * immediately after this method returns.
+       *
+       * \param date the date associated to the data
+       * \param data an array containing the data
+       */
+      template <int N>
+      void streamData(CDate date, const CArray<double, N>& data);
+
+      /*!
+       * Transforms the data received from the server into a packet and send it
+       * in the filter graph. The array containing the data can safely be reused
+       * immediately after this method returns.
+       *
+       * \param date the date associated to the data
+       * \param data an array containing the data
+       */
+
+    private:
+      CGrid* grid_;             //!< The grid attached to the data the filter can accept
+      const bool hasMissingValue_;
+      const double defaultValue_;
+  }; // class CSourceFilter
+} // namespace xios
+
+#endif // __XIOS_MODEL_TO_CLIENT_SOURCE_FILTER_HPP__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_from_client_source_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_from_client_source_filter.cpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_from_client_source_filter.cpp	(revision 1930)
@@ -0,0 +1,34 @@
+#include "server_from_client_source_filter.hpp"
+#include "grid.hpp"
+#include "exception.hpp"
+#include "calendar_util.hpp"
+#include "context.hpp"
+
+
+namespace xios
+{
+  CServerFromClientSourceFilter::CServerFromClientSourceFilter(CGarbageCollector& gc, CGrid* grid)
+    : COutputPin(gc)
+    , grid_(grid)
+  {
+    if (!grid_)
+      ERROR("CServerFromClientSourceFilter::CServerFromClientSourceFilter(CGarbageCollector& gc, CGrid* grid)",
+            "Impossible to construct a source filter without providing a grid.");
+  }
+
+  void CServerFromClientSourceFilter::streamData(CEventServer& event)
+  {
+    Time timeStamp ;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> timeStamp  ;
+    CDataPacketPtr packet(new CDataPacket);
+    packet->date = CContext::getCurrent()->getCalendar()->getTimeOrigin() + timeStamp*Second; // very bad, better to pass directly the date
+    packet->timestamp = timeStamp;
+    packet->status = CDataPacket::NO_ERROR;
+    grid_->getServerFromClientConnector()->transfer(event,packet->data) ;
+
+    onOutputReady(packet);
+  }
+
+ 
+  
+} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_from_client_source_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_from_client_source_filter.hpp	(revision 1930)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/server_from_client_source_filter.hpp	(revision 1930)
@@ -0,0 +1,47 @@
+#ifndef __XIOS_SERVER_FROM_CLIENT_SOURCE_FILTER__
+#define __XIOS_SERVER_FROM_CLIENT_SOURCE_FILTER__
+
+#include "output_pin.hpp"
+#include "event_server.hpp"
+
+namespace xios
+{
+  class CGrid;
+
+  /*!
+   * A source filter is the entry point of the data in the graph of filters.
+   */
+  class CServerFromClientSourceFilter : public COutputPin
+  {
+    public:
+      /*!
+       * Constructs a source filter accepting data attached to the specified grid.
+       *
+       * \param gc the garbage collector associated with this filter
+       * \param grid the grid to which the data is attached
+       * \param compression
+       * \param mask
+       * \param offset the offset applied to the timestamp of all packets
+       * \param manualTrigger whether the output should be triggered manually
+       * \param hasMissingValue whether data has missing value
+       * \param defaultValue missing value to detect
+       */
+      CServerFromClientSourceFilter(CGarbageCollector& gc, CGrid* grid);
+
+      /*!
+       * Transforms the data received from the model into a packet and send it
+       * in the filter graph. The array containing the data can safely be reused
+       * immediately after this method returns.
+       *
+       * \param date the date associated to the data
+       * \param data an array containing the data
+       */
+      void streamData(CEventServer& event);
+
+    private:
+      CGrid* grid_;             //!< The grid attached to the data the filter can accept
+
+  }; // class CServerFromClientSourceFilter
+} // namespace xios
+
+#endif // __XIOS_SERVER_FROM_CLIENT_SOURCE_FILTER__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/source_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/source_filter.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/source_filter.cpp	(revision 1930)
@@ -40,19 +40,26 @@
       packet->data = defaultValue;
       grid->uncompressField(data, packet->data);    
+      
+      // Convert missing values to NaN
+      if (hasMissingValue) // probably to removed later
+      {
+        const double nanValue = std::numeric_limits<double>::quiet_NaN();
+        const size_t nbData = packet->data.numElements();
+        for (size_t idx = 0; idx < nbData; ++idx)
+        {
+          if (defaultValue == packet->data(idx))
+          packet->data(idx) = nanValue;
+        }
+      }
     }
     else
     {
-      if (mask) grid->maskField(data, packet->data);
-      else grid->inputField(data, packet->data);
-    }
-    // Convert missing values to NaN
-    if (hasMissingValue)
-    {
-      const double nanValue = std::numeric_limits<double>::quiet_NaN();
-      const size_t nbData = packet->data.numElements();
-      for (size_t idx = 0; idx < nbData; ++idx)
+      if (mask) grid->maskField(data, packet->data);       // => ie coming from model
+      //else grid->inputField(data, packet->data);
+      else 
       {
-        if (defaultValue == packet->data(idx))
-          packet->data(idx) = nanValue;
+        packet->data.resize(data.numElements()) ; // temporary solution, create own source filter for data coming from client
+        CArray<double,1> tmp( (double*)data.dataFirst(),shape(data.numElements()),duplicateData) ;
+        packet->data.reference(tmp) ;   // nothing to do if coming from client to server => workflow view
       }
     }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/store_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/store_filter.cpp	(revision 1929)
+++ 	(revision )
@@ -1,137 +1,0 @@
-#include "store_filter.hpp"
-#include "context.hpp"
-#include "grid.hpp"
-#include "timer.hpp"
-#include "tracer.hpp"
-
-namespace xios
-{
-  CStoreFilter::CStoreFilter(CGarbageCollector& gc, CContext* context, CGrid* grid,
-                             bool detectMissingValues /*= false*/, double missingValue /*= 0.0*/)
-    : CInputPin(gc, 1)
-    , gc(gc)
-    , context(context)
-    , grid(grid)
-    , detectMissingValues(detectMissingValues)
-    , missingValue(missingValue)
-  {
-    if (!context)
-      ERROR("CStoreFilter::CStoreFilter(CContext* context, CGrid* grid)",
-            "Impossible to construct a store filter without providing a context.");
-    if (!grid)
-      ERROR("CStoreFilter::CStoreFilter(CContext* context, CGrid* grid)",
-            "Impossible to construct a store filter without providing a grid.");
-  }
-
-  CConstDataPacketPtr CStoreFilter::getPacket(Time timestamp)
-  {
-    CTimer timer("CStoreFilter::getPacket");
-//    timer.resume(); 
-    info(0)<<"ENTERING CStoreFilter::getPacket"<<std::endl ;
-    traceOff() ;
-//    timer.suspend();
-    CConstDataPacketPtr packet;
-    const double timeout = CXios::recvFieldTimeout;
-
-    do
-    {
-      if (canBeTriggered())
-        trigger(timestamp);
-
-      timer.resume();
-
-      std::map<Time, CDataPacketPtr>::const_iterator it = packets.find(timestamp);
-      if (it != packets.end())
-        packet = it->second;
-      else // if the packet is not available yet, check if it can be received
-//ym        context->checkBuffersAndListen();
-        context->eventLoop();
-
-      timer.suspend();
-    } while (!packet && timer.getCumulatedTime() < timeout);
-//    timer.resume();
-    traceOn() ;
-//    timer.suspend();
-
-    if (!packet)
-    {
-      std::map<Time, CDataPacketPtr>::const_iterator it ;
-      info(0)<<"Impossible to get the packet with timestamp = " << timestamp<<std::endl<<"Available timestamp are : "<<std::endl ;
-      for(it=packets.begin();it!=packets.end();++it) info(0)<<it->first<<"  ";
-      info(0)<<std::endl ;
-      ERROR("CConstDataPacketPtr CStoreFilter::getPacket(Time timestamp) const",
-            << "Impossible to get the packet with timestamp = " << timestamp);
-    }
-    return packet;
-  }
-
-  template <int N>
-  CDataPacket::StatusCode CStoreFilter::getData(Time timestamp, CArray<double, N>& data)
-  {
-    CConstDataPacketPtr packet = getPacket(timestamp);
-
-    if (packet->status == CDataPacket::NO_ERROR)
-      grid->outputField(packet->data, data);
-
-    return packet->status;
-  }
-
-  template CDataPacket::StatusCode CStoreFilter::getData<1>(Time timestamp, CArray<double, 1>& data);
-  template CDataPacket::StatusCode CStoreFilter::getData<2>(Time timestamp, CArray<double, 2>& data);
-  template CDataPacket::StatusCode CStoreFilter::getData<3>(Time timestamp, CArray<double, 3>& data);
-  template CDataPacket::StatusCode CStoreFilter::getData<4>(Time timestamp, CArray<double, 4>& data);
-  template CDataPacket::StatusCode CStoreFilter::getData<5>(Time timestamp, CArray<double, 5>& data);
-  template CDataPacket::StatusCode CStoreFilter::getData<6>(Time timestamp, CArray<double, 6>& data);
-  template CDataPacket::StatusCode CStoreFilter::getData<7>(Time timestamp, CArray<double, 7>& data);
-
-  void CStoreFilter::onInputReady(std::vector<CDataPacketPtr> data)
-  {
-
-    CDataPacketPtr packet;
-    if (detectMissingValues)
-    {
-      const size_t nbData = data[0]->data.numElements();
-
-      packet = CDataPacketPtr(new CDataPacket);
-      packet->date = data[0]->date;
-      packet->timestamp = data[0]->timestamp;
-      packet->status = data[0]->status;
-      packet->data.resize(nbData);
-      packet->data = data[0]->data;
-
-      for (size_t idx = 0; idx < nbData; ++idx)
-      {
-        if (NumTraits<double>::isNan(packet->data(idx)))
-          packet->data(idx) = missingValue;
-      }
-
-    }
-
-    else
-    {
-      packet = data[0];
-    }
-
-    packets.insert(std::make_pair(packet->timestamp, packet));
-    // The packet is always destroyed by the garbage collector
-    // so we register but never unregister
-    gc.registerObject(this, packet->timestamp);
-
-  }
-
-  bool CStoreFilter::mustAutoTrigger() const
-  {
-    return false;
-  }
-
-  bool CStoreFilter::isDataExpected(const CDate& date) const
-  {
-    return true;
-  }
-
-  void CStoreFilter::invalidate(Time timestamp)
-  {
-    CInputPin::invalidate(timestamp);
-    packets.erase(packets.begin(), packets.lower_bound(timestamp));
-  }
-} // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/store_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/store_filter.hpp	(revision 1929)
+++ 	(revision )
@@ -1,93 +1,0 @@
-#ifndef __XIOS_CStoreFilter__
-#define __XIOS_CStoreFilter__
-
-#include "input_pin.hpp"
-
-namespace xios
-{
-  class CContext;
-  class CGrid;
-
-  /*!
-   * A terminal filter which stores all the packets it receives.
-   */
-  class CStoreFilter : public CInputPin
-  {
-    public:
-      /*!
-       * Constructs the filter with one input slot and an associated
-       * garbage collector for the specified grid and context.
-       *
-       * \param gc the garbage collector associated with this input pin
-       * \param context the context to which the data belongs
-       * \param grid the grid to which the data is attached
-       * \param detectMissingValues whether missing values should be detected
-       * \param missingValue the value to use to replace missing values
-       */
-      CStoreFilter(CGarbageCollector& gc, CContext* context, CGrid* grid,
-                   bool detectMissingValues = false, double missingValue = 0.0);
-
-      /*!
-       * Accesses the filter storage and retuns the packet corresponding
-       * to the specified timestamp. If there is no packet available for
-       * the specified timestamp, the function waits until the data is
-       * received or a timeout occurs.
-       *
-       * \param timestamp the timestamp of the requested packet
-       * \return a pointer to a read-only packet
-       */
-      CConstDataPacketPtr getPacket(Time timestamp);
-
-      /*!
-       * Accesses the filter storage and retuns the data corresponding
-       * to the specified timestamp. If there is no data available for
-       * the specified timestamp, the function waits until the data is
-       * received or a timeout occurs.
-       *
-       * \param timestamp the timestamp of the requested data
-       * \param data the array where the data is to be copied
-       * \return the status code associated with the data
-       */
-      template <int N>
-      CDataPacket::StatusCode getData(Time timestamp, CArray<double, N>& data);
-
-      /*!
-       * Tests if the filter must auto-trigger.
-       *
-       * \return true if the filter must auto-trigger
-       */
-      bool virtual mustAutoTrigger() const;
-
-      /*!
-       * Tests whether data is expected for the specified date.
-       *
-       * \param date the date associated to the data
-       */
-      bool virtual isDataExpected(const CDate& date) const;
-
-      /*!
-       * Removes all pending packets which are older than the specified timestamp.
-       *
-       * \param timestamp the timestamp used for invalidation
-       */
-      void virtual invalidate(Time timestamp);
-
-    protected:
-      /*!
-       * Stores the packet for later access.
-       *
-       * \param data a vector of packets corresponding to each slot
-       */
-      void virtual onInputReady(std::vector<CDataPacketPtr> data);
-
-    private:
-      CGarbageCollector& gc; //!< The garbage collector associated to the filter
-      CContext* context; //!< The context to which the data belongs
-      CGrid* grid; //!< The grid attached to the data the filter can accept
-      const bool detectMissingValues; //!< Whether missing values should be detected
-      const double missingValue; //!< The value to use to replace missing values
-      std::map<Time, CDataPacketPtr> packets; //<! The stored packets
-  }; // class CStoreFilter
-} // namespace xios
-
-#endif //__XIOS_CStoreFilter__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.cpp	(revision 1930)
@@ -43,5 +43,5 @@
   CATCH
 
-  void CNc4DataInput::readFieldData_(CField* field, CArray<double,1>& dataOut)
+  void CNc4DataInput::readFieldData_(CField* field, int record, CArray<double,1>& dataOut)
   TRY
   {
@@ -50,16 +50,12 @@
     CGrid* grid = field->getGrid();
 
-    if (!grid->doGridHaveDataToWrite())
-      if (SuperClass::type==MULTI_FILE || !isCollective) return;
+    if (!grid->doGridHaveDataToWrite())  if (SuperClass::type==MULTI_FILE || !isCollective) return;
 
     StdString fieldId = field->getFieldOutputName();
 
-    CArray<double,1> fieldData(grid->getWrittenDataSize());
-    if (!field->default_value.isEmpty()) fieldData = field->default_value;
-
     switch (SuperClass::type)
     {
       case MULTI_FILE:
-        SuperClassWriter::getData(fieldData, fieldId, isCollective, (field->getNStep() - 1)%field->nstepMax );
+        SuperClassWriter::getData(dataOut, fieldId, isCollective, record );
         break;
       case ONE_FILE:
@@ -108,17 +104,7 @@
         }
 
-        SuperClassWriter::getData(fieldData, fieldId, isCollective, (field->getNStep() - 1)%field->nstepMax, &start, &count);
+        SuperClassWriter::getData(dataOut, fieldId, isCollective, record, &start, &count);
         break;
       }
-    }
-
-    field->inputField(fieldData, dataOut);
-
-    if (!field->scale_factor.isEmpty() || !field->add_offset.isEmpty())
-    {
-      double scaleFactor = 1.0, addOffset = 0.0;
-      if (!field->scale_factor.isEmpty()) scaleFactor = field->scale_factor;
-      if (!field->add_offset.isEmpty()) addOffset = field->add_offset;
-      field->invertScaleFactorAddOffset(dataOut,scaleFactor, addOffset);
     }
   }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.hpp	(revision 1930)
@@ -37,5 +37,5 @@
     // Read methods
     virtual StdSize getFieldNbRecords_(CField* field);
-    virtual void readFieldData_(CField* field, CArray<double,1>& data);
+    virtual void readFieldData_(CField* field, int record, CArray<double,1>& data);
     virtual void readFieldAttributes_(CField* field, bool readAttributeValues);
     virtual void closeFile_(void);
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_output.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_output.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_output.cpp	(revision 1930)
@@ -58,5 +58,5 @@
         StdString lonName,latName ;
          
-        domain->computeWrittenIndex();
+        //domain->computeWrittenIndex();
         domain->computeWrittenCompressedIndex(comm_file);
 
@@ -319,11 +319,11 @@
                    {
                      case CDomain::type_attr::curvilinear :                       
-                       SuperClassWriter::writeData(writtenLat, latid, isCollective, 0);
-                       SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0);
+                       SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0);
+                       SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0);
                        break;
                      case CDomain::type_attr::rectilinear :
-                       CArray<double,1> lat = writtenLat(Range(fromStart,toEnd,domain->ni)) ;
+                       CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,domain->ni)) ;
                        SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
-                       CArray<double,1> lon = writtenLon(Range(0,domain->ni-1)) ;
+                       CArray<double,1> lon = domain->lonvalue(Range(0,domain->ni-1)) ;
                        SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
                        break;
@@ -332,6 +332,6 @@
                    if (domain->hasBounds)
                    {
-                     SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0);
-                     SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0);
                    }
                  }
@@ -339,5 +339,5 @@
                  if (domain->hasArea)
                  {
-                   SuperClassWriter::writeData(writtenArea, areaId, isCollective, 0);                   
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0);                   
                  }
 
@@ -432,6 +432,9 @@
                      if (domain->hasLonLat)
                      {
-                       SuperClassWriter::writeData(writtenLat, latid, isCollective, 0,&start,&count);
-                       SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0,&start,&count);
+//                       SuperClassWriter::writeData(writtenLat, latid, isCollective, 0,&start,&count);
+//                       SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0,&start,&count);
+                       SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
+                       SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
+
                      }
                      break;
@@ -443,23 +446,14 @@
                        std::vector<StdSize> start(1) ;
                        std::vector<StdSize> count(1) ;
-                       if (domain->isEmpty())
-                       {
-                         start[0]=0 ;
-                         count[0]=0 ;
-                         SuperClassWriter::writeData(writtenLat, latid, isCollective, 0,&start,&count);
-                         SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0,&start,&count);
-                       }
-                       else
-                       { 
-                         start[0]=domain->jbegin;
-                         count[0]=domain->nj;
-                         CArray<double,1> lat = writtenLat(Range(fromStart,toEnd,domain->ni));
-                         SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
-
-                         start[0]=domain->ibegin;
-                         count[0]=domain->ni;
-                         CArray<double,1> lon = writtenLon(Range(0,domain->ni-1));
-                         SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
-                       }
+                       
+                       start[0]=domain->jbegin;
+                       count[0]=domain->nj;
+                       CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,domain->ni));
+                       SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
+
+                       start[0]=domain->ibegin;
+                       count[0]=domain->ni;
+                       CArray<double,1> lon = domain->lonvalue(Range(0,domain->ni-1));
+                       SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
                      }
                      break;
@@ -486,6 +480,8 @@
                    }
                  
-                   SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0, &start, &count);
-                   SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0, &start, &count);
+//                   SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0, &start, &count);
+//                   SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0, &start, &count); // will probably not working for rectilinear
+                   SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0, &start, &count);
                  }
 
@@ -495,18 +491,10 @@
                    std::vector<StdSize> count(2);
 
-                   if (domain->isEmpty())
-                   {
-                     start[0] = 0; start[1] = 0;
-                     count[0] = 0; count[1] = 0;
-                   }
-                   else
-                   {
-                     start[1] = domain->ibegin;
-                     start[0] = domain->jbegin;
-                     count[1] = domain->ni;
-                     count[0] = domain->nj;
-                   }
+                   start[1] = domain->ibegin;
+                   start[0] = domain->jbegin;
+                   count[1] = domain->ni;
+                   count[0] = domain->nj;
                    
-                   SuperClassWriter::writeData(writtenArea, areaId, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0, &start, &count);
                  }
 
@@ -1044,15 +1032,20 @@
                  if (domain->hasLonLat)
                  {
-                   SuperClassWriter::writeData(writtenLat, latid, isCollective, 0);
-                   SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0);
+//                   SuperClassWriter::writeData(writtenLat, latid, isCollective, 0);
+//                   SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0);
+                   SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0);
+                   SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0);
                    if (domain->hasBounds)
                    {
-                     SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0);
-                     SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0);
+//                     SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0);
+//                     SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0);
                    }
                  }
 
                  if (domain->hasArea)
-                   SuperClassWriter::writeData(writtenArea, areaId, isCollective, 0);
+//                   SuperClassWriter::writeData(writtenArea, areaId, isCollective, 0);
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0);
 
                  SuperClassWriter::definition_start();
@@ -1126,15 +1119,15 @@
                  if (domain->hasLonLat)
                  {
-                   SuperClassWriter::writeData(writtenLat, latid, isCollective, 0,&start,&count);
-                   SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0,&start,&count);
+                   SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
+                   SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
                    if (domain->hasBounds)
                    {
-                     SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
-                     SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0,&startBounds,&countBounds);
+                     SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
+                     SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0,&startBounds,&countBounds);
                    }
                  }
 
                  if (domain->hasArea)
-                   SuperClassWriter::writeData(writtenArea, areaId, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0, &start, &count);
 
                  SuperClassWriter::definition_start();
@@ -1166,5 +1159,5 @@
         axis->checkAttributes();
 
-        axis->computeWrittenIndex();
+//        axis->computeWrittenIndex();
         axis->computeWrittenCompressedIndex(comm_file);
        
@@ -1303,5 +1296,5 @@
               {
                 if (!axis->value.isEmpty())
-                  SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
+                  SuperClassWriter::writeData(axis->value, axisid, isCollective, 0);
 
                 if (!axis->bounds.isEmpty())
@@ -1321,5 +1314,5 @@
                     }
                   }
-                  SuperClassWriter::writeData(axis_bounds, axisBoundsId, isCollective, 0);
+                  SuperClassWriter::writeData(axis->bounds, axisBoundsId, isCollective, 0);
                 }
               }
@@ -1342,5 +1335,5 @@
               {
                 if (!axis->value.isEmpty())
-                  SuperClassWriter::writeData(axis_value, axisid, isCollective, 0, &start, &count);
+                  SuperClassWriter::writeData(axis->value, axisid, isCollective, 0, &start, &count);
 
                 if (!axis->bounds.isEmpty())
@@ -1360,5 +1353,5 @@
                     }
                   }
-                  SuperClassWriter::writeData(axis_bounds, axisBoundsId, isCollective, 0, &startBounds, &countBounds);
+                  SuperClassWriter::writeData(axis->bounds, axisBoundsId, isCollective, 0, &startBounds, &countBounds);
                 }
               }
@@ -2475,5 +2468,9 @@
              field->outputCompressedField(dataIn, fieldData);
            else
-             field->outputField(dataIn, fieldData);
+           {
+             //field->outputField(dataIn, fieldData);
+             if (!field->default_value.isEmpty()) field->getGrid()->getWorkflowToFullConnector()->transfer(dataIn, fieldData, (double)field->default_value ) ;
+             else field->getGrid()->getWorkflowToFullConnector()->transfer(dataIn, fieldData ) ;
+           }
 
            if (!field->prec.isEmpty() && field->prec == 2) fieldData = round(fieldData);
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 1930)
@@ -344,54 +344,4 @@
 
 
-   void CAxis::initializeLocalElement(void)
-   {
-      // after checkAttribute index of size n
-      int rank = CContext::getCurrent()->getIntraCommRank() ;
-      
-      CArray<size_t,1> ind(n) ;
-      for (int i=0;i<n;i++) ind(i)=index(i) ;
-
-      localElement_ = new CLocalElement(rank, n_glo, ind) ;
-   }
-
-   void CAxis::addFullView(void)
-   {
-      CArray<int,1> index(n) ;
-      for(int i=0; i<n ; i++) index(i)=i ;
-      localElement_ -> addView(CElementView::FULL, index) ;
-   }
-
-   void CAxis::addWorkflowView(void)
-   {
-     // mask + data are included into data_index
-     int nk=data_index.numElements() ;
-     int nMask=0 ;
-     for(int k=0;k<nk;k++) if (data_index(k)>=0 && data_index(k)<n) nMask++ ;
-     
-     CArray<int,1> index(nMask) ;
-     nMask=0 ;
-     for(int k=0;k<nk;k++) 
-       if (data_index(k)>=0 && data_index(k)<n) 
-       {
-         index(nMask) = data_index(k) ;
-         nMask++ ;
-       }
-     localElement_ -> addView(CElementView::WORKFLOW, index) ;
-   }
-
-   void CAxis::addModelView(void)
-   {
-     // information for model view is stored in data_index
-     localElement_->addView(CElementView::MODEL, data_index) ;
-   }
-
-   void CAxis::computeModelToWorkflowConnector(void)
-   { 
-     CLocalView* srcView=getLocalView(CElementView::MODEL) ;
-     CLocalView* dstView=getLocalView(CElementView::WORKFLOW) ;
-     modelToWorkflowConnector_ = new CLocalConnector(srcView, dstView); 
-     modelToWorkflowConnector_->computeConnector() ;
-   }
-
    /*!
       Check the validity of data, fill in values if any, and apply mask.
@@ -543,4 +493,12 @@
            break;
          case EVENT_ID_DISTRIBUTED_ATTRIBUTES:
+           recvDistributedAttributes_old(event);
+           return true;
+           break;
+         case EVENT_ID_AXIS_DISTRIBUTION:
+           recvAxisDistribution(event);
+           return true;
+           break;
+         case EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE:
            recvDistributedAttributes(event);
            return true;
@@ -671,5 +629,5 @@
          || (index.numElements() != n_glo))
      {
-       sendDistributedAttributes(client, axisId);       
+       sendDistributedAttributes_old(client, axisId);       
      }
      else
@@ -1171,5 +1129,5 @@
     In future, if new attributes are added, they should also be processed in this function
   */
-  void CAxis::sendDistributedAttributes(CContextClient* client, const string& axisId)
+  void CAxis::sendDistributedAttributes_old(CContextClient* client, const string& axisId)
   TRY
   {
@@ -1278,5 +1236,5 @@
     \param [in] event event containing data of these attributes
   */
-  void CAxis::recvDistributedAttributes(CEventServer& event)
+  void CAxis::recvDistributedAttributes_old(CEventServer& event)
   TRY
   {
@@ -1293,5 +1251,5 @@
       buffers.push_back(buffer);
     }
-    get(axisId)->recvDistributedAttributes(ranks, buffers);
+    get(axisId)->recvDistributedAttributes_old(ranks, buffers);
   }
   CATCH
@@ -1302,5 +1260,5 @@
     \param [in] buffers buffer containing data sent from the sender
   */
-  void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers)
+  void CAxis::recvDistributedAttributes_old(vector<int>& ranks, vector<CBufferIn*> buffers)
   TRY
   {
@@ -1585,4 +1543,303 @@
   CATCH_DUMP_ATTR
 
+
+   //////////////////////////////////////////////////////////////////////////////////////
+   //  this part is related to distribution, element definition, views and connectors  //
+   //////////////////////////////////////////////////////////////////////////////////////
+
+   void CAxis::initializeLocalElement(void)
+   {
+      // after checkAttribute index of size n
+      int rank = CContext::getCurrent()->getIntraCommRank() ;
+      
+      CArray<size_t,1> ind(n) ;
+      for (int i=0;i<n;i++) ind(i)=index(i) ;
+
+      localElement_ = new CLocalElement(rank, n_glo, ind) ;
+   }
+
+   void CAxis::addFullView(void)
+   {
+      CArray<int,1> index(n) ;
+      for(int i=0; i<n ; i++) index(i)=i ;
+      localElement_ -> addView(CElementView::FULL, index) ;
+   }
+
+   void CAxis::addWorkflowView(void)
+   {
+     // mask + data are included into data_index
+     int nk=data_index.numElements() ;
+     int nMask=0 ;
+     for(int k=0;k<nk;k++) if (data_index(k)>=0 && data_index(k)<n) nMask++ ;
+     
+     CArray<int,1> index(nMask) ;
+     nMask=0 ;
+     for(int k=0;k<nk;k++) 
+       if (data_index(k)>=0 && data_index(k)<n) 
+       {
+         index(nMask) = data_index(k) ;
+         nMask++ ;
+       }
+     localElement_ -> addView(CElementView::WORKFLOW, index) ;
+   }
+
+   void CAxis::addModelView(void)
+   {
+     // information for model view is stored in data_index
+     localElement_->addView(CElementView::MODEL, data_index) ;
+   }
+
+   void CAxis::computeModelToWorkflowConnector(void)
+   { 
+     CLocalView* srcView=getLocalView(CElementView::MODEL) ;
+     CLocalView* dstView=getLocalView(CElementView::WORKFLOW) ;
+     modelToWorkflowConnector_ = new CLocalConnector(srcView, dstView); 
+     modelToWorkflowConnector_->computeConnector() ;
+   }
+
+
+   void CAxis::computeRemoteElement(CContextClient* client, EDistributionType type)
+  {
+    CContext* context = CContext::getCurrent();
+    map<int, CArray<size_t,1>> globalIndex ;
+
+    if (type==EDistributionType::BANDS) // Bands distribution to send to file server
+    {
+      int nbServer = client->serverSize;
+      int nbClient = client->clientSize ;
+      int rankClient = client->clientRank ;
+      int size = nbServer / nbClient ;
+      int start ;
+      if (nbServer%nbClient > rankClient)
+      {
+       start = (size+1) * rankClient ;
+       size++ ;
+      }
+      else start = size*rankClient + nbServer%nbClient ;
+     
+      for(int i=0; i<size; i++)
+      { 
+        int rank=start+i ; 
+        size_t indSize = n_glo/nbServer ;
+        size_t indStart ;
+        if (n_glo % nbServer > rank)
+        {
+          indStart = (indSize+1) * rank ;
+          indSize++ ;
+        }
+        else indStart = indSize*rank + n_glo%nbServer ;
+       
+        auto& globalInd =  globalIndex[rank] ;
+        globalInd.resize(indSize) ;
+        for(size_t n = 0 ; n<indSize; n++) globalInd(n)=indStart+n ;
+      }
+    }
+    else if (type==EDistributionType::NONE) // domain is not distributed ie all servers get the same local domain
+    {
+      int nbServer = client->serverSize;
+      size_t nglo=n_glo ;
+      CArray<size_t,1> indGlo(nglo) ;
+      for(size_t i=0;i<nglo;i++) indGlo(i) = i ;
+      for (auto& rankServer : client->getRanksServerLeader()) globalIndex[rankServer].reference(indGlo.copy()); ; 
+    }
+    remoteElement_[client] = new CDistributedElement(n_glo, globalIndex) ;
+    remoteElement_[client]->addFullView() ;
+  }
+ 
+  void CAxis::distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex, const string& axisId)
+  {
+    string serverAxisId = axisId.empty() ? this->getId() : axisId ;
+    CContext* context = CContext::getCurrent();
+
+    this->sendAllAttributesToServer(client, serverAxisId)  ;
+
+    CDistributedElement scatteredElement(n_glo,globalIndex) ;
+    scatteredElement.addFullView() ;
+    CScattererConnector scattererConnector(localElement_->getView(CElementView::FULL), scatteredElement.getView(CElementView::FULL), context->getIntraComm()) ;
+    scattererConnector.computeConnector() ;
+    
+    // phase 0
+    // send remote element to construct the full view on server, ie without hole 
+    CEventClient event0(getType(), EVENT_ID_AXIS_DISTRIBUTION);
+    CMessage message0 ;
+    message0<<serverAxisId<<0 ; 
+    remoteElement_[client]->sendToServer(client,event0,message0) ; 
+    
+    // phase 1
+    // send the full view of element to construct the connector which connect distributed data coming from client to the full local view
+    CEventClient event1(getType(), EVENT_ID_AXIS_DISTRIBUTION);
+    CMessage message1 ;
+    message1<<serverAxisId<<1<<localElement_->getView(CElementView::FULL)->getGlobalSize() ; 
+    scattererConnector.transfer(localElement_->getView(CElementView::FULL)->getGlobalIndex(),client,event1,message1) ;
+
+    sendDistributedAttributes(client, scattererConnector, axisId) ;
+  
+    // phase 2 send the mask : data index + mask2D
+    CArray<bool,1> maskIn(localElement_->getView(CElementView::WORKFLOW)->getSize());
+    CArray<bool,1> maskOut ;
+    CLocalConnector workflowToFull(localElement_->getView(CElementView::WORKFLOW), localElement_->getView(CElementView::FULL)) ;
+    workflowToFull.computeConnector() ;
+    maskIn=true ;
+    workflowToFull.transfer(maskIn,maskOut,false) ;
+
+    // phase 3 : prepare grid scatterer connector to send data from client to server
+    map<int,CArray<size_t,1>> workflowGlobalIndex ;
+    map<int,CArray<bool,1>> maskOut2 ; 
+    scattererConnector.transfer(maskOut, maskOut2) ;
+    scatteredElement.addView(CElementView::WORKFLOW, maskOut2) ;
+    scatteredElement.getView(CElementView::WORKFLOW)->getGlobalIndexView(workflowGlobalIndex) ;
+    // create new workflow view for scattered element
+    CDistributedElement clientToServerElement(scatteredElement.getGlobalSize(), workflowGlobalIndex) ;
+    clientToServerElement.addFullView() ;
+    CEventClient event2(getType(), EVENT_ID_AXIS_DISTRIBUTION);
+    CMessage message2 ;
+    message2<<serverAxisId<<2 ; 
+    clientToServerElement.sendToServer(client, event2, message2) ; 
+    clientToServerConnector_[client] = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW),
+                                                              clientToServerElement.getView(CElementView::FULL), context->getIntraComm()) ;
+    clientToServerConnector_[client]->computeConnector() ;
+
+
+    CEventClient event3(getType(), EVENT_ID_AXIS_DISTRIBUTION);
+    CMessage message3 ;
+    message3<<serverAxisId<<3 ; 
+    clientToServerConnector_[client]->transfer(maskIn,client,event3,message3) ; 
+
+
+
+  }
+
+  void CAxis::recvAxisDistribution(CEventServer& event)
+  TRY
+  {
+    string axisId;
+    int phasis ;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> axisId >> phasis ;
+    get(axisId)->receivedAxisDistribution(event, phasis);
+  }
+  CATCH
+
+
+  void CAxis::receivedAxisDistribution(CEventServer& event, int phasis)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    if (phasis==0) // receive the remote element to construct the full view
+    {
+      localElement_ = new  CLocalElement(context->getIntraCommRank(),event) ;
+      localElement_->addFullView() ;
+      // construct the local dimension and indexes
+      auto& globalIndex=localElement_->getGlobalIndex() ;
+      int nk=globalIndex.numElements() ;
+      int minK=n_glo,maxK=-1 ;
+      int nGlo=n_glo ;
+      int indGlo ;
+      for(int k=0;k<nk;k++)
+      {
+        indGlo=globalIndex(k) ;
+        if (indGlo<minK) minK=indGlo ;
+        if (indGlo>maxK) maxK=indGlo ;
+      }  
+      if (maxK>=minK) { begin=minK ; n=maxK-minK+1 ; }
+      else {begin=0; n=0 ;}
+
+    }
+    else if (phasis==1) // receive the sent view from client to construct the full distributed full view on server
+    {
+      CContext* context = CContext::getCurrent();
+      CDistributedElement* elementFrom = new  CDistributedElement(event) ;
+      elementFrom->addFullView() ;
+      gathererConnector_ = new CGathererConnector(elementFrom->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ;
+      gathererConnector_->computeConnector() ; 
+    }
+    else if (phasis==2)
+    {
+      delete gathererConnector_ ;
+      elementFrom_ = new  CDistributedElement(event) ;
+      elementFrom_->addFullView() ;
+      gathererConnector_ =  new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ;
+      gathererConnector_ -> computeConnector() ;
+    }
+    else if (phasis==3)
+    {
+      CArray<bool,1> localMask ;
+      gathererConnector_->transfer(event,localMask,false) ;
+      localElement_->addView(CElementView::WORKFLOW, localMask) ;
+      mask.reference(localMask.copy()) ;
+ 
+      serverFromClientConnector_ = new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)) ;
+      serverFromClientConnector_->computeConnector() ;
+    }
+  }
+  CATCH
+
+  void CAxis::sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector, const string& axisId)
+  {
+    string serverAxisId = axisId.empty() ? this->getId() : axisId ;
+    CContext* context = CContext::getCurrent();
+
+    if (hasValue)
+    {
+      { // send level value
+        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+        CMessage message ;
+        message<<serverAxisId<<string("value") ; 
+        scattererConnector.transfer(value, client, event,message) ;
+      }
+    }
+
+    if (hasBounds)
+    {
+      { // send bounds level value
+        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+        CMessage message ;
+        message<<serverAxisId<<string("bounds") ; 
+        scattererConnector.transfer(2, bounds, client, event,message) ;
+      }
+    }
+
+    if (hasLabel)
+    {
+      { // send label
+        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+        CMessage message ;
+        message<<serverAxisId<<string("label") ;
+        // something to do ? => convert string label into char ?
+        //clientToServerConnector_[client]->transfer(2, bounds, client, event,message) ;
+      }
+    }
+  }
+
+  void CAxis::recvDistributedAttributes(CEventServer& event)
+  TRY
+  {
+    string axisId;
+    string type ;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> axisId >> type ;
+    get(axisId)->recvDistributedAttributes(event, type);
+  }
+  CATCH
+
+  void CAxis::recvDistributedAttributes(CEventServer& event, const string& type)
+  TRY
+  {
+    if (type=="value") 
+    {
+      gathererConnector_->transfer(event, value, 0.); 
+    }
+    else if (type=="bounds")
+    {
+      CArray<double,1> value ;
+      gathererConnector_->transfer(event, 2, value, 0.); 
+      bounds.resize(2,n) ;
+      bounds=CArray<double,2>(bounds.dataFirst(),shape(2,n),neverDeleteData) ; 
+    }
+    else if (type=="label")
+    {
+       
+    }
+  }
+  CATCH
+
   DEFINE_REF_FUNC(Axis,axis)
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 1930)
@@ -18,4 +18,8 @@
 #include "element.hpp"
 #include "local_connector.hpp"
+#include "scatterer_connector.hpp"
+#include "gatherer_connector.hpp"
+#include "distribution_type.hpp"
+
 
 namespace xios {
@@ -50,5 +54,7 @@
            EVENT_ID_NON_DISTRIBUTED_VALUE,
            EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES,
-           EVENT_ID_DISTRIBUTED_ATTRIBUTES
+           EVENT_ID_DISTRIBUTED_ATTRIBUTES,
+           EVENT_ID_AXIS_DISTRIBUTION,
+           EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE
          } ;
 
@@ -164,11 +170,11 @@
 
          void sendNonDistributedAttributes(CContextClient* client, const string& axisId="");
-         void sendDistributedAttributes(CContextClient* client, const string& axisId="");
+         void sendDistributedAttributes_old(CContextClient* client, const string& axisId="");
 
          static void recvNonDistributedAttributes(CEventServer& event);
-         static void recvDistributedAttributes(CEventServer& event);
+         static void recvDistributedAttributes_old(CEventServer& event);
          static void recvDistributionAttribute(CEventServer& event);
          void recvNonDistributedAttributes(int rank, CBufferIn& buffer);
-         void recvDistributedAttributes(vector<int>& rank, vector<CBufferIn*> buffers);
+         void recvDistributedAttributes_old(vector<int>& rank, vector<CBufferIn*> buffers);
          void recvDistributionAttribute(CBufferIn& buffer);
 
@@ -225,4 +231,7 @@
 
 
+       //////////////////////////////////////////////////////////////////////////////////////
+       //  this part is related to distribution, element definition, views and connectors  //
+       //////////////////////////////////////////////////////////////////////////////////////
          
         private:
@@ -242,4 +251,30 @@
         public:
          CLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_ ;}
+       
+       public:
+         void computeRemoteElement(CContextClient* client, EDistributionType) ;
+         void distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex, const string& axisId="") ;
+
+         static void recvAxisDistribution(CEventServer& event) ;
+         void receivedAxisDistribution(CEventServer& event, int phasis) ;
+
+         void sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector, const string& axisId) ;
+         static void recvDistributedAttributes(CEventServer& event) ;
+         void recvDistributedAttributes(CEventServer& event, const string& type) ;
+       private:
+         map<CContextClient*, CDistributedElement*> remoteElement_ ;
+       public: 
+         CDistributedElement* getRemoteElement(CContextClient* client) {return remoteElement_[client] ;}
+       private:
+         map<CContextClient*, CScattererConnector*> clientToServerConnector_ ;
+       public: 
+         CScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;}
+       private:
+         CGathererConnector*  gathererConnector_ ;
+         CGathererConnector* serverFromClientConnector_ ;
+         CDistributedElement* elementFrom_ ;
+       public:
+        CGathererConnector* getServerFromClientConnector(void) { return serverFromClientConnector_ ;}
+
 
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp	(revision 1930)
@@ -1745,8 +1745,9 @@
       this->completeLonLatClient();
       this->initializeLocalElement() ;
-      this->addFullView() ;
-      this->addWorkflowView() ;
-      this->addModelView() ;
+      this->addFullView() ; // probably do not automatically add View, but only if requested
+      this->addWorkflowView() ; // probably do not automatically add View, but only if requested
+      this->addModelView() ; // probably do not automatically add View, but only if requested
       // testing ?
+     /*
       CLocalView* local = localElement_->getView(CElementView::WORKFLOW) ;
       CLocalView* model = localElement_->getView(CElementView::MODEL) ;
@@ -1769,5 +1770,5 @@
       gridTest1.transfer(data_i_index,out1,-111) ;
       gridTest2.transfer(out1, out2,-111) ;
-      
+    */  
       this->checkAttributes_done_ = true;
    }
@@ -1820,8 +1821,17 @@
      for(int k=0;k<dataSize;k++)
      {
-        i=data_i_index(k)+data_ibegin ; // bad
-        j=data_j_index(k)+data_jbegin ; // bad
-        if (i>=0 && i<ni && j>=0 && j<nj) index(k)=i+j*ni ;
-        else index(k)=-1 ;
+        if (data_dim==2)
+        {
+          i=data_i_index(k)+data_ibegin ; // bad
+          j=data_j_index(k)+data_jbegin ; // bad
+          if (i>=0 && i<ni && j>=0 && j<nj) index(k)=i+j*ni ;
+          else index(k)=-1 ;
+        }
+        else if (data_dim==1)
+        {
+          i=data_i_index(k)+data_ibegin ; // bad
+          if (i>=0 && i<ni*nj) index(k)=i ;
+          else index(k)=-1 ;
+        }
      }
      localElement_->addView(CElementView::MODEL, index) ;
@@ -2194,11 +2204,9 @@
     this->sendAllAttributesToServer(client)  ;
     this->sendDistributionAttributes(client);   
-    this->sendIndex(client);       
-    this->sendLonLat(client);
-    this->sendArea(client);    
-    this->sendDataIndex(client);
-
-    // test new connector functionnality
-    this->sendDomainDistribution(client) ;
+    //this->sendIndex(client);       
+    //this->sendLonLat(client);
+    //this->sendArea(client);    
+    //this->sendDataIndex(client);
+
   }
 
@@ -2232,4 +2240,288 @@
   }
 
+
+  void CDomain::computeRemoteElement(CContextClient* client, EDistributionType type)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    map<int, CArray<size_t,1>> globalIndex ;
+
+    if (type==EDistributionType::BANDS) // Bands distribution to send to file server
+    {
+      int nbServer = client->serverSize;
+      std::vector<int> nGlobDomain(2);
+      nGlobDomain[0] = this->ni_glo;
+      nGlobDomain[1] = this->nj_glo;
+
+      // to be changed in future, need to rewrite more simply domain distribution
+      CServerDistributionDescription serverDescription(nGlobDomain, nbServer);
+      int distributedPosition ;
+      if (isUnstructed_) distributedPosition = 0 ;
+      else distributedPosition = 1 ;
+      
+      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
+      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
+      vector<unordered_map<size_t,vector<int>>> indexServerOnElement ;
+      CArray<int,1> axisDomainOrder(1) ; axisDomainOrder(0)=2 ;
+      auto zeroIndex=serverDescription.computeServerGlobalByElement(indexServerOnElement, context->getIntraCommRank(), context->getIntraCommSize(),
+                                                                  axisDomainOrder,distributedPosition) ;
+      // distribution is very bad => to redo
+      // convert indexServerOnElement => map<int,CArray<size_t,1>> - need to be changed later
+      map<int, vector<size_t>> vectGlobalIndex ;
+      for(auto& indexRanks : indexServerOnElement[0])
+      {
+        size_t index=indexRanks.first ;
+        auto& ranks=indexRanks.second ;
+        for(int rank : ranks) vectGlobalIndex[rank].push_back(index) ;
+      }
+      for(auto& vect : vectGlobalIndex ) globalIndex.emplace(vect.first, CArray<size_t,1>(vect.second.data(), shape(vect.second.size()),duplicateData)) ; 
+    }
+    else if (type==EDistributionType::NONE) // domain is not distributed ie all servers get the same local domain
+    {
+      int nbServer = client->serverSize;
+      int nglo=ni_glo*nj_glo ;
+      CArray<size_t,1> indGlo ;
+      for(size_t i=0;i<nglo;i++) indGlo(i) = i ;
+      for (auto& rankServer : client->getRanksServerLeader()) globalIndex[rankServer] = indGlo ; 
+    }
+    remoteElement_[client] = new CDistributedElement(ni_glo*nj_glo, globalIndex) ;
+    remoteElement_[client]->addFullView() ;
+  }
+  CATCH
+
+ 
+
+  void CDomain::distributeToServer(CContextClient* client, map<int, CArray<size_t,1>>& globalIndex, const string& domainId)
+  TRY
+  {
+    string serverDomainId = domainId.empty() ? this->getId() : domainId ;
+    CContext* context = CContext::getCurrent();
+
+    this->sendAllAttributesToServer(client, serverDomainId)  ;
+
+    CDistributedElement scatteredElement(ni_glo*nj_glo, globalIndex) ;
+    scatteredElement.addFullView() ;
+    CScattererConnector scattererConnector(localElement_->getView(CElementView::FULL), scatteredElement.getView(CElementView::FULL), context->getIntraComm()) ;
+    scattererConnector.computeConnector() ;
+
+    // phase 0
+    // send remote element to construct the full view on server, ie without hole 
+    CEventClient event0(getType(), EVENT_ID_DOMAIN_DISTRIBUTION);
+    CMessage message0 ;
+    message0<<serverDomainId<<0 ; 
+    remoteElement_[client]->sendToServer(client,event0,message0) ; 
+    
+    // phase 1
+    // send the full view of element to construct the connector which connect distributed data coming from client to the full local view
+    CEventClient event1(getType(), EVENT_ID_DOMAIN_DISTRIBUTION);
+    CMessage message1 ;
+    message1<<serverDomainId<<1<<localElement_->getView(CElementView::FULL)->getGlobalSize() ; 
+    scattererConnector.transfer(localElement_->getView(CElementView::FULL)->getGlobalIndex(),client,event1,message1) ;
+    
+    sendDistributedAttributes(client, scattererConnector, domainId) ;
+
+  
+    // phase 2 send the mask : data index + mask2D
+    CArray<bool,1> maskIn(localElement_->getView(CElementView::WORKFLOW)->getSize());
+    CArray<bool,1> maskOut ;
+    CLocalConnector workflowToFull(localElement_->getView(CElementView::WORKFLOW), localElement_->getView(CElementView::FULL)) ;
+    workflowToFull.computeConnector() ;
+    maskIn=true ;
+    workflowToFull.transfer(maskIn,maskOut,false) ;
+
+
+    // phase 3 : prepare grid scatterer connector to send data from client to server
+    map<int,CArray<size_t,1>> workflowGlobalIndex ;
+    map<int,CArray<bool,1>> maskOut2 ; 
+    scattererConnector.transfer(maskOut, maskOut2, false) ;
+    scatteredElement.addView(CElementView::WORKFLOW, maskOut2) ;
+    scatteredElement.getView(CElementView::WORKFLOW)->getGlobalIndexView(workflowGlobalIndex) ;
+    // create new workflow view for scattered element
+    CDistributedElement clientToServerElement(scatteredElement.getGlobalSize(), workflowGlobalIndex) ;
+    clientToServerElement.addFullView() ;
+    CEventClient event2(getType(), EVENT_ID_DOMAIN_DISTRIBUTION);
+    CMessage message2 ;
+    message2<<serverDomainId<<2 ; 
+    clientToServerElement.sendToServer(client, event2, message2) ; 
+    clientToServerConnector_[client] = new CScattererConnector(localElement_->getView(CElementView::WORKFLOW),
+                                                              clientToServerElement.getView(CElementView::FULL), context->getIntraComm()) ;
+    clientToServerConnector_[client]->computeConnector() ;
+
+
+    CEventClient event3(getType(), EVENT_ID_DOMAIN_DISTRIBUTION);
+    CMessage message3 ;
+    message3<<serverDomainId<<3 ; 
+    clientToServerConnector_[client]->transfer(maskIn,client,event3,message3) ; 
+    
+  }
+  CATCH
+ 
+  void CDomain::recvDomainDistribution(CEventServer& event)
+  TRY
+  {
+    string domainId;
+    int phasis ;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> domainId >> phasis ;
+    get(domainId)->receivedDomainDistribution(event, phasis);
+  }
+  CATCH
+
+  void CDomain::receivedDomainDistribution(CEventServer& event, int phasis)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    if (phasis==0) // receive the remote element to construct the full view
+    {
+      localElement_ = new  CLocalElement(context->getIntraCommRank(),event) ;
+      localElement_->addFullView() ;
+      // construct the local dimension and indexes
+      auto& globalIndex=localElement_->getGlobalIndex() ;
+      int nij=globalIndex.numElements() ;
+      int minI=ni_glo,maxI=-1,minJ=nj_glo,maxJ=-1 ;
+      int i,j ;
+      int niGlo=ni_glo, njGlo=njGlo ;
+      for(int ij=0;ij<nij;ij++)
+      {
+        j=globalIndex(ij)/niGlo ;
+        i=globalIndex(ij)%niGlo ;
+        if (i<minI) minI=i ;
+        if (i>maxI) maxI=i ;
+        if (j<minJ) minJ=j ;
+        if (j>maxJ) maxJ=j ;
+      }  
+      if (maxI>=minI) { ibegin=minI ; ni=maxI-minI+1 ; }
+      else {ibegin=0; ni=0 ;}
+      if (maxJ>=minJ) { jbegin=minJ ; nj=maxJ-minJ+1 ; }
+      else {jbegin=0; nj=0 ;}
+
+    }
+    else if (phasis==1) // receive the sent view from client to construct the full distributed full view on server
+    {
+      CContext* context = CContext::getCurrent();
+      CDistributedElement* elementFrom = new  CDistributedElement(event) ;
+      elementFrom->addFullView() ;
+      gathererConnector_ = new CGathererConnector(elementFrom->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ;
+      gathererConnector_->computeConnector() ; 
+    }
+    else if (phasis==2)
+    {
+      delete gathererConnector_ ;
+      elementFrom_ = new  CDistributedElement(event) ;
+      elementFrom_->addFullView() ;
+      gathererConnector_ =  new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ;
+      gathererConnector_ -> computeConnector() ;
+    }
+    else if (phasis==3)
+    {
+      CArray<bool,1> localMask ;
+      gathererConnector_->transfer(event,localMask,false) ;
+      localElement_->addView(CElementView::WORKFLOW, localMask) ;
+      mask_1d.reference(localMask.copy()) ;
+ 
+      serverFromClientConnector_ = new CGathererConnector(elementFrom_->getView(CElementView::FULL), localElement_->getView(CElementView::WORKFLOW)) ;
+      serverFromClientConnector_->computeConnector() ;
+    }
+  }
+  CATCH
+
+
+  void CDomain::sendDistributedAttributes(CContextClient* client, CScattererConnector& scattererConnector,  const string& domainId)
+  {
+    string serverDomainId = domainId.empty() ? this->getId() : domainId ;
+    CContext* context = CContext::getCurrent();
+
+    if (hasLonLat)
+    {
+      { // send longitude
+        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+        CMessage message ;
+        message<<serverDomainId<<string("lon") ; 
+        scattererConnector.transfer(lonvalue, client, event,message) ;
+      }
+      
+      { // send latitude
+        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+        CMessage message ;
+        message<<serverDomainId<<string("lat") ; 
+        scattererConnector.transfer(latvalue, client, event, message) ;
+      }
+    }
+
+    if (hasBounds)
+    { 
+      { // send longitude boudaries
+        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+        CMessage message ;
+        message<<serverDomainId<<string("boundslon") ; 
+        scattererConnector.transfer(nvertex, bounds_lonvalue, client, event, message ) ;
+      }
+
+      { // send latitude boudaries
+        CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+        CMessage message ;
+        message<<serverDomainId<<string("boundslat") ; 
+        scattererConnector.transfer(nvertex, bounds_latvalue, client, event, message ) ;
+      }
+    }
+
+    if (hasArea)
+    {  // send area
+      CEventClient event(getType(), EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE);
+      CMessage message ;
+      message<<serverDomainId<<string("area") ; 
+      scattererConnector.transfer(areavalue, client, event,message) ;
+    }
+  }
+
+  void CDomain::recvDistributedAttributes(CEventServer& event)
+  TRY
+  {
+    string domainId;
+    string type ;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> domainId >> type ;
+    get(domainId)->recvDistributedAttributes(event, type);
+  }
+  CATCH
+
+  void CDomain::recvDistributedAttributes(CEventServer& event, const string& type)
+  TRY
+  {
+    if (type=="lon") 
+    {
+      CArray<double,1> value ;
+      gathererConnector_->transfer(event, value, 0.); 
+      lonvalue_2d.resize(ni,nj) ;
+      lonvalue_2d=CArray<double,2>(value.dataFirst(),shape(ni,nj),neverDeleteData) ; 
+    }
+    else if (type=="lat")
+    {
+      CArray<double,1> value ;
+      gathererConnector_->transfer(event, value, 0.); 
+      latvalue_2d.resize(ni,nj) ;
+      latvalue_2d=CArray<double,2>(value.dataFirst(),shape(ni,nj),neverDeleteData) ; 
+    }
+    else if (type=="boundslon")
+    {
+      CArray<double,1> value ;
+      gathererConnector_->transfer(event, nvertex, value, 0.); 
+      bounds_lon_2d.resize(nvertex,ni,nj) ;
+      bounds_lon_2d=CArray<double,3>(value.dataFirst(),shape(nvertex,ni,nj),neverDeleteData) ; 
+    }
+    else if (type=="boundslat")
+    {
+      CArray<double,1> value ;
+      gathererConnector_->transfer(event, nvertex, value, 0.); 
+      bounds_lat_2d.resize(nvertex,ni,nj) ;
+      bounds_lat_2d=CArray<double,3>(value.dataFirst(),shape(nvertex,ni,nj),neverDeleteData) ; 
+    }
+    else if (type=="area") 
+    {
+      CArray<double,1> value ;
+      gathererConnector_->transfer(event, value, 0.); 
+      area.resize(ni,nj) ;
+      area=CArray<double,2>(value.dataFirst(),shape(ni,nj),neverDeleteData) ; 
+    }
+  }
+  CATCH
 
   void CDomain::sendDomainDistribution(CContextClient* client, const string& domainId)
@@ -2308,45 +2600,5 @@
   
 
-  void CDomain::recvDomainDistribution(CEventServer& event)
-  TRY
-  {
-    string domainId;
-    int phasis ;
-    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> domainId >> phasis ;
-    get(domainId)->receivedDomainDistribution(event, phasis);
-  }
-  CATCH
-
-  void CDomain::receivedDomainDistribution(CEventServer& event, int phasis)
-  TRY
-  {
-    CContext* context = CContext::getCurrent();
-    if (phasis==0)
-    {
-      localElement_ = new  CLocalElement(context->getIntraCommRank(),event) ;
-      localElement_->addFullView() ;
-    }
-    else if (phasis==1)
-    {
-      CContext* context = CContext::getCurrent();
-      CDistributedElement* elementFrom = new  CDistributedElement(event) ;
-      elementFrom->addFullView() ;
-      gathererConnector_ = new CGathererConnector(elementFrom->getView(CElementView::FULL), localElement_->getView(CElementView::FULL)) ;
-      gathererConnector_->computeConnector() ; 
-    }
-    else if (phasis==2)
-    {
-      CArray<size_t,1> globalIndex ;
-      //gathererConnector_->transfer(event,globalIndex) ;
-      CGridGathererConnector gridGathererConnector({gathererConnector_}) ;
-      gridGathererConnector.transfer(event, globalIndex) ;
-    }
-    else if (phasis==3)
-    {
-
-    }
-  }
-  CATCH
-
+ 
   
 
@@ -2707,4 +2959,8 @@
           return true;
           break;
+        case EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE:
+          recvDistributedAttributes(event);
+          return true;
+          break;  
         default:
           ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp	(revision 1930)
@@ -20,5 +20,8 @@
 #include "element.hpp"
 #include "local_connector.hpp"
+#include "scatterer_connector.hpp"
 #include "gatherer_connector.hpp"
+#include "distribution_type.hpp"
+
 
 namespace xios {
@@ -54,5 +57,5 @@
            EVENT_ID_AREA,
            EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT,
-           EVENT_ID_DOMAIN_DISTRIBUTION
+           EVENT_ID_DOMAIN_DISTRIBUTION, EVENT_ID_SEND_DISTRIBUTED_ATTRIBUTE
          } ;
 
@@ -220,8 +223,4 @@
        private:
 
-         static void recvDomainDistribution(CEventServer& event) ;
-         void receivedDomainDistribution(CEventServer& event, int phasis) ;
-        
-
          void sendDomainDistribution(CContextClient* client, const string& domainId="") ; //for testing
          void sendAttributes(); // ym obsolete -> to be removed
@@ -310,5 +309,7 @@
          static bool _dummyTransformationMapList;
 
- 
+       //////////////////////////////////////////////////////////////////////////////////////
+       //  this part is related to distribution, element definition, views and connectors  //
+       //////////////////////////////////////////////////////////////////////////////////////
        private:
          CLocalElement* localElement_ = nullptr ;
@@ -327,9 +328,34 @@
          CLocalConnector* modelToWorkflowConnector_ ;
          void computeModelToWorkflowConnector(void)  ;
+       public:
+         CLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_ ;}
+
+       public:
+         void computeRemoteElement(CContextClient* client, EDistributionType) ;
+         void distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex, const string& domainId="") ;
+
+         static void recvDomainDistribution(CEventServer& event) ;
+         void receivedDomainDistribution(CEventServer& event, int phasis) ;
+
+         void sendDistributedAttributes(CContextClient* client, CScattererConnector& scaterrerConnector, const string& domainId) ;
+         static void recvDistributedAttributes(CEventServer& event) ;
+         void recvDistributedAttributes(CEventServer& event, const string& type) ;
+       private:
+         map<CContextClient*, CDistributedElement*> remoteElement_ ;
+       public: 
+         CDistributedElement* getRemoteElement(CContextClient* client) {return remoteElement_[client] ;}
+       private:
+         map<CContextClient*, CScattererConnector*> clientToServerConnector_ ;
+       public: 
+         CScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;}
+       private:
          CGathererConnector*  gathererConnector_ ;
-
-       public:
-         CLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_ ;}
-         
+         CGathererConnector* serverFromClientConnector_ ;
+         CDistributedElement* elementFrom_ ;
+       public:
+        CGathererConnector* getServerFromClientConnector(void) { return serverFromClientConnector_ ;}
+
+         
+
          DECLARE_REF_FUNC(Domain,domain)
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1930)
@@ -26,4 +26,6 @@
 #include "file_server_reader_filter.hpp"
 #include "server_to_client_filter.hpp"
+#include "server_from_client_source_filter.hpp"
+#include "file_reader_source_filter.hpp"
 #include "tracer.hpp"
 
@@ -148,4 +150,5 @@
   CATCH
 
+/* obsolete old interface
   void CField::sendUpdateData(Time timeStamp, const CArray<double,1>& data, CContextClient* client)
   TRY
@@ -204,5 +207,20 @@
   }
   CATCH_DUMP_ATTR
-
+*/
+
+  void CField::sendUpdateData(Time timeStamp, const CArray<double,1>& data, CContextClient* client)
+  TRY
+  {
+    CTimer::get("Field : send data").resume();
+    CEventClient event(getType(), EVENT_ID_UPDATE_DATA);
+    CMessage message ;
+
+    message<<getId() << timeStamp ;
+    this->getGrid()->getClientToServerConnector(client)->transfer(data, client, event, message) ;
+    CTimer::get("Field : send data").suspend();
+  }
+  CATCH_DUMP_ATTR
+
+  /* old version obsolete
   void CField::recvUpdateData(CEventServer& event)
   TRY
@@ -224,14 +242,67 @@
   }
   CATCH
-
-
-  void  CField::recvUpdateData(std::map<int,CBufferIn*>& rankBuffers)
-  TRY
-  {
-    if (hasCouplerIn()) recvUpdateDataFromCoupler(rankBuffers) ;
-    else recvUpdateDataFromClient(rankBuffers) ;
+*/
+
+  void CField::recvUpdateData(CEventServer& event)
+  TRY
+  {
+    string fieldId;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> fieldId  ;
+    get(fieldId)->receiveUpdateData(event);
   }
   CATCH
 
+  void  CField::receiveUpdateData(CEventServer& event)
+  TRY
+  {
+    if (hasCouplerIn()) clientFromClientSourceFilter_->streamData(event) ;
+    else serverFromClientSourceFilter_->streamData(event) ;
+  }
+  CATCH
+/*
+  void  CField::recvUpdateDataFromClient(CEventServer& event)
+  TRY
+  {
+    Time timeStamp ;
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> timeStamp  ;
+
+    CArray<double,1> recvData ;
+    getGrid()->getServerFromClientConnector()->transfer(event,recvData) ;
+    this->setData(recvData);
+  }
+  CATCH
+*/
+
+/*  
+  void CField::recvUpdateDataFromCoupler(CEventServer& event)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    Time timeStamp ;
+    if (wasDataAlreadyReceivedFromServer)
+    {  
+      lastDataReceivedFromServer = lastDataReceivedFromServer + freq_op;
+    }
+    else
+    {
+      // unlikely to input from file server where data are received at ts=0
+      // for coupling, it would be after the first freq_op, because for now we don't have
+      // restart mecanism to send the value at ts=0. It must be changed in future
+      lastDataReceivedFromServer = context->getCalendar()->getInitDate();
+      wasDataAlreadyReceivedFromServer = true;
+    }
+
+    CArray<double,1> recvData ;
+    getGrid()->getServerFromClientConnector()->transfer(event,recvData) ;
+    clientSourceFilter->streamData(lastDataReceivedFromServer, recvData);
+
+  }
+  CATCH_DUMP_ATTR
+*/
+
+
+
+
+  /* old interface to be removed.... */
   void  CField::recvUpdateDataFromClient(std::map<int,CBufferIn*>& rankBuffers)
   TRY
@@ -330,5 +401,5 @@
     const CDate writeDate = last_Write_srv + freq_write_srv;
     last_Write_srv = writeDate;
-    grid_->computeWrittenIndex();
+    // grid_->computeWrittenIndex(); -> obselete function need to be removed
     /*
     recvDataSrv.resize(data.numElements()) ;
@@ -424,8 +495,8 @@
     StdString fieldId;
     *buffer >> fieldId;
-    get(fieldId)->recvReadDataRequest(event.getContextServer());
+    get(fieldId)->recvReadDataRequest();
   }
   CATCH
-
+  
   /*!
     Receive data request sent from client and process it
@@ -434,4 +505,12 @@
     In the future, this should (only) be done by the last level servers.
   */
+  void CField::recvReadDataRequest(void)
+  TRY
+  {
+    fileReaderSourceFilter_->streamData() ;
+  }
+  CATCH_DUMP_ATTR  
+
+/* old interface -> to remove
   void CField::recvReadDataRequest(CContextServer* server)
   TRY
@@ -446,5 +525,5 @@
   }
   CATCH_DUMP_ATTR
-
+*/
 
   void CField::sendUpdateDataServerToClient(bool isEOF, const CArray<double,1>& data, CContextClient* client)
@@ -509,4 +588,6 @@
     \return State of field can be read from a file
   */
+  // obsolete to remove
+  /*
   CField::EReadField CField::readField(CArray<double,1>& data)
   TRY
@@ -561,4 +642,5 @@
   }
   CATCH_DUMP_ATTR
+  */
 
   /*
@@ -572,20 +654,11 @@
   {
     string fieldId;
-    vector<int> ranks;
-    vector<CBufferIn*> buffers;
-
-    list<CEventServer::SSubEvent>::iterator it;
-    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
-    {
-      ranks.push_back(it->rank);
-      CBufferIn* buffer = it->buffer;
-      *buffer >> fieldId;
-      buffers.push_back(buffer);
-    }
-    get(fieldId)->recvReadDataReady(ranks, buffers);
+    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> fieldId  ;
+    get(fieldId)->recvReadDataReady(event);
   }
   CATCH
 
-  
+
+  /* old interface to be removed ..*/
   void CField::recvUpdateDataFromCoupler(std::map<int,CBufferIn*>& rankBuffers)
   TRY
@@ -622,4 +695,6 @@
   }
   CATCH_DUMP_ATTR
+ 
+
   /*!
     Receive read data from server
@@ -627,4 +702,5 @@
     \param [in] buffers buffers containing read data
   */
+  // old interface to remove 
   void CField::recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers)
   TRY
@@ -667,4 +743,15 @@
   CATCH_DUMP_ATTR
 
+
+
+  void CField::receiveReadDataReady(CEventServer& event)
+  TRY
+  {
+    clientFromServerSourceFilter_->streamData(event) ;    
+  }
+  CATCH_DUMP_ATTR
+
+
+
   void CField::checkForLateDataFromCoupler(void)
   TRY
@@ -677,18 +764,13 @@
     traceOff() ;
     timer.suspend();
-      
-    bool isDataLate;
+    
+    bool isDataLate;  
     do
     {
-      if (wasDataAlreadyReceivedFromServer) isDataLate = lastDataReceivedFromServer + freq_offset + freq_op <= currentDate ;
-      else isDataLate = context->getCalendar()->getInitDate()+freq_offset <= currentDate ;
-
+      isDataLate=clientFromClientSourceFilter_->isDataLate() ;
       if (isDataLate)
       {
         timer.resume();
-//ym          context->checkBuffersAndListen();
-//ym            context->eventLoop();
         context->globalEventLoop();
-
         timer.suspend();
       }
@@ -709,8 +791,6 @@
   {
     CContext* context = CContext::getCurrent();
-    const CDate& currentDate = context->getCalendar()->getCurrentDate();
-
     // Check if data previously requested has been received as expected
-    if (wasDataRequestedFromServer && !isEOF)
+    if (wasDataRequestedFromServer && !clientFromServerSourceFilter_->isEOF())
     {
       CTimer timer("CField::checkForLateDataFromServer");
@@ -722,7 +802,5 @@
       do
       {
-        const CDate nextDataDue = wasDataAlreadyReceivedFromServer ? (lastDataReceivedFromServer + fileIn_->output_freq) : context->getCalendar()->getInitDate();
-        isDataLate = (nextDataDue <= currentDate);
-
+        isDataLate=clientFromServerSourceFilter_->isDataLate();
         if (isDataLate)
         {
@@ -744,5 +822,5 @@
       if (isDataLate)
         ERROR("void CField::checkForLateDataFromServer(void)",
-              << "Late data at timestep = " << currentDate);
+              << "Late data at timestep = " << context->getCalendar()->getCurrentDate());
     }
   }
@@ -755,10 +833,10 @@
     {
       checkForLateDataFromServer() ;
-      serverSourceFilter->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()) ;
+      clientFromServerSourceFilter_->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()) ;
     } 
     else if (hasCouplerIn())
     {
       checkForLateDataFromCoupler() ;
-      clientSourceFilter->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()) ;
+      clientFromClientSourceFilter_->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate()) ;
     }
   }
@@ -769,5 +847,5 @@
   TRY
   {
-    mustAutoTrigger = serverSourceFilter ? serverSourceFilter->mustAutoTrigger() : false;
+    mustAutoTrigger = clientFromServerSourceFilter_ ? clientFromServerSourceFilter_->mustAutoTrigger() : false;
   }
   CATCH_DUMP_ATTR
@@ -777,5 +855,5 @@
   {
     if (mustAutoTrigger)
-      serverSourceFilter->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate());
+      clientFromServerSourceFilter_->trigger(CContext::getCurrent()->getCalendar()->getCurrentDate());
   }
   CATCH_DUMP_ATTR
@@ -860,8 +938,7 @@
   TRY
   {
-    if (clientSourceFilter)
-      return atCurrentTimestep ? clientSourceFilter->isDataExpected(CContext::getCurrent()->getCalendar()->getCurrentDate()) : true;
-    else if (storeFilter)
-      return true;
+    if (modelToClientSourceFilter_) 
+      return atCurrentTimestep ? modelToClientSourceFilter_->isDataExpected(CContext::getCurrent()->getCalendar()->getCurrentDate()) : true;
+    else if (clientToModelStoreFilter_)  return true;
     else if (instantDataFilter)
       ERROR("bool CField::isActive(bool atCurrentTimestep)",
@@ -1412,6 +1489,6 @@
 
     if (check_if_active.isEmpty()) check_if_active = false; 
-    clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, false, true, NoneDu, false, detectMissingValues, defaultValue));
-    clientSourceFilter -> connectOutput(inputFilter,0) ;
+    modelToClientSourceFilter_ = std::shared_ptr<CModelToClientSourceFilter>(new CModelToClientSourceFilter(gc, grid_, detectMissingValues, defaultValue));
+    modelToClientSourceFilter_ -> connectOutput(inputFilter,0) ;
   } 
  
@@ -1421,6 +1498,6 @@
   void CField::connectToClientInput(CGarbageCollector& gc)
   {
-    clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc,  grid_, false, false));
-    clientSourceFilter -> connectOutput(inputFilter,0) ;
+    serverFromClientSourceFilter_ = std::shared_ptr<CServerFromClientSourceFilter>(new CServerFromClientSourceFilter(gc,  grid_));
+    serverFromClientSourceFilter_ -> connectOutput(inputFilter,0) ;
   } 
 
@@ -1450,4 +1527,6 @@
     if (freq_op.isEmpty()) freq_op.setValue(TimeStep);
     if (freq_offset.isEmpty()) freq_offset.setValue(freq_op.getValue() - TimeStep);
+    
+    /* old 
 
     freq_operation_srv = freq_op ;
@@ -1458,6 +1537,12 @@
     clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, false, false, freq_offset, true)) ;
     clientSourceFilter -> connectOutput(inputFilter,0) ;
+
+    */
+    // new
+
+    clientFromClientSourceFilter_ = std::shared_ptr<CClientFromClientSourceFilter>(new CClientFromClientSourceFilter(gc, this)) ;
+    clientFromClientSourceFilter_ -> connectOutput(inputFilter,0) ;
+   
   } 
-
 
   /*!
@@ -1469,5 +1554,5 @@
     instantDataFilter->connectOutput(fileServerWriterFilter, 0);
   } 
-  
+
   /*!
    * Connect field to a file reader filter to read data from file (on server side).
@@ -1475,7 +1560,8 @@
   void CField::connectToFileReader(CGarbageCollector& gc)
   {
-    fileServerReaderFilter_ = std::shared_ptr<CFileServerReaderFilter>(new CFileServerReaderFilter(gc, this));
-    fileServerReaderFilter_->connectOutput(inputFilter, 0);
-  } 
+    fileReaderSourceFilter_ = std::shared_ptr<CFileReaderSourceFilter>(new CFileReaderSourceFilter(gc, this));
+    instantDataFilter->connectOutput(inputFilter, 0);
+  }
+
 
   /*!
@@ -1484,9 +1570,6 @@
   void CField::connectToModelOutput(CGarbageCollector& gc)
   {
-    const bool detectMissingValues = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true);
-    const double defaultValue  = detectMissingValues ? default_value : (!default_value.isEmpty() ? default_value : 0.0);
-
-    storeFilter = std::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid_, detectMissingValues, defaultValue));
-    instantDataFilter->connectOutput(storeFilter, 0);
+    clientToModelStoreFilter_ = std::shared_ptr<CClientToModelStoreFilter>(new CClientToModelStoreFilter(gc, this));
+    instantDataFilter->connectOutput(clientToModelStoreFilter_, 0);
   }
 
@@ -1565,5 +1648,5 @@
 
       // If the field data is to be read by the client or/and written to a file
-      if (enableOutput && !storeFilter && !fileWriterFilter)
+      if (enableOutput && !clientToModelStoreFilter_ && !fileWriterFilter)
       {
         if (getRelFile() && (getRelFile()->mode.isEmpty() || getRelFile()->mode == CFile::mode_attr::write))
@@ -1580,5 +1663,5 @@
 
       // If the field data is to be read by the client or/and written to a file
-      if (enableOutput && !storeFilter && !fileWriterFilter)
+      if (enableOutput && !clientToModelStoreFilter_ && !fileWriterFilter)
       {
         if (getRelFile() && (getRelFile()->mode.isEmpty() || getRelFile()->mode == CFile::mode_attr::write))
@@ -1633,11 +1716,10 @@
 
       // If the field data is to be read by the client or/and written to a file
-      if (enableOutput && !storeFilter && !fileWriterFilter)
+      if (enableOutput && !clientToModelStoreFilter_ && !fileWriterFilter)
       {
         if (!read_access.isEmpty() && read_access)
         {
-          storeFilter = std::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid_,
-                                                                          detectMissingValues, defaultValue));
-          instantDataFilter->connectOutput(storeFilter, 0);
+          clientToModelStoreFilter_ = std::shared_ptr<CClientToModelStoreFilter>(new CClientToModelStoreFilter(gc, this));
+          instantDataFilter->connectOutput(clientToModelStoreFilter_, 0);
         }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp	(revision 1930)
@@ -19,8 +19,14 @@
 #include "pass_through_filter.hpp"
 #include "temporal_filter.hpp"
-
-
-
-namespace xios {
+#include "model_to_client_source_filter.hpp"
+#include "client_from_client_source_filter.hpp"
+#include "client_from_server_source_filter.hpp"
+#include "client_to_model_store_filter.hpp"
+
+
+
+
+namespace xios 
+{
 
    /// ////////////////////// DÃ©clarations ////////////////////// ///
@@ -40,9 +46,10 @@
    class COutputPin;
    class CSourceFilter;
-   class CStoreFilter;
    class CFileWriterFilter;
    class CFileServerWriterFilter;
-   class CFileServerReaderFilter;
+   class CFileReaderSourceFilter;
    class CServerToClientFilter;
+   class CModelToClientSourceFilter;
+   class CServerFromClientSourceFilter;
    ///--------------------------------------------------------------
 
@@ -66,4 +73,5 @@
          typedef CFieldAttributes SuperClassAttribute;
 
+      public :   
          enum EReadField
          {
@@ -188,7 +196,9 @@
 
         static void recvUpdateData(CEventServer& event);
-        void recvUpdateData(std::map<int,CBufferIn*>& rankBuffers);
-        void recvUpdateDataFromClient(std::map<int,CBufferIn*>& rankBuffers);
-        void recvUpdateDataFromCoupler(std::map<int,CBufferIn*>& rankBuffers);
+        void receiveUpdateData(CEventServer& event);  
+        
+        void recvUpdateData(std::map<int,CBufferIn*>& rankBuffers); // old interface to be removed
+        void recvUpdateDataFromClient(std::map<int,CBufferIn*>& rankBuffers); // old interface to be removed
+        void recvUpdateDataFromCoupler(std::map<int,CBufferIn*>& rankBuffers); // old interface to be removed
         
         void writeField(const CArray<double,1>& data);
@@ -196,9 +206,10 @@
         bool sendReadDataRequestIfNeeded(void);
         static void recvReadDataRequest(CEventServer& event);
-        void recvReadDataRequest(CContextServer* server);
+        void recvReadDataRequest(void);
         EReadField readField(CArray<double,1>& data);
         static void recvReadDataReady(CEventServer& event);
-        void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers);
-        void recvDataFromCoupler(vector<int> ranks, vector<CBufferIn*> buffers) ;
+        void receiveReadDataReady(CEventServer& event);
+        void recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers); // old interface to remove
+        void recvDataFromCoupler(vector<int> ranks, vector<CBufferIn*> buffers) ; // old interface to remove
         void checkForLateDataFromServer(void);
         void checkForLateDataFromCoupler(void) ;
@@ -393,11 +404,26 @@
 
          //! The source filter for data provided by the client
-         std::shared_ptr<CSourceFilter> clientSourceFilter;
-         
+         std::shared_ptr<CSourceFilter> clientSourceFilter; // obsolete to remove
+ 
+         //! The source filter for data provided by the model to enter the client workflow
+         std::shared_ptr<CModelToClientSourceFilter> modelToClientSourceFilter_;
+
+         //! The source filter for data provided by the model to enter the client workflow
+         std::shared_ptr<CClientToModelStoreFilter> clientToModelStoreFilter_;
+
+         //! The source filter for data provided by the client that send data to server workflow
+         std::shared_ptr<CServerFromClientSourceFilter> serverFromClientSourceFilter_;
+
+         //! The source filter for data provided by an other to enter the current client workflow (coupling mode)
+         std::shared_ptr<CClientFromClientSourceFilter> clientFromClientSourceFilter_;
+
+         //! The source filter for data provided by server to enter the current client workflow (reading mode)
+         std::shared_ptr<CClientFromServerSourceFilter> clientFromServerSourceFilter_;
+         
+         //! The source filter for data read from file on server side 
+         std::shared_ptr<CFileReaderSourceFilter> fileReaderSourceFilter_;
+
          //! The source filter for data provided by the server
-         std::shared_ptr<CSourceFilter> serverSourceFilter;
-         
-         //! The terminal filter which stores the instant data
-         std::shared_ptr<CStoreFilter> storeFilter;
+         std::shared_ptr<CSourceFilter> serverSourceFilter; // obsolete to remove
         
          //! The terminal filter which writes the data to file
@@ -407,8 +433,5 @@
          std::shared_ptr<CFileServerWriterFilter> fileServerWriterFilter;
 
-         //! The source filter which read data from file
-         std::shared_ptr<CFileServerReaderFilter> fileServerReaderFilter_;
-
-         //! The terminal filter which send data from file server to client
+         //! The terminal filter which send data from server to client
          std::shared_ptr<CServerToClientFilter> serverToClientFilter_;
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field_impl.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field_impl.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field_impl.hpp	(revision 1930)
@@ -19,8 +19,8 @@
   TRY
   {
-    if (clientSourceFilter)
+    if (modelToClientSourceFilter_)
     {
       if (check_if_active.isEmpty() || (!check_if_active.isEmpty() && (!check_if_active) || isActive(true)))
-        clientSourceFilter->streamData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data);
+        modelToClientSourceFilter_->streamData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data);
     }
     else if (instantDataFilter)
@@ -34,7 +34,7 @@
   TRY
   {
-    if (storeFilter)
+    if (clientToModelStoreFilter_)
     {
-      CDataPacket::StatusCode status = storeFilter->getData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data);
+      CDataPacket::StatusCode status = clientToModelStoreFilter_->getData(CContext::getCurrent()->getCalendar()->getCurrentDate(), _data);
 
       if (status == CDataPacket::END_OF_STREAM)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1930)
@@ -19,4 +19,9 @@
 #include "grid_generate.hpp"
 #include "server.hpp"
+#include "distribution_type.hpp"
+#include "grid_remote_connector.hpp"
+#include "grid_elements.hpp"
+#include "grid_local_view.hpp"
+
 
 namespace xios {
@@ -79,4 +84,494 @@
    StdString CGrid::GetDefName(void) { return CGrid::GetName(); }
    ENodeType CGrid::GetType(void)    { return eGrid; }
+
+
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  /////////              MEMBER FUNCTION RELATED TO GRID CONSTRUCTION by ELEMNTS AND MANAGEMENT                      /////
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+   CGrid* CGrid::createGrid(CDomain* domain)
+   TRY
+   {
+     std::vector<CDomain*> vecDom(1, domain);
+     std::vector<CAxis*> vecAxis;
+     return createGrid(vecDom, vecAxis);
+   }
+   CATCH
+
+   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
+   TRY
+  {
+      std::vector<CDomain*> vecDom(1, domain);
+      std::vector<CAxis*> vecAxis(1, axis);
+
+      return createGrid(vecDom, vecAxis);
+   }
+   CATCH
+
+   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+                            const CArray<int,1>& axisDomainOrder)
+   TRY
+   {
+     std::vector<CScalar*> vecScalar;
+     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder);
+   }
+   CATCH
+
+   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
+   TRY
+   {
+     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder);
+   }
+   CATCH
+
+   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
+   TRY
+   {
+      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
+        ERROR("CGrid* CGrid::createGrid(...)",
+              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
+              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
+
+      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id);
+      grid->setDomainList(domains);
+      grid->setAxisList(axis);
+      grid->setScalarList(scalars);
+
+      // By default, domains are always the first elements of a grid
+      if (0 == axisDomainOrder.numElements())
+      {
+        int size = domains.size() + axis.size() + scalars.size();
+        int nb = 0;
+        grid->axis_domain_order.resize(size);
+        for (int i = 0; i < size; ++i)
+        {
+          if (i < domains.size()) {
+            grid->axis_domain_order(i) = 2;
+
+          }
+          else if ((scalars.size() < (size-nb)) < size) {
+            grid->axis_domain_order(i) = 1;
+          }
+          else
+            grid->axis_domain_order(i) = 0;
+          ++nb;
+        }
+      }
+      else
+      {
+        grid->axis_domain_order.resize(axisDomainOrder.numElements());
+        grid->axis_domain_order = axisDomainOrder;
+      }
+
+ //     grid->solveElementsRefInheritance(true);
+
+      return grid;
+   }
+   CATCH
+
+   //----------------------------------------------------------------
+
+   //! Change virtual field group to a new one
+   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
+   TRY
+   {
+      this->vDomainGroup_ = newVDomainGroup;
+   }
+   CATCH_DUMP_ATTR
+
+   //! Change virtual variable group to new one
+   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
+   TRY
+   {
+      this->vAxisGroup_ = newVAxisGroup;
+   }
+   CATCH_DUMP_ATTR
+
+   //! Change virtual variable group to new one
+   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup)
+   TRY
+   {
+      this->vScalarGroup_ = newVScalarGroup;
+   }
+   CATCH_DUMP_ATTR
+
+   //----------------------------------------------------------------
+
+   CDomainGroup* CGrid::getVirtualDomainGroup() const
+   TRY
+   {
+     return this->vDomainGroup_;
+   }
+   CATCH
+
+   CAxisGroup* CGrid::getVirtualAxisGroup() const
+   TRY
+   {
+     return this->vAxisGroup_;
+   }
+   CATCH
+
+   CScalarGroup* CGrid::getVirtualScalarGroup() const
+   TRY
+   {
+     return this->vScalarGroup_;
+   }
+   CATCH
+
+  ///---------------------------------------------------------------
+
+   CDomain* CGrid::addDomain(const std::string& id)
+   TRY
+   {
+     order_.push_back(2);
+     axis_domain_order.resize(order_.size());
+     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
+     return vDomainGroup_->createChild(id);
+   }
+   CATCH_DUMP_ATTR
+
+   CAxis* CGrid::addAxis(const std::string& id)
+   TRY
+   {
+     order_.push_back(1);
+     axis_domain_order.resize(order_.size());
+     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
+     return vAxisGroup_->createChild(id);
+   }
+   CATCH_DUMP_ATTR
+
+   CScalar* CGrid::addScalar(const std::string& id)
+   TRY
+   {
+     order_.push_back(0);
+     axis_domain_order.resize(order_.size());
+     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
+     return vScalarGroup_->createChild(id);
+   }
+   CATCH_DUMP_ATTR
+
+
+
+
+  /*!
+  \brief Get the list of domain pointers
+  \return list of domain pointers
+  */
+  std::vector<CDomain*> CGrid::getDomains()
+  TRY
+  {
+    std::vector<CDomain*> domList;
+    if (!domList_.empty())
+    {
+      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
+    }
+    return domList;
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Get the list of  axis pointers
+  \return list of axis pointers
+  */
+  std::vector<CAxis*> CGrid::getAxis()
+  TRY
+  {
+    std::vector<CAxis*> aList;
+    if (!axisList_.empty())
+      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
+
+    return aList;
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Get the list of  axis pointers
+  \return list of axis pointers
+  */
+  std::vector<CScalar*> CGrid::getScalars()
+  TRY
+  {
+    std::vector<CScalar*> sList;
+    if (!scalarList_.empty())
+      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i]));
+
+    return sList;
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Get domain pointer with index
+  \return domain pointer
+  */
+  CDomain* CGrid::getDomain(int domainIndex)
+  TRY
+  {
+    std::vector<CDomain*> domainListP = this->getDomains();
+    if (domainListP.empty())
+    {
+      ERROR("CGrid::getDomain(int domainIndex)",
+            << "No domain associated to this grid. " << std::endl
+            << "Grid id = " << this->getId());
+    }
+
+    if (domainIndex >= domainListP.size() || (domainIndex < 0))
+      ERROR("CGrid::getDomain(int domainIndex)",
+            << "Domain with the index doesn't exist " << std::endl
+            << "Grid id = " << this->getId() << std::endl
+            << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl);
+
+    return domainListP[domainIndex];
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Get the axis pointer with index
+  \return axis pointer
+  */
+  CAxis* CGrid::getAxis(int axisIndex)
+  TRY
+  {
+    std::vector<CAxis*> axisListP = this->getAxis();
+    if (axisListP.empty())
+    {
+      ERROR("CGrid::getDomain(int axisIndex)",
+            << "No axis associated to this grid. " << std::endl
+            << "Grid id = " << this->getId());
+    }
+
+    if (axisIndex >= axisListP.size() || (axisIndex < 0))
+      ERROR("CGrid::getDomain(int axisIndex)",
+            << "Domain with the index doesn't exist " << std::endl
+            << "Grid id = " << this->getId() << std::endl
+            << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl);
+
+    return axisListP[axisIndex];
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Get the a scalar pointer
+  \return scalar pointer
+  */
+  CScalar* CGrid::getScalar(int scalarIndex)
+  TRY
+  {
+    std::vector<CScalar*> scalarListP = this->getScalars();
+    if (scalarListP.empty())
+    {
+      ERROR("CGrid::getScalar(int scalarIndex)",
+            << "No scalar associated to this grid. " << std::endl
+            << "Grid id = " << this->getId());
+    }
+
+    if (scalarIndex >= scalarListP.size() || (scalarIndex < 0))
+      ERROR("CGrid::getScalar(int scalarIndex)",
+            << "Scalar with the index doesn't exist " << std::endl
+            << "Grid id = " << this->getId() << std::endl
+            << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl);
+
+    return scalarListP[scalarIndex];
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Set domain(s) of a grid from a list
+  \param[in] domains list of domains
+  */
+  void CGrid::setDomainList(const std::vector<CDomain*> domains)
+  TRY
+  {
+    if (isDomListSet) return;
+    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
+    if (!domains.empty() && domList.empty())
+    {
+      for (int i = 0; i < domains.size(); ++i)
+        this->getVirtualDomainGroup()->addChild(domains[i]);
+      domList = this->getVirtualDomainGroup()->getAllChildren();
+    }
+
+    if (!domList.empty())
+    {
+      int sizeDom = domList.size();
+      domList_.resize(sizeDom);
+      for (int i = 0; i < sizeDom; ++i)
+      {
+        domList_[i] = domList[i]->getId();
+      }
+      isDomListSet = true;
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Set axis(s) of a grid from a list
+  \param[in] axis list of axis
+  */
+  void CGrid::setAxisList(const std::vector<CAxis*> axis)
+  TRY
+  {
+    if (isAxisListSet) return;
+    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
+    if (!axis.empty() && aList.empty())
+    {
+      for (int i = 0; i < axis.size(); ++i)
+        this->getVirtualAxisGroup()->addChild(axis[i]);
+      aList = this->getVirtualAxisGroup()->getAllChildren();
+    }
+
+    if (!aList.empty())
+    {
+      int sizeAxis = aList.size();
+      axisList_.resize(sizeAxis);
+      for (int i = 0; i < sizeAxis; ++i)
+      {
+        axisList_[i] = aList[i]->getId();
+      }
+      isAxisListSet = true;
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Set scalar(s) of a grid from a list
+  \param[in] scalars list of scalars
+  */
+  void CGrid::setScalarList(const std::vector<CScalar*> scalars)
+  TRY
+  {
+    if (isScalarListSet) return;
+    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
+    if (!scalars.empty() && sList.empty())
+    {
+      for (int i = 0; i < scalars.size(); ++i)
+        this->getVirtualScalarGroup()->addChild(scalars[i]);
+      sList = this->getVirtualScalarGroup()->getAllChildren();
+    }
+
+    if (!sList.empty())
+    {
+      int sizeScalar = sList.size();
+      scalarList_.resize(sizeScalar);
+      for (int i = 0; i < sizeScalar; ++i)
+      {
+        scalarList_[i] = sList[i]->getId();
+      }
+      isScalarListSet = true;
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+  \brief Get list of id of domains
+  \return id list of domains
+  */
+  std::vector<StdString> CGrid::getDomainList()
+  TRY
+  {
+    setDomainList();
+    return domList_;
+  }
+  CATCH
+
+  /*!
+  \brief Get list of id of axis
+  \return id list of axis
+  */
+  std::vector<StdString> CGrid::getAxisList()
+  TRY
+  {
+    setAxisList();
+    return axisList_;
+  }
+  CATCH
+
+  /*!
+  \brief Get list of id of scalar
+  \return id list of scalar
+  */
+  std::vector<StdString> CGrid::getScalarList()
+  TRY
+  {
+    setScalarList();
+    return scalarList_;
+  }
+  CATCH
+
+
+  void CGrid::computeElements(void)
+  {
+    const auto& domains = getDomains() ;
+    const auto& axis = getAxis() ;
+    const auto& scalars = getScalars() ;
+    int idxDomain = 0, idxAxis=0 , idxScalar=0 ; 
+ 
+    for(auto type : order_)
+    {
+      if      (type == 0) { elements_.push_back({scalars[idxScalar], TYPE_SCALAR, scalars[idxScalar], nullptr, nullptr } ) ; idxScalar++;}
+      else if (type == 1) { elements_.push_back({axis[idxAxis], TYPE_AXIS, nullptr, axis[idxAxis], nullptr}) ; idxAxis++;}
+      else if (type == 2) { elements_.push_back({domains[idxDomain], TYPE_DOMAIN, nullptr, nullptr, domains[idxDomain] }) ; idxDomain++;}        
+    }
+    elementsComputed_ = true ;
+  }
+  
+  
+ /*!
+    Parse a grid, for now, it contains only domain, axis and scalar
+  */
+  void CGrid::parse(xml::CXMLNode& node)
+  TRY
+  {
+    SuperClass::parse(node);
+
+    if (node.goToChildElement())
+    {
+      StdString domainName("domain");
+      StdString axisName("axis");
+      StdString scalarName("scalar");
+      do
+      {
+        if (node.getElementName() == domainName) {
+          order_.push_back(2);
+          this->getVirtualDomainGroup()->parseChild(node);
+        }
+        if (node.getElementName() == axisName) {
+          order_.push_back(1);
+          this->getVirtualAxisGroup()->parseChild(node);
+        }
+        if (node.getElementName() == scalarName) {
+          order_.push_back(0);
+          this->getVirtualScalarGroup()->parseChild(node);
+        }
+      } while (node.goToNextElement());
+      node.goToParentElement();
+    }
+
+    if (!order_.empty())
+    {
+      int sizeOrd = order_.size();
+      axis_domain_order.resize(sizeOrd);
+      for (int i = 0; i < sizeOrd; ++i)
+      {
+        axis_domain_order(i) = order_[i];
+      }
+    }
+
+    setDomainList();
+    setAxisList();
+    setScalarList();
+   }
+   CATCH_DUMP_ATTR
+
+
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 
 
@@ -1169,86 +1664,5 @@
 //----------------------------------------------------------------
 
-   CGrid* CGrid::createGrid(CDomain* domain)
-   TRY
-   {
-      std::vector<CDomain*> vecDom(1, domain);
-      std::vector<CAxis*> vecAxis;
-
-      return createGrid(vecDom, vecAxis);
-   }
-   CATCH
-
-   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
-   TRY
-  {
-      std::vector<CDomain*> vecDom(1, domain);
-      std::vector<CAxis*> vecAxis(1, axis);
-
-      return createGrid(vecDom, vecAxis);
-   }
-   CATCH
-
-   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                            const CArray<int,1>& axisDomainOrder)
-   TRY
-   {
-     std::vector<CScalar*> vecScalar;
-     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder);
-   }
-   CATCH
-
-   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
-   TRY
-   {
-     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder);
-   }
-   CATCH
-
-   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
-   TRY
-   {
-      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
-        ERROR("CGrid* CGrid::createGrid(...)",
-              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
-              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
-
-      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id);
-      grid->setDomainList(domains);
-      grid->setAxisList(axis);
-      grid->setScalarList(scalars);
-
-      // By default, domains are always the first elements of a grid
-      if (0 == axisDomainOrder.numElements())
-      {
-        int size = domains.size() + axis.size() + scalars.size();
-        int nb = 0;
-        grid->axis_domain_order.resize(size);
-        for (int i = 0; i < size; ++i)
-        {
-          if (i < domains.size()) {
-            grid->axis_domain_order(i) = 2;
-
-          }
-          else if ((scalars.size() < (size-nb)) < size) {
-            grid->axis_domain_order(i) = 1;
-          }
-          else
-            grid->axis_domain_order(i) = 0;
-          ++nb;
-        }
-      }
-      else
-      {
-        grid->axis_domain_order.resize(axisDomainOrder.numElements());
-        grid->axis_domain_order = axisDomainOrder;
-      }
-
- //     grid->solveElementsRefInheritance(true);
-
-      return grid;
-   }
-   CATCH
+
 
    CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc)
@@ -1353,26 +1767,4 @@
    CATCH
 
-   //----------------------------------------------------------------
-
-   CDomainGroup* CGrid::getVirtualDomainGroup() const
-   TRY
-   {
-     return this->vDomainGroup_;
-   }
-   CATCH
-
-   CAxisGroup* CGrid::getVirtualAxisGroup() const
-   TRY
-   {
-     return this->vAxisGroup_;
-   }
-   CATCH
-
-   CScalarGroup* CGrid::getVirtualScalarGroup() const
-   TRY
-   {
-     return this->vScalarGroup_;
-   }
-   CATCH
 
    //----------------------------------------------------------------
@@ -2086,5 +2478,5 @@
   TRY
   {
-     return (0 != getWrittenDataSize());
+     return (0 != getGridLocalElements()->getView(CElementView::FULL)->getSize());
   }
   CATCH_DUMP_ATTR
@@ -2099,5 +2491,5 @@
   TRY
   {
-    return getServerDistribution()->getGridSize();
+    return getGridLocalElements()->getView(CElementView::FULL)->getSize() ;
   }
   CATCH
@@ -2205,60 +2597,5 @@
   CATCH
 
-   ///---------------------------------------------------------------
-
-   CDomain* CGrid::addDomain(const std::string& id)
-   TRY
-   {
-     order_.push_back(2);
-     axis_domain_order.resize(order_.size());
-     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
-     return vDomainGroup_->createChild(id);
-   }
-   CATCH_DUMP_ATTR
-
-   CAxis* CGrid::addAxis(const std::string& id)
-   TRY
-   {
-     order_.push_back(1);
-     axis_domain_order.resize(order_.size());
-     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
-     return vAxisGroup_->createChild(id);
-   }
-   CATCH_DUMP_ATTR
-
-   CScalar* CGrid::addScalar(const std::string& id)
-   TRY
-   {
-     order_.push_back(0);
-     axis_domain_order.resize(order_.size());
-     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
-     return vScalarGroup_->createChild(id);
-   }
-   CATCH_DUMP_ATTR
-
-   //! Change virtual field group to a new one
-   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
-   TRY
-   {
-      this->vDomainGroup_ = newVDomainGroup;
-   }
-   CATCH_DUMP_ATTR
-
-   //! Change virtual variable group to new one
-   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
-   TRY
-   {
-      this->vAxisGroup_ = newVAxisGroup;
-   }
-   CATCH_DUMP_ATTR
-
-   //! Change virtual variable group to new one
-   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup)
-   TRY
-   {
-      this->vScalarGroup_ = newVScalarGroup;
-   }
-   CATCH_DUMP_ATTR
-
+ 
 
   void CGrid::sendGridToFileServer(CContextClient* client)
@@ -2271,10 +2608,89 @@
     gridPtr->sendCreateChild(this->getId(),client);
     this->sendAllAttributesToServer(client);
-    if (isScalarGrid())  sendIndexScalarGrid(client);
-    else  sendIndex(client);
-    this->sendAllDomains(client);
-    this->sendAllAxis(client);
-    this->sendAllScalars(client);
-  }
+    //if (isScalarGrid())  sendIndexScalarGrid(client);
+    //else  sendIndex(client);
+    //this->sendAllDomains(client);
+    //this->sendAllAxis(client);
+    //this->sendAllScalars(client);
+
+    distributeGridToFileServer(client) ;
+  }
+
+
+  void CGrid::distributeGridToFileServer(CContextClient* client)
+  {
+    CContext* context = CContext::getCurrent();
+    // simple Distribution for now 
+    // distribute over the fisrt element except if it is a scalar
+    auto& elements = getElements() ;
+    int posDistributed = 0 ;
+    for(auto& element : elements)
+    {
+      if (element.type==TYPE_DOMAIN) break ;
+      else if (element.type==TYPE_AXIS) break ;
+      else if (element.type==TYPE_SCALAR) posDistributed++ ;
+    }
+    
+    vector<CLocalView*> localViews ;
+    vector<CDistributedView*> remoteViews ;
+
+    for(int i=0 ; i<elements.size() ; i++)
+    {
+      if (elements[i].type==TYPE_DOMAIN) 
+      { 
+         CDomain* domain = (CDomain*) elements[i].ptr ;
+         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
+         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ;
+         localViews.push_back(domain->getLocalView(CElementView::FULL)) ;
+      }
+      else if (elements[i].type==TYPE_AXIS)
+      {
+        CAxis* axis = (CAxis*) elements[i].ptr ;
+        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
+        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ;
+        localViews.push_back(axis->getLocalView(CElementView::FULL)) ;
+      }
+      else if (elements[i].type==TYPE_SCALAR)
+      {
+        CScalar* scalar = (CScalar*) elements[i].ptr ;
+        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
+        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ;
+        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ;
+      }
+    }
+    CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm()) ;
+    gridRemoteConnector.computeConnector() ;
+    
+    vector<CScattererConnector*> clientToServerConnectors ;
+    for(int i=0 ; i<elements.size() ; i++)
+    {
+      if (elements[i].type==TYPE_DOMAIN) 
+      { 
+         CDomain* domain = (CDomain*) elements[i].ptr ;
+         sendAddDomain(domain->getId(),client) ;
+         domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ;
+         clientToServerConnectors.push_back(domain->getClientToServerConnector(client)) ;
+      }
+      else if (elements[i].type==TYPE_AXIS)
+      {
+        CAxis* axis = (CAxis*) elements[i].ptr ;
+        sendAddAxis(axis->getId(),client) ;
+        axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ;
+        clientToServerConnectors.push_back(axis->getClientToServerConnector(client)) ;
+      }
+      else if (elements[i].type==TYPE_SCALAR)
+      {
+        CScalar* scalar = (CScalar*) elements[i].ptr ;
+        sendAddScalar(scalar->getId(),client) ;
+        scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ;
+        clientToServerConnectors.push_back(scalar->getClientToServerConnector(client)) ;
+      }
+    }
+    
+    // compute the grid clientToServerConnector to send flux from client to servers
+    clientToServerConnector_[client] = new CGridScattererConnector(clientToServerConnectors) ;
+
+  }
+
 
   void CGrid::sendGridToCouplerOut(CContextClient* client, const string& fieldId)
@@ -2282,18 +2698,75 @@
     if (sendGridToCouplerOut_done_.count(client)!=0) return ;
     else sendGridToCouplerOut_done_.insert(client) ;
-    string gridId="_grid_of_"+fieldId ;
-    this->sendAllAttributesToServer(client, gridId);
+ 
+    CContext* context = CContext::getCurrent();
+    // simple Distribution for now 
+    // distribute over the fisrt element except if it is a scalar
+    auto& elements = getElements() ;
+    int posDistributed = 0 ;
+    for(auto& element : elements)
+    {
+      if (element.type==TYPE_DOMAIN) break ;
+      else if (element.type==TYPE_AXIS) break ;
+      else if (element.type==TYPE_SCALAR) posDistributed++ ;
+    }
     
-    if (isScalarGrid())  sendIndexScalarGrid(client, gridId);
-    else sendIndex(client, gridId);
-
-    const auto& domVect = getDomains() ;
-    for (int pos=0; pos<domVect.size();pos++) domVect[pos]->sendDomainToCouplerOut(client, fieldId, pos);
-
-    const auto& axisVect=getAxis() ;
-    for (int pos=0; pos<axisVect.size();pos++) axisVect[pos]->sendAxisToCouplerOut(client, getGlobalDimension(), getAxisPositionInGrid()[pos], fieldId, pos);
-
-    const auto& scalVect=getScalars() ;
-    for (int pos=0; pos<scalVect.size();pos++) scalVect[pos]->sendScalarToCouplerOut(client, fieldId, pos);
+    vector<CLocalView*> localViews ;
+    vector<CDistributedView*> remoteViews ;
+
+    for(int i=0 ; i<elements.size() ; i++)
+    {
+      if (elements[i].type==TYPE_DOMAIN) 
+      { 
+         CDomain* domain = (CDomain*) elements[i].ptr ;
+         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
+         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ;
+         localViews.push_back(domain->getLocalView(CElementView::FULL)) ;
+      }
+      else if (elements[i].type==TYPE_AXIS)
+      {
+        CAxis* axis = (CAxis*) elements[i].ptr ;
+        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
+        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ;
+        localViews.push_back(axis->getLocalView(CElementView::FULL)) ;
+      }
+      else if (elements[i].type==TYPE_SCALAR)
+      {
+        CScalar* scalar = (CScalar*) elements[i].ptr ;
+        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
+        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ;
+        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ;
+      }
+    }
+    CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm()) ;
+    gridRemoteConnector.computeConnector() ;
+    
+    vector<CScattererConnector*> clientToClientConnectors ;
+    for(int i=0 ; i<elements.size() ; i++)
+    {
+      if (elements[i].type==TYPE_DOMAIN) 
+      { 
+         CDomain* domain = (CDomain*) elements[i].ptr ;
+         sendAddDomain(domain->getId(),client) ;
+         domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ;
+         clientToClientConnectors.push_back(domain->getClientToServerConnector(client)) ;
+      }
+      else if (elements[i].type==TYPE_AXIS)
+      {
+        CAxis* axis = (CAxis*) elements[i].ptr ;
+        sendAddAxis(axis->getId(),client) ;
+        axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ;
+        clientToClientConnectors.push_back(axis->getClientToServerConnector(client)) ;
+      }
+      else if (elements[i].type==TYPE_SCALAR)
+      {
+        CScalar* scalar = (CScalar*) elements[i].ptr ;
+        sendAddScalar(scalar->getId(),client) ;
+        scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ;
+        clientToClientConnectors.push_back(scalar->getClientToServerConnector(client)) ;
+      }
+    }
+    
+    // compute the grid clientToServerConnector to send flux from client to servers
+    clientToClientConnector_[client] = new CGridScattererConnector(clientToClientConnectors) ;
   }
 
@@ -2710,247 +3183,5 @@
   CATCH_DUMP_ATTR
 
-  /*!
-  \brief Get the list of domain pointers
-  \return list of domain pointers
-  */
-  std::vector<CDomain*> CGrid::getDomains()
-  TRY
-  {
-    std::vector<CDomain*> domList;
-    if (!domList_.empty())
-    {
-      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
-    }
-    return domList;
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Get the list of  axis pointers
-  \return list of axis pointers
-  */
-  std::vector<CAxis*> CGrid::getAxis()
-  TRY
-  {
-    std::vector<CAxis*> aList;
-    if (!axisList_.empty())
-      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
-
-    return aList;
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Get the list of  axis pointers
-  \return list of axis pointers
-  */
-  std::vector<CScalar*> CGrid::getScalars()
-  TRY
-  {
-    std::vector<CScalar*> sList;
-    if (!scalarList_.empty())
-      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i]));
-
-    return sList;
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Get domain pointer with index
-  \return domain pointer
-  */
-  CDomain* CGrid::getDomain(int domainIndex)
-  TRY
-  {
-    std::vector<CDomain*> domainListP = this->getDomains();
-    if (domainListP.empty())
-    {
-      ERROR("CGrid::getDomain(int domainIndex)",
-            << "No domain associated to this grid. " << std::endl
-            << "Grid id = " << this->getId());
-    }
-
-    if (domainIndex >= domainListP.size() || (domainIndex < 0))
-      ERROR("CGrid::getDomain(int domainIndex)",
-            << "Domain with the index doesn't exist " << std::endl
-            << "Grid id = " << this->getId() << std::endl
-            << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl);
-
-    return domainListP[domainIndex];
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Get the axis pointer with index
-  \return axis pointer
-  */
-  CAxis* CGrid::getAxis(int axisIndex)
-  TRY
-  {
-    std::vector<CAxis*> axisListP = this->getAxis();
-    if (axisListP.empty())
-    {
-      ERROR("CGrid::getDomain(int axisIndex)",
-            << "No axis associated to this grid. " << std::endl
-            << "Grid id = " << this->getId());
-    }
-
-    if (axisIndex >= axisListP.size() || (axisIndex < 0))
-      ERROR("CGrid::getDomain(int axisIndex)",
-            << "Domain with the index doesn't exist " << std::endl
-            << "Grid id = " << this->getId() << std::endl
-            << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl);
-
-    return axisListP[axisIndex];
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Get the a scalar pointer
-  \return scalar pointer
-  */
-  CScalar* CGrid::getScalar(int scalarIndex)
-  TRY
-  {
-    std::vector<CScalar*> scalarListP = this->getScalars();
-    if (scalarListP.empty())
-    {
-      ERROR("CGrid::getScalar(int scalarIndex)",
-            << "No scalar associated to this grid. " << std::endl
-            << "Grid id = " << this->getId());
-    }
-
-    if (scalarIndex >= scalarListP.size() || (scalarIndex < 0))
-      ERROR("CGrid::getScalar(int scalarIndex)",
-            << "Scalar with the index doesn't exist " << std::endl
-            << "Grid id = " << this->getId() << std::endl
-            << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl);
-
-    return scalarListP[scalarIndex];
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Set domain(s) of a grid from a list
-  \param[in] domains list of domains
-  */
-  void CGrid::setDomainList(const std::vector<CDomain*> domains)
-  TRY
-  {
-    if (isDomListSet) return;
-    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
-    if (!domains.empty() && domList.empty())
-    {
-      for (int i = 0; i < domains.size(); ++i)
-        this->getVirtualDomainGroup()->addChild(domains[i]);
-      domList = this->getVirtualDomainGroup()->getAllChildren();
-    }
-
-    if (!domList.empty())
-    {
-      int sizeDom = domList.size();
-      domList_.resize(sizeDom);
-      for (int i = 0; i < sizeDom; ++i)
-      {
-        domList_[i] = domList[i]->getId();
-      }
-      isDomListSet = true;
-    }
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Set axis(s) of a grid from a list
-  \param[in] axis list of axis
-  */
-  void CGrid::setAxisList(const std::vector<CAxis*> axis)
-  TRY
-  {
-    if (isAxisListSet) return;
-    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
-    if (!axis.empty() && aList.empty())
-    {
-      for (int i = 0; i < axis.size(); ++i)
-        this->getVirtualAxisGroup()->addChild(axis[i]);
-      aList = this->getVirtualAxisGroup()->getAllChildren();
-    }
-
-    if (!aList.empty())
-    {
-      int sizeAxis = aList.size();
-      axisList_.resize(sizeAxis);
-      for (int i = 0; i < sizeAxis; ++i)
-      {
-        axisList_[i] = aList[i]->getId();
-      }
-      isAxisListSet = true;
-    }
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Set scalar(s) of a grid from a list
-  \param[in] scalars list of scalars
-  */
-  void CGrid::setScalarList(const std::vector<CScalar*> scalars)
-  TRY
-  {
-    if (isScalarListSet) return;
-    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
-    if (!scalars.empty() && sList.empty())
-    {
-      for (int i = 0; i < scalars.size(); ++i)
-        this->getVirtualScalarGroup()->addChild(scalars[i]);
-      sList = this->getVirtualScalarGroup()->getAllChildren();
-    }
-
-    if (!sList.empty())
-    {
-      int sizeScalar = sList.size();
-      scalarList_.resize(sizeScalar);
-      for (int i = 0; i < sizeScalar; ++i)
-      {
-        scalarList_[i] = sList[i]->getId();
-      }
-      isScalarListSet = true;
-    }
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
-  \brief Get list of id of domains
-  \return id list of domains
-  */
-  std::vector<StdString> CGrid::getDomainList()
-  TRY
-  {
-    setDomainList();
-    return domList_;
-  }
-  CATCH
-
-  /*!
-  \brief Get list of id of axis
-  \return id list of axis
-  */
-  std::vector<StdString> CGrid::getAxisList()
-  TRY
-  {
-    setAxisList();
-    return axisList_;
-  }
-  CATCH
-
-  /*!
-  \brief Get list of id of scalar
-  \return id list of scalar
-  */
-  std::vector<StdString> CGrid::getScalarList()
-  TRY
-  {
-    setScalarList();
-    return scalarList_;
-  }
-  CATCH
+
 
   /*!
@@ -3014,52 +3245,5 @@
   CATCH_DUMP_ATTR
 
-  /*!
-    Parse a grid, for now, it contains only domain, axis and scalar
-  */
-  void CGrid::parse(xml::CXMLNode& node)
-  TRY
-  {
-    SuperClass::parse(node);
-
-    if (node.goToChildElement())
-    {
-      StdString domainName("domain");
-      StdString axisName("axis");
-      StdString scalarName("scalar");
-      do
-      {
-        if (node.getElementName() == domainName) {
-          order_.push_back(2);
-          this->getVirtualDomainGroup()->parseChild(node);
-        }
-        if (node.getElementName() == axisName) {
-          order_.push_back(1);
-          this->getVirtualAxisGroup()->parseChild(node);
-        }
-        if (node.getElementName() == scalarName) {
-          order_.push_back(0);
-          this->getVirtualScalarGroup()->parseChild(node);
-        }
-      } while (node.goToNextElement());
-      node.goToParentElement();
-    }
-
-    if (!order_.empty())
-    {
-      int sizeOrd = order_.size();
-      axis_domain_order.resize(sizeOrd);
-      for (int i = 0; i < sizeOrd; ++i)
-      {
-        axis_domain_order(i) = order_[i];
-      }
-    }
-
-    setDomainList();
-    setAxisList();
-    setScalarList();
-   }
-  CATCH_DUMP_ATTR
-
-
+ 
   void CGrid::computeGridLocalElements()
   {
@@ -3097,3 +3281,42 @@
     modelToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::MODEL,CElementView::WORKFLOW) ;
   }
+
+  void CGrid::computeWorkflowToFullConnector(void)
+  {
+    workflowToFullConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::FULL) ;
+  }
+
+  void CGrid::computeWorkflowToModelConnector(void)
+  {
+    workflowToModelConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::MODEL) ;
+  }
+
+  void CGrid::computeFullToWorkflowConnector(void)
+  {
+    fullToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::FULL,CElementView::WORKFLOW) ;
+  }
+
+  void CGrid::computeServerFromClientConnector(void)
+  {
+    vector<CGathererConnector*> connectors ;
+    for(auto& element : getElements())
+    {
+      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ;
+      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 
+      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 
+    }
+    serverFromClientConnector_ = new CGridGathererConnector(connectors) ;
+  }
+
+  void CGrid::computeClientFromClientConnector(void)
+  {
+    vector<CGathererConnector*> connectors ;
+    for(auto& element : getElements())
+    {
+      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ;
+      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 
+      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 
+    }
+    clientFromClientConnector_ = new CGridGathererConnector(connectors) ;
+  }
 } // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1930)
@@ -18,4 +18,7 @@
 #include "grid_local_connector.hpp"
 #include "grid_elements.hpp"
+#include "grid_scatterer_connector.hpp"
+#include "grid_gatherer_connector.hpp"
+
 
 namespace xios {
@@ -52,4 +55,17 @@
          typedef CGridAttributes SuperClassAttribute;
 
+      private:
+        
+        // define a structure to store elements (CDomain, CAxis, CScalar) using a void* and a type to cast the pointer
+         enum EElementType { TYPE_SCALAR, TYPE_AXIS, TYPE_DOMAIN } ;
+         struct SElement {void* ptr ; EElementType type ; CScalar* scalar ;  CAxis* axis ; CDomain* domain ; } ;
+         vector<SElement> elements_ ;
+         bool elementsComputed_ = false ; 
+         /** retrieve the vector of elements as a structure containing a void* and the type of pointer */
+         vector<SElement>& getElements(void) { if (!elementsComputed_) computeElements() ; return elements_ ; } 
+         void computeElements(void) ;
+         /** List order of axis and domain in a grid, if there is a domain, it will take value 2, axis 1, scalar 0 */
+         std::vector<int> order_;
+
       public:
 
@@ -72,5 +88,5 @@
 
          void checkEligibilityForCompressedOutput();
-
+         
 
 
@@ -504,7 +520,10 @@
         std::map<int, CClientServerMapping::GlobalIndexMap> globalIndexOnServer_;
 
-
-/** List order of axis and domain in a grid, if there is a domain, it will take value 2, axis 1, scalar 0 */
-        std::vector<int> order_;
+      
+
+     //////////////////////////////////////////////////////////////////////////////////////
+     //  this part is related to distribution, element definition, views and connectors  //
+     //////////////////////////////////////////////////////////////////////////////////////
+
 
       private:  
@@ -519,4 +538,54 @@
         void computeModelToWorkflowConnector(void) ;
         CGridLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_;}
+
+      private:
+        CGridLocalConnector* workflowToModelConnector_ ;
+      public:
+        void computeWorkflowToModelConnector(void) ;
+        CGridLocalConnector* getWorkflowToModelConnector(void) { if (workflowToModelConnector_==nullptr) computeWorkflowToModelConnector() ; return workflowToModelConnector_;}
+
+      public: //? 
+        void distributeGridToFileServer(CContextClient* client);
+      
+      private:
+         map<CContextClient*, CGridScattererConnector*> clientToServerConnector_ ;
+      public:
+         CGridScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;} // make some test to see if connector exits for the given client
+         
+      private:
+         CGridGathererConnector* serverFromClientConnector_ = nullptr ;
+      public:
+         CGridGathererConnector* getServerFromClientConnector(void) { if (serverFromClientConnector_==nullptr) computeServerFromClientConnector() ; return serverFromClientConnector_;}
+         void computeServerFromClientConnector(void) ;
+         
+      private:
+        CGridLocalConnector* workflowToFullConnector_ = nullptr;
+      public:
+        void computeWorkflowToFullConnector(void) ;
+        CGridLocalConnector* getWorkflowToFullConnector(void) { if (workflowToFullConnector_==nullptr) computeWorkflowToFullConnector() ; return workflowToFullConnector_;}
+
+      private:
+        CGridLocalConnector* fullToWorkflowConnector_ = nullptr;
+      public:
+        void computeFullToWorkflowConnector(void) ;
+        CGridLocalConnector* getFullToWorkflowConnector(void) { if (fullToWorkflowConnector_==nullptr) computeFullToWorkflowConnector() ; return fullToWorkflowConnector_;}
+
+      private:
+         CGridGathererConnector* clientFromClientConnector_ = nullptr ;
+      public:
+         CGridGathererConnector* getClientFromClientConnector(void) { if (clientFromClientConnector_==nullptr) computeClientFromClientConnector() ; return clientFromClientConnector_;}
+         void computeClientFromClientConnector(void) ;
+
+      private:
+         map<CContextClient*, CGridScattererConnector*> clientToClientConnector_ ;
+      public:
+         CGridScattererConnector* getClientToClientConnector(CContextClient* client) { return clientToClientConnector_[client] ;} // make some test to see if connector exits for the given client
+  
+
+      private:
+         CGridGathererConnector* clientFromServerConnector_ = nullptr ;
+      public:
+         CGridGathererConnector* getClientFromServerConnector(void) { if (clientFromServerConnector_==nullptr) computeClientFromServerConnector() ; return clientFromServerConnector_;}
+         void computeClientFromServerConnector(void) ;
 
    }; // class CGrid
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp	(revision 1930)
@@ -7,4 +7,5 @@
 #include "xios_spl.hpp"
 #include "type.hpp"
+#include "context.hpp"
 
 namespace xios {
@@ -231,4 +232,73 @@
   }
 
+   //////////////////////////////////////////////////////////////////////////////////////
+   //  this part is related to distribution, element definition, views and connectors  //
+   //////////////////////////////////////////////////////////////////////////////////////
+
+   void CScalar::initializeLocalElement(void)
+   {
+      // after checkAttribute index of size n
+      int rank = CContext::getCurrent()->getIntraCommRank() ;
+      
+      CArray<size_t,1> ind(1) ;
+      ind(0)=0 ;
+
+      localElement_ = new CLocalElement(rank, 1, ind) ;
+   }
+
+   void CScalar::addFullView(void)
+   {
+      CArray<int,1> index(1) ;
+      for(int i=0; i<1 ; i++) index(0)=0 ;
+      localElement_ -> addView(CElementView::FULL, index) ;
+   }
+
+   void CScalar::addWorkflowView(void)
+   {
+     CArray<int,1> index(1) ;
+     for(int i=0; i<1 ; i++) index(0)=0 ;
+     localElement_ -> addView(CElementView::WORKFLOW, index) ;
+   }
+
+   void CScalar::addModelView(void)
+   {
+     CArray<int,1> index(1) ;
+     for(int i=0; i<1 ; i++) index(0)=0 ;
+     localElement_->addView(CElementView::MODEL, index) ;
+   }
+
+   void CScalar::computeModelToWorkflowConnector(void)
+   { 
+     CLocalView* srcView=getLocalView(CElementView::MODEL) ;
+     CLocalView* dstView=getLocalView(CElementView::WORKFLOW) ;
+     modelToWorkflowConnector_ = new CLocalConnector(srcView, dstView); 
+     modelToWorkflowConnector_->computeConnector() ;
+   }
+
+
+   void CScalar::computeRemoteElement(CContextClient* client, EDistributionType type)
+  {
+    CContext* context = CContext::getCurrent();
+    map<int, CArray<size_t,1>> globalIndex ;
+
+    int nbServer = client->serverSize;
+    size_t nglo=1 ;
+    CArray<size_t,1> indGlo ;
+    for(size_t i=0;i<nglo;i++) indGlo(i) = i ;
+    for (auto& rankServer : client->getRanksServerLeader()) globalIndex[rankServer] = indGlo ; 
+
+    remoteElement_[client] = new CDistributedElement(nglo, globalIndex) ;
+    remoteElement_[client]->addFullView() ;
+  }
+ 
+  void CScalar::distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex)
+  {
+    CContext* context = CContext::getCurrent();
+    CDistributedElement scatteredElement(1,globalIndex) ;
+    clientToServerConnector_[client] = new CScattererConnector(localElement_->getView(CElementView::FULL), scatteredElement.getView(CElementView::FULL), context->getIntraComm()) ;
+    clientToServerConnector_[client] ->computeConnector() ;
+  }
+
+
   // Definition of some macros
   DEFINE_REF_FUNC(Scalar,scalar)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp	(revision 1929)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp	(revision 1930)
@@ -13,4 +13,11 @@
 #include "transformation.hpp"
 #include "transformation_enum.hpp"
+
+#include "element.hpp"
+#include "local_connector.hpp"
+#include "scatterer_connector.hpp"
+#include "gatherer_connector.hpp"
+#include "distribution_type.hpp"
+
 
 namespace xios
@@ -133,4 +140,50 @@
          void unsetCompleted(void) { isCompleted_=false ; }
 
+
+
+       //////////////////////////////////////////////////////////////////////////////////////
+       //  this part is related to distribution, element definition, views and connectors  //
+       //////////////////////////////////////////////////////////////////////////////////////
+       private:
+         CLocalElement* localElement_ = nullptr ;
+         void initializeLocalElement(void) ;
+       
+       public:  
+         CLocalElement* getLocalElement(void) { if (localElement_==nullptr) initializeLocalElement() ; return localElement_ ; }
+         CLocalView* getLocalView(CElementView::type type) { return getLocalElement()->getView(type) ;}
+       
+       private:  
+         void addFullView(void) ;
+         void addWorkflowView(void) ;
+         void addModelView(void) ;
+        
+       private:
+         CLocalConnector* modelToWorkflowConnector_ ;
+         void computeModelToWorkflowConnector(void)  ;
+       public:
+         CLocalConnector* getModelToWorkflowConnector(void) { if (modelToWorkflowConnector_==nullptr) computeModelToWorkflowConnector() ; return modelToWorkflowConnector_ ;}
+
+       public:
+         void computeRemoteElement(CContextClient* client, EDistributionType) ;
+         void distributeToServer(CContextClient* client, std::map<int, CArray<size_t,1>>& globalIndex) ;
+       private:
+         map<CContextClient*, CDistributedElement*> remoteElement_ ;
+       public: 
+         CDistributedElement* getRemoteElement(CContextClient* client) {return remoteElement_[client] ;}
+       private:
+         map<CContextClient*, CScattererConnector*> clientToServerConnector_ ;
+       public: 
+         CScattererConnector* getClientToServerConnector(CContextClient* client) { return clientToServerConnector_[client] ;}
+
+       private:
+         CGathererConnector*  gathererConnector_ ;
+         CGathererConnector* serverFromClientConnector_ ;
+       public:
+        CGathererConnector* getServerFromClientConnector(void) { return serverFromClientConnector_ ;}
+
+
+
+
+
       private:
             DECLARE_REF_FUNC(Scalar,scalar)
