Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution_client.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution_client.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution_client.cpp	(revision 1869)
@@ -396,4 +396,5 @@
 
   for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
+  localDataSize_=ssize ;
 
   localDataIndex_.resize(ssize);
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution_client.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution_client.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution_client.hpp	(revision 1869)
@@ -47,4 +47,5 @@
     const std::vector<int>& getLocalMaskedDataIndexOnClient();
 
+    size_t getLocalDataSize(void) { if (!isComputed_) createGlobalIndexSendToServer(); return localDataSize_ ;}
     std::vector<int> getNGlob() { return nGlob_; }
     std::vector<int> getDataNIndex() { return dataNIndex_; }
@@ -99,4 +100,6 @@
 
     std::vector<int> localMaskedDataIndex_;
+    //!< the size of local data of the grid
+    size_t localDataSize_ ;
 
   private:
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/source_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/source_filter.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/source_filter.cpp	(revision 1869)
@@ -34,5 +34,5 @@
     packet->status = CDataPacket::NO_ERROR;
 
-    packet->data.resize(grid->storeIndex_client_.numElements());    
+    packet->data.resize(grid->getStoreIndex_client().numElements());    
     
     if (compression)
@@ -85,5 +85,5 @@
             << " expected " << grid->storeIndex_fromSrv_.size() << " chunks but " << data.size() << " were given.");
 
-    packet->data.resize(grid->storeIndex_client_.numElements());
+    packet->data.resize(grid->getStoreIndex_client().numElements());
     std::map<int, CArray<double, 1> >::const_iterator it, itEnd = data.end();
     for (it = data.begin(); it != itEnd; it++)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/spatial_transform_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/spatial_transform_filter.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/spatial_transform_filter.cpp	(revision 1869)
@@ -174,5 +174,5 @@
         gridTransformation->computeAll(dataAuxInputs, packet->timestamp);
       }
-      packet->data.resize(gridTransformation->getGridDestination()->storeIndex_client_.numElements());
+      packet->data.resize(gridTransformation->getGridDestination()->getDataSize());
       if (0 != packet->data.numElements())
         (packet->data)(0) = defaultValue;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/interface/c/icfield.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/interface/c/icfield.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/interface/c/icfield.cpp	(revision 1869)
@@ -100,5 +100,5 @@
   {
      CTimer::get("XIOS").resume() ;
-     *domain_hdl_ret = field_hdl->grid->getDomain(domainIndex);
+     *domain_hdl_ret = field_hdl->getGrid()->getDomain(domainIndex);
      CTimer::get("XIOS").suspend();
   }
@@ -109,5 +109,5 @@
   {
      CTimer::get("XIOS").resume() ;
-     *axis_hdl_ret = field_hdl->grid->getAxis(axisIndex);
+     *axis_hdl_ret = field_hdl->getGrid()->getAxis(axisIndex);
      CTimer::get("XIOS").suspend();
   }
@@ -118,5 +118,5 @@
   {
      CTimer::get("XIOS").resume() ;
-     *scalar_hdl_ret = field_hdl->grid->getScalar(scalarIndex);
+     *scalar_hdl_ret = field_hdl->getGrid()->getScalar(scalarIndex);
      CTimer::get("XIOS").suspend();
   }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_input.cpp	(revision 1869)
@@ -48,5 +48,5 @@
     CContext* context = CContext::getCurrent();
 
-    CGrid* grid = field->grid;
+    CGrid* grid = field->getGrid();
 
     if (!grid->doGridHaveDataToWrite())
@@ -130,5 +130,5 @@
     StdString fieldId = field->getFieldOutputName();
 
-    CGrid* grid = field->grid;
+    CGrid* grid = field->getGrid();
 
     std::vector<CDomain*> domainP = grid->getDomains();
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_output.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_output.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/io/nc4_data_output.cpp	(revision 1869)
@@ -1805,5 +1805,5 @@
 
         std::vector<StdString> dims, coodinates;
-        CGrid* grid = field->grid;
+        CGrid* grid = field->getGrid();
         if (!grid->doGridHaveDataToWrite())
           if (SuperClass::type==MULTI_FILE) return ;
@@ -2346,5 +2346,5 @@
       {
         CContext* context = CContext::getCurrent();
-        CGrid* grid = field->grid;
+        CGrid* grid = field->getGrid();
 
         if (field->getNStep()<1) 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 1869)
@@ -274,4 +274,6 @@
    TRY
    {
+     if (checkAttributes_done_) return ;
+
      CContext* context=CContext::getCurrent();
 
@@ -318,25 +320,19 @@
       if (!this->value.isEmpty())
       {
-        // Avoid this check at writing because it fails in case of a hole
-        if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
-        {
-          StdSize true_size = value.numElements();
-          if (this->n.getValue() != true_size)
-            ERROR("CAxis::checkAttributes(void)",
-                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
-                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size
-                << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
-        }
+        StdSize true_size = value.numElements();
+        if (this->n.getValue() != true_size)
+          ERROR("CAxis::checkAttributes(void)",
+              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
+              << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size
+              << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
         this->hasValue = true;
       }
 
       this->checkBounds();
-
-      if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
-      {
-        this->checkMask();
-        this->checkData();
-        this->checkLabel();
-      }
+      this->checkMask();
+      this->checkData();
+      this->checkLabel();
+      
+      checkAttributes_done_ = true ;
    }
    CATCH_DUMP_ATTR
@@ -522,4 +518,5 @@
      Therefore, we should recheck them.
    */
+   // ym : obsolete to be removed
    void CAxis::checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid,
                                                           CServerDistributionDescription::ServerDistributionType distType)
@@ -531,7 +528,9 @@
      if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
      {        
+       /* suppressed because of interface changed
        if (orderPositionInGrid == CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), distType))
          computeConnectedClients(globalDim, orderPositionInGrid, distType);
        else if (index.numElements() != n_glo) computeConnectedClients(globalDim, orderPositionInGrid,  CServerDistributionDescription::ROOT_DISTRIBUTION);
+       */
      }
 
@@ -594,128 +593,131 @@
      \param [in] distType distribution type of the server. For now, we only have band distribution.
   */
-  void CAxis::computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid,
-                                     CServerDistributionDescription::ServerDistributionType distType)
-  TRY
-  {
+  void CAxis::computeConnectedClients(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid)
+  TRY
+  {
+    if (computeConnectedClients_done_.count(client)!=0) return ;
+    else computeConnectedClients_done_.insert(client) ;
+
     CContext* context = CContext::getCurrent();
-
-    set<int> listNbServer ;
-
-    for (auto client : clients)
-    {
-      int nbServer = client->serverSize;
-      int range, clientSize = client->clientSize;
-      int rank = client->clientRank;
-
-      if (listNbServer.find(nbServer)==listNbServer.end())
-      {
-        listNbServer.insert(nbServer) ;
- 
-        if (connectedServerRank_.find(nbServer) != connectedServerRank_.end())
-        {
-          nbSenders.erase(nbServer);
-          connectedServerRank_.erase(nbServer);
-        }
-
-        size_t ni = this->n.getValue();
-        size_t ibegin = this->begin.getValue();
-        size_t nbIndex = index.numElements();
-
-        // First of all, we should compute the mapping of the global index and local index of the current client
-        if (globalLocalIndexMap_.empty())
-        {
-          for (size_t idx = 0; idx < nbIndex; ++idx)
-          {
-            globalLocalIndexMap_[index(idx)] = idx;
-          }
-        }
-
-        // Calculate the compressed index if any
-//        std::set<int> writtenInd;
-//        if (isCompressible_)
-//        {
-//          for (int idx = 0; idx < data_index.numElements(); ++idx)
-//          {
-//            int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
-//
-//            if (ind >= 0 && ind < ni && mask(ind))
-//            {
-//              ind += ibegin;
-//              writtenInd.insert(ind);
-//            }
-//          }
-//        }
-
-        // Compute the global index of the current client (process) hold
-        std::vector<int> nGlobAxis(1);
-        nGlobAxis[0] = n_glo.getValue();
-
-        size_t globalSizeIndex = 1, indexBegin, indexEnd;
-        for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
-        indexBegin = 0;
-        if (globalSizeIndex <= clientSize)
-        {
-          indexBegin = rank%globalSizeIndex;
-          indexEnd = indexBegin;
-        }
-        else
-        {
-          for (int i = 0; i < clientSize; ++i)
-          {
-            range = globalSizeIndex / clientSize;
-            if (i < (globalSizeIndex%clientSize)) ++range;
-            if (i == client->clientRank) break;
-            indexBegin += range;
-          }
-          indexEnd = indexBegin + range - 1;
-        }
-
-        CArray<size_t,1> globalIndex(index.numElements());
-        for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
-          globalIndex(idx) = index(idx);
-
-        // Describe the distribution of server side
-
-        CServerDistributionDescription serverDescription(nGlobAxis, nbServer, distType);
-      
-        std::vector<int> serverZeroIndex;
-        serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0);
-
-        std::list<int> serverZeroIndexLeader;
-        std::list<int> serverZeroIndexNotLeader; 
-        CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
-        for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
-          *it = serverZeroIndex[*it];
-
-        // Find out the connection between client and server side
-        CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
-        clientServerMap->computeServerIndexMapping(globalIndex, nbServer);
-        CClientServerMapping::GlobalIndexMap& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();      
-
-        indSrv_[nbServer].swap(globalIndexAxisOnServer);
-
-        if (distType==CServerDistributionDescription::ROOT_DISTRIBUTION)
-        {
-          for(int i=1; i<nbServer; ++i) indSrv_[nbServer].insert(pair<int, vector<size_t> >(i,indSrv_[nbServer][0]) ) ;
-          serverZeroIndexLeader.clear() ;
-        }
-         
-        CClientServerMapping::GlobalIndexMap::const_iterator it  = indSrv_[nbServer].begin(),
-                                                             ite = indSrv_[nbServer].end();
-
-        for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first);
-
-        for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
-          connectedServerRank_[nbServer].push_back(*it);
-
-         // Even if a client has no index, it must connect to at least one server and 
-         // send an "empty" data to this server
-         if (connectedServerRank_[nbServer].empty())
-          connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize);
-
-        nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
-
-        delete clientServerMap;
-      }
+    CServerDistributionDescription::ServerDistributionType distType ;
+    int defaultDistributedPos = CServerDistributionDescription::defaultDistributedDimension(globalDim.size(), CServerDistributionDescription::BAND_DISTRIBUTION) ;
+    
+    if (orderPositionInGrid == defaultDistributedPos) distType =  CServerDistributionDescription::BAND_DISTRIBUTION ;
+    else if (index.numElements() != n_glo) distType =  CServerDistributionDescription::ROOT_DISTRIBUTION ;
+    else return ;
+
+    int nbServer = client->serverSize;
+    int range, clientSize = client->clientSize;
+    int rank = client->clientRank;
+
+    if (listNbServer_.count(nbServer) == 0)
+    {
+      listNbServer_.insert(nbServer) ;
+
+      if (connectedServerRank_.find(nbServer) != connectedServerRank_.end())
+      {
+        nbSenders.erase(nbServer);
+        connectedServerRank_.erase(nbServer);
+      }
+
+      size_t ni = this->n.getValue();
+      size_t ibegin = this->begin.getValue();
+      size_t nbIndex = index.numElements();
+
+      // First of all, we should compute the mapping of the global index and local index of the current client
+      if (globalLocalIndexMap_.empty())
+      {
+        for (size_t idx = 0; idx < nbIndex; ++idx)
+        {
+          globalLocalIndexMap_[index(idx)] = idx;
+        }
+      }
+
+      // Calculate the compressed index if any
+      //        std::set<int> writtenInd;
+      //        if (isCompressible_)
+      //        {
+      //          for (int idx = 0; idx < data_index.numElements(); ++idx)
+      //          {
+      //            int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni); 
+      //
+      //            if (ind >= 0 && ind < ni && mask(ind))
+      //            {
+      //              ind += ibegin;
+      //              writtenInd.insert(ind);
+      //            }
+      //          }
+      //        }
+
+      // Compute the global index of the current client (process) hold
+      std::vector<int> nGlobAxis(1);
+      nGlobAxis[0] = n_glo.getValue();
+
+      size_t globalSizeIndex = 1, indexBegin, indexEnd;
+      for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
+      indexBegin = 0;
+      if (globalSizeIndex <= clientSize)
+      {
+        indexBegin = rank%globalSizeIndex;
+        indexEnd = indexBegin;
+      }
+      else
+      {
+        for (int i = 0; i < clientSize; ++i)
+        {
+          range = globalSizeIndex / clientSize;
+          if (i < (globalSizeIndex%clientSize)) ++range;
+          if (i == client->clientRank) break;
+          indexBegin += range;
+        }
+        indexEnd = indexBegin + range - 1;
+      }
+
+      CArray<size_t,1> globalIndex(index.numElements());
+      for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
+        globalIndex(idx) = index(idx);
+
+      // Describe the distribution of server side
+
+      CServerDistributionDescription serverDescription(nGlobAxis, nbServer, distType);
+    
+      std::vector<int> serverZeroIndex;
+      serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0);
+
+      std::list<int> serverZeroIndexLeader;
+      std::list<int> serverZeroIndexNotLeader; 
+      CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
+      for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
+        *it = serverZeroIndex[*it];
+
+      // Find out the connection between client and server side
+      CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
+      clientServerMap->computeServerIndexMapping(globalIndex, nbServer);
+      CClientServerMapping::GlobalIndexMap& globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();      
+
+      indSrv_[nbServer].swap(globalIndexAxisOnServer);
+
+      if (distType==CServerDistributionDescription::ROOT_DISTRIBUTION)
+      {
+        for(int i=1; i<nbServer; ++i) indSrv_[nbServer].insert(pair<int, vector<size_t> >(i,indSrv_[nbServer][0]) ) ;
+        serverZeroIndexLeader.clear() ;
+      }
+       
+      CClientServerMapping::GlobalIndexMap::const_iterator it  = indSrv_[nbServer].begin(),
+                                                           ite = indSrv_[nbServer].end();
+
+      for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first);
+
+      for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
+        connectedServerRank_[nbServer].push_back(*it);
+
+       // Even if a client has no index, it must connect to at least one server and 
+       // send an "empty" data to this server
+       if (connectedServerRank_[nbServer].empty())
+        connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize);
+
+      nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
+
+      delete clientServerMap;
     }
   }
@@ -1431,4 +1433,41 @@
   CATCH_DUMP_ATTR
 
+/*!
+  \brief Check if a axis is completed
+  Before make any axis processing, we must be sure that all axis informations have
+  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
+  other context (coupling). So all direct reference of the axis (axis_ref) must be also completed
+  \return true if axis and axis reference are completed
+  */
+  bool CAxis::checkIfCompleted(void)
+  {
+    if (hasDirectAxisReference()) if (!getDirectAxisReference()->checkIfCompleted()) return false;
+    return isCompleted_ ;
+  }
+
+  /*!
+  \brief Set a axis as completed
+   When all information about a axis have been received, the axis is tagged as completed and is
+   suitable for processing
+  */
+  void CAxis::setCompleted(void)
+  {
+    if (hasDirectAxisReference()) getDirectAxisReference()->setCompleted() ;
+    isCompleted_=true ;
+  }
+
+  /*!
+  \brief Set a axis as uncompleted
+   When informations about a axis are expected from a grid reading from file or coupling, the axis is 
+   tagged as uncompleted and is not suitable for processing
+  */
+  void CAxis::setUncompleted(void)
+  {
+    if (hasDirectAxisReference()) getDirectAxisReference()->setUncompleted() ;
+    isCompleted_=false ;
+  }
+
+
+
   /*!
    * Go through the hierarchy to find the axis from which the transformations must be inherited
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 1869)
@@ -86,6 +86,5 @@
          void addRelFileCompressed(const StdString& filename);
 
-         /// VÃ©rifications ///
-         void checkAttributes(void);
+         
 
          /// Destructeur ///
@@ -102,4 +101,8 @@
 
          static bool dispatchEvent(CEventServer& event);         
+        
+         /// VÃ©rifications ///
+         void checkAttributes(void);
+         bool checkAttributes_done_ = false ;
          
          void checkAttributesOnClient();
@@ -121,4 +124,8 @@
          bool isEqual(CAxis* axis);
 
+         bool checkIfCompleted(void) ;
+         void setCompleted(void) ;
+         void setUncompleted(void) ;
+
       public: 
         bool hasValue;        
@@ -127,4 +134,9 @@
 
         CArray<int,1> localIndexToWriteOnServer;
+         
+         void computeConnectedClients(CContextClient* client, const std::vector<int>& globalDim, int orderPositionInGrid);
+         private: std::set<CContextClient*> computeConnectedClients_done_ ; public :
+         /** The number of server of a context client. Avoid to re-compute indice computed in a previous computeConnectedClient */
+         private: std::set<int> listNbServer_ ; public:
 
       private:
@@ -137,6 +149,5 @@
          void sendDistributionAttribute(const std::vector<int>& globalDim, int orderPositionInGrid,
                                         CServerDistributionDescription::ServerDistributionType distType);
-         void computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid,
-                                     CServerDistributionDescription::ServerDistributionType distType);
+         
 
          void sendNonDistributedAttributes(void);
@@ -157,4 +168,8 @@
          std::list<CContextClient*> clients;
          std::set<CContextClient*> clientsSet;
+
+         /** define if the axis is completed or not ie all attributes have been received before in case 
+             of grid reading from file or coupling */ 
+         bool isCompleted_=true ;  
 
          bool isChecked;
@@ -165,4 +180,5 @@
          //! True if and only if the data defined on the axis can be outputted in a compressed way
          bool isCompressible_;
+
          std::map<int, map<int,int> > nbSenders; // Mapping of number of communicating client to a server
          std::map<int, std::unordered_map<int, vector<size_t> > > indSrv_; // Global index of each client sent to server
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.cpp	(revision 1869)
@@ -730,5 +730,5 @@
 
      // Distribute files between secondary servers according to the data size
-     distributeFiles();
+     distributeFiles(this->enabledWriteModeFiles);
 
      // Check grid and calculate its distribution
@@ -852,12 +852,182 @@
    and the active fields (fields will be written onto active files)
    */
-
-   void CContext::closeDefinition(void)
+  void CContext::closeDefinition(void)
    TRY
    {
      CTimer::get("Context : close definition").resume() ;
+     
+     // create intercommunicator with servers. 
+     // not sure it is the good place to be called here 
+     createServerInterComm() ;
+
+
+     // After xml is parsed, there are some more works with post processing
+//     postProcessing();
+
+    // Make sure the calendar was correctly created
+    if (!calendar)
+      ERROR("CContext::postProcessing()", << "A calendar must be defined for the context \"" << getId() << "!\"")
+    else if (calendar->getTimeStep() == NoneDu)
+      ERROR("CContext::postProcessing()", << "A timestep must be defined for the context \"" << getId() << "!\"")
+    // Calendar first update to set the current date equals to the start date
+    calendar->update(0);
+
+    // RÃ©solution des hÃ©ritages descendants (cÃ d des hÃ©ritages de groupes)
+    // pour chacun des contextes.
+    solveDescInheritance(true);
+ 
+    // Solve inheritance for field to know if enabled or not.
+    for (auto field : CField::getAll()) field->solveRefInheritance();
+
+    // Check if some axis, domains or grids are eligible to for compressed indexed output.
+    // Warning: This must be done after solving the inheritance and before the rest of post-processing
+    // --> later ????    checkAxisDomainsGridsEligibilityForCompressedOutput();      
+
+      // Check if some automatic time series should be generated
+      // Warning: This must be done after solving the inheritance and before the rest of post-processing      
+
+    // The timeseries should only be prepared in client
+    prepareTimeseries();
+
+    //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers Ã  sortir.
+    findEnabledFiles();
+    findEnabledWriteModeFiles();
+    findEnabledReadModeFiles();
+    findEnabledCouplerIn();
+    findEnabledCouplerOut();
+    createCouplerInterCommunicator() ;
+
+    // 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);
+    findFieldsWithReadAccess();
+    const vector<CField*>& fieldWithReadAccess = fieldsWithReadAccess_ ;
+      
+// find all field potentially at workflow end
+    vector<CField*> endWorkflowFields ;
+    endWorkflowFields.reserve(fileOutField.size()+CouplerOutField.size()+fieldWithReadAccess.size()) ;
+    endWorkflowFields.insert(endWorkflowFields.end(),fileOutField.begin(), fileOutField.end()) ;
+    endWorkflowFields.insert(endWorkflowFields.end(),CouplerOutField.begin(), CouplerOutField.end()) ;
+    endWorkflowFields.insert(endWorkflowFields.end(),fieldWithReadAccess.begin(), fieldWithReadAccess.end()) ;
+
+    for(auto endWorkflowField : endWorkflowFields) endWorkflowField->buildWorkflowGraph(garbageCollector) ;
     
-    //
-    postProcessingGlobalAttributes();
+    // Distribute files between secondary servers according to the data size => assign a context to a file
+    if (serviceType_==CServicesManager::GATHERER) distributeFiles(this->enabledWriteModeFiles);
+    else if (serviceType_==CServicesManager::CLIENT) for(auto file : this->enabledWriteModeFiles) file->setContextClient(client) ;
+
+    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER)
+    {
+      for(auto field : fileOutField) 
+      {
+        field->connectToFileServer(garbageCollector) ; // connect the field to server filter
+        field->computeGridIndexToFileServer() ; // compute grid index for transfer to the server context
+      }
+    }
+    
+
+
+
+
+    // For now, only read files with client and only one level server
+    // if (hasClient && !hasServer) findEnabledReadModeFiles();      
+
+    // Find all enabled fields of each file      
+    findAllEnabledFieldsInFiles(this->enabledWriteModeFiles);
+    findAllEnabledFieldsInFiles(this->enabledReadModeFiles);
+
+    // For now, only read files with client and only one level server
+    // if (hasClient && !hasServer) 
+    //   findAllEnabledFieldsInFiles(this->enabledReadModeFiles);      
+
+    if (serviceType_==CServicesManager::CLIENT)
+    {
+      initReadFiles();
+      // Try to read attributes of fields in file then fill in corresponding grid (or domain, axis)
+      this->readAttributesOfEnabledFieldsInReadModeFiles();
+    }
+
+    // Only search and rebuild all reference objects of enable fields, don't transform
+    this->solveOnlyRefOfEnabledFields();
+
+    // Search and rebuild all reference object of enabled fields, and transform
+    this->solveAllRefOfEnabledFieldsAndTransform();
+
+    // Find all fields with read access from the public API
+    if (serviceType_==CServicesManager::CLIENT) findFieldsWithReadAccess();
+    // and solve the all reference for them
+    if (serviceType_==CServicesManager::CLIENT) solveAllRefOfFieldsWithReadAccess();
+
+    isPostProcessed = true;
+
+
+
+    // Distribute files between secondary servers according to the data size
+    distributeFiles(this->enabledWriteModeFiles);
+
+    // Check grid and calculate its distribution
+    checkGridEnabledFields();
+
+    setClientServerBuffer(client, (serviceType_==CServicesManager::CLIENT) ) ;
+    for (int i = 0; i < clientPrimServer.size(); ++i)
+         setClientServerBuffer(clientPrimServer[i], true);
+
+    
+    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER)
+    { 
+      if (serviceType_==CServicesManager::GATHERER)
+      { 
+        for (auto it=clientPrimServer.begin(); it!=clientPrimServer.end();++it) 
+        {
+          this->sendAllAttributesToServer(*it); // Send all attributes of current context to server
+          CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(*it); // Send all attributes of current calendar
+        }
+      }
+      else 
+      {
+        this->sendAllAttributesToServer(client);   // Send all attributes of current context to server
+        CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer(client); // Send all attributes of current calendar
+      }
+
+      // We have enough information to send to server
+      // First of all, send all enabled files
+      sendEnabledFiles(this->enabledWriteModeFiles);
+      // We only use server-level 1 (for now) to read data
+      if (serviceType_==CServicesManager::CLIENT)  sendEnabledFiles(this->enabledReadModeFiles);
+
+      // Then, send all enabled fields      
+      sendEnabledFieldsInFiles(this->enabledWriteModeFiles);
+      
+      if (serviceType_==CServicesManager::CLIENT) sendEnabledFieldsInFiles(this->enabledReadModeFiles);
+
+      // Then, check whether we have domain_ref, axis_ref or scalar_ref attached to the enabled fields
+      // If any, so send them to server
+      sendRefDomainsAxisScalars(this->enabledWriteModeFiles); 
+     
+      if (serviceType_==CServicesManager::CLIENT) sendRefDomainsAxisScalars(this->enabledReadModeFiles);        
+
+      // Check whether enabled fields have grid_ref, if any, send this info to server
+      sendRefGrid(this->enabledFiles);
+      // This code may be useful in the future when we want to seperate completely read and write
+      // sendRefGrid(this->enabledWriteModeFiles);
+      // if (!hasServer)
+      //   sendRefGrid(this->enabledReadModeFiles);
+      
+      // A grid of enabled fields composed of several components which must be checked then their
+      // checked attributes should be sent to server
+      sendGridComponentEnabledFieldsInFiles(this->enabledFiles); // This code can be seperated in two (one for reading, another for writing)
+
+      // We have a xml tree on the server side and now, it should be also processed
+      sendPostProcessing();
+       
+      // Finally, we send information of grid itself to server 
+      sendGridEnabledFieldsInFiles(this->enabledWriteModeFiles);       
+     
+      if (serviceType_==CServicesManager::CLIENT) sendGridEnabledFieldsInFiles(this->enabledReadModeFiles);       
+    }
+    allProcessed = true;
+
 
     if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendPostProcessingGlobalAttributes();
@@ -884,14 +1054,112 @@
     
     CTimer::get("Context : close definition").suspend() ;
-   }
-   CATCH_DUMP_ATTR
-
-   void CContext::findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles)
-   TRY
-   {
+  }
+  CATCH_DUMP_ATTR
+
+
+   void CContext::closeDefinition_old(void)
+   TRY
+   {
+     CTimer::get("Context : close definition").resume() ;
+    
+    //
+    postProcessingGlobalAttributes();
+
+    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendPostProcessingGlobalAttributes();
+
+    // There are some processings that should be done after all of above. For example: check mask or index
+    this->buildFilterGraphOfEnabledFields();
+    
+     if (serviceType_==CServicesManager::CLIENT)
+    {
+      buildFilterGraphOfFieldsWithReadAccess();
+      postProcessFilterGraph(); // For coupling in, modify this later
+    }
+    
+    checkGridEnabledFields();   
+
+    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendProcessingGridOfEnabledFields();
+    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) this->sendCloseDefinition();
+
+    // Nettoyage de l'arborescence
+    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) CleanTree(); // Only on client side??
+
+    if (serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER) sendCreateFileHeader();
+    if (serviceType_==CServicesManager::CLIENT) startPrefetchingOfEnabledReadModeFiles();
+    
+    CTimer::get("Context : close definition").suspend() ;
+   }
+   CATCH_DUMP_ATTR
+
+   vector<CField*> CContext::findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles)
+   TRY
+   {
+     vector<CField*> fields ;
      for (unsigned int i = 0; i < activeFiles.size(); i++)
-     (void)activeFiles[i]->getEnabledFields();
-   }
-   CATCH_DUMP_ATTR
+     {
+        const vector<CField*>&& field=activeFiles[i]->getEnabledFields() ;
+        fields.insert(fields.end(),field.begin(),field.end());
+     }
+     return fields ;
+   }
+   CATCH_DUMP_ATTR
+
+   vector<CField*> CContext::findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles)
+   TRY
+   {
+     vector<CField*> fields ;
+     for(auto file : activeFiles)
+     {
+        const vector<CField*>&& fieldList=file->getEnabledFields() ;
+        for(auto field : fieldList) field->setFileOut(file) ;
+        fields.insert(fields.end(),fieldList.begin(),fieldList.end());
+     }
+     return fields ;
+   }
+   CATCH_DUMP_ATTR
+
+   vector<CField*> CContext::findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles)
+   TRY
+   {
+     vector<CField*> fields ;
+     for(auto file : activeFiles)
+     {
+        const vector<CField*>&& fieldList=file->getEnabledFields() ;
+        for(auto field : fieldList) field->setFileIn(file) ;
+        fields.insert(fields.end(),fieldList.begin(),fieldList.end());
+     }
+     return fields ;
+   }
+   CATCH_DUMP_ATTR
+
+   vector<CField*> CContext::findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut)
+   TRY
+   {
+     vector<CField*> fields ;
+     for (auto couplerOut :activeCouplerOut)
+     {
+        const vector<CField*>&& fieldList=couplerOut->getEnabledFields() ;
+        for(auto field : fieldList) field->setCouplerOut(couplerOut) ;
+        fields.insert(fields.end(),fieldList.begin(),fieldList.end());
+     }
+     return fields ;
+   }
+   CATCH_DUMP_ATTR
+
+   vector<CField*> CContext::findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn)
+   TRY
+   {
+     vector<CField*> fields ;
+     for (auto couplerIn :activeCouplerIn)
+     {
+        const vector<CField*>&& fieldList=couplerIn->getEnabledFields() ;
+        for(auto field : fieldList) field->setCouplerIn(couplerIn) ;
+        fields.insert(fields.end(),fieldList.begin(),fieldList.end());
+     }
+     return fields ;
+   }
+   CATCH_DUMP_ATTR
+
+
 
    void CContext::readAttributesOfEnabledFieldsInReadModeFiles()
@@ -1081,14 +1349,14 @@
   TRY
   {
-    fieldsWithReadAccess.clear();
+    fieldsWithReadAccess_.clear();
     const vector<CField*> allFields = CField::getAll();
     for (size_t i = 0; i < allFields.size(); ++i)
     {
       CField* field = allFields[i];
-
-      if (field->file && !field->file->mode.isEmpty() && field->file->mode == CFile::mode_attr::read)
-        field->read_access = true;
-      else if (!field->read_access.isEmpty() && field->read_access && (field->enabled.isEmpty() || field->enabled))
-        fieldsWithReadAccess.push_back(field);
+      if (!field->read_access.isEmpty() && field->read_access && (field->enabled.isEmpty() || field->enabled))
+      {
+        fieldsWithReadAccess_.push_back(field);
+        field->setModelOut() ;
+      }
     }
   }
@@ -1098,6 +1366,6 @@
   TRY
   {
-    for (size_t i = 0; i < fieldsWithReadAccess.size(); ++i)
-      fieldsWithReadAccess[i]->solveAllReferenceEnabledField(false);
+    for (size_t i = 0; i < fieldsWithReadAccess_.size(); ++i)
+      fieldsWithReadAccess_[i]->solveAllReferenceEnabledField(false);
   }
   CATCH_DUMP_ATTR
@@ -1106,6 +1374,6 @@
   TRY
   {
-    for (size_t i = 0; i < fieldsWithReadAccess.size(); ++i)
-      fieldsWithReadAccess[i]->buildFilterGraph(garbageCollector, true);
+    for (size_t i = 0; i < fieldsWithReadAccess_.size(); ++i)
+      fieldsWithReadAccess_[i]->buildFilterGraph(garbageCollector, true);
   }
   CATCH_DUMP_ATTR
@@ -1139,5 +1407,5 @@
       unsigned int i = 0;
       for (i = 0; i < vecSize; ++i)
-        allGrids[i]->solveDomainAxisRefInheritance(apply);
+        allGrids[i]->solveElementsRefInheritance(apply);
 
    }
@@ -1227,5 +1495,5 @@
 
 
-   void CContext::distributeFiles(void)
+   void CContext::distributeFiles(const vector<CFile*>& files)
    TRY
    {
@@ -1233,182 +1501,155 @@
      distFileMemory=CXios::getin<bool>("server2_dist_file_memory", distFileMemory);
 
-     if (distFileMemory) distributeFileOverMemoryBandwith() ;
-     else distributeFileOverBandwith() ;
-   }
-   CATCH_DUMP_ATTR
-
-   void CContext::distributeFileOverBandwith(void)
+     if (distFileMemory) distributeFileOverMemoryBandwith(files) ;
+     else distributeFileOverBandwith(files) ;
+   }
+   CATCH_DUMP_ATTR
+
+   void CContext::distributeFileOverBandwith(const vector<CFile*>& files)
    TRY
    {
      double eps=std::numeric_limits<double>::epsilon()*10 ;
      
-     if (serviceType_==CServicesManager::GATHERER)
-     {
-       std::ofstream ofs(("distribute_file_"+getId()+".dat").c_str(), std::ofstream::out);
-       int nbPools = clientPrimServer.size();
-
-       // (1) Find all enabled files in write mode
-       // for (int i = 0; i < this->enabledFiles.size(); ++i)
-       // {
-       //   if (enabledFiles[i]->mode.isEmpty() || (!enabledFiles[i]->mode.isEmpty() && enabledFiles[i]->mode.getValue() == CFile::mode_attr::write ))
-       //    enabledWriteModeFiles.push_back(enabledFiles[i]);
-       // }
-
-       // (2) Estimate the data volume for each file
-       int size = this->enabledWriteModeFiles.size();
-       std::vector<std::pair<double, CFile*> > dataSizeMap;
-       double dataPerPool = 0;
-       int nfield=0 ;
-       ofs<<size<<endl ;
-       for (size_t i = 0; i < size; ++i)
+     std::ofstream ofs(("distribute_file_"+getId()+".dat").c_str(), std::ofstream::out);
+     int nbPools = clientPrimServer.size();
+
+     // (1) Find all enabled files in write mode
+     // for (int i = 0; i < this->enabledFiles.size(); ++i)
+     // {
+     //   if (enabledFiles[i]->mode.isEmpty() || (!enabledFiles[i]->mode.isEmpty() && enabledFiles[i]->mode.getValue() == CFile::mode_attr::write ))
+     //    enabledWriteModeFiles.push_back(enabledFiles[i]);
+     // }
+
+     // (2) Estimate the data volume for each file
+     int size = files.size();
+     std::vector<std::pair<double, CFile*> > dataSizeMap;
+     double dataPerPool = 0;
+     int nfield=0 ;
+     ofs<<size<<endl ;
+     for (size_t i = 0; i < size; ++i)
+     {
+       CFile* file = files[i];
+       ofs<<file->getId()<<endl ;
+       StdSize dataSize=0;
+       std::vector<CField*> enabledFields = file->getEnabledFields();
+       size_t numEnabledFields = enabledFields.size();
+       ofs<<numEnabledFields<<endl ;
+       for (size_t j = 0; j < numEnabledFields; ++j)
        {
-         CFile* file = this->enabledWriteModeFiles[i];
-         ofs<<file->getId()<<endl ;
-         StdSize dataSize=0;
-         std::vector<CField*> enabledFields = file->getEnabledFields();
-         size_t numEnabledFields = enabledFields.size();
-         ofs<<numEnabledFields<<endl ;
-         for (size_t j = 0; j < numEnabledFields; ++j)
+         dataSize += enabledFields[j]->getGlobalWrittenSize() ;
+         ofs<<enabledFields[j]->getGrid()->getId()<<endl ;
+         ofs<<enabledFields[j]->getGlobalWrittenSize()<<endl ;
+       }
+       double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ;
+       double dataSizeSec= dataSize/ outFreqSec;
+       ofs<<dataSizeSec<<endl ;
+       nfield++ ;
+// add epsilon*nField to dataSizeSec in order to  preserve reproductive ordering when sorting
+       dataSizeMap.push_back(make_pair(dataSizeSec + dataSizeSec * eps * nfield , file));
+       dataPerPool += dataSizeSec;
+     }
+     dataPerPool /= nbPools;
+     std::sort(dataSizeMap.begin(), dataSizeMap.end());
+
+     // (3) Assign contextClient to each enabled file
+
+     std::multimap<double,int> poolDataSize ;
+// multimap is not garanty to preserve stable sorting in c++98 but it seems it does for c++11
+
+     int j;
+     double dataSize ;
+     for (j = 0 ; j < nbPools ; ++j) poolDataSize.insert(std::pair<double,int>(0.,j)) ;  
+             
+     for (int i = dataSizeMap.size()-1; i >= 0; --i)
+     {
+       dataSize=(*poolDataSize.begin()).first ;
+       j=(*poolDataSize.begin()).second ;
+       dataSizeMap[i].second->setContextClient(clientPrimServer[j]);
+       dataSize+=dataSizeMap[i].first;
+       poolDataSize.erase(poolDataSize.begin()) ;
+       poolDataSize.insert(std::pair<double,int>(dataSize,j)) ; 
+     }
+
+     for (std::multimap<double,int>:: iterator it=poolDataSize.begin() ; it!=poolDataSize.end(); ++it) info(30)<<"Load Balancing for servers (perfect=1) : "<<it->second<<" :  ratio "<<it->first*1./dataPerPool<<endl ;
+   }
+   CATCH_DUMP_ATTR
+
+   void CContext::distributeFileOverMemoryBandwith(const vector<CFile*>& filesList)
+   TRY
+   {
+     int nbPools = clientPrimServer.size();
+     double ratio=0.5 ;
+     ratio=CXios::getin<double>("server2_dist_file_memory_ratio", ratio);
+
+     int nFiles = filesList.size();
+     vector<SDistFile> files(nFiles);
+     vector<SDistGrid> grids;
+     map<string,int> gridMap ;
+     string gridId; 
+     int gridIndex=0 ;
+
+     for (size_t i = 0; i < nFiles; ++i)
+     {
+       StdSize dataSize=0;
+       CFile* file = filesList[i];
+       std::vector<CField*> enabledFields = file->getEnabledFields();
+       size_t numEnabledFields = enabledFields.size();
+
+       files[i].id_=file->getId() ;
+       files[i].nbGrids_=numEnabledFields;
+       files[i].assignedGrid_ = new int[files[i].nbGrids_] ;
+         
+       for (size_t j = 0; j < numEnabledFields; ++j)
+       {
+         gridId=enabledFields[j]->getGrid()->getId() ;
+         if (gridMap.find(gridId)==gridMap.end())
          {
-           dataSize += enabledFields[j]->getGlobalWrittenSize() ;
-           ofs<<enabledFields[j]->grid->getId()<<endl ;
-           ofs<<enabledFields[j]->getGlobalWrittenSize()<<endl ;
+            gridMap[gridId]=gridIndex  ;
+            SDistGrid newGrid; 
+            grids.push_back(newGrid) ;
+            gridIndex++ ;
          }
-         double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ;
-         double dataSizeSec= dataSize/ outFreqSec;
-         ofs<<dataSizeSec<<endl ;
-         nfield++ ;
-// add epsilon*nField to dataSizeSec in order to  preserve reproductive ordering when sorting
-         dataSizeMap.push_back(make_pair(dataSizeSec + dataSizeSec * eps * nfield , file));
-         dataPerPool += dataSizeSec;
+         files[i].assignedGrid_[j]=gridMap[gridId] ;
+         grids[files[i].assignedGrid_[j]].size_=enabledFields[j]->getGlobalWrittenSize() ;
+         dataSize += enabledFields[j]->getGlobalWrittenSize() ; // usefull
        }
-       dataPerPool /= nbPools;
-       std::sort(dataSizeMap.begin(), dataSizeMap.end());
-
-       // (3) Assign contextClient to each enabled file
-
-       std::multimap<double,int> poolDataSize ;
-// multimap is not garanty to preserve stable sorting in c++98 but it seems it does for c++11
-
-       int j;
-       double dataSize ;
-       for (j = 0 ; j < nbPools ; ++j) poolDataSize.insert(std::pair<double,int>(0.,j)) ;  
-              
-       for (int i = dataSizeMap.size()-1; i >= 0; --i)
+       double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ;
+       files[i].bandwith_= dataSize/ outFreqSec ;
+     }
+
+     double bandwith=0 ;
+     double memory=0 ;
+   
+     for(int i=0; i<nFiles; i++)  bandwith+=files[i].bandwith_ ;
+     for(int i=0; i<nFiles; i++)  files[i].bandwith_ = files[i].bandwith_/bandwith * ratio ;
+
+     for(int i=0; i<grids.size(); i++)  memory+=grids[i].size_ ;
+     for(int i=0; i<grids.size(); i++)  grids[i].size_ = grids[i].size_ / memory * (1.0-ratio) ;
+       
+     distributeFileOverServer2(nbPools, grids.size(), &grids[0], nFiles, &files[0]) ;
+
+     vector<double> memorySize(nbPools,0.) ;
+     vector< set<int> > serverGrids(nbPools) ;
+     vector<double> bandwithSize(nbPools,0.) ;
+       
+     for (size_t i = 0; i < nFiles; ++i)
+     {
+       bandwithSize[files[i].assignedServer_] += files[i].bandwith_* bandwith /ratio ;
+       for(int j=0 ; j<files[i].nbGrids_;j++)
        {
-         dataSize=(*poolDataSize.begin()).first ;
-         j=(*poolDataSize.begin()).second ;
-         dataSizeMap[i].second->setContextClient(clientPrimServer[j]);
-         dataSize+=dataSizeMap[i].first;
-         poolDataSize.erase(poolDataSize.begin()) ;
-         poolDataSize.insert(std::pair<double,int>(dataSize,j)) ; 
+         if (serverGrids[files[i].assignedServer_].find(files[i].assignedGrid_[j]) == serverGrids[files[i].assignedServer_].end())
+         {
+           memorySize[files[i].assignedServer_]+= grids[files[i].assignedGrid_[j]].size_ * memory / (1.0-ratio);
+           serverGrids[files[i].assignedServer_].insert(files[i].assignedGrid_[j]) ;
+         }
        }
-
-       for (std::multimap<double,int>:: iterator it=poolDataSize.begin() ; it!=poolDataSize.end(); ++it) info(30)<<"Load Balancing for servers (perfect=1) : "<<it->second<<" :  ratio "<<it->first*1./dataPerPool<<endl ;
- 
-       for (int i = 0; i < this->enabledReadModeFiles.size(); ++i)
-       {
-         enabledReadModeFiles[i]->setContextClient(client);          
-       }
-     }
-     else
-     {
-       for (int i = 0; i < this->enabledFiles.size(); ++i)
-         enabledFiles[i]->setContextClient(client);
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   void CContext::distributeFileOverMemoryBandwith(void)
-   TRY
-   {
-     if (serviceType_==CServicesManager::GATHERER)
-     {
-       int nbPools = clientPrimServer.size();
-       double ratio=0.5 ;
-       ratio=CXios::getin<double>("server2_dist_file_memory_ratio", ratio);
-
-       int nFiles = this->enabledWriteModeFiles.size();
-       vector<SDistFile> files(nFiles);
-       vector<SDistGrid> grids;
-       map<string,int> gridMap ;
-       string gridId; 
-       int gridIndex=0 ;
-
-       for (size_t i = 0; i < nFiles; ++i)
-       {
-         StdSize dataSize=0;
-         CFile* file = this->enabledWriteModeFiles[i];
-         std::vector<CField*> enabledFields = file->getEnabledFields();
-         size_t numEnabledFields = enabledFields.size();
-
-         files[i].id_=file->getId() ;
-         files[i].nbGrids_=numEnabledFields;
-         files[i].assignedGrid_ = new int[files[i].nbGrids_] ;
-         
-         for (size_t j = 0; j < numEnabledFields; ++j)
-         {
-           gridId=enabledFields[j]->grid->getId() ;
-           if (gridMap.find(gridId)==gridMap.end())
-           {
-              gridMap[gridId]=gridIndex  ;
-              SDistGrid newGrid; 
-              grids.push_back(newGrid) ;
-              gridIndex++ ;
-           }
-           files[i].assignedGrid_[j]=gridMap[gridId] ;
-           grids[files[i].assignedGrid_[j]].size_=enabledFields[j]->getGlobalWrittenSize() ;
-           dataSize += enabledFields[j]->getGlobalWrittenSize() ; // usefull
-         }
-         double outFreqSec = (Time)(calendar->getCurrentDate()+file->output_freq)-(Time)(calendar->getCurrentDate()) ;
-         files[i].bandwith_= dataSize/ outFreqSec ;
-       }
-
-       double bandwith=0 ;
-       double memory=0 ;
-   
-       for(int i=0; i<nFiles; i++)  bandwith+=files[i].bandwith_ ;
-       for(int i=0; i<nFiles; i++)  files[i].bandwith_ = files[i].bandwith_/bandwith * ratio ;
-
-       for(int i=0; i<grids.size(); i++)  memory+=grids[i].size_ ;
-       for(int i=0; i<grids.size(); i++)  grids[i].size_ = grids[i].size_ / memory * (1.0-ratio) ;
-       
-       distributeFileOverServer2(nbPools, grids.size(), &grids[0], nFiles, &files[0]) ;
-
-       vector<double> memorySize(nbPools,0.) ;
-       vector< set<int> > serverGrids(nbPools) ;
-       vector<double> bandwithSize(nbPools,0.) ;
-       
-       for (size_t i = 0; i < nFiles; ++i)
-       {
-         bandwithSize[files[i].assignedServer_] += files[i].bandwith_* bandwith /ratio ;
-         for(int j=0 ; j<files[i].nbGrids_;j++)
-         {
-           if (serverGrids[files[i].assignedServer_].find(files[i].assignedGrid_[j]) == serverGrids[files[i].assignedServer_].end())
-           {
-             memorySize[files[i].assignedServer_]+= grids[files[i].assignedGrid_[j]].size_ * memory / (1.0-ratio);
-             serverGrids[files[i].assignedServer_].insert(files[i].assignedGrid_[j]) ;
-           }
-         }
-         enabledWriteModeFiles[i]->setContextClient(clientPrimServer[files[i].assignedServer_]) ;
-         delete [] files[i].assignedGrid_ ;
-       }
-
-       for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned file bandwith "<<bandwithSize[i]*86400.*4./1024/1024.<<" Mb / days"<<endl ;
-       for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned grid memory "<<memorySize[i]*100/1024./1024.<<" Mb"<<endl ;
-
-
-       for (int i = 0; i < this->enabledReadModeFiles.size(); ++i)
-       {
-         enabledReadModeFiles[i]->setContextClient(client);          
-       }
-
-   }
-   else
-   {
-     for (int i = 0; i < this->enabledFiles.size(); ++i)
-        enabledFiles[i]->setContextClient(client);
-   }
-}
+       filesList[i]->setContextClient(clientPrimServer[files[i].assignedServer_]) ;
+       delete [] files[i].assignedGrid_ ;
+     }
+
+     for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned file bandwith "<<bandwithSize[i]*86400.*4./1024/1024.<<" Mb / days"<<endl ;
+     for (int i = 0; i < nbPools; ++i) info(100)<<"Pool server level2 "<<i<<"   assigned grid memory "<<memorySize[i]*100/1024./1024.<<" Mb"<<endl ;
+
+   }
    CATCH_DUMP_ATTR
 
@@ -1759,12 +2000,9 @@
       // Check if some axis, domains or grids are eligible to for compressed indexed output.
       // Warning: This must be done after solving the inheritance and before the rest of post-processing
-      checkAxisDomainsGridsEligibilityForCompressedOutput();      
+      checkAxisDomainsGridsEligibilityForCompressedOutput();      // only for field written on IO_SERVER service ????
 
       // Check if some automatic time series should be generated
       // Warning: This must be done after solving the inheritance and before the rest of post-processing      
-
-      // The timeseries should only be prepared in client
-
-      if (serviceType_==CServicesManager::CLIENT) prepareTimeseries();
+      prepareTimeseries();
 
       //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers Ã  sortir.
@@ -1774,13 +2012,17 @@
       findEnabledCouplerIn();
       findEnabledCouplerOut();
-      
       createCouplerInterCommunicator() ;
+
+      // Find all enabled fields of each file      
+      const vector<CField*>&& fileOutField = findAllEnabledFieldsInFiles(this->enabledWriteModeFiles);
+      const vector<CField*>&& fileInField = findAllEnabledFieldsInFiles(this->enabledReadModeFiles);
+      const vector<CField*>&& CouplerOutField = findAllEnabledFieldsCouplerOut(this->enabledCouplerOut);
+      const vector<CField*>&& CouplerInField = findAllEnabledFieldsCouplerIn(this->enabledCouplerIn);
+
+
 
       // For now, only read files with client and only one level server
       // if (hasClient && !hasServer) findEnabledReadModeFiles();      
 
-      // Find all enabled fields of each file      
-      findAllEnabledFieldsInFiles(this->enabledWriteModeFiles);
-      findAllEnabledFieldsInFiles(this->enabledReadModeFiles);
 
       // For now, only read files with client and only one level server
@@ -1974,6 +2216,4 @@
    TRY
    {
-     if (!(serviceType_==CServicesManager::CLIENT || serviceType_==CServicesManager::GATHERER)) return;
-
      const std::vector<CFile*> allFiles = CFile::getAll();
      for (size_t i = 0; i < allFiles.size(); i++)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/context.hpp	(revision 1869)
@@ -114,7 +114,13 @@
 
          void closeDefinition(void);
-
+         void closeDefinition_old(void);
+
+         // to be removed     
+         std::vector<CField*> findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
          // Some functions to process context
-         void findAllEnabledFieldsInFiles(const std::vector<CFile*>& activeFiles);
+         std::vector<CField*> findAllEnabledFieldsInFileOut(const std::vector<CFile*>& activeFiles);
+         std::vector<CField*> findAllEnabledFieldsInFileIn(const std::vector<CFile*>& activeFiles);
+         std::vector<CField*> findAllEnabledFieldsCouplerOut(const std::vector<CCouplerOut*>& activeCouplerOut);
+         std::vector<CField*> findAllEnabledFieldsCouplerIn(const std::vector<CCouplerIn*>& activeCouplerIn);
          // void findAllEnabledFields(void);
          // void findAllEnabledFieldsInReadModeFiles(void);
@@ -156,7 +162,7 @@
 
          // Distribute files (in write mode) among secondary-server pools according to the estimated data flux
-         void distributeFiles(void);
-         void distributeFileOverBandwith() ;
-         void distributeFileOverMemoryBandwith() ;
+         void distributeFiles(const std::vector<CFile*>& files);
+         void distributeFileOverBandwith(const std::vector<CFile*>& files) ;
+         void distributeFileOverMemoryBandwith(const std::vector<CFile*>& files) ;
          
          // Send context close definition
@@ -244,5 +250,7 @@
          bool setProcessingEvent(void) {isProcessingEvent_=true ;}
          bool unsetProcessingEvent(void) {isProcessingEvent_=false ;}
-         MPI_Comm getIntraComm(void) { return intraComm_ ;}
+         MPI_Comm getIntraComm(void) {return intraComm_ ;}
+         int getIntraCommRank(void) {return intraCommRank_;}
+         int getIntraCommSize(void) {return intraCommSize_;}
 
          void addCouplingChanel(const std::string& contextId, bool out) ;
@@ -265,5 +273,5 @@
          // List of all enabled fields whose instant data is accessible from the public API
          // but which are not part of a file
-         std::vector<CField*> fieldsWithReadAccess;
+         std::vector<CField*> fieldsWithReadAccess_;
 
          // Context root
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.cpp	(revision 1869)
@@ -1721,19 +1721,18 @@
    CATCH_DUMP_ATTR
 
-   void CDomain::checkAttributesOnClientAfterTransformation()
-   TRY
-   {
-     CContext* context=CContext::getCurrent() ;
-
-     if (this->isClientAfterTransformationChecked) return;
-     if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
-     {
-      this->computeConnectedClients();
-       if (hasLonLat)
-         if (context->getServiceType()==CServicesManager::CLIENT)
-           this->completeLonLatClient();
-     }
-
-     this->isClientAfterTransformationChecked = true;
+   void CDomain::checkAttributes(void)
+   TRY
+   {
+      if (this->checkAttributes_done_) return;
+      this->checkDomain();
+      this->checkLonLat();
+      this->checkBounds();
+      this->checkArea();
+      this->checkMask();
+      this->checkDomainData();
+      this->checkCompression();
+      this->computeLocalMask() ;
+      this->completeLonLatClient();
+      this->checkAttributes_done_ = true;
    }
    CATCH_DUMP_ATTR
@@ -1770,6 +1769,25 @@
    }
    CATCH_DUMP_ATTR
-
-   // Send all checked attributes to server
+   
+   // ym obselete, to be removed
+   void CDomain::checkAttributesOnClientAfterTransformation()
+   TRY
+   {
+     CContext* context=CContext::getCurrent() ;
+
+     if (this->isClientAfterTransformationChecked) return;
+     if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
+     {
+       // this->computeConnectedClients();
+       if (hasLonLat)
+         if (context->getServiceType()==CServicesManager::CLIENT)
+           this->completeLonLatClient();
+     }
+
+     this->isClientAfterTransformationChecked = true;
+   }
+   CATCH_DUMP_ATTR
+
+      // Send all checked attributes to server
    void CDomain::sendCheckedAttributes()
    TRY
@@ -1788,4 +1806,5 @@
    CATCH_DUMP_ATTR
 
+/* old version
    void CDomain::checkAttributes(void)
    TRY
@@ -1820,5 +1839,6 @@
    }
    CATCH_DUMP_ATTR
-
+*/
+   
   /*!
      Compute the connection of a client to other clients to determine which clients to send attributes to.
@@ -1827,132 +1847,119 @@
      A client connects to other clients which holds the same global index as it.     
   */
-  void CDomain::computeConnectedClients()
+  void CDomain::computeConnectedClients(CContextClient* client)
   TRY
   {
+    if (computeConnectedClients_done_.count(client)==0) return ;
+    else computeConnectedClients_done_.insert(client) ;
+    
     CContext* context=CContext::getCurrent() ;
-    set<int> listNbServer ;
-
-    for (auto client : clients)
+   
+    int nbServer = client->serverSize;
+    int nbClient = client->clientSize;
+    int rank     = client->clientRank;
+        
+    if (listNbServer_.count(nbServer) == 0)
     {
-
-      int nbServer = client->serverSize;
-      int nbClient = client->clientSize;
-      int rank     = client->clientRank;
-      bool doComputeGlobalIndexServer = true;
-   
-      if (listNbServer.find(nbServer)==listNbServer.end())
-      {
-        listNbServer.insert(nbServer) ;
+      listNbServer_.insert(nbServer) ;
  
-        if (connectedServerRank_.find(nbServer) != connectedServerRank_.end())
-        {
-          nbSenders.erase(nbServer);
-          connectedServerRank_.erase(nbServer);
-        }
-
-        if (indSrv_.find(nbServer) == indSrv_.end())
-        {
-          int i,j,i_ind,j_ind, nbIndex=i_index.numElements();
-          int globalIndexCount = i_index.numElements();
-          // Fill in index
-          CArray<size_t,1> globalIndexDomain(nbIndex);
-          size_t globalIndex;
-
-          for (i = 0; i < nbIndex; ++i)
+      if (connectedServerRank_.find(nbServer) != connectedServerRank_.end())
+      {
+        nbSenders.erase(nbServer);
+        connectedServerRank_.erase(nbServer);
+      }
+
+      if (indSrv_.find(nbServer) == indSrv_.end())
+      {
+        int i,j,i_ind,j_ind, nbIndex=i_index.numElements();
+        int globalIndexCount = i_index.numElements();
+        // Fill in index
+        CArray<size_t,1> globalIndexDomain(nbIndex);
+        size_t globalIndex;
+
+        for (i = 0; i < nbIndex; ++i)
+        {
+          i_ind=i_index(i);
+          j_ind=j_index(i);
+          globalIndex = i_ind + j_ind * ni_glo;
+          globalIndexDomain(i) = globalIndex;
+        }
+
+        if (globalLocalIndexMap_.empty()) 
+          for (i = 0; i < nbIndex; ++i)  globalLocalIndexMap_[globalIndexDomain(i)] = i;
+          
+
+        size_t globalSizeIndex = 1, indexBegin, indexEnd;
+        int range, clientSize = client->clientSize;
+        std::vector<int> nGlobDomain(2);
+        nGlobDomain[0] = this->ni_glo;
+        nGlobDomain[1] = this->nj_glo;
+        for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i];
+        indexBegin = 0;
+        if (globalSizeIndex <= clientSize)
+        {
+          indexBegin = rank%globalSizeIndex;
+          indexEnd = indexBegin;
+        }
+        else
+        {
+          for (int i = 0; i < clientSize; ++i)
           {
-            i_ind=i_index(i);
-            j_ind=j_index(i);
-            globalIndex = i_ind + j_ind * ni_glo;
-            globalIndexDomain(i) = globalIndex;
+            range = globalSizeIndex / clientSize;
+            if (i < (globalSizeIndex%clientSize)) ++range;
+            if (i == client->clientRank) break;
+            indexBegin += range;
           }
-
-          if (globalLocalIndexMap_.empty())
-          {
-            for (i = 0; i < nbIndex; ++i)
-              globalLocalIndexMap_[globalIndexDomain(i)] = i;
-          }
-
-          size_t globalSizeIndex = 1, indexBegin, indexEnd;
-          int range, clientSize = client->clientSize;
-          std::vector<int> nGlobDomain(2);
-          nGlobDomain[0] = this->ni_glo;
-          nGlobDomain[1] = this->nj_glo;
-          for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i];
-          indexBegin = 0;
-          if (globalSizeIndex <= clientSize)
-          {
-            indexBegin = rank%globalSizeIndex;
-            indexEnd = indexBegin;
-          }
-          else
-          {
-            for (int i = 0; i < clientSize; ++i)
-            {
-              range = globalSizeIndex / clientSize;
-              if (i < (globalSizeIndex%clientSize)) ++range;
-              if (i == client->clientRank) break;
-              indexBegin += range;
-            }
-            indexEnd = indexBegin + range - 1;
-          }
-
-          // Even if servers have no index, they must received something from client
-          // We only use several client to send "empty" message to these servers
-          CServerDistributionDescription serverDescription(nGlobDomain, nbServer);
-          std::vector<int> serverZeroIndex;
-          if (isUnstructed_) serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0);
-          else serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 1);
-
-          std::list<int> serverZeroIndexLeader;
-          std::list<int> serverZeroIndexNotLeader;
-          CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
-          for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
-            *it = serverZeroIndex[*it];
-
-          CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
-          clientServerMap->computeServerIndexMapping(globalIndexDomain, nbServer);
-          CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
-
-          CClientServerMapping::GlobalIndexMap::const_iterator it  = globalIndexDomainOnServer.begin(),
-                 ite = globalIndexDomainOnServer.end();
-          indSrv_[nbServer].swap(globalIndexDomainOnServer);
-          connectedServerRank_[nbServer].clear();
-          for (it = indSrv_[nbServer].begin(); it != ite; ++it)
-            connectedServerRank_[nbServer].push_back(it->first);
-
-          for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
-            connectedServerRank_[nbServer].push_back(*it);
-
-          // Even if a client has no index, it must connect to at least one server and
-          // send an "empty" data to this server
-          if (connectedServerRank_[nbServer].empty())
-            connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize);
-
-          // Now check if all servers have data to receive. If not, master client will send empty data.
-          // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive.
-          std::vector<int> counts (clientSize);
-          std::vector<int> displs (clientSize);
-          displs[0] = 0;
-          int localCount = connectedServerRank_[nbServer].size() ;
-          MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ;
-          for (int i = 0; i < clientSize-1; ++i)
-          {
-            displs[i+1] = displs[i] + counts[i];
-          }
-          std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]);
-          MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm);
-
-          if ((allConnectedServers.size() != nbServer) && (rank == 0))
-          {
-            std::vector<bool> isSrvConnected (nbServer, false);
-            for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true;
-            for (int i = 0; i < nbServer; ++i)
-            {
-              if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i);
-            }
-          }
-          nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
-          delete clientServerMap;
-        }
+          indexEnd = indexBegin + range - 1;
+        }
+
+        // Even if servers have no index, they must received something from client
+        // We only use several client to send "empty" message to these servers
+        CServerDistributionDescription serverDescription(nGlobDomain, nbServer);
+        std::vector<int> serverZeroIndex;
+        if (isUnstructed_) serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 0);
+        else serverZeroIndex = serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t&,size_t&>(indexBegin, indexEnd), 1);
+
+        std::list<int> serverZeroIndexLeader;
+        std::list<int> serverZeroIndexNotLeader;
+        CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
+        for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
+          *it = serverZeroIndex[*it];
+
+        CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
+        clientServerMap->computeServerIndexMapping(globalIndexDomain, nbServer);
+        CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
+
+        CClientServerMapping::GlobalIndexMap::const_iterator it  = globalIndexDomainOnServer.begin(), ite = globalIndexDomainOnServer.end();
+        indSrv_[nbServer].swap(globalIndexDomainOnServer);
+        connectedServerRank_[nbServer].clear();
+        for (it = indSrv_[nbServer].begin(); it != ite; ++it) connectedServerRank_[nbServer].push_back(it->first);
+
+        for (std::list<int>::const_iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
+          connectedServerRank_[nbServer].push_back(*it);
+
+        // Even if a client has no index, it must connect to at least one server and
+        // send an "empty" data to this server
+        if (connectedServerRank_[nbServer].empty())
+          connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize);
+
+        // Now check if all servers have data to receive. If not, master client will send empty data.
+        // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive.
+        std::vector<int> counts (clientSize);
+        std::vector<int> displs (clientSize);
+        displs[0] = 0;
+        int localCount = connectedServerRank_[nbServer].size() ;
+        MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ;
+        for (int i = 0; i < clientSize-1; ++i) displs[i+1] = displs[i] + counts[i];
+        std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]);
+        MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm);
+
+        if ((allConnectedServers.size() != nbServer) && (rank == 0))
+        {
+          std::vector<bool> isSrvConnected (nbServer, false);
+          for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true;
+          for (int i = 0; i < nbServer; ++i) if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i);
+        }
+        nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
+        delete clientServerMap;
       }
     }
