Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 1870)
@@ -546,4 +546,5 @@
 
    */
+   //ym obsolete : to be removed
    void CAxis::sendCheckedAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
                                      CServerDistributionDescription::ServerDistributionType distType)
@@ -555,9 +556,22 @@
 
      if (this->isChecked) return;
-     if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER) sendAttributes(globalDim, orderPositionInGrid, distType);    
+     if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER) /*sendAttributes(globalDim, orderPositionInGrid, distType)*/;    
 
      this->isChecked = true;
    }
    CATCH_DUMP_ATTR
+
+  
+   void CAxis::sendAxisToFileServer(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid)
+   {
+     if (sendAxisToFileServer_done_.count(client)!=0) return ;
+     else sendAxisToFileServer_done_.insert(client) ;
+     
+     StdString axisDefRoot("axis_definition");
+     CAxisGroup* axisPtr = CAxisGroup::get(axisDefRoot);
+     axisPtr->sendCreateChild(this->getId(),client);
+     this->sendAllAttributesToServer(client)  ; 
+     this->sendAttributes(client, globalDim, orderPositionInGrid, CServerDistributionDescription::BAND_DISTRIBUTION) ;
+   }
 
   /*!
@@ -566,9 +580,9 @@
     \param[in] order
   */
-  void CAxis::sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
+  void CAxis::sendAttributes(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid,
                              CServerDistributionDescription::ServerDistributionType distType)
   TRY
   {
-     sendDistributionAttribute(globalDim, orderPositionInGrid, distType);
+     sendDistributionAttribute(client, globalDim, orderPositionInGrid, distType);
 
      // if (index.numElements() == n_glo.getValue())
@@ -576,9 +590,9 @@
          || (index.numElements() != n_glo))
      {
-       sendDistributedAttributes();       
+       sendDistributedAttributes(client);       
      }
      else
      {
-       sendNonDistributedAttributes();    
+       sendNonDistributedAttributes(client);    
      }     
   }
@@ -874,44 +888,39 @@
     \param [in] distType distribution type of the server. For now, we only have band distribution.
   */
-  void CAxis::sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid,
+  void CAxis::sendDistributionAttribute(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid,
                                         CServerDistributionDescription::ServerDistributionType distType)
   TRY
   {
-    std::list<CContextClient*>::iterator it;
-    for (it=clients.begin(); it!=clients.end(); ++it)
-    {
-      CContextClient* client = *it;
-      int nbServer = client->serverSize;
-
-      CServerDistributionDescription serverDescription(globalDim, nbServer);
-      serverDescription.computeServerDistribution();
-
-      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
-      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
-
-      CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE);
-      if (client->isServerLeader())
-      {
-        std::list<CMessage> msgs;
-
-        const std::list<int>& ranks = client->getRanksServerLeader();
-        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-        {
-          // Use const int to ensure CMessage holds a copy of the value instead of just a reference
-          const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
-          const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
-
-          msgs.push_back(CMessage());
-          CMessage& msg = msgs.back();
-          msg << this->getId();
-          msg << ni << begin;
-          msg << isCompressible_;                    
-
-          event.push(*itRank,1,msg);
-        }
-        client->sendEvent(event);
-      }
-      else client->sendEvent(event);
-    }
+    int nbServer = client->serverSize;
+
+    CServerDistributionDescription serverDescription(globalDim, nbServer);
+    serverDescription.computeServerDistribution();
+
+    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
+    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
+
+    CEventClient event(getType(),EVENT_ID_DISTRIBUTION_ATTRIBUTE);
+    if (client->isServerLeader())
+    {
+      std::list<CMessage> msgs;
+
+      const std::list<int>& ranks = client->getRanksServerLeader();
+      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+      {
+        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
+        const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
+        const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
+
+        msgs.push_back(CMessage());
+        CMessage& msg = msgs.back();
+        msg << this->getId();
+        msg << ni << begin;
+        msg << isCompressible_;                    
+
+        event.push(*itRank,1,msg);
+      }
+      client->sendEvent(event);
+    }
+    else client->sendEvent(event);
   }
   CATCH_DUMP_ATTR
@@ -953,58 +962,52 @@
     In the future, if new attributes are added, they should also be processed in this function
   */
-  void CAxis::sendNonDistributedAttributes()
-  TRY
-  {
-    std::list<CContextClient*>::iterator it;
-    for (it=clients.begin(); it!=clients.end(); ++it)
-	{
-	  CContextClient* client = *it;
-
-      CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES);
-      size_t nbIndex = index.numElements();
-      size_t nbDataIndex = 0;
-
-      for (int idx = 0; idx < data_index.numElements(); ++idx)
-      {
-        int ind = data_index(idx);
-        if (ind >= 0 && ind < nbIndex) ++nbDataIndex;
-      }
-
-      CArray<int,1> dataIndex(nbDataIndex);
-      nbDataIndex = 0;
-      for (int idx = 0; idx < data_index.numElements(); ++idx)
-      {
-        int ind = data_index(idx);
-        if (ind >= 0 && ind < nbIndex)
-        {
-          dataIndex(nbDataIndex) = ind;
-          ++nbDataIndex;
-        }
-      }
-
-      if (client->isServerLeader())
-      {
-        std::list<CMessage> msgs;
-
-        const std::list<int>& ranks = client->getRanksServerLeader();
-        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-        {
-          msgs.push_back(CMessage());
-          CMessage& msg = msgs.back();
-          msg << this->getId();
-          msg << index.getValue() << dataIndex << mask.getValue();
-          msg << hasValue;
-          if (hasValue) msg << value.getValue();
-          msg << hasBounds;
-          if (hasBounds) msg << bounds.getValue();
-          msg << hasLabel;
-          if (hasLabel) msg << label.getValue();
-
-          event.push(*itRank, 1, msg);
-        }
-        client->sendEvent(event);
-      }
-      else client->sendEvent(event);
-    }
+  void CAxis::sendNonDistributedAttributes(CContextClient* client)
+  TRY
+  {
+    CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES);
+    size_t nbIndex = index.numElements();
+    size_t nbDataIndex = 0;
+
+    for (int idx = 0; idx < data_index.numElements(); ++idx)
+    {
+      int ind = data_index(idx);
+      if (ind >= 0 && ind < nbIndex) ++nbDataIndex;
+    }
+
+    CArray<int,1> dataIndex(nbDataIndex);
+    nbDataIndex = 0;
+    for (int idx = 0; idx < data_index.numElements(); ++idx)
+    {
+      int ind = data_index(idx);
+      if (ind >= 0 && ind < nbIndex)
+      {
+        dataIndex(nbDataIndex) = ind;
+        ++nbDataIndex;
+      }
+    }
+
+    if (client->isServerLeader())
+    {
+      std::list<CMessage> msgs;
+
+      const std::list<int>& ranks = client->getRanksServerLeader();
+      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+      {
+        msgs.push_back(CMessage());
+        CMessage& msg = msgs.back();
+        msg << this->getId();
+        msg << index.getValue() << dataIndex << mask.getValue();
+        msg << hasValue;
+        if (hasValue) msg << value.getValue();
+        msg << hasBounds;
+        if (hasBounds) msg << bounds.getValue();
+        msg << hasLabel;
+        if (hasLabel) msg << label.getValue();
+
+        event.push(*itRank, 1, msg);
+      }
+      client->sendEvent(event);
+    }
+    else client->sendEvent(event);
   }
   CATCH_DUMP_ATTR
@@ -1083,108 +1086,102 @@
     In future, if new attributes are added, they should also be processed in this function
   */
-  void CAxis::sendDistributedAttributes(void)
+  void CAxis::sendDistributedAttributes(CContextClient* client)
   TRY
   {
     int ind, idx;
-    std::list<CContextClient*>::iterator it;
-
-    for (it=clients.begin(); it!=clients.end(); ++it)
-    {
-      CContextClient* client = *it;
-      int nbServer = client->serverSize;
-
-      CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES);
-
-      list<CMessage> listData;
-      list<CArray<int,1> > list_indi, list_dataInd;
-      list<CArray<double,1> > list_val;
-      list<CArray<double,2> > list_bounds;
-      list<CArray<string,1> > list_label;
-
-      // Cut off the ghost points
-      int nbIndex = index.numElements();
-      CArray<int,1> dataIndex(nbIndex);
-      dataIndex = -1;
-      for (idx = 0; idx < data_index.numElements(); ++idx)
-      {
-        if (0 <= data_index(idx) && data_index(idx) < nbIndex)
-          dataIndex(data_index(idx)) = 1;
-      }
-
-      std::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap;
-      iteMap = indSrv_[nbServer].end();
-      for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k)
-      {
-        int nbData = 0, nbDataCount = 0;
-        int rank = connectedServerRank_[nbServer][k];
-        it = indSrv_[nbServer].find(rank);
-        if (iteMap != it)
-          nbData = it->second.size();
-
-        list_indi.push_back(CArray<int,1>(nbData));
-        list_dataInd.push_back(CArray<int,1>(nbData));
+    int nbServer = client->serverSize;
+
+    CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES);
+
+    list<CMessage> listData;
+    list<CArray<int,1> > list_indi, list_dataInd;
+    list<CArray<double,1> > list_val;
+    list<CArray<double,2> > list_bounds;
+    list<CArray<string,1> > list_label;
+
+    // Cut off the ghost points
+    int nbIndex = index.numElements();
+    CArray<int,1> dataIndex(nbIndex);
+    dataIndex = -1;
+    for (idx = 0; idx < data_index.numElements(); ++idx)
+    {
+      if (0 <= data_index(idx) && data_index(idx) < nbIndex)
+        dataIndex(data_index(idx)) = 1;
+    }
+
+    std::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap;
+    iteMap = indSrv_[nbServer].end();
+    for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k)
+    {
+      int nbData = 0, nbDataCount = 0;
+      int rank = connectedServerRank_[nbServer][k];
+      it = indSrv_[nbServer].find(rank);
+      if (iteMap != it)
+        nbData = it->second.size();
+
+      list_indi.push_back(CArray<int,1>(nbData));
+      list_dataInd.push_back(CArray<int,1>(nbData));
+
+      if (hasValue)
+        list_val.push_back(CArray<double,1>(nbData));
+
+      if (hasBounds)        
+        list_bounds.push_back(CArray<double,2>(2,nbData));
+
+      if (hasLabel)
+        list_label.push_back(CArray<string,1>(nbData));
+
+      CArray<int,1>& indi = list_indi.back();
+      CArray<int,1>& dataIndi = list_dataInd.back();
+      dataIndi = -1;
+
+      for (int n = 0; n < nbData; ++n)
+      {
+        idx = static_cast<int>(it->second[n]);
+        indi(n) = idx;
+
+        ind = globalLocalIndexMap_[idx];
+        dataIndi(n) = dataIndex(ind);
 
         if (hasValue)
-          list_val.push_back(CArray<double,1>(nbData));
-
-        if (hasBounds)        
-          list_bounds.push_back(CArray<double,2>(2,nbData));
+        {
+          CArray<double,1>& val = list_val.back();
+          val(n) = value(ind);
+        }
+
+        if (hasBounds)
+        {
+          CArray<double,2>& boundsVal = list_bounds.back();
+          boundsVal(0, n) = bounds(0,ind);
+          boundsVal(1, n) = bounds(1,ind);
+        }
 
         if (hasLabel)
-          list_label.push_back(CArray<string,1>(nbData));
-
-        CArray<int,1>& indi = list_indi.back();
-        CArray<int,1>& dataIndi = list_dataInd.back();
-        dataIndi = -1;
-
-        for (int n = 0; n < nbData; ++n)
-        {
-          idx = static_cast<int>(it->second[n]);
-          indi(n) = idx;
-
-          ind = globalLocalIndexMap_[idx];
-          dataIndi(n) = dataIndex(ind);
-
-          if (hasValue)
-          {
-            CArray<double,1>& val = list_val.back();
-            val(n) = value(ind);
-          }
-
-          if (hasBounds)
-          {
-            CArray<double,2>& boundsVal = list_bounds.back();
-            boundsVal(0, n) = bounds(0,ind);
-            boundsVal(1, n) = bounds(1,ind);
-          }
-
-          if (hasLabel)
-          {
-            CArray<string,1>& labelVal = list_label.back();
-            labelVal(n) = label(ind); 
-          }
-        }
-
-        listData.push_back(CMessage());
-        listData.back() << this->getId()
-                        << list_indi.back() << list_dataInd.back();
-
-        listData.back() << hasValue;
-        if (hasValue)
-          listData.back() << list_val.back();
-
-        listData.back() << hasBounds;
-        if (hasBounds)
-          listData.back() << list_bounds.back();
-
-        listData.back() << hasLabel;
-        if (hasLabel)
-          listData.back() << list_label.back();
-
-        eventData.push(rank, nbSenders[nbServer][rank], listData.back());
-      }
-
-      client->sendEvent(eventData);
-    }
+        {
+          CArray<string,1>& labelVal = list_label.back();
+          labelVal(n) = label(ind); 
+        }
+      }
+
+      listData.push_back(CMessage());
+      listData.back() << this->getId()
+                      << list_indi.back() << list_dataInd.back();
+
+      listData.back() << hasValue;
+      if (hasValue)
+        listData.back() << list_val.back();
+
+      listData.back() << hasBounds;
+      if (hasBounds)
+        listData.back() << list_bounds.back();
+
+      listData.back() << hasLabel;
+      if (hasLabel)
+        listData.back() << list_label.back();
+
+      eventData.push(rank, nbSenders[nbServer][rank], listData.back());
+    }
+
+    client->sendEvent(eventData);
   }
   CATCH_DUMP_ATTR
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 1870)
@@ -145,12 +145,18 @@
          void checkBounds();
          void checkLabel();
