Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/element.hpp	(revision 1999)
@@ -32,5 +32,6 @@
     void recvFromClient(CEventServer& event) ;
     size_t getGlobalSize(void) { return globalSize_;}
-
+    std::map<int, CArray<size_t,1>>& getGlobalIndex(void) { return globalIndex_;}
+    
     CDistributedView* getView(CElementView::type type) 
     { 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_local_view.hpp	(revision 1999)
@@ -19,4 +19,5 @@
       CGridLocalView(CGridLocalElements* parent, CElementView::type type) ;
       std::vector<CLocalView*>& getViews(void) {return views_ ;}
+      CLocalView* getView(int i) {return views_[i] ;}
       int getSize() { return size_ ;}
   } ;
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.cpp	(revision 1999)
@@ -11,4 +11,10 @@
                        : srcView_(srcView), dstView_(dstView), localComm_(localComm), remoteSize_(remoteSize) 
   {}
+
+  CGridRemoteConnector::CGridRemoteConnector(vector<CLocalView*>& srcView, vector<CLocalView*>& dstView, MPI_Comm localComm, int remoteSize) 
+                       : srcView_(srcView), localComm_(localComm), remoteSize_(remoteSize) 
+  {
+    for(auto& it : dstView) dstView_.push_back((CDistributedView*) it) ; 
+  }
 
   void CGridRemoteConnector::computeConnector(void)
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_remote_connector.hpp	(revision 1999)
@@ -19,4 +19,5 @@
 
       CGridRemoteConnector(vector<CLocalView*>& srcView, vector<CDistributedView*>& dstView, MPI_Comm localComm, int remoteSize) ;