@@ -3025,4 +3032,39 @@
 
   /*!
+  \brief Check if a domain is completed
+  Before make any domain processing, we must be sure that all domain informations have
+  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
+  other context (coupling). So all direct reference of the domain (domain_ref) must be also completed
+  \return true if domain and domain reference are completed
+  */
+  bool CDomain::checkIfCompleted(void)
+  {
+    if (hasDirectDomainReference()) if (!getDirectDomainReference()->checkIfCompleted()) return false;
+    return isCompleted_ ;
+  }
+
+  /*!
+  \brief Set a domain as completed
+   When all information about a domain have been received, the domain is tagged as completed and is
+   suitable for processing
+  */
+  void CDomain::setCompleted(void)
+  {
+    if (hasDirectDomainReference()) getDirectDomainReference()->setCompleted() ;
+    isCompleted_=true ;
+  }
+
+  /*!
+  \brief Set a domain as uncompleted
+   When informations about a domain are expected from a grid reading from file or coupling, the domain is 
+   tagged as uncompleted and is not suitable for processing
+  */
+  void CDomain::setUncompleted(void)
+  {
+    if (hasDirectDomainReference()) getDirectDomainReference()->setUncompleted() ;
+    isCompleted_=false ;
+  }
+  
+  /*!
    * Go through the hierarchy to find the domain from which the transformations must be inherited
    */
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/domain.hpp	(revision 1869)
@@ -76,4 +76,6 @@
          /// VÃ©rifications ///
          void checkAttributes(void);
+         bool checkAttributes_done_ = false ;
+
          void checkAttributesOnClient();
          void checkAttributesOnClientAfterTransformation();
@@ -109,4 +111,8 @@
 
          static bool dispatchEvent(CEventServer& event);
+
+         bool checkIfCompleted(void) ;
+         void setCompleted(void) ;
+         void setUncompleted(void) ;
 
       public:
@@ -157,4 +163,10 @@
 
          void computeLocalMask(void) ;
+      
+         void computeConnectedClients(CContextClient* client);  
+         private: std::set<CContextClient*> computeConnectedClients_done_; public:
+         /** The number of server of a context client. Avoid to re-compute indice computed in a previous computeConnectedClient */
+         private: std::set<int> listNbServer_ ; public:
+         
       private:
          void checkDomain(void);
@@ -197,6 +209,6 @@
 
          void completeLonLatClient(void);  
-         void computeConnectedClients();    
-
+         
+         
        private:         
 
@@ -209,4 +221,8 @@
          bool isClientChecked; // Verify whether all attributes of domain on the client side are good
          bool isClientAfterTransformationChecked;
