Index: /XIOS/trunk/src/config/field_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/field_attribute.conf	(revision 886)
+++ /XIOS/trunk/src/config/field_attribute.conf	(revision 887)
@@ -18,4 +18,5 @@
 DECLARE_ATTRIBUTE(StdString, domain_ref)
 DECLARE_ATTRIBUTE(StdString, axis_ref)
+DECLARE_ATTRIBUTE(StdString, scalar_ref)
 DECLARE_ATTRIBUTE(StdString, grid_ref)
 DECLARE_ATTRIBUTE(StdString, field_ref)
Index: /XIOS/trunk/src/config/grid_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/grid_attribute.conf	(revision 886)
+++ /XIOS/trunk/src/config/grid_attribute.conf	(revision 887)
@@ -12,3 +12,4 @@
 
 // An array contains order of axis and domains composing of the grid
-DECLARE_ARRAY_PRIVATE(bool, 1, axis_domain_order)
+// Value of element: domain 2, axis 1 and sclar 0
+DECLARE_ARRAY_PRIVATE(int, 1, axis_domain_order)
Index: /XIOS/trunk/src/config/node_type.conf
===================================================================
--- /XIOS/trunk/src/config/node_type.conf	(revision 886)
+++ /XIOS/trunk/src/config/node_type.conf	(revision 887)
@@ -55,4 +55,7 @@
 #endif //__XIOS_CGenerateRectilinearDomain__
 
+#ifdef __XIOS_CScalar__
+   DECLARE_NODE(Scalar, scalar)
+#endif //__XIOS_CScalar__
 
 #ifdef __XIOS_CContext__
Index: /XIOS/trunk/src/config/scalar_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/scalar_attribute.conf	(revision 887)
+++ /XIOS/trunk/src/config/scalar_attribute.conf	(revision 887)
@@ -0,0 +1,10 @@
+DECLARE_ATTRIBUTE(StdString, name)
+DECLARE_ATTRIBUTE(StdString, standard_name)
+DECLARE_ATTRIBUTE(StdString, long_name)
+
+DECLARE_ATTRIBUTE(StdString, unit)
+
+/* LOCAL and GLOBAL*/
+DECLARE_ATTRIBUTE(double, value)
+
+DECLARE_ATTRIBUTE(StdString, scalar_ref)
Index: /XIOS/trunk/src/context_server.cpp
===================================================================
--- /XIOS/trunk/src/context_server.cpp	(revision 886)
+++ /XIOS/trunk/src/context_server.cpp	(revision 887)
@@ -184,5 +184,5 @@
          // The best way to properly solve this problem will be to use the event scheduler also in attached mode
          // for now just set up a MPI barrier
-         if (!CServer::eventScheduler) MPI_Barrier(intraComm) ; 
+         if (!CServer::eventScheduler) MPI_Barrier(intraComm) ;
 
          CTimer::get("Process events").resume();
@@ -238,4 +238,6 @@
     else if (event.classId==CAxis::GetType()) CAxis::dispatchEvent(event);
     else if (event.classId==CAxisGroup::GetType()) CAxisGroup::dispatchEvent(event);
+    else if (event.classId==CScalar::GetType()) CScalar::dispatchEvent(event);
+    else if (event.classId==CScalarGroup::GetType()) CScalarGroup::dispatchEvent(event);
     else if (event.classId==CGrid::GetType()) CGrid::dispatchEvent(event);
     else if (event.classId==CGridGroup::GetType()) CGridGroup::dispatchEvent(event);
Index: /XIOS/trunk/src/data_output.cpp
===================================================================
--- /XIOS/trunk/src/data_output.cpp	(revision 886)
+++ /XIOS/trunk/src/data_output.cpp	(revision 887)
@@ -16,5 +16,5 @@
       void CDataOutput::writeGrid(CGrid* grid, bool allowCompressedOutput /*= false*/)
       {
-        this->writeGrid(grid->getDomains(), grid->getAxis());
+        this->writeGrid(grid->getDomains(), grid->getAxis(), grid->getScalars());
 
         if (allowCompressedOutput)
@@ -58,4 +58,14 @@
         for (int i = 0; i < domSize; ++i) this->writeDomain_(domains[i]);
         for (int i = 0; i < aSize; ++i) this->writeAxis_(axis[i]);
+      }
+
+      void CDataOutput::writeGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis, std::vector<CScalar*> scalars)
+      {
+        int domSize = domains.size();
+        int aSize = axis.size();
+        int sSize = scalars.size();
+        for (int i = 0; i < domSize; ++i) this->writeDomain_(domains[i]);
+        for (int i = 0; i < aSize; ++i) this->writeAxis_(axis[i]);
+        for (int i = 0; i < sSize; ++i) this->writeScalar_(scalars[i]);
       }
 
Index: /XIOS/trunk/src/data_output.hpp
===================================================================
--- /XIOS/trunk/src/data_output.hpp	(revision 886)
+++ /XIOS/trunk/src/data_output.hpp	(revision 887)
@@ -44,4 +44,5 @@
             void writeGrid(CDomain* domain);
             void writeGrid(std::vector<CDomain*> domain, std::vector<CAxis*> axis);
+            void writeGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis, std::vector<CScalar*> scalars);
 
             virtual void writeFile_     (CFile*      file)   = 0;
@@ -53,4 +54,5 @@
             virtual void writeDomain_   (CDomain*    domain) = 0;
             virtual void writeAxis_     (CAxis*      axis)   = 0;
+            virtual void writeScalar_   (CScalar*    scalar) = 0;
             virtual void writeGridCompressed_(CGrid* grid)   = 0;
             virtual void writeTimeDimension_(void)           = 0;
Index: /XIOS/trunk/src/distribution.cpp
===================================================================
--- /XIOS/trunk/src/distribution.cpp	(revision 886)
+++ /XIOS/trunk/src/distribution.cpp	(revision 887)
@@ -21,9 +21,4 @@
 { /* Nothing to do */ }
 