+      CGridRemoteConnector(vector<CLocalView*>& srcView, vector<CLocalView*>& dstView, MPI_Comm localComm, int remoteSize) ;
       void computeConnector(void) ;
       void computeGenericMethod(void) ;
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 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.cpp	(revision 1999)
@@ -0,0 +1,81 @@
+#include "grid_transform_connector.hpp"
+#include "element.hpp"
+#include "scatterer_connector.hpp"
+#include "gatherer_connector.hpp"
+#include "grid_remote_connector.hpp"
+
+
+namespace xios
+{
+  void CGridTransformConnector::computeConnector(void)
+  {
+    int commSize ;
+    int commRank ;
+    MPI_Comm_size(localComm_, &commSize) ;
+    MPI_Comm_rank(localComm_, &commRank) ;
+    int nElements = srcViews_.size() ;
+
+    CGridRemoteConnector remoteConnector(srcViews_, remoteViews_, localComm_, commSize) ;  
+    remoteConnector.computeConnector() ;
+    
+    vector<CDistributedElement*> sendElements(nElements) ;
+    scattererConnector_.resize(nElements) ;
+    gathererConnector_.resize(nElements) ;
+
+    for(int i=0;i<nElements;i++)
+    {
+      sendElements[i] = new CDistributedElement(srcViews_[i]->getGlobalSize(), remoteConnector.getDistributedGlobalIndex(i)) ;
+      sendElements[i]->addFullView() ;
+      scattererConnector_[i] = new CScattererConnector(srcViews_[i], sendElements[i]->getView(CElementView::FULL), localComm_, commSize) ;
+      scattererConnector_[i]->computeConnector() ;
+      std::map<int, CArray<size_t,1>>& sendIndex = sendElements[i]->getGlobalIndex() ;
+
+      // how much sender ?
+      vector<int> nbSenders(commSize) ;
+      int nbSender ;
+      for(auto& it : sendIndex) nbSenders[it.first]=1 ;
+      vector<int> recvCounts(commSize,1) ;
+      MPI_Reduce_scatter(nbSenders.data(), &nbSender, recvCounts.data(), MPI_INT, MPI_SUM, localComm_) ;
+    
+      // transfer global index
+      // send Index
+      vector<MPI_Request> sendReq ;
+      for(auto& it : sendIndex)
+      {
+        MPI_Request req ;
+        MPI_Isend(it.second.dataFirst(), it.second.numElements(), MPI_SIZE_T, it.first,0, localComm_, &req) ;
+        sendReq.push_back(req) ;
+      }
+
+      // receive index
+      map<int,CArray<size_t,1>> recvIndex ;
+    
+      for(int j=0; j<nbSender; j++) 
+      {
+        int size ;
+        MPI_Status status ;
+        MPI_Probe(MPI_ANY_SOURCE, 0, localComm_, &status ) ;
+        MPI_Get_count(&status, MPI_SIZE_T, &size) ;
+        vector<size_t> recvBuff(size) ;
+        MPI_Recv(recvBuff.data(), size, MPI_SIZE_T, status.MPI_SOURCE,0, localComm_,&status) ;
+        CArray<size_t,1> arrayTmp(recvBuff.data(), shape(recvBuff.size()), duplicateData) ;
+        recvIndex[status.MPI_SOURCE].reference(arrayTmp) ;
+        if (recvRankSize_.count(status.MPI_SOURCE)==0) recvRankSize_[status.MPI_SOURCE] = size ; 
+        else recvRankSize_[status.MPI_SOURCE] *= size ; 
+      }
+      vector<MPI_Status> sendStatus(sendReq.size()) ;
+      MPI_Waitall(sendReq.size(),sendReq.data(),sendStatus.data()) ;
+      
+      // create gatherer connector
+
+      CDistributedElement recvElement(remoteViews_[i]->getGlobalSize(), recvIndex) ;
+      recvElement.addFullView() ;
+      gathererConnector_[i] = new CGathererConnector(recvElement.getView(CElementView::FULL), remoteViews_[i]) ;
+      gathererConnector_[i]->computeConnector() ;
+    }
+
+    gridScattererConnector_ = new CGridScattererConnector(scattererConnector_) ;
+    gridGathererConnector_  = new CGridGathererConnector(gathererConnector_) ;
+  }
+
+}
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 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/grid_transform_connector.hpp	(revision 1999)
@@ -0,0 +1,71 @@
+#ifndef __GRID_TRANSFORM_CONNECTOR_HPP__
+#define __GRID_TRANSFORM_CONNECTOR_HPP__
+
+#include "xios_spl.hpp"
+#include "array_new.hpp"
+#include "distributed_view.hpp"
+#include "local_view.hpp"
+#include "grid_scatterer_connector.hpp"
+#include "grid_gatherer_connector.hpp"
+#include "mpi.hpp"
+
+namespace xios
+{
+ 
+  
+  class CGridTransformConnector
+  {
+     
+    public:
+      CGridTransformConnector(vector<CLocalView*> srcViews, vector<CLocalView*> remoteViews, MPI_Comm localComm) 
+                          : srcViews_(srcViews), remoteViews_(remoteViews), localComm_(localComm) 
+                          { computeConnector();}
+    
+      void computeConnector(void) ; 
+    protected:
+     MPI_Comm localComm_ ;
+     vector<CLocalView*> srcViews_ ;
+     vector<CLocalView*> remoteViews_ ;
+     map<int,int> recvRankSize_ ;
+
+     vector<CScattererConnector*> scattererConnector_ ;
+     vector<CGathererConnector*>  gathererConnector_ ;
+     CGridScattererConnector* gridScattererConnector_ ;
+     CGridGathererConnector* gridGathererConnector_ ;
+  
+    public:
+      template<typename T> 
+      void transfer(const CArray<T,1>& dataIn, CArray<T,1>& dataOut)
+      {
+        map<int,CArray<T,1>> tmpArrayIn ;
+        gridScattererConnector_->transfer(dataIn, tmpArrayIn) ;
+        vector<MPI_Request> requests ;
+        MPI_Request request ;
+        for(auto it : tmpArrayIn)
+        {
+          auto& array = it.second ; 
+          MPI_Issend(array.dataFirst(), array.numElements(), MPI_GetType<T>(), it.first, 0, localComm_, &request) ;
+          requests.push_back(request) ;
+        }
+        
+        map<int,CArray<T,1>> tmpArrayOut ;
+        for(auto it : recvRankSize_)
+        {
+          auto& array = tmpArrayOut[it.first] ;
+          array.resize(it.second) ;
+          MPI_Irecv(array.dataFirst(), array.numElements(), MPI_GetType<T>(), it.first, 0, localComm_, &request) ;
+          requests.push_back(request) ;
+        }
+        
+        vector<MPI_Status> status(requests.size()) ;
+        MPI_Waitall(requests.size(), requests.data(),status.data()) ;
+        
+        const double nanValue = std::numeric_limits<double>::quiet_NaN();
+        gridGathererConnector_->transfer(tmpArrayOut, dataOut, nanValue) ;
+      }
+  
+  };
+
+}
+
+#endif
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/reduce_transform_connector.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/reduce_transform_connector.cpp	(revision 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/reduce_transform_connector.cpp	(revision 1999)
@@ -0,0 +1,56 @@
+#include "reduce_transform_connector.hpp"
+#include "exception.hpp"
+
+namespace xios
+{
+
+  CReduceTransformConnector::CReduceTransformConnector(CLocalView* srcView, CLocalView* dstView, EReduction op, 
+                                                       unordered_map<int, std::vector<int>>& indexMap, bool detectMissingValue)
+   : srcView_(srcView), dstView_(dstView), detectMissingValue_(detectMissingValue)
+  {
+    switch(op)
+    {
+      case EReduction::sum :
+        transfer_=&CReduceTransformConnector::transferSum ;
+        break ;
+      case EReduction::min :
+        break ;
+      case EReduction::max :
+        break ;
+      case EReduction::extract :
+        break ;
+      case EReduction::average :
+        break ;
+      default :
+       ERROR("CReduceTransformConnector::CReduceTransformConnector",
+             <<"reduction operator "<<(int)op<<" is not defined for this operation") ;
+       break ;
+    }
+
+    computeConnector(indexMap) ;
+  }
+
+  void CReduceTransformConnector::computeConnector(unordered_map<int, std::vector<int>>& indexMap)
+  {
+    CArray<size_t,1> dstGlobalIndex ;
+    CArray<size_t,1> srcGlobalIndex ;
+    dstView_->getGlobalIndexView(dstGlobalIndex) ;
+    srcView_->getGlobalIndexView(srcGlobalIndex) ;
+    unordered_map<size_t,int> srcMapIndex ;
+    srcSize_ = srcGlobalIndex.numElements() ;
+    dstSize_ = dstGlobalIndex.numElements() ;
+
+    for(int i=0;i<srcSize_;i++) srcMapIndex[srcGlobalIndex(i)]=i ;
+    for(int i=0; i< dstSize_;i++) 
+    {
+      if (indexMap.count(dstGlobalIndex(i))!=0)
+      {
+        auto& vectIndex  = indexMap[dstGlobalIndex(i)] ;
+        nSrc_.push_back(vectIndex.size()) ;
+        for(int j=0; j<vectIndex.size();j++) connector_.push_back(srcMapIndex[vectIndex[j]]) ;
+      }
+      else nSrc_.push_back(0) ;
+    }
+  }
+
+}
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 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/reduce_transform_connector.hpp	(revision 1999)
@@ -0,0 +1,136 @@
+#ifndef __REDUCE_TRANSFORM_CONNECTOR_HPP__
+#define __REDUCE_TRANSFORM_CONNECTOR_HPP__
+
+#include "xios_spl.hpp"
+#include "array_new.hpp"
+#include "local_view.hpp"
+#include "reduction_types.hpp"
+
+
+
+namespace xios
+{
+  
+  class CReduceTransformConnector
+  {
+    
+    private:
+      CLocalView* srcView_;
+      CLocalView* dstView_;
+
+      vector<int> connector_;  //  sizeof sum(nWeights_)  
+      vector<int> nSrc_ ;  //  sizeof dstSize_ 
+      int srcSize_ ;
+      int dstSize_ ;
+      bool detectMissingValue_ ;
+      EReduction type_ ;
+      
+      typedef void (CReduceTransformConnector::* transferPtr)(int, int, const CArray<double,1>& , CArray<double,1>&) ;
+      transferPtr transfer_ ;
+      
+     void computeConnector(unordered_map<int, std::vector<int>>& indexMap) ;
+      
+    public:
+
+    CReduceTransformConnector(CLocalView* srcView, CLocalView* dstView, EReduction op, unordered_map<int, std::vector<int>>& indexMap, 
+                              bool detectMissingValue=true) ;
+ 
+    void transfer(const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
+    {
+      transfer(1,1,dataIn, dataOut) ;
+    }
+        void transfer(int sizeT, const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
+    { 
+      transfer(1,sizeT, dataIn, dataOut) ;
+    }
+
+    void transfer(int repeat, int sizeT, const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
+    {
+      (this->*transfer_)(repeat, sizeT, dataIn, dataOut) ;
+    }
+    
+    private :
+    
+    void transferSum(int repeat, int sizeT, const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
+    {
+      double defaultValue = std::numeric_limits<double>::quiet_NaN();
+
+      int dstSlice = dstSize_*sizeT ;
+      int srcSlice = srcSize_*sizeT ;
+      dataOut.resize(repeat* dstSlice) ;
+      dataOut=0 ;
+           
+      const double* input = dataIn.dataFirst()  ;
+      double* output = dataOut.dataFirst()  ;
+
+      if (detectMissingValue_)
+      {
+        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 ;
+          for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
+          {
+            if (nSrc_[i]==0) for(int l=0; l<sizeT; l++) out[l] = defaultValue ;
+            else 
+            {
+              for(int j=0 ; j<nSrc_[i] ; j++,k++)
+                for(int l=0; l<sizeT; l++) 
+                {
+                  if (! std::isnan(in[connector_[k]*sizeT+l]) ) 
+                  {
+                    if (touched[pos+l]) out[l] += in[connector_[k]*sizeT+l] ;
+                    else 
+                    {
+                      touched[pos+l] = true ;
+                      out[l] = in[connector_[k]*sizeT+l] ;
+                    }
+                  }
+                }
+            }
+          }
+        }
+
+        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 ;
+          for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
+              for(int j=0 ; j<nSrc_[i] ; j++,k++)
+                for(int l=0; l<sizeT; l++) if (!touched[pos+l]) out[l] = defaultValue ;
+        }
+
+      }
+      else
+      {
+        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice)
+        {
+          const double* in = input;
+          double* out = output ;
+          int k=0 ;
+          for(int i=0; i<dstSize_; i++, out+=sizeT)
+            if (nSrc_[i]==0)
+              for(int l=0; l<sizeT; l++) out[l] = defaultValue ;
+            else 
+            {
+              for(int j=0 ; j<nSrc_[i] ; j++,k++)
+                for(int l=0; l<sizeT; l++) out[l] += in[connector_[k]*sizeT+l] ;
+            }
+        }
+      }
+    }
+
+
+  
+  };
+
+}
+
+#endif
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/transfer_transform_connector.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/transfer_transform_connector.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/transfer_transform_connector.hpp	(revision 1999)
@@ -47,5 +47,5 @@
           if (mask_[i])
           {
-            for(int l=0; l<sizeT; l++) out[l] += in[connector_[k]*sizeT+l] ;
+            for(int l=0; l<sizeT; l++) out[l] = in[connector_[k]*sizeT+l] ;
             k++ ;
           }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.cpp	(revision 1999)
@@ -1,10 +1,10 @@
 #include "transform_filter.hpp"
+#include "grid_algorithm.hpp"
 
 namespace xios
 {
   
-  CTransformFilter::CTransformFilter( CGarbageCollector& gc, CGenericAlgorithmTransformation* algo, int dimBefore, int dimAfter, 
-                                      bool detectMissingValues, double defaultValue) 
-                                    : CFilter(gc, 1, this), algorithm_(algo), dimBefore_(dimBefore), dimAfter_(dimAfter), 
+  CTransformFilter::CTransformFilter( CGarbageCollector& gc, CGridAlgorithm* algo, bool detectMissingValues, double defaultValue) 
+                                    : CFilter(gc, 1, this), algorithm_(algo), 
                                       detectMissingValues_(detectMissingValues), defaultValue_(defaultValue)
   {
@@ -20,5 +20,5 @@
     packet->status = data[0]->status;
 
-    if (packet->status == CDataPacket::NO_ERROR) algorithm_->apply(dimBefore_, dimAfter_, data[0]->data, packet->data);
+    if (packet->status == CDataPacket::NO_ERROR) algorithm_->apply(data[0]->data, packet->data);
     return packet;
   }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/filter/transform_filter.hpp	(revision 1999)
@@ -3,5 +3,5 @@
 
 #include "filter.hpp"
-#include "generic_algorithm_transformation.hpp"
+#include "grid_algorithm.hpp"
 
 namespace xios
@@ -15,6 +15,5 @@
     public:
 
-      CTransformFilter(CGarbageCollector& gc, CGenericAlgorithmTransformation* algo, int dimBefore, int dimAfter, 
-                              bool detectMissingValues, double defaultValue) ;
+      CTransformFilter(CGarbageCollector& gc, CGridAlgorithm* algo, bool detectMissingValues, double defaultValue) ;
 
     protected:
@@ -27,7 +26,5 @@
     private :
      
-     CGenericAlgorithmTransformation* algorithm_ ;
-     int dimBefore_ ;
-     int dimAfter_ ;
+     CGridAlgorithm* algorithm_ ;
      bool detectMissingValues_ ;
      bool defaultValue_ ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/field.cpp	(revision 1999)
@@ -850,4 +850,5 @@
         CGrid* newGrid ;
         std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = grid_->buildTransformationGraph(gc, true, nullptr, detectMissingValues, defaultValue, newGrid) ;
+        newGrid->duplicateAttributes(grid_) ; // for grid attributes (mask)
         grid_ = newGrid ;
         grid_ref=grid_->getId() ; // for server 
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp	(revision 1999)
@@ -27,4 +27,5 @@
 #include "grid_transformation_factory_impl.hpp"
 #include "transform_filter.hpp"
+#include "grid_algorithm.hpp"
 
 
@@ -241,4 +242,5 @@
      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
      CDomain* domain = vDomainGroup_->createChild(id);
+     isDomListSet=false ;
      computeElements();
      return domain ;
@@ -253,4 +255,5 @@
      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
      CAxis* axis=vAxisGroup_->createChild(id);
+     isAxisListSet=false ;
      computeElements(); 
      return axis ;
@@ -265,4 +268,5 @@
      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
      CScalar* scalar =  vScalarGroup_->createChild(id);
+     isScalarListSet=false ;
      computeElements();
      return scalar;
@@ -1922,5 +1926,5 @@
     else  
     {
-      newGrid = CGrid::create(newId) ; // give it an id later ??
+      newGrid = CGrid::create(newId) ;
       isNewGrid = true ;
     }
@@ -1930,6 +1934,5 @@
     bool hasRemainTransform=false ;
     CGenericAlgorithmTransformation* algo ;
-    int dimBefore=1 ;
-    int dimAfter=1 ;
+    int pos ;
 
     for(int i=0 ; i<elements_.size(); i++)
@@ -1958,4 +1961,5 @@
       if (hasTransform && !hadTransform)
       {
+        pos=i ;
         EElement dstElementType=transformationPath.getNextElementType() ;
         string dstElementId=transformationPath.getNextElementId() ;
@@ -2075,6 +2079,4 @@
           domain->checkAttributes() ;
          
-          if (hadTransform) dimBefore*=domain->getLocalView(CElementView::WORKFLOW)->getLocalSize() ;
-          else dimAfter*=domain->getLocalView(CElementView::WORKFLOW)->getLocalSize() ;
           if (isNewGrid) newGrid->addDomain(srcElementId) ;
         }
@@ -2091,6 +2093,4 @@
           axis->checkAttributes() ;
          
-          if (hadTransform) dimBefore*=axis->getLocalView(CElementView::WORKFLOW)->getLocalSize() ;
-          else dimAfter*=axis->getLocalView(CElementView::WORKFLOW)->getLocalSize() ;
           if (isNewGrid) newGrid->addAxis(srcElementId) ;
         }
@@ -2107,6 +2107,4 @@
           scalar->checkAttributes() ;
          
-          if (hadTransform) dimBefore*=scalar->getLocalView(CElementView::WORKFLOW)->getLocalSize() ;
-          else dimAfter*=scalar->getLocalView(CElementView::WORKFLOW)->getLocalSize() ;
           if (isNewGrid) newGrid->addScalar(srcElementId) ;
         }
@@ -2121,5 +2119,13 @@
       if (!isSource)
       {
-        shared_ptr<CTransformFilter> transformFilter = shared_ptr<CTransformFilter>(new CTransformFilter(gc, algo, dimBefore, dimAfter, detectMissingValues, defaultValue)) ;
+        CGridAlgorithm* gridAlgorithm  ;
+        if (isNewGrid)
+        { 
+          gridAlgorithm = algo->createGridAlgorithm(gridSrc, newGrid, pos) ;
+          newGrid->setGridAlgorithm(gridAlgorithm);
+        }
+        else gridAlgorithm = newGrid->getGridAlgorithm() ;
+
+        shared_ptr<CTransformFilter> transformFilter = shared_ptr<CTransformFilter>(new CTransformFilter(gc, gridAlgorithm, detectMissingValues, defaultValue)) ;
         outputFilter->connectOutput(transformFilter,0) ;
         outputFilter = transformFilter ;
@@ -2129,5 +2135,5 @@
       {
         gridSrc=newGrid ;
-        pair<shared_ptr<CFilter>, shared_ptr<CFilter> > filters = gridSrc->buildTransformationGraph(gc, isSource, gridSrc, detectMissingValues, defaultValue, newGrid) ;
+        pair<shared_ptr<CFilter>, shared_ptr<CFilter> > filters = this->buildTransformationGraph(gc, isSource, gridSrc, detectMissingValues, defaultValue, newGrid) ;
         outputFilter->connectOutput(filters.first,0) ;
         outputFilter=filters.second ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.hpp	(revision 1999)
@@ -22,4 +22,5 @@
 #include "transformation_path.hpp"
 #include "filter.hpp"
+#include "grid_algorithm.hpp"
 
 
@@ -239,4 +240,9 @@
                                                                                   double defaultValue, CGrid*& newGrid) ;
       private:
+        CGridAlgorithm* gridAlgorithm_ = nullptr ;
+      public:
+        void setGridAlgorithm(CGridAlgorithm* gridAlgorithm) {gridAlgorithm_ = gridAlgorithm;}
+        CGridAlgorithm* getGridAlgorithm(void) { return gridAlgorithm_ ;}
+      private:
          bool isTransformed_, isGenerated_;
          CGridTransformation* transformations_;
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/Functions/reduction_types.hpp	(revision 1999)
@@ -10,7 +10,8 @@
 #define __XIOS_REDUCTION_TYPES_HPP__
 
-namespace xios {
+namespace xios
+{
 
-  typedef enum reduction_alogirthm_type
+  typedef enum reduction_algurithm_type
   {
     TRANS_REDUCE_SUM = 0,
@@ -21,4 +22,8 @@
   } EReductionType;
 
+  enum class EReduction
+  {
+    sum, min, max, extract, average
+  } ;
 }
 #endif // __XIOS_REDUCTION_TYPES_HPP__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_reduce.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_reduce.cpp	(revision 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_reduce.cpp	(revision 1999)
@@ -0,0 +1,35 @@
+#include "algorithm_transformation_reduce.hpp"
+#include "context.hpp"
+
+namespace xios
+{
+
+
+  void CAlgorithmTransformationReduce::computeAlgorithm(CLocalView* srcView, CLocalView* dstView)
+ {
+    this->computeRecvElement(srcView, dstView) ;
+    reduceTransformConnector_ = new  CReduceTransformConnector( recvElement_->getView(CElementView::FULL), dstView, operator_, transformationMapping_, detectMissingValue_) ; 
+  }
+ 
+
+  void CAlgorithmTransformationReduce::apply(int dimBefore, int dimAfter, const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
+  {
+   // CArray<double,1> dataOutTmp ;
+   // transformConnector_->transfer(dimBefore, dimAfter, dataIn, dataOutTmp) ;
+    reduceTransformConnector_ -> transfer(dimBefore, dimAfter, dataIn, dataOut) ;
+  }
+  
+  void CAlgorithmTransformationReduce::computeRecvElement(CLocalView* srcView, CLocalView* dstView)
+  {
+    auto& srcMap = transformationMapping_ ;
+    set<size_t> srcIndex ;
+    for(auto& it : srcMap)
+      for(size_t index : it.second) srcIndex.insert(index) ;
+
+    CArray<size_t,1> srcArrayIndex(srcIndex.size()) ;
+    int i=0 ;
+    for(size_t index : srcIndex) { srcArrayIndex(i) = index ; i++ ;}
+    recvElement_ = new CLocalElement(CContext::getCurrent()->getIntraCommRank(), srcView->getGlobalSize(), srcArrayIndex) ;
+    recvElement_->addFullView() ;
+  }
+}
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 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_reduce.hpp	(revision 1999)
@@ -0,0 +1,35 @@
+#ifndef __XIOS_ALGORITHM_TRANSFORMATION_REDUCE_HPP__
+#define __XIOS_ALGORITHM_TRANSFORMATION_REDUCE_HPP__
+
+#include "generic_algorithm_transformation.hpp"
+#include "array_new.hpp"
+#include "local_view.hpp"
+#include "transform_connector.hpp"
+#include "reduce_transform_connector.hpp"
+
+namespace xios
+{
+
+  class CAlgorithmTransformationReduce : public CGenericAlgorithmTransformation
+  {
+    public:
+
+      CAlgorithmTransformationReduce(bool isSource) : CGenericAlgorithmTransformation(isSource) {}
+      virtual ~CAlgorithmTransformationReduce() {};
+      virtual void apply(int dimBefore, int dimAfter, const CArray<double,1>& dataIn, CArray<double,1>& dataOut);
+      void computeRecvElement(CLocalView* srcView, CLocalView* dstView) ;
+      
+    protected:
+      virtual void computeAlgorithm(CLocalView* srcView, CLocalView* dstView) ;
+       
+      //! Map between global index of destination element and source element
+      EReduction operator_ ;
+      TransformationIndexMap transformationMapping_;
+      CTransformConnector* transformConnector_ ;
+      CReduceTransformConnector* reduceTransformConnector_ ;
+      bool detectMissingValue_=true ;
+      bool eliminateRedondantSrc_ = true ; 
+  };
+
+}
+#endif //__XIOS_ALGORITHM_TRANSFORMATION_REDUCE_HPP__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_transfer.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_transfer.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_transfer.cpp	(revision 1999)
@@ -32,3 +32,15 @@
   }
   
+  void CAlgorithmTransformationTransfer::computeRecvElement(CLocalView* srcView, CLocalView* dstView)
+  {
+    set<size_t> srcIndex ;
+    for(auto& it : transformationMapping_) srcIndex.insert(it.second) ;
+
+    CArray<size_t,1> srcArrayIndex(srcIndex.size()) ;
+    int i=0 ;
+    for(size_t index : srcIndex) { srcArrayIndex(i) = index ; i++ ;}
+    recvElement_ = new CLocalElement(CContext::getCurrent()->getIntraCommRank(), srcView->getGlobalSize(), srcArrayIndex) ;
+    recvElement_->addFullView() ;
+  }
+
 }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_transfer.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_transfer.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_transfer.hpp	(revision 1999)
@@ -16,4 +16,5 @@
       virtual ~CAlgorithmTransformationTransfer() {};
       virtual void apply(int dimBefore, int dimAfter, const CArray<double,1>& dataIn, CArray<double,1>& dataOut);
+      void computeRecvElement(CLocalView* srcView, CLocalView* dstView) ;
    
     protected:
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_weight.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_weight.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_weight.cpp	(revision 1999)
@@ -8,18 +8,6 @@
   void CAlgorithmTransformationWeight::computeAlgorithm(CLocalView* srcView, CLocalView* dstView)
  {
-   auto& srcMap = transformationMapping_ ;
-   set<size_t> srcIndex ;
-   for(auto& it : srcMap)
-     for(size_t index : it.second) srcIndex.insert(index) ;
-
-    CArray<size_t,1> srcArrayIndex(srcIndex.size()) ;
-    int i=0 ;
-    for(size_t index : srcIndex) { srcArrayIndex(i) = index ; i++ ;}
-    CLocalElement recvElement(CContext::getCurrent()->getIntraCommRank(), srcView->getGlobalSize(), srcArrayIndex) ;
-    recvElement.addFullView() ;
-
-    transformConnector_ = new CTransformConnector(srcView, recvElement.getView(CElementView::FULL), CContext::getCurrent()->getIntraComm())  ;
-    transformConnector_->computeConnector() ;
-    weightTransformConnector_ = new  CWeightTransformConnector( recvElement.getView(CElementView::FULL), dstView, transformationMapping_, transformationWeight_) ; 
+    this->computeRecvElement(srcView, dstView) ;
+    weightTransformConnector_ = new  CWeightTransformConnector( recvElement_->getView(CElementView::FULL), dstView, transformationMapping_, transformationWeight_) ; 
   }
  
@@ -32,3 +20,16 @@
   }
 
+  void CAlgorithmTransformationWeight::computeRecvElement(CLocalView* srcView, CLocalView* dstView)
+  {
+    auto& srcMap = transformationMapping_ ;
+    set<size_t> srcIndex ;
+    for(auto& it : srcMap)
+      for(size_t index : it.second) srcIndex.insert(index) ;
+
+    CArray<size_t,1> srcArrayIndex(srcIndex.size()) ;
+    int i=0 ;
+    for(size_t index : srcIndex) { srcArrayIndex(i) = index ; i++ ;}
+    recvElement_ = new CLocalElement(CContext::getCurrent()->getIntraCommRank(), srcView->getGlobalSize(), srcArrayIndex) ;
+    recvElement_->addFullView() ;
+  }
 }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_weight.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_weight.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/algorithm_transformation_weight.hpp	(revision 1999)