+         
+         /** define if the domain is completed or not ie all attributes have been received before in case 
+             of grid reading from file or coupling */ 
+         bool isCompleted_=true ;  
 
 /** global index of the domain on server side, sent by the clients. This is global index for lon, lat, mask elements (ie non masked elements)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1869)
@@ -26,77 +26,78 @@
 #include "tracer.hpp"
 
-namespace xios{
-
-   /// ////////////////////// DÃ©finitions ////////////////////// ///
-
-   CField::CField(void)
-      : CObjectTemplate<CField>(), CFieldAttributes()
-      , grid(), file()
-      , written(false)
-      , nstep(0), nstepMax(0)
-      , hasOutputFile(false)
-      , domAxisScalarIds_(vector<StdString>(3,""))
-      , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false)
-      , isGridChecked(false)
-      , useCompressedOutput(false)
-      , hasTimeInstant(false)
-      , hasTimeCentered(false)
-      , wasDataRequestedFromServer(false)
-      , wasDataAlreadyReceivedFromServer(false)
-      , mustAutoTrigger(false)
-      , isEOF(false), nstepMaxRead(false)
-   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
-
-   CField::CField(const StdString& id)
-      : CObjectTemplate<CField>(id), CFieldAttributes()
-      , grid(), file()
-      , written(false)
-      , nstep(0), nstepMax(0)
-      , hasOutputFile(false)
-      , domAxisScalarIds_(vector<StdString>(3,""))
-      , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false)
-      , isGridChecked(false)
-      , useCompressedOutput(false)
-      , hasTimeInstant(false)
-      , hasTimeCentered(false)
-      , wasDataRequestedFromServer(false)
-      , wasDataAlreadyReceivedFromServer(false)
-      , mustAutoTrigger(false)
-      , isEOF(false), nstepMaxRead(false)
-   { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
-
-   CField::~CField(void)
-   {}
+namespace xios
+{
+
+  /// ////////////////////// DÃ©finitions ////////////////////// ///
+
+  CField::CField(void)
+    : CObjectTemplate<CField>(), CFieldAttributes()
+    , file()
+    , written(false)
+    , nstep(0), nstepMax(0)
+    , hasOutputFile(false)
+    , domAxisScalarIds_(vector<StdString>(3,""))
+    , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false)
+    , isGridChecked(false)
+    , useCompressedOutput(false)
+    , hasTimeInstant(false)
+    , hasTimeCentered(false)
+    , wasDataRequestedFromServer(false)
+    , wasDataAlreadyReceivedFromServer(false)
+    , mustAutoTrigger(false)
+    , isEOF(false), nstepMaxRead(false)
+  { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
+
+  CField::CField(const StdString& id)
+    : CObjectTemplate<CField>(id), CFieldAttributes()
+    , file()
+    , written(false)
+    , nstep(0), nstepMax(0)
+    , hasOutputFile(false)
+    , domAxisScalarIds_(vector<StdString>(3,""))
+    , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false)
+    , isGridChecked(false)
+    , useCompressedOutput(false)
+    , hasTimeInstant(false)
+    , hasTimeCentered(false)
+    , wasDataRequestedFromServer(false)
+    , wasDataAlreadyReceivedFromServer(false)
+    , mustAutoTrigger(false)
+    , isEOF(false), nstepMaxRead(false)
+  { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
+
+  CField::~CField(void)
+  {}
 
   //----------------------------------------------------------------
 
-   void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup)
-   TRY
-   {
-      this->vVariableGroup = newVVariableGroup;
-   }
-   CATCH
-
-   CVariableGroup* CField::getVirtualVariableGroup(void) const
-   TRY
-   {
-      return this->vVariableGroup;
-   }
-   CATCH
-
-   std::vector<CVariable*> CField::getAllVariables(void) const
-   TRY
-   {
-      return this->vVariableGroup->getAllChildren();
-   }
-   CATCH
-
-   void CField::solveDescInheritance(bool apply, const CAttributeMap* const parent)
-   TRY
-   {
-      SuperClassAttribute::setAttributes(parent, apply);
-      this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL);
-   }
-   CATCH_DUMP_ATTR
+  void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup)
+  TRY
+  {
+    this->vVariableGroup = newVVariableGroup;
+  }
+  CATCH
+
+  CVariableGroup* CField::getVirtualVariableGroup(void) const
+  TRY
+  {
+     return this->vVariableGroup;
+  }
+  CATCH
+
+  std::vector<CVariable*> CField::getAllVariables(void) const
+  TRY
+  {
+    return this->vVariableGroup->getAllChildren();
+  }
+  CATCH
+
+  void CField::solveDescInheritance(bool apply, const CAttributeMap* const parent)
+  TRY
+  {
+    SuperClassAttribute::setAttributes(parent, apply);
+    this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL);
+  }
+  CATCH_DUMP_ATTR
 
   //----------------------------------------------------------------
@@ -155,9 +156,9 @@
     list<CArray<double,1> > list_data;
 
-    if (!grid->doGridHaveDataDistributed(client))
+    if (!grid_->doGridHaveDataDistributed(client))
     {
        if (client->isServerLeader())
        {
-          for (it = grid->storeIndex_toSrv_[client].begin(); it != grid->storeIndex_toSrv_[client].end(); it++)
+          for (it = grid_->storeIndex_toSrv_[client].begin(); it != grid_->storeIndex_toSrv_[client].end(); it++)
           {
             int rank = it->first;
@@ -179,5 +180,5 @@
     else
     {
-      for (it = grid->storeIndex_toSrv_[client].begin(); it != grid->storeIndex_toSrv_[client].end(); it++)
+      for (it = grid_->storeIndex_toSrv_[client].begin(); it != grid_->storeIndex_toSrv_[client].end(); it++)
       {
         int rank = it->first;
@@ -191,5 +192,5 @@
 
         list_msg.back() << getId() << data_tmp;
-        event.push(rank, grid->nbSenders_[receiverSize][rank], list_msg.back());
+        event.push(rank, grid_->nbSenders_[receiverSize][rank], list_msg.back());
       }
       client->sendEvent(event);
@@ -228,5 +229,5 @@
     if (0 == recvDataSrv.numElements())
     {            
-      CArray<int,1>& storeClient = grid->storeIndex_client_;
+      CArray<int,1>& storeClient = grid_->getStoreIndex_client();
 
       // Gather all data from different clients      
@@ -238,12 +239,12 @@
     const CDate& currDate = context->getCalendar()->getCurrentDate();
     CDuration offsetAllButMonth (freq_offset.getValue().year, 0 , freq_offset.getValue().day,
-                                   freq_offset.getValue().hour, freq_offset.getValue().minute,
-                                   freq_offset.getValue().second, freq_offset.getValue().timestep);
+                                 freq_offset.getValue().hour, freq_offset.getValue().minute,
+                                 freq_offset.getValue().second, freq_offset.getValue().timestep);
     const CDate opeDate   = (last_operation_srv - offsetAllButMonth + context->getCalendar()->getTimeStep())
-                              + freq_op + freq_operation_srv - freq_op - context->getCalendar()->getTimeStep() + offsetAllButMonth;
+                             + freq_op + freq_operation_srv - freq_op - context->getCalendar()->getTimeStep() + offsetAllButMonth;
 
     if (opeDate <= currDate)
     {
-      for (map<int, CArray<size_t, 1> >::iterator it = grid->outLocalIndexStoreOnClient_.begin(); it != grid->outLocalIndexStoreOnClient_.end(); ++it)
+      for (map<int, CArray<size_t, 1> >::iterator it = grid_->outLocalIndexStoreOnClient_.begin(); it != grid_->outLocalIndexStoreOnClient_.end(); ++it)
       {
         CArray<double,1> tmp;
@@ -287,5 +288,5 @@
       recvFoperationSrv->final();
       last_Write_srv = writeDate;
-      grid->computeWrittenIndex();
+      grid_->computeWrittenIndex();
       writeField();
       lastlast_Write_srv = last_Write_srv;
@@ -299,5 +300,5 @@
     if (!getRelFile()->isEmptyZone())
     {
-      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
+      if (grid_->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
       {
         getRelFile()->checkWriteFile();
@@ -338,6 +339,5 @@
       else client->sendEvent(event);
     }
-    else
-      serverSourceFilter->signalEndOfStream(tsDataRequested);
+    else serverSourceFilter->signalEndOfStream(tsDataRequested);
 
     wasDataRequestedFromServer = true;
@@ -398,5 +398,5 @@
 
     map<int, CArray<double,1> >::iterator it;
-    if (!grid->doGridHaveDataDistributed(client))
+    if (!grid_->doGridHaveDataDistributed(client))
     {
        if (client->isServerLeader())
@@ -436,6 +436,6 @@
     else
     {
-      for (map<int, CArray<size_t, 1> >::iterator it = grid->outLocalIndexStoreOnClient_.begin(); 
-                                                  it != grid->outLocalIndexStoreOnClient_.end(); ++it)
+      for (map<int, CArray<size_t, 1> >::iterator it = grid_->outLocalIndexStoreOnClient_.begin(); 
+                                                  it != grid_->outLocalIndexStoreOnClient_.end(); ++it)
       {
         CArray<size_t,1>& indexTmp = it->second;
@@ -463,5 +463,5 @@
         }
 
-        event.push(it->first, grid->nbReadSenders_[client][it->first], msg);
+        event.push(it->first, grid_->nbReadSenders_[client][it->first], msg);
       }
       client->sendEvent(event);
@@ -479,5 +479,5 @@
   {
     CContext* context = CContext::getCurrent();
-    grid->computeWrittenIndex();
+    grid_->computeWrittenIndex();
     getRelFile()->initRead();
     EReadField readState = RF_DATA;
@@ -485,9 +485,9 @@
     if (!getRelFile()->isEmptyZone())
     {      
-      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)      
+      if (grid_->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)      
       {
         if (0 == recvDataSrv.numElements())
         {            
-          CArray<int,1>& storeClient = grid->storeIndex_client_;          
+          CArray<int,1>& storeClient = grid_->getStoreIndex_client();          
           recvDataSrv.resize(storeClient.numElements());          
         }
@@ -660,682 +660,816 @@
   CATCH_DUMP_ATTR
 
+  //----------------------------------------------------------------
+
+  void CField::setRelFile(CFile* _file)
+  TRY
+  {
+    this->file = _file;
+    hasOutputFile = true;
+  }
+  CATCH_DUMP_ATTR
+
+  //----------------------------------------------------------------
+
+  StdString CField::GetName(void)    { return StdString("field"); }
+  StdString CField::GetDefName(void) { return CField::GetName(); }
+  ENodeType CField::GetType(void)    { return eField; }
+
+  //----------------------------------------------------------------
+
+  CGrid* CField::getRelGrid(void) const
+  TRY
+  {
+    return this->grid_;
+  }
+  CATCH
+
+  //----------------------------------------------------------------
+
+  CFile* CField::getRelFile(void) const
+  TRY
+  {
+    return this->file;
+  }
+  CATCH
+
+  int CField::getNStep(void) const
+  TRY
+  {
+    return this->nstep;
+  }
+  CATCH
+
+  func::CFunctor::ETimeType CField::getOperationTimeType() const
+  TRY
+  {
+    return operationTimeType;
+  }
+  CATCH
+
    //----------------------------------------------------------------
 
-   void CField::setRelFile(CFile* _file)
-   TRY
-   {
-      this->file = _file;
-      hasOutputFile = true;
-   }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
-
-   StdString CField::GetName(void)    { return StdString("field"); }
-   StdString CField::GetDefName(void) { return CField::GetName(); }
-   ENodeType CField::GetType(void)    { return eField; }
-
-   //----------------------------------------------------------------
-
-   CGrid* CField::getRelGrid(void) const
-   TRY
-   {
-      return this->grid;
-   }
-   CATCH
-
-   //----------------------------------------------------------------
-
-   CFile* CField::getRelFile(void) const
-   TRY
-   {
-      return this->file;
-   }
-   CATCH
-
-   int CField::getNStep(void) const
-   TRY
-   {
-      return this->nstep;
-   }
-   CATCH
-
-   func::CFunctor::ETimeType CField::getOperationTimeType() const
-   TRY
-   {
-     return operationTimeType;
-   }
-   CATCH
-
-   //----------------------------------------------------------------
-
-   void CField::incrementNStep(void)
-   TRY
-   {
-      this->nstep++;
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::resetNStep(int nstep /*= 0*/)
-   TRY
-   {
-      this->nstep = nstep;
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::resetNStepMax(void)
-   TRY
-   {
-      this->nstepMax = 0;
-      nstepMaxRead = false;
-   }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
-
-   bool CField::isActive(bool atCurrentTimestep /*= false*/) const
-   TRY
-   {
-      if (clientSourceFilter)
-        return atCurrentTimestep ? clientSourceFilter->isDataExpected(CContext::getCurrent()->getCalendar()->getCurrentDate()) : true;
-      else if (storeFilter)
-        return true;
-      else if (instantDataFilter)
-        ERROR("bool CField::isActive(bool atCurrentTimestep)",
-              << "Impossible to check if field [ id = " << getId() << " ] is active as it cannot be used to receive nor send data.");
-
-      return false;
-   }
-   CATCH
-
-   //----------------------------------------------------------------
-
-   bool CField::wasWritten() const
-   TRY
-   {
-     return written;
-   }
-   CATCH
-
-   void CField::setWritten()
-   TRY
-   {
-     written = true;
-   }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
-
-   bool CField::getUseCompressedOutput() const
-   TRY
-   {
-     return useCompressedOutput;
-   }
-   CATCH
-
-   void CField::setUseCompressedOutput()
-   TRY
-   {
-     useCompressedOutput = true;
-   }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
-
-   std::shared_ptr<COutputPin> CField::getInstantDataFilter()
-   TRY
-   {
-     return instantDataFilter;
-   }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
+  void CField::incrementNStep(void)
+  TRY
+  {
+    this->nstep++;
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::resetNStep(int nstep /*= 0*/)
+  TRY
+  {
+    this->nstep = nstep;
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::resetNStepMax(void)
+  TRY
+  {
+    this->nstepMax = 0;
+    nstepMaxRead = false;
+  }
+  CATCH_DUMP_ATTR
+
+  //----------------------------------------------------------------
+
+  bool CField::isActive(bool atCurrentTimestep /*= false*/) const
+  TRY
+  {
+    if (clientSourceFilter)
+      return atCurrentTimestep ? clientSourceFilter->isDataExpected(CContext::getCurrent()->getCalendar()->getCurrentDate()) : true;
+    else if (storeFilter)
+      return true;
+    else if (instantDataFilter)
+      ERROR("bool CField::isActive(bool atCurrentTimestep)",
+            << "Impossible to check if field [ id = " << getId() << " ] is active as it cannot be used to receive nor send data.");
+
+    return false;
+  }
+  CATCH
+
+  //----------------------------------------------------------------
+
+  bool CField::wasWritten() const
+  TRY
+  {
+    return written;
+  }
+  CATCH
+
+  void CField::setWritten()
+  TRY
+  {
+    written = true;
+  }
+  CATCH_DUMP_ATTR
+
+  //----------------------------------------------------------------
+
+  bool CField::getUseCompressedOutput() const
+  TRY
+  {
+    return useCompressedOutput;
+  }
+  CATCH
+
+  void CField::setUseCompressedOutput()
+  TRY
+  {
+    useCompressedOutput = true;
+  }
+  CATCH_DUMP_ATTR
+
+  //----------------------------------------------------------------
+
+  std::shared_ptr<COutputPin> CField::getInstantDataFilter()
+  TRY
+  {
+    return instantDataFilter;
+  }
+  CATCH_DUMP_ATTR
+
+  //----------------------------------------------------------------
+
+  /*!
+    Build up graph of grids which plays role of destination and source in grid transformation
+    This function should be called before \func solveGridReference()
+  */
+  void CField::buildGridTransformationGraph()
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    if (context->getServiceType()==CServicesManager::CLIENT)
+    {
+      if (grid_ && !grid_->isTransformed() && hasDirectFieldReference() && grid_ != getDirectFieldReference()->grid_)
+      {
+        grid_->addTransGridSource(getDirectFieldReference()->grid_);
+      }
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+    Generate a new grid destination if there are more than one grid source pointing to a same grid destination
+  */
+  void CField::generateNewTransformationGridDest()
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    if (context->getServiceType()==CServicesManager::CLIENT)
+    {
+      std::map<CGrid*,std::pair<bool,StdString> >& gridSrcMap = grid_->getTransGridSource();
+      if (1 < gridSrcMap.size())
+      {
+        // Search for grid source
+        CGrid* gridSrc = grid_;
+        CField* currField = this;
+        std::vector<CField*> hieraField;
+        while (currField->hasDirectFieldReference() && (gridSrc == grid_))
+        {
+          hieraField.push_back(currField);
+          CField* tmp = currField->getDirectFieldReference();
+          currField = tmp;
+          gridSrc = currField->grid_;
+        }
+
+        if (gridSrcMap.end() != gridSrcMap.find(gridSrc))
+        {
+          CGrid* gridTmp;
+          std::pair<bool,StdString> newGridDest = gridSrcMap[gridSrc];
+          if (newGridDest.first)
+          {
+            StdString newIdGridDest = newGridDest.second;
+            if (!CGrid::has(newIdGridDest))
+            {
+              ERROR("CGrid* CGrid::generateNewTransformationGridDest()",
+                << " Something wrong happened! Grid whose id " << newIdGridDest
+                << "should exist ");
+            }
+            gridTmp = CGrid::get(newIdGridDest);
+          }
+          else
+          {
+            StdString newIdGridDest = CGrid::generateId(gridSrc, grid_);
+            gridTmp = CGrid::cloneGrid(newIdGridDest, grid_);
+
+            (gridSrcMap[gridSrc]).first = true;
+            (gridSrcMap[gridSrc]).second = newIdGridDest;
+          }
+
+          // Update all descendants
+          for (std::vector<CField*>::iterator it = hieraField.begin(); it != hieraField.end(); ++it)
+          {
+            (*it)->grid_ = gridTmp;
+            (*it)->updateRef((*it)->grid_);
+          }
+        }
+      }
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::updateRef(CGrid* grid)
+  TRY
+  {
+    if (!grid_ref.isEmpty()) grid_ref.setValue(grid->getId());
+    else
+    {
+      std::vector<CAxis*> axisTmp = grid->getAxis();
+      std::vector<CDomain*> domainTmp = grid->getDomains();
+      if ((1<axisTmp.size()) || (1<domainTmp.size()))
+        ERROR("void CField::updateRef(CGrid* grid)",
+          << "More than one domain or axis is available for domain_ref/axis_ref of field " << this->getId());
+
+      if ((!domain_ref.isEmpty()) && (domainTmp.empty()))
+        ERROR("void CField::updateRef(CGrid* grid)",
+          << "Incoherent between available domain and domain_ref of field " << this->getId());
+      if ((!axis_ref.isEmpty()) && (axisTmp.empty()))
+        ERROR("void CField::updateRef(CGrid* grid)",
+          << "Incoherent between available axis and axis_ref of field " << this->getId());
+
+      if (!domain_ref.isEmpty()) domain_ref.setValue(domainTmp[0]->getId());
+      if (!axis_ref.isEmpty()) axis_ref.setValue(axisTmp[0]->getId());
+    }
+  }
+  CATCH_DUMP_ATTR
+   
+  /*!
+    Solve reference of all enabled fields even the source fields .
+    In this step, we do transformations.
+  */
+  void CField::solveAllEnabledFieldsAndTransform()
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+
+    if (!isReferenceSolvedAndTransformed)
+    {
+      isReferenceSolvedAndTransformed = true;
+
+      if (context->getServiceType()==CServicesManager::CLIENT)
+      {
+        solveRefInheritance(true);
+        if (hasDirectFieldReference()) getDirectFieldReference()->solveAllEnabledFieldsAndTransform();
+      }
+
+      if (context->getServiceType()==CServicesManager::GATHERER || context->getServiceType()==CServicesManager::OUT_SERVER)
+        solveServerOperation();
+
+      solveGridReference();
+
+      if (context->getServiceType()==CServicesManager::CLIENT)
+      {
+        solveGenerateGrid();
+        buildGridTransformationGraph();
+      }
+
+      solveGridDomainAxisRef(false);
+
+      if (context->getServiceType()==CServicesManager::CLIENT)
+      {
+        solveTransformedGrid();
+      }
+
+      solveGridDomainAxisRef(false);
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::checkGridOfEnabledFields()
+  TRY
+  {
+    if (!isGridChecked)
+    {
+      isGridChecked = true;
+      solveCheckMaskIndex(false);
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::sendGridComponentOfEnabledFields()
+  TRY
+  {
+    solveGridDomainAxisRef(true);
+    // solveCheckMaskIndex(true);
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::sendGridOfEnabledFields()
+  TRY
+  {
+    // solveGridDomainAxisRef(true);
+    solveCheckMaskIndex(true);
+  }   
+  CATCH_DUMP_ATTR
+
+  void CField::solveOnlyReferenceEnabledField(void)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    if (!isReferenceSolved)
+    {
+      isReferenceSolved = true;
+
+      if (context->getServiceType()==CServicesManager::CLIENT)
+      {
+        solveRefInheritance(true);
+        if (hasDirectFieldReference()) getDirectFieldReference()->solveOnlyReferenceEnabledField();
+      }
+
+      if (context->getServiceType()==CServicesManager::GATHERER || context->getServiceType()==CServicesManager::OUT_SERVER)
+        solveServerOperation();
+
+      solveGridReference();
+      grid_->solveElementsRefInheritance(true); // make it again to solve grid reading from file
+
+      if (context->getServiceType()==CServicesManager::CLIENT)
+      {
+        solveGenerateGrid();
+        buildGridTransformationGraph();
+      }
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::solveAllReferenceEnabledField(bool doSending2Server)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    solveOnlyReferenceEnabledField();
+
+    if (!areAllReferenceSolved)
+    {
+      areAllReferenceSolved = true;
+      
+      if (context->getServiceType()==CServicesManager::CLIENT)
+      {
+        solveRefInheritance(true);
+        if (hasDirectFieldReference()) getDirectFieldReference()->solveAllReferenceEnabledField(false);
+      }
+      else if (context->getServiceType()==CServicesManager::GATHERER || context->getServiceType()==CServicesManager::OUT_SERVER)
+        solveServerOperation();
+
+      solveGridReference();
+    }
+
+    solveGridDomainAxisRef(doSending2Server);
+
+    if (context->getServiceType()==CServicesManager::CLIENT)
+    {
+      solveTransformedGrid();
+    }
+
+    solveCheckMaskIndex(doSending2Server);
+  }
+  CATCH_DUMP_ATTR
+
+  std::map<int, StdSize> CField::getGridAttributesBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/)
+  TRY
+  {
+    return grid_->getAttributesBufferSize(client, bufferForWriting);
+  }
+  CATCH_DUMP_ATTR
+
+  std::map<int, StdSize> CField::getGridDataBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/)
+  TRY
+  {
+    return grid_->getDataBufferSize(client, getId(), bufferForWriting);
+  }
+  CATCH_DUMP_ATTR
+
+  size_t CField::getGlobalWrittenSize()
+  TRY
+  {
+    return grid_->getGlobalWrittenSize();
+  }
+  CATCH_DUMP_ATTR
+
+  //----------------------------------------------------------------
+
+  void CField::solveServerOperation(void)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+
+    if (context->getServiceType()==CServicesManager::CLIENT || !hasOutputFile) return;
+
+    if (freq_op.isEmpty()) freq_op.setValue(TimeStep);
+
+    if (freq_offset.isEmpty()) freq_offset.setValue(NoneDu);
+
+    freq_operation_srv = file->output_freq.getValue();
+    freq_write_srv     = file->output_freq.getValue();
+
+    lastlast_Write_srv = context->getCalendar()->getInitDate();
+    last_Write_srv     = context->getCalendar()->getInitDate();
+    last_operation_srv = context->getCalendar()->getInitDate();
+
+    const CDuration toffset = freq_operation_srv - freq_offset.getValue() - context->getCalendar()->getTimeStep();
+    last_operation_srv     = last_operation_srv - toffset;
+
+    if (operation.isEmpty())
+      ERROR("void CField::solveServerOperation(void)",
+            << "An operation must be defined for field \"" << getId() << "\".");
+
+    std::shared_ptr<func::CFunctor> functor;
+    CArray<double, 1> dummyData;
+
+#define DECLARE_FUNCTOR(MType, mtype) \
+    if (operation.getValue().compare(#mtype) == 0) \
+    { \
+      functor.reset(new func::C##MType(dummyData)); \
+    }
+
+#include "functor_type.conf"
+
+    if (!functor)
+      ERROR("void CField::solveServerOperation(void)",
+            << "\"" << operation << "\" is not a valid operation.");
+
+    operationTimeType = functor->timeType();
+  }
+  CATCH_DUMP_ATTR
+
+ //----------------------------------------------------------------
+
+  bool CField::buildWorkflowGraph(CGarbageCollector& gc)
+  {
+    if (buildWorkflowGraphDone_) return true ;
+    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 (!inputFilter) inputFilter = std::shared_ptr<CPassThroughFilter>(new CPassThroughFilter(gc)); 
+     
+    if (hasDirectFieldReference())
+    {
+      CField* fieldRef = getDirectFieldReference();
+      bool ret=fieldRef->buildWorkflowGraph(gc); 
+      if (!ret) return false ; // workflow graph cannot be built at this stage
+    }
+
+    // Check if we have an expression to parse
+    std::shared_ptr<COutputPin> filterExpr ;
+    if (hasExpression())
+    {
+      boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0'));
+      filterExpr = expr->reduce(gc, *this);
+      if (!filterExpr) return false ; // workflow graph cannot be built at this stage
+    }
+    
+    // now construct grid and check if element are enabled
+    solveGridReference() ; // grid_ is now defined
+    
+    // prepare transformation. Need to know before if workflow of auxillary field can be built
+    if (hasDirectFieldReference())
+    {
+      auto gridPath=getGridPath() ;
+      gridPath.push_back(grid_) ;
+
+      CGrid* gridSrc=getDirectFieldReference()->getGrid() ;
+      for(auto grid : gridPath)
+      {
+        if (!grid->checkIfCompleted()) return false ;
+        grid->solveElementsRefInheritance() ;
+        grid_->completeGrid(gridSrc); // grid generation, to be checked
+        grid->prepareTransformGrid(gridSrc) ; // prepare the grid tranformation
+        for(auto fieldId : grid->getAuxInputTransformGrid()) // try to build workflow graph for auxillary field tranformation
+          if (!CField::get(fieldId)->buildWorkflowGraph(gc)) return false ;
+        gridSrc=grid ;
+      }
+      
+      std::shared_ptr<COutputPin> lastFilter ;
+      if (filterExpr) lastFilter=filterExpr ;
+      else lastFilter = inputFilter ;
+      
+      gridSrc=getDirectFieldReference()->getGrid() ;
+      for(auto grid : gridPath) 
+      {
+        grid->makeTransformGrid() ; // make the grid transformation
+        std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridSrc, grid, detectMissingValues, defaultValue); 
+        lastFilter->connectOutput(filters.first, 0);
+        lastFilter = filters.second;
+        gridSrc=grid ;
+      }
+      instantDataFilter = lastFilter ;
+      
+      // connect the input Filter to the reference
+      getDirectFieldReference()->getInstantDataFilter()->connectOutput(inputFilter,0);
+    }
+    else 
+    {
+      if (!grid_->checkIfCompleted()) return false ;
+      grid_->solveElementsRefInheritance() ;
+      grid_->completeGrid(); // grid generation, to be checked
+      grid_->checkElementsAttributes() ;
+      instantDataFilter=inputFilter ;
+      setModelIn() ; // no reference, the field is potentially a source field from model
+    }
+    
+    buildWorkflowGraphDone_ = true ;
+    workflowEnabled_ = true ;
+    return true ;
+  }
+   
+  
+  void CField::connectToFileServer(CGarbageCollector& gc)
+  {
+    // insert temporal filter before sending to files
+    fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this, file->getContextClient()));
+    // insert temporal filter before sending to files
+    getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0);
+  } 
+
+  void CField::computeGridIndexToFileServer(void)
+  {
+    grid_->computeGridIndexToFileServer(client) ;
+  }
 
    /*!
-     Build up graph of grids which plays role of destination and source in grid transformation
-     This function should be called before \func solveGridReference()
+   * Transform the grid_path attribut into vector of grid.
+   * \return the vector CGrid* containing the list of grid path for tranformation
+   */ 
+  vector<CGrid*> CField::getGridPath(void)
+  {
+    std::vector<CGrid*> gridPath;
+
+    if (hasDirectFieldReference() && grid_ != getDirectFieldReference()->grid_)
+    {
+      if (!grid_path.isEmpty())
+      {
+        std::string gridId;
+        size_t start = 0, end;
+
+        do
+        {
+          end = grid_path.getValue().find(',', start);
+          if (end != std::string::npos)
+          {
+            gridId = grid_path.getValue().substr(start, end - start);
+            start = end + 1;
+          }
+          else gridId = grid_path.getValue().substr(start);
+
+          if (!CGrid::has(gridId))
+            ERROR("void CField::solveTransformedGrid()",
+               << "Invalid grid_path, the grid '" << gridId << "' does not exist.");
+
+          gridPath.push_back(CGrid::get(gridId));
+        }
+        while (end != std::string::npos);
+      }
+    }
+    return gridPath ;
+  }
+
+  /*!
+   * Constructs the graph filter for the field, enabling or not the data output.
+   * This method should not be called more than once with enableOutput equal to true.
+   *
+   * \param gc the garbage collector to use when building the filter graph
+   * \param enableOutput must be true when the field data is to be
+   *                     read by the client or/and written to a file
    */
-   void CField::buildGridTransformationGraph()
-   TRY
-   {
-     CContext* context = CContext::getCurrent();
-     if (context->getServiceType()==CServicesManager::CLIENT)
-     {
-       if (grid && !grid->isTransformed() && hasDirectFieldReference() && grid != getDirectFieldReference()->grid)
-       {
-         grid->addTransGridSource(getDirectFieldReference()->grid);
-       }
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-     Generate a new grid destination if there are more than one grid source pointing to a same grid destination
-   */
-   void CField::generateNewTransformationGridDest()
-   TRY
-   {
-     CContext* context = CContext::getCurrent();
-     if (context->getServiceType()==CServicesManager::CLIENT)
-     {
-       std::map<CGrid*,std::pair<bool,StdString> >& gridSrcMap = grid->getTransGridSource();
-       if (1 < gridSrcMap.size())
-       {
-         // Search for grid source
-         CGrid* gridSrc = grid;
-         CField* currField = this;
-         std::vector<CField*> hieraField;
-
-         while (currField->hasDirectFieldReference() && (gridSrc == grid))
-         {
-           hieraField.push_back(currField);
-           CField* tmp = currField->getDirectFieldReference();
-           currField = tmp;
-           gridSrc = currField->grid;
-         }
-
-         if (gridSrcMap.end() != gridSrcMap.find(gridSrc))
-         {
-           CGrid* gridTmp;
-           std::pair<bool,StdString> newGridDest = gridSrcMap[gridSrc];
-           if (newGridDest.first)
-           {
-             StdString newIdGridDest = newGridDest.second;
-             if (!CGrid::has(newIdGridDest))
-             {
-                ERROR("CGrid* CGrid::generateNewTransformationGridDest()",
-                  << " Something wrong happened! Grid whose id " << newIdGridDest
-                  << "should exist ");
-             }
-             gridTmp = CGrid::get(newIdGridDest);
-           }
-           else
-           {
-             StdString newIdGridDest = CGrid::generateId(gridSrc, grid);
-             gridTmp = CGrid::cloneGrid(newIdGridDest, grid);
-
-             (gridSrcMap[gridSrc]).first = true;
-             (gridSrcMap[gridSrc]).second = newIdGridDest;
-           }
-
-           // Update all descendants
-           for (std::vector<CField*>::iterator it = hieraField.begin(); it != hieraField.end(); ++it)
-           {
-             (*it)->grid = gridTmp;
-             (*it)->updateRef((*it)->grid);
-           }
-         }
-       }
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::updateRef(CGrid* grid)
-   TRY
-   {
-     if (!grid_ref.isEmpty()) grid_ref.setValue(grid->getId());
-     else
-     {
-       std::vector<CAxis*> axisTmp = grid->getAxis();
-       std::vector<CDomain*> domainTmp = grid->getDomains();
-       if ((1<axisTmp.size()) || (1<domainTmp.size()))
-         ERROR("void CField::updateRef(CGrid* grid)",
-           << "More than one domain or axis is available for domain_ref/axis_ref of field " << this->getId());
-
-       if ((!domain_ref.isEmpty()) && (domainTmp.empty()))
-         ERROR("void CField::updateRef(CGrid* grid)",
-           << "Incoherent between available domain and domain_ref of field " << this->getId());
-       if ((!axis_ref.isEmpty()) && (axisTmp.empty()))
-         ERROR("void CField::updateRef(CGrid* grid)",
-           << "Incoherent between available axis and axis_ref of field " << this->getId());
-
-       if (!domain_ref.isEmpty()) domain_ref.setValue(domainTmp[0]->getId());
-       if (!axis_ref.isEmpty()) axis_ref.setValue(axisTmp[0]->getId());
-     }
-   }
-   CATCH_DUMP_ATTR
-   
-   /*!
-     Solve reference of all enabled fields even the source fields .
-     In this step, we do transformations.
-   */
-   void CField::solveAllEnabledFieldsAndTransform()
-   TRY
-   {
-     CContext* context = CContext::getCurrent();
-
-     if (!isReferenceSolvedAndTransformed)
-     {
-        isReferenceSolvedAndTransformed = true;
-
-        if (context->getServiceType()==CServicesManager::CLIENT)
-        {
-          solveRefInheritance(true);
-          if (hasDirectFieldReference()) getDirectFieldReference()->solveAllEnabledFieldsAndTransform();
-        }
-
-        if (context->getServiceType()==CServicesManager::GATHERER || context->getServiceType()==CServicesManager::OUT_SERVER)
-          solveServerOperation();
-
-        solveGridReference();
-
-       if (context->getServiceType()==CServicesManager::CLIENT)
-       {
-         solveGenerateGrid();
-         buildGridTransformationGraph();
-       }
-
-       solveGridDomainAxisRef(false);
-
-       if (context->getServiceType()==CServicesManager::CLIENT)
-       {
-         solveTransformedGrid();
-       }
-
-       solveGridDomainAxisRef(false);
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::checkGridOfEnabledFields()
-   TRY
-   {
-     if (!isGridChecked)
-     {
-       isGridChecked = true;
-       solveCheckMaskIndex(false);
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::sendGridComponentOfEnabledFields()
-   TRY
-   {
-      solveGridDomainAxisRef(true);
-      // solveCheckMaskIndex(true);
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::sendGridOfEnabledFields()
-   TRY
-   {
-      // solveGridDomainAxisRef(true);
-      solveCheckMaskIndex(true);
-   }   
-   CATCH_DUMP_ATTR
-
-   void CField::solveOnlyReferenceEnabledField(void)
-   TRY
-   {
-     CContext* context = CContext::getCurrent();
-     if (!isReferenceSolved)
-     {
-        isReferenceSolved = true;
-
-        if (context->getServiceType()==CServicesManager::CLIENT)
-        {
-          solveRefInheritance(true);
-          if (hasDirectFieldReference()) getDirectFieldReference()->solveOnlyReferenceEnabledField();
-        }
-
-        if (context->getServiceType()==CServicesManager::GATHERER || context->getServiceType()==CServicesManager::OUT_SERVER)
-          solveServerOperation();
-
-        solveGridReference();
-        grid->solveDomainAxisRefInheritance(true); // make it again to solve grid reading from file
-
-       if (context->getServiceType()==CServicesManager::CLIENT)
-       {
-         solveGenerateGrid();
-         buildGridTransformationGraph();
-       }
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::solveAllReferenceEnabledField(bool doSending2Server)
-   TRY
-   {
-     CContext* context = CContext::getCurrent();
-     solveOnlyReferenceEnabledField();
-
-     if (!areAllReferenceSolved)
-     {
-        areAllReferenceSolved = true;
-       
-        if (context->getServiceType()==CServicesManager::CLIENT)
-        {
-          solveRefInheritance(true);
-          if (hasDirectFieldReference()) getDirectFieldReference()->solveAllReferenceEnabledField(false);
-        }
-        else if (context->getServiceType()==CServicesManager::GATHERER || context->getServiceType()==CServicesManager::OUT_SERVER)
-          solveServerOperation();
-
-        solveGridReference();
-     }
-
-     solveGridDomainAxisRef(doSending2Server);
-
-     if (context->getServiceType()==CServicesManager::CLIENT)
-     {
-       solveTransformedGrid();
-     }
-
-     solveCheckMaskIndex(doSending2Server);
-   }
-   CATCH_DUMP_ATTR
-
-   std::map<int, StdSize> CField::getGridAttributesBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/)
-   TRY
-   {
-     return grid->getAttributesBufferSize(client, bufferForWriting);
-   }
-   CATCH_DUMP_ATTR
-
-   std::map<int, StdSize> CField::getGridDataBufferSize(CContextClient* client, bool bufferForWriting /*= "false"*/)
-   TRY
-   {
-     return grid->getDataBufferSize(client, getId(), bufferForWriting);
-   }
-   CATCH_DUMP_ATTR
-
-   size_t CField::getGlobalWrittenSize()
-   TRY
-   {
-     return grid->getGlobalWrittenSize();
-   }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
-
-   void CField::solveServerOperation(void)
-   TRY
-   {
-      CContext* context = CContext::getCurrent();
-
-      if (context->getServiceType()==CServicesManager::CLIENT || !hasOutputFile) return;
-
-      if (freq_op.isEmpty())
-        freq_op.setValue(TimeStep);
-
-      if (freq_offset.isEmpty())
-        freq_offset.setValue(NoneDu);
-
-      freq_operation_srv = file->output_freq.getValue();
-      freq_write_srv     = file->output_freq.getValue();
-
-      lastlast_Write_srv = context->getCalendar()->getInitDate();
-      last_Write_srv     = context->getCalendar()->getInitDate();
-      last_operation_srv = context->getCalendar()->getInitDate();
-
-      const CDuration toffset = freq_operation_srv - freq_offset.getValue() - context->getCalendar()->getTimeStep();
-      last_operation_srv     = last_operation_srv - toffset;
-
-      if (operation.isEmpty())
-        ERROR("void CField::solveServerOperation(void)",
-              << "An operation must be defined for field \"" << getId() << "\".");
-
-      std::shared_ptr<func::CFunctor> functor;
-      CArray<double, 1> dummyData;
-
-#define DECLARE_FUNCTOR(MType, mtype) \
-      if (operation.getValue().compare(#mtype) == 0) \
-      { \
-        functor.reset(new func::C##MType(dummyData)); \
-      }
-
-#include "functor_type.conf"
-
-      if (!functor)
-        ERROR("void CField::solveServerOperation(void)",
-              << "\"" << operation << "\" is not a valid operation.");
-
-      operationTimeType = functor->timeType();
-   }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
-
-   /*!
-    * Constructs the graph filter for the field, enabling or not the data output.
-    * This method should not be called more than once with enableOutput equal to true.
-    *
-    * \param gc the garbage collector to use when building the filter graph
-    * \param enableOutput must be true when the field data is to be
-    *                     read by the client or/and written to a file
-    */
-   void CField::buildFilterGraph(CGarbageCollector& gc, bool enableOutput)
-   TRY
-   {     
+
+  void CField::buildFilterGraph(CGarbageCollector& gc, bool enableOutput)
+  TRY
+  {     
     if (!isReferenceSolvedAndTransformed) solveAllEnabledFieldsAndTransform();
     if (!isGridChecked) checkGridOfEnabledFields();
 
-     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);
-
-     CContext* context = CContext::getCurrent();
-     bool hasWriterServer = context->getServiceType()==CServicesManager::OUT_SERVER ;
-     bool hasIntermediateServer = context->getServiceType()==CServicesManager::GATHERER ;
-
-     if (hasWriterServer)
-     {
-        if (!instantDataFilter)
-          instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false));
-
-
-       // If the field data is to be read by the client or/and written to a file
-       if (enableOutput && !storeFilter && !fileWriterFilter)
-       {
-         if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
-         {
-           fileServerWriterFilter = std::shared_ptr<CFileServerWriterFilter>(new CFileServerWriterFilter(gc, this));
-           instantDataFilter->connectOutput(fileServerWriterFilter, 0);
+    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);
+
+    CContext* context = CContext::getCurrent();
+    bool hasWriterServer = context->getServiceType()==CServicesManager::OUT_SERVER ;
+    bool hasIntermediateServer = context->getServiceType()==CServicesManager::GATHERER ;
+
+    if (hasWriterServer)
+    {
+      if (!instantDataFilter)
+        instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, true, false));
+
+
+      // If the field data is to be read by the client or/and written to a file
+      if (enableOutput && !storeFilter && !fileWriterFilter)
+      {
+        if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
+        {
+          fileServerWriterFilter = std::shared_ptr<CFileServerWriterFilter>(new CFileServerWriterFilter(gc, this));
+          instantDataFilter->connectOutput(fileServerWriterFilter, 0);
+        }
+      }
+    }
+    else if (hasIntermediateServer)
+    {
+      if (!instantDataFilter)
+        instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, false, false));
+
+      // If the field data is to be read by the client or/and written to a file
+      if (enableOutput && !storeFilter && !fileWriterFilter)
+      {
+        if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
+        {
+          fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this, file->getContextClient()));
+          instantDataFilter->connectOutput(fileWriterFilter, 0);
+        }
+      }
+    }
+    else
+    {
+      // Start by building a filter which can provide the field's instant data
+      if (!instantDataFilter)
+      {
+        // Check if we have an expression to parse
+        if (hasExpression())
+        {
+          boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0'));
+          std::shared_ptr<COutputPin> filter = expr->reduce(gc, *this);
+
+          // Check if a spatial transformation is needed
+          if (!field_ref.isEmpty())
+          {
+            CGrid* gridRef = CField::get(field_ref)->grid_;
+            if (grid_ && grid_ != gridRef && grid_->hasTransform())
+            {
+                std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid_, detectMissingValues, defaultValue); 
+
+              filter->connectOutput(filters.first, 0);
+              filter = filters.second;
+            }
+          }
+
+          instantDataFilter = filter;
+        }
+        // Check if we have a reference on another field
+        else if (!field_ref.isEmpty()) instantDataFilter = getFieldReference(gc);
+        // Check if the data is to be read from a file
+        else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
+        {
+          checkTimeAttributes();
+          instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, true, false, freq_offset, true,
+                                                                                                       detectMissingValues, defaultValue));
+        }
+        else // The data might be passed from the model
+        {
+          if (check_if_active.isEmpty()) check_if_active = false; 
+          instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, false, true, NoneDu, false,
+                                                                                                      detectMissingValues, defaultValue));
+        }
+      }
+
+      // If the field data is to be read by the client or/and written to a file
+      if (enableOutput && !storeFilter && !fileWriterFilter)
+      {
+        if (!read_access.isEmpty() && read_access)
+        {
+          storeFilter = std::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid_,
+                                                                          detectMissingValues, defaultValue));
+          instantDataFilter->connectOutput(storeFilter, 0);
+        }
+
+        if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
+        {
+          fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this, file->getContextClient()));
+          getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0);
+        }
+      }
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+   * Returns the filter needed to handle the field reference.
+   * This method should only be called when building the filter graph corresponding to the field.
+   *
+   * \param gc the garbage collector to use
+   * \return the output pin corresponding to the field reference
+   */
+  std::shared_ptr<COutputPin> CField::getFieldReference(CGarbageCollector& gc)
+  TRY
+  {
+    if (instantDataFilter || field_ref.isEmpty())
+      ERROR("COutputPin* CField::getFieldReference(CGarbageCollector& gc)",
+            "Impossible to get the field reference for a field which has already been parsed or which does not have a field_ref.");
+
+    CField* fieldRef = CField::get(field_ref);
+    fieldRef->buildFilterGraph(gc, false);
+
+    std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters;
+    // Check if a spatial transformation is needed
+    if (grid_ && grid_ != fieldRef->grid_ && grid_->hasTransform())
+    {       
+      bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true);
+      double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);                                
+      filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid_, grid_, hasMissingValue, defaultValue);
+    }
+    else
+      filters.first = filters.second = std::shared_ptr<CFilter>(new CPassThroughFilter(gc));
+
+    fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0);
+
+    return filters.second;
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+   * Returns the filter needed to handle a self reference in the field's expression.
+   * If the needed filter does not exist, it is created, otherwise it is reused.
+   * This method should only be called when building the filter graph corresponding
+   * to the field's expression.
+   *
+   * \param gc the garbage collector to use
+   * \return the output pin corresponding to a self reference
+   */
+
+/* old version
+  std::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc)
+  TRY
+  {
+    if (instantDataFilter || !hasExpression())
+      ERROR("COutputPin* CField::getSelfReference(CGarbageCollector& gc)",
+            "Impossible to add a self reference to a field which has already been parsed or which does not have an expression.");
+
+    if (!selfReferenceFilter)
+    {
+      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 (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
+      {
+        if (!serverSourceFilter)
+        {
+          checkTimeAttributes();
+          serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, true, false, freq_offset, true,
+                                                              detectMissingValues, defaultValue));
          }
-       }
-     }
-     else if (hasIntermediateServer)
-     {
-       if (!instantDataFilter)
-         instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, false));
-
-             // If the field data is to be read by the client or/and written to a file
-       if (enableOutput && !storeFilter && !fileWriterFilter)
-       {
-         if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
-         {
-           fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this, file->getContextClient()));
-           instantDataFilter->connectOutput(fileWriterFilter, 0);
-         }
-       }
-     }
-     else
-     {
-       // Start by building a filter which can provide the field's instant data
-       if (!instantDataFilter)
-       {
-         // Check if we have an expression to parse
-         if (hasExpression())
-         {
-           boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0'));
-           std::shared_ptr<COutputPin> filter = expr->reduce(gc, *this);
-
-           // Check if a spatial transformation is needed
-           if (!field_ref.isEmpty())
-           {
-             CGrid* gridRef = CField::get(field_ref)->grid;
-
-             if (grid && grid != gridRef && grid->hasTransform())
-             {
-                 std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, detectMissingValues, defaultValue); 
-
-               filter->connectOutput(filters.first, 0);
-               filter = filters.second;
-             }
-           }
-
-           instantDataFilter = filter;
-         }
-         // Check if we have a reference on another field
-         else if (!field_ref.isEmpty())
-           instantDataFilter = getFieldReference(gc);
-         // Check if the data is to be read from a file
-         else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
-         {
-           checkTimeAttributes();
-           instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true,
-                                                                                                       detectMissingValues, defaultValue));
-         }
-         else // The data might be passed from the model
-         {
-            if (check_if_active.isEmpty()) check_if_active = false; 
-            instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false,
-                                                                                                        detectMissingValues, defaultValue));
-         }
-       }
-
-       // If the field data is to be read by the client or/and written to a file
-       if (enableOutput && !storeFilter && !fileWriterFilter)
-       {
-         if (!read_access.isEmpty() && read_access)
-         {
-           storeFilter = std::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid,
-                                                                          detectMissingValues, defaultValue));
-           instantDataFilter->connectOutput(storeFilter, 0);
-         }
-
-         if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
-         {
-           fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this, file->getContextClient()));
-           getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0);
-         }
-       }
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-    * Returns the filter needed to handle the field reference.
-    * This method should only be called when building the filter graph corresponding to the field.
-    *
-    * \param gc the garbage collector to use
-    * \return the output pin corresponding to the field reference
-    */
-   std::shared_ptr<COutputPin> CField::getFieldReference(CGarbageCollector& gc)
-   TRY
-   {
-     if (instantDataFilter || field_ref.isEmpty())
-       ERROR("COutputPin* CField::getFieldReference(CGarbageCollector& gc)",
-             "Impossible to get the field reference for a field which has already been parsed or which does not have a field_ref.");
-
-     CField* fieldRef = CField::get(field_ref);
-     fieldRef->buildFilterGraph(gc, false);
-
-     std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters;
-     // Check if a spatial transformation is needed
-     if (grid && grid != fieldRef->grid && grid->hasTransform())
-     {       
-       bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true);
-       double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);                                
-       filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue);
-     }
-     else
-       filters.first = filters.second = std::shared_ptr<CFilter>(new CPassThroughFilter(gc));
-
-     fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0);
-
-     return filters.second;
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-    * Returns the filter needed to handle a self reference in the field's expression.
-    * If the needed filter does not exist, it is created, otherwise it is reused.
-    * This method should only be called when building the filter graph corresponding
-    * to the field's expression.
-    *
-    * \param gc the garbage collector to use
-    * \return the output pin corresponding to a self reference
-    */
-   std::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc)
-   TRY
-   {
-     if (instantDataFilter || !hasExpression())
-       ERROR("COutputPin* CField::getSelfReference(CGarbageCollector& gc)",
-             "Impossible to add a self reference to a field which has already been parsed or which does not have an expression.");
-
-     if (!selfReferenceFilter)
-     {
-       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 (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
-       {
-         if (!serverSourceFilter)
-         {
-           checkTimeAttributes();
-           serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true,
-                                                                                   detectMissingValues, defaultValue));
-         }
-
-         selfReferenceFilter = serverSourceFilter;
-       }
-       else if (!field_ref.isEmpty())
-       {
-         CField* fieldRef = CField::get(field_ref);
-         fieldRef->buildFilterGraph(gc, false);
-         selfReferenceFilter = fieldRef->getInstantDataFilter();
-       }
-       else
-       {
-         if (!clientSourceFilter)
-         {
-           if (check_if_active.isEmpty()) check_if_active = false;
-           clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, true, NoneDu, false,
-                                                                                   detectMissingValues, defaultValue));
-         }
-
-         selfReferenceFilter = clientSourceFilter;
-       }
-     }
-
-     return selfReferenceFilter;
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-    * Returns the temporal filter corresponding to the field's temporal operation
-    * for the specified operation frequency. The filter is created if it does not
-    * exist, otherwise it is reused.
-    *
-    * \param gc the garbage collector to use
-    * \param outFreq the operation frequency, i.e. the frequency at which the output data will be computed
-    * \return the output pin corresponding to the requested temporal filter
-    */
-   std::shared_ptr<COutputPin> CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)
-   TRY
-   {
-     std::map<CDuration, std::shared_ptr<COutputPin> >::iterator it = temporalDataFilters.find(outFreq);
-
-     if (it == temporalDataFilters.end())
-     {
-       if (operation.isEmpty())
-         ERROR("void CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)",
-               << "An operation must be defined for field \"" << getId() << "\".");
-
-       checkTimeAttributes(&outFreq);
-
-       const bool detectMissingValues = (!detect_missing_value.isEmpty()  && detect_missing_value == true);
-       std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation,
+
+        selfReferenceFilter = serverSourceFilter;
+      }
+      else if (!field_ref.isEmpty())
+      {
+        CField* fieldRef = CField::get(field_ref);
+        fieldRef->buildFilterGraph(gc, false);
+        selfReferenceFilter = fieldRef->getInstantDataFilter();
+      }
+      else
+      {
+        if (!clientSourceFilter)
+        {
+          if (check_if_active.isEmpty()) check_if_active = false;
+          clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid_, true, true, NoneDu, false,
+                                                                                detectMissingValues, defaultValue));
+        }
+
+        selfReferenceFilter = clientSourceFilter;
+      }
+    }
+
+    return selfReferenceFilter;
+  }
+  CATCH_DUMP_ATTR
+*/
+  std::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc)
+  TRY
+  {
+    return inputFilter ;
+  } 
+  CATCH_DUMP_ATTR
+
+  /*!
+   * Returns the temporal filter corresponding to the field's temporal operation
+   * for the specified operation frequency. The filter is created if it does not
+   * exist, otherwise it is reused.
+   *
+   * \param gc the garbage collector to use
+   * \param outFreq the operation frequency, i.e. the frequency at which the output data will be computed
+   * \return the output pin corresponding to the requested temporal filter
+   */
+  std::shared_ptr<COutputPin> CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)
+  TRY
+  {
+    std::map<CDuration, std::shared_ptr<COutputPin> >::iterator it = temporalDataFilters.find(outFreq);
+
+    if (it == temporalDataFilters.end())
+    {
+      if (operation.isEmpty())
+        ERROR("void CField::getTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)",
+              << "An operation must be defined for field \"" << getId() << "\".");
+
+      checkTimeAttributes(&outFreq);
+
+      const bool detectMissingValues = (!detect_missing_value.isEmpty()  && detect_missing_value == true);
+      std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation,
                                                                              CContext::getCurrent()->getCalendar()->getInitDate(),
                                                                              freq_op, freq_offset, outFreq, detectMissingValues));
 