-const CArray<size_t,1>& CDistribution::getGlobalIndex() const
-{
-  return globalIndex_;
-}
-
 int CDistribution::getDims() const
 {
Index: /XIOS/trunk/src/distribution.hpp
===================================================================
--- /XIOS/trunk/src/distribution.hpp	(revision 886)
+++ /XIOS/trunk/src/distribution.hpp	(revision 887)
@@ -32,8 +32,7 @@
     int getRank() const; //! Get rank of current process
 
-    //! Get global index
-    const CArray<size_t,1>& getGlobalIndex() const;
   protected:
-    virtual void createGlobalIndex() = 0;
+    virtual void createGlobalIndex() {};
+
   protected:
     CArray<size_t,1> globalIndex_;
Index: /XIOS/trunk/src/distribution_client.cpp
===================================================================
--- /XIOS/trunk/src/distribution_client.cpp	(revision 886)
+++ /XIOS/trunk/src/distribution_client.cpp	(revision 887)
@@ -56,13 +56,8 @@
   std::vector<CDomain*> domList = grid->getDomains();
   std::vector<CAxis*> axisList = grid->getAxis();
-  CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
-
-  std::vector<CDomain*>::iterator itbDom, iteDom, itDom;
-  std::vector<CAxis*>::iterator itbAxis, iteAxis, itAxis;
-
-  itbDom  = itDom  = domList.begin();  iteDom  = domList.end();
-  itbAxis = itAxis = axisList.begin(); iteAxis = axisList.end();
-
-  readDistributionInfo(domList, axisList, axisDomainOrder);
+  std::vector<CScalar*> scalarList = grid->getScalars();
+  CArray<int,1> axisDomainOrder = grid->axis_domain_order;
+
+  readDistributionInfo(domList, axisList, scalarList, axisDomainOrder);
 
   // Then check mask of grid
@@ -92,10 +87,12 @@
   \param [in] domList List of domains of grid
   \param [in] axisList List of axis of grid
-  \param [in] axisDomainOrder order of axis and domain inside a grid. True if domain, false if axis
+  \param [in] scalarList List of scalar of grid
+  \param [in] axisDomainOrder order of axis and domain inside a grid. 2 if domain, 1 if axis and zero if scalar
 //  \param [in] gridMask Mask of grid, for now, keep it 3 dimension, but it needs changing
 */
 void CDistributionClient::readDistributionInfo(const std::vector<CDomain*>& domList,
                                                const std::vector<CAxis*>& axisList,
-                                               const CArray<bool,1>& axisDomainOrder)
+                                               const std::vector<CScalar*>& scalarList,
+                                               const CArray<int,1>& axisDomainOrder)
 {
   domainNum_ = domList.size();
@@ -129,5 +126,5 @@
   {
     indexMap_[i] = idx;
-    if (true == axisDomainOrder(i))
+    if (2 == axisDomainOrder(i))
     {
       ++(this->dims_);
@@ -155,5 +152,5 @@
 
   // A trick to determine position of each domain in domainList
-  int domIndex = 0, axisIndex = 0;
+  int domIndex = 0, axisIndex = 0, scalarIndex = 0;
   idx = 0;
 
@@ -172,10 +169,10 @@
   for (idx = 0; idx < numElement_; ++idx)
   {
-    bool isDomain = axisDomainOrder(idx);
+    int eleDim = axisDomainOrder(idx);
     elementNLocal_[idx] = localSize;
     elementNGlobal_[idx] = globalSize;
 
     // If this is a domain
-    if (isDomain)
+    if (2 == eleDim)
     {
       // On the j axis
@@ -188,6 +185,8 @@
 
       dataBegin_.at(indexMap_[idx]+1) = domList[domIndex]->data_jbegin.getValue(); //(2 == domList[domIndex]->data_dim) ? domList[domIndex]->data_jbegin.getValue() : -1;
-      dataIndex_.at(indexMap_[idx]+1) = &(domList[domIndex]->data_j_index);
-      infoIndex_.at(indexMap_[idx]+1) = &(domList[domIndex]->j_index);
+//      dataIndex_.at(indexMap_[idx]+1) = &(domList[domIndex]->data_j_index);
+//      infoIndex_.at(indexMap_[idx]+1) = &(domList[domIndex]->j_index);
+      dataIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->data_j_index);
+      infoIndex_.at(indexMap_[idx]+1).reference(domList[domIndex]->j_index);
 
       // On the i axis
@@ -200,6 +199,8 @@
 
       dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
-      dataIndex_.at(indexMap_[idx]) = &(domList[domIndex]->data_i_index);
-      infoIndex_.at(indexMap_[idx]) = &(domList[domIndex]->i_index);
+//      dataIndex_.at(indexMap_[idx]) = &(domList[domIndex]->data_i_index);
+//      infoIndex_.at(indexMap_[idx]) = &(domList[domIndex]->i_index);
+      dataIndex_.at(indexMap_[idx]).reference(domList[domIndex]->data_i_index);
+      infoIndex_.at(indexMap_[idx]).reference(domList[domIndex]->i_index);
 
       dataNIndex_.at(idx) = domList[domIndex]->data_i_index.numElements();
@@ -212,5 +213,5 @@
       ++domIndex;
     }
-    else // So it's an axis
+    else if (1 == eleDim)// So it's an axis
     {
       nLocal_.at(indexMap_[idx]) = axisList[axisIndex]->n.getValue();
@@ -222,6 +223,8 @@
 
       dataBegin_.at(indexMap_[idx]) = axisList[axisIndex]->data_begin.getValue();
-      dataIndex_.at(indexMap_[idx]) = &(axisList[axisIndex]->data_index);
-      infoIndex_.at(indexMap_[idx]) = &(axisList[axisIndex]->index);
+//      dataIndex_.at(indexMap_[idx]) = &(axisList[axisIndex]->data_index);
+//      infoIndex_.at(indexMap_[idx]) = &(axisList[axisIndex]->index);
+      dataIndex_.at(indexMap_[idx]).reference(axisList[axisIndex]->data_index);
+      infoIndex_.at(indexMap_[idx]).reference(axisList[axisIndex]->index);
       dataNIndex_.at(idx) = axisList[axisIndex]->data_index.numElements();
       dataDims_.at(idx) = 1;
@@ -233,4 +236,26 @@
 
       ++axisIndex;
+    }
+    else // scalar
+    {
+      nLocal_.at(indexMap_[idx]) = 1;
+      nGlob_.at(indexMap_[idx]) = 1;
+      nBeginLocal_.at(indexMap_[idx]) = 0;
+      nBeginGlobal_.at(indexMap_[idx]) = 1;
+      nZoomBegin_.at((indexMap_[idx])) = 0;
+      nZoomEnd_.at((indexMap_[idx])) = 0;
+
+      dataBegin_.at(indexMap_[idx]) = 0;
+      dataIndex_.at(indexMap_[idx]).resize(1); dataIndex_.at(indexMap_[idx])(0) = 0;
+      infoIndex_.at(indexMap_[idx]).resize(1); infoIndex_.at(indexMap_[idx])(0) = 0;
+      dataNIndex_.at(idx) = 1;
+      dataDims_.at(idx) = 1;
+
+      isDataDistributed_ |= false;
+
+      localSize *= nLocal_.at(indexMap_[idx]);
+      globalSize *= nGlob_.at(indexMap_[idx]);
+
+      ++scalarIndex;
     }
   }
@@ -248,5 +273,5 @@
   for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
   {
-    if (axisDomainOrder_(i))
+    if (2 == axisDomainOrder_(i))
     {
       elementIndexData_[i].resize(dataNIndex_[i]);
@@ -255,5 +280,5 @@
       for (int j = 0; j < dataNIndex_[i]; ++j)
       {
-        iIdx = getDomainIndex((*dataIndex_[indexMap_[i]])(j), (*dataIndex_[indexMap_[i]+1])(j),
+        iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
                               dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
                               dataDims_[i], nLocal_[indexMap_[i]], jIdx);
@@ -281,13 +306,13 @@
         if (tmpIndexElementData(j))
         {
-          iIdx = getDomainIndex((*dataIndex_[indexMap_[i]])(j), (*dataIndex_[indexMap_[i]+1])(j),
+          iIdx = getDomainIndex((dataIndex_[indexMap_[i]])(j), (dataIndex_[indexMap_[i]+1])(j),
                                 dataBegin_[indexMap_[i]], dataBegin_[indexMap_[i]+1],
                                 dataDims_[i], nLocal_[indexMap_[i]], jIdx);
           localIndex = tmpLocalElementIndex(count) = iIdx + jIdx * nLocal_[indexMap_[i]];
-          tmpGlobalElementIndex(count) = (*infoIndex_[indexMap_[i]])(localIndex) + ((*infoIndex_[indexMap_[i]+1])(localIndex))*nGlob_[indexMap_[i]];
-          if ((((*infoIndex_[indexMap_[i]])(localIndex)) <= nZoomEnd_[indexMap_[i]])
-             && (nZoomBegin_[indexMap_[i]] <= ((*infoIndex_[indexMap_[i]])(localIndex)))
-             && (((*infoIndex_[indexMap_[i]+1])(localIndex)) <= nZoomEnd_[indexMap_[i]+1])
-             && (nZoomBegin_[indexMap_[i]+1] <= ((*infoIndex_[indexMap_[i]+1])(localIndex))))
+          tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(localIndex) + ((infoIndex_[indexMap_[i]+1])(localIndex))*nGlob_[indexMap_[i]];
+          if ((((infoIndex_[indexMap_[i]])(localIndex)) <= nZoomEnd_[indexMap_[i]])
+             && (nZoomBegin_[indexMap_[i]] <= ((infoIndex_[indexMap_[i]])(localIndex)))
+             && (((infoIndex_[indexMap_[i]+1])(localIndex)) <= nZoomEnd_[indexMap_[i]+1])
+             && (nZoomBegin_[indexMap_[i]+1] <= ((infoIndex_[indexMap_[i]+1])(localIndex))))
           {
             tmpZoomMaskElement(count) = true;
@@ -309,5 +334,5 @@
   for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
   {
-    if (!axisDomainOrder_(i))
+    if (1 == axisDomainOrder_(i))
     {
       elementIndexData_[i].resize(dataNIndex_[i]);
@@ -316,5 +341,5 @@
       for (int j = 0; j < dataNIndex_[i]; ++j)
       {
-        iIdx = getAxisIndex((*dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
+        iIdx = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
         if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
            (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))
@@ -338,8 +363,8 @@
         if (tmpIndexElementData(j))
         {
-          iIdx = tmpLocalElementIndex(count) = getAxisIndex((*dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
-          tmpGlobalElementIndex(count) = (*infoIndex_[indexMap_[i]])(iIdx);
-          if ((((*infoIndex_[indexMap_[i]])(iIdx)) <= nZoomEnd_[indexMap_[i]])
-             && (nZoomBegin_[indexMap_[i]] <= ((*infoIndex_[indexMap_[i]])(iIdx))))
+          iIdx = tmpLocalElementIndex(count) = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
+          tmpGlobalElementIndex(count) = (infoIndex_[indexMap_[i]])(iIdx);
+          if ((((infoIndex_[indexMap_[i]])(iIdx)) <= nZoomEnd_[indexMap_[i]])
+             && (nZoomBegin_[indexMap_[i]] <= ((infoIndex_[indexMap_[i]])(iIdx))))
           {
             tmpZoomMaskElement(count) = true;
@@ -349,4 +374,28 @@
       }
       ++idxAxis;
+    }
+  }
+}
+
+/*!
+  Create local index of scalar.
+*/
+void CDistributionClient::createLocalScalarDataIndex()
+{
+  int idxAxis = 0;
+  for (int i = 0; i < axisDomainOrder_.numElements(); ++i)
+  {
+    if (0 == axisDomainOrder_(i))
+    {
+      elementIndexData_[i].resize(dataNIndex_[i]);
+      elementIndexData_[i] = true;
+      int count = 1;
+
+      elementLocalIndex_[i].resize(count);
+      elementLocalIndex_[i] = 0;
+      elementGlobalIndex_[i].resize(count);
+      elementGlobalIndex_[i] = 0;
+      elementZoomMask_[i].resize(count);
+      elementZoomMask_[i] = true;
     }
   }
@@ -530,53 +579,52 @@
 void CDistributionClient::createGlobalIndex()
 {
-  size_t ssize = 1, idx = 0;
-  for (int i = 0; i < this->dims_; ++i)
-  ssize *= nLocal_[i];
-
-  this->globalIndex_.resize(ssize);
-  std::vector<int> idxLoop(this->numElement_,0);
-  int innnerLoopSize = (*infoIndex_[0]).numElements();
-  while (idx < ssize)
-  {
-    for (int i = 0; i < this->numElement_; ++i)
-    {
-      if (idxLoop[i] == (*infoIndex_[indexMap_[i]]).numElements())
-      {
-        idxLoop[i] = 0;
-        ++idxLoop[i+1];
-      }
-    }
-
-    for (int i = 0; i < innnerLoopSize; ++i)
-    {
-      size_t globalIndex = (*infoIndex_[0])(idxLoop[0]);
-      size_t mulDim = 1;
-      for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
-      {
-        if (axisDomainOrder_(idxElement))
-        {
-          int jb = (0 == idxElement) ? 1 : 0;
-          for (int j = jb; j <= 1; ++j)
-          {
-            mulDim *= nGlob_[indexMap_[idxElement]+j-1];
-            globalIndex += ((*infoIndex_[indexMap_[idxElement]+j])(idxLoop[idxElement]))*mulDim;
-          }
-        }
-        else
-        {
-          if (0 != idxElement)
-          {
-            mulDim *= nGlob_[indexMap_[idxElement]-1];
-            globalIndex += ((*infoIndex_[indexMap_[idxElement]])(idxLoop[idxElement]))*mulDim;
-          }
-        }
-      }
-
-      this->globalIndex_(idx) = globalIndex;
-      ++idxLoop[0];
-      ++idx;
-    }
-  }
-
+//  size_t ssize = 1, idx = 0;
+//  for (int i = 0; i < this->dims_; ++i)
+//  ssize *= nLocal_[i];
+//
+//  this->globalIndex_.resize(ssize);
+//  std::vector<int> idxLoop(this->numElement_,0);
+//  int innnerLoopSize = (infoIndex_[0]).numElements();
+//  while (idx < ssize)
+//  {
+//    for (int i = 0; i < this->numElement_; ++i)
+////    {
+//      if (idxLoop[i] == (infoIndex_[indexMap_[i]]).numElements())
+//      {
+//        idxLoop[i] = 0;
+//        ++idxLoop[i+1];
+//      }
+//    }
+//
+//    for (int i = 0; i < innnerLoopSize; ++i)
+//    {
+//      size_t globalIndex = (infoIndex_[0])(idxLoop[0]);
+//      size_t mulDim = 1;
+//      for (int idxElement = 0; idxElement < this->numElement_; ++idxElement)
+//      {
+//        if (axisDomainOrder_(idxElement))
+//        {
+//          int jb = (0 == idxElement) ? 1 : 0;
+//          for (int j = jb; j <= 1; ++j)
+//          {
+//            mulDim *= nGlob_[indexMap_[idxElement]+j-1];
+//            globalIndex += ((infoIndex_[indexMap_[idxElement]+j])(idxLoop[idxElement]))*mulDim;
+//          }
+//        }
+//        else
+//        {
+//          if (0 != idxElement)
+//          {
+//            mulDim *= nGlob_[indexMap_[idxElement]-1];
+//            globalIndex += ((infoIndex_[indexMap_[idxElement]])(idxLoop[idxElement]))*mulDim;
+//          }
+//        }
+//      }
+//
+//      this->globalIndex_(idx) = globalIndex;
+//      ++idxLoop[0];
+//      ++idx;
+//    }
+//  }
 }
 
Index: /XIOS/trunk/src/distribution_client.hpp
===================================================================
--- /XIOS/trunk/src/distribution_client.hpp	(revision 886)
+++ /XIOS/trunk/src/distribution_client.hpp	(revision 887)
@@ -21,4 +21,5 @@
 class CDomain;
 class CAxis;
+class CScalar;
 
 /*!
@@ -61,5 +62,6 @@
     void readDistributionInfo(const std::vector<CDomain*>& domList,
                               const std::vector<CAxis*>& axisList,
-                              const CArray<bool,1>& axisDomainOrder);
+                              const std::vector<CScalar*>& scalarList,
+                              const CArray<int,1>& axisDomainOrder);
   private:
     //! Create local index of a domain
@@ -68,4 +70,7 @@
     //! Create local index of an axis
     void createLocalAxisDataIndex();
+
+    //! Create local index of a scalar
+    void createLocalScalarDataIndex();
 
     template<int N>
@@ -82,5 +87,5 @@
      * A grid composed of 1 domain and 1 axis has 2 elements */
     int numElement_;
-    CArray<bool,1> axisDomainOrder_; //!< Order of axis and domain of a grid
+    CArray<int,1> axisDomainOrder_; //!< Order of axis and domain of a grid
 
     std::vector<int> nLocal_; //!< Local size of each dimension (ni, nj, etc, ...)
@@ -95,6 +100,6 @@
     std::vector<int> dataDims_; //!< Data_dim, domain can have data_dim == 1 or 2
     std::vector<int> dataBegin_; //!< Data begin (data_ibegin, data_jbegin, etc)
-    std::vector<CArray<int,1>* > dataIndex_; //!< Data index
-    std::vector<CArray<int,1>* > infoIndex_; //!< i_index, j_index
+    std::vector<CArray<int,1> > dataIndex_; //!< Data index
+    std::vector<CArray<int,1> > infoIndex_; //!< i_index, j_index
 
     std::vector<CArray<bool,1> > domainMasks_; //!< Domain mask
Index: /XIOS/trunk/src/group_factory_decl.cpp
===================================================================
--- /XIOS/trunk/src/group_factory_decl.cpp	(revision 886)
+++ /XIOS/trunk/src/group_factory_decl.cpp	(revision 887)
@@ -31,3 +31,4 @@
   macro(CInterpolateDomainGroup)
   macro(CGenerateRectilinearDomainGroup)
+  macro(CScalarGroup)
 }
Index: /XIOS/trunk/src/group_template_decl.cpp
===================================================================
--- /XIOS/trunk/src/group_template_decl.cpp	(revision 886)
+++ /XIOS/trunk/src/group_template_decl.cpp	(revision 887)
@@ -20,4 +20,5 @@
   macro(InterpolateDomain)
   macro(GenerateRectilinearDomain)
+  macro(Scalar)
 
 }
Index: /XIOS/trunk/src/io/nc4_data_input.cpp
===================================================================
--- /XIOS/trunk/src/io/nc4_data_input.cpp	(revision 886)
+++ /XIOS/trunk/src/io/nc4_data_input.cpp	(revision 887)
@@ -82,5 +82,5 @@
         std::vector<StdSize> start, count;
 
-        CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
+        CArray<int,1> axisDomainOrder = grid->axis_domain_order;
         std::vector<StdString> domainList = grid->getDomainList();
         std::vector<StdString> axisList   = grid->getAxisList();
@@ -94,5 +94,5 @@
         for (int i = numElement - 1; i >= 0; --i)
         {
-          if (axisDomainOrder(i))
+          if (2 == axisDomainOrder(i))
           {
             CDomain* domain = CDomain::get(domainList[idxDomain]);
@@ -108,5 +108,5 @@
             --idxDomain;
           }
-          else
+          else if (1 == axisDomainOrder(i))
           {
             start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
@@ -173,5 +173,5 @@
 
     // Now process domain and axis
-    CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
+    CArray<int,1> axisDomainOrder = grid->axis_domain_order;
     int numElement = domainP.size() + axisP.size();
     int elementPosition = 0;
@@ -181,5 +181,5 @@
     for (int i = 0; i < numElement; ++i)
     {
-      if(axisDomainOrder(i))
+      if(2 == axisDomainOrder(i))
       {
         if (readAttributeValues)
@@ -197,5 +197,5 @@
         else elementPosition += 2;
       }
-      else
+      else if (1 == axisDomainOrder(i))
       {
         if (readAttributeValues)
Index: /XIOS/trunk/src/io/nc4_data_output.cpp
===================================================================
--- /XIOS/trunk/src/io/nc4_data_output.cpp	(revision 886)
+++ /XIOS/trunk/src/io/nc4_data_output.cpp	(revision 887)
@@ -1014,4 +1014,81 @@
      }
 
+      void CNc4DataOutput::writeScalar_(CScalar* scalar)
+      {
+        if (scalar->IsWritten(this->filename)) return;
+        scalar->checkAttributes();
+        int scalarSize = 1;
+
+        StdString scalaId = scalar->getScalarOutputName();
+        if (isWrittenAxis(scalaId)) return ;
+        else setWrittenAxis(scalaId);
+
+        try
+        {
+          if (!scalar->value.isEmpty())
+          {
+//            dims.push_back(scalaId);
+            std::vector<StdString> dims;
+            SuperClassWriter::addVariable(scalaId, NC_FLOAT, dims);
+
+            if (!scalar->name.isEmpty())
+              SuperClassWriter::addAttribute("name", scalar->name.getValue(), &scalaId);
+
+            if (!scalar->standard_name.isEmpty())
+              SuperClassWriter::addAttribute("standard_name", scalar->standard_name.getValue(), &scalaId);
+
+            if (!scalar->long_name.isEmpty())
+              SuperClassWriter::addAttribute("long_name", scalar->long_name.getValue(), &scalaId);
+
+            if (!scalar->unit.isEmpty())
+              SuperClassWriter::addAttribute("units", scalar->unit.getValue(), &scalaId);
+
+            SuperClassWriter::definition_end();
+
+            switch (SuperClass::type)
+            {
+              case MULTI_FILE:
+              {
+                CArray<double,1> scalarValue(scalarSize);
+                scalarValue(0) = scalar->value;
+                SuperClassWriter::writeData(scalarValue, scalaId, isCollective, 0);
+                SuperClassWriter::definition_start();
+
+                break;
+              }
+              case ONE_FILE:
+              {
+                CArray<double,1> scalarValue(scalarSize);
+                scalarValue(0) = scalar->value;
+
+                std::vector<StdSize> start(1);
+                std::vector<StdSize> count(1);
+                start[0] = 0;
+                count[0] = 1;
+                SuperClassWriter::writeData(scalarValue, scalaId, isCollective, 0, &start, &count);
+                SuperClassWriter::definition_start();
+
+                break;
+              }
+              default :
+                ERROR("CNc4DataOutput::writeAxis_(CAxis* scalar)",
+                      << "[ type = " << SuperClass::type << "]"
+                      << " not implemented yet !");
+            }
+          }
+        }
+        catch (CNetCdfException& e)
+        {
+          StdString msg("On writing the scalar : ");
+          msg.append(scalaId); msg.append("\n");
+          msg.append("In the context : ");
+          CContext* context = CContext::getCurrent() ;
+          msg.append(context->getId()); msg.append("\n");
+          msg.append(e.what());
+          ERROR("CNc4DataOutput::writeScalar_(CScalar* scalar)", << msg);
+        }
+        scalar->addRelFile(this->filename);
+     }
+
      //--------------------------------------------------------------
 
@@ -1022,8 +1099,9 @@
        try
        {
-         CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
+         CArray<int,1> axisDomainOrder = grid->axis_domain_order;
          std::vector<StdString> domainList = grid->getDomainList();
          std::vector<StdString> axisList   = grid->getAxisList();
-         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0;
+         std::vector<StdString> scalarList = grid->getScalarList();
+         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0, idxScalar = 0;
 
          std::vector<StdString> dims;
@@ -1042,5 +1120,5 @@
            for (int i = numElement - 1; i >= 0; --i)
            {
-             if (axisDomainOrder(i))
+             if (2 == axisDomainOrder(i))
              {
                CDomain* domain = CDomain::get(domainList[domainList.size() - idxDomain - 1]);
@@ -1062,9 +1140,15 @@
                ++idxDomain;
              }
-             else
+             else if (1 == axisDomainOrder(i))
              {
                CAxis* axis = CAxis::get(axisList[axisList.size() - idxAxis - 1]);
                compress << axis->getAxisOutputName();
                ++idxAxis;
+             }
+             else
+             {
+               CScalar* scalar = CScalar::get(scalarList[scalarList.size() - idxScalar - 1]);
+               compress << scalar->getScalarOutputName();
+               ++idxScalar;
              }
 
@@ -1115,5 +1199,5 @@
              int firstGlobalIndex;
 
-             if (axisDomainOrder(i))
+             if (2 == axisDomainOrder(i))
              {
                CDomain* domain = CDomain::get(domainList[idxDomain]);
@@ -1154,5 +1238,5 @@
                ++idxDomain;
              }
-             else
+             else if (1 == axisDomainOrder(i))
              {
                CAxis* axis = CAxis::get(axisList[idxAxis]);
@@ -1181,4 +1265,7 @@
                setWrittenCompressedAxis(axisId);
                ++idxAxis;
+             }
+             else
+             {
              }
 
@@ -1263,8 +1350,9 @@
           if (SuperClass::type==MULTI_FILE) return ;
 
-         CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
-         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0;
+         CArray<int,1> axisDomainOrder = grid->axis_domain_order;
+         int numElement = axisDomainOrder.numElements(), idxDomain = 0, idxAxis = 0, idxScalar = 0;
          std::vector<StdString> domainList = grid->getDomainList();
          std::vector<StdString> axisList   = grid->getAxisList();
+         std::vector<StdString> scalarList = grid->getScalarList();
 
          StdString timeid  = getTimeCounterName();
@@ -1277,5 +1365,5 @@
          for (int i = 0; i < numElement; ++i)
          {
-           if (axisDomainOrder(i))
+           if (2 == axisDomainOrder(i))
            {
              CDomain* domain = CDomain::get(domainList[idxDomain]);
@@ -1355,5 +1443,5 @@
              ++idxDomain;
            }
-           else
+           else if (1 == axisDomainOrder(i))
            {
              CAxis* axis = CAxis::get(axisList[idxAxis]);
@@ -1370,4 +1458,8 @@
              dimCoordList.push_back(axisId);
              ++idxAxis;
+           }
+           else // scalar
+           {
+             /* Do nothing here */
            }
          }
@@ -1382,8 +1474,4 @@
 */
          StdString fieldid = field->getFieldOutputName();
-
-//         unsigned int ssize = domain->zoom_ni_loc.getValue() * domain->zoom_nj_loc.getValue();
-//         bool isCurvilinear = (domain->lonvalue.getValue()->size() == ssize);
-//          bool isCurvilinear = domain->isCurvilinear ;
 
          nc_type type ;
@@ -1839,5 +1927,5 @@
                   else
                   {
-                    CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
+                    CArray<int,1> axisDomainOrder = grid->axis_domain_order;
                     std::vector<StdString> domainList = grid->getDomainList();
                     std::vector<StdString> axisList   = grid->getAxisList();
@@ -1852,5 +1940,5 @@
                     for (int i = numElement - 1; i >= 0; --i)
                     {
-                      if (axisDomainOrder(i))
+                      if (2 == axisDomainOrder(i))
                       {
                         CDomain* domain = CDomain::get(domainList[idxDomain]);
@@ -1876,5 +1964,5 @@
                         --idxDomain;
                       }
-                      else
+                      else if (1 == axisDomainOrder(i))
                       {
                         CAxis* axis = CAxis::get(axisList[idxAxis]);
@@ -1900,5 +1988,5 @@
                 {
 
-                  CArray<bool,1> axisDomainOrder = grid->axis_domain_order;
+                  CArray<int,1> axisDomainOrder = grid->axis_domain_order;
                   std::vector<StdString> domainList = grid->getDomainList();
                   std::vector<StdString> axisList   = grid->getAxisList();
@@ -1912,5 +2000,5 @@
                   for (int i = numElement - 1; i >= 0; --i)
                   {
-                    if (axisDomainOrder(i))
+                    if (2 == axisDomainOrder(i))
                     {
                       CDomain* domain = CDomain::get(domainList[idxDomain]);
@@ -1926,10 +2014,19 @@
                       --idxDomain;
                     }
-                    else
+                    else if (1 == axisDomainOrder(i))
                     {
                       start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
                       count.push_back(nZoomSizeServer[idx]);
                       --idx;
-                     }
+                    }
+                    else
+                    {
+                      if (1 == axisDomainOrder.numElements())
+                      {
+                        start.push_back(0);
+                        count.push_back(1);
+                      }
+                      --idx;
+                    }
                   }
                 }
@@ -2322,4 +2419,9 @@
       }
 
+      bool CNc4DataOutput::isWrittenScalar(const std::string& scalarName) const
+      {
+        return (this->writtenScalar.find(scalarName) != this->writtenScalar.end());
+      }
+
       void CNc4DataOutput::setWrittenDomain(const std::string& domainName)
       {
@@ -2341,3 +2443,8 @@
         this->writtenCompressedAxis.insert(axisName);
       }
+
+      void CNc4DataOutput::setWrittenScalar(const std::string& scalarName)
+      {
+        this->writtenScalar.insert(scalarName);
+      }
 } // namespace xios
Index: /XIOS/trunk/src/io/nc4_data_output.hpp
===================================================================
--- /XIOS/trunk/src/io/nc4_data_output.hpp	(revision 886)
+++ /XIOS/trunk/src/io/nc4_data_output.hpp	(revision 887)
@@ -49,4 +49,5 @@
             virtual void writeDomain_   (CDomain* domain);
             virtual void writeAxis_     (CAxis* axis);
+            virtual void writeScalar_   (CScalar* scalar);
             virtual void writeGridCompressed_(CGrid* grid);
             virtual void writeTimeDimension_(void);
@@ -106,4 +107,5 @@
             bool isWrittenAxis(const std::string& axisName) const;
             bool isWrittenCompressedAxis(const std::string& axisName) const;
+            bool isWrittenScalar(const std::string& scalarName) const;
 
             void setWrittenDomain(const std::string& domainName);
@@ -111,4 +113,5 @@
             void setWrittenAxis(const std::string& axisName);
             void setWrittenCompressedAxis(const std::string& axisName);
+            void setWrittenScalar(const std::string& scalarName);
 
             /// PropriÃ©tÃ©s privÃ©es ///
@@ -119,4 +122,5 @@
             std::set<std::string> writtenDomains, writtenCompressedDomains;
             std::set<std::string> writtenAxis, writtenCompressedAxis;
+            std::set<std::string> writtenScalar;
       }; // class CNc4DataOutput
 
Index: /XIOS/trunk/src/node/context.cpp
===================================================================
--- /XIOS/trunk/src/node/context.cpp	(revision 886)
+++ /XIOS/trunk/src/node/context.cpp	(revision 887)
@@ -1027,4 +1027,5 @@
        CGrid::get(*it)->sendAllDomains();
        CGrid::get(*it)->sendAllAxis();
+       CGrid::get(*it)->sendAllScalars();
      }
    }
@@ -1034,6 +1035,5 @@
    void CContext::sendRefDomainsAxis()
    {
-     std::set<StdString> domainIds;
-     std::set<StdString> axisIds;
+     std::set<StdString> domainIds, axisIds, scalarIds;
 
      // Find all reference domain and axis of all active fields
@@ -1045,13 +1045,26 @@
        for (int j = 0; j < numEnabledFields; ++j)
        {
-         const std::pair<StdString, StdString>& prDomAxisId = enabledFields[j]->getRefDomainAxisIds();
-         if ("" != prDomAxisId.first) domainIds.insert(prDomAxisId.first);
-         if ("" != prDomAxisId.second) axisIds.insert(prDomAxisId.second);
+         const std::vector<StdString>& prDomAxisScalarId = enabledFields[j]->getRefDomainAxisIds();
+         if ("" != prDomAxisScalarId[0]) domainIds.insert(prDomAxisScalarId[0]);
+         if ("" != prDomAxisScalarId[1]) axisIds.insert(prDomAxisScalarId[1]);
+         if ("" != prDomAxisScalarId[2]) scalarIds.insert(prDomAxisScalarId[2]);
        }
      }
 
      // Create all reference axis on server side
-     std::set<StdString>::iterator itDom, itAxis;
+     std::set<StdString>::iterator itDom, itAxis, itScalar;
      std::set<StdString>::const_iterator itE;
+
+     StdString scalarDefRoot("scalar_definition");
+     CScalarGroup* scalarPtr = CScalarGroup::get(scalarDefRoot);
+     itE = scalarIds.end();
+     for (itScalar = scalarIds.begin(); itScalar != itE; ++itScalar)
+     {
+       if (!itScalar->empty())
+       {
+         scalarPtr->sendCreateChild(*itScalar);
+         CScalar::get(*itScalar)->sendAllAttributesToServer();
+       }
+     }
 
      StdString axiDefRoot("axis_definition");
Index: /XIOS/trunk/src/node/field.cpp
===================================================================
--- /XIOS/trunk/src/node/field.cpp	(revision 886)
+++ /XIOS/trunk/src/node/field.cpp	(revision 887)
@@ -34,5 +34,5 @@
       , nstep(0), nstepMax(0)
       , hasOutputFile(false)
-      , domAxisIds_("", ""), areAllReferenceSolved(false), isReferenceSolved(false)
+      , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false)
       , useCompressedOutput(false)
       , isReadDataRequestPending(false)
@@ -45,5 +45,5 @@
       , nstep(0), nstepMax(0)
       , hasOutputFile(false)
-      , domAxisIds_("", ""), areAllReferenceSolved(false), isReferenceSolved(false)
+      , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false)
       , useCompressedOutput(false)
       , isReadDataRequestPending(false)
@@ -889,14 +889,14 @@
    void CField::solveGridReference(void)
    {
-      if (grid_ref.isEmpty() && domain_ref.isEmpty() && axis_ref.isEmpty())
+      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()))
+      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." << std::endl
-              << "Please define either 'grid_ref' or 'domain_ref'/'axis_ref'.");
+              << "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'.");
       }
 
@@ -905,4 +905,5 @@
         std::vector<CDomain*> vecDom;
         std::vector<CAxis*> vecAxis;
+        std::vector<CScalar*> vecScalar;
 
         if (!domain_ref.isEmpty())
@@ -925,10 +926,19 @@
         }
 
+        if (!scalar_ref.isEmpty())
+        {
+          if (CScalar::has(scalar_ref))
+            vecScalar.push_back(CScalar::get(scalar_ref));
+          else
+            ERROR("CField::solveGridReference(void)",
+                  << "Invalid reference to scalar '" << scalar_ref.getValue() << "'.");
+        }
+
         // Warning: the gridId shouldn't be set as the grid_ref since it could be inherited
-        StdString gridId = CGrid::generateId(vecDom, vecAxis);
+        StdString gridId = CGrid::generateId(vecDom, vecAxis, vecScalar);
         if (CGrid::has(gridId))
           this->grid = CGrid::get(gridId);
         else
-          this->grid = CGrid::createGrid(gridId, vecDom, vecAxis);
+          this->grid = CGrid::createGrid(gridId, vecDom, vecAxis, vecScalar);
       }
       else
@@ -1138,5 +1148,5 @@
    \return pair of Domain and Axis id
    */
-   const std::pair<StdString,StdString>& CField::getRefDomainAxisIds()
+   const std::vector<StdString>& CField::getRefDomainAxisIds()
    {
      CGrid* cgPtr = getRelGrid();
@@ -1148,5 +1158,5 @@
          std::vector<StdString> domainList = cgPtr->getDomainList();
          it = std::find(domainList.begin(), domainList.end(), domain_ref.getValue());
-         if (domainList.end() != it) domAxisIds_.first = *it;
+         if (domainList.end() != it) domAxisScalarIds_[0] = *it;
        }
 
@@ -1155,8 +1165,15 @@
          std::vector<StdString> axisList = cgPtr->getAxisList();
          it = std::find(axisList.begin(), axisList.end(), axis_ref.getValue());
-         if (axisList.end() != it) domAxisIds_.second = *it;
-       }
-     }
-     return (domAxisIds_);
+         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_);
    }
 
Index: /XIOS/trunk/src/node/field.hpp
===================================================================
--- /XIOS/trunk/src/node/field.hpp	(revision 886)
+++ /XIOS/trunk/src/node/field.hpp	(revision 887)
@@ -177,5 +177,5 @@
 
 
-        const std::pair<StdString, StdString>& getRefDomainAxisIds();
+        const std::vector<StdString>& getRefDomainAxisIds();
 
       public:
@@ -201,5 +201,5 @@
          bool areAllReferenceSolved;
          bool isReferenceSolved;
-         std::pair<StdString,StdString> domAxisIds_;
+         std::vector<StdString> domAxisScalarIds_;
          bool isReadDataRequestPending;
          bool useCompressedOutput;
Index: /XIOS/trunk/src/node/grid.cpp
===================================================================
--- /XIOS/trunk/src/node/grid.cpp	(revision 886)
+++ /XIOS/trunk/src/node/grid.cpp	(revision 887)
@@ -26,5 +26,7 @@
       : CObjectTemplate<CGrid>(), CGridAttributes()
       , isChecked(false), isDomainAxisChecked(false)
-      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false)
+      , vDomainGroup_(), domList_(), isDomListSet(false)
+      , vAxisGroup_(), axisList_(), isAxisListSet(false)
+      , vScalarGroup_(), scalarList_(), isScalarListSet(false)
       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