@@ -18,5 +18,5 @@
       virtual ~CAlgorithmTransformationWeight() {};
       virtual void apply(int dimBefore, int dimAfter, const CArray<double,1>& dataIn, CArray<double,1>& dataOut);
-      
+      void computeRecvElement(CLocalView* srcView, CLocalView* dstView);
     protected:
       virtual void computeAlgorithm(CLocalView* srcView, CLocalView* dstView) ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_duplicate_scalar.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_duplicate_scalar.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_duplicate_scalar.cpp	(revision 1999)
@@ -47,5 +47,5 @@
 {
   
-  CArray<int,1>& axisDstIndex = axisDest_->index;
+  CArray<int,1>& axisDstIndex = axisDestination->index;
 
   int nbAxisIdx = axisDstIndex.numElements();
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_duplicate_scalar.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_duplicate_scalar.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_duplicate_scalar.hpp	(revision 1999)
@@ -36,7 +36,4 @@
 private:
 
-  CAxis* axisSrc_;
-  CAxis* axisDest_;
-
   static CGenericAlgorithmTransformation* create(bool isSource, CGrid* gridDst, CGrid* gridSrc,
                                                 CTransformation<CAxis>* transformation,
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_extract_domain.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_extract_domain.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_extract_domain.cpp	(revision 1999)
@@ -48,5 +48,5 @@
 
 CAxisAlgorithmExtractDomain::CAxisAlgorithmExtractDomain(bool isSource, CAxis* axisDestination, CDomain* domainSource, CExtractDomainToAxis* algo)
- : CAxisAlgorithmTransformation(isSource, axisDestination, domainSource), pos_(-1), reduction_(0)
+ : CAlgorithmTransformationTransfer(isSource), pos_(-1), axisDest_(axisDestination), domainSrc_(domainSource)
 TRY
 {
@@ -67,34 +67,6 @@
 
   pos_ = algo->position;
-  reduction_ = CReductionAlgorithm::createOperation(CReductionAlgorithm::ReductionOperations[op]);
-}
-CATCH
 
-void CAxisAlgorithmExtractDomain::apply(const std::vector<std::pair<int,double> >& localIndex,
-                                        const double* dataInput,
-                                        CArray<double,1>& dataOut,
-                                        std::vector<bool>& flagInitial,                     
-                                        bool ignoreMissingValue, bool firstPass)
-TRY
-{
-  reduction_->apply(localIndex, dataInput, dataOut, flagInitial, ignoreMissingValue, firstPass);
-}
-CATCH
-
-CAxisAlgorithmExtractDomain::~CAxisAlgorithmExtractDomain()
-TRY
-{
-  if (0 != reduction_) delete reduction_;
-}
-CATCH
-
-void CAxisAlgorithmExtractDomain::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
-TRY
-{
-  this->transformationMapping_.resize(1);
-  this->transformationWeight_.resize(1);
-
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationWeightMap& transWeight = this->transformationWeight_[0];
+  auto& transMap = this->transformationMapping_;
 
   CArray<int,1>& axisDstIndex = axisDest_->index;
@@ -106,9 +78,5 @@
     {
       int globalAxisIdx = axisDstIndex(idxAxis);
-      transMap[globalAxisIdx].resize(1);
-      transWeight[globalAxisIdx].resize(1);
-      transMap[globalAxisIdx][0] = globalAxisIdx * ni_glo + pos_;
-      transWeight[globalAxisIdx][0] = 1.0;
-
+      transMap[globalAxisIdx] = globalAxisIdx * ni_glo + pos_;
     }
   }
@@ -119,13 +87,21 @@
     {
       int globalAxisIdx = axisDstIndex(idxAxis);
-      transMap[globalAxisIdx].resize(1);
-      transWeight[globalAxisIdx].resize(1);
-      transMap[globalAxisIdx][0] = globalAxisIdx + ni_glo * pos_;
-      transWeight[globalAxisIdx][0] = 1.0;
+      transMap[globalAxisIdx] = globalAxisIdx + ni_glo * pos_;
     }
   }
   else
   {}
+
+  axisDestination->checkAttributes() ;
+  this->computeAlgorithm(domainSource->getLocalView(CElementView::WORKFLOW), axisDestination->getLocalView(CElementView::WORKFLOW)) ;
 }
 CATCH
