Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/config/reduce_axis_to_scalar_attribute.conf
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/config/reduce_axis_to_scalar_attribute.conf	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/config/reduce_axis_to_scalar_attribute.conf	(revision 2291)
@@ -1,3 +1,5 @@
 DECLARE_ENUM4(operation, min, max, sum, average)
+DECLARE_ATTRIBUTE(bool, local)
 
 
+
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/gatherer_connector.hpp	(revision 2291)
@@ -9,4 +9,5 @@
 #include "distributed_view.hpp"
 #include "context_client.hpp"
+#include "reduction_types.hpp"
 
 
@@ -29,51 +30,126 @@
       
       template<typename T>
-      void transfer(int repeat, int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut)
+      void transfer(int repeat, int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, EReduction op = EReduction::none)
       {
         // for future, make a specific transfer function for sizeT=1 to avoid multiplication (increasing performance)
+       
         size_t dstSlice = dstSize_*sizeT ;
         dataOut.resize(repeat* dstSlice) ;  
         
-        for(auto& data : dataIn)
-        {
+        
+        if (op == EReduction::none) // tranfer without reduction
+        {
+          for(auto& data : dataIn)
+          {
+            T* output = dataOut.dataFirst() ;
+            int rank=data.first ;
+            auto input  = data.second.dataFirst() ;
+            auto& connector=connector_[rank] ;
+            auto& mask=mask_[rank] ;
+            int size=mask.size() ;
+            size_t srcSlice = size * sizeT ;
+            for(int l=0; l<repeat; l++)
+            {   
+              for(int i=0, j=0 ;i<size;i++)
+              {
+                if (mask[i]) 
+                {
+                  int cj = connector[j]*sizeT ;
+                  int ci = i*sizeT ;
+                  for (int k=0;k<sizeT;k++) output[cj+k] = input[ci+k] ;
+                  j++ ;
+                }
+              }
+              input+=srcSlice ;
+              output+=dstSlice ;
+           }
+          }
+        }
+        else // with reduction, to be optimized, see how to vectorize
+        {
+          vector<int> vcount(dataOut.size(),0) ;
+          int* count = vcount.data() ;
+          T defaultValue = std::numeric_limits<T>::quiet_NaN();
+          for(auto& data : dataIn)
+          {
+            T* output = dataOut.dataFirst() ;
+            int rank=data.first ;
+            auto input  = data.second.dataFirst() ;
+            auto& connector=connector_[rank] ;
+            auto& mask=mask_[rank] ;
+            int size=mask.size() ;
+            size_t srcSlice = size * sizeT ;
+            for(int l=0; l<repeat; l++)
+            {   
+              for(int i=0, j=0 ;i<size;i++)
+              {
+                if (mask[i]) 
+                {
+                  int cj = connector[j]*sizeT ;
+                  int ci = i*sizeT ;
+                  for (int k=0;k<sizeT;k++)
+                  { 
+                    if (!std::isnan(input[ci+k])) // manage missing value
+                    {
+                      if (count[cj+k]==0)  output[cj+k] = input[ci+k] ;
+                      else
+                      {
+                        switch(op)
+                        {
+                          case EReduction::sum :
+                            output[cj+k] += input[ci+k] ;
+                            break ;
+                          case EReduction::min :
+                            output[cj+k]= std::min(output[cj+k],input[ci+k]) ;
+                            break ;
+                          case EReduction::max :
+                            output[cj+k]= std::max(output[cj+k],input[ci+k]) ;
+                            break ;
+                          case EReduction::average :
+                            output[cj+k] += input[ci+k] ;
+                            break ;
+                          default :
+                            ERROR("CGathererConnector::transfer",
+                               <<"reduction operator "<<(int)op<<" is not defined for this operation") ;
+                          break ;
+                        }
+                      }
+                      count[cj+k]++ ; 
+                    }
+                  }
+                  j++ ;
+                }
+              }
+              input+=srcSlice ;
+              output+=dstSlice ;
+              count+=dstSlice ;
+            }
+          }
+
           T* output = dataOut.dataFirst() ;
-          int rank=data.first ;
-          auto input  = data.second.dataFirst() ;
-          auto& connector=connector_[rank] ;
-          auto& mask=mask_[rank] ;
-          int size=mask.size() ;
-          size_t srcSlice = size * sizeT ;
-          for(int l=0; l<repeat; l++)
-          {   
-            for(int i=0, j=0 ;i<size;i++)
-            {
-              if (mask[i]) 
-              {
-                int cj = connector[j]*sizeT ;
-                int ci = i*sizeT ;
-                for (int k=0;k<sizeT;k++) output[cj+k] = input[ci+k] ;
-                j++ ;
-              }
-            }
-            input+=srcSlice ;
-            output+=dstSlice ;
-          }
-        }
-      }
-
-      template<typename T>
-      void transfer(int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut)
-      {
-        transfer(1, sizeT, dataIn, dataOut) ;
+          if (op==EReduction::average)
+            for(int i=0;  i < dataOut.size() ; i++) 
+            {
+              if (count[i]>0) dataOut[i]/=count[i] ;
+              else dataOut[i] = defaultValue ;
+            }
+          else for(int i=0;  i < dataOut.size() ; i++) if (count[i]==0) dataOut[i] = defaultValue ;
+        }
+      }
+
+      template<typename T>
+      void transfer(int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, EReduction op = EReduction::none)
+      {
+        transfer(1, sizeT, dataIn, dataOut, op) ;
       }
     
       template<typename T>