-       instantDataFilter->connectOutput(temporalFilter, 0);
-
-       it = temporalDataFilters.insert(std::make_pair(outFreq, temporalFilter)).first;
-     }
-
-     return it->second;
-   }
-   CATCH_DUMP_ATTR
+      instantDataFilter->connectOutput(temporalFilter, 0);
+
+      it = temporalDataFilters.insert(std::make_pair(outFreq, temporalFilter)).first;
+    }
+
+    return it->second;
+  }
+  CATCH_DUMP_ATTR
 
   /*!
@@ -1347,40 +1481,77 @@
     * \return the output pin corresponding to the requested temporal filter
     */
-   
-   std::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)
-   TRY
-   {
-     if (instantDataFilter || !hasExpression())
-       ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)",
-             "Impossible to add a self reference to a field which has already been parsed or which does not have an expression.");
-
-     if (!selfReferenceFilter) getSelfReference(gc) ;
-
-     if (serverSourceFilter || clientSourceFilter)
-     {
-       if (operation.isEmpty())
-         ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)",
-               << "An operation must be defined for field \"" << getId() << "\".");
-
-       checkTimeAttributes(&outFreq);
-
-       const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true);
-       std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation,
-                                                                             CContext::getCurrent()->getCalendar()->getInitDate(),
-                                                                             freq_op, freq_offset, outFreq, detectMissingValues));
-
-       selfReferenceFilter->connectOutput(temporalFilter, 0);
-       return temporalFilter ;
-     }
-     else if (!field_ref.isEmpty())
-     {
-       CField* fieldRef = CField::get(field_ref);
-       fieldRef->buildFilterGraph(gc, false); 
-       return fieldRef->getTemporalDataFilter(gc, outFreq) ;
-     }
-  }
-   CATCH_DUMP_ATTR
-
-   //----------------------------------------------------------------
+
+  std::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)
+  TRY
+  {
+    if (instantDataFilter || !hasExpression())
+      ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)",
+            "Impossible to add a self reference to a field which has already been parsed or which does not have an expression.");
+    
+    if (selfTemporalDataFilter) return selfTemporalDataFilter;
+
+    if (hasDirectFieldReference())
+    {
+      CField* fieldRef=getDirectFieldReference();
+      return fieldRef->getTemporalDataFilter(gc, outFreq) ;
+    }
+    else
+    {
+      if (selfTemporalDataFilter) return selfTemporalDataFilter ;
+
+      if (operation.isEmpty())
+        ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)",
+              << "An operation must be defined for field \"" << getId() << "\".");
+
+      checkTimeAttributes(&outFreq); //bof
+
+      const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true);
+      selfTemporalDataFilter = std::shared_ptr<CTemporalFilter>(new CTemporalFilter(gc, operation,
+                                                                CContext::getCurrent()->getCalendar()->getInitDate(),
+                                                                freq_op, freq_offset, outFreq, detectMissingValues));
+
+      inputFilter->connectOutput(selfTemporalDataFilter, 0);
+      return selfTemporalDataFilter ;
+    }
+  }
+  CATCH_DUMP_ATTR
+
+/* old version   
+  std::shared_ptr<COutputPin> CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)
+  TRY
+  {
+    if (instantDataFilter || !hasExpression())
+      ERROR("COutputPin* CField::getSelfTemporalDataFilter(CGarbageCollector& gc)",
+            "Impossible to add a self reference to a field which has already been parsed or which does not have an expression.");
+
+    if (!selfReferenceFilter) getSelfReference(gc) ;
+
+    if (serverSourceFilter || clientSourceFilter)
+    {
+      if (operation.isEmpty())
+        ERROR("void CField::getSelfTemporalDataFilter(CGarbageCollector& gc, CDuration outFreq)",
+              << "An operation must be defined for field \"" << getId() << "\".");
+
+      checkTimeAttributes(&outFreq);
+
+      const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true);
+      std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation,
+                                                                          CContext::getCurrent()->getCalendar()->getInitDate(),
+                                                                          freq_op, freq_offset, outFreq, detectMissingValues));
+
+      selfReferenceFilter->connectOutput(temporalFilter, 0);
+      return temporalFilter ;
+    }
+    else if (!field_ref.isEmpty())
+    {
+      CField* fieldRef = CField::get(field_ref);
+      fieldRef->buildFilterGraph(gc, false); 
+      return fieldRef->getTemporalDataFilter(gc, outFreq) ;
+    }
+  }
+  CATCH_DUMP_ATTR
+*/
+
+  //----------------------------------------------------------------
 /*
    void CField::fromBinary(StdIStream& is)
@@ -1398,497 +1569,466 @@
    //----------------------------------------------------------------
 
-   void CField::solveGridReference(void)
-   TRY
-   {
-      if (grid_ref.isEmpty() && domain_ref.isEmpty() && axis_ref.isEmpty() && scalar_ref.isEmpty())
-      {
-        ERROR("CField::solveGridReference(void)",
-              << "A grid must be defined for field '" << getFieldOutputName() << "' .");
-      }
-      else if (!grid_ref.isEmpty() && (!domain_ref.isEmpty() || !axis_ref.isEmpty() || !scalar_ref.isEmpty()))
-      {
-        ERROR("CField::solveGridReference(void)",
-              << "Field '" << getFieldOutputName() << "' has both a grid and a domain/axis/scalar." << std::endl
-              << "Please define either 'grid_ref' or 'domain_ref'/'axis_ref'/'scalar_ref'.");
-      }
-
-      if (grid_ref.isEmpty())
-      {
-        std::vector<CDomain*> vecDom;
-        std::vector<CAxis*> vecAxis;
-        std::vector<CScalar*> vecScalar;
-        std::vector<int> axisDomainOrderTmp;
-
-        std::vector<CDomain*> vecDomRef;
-        std::vector<CAxis*> vecAxisRef;
-        std::vector<CScalar*> vecScalarRef;
-
+  void CField::solveGridReference(void)
+  TRY
+  {
+    if (grid_!=nullptr) return ; // already done
+
+    if (grid_ref.isEmpty() && domain_ref.isEmpty() && axis_ref.isEmpty() && scalar_ref.isEmpty())
+    {
+      ERROR("CField::solveGridReference(void)",
+            << "A grid must be defined for field '" << getFieldOutputName() << "' .");
+    }
+    else if (!grid_ref.isEmpty() && (!domain_ref.isEmpty() || !axis_ref.isEmpty() || !scalar_ref.isEmpty()))
+    {
+      ERROR("CField::solveGridReference(void)",
+            << "Field '" << getFieldOutputName() << "' has both a grid and a domain/axis/scalar." << std::endl
+            << "Please define either 'grid_ref' or 'domain_ref'/'axis_ref'/'scalar_ref'.");
+    }
+
+    if (grid_ref.isEmpty())
+    {
+      std::vector<CDomain*> vecDom;
+      std::vector<CAxis*> vecAxis;
+      std::vector<CScalar*> vecScalar;
+      std::vector<int> axisDomainOrderTmp;
+
+      std::vector<CDomain*> vecDomRef;
+      std::vector<CAxis*> vecAxisRef;
+      std::vector<CScalar*> vecScalarRef;
         
-        if (!domain_ref.isEmpty())
+      if (!domain_ref.isEmpty())
+      {
+        StdString tmp = domain_ref.getValue();
+        if (CDomain::has(domain_ref))
         {
-          StdString tmp = domain_ref.getValue();
-          if (CDomain::has(domain_ref))
-          {
-            vecDom.push_back(CDomain::get(domain_ref));
-            vecDomRef.push_back(CDomain::createDomain());
-            vecDomRef.back()->domain_ref=domain_ref;
-            axisDomainOrderTmp.push_back(2);
-          }
-          else  ERROR("CField::solveGridReference(void)",
-                      << "Invalid reference to domain '" << domain_ref.getValue() << "'.");
+          vecDom.push_back(CDomain::get(domain_ref));
+          vecDomRef.push_back(CDomain::createDomain());
+          vecDomRef.back()->domain_ref=domain_ref;
+          axisDomainOrderTmp.push_back(2);
         }
-
-        if (!axis_ref.isEmpty())
+        else  ERROR("CField::solveGridReference(void)",
+                    << "Invalid reference to domain '" << domain_ref.getValue() << "'.");
+      }
+
+      if (!axis_ref.isEmpty())
+      {
+        if (CAxis::has(axis_ref))
         {
-          if (CAxis::has(axis_ref))
-          {
-            vecAxis.push_back(CAxis::get(axis_ref));
-            vecAxisRef.push_back(CAxis::createAxis());
-            vecAxisRef.back()->axis_ref=axis_ref;
-            axisDomainOrderTmp.push_back(1);
-          }
-          else  ERROR("CField::solveGridReference(void)",
-                      << "Invalid reference to axis '" << axis_ref.getValue() << "'.");
+          vecAxis.push_back(CAxis::get(axis_ref));
+          vecAxisRef.push_back(CAxis::createAxis());
+          vecAxisRef.back()->axis_ref=axis_ref;
+          axisDomainOrderTmp.push_back(1);
         }
-
-        if (!scalar_ref.isEmpty())
+        else  ERROR("CField::solveGridReference(void)",
+                    << "Invalid reference to axis '" << axis_ref.getValue() << "'.");
+      }
+
+      if (!scalar_ref.isEmpty())
+      {
+        if (CScalar::has(scalar_ref))
         {
-          if (CScalar::has(scalar_ref))
-          {
-            vecScalar.push_back(CScalar::get(scalar_ref));
-            vecScalarRef.push_back(CScalar::createScalar());
-            vecScalarRef.back()->scalar_ref=scalar_ref;
-            axisDomainOrderTmp.push_back(0);
-          }
-          else ERROR("CField::solveGridReference(void)",
-                     << "Invalid reference to scalar '" << scalar_ref.getValue() << "'.");
+          vecScalar.push_back(CScalar::get(scalar_ref));
+          vecScalarRef.push_back(CScalar::createScalar());
+          vecScalarRef.back()->scalar_ref=scalar_ref;
+          axisDomainOrderTmp.push_back(0);
         }
+        else ERROR("CField::solveGridReference(void)",
+                   << "Invalid reference to scalar '" << scalar_ref.getValue() << "'.");
+      }
         
-        CArray<int,1> axisDomainOrder(axisDomainOrderTmp.size());
-        for (int idx = 0; idx < axisDomainOrderTmp.size(); ++idx)
-        {
-          axisDomainOrder(idx) = axisDomainOrderTmp[idx];
-        }
-
-        // Warning: the gridId shouldn't be set as the grid_ref since it could be inherited
-        StdString gridId = CGrid::generateId(vecDom, vecAxis, vecScalar,axisDomainOrder);
-        if (CGrid::has(gridId)) this->grid = CGrid::get(gridId);
-        else  this->grid = CGrid::createGrid(gridId, vecDomRef, vecAxisRef, vecScalarRef,axisDomainOrder);
-      }
-      else
-      {
-        if (CGrid::has(grid_ref)) this->grid = CGrid::get(grid_ref);
-        else  ERROR("CField::solveGridReference(void)",
-                     << "Invalid reference to grid '" << grid_ref.getValue() << "'.");
-      }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::solveGridDomainAxisRef(bool checkAtt)
-   TRY
-   {
-     grid->solveDomainAxisRef(checkAtt);
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::solveCheckMaskIndex(bool doSendingIndex)
-   TRY
-   {
-     grid->checkMaskIndex(doSendingIndex);
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::solveTransformedGrid()
-   TRY
-   {
-     if (grid && !grid->isTransformed() && hasDirectFieldReference() && grid != getDirectFieldReference()->grid)
-     {
-       std::vector<CGrid*> grids;
-       // Source grid
-       grids.push_back(getDirectFieldReference()->grid);
-       // Intermediate grids
-       if (!grid_path.isEmpty())
-       {
-         std::string gridId;
-         size_t start = 0, end;
-
-         do
-         {
-           end = grid_path.getValue().find(',', start);
-           if (end != std::string::npos)
-           {
-             gridId = grid_path.getValue().substr(start, end - start);
-             start = end + 1;
-           }
-           else
-             gridId = grid_path.getValue().substr(start);
-
-           if (!CGrid::has(gridId))
-             ERROR("void CField::solveTransformedGrid()",
-                   << "Invalid grid_path, the grid '" << gridId << "' does not exist.");
-
-           grids.push_back(CGrid::get(gridId));
-         }
-         while (end != std::string::npos);
-       }
-       // Destination grid
-       grids.push_back(grid);
-
-       for (size_t i = 0, count = grids.size() - 1; i < count; ++i)
-       {
-         CGrid *gridSrc  = grids[i];
-         CGrid *gridDest = grids[i + 1];
-         if (!gridDest->isTransformed())
-           gridDest->transformGrid(gridSrc);
-       }
-     }
-     else if (grid && grid->hasTransform() && !grid->isTransformed())
-     {
-       // Temporarily deactivate the self-transformation of grid
-       // grid->transformGrid(grid);
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::solveGenerateGrid()
-   TRY
-   {
-     if (grid && !grid->isTransformed() && hasDirectFieldReference() && grid != getDirectFieldReference()->grid)
-       grid->completeGrid(getDirectFieldReference()->grid);
-     else
-       grid->completeGrid();
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::solveGridDomainAxisBaseRef()
-   TRY
-   {
-     grid->solveDomainAxisRef(false);
-     grid->solveDomainAxisBaseRef();
-   }
-   CATCH_DUMP_ATTR
-
-   ///-------------------------------------------------------------------
-
-   template <>
-   void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)
-   TRY
-   {
-      if (this->group_ref.isEmpty()) return;
-      StdString gref = this->group_ref.getValue();
-
-      if (!CFieldGroup::has(gref))
-         ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)",
-               << "[ gref = " << gref << "]"
-               << " invalid group name !");
-
-      CFieldGroup* group = CFieldGroup::get(gref);
-      CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this));
-      owner->setAttributes(group); // inherite of attributes of group reference
+      CArray<int,1> axisDomainOrder(axisDomainOrderTmp.size());
+      for (int idx = 0; idx < axisDomainOrderTmp.size(); ++idx)
+      {
+        axisDomainOrder(idx) = axisDomainOrderTmp[idx];
+      }
+
+      // Warning: the gridId shouldn't be set as the grid_ref since it could be inherited
+      StdString gridId = CGrid::generateId(vecDom, vecAxis, vecScalar,axisDomainOrder);
+      if (CGrid::has(gridId)) this->grid_ = CGrid::get(gridId);
+      else  this->grid_ = CGrid::createGrid(gridId, vecDomRef, vecAxisRef, vecScalarRef,axisDomainOrder);
+    }
+    else
+    {
+      if (CGrid::has(grid_ref)) this->grid_ = CGrid::get(grid_ref);
+      else  ERROR("CField::solveGridReference(void)",
+                   << "Invalid reference to grid '" << grid_ref.getValue() << "'.");
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::solveGridDomainAxisRef(bool checkAtt)
+  TRY
+  {
+    grid_->solveDomainAxisRef(checkAtt);
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::solveCheckMaskIndex(bool doSendingIndex)
+  TRY
+  {
+    grid_->checkMaskIndex(doSendingIndex);
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::solveTransformedGrid()
+  TRY
+  {
+    if (grid_ && !grid_->isTransformed() && hasDirectFieldReference() && grid_ != getDirectFieldReference()->grid_)
+    {
+      std::vector<CGrid*> grids;
+      // Source grid
+      grids.push_back(getDirectFieldReference()->grid_);
+      auto gridPath = getGridPath() ;
+      grids.insert(grids.begin(), gridPath.begin(), gridPath.end());
+
+      for (size_t i = 0, count = grids.size() - 1; i < count; ++i)
+      {
+        CGrid *gridSrc  = grids[i];
+        CGrid *gridDest = grids[i + 1];
+        if (!gridDest->isTransformed()) gridDest->transformGrid(gridSrc);
+      }
+    }
+    else if (grid_ && grid_->hasTransform() && !grid_->isTransformed())
+    {
+      // Temporarily deactivate the self-transformation of grid
+      // grid_->transformGrid(grid_);
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::solveGenerateGrid()
+  TRY
+  {
+    if (grid_ && !grid_->isTransformed() && hasDirectFieldReference() && grid_ != getDirectFieldReference()->grid_)
+      grid_->completeGrid(getDirectFieldReference()->grid_);
+    else grid_->completeGrid();
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::solveGridDomainAxisBaseRef()
+  TRY
+  {
+    grid_->solveDomainAxisRef(false);
+    grid_->solveDomainAxisBaseRef();
+  }
+  CATCH_DUMP_ATTR
+
+  ///-------------------------------------------------------------------
+
+  template <>
+  void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)
+  TRY
+  {
+    if (this->group_ref.isEmpty()) return;
+    StdString gref = this->group_ref.getValue();
+
+    if (!CFieldGroup::has(gref))
+      ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)",
+         << "[ gref = " << gref << "]"
+         << " invalid group name !");
+
+    CFieldGroup* group = CFieldGroup::get(gref);
+    CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this));
+    owner->setAttributes(group); // inherite of attributes of group reference
       
-      std::vector<CField*> allChildren  = group->getAllChildren();
-      std::vector<CField*>::iterator it = allChildren.begin(), end = allChildren.end();
-
-      for (; it != end; it++)
-      {
-         CField* child = *it;
-         if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId());
-
-      }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::scaleFactorAddOffset(double scaleFactor, double addOffset)
-   TRY
-   {
-     recvDataSrv = (recvDataSrv - addOffset) / scaleFactor;
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::invertScaleFactorAddOffset(double scaleFactor, double addOffset)
-   TRY
-   {
-     recvDataSrv = recvDataSrv * scaleFactor + addOffset;
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::outputField(CArray<double,1>& fieldOut)
-   TRY
-   { 
-      CArray<size_t,1>& outIndexClient = grid->localIndexToWriteOnClient_;
-      CArray<size_t,1>& outIndexServer = grid->localIndexToWriteOnServer_;
-      for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx)
-      {
-        fieldOut(outIndexServer(idx)) = recvDataSrv(outIndexClient(idx));
-      }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::inputField(CArray<double,1>& fieldIn)
-   TRY
-   {
-      CArray<size_t,1>& outIndexClient = grid->localIndexToWriteOnClient_;
-      CArray<size_t,1>& outIndexServer = grid->localIndexToWriteOnServer_;
-      for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx)
-      {
-        recvDataSrv(outIndexClient(idx)) = fieldIn(outIndexServer(idx));
-      }
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::outputCompressedField(CArray<double,1>& fieldOut)
-   TRY
-   {
-      CArray<size_t,1>& outIndexClient = grid->localIndexToWriteOnClient_;
-      CArray<size_t,1>& outIndexServer = grid->localIndexToWriteOnServer_;
-      for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx)
-      {
-        fieldOut((idx)) = recvDataSrv(outIndexClient(idx));
-      }
-   }
-   CATCH_DUMP_ATTR
-
-   ///-------------------------------------------------------------------
-
-   void CField::parse(xml::CXMLNode& node)
-   TRY
-   {
-      string newContent ;
-      SuperClass::parse(node);
-      if (node.goToChildElement())
-      {
-        do
-        {
-          if (node.getElementName() == "variable" || node.getElementName() == "variable_group") this->getVirtualVariableGroup()->parseChild(node);
-          else if (node.getElementName() == "expr") if (node.getContent(newContent)) content+=newContent ;
-        } while (node.goToNextElement());
-        node.goToParentElement();
-      }
-      if (node.getContent(newContent)) content=newContent ;
-    }
-   CATCH_DUMP_ATTR
-
-   /*!
-     This function retrieves Id of corresponding domain_ref and axis_ref (if any)
+    std::vector<CField*> allChildren  = group->getAllChildren();
+    std::vector<CField*>::iterator it = allChildren.begin(), end = allChildren.end();
+
+    for (; it != end; it++)
+    {
+      CField* child = *it;
+     if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId());
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::scaleFactorAddOffset(double scaleFactor, double addOffset)
+  TRY
+  {
+    recvDataSrv = (recvDataSrv - addOffset) / scaleFactor;
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::invertScaleFactorAddOffset(double scaleFactor, double addOffset)
+  TRY
+  {
+    recvDataSrv = recvDataSrv * scaleFactor + addOffset;
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::outputField(CArray<double,1>& fieldOut)
+  TRY
+  { 
+    CArray<size_t,1>& outIndexClient = grid_->localIndexToWriteOnClient_;
+    CArray<size_t,1>& outIndexServer = grid_->localIndexToWriteOnServer_;
+    for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx)
+    {
+      fieldOut(outIndexServer(idx)) = recvDataSrv(outIndexClient(idx));
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::inputField(CArray<double,1>& fieldIn)
+  TRY
+  {
+    CArray<size_t,1>& outIndexClient = grid_->localIndexToWriteOnClient_;
+    CArray<size_t,1>& outIndexServer = grid_->localIndexToWriteOnServer_;
+    for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx)
+    {
+      recvDataSrv(outIndexClient(idx)) = fieldIn(outIndexServer(idx));
+    }
+  }
+  CATCH_DUMP_ATTR
+
+ void CField::outputCompressedField(CArray<double,1>& fieldOut)
+ TRY
+ {
+    CArray<size_t,1>& outIndexClient = grid_->localIndexToWriteOnClient_;
+    CArray<size_t,1>& outIndexServer = grid_->localIndexToWriteOnServer_;
+    for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx)
+    {
+      fieldOut((idx)) = recvDataSrv(outIndexClient(idx));
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  ///-------------------------------------------------------------------
+
+  void CField::parse(xml::CXMLNode& node)
+  TRY
+  {
+    string newContent ;
+    SuperClass::parse(node);
+    if (node.goToChildElement())
+    {
+      do
+      {
+        if (node.getElementName() == "variable" || node.getElementName() == "variable_group") this->getVirtualVariableGroup()->parseChild(node);
+        else if (node.getElementName() == "expr") if (node.getContent(newContent)) content+=newContent ;
+      } while (node.goToNextElement());
+      node.goToParentElement();
+    }
+    if (node.getContent(newContent)) content=newContent ;
+  }
+  CATCH_DUMP_ATTR
+
+ /*!
+   This function retrieves Id of corresponding domain_ref and axis_ref (if any)
    of a field. In some cases, only domain exists but axis doesn't
    \return pair of Domain and Axis id
+  */
+  const std::vector<StdString>& CField::getRefDomainAxisIds()
+  TRY
+  {
+    CGrid* cgPtr = getRelGrid();
+    if (NULL != cgPtr)
+    {
+      std::vector<StdString>::iterator it;
+      if (!domain_ref.isEmpty())
+      {
+        std::vector<StdString> domainList = cgPtr->getDomainList();
+        it = std::find(domainList.begin(), domainList.end(), domain_ref.getValue());
+        if (domainList.end() != it) domAxisScalarIds_[0] = *it;
+      }
+
+      if (!axis_ref.isEmpty())
+      {
+        std::vector<StdString> axisList = cgPtr->getAxisList();
+        it = std::find(axisList.begin(), axisList.end(), axis_ref.getValue());
+        if (axisList.end() != it) domAxisScalarIds_[1] = *it;
+      }
+
+      if (!scalar_ref.isEmpty())
+      {
+        std::vector<StdString> scalarList = cgPtr->getScalarList();
+        it = std::find(scalarList.begin(), scalarList.end(), scalar_ref.getValue());
+        if (scalarList.end() != it) domAxisScalarIds_[2] = *it;
+      }
+    }
+    return (domAxisScalarIds_);
+  }
+  CATCH_DUMP_ATTR
+
+  CVariable* CField::addVariable(const string& id)
+  TRY
+  {
+    return vVariableGroup->createChild(id);
+  }
+  CATCH
+
+  CVariableGroup* CField::addVariableGroup(const string& id)
+  TRY
+  {
+    return vVariableGroup->createChildGroup(id);
+  }
+  CATCH
+
+  void CField::setContextClient(CContextClient* contextClient)
+  TRY
+  {
+    CContext* context = CContext::getCurrent();
+    client = contextClient;
+  
+    // A grid is sent by a client (both for read or write) or by primary server (write only)
+    if (context->getServiceType()==CServicesManager::GATHERER)
+    {
+      if (file->mode.isEmpty() || (!file->mode.isEmpty() && file->mode == CFile::mode_attr::write))
+        grid_->setContextClient(contextClient);
+    }
+    else if (context->getServiceType()==CServicesManager::CLIENT)
+      grid_->setContextClient(contextClient);
+  }
+  CATCH_DUMP_ATTR
+
+  CContextClient* CField::getContextClient()
+  TRY
+  {
+    return client;
+  }
+  CATCH
+
+  void CField::sendAddAllVariables(CContextClient* client)
+  TRY
+  {
+    std::vector<CVariable*> allVar = getAllVariables();
+    std::vector<CVariable*>::const_iterator it = allVar.begin();
+    std::vector<CVariable*>::const_iterator itE = allVar.end();
+
+    for (; it != itE; ++it)
+    {
+      this->sendAddVariable((*it)->getId(), client);
+      (*it)->sendAllAttributesToServer(client);
+      (*it)->sendValue(client);
+    }
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+   * Send all Attributes to server. This method is overloaded, since only grid_ref attribute
+   * must be sent to server and not domain_ref/axis_ref/scalar_ref. 
    */
-   const std::vector<StdString>& CField::getRefDomainAxisIds()
-   TRY
-   {
-     CGrid* cgPtr = getRelGrid();
-     if (NULL != cgPtr)
-     {
-       std::vector<StdString>::iterator it;
-       if (!domain_ref.isEmpty())
-       {
-         std::vector<StdString> domainList = cgPtr->getDomainList();
-         it = std::find(domainList.begin(), domainList.end(), domain_ref.getValue());
-         if (domainList.end() != it) domAxisScalarIds_[0] = *it;
-       }
-
-       if (!axis_ref.isEmpty())
-       {
-         std::vector<StdString> axisList = cgPtr->getAxisList();
-         it = std::find(axisList.begin(), axisList.end(), axis_ref.getValue());
-         if (axisList.end() != it) domAxisScalarIds_[1] = *it;
-       }
-
-       if (!scalar_ref.isEmpty())
-       {
-         std::vector<StdString> scalarList = cgPtr->getScalarList();
-         it = std::find(scalarList.begin(), scalarList.end(), scalar_ref.getValue());
-         if (scalarList.end() != it) domAxisScalarIds_[2] = *it;
-       }
-     }
-     return (domAxisScalarIds_);
-   }
-   CATCH_DUMP_ATTR
-
-   CVariable* CField::addVariable(const string& id)
-   TRY
-   {
-     return vVariableGroup->createChild(id);
-   }
-   CATCH
-
-   CVariableGroup* CField::addVariableGroup(const string& id)
-   TRY
-   {
-     return vVariableGroup->createChildGroup(id);
-   }
-   CATCH
-
-   void CField::setContextClient(CContextClient* contextClient)
-   TRY
-   {
-     CContext* context = CContext::getCurrent();
-     client = contextClient;
-  
-     // A grid is sent by a client (both for read or write) or by primary server (write only)
-     if (context->getServiceType()==CServicesManager::GATHERER)
-     {
-       if (file->mode.isEmpty() || (!file->mode.isEmpty() && file->mode == CFile::mode_attr::write))
-         grid->setContextClient(contextClient);
-     }
-     else if (context->getServiceType()==CServicesManager::CLIENT)
-       grid->setContextClient(contextClient);
-   }
-   CATCH_DUMP_ATTR
-
-   CContextClient* CField::getContextClient()
-   TRY
-   {
-     return client;
-   }
-   CATCH
-
-   void CField::sendAddAllVariables(CContextClient* client)
-   TRY
-   {
-     std::vector<CVariable*> allVar = getAllVariables();
-     std::vector<CVariable*>::const_iterator it = allVar.begin();
-     std::vector<CVariable*>::const_iterator itE = allVar.end();
-
-     for (; it != itE; ++it)
-     {
-       this->sendAddVariable((*it)->getId(), client);
-       (*it)->sendAllAttributesToServer(client);
-       (*it)->sendValue(client);
-     }
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-    * Send all Attributes to server. This method is overloaded, since only grid_ref attribute
-    * must be sent to server and not domain_ref/axis_ref/scalar_ref. 
-    */
     
-   void CField::sendAllAttributesToServer(CContextClient* client)
-   TRY
-   {
-     if (grid_ref.isEmpty())
-     {
-       grid_ref=grid->getId() ;
-       SuperClass::sendAllAttributesToServer(client) ;
-       grid_ref.reset();
-     }
-     else SuperClass::sendAllAttributesToServer(client) ;
-   }
-   CATCH_DUMP_ATTR
+  void CField::sendAllAttributesToServer(CContextClient* client)
+  TRY
+  {
+    if (grid_ref.isEmpty())
+    {
+      grid_ref=grid_->getId() ;
+      SuperClass::sendAllAttributesToServer(client) ;
+      grid_ref.reset();
+    }
+    else SuperClass::sendAllAttributesToServer(client) ;
+  }
+  CATCH_DUMP_ATTR
     
-   void CField::sendAddVariable(const string& id, CContextClient* client)
-   TRY
-   {
-      sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE, client);
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::sendAddVariableGroup(const string& id, CContextClient* client)
-   TRY
-   {
-      sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE_GROUP, client);
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::recvAddVariable(CEventServer& event)
-   TRY
-   {
-
-      CBufferIn* buffer = event.subEvents.begin()->buffer;
-      string id;
-      *buffer >> id;
-      get(id)->recvAddVariable(*buffer);
-   }
-   CATCH
-
-   void CField::recvAddVariable(CBufferIn& buffer)
-   TRY
-   {
-      string id;
-      buffer >> id;
-      addVariable(id);
-   }
-   CATCH_DUMP_ATTR
-
-   void CField::recvAddVariableGroup(CEventServer& event)
-   TRY
-   {
-
-      CBufferIn* buffer = event.subEvents.begin()->buffer;
-      string id;
-      *buffer >> id;
-      get(id)->recvAddVariableGroup(*buffer);
-   }
-   CATCH
-
-   void CField::recvAddVariableGroup(CBufferIn& buffer)
-   TRY
-   {
-      string id;
-      buffer >> id;
-      addVariableGroup(id);
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-    * Check on freq_off and freq_op attributes.
-    */
-   void CField::checkTimeAttributes(CDuration* freqOp)
-   TRY
-   {
-     bool isFieldRead  = file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read;
-     bool isFieldWrite = file && ( file->mode.isEmpty() ||  file->mode == CFile::mode_attr::write);
-     if (isFieldRead && !(operation.getValue() == "instant" || operation.getValue() == "once") )     
-       ERROR("void CField::checkTimeAttributes(void)",
-             << "Unsupported operation for field '" << getFieldOutputName() << "'." << std::endl
-             << "Currently only \"instant\" is supported for fields read from file.")
-
-     if (freq_op.isEmpty())
-     {
-       if (operation.getValue() == "instant")
-       {
-         if (isFieldRead || isFieldWrite) freq_op.setValue(file->output_freq.getValue());
-         else freq_op=*freqOp ;
-       }
-       else
-         freq_op.setValue(TimeStep);
-     }
-     if (freq_offset.isEmpty())
-       freq_offset.setValue(isFieldRead ? NoneDu : (freq_op.getValue() - TimeStep));
-   }
-   CATCH_DUMP_ATTR
-
-   /*!
-    * Returns string arithmetic expression associated to the field.
-    * \return if content is defined return content string, otherwise, if "expr" attribute is defined, return expr string.
-    */
-   const string& CField::getExpression(void)
-   TRY
-   {
-     if (!expr.isEmpty() && content.empty())
-     {
-       content = expr;
-       expr.reset();
-     }
-
-     return content;
-   }
-   CATCH_DUMP_ATTR
-
-   bool CField::hasExpression(void) const
-   TRY
-   {
-     return (!expr.isEmpty() || !content.empty());
-   }
-   CATCH
-
-   bool CField::hasGridMask(void) const
-   TRY
-   {
-     return (this->grid->hasMask());
-   }
-   CATCH
-
-   DEFINE_REF_FUNC(Field,field)
+  void CField::sendAddVariable(const string& id, CContextClient* client)
+  TRY
+  {
+    sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE, client);
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::sendAddVariableGroup(const string& id, CContextClient* client)
+  TRY
+  {
+    sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE_GROUP, client);
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::recvAddVariable(CEventServer& event)
+  TRY
+  {
+    CBufferIn* buffer = event.subEvents.begin()->buffer;
+    string id;
+    *buffer >> id;
+    get(id)->recvAddVariable(*buffer);
+  }
+  CATCH
+
+  void CField::recvAddVariable(CBufferIn& buffer)
+  TRY
+  {
+    string id;
+    buffer >> id;
+    addVariable(id);
+  }
+  CATCH_DUMP_ATTR
+
+  void CField::recvAddVariableGroup(CEventServer& event)
+  TRY
+  {
+    CBufferIn* buffer = event.subEvents.begin()->buffer;
+    string id;
+    *buffer >> id;
+    get(id)->recvAddVariableGroup(*buffer);
+  }
+  CATCH
+
+  void CField::recvAddVariableGroup(CBufferIn& buffer)
+  TRY
+  {
+    string id;
+    buffer >> id;
+    addVariableGroup(id);
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+   * Check on freq_off and freq_op attributes.
+   */
+  void CField::checkTimeAttributes(CDuration* freqOp)
+  TRY
+  {
+    bool isFieldRead  = file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read;
+    bool isFieldWrite = file && ( file->mode.isEmpty() ||  file->mode == CFile::mode_attr::write);
+    if (isFieldRead && !(operation.getValue() == "instant" || operation.getValue() == "once") )     
+      ERROR("void CField::checkTimeAttributes(void)",
+         << "Unsupported operation for field '" << getFieldOutputName() << "'." << std::endl
+         << "Currently only \"instant\" is supported for fields read from file.")
+
+    if (freq_op.isEmpty())
+    {
+      if (operation.getValue() == "instant")
+      {
+        if (isFieldRead || isFieldWrite) freq_op.setValue(file->output_freq.getValue());
+        else freq_op=*freqOp ;
+      }
+      else freq_op.setValue(TimeStep);
+    }
+    if (freq_offset.isEmpty()) freq_offset.setValue(isFieldRead ? NoneDu : (freq_op.getValue() - TimeStep));
+  }
+  CATCH_DUMP_ATTR
+
+  /*!
+   * Returns string arithmetic expression associated to the field.
+   * \return if content is defined return content string, otherwise, if "expr" attribute is defined, return expr string.
+   */
+  const string& CField::getExpression(void)
+  TRY
+  {
+    if (!expr.isEmpty() && content.empty())
+    {
+      content = expr;
+      expr.reset();
+    }
+
+    return content;
+  }
+  CATCH_DUMP_ATTR
+
+  bool CField::hasExpression(void) const
+  TRY
+  {
+    return (!expr.isEmpty() || !content.empty());
+  }
+  CATCH
+
+  bool CField::hasGridMask(void) const
+  TRY
+  {
+    return (this->grid_->hasMask());
+  }
+  CATCH
+
+  DEFINE_REF_FUNC(Field,field)
 } // namespace xios
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.hpp	(revision 1869)
@@ -17,4 +17,7 @@
 #include "variable.hpp"
 #include "context_client.hpp"
+#include "pass_through_filter.hpp"
+#include "temporal_filter.hpp"
+
 
 
@@ -28,4 +31,6 @@
 
    class CFile;
+   class CCouplerIn ;
+   class CCouplerOut ;
    class CGrid;
    class CContext;
@@ -47,4 +52,5 @@
 
    class CContextClient ;
+
    ///--------------------------------------------------------------
    class CField
@@ -141,4 +147,8 @@
 
          void buildFilterGraph(CGarbageCollector& gc, bool enableOutput);
+
+         bool buildWorkflowGraph(CGarbageCollector& gc) ;
+         bool buildWorkflowGraphDone_ = false ;
+
          size_t getGlobalWrittenSize(void) ;
          
@@ -211,4 +221,10 @@
 
         bool hasGridMask(void) const;
+        CGrid* getGrid(void) { return grid_; } 
+
+        void connectToFileServer(CGarbageCollector& gc) ;
+        void computeGridIndexToFileServer(void) ;
+      private:
+        std::vector<CGrid*> getGridPath(void) ;
 
       public:
@@ -216,6 +232,40 @@
          CVariableGroup* vVariableGroup;
 
-         CGrid*  grid;
+         CGrid*  grid_=nullptr;
          CFile*  file;
+         
+         CFile* fileIn_ = nullptr ; //<! pointer to input related file
+         bool hasFileIn(void) { fileIn_==nullptr ? false : true ;}
+         CFile* getFileIn(void) {return fileIn_;}
+         void setFileIn(CFile* fileIn) { fileIn_ = fileIn ;}
+         void unsetFileIn(void) { fileIn_ = nullptr ;}
+
+         CFile* fileOut_ = nullptr ; //<! pointer to output related file
+         bool hasFileOut(void) { fileOut_==nullptr ? false : true ;}
+         CFile* getFileOut(void) {return fileOut_;}
+         void setFileOut(CFile* fileOut) { fileOut_ = fileOut ;}
+         void unsetFileOut(void) { fileOut_ = nullptr ;}
+
+         CCouplerIn* couplerIn_ = nullptr ; //<!pointer to input related coupler
+         bool hasCouplerIn(void) { couplerIn_==nullptr ? false : true ;}
+         CCouplerIn* getCouplerIn(void) {return couplerIn_;}
+         void setCouplerIn(CCouplerIn* couplerIn) { couplerIn_ = couplerIn ;}
+         void unsetCouplerIn(void) { couplerIn_ = nullptr ;}
+
+         CCouplerOut* couplerOut_ = nullptr ; //<!pointer to output related coupler
+         bool hasCouplerOut(void) { couplerOut_==nullptr ? false : true ;}
+         CCouplerOut* getCouplerOut(void) {return couplerOut_;}
+         void setCouplerOut(CCouplerOut* couplerOut) { couplerOut_ = couplerOut ;}
+         void unsetCouplerOut(void) { couplerOut_ = nullptr ;}
+
+         bool modelIn_ = false ; //<! field can be received from model == true 
+         bool getModelIn(void) { return modelIn_ ;}
+         void setModelIn(void) { modelIn_ = true ;}
+         void unsetModelIn(void) { modelIn_ = false ;}
+         
+         bool modelOut_ = false ; //<! field can be retrieve to model == true
+         bool getModelOut(void) { return modelOut_ ;}
+         void setModelOut(void) { modelOut_ = true ;}
+         void unsetModelOut(void) { modelOut_ = false ;}
 
          CDuration freq_operation_srv, freq_write_srv;
@@ -246,5 +296,5 @@
 
          DECLARE_REF_FUNC(Field,field)
-
+        
       private:
          CContextClient* client;
@@ -256,22 +306,45 @@
          bool nstepMaxRead;
 
+       private: 
+         //! define if the field is part of the active workflow. It will be tagged to true when CField::buildWorkflowGraph is successfull 
+         bool workflowEnabled_ = false ;
+       public: 
+         /*! workflowEnabled_ public accessor
+          * \return Value of workflowEnabled_ */
+         bool getWorkflowEnabled(void) { return  workflowEnabled_; }
+ 
+
       private:
+     
          //! The type of operation attached to the field
          func::CFunctor::ETimeType operationTimeType;
 
+         //! The output pin of the input filter of the field
+         std::shared_ptr<CPassThroughFilter> inputFilter;
+
+         //! The self temporal data filter
+         std::shared_ptr<CTemporalFilter> selfTemporalDataFilter ;
+         
          //! The output pin of the filter providing the instant data for the field
          std::shared_ptr<COutputPin> instantDataFilter;
+         
          //! The output pin of the filters providing the result of the field's temporal operation
          std::map<CDuration, std::shared_ptr<COutputPin>, DurationFakeLessComparator> temporalDataFilters;
+         
          //! The output pin of the filter providing the instant data for self references
-         std::shared_ptr<COutputPin> selfReferenceFilter;
+         std::shared_ptr<COutputPin> selfReferenceFilter; // probably redondant with inputFilter
+
          //! The source filter for data provided by the client
          std::shared_ptr<CSourceFilter> clientSourceFilter;
+         
          //! The source filter for data provided by the server
          std::shared_ptr<CSourceFilter> serverSourceFilter;
+         
          //! The terminal filter which stores the instant data
          std::shared_ptr<CStoreFilter> storeFilter;
+        
          //! The terminal filter which writes the data to file
          std::shared_ptr<CFileWriterFilter> fileWriterFilter;
+        
          //! The terminal filter which writes data to file
          std::shared_ptr<CFileServerWriterFilter> fileServerWriterFilter;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/file.cpp	(revision 1869)
@@ -145,9 +145,7 @@
    TRY
    {
-      if (!this->enabledFields.empty())
-         return (this->enabledFields);
-
-      const int _outputlevel =
-         (!output_level.isEmpty()) ? output_level.getValue() : default_outputlevel;
+      if (!this->enabledFields.empty()) return (this->enabledFields);
+
+      const int _outputlevel = (!output_level.isEmpty()) ? output_level.getValue() : default_outputlevel;
       std::vector<CField*>::iterator it;
       this->enabledFields = this->getAllFields();
@@ -176,6 +174,4 @@
 
          newEnabledFields.push_back(*it);
-         // Le champ est finalement actif, on y ajoute la rfrence au champ de base.
-         (*it)->setRelFile(CFile::get(this));
       }
       enabledFields = newEnabledFields;
@@ -256,8 +252,8 @@
       {
          CField* field = *it;         
-         std::vector<CAxis*> vecAxis = field->grid->getAxis();
+         std::vector<CAxis*> vecAxis = field->getGrid()->getAxis();
          for (size_t i = 0; i < vecAxis.size(); ++i)
            setAxis.insert(vecAxis[i]->getAxisOutputName());
-         std::vector<CDomain*> vecDomains = field->grid->getDomains();
+         std::vector<CDomain*> vecDomains = field->getGrid()->getDomains();
          for (size_t i = 0; i < vecDomains.size(); ++i)
            setDomains.insert(vecDomains[i]->getDomainOutputName());
@@ -300,6 +296,6 @@
       {
          CField* field = *it;
-         bool nullGrid = (0 == field->grid);
-         allZoneEmpty &= nullGrid ? false : !field->grid->doGridHaveDataToWrite();
+         bool nullGrid = (nullptr == field->getGrid());
+         allZoneEmpty &= nullGrid ? false : !field->getGrid()->doGridHaveDataToWrite();
       }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1869)
@@ -90,5 +90,5 @@
    //---------------------------------------------------------------
 
-   StdSize CGrid::getDataSize(void) const
+   StdSize CGrid::getDataSize(void) 
    TRY
    {
@@ -96,5 +96,5 @@
      if (!isScalarGrid())
      {
-       std::vector<int> dataNindex = clientDistribution_->getDataNIndex();
+       std::vector<int> dataNindex = getDistributionClient()->getDataNIndex();
        for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];       
      }
@@ -634,5 +634,5 @@
 
       size_t nbWritten = 0, indGlo;
-      CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient();
+      CDistributionClient::GlobalLocalDataMap& globalDataIndex = getDistributionClient()->getGlobalDataIndexOnClient();
       CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(),
                                                               ite = globalDataIndex.end(), it;    
@@ -677,5 +677,93 @@
    CATCH_DUMP_ATTR
 
+   
+
+   /*!
+     Compute the global index of grid to send to server as well as the connected server of the current client.
+     First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know
+     their global index. We can have a map of global index of grid and local index that each client holds
+     Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s)
+     of the current client.
+   */
+   void CGrid::computeGridIndexToFileServer(CContextClient* client)
+   {
+     if (isScalarGrid())
+     {
+       computeClientIndexScalarGrid();
+       computeConnectedClientsScalarGrid(client);
+     }
+     else
+     {
+       computeClientIndex();
+       computeConnectedClients(client);
+     }
+
+     // compute indices for client/server transfer for domain
+     for (const auto& domainId : domList_) CDomain::get(domainId)->computeConnectedClients(client);
+   
+   
+     // 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]) ;
+   }
    //---------------------------------------------------------------
+
+   
+   void CGrid::computeClientDistribution(void)
+   {
+     if (computeClientDistribution_done_) return ;
+     else computeClientDistribution_done_ = true ;
+
+     CContext* context = CContext::getCurrent();
+     int rank = context-> getIntraCommRank();
+     clientDistribution_ = new CDistributionClient(rank, this);
+   }
+
+   void CGrid::computeStoreIndex_client(void)
+   {
+     if (computeStoreIndex_client_done_) return ;
+     else computeStoreIndex_client_done_ = true ;
+     if (isScalarGrid())
+     {
+       storeIndex_client_.resize(1);
+       storeIndex_client_(0) = 0;
+     }
+     else
+     {
+       CDistributionClient* clientDistribution = getDistributionClient() ;
+       const std::vector<int>& localDataIndex = clientDistribution->getLocalDataIndexOnClient() ;
+       int nbStoreIndex = localDataIndex.size() ;
+       storeIndex_client_.resize(nbStoreIndex);
+       for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client_(idx) = localDataIndex[idx];
+     }
+   }
+
+   void CGrid::computeStoreMask_client(void)
+   {
+     if (computeStoreMask_client_done_) return ;
+     else computeStoreMask_client_done_ = true ;
+     if (isScalarGrid())
+     {
+       storeMask_client_.resize(1);
+       storeMask_client_(0) = true;
+     }
+     else
+     {
+       CDistributionClient* clientDistribution = getDistributionClient() ;
+       const std::vector<bool>& localMaskIndex = clientDistribution->getLocalMaskIndexOnClient() ;
+       int nbMaskIndex = localMaskIndex.size() ;
+       storeMask_client_.resize(nbMaskIndex);
+       for (int idx = 0; idx < nbMaskIndex; ++idx) storeMask_client_(idx) = localMaskIndex[idx];
+     }
+   }
 
    /*
@@ -688,24 +776,24 @@
    TRY
    {
+     if (computeClientIndex_done_) return ;
+
      CContext* context = CContext::getCurrent();
-
-     CContextClient* client = context->client;
-     int rank = client->clientRank;
-
-     clientDistribution_ = new CDistributionClient(rank, this);
+     int rank = context-> getIntraCommRank();
+
+     auto clientDistribution = getDistributionClient();
      // Get local data index on client
-     int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size();
-     int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size();
+     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();
+     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& globalDataIndex = clientDistribution->getGlobalDataIndexOnClient();
         CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end();
         map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient_.begin(),
@@ -746,4 +834,5 @@
         }
       }
+      computeClientIndex_done_ = true ;
    }
    CATCH_DUMP_ATTR
@@ -752,49 +841,46 @@
      Compute connected receivers and indexes to be sent to these receivers.
    */
-   void CGrid::computeConnectedClients()
-   TRY
-   {
+   void CGrid::computeConnectedClients(CContextClient* client)
+   TRY
+   {
+     if (computeConnectedClients_done_.count(client)!=0) return ;
+
      CContext* context = CContext::getCurrent();
      
      set<int> listReceiverSize ;
-     for (auto it=clients.begin(); it!=clients.end(); ++it)
+     int receiverSize = client->serverSize;
+      
+     if (listReceiverSize.find(receiverSize)==listReceiverSize.end())
      {
-       
-       CContextClient* client = *it ;
-
-       int receiverSize = client->serverSize;
-      
-       if (listReceiverSize.find(receiverSize)==listReceiverSize.end())
+       listReceiverSize.insert(receiverSize) ;
+       if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end())
        {
-         listReceiverSize.insert(receiverSize) ;
-         if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end())
-         {
-            // delete corresponding map in case of recompute, probably because a grid could has been modifiedd 
-            // by a transformation
-            connectedServerRank_.erase(receiverSize);
-            connectedDataSize_.erase(receiverSize);
-            globalIndexOnServer_.erase(receiverSize);
-            nbSenders_.erase(receiverSize);
-         }
-
-         if (!doGridHaveDataDistributed(client))
-         {
-            if (client->isServerLeader())
+          // delete corresponding map in case of recompute, probably because a grid could has been modifiedd 
+          // by a transformation
+          connectedServerRank_.erase(receiverSize);
+          connectedDataSize_.erase(receiverSize);
+          globalIndexOnServer_.erase(receiverSize);
+          nbSenders_.erase(receiverSize);
+       }
+
+       if (!doGridHaveDataDistributed(client))
+       {
+          if (client->isServerLeader())
+          {
+            size_t ssize = getDistributionClient()->getLocalDataIndexOnClient().size();
+            const std::list<int>& ranks = client->getRanksServerLeader();
+            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
             {
-              size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size();
-              const std::list<int>& ranks = client->getRanksServerLeader();
-              for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-              {
-                connectedServerRank_[receiverSize].push_back(*itRank);
-                connectedDataSize_[receiverSize][*itRank] = ssize;
-              }
+              connectedServerRank_[receiverSize].push_back(*itRank);
+              connectedDataSize_[receiverSize][*itRank] = ssize;
             }
-            return;
-         }
-
-         // Compute mapping between client and server
-         std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement;
-         CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize);
-         std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement,
+          }
+          return;
+       }
+
+       // Compute mapping between client and server
+       std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement;
+       CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize);
+       std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement,
                                                                                                     client->clientRank,
                                                                                                     client->clientSize,
@@ -802,80 +888,73 @@
                                                                                                     getDistributedDimension());
 
-         // Even if servers have no index, they must received something from client
-         // We only use several client to send "empty" message to these servers
-         std::list<int> serverZeroIndexLeader;
-         std::list<int> serverZeroIndexNotLeader;
-         CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
-         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
-           *it = serverZeroIndex[*it];
-
-         if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end())
-           computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]);
-
-         const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
-         CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
-         CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
-         itbGlobalMap = globalIndexOnServer_[receiverSize].begin();
-         iteGlobalMap = globalIndexOnServer_[receiverSize].end();
-
-         for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
+       // Even if servers have no index, they must received something from client
+       // We only use several client to send "empty" message to these servers
+       std::list<int> serverZeroIndexLeader;
+       std::list<int> serverZeroIndexNotLeader;
+       CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
+       for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
+         *it = serverZeroIndex[*it];
+
+       if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end())
+         computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]);
+
+       const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getDistributionClient()->getGlobalLocalDataSendToServer();
+       CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
+       CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
+       itbGlobalMap = globalIndexOnServer_[receiverSize].begin();
+       iteGlobalMap = globalIndexOnServer_[receiverSize].end();
+
+       for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
+       {
+         int serverRank = itGlobalMap->first;
+         int indexSize = itGlobalMap->second.size();
+         const std::vector<size_t>& indexVec = itGlobalMap->second;
+         for (int idx = 0; idx < indexSize; ++idx)
          {
-           int serverRank = itGlobalMap->first;
-           int indexSize = itGlobalMap->second.size();
-           const std::vector<size_t>& indexVec = itGlobalMap->second;
-           for (int idx = 0; idx < indexSize; ++idx)
-           {
-              itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]);
-              if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap)
-              {
-                if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank))
-                  connectedDataSize_[receiverSize][serverRank] = 1;
-                else
-                  ++connectedDataSize_[receiverSize][serverRank];
-              }
-           }
+            itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]);
+            if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap)
+            {
+              if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank))
+                connectedDataSize_[receiverSize][serverRank] = 1;
+              else
+                ++connectedDataSize_[receiverSize][serverRank];
+            }
          }