+
+
+CAxisAlgorithmExtractDomain::~CAxisAlgorithmExtractDomain()
+TRY
+{
 }
+CATCH
+
+}
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_extract_domain.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_extract_domain.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_extract_domain.hpp	(revision 1999)
@@ -10,5 +10,5 @@
 #define __XIOS_AXIS_ALGORITHM_EXTRACT_DOMAIN_HPP__
 
-#include "axis_algorithm_transformation.hpp"
+#include "algorithm_transformation_transfer.hpp"
 #include "transformation.hpp"
 
@@ -25,16 +25,10 @@
   Extract a domain to an axis
 */
-class CAxisAlgorithmExtractDomain : public CAxisAlgorithmTransformation
+class CAxisAlgorithmExtractDomain : public CAlgorithmTransformationTransfer
 {
 public:
   CAxisAlgorithmExtractDomain(bool isSource, CAxis* axisDestination, CDomain* domainSource, CExtractDomainToAxis* algo);
 
-  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
-                     const double* dataInput,
-                     CArray<double,1>& dataOut,
-                     std::vector<bool>& flagInitial,                     
-                     bool ignoreMissingValue, bool firstPass);
-
-  virtual ~CAxisAlgorithmExtractDomain();
+   virtual ~CAxisAlgorithmExtractDomain();
 
   static bool registerTrans();
@@ -48,11 +42,8 @@
   ExtractDirection dir_;
   int pos_; //! Position to extract
-protected:
-  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
-
-protected:
-  CReductionAlgorithm* reduction_;
-
+  
 private:
+  CDomain* domainSrc_;
+  CAxis* axisDest_ ;
   static CGenericAlgorithmTransformation* create(bool isSource, CGrid* gridDst, CGrid* gridSrc,
                                                 CTransformation<CAxis>* transformation,
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.cpp	(revision 1999)
@@ -49,5 +49,5 @@
 
 CAxisAlgorithmInverse::CAxisAlgorithmInverse(bool isSource, CAxis* axisDestination, CAxis* axisSource, CInverseAxis* inverseAxis)
- : CAxisAlgorithmTransformation(isSource, axisDestination, axisSource)
+ : CAlgorithmTransformationTransfer(isSource), axisDest_(axisDestination), axisSrc_(axisSource)
 TRY
 {
@@ -59,21 +59,11 @@
            << "Size of axis destination " <<axisDestination->getId() << " is " << axisDestination->n_glo.getValue());
   }
-}
-CATCH
-
-void CAxisAlgorithmInverse::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
-TRY
-{
-  this->transformationMapping_.resize(1);
-  this->transformationWeight_.resize(1);
-
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationWeightMap& transWeight = this->transformationWeight_[0];
-
-  int globalIndexSize = axisDestGlobalIndex_.size();
+
+  auto& transMap = this->transformationMapping_;
+
+  int globalIndexSize = axisDestination->index.size();
   for (int idx = 0; idx < globalIndexSize; ++idx)
   {
-    transMap[axisDestGlobalIndex_[idx]].push_back(axisDestGlobalSize_-axisDestGlobalIndex_[idx]-1);
-    transWeight[axisDestGlobalIndex_[idx]].push_back(1.0);
+    transMap[axisDestination->index(idx)] = globalIndexSize-axisDestination->index(idx)-1;
   }
 
@@ -88,6 +78,11 @@
     }
   }
-}
-CATCH
+
+  axisDestination->checkAttributes() ;
+  this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), axisDestination->getLocalView(CElementView::WORKFLOW)) ;
+
+}
+CATCH
+
 
 /*!
@@ -118,11 +113,10 @@
   typedef std::unordered_map<size_t, std::vector<double> > GlobalIndexMapFromSrcToDest;
   GlobalIndexMapFromSrcToDest globalIndexMapFromSrcToDest;
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationIndexMap::const_iterator itb = transMap.begin(), ite = transMap.end(), it;
+  auto& transMap = this->transformationMapping_;
   CArray<size_t,1> globalSrcIndex(transMap.size());
   int localIndex = 0;
-  for (it = itb; it != ite; ++it)
-  {
-    size_t srcIndex = it->second[0];
+  for (auto it = transMap.begin(); it != transMap.end(); ++it)
+  {
+    size_t srcIndex = it->second;
     globalIndexMapFromSrcToDest[srcIndex].resize(1);
     globalIndexMapFromSrcToDest[srcIndex][0] = it->first;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_inverse.hpp	(revision 1999)
@@ -10,5 +10,5 @@
 #define __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
 
-#include "axis_algorithm_transformation.hpp"
+#include "algorithm_transformation_transfer.hpp"
 #include "transformation.hpp"
 
@@ -22,5 +22,5 @@
   Inversing an axis
 */
-class CAxisAlgorithmInverse : public CAxisAlgorithmTransformation
+class CAxisAlgorithmInverse : public CAlgorithmTransformationTransfer
 {
 public:
@@ -31,8 +31,8 @@
   static bool registerTrans();
 
-protected:
-  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
+  CAxis* axisSrc_;
+  CAxis* axisDest_;
   void updateAxisValue();
 
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.cpp	(revision 1999)
@@ -12,5 +12,5 @@
 #include "grid.hpp"
 #include "grid_transformation_factory_impl.hpp"
-#include "reduction.hpp"
+
 
 namespace xios {
@@ -47,23 +47,23 @@
 
 CAxisAlgorithmReduceAxis::CAxisAlgorithmReduceAxis(bool isSource, CAxis* axisDestination, CAxis* axisSource, CReduceAxisToAxis* algo)
- : CAxisAlgorithmTransformation(isSource, axisDestination, axisSource), reduction_(0)
+ : CAlgorithmTransformationReduce(isSource)
 TRY
 {
   eliminateRedondantSrc_= false ;
   algo->checkValid(axisDestination, axisSource);
-  StdString op;
+
   switch (algo->operation)
   {
     case CReduceAxisToAxis::operation_attr::sum:
-      op = "sum";
+      operator_ = EReduction::sum;
       break;
     case CReduceAxisToAxis::operation_attr::min:
-      op = "min";
+      operator_ = EReduction::min;
       break;
     case CReduceAxisToAxis::operation_attr::max:
-      op = "max";
+      operator_ = EReduction::max;
       break;
     case CReduceAxisToAxis::operation_attr::average:
-      op = "average";
+      operator_ = EReduction::average;
       break;
     default:
@@ -73,55 +73,29 @@
          << "Axis destination " << axisDestination->getId());
 
+    TransformationIndexMap& transMap = this->transformationMapping_;
+    CArray<int,1>& axisDstIndex = axisDestination->index;
+    int nbAxisIdx = axisDstIndex.numElements();
+    for (int idxAxis = 0; idxAxis < nbAxisIdx; ++idxAxis)
+    {
+      int globalAxisIdx = axisDstIndex(idxAxis);
+      transMap[globalAxisIdx].resize(1);
+      transMap[globalAxisIdx][0]=globalAxisIdx ;      
+    }
+
   }
-
-  reduction_ = CReductionAlgorithm::createOperation(CReductionAlgorithm::ReductionOperations[op]);
+ 
+  axisDestination->checkAttributes() ;
+  this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), axisDestination->getLocalView(CElementView::WORKFLOW)) ;
 }
 CATCH
 
-void CAxisAlgorithmReduceAxis::apply(const std::vector<std::pair<int,double> >& localIndex,
-                                       const double* dataInput,
-                                       CArray<double,1>& dataOut,
-                                       std::vector<bool>& flagInitial,                     
-                                       bool ignoreMissingValue, bool firstPass)
-TRY
-{
-  reduction_->apply(localIndex, dataInput, dataOut, flagInitial, ignoreMissingValue, firstPass);
-}
-CATCH
-
-void CAxisAlgorithmReduceAxis::updateData(CArray<double,1>& dataOut)
-TRY
-{
-  reduction_->updateData(dataOut);
-}
-CATCH
 
 CAxisAlgorithmReduceAxis::~CAxisAlgorithmReduceAxis()
 TRY
 {
-  if (0 != reduction_) delete reduction_;
+ 
 }
 CATCH
 
-void CAxisAlgorithmReduceAxis::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
-TRY
-{
-  this->transformationMapping_.resize(1);
-  this->transformationWeight_.resize(1);
-
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationWeightMap& transWeight = this->transformationWeight_[0];
-  CArray<int,1>& axisDstIndex = axisDest_->index;
-  int nbAxisIdx = axisDstIndex.numElements();
-  for (int idxAxis = 0; idxAxis < nbAxisIdx; ++idxAxis)
-  {
-    int globalAxisIdx = axisDstIndex(idxAxis);
-    transMap[globalAxisIdx].resize(1);
-    transWeight[globalAxisIdx].resize(1);
-    transMap[globalAxisIdx][0]=globalAxisIdx ;      
-    transWeight[globalAxisIdx][0] = 1.0 ;      
-  }
-}
-CATCH
 
 }
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_axis.hpp	(revision 1999)
@@ -10,5 +10,5 @@
 #define __XIOS_AXIS_ALGORITHM_REDUCE_AXIS_HPP__
 
-#include "axis_algorithm_transformation.hpp"
+#include "algorithm_transformation_reduce.hpp"
 #include "transformation.hpp"
 
@@ -23,28 +23,14 @@
   Reduce a axis to an axis
 */
-class CAxisAlgorithmReduceAxis : public CAxisAlgorithmTransformation
+class CAxisAlgorithmReduceAxis : public CAlgorithmTransformationReduce
 {
 public:
   CAxisAlgorithmReduceAxis(bool isSource, CAxis* axisDestination, CAxis* axisSource, CReduceAxisToAxis* algo);
 
-  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
-                     const double* dataInput,
-                     CArray<double,1>& dataOut,
-                     std::vector<bool>& flagInitial,                     
-                     bool ignoreMissingValue, bool firstPass);
-
-  virtual void updateData(CArray<double,1>& dataOut);
   
   virtual ~CAxisAlgorithmReduceAxis();
 
   static bool registerTrans();
-protected:
   