-      void transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut)
-      {
-        transfer(1,dataIn,dataOut) ;
-      }
-
-      template<typename T>
-      void transfer(int rank,  shared_ptr<CGathererConnector>* connectors, int nConnectors, const T* input, T* output)
+      void transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, EReduction op = EReduction::none)
+      {
+        transfer(1,dataIn,dataOut, op) ;
+      }
+
+      template<typename T>
+      void transfer(int rank,  shared_ptr<CGathererConnector>* connectors, int nConnectors, const T* input, T* output, EReduction op = EReduction::none, int* count=nullptr)
       {
         auto& connector = connector_[rank] ; // probably costly, find a better way to avoid the map
@@ -83,10 +159,75 @@
         if (nConnectors==0)
         {
-          for(int i=0, j=0; i<srcSize; i++)
-            if (mask[i]) 
-            {
-              *(output+connector[j]) = *(input + i) ;
-              j++ ;
-            }
+          if (op == EReduction::none)
+          {
+            for(int i=0, j=0; i<srcSize; i++)
+              if (mask[i]) 
+              {
+                *(output+connector[j]) = *(input + i) ;
+                j++ ;
+              }
+          }
+          else
+          {
+            switch(op)
+            {
+              case EReduction::sum :
+                for(int i=0, j=0; i<srcSize; i++)
+                  if (mask[i]) 
+                  {
+                    if (!std::isnan(*(input + i)))
+                    {
+                      if (*(count+connector[j])==0) *(output+connector[j]) = *(input + i) ;
+                      else *(output+connector[j]) += *(input + i) ;
+                      (*(count+connector[j]))++ ;
+                    } 
+                    j++ ;
+                  }
+                break ;
+              case EReduction::min :
+                for(int i=0, j=0; i<srcSize; i++)
+                  if (mask[i]) 
+                  {
+                    if (!std::isnan(*(input + i)))
+                    {
+                      if (*(count+connector[j])==0) *(output+connector[j]) = *(input + i) ;
+                      else *(output+connector[j]) = std::min(*(output+connector[j]),*(input + i)) ;
+                      (*(count+connector[j]))++ ;
+                    } 
+                    j++ ;
+                  }
+                break ;
+              case EReduction::max :
+                for(int i=0, j=0; i<srcSize; i++)
+                  if (mask[i]) 
+                  {
+                    if (!std::isnan(*(input + i)))
+                    {
+                      if (*(count+connector[j])==0) *(output+connector[j]) = *(input + i) ;
+                      else *(output+connector[j]) = std::max(*(output+connector[j]),*(input + i)) ;
+                      (*(count+connector[j]))++ ;
+                    } 
+                    j++ ;
+                  }
+                break ;
+              case EReduction::average :
+                for(int i=0, j=0; i<srcSize; i++)
+                  if (mask[i]) 
+                  {
+                    if (!std::isnan(*(input + i)))
+                    {
+                      if (*(count+connector[j])==0) *(output+connector[j]) = *(input + i) ;
+                      else *(output+connector[j]) += *(input + i) ;
+                      (*(count+connector[j]))++ ;
+                    } 
+                    j++ ;
+                  }
+                break ;
+              default :
+                ERROR("CGathererConnector::transfer",
+                     <<"reduction operator "<<(int)op<<" is not defined for this operation") ;
+                break ;
+            }
+          }
 
         }
@@ -101,5 +242,5 @@
             if (mask[i]) 
             {
-              (*(connectors-1))->transfer(rank, connectors-1, nConnectors-1, in, output+connector[j]*dstSliceSize) ; // the multiplication must be avoid in further optimization
+              (*(connectors-1))->transfer(rank, connectors-1, nConnectors-1, in, output+connector[j]*dstSliceSize, op, count+connector[j]*dstSliceSize) ; // the multiplication must be avoid in further optimization
               j++ ;
             }
@@ -149,25 +290,25 @@
 
       template<typename T>
-      void transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue)
-      {
-        transfer(1, 1, dataIn, dataOut, missingValue);
-      }
-      
-      template<typename T>
-      void transfer(int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue)
-      {
-         transfer(1, sizeT, dataIn, dataOut, missingValue) ;
-      }
-
-      template<typename T>
-      void transfer(int repeat , int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue)
+      void transfer(map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue, EReduction op = EReduction::none)
+      {
+        transfer(1, 1, dataIn, dataOut, missingValue, op);
+      }
+      
+      template<typename T>
+      void transfer(int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue, EReduction op = EReduction::none)
+      {
+         transfer(1, sizeT, dataIn, dataOut, missingValue, op) ;
+      }
+
+      template<typename T>
+      void transfer(int repeat , int sizeT, map<int, CArray<T,1>>& dataIn, CArray<T,1>& dataOut, T missingValue, EReduction op = EReduction::none)
       {
         dataOut.resize(repeat*dstSize_*sizeT) ;
         dataOut=missingValue ;
-        transfer(repeat, sizeT, dataIn, dataOut) ;
-      }
-
-      template<typename T>
-      void transfer(CEventServer& event, int sizeT, CArray<T,1>& dataOut)
+        transfer(repeat, sizeT, dataIn, dataOut, op) ;
+      }
+
+      template<typename T>
+      void transfer(CEventServer& event, int sizeT, CArray<T,1>& dataOut, EReduction op = EReduction::none)
       {
         map<int, CArray<T,1>> dataIn ;
@@ -177,15 +318,15 @@
           (*subEvent.buffer) >> data ;
         }
-        transfer(1, sizeT, dataIn, dataOut) ;
-      }
-      
-      template<typename T>
-      void transfer(CEventServer& event, CArray<T,1>& dataOut)
-      {
-        transfer(event, 1, dataOut) ;
-      }
-
-      template<typename T>
-      void transfer(CEventServer& event, int sizeT, CArray<T,1>& dataOut, T missingValue)
+        transfer(1, sizeT, dataIn, dataOut, op) ;
+      }
+      
+      template<typename T>
+      void transfer(CEventServer& event, CArray<T,1>& dataOut, EReduction op = EReduction::none)
+      {
+        transfer(event, 1, dataOut, op) ;
+      }
+
+      template<typename T>
+      void transfer(CEventServer& event, int sizeT, CArray<T,1>& dataOut, T missingValue, EReduction op = EReduction::none)
       {
         map<int, CArray<T,1>> dataIn ;
@@ -195,9 +336,9 @@
           (*subEvent.buffer) >> data ;
         }
-        transfer(1, sizeT, dataIn, dataOut, missingValue) ;
-      }
-
-      template<typename T>
-      void transfer(CEventServer& event, CArray<T,1>& dataOut, T missingValue)
+        transfer(1, sizeT, dataIn, dataOut, missingValue, op) ;
+      }
+
+      template<typename T>
+      void transfer(CEventServer& event, CArray<T,1>& dataOut, T missingValue, EReduction op = EReduction::none)
       {
         map<int, CArray<T,1>> dataIn ;
@@ -207,5 +348,5 @@
           (*subEvent.buffer) >> data ;
         }
-        transfer(1, 1, dataIn, dataOut, missingValue) ;
+        transfer(1, 1, dataIn, dataOut, missingValue, op) ;
       }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_gatherer_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_gatherer_connector.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_gatherer_connector.hpp	(revision 2291)
@@ -10,4 +10,5 @@
 #include "context_client.hpp"
 #include "gatherer_connector.hpp"
+#include "reduction_types.hpp"
 
 
@@ -30,12 +31,21 @@
 
       template<typename T> 
-      void transfer(const map<int, CArray<T,1>>& input, CArray<T,1>& output)
+      void transfer(const map<int, CArray<T,1>>& input, CArray<T,1>& output, EReduction op = EReduction::none)
       {
         int n = elementsConnector_.size()-1 ;
-       shared_ptr<CGathererConnector>* connector = elementsConnector_.data() + n ;
+        shared_ptr<CGathererConnector>* connector = elementsConnector_.data() + n ;
         output.resize(dstSize_) ;
-        for(auto& rankDataIn : input) 
+       
+        if (op == EReduction::none)
+          for(auto& rankDataIn : input) 
+            elementsConnector_[n]->transfer(rankDataIn.first, connector, n, rankDataIn.second.dataFirst(), output.dataFirst()) ;
+        else
         {
-          elementsConnector_[n]->transfer(rankDataIn.first, connector, n, rankDataIn.second.dataFirst(), output.dataFirst()) ;
+          T defaultValue = std::numeric_limits<T>::quiet_NaN();
+          vector<int> count(dstSize_,0) ;
+          for(auto& rankDataIn : input) 
+            elementsConnector_[n]->transfer(rankDataIn.first, connector, n, rankDataIn.second.dataFirst(), output.dataFirst(), op, count.data()) ;
+
+          for(int i=0;i<dstSize_;i++) if (count[i]==0) output(i)=defaultValue ;
         }
       } 
@@ -55,5 +65,5 @@
 
       template<typename T>
-      void transfer(CEventServer& event, CArray<T,1>& dataOut)
+      void transfer(CEventServer& event, CArray<T,1>& dataOut, EReduction op = EReduction::none)
       {
         map<int, CArray<T,1>> dataIn ;
@@ -63,5 +73,5 @@
           (*subEvent.buffer) >> data ;
         }
-        transfer(dataIn, dataOut) ;
+        transfer(dataIn, dataOut, op) ;
       }
       
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.cpp	(revision 2291)
@@ -114,12 +114,60 @@
   *         some redondant ranks can be removed from the elements_ map.
   */
