Index: XIOS/trunk/src/config/node_type.conf
===================================================================
--- XIOS/trunk/src/config/node_type.conf	(revision 887)
+++ XIOS/trunk/src/config/node_type.conf	(revision 888)
@@ -59,4 +59,8 @@
 #endif //__XIOS_CScalar__
 
+#ifdef __XIOS_CReduceAxisToScalar__
+   DECLARE_NODE(ReduceAxisToScalar, reduce_axis)
+#endif //__XIOS_CReduceAxisToScalar__
+
 #ifdef __XIOS_CContext__
    DECLARE_NODE_PAR(Context, context)
Index: XIOS/trunk/src/config/reduce_axis_to_scalar_attribute.conf
===================================================================
--- XIOS/trunk/src/config/reduce_axis_to_scalar_attribute.conf	(revision 888)
+++ XIOS/trunk/src/config/reduce_axis_to_scalar_attribute.conf	(revision 888)
@@ -0,0 +1,3 @@
+DECLARE_ATTRIBUTE(StdString, operation)
+
+
Index: XIOS/trunk/src/distribution_client.cpp
===================================================================
--- XIOS/trunk/src/distribution_client.cpp	(revision 887)
+++ XIOS/trunk/src/distribution_client.cpp	(revision 888)
@@ -65,4 +65,8 @@
   grid->checkMask();
   switch (gridDim) {
+    case 0:
+      gridMask_.resize(1);
+      gridMask_(0) = true;
+      break;
     case 1:
       readGridMaskInfo(grid->mask_1d);
@@ -416,4 +420,5 @@
   createLocalDomainDataIndex();
   createLocalAxisDataIndex();
+  createLocalScalarDataIndex();
 
   int idxDomain = 0, idxAxis = 0;
@@ -579,52 +584,4 @@
 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;
-//    }
-//  }
 }
 
Index: XIOS/trunk/src/filter/spatial_transform_filter.cpp
===================================================================
--- XIOS/trunk/src/filter/spatial_transform_filter.cpp	(revision 887)
+++ XIOS/trunk/src/filter/spatial_transform_filter.cpp	(revision 888)
@@ -122,4 +122,5 @@
     const std::list<size_t>& listNbLocalIndexToReceive = gridTransformation->getNbLocalIndexToReceiveOnGridDest();
     const std::list<std::vector<bool> >& listLocalIndexMaskOnDest = gridTransformation->getLocalMaskIndexOnGridDest();
+    const std::vector<CGenericAlgorithmTransformation*>& listAlgos = gridTransformation->getAlgos();
 
     CArray<double,1> dataCurrentDest(dataSrc.copy());
@@ -130,6 +131,7 @@
     std::list<size_t>::const_iterator itNbListRecv = listNbLocalIndexToReceive.begin();
     std::list<std::vector<bool> >::const_iterator itLocalMaskIndexOnDest = listLocalIndexMaskOnDest.begin();
-
-    for (; itListSend != iteListSend; ++itListSend, ++itListRecv, ++itNbListRecv, ++itLocalMaskIndexOnDest)
+    std::vector<CGenericAlgorithmTransformation*>::const_iterator itAlgo = listAlgos.begin();
+
+    for (; itListSend != iteListSend; ++itListSend, ++itListRecv, ++itNbListRecv, ++itLocalMaskIndexOnDest, ++itAlgo)
     {
       CArray<double,1> dataCurrentSrc(dataCurrentDest);
@@ -189,4 +191,5 @@
         else dataCurrentDest(i) = defaultValue;
 
+      std::vector<bool> localInitFlag(dataCurrentDest.size(), true);
       currentBuff = 0;
       for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
@@ -194,8 +197,13 @@
         int countSize = itRecv->second.size();
         const std::vector<std::pair<int,double> >& localIndex_p = itRecv->second;
-        for (int idx = 0; idx < countSize; ++idx)
-        {
-          dataCurrentDest(localIndex_p[idx].first) += *(recvBuff+currentBuff+idx) * localIndex_p[idx].second;
-        }
+//        for (int idx = 0; idx < countSize; ++idx)
+//        {
+//          dataCurrentDest(localIndex_p[idx].first) += *(recvBuff+currentBuff+idx) * localIndex_p[idx].second;
+//        }
+        (*itAlgo)->apply(localIndex_p,
+                         recvBuff+currentBuff,
+                         dataCurrentDest,
+                         localInitFlag);
+
         currentBuff += countSize;
       }
Index: XIOS/trunk/src/group_factory_decl.cpp
===================================================================
--- XIOS/trunk/src/group_factory_decl.cpp	(revision 887)
+++ XIOS/trunk/src/group_factory_decl.cpp	(revision 888)
@@ -32,3 +32,4 @@
   macro(CGenerateRectilinearDomainGroup)
   macro(CScalarGroup)
+  macro(CReduceAxisToScalarGroup)
 }
Index: XIOS/trunk/src/group_template_decl.cpp
===================================================================
--- XIOS/trunk/src/group_template_decl.cpp	(revision 887)
+++ XIOS/trunk/src/group_template_decl.cpp	(revision 888)
@@ -21,4 +21,5 @@
   macro(GenerateRectilinearDomain)
   macro(Scalar)
+  macro(ReduceAxisToScalar)
 
 }
Index: XIOS/trunk/src/node/node_enum.hpp
===================================================================
--- XIOS/trunk/src/node/node_enum.hpp	(revision 887)
+++ XIOS/trunk/src/node/node_enum.hpp	(revision 888)
@@ -26,5 +26,6 @@
          eInterpolateDomain,
          eGenerateRectilinearDomain,
-         eScalar
+         eScalar,
+         eReduceAxisToScalar
 
       } ENodeType;
Index: XIOS/trunk/src/node/node_type.hpp
===================================================================
--- XIOS/trunk/src/node/node_type.hpp	(revision 887)
+++ XIOS/trunk/src/node/node_type.hpp	(revision 888)
@@ -17,4 +17,5 @@
 #include "generate_rectilinear_domain.hpp"
 #include "scalar.hpp"
