Index: XIOS/trunk/inputs/Version2/iodef.xml
===================================================================
--- XIOS/trunk/inputs/Version2/iodef.xml	(revision 826)
+++ XIOS/trunk/inputs/Version2/iodef.xml	(revision 827)
@@ -15,4 +15,5 @@
      <field id="field_Domain_transformed_Interpolated"  operation="average" freq_op="3600s" field_ref="field_A" grid_ref="grid_Domain_tranformed_Interpolated" />
      <field id="field_Scalar" operation="average" freq_op="3600s" grid_ref="ScalarGrid" />
+     <field id="field_Value"  operation="average" freq_op="3600s" grid_ref="grid_A" />
    </field_definition>
 
@@ -53,7 +54,8 @@
      </axis>
      <axis id="axis_F" axis_ref="axis_C">
-        <inverse_axis />
-        <zoom_axis begin="0" n="4" />
-        <inverse_axis />
+       <interpolate_axis type="polynomial" order="3" coordinate="field_Value"/>
+<!--       <inverse_axis />-->
+<!--        <zoom_axis begin="0" n="4" />-->
+<!--        <inverse_axis />-->
      </axis>
    </axis_definition>
Index: XIOS/trunk/src/config/interpolate_axis_attribute.conf
===================================================================
--- XIOS/trunk/src/config/interpolate_axis_attribute.conf	(revision 826)
+++ XIOS/trunk/src/config/interpolate_axis_attribute.conf	(revision 827)
@@ -2,2 +2,3 @@
 DECLARE_ATTRIBUTE(StdString, type)
 DECLARE_ATTRIBUTE(int, order)
+DECLARE_ATTRIBUTE(StdString, coordinate)
Index: XIOS/trunk/src/filter/filter.cpp
===================================================================
--- XIOS/trunk/src/filter/filter.cpp	(revision 826)
+++ XIOS/trunk/src/filter/filter.cpp	(revision 827)
@@ -7,4 +7,5 @@
     , COutputPin()
     , engine(engine)
+    , inputSlotCount(inputSlotCount)
   { /* Nothing to do */ }
 
Index: XIOS/trunk/src/filter/filter.hpp
===================================================================
--- XIOS/trunk/src/filter/filter.hpp	(revision 826)
+++ XIOS/trunk/src/filter/filter.hpp	(revision 827)
@@ -28,4 +28,5 @@
     protected:
       IFilterEngine* engine; //!< The filter engine, might be the filter itself
+      size_t inputSlotCount; //!< Number of slot on filter
 
       /*!
Index: XIOS/trunk/src/filter/spatial_transform_filter.cpp
===================================================================
--- XIOS/trunk/src/filter/spatial_transform_filter.cpp	(revision 826)
+++ XIOS/trunk/src/filter/spatial_transform_filter.cpp	(revision 827)
@@ -6,6 +6,6 @@
 namespace xios
 {
-  CSpatialTransformFilter::CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine)
-    : CFilter(gc, 1, engine)
+  CSpatialTransformFilter::CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, size_t inputSlotsCount)
+    : CFilter(gc, inputSlotsCount, engine)
   { /* Nothing to do */ }
 
@@ -24,5 +24,7 @@
       CGridTransformation* gridTransformation = destGrid->getTransformations();
       CSpatialTransformFilterEngine* engine = CSpatialTransformFilterEngine::get(destGrid->getTransformations());
-      boost::shared_ptr<CSpatialTransformFilter> filter(new CSpatialTransformFilter(gc, engine));
+      const std::vector<StdString>& auxInputs = gridTransformation->getAuxInputs();
+      size_t inputCount = 1 + (auxInputs.empty() ? 0 : auxInputs.size());
+      boost::shared_ptr<CSpatialTransformFilter> filter(new CSpatialTransformFilter(gc, engine, inputCount));
 
       if (!lastFilter)
@@ -32,4 +34,11 @@
 
       firstFilter = filter;
+      for (size_t idx = 0; idx < auxInputs.size(); ++idx)
+      {
+        CField* fieldAuxInput = CField::get(auxInputs[idx]);
+        fieldAuxInput->buildFilterGraph(gc, false);
+        fieldAuxInput->getInstantDataFilter()->connectOutput(firstFilter,idx+1);
+      }
+
       destGrid = gridTransformation->getGridSource();
     }