-  void CGridRemoteConnector::computeConnector(void)
-  {
-    computeViewDistribution() ;
-    computeConnectorMethods() ;
-    computeRedondantRanks() ; 
-    for(auto& rank : rankToRemove_)
-      for(auto& element : elements_) element.erase(rank) ;
-  }
+  void CGridRemoteConnector::computeConnector(bool eliminateRedundant)
+  {
+    if (eliminateRedundant)
+    {
+      computeViewDistribution() ;
+      computeConnectorMethods() ;
+      computeRedondantRanks() ; 
+      for(auto& rank : rankToRemove_)
+        for(auto& element : elements_) element.erase(rank) ;
+    }
+    else
+    {
+       computeViewDistribution() ;
+       computeConnectorRedundant() ;
+    }
+  }
+
+/**
+  * \brief Compute the connector, i.e. compute the \b elements_ attribute. 
+  * \detail In this routine we don't eliminate redundant cells as it it performed in 
+  *         computeConnectorMethods. It can be usefull to perform reduce operation over processes.
+            In future, some optimisation could be done considering full redondance of the 
+            source view or the destination view.
+  */
+  void CGridRemoteConnector::computeConnectorRedundant(void)
+  {
+    vector<shared_ptr<CLocalView>> srcView ;
+    vector<shared_ptr<CDistributedView>> dstView ;
+    vector<int> indElements ;
+    elements_.resize(srcView_.size()) ;
+    
+    bool srcViewsNonDistributed=true ; // not usefull now but later for optimization
+    for(int i=0;i<srcView_.size();i++) srcViewsNonDistributed = srcViewsNonDistributed && !isSrcViewDistributed_[i]  ;
+    
+    bool dstViewsNonDistributed=true ;  // not usefull now but later for optimization
+    for(int i=0;i<dstView_.size();i++) dstViewsNonDistributed = dstViewsNonDistributed && !isDstViewDistributed_[i] ;
+    
+    for(int i=0;i<srcView_.size();i++) 
+    {
+      srcView.push_back(srcView_[i]) ;
+      dstView.push_back(dstView_[i]) ;
+      indElements.push_back(i) ;
+    }
+
+    computeGenericMethod(srcView, dstView, indElements) ;
+    
+    map<int,bool> ranks ;  
+    for(auto& it : elements_[indElements[0]]) 
+    {
+      if (it.second.numElements()==0) ranks[it.first] = false ;
+      else  ranks[it.first] = true ;
+    }
+   
+  }
+
+
 /**
   * \brief Compute the connector, i.e. compute the \b elements_ attribute. 
@@ -426,5 +474,5 @@
   }
 
-  
+
  /**
   * \brief Generic method the compute the grid remote connector. Only distributed elements are specifed in the source view and remote view. 
@@ -650,4 +698,4 @@
     }
   }
-
+  
 }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.hpp	(revision 2291)
@@ -21,6 +21,7 @@
       CGridRemoteConnector(vector<shared_ptr<CLocalView>>& srcView, vector<shared_ptr<CLocalView>>& dstView, MPI_Comm localComm, int remoteSize) ;
       void computeViewDistribution(void) ;
-      void computeConnector(void) ;
+      void computeConnector(bool eliminateRedundant=true) ;
       void computeConnectorMethods(void) ;
+      void computeConnectorRedundant(void) ;
       void computeGenericMethod(vector<shared_ptr<CLocalView>>& srcView, vector<shared_ptr<CDistributedView>>& dstView, vector<int>& indElements) ;
       void computeSrcDstNonDistributed(int i, map<int,bool>& ranks) ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.cpp	(revision 2291)
@@ -4,9 +4,10 @@
 #include "gatherer_connector.hpp"
 #include "grid_remote_connector.hpp"
+#include "grid_redondant_remote_connector.hpp"
 
 
 namespace xios
 {
-  void CGridTransformConnector::computeConnector(void)
+  void CGridTransformConnector::computeConnector(bool eliminateRedundant)
   {
     int commSize ;
@@ -17,5 +18,5 @@
 
     auto remoteConnector = make_shared<CGridRemoteConnector>(srcViews_, remoteViews_, localComm_, commSize) ;  
-    remoteConnector->computeConnector() ;
+    remoteConnector->computeConnector(eliminateRedundant) ; 
     
     vector<shared_ptr<CDistributedElement>> sendElements(nElements) ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.hpp	(revision 2291)
@@ -8,4 +8,5 @@
 #include "grid_scatterer_connector.hpp"
 #include "grid_gatherer_connector.hpp"
+#include "reduction_types.hpp"
 #include "mpi.hpp"
 
@@ -20,7 +21,7 @@
       CGridTransformConnector(vector<shared_ptr<CLocalView>> srcViews, vector<shared_ptr<CLocalView>> remoteViews, MPI_Comm localComm) 
                           : srcViews_(srcViews), remoteViews_(remoteViews), localComm_(localComm) 
-                          { computeConnector();}
+                          { }
     
-      void computeConnector(void) ; 
+      void computeConnector(bool eliminateRedundant=true) ; 
     protected:
      MPI_Comm localComm_ ;
@@ -36,5 +37,5 @@
     public:
       template<typename T> 
-      void transfer(const CArray<T,1>& dataIn, CArray<T,1>& dataOut)
+      void transfer(const CArray<T,1>& dataIn, CArray<T,1>& dataOut, EReduction op = EReduction::none)
       {
         map<int,CArray<T,1>> tmpArrayIn ;
@@ -62,5 +63,7 @@
         
         const double nanValue = std::numeric_limits<double>::quiet_NaN();
-        gridGathererConnector_->transfer(tmpArrayOut, dataOut, nanValue) ;
+
+        if (op == EReduction::none) gridGathererConnector_->transfer(tmpArrayOut, dataOut, nanValue) ;
+        else gridGathererConnector_->transfer(tmpArrayOut, dataOut, op) ;
       }
   
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/reduce_transform_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/reduce_transform_connector.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/reduce_transform_connector.hpp	(revision 2291)
@@ -68,10 +68,11 @@
       {
         vector<bool> touched(repeat* dstSlice, false) ;
-        int pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
+        int posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos = posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
           {
@@ -97,11 +98,11 @@
 
         output = dataOut.dataFirst()  ;
-        pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
-          int pos=0 ;
+        posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos=posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
               for(int j=0 ; j<nSrc_[i] ; j++,k++)
@@ -144,10 +145,11 @@
       {
         vector<bool> touched(repeat* dstSlice, false) ;
-        int pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
+        int posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos=posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
           {
@@ -173,11 +175,11 @@
 
         output = dataOut.dataFirst()  ;
-        pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
-          int pos=0 ;
+        posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos=posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
               for(int j=0 ; j<nSrc_[i] ; j++,k++)
@@ -220,10 +222,11 @@
       {
         vector<bool> touched(repeat* dstSlice, false) ;
-        int pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
+        int posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos=posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
           {
@@ -249,11 +252,11 @@
 
         output = dataOut.dataFirst()  ;
-        pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
-          int pos=0 ;
+        posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos=posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
               for(int j=0 ; j<nSrc_[i] ; j++,k++)
@@ -296,10 +299,11 @@
       {
         vector<int> touched(repeat* dstSlice, 0) ;
-        int pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
+        int posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos=posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
           {
@@ -331,11 +335,11 @@
 
         output = dataOut.dataFirst()  ;
-        pos=0 ;
-        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, pos+=dstSlice)
-        {
-          const double* in = input;
-          double* out = output ;
-          int k=0 ;
-          int pos=0 ;
+        posr=0 ;
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, posr+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          int pos=posr ;
           for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
               for(int j=0 ; j<nSrc_[i] ; j++,k++)
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.cpp	(revision 2291)
@@ -276,66 +276,9 @@
      This check should be done in the very beginning of work flow
    */
+   
    void CAxis::checkAttributes(void)