+#include "reduce_axis_to_scalar.hpp"
 
 
Index: XIOS/trunk/src/node/reduce_axis_to_scalar.cpp
===================================================================
--- XIOS/trunk/src/node/reduce_axis_to_scalar.cpp	(revision 888)
+++ XIOS/trunk/src/node/reduce_axis_to_scalar.cpp	(revision 888)
@@ -0,0 +1,63 @@
+#include "reduce_axis_to_scalar.hpp"
+#include "type.hpp"
+
+namespace xios {
+
+  /// ////////////////////// DÃ©finitions ////////////////////// ///
+
+  CReduceAxisToScalar::CReduceAxisToScalar(void)
+    : CObjectTemplate<CReduceAxisToScalar>(), CReduceAxisToScalarAttributes(), CTransformation<CScalar>()
+  { /* Ne rien faire de plus */ }
+
+  CReduceAxisToScalar::CReduceAxisToScalar(const StdString & id)
+    : CObjectTemplate<CReduceAxisToScalar>(id), CReduceAxisToScalarAttributes(), CTransformation<CScalar>()
+  { /* Ne rien faire de plus */ }
+
+  CReduceAxisToScalar::~CReduceAxisToScalar(void)
+  {}
+
+  CTransformation<CScalar>* CReduceAxisToScalar::create(const StdString& id, xml::CXMLNode* node)
+  {
+    CReduceAxisToScalar* reduceAxis = CReduceAxisToScalarGroup::get("reduce_axis_definition")->createChild(id);
+    if (node) reduceAxis->parse(*node);
+    return static_cast<CTransformation<CScalar>*>(reduceAxis);
+  }
+
+  bool CReduceAxisToScalar::registerTrans()
+  {
+    return registerTransformation(TRANS_REDUCE_AXIS_TO_SCALAR, CReduceAxisToScalar::create);
+  }
+
+  bool CReduceAxisToScalar::_dummyRegistered = CReduceAxisToScalar::registerTrans();
+
+  //----------------------------------------------------------------
+
+  StdString CReduceAxisToScalar::GetName(void)    { return StdString("reduce_axis"); }
+  StdString CReduceAxisToScalar::GetDefName(void) { return StdString("reduce_axis"); }
+  ENodeType CReduceAxisToScalar::GetType(void)    { return eReduceAxisToScalar; }
+
+  void CReduceAxisToScalar::checkValid(CScalar* scalarDst)
+  {
+//    int axisIBegin, axisNi, axisGlobalSize;
+//    int begin, end, n;
+//
+//    axisIBegin = axisDest->begin.getValue();
+//    axisNi     = axisDest->n.getValue();
+//    axisGlobalSize   = axisDest->n_glo.getValue();
+//
+//    begin = (this->begin.isEmpty()) ?  0 : this->begin.getValue();
+//    n     = (this->n.isEmpty()) ?  axisGlobalSize : this->n.getValue();
+//    end   = begin+n-1;
+//
+//    if (begin < 0 || begin > axisGlobalSize - 1 || end < 0 || end > axisGlobalSize - 1
+//        || n < 1 || n > axisGlobalSize || begin > end)
+//      ERROR("CReduceAxisToScalar::checkValid(CAxis* axisDest)",
+//            << "One or more attributes among 'begin' (" << begin << "), 'end' (" << end << "), 'n' (" << n << ") "
+//            << "of axis transformation [ id = '" << axisDest->getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
+//
+//    this->begin.setValue(begin);
+//    this->n.setValue(n);
+
+  }
+
+}
Index: XIOS/trunk/src/node/reduce_axis_to_scalar.hpp
===================================================================
--- XIOS/trunk/src/node/reduce_axis_to_scalar.hpp	(revision 888)
+++ XIOS/trunk/src/node/reduce_axis_to_scalar.hpp	(revision 888)
@@ -0,0 +1,66 @@
+#ifndef __XIOS_CReduceAxisToScalar__
+#define __XIOS_CReduceAxisToScalar__
+
+/// xios headers ///
+#include "xios_spl.hpp"
+#include "attribute_enum.hpp"
+#include "attribute_enum_impl.hpp"
+#include "attribute_array.hpp"
+#include "declare_attribute.hpp"
+#include "object_template.hpp"
+#include "group_factory.hpp"
+#include "declare_group.hpp"
+#include "transformation.hpp"
+
+namespace xios {
+  /// ////////////////////// DÃ©clarations ////////////////////// ///
+  class CReduceAxisToScalarGroup;
+  class CReduceAxisToScalarAttributes;
+  class CReduceAxisToScalar;
+  class CScalar;
+
+  ///--------------------------------------------------------------
+
+  // Declare/Define CFileAttribute
+  BEGIN_DECLARE_ATTRIBUTE_MAP(CReduceAxisToScalar)
+#include "reduce_axis_to_scalar_attribute.conf"
+  END_DECLARE_ATTRIBUTE_MAP(CReduceAxisToScalar)
+
+  ///--------------------------------------------------------------
+  /*!
+    \class CReduceAxisToScalar
+    This class describes reduce_axis in xml file.
+  */
+  class CReduceAxisToScalar
+    : public CObjectTemplate<CReduceAxisToScalar>
+    , public CReduceAxisToScalarAttributes
+    , public CTransformation<CScalar>
+  {
+    public :
+      typedef CObjectTemplate<CReduceAxisToScalar> SuperClass;
+      typedef CReduceAxisToScalarAttributes SuperClassAttribute;
+
+    public :
+      /// Constructeurs ///
+      CReduceAxisToScalar(void);
+      explicit CReduceAxisToScalar(const StdString& id);
+
+      /// Destructeur ///
+      virtual ~CReduceAxisToScalar(void);
+
+      virtual void checkValid(CScalar* scalarDst);
+
+      /// Accesseurs statiques ///
+      static StdString GetName(void);
+      static StdString GetDefName(void);
+      static ENodeType GetType(void);
+    private:
+      static bool registerTrans();
+      static CTransformation<CScalar>* create(const StdString& id, xml::CXMLNode* node);
+      static bool _dummyRegistered;
+  }; // class CReduceAxisToScalar
+
+  DECLARE_GROUP(CReduceAxisToScalar);
+} // namespace xios
+
+#endif // __XIOS_CReduceAxisToScalar__
Index: XIOS/trunk/src/node/scalar.cpp
===================================================================
--- XIOS/trunk/src/node/scalar.cpp	(revision 887)
+++ XIOS/trunk/src/node/scalar.cpp	(revision 888)
@@ -27,4 +27,11 @@
    { /* Ne rien faire de plus */ }
 
+   std::map<StdString, ETranformationType> CScalar::transformationMapList_ = std::map<StdString, ETranformationType>();
+   bool CScalar::dummyTransformationMapList_ = CScalar::initializeTransformationMap(CScalar::transformationMapList_);
+   bool CScalar::initializeTransformationMap(std::map<StdString, ETranformationType>& m)
+   {
+     m["reduce_axis"] = TRANS_REDUCE_AXIS_TO_SCALAR;
+   }
+
    StdString CScalar::GetName(void)   { return (StdString("scalar")); }
    StdString CScalar::GetDefName(void){ return (CScalar::GetName()); }
@@ -49,8 +56,4 @@
    void CScalar::checkAttributes(void)
    {
-//      if (this->value.isEmpty())
-//      {
-//        this->value.setValue(0);
-//      }
    }
 
@@ -124,4 +127,34 @@
   }
 
+  /*!
+    Parse children nodes of a scalar in xml file.
+    \param node child node to process
+  */
+  void CScalar::parse(xml::CXMLNode & node)
+  {
+    SuperClass::parse(node);
+
+    if (node.goToChildElement())
+    {
+      StdString nodeElementName;
+      do
+      {
+        StdString nodeId("");
+        if (node.getAttributes().end() != node.getAttributes().find("id"))
+        { nodeId = node.getAttributes()["id"]; }
+
+        nodeElementName = node.getElementName();
+        std::map<StdString, ETranformationType>::const_iterator ite = transformationMapList_.end(), it;
+        it = transformationMapList_.find(nodeElementName);
+        if (ite != it)
+        {
+          transformationMap_.push_back(std::make_pair(it->second, CTransformation<CScalar>::createTransformation(it->second,
+                                                                                                                 nodeId,
+                                                                                                                 &node)));
+        }
+      } while (node.goToNextElement()) ;
+      node.goToParentElement();
+    }
+  }
 
   // Definition of some macros