-
-         // Connected servers which really have index
-         for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) {
-           connectedServerRank_[receiverSize].push_back(itGlobalMap->first);
-         }
-
-         // Connected servers which have no index at all
-         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
-           connectedServerRank_[receiverSize].push_back(*it);
-
-         // Even if a client has no index, it must connect to at least one server and
-         // send an "empty" data to this server
-         if (connectedServerRank_[receiverSize].empty())
-          connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize);
-
-         // Now check if all servers have data to receive. If not, master client will send empty data.
-         // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive.
-         std::vector<int> counts (client->clientSize);
-         std::vector<int> displs (client->clientSize);
-         displs[0] = 0;
-         int localCount = connectedServerRank_[receiverSize].size() ;
-         MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ;
-         for (int i = 0; i < client->clientSize-1; ++i)
-         {
-           displs[i+1] = displs[i] + counts[i];
-         }
-         std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]);
-         MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm);
-
-         if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0))
-         {
-           std::vector<bool> isSrvConnected (receiverSize, false);
-           for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true;
-           for (int i = 0; i < receiverSize; ++i)
-           {
-             if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i);
-           }
-         }
-
-         nbSenders_[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]);
        }
+
+       // Connected servers which really have index
+       for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
+         connectedServerRank_[receiverSize].push_back(itGlobalMap->first);
+     
+       // Connected servers which have no index at all
+       for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
+         connectedServerRank_[receiverSize].push_back(*it);
+
+       // Even if a client has no index, it must connect to at least one server and
+       // send an "empty" data to this server
+       if (connectedServerRank_[receiverSize].empty())
+         connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize);
+ 
+       // Now check if all servers have data to receive. If not, master client will send empty data.
+       // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive.
+       std::vector<int> counts (client->clientSize);
+       std::vector<int> displs (client->clientSize);
+       displs[0] = 0;
+       int localCount = connectedServerRank_[receiverSize].size() ;
+       MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ;
+       for (int i = 0; i < client->clientSize-1; ++i) displs[i+1] = displs[i] + counts[i];
+       std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]);
+       MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm);
+
+       if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0))
+       {
+         std::vector<bool> isSrvConnected (receiverSize, false);
+         for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true;
+         for (int i = 0; i < receiverSize; ++i) if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i);
+       }
+
+       nbSenders_[receiverSize] = CClientServerMapping::computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]);
      }