-   TRY
-   {
-     if (checkAttributes_done_) return ;
-
-     CContext* context=CContext::getCurrent();
-
-     if (this->n_glo.isEmpty())
-        ERROR("CAxis::checkAttributes(void)",
-              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
-              << "The axis is wrongly defined, attribute 'n_glo' must be specified");
-      StdSize size = this->n_glo.getValue();
-
-      if (!this->index.isEmpty())
-      {
-        if (n.isEmpty()) n = index.numElements();
-
-        // It's not so correct but if begin is not the first value of index 
-        // then data on the local axis has user-defined distribution. In this case, begin has no meaning.
-        if (begin.isEmpty()) begin = index(0);         
-      }
-      else 
-      {
-        if (!this->begin.isEmpty())
-        {
-          if (begin < 0 || begin > size - 1)
-            ERROR("CAxis::checkAttributes(void)",
-                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
-                  << "The axis is wrongly defined, attribute 'begin' (" << begin.getValue() << ") must be non-negative and smaller than size-1 (" << size - 1 << ").");
-        }
-        else this->begin.setValue(0);
-
-        if (!this->n.isEmpty())
-        {
-          if (n < 0 || n > size)
-            ERROR("CAxis::checkAttributes(void)",
-                  << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
-                  << "The axis is wrongly defined, attribute 'n' (" << n.getValue() << ") must be non-negative and smaller than size (" << size << ").");
-        }
-        else this->n.setValue(size);
-
-        {
-          index.resize(n);
-          for (int i = 0; i < n; ++i) index(i) = i+begin;
-        }
-      }
-
-      if (!this->value.isEmpty())
-      {
-        StdSize true_size = value.numElements();
-        if (this->n.getValue() != true_size)
-          ERROR("CAxis::checkAttributes(void)",
-              << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
-              << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size
-              << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
-        this->hasValue = true;
-      }
-
-      this->checkBounds();
-      this->checkMask();
-      this->checkData();
-      this->checkLabel();
+   {
+      if (checkAttributes_done_) return ;
+      checkGeometricAttributes(true) ;
       initializeLocalElement() ;
       addFullView() ;
@@ -345,6 +288,133 @@
       checkAttributes_done_ = true ;
    }
+   
+   void CAxis::resetGeometricAttributes(void)
+   {
+     n_glo.reset();
+     index.reset();
+     n.reset();
+     begin.reset();
+     mask.reset();
+     data_index.reset();
+     data_n.reset();
+     data_begin.reset();
+     value.reset();
+     bounds.reset();
+     label.reset() ;
+   }
+
+   void CAxis::setGeometricAttributes(const CAxis& axisSrc)
+   {
+     resetGeometricAttributes() ;
+     n_glo=axisSrc.n_glo;
+     if (!axisSrc.index.isEmpty())
+     {
+       index.resize(axisSrc.index.shape()) ;
+       index=axisSrc.index;
+     }
+
+     n=axisSrc.n;
+     begin=axisSrc.begin;
+     if (!axisSrc.mask.isEmpty())
+     {
+       mask.resize(axisSrc.mask.shape()) ;
+       mask=axisSrc.mask;
+     }
+     if (!axisSrc.data_index.isEmpty())
+     {
+       data_index.resize(axisSrc.data_index.shape()) ;
+       data_index=axisSrc.data_index;
+     }
+     data_n=axisSrc.data_n;
+     data_begin=axisSrc.data_begin;
+     if (!axisSrc.value.isEmpty())
+     {
+       value.resize(axisSrc.value.shape()) ;
+       value=axisSrc.value;
+     }
+     
+     if (!axisSrc.bounds.isEmpty())
+     {
+       bounds.resize(axisSrc.bounds.shape()) ;
+       bounds=axisSrc.bounds;
+     }
+     if (!axisSrc.label.isEmpty())
+     {
+       label.resize(axisSrc.label.shape()) ;
+       label=axisSrc.label;
+     }
+
+   }
+   
+   bool CAxis::checkGeometricAttributes(bool generateError)
+   TRY
+   {
+     CContext* context=CContext::getCurrent();
+
+     if (this->n_glo.isEmpty())
+        if (generateError) ERROR("CAxis::checkAttributes(void)",
+                                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
+                                << "The axis is wrongly defined, attribute 'n_glo' must be specified")
+        else return false ; 
+      StdSize size = this->n_glo.getValue();
+
+      if (!this->index.isEmpty())
+      {
+        if (n.isEmpty()) n = index.numElements();
+
+        // It's not so correct but if begin is not the first value of index 
+        // then data on the local axis has user-defined distribution. In this case, begin has no meaning.
+        if (begin.isEmpty()) begin = index(0);         
+      }
+      else 
+      {
+        if (!this->begin.isEmpty())
+        {
+          if (begin < 0 || begin > size - 1)
+             if (generateError) ERROR("CAxis::checkAttributes(void)",
+                                      << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
+                                      << "The axis is wrongly defined, attribute 'begin' (" 
+                                      << begin.getValue() << ") must be non-negative and smaller than size-1 (" << size - 1 << ").")
+              else return false ; 
+        }
+        else this->begin.setValue(0);
+
+        if (!this->n.isEmpty())
+        {
+          if (n < 0 || n > size)
+            if (generateError) ERROR("CAxis::checkAttributes(void)",
+                                      << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
+                                      << "The axis is wrongly defined, attribute 'n' (" << n.getValue() << ") must be non-negative and smaller than size (" 
+                                      << size << ").")
+            else return false ; 
+        }
+        else this->n.setValue(size);
+
+        {
+          index.resize(n);
+          for (int i = 0; i < n; ++i) index(i) = i+begin;
+        }
+      }
+
+      if (!this->value.isEmpty())
+      {
+        StdSize true_size = value.numElements();
+        if (this->n.getValue() != true_size)
+          if (generateError) ERROR("CAxis::checkAttributes(void)",
+                                   << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
+                                   << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size
+                                   << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").")
+          else return false ; 
+        this->hasValue = true;
+      }
+
+      if (!this->checkBounds(generateError)) return false;
+      if (!this->checkMask(generateError))   return false;
+      if (!this->checkData(generateError))   return false;
+      if (!this->checkLabel(generateError))  return false;
+      
+      return true ;
+   }
    CATCH_DUMP_ATTR
-
 
 
@@ -352,5 +422,5 @@
       Check the validity of data, fill in values if any, and apply mask.
    */
-   void CAxis::checkData()
+   bool CAxis::checkData(bool generateError)
    TRY
    {
@@ -363,7 +433,8 @@
       else if (data_n.getValue() < 0)
       {
-        ERROR("CAxis::checkData(void)",
-              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
-              << "The data size should be strictly positive ('data_n' = " << data_n.getValue() << ").");
+        if (generateError) ERROR("CAxis::checkData(void)",
+                              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
+                              << "The data size should be strictly positive ('data_n' = " << data_n.getValue() << ").")
+        else return false ;
       }
 
@@ -388,7 +459,9 @@
         if (data_index.numElements() != data_n)
         {
-          ERROR("CAxis::checkData(void)",
-                << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
-                << "The size of data_index = "<< data_index.numElements() << "is not equal to the data size data_n = " << data_n.getValue() << ").");
+          if (generateError) ERROR("CAxis::checkData(void)",
+                               << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
+                               << "The size of data_index = "<< data_index.numElements() << "is not equal to the data size data_n = " 
+                               << data_n.getValue() << ").")
+          else return false ;
         }
         for (int i = 0; i < data_n; ++i)
@@ -398,17 +471,12 @@
         }
       }
-
+      return true ;
    }
    CATCH_DUMP_ATTR
 