@@ -74,4 +83,10 @@
     if (packet->status == CDataPacket::NO_ERROR)
     {
+      if (1 < data.size())  // Dynamical transformations
+      {
+        std::vector<CArray<double,1>* > dataAuxInputs(data.size()-1);
+        for (size_t idx = 0; idx < dataAuxInputs.size(); ++idx) dataAuxInputs[idx] = &(data[idx+1]->data);
+        gridTransformation->computeAll(dataAuxInputs);
+      }
       packet->data.resize(gridTransformation->getGridDestination()->storeIndex_client.numElements());
       apply(data[0]->data, packet->data);
Index: XIOS/trunk/src/filter/spatial_transform_filter.hpp
===================================================================
--- XIOS/trunk/src/filter/spatial_transform_filter.hpp	(revision 826)
+++ XIOS/trunk/src/filter/spatial_transform_filter.hpp	(revision 827)
@@ -11,5 +11,5 @@
 
   /*!
-   * A generic filter with one input slot wrapping any type of spatial transformations.
+   * A generic filter with multiple input slots wrapping any type of spatial transformations.
    */
   class CSpatialTransformFilter : public CFilter
@@ -21,6 +21,7 @@
        * \param gc the associated garbage collector
        * \param engine the engine defining the spatial transformation
+       * \param [in] inputSlotsCount number of input, by default there is only one for field src
        */
-      CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine);
+      CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, size_t inputSlotsCount = 1);
 
       /*!
Index: XIOS/trunk/src/node/interpolate_axis.cpp
===================================================================
--- XIOS/trunk/src/node/interpolate_axis.cpp	(revision 826)
+++ XIOS/trunk/src/node/interpolate_axis.cpp	(revision 827)
@@ -1,4 +1,5 @@
 #include "interpolate_axis.hpp"
 #include "type.hpp"
+#include "field.hpp"
 
 namespace xios {
@@ -23,7 +24,41 @@
   ENodeType CInterpolateAxis::GetType(void)    { return eInterpolateAxis; }
 
-  void CInterpolateAxis::checkValid(CAxis* axisDest)
+  void CInterpolateAxis::checkValid(CAxis* axisSrc)
   {
+    if (this->order.isEmpty()) this->order.setValue(2);
+    int order = this->order.getValue();
+    if (order >= axisSrc->n_glo.getValue())
+    {
+      ERROR("CInterpolateAxis::checkValid(CAxis* axisSrc)",
+             << "Order of interpolation is greater than global size of axis source"
+             << "Size of axis source " <<axisSrc->getId() << " is " << axisSrc->n_glo.getValue()  << std::endl
+             << "Order of interpolation is " << order );
+    }
+
+
+    if (!this->coordinate.isEmpty())
+    {
+      StdString coordinate = this->coordinate.getValue();
+      if (!CField::has(coordinate))
+        ERROR("CInterpolateAxis::checkValid(CAxis* axisSrc)",
+               << "Coordinate field whose id " << coordinate << "does not exist "
+               << "Please define one");
+    }
   }
 
+  std::vector<StdString> CInterpolateAxis::checkAuxInputs_()
+  {
+    std::vector<StdString> auxInputs;
+    if (!this->coordinate.isEmpty())
+    {
+      StdString coordinate = this->coordinate.getValue();
+      if (!CField::has(coordinate))
+        ERROR("CInterpolateAxis::checkValid(CAxis* axisSrc)",
+               << "Coordinate field whose id " << coordinate << "does not exist "
+               << "Please define one");
+      auxInputs.push_back(coordinate);
+    }
+
+    return auxInputs;
+  }
 }
Index: XIOS/trunk/src/node/interpolate_axis.hpp
===================================================================
--- XIOS/trunk/src/node/interpolate_axis.hpp	(revision 826)
+++ XIOS/trunk/src/node/interpolate_axis.hpp	(revision 827)
@@ -52,4 +52,6 @@
       virtual void checkValid(CAxis* axisDest);
 
+      std::vector<StdString> checkAuxInputs_();
+
       /// Accesseurs statiques ///
       static StdString GetName(void);
Index: XIOS/trunk/src/node/transformation.hpp
===================================================================
--- XIOS/trunk/src/node/transformation.hpp	(revision 826)
+++ XIOS/trunk/src/node/transformation.hpp	(revision 827)
@@ -24,6 +24,11 @@
       virtual void checkValid(T* dest) = 0;
 
+      std::vector<StdString> checkAuxInputs() { return checkAuxInputs_(); }
+
       /// Destructeur ///
       virtual ~CTransformation(void) {}
+
+    protected:
+      virtual std::vector<StdString> checkAuxInputs_() { return std::vector<StdString>(); }
   }; // class CTransformation
 
Index: XIOS/trunk/src/test/test_new_features.f90
===================================================================
--- XIOS/trunk/src/test/test_new_features.f90	(revision 826)
+++ XIOS/trunk/src/test/test_new_features.f90	(revision 827)
@@ -28,9 +28,9 @@
   DOUBLE PRECISION,DIMENSION(ni_glo,nj_glo) :: lon_glo,lat_glo
   DOUBLE PRECISION,DIMENSION(4,ni_glo,nj_glo) :: bnds_lon_glo, bnds_lat_glo
-  DOUBLE PRECISION :: field_A_glo(ni_glo,nj_glo,llm), lval_ni_glo(ni_glo), lval_nj_glo(nj_glo)
+  DOUBLE PRECISION :: field_A_glo(ni_glo,nj_glo,llm), lval_ni_glo(ni_glo), lval_nj_glo(nj_glo), field_Value_glo(ni_glo,nj_glo,llm)
   DOUBLE PRECISION,ALLOCATABLE :: lon(:,:),lat(:,:),field_A(:,:,:), field_All_Axis(:,:,:), lonvalue(:) , &
                                   field_Axis(:), lvaln(:), lval_ni(:), lval_nj(:), field_Two_Axis(:,:), lvalnInterp(:), &
                                   lontransformed(:,:), lattransformed(:,:), lon_glotransformed(:,:), lat_glotransformed(:,:), &
-                                  bnds_lon(:,:,:), bnds_lat(:,:,:)
+                                  bnds_lon(:,:,:), bnds_lat(:,:,:), field_value(:,:,:)
   INTEGER :: ni,ibegin,iend,nj,jbegin,jend, nAxis, axisBegin, axisEnd
   INTEGER :: axisterpBegin, nAxisinterp, axisinterpEnd
@@ -68,4 +68,5 @@
       DO l=1,llm
         field_A_glo(i,j,l)=(i-1)+(j-1)*ni_glo+10000*l
+        field_Value_glo(i,j,l)=l*100
       ENDDO
     ENDDO
@@ -80,5 +81,5 @@
 
   DO j=1,llm
-    lval(j) = j *10
+    lval(j) = j *100
   ENDDO
   axisBegin = 0
@@ -109,5 +110,5 @@
           lvaln(nAxis), lval_ni(ni), lval_nj(nj), lvalnInterp(nAxisinterp), &
           lontransformed(niDomInterp, njDomInterp), lattransformed(niDomInterp, njDomInterp), &
-          bnds_lon(4,ni,nj), bnds_lat(4,ni,nj))
+          bnds_lon(4,ni,nj), bnds_lat(4,ni,nj), field_value(0:ni+1,-1:nj+2,llm))
 
   ALLOCATE(mask(nj))
@@ -126,4 +127,5 @@
   lattransformed(:,:) = lat_glotransformed(ibeginDomInterp+1:iendDomInterp+1,jbeginDomInterp+1:jendDomInterp+1)
   field_A(1:ni,1:nj,:) = field_A_glo(ibegin+1:iend+1,jbegin+1:jend+1,:)
+  field_value(1:ni,1:nj,:) = field_Value_glo(ibegin+1:iend+1,jbegin+1:jend+1,:)
   field_Axis(1:nAxis)  = field_A_glo(1,1,axisBegin+1:axisEnd+1)
   field_Two_Axis(:,1:nj)  = field_A_glo(:,jbegin+1:jend+1,1)
@@ -201,7 +203,8 @@
 
   PRINT*,"field field_A is active ? ",xios_field_is_active("field_A")
-  DO ts=1,24*10
+  DO ts=1,24*1
     CALL xios_update_calendar(ts)
     CALL xios_send_field("field_A",field_A)
+    CALL xios_send_field("field_Value",field_value)
     CALL xios_send_field("field_Axis",field_Axis)
     CALL xios_send_field("field_Two_Axis",field_Two_Axis)
Index: XIOS/trunk/src/transformation/axis_algorithm_interpolate.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_interpolate.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_interpolate.cpp	(revision 827)
@@ -12,21 +12,22 @@
 #include "context_client.hpp"
 #include "utils.hpp"
+#include "grid.hpp"
+#include "distribution_client.hpp"
 
 namespace xios {
 
 CAxisAlgorithmInterpolate::CAxisAlgorithmInterpolate(CAxis* axisDestination, CAxis* axisSource, CInterpolateAxis* interpAxis)
-: CAxisAlgorithmTransformation(axisDestination, axisSource)
+: CAxisAlgorithmTransformation(axisDestination, axisSource), coordinate_(), transPosition_()
 {
   interpAxis->checkValid(axisSource);
   order_ = interpAxis->order.getValue();
-  if (order_ >= axisSource->n_glo.getValue())
-  {
-    ERROR("CAxisAlgorithmInterpolate::CAxisAlgorithmInterpolate(CAxis* axisDestination, CAxis* axisSource, CInterpolateAxis* interpAxis)",
-           << "Order of interpolation is greater than global size of axis source"
-           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->n_glo.getValue()  << std::endl
-           << "Order of interpolation is " << order_ );
-  }
-
-  computeIndexSourceMapping();
+  if (!interpAxis->coordinate.isEmpty())
+  {
+    coordinate_ = interpAxis->coordinate.getValue();
+    this->idAuxInputs_.resize(1);
+    this->idAuxInputs_[0] = coordinate_;
+  }
+
+//  computeIndexSourceMapping();
 }
 
@@ -34,22 +35,25 @@
   Compute the index mapping between axis on grid source and one on grid destination
 */