+     computeConnectedClients_done_.insert(client) ;
    }
    CATCH_DUMP_ATTR
@@ -888,7 +967,9 @@
      of the current client.
    */
+   // ym obsolete : to be removed....
    void CGrid::computeIndex(void)
    TRY
    {
+    // old interface
      CContext* context = CContext::getCurrent();
      if (isScalarGrid())
@@ -897,5 +978,5 @@
        if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
        {
-         computeConnectedClientsScalarGrid();
+         // ym computeConnectedClientsScalarGrid();
        }
      }
@@ -905,5 +986,5 @@
        if (context->getServiceType()==CServicesManager::CLIENT || context->getServiceType()==CServicesManager::GATHERER)
        {
-         computeConnectedClients();
+         //computeConnectedClients();
        }
      }
@@ -1178,5 +1259,5 @@
       }
 
-      grid->solveDomainAxisRefInheritance(true);
+ //     grid->solveElementsRefInheritance(true);
 
       return grid;
@@ -1310,39 +1391,44 @@
    //----------------------------------------------------------------
 
-   void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const
-   TRY
-   {
-      const StdSize size = storeIndex_client_.numElements();
+   void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) 
+   TRY
+   {
+      auto& storeIndex_client = getStoreIndex_client() ;
+      const StdSize size = storeIndex_client.numElements();
 
       stored.resize(size);
-      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client_(i)];
+      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
    }
    CATCH
 
-   void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const
-   TRY
-   {
-      const StdSize size = storeIndex_client_.numElements();
-
-      for(StdSize i = 0; i < size; i++) data[storeIndex_client_(i)] = stored(i);
+   void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) 
+   TRY
+   {
+      auto& storeIndex_client=getStoreIndex_client() ;
+      const StdSize size = storeIndex_client.numElements();
+
+      for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i);
    }
    CATCH
 
-   void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const
-   {
-      const StdSize size = storeIndex_client_.numElements();
+   void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) 
+   {
+      auto& storeIndex_client=getStoreIndex_client() ;
+      auto& storeMask_client=getStoreMask_client() ;
+        
+      const StdSize size = storeIndex_client.numElements();
       stored.resize(size);
       const double nanValue = std::numeric_limits<double>::quiet_NaN();
 
-      if (storeMask_client_.numElements() != 0)
-        for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client_(i)) ? data[storeIndex_client_(i)] : nanValue;
+      if (storeMask_client.numElements() != 0)
+        for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue;
       else
-        for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client_(i)];
-   }
-
-   void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const
-   TRY
-   {
-      const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient();
+        for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
+   }
+
+   void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) 
+   TRY
+   {
+      const std::vector<int>& localMaskedDataIndex = getDistributionClient()->getLocalMaskedDataIndexOnClient();
       const int size = localMaskedDataIndex.size();
       for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i];
@@ -1353,9 +1439,11 @@
   TRY
   {
+    if (computeClientIndexScalarGrid_done_) return ;
+
     CContext* context = CContext::getCurrent();    
     {
       int rank = context->intraCommRank_;
 
-      clientDistribution_ = new CDistributionClient(rank, this);
+      auto clientDistribution = getDistributionClient();
 
       storeIndex_client_.resize(1);
@@ -1382,61 +1470,59 @@
       }
     }
-  }
-  CATCH_DUMP_ATTR
-
-  void CGrid::computeConnectedClientsScalarGrid()
-  TRY
-  {
+    computeClientIndexScalarGrid_done_ = true ;
+  }
+  CATCH_DUMP_ATTR
+
+  void CGrid::computeConnectedClientsScalarGrid(CContextClient* client)
+  TRY
+  {
+    if (computeConnectedClientsScalarGrid_done_.count(client)!=0) return ;
 
     CContext* context = CContext::getCurrent();
      
     set<int> listReceiverSize ;
-    for (auto it=clients.begin(); it!=clients.end(); ++it)
-    {
-       
-      CContextClient* client = *it ;
-
-      int receiverSize = client->serverSize;
+
+    int receiverSize = client->serverSize;
       
-      if (listReceiverSize.find(receiverSize)==listReceiverSize.end())
-      {
-        listReceiverSize.insert(receiverSize) ;
-        if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end())
+    if (listReceiverSize.find(receiverSize)==listReceiverSize.end())
+    {
+      listReceiverSize.insert(receiverSize) ;
+      if (connectedServerRank_.find(receiverSize) != connectedServerRank_.end())
+      {
+         // delete corresponding map in case of recompute, probably because a grid could has been modifiedd 
+         // by a transformation
+        connectedServerRank_.erase(receiverSize);
+        connectedDataSize_.erase(receiverSize);
+        globalIndexOnServer_.erase(receiverSize);
+        nbSenders_.erase(receiverSize);
+      }
+
+      if (client->isServerLeader())
+      {
+        const std::list<int>& ranks = client->getRanksServerLeader();
+        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
         {
-           // delete corresponding map in case of recompute, probably because a grid could has been modifiedd 
-           // by a transformation
-          connectedServerRank_.erase(receiverSize);
-          connectedDataSize_.erase(receiverSize);
-          globalIndexOnServer_.erase(receiverSize);
-          nbSenders_.erase(receiverSize);
-        }
-
-        if (client->isServerLeader())
+          int rank = *itRank;
+          int nb = 1;
+          connectedServerRank_[receiverSize].push_back(rank);
+          connectedDataSize_[receiverSize][rank] = nb;
+          nbSenders_[receiverSize][rank] = nb;
+        }
+      }
+      else
+      {
+        const std::list<int>& ranks = client->getRanksServerNotLeader();
+        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
         {
-          const std::list<int>& ranks = client->getRanksServerLeader();
-          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-          {
-            int rank = *itRank;
-            int nb = 1;
-            connectedServerRank_[receiverSize].push_back(rank);
-            connectedDataSize_[receiverSize][rank] = nb;
-            nbSenders_[receiverSize][rank] = nb;
-          }
-        }
-        else
-        {
-          const std::list<int>& ranks = client->getRanksServerNotLeader();
-          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-          {
-            int rank = *itRank;
-            int nb = 1;
-            connectedServerRank_[receiverSize].push_back(rank);
-            connectedDataSize_[receiverSize][rank] = nb;
-            nbSenders_[receiverSize][rank] = nb;
-          }
-        }
-      }
-      isDataDistributed_ = false;
-    }
+          int rank = *itRank;
+          int nb = 1;
+          connectedServerRank_[receiverSize].push_back(rank);
+          connectedDataSize_[receiverSize][rank] = nb;
+          nbSenders_[receiverSize][rank] = nb;
+        }
+      }
+    }
+    isDataDistributed_ = false;
+    computeConnectedClientsScalarGrid_done_.insert(client) ;
   }
   CATCH_DUMP_ATTR
@@ -1525,5 +1611,5 @@
       list<CMessage> listMsg;
       list<CArray<size_t,1> > listOutIndex;
-      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
+      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = getDistributionClient()->getGlobalLocalDataSendToServer();
       CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex,
                                                               iteIndex = globalLocalIndexSendToServer.end();
@@ -1971,4 +2057,5 @@
   TRY
   {
+    if (!computeClientDistribution_done_) computeClientDistribution() ;
     return clientDistribution_;
   }
@@ -2209,4 +2296,21 @@
 
   /*!
+  \brief Check if all elements of the grid are complete
+  Before make any grid processing, we must be sure that all grid information elements have
+  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
+  other context (coupling)
+  */
+  bool CGrid::checkIfCompleted(void)
+  {
+    setDomainList();
+    for (auto domainId : domList_) if (!CDomain::get(domainId)->checkIfCompleted()) return false ;
+    setAxisList() ;
+    for (auto axisId : axisList_) if (!CAxis::get(axisId)->checkIfCompleted()) return false ;
+    setScalarList() ;
+    for (auto scalarId : scalarList_) if (!CScalar::get(scalarId)->checkIfCompleted()) return false ;
+    return true ;
+  }
+
+  /*!
   \brief Solve domain and axis references
   As field, domain and axis can refer to other domains or axis. In order to inherit correctly
@@ -2214,45 +2318,47 @@
   \param[in] apply inherit all attributes of parents (true)
   */