@@ -36,4 +38,5 @@
      setVirtualDomainGroup();
      setVirtualAxisGroup();
+     setVirtualScalarGroup();
    }
 
@@ -41,5 +44,7 @@
       : CObjectTemplate<CGrid>(id), CGridAttributes()
       , isChecked(false), isDomainAxisChecked(false)
-      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false)
+      , vDomainGroup_(), domList_(), isDomListSet(false)
+      , vAxisGroup_(), axisList_(), isAxisListSet(false)
+      , vScalarGroup_(), scalarList_(), isScalarListSet(false)
       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
@@ -51,4 +56,5 @@
      setVirtualDomainGroup();
      setVirtualAxisGroup();
+     setVirtualScalarGroup();
    }
 
@@ -201,7 +207,8 @@
      if (this->isDomainAxisChecked) return;
 
+     this->solveScalarRef(areAttributesChecked);
      this->solveAxisRef(areAttributesChecked);
      this->solveDomainRef(areAttributesChecked);
-     computeGridGlobalDimension(getDomains(), getAxis(), axis_domain_order);
+     computeGridGlobalDimension(getDomains(), getAxis(), getScalars(), axis_domain_order);
      this->isDomainAxisChecked = areAttributesChecked;
    }
@@ -210,4 +217,11 @@
    {
      if (this->hasDomainAxisBaseRef_) return;
+     // Account for the scalar attributes
+     std::vector<CScalar*> scalarList = getScalars();
+     for (size_t i = 0; i < scalarList.size(); ++i)
+     {
+       scalarList[i]->setAttributesReference();
+     }
+
      // Account for the axis attributes
      std::vector<CAxis*> axisList = getAxis();
@@ -223,4 +237,5 @@
        domList[i]->setAttributesReference();
      }
+
      this->hasDomainAxisBaseRef_ = true;
    }
@@ -383,10 +398,11 @@
         for (int i = 0; i < axis_domain_order.numElements(); ++i)
         {
-          if (false == axis_domain_order(i))
+          int elementDimension = axis_domain_order(i);
+          if (1 == elementDimension)
           {
             axisPositionInGrid_.push_back(idx);
             ++idx;
           }
-          else idx += 2;
+          else if (2 == elementDimension) idx += 2;
         }
 
@@ -397,5 +413,21 @@
           else
             axisListP[i]->checkAttributesOnClient();
-          ++idx;
+        }
+      }
+   }
+
+   //---------------------------------------------------------------
+
+   void CGrid::solveScalarRef(bool sendAtt)
+   {
+      setScalarList();
+      std::vector<CScalar*> scalarListP = this->getScalars();
+      if (!scalarListP.empty())
+      {
+        for (int i = 0; i < scalarListP.size(); ++i)
+        {
+          /*Nothing to do for now */
+//          if (sendAtt) scalarListP[i]->sendCheckedAttributes();
+//          else scalarListP[i]->checkAttributesOnClient();
         }
       }
@@ -502,5 +534,5 @@
      int nbElement = axis_domain_order.numElements();
      std::vector<CArray<size_t,1> > globalIndexElement(nbElement);
-     int domainIdx = 0, axisIdx = 0;
+     int domainIdx = 0, axisIdx = 0, scalarIdx = 0;
      std::vector<size_t> elementNGlobal(nbElement);
      elementNGlobal[0] = 1;
@@ -511,5 +543,5 @@
        size_t elementSize;
        size_t elementGlobalSize = 1;
-       if (axis_domain_order(idx))
+       if (2 == axis_domain_order(idx))
        {
          elementSize = domList[domainIdx]->i_index.numElements();
@@ -522,5 +554,5 @@
          ++domainIdx;
        }
-       else
+       else if (1 == axis_domain_order(idx))
        {
          elementSize = axisList[axisIdx]->index.numElements();
@@ -532,4 +564,10 @@
          elementGlobalSize = axisList[axisIdx]->n_glo.getValue();
          ++axisIdx;
+       }
+       else
+       {
+         globalIndexElement[idx].resize(1);
+         globalIndexElement[idx](0) = 0;
+         elementGlobalSize = 1;
        }
        globalSize *= elementGlobalSize;
@@ -657,13 +695,54 @@
 
    CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                            const CArray<bool,1>& axisDomainOrder)
-   {
-      return createGrid(generateId(domains, axis, axisDomainOrder), domains, axis, axisDomainOrder);
-   }
+                            const CArray<int,1>& axisDomainOrder)
+   {
+     std::vector<CScalar*> vecScalar;
+     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder);
+   }
+
+   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
+   {
+     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder);
+   }
+
+//   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+//                            const CArray<int,1>& axisDomainOrder)
+//   {
+//      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size()))
+//        ERROR("CGrid* CGrid::createGrid(...)",
+//              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
+//              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
+//
+//      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id);
+//      grid->setDomainList(domains);
+//      grid->setAxisList(axis);
+//
+//      // By default, domains are always the first elements of a grid
+//      if (0 == axisDomainOrder.numElements())
+//      {
+//        int size = domains.size() + axis.size();
+//        grid->axis_domain_order.resize(size);
+//        for (int i = 0; i < size; ++i)
+//        {
+//          if (i < domains.size()) grid->axis_domain_order(i) = 2;
+//          else grid->axis_domain_order(i) = 1;
+//        }
+//      }
+//      else
+//      {
+//        grid->axis_domain_order.resize(axisDomainOrder.numElements());
+//        grid->axis_domain_order = axisDomainOrder;
+//      }
+//
+//      grid->solveDomainAxisRefInheritance(true);
+//
+//      return grid;
+//   }
 
    CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                            const CArray<bool,1>& axisDomainOrder)