-void CAxisAlgorithmInterpolate::computeIndexSourceMapping()
-{
-  CArray<double,1>& axisValue = axisSrc_->value;
-  CArray<bool,1>& axisMask = axisSrc_->mask;
-
+void CAxisAlgorithmInterpolate::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
+{
   CContext* context = CContext::getCurrent();
   CContextClient* client=context->client;
   int nbClient = client->clientSize;
-
+  CArray<bool,1>& axisMask = axisSrc_->mask;
   int srcSize  = axisSrc_->n_glo.getValue();
-  int numValue = axisValue.numElements();
-
-  std::vector<double> recvBuff(srcSize);
-  std::vector<int> indexVec(srcSize);
-
-  retrieveAllAxisValue(recvBuff, indexVec);
-  XIOSAlgorithms::sortWithIndex<double, CVectorStorage>(recvBuff, indexVec);
-  computeInterpolantPoint(recvBuff, indexVec);
+  std::vector<CArray<double,1> > vecAxisValue;
+
+  // Fill in axis value from coordinate
+  fillInAxisValue(vecAxisValue, dataAuxInputs);
+
+  for (int idx = 0; idx < vecAxisValue.size(); ++idx)
+  {
+    CArray<double,1>& axisValue = vecAxisValue[idx];
+    std::vector<double> recvBuff(srcSize);
+    std::vector<int> indexVec(srcSize);
+    retrieveAllAxisValue(axisValue, axisMask, recvBuff, indexVec);
+    XIOSAlgorithms::sortWithIndex<double, CVectorStorage>(recvBuff, indexVec);
+    computeInterpolantPoint(recvBuff, indexVec, idx);
+  }
 }
 
@@ -60,5 +64,5 @@
   \param [in] indexVec permutation index of axisValue
 */
-void CAxisAlgorithmInterpolate::computeInterpolantPoint(const std::vector<double>& axisValue, const std::vector<int>& indexVec)
+void CAxisAlgorithmInterpolate::computeInterpolantPoint(const std::vector<double>& axisValue, const std::vector<int>& indexVec, int transPos)
 {
   std::vector<double>::const_iterator itb = axisValue.begin(), ite = axisValue.end();
@@ -78,5 +82,4 @@
     itUpperBound = std::upper_bound(itb, ite, destValue);
     if ((ite != itUpperBound) && (sfmax == *itUpperBound)) itUpperBound = ite;
-
 
     // If the value is not in the range, that means we'll do extra-polation
@@ -118,5 +121,5 @@
     }
   }
-  computeWeightedValueAndMapping(interpolatingIndexValues);
+  computeWeightedValueAndMapping(interpolatingIndexValues, transPos);
 }
 
@@ -125,8 +128,8 @@
   \param [in] interpolatingIndexValues the necessary axis value to calculate the coeffs
 */
-void CAxisAlgorithmInterpolate::computeWeightedValueAndMapping(const std::map<int, std::vector<std::pair<int,double> > >& interpolatingIndexValues)
-{
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_;
+void CAxisAlgorithmInterpolate::computeWeightedValueAndMapping(const std::map<int, std::vector<std::pair<int,double> > >& interpolatingIndexValues, int transPos)
+{
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[transPos];
+  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[transPos];
   std::map<int, std::vector<std::pair<int,double> > >::const_iterator itb = interpolatingIndexValues.begin(), it,
                                                                       ite = interpolatingIndexValues.end();
@@ -138,4 +141,6 @@
     const std::vector<std::pair<int,double> >& interpVal = it->second;
     int interpSize = interpVal.size();
+    transMap[globalIndexDest].resize(interpSize);
+    transWeight[globalIndexDest].resize(interpSize);
     for (int idx = 0; idx < interpSize; ++idx)
     {
@@ -149,6 +154,10 @@
         weight /= (interpVal[idx].second - interpVal[k].second);
       }
-      transMap[globalIndexDest].push_back(index);
-      transWeight[globalIndexDest].push_back(weight);
+      transMap[globalIndexDest][idx] = index;
+      transWeight[globalIndexDest][idx] = weight;
+      if (!transPosition_.empty())
+      {
+        (this->transformationPosition_[transPos])[globalIndexDest] = transPosition_[transPos];
+      }
     }
   }
@@ -160,9 +169,7 @@
   \param [in/out] indexVec mapping between values and global index of axis
 */