Index: XIOS/trunk/src/node/scalar.hpp
===================================================================
--- XIOS/trunk/src/node/scalar.hpp	(revision 887)
+++ XIOS/trunk/src/node/scalar.hpp	(revision 888)
@@ -68,4 +68,5 @@
             bool IsWritten(const StdString& filename) const;
             void checkAttributesOnClient();
+            virtual void parse(xml::CXMLNode & node);
 
          public:
@@ -75,4 +76,5 @@
            void duplicateTransformation(CScalar*);
            CTransformation<CScalar>* addTransformation(ETranformationType transType, const StdString& id="");
+
          private:
            std::set<StdString> relFiles;
@@ -82,5 +84,11 @@
             void checkTransformations();
             void setTransformations(const TransMapTypes&);
-         private:
+
+       private:
+           static bool initializeTransformationMap(std::map<StdString, ETranformationType>& m);
+           static std::map<StdString, ETranformationType> transformationMapList_;
+           static bool dummyTransformationMapList_;
+
+
             DECLARE_REF_FUNC(Scalar,scalar)
 
Index: XIOS/trunk/src/node/transformation_enum.hpp
===================================================================
--- XIOS/trunk/src/node/transformation_enum.hpp	(revision 887)
+++ XIOS/trunk/src/node/transformation_enum.hpp	(revision 888)
@@ -12,5 +12,6 @@
         TRANS_ZOOM_DOMAIN = 3,
         TRANS_INTERPOLATE_DOMAIN = 4,
-        TRANS_GENERATE_RECTILINEAR_DOMAIN = 5
+        TRANS_GENERATE_RECTILINEAR_DOMAIN = 5,
+        TRANS_REDUCE_AXIS_TO_SCALAR = 6
       } ETranformationType;
 
Index: XIOS/trunk/src/object_factory_decl.cpp
===================================================================
--- XIOS/trunk/src/object_factory_decl.cpp	(revision 887)
+++ XIOS/trunk/src/object_factory_decl.cpp	(revision 888)
@@ -33,4 +33,5 @@
   macro(CGenerateRectilinearDomain)
   macro(CScalar)
+  macro(CReduceAxisToScalar)
 
   macro(CFieldGroup)
@@ -48,3 +49,4 @@
   macro(CGenerateRectilinearDomainGroup)
   macro(CScalarGroup)
+  macro(CReduceAxisToScalarGroup)
 }
Index: XIOS/trunk/src/object_template_decl.cpp
===================================================================
--- XIOS/trunk/src/object_template_decl.cpp	(revision 887)
+++ XIOS/trunk/src/object_template_decl.cpp	(revision 888)
@@ -20,4 +20,5 @@
   template class CObjectTemplate<CGenerateRectilinearDomain>;
   template class CObjectTemplate<CScalar>;
+  template class CObjectTemplate<CReduceAxisToScalar>;
 
   template class CObjectTemplate<CContextGroup>;
@@ -35,3 +36,4 @@
   template class CObjectTemplate<CGenerateRectilinearDomainGroup>;
   template class CObjectTemplate<CScalarGroup>;
+  template class CObjectTemplate<CReduceAxisToScalarGroup>;
 }
