Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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 1918)
+++ 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)