-void CAxisAlgorithmInterpolate::retrieveAllAxisValue(std::vector<double>& recvBuff, std::vector<int>& indexVec)
-{
-  CArray<double,1>& axisValue = axisSrc_->value;
-  CArray<bool,1>& axisMask = axisSrc_->mask;
-
+void CAxisAlgorithmInterpolate::retrieveAllAxisValue(const CArray<double,1>& axisValue, const CArray<bool,1>& axisMask,
+                                                     std::vector<double>& recvBuff, std::vector<int>& indexVec)
+{
   CContext* context = CContext::getCurrent();
   CContextClient* client=context->client;
@@ -230,3 +237,84 @@
 }
 
-}
+/*!
+  Fill in axis value dynamically from a field whose grid is composed of a domain and an axis
+  \param [in/out] vecAxisValue vector axis value filled in from input field
+*/
+void CAxisAlgorithmInterpolate::fillInAxisValue(std::vector<CArray<double,1> >& vecAxisValue,
+                                                const std::vector<CArray<double,1>* >& dataAuxInputs)
+{
+  if (coordinate_.empty())
+  {
+    vecAxisValue.resize(1);
+    vecAxisValue[0].resize(axisSrc_->value.numElements());
+    vecAxisValue[0] = axisSrc_->value;
+    this->transformationMapping_.resize(1);
+    this->transformationWeight_.resize(1);
+  }
+  else
+  {
+    CField* field = CField::get(coordinate_);
+    CGrid* grid = field->grid;
+
+    std::vector<CDomain*> domListP = grid->getDomains();
+    std::vector<CAxis*> axisListP = grid->getAxis();
+    if (domListP.empty() || axisListP.empty() || (1 < domListP.size()) || (1 < axisListP.size()))
+      ERROR("CAxisAlgorithmInterpolate::fillInAxisValue(std::vector<CArray<double,1> >& vecAxisValue)",
+             << "XIOS only supports dynamic interpolation with coordinate (field) associated with grid composed of a domain and an axis"
+             << "Coordinate (field) id = " <<field->getId() << std::endl
+             << "Associated grid id = " << grid->getId());
+
+    CDomain* dom = domListP[0];
+    size_t vecAxisValueSize = dom->i_index.numElements();
+    vecAxisValue.resize(vecAxisValueSize);
+    if (transPosition_.empty())
+    {
+      transPosition_.resize(vecAxisValueSize);
+      for (size_t idx = 0; idx < vecAxisValueSize; ++idx)
+      {
+        transPosition_[idx].resize(2);
+        transPosition_[idx][0] = (dom->i_index)(idx);
+        transPosition_[idx][1] = (dom->j_index)(idx);
+      }
+    }
+    this->transformationMapping_.resize(vecAxisValueSize);
+    this->transformationWeight_.resize(vecAxisValueSize);
+    this->transformationPosition_.resize(vecAxisValueSize);
+
+    const std::vector<size_t>& globalIndexSendToServer = grid->getDistributionClient()->getGlobalDataIndexSendToServer();
+    const std::vector<int>& localDataSendToServer = grid->getDistributionClient()->getLocalDataIndexSendToServer();
+    std::vector<int> permutIndex(globalIndexSendToServer.size());
+    std::vector<int>::iterator itVec;
+    XIOSAlgorithms::fillInIndex(globalIndexSendToServer.size(), permutIndex);
+    XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexSendToServer, permutIndex);
+    size_t axisSrcSize = axisSrc_->index.numElements();
+    std::vector<int> globalDimension = grid->getGlobalDimension();
+    XIOSBinarySearchWithIndex<size_t> binSearch(globalIndexSendToServer);
+    for (size_t idx = 0; idx < vecAxisValueSize; ++idx)
+    {
+      size_t axisValueSize = 0;
+      for (size_t jdx = 0; jdx < axisSrcSize; ++jdx)
+      {
+        size_t globalIndex = ((dom->i_index)(idx) + (dom->j_index)(idx)*globalDimension[0]) + (axisSrc_->index)(jdx)*globalDimension[0]*globalDimension[1];
+        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndex, itVec))
+        {
+          ++axisValueSize;
+        }
+      }
+
+      vecAxisValue[idx].resize(axisValueSize);
+      axisValueSize = 0;
+      for (size_t jdx = 0; jdx < axisSrcSize; ++jdx)
+      {
+        size_t globalIndex = ((dom->i_index)(idx) + (dom->j_index)(idx)*globalDimension[0]) + (axisSrc_->index)(jdx)*globalDimension[0]*globalDimension[1];
+        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndex, itVec))
+        {
+          vecAxisValue[idx](axisValueSize) = (*dataAuxInputs[0])(localDataSendToServer[*itVec]);
+          ++axisValueSize;
+        }
+      }
+    }
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/axis_algorithm_interpolate.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_interpolate.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_interpolate.hpp	(revision 827)
@@ -27,14 +27,20 @@
   virtual ~CAxisAlgorithmInterpolate() {}
 
-  virtual void computeIndexSourceMapping();
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
-  void retrieveAllAxisValue(std::vector<double>& recvBuff, std::vector<int>& indexVec);
-  void computeInterpolantPoint(const std::vector<double>& recvBuff, const std::vector<int>& indexVec);
-  void computeWeightedValueAndMapping(const std::map<int, std::vector<std::pair<int,double> > >& interpolatingIndexValues);
+  void retrieveAllAxisValue(const CArray<double,1>& axisValue, const CArray<bool,1>& axisMask,
+                            std::vector<double>& recvBuff, std::vector<int>& indexVec);
+  void computeInterpolantPoint(const std::vector<double>& recvBuff, const std::vector<int>& indexVec, int transPos = 0);
+  void computeWeightedValueAndMapping(const std::map<int, std::vector<std::pair<int,double> > >& interpolatingIndexValues, int transPos = 0);
+  void fillInAxisValue(std::vector<CArray<double,1> >& vecAxisValue,
+                       const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
   // Interpolation order
   int order_;
+  StdString coordinate_;
+  std::vector<std::vector<int> > transPosition_;
 };
 
Index: XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 827)
@@ -25,5 +25,22 @@
   }
 
-  this->computeIndexSourceMapping();
+//  this->computeIndexSourceMapping();
+}
+
+void CAxisAlgorithmInverse::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
+{
+  this->transformationMapping_.resize(1);
+  this->transformationWeight_.resize(1);
+
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[0];
+  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[0];
+
+  int globalIndexSize = axisDestGlobalIndex_.size();
+  for (int idx = 0; idx < globalIndexSize; ++idx)
+  {
+    transMap[axisDestGlobalIndex_[idx]].push_back(axisDestGlobalSize_-axisDestGlobalIndex_[idx]-1);
+    transWeight[axisDestGlobalIndex_[idx]].push_back(1.0);
+  }
+
   int niSrc   = axisSrc_->n.getValue();
   int sizeSrc = axisSrc_->n_glo.getValue();
@@ -35,17 +52,4 @@
       axisDest_->value(idx) = axisSrc_->value(sizeSrc-idx-1);
     }
-  }
-}
-
-void CAxisAlgorithmInverse::computeIndexSourceMapping()
-{
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_;
-
-  int globalIndexSize = axisDestGlobalIndex_.size();
-  for (int idx = 0; idx < globalIndexSize; ++idx)
-  {
-    transMap[axisDestGlobalIndex_[idx]].push_back(axisDestGlobalSize_-axisDestGlobalIndex_[idx]-1);
-    transWeight[axisDestGlobalIndex_[idx]].push_back(1.0);
   }
 }
@@ -65,6 +69,6 @@
   CTransformationMapping transformationMap(axisDest_, axisSrc_);
 
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_;
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[0];
+  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[0];
 
   std::map<size_t, std::vector<std::pair<size_t,double> > > globaIndexMapFromDestToSource;
Index: XIOS/trunk/src/transformation/axis_algorithm_inverse.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_inverse.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_inverse.hpp	(revision 827)
@@ -25,5 +25,6 @@
   virtual ~CAxisAlgorithmInverse() {}
 
-  virtual void computeIndexSourceMapping();
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 827)
@@ -29,5 +29,5 @@
 }
 
-void CAxisAlgorithmTransformation::computeIndexSourceMapping()
+void CAxisAlgorithmTransformation::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
 }
@@ -45,4 +45,5 @@
 void CAxisAlgorithmTransformation::computeGlobalGridIndexFromGlobalIndexElement(int axisDestGlobalIndex,
                                                                           const std::vector<int>& axisSrcGlobalIndex,
+                                                                          const std::vector<int>& destGlobalIndexPositionInGrid,
                                                                           int axisPositionInGrid,
                                                                           const std::vector<int>& gridDestGlobalDim,
@@ -52,4 +53,5 @@
                                                                           std::vector<std::vector<size_t> >& globalIndexSrcGrid)
 {
+  bool hasDestGlobalIndexPos = !destGlobalIndexPositionInGrid.empty();
   int globalDim = gridDestGlobalDim.size();
 
@@ -62,5 +64,9 @@
   {
     if (axisPositionInGrid == i) gridAxisGlobalDim[i] = 1;
-    else gridAxisGlobalDim[i] = gridDestGlobalDim[i];
+    else
+    {
+      if (!hasDestGlobalIndexPos) gridAxisGlobalDim[i] = gridDestGlobalDim[i];
+      else gridAxisGlobalDim[i] = 1;
+    }
     ssize *= gridAxisGlobalDim[i];
   }
@@ -80,5 +86,19 @@
     }
 