-   {
-      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size()))
+                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
+   {
+      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
         ERROR("CGrid* CGrid::createGrid(...)",
               << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
@@ -673,14 +752,24 @@
       grid->setDomainList(domains);
       grid->setAxisList(axis);
+      grid->setScalarList(scalars);
 
       // By default, domains are always the first elements of a grid
       if (0 == axisDomainOrder.numElements())
       {
-        int size = domains.size() + axis.size();
+        int size = domains.size() + axis.size() + scalars.size();
+        int nb = 0;
         grid->axis_domain_order.resize(size);
         for (int i = 0; i < size; ++i)
         {
-          if (i < domains.size()) grid->axis_domain_order(i) = true;
-          else grid->axis_domain_order(i) = false;
+          if (i < domains.size()) {
+            grid->axis_domain_order(i) = 2;
+
+          }
+          else if ((scalars.size() < (size-nb)) < size) {
+            grid->axis_domain_order(i) = 1;
+          }
+          else
+            grid->axis_domain_order(i) = 0;
+          ++nb;
         }
       }
@@ -698,6 +787,18 @@
    CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc)
    {
+     std::vector<CDomain*> domainSrcTmp = gridSrc->getDomains(), domainSrc;
      std::vector<CAxis*> axisSrcTmp = gridSrc->getAxis(), axisSrc;
-     std::vector<CDomain*> domainSrcTmp = gridSrc->getDomains(), domainSrc;
+     std::vector<CScalar*> scalarSrcTmp = gridSrc->getScalars(), scalarSrc;
+
+     for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
+     {
+       CDomain* domain = CDomain::createDomain();
+       domain->duplicateAttributes(domainSrcTmp[idx]);
+       domain->duplicateTransformation(domainSrcTmp[idx]);
+       domain->solveRefInheritance(true);
+       domain->solveInheritanceTransformation();
+       domainSrc.push_back(domain);
+     }
+
      for (int idx = 0; idx < axisSrcTmp.size(); ++idx)
      {
@@ -710,15 +811,15 @@
      }
 
-     for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
+     for (int idx = 0; idx < scalarSrcTmp.size(); ++idx)
      {
-       CDomain* domain = CDomain::createDomain();
-       domain->duplicateAttributes(domainSrcTmp[idx]);
-       domain->duplicateTransformation(domainSrcTmp[idx]);
-       domain->solveRefInheritance(true);
-       domain->solveInheritanceTransformation();
-       domainSrc.push_back(domain);
-     }
-
-      CGrid* grid = CGrid::createGrid(idNewGrid, domainSrc, axisSrc, gridSrc->axis_domain_order);
+       CScalar* scalar = CScalar::createScalar();
+       scalar->duplicateAttributes(scalarSrcTmp[idx]);
+       scalar->duplicateTransformation(scalarSrcTmp[idx]);
+       scalar->solveRefInheritance(true);
+       scalar->solveInheritanceTransformation();
+       scalarSrc.push_back(scalar);
+     }
+
+      CGrid* grid = CGrid::createGrid(idNewGrid, domainSrc, axisSrc, scalarSrc, gridSrc->axis_domain_order);
 
       return grid;
@@ -726,7 +827,7 @@
 
    StdString CGrid::generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                               const CArray<bool,1>& axisDomainOrder)
-   {
-      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size()))
+                               const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
+   {
+      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
         ERROR("CGrid* CGrid::generateId(...)",
               << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
@@ -735,7 +836,8 @@
       std::ostringstream id;
 
-      if (domains.empty() && axis.empty())
-        id << "__scalar_grid__";
-      else
+      if (domains.empty() && axis.empty() && !scalars.empty())
+        id << "__scalar_";
+
+      if (0 != (domains.size() + axis.size() + scalars.size()))
       {
         id << "__grid";
@@ -745,14 +847,17 @@
           for (size_t i = 0; i < domains.size(); ++i) id << "_" << domains[i]->getId();
           for (size_t i = 0; i < axis.size(); ++i) id << "_" << axis[i]->getId();
+          for (size_t i = 0; i < scalars.size(); ++i) id << "_" << scalars[i]->getId();
         }
         else
         {
-          size_t iDomain = 0, iAxis = 0;
+          size_t iDomain = 0, iAxis = 0, iScalar = 0;
           for (size_t i = 0; i < axisDomainOrder.numElements(); ++i)
           {
-            if (axisDomainOrder(i))
+            if (2 == axisDomainOrder(i))
               id << "_" << domains[iDomain++]->getId();
+            else if (1 == axisDomainOrder(i))
+              id << "_" << axis[iAxis++]->getId();
             else
-              id << "_" << axis[iAxis++]->getId();
+              id << "_" << scalars[iScalar++]->getId();
           }
         }
@@ -785,4 +890,9 @@
    {
      return this->vAxisGroup_;
+   }
+
+   CScalarGroup* CGrid::getVirtualScalarGroup() const
+   {
+     return this->vScalarGroup_;
    }
 
@@ -1037,11 +1147,12 @@
   void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains,
                                          const std::vector<CAxis*>& axis,
-                                         const CArray<bool,1>& axisDomainOrder)
-  {
-    globalDim_.resize(domains.size()*2+axis.size());
-    int idx = 0, idxDomain = 0, idxAxis = 0;
+                                         const std::vector<CScalar*>& scalars,
+                                         const CArray<int,1>& axisDomainOrder)
+  {
+    globalDim_.resize(domains.size()*2+axis.size()+scalars.size());
+    int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0;
     for (int i = 0; i < axisDomainOrder.numElements(); ++i)
     {
-      if (axisDomainOrder(i))
+      if (2 == axisDomainOrder(i))
       {
         if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured))
@@ -1060,8 +1171,14 @@
         idx += 2;
       }
-      else
+      else if (1 == axisDomainOrder(i))
       {
         globalDim_[idx] = axis[idxAxis]->n_glo.getValue();
         ++idxAxis;
+        ++idx;
+      }
+      else
+      {
+        globalDim_[idx] = 1;
+        ++idxScalar;
         ++idx;
       }
@@ -1179,5 +1296,5 @@
         {
           indexMap[i] = idx;
-          if (true == axis_domain_order(i))
+          if (2 == axis_domain_order(i))
           {
             ++ssize;
@@ -1188,5 +1305,5 @@
         }
 
-        int axisId = 0, domainId = 0;
+        int axisId = 0, domainId = 0, scalarId = 0;
         std::vector<CDomain*> domainList = getDomains();
         std::vector<CAxis*> axisList = getAxis();
@@ -1194,5 +1311,5 @@
         for (int i = 0; i < numElement; ++i)
         {
-          if (axis_domain_order(i))
+          if (2 == axis_domain_order(i)) //domain
           {
             nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin_srv;
@@ -1207,5 +1324,5 @@
             ++domainId;
           }
-          else
+          else if (1 == axis_domain_order(i)) // axis
           {
             nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
@@ -1214,4 +1331,12 @@
             nGlob[indexMap[i]] = axisList[axisId]->n_glo;
             ++axisId;
+          }
+          else // scalar
+          {
+            nZoomBegin[indexMap[i]] = 0;
+            nZoomSize[indexMap[i]]  = 1;
+            nZoomBeginGlobal[indexMap[i]] = 0;
+            nGlob[indexMap[i]] = 1;
+            ++scalarId;
           }
         }
@@ -1281,4 +1406,9 @@
            return true;
            break;
+
+         case EVENT_ID_ADD_SCALAR :
+           recvAddScalar(event);
+           return true;
+           break;
         default :
           ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
@@ -1293,5 +1423,5 @@
    CDomain* CGrid::addDomain(const std::string& id)
    {
-     order_.push_back(true);
+     order_.push_back(2);
      axis_domain_order.resize(order_.size());
      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
@@ -1301,5 +1431,5 @@
    CAxis* CGrid::addAxis(const std::string& id)
    {
-     order_.push_back(false);
+     order_.push_back(1);
      axis_domain_order.resize(order_.size());
      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
@@ -1307,4 +1437,12 @@
    }
 
+   CScalar* CGrid::addScalar(const std::string& id)
+   {
+     order_.push_back(0);
+     axis_domain_order.resize(order_.size());
+     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
+     return vScalarGroup_->createChild(id);
+   }
+
    //! Change virtual field group to a new one
    void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
@@ -1317,4 +1455,10 @@
    {
       this->vAxisGroup_ = newVAxisGroup;
+   }
+
+   //! Change virtual variable group to new one
+   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup)
+   {
+      this->vScalarGroup_ = newVScalarGroup;
    }
 
@@ -1330,4 +1474,10 @@
    {
       this->setVirtualAxisGroup(CAxisGroup::create());
+   }
+
+   //! Create virtual variable group, which is done normally on initializing file
+   void CGrid::setVirtualScalarGroup(void)
+   {
+      this->setVirtualScalarGroup(CScalarGroup::create());
    }
 
@@ -1387,4 +1537,31 @@
 
    /*!
+   \brief Send a message to create a scalar on server side
+   \param[in] id String identity of scalar that will be created on server
+   */
+   void CGrid::sendAddScalar(const string& id)
+   {
+    CContext* context=CContext::getCurrent();
+
+    if (! context->hasServer )
+    {
+       CContextClient* client=context->client;
+
+       CEventClient event(this->getType(),EVENT_ID_ADD_SCALAR);
+       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);
+    }
+   }
+
+   /*!
    \brief Receive a message annoucing the creation of a domain on server side
    \param[in] event Received event
@@ -1432,4 +1609,28 @@
       buffer >> id;
       addAxis(id);
+   }
+
+   /*!
+   \brief Receive a message annoucing the creation of an scalar on server side
+   \param[in] event Received event
+   */
+   void CGrid::recvAddScalar(CEventServer& event)
+   {
+
+      CBufferIn* buffer = event.subEvents.begin()->buffer;
+      string id;
+      *buffer >> id;
+      get(id)->recvAddScalar(*buffer);
+   }
+
+   /*!
+   \brief Receive a message annoucing the creation of an scalar on server side
+   \param[in] buffer Buffer containing message
+   */
+   void CGrid::recvAddScalar(CBufferIn& buffer)
+   {
+      string id;
+      buffer >> id;
+      addScalar(id);
    }
 
@@ -1468,4 +1669,16 @@
       }
     }
+
+    setScalarList();
+    it = scalarList_.begin(); itE = scalarList_.end();
+    for (; it != itE; ++it)
+    {
+      CScalar* pScalar = CScalar::get(*it);
+      if (context->hasClient)
+      {
+        pScalar->solveRefInheritance(apply);
+        pScalar->solveInheritanceTransformation();
+      }
+    }
   }
 
@@ -1513,10 +1726,10 @@
       else
       {
-        int ssize = axis_domain_order.numElements();
-        for (int i = 0; i < ssize; ++i)
-          if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
-            ERROR("CGrid::completeGrid(CGrid* transformGridSrc)",
-                  << "Grids " << this->getId() << " and " << transformGridSrc->getId()
-                  << " don't have elements in the same order");
+//        int ssize = axis_domain_order.numElements();
+//        for (int i = 0; i < ssize; ++i)
+//          if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
+//            ERROR("CGrid::completeGrid(CGrid* transformGridSrc)",
+//                  << "Grids " << this->getId() << " and " << transformGridSrc->getId()
+//                  << " don't have elements in the same order");
       }
     }
@@ -1543,10 +1756,10 @@
     else
     {
-      int ssize = axis_domain_order.numElements();
-      for (int i = 0; i < ssize; ++i)
-        if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
-          ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
-                << "Grids " << this->getId() << " and " << transformGridSrc->getId()
-                << " don't have elements in the same order");
+//      int ssize = axis_domain_order.numElements();
+//      for (int i = 0; i < ssize; ++i)
+//        if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
+//          ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
+//                << "Grids " << this->getId() << " and " << transformGridSrc->getId()
+//                << " don't have elements in the same order");
     }
 
@@ -1592,4 +1805,17 @@
 
   /*!
+  \brief Get the list of  axis pointers
+  \return list of axis pointers
+  */
+  std::vector<CScalar*> CGrid::getScalars()
+  {
+    std::vector<CScalar*> sList;
+    if (!scalarList_.empty())
+      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i]));
+
+    return sList;
+  }
+
+  /*!
   \brief Set domain(s) of a grid from a list
   \param[in] domains list of domains
@@ -1647,4 +1873,31 @@
 
   /*!
+  \brief Set scalar(s) of a grid from a list
+  \param[in] scalars list of scalars
+  */
+  void CGrid::setScalarList(const std::vector<CScalar*> scalars)
+  {
+    if (isScalarListSet) return;
+    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
+    if (!scalars.empty() && sList.empty())
+    {
+      for (int i = 0; i < scalars.size(); ++i)
+        this->getVirtualScalarGroup()->addChild(scalars[i]);
+      sList = this->getVirtualScalarGroup()->getAllChildren();
+    }
+
+    if (!sList.empty())
+    {
+      int sizeScalar = sList.size();
+      scalarList_.resize(sizeScalar);
+      for (int i = 0; i < sizeScalar; ++i)
+      {
+        scalarList_[i] = sList[i]->getId();
+      }
+      isScalarListSet = true;
+    }
+  }
+
+  /*!
   \brief Get list of id of domains
   \return id list of domains
@@ -1666,4 +1919,17 @@
   }
 
+  /*!
+  \brief Get list of id of scalar
+  \return id list of scalar
+  */
+  std::vector<StdString> CGrid::getScalarList()
+  {
+    setScalarList();
+    return scalarList_;
+  }
+
+  /*!
+    Send all attributes of domains from client to server
+  */
   void CGrid::sendAllDomains()
   {
@@ -1677,4 +1943,7 @@
   }
 
+  /*!
+    Send all attributes of axis from client to server
+  */
   void CGrid::sendAllAxis()
   {
@@ -1689,4 +1958,22 @@
   }
 
+  /*!
+    Send all attributes of scalars from client to server
+  */
+  void CGrid::sendAllScalars()
+  {
+    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
+    int sSize = sList.size();
+
+    for (int i = 0; i < sSize; ++i)
+    {
+      sendAddScalar(sList[i]->getId());
+      sList[i]->sendAllAttributesToServer();
+    }
+  }
+
+  /*!
+    Parse a grid, for now, it contains only domain, axis and scalar
+  */
   void CGrid::parse(xml::CXMLNode& node)
   {
@@ -1697,13 +1984,18 @@
       StdString domainName("domain");
       StdString axisName("axis");
+      StdString scalarName("scalar");
       do
       {
         if (node.getElementName() == domainName) {
-          order_.push_back(true);
+          order_.push_back(2);
           this->getVirtualDomainGroup()->parseChild(node);
         }
         if (node.getElementName() == axisName) {
-          order_.push_back(false);
+          order_.push_back(1);
           this->getVirtualAxisGroup()->parseChild(node);
+        }
+        if (node.getElementName() == scalarName) {
+          order_.push_back(0);
+          this->getVirtualScalarGroup()->parseChild(node);
         }
       } while (node.goToNextElement());
@@ -1723,4 +2015,5 @@
     setDomainList();
     setAxisList();
+    setScalarList();
    }
 } // namespace xios
Index: /XIOS/trunk/src/node/grid.hpp
===================================================================
--- /XIOS/trunk/src/node/grid.hpp	(revision 886)
+++ /XIOS/trunk/src/node/grid.hpp	(revision 887)
@@ -9,4 +9,5 @@
 #include "domain.hpp"
 #include "axis.hpp"
+#include "scalar.hpp"
 #include "array_new.hpp"
 #include "attribute_array.hpp"
@@ -24,4 +25,5 @@
    class CDomainGroup;
    class CAxisGroup;
+   class CScalarGroup;
    class CGrid;
    class CDistributionClient;
@@ -55,10 +57,5 @@
          enum EEventId
          {
-           EVENT_ID_INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS
-         };
-
-         enum EElementType
-         {
-           GRID_ONLY_AXIS, GRID_ONLY_DOMAIN, GRID_AXIS_DOMAIN
+           EVENT_ID_INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS, EVENT_ID_ADD_SCALAR
          };
 
@@ -122,9 +119,15 @@
          static CGrid* createGrid(CDomain* domain, CAxis* axis);
          static CGrid* createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                                  const CArray<bool,1>& axisDomainOrder = CArray<bool,1>());
+                                  const CArray<int,1>& axisDomainOrder = CArray<int,1>());
+//         static CGrid* createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+//                                  const CArray<int,1>& axisDomainOrder = CArray<int,1>());
          static CGrid* createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                                  const CArray<bool,1>& axisDomainOrder = CArray<bool,1>());
+                                  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder = CArray<int,1>());
+         static CGrid* createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+                                  const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder);
+//         static StdString generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
+//                                     const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder = CArray<int,1>());
          static StdString generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