Index: XIOS/trunk/src/transformation/Functions/max.cpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/max.cpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/max.cpp	(revision 888)
@@ -0,0 +1,52 @@
+/*!
+   \file max.cpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief max reduction
+ */
+#include "max.hpp"
+
+namespace xios {
+
+CMaxReductionAlgorithm::CMaxReductionAlgorithm()
+  : CReductionAlgorithm()
+{
+}
+
+CReductionAlgorithm* CMaxReductionAlgorithm::create()
+{
+  return (new CMaxReductionAlgorithm());
+}
+
+bool CMaxReductionAlgorithm::registerTrans()
+{
+  return registerOperation(TRANS_REDUCE_MAX, CMaxReductionAlgorithm::create);
+}
+
+void CMaxReductionAlgorithm::apply(const std::vector<std::pair<int,double> >& localIndex,
+                                   const double* dataInput,
+                                   CArray<double,1>& dataOut,
+                                   std::vector<bool>& flagInitial)
+{
+  int nbLocalIndex = localIndex.size();
+  int currentlocalIndex = 0;
+  double currentWeight  = 0.0;
+  for (int idx = 0; idx < nbLocalIndex; ++idx)
+  {
+    currentlocalIndex = localIndex[idx].first;
+    currentWeight     = localIndex[idx].second;
+    if (flagInitial[currentlocalIndex])
+    {
+      dataOut(currentlocalIndex) = *(dataInput + idx);
+      flagInitial[currentlocalIndex] = false;
+    }
+    else
+    {
+      dataOut(currentlocalIndex) = std::max(*(dataInput + idx), dataOut(currentlocalIndex));
+    }
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/Functions/max.hpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/max.hpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/max.hpp	(revision 888)
@@ -0,0 +1,40 @@
+/*!
+   \file max.hpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief Max reduction
+ */
+#ifndef __XIOS_REDUCTION_MAX_ALGORITHM_HPP__
+#define __XIOS_REDUCTION_MAX_ALGORITHM_HPP__
+
+#include "reduction.hpp"
+
+namespace xios {
+
+/*!
+  \class CMaxReductionAlgorithm
+  Interface for all reduction alogrithms.
+*/
+class CMaxReductionAlgorithm : public CReductionAlgorithm
+{
+public:
+  CMaxReductionAlgorithm();
+
+  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
+                     const double* dataInput,
+                     CArray<double,1>& dataOut,
+                     std::vector<bool>& flagInitial);
+
+  virtual ~CMaxReductionAlgorithm() {}
+
+public:
+  static bool registerTrans();
+
+protected:
+  static CReductionAlgorithm* create();
+};
+
+}
+#endif // __XIOS_REDUCTION_MAX_ALGORITHM_HPP__
Index: XIOS/trunk/src/transformation/Functions/min.cpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/min.cpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/min.cpp	(revision 888)
@@ -0,0 +1,50 @@
+/*!
+   \file min.cpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief min reduction
+ */
+#include "min.hpp"
+
+namespace xios {
+
+CMinReductionAlgorithm::CMinReductionAlgorithm()
+  : CReductionAlgorithm()
+{
+}
+
+CReductionAlgorithm* CMinReductionAlgorithm::create()
+{
+  return (new CMinReductionAlgorithm());
+}
+
+bool CMinReductionAlgorithm::registerTrans()
+{
+  return registerOperation(TRANS_REDUCE_MIN, CMinReductionAlgorithm::create);
+}
+
+void CMinReductionAlgorithm::apply(const std::vector<std::pair<int,double> >& localIndex,
+                                   const double* dataInput,
+                                   CArray<double,1>& dataOut,
+                                   std::vector<bool>& flagInitial)
+{
+  int nbLocalIndex = localIndex.size();
+  int currentlocalIndex = 0;
+  for (int idx = 0; idx < nbLocalIndex; ++idx)
+  {
+    currentlocalIndex = localIndex[idx].first;
+    if (flagInitial[currentlocalIndex])
+    {
+      dataOut(currentlocalIndex) = *(dataInput + idx);
+      flagInitial[currentlocalIndex] = false;
+    }
+    else
+    {
+      dataOut(currentlocalIndex) = std::min(*(dataInput + idx), dataOut(currentlocalIndex));
+    }
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/Functions/min.hpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/min.hpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/min.hpp	(revision 888)
@@ -0,0 +1,40 @@
+/*!
+   \file min.hpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief Min reduction
+ */
+#ifndef __XIOS_REDUCTION_MIN_ALGORITHM_HPP__
+#define __XIOS_REDUCTION_MIN_ALGORITHM_HPP__
+
+#include "reduction.hpp"
+
+namespace xios {
+
+/*!
+  \class CMinReductionAlgorithm
+  Interface for all reduction alogrithms.
+*/
+class CMinReductionAlgorithm : public CReductionAlgorithm
+{
+public:
+  CMinReductionAlgorithm();
+
+  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
+                     const double* dataInput,
+                     CArray<double,1>& dataOut,
+                     std::vector<bool>& flagInitial);
+
+  virtual ~CMinReductionAlgorithm() {}
+
+public:
+  static bool registerTrans();
+
+protected:
+  static CReductionAlgorithm* create();
+};
+
+}
+#endif // __XIOS_REDUCTION_MIN_ALGORITHM_HPP__
Index: XIOS/trunk/src/transformation/Functions/reduction.cpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/reduction.cpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/reduction.cpp	(revision 888)
@@ -0,0 +1,53 @@
+#include "reduction.hpp"
+#include "sum.hpp"
+#include "min.hpp"
+#include "max.hpp"
+
+namespace xios {
+
+CReductionAlgorithm::CallBackMap* CReductionAlgorithm::reductionCreationCallBacks_ = 0;
+std::map<StdString,EReductionType> CReductionAlgorithm::ReductionOperations = std::map<StdString,EReductionType>();
+bool CReductionAlgorithm::initReductionOperation(std::map<StdString,EReductionType>& m)
+{
+  // So so stupid way to intialize operation but it works ...
+  m["sum"] = TRANS_REDUCE_SUM;
+  CSumReductionAlgorithm::registerTrans();
+
+  m["min"] = TRANS_REDUCE_MIN;
+  CMinReductionAlgorithm::registerTrans();
+
+  m["max"] = TRANS_REDUCE_MAX;
+  CMaxReductionAlgorithm::registerTrans();
+}
+
+bool CReductionAlgorithm::_dummyInit = CReductionAlgorithm::initReductionOperation(CReductionAlgorithm::ReductionOperations);
+
+CReductionAlgorithm* CReductionAlgorithm::createOperation(EReductionType reduceType)
+{
+  int reduceTypeInt = reduceType;
+  typename CallBackMap::const_iterator it = (*reductionCreationCallBacks_).find(reduceType);
+  if ((*reductionCreationCallBacks_).end() == it)
+  {
+     ERROR("CReductionAlgorithm::createOperation(EReductionType reduceType)",
+           << "Operation type " << reduceType
+           << "doesn't exist. Please define.");
+  }
+  return (it->second)();
+}
+
+bool CReductionAlgorithm::registerOperation(EReductionType reduceType, CreateOperationCallBack createFn)
+{
+  if (0 == reductionCreationCallBacks_)
+    reductionCreationCallBacks_ = new CallBackMap();
+
+  return (*reductionCreationCallBacks_).insert(make_pair(reduceType, createFn)).second;
+}
+
+bool CReductionAlgorithm::unregisterOperation(EReductionType reduceType)
+{
+  int reduceTypeInt = reduceType;
+  return (1 == (*reductionCreationCallBacks_).erase(reduceType));
+}
+
+
+}
Index: XIOS/trunk/src/transformation/Functions/reduction.hpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/reduction.hpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/reduction.hpp	(revision 888)
@@ -0,0 +1,65 @@
+/*!
+   \file reduction.hpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief Parent class for all reduction
+ */
+#ifndef __XIOS_REDUCTION_ALGORITHM_HPP__
+#define __XIOS_REDUCTION_ALGORITHM_HPP__
+
+#include <vector>
+#include "array_new.hpp"
+#include "reduction_types.hpp"
+
+namespace xios {
+
+/*!
+  \class CReductionAlgorithm
+  Interface for all reduction alogrithms.
+*/
+class CReductionAlgorithm
+{
+public:
+  static std::map<StdString,EReductionType> ReductionOperations;
+
+public:
+  CReductionAlgorithm() {}
+
+  /*!
+    Create an operation (sum, max, min) based on type
+    \param [in] reduceType type to create
+    return pointer to base class
+  */
+  static CReductionAlgorithm* createOperation(EReductionType reduceType);
+
+  /*!
+    Apply a reduction operation on local data.
+    \param [in] localIndex vector contains local index of local data output and the corresponding weight
+    \param [in] dataInput Pointer to the first element of data input array (in form of buffer)
+    \param [in/out] dataOut Array contains local data
+    \param [in/out] flagInitial vector of boolean to mark the local index already initialized. True means there is a need for initalization
+  */
+  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
+                     const double* dataInput,
+                     CArray<double,1>& dataOut,
+                     std::vector<bool>& flagInitial) = 0;
+
+  virtual ~CReductionAlgorithm() {}
+
+protected:
+  typedef CReductionAlgorithm* (*CreateOperationCallBack)();
+  typedef std::map<EReductionType, CreateOperationCallBack> CallBackMap;
+  static CallBackMap* reductionCreationCallBacks_;
+
+  static bool registerOperation(EReductionType reduceType, CreateOperationCallBack createFn);
+  static bool unregisterOperation(EReductionType reduceType);
+
+protected:
+  static bool initReductionOperation(std::map<StdString,EReductionType>& m);
+  static bool _dummyInit;
+};
+
+}
+#endif // __XIOS_REDUCTION_ALGORITHM_HPP__
Index: XIOS/trunk/src/transformation/Functions/reduction_types.hpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/reduction_types.hpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/reduction_types.hpp	(revision 888)
@@ -0,0 +1,22 @@
+/*!
+   \file reduction_types.hpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief Different reduction types
+ */
+#ifndef __XIOS_REDUCTION_TYPES_HPP__
+#define __XIOS_REDUCTION_TYPES_HPP__
+
+namespace xios {
+
+  typedef enum reduction_alogirthm_type
+  {
+    TRANS_REDUCE_SUM = 0,
+    TRANS_REDUCE_MIN = 1,
+    TRANS_REDUCE_MAX = 2
+  } EReductionType;
+
+}
+#endif // __XIOS_REDUCTION_TYPES_HPP__
Index: XIOS/trunk/src/transformation/Functions/sum.cpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/sum.cpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/sum.cpp	(revision 888)
@@ -0,0 +1,52 @@
+/*!
+   \file sum.cpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief sum reduction
+ */
+#include "sum.hpp"
+
+namespace xios {
+
+CSumReductionAlgorithm::CSumReductionAlgorithm()
+  : CReductionAlgorithm()
+{
+}
+
+CReductionAlgorithm* CSumReductionAlgorithm::create()
+{
+  return (new CSumReductionAlgorithm());
+}
+
+bool CSumReductionAlgorithm::registerTrans()
+{
+  return registerOperation(TRANS_REDUCE_SUM, CSumReductionAlgorithm::create);
+}
+
+void CSumReductionAlgorithm::apply(const std::vector<std::pair<int,double> >& localIndex,
+                                   const double* dataInput,
+                                   CArray<double,1>& dataOut,
+                                   std::vector<bool>& flagInitial)
+{
+  int nbLocalIndex = localIndex.size();
+  int currentlocalIndex = 0;
+  double currentWeight  = 0.0;
+  for (int idx = 0; idx < nbLocalIndex; ++idx)
+  {
+    currentlocalIndex = localIndex[idx].first;
+    currentWeight     = localIndex[idx].second;
+    if (flagInitial[currentlocalIndex])
+    {
+      dataOut(currentlocalIndex) = *(dataInput + idx);
+      flagInitial[currentlocalIndex] = false;
+    }
+    else
+    {
+      dataOut(currentlocalIndex) += *(dataInput + idx);
+    }
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/Functions/sum.hpp
===================================================================
--- XIOS/trunk/src/transformation/Functions/sum.hpp	(revision 888)
+++ XIOS/trunk/src/transformation/Functions/sum.hpp	(revision 888)
@@ -0,0 +1,40 @@
+/*!
+   \file sum.hpp
+   \author Ha NGUYEN
+   \since 27 June 2016
+   \date 27 June 2016
+
+   \brief Sum reduction
+ */
+#ifndef __XIOS_REDUCTION_SUM_ALGORITHM_HPP__
+#define __XIOS_REDUCTION_SUM_ALGORITHM_HPP__
+
+#include "reduction.hpp"
+
+namespace xios {
+
+/*!
+  \class CSumReductionAlgorithm
+  Interface for all reduction alogrithms.
+*/
+class CSumReductionAlgorithm : public CReductionAlgorithm
+{
+public:
+  CSumReductionAlgorithm();
+
+  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
+                     const double* dataInput,
+                     CArray<double,1>& dataOut,
+                     std::vector<bool>& flagInitial);
+
+  virtual ~CSumReductionAlgorithm() {}
+
+public:
+  static bool registerTrans();
+
+protected:
+  static CReductionAlgorithm* create();
+};
+
+}
+#endif // __XIOS_REDUCTION_SUM_ALGORITHM_HPP__
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 887)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 888)
@@ -43,4 +43,5 @@
 */
 void CAxisAlgorithmTransformation::computeExchangeGlobalIndex(const CArray<size_t,1>& globalAxisIndex,
+                                                              int elementType,
                                                               CClientClientDHTInt::Index2VectorInfoTypeMap& globalAxisIndexOnProc)
 {
@@ -49,4 +50,5 @@
   int clientRank = client->clientRank;
   int clientSize = client->clientSize;
+
 
   size_t globalIndex;
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 887)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 888)
@@ -30,4 +30,5 @@
 
   virtual void computeExchangeGlobalIndex(const CArray<size_t,1>& globalAxisIndex,
+                                          int elementType,
                                           CClientClientDHTInt::Index2VectorInfoTypeMap& globalDomainIndexOnProc);
 
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 887)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 888)
@@ -34,4 +34,5 @@
 */
 void CDomainAlgorithmTransformation::computeExchangeGlobalIndex(const CArray<size_t,1>& globalDomainIndex,
+                                                                int elementType,
                                                                 CClientClientDHTInt::Index2VectorInfoTypeMap& globalDomainIndexOnProc)
 {
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 887)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 888)
@@ -31,5 +31,6 @@
 
   virtual void computeExchangeGlobalIndex(const CArray<size_t,1>& globalDomainIndex,
-                                  CClientClientDHTInt::Index2VectorInfoTypeMap& globalDomainIndexOnProc);
+                                          int elementType,
+                                          CClientClientDHTInt::Index2VectorInfoTypeMap& globalDomainIndexOnProc);
 
 protected:
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 887)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 888)
@@ -17,4 +17,63 @@
  : transformationMapping_(), transformationWeight_(), transformationPosition_(), idAuxInputs_()
 {
+}
+
+void CGenericAlgorithmTransformation::apply(const std::vector<std::pair<int,double> >& localIndex,
+                                            const double* dataInput,
+                                            CArray<double,1>& dataOut,
+                                            std::vector<bool>& flagInitial)
+{
+  int nbLocalIndex = localIndex.size();
+  for (int idx = 0; idx < nbLocalIndex; ++idx)
+  {
+    dataOut(localIndex[idx].first) = *(dataInput + idx) * localIndex[idx].second;
+  }
+}
+
+void CGenericAlgorithmTransformation::computePositionElements(CGrid* dst, CGrid* src)
+{
+  int idxScalar = 0, idxAxis = 0, idxDomain = 0;
+  CArray<int,1> axisDomainOrderDst = dst->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 = src->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;
+    }
+  }
 }
 