-    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
+    int j = 0;
+    for (int i = 0; i < globalDim; ++i)
+    {
+      if (!hasDestGlobalIndexPos) currentIndex[i] = idxLoop[i];
+      else
+      {
+        if (axisPositionInGrid == i) currentIndex[i] = axisDestGlobalIndex;
+        else
+        {
+          currentIndex[i] = destGlobalIndexPositionInGrid[j];
+          ++j;
+        }
+      }
+    }
+
     currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
 
@@ -118,5 +138,18 @@
     }
 
-    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
+    int j = 0;
+    for (int i = 0; i < globalDim; ++i)
+    {
+      if (!hasDestGlobalIndexPos) currentIndex[i] = idxLoop[i];
+      else
+      {
+        if (axisPositionInGrid == i) currentIndex[i] = axisDestGlobalIndex;
+        else
+        {
+          currentIndex[i] = destGlobalIndexPositionInGrid[j];
+          ++j;
+        }
+      }
+    }
     currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
 
@@ -150,4 +183,105 @@
     ++idx;
   }
-}
-}
+
+
+
+//  int globalDim = gridDestGlobalDim.size();
+//
+//  std::vector<size_t> currentIndex(globalDim);
+//  std::vector<int> gridAxisGlobalDim(globalDim);
+//  std::vector<int> idxLoop(globalDim, 0);
+//
+//  size_t ssize = 1, idx = 0, realGlobalIndexSize = 0;
+//  for (int i = 0; i< globalDim; ++i)
+//  {
+//    if (axisPositionInGrid == i) gridAxisGlobalDim[i] = 1;
+//    else gridAxisGlobalDim[i] = gridDestGlobalDim[i];
+//    ssize *= gridAxisGlobalDim[i];
+//  }
+//
+//  std::vector<size_t>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
+//                                      iteArr = globalIndexGridDestSendToServer.end();
+//
+//  while (idx < ssize)
+//  {
+//    for (int i = 0; i < globalDim-1; ++i)
+//    {
+//      if (idxLoop[i] == gridAxisGlobalDim[i])
+//      {
+//        idxLoop[i] = 0;
+//        ++idxLoop[i+1];
+//      }
+//    }
+//
+//    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
+//    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
+//
+//    size_t globIndex = currentIndex[0];
+//    size_t mulDim = 1;
+//    for (int k = 1; k < globalDim; ++k)
+//    {
+//      mulDim *= gridDestGlobalDim[k-1];
+//      globIndex += (currentIndex[k])*mulDim;
+//    }
+//
+//    if (std::binary_search(itbArr, iteArr, globIndex)) ++realGlobalIndexSize;
+//    ++idxLoop[0];
+//    ++idx;
+//  }
+//
+//  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
+//    globalIndexDestGrid.resize(realGlobalIndexSize);
+//
+//  if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
+//  for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
+//    if (globalIndexSrcGrid[i].size() != axisSrcGlobalIndex.size())
+//      globalIndexSrcGrid[i].resize(axisSrcGlobalIndex.size());
+//
+//  size_t realGlobalIndex = 0;
+//  idx = 0;
+//  idxLoop.assign(globalDim, 0);
+//  while (idx < ssize)
+//  {
+//    for (int i = 0; i < globalDim-1; ++i)
+//    {
+//      if (idxLoop[i] == gridAxisGlobalDim[i])
+//      {
+//        idxLoop[i] = 0;
+//        ++idxLoop[i+1];
+//      }
+//    }
+//
+//    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
+//    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
+//
+//    size_t globIndex = currentIndex[0];
+//    size_t mulDim = 1;
+//    for (int k = 1; k < globalDim; ++k)
+//    {
+//      mulDim *= gridDestGlobalDim[k-1];
+//      globIndex += (currentIndex[k])*mulDim;
+//    }
+//
+//    if (std::binary_search(itbArr, iteArr, globIndex))
+//    {
+//      globalIndexDestGrid(realGlobalIndex) = globIndex;
+//      for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
+//      {
+//        currentIndex[axisPositionInGrid] = axisSrcGlobalIndex[i];
+//        globIndex = currentIndex[0];
+//        mulDim = 1;
+//        for (int k = 1; k < globalDim; ++k)
+//        {
+//          mulDim *= gridDestGlobalDim[k-1];
+//          globIndex += (currentIndex[k])*mulDim;
+//        }
+//        (globalIndexSrcGrid[realGlobalIndex])[i] = globIndex;
+//      }
+//      ++realGlobalIndex;
+//    }
+//
+//    ++idxLoop[0];
+//    ++idx;
+//  }
+}
+}
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 827)
@@ -29,4 +29,5 @@
   virtual void computeGlobalGridIndexFromGlobalIndexElement(int axisDestGlobalIndex,
                                                         const std::vector<int>& axisSrcGlobalIndex,
+                                                        const std::vector<int>& destGlobalIndexPositionInGrid,
                                                         int axisPositionInGrid,
                                                         const std::vector<int>& gridDestGlobalDim,
@@ -35,5 +36,6 @@
                                                         CArray<size_t,1>& globalIndexDestGrid,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid);
-  void computeIndexSourceMapping();
+
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 protected:
Index: XIOS/trunk/src/transformation/axis_algorithm_zoom.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_zoom.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_zoom.cpp	(revision 827)
@@ -27,5 +27,5 @@
   }
 
-  computeIndexSourceMapping();
+//  computeIndexSourceMapping();
 }
 
@@ -33,5 +33,5 @@
   Compute the index mapping between axis on grid source and one on grid destination
 */
-void CAxisAlgorithmZoom::computeIndexSourceMapping()
+void CAxisAlgorithmZoom::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
   StdSize niSource = axisSrc_->n.getValue();