-                                     const CArray<bool,1>& axisDomainOrder = CArray<bool,1>());
+                                     const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder = CArray<int,1>());
          static StdString generateId(const CGrid* gridSrc, const CGrid* gridDest);
          static CGrid* cloneGrid(const StdString& idNewGrid, CGrid* gridSrc);
@@ -144,4 +147,5 @@
          void solveDomainRef(bool checkAtt);
          void solveAxisRef(bool checkAtt);
+         void solveScalarRef(bool checkAtt);
          void solveDomainAxisRefInheritance(bool apply = true);
          void solveTransformations();
@@ -150,8 +154,11 @@
          CDomain* addDomain(const std::string& id=StdString());
          CAxis* addAxis(const std::string& id=StdString());
+         CScalar* addScalar(const std::string& id=StdString());
          void sendAddDomain(const std::string& id="");
          void sendAddAxis(const std::string& id="");
+         void sendAddScalar(const std::string& id="");
          void sendAllDomains();
          void sendAllAxis();
+         void sendAllScalars();
 
          static void recvAddDomain(CEventServer& event);
@@ -159,4 +166,6 @@
          static void recvAddAxis(CEventServer& event);
          void recvAddAxis(CBufferIn& buffer);
+         static void recvAddScalar(CEventServer& event);
+         void recvAddScalar(CBufferIn& buffer);
 
          static bool dispatchEvent(CEventServer& event);
@@ -172,6 +181,8 @@
          std::vector<StdString> getDomainList();
          std::vector<StdString> getAxisList();
+         std::vector<StdString> getScalarList();
          std::vector<CDomain*> getDomains();
          std::vector<CAxis*> getAxis();
+         std::vector<CScalar*> getScalars();
          std::vector<int> getAxisOrder();
          std::vector<int> getGlobalDimension();
@@ -218,5 +229,6 @@
          void computeGridGlobalDimension(const std::vector<CDomain*>& domains,
                                          const std::vector<CAxis*>& axis,
-                                         const CArray<bool,1>& axisDomainOrder);
+                                         const std::vector<CScalar*>& scalars,
+                                         const CArray<int,1>& axisDomainOrder);
 
       private:
@@ -225,5 +237,5 @@
                           const std::vector<CArray<bool,1>* >& domainMasks,
                           const std::vector<CArray<bool,1>* >& axisMasks,
-                          const CArray<bool,1>& axisDomainOrder,
+                          const CArray<int,1>& axisDomainOrder,
                           bool createMask = false);
         template<int N>
@@ -234,10 +246,14 @@
         void setVirtualAxisGroup(CAxisGroup* newVAxisGroup);
         void setVirtualAxisGroup();
-
+        void setVirtualScalarGroup(CScalarGroup* newVScalarGroup);
+        void setVirtualScalarGroup();
+
+        void setDomainList(const std::vector<CDomain*> domains = std::vector<CDomain*>());
         void setAxisList(const std::vector<CAxis*> axis = std::vector<CAxis*>());
-        void setDomainList(const std::vector<CDomain*> domains = std::vector<CDomain*>());
-
+        void setScalarList(const std::vector<CScalar*> scalars = std::vector<CScalar*>());
+
+        CDomainGroup* getVirtualDomainGroup() const;
         CAxisGroup* getVirtualAxisGroup() const;
-        CDomainGroup* getVirtualDomainGroup() const;
+        CScalarGroup* getVirtualScalarGroup() const;
 
         void checkAttributesAfterTransformation();
@@ -246,10 +262,10 @@
                                    CClientServerMapping::GlobalIndexMap& globalIndexOnServer);
 
-
       private:
         CDomainGroup* vDomainGroup_;
         CAxisGroup* vAxisGroup_;
-        std::vector<std::string> axisList_, domList_;
-        bool isAxisListSet, isDomListSet;
+        CScalarGroup* vScalarGroup_;
+        std::vector<std::string> axisList_, domList_, scalarList_;
+        bool isAxisListSet, isDomListSet, isScalarListSet;
 
         CDistributionClient* clientDistribution_;
@@ -275,5 +291,5 @@
         CClientServerMapping::GlobalIndexMap globalIndexOnServer_;
             // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
-        std::vector<bool> order_;
+        std::vector<int> order_;
    }; // class CGrid
 
@@ -306,5 +322,5 @@
                              const std::vector<CArray<bool,1>* >& domainMasks,
                              const std::vector<CArray<bool,1>* >& axisMasks,
-                             const CArray<bool,1>& axisDomainOrder,
+                             const CArray<int,1>& axisDomainOrder,
                              bool createMask)
    {
@@ -320,13 +336,14 @@
     {
       indexMap[i] = idx;
-      if (true == axisDomainOrder(i)) {
+      if (2 == axisDomainOrder(i)) {
           eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni;
           eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj;
           idx += 2; ++idxDomain;
       }
-      else {
+      else if (1 == axisDomainOrder(i)) {
         eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements();
         ++idx; ++idxAxis;
       }
+      else ++idx;
     }
 
@@ -365,10 +382,10 @@
       for (int i = 0; i < numElement; ++i)
       {
-        if (axisDomainOrder(i))
+        if (2 == axisDomainOrder(i))
         {
           maskValue = maskValue && (*domainMasks[idxDomain])(idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]]);
           ++idxDomain;
         }
-        else
+        else if (1 == axisDomainOrder(i))
         {
           maskValue = maskValue && (*axisMasks[idxAxis])(idxLoop[indexMap[i]]);
Index: /XIOS/trunk/src/node/node_enum.hpp
===================================================================
--- /XIOS/trunk/src/node/node_enum.hpp	(revision 886)
+++ /XIOS/trunk/src/node/node_enum.hpp	(revision 887)
@@ -25,5 +25,6 @@
          eZoomDomain,
          eInterpolateDomain,
-         eGenerateRectilinearDomain
+         eGenerateRectilinearDomain,
+         eScalar
 
       } ENodeType;
Index: /XIOS/trunk/src/node/node_type.hpp
===================================================================
--- /XIOS/trunk/src/node/node_type.hpp	(revision 886)
+++ /XIOS/trunk/src/node/node_type.hpp	(revision 887)
@@ -16,4 +16,6 @@
 #include "interpolate_domain.hpp"
 #include "generate_rectilinear_domain.hpp"
+#include "scalar.hpp"
+
 
 #endif // __XIOS_NODE_TYPE__
Index: /XIOS/trunk/src/node/scalar.cpp
===================================================================
--- /XIOS/trunk/src/node/scalar.cpp	(revision 887)
+++ /XIOS/trunk/src/node/scalar.cpp	(revision 887)
@@ -0,0 +1,130 @@
+#include "scalar.hpp"
+
+#include "attribute_template.hpp"
+#include "object_template.hpp"
+#include "group_template.hpp"
+#include "object_factory.hpp"
+#include "xios_spl.hpp"
+#include "type.hpp"
+
+namespace xios {
+
+   /// ////////////////////// DÃ©finitions ////////////////////// ///
+
+   CScalar::CScalar(void)
+      : CObjectTemplate<CScalar>()
+      , CScalarAttributes()
+      , relFiles()
+   { /* Ne rien faire de plus */ }
+
+   CScalar::CScalar(const StdString & id)
+      : CObjectTemplate<CScalar>(id)
+      , CScalarAttributes()
+      , relFiles()
+   { /* Ne rien faire de plus */ }
+
+   CScalar::~CScalar(void)
+   { /* Ne rien faire de plus */ }
+
+   StdString CScalar::GetName(void)   { return (StdString("scalar")); }
+   StdString CScalar::GetDefName(void){ return (CScalar::GetName()); }
+   ENodeType CScalar::GetType(void)   { return (eScalar); }
+
+   CScalar* CScalar::createScalar()
+   {
+     CScalar* scalar = CScalarGroup::get("scalar_definition")->createChild();
+     return scalar;
+   }
+
+   bool CScalar::IsWritten(const StdString & filename) const
+   {
+      return (this->relFiles.find(filename) != this->relFiles.end());
+   }
+
+   void CScalar::addRelFile(const StdString& filename)
+   {
+      this->relFiles.insert(filename);
+   }
+
+   void CScalar::checkAttributes(void)
+   {
+//      if (this->value.isEmpty())
+//      {
+//        this->value.setValue(0);
+//      }
+   }
+
+  void CScalar::checkAttributesOnClient()
+  {
+
+  }
+
+  CTransformation<CScalar>* CScalar::addTransformation(ETranformationType transType, const StdString& id)
+  {
+    transformationMap_.push_back(std::make_pair(transType, CTransformation<CScalar>::createTransformation(transType,id)));
+    return transformationMap_.back().second;
+  }
+
+  bool CScalar::hasTransformation()
+  {
+    return (!transformationMap_.empty());
+  }
+
+  void CScalar::setTransformations(const TransMapTypes& scalarTrans)
+  {
+    transformationMap_ = scalarTrans;
+  }
+
+  CScalar::TransMapTypes CScalar::getAllTransformations(void)
+  {
+    return transformationMap_;
+  }
+
+  /*!
+    Check the validity of all transformations applied on scalar
+  This functions is called AFTER all inherited attributes are solved
+  */
+  void CScalar::checkTransformations()
+  {
+    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
+                                  ite = transformationMap_.end();
+    for (it = itb; it != ite; ++it)
+    {
+      (it->second)->checkValid(this);
+    }
+  }
+
+  void CScalar::duplicateTransformation(CScalar* src)
+  {
+    if (src->hasTransformation())
+    {
+      this->setTransformations(src->getAllTransformations());
+    }
+  }
+
+  /*!
+   * Go through the hierarchy to find the scalar from which the transformations must be inherited
+   */
+  void CScalar::solveInheritanceTransformation()
+  {
+    if (hasTransformation() || !hasDirectScalarReference())
+      return;
+
+    CScalar* scalar = this;
+    std::vector<CScalar*> refScalar;
+    while (!scalar->hasTransformation() && scalar->hasDirectScalarReference())
+    {
+      refScalar.push_back(scalar);
+      scalar = scalar->getDirectScalarReference();
+    }
+
+    if (scalar->hasTransformation())
+      for (size_t i = 0; i < refScalar.size(); ++i)
+        refScalar[i]->setTransformations(scalar->getAllTransformations());
+  }
+
+
+  // Definition of some macros
+  DEFINE_REF_FUNC(Scalar,scalar)
+
+} // namespace xios
Index: /XIOS/trunk/src/node/scalar.hpp
===================================================================
--- /XIOS/trunk/src/node/scalar.hpp	(revision 887)
+++ /XIOS/trunk/src/node/scalar.hpp	(revision 887)
@@ -0,0 +1,94 @@
+#ifndef __XIOS_CScalar__
+#define __XIOS_CScalar__
+
+/// XIOS headers ///
+#include "xios_spl.hpp"
+#include "declare_group.hpp"
+#include "declare_ref_func.hpp"
+#include "group_template.hpp"
+#include "array_new.hpp"
+#include "attribute_enum.hpp"
+#include "attribute_enum_impl.hpp"
+#include "transformation.hpp"
+#include "transformation_enum.hpp"
+
+namespace xios
+{
+      /// ////////////////////// DÃ©clarations ////////////////////// ///
+
+      class CScalarGroup;
+      class CScalarAttributes;
+      class CScalar;
+      ///--------------------------------------------------------------
+
+      // Declare/Define CVarAttribute
+      BEGIN_DECLARE_ATTRIBUTE_MAP(CScalar)
+#include "scalar_attribute.conf"
+      END_DECLARE_ATTRIBUTE_MAP(CScalar)
+
+      ///--------------------------------------------------------------
+
+      class CScalar
+         : public CObjectTemplate<CScalar>
+         , public CScalarAttributes
+      {
+            /// typedef ///
+            typedef CObjectTemplate<CScalar>   SuperClass;
+            typedef CScalarAttributes SuperClassAttribute;
+
+            friend class CScalarGroup;
+
+         public :
+
+            typedef CScalarAttributes RelAttributes;
+            typedef CScalarGroup      RelGroup;
+            typedef CTransformation<CScalar>::TransformationMapTypes TransMapTypes;
+
+            /// Constructeurs ///
+            CScalar(void);
+            explicit CScalar(const StdString & id);
+            CScalar(const CScalar & var);       // Not implemented yet.
+            CScalar(const CScalar * const var); // Not implemented yet.
+
+            /// Destructeur ///
+            virtual ~CScalar(void);
+
+         public :
+            /// Accesseurs statiques ///
+            static StdString GetName(void);
+            static StdString GetDefName(void);
+            static ENodeType GetType(void);
+
+         public:
+            static CScalar* createScalar();
+
+         public:
+            void checkAttributes(void);
+            void addRelFile(const StdString& filename);
+            bool IsWritten(const StdString& filename) const;
+            void checkAttributesOnClient();
+
+         public:
+           bool hasTransformation();
+           void solveInheritanceTransformation();
+           TransMapTypes getAllTransformations();
+           void duplicateTransformation(CScalar*);
+           CTransformation<CScalar>* addTransformation(ETranformationType transType, const StdString& id="");
+         private:
+           std::set<StdString> relFiles;
+
+         private:
+            TransMapTypes transformationMap_;
+            void checkTransformations();
+            void setTransformations(const TransMapTypes&);
+         private:
+            DECLARE_REF_FUNC(Scalar,scalar)
+
+      }; // class CVar
+      ///--------------------------------------------------------------
+
+      // Declare/Define CScalarGroup and CScalarDefinition
+      DECLARE_GROUP(CScalar);
+} // namespace xios
+
+#endif // __XIOS_CScalar__
Index: /XIOS/trunk/src/object_factory_decl.cpp
===================================================================
--- /XIOS/trunk/src/object_factory_decl.cpp	(revision 886)
+++ /XIOS/trunk/src/object_factory_decl.cpp	(revision 887)
@@ -32,4 +32,5 @@
   macro(CInterpolateDomain)
   macro(CGenerateRectilinearDomain)
+  macro(CScalar)
 
   macro(CFieldGroup)
@@ -46,3 +47,4 @@
   macro(CInterpolateDomainGroup)
   macro(CGenerateRectilinearDomainGroup)
+  macro(CScalarGroup)
 }
Index: /XIOS/trunk/src/object_template_decl.cpp
===================================================================
--- /XIOS/trunk/src/object_template_decl.cpp	(revision 886)
+++ /XIOS/trunk/src/object_template_decl.cpp	(revision 887)
@@ -19,4 +19,5 @@
   template class CObjectTemplate<CInterpolateDomain>;
   template class CObjectTemplate<CGenerateRectilinearDomain>;
+  template class CObjectTemplate<CScalar>;
 
   template class CObjectTemplate<CContextGroup>;
@@ -33,3 +34,4 @@
   template class CObjectTemplate<CInterpolateDomainGroup>;
   template class CObjectTemplate<CGenerateRectilinearDomainGroup>;
+  template class CObjectTemplate<CScalarGroup>;
 }
Index: /XIOS/trunk/src/server_distribution_description.cpp
===================================================================
--- /XIOS/trunk/src/server_distribution_description.cpp	(revision 886)
+++ /XIOS/trunk/src/server_distribution_description.cpp	(revision 887)
@@ -169,5 +169,5 @@
   \param [in] clientRank rank of client
   \param [in] clientSize number of client
-  \param [in] axisDomainOrder the order of element in grid (true for domain, false for axis)
+  \param [in] axisDomainOrder the order of element in grid (2 for domain, 1 for axis, 0 for scalar)
   \param [in] positionDimensionDistributed dimension of server on which we make the cut.
 */
@@ -175,5 +175,5 @@
                                                                   int clientRank,
                                                                   int clientSize,