-    size_t CAxis::getGlobalWrittenSize(void)
-    {
-      return n_glo ;
-    }
-
-   /*!
-     Check validity of mask info and fill in values if any.
-   */
-   void CAxis::checkMask()
+/*!
+   Check validity of mask info and fill in values if any.
+  */
+   bool CAxis::checkMask(bool generateError)
    TRY
    {
@@ -417,9 +485,10 @@
         if (mask.extent(0) != n)
         {
-          ERROR("CAxis::checkMask(void)",
-              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
-              << "The mask does not have the same size as the local domain." << std::endl
-              << "Local size is " << n.getValue() << "." << std::endl
-              << "Mask size is " << mask.extent(0) << ".");
+          if (generateError) ERROR("CAxis::checkMask(void)",
+                                  << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
+                                  << "The mask does not have the same size as the local domain." << std::endl
+                                  << "Local size is " << n.getValue() << "." << std::endl
+                                  << "Mask size is " << mask.extent(0) << ".")
+          else return false ;
         }
       }
@@ -429,4 +498,5 @@
         mask = true;
       }
+      return true ;
    }
    CATCH_DUMP_ATTR
@@ -435,5 +505,5 @@
      Check validity of bounds info and fill in values if any.
    */
-   void CAxis::checkBounds()
+   bool CAxis::checkBounds(bool generateError)
    TRY
    {
@@ -441,15 +511,17 @@
      {
        if (bounds.extent(0) != 2 || bounds.extent(1) != n)
-         ERROR("CAxis::checkAttributes(void)",
-               << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl
-               << "Axis size is " << n.getValue() << "." << std::endl
-               << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << ".");
+         if (generateError) ERROR("CAxis::checkAttributes(void)",
+                               << "The bounds array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension 2 x axis size." << std::endl
+                               << "Axis size is " << n.getValue() << "." << std::endl
+                               << "Bounds size is "<< bounds.extent(0) << " x " << bounds.extent(1) << ".")
+         else return false ;
        hasBounds = true;
      }
      else hasBounds = false;
+     return true ;
    }
    CATCH_DUMP_ATTR
 
-  void CAxis::checkLabel()
+  bool CAxis::checkLabel(bool generateError)
   TRY
   {
@@ -457,13 +529,23 @@
     {
       if (label.extent(0) != n)
-        ERROR("CAxis::checkLabel(void)",
-              << "The label array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension of axis size." << std::endl
-              << "Axis size is " << n.getValue() << "." << std::endl
-              << "label size is "<< label.extent(0)<<  " .");
+        if (generateError) ERROR("CAxis::checkLabel(void)",
+                              << "The label array of the axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] must be of dimension of axis size." << std::endl
+                              << "Axis size is " << n.getValue() << "." << std::endl
+                              << "label size is "<< label.extent(0)<<  " .")
+        else return false ;
       hasLabel = true;
     }
     else hasLabel = false;
-  }
-  CATCH_DUMP_ATTR
+    return true ;
+  }
+  CATCH_DUMP_ATTR
+
+
+  size_t CAxis::getGlobalWrittenSize(void)
+  {
+    return n_glo ;
+  }
+
+   
 
  
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/axis.hpp	(revision 2291)
@@ -124,4 +124,7 @@
          void checkAttributes(void);
          bool checkAttributes_done_ = false ;
+         bool checkGeometricAttributes(bool generateError) ; 
+         void setGeometricAttributes(const CAxis& axisSrc) ;
+         void resetGeometricAttributes(void) ;
 
          size_t getGlobalWrittenSize(void) ;
@@ -173,8 +176,8 @@
 
       private:
-         void checkData();
-         void checkMask();
-         void checkBounds();
-         void checkLabel();
+         bool checkData(bool generateError);
+         bool checkMask(bool generateError);
+         bool checkBounds(bool generateError);
+         bool checkLabel(bool generateError);
       
       public:
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/reduce_domain_to_axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/reduce_domain_to_axis.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/reduce_domain_to_axis.cpp	(revision 2291)
@@ -48,8 +48,4 @@
        << "Axis destination " << axisDst->getId());
 
-    int axis_n_glo = axisDst->n_glo;
-    int domain_ni_glo = domainSrc->ni_glo;
-    int domain_nj_glo = domainSrc->nj_glo;
-
     if (this->operation.isEmpty())
       ERROR("CReduceDomainToAxis::checkValid(CAxis* axisDst, CDomain* domainSrc)",
@@ -65,25 +61,4 @@
     if (this->local.isEmpty()) local=false ;
 
-    switch (direction)
-    {
-      case direction_attr::jDir:
-        if (axis_n_glo != domain_ni_glo)
-          ERROR("CReduceDomainToAxis::checkValid(CAxis* axisDst, CDomain* domainSrc)",
-            << "Extract domain along j, axis destination should have n_glo equal to ni_glo of domain source"
-            << "Domain source " <<domainSrc->getId() << " has nj_glo " << domain_ni_glo << std::endl
-            << "Axis destination " << axisDst->getId() << " has n_glo " << axis_n_glo);
-         break;
-
-      case direction_attr::iDir:
-        if (axis_n_glo != domain_nj_glo)
-          ERROR("CReduceDomainToAxis::checkValid(CAxis* axisDst, CDomain* domainSrc)",
-            << "Extract domain along i, axis destination should have n_glo equal to nj_glo of domain source"
-            << "Domain source " <<domainSrc->getId() << " has nj_glo " << domain_nj_glo << std::endl
-            << "Axis destination " << axisDst->getId() << " has n_glo " << axis_n_glo);
-        break;
-
-      default:
-        break;
-    }
   }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/Functions/reduction_types.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/Functions/reduction_types.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/Functions/reduction_types.hpp	(revision 2291)
@@ -13,16 +13,17 @@
 {
 
-  typedef enum reduction_algurithm_type
+  typedef enum reduction_algorithm_type
   {
-    TRANS_REDUCE_SUM = 0,
-    TRANS_REDUCE_MIN = 1,
-    TRANS_REDUCE_MAX = 2,
-    TRANS_REDUCE_EXTRACT = 3,
-    TRANS_REDUCE_AVERAGE = 4
+    TRANS_REDUCE_NONE = 0, 
+    TRANS_REDUCE_SUM = 1,
+    TRANS_REDUCE_MIN = 2,
+    TRANS_REDUCE_MAX = 3,
+    TRANS_REDUCE_EXTRACT = 4,
+    TRANS_REDUCE_AVERAGE = 5
   } EReductionType;
 
   enum class EReduction
   {
-    sum, min, max, extract, average
+    none, sum, min, max, extract, average
   } ;
 }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_no_data_modification.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_no_data_modification.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_no_data_modification.cpp	(revision 2291)
@@ -12,5 +12,7 @@
   shared_ptr<CGridAlgorithm> CAlgorithmTransformationNoDataModification::createGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos)
   {
-    return make_shared<CGridAlgorithmNoDataModification>(static_pointer_cast<CAlgorithmTransformationNoDataModification>(shared_from_this())) ;
+    auto algo=make_shared<CGridAlgorithmNoDataModification>(static_pointer_cast<CAlgorithmTransformationNoDataModification>(shared_from_this())) ;
+    algo->computeAlgorithm() ;
+    return algo ; 
   }
 }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_reduce.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_reduce.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_reduce.hpp	(revision 2291)
@@ -28,5 +28,4 @@
       shared_ptr<CReduceTransformConnector> reduceTransformConnector_ ;
       bool detectMissingValue_=true ;
-      bool eliminateRedondantSrc_ = true ; 
   };
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.cpp	(revision 2291)
@@ -12,4 +12,5 @@
 #include "grid.hpp"
 #include "grid_transformation_factory_impl.hpp"