@@ -44,6 +44,10 @@
   if (iend < ibegin) ni = 0;
 
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_;
+  this->transformationMapping_.resize(1);
+  this->transformationWeight_.resize(1);
+
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[0];
+  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[0];
+
   for (StdSize idx = 0; idx < ni; ++idx)
   {
@@ -75,5 +79,5 @@
   StdSize iBeginMask = axisDest_->begin.getValue();
   StdSize globalIndexMask = 0;
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[0];
   std::map<int, std::vector<int> >::const_iterator ite = (transMap).end();
   for (StdSize idx = 0; idx < niMask; ++idx)
Index: XIOS/trunk/src/transformation/axis_algorithm_zoom.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_zoom.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/axis_algorithm_zoom.hpp	(revision 827)
@@ -28,5 +28,6 @@
   virtual ~CAxisAlgorithmZoom() {}
 
-  virtual void computeIndexSourceMapping();
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
Index: XIOS/trunk/src/transformation/domain_algorithm_generate_rectilinear.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_generate_rectilinear.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_generate_rectilinear.cpp	(revision 827)
@@ -33,5 +33,5 @@
   Compute the index mapping between domain on grid source and one on grid destination
 */
-void CDomainAlgorithmGenerateRectilinear::computeIndexSourceMapping()
+void CDomainAlgorithmGenerateRectilinear::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
  /* Nothing to do */
Index: XIOS/trunk/src/transformation/domain_algorithm_generate_rectilinear.hpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_generate_rectilinear.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_generate_rectilinear.hpp	(revision 827)
@@ -33,5 +33,6 @@
   virtual ~CDomainAlgorithmGenerateRectilinear() {}
 
-  virtual void computeIndexSourceMapping();
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
Index: XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp	(revision 827)
@@ -23,5 +23,5 @@
 {
   interpDomain_->checkValid(domainSource);
-  computeIndexSourceMapping();
+//  computeIndexSourceMapping();
 }
 
@@ -351,5 +351,5 @@
   Compute the index mapping between domain on grid source and one on grid destination
 */
-void CDomainAlgorithmInterpolate::computeIndexSourceMapping()
+void CDomainAlgorithmInterpolate::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
   if (!interpDomain_->file.isEmpty())
@@ -381,4 +381,10 @@
   CContextClient* client=context->client;
   int clientRank = client->clientRank;
+
+  this->transformationMapping_.resize(1);
+  this->transformationWeight_.resize(1);
+
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[0];
+  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[0];
 
   boost::unordered_map<size_t,int> globalIndexOfDomainDest;
@@ -531,6 +537,6 @@
     for (int idx = 0; idx < countBuff; ++idx)
     {
-      transformationMapping_[*(recvIndexDestBuff + receivedSize + idx)].push_back(*(recvIndexSrcBuff + receivedSize + idx));
-      transformationWeight_[*(recvIndexDestBuff + receivedSize + idx)].push_back(*(recvWeightBuff + receivedSize + idx));
+      transMap[*(recvIndexDestBuff + receivedSize + idx)].push_back(*(recvIndexSrcBuff + receivedSize + idx));
+      transWeight[*(recvIndexDestBuff + receivedSize + idx)].push_back(*(recvWeightBuff + receivedSize + idx));
     }
     receivedSize += countBuff;
Index: XIOS/trunk/src/transformation/domain_algorithm_interpolate.hpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_interpolate.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_interpolate.hpp	(revision 827)
@@ -26,5 +26,6 @@
   virtual ~CDomainAlgorithmInterpolate() {}
 
-  virtual void computeIndexSourceMapping();
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 827)
@@ -21,5 +21,5 @@
 }
 
-void CDomainAlgorithmTransformation::computeIndexSourceMapping()
+void CDomainAlgorithmTransformation::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
 }
@@ -38,4 +38,5 @@
 void CDomainAlgorithmTransformation::computeGlobalGridIndexFromGlobalIndexElement(int domainDestGlobalIndex,
                                                                           const std::vector<int>& domainSrcGlobalIndex,
+                                                                          const std::vector<int>& destGlobalIndexPositionInGrid,
                                                                           int domainPositionInGrid,
                                                                           const std::vector<int>& gridDestGlobalDim,
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 827)
@@ -29,4 +29,5 @@
   virtual void computeGlobalGridIndexFromGlobalIndexElement(int domainDestGlobalIndex,
                                                         const std::vector<int>& domainSrcGlobalIndex,
+                                                        const std::vector<int>& destGlobalIndexPositionInGrid,
                                                         int domainPositionInGrid,
                                                         const std::vector<int>& gridDestGlobalDim,
@@ -35,5 +36,6 @@
                                                         CArray<size_t,1>& globalIndexDestGrid,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid);
-  void computeIndexSourceMapping();
+
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >&);
 
 protected:
Index: XIOS/trunk/src/transformation/domain_algorithm_zoom.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_zoom.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_zoom.cpp	(revision 827)
@@ -40,5 +40,5 @@
   }
 
-  computeIndexSourceMapping();
+//  computeIndexSourceMapping();
 }
 
@@ -46,5 +46,5 @@
   Compute the index mapping between domain on grid source and one on grid destination
 */
-void CDomainAlgorithmZoom::computeIndexSourceMapping()
+void CDomainAlgorithmZoom::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
   int niSource = domainSrc_->ni.getValue();
@@ -68,6 +68,13 @@
   int niGlob = domainSrc_->ni_glo.getValue();
   int njGlob = domainSrc_->nj_glo.getValue();
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_;
+
+  this->transformationMapping_.resize(1);
+  this->transformationWeight_.resize(1);
+
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[0];
+  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[0];
+
+//  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+//  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_;
   int domainGlobalIndex;
   for (int j = 0; j < nj; ++j)
@@ -110,5 +117,5 @@
   int globalIndexMask = 0;
 
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[0];
   std::map<int, std::vector<int> >::const_iterator ite = (transMap).end();
   for (int j = 0; j < njMask; ++j)
Index: XIOS/trunk/src/transformation/domain_algorithm_zoom.hpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_zoom.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/domain_algorithm_zoom.hpp	(revision 827)
@@ -28,5 +28,6 @@
   virtual ~CDomainAlgorithmZoom() {}
 
-  virtual void computeIndexSourceMapping();
+protected:
+  void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs);
 
 private:
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 827)
@@ -12,5 +12,5 @@
 
 CGenericAlgorithmTransformation::CGenericAlgorithmTransformation()
- : transformationMapping_(), transformationWeight_()
+ : transformationMapping_(), transformationWeight_(), transformationPosition_(), idAuxInputs_()
 {
 }