-                                                                  const CArray<bool,1>& axisDomainOrder,
+                                                                  const CArray<int,1>& axisDomainOrder,
                                                                   int positionDimensionDistributed)
 {
@@ -193,5 +193,5 @@
   {
     idxMap[i] = idx;
-    if (true == axisDomainOrder(i)) idx += 2;
+    if (2 == axisDomainOrder(i)) idx += 2;
     else ++idx;
   }
@@ -203,5 +203,5 @@
     {
       int elementSize = 1;
-      if (axisDomainOrder(i))
+      if (2 == axisDomainOrder(i))
       {
         elementSize *= dimensionSizes_[idxServer][idxMap[i]] * dimensionSizes_[idxServer][idxMap[i]+1];
@@ -212,5 +212,5 @@
       }
 
-      else
+      else if (1 == axisDomainOrder(i))
       {
         elementSize *= dimensionSizes_[idxServer][idxMap[i]];
@@ -218,4 +218,12 @@
         elementDimension[1] = 0;
         elementDimension[2] = dimensionSizes_[idxServer][idxMap[i]];
+        elementDimension[3] = 1;
+      }
+      else
+      {
+        elementSize *= dimensionSizes_[idxServer][idxMap[i]];
+        elementDimension[0] = 0;
+        elementDimension[1] = 0;
+        elementDimension[2] = 1;
         elementDimension[3] = 1;
       }
Index: /XIOS/trunk/src/server_distribution_description.hpp
===================================================================
--- /XIOS/trunk/src/server_distribution_description.hpp	(revision 886)
+++ /XIOS/trunk/src/server_distribution_description.hpp	(revision 887)
@@ -42,5 +42,5 @@
                                       int rank,
                                       int clientSize,
-                                      const CArray<bool,1>& axisDomainOrder,
+                                      const CArray<int,1>& axisDomainOrder,
                                       int positionDimensionDistributed = 1);
 
Index: /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 886)
+++ /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 887)
@@ -84,5 +84,5 @@
   std::vector<CAxis*> axisListDestP = gridDst->getAxis();
   std::vector<CDomain*> domainListDestP = gridDst->getDomains();
-  CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order;
+  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
   std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
   std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
@@ -96,5 +96,5 @@
     if (idx == elementPositionInGrid)
       computeExchangeGlobalIndex(indexSrc, globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]);
-    if (axisDomainDstOrder(idx)) // It's domain
+    if (2 == axisDomainDstOrder(idx)) // It's domain
     {
       if (idx != elementPositionInGrid)
@@ -106,5 +106,5 @@
 
     }
-    else //it's an axis
+    else if (1 == axisDomainDstOrder(idx))//it's an axis
     {
       if (idx != elementPositionInGrid)
@@ -226,33 +226,64 @@
                                                                    SourceDestinationIndexMap& globaIndexWeightFromSrcToDst)
 {
+  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
+  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
+  std::vector<CScalar*> scalarListSrcP = gridSrc->getScalars();
+  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;
+
+  size_t nbElement = axisDomainSrcOrder.numElements();
+  std::vector<size_t> nGlobSrc(nbElement);
+  size_t globalSrcSize = 1;
+  int domainIndex = 0, axisIndex = 0, scalarIndex = 0;
+  for (int idx = 0; idx < nbElement; ++idx)
+  {
+    nGlobSrc[idx] = globalSrcSize;
+    int elementDimension = axisDomainSrcOrder(idx);
+
+    // If this is a domain
+    if (2 == elementDimension)
+    {
+      globalSrcSize *= domainListSrcP[domainIndex]->nj_glo.getValue() * domainListSrcP[domainIndex]->ni_glo.getValue();
+      ++domainIndex;
+    }
+    else if (1 == elementDimension) // So it's an axis
+    {
+      globalSrcSize *= axisListSrcP[axisIndex]->n_glo.getValue();
+      ++axisIndex;
+    }
+    else
+    {
+      globalSrcSize *= 1;
+      ++scalarIndex;
+    }
+  }
+
+  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
   std::vector<CAxis*> axisListDestP = gridDst->getAxis();
-  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
-  CArray<bool,1> axisDomainDstOrder = gridDst->axis_domain_order;
-  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
-  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
-  CArray<bool,1> axisDomainSrcOrder = gridDst->axis_domain_order;
-  size_t nbElement = axisDomainSrcOrder.numElements();
-  std::vector<size_t> nGlobSrc(nbElement), nGlobDst(nbElement);
-  size_t globalSrcSize = 1, globalDstSize = 1;
-  int domainIndex = 0;
-  int axisIndex = 0;
+  std::vector<CScalar*> scalarListDestP = gridDst->getScalars();
+  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
+
+  std::vector<size_t> nGlobDst(nbElement);
+  size_t globalDstSize = 1;
+  domainIndex = axisIndex = scalarIndex = 0;
   for (int idx = 0; idx < nbElement; ++idx)
   {
-    nGlobSrc[idx] = globalSrcSize;
     nGlobDst[idx] = globalDstSize;
-    bool isDomain = axisDomainSrcOrder(idx);
+    int elementDimension = axisDomainSrcOrder(idx);
 
     // If this is a domain
-    if (isDomain)
-    {
-      globalSrcSize *= domainListSrcP[domainIndex]->nj_glo.getValue() * domainListSrcP[domainIndex]->ni_glo.getValue();
+    if (2 == elementDimension)
+    {
       globalDstSize *= domainListDestP[domainIndex]->nj_glo.getValue() * domainListDestP[domainIndex]->ni_glo.getValue();
       ++domainIndex;
     }
-    else // So it's an axis
-    {
-      globalSrcSize *= axisListSrcP[axisIndex]->n_glo.getValue();
+    else if (1 == elementDimension) // So it's an axis
+    {
       globalDstSize *= axisListDestP[axisIndex]->n_glo.getValue();
       ++axisIndex;
+    }
+    else
+    {
+      globalDstSize *= 1;
+      ++scalarIndex;
     }
   }
Index: /XIOS/trunk/src/transformation/grid_generate.cpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_generate.cpp	(revision 886)
+++ /XIOS/trunk/src/transformation/grid_generate.cpp	(revision 887)
@@ -3,171 +3,34 @@
    \author Ha NGUYEN
    \since 28 Aug 2015
-   \date 28 Aug 2015
+   \date 23 June 2016
 
    \brief A special transformation to generate a grid.
  */
 #include "grid_generate.hpp"
+#include "grid.hpp"
 #include "domain_algorithm_generate_rectilinear.hpp"
-#include "context.hpp"
-#include "context_client.hpp"
 #include "generate_rectilinear_domain.hpp"
 
 namespace xios {
 CGridGenerate::CGridGenerate(CGrid* destination, CGrid* source)
-: gridSource_(source), gridDestination_(destination), algoTypes_()
+  : CGridTransformationSelector(destination, source)
 {
-  if (0 != source)
-  {
-    //Verify the compatibity between two grids
-    int numElement = gridDestination_->axis_domain_order.numElements();
-    if (numElement != gridSource_->axis_domain_order.numElements())
-      ERROR("CGridGenerate::CGridGenerate(CGrid* destination, CGrid* source)",
-         << "Two grids have different number of elements"
-         << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
-         << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
-
-    for (int i = 0; i < numElement; ++i)
-    {
-      if (gridDestination_->axis_domain_order(i) != gridSource_->axis_domain_order(i))
-        ERROR("CGridGenerate::CGridGenerate(CGrid* destination, CGrid* source)",
-           << "Transformed grid and its grid source have incompatible elements"
-           << "Grid source " <<gridSource_->getId() << std::endl
-           << "Grid destination " <<gridDestination_->getId());
-    }
-  }
-
-  initializeAlgorithms();
 }
 
 CGridGenerate::~CGridGenerate()
 {
-  std::list<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
-                                                              ite = algoTransformation_.end();
-  for (it = itb; it != ite; ++it) delete (*it);
 }
 
 /*!
-  Initialize the algorithms (transformations)
-*/
-void CGridGenerate::initializeAlgorithms()
-{
-  std::vector<int> axisPositionInGrid;
-  std::vector<int> domPositionInGrid;
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
-
-  int idx = 0;
-  for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
-  {
-    if (false == (gridDestination_->axis_domain_order)(i))
-    {
-      axisPositionInGrid.push_back(idx);
-      ++idx;
-    }
-    else
-    {
-      ++idx;
-      domPositionInGrid.push_back(idx);
-      ++idx;
-    }
-  }
-
-  for (int i = 0; i < axisListDestP.size(); ++i)
-  {
-    elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
-  }
-
-  for (int i = 0; i < domListDestP.size(); ++i)
-  {
-    elementPosition2DomainPositionInGrid_[domPositionInGrid[i]] = i;
-  }
-
-  idx = 0;
-  for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
-  {
-    if (false == (gridDestination_->axis_domain_order)(i))
-    {
-      initializeAxisAlgorithms(idx);
-      ++idx;
-    }
-    else
-    {
-      ++idx;
-      initializeDomainAlgorithms(idx);
-      ++idx;
-    }
-  }
-}
-
-
-
-/*!
-  Initialize the algorithms corresponding to transformation info contained in each axis.
-If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
-In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
-For now, one approach is to do these combinely but maybe this needs changing.
-\param [in] axisPositionInGrid position of an axis in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
-*/
-void CGridGenerate::initializeAxisAlgorithms(int axisPositionInGrid)
-{
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  if (!axisListDestP.empty())
-  {
-    if (axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->hasTransformation())
-    {
-      CAxis::TransMapTypes trans = axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->getAllTransformations();
-      CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
-                                           ite = trans.end();
-      int transformationOrder = 0;
-      for (it = itb; it != ite; ++it)
-      {
-        listAlgos_.push_back(std::make_pair(axisPositionInGrid, std::make_pair(it->first, transformationOrder)));
-        algoTypes_.push_back(false);
-        ++transformationOrder;
-      }
-    }
-  }
-}
-
-/*!
-  Initialize the algorithms corresponding to transformation info contained in each domain.
-If a domain has transformations, they will be represented in form of vector of CTransformation pointers
-In general, each domain can have several transformations performed on itself.
-\param [in] domPositionInGrid position of a domain in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
-*/
-void CGridGenerate::initializeDomainAlgorithms(int domPositionInGrid)
-{
-  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
-  if (!domListDestP.empty())
-  {
-    if (domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->hasTransformation())
-    {
-      CDomain::TransMapTypes trans = domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->getAllTransformations();
-      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
-                                             ite = trans.end();
-      int transformationOrder = 0;
-      for (it = itb; it != ite; ++it)
-      {
-        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, transformationOrder)));
-        algoTypes_.push_back(true);
-        ++transformationOrder;
-      }
-    }
-  }
-
-}
-
-/*!
-  Select algorithm correspoding to its transformation type and its position in each element
+  Select algorithm of an axis correspoding to its transformation type and its position in each element
   \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
                                              and position of axis is 2
   \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
   \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
-  \param [in] isDomainAlgo flag to specify type of algorithm (for domain or axis)
 */
-void CGridGenerate::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo)
+void CGridGenerate::selectScalarAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
 {
-   if (isDomainAlgo) selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
-   else selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
+  CGenericAlgorithmTransformation* algo = 0;
+  algoTransformation_.push_back(algo);
 }
 
@@ -181,20 +44,6 @@
 void CGridGenerate::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
 {
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-
-  int axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
-  CAxis::TransMapTypes trans = axisListDestP[axisIndex]->getAllTransformations();
-  CAxis::TransMapTypes::const_iterator it = trans.begin();
-
-  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
-
   CGenericAlgorithmTransformation* algo = 0;
-  switch (transType)
-  {
-    default:
-    break;
-  }
   algoTransformation_.push_back(algo);
-
 }
 
@@ -212,5 +61,5 @@
   if (0 != gridSource_) domainListSrcP = gridSource_->getDomains();
 
-  int domainIndex =  elementPosition2DomainPositionInGrid_[elementPositionInGrid];
+  int domainIndex =  elementPositionInGridDst2DomainPosition_[elementPositionInGrid];
   CDomain::TransMapTypes trans = domainListDestP[domainIndex]->getAllTransformations();
   CDomain::TransMapTypes::const_iterator it = trans.begin();
@@ -246,7 +95,4 @@
 void CGridGenerate::completeGrid()
 {
-  CContext* context = CContext::getCurrent();
-  CContextClient* client = context->client;
-
   ListAlgoType::const_iterator itb = listAlgos_.begin(),
                                ite = listAlgos_.end(), it;
Index: /XIOS/trunk/src/transformation/grid_generate.hpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_generate.hpp	(revision 886)
+++ /XIOS/trunk/src/transformation/grid_generate.hpp	(revision 887)
@@ -12,5 +12,5 @@
 #include "xios_spl.hpp"
 #include "transformation_enum.hpp"
-#include "generic_algorithm_transformation.hpp"
+#include "grid_transformation_selector.hpp"
 
 namespace xios {
@@ -25,9 +25,6 @@
 This class only plays a role of interface between XIOS and specific algorithm of auto filling-in and auto distributing on sub-component
 */
-class CGridGenerate
+class CGridGenerate : public CGridTransformationSelector
 {
-public:
-  typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
-
 public:
   /** Default constructor */
@@ -36,33 +33,9 @@
 
   void completeGrid();
-  ListAlgoType getAlgoList() const {return listAlgos_; }
 
 protected:
-  void initializeAlgorithms();
-  void initializeAxisAlgorithms(int axisPositionInGrid);
-  void initializeDomainAlgorithms(int domPositionInGrid);
-
-  void selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
-  void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
-  void selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo);
-
-protected:
-  //! Grid source on transformation
-  CGrid* gridSource_;
-
-  //! Grid destination on transformation
-  CGrid* gridDestination_;
-
-protected:
-  //! List of algorithm types and their order
-  ListAlgoType listAlgos_;
-  // true if domain algorithm and false if axis algorithm (can be replaced by tuple with listAlgos_
-  std::vector<bool> algoTypes_;
-
-  // Mapping between position of an element in grid and its transformation (if any)
-  std::list<CGenericAlgorithmTransformation*> algoTransformation_;
-
-  //! Position of axis and domain in grid
-  std::map<int, int> elementPosition2AxisPositionInGrid_, elementPosition2DomainPositionInGrid_;
+  virtual void selectScalarAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+  virtual void selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+  virtual void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
 };
 
Index: /XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 886)
+++ /XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 887)
@@ -23,204 +23,38 @@
 namespace xios {
 CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)