@@ -82,9 +141,14 @@
   }
 
+  // compute position of elements on grids
+  computePositionElements(gridDst, gridSrc);
+  std::vector<CScalar*> scalarListDestP = gridDst->getScalars();
   std::vector<CAxis*> axisListDestP = gridDst->getAxis();
   std::vector<CDomain*> domainListDestP = gridDst->getDomains();
   CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
+  std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars();
   std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
   std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
+  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;
 
   // Find out global index source of transformed element on corresponding process.
@@ -95,10 +159,10 @@
   {
     if (idx == elementPositionInGrid)
-      computeExchangeGlobalIndex(indexSrc, globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]);
+      computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]);
     if (2 == axisDomainDstOrder(idx)) // It's domain
     {
       if (idx != elementPositionInGrid)
-        computeExchangeDomainIndex(domainListDestP[domainIndex],
-                                   domainListSrcP[domainIndex],
+        computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]],
+                                   domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]],
                                    transPos,
                                    globalElementIndexOnProc[idx]);
@@ -109,9 +173,18 @@
     {
       if (idx != elementPositionInGrid)
-        computeExchangeAxisIndex(axisListDestP[axisIndex],
-                                 axisListSrcP[axisIndex],
+        computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]],
+                                 axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]],
                                  transPos,
                                  globalElementIndexOnProc[idx]);
       ++axisIndex;