-         void sendAttributes(const std::vector<int>& globalDim, int orderPositionInGrid,
+      public:
+         void sendAxisToFileServer(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid) ;
+      private:
+         std::set<CContextClient*> sendAxisToFileServer_done_ ;
+      
+      private:
+         void sendAttributes(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid,
                              CServerDistributionDescription::ServerDistributionType distType);
-         void sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid,
+         void sendDistributionAttribute(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid,
                                         CServerDistributionDescription::ServerDistributionType distType);
          
 
-         void sendNonDistributedAttributes(void);
-         void sendDistributedAttributes(void);
+         void sendNonDistributedAttributes(CContextClient* client);
+         void sendDistributedAttributes(CContextClient* client);
 
          static void recvNonDistributedAttributes(CEventServer& event);
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp	(revision 1870)
@@ -271,4 +271,63 @@
 
 
+   void CContext::setClientServerBuffer(vector<CField*>& fields, bool bufferForWriting)
+   TRY
+   {
+      // Estimated minimum event size for small events (20 is an arbitrary constant just for safety)
+     const size_t minEventSize = CEventClient::headerSize + 20 * sizeof(int);
+      // Ensure there is at least some room for 20 of such events in the buffers
+     size_t minBufferSize = std::max(CXios::minBufferSize, 20 * minEventSize);
+
+#define DECLARE_NODE(Name_, name_)    \
+     if (minBufferSize < sizeof(C##Name_##Definition)) minBufferSize = sizeof(C##Name_##Definition);
+#define DECLARE_NODE_PAR(Name_, name_)
+#include "node_type.conf"
+#undef DECLARE_NODE
+#undef DECLARE_NODE_PAR
+
+
+     map<CContextClient*,map<int,size_t>> dataSize ;
+     map<CContextClient*,map<int,size_t>> maxEventSize ;
+     map<CContextClient*,map<int,size_t>> attributesSize ;  
+
+     for(auto field : fields)
+     {
+       field->setContextClientDataBufferSize(dataSize, maxEventSize, bufferForWriting) ;
+       field->setContextClientAttributesBufferSize(attributesSize, maxEventSize, bufferForWriting) ;
+     }
+     
+
+     for(auto& it : attributesSize)
+     {
+       auto contextClient = it.first ;
+       auto& contextDataSize =  dataSize[contextClient] ;
+       auto& contextAttributesSize =  attributesSize[contextClient] ;
+       auto& contextMaxEventSize =  maxEventSize[contextClient] ;
+   
+       for (auto& it : contextAttributesSize)
+       {
+         auto serverRank=it.first ;
+         auto& buffer = contextAttributesSize[serverRank] ;
+         if (contextDataSize[serverRank] > buffer) buffer=contextDataSize[serverRank] ;
+         buffer *= CXios::bufferSizeFactor;
+         if (buffer < minBufferSize) buffer = minBufferSize;
+         if (buffer > CXios::maxBufferSize ) buffer = CXios::maxBufferSize;
+       }
+
+       // Leaders will have to send some control events so ensure there is some room for those in the buffers
+       if (contextClient->isServerLeader())
+         for(auto& rank : contextClient->getRanksServerLeader())
+           if (!contextAttributesSize.count(rank))
+           {
+             contextAttributesSize[rank] = minBufferSize;
+             contextMaxEventSize[rank] = minEventSize;
+           }
+      
+       contextClient->setBufferSize(contextAttributesSize, contextMaxEventSize);    
+     }
+   }
+   CATCH_DUMP_ATTR
+
+
     /*!
     Sets client buffers.
@@ -277,4 +336,5 @@
     This flag is only true for client and server-1 for communication with server-2
   */
+  // ym obsolete to be removed
    void CContext::setClientServerBuffer(CContextClient* contextClient, bool bufferForWriting)
    TRY
@@ -327,4 +387,96 @@
    }
    CATCH_DUMP_ATTR
+
+ /*!
+    * Compute the required buffer size to send the fields data.
+    * \param maxEventSize [in/out] the size of the bigger event for each connected server
+    * \param [in] contextClient
+    * \param [in] bufferForWriting True if buffers are used for sending data for writing
+      This flag is only true for client and server-1 for communication with server-2
+    */
+   std::map<int, StdSize> CContext::getDataBufferSize(std::map<int, StdSize>& maxEventSize,
+                                                      CContextClient* contextClient, bool bufferForWriting /*= "false"*/)
+   TRY
+   {
+     std::map<int, StdSize> dataSize;
+
+     // Find all reference domain and axis of all active fields
+     std::vector<CFile*>& fileList = bufferForWriting ? this->enabledWriteModeFiles : this->enabledReadModeFiles;
+     size_t numEnabledFiles = fileList.size();
+     for (size_t i = 0; i < numEnabledFiles; ++i)
+     {
+       CFile* file = fileList[i];
+       if (file->getContextClient() == contextClient)
+       {
+         std::vector<CField*> enabledFields = file->getEnabledFields();
+         size_t numEnabledFields = enabledFields.size();
+         for (size_t j = 0; j < numEnabledFields; ++j)
+         {
+           // const std::vector<std::map<int, StdSize> > mapSize = enabledFields[j]->getGridDataBufferSize(contextClient);
+           const std::map<int, StdSize> mapSize = enabledFields[j]->getGridDataBufferSize(contextClient,bufferForWriting);
+           std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end();
+           for (; it != itE; ++it)
+           {
+             // If dataSize[it->first] does not exist, it will be zero-initialized
+             // so we can use it safely without checking for its existance
+           if (CXios::isOptPerformance)
+               dataSize[it->first] += it->second;
+             else if (dataSize[it->first] < it->second)
+               dataSize[it->first] = it->second;
+
+           if (maxEventSize[it->first] < it->second)
+               maxEventSize[it->first] = it->second;
+           }
+         }
+       }
+     }
+     return dataSize;
+   }
+   CATCH_DUMP_ATTR
+
+/*!
+    * Compute the required buffer size to send the attributes (mostly those grid related).
+    * \param maxEventSize [in/out] the size of the bigger event for each connected server
+    * \param [in] contextClient
+    * \param [in] bufferForWriting True if buffers are used for sending data for writing
+      This flag is only true for client and server-1 for communication with server-2
+    */
+   std::map<int, StdSize> CContext::getAttributesBufferSize(std::map<int, StdSize>& maxEventSize,
+                                                           CContextClient* contextClient, bool bufferForWriting /*= "false"*/)
+   TRY
+   {
+   // As calendar attributes are sent even if there are no active files or fields, maps are initialized according the size of calendar attributes
+     std::map<int, StdSize> attributesSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient);
+     maxEventSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient);
+
+     std::vector<CFile*>& fileList = this->enabledFiles;
+     size_t numEnabledFiles = fileList.size();
+     for (size_t i = 0; i < numEnabledFiles; ++i)
+     {
+//         CFile* file = this->enabledWriteModeFiles[i];
+        CFile* file = fileList[i];
+        std::vector<CField*> enabledFields = file->getEnabledFields();
+        size_t numEnabledFields = enabledFields.size();
+        for (size_t j = 0; j < numEnabledFields; ++j)
+        {
+          const std::map<int, StdSize> mapSize = enabledFields[j]->getGridAttributesBufferSize(contextClient, bufferForWriting);
+          std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end();
+          for (; it != itE; ++it)
+          {
+         // If attributesSize[it->first] does not exist, it will be zero-initialized
+         // so we can use it safely without checking for its existence
+             if (attributesSize[it->first] < it->second)
+         attributesSize[it->first] = it->second;
+
+         if (maxEventSize[it->first] < it->second)
+         maxEventSize[it->first] = it->second;
+          }
+        }
+     }
+     return attributesSize;
+   }
+   CATCH_DUMP_ATTR
+
+
 
    //! Verify whether a context is initialized
@@ -899,10 +1051,11 @@
 
     // Find all enabled fields of each file      