-protected:
-  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs); 
-  
-protected:
-  CReductionAlgorithm* reduction_;
-
 private:
   static CGenericAlgorithmTransformation* create(bool isSource, CGrid* gridDst, CGrid* gridSrc,
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_domain.cpp	(revision 1999)
@@ -48,22 +48,21 @@
 
 CAxisAlgorithmReduceDomain::CAxisAlgorithmReduceDomain(bool isSource, CAxis* axisDestination, CDomain* domainSource, CReduceDomainToAxis* algo)
- : CAxisAlgorithmTransformation(isSource, axisDestination, domainSource), reduction_(0)
+ : CAlgorithmTransformationReduce(isSource), domainSrc_(domainSource), axisDest_(axisDestination)
 TRY
 {
   algo->checkValid(axisDestination, domainSource);
-  StdString op;
   switch (algo->operation)
   {
     case CReduceDomainToAxis::operation_attr::sum:
-      op = "sum";
+       operator_ = EReduction::sum;
       break;
     case CReduceDomainToAxis::operation_attr::min:
-      op = "min";
+       operator_ = EReduction::min;
       break;
     case CReduceDomainToAxis::operation_attr::max:
-      op = "max";
+       operator_ = EReduction::max;
       break;
     case CReduceDomainToAxis::operation_attr::average:
-      op = "average";
+       operator_ = EReduction::average;
       break;
     default:
@@ -76,42 +75,7 @@
 
   dir_ = (CReduceDomainToAxis::direction_attr::iDir == algo->direction)  ? iDir : jDir;
-  reduction_ = CReductionAlgorithm::createOperation(CReductionAlgorithm::ReductionOperations[op]);
-  local = algo->local ;
-}
-CATCH
+  bool local = algo->local ;
 
-void CAxisAlgorithmReduceDomain::apply(const std::vector<std::pair<int,double> >& localIndex,
-                                       const double* dataInput,
-                                       CArray<double,1>& dataOut,
-                                       std::vector<bool>& flagInitial,                     
-                                       bool ignoreMissingValue, bool firstPass)
-TRY
-{
-  reduction_->apply(localIndex, dataInput, dataOut, flagInitial, ignoreMissingValue, firstPass);
-}
-CATCH
-
-void CAxisAlgorithmReduceDomain::updateData(CArray<double,1>& dataOut)
-TRY
-{
-  reduction_->updateData(dataOut);
-}
-CATCH
-
-CAxisAlgorithmReduceDomain::~CAxisAlgorithmReduceDomain()
-TRY
-{
-  if (0 != reduction_) delete reduction_;
-}
-CATCH
-
-void CAxisAlgorithmReduceDomain::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
-TRY
-{
-  this->transformationMapping_.resize(1);
-  this->transformationWeight_.resize(1);
-
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationWeightMap& transWeight = this->transformationWeight_[0];
+  TransformationIndexMap& transMap = transformationMapping_;
 
   CArray<int,1>& axisDstIndex = axisDest_->index;
@@ -131,5 +95,4 @@
         { 
           transMap[j_index(idxDomain)].push_back(j_index(idxDomain)* ni_glo + i_index(idxDomain));
-          transWeight[j_index(idxDomain)].push_back(1.0) ;
         }
       }
@@ -142,9 +105,7 @@
         int globalAxisIdx = axisDstIndex(idxAxis);
         transMap[globalAxisIdx].resize(ni_glo);
-        transWeight[globalAxisIdx].resize(ni_glo);
         for (int idx = 0; idx < ni_glo; ++idx)
         {
           transMap[globalAxisIdx][idx] = globalAxisIdx * ni_glo + idx;
-          transWeight[globalAxisIdx][idx] = 1.0;
         }
       }
@@ -166,5 +127,4 @@
         { 
           transMap[i_index(idxDomain)].push_back(j_index(idxDomain)* ni_glo + i_index(idxDomain));
-          transWeight[i_index(idxDomain)].push_back(1.0) ;
         }
       }
@@ -176,9 +136,7 @@
         int globalAxisIdx = axisDstIndex(idxAxis);
         transMap[globalAxisIdx].resize(nj_glo);
-        transWeight[globalAxisIdx].resize(nj_glo);
         for (int idx = 0; idx < nj_glo; ++idx)
         {
           transMap[globalAxisIdx][idx] = globalAxisIdx + ni_glo*idx;
-          transWeight[globalAxisIdx][idx] = 1.0;
         }
       }
@@ -187,6 +145,18 @@
   else
   {}
+
+  axisDestination->checkAttributes() ;
+  this->computeAlgorithm(domainSource->getLocalView(CElementView::WORKFLOW), axisDestination->getLocalView(CElementView::WORKFLOW)) ;
+
 }
 CATCH
 
+
+CAxisAlgorithmReduceDomain::~CAxisAlgorithmReduceDomain()
+TRY
+{
 }
+CATCH
+
+
+}
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_domain.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_domain.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_reduce_domain.hpp	(revision 1999)
@@ -10,5 +10,5 @@
 #define __XIOS_AXIS_ALGORITHM_REDUCE_DOMAIN_HPP__
 
-#include "axis_algorithm_transformation.hpp"
+#include "algorithm_transformation_reduce.hpp"
 #include "transformation.hpp"
 
@@ -24,16 +24,8 @@
   Reduce a domain to an axis
 */
-class CAxisAlgorithmReduceDomain : public CAxisAlgorithmTransformation
+class CAxisAlgorithmReduceDomain : public CAlgorithmTransformationReduce
 {
 public:
   CAxisAlgorithmReduceDomain(bool isSource, CAxis* axisDestination, CDomain* domainSource, CReduceDomainToAxis* algo);
-
-  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
-                     const double* dataInput,
-                     CArray<double,1>& dataOut,
-                     std::vector<bool>& flagInitial,                     
-                     bool ignoreMissingValue, bool firstPass);
-
-  virtual void updateData(CArray<double,1>& dataOut);
   
   virtual ~CAxisAlgorithmReduceDomain();
@@ -50,9 +42,6 @@
   bool local ;
   
-protected:
-  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs); 
-  
-protected:
-  CReductionAlgorithm* reduction_;
+  CDomain* domainSrc_ ;
+  CAxis* axisDest_ ;
 
 private:
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.cpp	(revision 1999)
@@ -1143,7 +1143,22 @@
 ///////////////////////////////////////////////////////////////
 
+CGridAlgorithm* CGenericAlgorithmTransformation::createGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos)
+{
+  return new CGridAlgorithm(gridSrc, gridDst, pos, this) ;
+}
 
 
 void CGenericAlgorithmTransformation::computeAlgorithm(CLocalView* srcView, CLocalView* dstView)
+{
+ 
+  this->computeRecvElement(srcView, dstView) ;
+/*
+  transformConnector_ = new CTransformConnector(srcView, recvElement.getView(CElementView::FULL), CContext::getCurrent()->getIntraComm())  ;
+  transformConnector_->computeConnector() ; 
+*/
+  weightTransformConnector_ = new  CWeightTransformConnector(recvElement_->getView(CElementView::FULL), dstView, transformationMapping_[0], transformationWeight_[0]) ; 
+}
+ 
+void CGenericAlgorithmTransformation::computeRecvElement(CLocalView* srcView, CLocalView* dstView)
 {
   auto& srcMap = transformationMapping_[0] ;
@@ -1155,24 +1170,14 @@
   int i=0 ;
   for(size_t index : srcIndex) { srcArrayIndex(i) = index ; i++ ;}
-  CLocalElement recvElement(CContext::getCurrent()->getIntraCommRank(), srcView->getGlobalSize(), srcArrayIndex) ;
-  recvElement.addFullView() ;
-
-  transformConnector_ = new CTransformConnector(srcView, recvElement.getView(CElementView::FULL), CContext::getCurrent()->getIntraComm())  ;
-  transformConnector_->computeConnector() ;
-  weightTransformConnector_ = new  CWeightTransformConnector( recvElement.getView(CElementView::FULL), dstView, transformationMapping_[0], transformationWeight_[0]) ; 
-}
- 
+  recvElement_ = new CLocalElement(CContext::getCurrent()->getIntraCommRank(), srcView->getGlobalSize(), srcArrayIndex) ;
+  recvElement_->addFullView() ;
+}
 
 void CGenericAlgorithmTransformation::apply(int dimBefore, int dimAfter, const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
 {
-  CArray<double,1> dataOutTmp ;
-  transformConnector_->transfer(dimBefore, dimAfter, dataIn, dataOutTmp) ;
-  weightTransformConnector_ -> transfer(dimBefore, dimAfter, dataOutTmp, dataOut) ;
-}
-
-
-
-
-
-
-}
+  //CArray<double,1> dataOutTmp ;
+  //transformConnector_->transfer(dimBefore, dimAfter, dataIn, dataOutTmp) ;
+  weightTransformConnector_ -> transfer(dimBefore, dimAfter, dataIn, dataOut) ;
+}
+
+}
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.hpp	(revision 1999)
@@ -24,4 +24,5 @@
   class CAxis;
   class CScalar;