+#include "grid_algorithm_reduce.hpp"
 
 
@@ -50,7 +51,12 @@
 TRY
 {
-  eliminateRedondantSrc_= false ;
+  if (!axisDestination->checkGeometricAttributes(false))
+  {
+    axisDestination->resetGeometricAttributes();
+    axisDestination->setGeometricAttributes(*axisSource) ;
+  }
+  axisDestination->checkAttributes() ; 
   algo->checkValid(axisDestination, axisSource);
-  axisDestination->checkAttributes() ;
+  
 
   switch (algo->operation)
@@ -75,20 +81,33 @@
   }
 
-  TransformationIndexMap& transMap = this->transformationMapping_;
-  CArray<int,1>& axisDstIndex = axisDestination->index;
-  int nbAxisIdx = axisDstIndex.numElements();
-  for (int idxAxis = 0; idxAxis < nbAxisIdx; ++idxAxis)
+  //TransformationIndexMap& transMap = this->transformationMapping_;
+  //CArray<int,1>& axisDstIndex = axisDestination->index;
+  //int nbAxisIdx = axisDstIndex.numElements();
+
+
+
+  auto& transMap = this->transformationMapping_;
+  
+  CArray<size_t,1> dstGlobalIndex ;
+  axisDestination->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(dstGlobalIndex) ;
+  size_t nbIdx = dstGlobalIndex.numElements();
+
+  for (size_t idx = 0; idx < nbIdx; ++idx)
   {
-    int globalAxisIdx = axisDstIndex(idxAxis);
-    transMap[globalAxisIdx].resize(1);
-    transMap[globalAxisIdx][0]=globalAxisIdx ;      
+    size_t globalIdx = dstGlobalIndex(idx);
+    transMap[globalIdx].resize(1);
+    transMap[globalIdx][0]=globalIdx ;      
   }
 
- 
-  axisDestination->checkAttributes() ;
   this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), axisDestination->getLocalView(CElementView::WORKFLOW)) ;
 }
 CATCH
 
+shared_ptr<CGridAlgorithm> CAxisAlgorithmReduceAxis::createGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos)
+{
+  auto algo=make_shared<CGridAlgorithmReduce>(gridSrc, gridDst, pos, shared_from_this(), operator_) ;
+  algo->computeAlgorithm(false) ;
+  return algo ; 
+}
 
 CAxisAlgorithmReduceAxis::~CAxisAlgorithmReduceAxis()
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.hpp	(revision 2291)
@@ -44,4 +44,6 @@
                                                 std::map<int, int>& elementPositionInGridDst2AxisPosition,
                                                 std::map<int, int>& elementPositionInGridDst2DomainPosition);
+
+  virtual shared_ptr<CGridAlgorithm> createGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos);
   static bool dummyRegistered_;
 };
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_domain.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_domain.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_domain.cpp	(revision 2291)
@@ -51,6 +51,4 @@
 TRY
 {
-  algo->checkValid(axisDestination, domainSource);
-  axisDestination->checkAttributes() ;
   switch (algo->operation)
   {
@@ -74,7 +72,169 @@
 
   }
-
+  
+  algo->checkValid(axisDestination, domainSource);
   dir_ = (CReduceDomainToAxis::direction_attr::iDir == algo->direction)  ? iDir : jDir;
-  bool local = algo->local ;
+
+  bool local = false;
+  if (!algo->local.isEmpty()) local=algo->local ;
+  
+  size_t nj_glo = domainSource->nj_glo ;
+  size_t ni_glo = domainSource->ni_glo ;
+
+  bool validAxis = axisDestination->checkGeometricAttributes(false) ;
+  if (validAxis && !local) 
+  {
+    
+    axisDestination->checkAttributes() ; 
+    if (dir_==jDir)
+    {
+        if (axisDestination->n_glo != domainSource->nj_glo)
+          ERROR("CAxisAlgorithmReduceDomain::CAxisAlgorithmReduceDomain(bool isSource, CAxis* axisDestination, CDomain* domainSource, CReduceDomainToAxis* algo)",
+            << "Extract domain along j, axis destination should have n_glo equal to nj_glo of domain source"
+            << "Domain source " <<domainSource->getId() << " has nj_glo " << domainSource->nj_glo << std::endl
+            << "Axis destination " << axisDestination->getId() << " has n_glo " << axisDestination->n_glo)
+    }
+    else
+    {
+      if (axisDestination->n_glo != domainSource->ni_glo)
+          ERROR("CAxisAlgorithmReduceDomain::CAxisAlgorithmReduceDomain(bool isSource, CAxis* axisDestination, CDomain* domainSource, CReduceDomainToAxis* algo)",
+            << "Extract domain along j, axis destination should have n_glo equal to ni_glo of domain source"
+            << "Domain source " <<domainSource->getId() << " has ni_glo " << domainSource->ni_glo << std::endl
+            << "Axis destination " << axisDestination->getId() << " has n_glo " << axisDestination->n_glo);
+    }
+  }
+  else
+  {
+    // create axis destination from source domain
+
+    axisDestination->resetGeometricAttributes();
+    if (dir_== jDir)
+    {
+      axisDestination->n_glo = domainSource->nj_glo ;
+      
+      CArray<size_t, 1> srcGlobalIndex ;
+      set<size_t> indexFullView;
+      set<size_t> indexWorkflowView;
+      domainSource->getLocalView(CElementView::FULL)->getGlobalIndexView(srcGlobalIndex) ;
+      for(int i=0; i<srcGlobalIndex.numElements(); i++) indexFullView.insert(srcGlobalIndex(i)/ni_glo) ;
+      domainSource->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(srcGlobalIndex) ;
+      for(int i=0; i<srcGlobalIndex.numElements(); i++) indexWorkflowView.insert(srcGlobalIndex(i)/ni_glo) ;
+
+      axisDestination-> n = indexFullView.size() ;
+      axisDestination-> index.resize(axisDestination-> n) ;
+      axisDestination-> mask.resize(axisDestination-> n) ;
+      
+      map<size_t,int> globalToLocalIndex ;
+      auto it=indexFullView.begin();
+      for(int i=0; it!=indexFullView.end(); ++i,++it) 
+      {
+        axisDestination->index(i) = *it ;
+        if (indexWorkflowView.count(*it)==0) axisDestination->mask(i) = false ;
+        else axisDestination->mask(i) = true ;
+        globalToLocalIndex[*it] = i ;
+      }
+      if (domainSource->hasLonLat && domainSource->type == CDomain::type_attr::rectilinear)
+      {
+        axisDestination->value.resize(axisDestination-> n) ;
+        axisDestination->axis_type.setValue(CAxis::axis_type_attr::Y) ;
+        if (domainSource->hasBounds) axisDestination-> bounds.resize(axisDestination-> n, 2) ;
+
+        domainSource->getLocalView(CElementView::FULL)->getGlobalIndexView(srcGlobalIndex) ;
+        for(int i=0; i<srcGlobalIndex.numElements(); i++) 
+        {
+          axisDestination->value(globalToLocalIndex[srcGlobalIndex(i)/ni_glo]) = domainSource->latvalue(i) ;
+          if (domainSource->hasBounds) 
+          {
+            axisDestination->bounds(globalToLocalIndex[srcGlobalIndex(i)/ni_glo,0]) = domainSource->bounds_latvalue(i,0) ;
+            axisDestination->bounds(globalToLocalIndex[srcGlobalIndex(i)/ni_glo,1]) = domainSource->bounds_latvalue(i,1) ;
+          }
+        } 
+      }
+      
+    }
+    else // dir_== iDir
+    {
+      axisDestination->n_glo = domainSource->ni_glo ;
+      
+      CArray<size_t, 1> srcGlobalIndex ;
+      set<size_t> indexFullView;
+      set<size_t> indexWorkflowView;
+      domainSource->getLocalView(CElementView::FULL)->getGlobalIndexView(srcGlobalIndex) ;
+      for(int i=0; i<srcGlobalIndex.numElements(); i++) indexFullView.insert(srcGlobalIndex(i)%ni_glo) ;
+      domainSource->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(srcGlobalIndex) ;
+      for(int i=0; i<srcGlobalIndex.numElements(); i++) indexWorkflowView.insert(srcGlobalIndex(i)%ni_glo) ;
+
+      axisDestination-> n = indexFullView.size() ;
+      axisDestination-> index.resize(axisDestination-> n) ;
+      axisDestination-> mask.resize(axisDestination-> n) ;
+      map<size_t,int> globalToLocalIndex ;
+      auto it=indexFullView.begin();
+      for(int i=0; it!=indexFullView.end(); ++i,++it) 
+      {
+        axisDestination->index(i) = *it ;
+        if (indexWorkflowView.count(*it)==0) axisDestination->mask(i) = false ;
+        else axisDestination->mask(i) = true ;
+        globalToLocalIndex[*it] = i ;
+      }
+    
+      if (domainSource->hasLonLat && domainSource->type == CDomain::type_attr::rectilinear)
+      {
+        axisDestination-> value.resize(axisDestination-> n) ;
+        axisDestination-> axis_type.setValue(CAxis::axis_type_attr::X) ;
+        if (domainSource->hasBounds) axisDestination->bounds.resize(axisDestination-> n, 2) ;
+
+        domainSource->getLocalView(CElementView::FULL)->getGlobalIndexView(srcGlobalIndex) ;
+        for(int i=0; i<srcGlobalIndex.numElements(); i++) 
+        {
+          axisDestination->value(globalToLocalIndex[srcGlobalIndex(i)%ni_glo]) = domainSource->lonvalue(i) ;
+          if (domainSource->hasBounds) 
+          {
+            axisDestination->bounds(globalToLocalIndex[srcGlobalIndex(i)%ni_glo,0]) = domainSource->bounds_lonvalue(i,0) ;
+            axisDestination->bounds(globalToLocalIndex[srcGlobalIndex(i)%ni_glo,1]) = domainSource->bounds_lonvalue(i,1) ;
+          }
+        } 
+      }
+    
+    }
+   
+    axisDestination->checkAttributes() ;   
+  }
+  
+  // compute needed index for tranformation
+
+  TransformationIndexMap& transMap = transformationMapping_;
+
+  CArray<size_t, 1> srcGlobalIndex ;
+  domainSource->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(srcGlobalIndex) ;
+  CArray<size_t, 1> dstGlobalIndex ;
+  axisDestination->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(dstGlobalIndex) ;
+  
+  if (local)
+  {
+    
+    set<size_t> dstGlobalIndexSet ;
+    for(int i=0; i<dstGlobalIndex.numElements() ; i++) dstGlobalIndexSet.insert(dstGlobalIndex(i)) ; // for mask
+
+    size_t dstInd ; 
+    for(int i=0; i<srcGlobalIndex.numElements(); i++) 
+    {
+      if (dir_== jDir) dstInd=srcGlobalIndex(i)/ni_glo ;
+      else dstInd=srcGlobalIndex(i)%ni_glo ;
+      if (dstGlobalIndexSet.count(dstInd)!=0) transMap[dstInd].push_back(srcGlobalIndex(i)) ; 
+    }
+  }
+  else
+  {
+    for(int i=0; i<dstGlobalIndex.numElements() ;i++)
+    {
+      if (dir_== jDir) 
+        for(size_t j=0; j<ni_glo;j++) transMap[dstGlobalIndex(i)].push_back(dstGlobalIndex(i)*ni_glo+j) ;
+      else
+        for(size_t j=0; j<nj_glo;j++) transMap[dstGlobalIndex(i)].push_back(ni_glo*j+dstGlobalIndex(i)) ;
+    }
+  }
+
+/*
+
 
   TransformationIndexMap& transMap = transformationMapping_;
@@ -148,4 +308,5 @@
 
   axisDestination->checkAttributes() ;
+*/
   this->computeAlgorithm(domainSource->getLocalView(CElementView::WORKFLOW), axisDestination->getLocalView(CElementView::WORKFLOW)) ;
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.cpp	(revision 2291)
@@ -35,5 +35,7 @@
 shared_ptr<CGridAlgorithm> CGenericAlgorithmTransformation::createGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos)
 {
-  return make_shared<CGridAlgorithmGeneric>(gridSrc, gridDst, pos, shared_from_this()) ;
+  auto algo = make_shared<CGridAlgorithmGeneric>(gridSrc, gridDst, pos, shared_from_this()) ;
+  algo->computeAlgorithm() ;
+  return algo ; 
 }
 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_generic.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_generic.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_generic.cpp	(revision 2291)