-    const vector<CField*>&& fileOutField = findAllEnabledFieldsInFileOut(this->enabledWriteModeFiles);
-    const vector<CField*>&& fileInField = findAllEnabledFieldsInFileIn(this->enabledReadModeFiles);
-    const vector<CField*>&& CouplerOutField = findAllEnabledFieldsCouplerOut(this->enabledCouplerOut);
-    const vector<CField*>&& CouplerInField = findAllEnabledFieldsCouplerIn(this->enabledCouplerIn);
+    vector<CField*>&& fileOutField = findAllEnabledFieldsInFileOut(this->enabledWriteModeFiles);
+    vector<CField*>&& fileInField = findAllEnabledFieldsInFileIn(this->enabledReadModeFiles);
+    vector<CField*>&& CouplerOutField = findAllEnabledFieldsCouplerOut(this->enabledCouplerOut);
+    vector<CField*>&& CouplerInField = findAllEnabledFieldsCouplerIn(this->enabledCouplerIn);
     findFieldsWithReadAccess();
-    const vector<CField*>& fieldWithReadAccess = fieldsWithReadAccess_ ;
+    vector<CField*>& fieldWithReadAccess = fieldsWithReadAccess_ ;
+    vector<CField*> fieldModelIn ; // fields potentially from model
       
 // find all field potentially at workflow end
@@ -915,8 +1068,13 @@
     for(auto endWorkflowField : endWorkflowFields) endWorkflowField->buildWorkflowGraph(garbageCollector) ;
     
-    // Distribute files between secondary servers according to the data size => assign a context to a file
+    // get all field coming potentially from model
+    for (auto field : CField::getAll() ) if (field->getModelIn()) fieldModelIn.push_back(field) ;
+
+    // Distribute files between secondary servers according to the data size => assign a context to a file and then to fields
     if (serviceType_==CServicesManager::GATHERER) distributeFiles(this->enabledWriteModeFiles);
     else if (serviceType_==CServicesManager::CLIENT) for(auto file : this->enabledWriteModeFiles) file->setContextClient(client) ;
 
+   
+    // workflow endpoint => sent to IO/SERVER
     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER)
     {
@@ -926,10 +1084,23 @@
         field->computeGridIndexToFileServer() ; // compute grid index for transfer to the server context
       }
+      setClientServerBuffer(fileOutField, true) ; // set context
+      for(auto field : fileOutField) field->sendFieldToFileServer() ;
     }
-    
-
-
-
-
+
+
+    // workflow startpoint => data from model
+    if (serviceType_==CServicesManager::CLIENT)
+    {
+      for(auto field : fieldModelIn) 
+      {
+        field->connectToModelInput(garbageCollector) ; // connect the field to server filter
+        // grid index will be computed on the fly
+      }
+    }
+
+  
+
+
+    return ;
     // For now, only read files with client and only one level server
     // if (hasClient && !hasServer) findEnabledReadModeFiles();      
@@ -1057,5 +1228,18 @@
   CATCH_DUMP_ATTR
 
-
+ /*!
+  * Send context attribute and calendar to file server, it must be done once by context file server
+  * \param[in] client : context client to send   
+  */  
+  void CContext::sendContextToFileServer(CContextClient* client)
+  {
+    if (sendToFileServer_done_.count(client)!=0) return ;
+    else sendToFileServer_done_.insert(client) ;
+    
+    this->sendAllAttributesToServer(client); // Send all attributes of current context to server
+    CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(client); // Send all attributes of current cale
+  }
+
+  // ym obsolete now to be removed
    void CContext::closeDefinition_old(void)
    TRY
@@ -2068,95 +2252,6 @@
    CATCH_DUMP_ATTR
 
-   /*!
-    * Compute the required buffer size to send the attributes (mostly those grid related).
-    * \param maxEventSize [in/out] the size of the bigger event for each connected server
-    * \param [in] contextClient
-    * \param [in] bufferForWriting True if buffers are used for sending data for writing
-      This flag is only true for client and server-1 for communication with server-2
-    */
-   std::map<int, StdSize> CContext::getAttributesBufferSize(std::map<int, StdSize>& maxEventSize,
-                                                           CContextClient* contextClient, bool bufferForWriting /*= "false"*/)
-   TRY
-   {
-	 // As calendar attributes are sent even if there are no active files or fields, maps are initialized according the size of calendar attributes
-     std::map<int, StdSize> attributesSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient);
-     maxEventSize = CCalendarWrapper::get(CCalendarWrapper::GetDefName())->getMinimumBufferSizeForAttributes(contextClient);
-
-     std::vector<CFile*>& fileList = this->enabledFiles;
-     size_t numEnabledFiles = fileList.size();
-     for (size_t i = 0; i < numEnabledFiles; ++i)
-     {
-//         CFile* file = this->enabledWriteModeFiles[i];
-        CFile* file = fileList[i];
-        std::vector<CField*> enabledFields = file->getEnabledFields();
-        size_t numEnabledFields = enabledFields.size();
-        for (size_t j = 0; j < numEnabledFields; ++j)
-        {
-          const std::map<int, StdSize> mapSize = enabledFields[j]->getGridAttributesBufferSize(contextClient, bufferForWriting);
-          std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end();
-          for (; it != itE; ++it)
-          {
-		     // If attributesSize[it->first] does not exist, it will be zero-initialized
-		     // so we can use it safely without checking for its existence
-             if (attributesSize[it->first] < it->second)
-			   attributesSize[it->first] = it->second;
-
-		     if (maxEventSize[it->first] < it->second)
-			   maxEventSize[it->first] = it->second;
-          }
-        }
-     }
-     return attributesSize;
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-    * Compute the required buffer size to send the fields data.
-    * \param maxEventSize [in/out] the size of the bigger event for each connected server
-    * \param [in] contextClient
-    * \param [in] bufferForWriting True if buffers are used for sending data for writing
-      This flag is only true for client and server-1 for communication with server-2
-    */
-   std::map<int, StdSize> CContext::getDataBufferSize(std::map<int, StdSize>& maxEventSize,
-                                                      CContextClient* contextClient, bool bufferForWriting /*= "false"*/)
-   TRY
-   {
-     std::map<int, StdSize> dataSize;
-
-     // Find all reference domain and axis of all active fields
-     std::vector<CFile*>& fileList = bufferForWriting ? this->enabledWriteModeFiles : this->enabledReadModeFiles;
-     size_t numEnabledFiles = fileList.size();
-     for (size_t i = 0; i < numEnabledFiles; ++i)
-     {
-       CFile* file = fileList[i];
-       if (file->getContextClient() == contextClient)
-       {
-         std::vector<CField*> enabledFields = file->getEnabledFields();
-         size_t numEnabledFields = enabledFields.size();
-         for (size_t j = 0; j < numEnabledFields; ++j)
-         {
-           // const std::vector<std::map<int, StdSize> > mapSize = enabledFields[j]->getGridDataBufferSize(contextClient);
-           const std::map<int, StdSize> mapSize = enabledFields[j]->getGridDataBufferSize(contextClient,bufferForWriting);
-           std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end();
-           for (; it != itE; ++it)
-           {
-             // If dataSize[it->first] does not exist, it will be zero-initialized
-             // so we can use it safely without checking for its existance
-        	 if (CXios::isOptPerformance)
-               dataSize[it->first] += it->second;
-             else if (dataSize[it->first] < it->second)
-               dataSize[it->first] = it->second;
-
-        	 if (maxEventSize[it->first] < it->second)
-               maxEventSize[it->first] = it->second;
-           }
-         }
-       }
-     }
-     return dataSize;
-   }
-   CATCH_DUMP_ATTR
-
-   //! Client side: Send infomation of active files (files are enabled to write out)
+  
+     //! Client side: Send infomation of active files (files are enabled to write out)
    void CContext::sendEnabledFiles(const std::vector<CFile*>& activeFiles)
    TRY
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp	(revision 1870)
@@ -159,5 +159,6 @@
          std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
          std::map<int, StdSize> getDataBufferSize(std::map<int, StdSize>& maxEventSize, CContextClient* contextClient, bool bufferForWriting = false);
-         void setClientServerBuffer(CContextClient* contextClient, bool bufferForWriting = false);
+         void setClientServerBuffer(CContextClient* contextClient, bool bufferForWriting = false); // old interface to be removed
+         void setClientServerBuffer(vector<CField*>& fields, bool bufferForWriting) ; 
 
          // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
@@ -181,5 +182,11 @@
          void sendRegistry(void) ;
          void sendFinalizeClient(CContextClient* contextClient, const string& contextClientId);
-
+         
+         public:
+         void sendContextToFileServer(CContextClient* client) ;
+         private:
+         std::set<CContextClient*> sendToFileServer_done_ ;
+         
+         public: 
          std::string getContextId() {return contextId_;}
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp	(revision 1870)
@@ -2085,16 +2085,33 @@
   CATCH_DUMP_ATTR
 
+  void CDomain::sendDomainToFileServer(CContextClient* client)
+  {
+    if (sendDomainToFileServer_done_.count(client)!=0) return ;
+    else sendDomainToFileServer_done_.insert(client) ;
+
+    StdString domDefRoot("domain_definition");
+    CDomainGroup* domPtr = CDomainGroup::get(domDefRoot);
+    domPtr->sendCreateChild(this->getId(), client);
+    this->sendAllAttributesToServer(client)  ;
+    this->sendDistributionAttributes(client);   
+    this->sendIndex(client);       
+    this->sendLonLat(client);
+    this->sendArea(client);    
+    this->sendDataIndex(client);
+  }
+
   /*!
     Send all attributes from client to connected clients
     The attributes will be rebuilt on receiving side
   */
+  // ym obsolete to be removed
   void CDomain::sendAttributes()
   TRY
   {
-    sendDistributionAttributes();
-    sendIndex();       
-    sendLonLat();
-    sendArea();    
-    sendDataIndex();
+    //sendDistributionAttributes();
+    //sendIndex();       
+    //sendLonLat();
+    //sendArea();    
+    //sendDataIndex();
   }
   CATCH
@@ -2102,47 +2119,38 @@
     Send global index from client to connected client(s)
   */