+
+    }
+    else //it's a scalar
+    {
+      if (idx != elementPositionInGrid)
+        computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]],
+                                   scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]],
+                                   transPos,
+                                   globalElementIndexOnProc[idx]);
 
     }
@@ -269,5 +342,5 @@
   {
     nGlobDst[idx] = globalDstSize;
-    int elementDimension = axisDomainSrcOrder(idx);
+    int elementDimension = axisDomainDstOrder(idx);
 
     // If this is a domain
@@ -359,4 +432,28 @@
 /*!
   Find out proc and global index of axis source which axis destination is on demande
+  \param[in] scalar Scalar destination
+  \param[in] scalar Scalar source
+  \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid.
+  \param[out] globalScalarIndexOnProc Global index of axis source on different procs
+*/
+void CGenericAlgorithmTransformation::computeExchangeScalarIndex(CScalar* scalarDst,
+                                                                 CScalar* scalarSrc,
+                                                                 CArray<size_t,1>& destGlobalIndexPositionInGrid,
+                                                                 boost::unordered_map<int,std::vector<size_t> >& globalScalarIndexOnProc)
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+  int clientRank = client->clientRank;
+  int clientSize = client->clientSize;
+
+  globalScalarIndexOnProc.rehash(std::ceil(clientSize/globalScalarIndexOnProc.max_load_factor()));
+  for (int idx = 0; idx < clientSize; ++idx)
+  {
+    globalScalarIndexOnProc[idx].push_back(0);
+  }
+}
+
+/*!
+  Find out proc and global index of axis source which axis destination is on demande
   \param[in] axisDst Axis destination
   \param[in] axisSrc Axis source
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 887)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 888)
@@ -19,4 +19,5 @@
   class CDomain;
   class CAxis;
+  class CScalar;
 
   /*!
@@ -52,4 +53,16 @@
                                SourceDestinationIndexMap& globaIndexWeightFromSrcToDst);
 
+    /*!
+    Apply a reduction operation on local data.
+    \param [in] localIndex vector contains local index of local data output and the corresponding weight
+    \param [in] dataInput Pointer to the first element of data input array (in form of buffer)
+    \param [in/out] dataOut Array contains local data
+    \param [in/out] flagInitial vector of boolean to mark the local index already initialized. True means there is a need for initalization
+  */
+  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
+                     const double* dataInput,
+                     CArray<double,1>& dataOut,
+                     std::vector<bool>& flagInitial);
+
   std::vector<StdString> getIdAuxInputs();
 
@@ -65,7 +78,9 @@
   Compute proc which contains global index of an element
     \param[in] globalElementIndex demanding global index of an element of source grid
+    \param[in] elementType type of source element, 2: domain, 1: axis and 0: scalar
     \param[out] globalElementIndexOnProc Proc contains the demanding global index
   */
   virtual void computeExchangeGlobalIndex(const CArray<size_t,1>& globalElementIndex,
+                                          int elementType,
                                           CClientClientDHTInt::Index2VectorInfoTypeMap& globalElementIndexOnProc) = 0;
 
@@ -89,4 +104,11 @@
                                 boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc);
 
+  void computeExchangeScalarIndex(CScalar* scalarDst,
+                                  CScalar* scalarSrc,
+                                  CArray<size_t,1>& destGlobalIndexPositionInGrid,
+                                  boost::unordered_map<int,std::vector<size_t> >& globalScalarIndexOnProc);
+
+  void computePositionElements(CGrid* dst, CGrid* src);
+
 protected:
   //! Map between global index of destination element and source element
@@ -100,4 +122,7 @@
   //! Id of auxillary inputs which helps doing transformation dynamically
   std::vector<StdString> idAuxInputs_;
+
+  std::map<int, int> elementPositionInGridSrc2AxisPosition_, elementPositionInGridSrc2DomainPosition_, elementPositionInGridSrc2ScalarPosition_;
+  std::map<int, int> elementPositionInGridDst2AxisPosition_, elementPositionInGridDst2DomainPosition_, elementPositionInGridDst2ScalarPosition_;
 };
 
Index: XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 887)
+++ XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 888)
@@ -8,4 +8,6 @@
  */
 #include "grid_transformation.hpp"
+#include "reduce_axis_to_scalar.hpp"
+#include "scalar_algorithm_reduce_axis.hpp"
 #include "axis_algorithm_inverse.hpp"
 #include "axis_algorithm_zoom.hpp"
@@ -42,5 +44,29 @@
 void CGridTransformation::selectScalarAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
 {
-
+  int scalarSrcIndex = -1, axisSrcIndex = -1, domainSrcIndex = -1;
+  std::vector<CScalar*> scaListDestP = gridDestination_->getScalars();
+  std::vector<CScalar*> scaListSrcP  = gridSource_->getScalars();
+  std::vector<CAxis*> axisListSrcP   = gridSource_->getAxis();
+  std::vector<CDomain*> domainListSrcP = gridSource_->getDomains();
+
+  int scalarDstIndex =  elementPositionInGridDst2ScalarPosition_[elementPositionInGrid];
+  CScalar::TransMapTypes trans = scaListDestP[scalarDstIndex]->getAllTransformations();
+  CScalar::TransMapTypes::const_iterator it = trans.begin();
+
+  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
+
+  CReduceAxisToScalar* reduceAxis = 0;
+  CGenericAlgorithmTransformation* algo = 0;
+  switch (transType)
+  {
+    case TRANS_REDUCE_AXIS_TO_SCALAR:
+      reduceAxis = dynamic_cast<CReduceAxisToScalar*> (it->second);
+      axisSrcIndex = elementPositionInGridSrc2AxisPosition_[elementPositionInGrid];
+      algo = new CScalarAlgorithmReduceScalar(scaListDestP[scalarDstIndex], axisListSrcP[axisSrcIndex], reduceAxis);
+      break;
+    default:
+      break;
+  }
+  algoTransformation_.push_back(algo);
 }
 