-: gridSource_(source), gridDestination_(destination), tmpGridDestination_(destination),
-  originalGridSource_(source), algoTypes_(), nbAlgos_(0), tempGridSrcs_(), tempGridDests_(),
-  auxInputs_(), dynamicalTransformation_(false), timeStamp_()
-
-{
-  //Verify the compatibity between two grids
-  int numElement = gridDestination_->axis_domain_order.numElements();
-  if (numElement != gridSource_->axis_domain_order.numElements())
-    ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
-       << "Two grids have different number of elements"
-       << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
-       << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
-
-  for (int i = 0; i < numElement; ++i)
-  {
-    if (gridDestination_->axis_domain_order(i) != gridSource_->axis_domain_order(i))
-      ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
-         << "Transformed grid and its grid source have incompatible elements"
-         << "Grid source " <<gridSource_->getId() << std::endl
-         << "Grid destination " <<gridDestination_->getId());
-  }
-
-  initializeTransformations();
-}
-
-/*!
-  Initialize the mapping between the first grid source and the original one
-  In a series of transformation, for each step, there is a need to "create" a new grid that plays a role of "temporary" source.
-Because at the end of the series, we need to know about the index mapping between the final grid destination and original grid source,
-for each transformation, we need to make sure that the current "temporary source" maps its global index correctly to the original one.
-*/
-void CGridTransformation::initializeTransformations()
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client = context->client;
-
-  // Initialize algorithms
-  initializeAlgorithms();
-
-  ListAlgoType::const_iterator itb = listAlgos_.begin(),
-                               ite = listAlgos_.end(), it;
-
-  for (it = itb; it != ite; ++it)
-  {
-    ETranformationType transType = (it->second).first;
-    if (!isSpecialTransformation(transType)) ++nbAlgos_;
-  }
+ : CGridTransformationSelector(destination, source),
+  tmpGridDestination_(destination), originalGridSource_(source),
+  tempGridSrcs_(), tempGridDests_(),
+  dynamicalTransformation_(false), timeStamp_()
+{
 }
 
 CGridTransformation::~CGridTransformation()
 {
-  std::vector<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
-                                                                ite = algoTransformation_.end();
-  for (it = itb; it != ite; ++it) delete (*it);
-}
-
-/*!
-  Initialize the algorithms (transformations)
-*/
-void CGridTransformation::initializeAlgorithms()
-{
-  std::vector<int> axisPositionInGrid;
-  std::vector<int> domPositionInGrid;
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
-
-  int idx = 0;
-  for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
-  {
-    if (false == (gridDestination_->axis_domain_order)(i))
-    {
-      axisPositionInGrid.push_back(i);
-    }
-    else
-    {
-      domPositionInGrid.push_back(i);
-    }
-  }
-
-  for (int i = 0; i < axisListDestP.size(); ++i)
-  {
-    elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
-  }
-
-  for (int i = 0; i < domListDestP.size(); ++i)
-  {
-    elementPosition2DomainPositionInGrid_[domPositionInGrid[i]] = i;
-  }
-
-  idx = 0;
-  for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
-  {
-    if (false == (gridDestination_->axis_domain_order)(i))
-    {
-      initializeAxisAlgorithms(i);
-    }
-    else
-    {
-      initializeDomainAlgorithms(i);
-    }
-  }
-}
-
-/*!
-  Initialize the algorithms corresponding to transformation info contained in each axis.
-If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
-In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
-For now, one approach is to do these combinely but maybe this needs changing.
-\param [in] axisPositionInGrid position of an axis in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
-*/
-void CGridTransformation::initializeAxisAlgorithms(int axisPositionInGrid)
+}
+
+/*!
+  Select algorithm of a scalar correspoding to its transformation type and its position in each element
+  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 0 and position of axis is 1
+  \param [in] transType transformation type, for now we have
+  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
+*/
+void CGridTransformation::selectScalarAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
+{
+
+}
+
+/*!
+  Select algorithm of an axis correspoding to its transformation type and its position in each element
+  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 0 and position of axis is 1
+  \param [in] transType transformation type, for now we have zoom_axis, inverse_axis, interpolate_axis
+  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
+*/
+void CGridTransformation::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
 {
   std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
   std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
-  if (!axisListDestP.empty())
-  {
-    // If source and destination grid share the same axis
-    if (axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]] ==
-        axisListSrcP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]) return;
-
-    if (axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->hasTransformation())
-    {
-      CAxis::TransMapTypes trans = axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->getAllTransformations();
-      CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
-                                           ite = trans.end();
-      int transformationOrder = 0;
-      for (it = itb; it != ite; ++it)
-      {
-        listAlgos_.push_back(std::make_pair(axisPositionInGrid, std::make_pair(it->first, transformationOrder)));
-        algoTypes_.push_back(false);
-        ++transformationOrder;
-        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
-        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
-      }
-    }
-  }
-}
-
-/*!
-  Initialize the algorithms corresponding to transformation info contained in each domain.
-If a domain has transformations, they will be represented in form of vector of CTransformation pointers
-In general, each domain can have several transformations performed on itself.
-\param [in] domPositionInGrid position of a domain in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
-*/
-void CGridTransformation::initializeDomainAlgorithms(int domPositionInGrid)
-{
-  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
-  std::vector<CDomain*> domListSrcP = gridSource_->getDomains();
-  if (!domListDestP.empty())
-  {
-    // If source and destination grid share the same domain
-    if (domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]] ==
-        domListSrcP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]) return;
-
-    if (domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->hasTransformation())
-    {
-      CDomain::TransMapTypes trans = domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->getAllTransformations();
-      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
-                                             ite = trans.end();
-      int transformationOrder = 0;
-      for (it = itb; it != ite; ++it)
-      {
-        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, transformationOrder)));
-        algoTypes_.push_back(true);
-        ++transformationOrder;
-        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
-        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
-      }
-    }
-  }
-
-}
-
-/*!
-  Select algorithm correspoding to its transformation type and its position in each element
-  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
-                                             and position of axis is 2
-  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
-  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
-  \param [in] isDomainAlgo flag to specify type of algorithm (for domain or axis)
-*/
-void CGridTransformation::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo)
-{
-   if (isDomainAlgo) selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
-   else selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
-}
-
-/*!
-  Select algorithm of an axis correspoding to its transformation type and its position in each element
-  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
-                                             and position of axis is 2
-  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
-  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
-*/
-void CGridTransformation::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
-{
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
-
-  int axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
+
+  int axisIndex =  elementPositionInGridDst2AxisPosition_[elementPositionInGrid];
   CAxis::TransMapTypes trans = axisListDestP[axisIndex]->getAllTransformations();
   CAxis::TransMapTypes::const_iterator it = trans.begin();
@@ -248,12 +82,10 @@
   }
   algoTransformation_.push_back(algo);
-
 }
 
 /*!
   Select algorithm of a domain correspoding to its transformation type and its position in each element
-  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
-                                             and position of axis is 2
-  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
+  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 0 and position of axis is 1
+  \param [in] transType transformation type, for now we have zoom_domain, interpolate_domain
   \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
 */
@@ -263,5 +95,5 @@
   std::vector<CDomain*> domainListSrcP = gridSource_->getDomains();
 
-  int domainIndex =  elementPosition2DomainPositionInGrid_[elementPositionInGrid];
+  int domainIndex =  elementPositionInGridDst2DomainPosition_[elementPositionInGrid];
   CDomain::TransMapTypes trans = domainListDestP[domainIndex]->getAllTransformations();
   CDomain::TransMapTypes::const_iterator it = trans.begin();
@@ -302,4 +134,8 @@
     tempGridDests_.resize(0);
   }
+
+  std::vector<CScalar*> scalarListDestP = gridDestination_->getScalars();
+  std::vector<CScalar*> scalarListSrcP = gridSource_->getScalars(), scalarDst;
+
   std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
   std::vector<CAxis*> axisListSrcP = gridSource_->getAxis(), axisDst;
@@ -308,10 +144,13 @@
   std::vector<CDomain*> domListSrcP = gridSource_->getDomains(), domainDst;
 
-  int axisIndex = -1, domainIndex = -1;
+  CArray<int,1> axisDomainOrderSrc = gridSource_->axis_domain_order;
+  CArray<int,1> axisDomainOrderDst = gridDestination_->axis_domain_order;
+
+  int scalarIndex = -1, axisIndex = -1, domainIndex = -1;
   switch (transType)
   {
     case TRANS_INTERPOLATE_DOMAIN:
     case TRANS_ZOOM_DOMAIN:
-      domainIndex = elementPosition2DomainPositionInGrid_[elementPositionInGrid];
+      domainIndex = elementPositionInGridDst2DomainPosition_[elementPositionInGrid];
       break;
 
@@ -319,5 +158,5 @@
     case TRANS_ZOOM_AXIS:
     case TRANS_INVERSE_AXIS:
-      axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
+      axisIndex =  elementPositionInGridDst2AxisPosition_[elementPositionInGrid];
       break;
     default:
@@ -325,18 +164,32 @@
   }
 
-  for (int idx = 0; idx < axisListSrcP.size(); ++idx)
-  {
-    CAxis* axis = (axisIndex != idx) ? axisListSrcP[idx] : axisListDestP[idx];
-    axisDst.push_back(axis);
-  }
-
-  for (int idx = 0; idx < domListSrcP.size(); ++idx)
-  {
-    CDomain* domain = (domainIndex != idx) ? domListSrcP[idx] : domListDestP[idx];
-    domainDst.push_back(domain);
-  }
-
-  tmpGridDestination_ = CGrid::createGrid(domainDst, axisDst, gridDestination_->axis_domain_order);
-  tmpGridDestination_->computeGridGlobalDimension(domainDst, axisDst, gridDestination_->axis_domain_order);
+  for (int idx = 0; idx < axisDomainOrderDst.numElements(); ++idx)
+  {
+    int dimElementDst = axisDomainOrderDst(idx);
+    if (2 == dimElementDst)
+    {
+      if (elementPositionInGrid == idx)
+        domainDst.push_back(domListDestP[domainIndex]);
+      else
+        domainDst.push_back(domListSrcP[elementPositionInGridSrc2DomainPosition_[elementPositionInGrid]]);
+    }
+    else if (1 == dimElementDst)
+    {
+      if (elementPositionInGrid == idx)
+        axisDst.push_back(axisListDestP[axisIndex]);
+      else
+        axisDst.push_back(axisListSrcP[elementPositionInGridSrc2AxisPosition_[elementPositionInGrid]]);
+    }
+    else
+    {
+      if (elementPositionInGrid == idx)
+        scalarDst.push_back(scalarListDestP[scalarIndex]);
+      else
+        scalarDst.push_back(scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[elementPositionInGrid]]);
+    }
+  }
+
+  tmpGridDestination_ = CGrid::createGrid(domainDst, axisDst, scalarDst, gridDestination_->axis_domain_order);
+  tmpGridDestination_->computeGridGlobalDimension(domainDst, axisDst, scalarDst, gridDestination_->axis_domain_order);
   tempGridDests_.push_back(tmpGridDestination_);
 }
@@ -356,4 +209,7 @@
   }
 
+  std::vector<CScalar*> scalarListDestP = tmpGridDestination_->getScalars();
+  std::vector<CScalar*> scalarListSrcP = gridSource_->getScalars(), scalarSrc;
+
   std::vector<CAxis*> axisListDestP = tmpGridDestination_->getAxis();
   std::vector<CAxis*> axisListSrcP = gridSource_->getAxis(), axisSrc;
@@ -362,10 +218,13 @@
   std::vector<CDomain*> domListSrcP = gridSource_->getDomains(), domainSrc;
 
-  int axisIndex = -1, domainIndex = -1;
+  CArray<int,1> axisDomainOrderDst = gridDestination_->axis_domain_order;
+
+  int axisIndex = -1, domainIndex = -1, scalarIndex = -1;
+  int axisListIndex = 0, domainListIndex = 0, scalarListIndex = 0;
   switch (transType)
   {
     case TRANS_INTERPOLATE_DOMAIN:
     case TRANS_ZOOM_DOMAIN:
-      domainIndex = elementPosition2DomainPositionInGrid_[elementPositionInGrid];
+      domainIndex = elementPositionInGridDst2DomainPosition_[elementPositionInGrid];
       break;
 
@@ -373,5 +232,5 @@
     case TRANS_ZOOM_AXIS:
     case TRANS_INVERSE_AXIS:
-      axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
+      axisIndex =  elementPositionInGridDst2AxisPosition_[elementPositionInGrid];
       break;
     default:
@@ -379,40 +238,53 @@
   }
 
-  for (int idx = 0; idx < axisListSrcP.size(); ++idx)
-  {
-    if (axisIndex != idx)
-    {
-      CAxis* axis = axisListDestP[idx];
-      axisSrc.push_back(axis);
+  for (int idx = 0; idx < axisDomainOrderDst.numElements(); ++idx)
+  {
+    int dimElementDst = axisDomainOrderDst(idx);
+    if (2 == dimElementDst)
+    {
+      if (elementPositionInGrid == idx)
+        domainSrc.push_back(domListDestP[domainIndex]);
+      else
+      {
+        CDomain* domain = CDomain::createDomain();
+        domain->domain_ref.setValue(domListDestP[domainListIndex]->getId());
+        domain->solveRefInheritance(true);
+        domain->checkAttributesOnClient();
+        domainSrc.push_back(domain);
+      }
+      ++domainListIndex;
+    }
+    else if (1 == dimElementDst)
+    {
+      if (elementPositionInGrid == idx)
+        axisSrc.push_back(axisListDestP[axisIndex]);
+      else
+      {
+        CAxis* axis = CAxis::createAxis();
+        axis->axis_ref.setValue(axisListDestP[axisListIndex]->getId());
+        axis->solveRefInheritance(true);
+        axis->checkAttributesOnClient();
+        axisSrc.push_back(axis);
+      }
+      ++axisListIndex;
     }
     else
     {
-      CAxis* axis = CAxis::createAxis();
-      axis->axis_ref.setValue(axisListDestP[idx]->getId());
-      axis->solveRefInheritance(true);
-      axis->checkAttributesOnClient();
-      axisSrc.push_back(axis);
-    }
-  }
-
-  for (int idx = 0; idx < domListSrcP.size(); ++idx)
-  {
-    if (domainIndex != idx)
-    {
-      CDomain* domain = domListDestP[idx];
-      domainSrc.push_back(domain);
-    }
-    else
-    {
-      CDomain* domain = CDomain::createDomain();
-      domain->domain_ref.setValue(domListDestP[idx]->getId());
-      domain->solveRefInheritance(true);
-      domain->checkAttributesOnClient();
-      domainSrc.push_back(domain);
-    }
-  }
-
-  gridSource_ = CGrid::createGrid(domainSrc, axisSrc, tmpGridDestination_->axis_domain_order);
-  gridSource_->computeGridGlobalDimension(domainSrc, axisSrc, tmpGridDestination_->axis_domain_order);
+      if (elementPositionInGrid == idx)
+        scalarSrc.push_back(scalarListDestP[scalarIndex]);
+      else
+      {
+        CScalar* scalar = CScalar::createScalar();
+        scalar->scalar_ref.setValue(scalarListDestP[scalarListIndex]->getId());
+        scalar->solveRefInheritance(true);
+        scalar->checkAttributesOnClient();
+        scalarSrc.push_back(scalar);
+      }
+      ++scalarListIndex;
+    }
+  }
+
+  gridSource_ = CGrid::createGrid(domainSrc, axisSrc, scalarSrc, tmpGridDestination_->axis_domain_order);
+  gridSource_->computeGridGlobalDimension(domainSrc, axisSrc, scalarSrc, tmpGridDestination_->axis_domain_order);
 
   tempGridSrcs_.push_back(gridSource_);
@@ -429,5 +301,5 @@
 void CGridTransformation::computeAll(const std::vector<CArray<double,1>* >& dataAuxInputs, Time timeStamp)
 {
-  if (nbAlgos_ < 1) return;
+  if (nbNormalAlgos_ < 1) return;
   if (!auxInputs_.empty() && !dynamicalTransformation_) { dynamicalTransformation_ = true; return; }
   if (dynamicalTransformation_)
@@ -486,8 +358,8 @@
       computeTransformationMapping(globaIndexWeightFromSrcToDst);
 
-      if (1 < nbAlgos_)
+      if (1 < nbNormalAlgos_)
       {
         // Now grid destination becomes grid source in a new transformation
-        if (nbAgloTransformation != (nbAlgos_-1)) setUpGridSource(elementPositionInGrid, transType, nbAgloTransformation);
+        if (nbAgloTransformation != (nbNormalAlgos_-1)) setUpGridSource(elementPositionInGrid, transType, nbAgloTransformation);
       }
       ++nbAgloTransformation;
@@ -725,20 +597,4 @@
 }
 
-bool CGridTransformation::isSpecialTransformation(ETranformationType transType)
-{
-  bool res;
-  switch (transType)
-  {
-    case TRANS_GENERATE_RECTILINEAR_DOMAIN:
-     res = true;
-     break;
-    default:
-     res = false;
-     break;
-  }
-
-  return res;
-}
-
 /*!
   Local index of data which need sending from the grid source
Index: /XIOS/trunk/src/transformation/grid_transformation.hpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 886)
+++ /XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 887)
@@ -15,4 +15,5 @@
 #include "transformation_enum.hpp"
 #include "duration.hpp"
+#include "grid_transformation_selector.hpp"
 
 namespace xios {
@@ -30,9 +31,7 @@
 the grid destination of current transformation will be grid source of the next transformation
 */
-class CGridTransformation
+class CGridTransformation : public CGridTransformationSelector
 {
 public:
-  typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
-  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap;
   typedef std::map<int, CArray<int,1> > SendingIndexGridSourceMap;
   typedef std::map<int,std::vector<std::pair<int,double> > > RecvIndexGridDestinationMap;
@@ -53,46 +52,23 @@
   CGrid* getGridSource() { return originalGridSource_; }
   CGrid* getGridDestination() { return gridDestination_; }
-  ListAlgoType getAlgoList() const {return listAlgos_; }
-  int getNbAlgo() { return nbAlgos_; }
-  const std::vector<StdString>& getAuxInputs() const { return auxInputs_; }
 
 protected:
   void computeTransformation();
-  void initializeAlgorithms();
-  void initializeAxisAlgorithms(int axisPositionInGrid);
-  void initializeDomainAlgorithms(int domPositionInGrid);
-  void initializeTransformations();
 
-  void selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
-  void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
-  void selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo);
+  virtual void selectScalarAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+  virtual void selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+  virtual void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+
   void setUpGridSource(int elementPositionInGrid, ETranformationType transType, int nbTransformation);
   void setUpGridDestination(int elementPositionInGrid, ETranformationType transType, int nbTransformation);
   void computeTransformationMapping(const SourceDestinationIndexMap& globalIndexWeightFromSrcToDest);
-  bool isSpecialTransformation(ETranformationType transType);
 
 protected:
-  //! Grid source on transformation
-  CGrid* gridSource_;
-
-  //! Grid destination on transformation
-  CGrid* gridDestination_, *tmpGridDestination_;
-
   //! The grid source of the first transformation (original grid source)
+  CGrid* tmpGridDestination_;
   CGrid* originalGridSource_;
+  std::vector<CGrid*> tempGridSrcs_, tempGridDests_;
 
 protected:
-  //! List of algorithm types and their order
-  ListAlgoType listAlgos_;
-
-  //! Number of algorithm
-  int nbAlgos_;
-
-  // true if domain algorithm and false if axis algorithm (can be replaced by tuple with listAlgos_
-  std::vector<bool> algoTypes_;
-
-  // Mapping between position of an element in grid and its transformation (if any)
-  std::vector<CGenericAlgorithmTransformation*> algoTransformation_;
-
   //! Mapping of (grid) global index representing tranformation.
   std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource_;
@@ -108,11 +84,5 @@
   std::list<std::vector<bool> > localMaskOnGridDest_;
 
-  //! Position of axis and domain in grid
-  std::map<int, int> elementPosition2AxisPositionInGrid_, elementPosition2DomainPositionInGrid_;
-
-  std::vector<CGrid*> tempGridSrcs_, tempGridDests_;
-  std::vector<StdString> auxInputs_;
   bool dynamicalTransformation_;
-
   std::set<Time> timeStamp_; //! Time stamps for auxillary inputs
 };
Index: /XIOS/trunk/src/transformation/grid_transformation_selector.cpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation_selector.cpp	(revision 887)
+++ /XIOS/trunk/src/transformation/grid_transformation_selector.cpp	(revision 887)
@@ -0,0 +1,290 @@
+/*!
+   \file grid_transformation.cpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 02 Jul 2015
+
+   \brief Interface for all transformations.
+ */
+#include "grid_transformation_selector.hpp"
+#include "grid.hpp"
+//#include <boost/unordered_map.hpp>
+
+namespace xios {
+
+CGridTransformationSelector::CGridTransformationSelector(CGrid* destination, CGrid* source)
+ : gridSource_(source), gridDestination_(destination),
+  listAlgos_(), algoTypes_(), nbNormalAlgos_(0), nbSpecialAlgos_(0), auxInputs_()
+{
+  if (0 == source) gridSource_ = gridDestination_;
+
+  //Verify the compatibity between two grids
+  int numElement = gridDestination_->axis_domain_order.numElements();
+  if (numElement != gridSource_->axis_domain_order.numElements())
+    ERROR("CGridTransformationSelector::CGridTransformationSelector(CGrid* destination, CGrid* source)",
+       << "Two grids have different number of elements"
+       << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
+       << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
+  initializeTransformations();
+}
+
+/*!
+  Initialize the mapping between the first grid source and the original one
+  In a series of transformation, for each step, there is a need to "create" a new grid that plays a role of "temporary" source.
+Because at the end of the series, we need to know about the index mapping between the final grid destination and original grid source,
+for each transformation, we need to make sure that the current "temporary source" maps its global index correctly to the original one.
+*/
+void CGridTransformationSelector::initializeTransformations()
+{
+  // Initialize algorithms
+  initializeAlgorithms();
+  ListAlgoType::const_iterator itb = listAlgos_.begin(),
+                               ite = listAlgos_.end(), it;
+
+  for (it = itb; it != ite; ++it)
+  {
+    ETranformationType transType = (it->second).first;
+    if (!isSpecialTransformation(transType)) ++nbNormalAlgos_;
+    else ++nbSpecialAlgos_;
+  }
+}
+
+CGridTransformationSelector::~CGridTransformationSelector()
+{
+  std::vector<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
+                                                                ite = algoTransformation_.end();
+  for (it = itb; it != ite; ++it) delete (*it);
+}
+
+/*!
+  Initialize the algorithms (transformations)
+*/
+void CGridTransformationSelector::initializeAlgorithms()
+{
+  int idxScalar = 0, idxAxis = 0, idxDomain = 0;
+  CArray<int,1> axisDomainOrderDst = gridDestination_->axis_domain_order;
+  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
+  {
+    int dimElement = axisDomainOrderDst(i);
+    if (2 == dimElement)
+    {
+      elementPositionInGridDst2DomainPosition_[i] = idxDomain;
+      ++idxDomain;
+    }
+    else if (1 == dimElement)
+    {
+      elementPositionInGridDst2AxisPosition_[i] = idxAxis;
+      ++idxAxis;
+    }
+    else
+    {
+      elementPositionInGridDst2ScalarPosition_[i] = idxScalar;
+      ++idxScalar;
+    }
+  }
+
+  idxScalar = idxAxis = idxDomain = 0;
+  CArray<int,1> axisDomainOrderSrc = gridSource_->axis_domain_order;
+  for (int i = 0; i < axisDomainOrderSrc.numElements(); ++i)
+  {
+    int dimElement = axisDomainOrderSrc(i);
+    if (2 == dimElement)
+    {
+      elementPositionInGridSrc2DomainPosition_[i] = idxDomain;
+      ++idxDomain;
+    }
+    else if (1 == dimElement)
+    {
+      elementPositionInGridSrc2AxisPosition_[i] = idxAxis;
+      ++idxAxis;
+    }
+    else
+    {
+      elementPositionInGridSrc2ScalarPosition_[i] = idxScalar;
+      ++idxScalar;
+    }
+  }
+
+  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
+  {
+    int dimElement = axisDomainOrderDst(i);
+    if (2 == dimElement)
+    {
+      initializeDomainAlgorithms(i);
+    }
+    else if (1 == dimElement)
+    {
+      initializeAxisAlgorithms(i);
+    }
+    else
+    {
+      initializeScalarAlgorithms(i);
+    }
+  }
+}
+
+/*!
+  Initialize the algorithms corresponding to transformation info contained in each scalar.
+If an scalar has transformations, these transformations will be represented in form of vector of CTransformation pointers
+In general, each scalar can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
+For now, one approach is to do these combinely but maybe this needs changing.
+\param [in] axisPositionInGrid position of an axis in grid. (for example: a grid with one domain and one scalar, position of domain is 0, position of axis is 1)
+*/
+void CGridTransformationSelector::initializeScalarAlgorithms(int scalarPositionInGrid)
+{
+  std::vector<CScalar*> scalarListDestP = gridDestination_->getScalars();
+  std::vector<CScalar*> scalarListSrcP = gridSource_->getScalars();
+  if (!scalarListDestP.empty())
+  {
+    int scalarDstPos = -1, scalarSrcPos = -1;
+    if (0 < elementPositionInGridDst2ScalarPosition_.count(scalarPositionInGrid))
+      scalarDstPos = elementPositionInGridDst2AxisPosition_[scalarPositionInGrid];
+    if (0 < elementPositionInGridSrc2ScalarPosition_.count(scalarPositionInGrid))
+      scalarSrcPos = elementPositionInGridSrc2AxisPosition_[scalarPositionInGrid];
+
+    // If source and destination grid share the same scalar
+    if ((-1 != scalarDstPos) && (-1 != scalarSrcPos) &&
+        (scalarListDestP[scalarDstPos] == scalarListSrcP[scalarSrcPos])) return;
+
+    if (scalarListDestP[scalarDstPos]->hasTransformation())
+    {
+      CScalar::TransMapTypes trans = scalarListDestP[scalarDstPos]->getAllTransformations();
+      CScalar::TransMapTypes::const_iterator itb = trans.begin(), it,
+                                           ite = trans.end();
+      int transformationOrder = 0;
+      for (it = itb; it != ite; ++it)
+      {
+        listAlgos_.push_back(std::make_pair(scalarPositionInGrid, std::make_pair(it->first, transformationOrder)));
+        algoTypes_.push_back(scalarType);
+        ++transformationOrder;
+        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
+        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
+      }
+    }
+  }
+}
+
+/*!
+  Initialize the algorithms corresponding to transformation info contained in each axis.
+If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
+In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
+For now, one approach is to do these combinely but maybe this needs changing.
+\param [in] axisPositionInGrid position of an axis in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
+*/
+void CGridTransformationSelector::initializeAxisAlgorithms(int axisPositionInGrid)
+{
+  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
+  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
+  if (!axisListDestP.empty())
+  {
+    int axisDstPos = -1, axisSrcPos = -1;
+    if (0 < elementPositionInGridDst2AxisPosition_.count(axisPositionInGrid))
+      axisDstPos = elementPositionInGridDst2AxisPosition_[axisPositionInGrid];
+    if (0 < elementPositionInGridSrc2AxisPosition_.count(axisPositionInGrid))
+      axisSrcPos = elementPositionInGridSrc2AxisPosition_[axisPositionInGrid];
+
+    // If source and destination grid share the same axis
+    if ((-1 != axisDstPos) && (-1 != axisSrcPos) &&
+        (axisListDestP[axisDstPos] == axisListSrcP[axisSrcPos])) return;
+
+    if (axisListDestP[axisDstPos]->hasTransformation())
+    {
+      CAxis::TransMapTypes trans = axisListDestP[axisDstPos]->getAllTransformations();
+      CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
+                                           ite = trans.end();
+      int transformationOrder = 0;
+      for (it = itb; it != ite; ++it)
+      {
+        listAlgos_.push_back(std::make_pair(axisPositionInGrid, std::make_pair(it->first, transformationOrder)));
+        algoTypes_.push_back(axisType);
+        ++transformationOrder;
+        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
+        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
+      }
+    }
+  }
+}
+
+/*!
+  Initialize the algorithms corresponding to transformation info contained in each domain.
+If a domain has transformations, they will be represented in form of vector of CTransformation pointers
+In general, each domain can have several transformations performed on itself.
+\param [in] domPositionInGrid position of a domain in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
+*/
+void CGridTransformationSelector::initializeDomainAlgorithms(int domPositionInGrid)
+{
+  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
+  std::vector<CDomain*> domListSrcP = gridSource_->getDomains();
+  if (!domListDestP.empty())
+  {
+    int domDstPos = -1, domSrcPos = -1;
+    if (0 < elementPositionInGridDst2DomainPosition_.count(domPositionInGrid))
+      domDstPos = elementPositionInGridDst2AxisPosition_[domPositionInGrid];
+    if (0 < elementPositionInGridSrc2DomainPosition_.count(domPositionInGrid))
+      domSrcPos = elementPositionInGridSrc2AxisPosition_[domPositionInGrid];
+
+    // If source and destination grid share the same domain
+    if ((-1 != domDstPos) && (-1 != domSrcPos) &&
+        (domListDestP[domDstPos] == domListSrcP[domSrcPos])) return;
+
+    if (domListDestP[domDstPos]->hasTransformation())
+    {
+      CDomain::TransMapTypes trans = domListDestP[domDstPos]->getAllTransformations();
+      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
+                                             ite = trans.end();
+      int transformationOrder = 0;
+      for (it = itb; it != ite; ++it)
+      {
+        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, transformationOrder)));
+        algoTypes_.push_back(domainType);
+        ++transformationOrder;
+        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
+        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
+      }
+    }
+  }
+
+}
+
+/*!
+  Select algorithm correspoding to its transformation type and its position in each element
+  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
+                                             and position of axis is 2
+  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
+  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
+  \param [in] isDomainAlgo flag to specify type of algorithm (for domain or axis)
+*/
+void CGridTransformationSelector::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, AlgoType algoType)
+{
+  switch (algoType)
+  {
+  case scalarType:
+    selectScalarAlgo(elementPositionInGrid, transType, transformationOrder);
+    break;
+  case axisType:
+    selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
+    break;
+  case domainType:
+    selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
+    break;
+  default:
+    break;
+  }
+}
+
+bool CGridTransformationSelector::isSpecialTransformation(ETranformationType transType)
+{
+  bool res = false;
+  switch (transType)
+  {
+    case TRANS_GENERATE_RECTILINEAR_DOMAIN:
+     res = true;
+     break;
+    default:
+     break;
+  }
+
+  return res;
+}
+
+}
Index: /XIOS/trunk/src/transformation/grid_transformation_selector.hpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation_selector.hpp	(revision 887)
+++ /XIOS/trunk/src/transformation/grid_transformation_selector.hpp	(revision 887)
@@ -0,0 +1,91 @@
+/*!
+   \file grid_transformation.hpp
+   \author Ha NGUYEN
+   \since 23 June 2016
+   \date 23 June 2016
+
+   \brief Helper class to select different transformations.
+ */
+#ifndef __XIOS_GRID_TRANSFORMATION_SELECTOR_HPP__
+#define __XIOS_GRID_TRANSFORMATION_SELECTOR_HPP__
+
+#include <map>
+#include <vector>
+#include "generic_algorithm_transformation.hpp"
+#include "transformation_enum.hpp"
+#include "duration.hpp"
+
+namespace xios {
+
+class CGrid;
+
+/*!
+  \class CGridTransformationSelector
+  This class is a helper class to chose a algorithm (transformation) from the alogrithm list of
+specific grid.
+*/
+class CGridTransformationSelector
+{
+public:
+  typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
+protected:
+  enum AlgoType {
+    scalarType = 0, axisType = 1, domainType = 2
+  };
+
+public:
+  /** Default constructor */
+  CGridTransformationSelector(CGrid* destination, CGrid* source);
+  virtual ~CGridTransformationSelector();
+
+  ListAlgoType getAlgoList() const { return listAlgos_; }
+  int getNbAlgo() { return nbNormalAlgos_; }
+  const std::vector<StdString>& getAuxInputs() const { return auxInputs_; }
+
+protected:
+  void initializeAlgorithms();
+  void initializeDomainAlgorithms(int domPositionInGrid);
+  void initializeAxisAlgorithms(int axisPositionInGrid);
+  void initializeScalarAlgorithms(int scalarPositionInGrid);
+  void initializeTransformations();
+  void selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, AlgoType algo);
+  bool isSpecialTransformation(ETranformationType transType);
+
+protected:
+  virtual void selectScalarAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder) = 0;
+  virtual void selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder) = 0;
+  virtual void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder) = 0;
+
+protected:
+  //! Grid source on transformation
+  CGrid* gridSource_;
+
+  //! Grid destination on transformation
+  CGrid* gridDestination_;
+
+protected:
+  //! List of algorithm types and their order
+  ListAlgoType listAlgos_;
+
+  //! Number of normal algorithm
+  int nbNormalAlgos_;
+
+  //! Number of special algorithms (such as generate_rectilinear_grid)
+  int nbSpecialAlgos_;
+
+  // true if domain algorithm and false if axis algorithm (can be replaced by tuple with listAlgos_
+  std::vector<AlgoType> algoTypes_;
+
+  // Mapping between position of an element in grid and its transformation (if any)
+  std::vector<CGenericAlgorithmTransformation*> algoTransformation_;
+
+  //! Position of axis and domain in grid
+  std::map<int, int> elementPositionInGridSrc2AxisPosition_, elementPositionInGridSrc2DomainPosition_, elementPositionInGridSrc2ScalarPosition_;
+  std::map<int, int> elementPositionInGridDst2AxisPosition_, elementPositionInGridDst2DomainPosition_, elementPositionInGridDst2ScalarPosition_;
+
+  std::vector<StdString> auxInputs_;
+  std::set<Time> timeStamp_; //! Time stamps for auxillary inputs
+};
+
+}
+#endif // __XIOS_GRID_TRANSFORMATION_SELECTOR_HPP__
Index: /XIOS/trunk/src/type/type_util.hpp
===================================================================
--- /XIOS/trunk/src/type/type_util.hpp	(revision 886)
+++ /XIOS/trunk/src/type/type_util.hpp	(revision 887)
@@ -32,4 +32,6 @@
     class CGenerateRectilinearDomain;
     class CGenerateRectilinearDomainGroup;
+    class CScalar;
+    class CScalarGroup;
 
   template <typename T> inline string getStrType(void);
@@ -80,4 +82,6 @@
   macro(CGenerateRectilinearDomain)
   macro(CGenerateRectilinearDomainGroup)
+  macro(CScalar)
+  macro(CScalarGroup)
 #undef macro
 }
Index: /XIOS/trunk/src/xml_parser_decl.cpp
===================================================================
--- /XIOS/trunk/src/xml_parser_decl.cpp	(revision 886)
+++ /XIOS/trunk/src/xml_parser_decl.cpp	(revision 887)
@@ -25,4 +25,5 @@
     macro( InterpolateDomain )
     macro( GenerateRectilinearDomain )
+    macro( Scalar )
   }
 }