-  void CDomain::sendIndex()
+  void CDomain::sendIndex(CContextClient* client)
   TRY
   {
     int ns, n, i, j, ind, nv, idx;
-    std::list<CContextClient*>::iterator it;
-    for (it=clients.begin(); it!=clients.end(); ++it)
+   
+    int serverSize = client->serverSize;
+    CEventClient eventIndex(getType(), EVENT_ID_INDEX);
+
+    list<CMessage> list_msgsIndex;
+    list<CArray<int,1> > list_indGlob;
+
+    std::unordered_map<int, vector<size_t> >::const_iterator itIndex, iteIndex;
+    iteIndex = indSrv_[serverSize].end();
+    for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
     {
-      CContextClient* client = *it;
-
-      int serverSize = client->serverSize;
-      CEventClient eventIndex(getType(), EVENT_ID_INDEX);
-
-      list<CMessage> list_msgsIndex;
-      list<CArray<int,1> > list_indGlob;
-
-      std::unordered_map<int, vector<size_t> >::const_iterator itIndex, iteIndex;
-      iteIndex = indSrv_[serverSize].end();
-      for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
-      {
-        int nbIndGlob = 0;
-        int rank = connectedServerRank_[serverSize][k];
-        itIndex = indSrv_[serverSize].find(rank);
-        if (iteIndex != itIndex)
-          nbIndGlob = itIndex->second.size();
-
-        list_indGlob.push_back(CArray<int,1>(nbIndGlob));        
-
-        CArray<int,1>& indGlob = list_indGlob.back();
-        for (n = 0; n < nbIndGlob; ++n)
-        {
-          indGlob(n) = static_cast<int>(itIndex->second[n]);
-        }
-
-        list_msgsIndex.push_back(CMessage());
-        list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix
-        list_msgsIndex.back() << isCurvilinear;
-        list_msgsIndex.back() << list_indGlob.back(); //list_indi.back() << list_indj.back();
+      int nbIndGlob = 0;
+      int rank = connectedServerRank_[serverSize][k];
+      itIndex = indSrv_[serverSize].find(rank);
+      if (iteIndex != itIndex)
+        nbIndGlob = itIndex->second.size();
+
+      list_indGlob.push_back(CArray<int,1>(nbIndGlob));        
+
+      CArray<int,1>& indGlob = list_indGlob.back();
+      for (n = 0; n < nbIndGlob; ++n) indGlob(n) = static_cast<int>(itIndex->second[n]);
+
+      list_msgsIndex.push_back(CMessage());
+      list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix
+      list_msgsIndex.back() << isCurvilinear;
+      list_msgsIndex.back() << list_indGlob.back(); //list_indi.back() << list_indj.back();
        
-        eventIndex.push(rank, nbSenders[serverSize][rank], list_msgsIndex.back());
-      }
-
-      client->sendEvent(eventIndex);
-    }
+      eventIndex.push(rank, nbSenders[serverSize][rank], list_msgsIndex.back());
+    }
+    client->sendEvent(eventIndex);
   }
   CATCH_DUMP_ATTR
@@ -2153,51 +2161,46 @@
     it calculates this distribution then sends it to the corresponding clients on the next level
   */
-  void CDomain::sendDistributionAttributes(void)
+  void CDomain::sendDistributionAttributes(CContextClient* client)
   TRY
   {
-    std::list<CContextClient*>::iterator it;
-    for (it=clients.begin(); it!=clients.end(); ++it)
+    int nbServer = client->serverSize;
+    std::vector<int> nGlobDomain(2);
+    nGlobDomain[0] = this->ni_glo;
+    nGlobDomain[1] = this->nj_glo;
+
+    CServerDistributionDescription serverDescription(nGlobDomain, nbServer);
+    if (isUnstructed_) serverDescription.computeServerDistribution(false, 0);
+    else serverDescription.computeServerDistribution(false, 1);
+
+    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
+    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
+
+    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
+    if (client->isServerLeader())
     {
-      CContextClient* client = *it;
-      int nbServer = client->serverSize;
-      std::vector<int> nGlobDomain(2);
-      nGlobDomain[0] = this->ni_glo;
-      nGlobDomain[1] = this->nj_glo;
-
-      CServerDistributionDescription serverDescription(nGlobDomain, nbServer);
-      if (isUnstructed_) serverDescription.computeServerDistribution(false, 0);
-      else serverDescription.computeServerDistribution(false, 1);
-
-      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
-      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
-
-      CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
-      if (client->isServerLeader())
-      {
-        std::list<CMessage> msgs;
-
-        const std::list<int>& ranks = client->getRanksServerLeader();
-        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-        {
-          // Use const int to ensure CMessage holds a copy of the value instead of just a reference
-          const int ibegin_srv = serverIndexBegin[*itRank][0];
-          const int jbegin_srv = serverIndexBegin[*itRank][1];
-          const int ni_srv = serverDimensionSizes[*itRank][0];
-          const int nj_srv = serverDimensionSizes[*itRank][1];
-
-          msgs.push_back(CMessage());
-          CMessage& msg = msgs.back();
-          msg << this->getId() ;
-          msg << isUnstructed_;
-          msg << ni_srv << ibegin_srv << nj_srv << jbegin_srv;
-          msg << ni_glo.getValue() << nj_glo.getValue();
-          msg << isCompressible_;
-
-          event.push(*itRank,1,msg);
-        }
-        client->sendEvent(event);
-      }
-      else client->sendEvent(event);
-    }
+      std::list<CMessage> msgs;
+
+      const std::list<int>& ranks = client->getRanksServerLeader();
+      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+      {
+        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
+        const int ibegin_srv = serverIndexBegin[*itRank][0];
+        const int jbegin_srv = serverIndexBegin[*itRank][1];
+        const int ni_srv = serverDimensionSizes[*itRank][0];
+        const int nj_srv = serverDimensionSizes[*itRank][1];
+
+        msgs.push_back(CMessage());
+        CMessage& msg = msgs.back();
+        msg << this->getId() ;
+        msg << isUnstructed_;
+        msg << ni_srv << ibegin_srv << nj_srv << jbegin_srv;
+        msg << ni_glo.getValue() << nj_glo.getValue();
+        msg << isCompressible_;
+
+        event.push(*itRank,1,msg);
+      }
+      client->sendEvent(event);
+    }
+    else client->sendEvent(event);
   }
   CATCH_DUMP_ATTR
@@ -2206,5 +2209,5 @@
     Send area from client to connected client(s)
   */
-  void CDomain::sendArea()
+  void CDomain::sendArea(CContextClient* client)
   TRY
   {
@@ -2212,42 +2215,36 @@
 
     int ns, n, i, j, ind, nv, idx;
-    std::list<CContextClient*>::iterator it;
-
-    for (it=clients.begin(); it!=clients.end(); ++it)
+    int serverSize = client->serverSize;
+
+    // send area for each connected server
+    CEventClient eventArea(getType(), EVENT_ID_AREA);
+
+    list<CMessage> list_msgsArea;
+    list<CArray<double,1> > list_area;
+
+    std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
+    iteMap = indSrv_[serverSize].end();
+    for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
     {
-      CContextClient* client = *it;
-      int serverSize = client->serverSize;
-
-      // send area for each connected server
-      CEventClient eventArea(getType(), EVENT_ID_AREA);
-
-      list<CMessage> list_msgsArea;
-      list<CArray<double,1> > list_area;
-
-      std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
-      iteMap = indSrv_[serverSize].end();
-      for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
-      {
-        int nbData = 0;
-        int rank = connectedServerRank_[serverSize][k];
-        it = indSrv_[serverSize].find(rank);
-        if (iteMap != it)
-          nbData = it->second.size();
-        list_area.push_back(CArray<double,1>(nbData));
-
-        const std::vector<size_t>& temp = it->second;
-        for (n = 0; n < nbData; ++n)
-        {
-          idx = static_cast<int>(it->second[n]);
-          list_area.back()(n) = areavalue(globalLocalIndexMap_[idx]);
-        }
-
-        list_msgsArea.push_back(CMessage());
-        list_msgsArea.back() << this->getId() << hasArea;
-        list_msgsArea.back() << list_area.back();
-        eventArea.push(rank, nbSenders[serverSize][rank], list_msgsArea.back());
-      }
-      client->sendEvent(eventArea);
-    }
+      int nbData = 0;
+      int rank = connectedServerRank_[serverSize][k];
+      it = indSrv_[serverSize].find(rank);
+      if (iteMap != it)
+        nbData = it->second.size();
+      list_area.push_back(CArray<double,1>(nbData));
+
+      const std::vector<size_t>& temp = it->second;
+      for (n = 0; n < nbData; ++n)
+      {
+        idx = static_cast<int>(it->second[n]);
+        list_area.back()(n) = areavalue(globalLocalIndexMap_[idx]);
+      }
+
+      list_msgsArea.push_back(CMessage());
+      list_msgsArea.back() << this->getId() << hasArea;
+      list_msgsArea.back() << list_area.back();
+      eventArea.push(rank, nbSenders[serverSize][rank], list_msgsArea.back());
+    }
+    client->sendEvent(eventArea);
   }
   CATCH_DUMP_ATTR
@@ -2258,5 +2255,5 @@
     Because longitude and latitude are optional, this function only called if latitude and longitude exist
   */