@@ -53,9 +79,11 @@
 void CGridTransformation::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
 {
+  int axisSrcIndex = -1, domainSrcIndex = -1;
   std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
   std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
-
-  int axisIndex =  elementPositionInGridDst2AxisPosition_[elementPositionInGrid];
-  CAxis::TransMapTypes trans = axisListDestP[axisIndex]->getAllTransformations();
+  std::vector<CDomain*> domainListSrcP = gridSource_->getDomains();
+
+  int axisDstIndex =  elementPositionInGridDst2AxisPosition_[elementPositionInGrid];
+  CAxis::TransMapTypes trans = axisListDestP[axisDstIndex]->getAllTransformations();
   CAxis::TransMapTypes::const_iterator it = trans.begin();
 
@@ -69,12 +97,15 @@
     case TRANS_INTERPOLATE_AXIS:
       interpAxis = dynamic_cast<CInterpolateAxis*> (it->second);
-      algo = new CAxisAlgorithmInterpolate(axisListDestP[axisIndex], axisListSrcP[axisIndex], interpAxis);
+      axisSrcIndex = elementPositionInGridSrc2AxisPosition_[elementPositionInGrid];
+      algo = new CAxisAlgorithmInterpolate(axisListDestP[axisDstIndex], axisListSrcP[axisSrcIndex], interpAxis);
       break;
     case TRANS_ZOOM_AXIS:
       zoomAxis = dynamic_cast<CZoomAxis*> (it->second);
-      algo = new CAxisAlgorithmZoom(axisListDestP[axisIndex], axisListSrcP[axisIndex], zoomAxis);
+      axisSrcIndex = elementPositionInGridSrc2AxisPosition_[elementPositionInGrid];
+      algo = new CAxisAlgorithmZoom(axisListDestP[axisDstIndex], axisListSrcP[axisSrcIndex], zoomAxis);
       break;
     case TRANS_INVERSE_AXIS:
-      algo = new CAxisAlgorithmInverse(axisListDestP[axisIndex], axisListSrcP[axisIndex]);
+      axisSrcIndex = elementPositionInGridSrc2AxisPosition_[elementPositionInGrid];
+      algo = new CAxisAlgorithmInverse(axisListDestP[axisDstIndex], axisListSrcP[axisSrcIndex]);
       break;
     default:
@@ -159,4 +190,8 @@
     case TRANS_INVERSE_AXIS:
       axisIndex =  elementPositionInGridDst2AxisPosition_[elementPositionInGrid];
+      break;
+
+    case TRANS_REDUCE_AXIS_TO_SCALAR:
+      scalarIndex = elementPositionInGridDst2ScalarPosition_[elementPositionInGrid];
       break;
     default:
@@ -233,4 +268,8 @@
     case TRANS_INVERSE_AXIS:
       axisIndex =  elementPositionInGridDst2AxisPosition_[elementPositionInGrid];
+      break;
+
+    case TRANS_REDUCE_AXIS_TO_SCALAR:
+      scalarIndex = elementPositionInGridDst2ScalarPosition_[elementPositionInGrid];
       break;
     default:
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 888)
@@ -42,4 +42,5 @@
   int getNbAlgo() { return nbNormalAlgos_; }
   const std::vector<StdString>& getAuxInputs() const { return auxInputs_; }
+  const std::vector<CGenericAlgorithmTransformation*>& getAlgos() const { return algoTransformation_; }
 
 protected:
@@ -80,5 +81,5 @@
   std::vector<CGenericAlgorithmTransformation*> algoTransformation_;
 
-  //! Position of axis and domain in grid
+  //! Position of scalar, axis and domain in grid
   std::map<int, int> elementPositionInGridSrc2AxisPosition_, elementPositionInGridSrc2DomainPosition_, elementPositionInGridSrc2ScalarPosition_;
   std::map<int, int> elementPositionInGridDst2AxisPosition_, elementPositionInGridDst2DomainPosition_, elementPositionInGridDst2ScalarPosition_;