@@ -32,29 +32,62 @@
                                                              std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource)
 {
-  std::map<int, std::vector<int> >::const_iterator itbTransMap = transformationMapping_.begin(), itTransMap,
-                                                   iteTransMap = transformationMapping_.end();
-  std::map<int, std::vector<double> >::const_iterator itTransWeight = transformationWeight_.begin();
-  std::vector<std::vector<size_t> > globalIndexSrcGrid;
-  CArray<size_t,1> globalIndexDestGrid;
+  bool isTransPosEmpty = transformationPosition_.empty();
   std::vector<size_t> vecGlobalIndexGridSendToServer(globalIndexGridDestSendToServer.begin(), globalIndexGridDestSendToServer.end());
   std::sort(vecGlobalIndexGridSendToServer.begin(), vecGlobalIndexGridSendToServer.end());
-  for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
+  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
   {
-    this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
-                                                   itTransMap->second,
-                                                   elementPositionInGrid,
-                                                   gridDestGlobalDim,
-                                                   gridSrcGlobalDim,
-                                                   vecGlobalIndexGridSendToServer,
-                                                   globalIndexDestGrid,
-                                                   globalIndexSrcGrid);
-    size_t globalIndexSize = globalIndexDestGrid.numElements();
-    const std::vector<double>& currentVecWeight = itTransWeight->second;
-    for (size_t idx = 0; idx < globalIndexSize; ++idx)
+    std::map<int, std::vector<int> >::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
+                                                     iteTransMap = transformationMapping_[idxTrans].end();
+    std::map<int, std::vector<double> >::const_iterator itTransWeight = transformationWeight_[idxTrans].begin();
+
+    // If transformation position exists
+    std::map<int, std::vector<int> >::const_iterator itTransPos, iteTransPos;
+    if (!isTransPosEmpty)
     {
-      size_t globalIndex = globalIndexDestGrid(idx);
-      for (int i = 0; i < globalIndexSrcGrid[idx].size(); ++i)
+      itTransPos  = transformationPosition_[idxTrans].begin(),
+      iteTransPos = transformationPosition_[idxTrans].end();
+    }
+    std::vector<int> emptyTransPos;
+
+    std::vector<std::vector<size_t> > globalIndexSrcGrid;
+    CArray<size_t,1> globalIndexDestGrid;
+//    std::vector<size_t> vecGlobalIndexGridSendToServer(globalIndexGridDestSendToServer.begin(), globalIndexGridDestSendToServer.end());
+//    std::sort(vecGlobalIndexGridSendToServer.begin(), vecGlobalIndexGridSendToServer.end());
+    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
+    {
+      if (!isTransPosEmpty)
       {
-        globaIndexWeightFromDestToSource[globalIndex].push_back(make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]));
+        this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
+                                                       itTransMap->second,
+                                                       itTransPos->second,
+                                                       elementPositionInGrid,
+                                                       gridDestGlobalDim,
+                                                       gridSrcGlobalDim,
+                                                       vecGlobalIndexGridSendToServer,
+                                                       globalIndexDestGrid,
+                                                       globalIndexSrcGrid);
+        ++itTransPos;
+      }
+      else
+      {
+        this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
+                                                       itTransMap->second,
+                                                       emptyTransPos,
+                                                       elementPositionInGrid,
+                                                       gridDestGlobalDim,
+                                                       gridSrcGlobalDim,
+                                                       vecGlobalIndexGridSendToServer,
+                                                       globalIndexDestGrid,
+                                                       globalIndexSrcGrid);
+      }
+      size_t globalIndexSize = globalIndexDestGrid.numElements();
+      const std::vector<double>& currentVecWeight = itTransWeight->second;
+      for (size_t idx = 0; idx < globalIndexSize; ++idx)
+      {
+        size_t globalIndex = globalIndexDestGrid(idx);
+        for (int i = 0; i < globalIndexSrcGrid[idx].size(); ++i)
+        {
+          globaIndexWeightFromDestToSource[globalIndex].push_back(make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]));
+        }
       }
     }
@@ -62,3 +95,13 @@
 }
 
+void CGenericAlgorithmTransformation::computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs)
+{
+  computeIndexSourceMapping_(dataAuxInputs);
 }
+
+std::vector<StdString> CGenericAlgorithmTransformation::getIdAuxInputs()
+{
+  return idAuxInputs_;
+}
+
+}
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 827)
@@ -32,8 +32,10 @@
                                 std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource);
 
+  std::vector<StdString> getIdAuxInputs();
+
   /*!
   Compute global index mapping from one element of destination grid to the corresponding element of source grid
   */
-  virtual void computeIndexSourceMapping() = 0;
+  void computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs = std::vector<CArray<double,1>* >());
 
 protected:
@@ -50,4 +52,5 @@
   virtual void computeGlobalGridIndexFromGlobalIndexElement(int destGlobalIndex,
                                                         const std::vector<int>& srcGlobalIndex,
+                                                        const std::vector<int>& destGlobalIndexPositionInGrid,
                                                         int elementPositionInGrid,
                                                         const std::vector<int>& gridDestGlobalDim,
@@ -57,9 +60,17 @@
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid) = 0;
 
-
+  virtual void computeIndexSourceMapping_(const std::vector<CArray<double,1>* >&) = 0;
 
 protected:
-  std::map<int, std::vector<int> > transformationMapping_;
-  std::map<int, std::vector<double> > transformationWeight_;
+  //! Map between global index of destination element and source element
+  std::vector<std::map<int, std::vector<int> > > transformationMapping_;
+  //! Weight corresponding of source to destination
+  std::vector<std::map<int, std::vector<double> > > transformationWeight_;
+  //! Map of global index of destination element and corresponding global index of other elements in the same grid
+  //! By default, one index of an element corresponds to all index of remaining element in the grid. So it's empty
+  std::vector<std::map<int, std::vector<int> > > transformationPosition_;
+
+  //! Id of auxillary inputs which help doing transformation dynamically
+  std::vector<StdString> idAuxInputs_;
 };
 
Index: XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 826)
+++ XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 827)
@@ -23,5 +23,6 @@
 CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)
 : gridSource_(source), gridDestination_(destination), originalGridSource_(source),
-  algoTypes_(), nbAlgos_(0), currentGridIndexToOriginalGridIndex_()
+  algoTypes_(), nbAlgos_(0), currentGridIndexToOriginalGridIndex_(), tempGrids_(),
+  auxInputs_(), dynamicalTransformation_(false)
 
 {
@@ -68,38 +69,10 @@
     if (!isSpecialTransformation(transType)) ++nbAlgos_;
   }
-
-  if (1<nbAlgos_)  // Only when there are more than 1 algorithm, will we create temporary grid source
-  {
-    std::vector<CAxis*> axisSrcTmp = gridSource_->getAxis(), axisSrc;
-    std::vector<CDomain*> domainSrcTmp = gridSource_->getDomains(), domainSrc;
-    for (int idx = 0; idx < axisSrcTmp.size(); ++idx)
-    {
-      CAxis* axis = CAxis::createAxis();
-      axis->axis_ref.setValue(axisSrcTmp[idx]->getId());
-      axis->solveRefInheritance(true);
-      axis->solveInheritanceTransformation();
-      axis->checkAttributesOnClient();
-      axisSrc.push_back(axis);
-    }
-
-    for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
-    {
-      CDomain* domain = CDomain::createDomain();
-      domain->domain_ref.setValue(domainSrcTmp[idx]->getId());
-      domain->solveRefInheritance(true);
-      domain->solveInheritanceTransformation();
-      domain->checkAttributesOnClient();
-      domainSrc.push_back(domain);
-    }
-
-    gridSource_ = CGrid::createGrid(domainSrc, axisSrc, gridDestination_->axis_domain_order);
-    gridSource_->computeGridGlobalDimension(domainSrc, axisSrc, gridDestination_->axis_domain_order);
-  }
 }
 
 CGridTransformation::~CGridTransformation()
 {
-  std::list<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
-                                                              ite = algoTransformation_.end();
+  std::vector<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
+                                                                ite = algoTransformation_.end();
   for (it = itb; it != ite; ++it) delete (*it);
 }
@@ -181,4 +154,6 @@
         algoTypes_.push_back(false);
         ++transformationOrder;