-  void CDomain::sendLonLat()
+  void CDomain::sendLonLat(CContextClient* client)
   TRY
   {
@@ -2264,87 +2261,82 @@
 
     int ns, n, i, j, ind, nv, idx;
-    std::list<CContextClient*>::iterator it;
-    for (it=clients.begin(); it!=clients.end(); ++it)
+    int serverSize = client->serverSize;
+
+    // send lon lat for each connected server
+    CEventClient eventLon(getType(), EVENT_ID_LON);
+    CEventClient eventLat(getType(), EVENT_ID_LAT);
+
+    list<CMessage> list_msgsLon, list_msgsLat;
+    list<CArray<double,1> > list_lon, list_lat;
+    list<CArray<double,2> > list_boundslon, list_boundslat;
+
+    std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
+    iteMap = indSrv_[serverSize].end();
+    for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
     {
-      CContextClient* client = *it;
-      int serverSize = client->serverSize;
-
-      // send lon lat for each connected server
-      CEventClient eventLon(getType(), EVENT_ID_LON);
-      CEventClient eventLat(getType(), EVENT_ID_LAT);
-
-      list<CMessage> list_msgsLon, list_msgsLat;
-      list<CArray<double,1> > list_lon, list_lat;
-      list<CArray<double,2> > list_boundslon, list_boundslat;
-
-      std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
-      iteMap = indSrv_[serverSize].end();
-      for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
-      {
-        int nbData = 0;
-        int rank = connectedServerRank_[serverSize][k];
-        it = indSrv_[serverSize].find(rank);
-        if (iteMap != it)
-          nbData = it->second.size();
-
-        list_lon.push_back(CArray<double,1>(nbData));
-        list_lat.push_back(CArray<double,1>(nbData));
+      int nbData = 0;
+      int rank = connectedServerRank_[serverSize][k];
+      it = indSrv_[serverSize].find(rank);
+      if (iteMap != it)
+        nbData = it->second.size();
+
+      list_lon.push_back(CArray<double,1>(nbData));
+      list_lat.push_back(CArray<double,1>(nbData));
+
+      if (hasBounds)
+      {
+        list_boundslon.push_back(CArray<double,2>(nvertex, nbData));
+        list_boundslat.push_back(CArray<double,2>(nvertex, nbData));
+      }
+
+      CArray<double,1>& lon = list_lon.back();
+      CArray<double,1>& lat = list_lat.back();
+      const std::vector<size_t>& temp = it->second;
+      for (n = 0; n < nbData; ++n)
+      {
+        idx = static_cast<int>(it->second[n]);
+        int localInd = globalLocalIndexMap_[idx];
+        lon(n) = lonvalue(localInd);
+        lat(n) = latvalue(localInd);
 
         if (hasBounds)
         {
-          list_boundslon.push_back(CArray<double,2>(nvertex, nbData));
-          list_boundslat.push_back(CArray<double,2>(nvertex, nbData));
-        }
-
-        CArray<double,1>& lon = list_lon.back();
-        CArray<double,1>& lat = list_lat.back();
-        const std::vector<size_t>& temp = it->second;
-        for (n = 0; n < nbData; ++n)
-        {
-          idx = static_cast<int>(it->second[n]);
-          int localInd = globalLocalIndexMap_[idx];
-          lon(n) = lonvalue(localInd);
-          lat(n) = latvalue(localInd);
-
-          if (hasBounds)
+          CArray<double,2>& boundslon = list_boundslon.back();
+          CArray<double,2>& boundslat = list_boundslat.back();
+
+          for (nv = 0; nv < nvertex; ++nv)
           {
-            CArray<double,2>& boundslon = list_boundslon.back();
-            CArray<double,2>& boundslat = list_boundslat.back();
-
-            for (nv = 0; nv < nvertex; ++nv)
-            {
-              boundslon(nv, n) = bounds_lonvalue(nv, localInd);
-              boundslat(nv, n) = bounds_latvalue(nv, localInd);
-            }
+            boundslon(nv, n) = bounds_lonvalue(nv, localInd);
+            boundslat(nv, n) = bounds_latvalue(nv, localInd);
           }
         }
-
-        list_msgsLon.push_back(CMessage());
-        list_msgsLat.push_back(CMessage());
-
-        list_msgsLon.back() << this->getId() << hasLonLat;
-        if (hasLonLat) 
-          list_msgsLon.back() << list_lon.back();
-        list_msgsLon.back()  << hasBounds;
-        if (hasBounds)
-        {
-          list_msgsLon.back() << list_boundslon.back();
-        }
-
-        list_msgsLat.back() << this->getId() << hasLonLat;
-        if (hasLonLat)
-          list_msgsLat.back() << list_lat.back();
-        list_msgsLat.back() << hasBounds;
-        if (hasBounds)
-        {          
-          list_msgsLat.back() << list_boundslat.back();
-        }
-
-        eventLon.push(rank, nbSenders[serverSize][rank], list_msgsLon.back());
-        eventLat.push(rank, nbSenders[serverSize][rank], list_msgsLat.back());
-      }
-      client->sendEvent(eventLon);
-      client->sendEvent(eventLat);
-    }
+      }
+
+      list_msgsLon.push_back(CMessage());
+      list_msgsLat.push_back(CMessage());
+
+      list_msgsLon.back() << this->getId() << hasLonLat;
+      if (hasLonLat) 
+        list_msgsLon.back() << list_lon.back();
+      list_msgsLon.back()  << hasBounds;
+      if (hasBounds)
+      {
+        list_msgsLon.back() << list_boundslon.back();
+      }
+
+      list_msgsLat.back() << this->getId() << hasLonLat;
+      if (hasLonLat)
+        list_msgsLat.back() << list_lat.back();
+      list_msgsLat.back() << hasBounds;
+      if (hasBounds)
+      {          
+        list_msgsLat.back() << list_boundslat.back();
+      }
+
+      eventLon.push(rank, nbSenders[serverSize][rank], list_msgsLon.back());
+      eventLat.push(rank, nbSenders[serverSize][rank], list_msgsLat.back());
+    }
+    client->sendEvent(eventLon);
+    client->sendEvent(eventLat);
   }
   CATCH_DUMP_ATTR
@@ -2356,73 +2348,67 @@
     The compressed index are represented with 1 and others are represented with -1
   */
-  void CDomain::sendDataIndex()
+  void CDomain::sendDataIndex(CContextClient* client)
   TRY
   {
     int ns, n, i, j, ind, nv, idx;
-    std::list<CContextClient*>::iterator it;
-    for (it=clients.begin(); it!=clients.end(); ++it)
+    int serverSize = client->serverSize;
+
+    // send area for each connected server
+    CEventClient eventDataIndex(getType(), EVENT_ID_DATA_INDEX);
+
+    list<CMessage> list_msgsDataIndex;
+    list<CArray<int,1> > list_data_i_index, list_data_j_index;
+
+    int nbIndex = i_index.numElements();
+    int niByIndex = max(i_index) - min(i_index) + 1;
+    int njByIndex = max(j_index) - min(j_index) + 1; 
+    int dataIindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : niByIndex;
+    int dataJindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : njByIndex;
+
+    
+    CArray<int,1> dataIIndex(nbIndex), dataJIndex(nbIndex);
+    dataIIndex = -1; 
+    dataJIndex = -1;
+    ind = 0;
+
+    for (idx = 0; idx < data_i_index.numElements(); ++idx)
     {
-      CContextClient* client = *it;
-
-      int serverSize = client->serverSize;
-
-      // send area for each connected server
-      CEventClient eventDataIndex(getType(), EVENT_ID_DATA_INDEX);
-
-      list<CMessage> list_msgsDataIndex;
-      list<CArray<int,1> > list_data_i_index, list_data_j_index;
-
-      int nbIndex = i_index.numElements();
-      int niByIndex = max(i_index) - min(i_index) + 1;
-      int njByIndex = max(j_index) - min(j_index) + 1; 
-      int dataIindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : niByIndex;
-      int dataJindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : njByIndex;
-
-      
-      CArray<int,1> dataIIndex(nbIndex), dataJIndex(nbIndex);
-      dataIIndex = -1; 
-      dataJIndex = -1;
-      ind = 0;
-
-      for (idx = 0; idx < data_i_index.numElements(); ++idx)
-      {
-        int dataIidx = data_i_index(idx) + data_ibegin;
-        int dataJidx = data_j_index(idx) + data_jbegin;
-        if ((0 <= dataIidx) && (dataIidx < dataIindexBound) &&
-            (0 <= dataJidx) && (dataJidx < dataJindexBound))
-        {
-          dataIIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //i_index(dataIidx);//dataIidx;
-          dataJIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //j_index(dataJidx);//          
-        }
-      }
-
-      std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
-      iteMap = indSrv_[serverSize].end();
-      for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
-      {
-        int nbData = 0;
-        int rank = connectedServerRank_[serverSize][k];
-        it = indSrv_[serverSize].find(rank);
-        if (iteMap != it)
-          nbData = it->second.size();
-        list_data_i_index.push_back(CArray<int,1>(nbData));
-        list_data_j_index.push_back(CArray<int,1>(nbData));
-
-        const std::vector<size_t>& temp = it->second;
-        for (n = 0; n < nbData; ++n)
-        {
-          idx = static_cast<int>(it->second[n]);
-          i = globalLocalIndexMap_[idx];
-          list_data_i_index.back()(n) = dataIIndex(i);
-          list_data_j_index.back()(n) = dataJIndex(i);
-        }
-
-        list_msgsDataIndex.push_back(CMessage());
-        list_msgsDataIndex.back() << this->getId();
-        list_msgsDataIndex.back() << list_data_i_index.back() << list_data_j_index.back();
-        eventDataIndex.push(rank, nbSenders[serverSize][rank], list_msgsDataIndex.back());
-      }
-      client->sendEvent(eventDataIndex);
-    }
+      int dataIidx = data_i_index(idx) + data_ibegin;
+      int dataJidx = data_j_index(idx) + data_jbegin;
+      if ((0 <= dataIidx) && (dataIidx < dataIindexBound) &&
+          (0 <= dataJidx) && (dataJidx < dataJindexBound))
+      {
+        dataIIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //i_index(dataIidx);//dataIidx;
+        dataJIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //j_index(dataJidx);//          
+      }
+    }
+
+    std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
+    iteMap = indSrv_[serverSize].end();
+    for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
+    {
+      int nbData = 0;
+      int rank = connectedServerRank_[serverSize][k];
+      it = indSrv_[serverSize].find(rank);
+      if (iteMap != it)
+        nbData = it->second.size();
+      list_data_i_index.push_back(CArray<int,1>(nbData));
+      list_data_j_index.push_back(CArray<int,1>(nbData));
+
+      const std::vector<size_t>& temp = it->second;
+      for (n = 0; n < nbData; ++n)
+      {
+        idx = static_cast<int>(it->second[n]);
+        i = globalLocalIndexMap_[idx];
+        list_data_i_index.back()(n) = dataIIndex(i);
+        list_data_j_index.back()(n) = dataJIndex(i);
+      }
+
+      list_msgsDataIndex.push_back(CMessage());
+      list_msgsDataIndex.back() << this->getId();
+      list_msgsDataIndex.back() << list_data_i_index.back() << list_data_j_index.back();
+      eventDataIndex.push(rank, nbSenders[serverSize][rank], list_msgsDataIndex.back());
+    }
+    client->sendEvent(eventDataIndex);
   }
   CATCH
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp	(revision 1870)
@@ -184,10 +184,17 @@
          void setTransformations(const TransMapTypes&);         
          void computeNGlobDomain();
-         void sendAttributes();
-         void sendIndex();
-         void sendDistributionAttributes();
-         void sendArea();
-         void sendLonLat();         
-         void sendDataIndex();
+         
+       public:
+         void sendDomainToFileServer(CContextClient* client) ;
+       private:
+         std::set<CContextClient*> sendDomainToFileServer_done_ ;
+       private:
+         
+         void sendAttributes(); // ym obsolete -> to be removed
+         void sendIndex(CContextClient* client);
+         void sendDistributionAttributes(CContextClient* client);
+         void sendArea(CContextClient* client);
+         void sendLonLat(CContextClient* client);         
+         void sendDataIndex(CContextClient* client);
          void convertLonLatValue();
          void fillInRectilinearLonLat();
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1870)
@@ -246,13 +246,11 @@
     if (opeDate <= currDate)
     {
-      for (map<int, CArray<size_t, 1> >::iterator it = grid_->outLocalIndexStoreOnClient_.begin(); it != grid_->outLocalIndexStoreOnClient_.end(); ++it)
+      auto& outLocalIndexStoreOnClient = grid_-> getOutLocalIndexStoreOnClient() ;
+      for (auto it = outLocalIndexStoreOnClient.begin(); it != outLocalIndexStoreOnClient.end(); ++it)
       {
         CArray<double,1> tmp;
         CArray<size_t,1>& indexTmp = it->second;
         *(rankBuffers[it->first]) >> tmp;
-        for (int idx = 0; idx < indexTmp.numElements(); ++idx)
-        {
-          recv_data_tmp(indexTmp(idx)) = tmp(idx);
-        }      
+        for (int idx = 0; idx < indexTmp.numElements(); ++idx) recv_data_tmp(indexTmp(idx)) = tmp(idx);
       }
     }