Index: XIOS/trunk/src/transformation/scalar_algorithm_reduce_axis.cpp
===================================================================
--- XIOS/trunk/src/transformation/scalar_algorithm_reduce_axis.cpp	(revision 888)
+++ XIOS/trunk/src/transformation/scalar_algorithm_reduce_axis.cpp	(revision 888)
@@ -0,0 +1,70 @@
+/*!
+   \file scalar_algorithm_reduce_scalar.cpp
+   \author Ha NGUYEN
+   \since 23 June 2016
+   \date 23 June 2016
+
+   \brief Algorithm for reduce an axis to a scalar
+ */
+#include "scalar_algorithm_reduce_axis.hpp"
+//#include "context.hpp"
+//#include "context_client.hpp"
+//#include "client_client_dht_template.hpp"
+#include "axis.hpp"
+#include "scalar.hpp"
+#include "reduce_axis_to_scalar.hpp"
+#include "sum.hpp"
+
+namespace xios {
+
+CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CScalar* scalarDestination, CAxis* axisSource, CReduceAxisToScalar* algo)
+ : CScalarAlgorithmTransformation(scalarDestination, axisSource),
+   reduction_(0)
+{
+  if (algo->operation.isEmpty())
+    ERROR("CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CAxis* axisDestination, CAxis* axisSource, CReduceAxisToScalar* algo)",
+           << "Operation must be defined."
+           << "Axis source " <<axisSource->getId() << std::endl
+           << "Scalar destination " << scalarDestination->getId());
+  StdString op = algo->operation;
+  if (CReductionAlgorithm::ReductionOperations.end() == CReductionAlgorithm::ReductionOperations.find(op))
+    ERROR("CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CAxis* axisDestination, CAxis* axisSource, CReduceAxisToScalar* algo)",
+       << "Operation '" << op << "' not found. Please make sure to use a supported one"
+       << "Axis source " <<axisSource->getId() << std::endl
+       << "Scalar destination " << scalarDestination->getId());
+
+  reduction_ = CReductionAlgorithm::createOperation(CReductionAlgorithm::ReductionOperations[op]);
+}
+
+void CScalarAlgorithmReduceScalar::apply(const std::vector<std::pair<int,double> >& localIndex,
+                                         const double* dataInput,
+                                         CArray<double,1>& dataOut,
+                                         std::vector<bool>& flagInitial)
+{
+  reduction_->apply(localIndex, dataInput, dataOut, flagInitial);
+}
+
+CScalarAlgorithmReduceScalar::~CScalarAlgorithmReduceScalar()
+{
+  if (0 != reduction_) delete reduction_;
+}
+
+void CScalarAlgorithmReduceScalar::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
+{
+  this->transformationMapping_.resize(1);
+  this->transformationWeight_.resize(1);
+
+  TransformationIndexMap& transMap = this->transformationMapping_[0];
+  TransformationWeightMap& transWeight = this->transformationWeight_[0];
+
+  CArray<int,1>& axisSrcIndex = axisSrc_->index;
+  int globalIndexSize = axisSrcIndex.numElements();
+
+  for (int idx = 0; idx < globalIndexSize; ++idx)
+  {
+    transMap[0].push_back(axisSrcIndex(idx));
+    transWeight[0].push_back(1.0);
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/scalar_algorithm_reduce_axis.hpp
===================================================================
--- XIOS/trunk/src/transformation/scalar_algorithm_reduce_axis.hpp	(revision 888)
+++ XIOS/trunk/src/transformation/scalar_algorithm_reduce_axis.hpp	(revision 888)
@@ -0,0 +1,46 @@
+/*!
+   \file scalar_algorithm_reduce_scalar.hpp
+   \author Ha NGUYEN
+   \since 23 June 2016
+   \date 23 June 2016
+
+   \brief Algorithm for reduce an axis to a scalar
+ */
+#ifndef __XIOS_SCALAR_ALGORITHM_REDUCE_AXIS_HPP__
+#define __XIOS_SCALAR_ALGORITHM_REDUCE_AXIS_HPP__
+
+#include "scalar_algorithm_transformation.hpp"
+
+namespace xios {
+
+class CScalar;
+class CAxis;
+class CReduceAxisToScalar;
+class CReductionAlgorithm;
+
+/*!
+  \class CScalarAlgorithmReduceScalar
+  Inversing an axis to a scalar
+*/
+class CScalarAlgorithmReduceScalar : public CScalarAlgorithmTransformation
+{
+public:
+  CScalarAlgorithmReduceScalar(CScalar* scalarDestination, CAxis* axisSource, CReduceAxisToScalar* algo);
+
+  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
+                     const double* dataInput,
+                     CArray<double,1>& dataOut,
+                     std::vector<bool>& flagInitial);
+
+  virtual ~CScalarAlgorithmReduceScalar();
+
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
+
+protected:
+  CReductionAlgorithm* reduction_;
+
+};
+
+}
+#endif // __XIOS_SCALAR_ALGORITHM_REDUCE_AXIS_HPP__
Index: XIOS/trunk/src/transformation/scalar_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/scalar_algorithm_transformation.cpp	(revision 888)
+++ XIOS/trunk/src/transformation/scalar_algorithm_transformation.cpp	(revision 888)
@@ -0,0 +1,82 @@
+/*!
+   \file scalar_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 23 June 2016
+   \date 23 June 2016
+
+   \brief Interface for all scalar transformation algorithms.
+ */
+
+#include "scalar_algorithm_transformation.hpp"
+#include "context.hpp"
+#include "context_client.hpp"
+#include "client_client_dht_template.hpp"
+#include "domain.hpp"
+#include "axis.hpp"
+#include "scalar.hpp"
+
+namespace xios {
+
+CScalarAlgorithmTransformation::CScalarAlgorithmTransformation(CScalar* scalarDestination, CScalar* scalarSource)
+ : CGenericAlgorithmTransformation(),
+   scalarDest_(scalarDestination),
+   scalarSrc_(scalarSource), axisSrc_(0), domainSrc_(0)
+{
+}
+
+CScalarAlgorithmTransformation::CScalarAlgorithmTransformation(CScalar* scalarDestination, CAxis* axisSource)
+ : CGenericAlgorithmTransformation(),
+   scalarDest_(scalarDestination),
+   scalarSrc_(0), axisSrc_(axisSource), domainSrc_(0)
+{
+}
+
+CScalarAlgorithmTransformation::CScalarAlgorithmTransformation(CScalar* scalarDestination, CDomain* domainSource)
+ : CGenericAlgorithmTransformation(),
+   scalarDest_(scalarDestination),
+   scalarSrc_(0), axisSrc_(0), domainSrc_(domainSource)
+{
+}
+
+CScalarAlgorithmTransformation::~CScalarAlgorithmTransformation()
+{
+}
+
+void CScalarAlgorithmTransformation::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
+{
+}
+
+/*!
+  Compute global index of scalar on different processes
+  \param [in] globalScalarIndex global index of scalar source
+  \param [out] globalScalarIndexOnProc processes which contain the corresponding global index of scalar source
+*/
+void CScalarAlgorithmTransformation::computeExchangeGlobalIndex(const CArray<size_t,1>& globalScalarIndex,
+                                                                int elementType,
+                                                                CClientClientDHTInt::Index2VectorInfoTypeMap& globalScalarIndexOnProc)
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+  int clientRank = client->clientRank;
+  int clientSize = client->clientSize;
+
+  if (1 == elementType)
+  {
+    size_t globalIndex;
+    int nIndexSize = axisSrc_->index.numElements();
+    CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
+    globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
+    for (int idx = 0; idx < nIndexSize; ++idx)
+    {
+      globalIndex = axisSrc_->index(idx);
+      globalIndex2ProcRank[globalIndex].resize(1);
+      globalIndex2ProcRank[globalIndex][0] = clientRank;
+    }
+
+    CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
+    dhtIndexProcRank.computeIndexInfoMapping(globalScalarIndex);
+    globalScalarIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/scalar_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/scalar_algorithm_transformation.hpp	(revision 888)
+++ XIOS/trunk/src/transformation/scalar_algorithm_transformation.hpp	(revision 888)
@@ -0,0 +1,59 @@
+/*!
+   \file scalar_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 23 June 2016
+   \date 23 June 2016
+
+   \brief Interface for all scalar transformation algorithms.
+ */
+#ifndef __XIOS_SCALAR_ALGORITHM_TRANSFORMATION_HPP__
+#define __XIOS_SCALAR_ALGORITHM_TRANSFORMATION_HPP__
+
+#include "generic_algorithm_transformation.hpp"
+
+namespace xios {
+
+class CScalar;
+class CAxis;
+class CDomain;
+
+/*!
+  \class CScalarAlgorithmTransformation
+  Algorithms for scalar.
+*/
+class CScalarAlgorithmTransformation : public virtual CGenericAlgorithmTransformation
+{
+public:
+  CScalarAlgorithmTransformation(CScalar* scalarDestination, CScalar* scalarSource);
+  CScalarAlgorithmTransformation(CScalar* scalarDestination, CAxis* axisSource);
+  CScalarAlgorithmTransformation(CScalar* scalarDestination, CDomain* domainSource);
+
+  virtual ~CScalarAlgorithmTransformation();
+
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
+
+  virtual void computeExchangeGlobalIndex(const CArray<size_t,1>& globalScalarIndex,
+                                          int elementType,
+                                          CClientClientDHTInt::Index2VectorInfoTypeMap& globalScalarIndexOnProc);
+
+protected:
+  //! Global index of an scalar on grid destination
+  std::vector<int> scalarDestGlobalIndex_;
+
+  //! Size of
+  int scalarDestGlobalSize_;
+
+    //! Scalar on grid destination
+  CScalar* scalarDest_;
+
+  //! Scalar on grid source
+  CScalar* scalarSrc_;
+  //! Axis source
+  CAxis* axisSrc_;
+  //! Domain source
+  CDomain* domainSrc_;
+};
+
+}
+#endif // __XIOS_SCALAR_ALGORITHM_TRANSFORMATION_HPP__
Index: XIOS/trunk/src/type/type_util.hpp
===================================================================
--- XIOS/trunk/src/type/type_util.hpp	(revision 887)
+++ XIOS/trunk/src/type/type_util.hpp	(revision 888)
@@ -34,4 +34,6 @@
     class CScalar;
     class CScalarGroup;
+    class CReduceAxisToScalar;
+    class CReduceAxisToScalarGroup;
 
   template <typename T> inline string getStrType(void);
@@ -84,4 +86,6 @@
   macro(CScalar)
   macro(CScalarGroup)
+  macro(CReduceAxisToScalar)
+  macro(CReduceAxisToScalarGroup)
 #undef macro
 }
Index: XIOS/trunk/src/xml_parser_decl.cpp
===================================================================
--- XIOS/trunk/src/xml_parser_decl.cpp	(revision 887)
+++ XIOS/trunk/src/xml_parser_decl.cpp	(revision 888)
@@ -26,4 +26,5 @@
     macro( GenerateRectilinearDomain )
     macro( Scalar )
+    macro( ReduceAxisToScalar )
   }
 }