+        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
+        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
       }
     }
@@ -208,4 +183,6 @@
         algoTypes_.push_back(true);
         ++transformationOrder;
+        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
+        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
       }
     }
@@ -313,13 +290,19 @@
   \param [in] transType transformation type
 */
-void CGridTransformation::setUpGrid(int elementPositionInGrid, ETranformationType transType)
-{
+void CGridTransformation::setUpGrid(int elementPositionInGrid, ETranformationType transType, int nbTransformation)
+{
+  if (!tempGrids_.empty() && (getNbAlgo()-1) == tempGrids_.size())
+  {
+    gridSource_ = tempGrids_[nbTransformation];
+    return;
+  }
+
   std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
+  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis(), axisSrc;
 
   std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
-  std::vector<CDomain*> domListSrcP = gridSource_->getDomains();
-
-  int axisIndex, domainIndex;
+  std::vector<CDomain*> domListSrcP = gridSource_->getDomains(), domainSrc;
+
+  int axisIndex = -1, domainIndex = -1;
   switch (transType)
   {
@@ -327,6 +310,4 @@
     case TRANS_ZOOM_DOMAIN:
       domainIndex = elementPosition2DomainPositionInGrid_[elementPositionInGrid];
-      domListSrcP[domainIndex]->clearAllAttributes();
-      domListSrcP[domainIndex]->duplicateAttributes(domListDestP[domainIndex]);
       break;
 
@@ -335,12 +316,33 @@
     case TRANS_INVERSE_AXIS:
       axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
-      axisListSrcP[axisIndex]->clearAllAttributes();
-      axisListSrcP[axisIndex]->duplicateAttributes(axisListDestP[axisIndex]);
       break;
     default:
       break;
   }
-  gridSource_->createMask();
-  gridSource_->computeGridGlobalDimension(domListSrcP, axisListSrcP, gridSource_->axis_domain_order);
+
+  for (int idx = 0; idx < axisListSrcP.size(); ++idx)
+  {
+    CAxis* axis = CAxis::createAxis();
+    if (axisIndex != idx) axis->axis_ref.setValue(axisListSrcP[idx]->getId());
+    else axis->axis_ref.setValue(axisListDestP[idx]->getId());
+    axis->solveRefInheritance(true);
+    axis->checkAttributesOnClient();
+    axisSrc.push_back(axis);
+  }
+
+  for (int idx = 0; idx < domListSrcP.size(); ++idx)
+  {
+    CDomain* domain = CDomain::createDomain();
+    if (domainIndex != idx) domain->domain_ref.setValue(domListSrcP[idx]->getId());
+    else domain->domain_ref.setValue(domListDestP[idx]->getId());
+    domain->solveRefInheritance(true);
+    domain->checkAttributesOnClient();
+    domainSrc.push_back(domain);
+  }
+
+  gridSource_ = CGrid::createGrid(domainSrc, axisSrc, gridDestination_->axis_domain_order);
+  gridSource_->computeGridGlobalDimension(domainSrc, axisSrc, gridDestination_->axis_domain_order);
+
+  tempGrids_.push_back(gridSource_);
 }
 
@@ -353,7 +355,9 @@
   -) Make current grid destination become grid source in the next transformation
 */
-void CGridTransformation::computeAll()
+void CGridTransformation::computeAll(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
   if (nbAlgos_ < 1) return;
+  if (!auxInputs_.empty() && !dynamicalTransformation_) { dynamicalTransformation_ = true; return; }
+  if (dynamicalTransformation_) GlobalIndexMap().swap(currentGridIndexToOriginalGridIndex_);  // Reset map
 
   CContext* context = CContext::getCurrent();
@@ -373,9 +377,16 @@
 
     // First of all, select an algorithm
-    selectAlgo(elementPositionInGrid, transType, transformationOrder, algoTypes_[std::distance(itb, it)]);
-    algo = algoTransformation_.back();
+    if (!dynamicalTransformation_ || (algoTransformation_.size() < listAlgos_.size()))
+    {
+      selectAlgo(elementPositionInGrid, transType, transformationOrder, algoTypes_[std::distance(itb, it)]);
+      algo = algoTransformation_.back();
+    }
+    else
+      algo = algoTransformation_[std::distance(itb, it)];
 
     if (0 != algo) // Only registered transformation can be executed
     {
+      algo->computeIndexSourceMapping(dataAuxInputs);
+
       // Recalculate the distribution of grid destination
       CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
@@ -398,5 +409,5 @@
 
         // Now grid destination becomes grid source in a new transformation
-        if (nbAgloTransformation != (nbAlgos_-1)) setUpGrid(elementPositionInGrid, transType);
+        if (nbAgloTransformation != (nbAlgos_-1)) setUpGrid(elementPositionInGrid, transType, nbAgloTransformation);
       }
       else
@@ -741,4 +752,5 @@
     int sourceRank = itMapRecv->first;
     int numGlobalIndex = (itMapRecv->second).size();
+    localIndexToReceiveOnGridDest_[sourceRank].resize(numGlobalIndex);
     for (int i = 0; i < numGlobalIndex; ++i)
     {
@@ -754,5 +766,5 @@
         }
       }
-      localIndexToReceiveOnGridDest_[sourceRank].push_back(tmpVec);
+      localIndexToReceiveOnGridDest_[sourceRank][i] = tmpVec;
     }
   }
Index: XIOS/trunk/src/transformation/grid_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 826)
+++ XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 827)
@@ -41,5 +41,5 @@
   ~CGridTransformation();
 
-  void computeAll();
+  void computeAll(const std::vector<CArray<double,1>* >& dataAuxInput=std::vector<CArray<double,1>* >());
 
   const std::map<int, CArray<int,1> >& getLocalIndexToSendFromGridSource() const;
@@ -49,4 +49,5 @@
   ListAlgoType getAlgoList() const {return listAlgos_; }
   int getNbAlgo() { return nbAlgos_; }
+  const std::vector<StdString>& getAuxInputs() const { return auxInputs_; }
 
 protected:
@@ -60,5 +61,5 @@
   void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
   void selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo);
-  void setUpGrid(int elementPositionInGrid, ETranformationType transType);
+  void setUpGrid(int elementPositionInGrid, ETranformationType transType, int nbTransformation);
   void computeFinalTransformationMapping();
   void computeTransformationFromOriginalGridSource(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexMapFromDestToSource);
@@ -89,5 +90,5 @@
 
   // Mapping between position of an element in grid and its transformation (if any)
-  std::list<CGenericAlgorithmTransformation*> algoTransformation_;
+  std::vector<CGenericAlgorithmTransformation*> algoTransformation_;
 
   //! Mapping of (grid) global index representing tranformation.
@@ -105,4 +106,8 @@
   //! (Grid) Global index of grid source
   GlobalIndexMap currentGridIndexToOriginalGridIndex_;
+
+  std::vector<CGrid*> tempGrids_;
+  std::vector<StdString> auxInputs_;
+  bool dynamicalTransformation_;
 };
 