@@ -436,6 +434,6 @@
     else
     {
-      for (map<int, CArray<size_t, 1> >::iterator it = grid_->outLocalIndexStoreOnClient_.begin(); 
-                                                  it != grid_->outLocalIndexStoreOnClient_.end(); ++it)
+      auto& outLocalIndexStoreOnClient = grid_-> getOutLocalIndexStoreOnClient() ;
+      for (auto it = outLocalIndexStoreOnClient.begin(); it != outLocalIndexStoreOnClient.end(); ++it)
       {
         CArray<size_t,1>& indexTmp = it->second;
@@ -1025,4 +1023,48 @@
   CATCH_DUMP_ATTR
 
+  /*!
+   * Compute the required buffer size to send the fields data.
+   * \param [in/out] bufferSize Modifying the bufferSize for the client context
+   * \param [in/out] maxEventSize Modifying the maximum event size for the client context 
+   * \param [in] bufferForWriting True if buffers are used for sending data for writing
+   */  
+  void CField::setContextClientDataBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize, 
+                                              map<CContextClient*,map<int,size_t>>& maxEventSize, 
+                                              bool bufferForWriting)
+  {
+    auto& contextBufferSize = bufferSize[client] ;
+    auto& contextMaxEventSize = maxEventSize[client] ;
+    const std::map<int, size_t> mapSize = grid_->getDataBufferSize(client, getId(), bufferForWriting);
+    for(auto& it : mapSize )
+    {
+      // If contextBufferSize[it.first] does not exist, it will be zero-initialized
+      // so we can use it safely without checking for its existance
+      if (CXios::isOptPerformance) contextBufferSize[it.first] += it.second;
+      else if (contextBufferSize[it.first] < it.second) contextBufferSize[it.first] = it.second;
+
+      if (contextMaxEventSize[it.first] < it.second) contextMaxEventSize[it.first] = it.second;
+    }
+
+  }
+
+  void CField::setContextClientAttributesBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize, 
+                                                   map<CContextClient*,map<int,size_t>>& maxEventSize, 
+                                                   bool bufferForWriting)
+  {
+    auto& contextBufferSize = bufferSize[client] ;
+    auto& contextMaxEventSize = maxEventSize[client] ;
+    const std::map<int, size_t> mapSize = grid_->getAttributesBufferSize(client, bufferForWriting);
+    for(auto& it : mapSize )
+    {
+      // If contextBufferSize[it.first] does not exist, it will be zero-initialized
+      // so we can use it safely without checking for its existance
+      if (contextBufferSize[it.first] < it.second) contextBufferSize[it.first] = it.second;
+      if (contextMaxEventSize[it.first] < it.second) contextMaxEventSize[it.first] = it.second;
+    }
+
+  }
+
+
+// ym obsolete to be removed 
   std::map<int, StdSize> CField::getGridAttributesBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/)
   TRY
@@ -1032,4 +1074,5 @@
   CATCH_DUMP_ATTR
 
+// ym obsolete to be removed 
   std::map<int, StdSize> CField::getGridDataBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/)
   TRY
@@ -1038,4 +1081,6 @@
   }
   CATCH_DUMP_ATTR
+
+
 
   size_t CField::getGlobalWrittenSize()
@@ -1172,5 +1217,9 @@
   }
    
-  
+  /*!
+   * Connect field to filter to send data to server. A temporal filter is inserted before accordingly to the 
+   * output frequency of the file
+   * \param gc the garbage collector to use when building the filter graph
+   */
   void CField::connectToFileServer(CGarbageCollector& gc)
   {
@@ -1181,4 +1230,7 @@
   } 
 
+  /*!
+   * Compute grid index needed to send grid and data to server
+   */
   void CField::computeGridIndexToFileServer(void)
   {
@@ -1186,5 +1238,18 @@
   }
 
-   /*!
+  /*!
+   * Connect field to a source filter to receive data from model.
+   */
+  void CField::connectToModelInput(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);
+
+    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) ;
+  } 
+ 
+  /*!
    * Transform the grid_path attribut into vector of grid.
    * \return the vector CGrid* containing the list of grid path for tranformation
@@ -1231,5 +1296,5 @@
    *                     read by the client or/and written to a file
    */
-
+   // ym obselete : to be removed later....
   void CField::buildFilterGraph(CGarbageCollector& gc, bool enableOutput)
   TRY
@@ -1888,4 +1953,14 @@
   CATCH
 
+  
+  void CField::sendFieldToFileServer(void)
+  {
+    CContext::getCurrent()->sendContextToFileServer(client);
+    fileOut_->sendFileToFileServer(client);
+    grid_->sendGridToFileServer(client);
+    this->sendAllAttributesToServer(client);
+    this->sendAddAllVariables(client);
+  }
+
   void CField::sendAddAllVariables(CContextClient* client)
   TRY
@@ -1916,4 +1991,7 @@
       grid_ref=grid_->getId() ;
       SuperClass::sendAllAttributesToServer(client) ;
+      domain_ref.reset() ;
+      axis_ref.reset() ;
+      scalar_ref.reset() ;
       grid_ref.reset();
     }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp	(revision 1870)
@@ -142,4 +142,6 @@
          void sendGridOfEnabledFields();
          void sendGridComponentOfEnabledFields();
+
+         void sendFieldToFileServer(void) ;
 
          /// VÃ©rifications ///
@@ -224,5 +226,13 @@
 
         void connectToFileServer(CGarbageCollector& gc) ;
+        void connectToModelInput(CGarbageCollector& gc) ;
         void computeGridIndexToFileServer(void) ;
+
+        void setContextClientDataBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize, 
+                                        map<CContextClient*,map<int,size_t>>& maxEventSize, 
+                                        bool bufferForWriting) ;
+        void setContextClientAttributesBufferSize(map<CContextClient*,map<int,size_t>>& bufferSize, 
+                                                 map<CContextClient*,map<int,size_t>>& maxEventSize, 
+                                                 bool bufferForWriting) ;
       private:
         std::vector<CGrid*> getGridPath(void) ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.cpp	(revision 1870)
@@ -1345,4 +1345,24 @@
    CATCH_DUMP_ATTR
 