@@ -13,8 +13,7 @@
   : CGridAlgorithm(algo), gridSrc_(gridSrc), gridDst_(gridDst), pos_(pos)
   {
-    computeAlgorithm() ;
   }
 
-  void CGridAlgorithmGeneric::computeAlgorithm(void)
+  void CGridAlgorithmGeneric::computeAlgorithm(bool eliminateRedondant)
   {
     shared_ptr<CGridLocalElements> gridSrcElements = gridSrc_->getGridLocalElements() ;
@@ -48,4 +47,5 @@
 
     gridTransformConnector_ = make_shared<CGridTransformConnector>(srcView->getViews(), remoteViews, comm ) ;
+    gridTransformConnector_->computeConnector(eliminateRedondant) ;
  
   }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_generic.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_generic.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_generic.hpp	(revision 2291)
@@ -26,9 +26,10 @@
     virtual ~CGridAlgorithmGeneric() {} ;
 
-    void computeAlgorithm(void) ;
+    void computeAlgorithm(bool eliminateRedundant=true) ;
     virtual void apply(const CArray<double,1>& dataIn, CArray<double,1>& dataOut) ;
     virtual void apply(const CArray<double,1>& dataIn, const vector<CArray<double,1>>& auxData, CArray<double,1>& dataOut) ;
     
   protected:
+
     shared_ptr<CGridTransformConnector> gridTransformConnector_=nullptr ;
     CGrid* gridSrc_ = nullptr ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_reduce.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_reduce.cpp	(revision 2291)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_reduce.cpp	(revision 2291)
@@ -0,0 +1,13 @@
+#include "grid_algorithm_reduce.hpp"
+#include "algo_types.hpp"
+
+namespace xios
+{
+ 
+  void CGridAlgorithmReduce::apply(const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
+  {
+    CArray<double,1> dataOutTmp ;
+    gridTransformConnector_->transfer(dataIn, dataOutTmp, operator_) ;
+    algorithm_->apply(dimBefore_, dimAfter_, dataOutTmp, dataOut) ;
+  }
+}
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_reduce.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_reduce.hpp	(revision 2291)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm_reduce.hpp	(revision 2291)
@@ -0,0 +1,40 @@
+#ifndef __XIOS_GRID_ALGORITHM_REDUCE_HPP__
+#define __XIOS_GRID_ALGORITHM_REDUCE_HPP__
+
+#include "grid_transform_connector.hpp"
+#include <map>
+#include "array_new.hpp"
+#include "local_view.hpp"
+#include "grid_algorithm_generic.hpp" 
+#include "reduction_types.hpp"
+
+namespace xios
+{
+  class CGrid;
+  class CGenericAlgorithmTransformation ;
+
+  /*!
+  \class CGenericAlgorithmTransformation
+  This class defines the interface for all other inherited algorithms class
+  */
+  class CTransformFilter ;
+  class CGarbageCollector ;
+
+  class CGridAlgorithmReduce : public CGridAlgorithmGeneric
+  {
+    public:
+      CGridAlgorithmReduce(CGrid* gridSrc, CGrid* gridDst, int pos,  shared_ptr<CGenericAlgorithmTransformation> algo, EReduction op) 
+                          : CGridAlgorithmGeneric(gridSrc, gridDst, pos, algo), operator_(op) {}
+      virtual ~CGridAlgorithmReduce() {} 
+
+       virtual void apply(const CArray<double,1>& dataIn, CArray<double,1>& dataOut) ;
+   
+    protected:
+
+     EReduction operator_ ; // reduction operator to apply
+
+  };
+
+}
+
+#endif // __XIOS_GRID_ALGORITHM_REDUCE_HPP__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_axis.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_axis.cpp	(revision 2291)
@@ -79,9 +79,39 @@
 
   } 