-  void CGrid::solveDomainAxisRefInheritance(bool apply)
-  TRY
-  {
-    CContext* context = CContext::getCurrent();
-    unsigned int vecSize, i;
-    std::vector<StdString>::iterator it, itE;
+  void CGrid::solveElementsRefInheritance(bool apply)
+  TRY
+  {
     setDomainList();
-    it = domList_.begin(); itE = domList_.end();
-    for (; it != itE; ++it)
-    {
-      CDomain* pDom = CDomain::get(*it);
-      if (context->getServiceType()==CServicesManager::CLIENT)
-      {
-        pDom->solveRefInheritance(apply);
-        pDom->solveInheritanceTransformation();
-      }
+    for (auto domainId : domList_)
+    {
+      CDomain* pDom = CDomain::get(domainId);
+      pDom->solveRefInheritance(apply);
+      pDom->solveInheritanceTransformation();
     }
 
     setAxisList();
-    it = axisList_.begin(); itE = axisList_.end();
-    for (; it != itE; ++it)
-    {
-      CAxis* pAxis = CAxis::get(*it);
-      if (context->getServiceType()==CServicesManager::CLIENT)
-      {
-        pAxis->solveRefInheritance(apply);
-        pAxis->solveInheritanceTransformation();
-      }
+    for (auto axisId : axisList_)
+    {
+      CAxis* pAxis = CAxis::get(axisId);
+      pAxis->solveRefInheritance(apply);
+      pAxis->solveInheritanceTransformation();
     }
 
     setScalarList();
-    it = scalarList_.begin(); itE = scalarList_.end();
-    for (; it != itE; ++it)
-    {
-      CScalar* pScalar = CScalar::get(*it);
-      if (context->getServiceType()==CServicesManager::CLIENT)
-      {
-        pScalar->solveRefInheritance(apply);
-        pScalar->solveInheritanceTransformation();
-      }
-    }
+    for (auto scalarId : scalarList_)
+    {
+      CScalar* pScalar = CScalar::get(scalarId);
+      pScalar->solveRefInheritance(apply);
+      pScalar->solveInheritanceTransformation();
+    }
+  }
+  CATCH_DUMP_ATTR
+
+ /*!
+  \brief check attributes of all elements of the grid
+  */
+  void CGrid::checkElementsAttributes(void)
+  TRY
+  {
+    setDomainList();
+    for (auto domainId : domList_) CDomain::get(domainId)->checkAttributes();
+
+    setAxisList();
+    for (auto axisId : axisList_) CAxis::get(axisId)->checkAttributes();
+    
+    setScalarList();
+    for (auto scalarId : scalarList_) CScalar::get(scalarId)->checkAttributes();
   }
   CATCH_DUMP_ATTR
@@ -2301,5 +2407,5 @@
   TRY
   {
-    if (0 != transformGridSrc)
+    if (nullptr != transformGridSrc)
     {
       if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
@@ -2362,4 +2468,61 @@
   }
   CATCH_DUMP_ATTR
+
+
+
+
+  void CGrid::prepareTransformGrid(CGrid* transformGridSrc)
+  TRY
+  {
+    if (prepareTransformGrid_done_) return ;
+
+    if (!transformGridSrc)
+      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
+            << "Impossible to transform grid '" << getId() << "', the source grid is null.");
+
+    if (isTransformed()) return;
+    setTransformed();
+    if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
+    {
+      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
+           << "Two grids have different number of elements. " << std::endl
+           << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
+           << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
+    }
+    else
+    {
+    }
+
+    transformations_ = new CGridTransformation(this, transformGridSrc);
+    if (0 < transformations_->getNbAlgo()) hasTransform_ = true;
+
+    prepareTransformGrid_done_ = true; 
+  }
+  CATCH_DUMP_ATTR
+
+
+  void CGrid::makeTransformGrid(void)
+  TRY
+  {
+    if (makeTransformGrid_done_) return ;
+    transformations_->computeAll();
+
+    makeTransformGrid_done_ = true ; 
+  }
+  CATCH_DUMP_ATTR
+
+
+  vector<std::string> CGrid::getAuxInputTransformGrid(void)
+  TRY
+  {
+    if (transformations_ != nullptr) return transformations_->getAuxInputs() ;
+  }
+  CATCH_DUMP_ATTR
+
+
+
+
+
+
 
   bool CGrid::hasTransform()
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1869)
@@ -71,5 +71,5 @@
          void checkEligibilityForCompressedOutput();
 
-         void solveDomainAxisRef(bool areAttributesChecked);
+
 
          void checkMaskIndex(bool doCalculateIndex);
@@ -89,15 +89,15 @@
          StdSize getDimension(void);
 
-         StdSize  getDataSize(void) const;
+         StdSize  getDataSize(void) ;
 
          /// Entrees-sorties de champs
          template <int n>
-         void inputField(const CArray<double,n>& field, CArray<double,1>& stored) const;
+         void inputField(const CArray<double,n>& field, CArray<double,1>& stored) ;
          template <int n>
-         void maskField(const CArray<double,n>& field, CArray<double,1>& stored) const;
+         void maskField(const CArray<double,n>& field, CArray<double,1>& stored) ;
          template <int n>
-         void outputField(const CArray<double,1>& stored, CArray<double,n>& field) const;  
+         void outputField(const CArray<double,1>& stored, CArray<double,n>& field) ;  
          template <int n>
-         void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) const; 
+         void uncompressField(const CArray<double,n>& data, CArray<double,1>& outData) ; 
 
          virtual void parse(xml::CXMLNode& node);
@@ -133,10 +133,12 @@
          void computeIndexScalarGrid();
          void computeWrittenIndex();
+         void solveDomainAxisRef(bool areAttributesChecked);
+         void checkElementsAttributes(void) ;
 
          void solveDomainRef(bool checkAtt);
          void solveAxisRef(bool checkAtt);
          void solveScalarRef(bool checkAtt);
-         void solveDomainAxisRefInheritance(bool apply = true);
-         void solveTransformations();
+         void solveElementsRefInheritance(bool apply = true);
+        // void solveTransformations();
          void solveDomainAxisBaseRef();
 
@@ -195,4 +197,13 @@
 
          void transformGrid(CGrid* transformGridSrc);
+         
+         void prepareTransformGrid(CGrid* transformGridSrc);
+         bool prepareTransformGrid_done_ = false ;
+
+         void makeTransformGrid(void); 
+         bool makeTransformGrid_done_ = false ;
+         
+         std::vector<std::string> getAuxInputTransformGrid(void) ; 
+
          void completeGrid(CGrid* transformGridSrc = 0);
          void doAutoDistribution(CGrid* transformGridSrc);
@@ -205,4 +216,6 @@
          bool hasTransform();
          size_t getGlobalWrittenSize(void) ;
+         bool checkIfCompleted(void) ;
+
 
          bool hasMask(void) const;
@@ -217,5 +230,10 @@
                                          const CArray<int,1>& axisDomainOrder);
 
+         void computeGridIndexToFileServer(CContextClient* client) ;
+
       private:
+       void computeClientDistribution(void) ;
+       bool computeClientDistribution_done_ = false ;
+
        template<int N>
        void checkGridMask(CArray<bool,N>& gridMask,
@@ -230,8 +248,8 @@
         void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue);
 
-        void storeField_arr(const double* const data, CArray<double, 1>& stored) const;
-        void restoreField_arr(const CArray<double, 1>& stored, double* const data) const;
-        void uncompressField_arr(const double* const data, CArray<double, 1>& outData) const;
-        void maskField_arr(const double* const data, CArray<double, 1>& stored) const;
+        void storeField_arr(const double* const data, CArray<double, 1>& stored) ;
+        void restoreField_arr(const CArray<double, 1>& stored, double* const data) ;
+        void uncompressField_arr(const double* const data, CArray<double, 1>& outData) ;
+        void maskField_arr(const double* const data, CArray<double, 1>& stored) ;
 
         void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
@@ -259,9 +277,16 @@
         int getDistributedDimension();
 
+       
         void computeClientIndex();
-        void computeConnectedClients();
+        bool computeClientIndex_done_ = false ;
+        
+        void computeConnectedClients(CContextClient* client);
+        set<CContextClient*> computeConnectedClients_done_ ;
+
         void computeClientIndexScalarGrid(); 
-        void computeConnectedClientsScalarGrid(); 
-
+        bool computeClientIndexScalarGrid_done_ = false ;
+
+        void computeConnectedClientsScalarGrid(CContextClient* client); 
+        set<CContextClient*> computeConnectedClientsScalarGrid_done_ ;
 
       public:
@@ -270,10 +295,16 @@
  *  Used to store field from model into the worklow, or to return field into models.  
  *  The size of the array is the number of local index of the workflow grid */        
-         CArray<int, 1> storeIndex_client_;
+        CArray<int, 1> storeIndex_client_;
+        void computeStoreIndex_client(void) ;
+        bool computeStoreIndex_client_done_ = false ;
+        CArray<int, 1>& getStoreIndex_client(void) { if (!computeStoreIndex_client_done_) computeStoreIndex_client() ; return storeIndex_client_ ;}
 
 /** Array containing the grid mask masked defined by the mask_nd grid attribute.        
   * The corresponding masked field value provided by the model will be replaced by a NaN value
   * in the workflow.  */
-         CArray<bool, 1> storeMask_client_;
+        CArray<bool, 1> storeMask_client_;
+        void computeStoreMask_client(void) ;
+        bool computeStoreMask_client_done_ = false ;
+        CArray<bool, 1>& getStoreMask_client(void) { if (!computeStoreMask_client_done_) computeStoreMask_client() ; return storeMask_client_ ;}
 
 /** Map containing the indexes on client side that will be sent to each connected server.
@@ -419,5 +450,5 @@
 
    template <int n>
-   void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored) const
+   void CGrid::inputField(const CArray<double,n>& field, CArray<double,1>& stored)
    TRY
    {
@@ -435,5 +466,5 @@
 
    template <int n>
-   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) const
+   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored)
    {
 //#ifdef __XIOS_DEBUG
@@ -449,5 +480,5 @@
 
    template <int n>
-   void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const
+   void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field)
    TRY
    {
@@ -471,5 +502,5 @@
    */
    template <int N>
-   void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData) const
+   void CGrid::uncompressField(const CArray<double,N>& data, CArray<double,1>& outData)
    TRY
    {      
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.cpp	(revision 1869)
@@ -59,4 +59,7 @@
    void CScalar::checkAttributes(void)
    {
+      if (checkAttributes_done_) return ;
+
+      checkAttributes_done_ = true ; 
    }
 
@@ -65,4 +68,42 @@
 
   }
+
+  /*!
+  \brief Check if a scalar is completed
+  Before make any scalar processing, we must be sure that all scalar informations have
+  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
+  other context (coupling). So all direct reference of the scalar (scalar_ref) must be also completed
+  \return true if scalar and scalar reference are completed
+  */
+  bool CScalar::checkIfCompleted(void)
+  {
+    if (hasDirectScalarReference()) if (!getDirectScalarReference()->checkIfCompleted()) return false;
+    return isCompleted_ ;
+  }
+
+  /*!
+  \brief Set a scalar as completed
+   When all information about a scalar have been received, the scalar is tagged as completed and is
+   suitable for processing
+  */
+  void CScalar::setCompleted(void)
+  {
+    if (hasDirectScalarReference()) getDirectScalarReference()->setCompleted() ;
+    isCompleted_=true ;
+  }
+
+  /*!
+  \brief Set a scalar as uncompleted
+   When informations about a scalar are expected from a grid reading from file or coupling, the scalar is 
+   tagged as uncompleted and is not suitable for processing
+  */
+  void CScalar::setUncompleted(void)
+  {
+    if (hasDirectScalarReference()) getDirectScalarReference()->setUncompleted() ;
+    isCompleted_=false ;
+  }
+
+
+
 
   /*!
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/scalar.hpp	(revision 1869)
@@ -66,8 +66,14 @@
          public:
             void checkAttributes(void);
+            bool checkAttributes_done_ = false ;
+            
             void addRelFile(const StdString& filename);
             bool IsWritten(const StdString& filename) const;
             void checkAttributesOnClient();
             virtual void parse(xml::CXMLNode & node);
+
+            bool checkIfCompleted(void) ;
+            void setCompleted(void) ;
+            void setUncompleted(void) ;
 
          public:
@@ -90,4 +96,7 @@
            static bool dummyTransformationMapList_;
 
+           /** define if the scalar is completed or not ie all attributes have been received before in case 
+               of grid reading from file or coupling */ 
+           bool isCompleted_=true ;  
 
             DECLARE_REF_FUNC(Scalar,scalar)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory.hpp	(revision 1869)
@@ -50,5 +50,8 @@
          template <typename U>
             static  std::shared_ptr<U> CreateObject(const StdString & id = StdString(""));
-
+ 
+         template <typename U>
+             static std::shared_ptr<U> CreateAlias(const StdString& id, const StdString& alias) ;
+         
          template <typename U> static const StdString& GetUIdBase(void);
          template <typename U> static StdString GenUId(void);
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory_decl_macro.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory_decl_macro.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory_decl_macro.hpp	(revision 1869)
@@ -13,4 +13,5 @@
   template bool CObjectFactory::HasObject<U>(const StdString& context,const StdString& id); \
   template std::shared_ptr<U> CObjectFactory::CreateObject<U>(const StdString& id ); \
+  template std::shared_ptr<U> CObjectFactory::CreateAlias<U>(const StdString& id, const StdString& alias ); \
   template const StdString& CObjectFactory::GetUIdBase<U>(void); \
   template StdString CObjectFactory::GenUId<U>(void); \
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory_impl.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory_impl.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/object_factory_impl.hpp	(revision 1869)
@@ -113,4 +113,31 @@
 
    template <typename U>
+   std::shared_ptr<U> CObjectFactory::CreateAlias(const StdString& id, const StdString& alias)
+   {
+      if (CurrContext.empty())
+         ERROR("CObjectFactory::CreateAlias(const StdString& id, const StdString& alias)",
+               << "[ id = " << id << " alias = "<<alias<<" ] please define current context id !");
+
+      if (CObjectFactory::HasObject<U>(alias))
+      {
+         return CObjectFactory::GetObject<U>(alias);
+      }
+      else
+      {
+        if (! CObjectFactory::HasObject<U>(id))
+        {
+            ERROR("CObjectFactory::CreateAlias(const StdString& id, const StdString& alias)",
+               << "[ id = " << id << " alias = "<<alias<<" ] object id doesn't exist"); 
+        }
+        else  
+        {
+          std::shared_ptr<U> value = CObjectFactory::GetObject<U>(id);  
+          U::AllMapObj[CObjectFactory::CurrContext].insert(std::make_pair(alias, value));
+          return value;
+         }
+      }
+   }
+
+   template <typename U>
       const std::vector<std::shared_ptr<U> > &
          CObjectFactory::GetObjectVector(const StdString & context)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template.hpp	(revision 1869)
@@ -83,4 +83,7 @@
 
          static T* create(const string& id=string("")) ;
+         static T* createAlias(const string& id, const string& alias) ;
+         void createAlias(const string& alias) ;
+         
          static const vector<T*> getAll() ;
          static const vector<T*> getAll(const string& contextId) ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template_impl.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template_impl.hpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/object_template_impl.hpp	(revision 1869)
@@ -420,4 +420,16 @@
    }   ///--------------------------------------------------------------
 
+   template <typename T>
+   T* CObjectTemplate<T>::createAlias(const string & id, const string& alias)
+   {
+     return CObjectFactory::CreateAlias<T>(id, alias).get();
+   }   ///--------------------------------------------------------------
+
+   template <typename T>
+   void CObjectTemplate<T>::createAlias(const string& alias)
+   {
+     get()->createAlias(getId(),alias) ;
+   }   //
+
   template <typename T>
   T* CObjectTemplate<T>::get(void)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/parse_expr/filter_expr_node.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/parse_expr/filter_expr_node.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/parse_expr/filter_expr_node.cpp	(revision 1869)
@@ -40,6 +40,6 @@
                 << "Use the keyword \"this\" if you want to reference the input data sent to this field.");
 
-        field->buildFilterGraph(gc, false);
-        outputPin = field->getInstantDataFilter();
+        bool ret=field->buildWorkflowGraph(gc);
+        if (ret) outputPin = field->getInstantDataFilter(); // if dependency is complete build the graph other return nullptr
       }
       else ERROR("boost::shared_ptr<COutputPin> CFilterFieldExprNode::reduce(CGarbageCollector& gc, CField& thisField) const",
@@ -84,6 +84,6 @@
                 << "Use the keyword \"this\" if you want to reference the input data sent to this field.");
 
-        field->buildFilterGraph(gc, false);
-        outputPin = field->getTemporalDataFilter(gc, thisField.freq_op.isEmpty() ? TimeStep : thisField.freq_op);
+        bool ret=field->buildWorkflowGraph(gc);
+        if (ret) outputPin = field->getTemporalDataFilter(gc, thisField.freq_op.isEmpty() ? TimeStep : thisField.freq_op);
       }
       else
@@ -107,5 +107,7 @@
   {
     std::shared_ptr<CUnaryArithmeticFilter> filter(new CUnaryArithmeticFilter(gc, opId));
-    child->reduce(gc, thisField)->connectOutput(filter, 0);
+    auto ret=child->reduce(gc, thisField) ;
+    if (ret) ret->connectOutput(filter, 0);
+    else filter.reset() ;
     return filter;
   }
@@ -124,5 +126,8 @@
   {
     std::shared_ptr<CScalarFieldArithmeticFilter> filter(new CScalarFieldArithmeticFilter(gc, opId, child1->reduce()));
-    child2->reduce(gc, thisField)->connectOutput(filter, 0);
+    
+    auto ret=child2->reduce(gc, thisField) ;
+    if (ret) ret->connectOutput(filter, 0);
+    else filter.reset() ;
     return filter;
   }
@@ -141,5 +146,7 @@
   {
     std::shared_ptr<CFieldScalarArithmeticFilter> filter(new CFieldScalarArithmeticFilter(gc, opId, child2->reduce()));
-    child1->reduce(gc, thisField)->connectOutput(filter, 0);
+    auto ret=child1->reduce(gc, thisField) ;
+    if (ret) ret->connectOutput(filter, 0);
+    else filter.reset() ;
     return filter;
   }
@@ -158,6 +165,12 @@
   {
     std::shared_ptr<CFieldFieldArithmeticFilter> filter(new CFieldFieldArithmeticFilter(gc, opId));
-    child1->reduce(gc, thisField)->connectOutput(filter, 0);
-    child2->reduce(gc, thisField)->connectOutput(filter, 1);
+    auto ret1 = child1->reduce(gc, thisField);
+    auto ret2 = child2->reduce(gc, thisField);
+    if (ret1 && ret2) 
+    {
+      ret1->connectOutput(filter, 0) ;
+      ret2->connectOutput(filter, 1) ;
+    }
+    else filter.reset() ;
     return filter;
   }
@@ -180,5 +193,7 @@
   {
     std::shared_ptr<CScalarScalarFieldArithmeticFilter> filter(new CScalarScalarFieldArithmeticFilter(gc, opId, child1->reduce(),child2->reduce()));
-    child3->reduce(gc, thisField)->connectOutput(filter, 0);
+    auto ret=child3->reduce(gc, thisField) ;
+    if (ret) ret->connectOutput(filter, 0);
+    else filter.reset() ;
     return filter;
   }
@@ -199,5 +214,7 @@
   {
     std::shared_ptr<CScalarFieldScalarArithmeticFilter> filter(new CScalarFieldScalarArithmeticFilter(gc, opId, child1->reduce(),child3->reduce()));
-    child2->reduce(gc, thisField)->connectOutput(filter, 0);
+    auto ret=child2->reduce(gc, thisField);
+    if (ret) ret->connectOutput(filter, 0);
+    else filter.reset() ;
     return filter;
   }
@@ -218,6 +235,12 @@
   {
     std::shared_ptr<CScalarFieldFieldArithmeticFilter> filter(new CScalarFieldFieldArithmeticFilter(gc, opId, child1->reduce()));
-    child2->reduce(gc, thisField)->connectOutput(filter, 0);
-    child3->reduce(gc, thisField)->connectOutput(filter, 1);
+    auto ret1=child2->reduce(gc, thisField);
+    auto ret2=child3->reduce(gc, thisField);
+    if (ret1 && ret2)
+    {
+      ret1->connectOutput(filter, 0);
+      ret2->connectOutput(filter, 1);
+    }
+    else filter.reset() ;
     return filter;
   }
@@ -239,5 +262,7 @@
   {
     std::shared_ptr<CFieldScalarScalarArithmeticFilter> filter(new CFieldScalarScalarArithmeticFilter(gc, opId, child2->reduce(),child3->reduce()));
-    child1->reduce(gc, thisField)->connectOutput(filter, 0);
+    auto ret = child1->reduce(gc, thisField) ;
+    if (ret) ret->connectOutput(filter, 0);
+    else filter.reset() ;
     return filter;
   }
@@ -259,6 +284,12 @@
   {
     std::shared_ptr<CFieldScalarFieldArithmeticFilter> filter(new CFieldScalarFieldArithmeticFilter(gc, opId, child2->reduce()));
-    child1->reduce(gc, thisField)->connectOutput(filter, 0);
-    child3->reduce(gc, thisField)->connectOutput(filter, 1);
+    auto ret1 = child1->reduce(gc, thisField);
+    auto ret2 = child3->reduce(gc, thisField);
+    if (ret1 && ret2)
+    {
+      ret1 -> connectOutput(filter, 0);
+      ret2 -> connectOutput(filter, 1);
+    }
+    else filter.reset() ;
     return filter;
   }
@@ -280,6 +311,12 @@
   {
     std::shared_ptr<CFieldFieldScalarArithmeticFilter> filter(new CFieldFieldScalarArithmeticFilter(gc, opId, child3->reduce()));
-    child1->reduce(gc, thisField)->connectOutput(filter, 0);
-    child2->reduce(gc, thisField)->connectOutput(filter, 1);
+    auto ret1 = child1->reduce(gc, thisField);
+    auto ret2 = child2->reduce(gc, thisField);
+    if (ret1 && ret2)
+    {
+      ret1->connectOutput(filter, 0);
+      ret2->connectOutput(filter, 1);
+    }
+    else filter.reset() ;
     return filter;
   }
@@ -300,7 +337,14 @@
   {
     std::shared_ptr<CFieldFieldFieldArithmeticFilter> filter(new CFieldFieldFieldArithmeticFilter(gc, opId));
-    child1->reduce(gc, thisField)->connectOutput(filter, 0);
-    child2->reduce(gc, thisField)->connectOutput(filter, 1);
-    child3->reduce(gc, thisField)->connectOutput(filter, 2);
+    auto ret1=child1->reduce(gc, thisField);
+    auto ret2=child2->reduce(gc, thisField);
+    auto ret3=child3->reduce(gc, thisField);
+    if (ret1 && ret2 && ret3)
+    {
+      ret1->connectOutput(filter, 0);
+      ret2->connectOutput(filter, 1);
+      ret3->connectOutput(filter, 2);
+    }
+    else filter.reset() ;
     return filter;
   }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/test/generic_testcase.f90
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/test/generic_testcase.f90	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/test/generic_testcase.f90	(revision 1869)
@@ -258,5 +258,5 @@
     
     ok_field3D_recv_W=xios_is_valid_field("field3D_recv_W").AND.xios_is_valid_field("field3D_resend_W") ;
-    IF (ok_field3D_recv) THEN
+    IF (ok_field3D_recv_W) THEN
       CALL xios_is_defined_field_attr("field3D_recv_W",freq_op=ok)
       IF (ok) THEN
@@ -463,5 +463,5 @@
     
     ok_other_field3D_recv_W=xios_is_valid_field("other_field3D_recv_W").AND.xios_is_valid_field("other_field3D_resend_W") ;
-    IF (ok_other_field3D_recv) THEN
+    IF (ok_other_field3D_recv_W) THEN
       CALL xios_is_defined_field_attr("other_field3D_recv_W",freq_op=ok)
       IF (ok) THEN
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 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm_interpolate.cpp	(revision 1869)
@@ -313,5 +313,5 @@
   {
     CField* field = CField::get(coordinate_);
-    CGrid* grid = field->grid;
+    CGrid* grid = field->getGrid();
 
     std::vector<CDomain*> domListP = grid->getDomains();
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_transformation.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_transformation.cpp	(revision 1853)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_transformation.cpp	(revision 1869)
@@ -246,5 +246,6 @@
   }
 
-  tmpGridDestination_ = CGrid::createGrid(domainDst, axisDst, scalarDst, elementOrder);  
+  tmpGridDestination_ = CGrid::createGrid(domainDst, axisDst, scalarDst, elementOrder); 
+  tmpGridDestination_-> solveElementsRefInheritance() ; // ym not sure 
   tempGridDests_.push_back(tmpGridDestination_);
 }
@@ -292,5 +293,5 @@
         domain->domain_ref.setValue(domListDestP[elementIndex]->getId());
         domain->solveRefInheritance(true);
-        domain->checkAttributesOnClient();
+        domain->checkAttributes();
         domainSrc.push_back(domain);
       }
@@ -300,5 +301,5 @@
         axis->axis_ref.setValue(axisListDestP[elementIndex]->getId());
         axis->solveRefInheritance(true);
-        axis->checkAttributesOnClient();
+        axis->checkAttributes();
         axisSrc.push_back(axis); 
       }
@@ -308,5 +309,5 @@
         scalar->scalar_ref.setValue(scalarListDestP[elementIndex]->getId());
         scalar->solveRefInheritance(true);
-        scalar->checkAttributesOnClient();
+        scalar->checkAttributes();
         scalarSrc.push_back(scalar);
       }
@@ -334,4 +335,5 @@
 
   gridSource_ = CGrid::createGrid(domainSrc, axisSrc, scalarSrc, tmpGridDestination_->axis_domain_order);  
+  gridSource_->solveElementsRefInheritance() ; // ym not sure
 
   tempGridSrcs_.push_back(gridSource_);