+
+  
+   /*!
+    * Send file attribute, related variable and chield field tree to a given file server.
+    * \param[in] client : the context client where to send file
+    */
+   void CFile::sendFileToFileServer(CContextClient* client)
+   TRY
+   {
+     if (sendFileToFileServer_done_.count(client)!=0) return ;
+     else sendFileToFileServer_done_.insert(client) ;
+     
+     StdString fileDefRoot("file_definition");
+     CFileGroup* cfgrpPtr = CFileGroup::get(fileDefRoot);
+     cfgrpPtr->sendCreateChild(this->getId(), client);
+     this->sendAllAttributesToServer(client);
+     this->sendAddAllVariables(client);
+     for(auto field : enabledFields) this->sendAddField(field->getId(), client);
+   }
+   CATCH_DUMP_ATTR
    /*!
    \brief Dispatch event received from client
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.hpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.hpp	(revision 1870)
@@ -142,5 +142,10 @@
          void sendAddVariableGroup(const string& id, CContextClient* client);
          void sendAddAllVariables(CContextClient* client);
-         
+      public:
+         void sendFileToFileServer(CContextClient* client) ;
+      private:
+         std::set<CContextClient*> sendFileToFileServer_done_ ;
+
+      public:
          // Receive info from client
          static void recvAddField(CEventServer& event);
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1870)
@@ -33,5 +33,5 @@
       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
       , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_()
-	  , isDataDistributed_(true), isCompressible_(false)
+	    , isCompressible_(false)
       , transformations_(0), isTransformed_(false)
       , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
@@ -54,5 +54,5 @@
       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
       , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_()
-	  , isDataDistributed_(true), isCompressible_(false)
+	    , isCompressible_(false)
       , transformations_(0), isTransformed_(false)
       , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
@@ -96,5 +96,5 @@
      if (!isScalarGrid())
      {
-       std::vector<int> dataNindex = getDistributionClient()->getDataNIndex();
+       std::vector<int> dataNindex = getClientDistribution()->getDataNIndex();
        for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];       
      }
@@ -128,5 +128,5 @@
      for (size_t i = 0; i < axisList.size(); ++i)
      {
-       std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),axisPositionInGrid_[i]);
+       std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),getAxisPositionInGrid()[i]);
        for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it)
        {
@@ -202,4 +202,21 @@
    CATCH_DUMP_ATTR
    
+
+   void CGrid::computeAxisPositionInGrid(void)
+   {
+     axisPositionInGrid_.resize(0);
+     int idx = 0;
+     for (int i = 0; i < axis_domain_order.numElements(); ++i)
+     {
+       int elementDimension = axis_domain_order(i);
+       if (1 == elementDimension)
+       {
+         axisPositionInGrid_.push_back(idx);
+         ++idx;
+       }
+       else if (2 == elementDimension) idx += 2;
+     }
+   }
+
    void CGrid::checkAttributesAfterTransformation()
    TRY
@@ -207,25 +224,7 @@
       setAxisList();
       std::vector<CAxis*> axisListP = this->getAxis();
-      if (!axisListP.empty())
-      {
-        int idx = 0;
-        axisPositionInGrid_.resize(0);
-        for (int i = 0; i < axis_domain_order.numElements(); ++i)
-        {
-          int elementDimension = axis_domain_order(i);
-          if (1 == elementDimension)
-          {
-            axisPositionInGrid_.push_back(idx);
-            ++idx;
-          }
-          else if (2 == elementDimension) idx += 2;
-        }
-
-        for (int i = 0; i < axisListP.size(); ++i)
-        {
-          axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(),axisPositionInGrid_[i]);
-        }
-      }
-
+      for (int i = 0; i < axisListP.size(); ++i)
+        axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(), getAxisPositionInGrid()[i]);
+   
       setDomainList();
       std::vector<CDomain*> domListP = this->getDomains();
@@ -568,21 +567,8 @@
       if (!axisListP.empty())
       {
-        int idx = 0;
-        axisPositionInGrid_.resize(0);
-        for (int i = 0; i < axis_domain_order.numElements(); ++i)
-        {
-          int elementDimension = axis_domain_order(i);
-          if (1 == elementDimension)
-          {
-            axisPositionInGrid_.push_back(idx);
-            ++idx;
-          }
-          else if (2 == elementDimension) idx += 2;
-        }
-
         for (int i = 0; i < axisListP.size(); ++i)
         {
           if (sendAtt)
-            axisListP[i]->sendCheckedAttributes(getGlobalDimension(),axisPositionInGrid_[i]);
+            axisListP[i]->sendCheckedAttributes(getGlobalDimension(),getAxisPositionInGrid()[i]);
           else
             axisListP[i]->checkAttributesOnClient();
@@ -634,5 +620,5 @@
 
       size_t nbWritten = 0, indGlo;
-      CDistributionClient::GlobalLocalDataMap& globalDataIndex = getDistributionClient()->getGlobalDataIndexOnClient();
+      CDistributionClient::GlobalLocalDataMap& globalDataIndex = getClientDistribution()->getGlobalDataIndexOnClient();
       CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(),
                                                               ite = globalDataIndex.end(), it;    
@@ -651,5 +637,5 @@
       {
         numberWrittenIndexes_ = nbWritten;
-        if (isDataDistributed_)
+        if (isDataDistributed())
         {
           CContext* context = CContext::getCurrent();      
@@ -688,15 +674,7 @@
    void CGrid::computeGridIndexToFileServer(CContextClient* client)
    {
-     if (isScalarGrid())
-     {
-       computeClientIndexScalarGrid();
-       computeConnectedClientsScalarGrid(client);
-     }
-     else
-     {
-       computeClientIndex();
-       computeConnectedClients(client);
-     }
-
+     if (isScalarGrid()) computeConnectedClientsScalarGrid(client);
+     else computeConnectedClients(client);
+    
      // compute indices for client/server transfer for domain
      for (const auto& domainId : domList_) CDomain::get(domainId)->computeConnectedClients(client);
@@ -705,14 +683,5 @@
      // compute indices for client/server transfer for axis
      std::vector<CAxis*> axisList = this->getAxis();
-     std::vector<int> axisPosInGrid ;
-     // compute axis position in grid     
-     int idx=0 ;
-     for (int i = 0 ; i < axis_domain_order.numElements(); ++i)
-     {
-       if (axis_domain_order(i) == 0)  idx += 0 ;
-       else if (axis_domain_order(i) == 1) { axisPosInGrid.push_back(idx) ; ++idx; }
-       else if (axis_domain_order(i) == 2) idx += 2;
-     }
-     for(int i=0 ; i<axisList.size(); i++) axisList[i] -> computeConnectedClients(client, getGlobalDimension(),axisPositionInGrid_[i]) ;
+     for(int i=0 ; i<axisList.size(); i++) axisList[i] -> computeConnectedClients(client, getGlobalDimension(),getAxisPositionInGrid()[i]) ;
    }
    //---------------------------------------------------------------
@@ -740,5 +709,5 @@
      else
      {
-       CDistributionClient* clientDistribution = getDistributionClient() ;
+       CDistributionClient* clientDistribution = getClientDistribution() ;
        const std::vector<int>& localDataIndex = clientDistribution->getLocalDataIndexOnClient() ;
        int nbStoreIndex = localDataIndex.size() ;
@@ -759,5 +728,5 @@
      else
      {
-       CDistributionClient* clientDistribution = getDistributionClient() ;
+       CDistributionClient* clientDistribution = getClientDistribution() ;
        const std::vector<bool>& localMaskIndex = clientDistribution->getLocalMaskIndexOnClient() ;
        int nbMaskIndex = localMaskIndex.size() ;
@@ -767,74 +736,67 @@
    }
 
-   /*
-     Compute the global index and its local index taking account mask and data index.
-     These global indexes will be used to compute the connection of this client (sender) to its servers (receivers)
-     (via function computeConnectedClient)
-     These global indexes also correspond to data sent to servers (if any)
-   */
-   void CGrid::computeClientIndex()
-   TRY
-   {
-     if (computeClientIndex_done_) return ;
-
-     CContext* context = CContext::getCurrent();
-     int rank = context-> getIntraCommRank();
-
-     auto clientDistribution = getDistributionClient();
-     // Get local data index on client
-     int nbStoreIndex = clientDistribution->getLocalDataIndexOnClient().size();
-     int nbStoreGridMask = clientDistribution->getLocalMaskIndexOnClient().size();
-     // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise
-     storeIndex_client_.resize(nbStoreIndex);
-     storeMask_client_.resize(nbStoreGridMask);
-     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client_(idx) = (clientDistribution->getLocalDataIndexOnClient())[idx];
-     for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client_(idx) = (clientDistribution->getLocalMaskIndexOnClient())[idx];
-
-     if (0 == serverDistribution_) isDataDistributed_= clientDistribution->isDataDistributed();
-     else
-     {
-        // Mapping global index received from clients to the storeIndex_client_
-        CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution->getGlobalDataIndexOnClient();
-        CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end();
-        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient_.begin(),
-                                               ite = outGlobalIndexFromClient_.end(), it;
-
-        for (it = itb; it != ite; ++it)
+
+  void CGrid::computeOutLocalIndexStoreOnClient(void)
+  {
+    if (computeOutLocalIndexStoreOnClient_done_) return ;
+    else computeOutLocalIndexStoreOnClient_done_=true ;
+
+    if (isScalarGrid())
+    {
+        auto& outGlobalIndexFromClient  = getOutGlobalIndexFromClient();
+        auto itb = outGlobalIndexFromClient.begin(), ite = outGlobalIndexFromClient.end() ;
+        for (auto it = itb; it != ite; ++it)
         {
           int rank = it->first;
-          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient_[rank];
+          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];
           outLocalIndexStoreOnClient_.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));
           CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient_[rank];
-          size_t nbIndex = 0;
-
-          // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance
-          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
-          {
-            if (itGloe != globalDataIndex.find(globalIndex(idx)))
-            {
-              ++nbIndex;
-            }
-          }
-
-          if (nbIndex != localIndex.numElements())
-               ERROR("void CGrid::computeClientIndex()",
-                  << "Number of local index on client is different from number of received global index"
-                  << "Rank of sent client " << rank <<"."
-                  << "Number of local index " << nbIndex << ". "
-                  << "Number of received global index " << localIndex.numElements() << ".");
-
-          nbIndex = 0;
-          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
-          {
-            if (itGloe != globalDataIndex.find(globalIndex(idx)))
-            {
-              localIndex(idx) = globalDataIndex[globalIndex(idx)];
-            }
-          }
+          if (1 != globalIndex.numElements())
+            ERROR("void CGrid::computeClientIndexScalarGrid()",
+              << "Something wrong happened. "
+              << "Number of received global index on scalar grid should equal to 1" 
+              << "Number of received global index " << globalIndex.numElements() << ".");
+
+          localIndex(0) = globalIndex(0);
         }
-      }
-      computeClientIndex_done_ = true ;
-   }
-   CATCH_DUMP_ATTR
+    }
+    else
+    {
+      CDistributionClient::GlobalLocalDataMap& globalDataIndex = getClientDistribution()->getGlobalDataIndexOnClient();
+      CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end();
+      auto& outGlobalIndexFromClient  = getOutGlobalIndexFromClient();
+      auto itb = outGlobalIndexFromClient.begin(), ite = outGlobalIndexFromClient.end() ;
+    
+      for (auto it = itb; it != ite; ++it)
+      {
+         int rank = it->first;
+         CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];
+         outLocalIndexStoreOnClient_.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));
+         CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient_[rank];
+         size_t nbIndex = 0;
+
+        // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance
+        for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
+          if (itGloe != globalDataIndex.find(globalIndex(idx))) ++nbIndex;
+
+        if (nbIndex != localIndex.numElements())
+             ERROR("void CGrid::computeClientIndex()",
+                 << "Number of local index on client is different from number of received global index"
+                 << "Rank of sent client " << rank <<"."
+                 << "Number of local index " << nbIndex << ". "
+                 << "Number of received global index " << localIndex.numElements() << ".");
+
+        nbIndex = 0;
+        for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
+          if (itGloe != globalDataIndex.find(globalIndex(idx)))
+            localIndex(idx) = globalDataIndex[globalIndex(idx)];
+      }
+    }
+  }
+
+  bool CGrid::isDataDistributed(void) 
+  { 
+    return getClientDistribution()->isDataDistributed() ;
+  }
 
    /*!
@@ -845,4 +807,5 @@
    {
      if (computeConnectedClients_done_.count(client)!=0) return ;
+     else  computeConnectedClients_done_.insert(client) ;
 
      CContext* context = CContext::getCurrent();
@@ -868,5 +831,5 @@
           if (client->isServerLeader())
           {
-            size_t ssize = getDistributionClient()->getLocalDataIndexOnClient().size();
+            size_t ssize = getClientDistribution()->getLocalDataIndexOnClient().size();
             const std::list<int>& ranks = client->getRanksServerLeader();
             for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
@@ -899,5 +862,5 @@
          computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]);
 
-       const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getDistributionClient()->getGlobalLocalDataSendToServer();
+       const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getClientDistribution()->getGlobalLocalDataSendToServer();
        CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
@@ -956,5 +919,4 @@
        nbSenders_[receiverSize] = CClientServerMapping::computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]);
      }
-     computeConnectedClients_done_.insert(client) ;
    }
    CATCH_DUMP_ATTR
@@ -975,5 +937,5 @@
      if (isScalarGrid())
      {
-       computeClientIndexScalarGrid();
+       //computeClientIndexScalarGrid();
        if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
        {
@@ -983,5 +945,5 @@
      else
      {
-       computeClientIndex();
+       //computeClientIndex();
        if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
        {
@@ -1430,5 +1392,5 @@
    TRY
    {
-      const std::vector<int>& localMaskedDataIndex = getDistributionClient()->getLocalMaskedDataIndexOnClient();
+      const std::vector<int>& localMaskedDataIndex = getClientDistribution()->getLocalMaskedDataIndexOnClient();
       const int size = localMaskedDataIndex.size();
       for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i];
@@ -1436,42 +1398,5 @@
    CATCH
 
-  void CGrid::computeClientIndexScalarGrid()
-  TRY
-  {
-    if (computeClientIndexScalarGrid_done_) return ;
-
-    CContext* context = CContext::getCurrent();    
-    {
-      int rank = context->intraCommRank_;
-
-      auto clientDistribution = getDistributionClient();
-
-      storeIndex_client_.resize(1);
-      storeIndex_client_(0) = 0;      
-
-      if (0 != serverDistribution_)
-      {
-        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient_.begin(),
-                                               ite = outGlobalIndexFromClient_.end(), it;
-        for (it = itb; it != ite; ++it)
-        {
-          int rank = it->first;
-          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient_[rank];
-          outLocalIndexStoreOnClient_.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));
-          CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient_[rank];
-          if (1 != globalIndex.numElements())
-            ERROR("void CGrid::computeClientIndexScalarGrid()",
-              << "Something wrong happened. "
-              << "Number of received global index on scalar grid should equal to 1" 
-              << "Number of received global index " << globalIndex.numElements() << ".");
-
-          localIndex(0) = globalIndex(0);
-        }
-      }
-    }
-    computeClientIndexScalarGrid_done_ = true ;
-  }
-  CATCH_DUMP_ATTR
-
+  
   void CGrid::computeConnectedClientsScalarGrid(CContextClient* client)
   TRY
@@ -1523,5 +1448,5 @@
       }
     }
-    isDataDistributed_ = false;
+   
     computeConnectedClientsScalarGrid_done_.insert(client) ;
   }
@@ -1567,5 +1492,5 @@
 
           listMsg.push_back(CMessage());
-          listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
+          listMsg.back() << getId( )<< isCompressible_ << listOutIndex.back();
 
           event.push(rank, 1, listMsg.back());
@@ -1611,5 +1536,5 @@
       list<CMessage> listMsg;
       list<CArray<size_t,1> > listOutIndex;
-      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getDistributionClient()->getGlobalLocalDataSendToServer();
+      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getClientDistribution()->getGlobalLocalDataSendToServer();
       CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex,
                                                               iteIndex = globalLocalIndexSendToServer.end();
@@ -1639,5 +1564,5 @@
 
             listMsg.push_back(CMessage());
-            listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
+            listMsg.back() << getId() << isCompressible_ << listOutIndex.back();
 
             event.push(*itRank, 1, listMsg.back());
@@ -1707,5 +1632,5 @@
           storeIndex_fromSrv_.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
           listMsg.push_back(CMessage());
-          listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
+          listMsg.back() << getId()  << isCompressible_ << listOutIndex.back();
 
           event.push(rank, nbSenders_[receiverSize][rank], listMsg.back());
@@ -1766,5 +1691,5 @@
       CBufferIn& buffer = *buffers[n];
 
-      buffer >> isDataDistributed_ >> isCompressible_;
+      buffer >>  isCompressible_;
       size_t dataSize = 0;
 
@@ -2054,5 +1979,5 @@
   CATCH_DUMP_ATTR
 
-  CDistributionClient* CGrid::getDistributionClient()
+  CDistributionClient* CGrid::getClientDistribution()
   TRY
   {
@@ -2071,8 +1996,8 @@
     else if (0 != client)
     {
-      return  (isDataDistributed_ ||  (1 != client->clientSize) || (1 != client->serverSize));
+      return  (isDataDistributed() ||  (1 != client->clientSize) || (1 != client->serverSize));
     }
     else
-      return isDataDistributed_;    
+      return isDataDistributed();    
   }
   CATCH_DUMP_ATTR
@@ -2178,4 +2103,19 @@
    CATCH_DUMP_ATTR
 
+
+  void CGrid::sendGridToFileServer(CContextClient* client)
+  {
+    if (sendGridToFileServer_done_.count(client)!=0) return ;
+    else sendGridToFileServer_done_.insert(client) ;
+
+    StdString gridDefRoot("grid_definition");
+    CGridGroup* gridPtr = CGridGroup::get(gridDefRoot);
+    gridPtr->sendCreateChild(this->getId(),client);
+    this->sendAllAttributesToServer(client);
+    this->sendAllDomains(client);
+    this->sendAllAxis(client);
+    this->sendAllScalars(client);
+  }
+
    /*!
    \brief Send a message to create a domain on server side
@@ -2794,9 +2734,8 @@
   {
     std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
-    int dSize = domList.size();
-    for (int i = 0; i < dSize; ++i)
-    {
-      sendAddDomain(domList[i]->getId(),contextClient);
-      domList[i]->sendAllAttributesToServer(contextClient);
+    for (auto domain : domList)
+    {
+      sendAddDomain(domain->getId(),contextClient);
+      domain->sendDomainToFileServer(contextClient);
     }
   }
@@ -2810,10 +2749,8 @@
   {
     std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
-    int aSize = aList.size();
-
-    for (int i = 0; i < aSize; ++i)
+    for (int i=0; i<aList.size() ; ++i)
     {
       sendAddAxis(aList[i]->getId(),contextClient);
-      aList[i]->sendAllAttributesToServer(contextClient);
+      aList[i]->sendAxisToFileServer(contextClient, getGlobalDimension(), getAxisPositionInGrid()[i]);
     }
   }
@@ -2827,10 +2764,8 @@
   {
     std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
-    int sSize = sList.size();
-
-    for (int i = 0; i < sSize; ++i)
-    {
-      sendAddScalar(sList[i]->getId(),contextClient);
-      sList[i]->sendAllAttributesToServer(contextClient);
+    for (auto scalar : sList)
+    {
+      sendAddScalar(scalar->getId(),contextClient);
+      scalar->sendScalarToFileServer(contextClient);
     }
   }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1870)
@@ -146,4 +146,11 @@
          CAxis* addAxis(const std::string& id=StdString());
          CScalar* addScalar(const std::string& id=StdString());
+
+      public:
+         void sendGridToFileServer(CContextClient* client) ;
+      private:
+         std::set<CContextClient*> sendGridToFileServer_done_ ;
+      
+      public:
          void sendAddDomain(const std::string& id,CContextClient* contextClient);
          void sendAddAxis(const std::string& id,CContextClient* contextClient);
@@ -193,5 +200,4 @@
 
          CDistributionServer* getDistributionServer();
-         CDistributionClient* getDistributionClient();
          CGridTransformation* getTransformations();
 
@@ -231,9 +237,16 @@
 
          void computeGridIndexToFileServer(CContextClient* client) ;
-
-      private:
+ 
+     private:
+        /** Client-like distribution calculated based on the knowledge of the entire grid */
+       CDistributionClient* clientDistribution_;
+     public: 
        void computeClientDistribution(void) ;
