Index: XIOS/dev/dev_olga/src/node/field.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/field.cpp	(revision 1009)
+++ XIOS/dev/dev_olga/src/node/field.cpp	(revision 1021)
@@ -36,5 +36,5 @@
       , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false)
       , useCompressedOutput(false)
-      , isReadDataRequestPending(false)
+      , wasDataAlreadyReceivedFromServer(false)
    { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
 
@@ -47,5 +47,5 @@
       , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false)
       , useCompressedOutput(false)
-      , isReadDataRequestPending(false)
+      , wasDataAlreadyReceivedFromServer(false)
    { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
 
@@ -179,10 +179,7 @@
   }
 
-  void CField::sendUpdateData(const CArray<double,1>& data, const int srvPool)
+  void CField::sendUpdateData(const CArray<double,1>& data, CContextClient* client)
   {
     CTimer::get("XIOS Send Data").resume();
-
-    CContext* context = CContext::getCurrent();
-    CContextClient* client = context->clientPrimServer[srvPool];
 
     CEventClient event(getType(), EVENT_ID_UPDATE_DATA);
@@ -312,5 +309,5 @@
         int fileIdx = std::find(context->enabledFiles.begin(), context->enabledFiles.end(), this->file) - context->enabledFiles.begin();
         int srvId = fileIdx % context->clientPrimServer.size();
-        sendUpdateData(fieldData, srvId);
+        sendUpdateData(fieldData, context->clientPrimServer[srvId]);
     }
     if (!context->hasClient && context->hasServer)
@@ -348,11 +345,10 @@
   }
 
-  void CField::sendReadDataRequest(void)
+  void CField::sendReadDataRequest(const CDate& tsDataRequested)
   {
     CContext* context = CContext::getCurrent();
     CContextClient* client = context->client;
 
-    lastDataRequestedFromServer = context->getCalendar()->getCurrentDate();
-    isReadDataRequestPending = true;
+    lastDataRequestedFromServer = tsDataRequested;
 
     CEventClient event(getType(), EVENT_ID_READ_DATA);
@@ -377,17 +373,17 @@
     const CDate& currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate();
 
-    bool requestData = (currentDate >= lastDataRequestedFromServer + file->output_freq.getValue());
-
-    if (requestData)
-    {
-      cout<<"currentDate : "<<currentDate<<endl ;
-      cout<<"lastDataRequestedFromServer : "<<lastDataRequestedFromServer<<endl ;
-      cout<<"file->output_freq.getValue() : "<<file->output_freq.getValue()<<endl ;
-      cout<<"lastDataRequestedFromServer + file->output_freq.getValue() : "<<lastDataRequestedFromServer + file->output_freq.getValue()<<endl ;
-
-      sendReadDataRequest();
-    }
-
-    return requestData;
+    bool dataRequested = false;
+    while (currentDate >= lastDataRequestedFromServer)
+    {
+      info(20) << "currentDate : " << currentDate << endl ;
+      info(20) << "lastDataRequestedFromServer : " << lastDataRequestedFromServer << endl ;
+      info(20) << "file->output_freq.getValue() : " << file->output_freq.getValue() << endl ;
+      info(20) << "lastDataRequestedFromServer + file->output_freq.getValue() : " << lastDataRequestedFromServer + file->output_freq << endl ;
+
+      sendReadDataRequest(lastDataRequestedFromServer + file->output_freq);
+
+      dataRequested = true;
+    }
+    return dataRequested;
   }
 
@@ -411,16 +407,74 @@
 
     map<int, CArray<double,1> >::iterator it;
