Index: XIOS/dev/XIOS_DEV_CMIP6/src/node/field.cpp
===================================================================
--- XIOS/dev/XIOS_DEV_CMIP6/src/node/field.cpp	(revision 1215)
+++ XIOS/dev/XIOS_DEV_CMIP6/src/node/field.cpp	(revision 1232)
@@ -41,5 +41,5 @@
       , hasTimeCentered(false)
       , wasDataAlreadyReceivedFromServer(false)
-      , isEOF(false)
+      , isEOF(false), nstepMaxRead(false)
    { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
 
@@ -56,5 +56,5 @@
       , hasTimeCentered(false)
       , wasDataAlreadyReceivedFromServer(false)
-      , isEOF(false)
+      , isEOF(false), nstepMaxRead(false)
    { setVirtualVariableGroup(CVariableGroup::create(getId() + "_virtual_variable_group")); }
 
@@ -262,5 +262,5 @@
   void CField::writeField(void)
   {
-    if (!getRelFile()->allDomainEmpty)
+    if (!getRelFile()->isEmptyZone())
     {
       if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
@@ -273,8 +273,17 @@
   }
 
+  /*
+    Send a request for reading data.
+    Client sends a request to server for demanding server to read data and send back to it.
+    For now, this function is called only by client
+    In the future, it can be called by level-1 servers
+    \param [in] tsDataRequested timestamp when the call is made
+  */
   bool CField::sendReadDataRequest(const CDate& tsDataRequested)
   {
     CContext* context = CContext::getCurrent();
-//    CContextClient* client = context->client;
+    // CContextClient* client = context->client;
+
+    // This code is for future: If we want to read file with level-2 servers
     CContextClient* client = (!context->hasServer) ? context->client : this->file->getContextClient();
 
@@ -332,14 +341,19 @@
   }
 
+  /*!
+    Receive data request sent from client and process it
+    Every time server receives this request, it will try to read data and sent read data back to client
+    At the moment, this function is called by server level 1
+    In the future, this should (only) be done by the last level servers.
+  */
   void CField::recvReadDataRequest(void)
   {
     CContext* context = CContext::getCurrent();
     CContextClient* client = context->client;
-//    CContextClient* client = (!context->hasServer) ? context->client : this->file->getContextClient();
 
     CEventClient event(getType(), EVENT_ID_READ_DATA_READY);
     std::list<CMessage> msgs;
 
-    bool hasData = readField();
+    EReadField hasData = readField();
 
     map<int, CArray<double,1> >::iterator it;
@@ -356,8 +370,18 @@
               CMessage& msg = msgs.back();
               msg << getId();
-              if (hasData)
-                msg << getNStep() - 1 << recvDataSrv;
-              else
-                msg << int(-1);
+              switch (hasData)
+              {
+                case RF_DATA:
+                  msg << getNStep() - 1 << recvDataSrv;
+                  break;
+                case RF_NODATA:
+                  msg << int(-2);
+                  break;
+                case RF_EOF:                  
+                default:
+                  msg << int(-1);
+                  break;
+              }
+
               event.push(*itRank, 1, msg);
             }
@@ -385,8 +409,18 @@
         CMessage& msg = msgs.back();
         msg << getId();
-        if (hasData)
-          msg << getNStep() - 1 << tmp;
-        else
-          msg << int(-1);
+        switch (hasData)
+        {
+          case RF_DATA:
+            msg << getNStep() - 1 << tmp;
+            break;
+          case RF_NODATA:
+            msg << int(-2) << tmp;
+            break;
+          case RF_EOF:                  
+          default:
+            msg << int(-1);
+            break;
+        }
+
         event.push(it->first, grid->nbReadSenders[0][it->first], msg);
       }
@@ -395,10 +429,19 @@
   }
 
-  bool CField::readField(void)
+  /*!
+    Read field from a file.
+    A field is read with the distribution of data on the server side
+    \return State of field can be read from a file
+  */
+  CField::EReadField CField::readField(void)
   {
+    CContext* context = CContext::getCurrent();
     grid->computeWrittenIndex();
-    if (!getRelFile()->allDomainEmpty)
-    {
-      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)
+    getRelFile()->initRead();
+    EReadField readState = RF_DATA;
+
+    if (!getRelFile()->isEmptyZone())
+    {      
+      if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file)      
       {
         if (0 == recvDataSrv.numElements())
@@ -407,6 +450,7 @@
           recvDataSrv.resize(storeClient.numElements());          
         }
-
+        
         getRelFile()->checkReadFile();
+
         if (!nstepMax)
         {
@@ -417,13 +461,37 @@
 
         if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) )
-          return false;
-
-        getRelFile()->getDataInput()->readFieldData(CField::get(this));
-      }
-    }
-
-    return true;
+          readState = RF_EOF;
+
+        if (RF_EOF != readState)
+          getRelFile()->getDataInput()->readFieldData(CField::get(this));
+      }
+    }
+    else
+    {
+      this->incrementNStep();
+      if (getNStep() > nstepMax && (getRelFile()->cyclic.isEmpty() || !getRelFile()->cyclic) )
+        readState = RF_EOF;
+      else
+        readState = RF_NODATA;
+
+      if (!nstepMaxRead) // This can be a bug if we try to read field from zero time record
+        readState = RF_NODATA;
+    }
+
+    if (!nstepMaxRead)
+    {
+       MPI_Allreduce(&nstepMax, &nstepMax, 1, MPI_INT, MPI_MAX, context->server->intraComm);
+       nstepMaxRead = true;
+    }
+
+    return readState;
   }
 
+  /*
+    Receive read data from server.
+    At the moment, this function is called in the client side.
+    In the future, this function can be called hiearachically (server n-1, server n -2, ..., client)
+    \param event event containing read data
+  */
   void CField::recvReadDataReady(CEventServer& event)
   {
@@ -443,4 +511,9 @@
   }
 
+  /*!
+    Receive read data from server
+    \param [in] ranks Ranks of sending processes
+    \param [in] buffers buffers containing read data
+  */
   void CField::recvReadDataReady(vector<int> ranks, vector<CBufferIn*> buffers)
   {
@@ -528,4 +601,5 @@
    {
       this->nstepMax = 0;
+      nstepMaxRead = false;
    }
 