+     private:
        bool computeClientDistribution_done_ = false ;
-
+     public:
+       CDistributionClient* getClientDistribution(void); 
+
+     private:
        template<int N>
        void checkGridMask(CArray<bool,N>& gridMask,
@@ -277,13 +290,6 @@
         int getDistributedDimension();
 
-       
-        void computeClientIndex();
-        bool computeClientIndex_done_ = false ;
-        
         void computeConnectedClients(CContextClient* client);
         set<CContextClient*> computeConnectedClients_done_ ;
-
-        void computeClientIndexScalarGrid(); 
-        bool computeClientIndexScalarGrid_done_ = false ;
 
         void computeConnectedClientsScalarGrid(CContextClient* client); 
@@ -346,14 +352,22 @@
 // Maybe we need a flag to determine whether a client wants to write. TODO "
 
-/** Map storing received data on server side. This map is the equivalent to the storeIndex_client, but for data received from client
-  * instead that from model. This map is used to concatenate data received from several clients into a single array on server side
-  * which match the local workflow grid.
-  * outLocalIndexStoreOnClient_[client_rank] -> Array of index from client of rank "client_rank"
-  * outLocalIndexStoreOnClient_[client_rank](index of buffer from client) -> local index of the workflow grid
-  * The map is created in CGrid::computeClientIndex and filled upon receiving data in CField::recvUpdateData().
-  * Symetrically it is also used to send data from a server to several client for reading case. */
-         map<int, CArray<size_t, 1> > outLocalIndexStoreOnClient_; 
-
-
+      private:
+       /** Map storing received data on server side. This map is the equivalent to the storeIndex_client, but for data received from client
+        * instead that from model. This map is used to concatenate data received from several clients into a single array on server side
+        * which match the local workflow grid.
+        * outLocalIndexStoreOnClient_[client_rank] -> Array of index from client of rank "client_rank"
+        * outLocalIndexStoreOnClient_[client_rank](index of buffer from client) -> local index of the workflow grid
+        * The map is created in CGrid::computeClientIndex and filled upon receiving data in CField::recvUpdateData().
+        * Symetrically it is also used to send data from a server to several client for reading case. */
+        map<int, CArray<size_t, 1>> outLocalIndexStoreOnClient_; 
+      public:
+         void computeOutLocalIndexStoreOnClient(void) ;
+      private:
+         bool computeOutLocalIndexStoreOnClient_done_ = false ;  
+      public:   
+         map<int, CArray<size_t, 1>>& getOutLocalIndexStoreOnClient(void) 
+         { if (!computeOutLocalIndexStoreOnClient_done_) computeOutLocalIndexStoreOnClient(); return outLocalIndexStoreOnClient_ ; }
+
+      public:
 /** Indexes calculated based on server-like distribution.
  *  They are used for writing/reading data and only calculated for server level that does the writing/reading.
@@ -370,4 +384,6 @@
          CArray<size_t,1> localIndexToWriteOnClient_;
 
+      public: 
+        bool isDataDistributed(void) ; 
       private:
 
@@ -376,11 +392,15 @@
         std::set<CContextClient*> clientsSet;
 
-/** Map storing received indexes on server side sent by clients. Key = sender rank, value = global index array. 
-    Later, the global indexes received will be mapped onto local index computed with the local distribution.
-    outGlobalIndexFromClient_[rank] -> array of global index send by client of rank "rank"
-    outGlobalIndexFromClient_[rank](n) -> global index of datav n sent by client
-*/
+      private:  
+        /** Map storing received indexes on server side sent by clients. Key = sender rank, value = global index array. 
+            Later, the global indexes received will be mapped onto local index computed with the local distribution.
+            outGlobalIndexFromClient_[rank] -> array of global index send by client of rank "rank"
+            outGlobalIndexFromClient_[rank](n) -> global index of datav n sent by client
+        */      
         map<int, CArray<size_t, 1> > outGlobalIndexFromClient_;
-
+      public:  
+        map<int, CArray<size_t, 1> >& getOutGlobalIndexFromClient() { return outGlobalIndexFromClient_ ;}
+
+      private:
         bool isChecked;
         bool isDomainAxisChecked;
@@ -393,7 +413,4 @@
         bool isAxisListSet, isDomListSet, isScalarListSet;
 
-/** Client-like distribution calculated based on the knowledge of the entire grid */
-        CDistributionClient* clientDistribution_;
-
 /** Server-like distribution calculated upon receiving indexes */
         CDistributionServer* serverDistribution_;
@@ -416,6 +433,5 @@
 /** Size of data to be send in case of reading. It is calculated in recvIndex(). */
         std::map<int,size_t> connectedDataSizeRead_;
-
-        bool isDataDistributed_;        
+      
          //! True if and only if the data defined on the grid can be outputted in a compressed way
         bool isCompressible_;
@@ -424,5 +440,10 @@
         bool isTransformed_, isGenerated_;
         bool computedWrittenIndex_;
+        
         std::vector<int> axisPositionInGrid_;
+        void computeAxisPositionInGrid(void) ;
+        bool computeAxisPositionInGrid_done_ = false ;
+        std::vector<int>& getAxisPositionInGrid(void) { if (!computeAxisPositionInGrid_done_) computeAxisPositionInGrid() ; return axisPositionInGrid_ ;}
+
         CGridTransformation* transformations_;
         bool hasDomainAxisBaseRef_;        
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp	(revision 1870)
@@ -188,4 +188,13 @@
   }
 
+  void CScalar::sendScalarToFileServer(CContextClient* client)
+  {
+    if (sendScalarToFileServer_done_.count(client)!=0) return ;
+    else sendScalarToFileServer_done_.insert(client) ;
+
+    StdString scalarDefRoot("scalar_definition");
+    CScalarGroup* scalarPtr = CScalarGroup::get(scalarDefRoot);
+    this->sendAllAttributesToServer(client);
+  }
   /*!
     Parse children nodes of a scalar in xml file.
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp	(revision 1870)
@@ -76,4 +76,9 @@
             void setCompleted(void) ;
             void setUncompleted(void) ;
+         
+         public:
+            void sendScalarToFileServer(CContextClient* client) ;
+         private:
+            std::set<CContextClient*> sendScalarToFileServer_done_ ;
 
          public:
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm_interpolate.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm_interpolate.cpp	(revision 1869)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm_interpolate.cpp	(revision 1870)
@@ -352,5 +352,5 @@
     this->transformationPosition_.resize(vecAxisValueSizeWithMask);
 
-    const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = grid->getDistributionClient()->getGlobalLocalDataSendToServer();
+    const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = grid->getClientDistribution()->getGlobalLocalDataSendToServer();
     CDistributionClient::GlobalLocalDataMap::const_iterator itIndex, iteIndex = globalLocalIndexSendToServer.end();
     size_t axisSrcSize = axisSrc_->index.numElements();