+
+  bool local=false ;
+  if (!algo->local.isEmpty()) local=algo->local ;
   
-  int globalIndexSize = axisSource-> n_glo;
-  for (int idx = 0; idx < globalIndexSize; ++idx)  transformationMapping_[0].push_back(idx);
+  auto& transMap = this->transformationMapping_;  
+  
+  if (local)
+  {
+    scalarDestination->n=1 ; // no mask
+    scalarDestination->mask.reset() ;
+    
+    CArray<size_t,1> srcGlobalIndex ;
+    axisSource->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(srcGlobalIndex) ;
+    size_t nbIdx = srcGlobalIndex.numElements();
+    if (nbIdx==0) scalarDestination->n=0 ;
+    scalarDestination->checkAttributes() ;
 
-  scalarDestination->checkAttributes() ;
+    for (size_t idx = 0; idx < nbIdx; ++idx)
+    {
+      size_t globalIdx = srcGlobalIndex(idx);
+      transformationMapping_[0].push_back(globalIdx);
+    }
+
+  }
+  else
+  {
+   scalarDestination->checkAttributes() ;
+
+   int globalIndexSize = axisSource->getLocalView(CElementView::WORKFLOW)->getGlobalSize();
+   CArray<size_t,1> dstGlobalIndex ;
+   scalarDestination->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(dstGlobalIndex) ;
+   if (dstGlobalIndex.numElements()!=0)
+     for (int idx = 0; idx < globalIndexSize; ++idx)  transformationMapping_[0].push_back(idx);
+  }
+
   this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), scalarDestination->getLocalView(CElementView::WORKFLOW)) ;
   
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_domain.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_domain.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_domain.cpp	(revision 2291)
@@ -74,35 +74,40 @@
   }
 
-  TransformationIndexMap& transMap = this->transformationMapping_;
-
-  int ni_glo = domainSrc_->ni_glo ;
-  int nj_glo = domainSrc_->nj_glo ;
-  int nbDomainIdx ;
+  bool local=false ;
+  if (!algo->local.isEmpty()) local=algo->local ;
   
-  bool  local = algo->local ;
+  auto& transMap = this->transformationMapping_;  
   
   if (local)
   {
-      const CArray<int, 1>& i_index = domainSrc_-> i_index.getValue() ;
-      const CArray<int, 1>& j_index = domainSrc_-> j_index.getValue() ;
-      const CArray<bool,1>& localMask = domainSrc_-> localMask ;
-      int nbDomainIdx = i_index.numElements();
+    scalarDestination->n=1 ; // no mask
+    scalarDestination->mask.reset() ;
+    
+    CArray<size_t,1> srcGlobalIndex ;
+    domainSource->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(srcGlobalIndex) ;
+    size_t nbIdx = srcGlobalIndex.numElements();
+    if (nbIdx==0) scalarDestination->n=0 ;
+    scalarDestination->checkAttributes() ;
 
-      for (int idxDomain = 0; idxDomain < nbDomainIdx; ++idxDomain)
-      {
-        if (localMask(idxDomain))
-        { 
-          transMap[0].push_back(j_index(idxDomain)* ni_glo + i_index(idxDomain));
-        }
-      }
+    for (size_t idx = 0; idx < nbIdx; ++idx)
+    {
+      size_t globalIdx = srcGlobalIndex(idx);
+      transformationMapping_[0].push_back(globalIdx);
+    }
+
   }
   else
-  {  
-    nbDomainIdx = ni_glo * nj_glo;
-    for (int idxDomain = 0; idxDomain < nbDomainIdx; ++idxDomain) transMap[0].push_back(idxDomain);    
+  {
+   scalarDestination->checkAttributes() ;
+
+   int globalIndexSize = domainSource->getLocalView(CElementView::WORKFLOW)->getGlobalSize();
+   CArray<size_t,1> dstGlobalIndex ;
+   scalarDestination->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(dstGlobalIndex) ;
+   if (dstGlobalIndex.numElements()!=0)
+     for (int idx = 0; idx < globalIndexSize; ++idx)  transformationMapping_[0].push_back(idx);
   }
-  
-  scalarDestination->checkAttributes() ;
+
   this->computeAlgorithm(domainSource->getLocalView(CElementView::WORKFLOW), scalarDestination->getLocalView(CElementView::WORKFLOW)) ;
+
 }
 CATCH
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_scalar.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_scalar.cpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_scalar.cpp	(revision 2291)
@@ -10,4 +10,6 @@
 #include "grid_transformation_factory_impl.hpp"
 #include "reduction.hpp"
+#include "grid_algorithm_reduce.hpp"
+
 
 
@@ -47,5 +49,5 @@
 TRY
 {
-  eliminateRedondantSrc_= false ;
+  scalarDestination->checkAttributes() ;
   if (algo->operation.isEmpty())
     ERROR("CScalarAlgorithmReduceScalar::CScalarAlgorithmReduceScalar(CScalar* scalarDestination, CScalar* scalarSource, CReduceScalarToScalar* algo)",
@@ -75,10 +77,28 @@
 
   }
-  transformationMapping_[0].push_back(0) ;
+  
+  auto& transMap = this->transformationMapping_;
+  
+  CArray<size_t,1> dstGlobalIndex ;
+  scalarDestination->getLocalView(CElementView::WORKFLOW)->getGlobalIndexView(dstGlobalIndex) ;
+  size_t nbIdx = dstGlobalIndex.numElements();
 
-  scalarDestination->checkAttributes() ;
+  for (size_t idx = 0; idx < nbIdx; ++idx)
+  {
+    size_t globalIdx = dstGlobalIndex(idx);
+    transMap[globalIdx].resize(1);
+    transMap[globalIdx][0]=globalIdx ;      
+  }
+
   this->computeAlgorithm(scalarSource->getLocalView(CElementView::WORKFLOW), scalarDestination->getLocalView(CElementView::WORKFLOW)) ; 
 }
 CATCH
+
+shared_ptr<CGridAlgorithm> CScalarAlgorithmReduceScalar::createGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos)
+{
+  auto algo=make_shared<CGridAlgorithmReduce>(gridSrc, gridDst, pos, shared_from_this(), operator_) ;
+  algo->computeAlgorithm(false) ;
+  return algo ; 
+}
 
 CScalarAlgorithmReduceScalar::~CScalarAlgorithmReduceScalar()
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_scalar.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_scalar.hpp	(revision 2290)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_scalar.hpp	(revision 2291)
@@ -42,4 +42,5 @@
                                                 std::map<int, int>& elementPositionInGridDst2AxisPosition,
                                                 std::map<int, int>& elementPositionInGridDst2DomainPosition);
+  virtual shared_ptr<CGridAlgorithm> createGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos);
   static bool dummyRegistered_;
 };