+  class CGridAlgorithm ;
 
   /*!
@@ -183,5 +184,13 @@
     virtual void computeAlgorithm(CLocalView* srcView, CLocalView* dstView) ;
     virtual void apply(int dimBefore, int dimAfter, const CArray<double,1>& dataIn, CArray<double,1>& dataOut);
-    
+    virtual CGridAlgorithm* createGridAlgorithm(CGrid* gridSrc, CGrid* newGrid, int pos) ;
+    virtual void computeRecvElement(CLocalView* srcView, CLocalView* dstView) ;
+  protected :
+
+    CLocalElement* recvElement_=nullptr ;
+  public:
+    CLocalElement* getRecvElement(void) { return recvElement_ ;}
+  
+  protected:
     CTransformConnector* transformConnector_ ;
     CWeightTransformConnector* weightTransformConnector_ ;
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm.cpp	(revision 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm.cpp	(revision 1999)
@@ -0,0 +1,59 @@
+#include "grid_algorithm.hpp"
+#include "grid_elements.hpp"
+#include "grid_local_view.hpp"
+#include "grid.hpp"
+#include "context.hpp"
+
+namespace xios
+{
+
+  CGridAlgorithm::CGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos,  CGenericAlgorithmTransformation* algo)
+  : gridSrc_(gridSrc), gridDst_(gridDst), pos_(pos), algorithm_(algo)
+  {
+    this->computeAlgorithm() ;
+  }
+
+  void CGridAlgorithm::computeAlgorithm(void)
+  {
+    CGridLocalElements* gridSrcElements = gridSrc_->getGridLocalElements() ;
+    CGridLocalElements* gridDstElements = gridDst_->getGridLocalElements() ;
+    
+    CGridLocalView* srcView = gridSrcElements->getView(CElementView::WORKFLOW) ;
+    CGridLocalView* dstView = gridDstElements->getView(CElementView::WORKFLOW) ;
+    MPI_Comm comm = CContext::getCurrent()->getIntraComm() ;
+    int commSize = CContext::getCurrent()->getIntraCommSize() ;
+    int commRank = CContext::getCurrent()->getIntraCommRank() ;
+    
+    auto& elements =  gridSrcElements->getElements() ;
+    int nElements = elements.size() ;
+    vector<CLocalElement*> remoteElements(nElements) ;
+    vector<CLocalView*> remoteViews(nElements) ;
+    for(int i=0;i<nElements;i++)
+    {
+      if (i==pos_) remoteElements[i] = algorithm_->getRecvElement() ;
+      else
+      { 
+        CArray<size_t,1> globalIndexView ;
+        srcView->getView(i)->getGlobalIndexView(globalIndexView) ;
+        remoteElements[i] = new CLocalElement(commRank, srcView->getView(i)->getGlobalSize(),globalIndexView) ;
+        remoteElements[i]->addFullView() ;
+        if (i>pos_) dimBefore_ *= srcView->getView(i)->getSize() ;
+        else dimAfter_ *= srcView->getView(i)->getSize() ;
+          
+      }
+      remoteViews[i] = remoteElements[i] -> getView(CElementView::FULL);
+    }
+
+    gridTransformConnector_ = new CGridTransformConnector(srcView->getViews(), remoteViews, comm ) ;
+ 
+  }
+
+  void CGridAlgorithm::apply(const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
+  {
+    CArray<double,1> dataOutTmp ;
+    gridTransformConnector_->transfer(dataIn, dataOutTmp) ;
+    algorithm_->apply(dimBefore_, dimAfter_, dataOutTmp, dataOut) ;
+  }
+
+
+}
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm.hpp	(revision 1999)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/grid_algorithm.hpp	(revision 1999)
@@ -0,0 +1,38 @@
+#ifndef __XIOS_GRID_ALGORITHM_TRANSFORMATION_HPP__
+#define __XIOS_GRID_ALGORITHM_TRANSFORMATION_HPP__
+
+#include "grid_transform_connector.hpp"
+#include <map>
+#include "array_new.hpp"
+#include "local_view.hpp"
+
+namespace xios
+{
+  class CGrid;
+  class CGenericAlgorithmTransformation ;
+
+  /*!
+  \class CGenericAlgorithmTransformation
+  This class defines the interface for all other inherited algorithms class
+  */
+class CGridAlgorithm
+{
+  public:
+    CGridAlgorithm(CGrid* gridSrc, CGrid* gridDst, int pos,  CGenericAlgorithmTransformation* algo) ;
+    virtual void computeAlgorithm(void) ;
+    
+    void apply(const CArray<double,1>& dataIn, CArray<double,1>& dataOut) ;
+
+  private:
+    CGenericAlgorithmTransformation* algorithm_=nullptr ;
+    CGridTransformConnector* gridTransformConnector_=nullptr ;
+    CGrid* gridSrc_ = nullptr ;
+    CGrid* gridDst_ = nullptr ;
+    int pos_ ;
+    int dimBefore_=1 ;
+    int dimAfter_=1 ;
+
+};
+
+}
+#endif // __XIOS_GRID_ALGORITHM_TRANSFORMATION_HPP__
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_extract_axis.cpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_extract_axis.cpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_extract_axis.cpp	(revision 1999)
@@ -48,45 +48,17 @@
 
 CScalarAlgorithmExtractAxis::CScalarAlgorithmExtractAxis(bool isSource, CScalar* scalarDestination, CAxis* axisSource, CExtractAxisToScalar* algo)
- : CScalarAlgorithmTransformation(isSource, scalarDestination, axisSource), reduction_(0)
+ : CAlgorithmTransformationTransfer(isSource)
 TRY
 {
   algo->checkValid(scalarDestination, axisSource);
-  StdString op = "extract";
   pos_ = algo->position;
-  reduction_ = CReductionAlgorithm::createOperation(CReductionAlgorithm::ReductionOperations[op]);
+  this->transformationMapping_[0]=pos_ ;
+
+  scalarDestination->checkAttributes() ;
+  this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), scalarDestination->getLocalView(CElementView::WORKFLOW)) ;
 }
 CATCH
 
-void CScalarAlgorithmExtractAxis::apply(const std::vector<std::pair<int,double> >& localIndex,
-                                         const double* dataInput,
-                                         CArray<double,1>& dataOut,
-                                         std::vector<bool>& flagInitial,                     
-                                         bool ignoreMissingValue, bool firstPass)
-TRY
-{
-  reduction_->apply(localIndex, dataInput, dataOut, flagInitial, ignoreMissingValue, firstPass);
-}
-CATCH
 
-CScalarAlgorithmExtractAxis::~CScalarAlgorithmExtractAxis()
-TRY
-{
-  if (0 != reduction_) delete reduction_;
-}
-CATCH
-
-void CScalarAlgorithmExtractAxis::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
-TRY
-{
-  this->transformationMapping_.resize(1);
-  this->transformationWeight_.resize(1);
-
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationWeightMap& transWeight = this->transformationWeight_[0];
-
-  transMap[0].push_back(pos_);
-  transWeight[0].push_back(1.0);
-}
-CATCH
 
 }
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_extract_axis.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_extract_axis.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_extract_axis.hpp	(revision 1999)
@@ -10,5 +10,5 @@
 #define __XIOS_SCALAR_ALGORITHM_EXTRACT_AXIS_HPP__
 
-#include "scalar_algorithm_transformation.hpp"
+#include "algorithm_transformation_transfer.hpp"
 #include "transformation.hpp"
 
@@ -24,16 +24,11 @@
   Extract a scalar from an axis
 */
-class CScalarAlgorithmExtractAxis : public CScalarAlgorithmTransformation
+class CScalarAlgorithmExtractAxis : public CAlgorithmTransformationTransfer
 {
 public:
   CScalarAlgorithmExtractAxis(bool isSource, CScalar* scalarDestination, CAxis* axisSource, CExtractAxisToScalar* algo);
 
-  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
-                     const double* dataInput,
-                     CArray<double,1>& dataOut,
-                     std::vector<bool>& flagInitial,                     
-                     bool ignoreMissingValue, bool firstPass);
-
-  virtual ~CScalarAlgorithmExtractAxis();
+  
+  virtual ~CScalarAlgorithmExtractAxis() {} ;
 
   static bool registerTrans();
@@ -41,10 +36,4 @@
 protected:
   int pos_;
-
-protected:
-  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
-
-protected:
-  CReductionAlgorithm* reduction_;
 
 private:
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_axis.cpp	(revision 1999)
@@ -49,5 +49,5 @@
 
 CScalarAlgorithmReduceAxis::CScalarAlgorithmReduceAxis(bool isSource, CScalar* scalarDestination, CAxis* axisSource, CReduceAxisToScalar* algo)
- : CScalarAlgorithmTransformation(isSource, scalarDestination, axisSource),reduction_(0)
+ : CAlgorithmTransformationReduce(isSource)
 TRY
 {
@@ -61,14 +61,14 @@
   {
     case CReduceAxisToScalar::operation_attr::sum:
-      op = "sum";
+      operator_ = EReduction::sum;
       break;
     case CReduceAxisToScalar::operation_attr::min:
-      op = "min";
+      operator_ = EReduction::min;
       break;
     case CReduceAxisToScalar::operation_attr::max:
-      op = "max";
+      operator_ = EReduction::max;
       break;
     case CReduceAxisToScalar::operation_attr::average:
-      op = "average";
+      operator_ = EReduction::average;
       break;
     default:
@@ -78,54 +78,19 @@
          << "Scalar destination " << scalarDestination->getId());
 
-  }
+  } 
   