-    for (it = data_srv.begin(); it != data_srv.end(); it++)
-    {
-      msgs.push_back(CMessage());
-      CMessage& msg = msgs.back();
-      msg << getId();
-      if (hasData)
-        msg << getNStep() - 1 << it->second;
-      else
-        msg << int(-1);
-      event.push(it->first, grid->nbSenders[it->first], msg);
-    }
-    client->sendEvent(event);
+//    for (it = data_srv.begin(); it != data_srv.end(); it++)
+//    {
+//      msgs.push_back(CMessage());
+//      CMessage& msg = msgs.back();
+//      msg << getId();
+//      if (hasData)
+//        msg << getNStep() - 1 << it->second;
+//      else
+//        msg << int(-1);
+//      event.push(it->first, grid->nbSenders[it->first], msg);
+//    }
+//    client->sendEvent(event);
+    if (!grid->doGridHaveDataDistributed())
+    {
+       if (client->isServerLeader())
+       {
+          if (!data_srv.empty())
+          {
+            it = data_srv.begin();
+            const std::list<int>& ranks = client->getRanksServerLeader();
+            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+            {
+              msgs.push_back(CMessage());
+              CMessage& msg = msgs.back();
+              msg << getId();
+              if (hasData)
+                msg << getNStep() - 1 << it->second;
+              else
+                msg << int(-1);
+              event.push(*itRank, 1, msg);
+            }
+          }
+          client->sendEvent(event);
+       }
+       else
+       {
+          // if (!data_srv.empty())
+          // {
+          //   it = data_srv.begin();
+          //   const std::list<int>& ranks = client->getRanksServerNotLeader();
+          //   for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+          //   {
+          //     msgs.push_back(CMessage());
+          //     CMessage& msg = msgs.back();
+          //     msg << getId();
+          //     if (hasData)
+          //       msg << getNStep() - 1 << it->second;
+          //     else
+          //       msg << int(-1);
+          //     event.push(*itRank, 1, msg);
+          //   }
+          // }
+          client->sendEvent(event);
+       }
+    }
+    else
+    {
+      for (it = data_srv.begin(); it != data_srv.end(); it++)
+      {
+        msgs.push_back(CMessage());
+        CMessage& msg = msgs.back();
+        msg << getId();
+        if (hasData)
+          msg << getNStep() - 1 << it->second;
+        else
+          msg << int(-1);
+        event.push(it->first, grid->nbSenders[it->first], msg);
+      }
+      client->sendEvent(event);
+    }
   }
 
@@ -494,10 +548,16 @@
     }
 
+    if (wasDataAlreadyReceivedFromServer)
+      lastDataReceivedFromServer = lastDataReceivedFromServer + file->output_freq;
+    else
+    {
+      lastDataReceivedFromServer = context->getCalendar()->getInitDate();
+      wasDataAlreadyReceivedFromServer = true;
+    }
+
     if (isEOF)
-      serverSourceFilter->signalEndOfStream(lastDataRequestedFromServer);
+      serverSourceFilter->signalEndOfStream(lastDataReceivedFromServer);
     else
-      serverSourceFilter->streamDataFromServer(lastDataRequestedFromServer, data);
-
-    isReadDataRequestPending = false;
+      serverSourceFilter->streamDataFromServer(lastDataReceivedFromServer, data);
   }
 
@@ -749,5 +809,5 @@
      solveGridDomainAxisRef(doSending2Server);
 
-     if (context->hasClient && !context->hasClient)
+     if (context->hasClient && !context->hasServer)
      {
        solveTransformedGrid();
@@ -831,8 +891,25 @@
      {
        // Check if we have an expression to parse
-       if (!content.empty())
-       {
-         boost::scoped_ptr<IFilterExprNode> expr(parseExpr(content + '\0'));
-         instantDataFilter = expr->reduce(gc, *this);
+       if (hasExpression())
+       {
+         boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0'));
+         boost::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())
+           {
+             double defaultValue = !default_value.isEmpty() ? default_value : 0.0;
+             std::pair<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, defaultValue);
+
+             filter->connectOutput(filters.first, 0);
+             filter = filters.second;
+           }
+         }
+
+         instantDataFilter = filter;
        }
        // Check if we have a reference on another field
@@ -841,8 +918,9 @@
        // Check if the data is to be read from a file
        else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
-         instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid,
-                                                                                                     freq_offset.isEmpty() ? NoneDu : freq_offset));
+         instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid,
+                                                                                                     freq_offset.isEmpty() ? NoneDu : freq_offset,
+                                                                                                     true));
        else // The data might be passed from the model
-         instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid));
+         instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid));
      }
 
@@ -863,4 +941,5 @@
      }
    }
+
 
    /*!
@@ -871,29 +950,27 @@
     * \return the output pin corresponding to the field reference
     */
-   boost::shared_ptr<COutputPin> CField::getFieldReference(CGarbageCollector& gc)
-   {
-     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<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters;
-     // Check if a spatial transformation is needed
-     if (grid && grid != fieldRef->grid && grid->hasTransform())
-     {
-       double defaultValue = 0.0;
-       if (!default_value.isEmpty()) defaultValue = this->default_value;
-       filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, defaultValue);
-     }
-
-     else
-       filters.first = filters.second = boost::shared_ptr<CFilter>(new CPassThroughFilter(gc));
-
-     fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0);
-
-     return filters.second;
-   }
+     boost::shared_ptr<COutputPin> CField::getFieldReference(CGarbageCollector& gc)
+     {
+       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<boost::shared_ptr<CFilter>, boost::shared_ptr<CFilter> > filters;
+       // Check if a spatial transformation is needed
+       if (grid && grid != fieldRef->grid && grid->hasTransform())
+       {
+         double defaultValue = !default_value.isEmpty() ? default_value : 0.0;
+         filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, defaultValue);
+       }
+       else
+         filters.first = filters.second = boost::shared_ptr<CFilter>(new CPassThroughFilter(gc));
+
+       fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0);
+
+       return filters.second;
+     }
 
    /*!
@@ -908,5 +985,5 @@
    boost::shared_ptr<COutputPin> CField::getSelfReference(CGarbageCollector& gc)
    {
-     if (instantDataFilter || content.empty())
+     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.");
@@ -917,15 +994,19 @@
        {
          if (!serverSourceFilter)
-           serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid,
-                                                                                   freq_offset.isEmpty() ? NoneDu : freq_offset));
-
+           serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid,
+                                                                                   freq_offset.isEmpty() ? NoneDu : freq_offset,
+                                                                                   true));
          selfReferenceFilter = serverSourceFilter;
        }
        else if (!field_ref.isEmpty())
-         selfReferenceFilter = getFieldReference(gc);
+       {
+         CField* fieldRef = CField::get(field_ref);
+         fieldRef->buildFilterGraph(gc, false);
+         selfReferenceFilter = fieldRef->getInstantDataFilter();
+       }
        else
        {
          if (!clientSourceFilter)
-           clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid));
+           clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid));
 
          selfReferenceFilter = clientSourceFilter;
@@ -1126,5 +1207,6 @@
      else if (grid && grid->hasTransform() && !grid->isTransformed())
      {
-       grid->transformGrid(grid);
+       // Temporarily deactivate the self-transformation of grid
+       //grid->transformGrid(grid);
      }
    }
@@ -1325,5 +1407,5 @@
    }
 
-   void CField::sendAddAllVariables(const int srvPool)
+   void CField::sendAddAllVariables(CContextClient* client)
    {
      std::vector<CVariable*> allVar = getAllVariables();
@@ -1333,7 +1415,7 @@
      for (; it != itE; ++it)
      {
-       this->sendAddVariable((*it)->getId());
-       (*it)->sendAllAttributesToServer(srvPool);
-       (*it)->sendValue(srvPool);
+       this->sendAddVariable((*it)->getId(), client);
+       (*it)->sendAllAttributesToServer(client);
+       (*it)->sendValue(client);
      }
    }
@@ -1363,4 +1445,28 @@
    }
 
+   void CField::sendAddVariable(const string& id, CContextClient* client)
+   {
+      sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE, client);
+    // CContext* context = CContext::getCurrent();
+
+    // if (!context->hasServer)
+    // {
+    //    CContextClient* client = context->client;
+
+    //    CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE);
+    //    if (client->isServerLeader())
+    //    {
+    //      CMessage msg;
+    //      msg << this->getId();
+    //      msg << id;
+    //      const std::list<int>& ranks = client->getRanksServerLeader();
+    //      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+    //        event.push(*itRank,1,msg);
+    //      client->sendEvent(event);
+    //    }
+    //    else client->sendEvent(event);
+    // }
+   }
+
    void CField::sendAddVariableGroup(const string& id)
    {
@@ -1418,4 +1524,25 @@
    }
 
+   /*!
+    * 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)
+   {
+     if (!expr.isEmpty() && content.empty())
+     {
+       content = expr;
+       expr.reset();
+     }
+
+     return content;
+   }
+
+   bool CField::hasExpression(void) const
+   {
+     return (!expr.isEmpty() || !content.empty());
+   }
+
+
    DEFINE_REF_FUNC(Field,field)
 } // namespace xios