-  if (CReductionAlgorithm::ReductionOperations.end() == CReductionAlgorithm::ReductionOperations.find(op))
-    ERROR("CScalarAlgorithmReduceAxis::CScalarAlgorithmReduceAxis(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());
+  int globalIndexSize = axisSource-> n_glo;
+  for (int idx = 0; idx < globalIndexSize; ++idx)  transformationMapping_[0].push_back(idx);
 
-  reduction_ = CReductionAlgorithm::createOperation(CReductionAlgorithm::ReductionOperations[op]);
+  scalarDestination->checkAttributes() ;
+  this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), scalarDestination->getLocalView(CElementView::WORKFLOW)) ;
+  
 }
 CATCH
 
-void CScalarAlgorithmReduceAxis::apply(const std::vector<std::pair<int,double> >& localIndex, const double* dataInput, CArray<double,1>& dataOut,
-                                         std::vector<bool>& flagInitial, bool ignoreMissingValue, bool firstPass)
-TRY
-{
-  reduction_->apply(localIndex, dataInput, dataOut, flagInitial, ignoreMissingValue, firstPass);
-}
-CATCH
-
-void CScalarAlgorithmReduceAxis::updateData(CArray<double,1>& dataOut)
-TRY
-{
-  reduction_->updateData(dataOut);
-}
-CATCH
 
 CScalarAlgorithmReduceAxis::~CScalarAlgorithmReduceAxis()
 TRY
 {
-  if (0 != reduction_) delete reduction_;
-}
-CATCH
-
-void CScalarAlgorithmReduceAxis::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
-TRY
-{
-  this->transformationMapping_.resize(1);
-  this->transformationWeight_.resize(1);
-
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationWeightMap& transWeight = this->transformationWeight_[0];
-
-  int globalIndexSize = axisSrc_-> n_glo;
-
-  for (int idx = 0; idx < globalIndexSize; ++idx)
-  {
-    transMap[0].push_back(idx);
-    transWeight[0].push_back(1.0);
-  }
 }
 CATCH
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_axis.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_axis.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_axis.hpp	(revision 1999)
@@ -10,5 +10,5 @@
 #define __XIOS_SCALAR_ALGORITHM_REDUCE_AXIS_HPP__
 
-#include "scalar_algorithm_transformation.hpp"
+#include "algorithm_transformation_reduce.hpp"
 #include "transformation.hpp"
 
@@ -24,25 +24,13 @@
   Reducing an axis to a scalar
 */
-class CScalarAlgorithmReduceAxis : public CScalarAlgorithmTransformation
+class CScalarAlgorithmReduceAxis : public CAlgorithmTransformationReduce
 {
 public:
   CScalarAlgorithmReduceAxis(bool isSource, 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,
-                     bool ignoreMissingValue, bool firstPass);
-
-  virtual void updateData(CArray<double,1>& dataOut);
   
   virtual ~CScalarAlgorithmReduceAxis();
 
   static bool registerTrans();
-protected:
-  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
-
-protected:
-  CReductionAlgorithm* reduction_;
 
 private:
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 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_domain.cpp	(revision 1999)
@@ -13,6 +13,4 @@
 #include "grid.hpp"
 #include "grid_transformation_factory_impl.hpp"
-
-#include "reduction.hpp"
 
 namespace xios {
@@ -48,6 +46,5 @@
 
 CScalarAlgorithmReduceDomain::CScalarAlgorithmReduceDomain(bool isSource, CScalar* scalarDestination, CDomain* domainSource, CReduceDomainToScalar* algo)
- : CScalarAlgorithmTransformation(isSource, scalarDestination, domainSource),
-   reduction_(0)
+ : CAlgorithmTransformationReduce(isSource), domainSrc_(domainSource)
 TRY
 {
@@ -58,14 +55,14 @@
   {
     case CReduceDomainToScalar::operation_attr::sum:
-      op = "sum";
+      operator_ = EReduction::sum;
       break;
     case CReduceDomainToScalar::operation_attr::min:
-      op = "min";
+      operator_ = EReduction::min;
       break;
     case CReduceDomainToScalar::operation_attr::max:
-      op = "max";
+      operator_ = EReduction::max;
       break;
     case CReduceDomainToScalar::operation_attr::average:
-      op = "average";
+      operator_ = EReduction::average;
       break;
     default:
@@ -76,53 +73,12 @@
 
   }
-  
-  if (CReductionAlgorithm::ReductionOperations.end() == CReductionAlgorithm::ReductionOperations.find(op))
-    ERROR("CScalarAlgorithmReduceDomain::CScalarAlgorithmReduceDomain(CDomain* domainDestination, CDomain* domainSource, CReduceDomainToScalar* algo)",
-       << "Operation '" << op << "' not found. Please make sure to use a supported one"
-       << "Domain source " <<domainSource->getId() << std::endl
-       << "Scalar destination " << scalarDestination->getId());
 
-  reduction_ = CReductionAlgorithm::createOperation(CReductionAlgorithm::ReductionOperations[op]);
-  local = algo->local ;
-}
-CATCH
-
-void CScalarAlgorithmReduceDomain::apply(const std::vector<std::pair<int,double> >& localIndex,
-                                         const double* dataInput,
-                                         CArray<double,1>& dataOut,
-                                         std::vector<bool>& flagInitial,                     
-                                         bool ignoreMissingValue, bool firstPass)
-TRY
-{
-  reduction_->apply(localIndex, dataInput, dataOut, flagInitial, ignoreMissingValue, firstPass);
-}
-CATCH
-
-void CScalarAlgorithmReduceDomain::updateData(CArray<double,1>& dataOut)
-TRY
-{
-  reduction_->updateData(dataOut);
-}
-CATCH
-
-CScalarAlgorithmReduceDomain::~CScalarAlgorithmReduceDomain()
-TRY
-{
-  if (0 != reduction_) delete reduction_;
-}
-CATCH
-
-void CScalarAlgorithmReduceDomain::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
-TRY
-{
-  this->transformationMapping_.resize(1);
-  this->transformationWeight_.resize(1);
-
-  TransformationIndexMap& transMap = this->transformationMapping_[0];
-  TransformationWeightMap& transWeight = this->transformationWeight_[0];
+  TransformationIndexMap& transMap = this->transformationMapping_;
 
   int ni_glo = domainSrc_->ni_glo ;
   int nj_glo = domainSrc_->nj_glo ;
   int nbDomainIdx ;
+  
+  bool  local = algo->local ;
   
   if (local)
@@ -138,5 +94,4 @@
         { 
           transMap[0].push_back(j_index(idxDomain)* ni_glo + i_index(idxDomain));
-          transWeight[0].push_back(1.0) ;
         }
       }
@@ -145,11 +100,20 @@
   {  
     nbDomainIdx = ni_glo * nj_glo;
-    transMap[0].resize(nbDomainIdx);
-    transWeight[0].resize(nbDomainIdx, 1.0);
-    for (int idxDomain = 0; idxDomain < nbDomainIdx; ++idxDomain) transMap[0][idxDomain] = idxDomain;    
+    for (int idxDomain = 0; idxDomain < nbDomainIdx; ++idxDomain) transMap[0].push_back(idxDomain);    
   }
   
+  scalarDestination->checkAttributes() ;
+  this->computeAlgorithm(domainSource->getLocalView(CElementView::WORKFLOW), scalarDestination->getLocalView(CElementView::WORKFLOW)) ;
 }
 CATCH
 
+
+
+CScalarAlgorithmReduceDomain::~CScalarAlgorithmReduceDomain()
+TRY
+{
 }
+CATCH
+
+
+}
Index: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_domain.hpp
===================================================================
--- XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_domain.hpp	(revision 1998)
+++ XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/scalar_algorithm/scalar_algorithm_reduce_domain.hpp	(revision 1999)
@@ -10,5 +10,5 @@
 #define __XIOS_SCALAR_ALGORITHM_REDUCE_DOMAIN_HPP__
 
-#include "scalar_algorithm_transformation.hpp"
+#include "algorithm_transformation_reduce.hpp"
 #include "transformation.hpp"
 
@@ -24,26 +24,15 @@
   Reducing an DOMAIN to a scalar
 */
-class CScalarAlgorithmReduceDomain : public CScalarAlgorithmTransformation
+class CScalarAlgorithmReduceDomain : public CAlgorithmTransformationReduce
 {
 public:
   CScalarAlgorithmReduceDomain(bool isSource, CScalar* scalarDestination, CDomain* domainSource, CReduceDomainToScalar* algo);
 
-  virtual void apply(const std::vector<std::pair<int,double> >& localIndex,
-                     const double* dataInput,
-                     CArray<double,1>& dataOut,
-                     std::vector<bool>& flagInitial,                     
-                     bool ignoreMissingValue, bool firstPass);
-
-  virtual void updateData(CArray<double,1>& dataOut);
-  
   virtual ~CScalarAlgorithmReduceDomain();
 
   static bool registerTrans();
-protected:
-  bool local ;
-  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 protected:
-  CReductionAlgorithm* reduction_;
+  CDomain* domainSrc_ ;
 
 private:
