Index: XIOS/trunk/inputs/COMPLETE/context_atmosphere.xml
===================================================================
--- XIOS/trunk/inputs/COMPLETE/context_atmosphere.xml	(revision 623)
+++ XIOS/trunk/inputs/COMPLETE/context_atmosphere.xml	(revision 624)
@@ -4,18 +4,22 @@
 
   <field_definition level="1" enabled=".FALSE." default_value="9.96921e+36">
-    <field id="field_A_atm"  name="field_A_atm" operation="average" freq_op="1ts" domain_ref="domain_atm"  axis_ref="axis_atm" />
+    <field id="field_A_atm"  name="field_A_atm_origin" operation="average" freq_op="1ts" grid_ref="grid_A_atm" />
+    <field id="field_A_atm_zoom"  name="field_A_atm" operation="average" freq_op="1ts" field_ref="field_A_atm" grid_ref="grid_A_atm_zoom" />
   </field_definition>
 
   <file_definition type="multiple_file" par_access="collective" output_freq="6h" sync_freq="6h" output_level="10" enabled=".TRUE.">
     <file id="output_atmosphere" name="output_atmosphere">
-      <field field_ref="field_A_atm" />
+      <field field_ref="field_A_atm_zoom" />
     </file>
     <file id="output_atmosphere_zoom" name="output_atmosphere_zoom">
-      <field field_ref="field_A_atm" name="field_A_atm_zoom" domain_ref="domain_atm_zoom" />
+      <field field_ref="field_A_atm" name="field_A_atm_zoom" />
     </file>
   </file_definition>
 
   <axis_definition>
-    <axis id="axis_atm" zoom_size="2" zoom_end="2" />
+    <axis id="axis_atm"/>
+    <axis id="axis_atm_zoom" axis_ref="axis_atm">
+      <zoom_axis zoom_size="2" zoom_end="2" />
+    </axis>
   </axis_definition>
 
@@ -25,5 +29,15 @@
   </domain_definition>
 
-  <grid_definition />
+  <grid_definition>
+   <grid id="grid_A_atm">
+     <domain domain_ref="domain_atm" />
+     <axis axis_ref="axis_atm" />
+   </grid>
+   <grid id="grid_A_atm_zoom">
+     <domain domain_ref="domain_atm" />
+     <axis axis_ref="axis_atm_zoom" />
+   </grid>
+  </grid_definition>
+
 
 </context>
Index: XIOS/trunk/inputs/Version2/iodef.xml
===================================================================
--- XIOS/trunk/inputs/Version2/iodef.xml	(revision 623)
+++ XIOS/trunk/inputs/Version2/iodef.xml	(revision 624)
@@ -6,10 +6,10 @@
 
 
-   <field_definition level="1" enabled=".FALSE.">
+   <field_definition level="1" enabled=".FALSE." default_value="9.96921e+36">
      <field id="field_AA"  operation="average" freq_op="3600s" domain_ref="domain_A"  axis_ref="axis_A" />
      <field id="field_A"  operation="average" freq_op="3600s" grid_ref="grid_A" />
      <field id="field_Axis"  operation="average" freq_op="3600s" grid_ref="grid_Axis" />
      <field id="field_Two_Axis"  operation="average" freq_op="3600s" grid_ref="grid_Two_Axis" />
-     <field id="field_Axis_transformed"  operation="average" freq_op="3600s" field_ref="field_Two_Axis" grid_ref="grid_Axis_tranformed" />
+     <field id="field_Axis_transformed"  operation="average" freq_op="3600s" field_ref="field_A" grid_ref="grid_Axis_tranformed" />
      <field id="field_All_Axis" operation="average" freq_op="3600s" grid_ref="grid_All_Axis" />
      <field id="field_Scalar" operation="average" freq_op="3600s" grid_ref="ScalarGrid" />
@@ -35,5 +35,4 @@
    </file_definition>
 
-
    <axis_definition>
      <axis id="axis_A" />
@@ -41,12 +40,12 @@
      <axis id="axis_C" />
      <axis id="axis_D" />
-     <axis id="axis_E" axis_ref="axis_B">
-        <inverse_axis />
+     <axis id="axis_E" axis_ref="axis_C">
+<!--        <inverse_axis />-->
 
-        <zoom_axis zoom_begin="0" zoom_size="4" />
+        <zoom_axis zoom_begin="1" zoom_size="2" />
 <!--        <inverse_axis />-->
      </axis>
      <axis id="axis_F" axis_ref="axis_A">
-<!--       <inverse_axis />-->
+       <inverse_axis />
      </axis>
    </axis_definition>
@@ -71,7 +70,8 @@
        </grid>
        <grid id="grid_Axis_tranformed">
-<!--         <domain domain_ref="domain_A" />-->
-         <axis axis_ref="axis_F" />
-         <axis axis_ref="axis_E" />
+         <domain domain_ref="domain_A" />
+            <axis axis_ref="axis_E" />
+<!--         <axis axis_ref="axis_F" />-->
+<!--         <axis axis_ref="axis_E" />-->
        </grid>
        <grid id="grid_All_Axis">
Index: XIOS/trunk/inputs/iodef.xml
===================================================================
--- XIOS/trunk/inputs/iodef.xml	(revision 623)
+++ XIOS/trunk/inputs/iodef.xml	(revision 624)
@@ -7,5 +7,6 @@
 
    <field_definition level="1" enabled=".FALSE.">
-     <field id="field_A"  operation="average" freq_op="3600s" domain_ref="domain_A"  axis_ref="axis_A" />
+     <field id="field_A"  operation="average" freq_op="3600s" grid_ref="grid_A"/>
+     <field id="field_A_zoom"  operation="average" freq_op="3600s" field_ref="field_A" grid_ref="grid_A_zoom"/>
    </field_definition>
 
@@ -13,5 +14,5 @@
    <file_definition type="multiple_file" par_access="collective" output_freq="6h" output_level="10" enabled=".TRUE.">
      <file id="output" name="output">
-        <field field_ref="field_A" />
+        <field field_ref="field_A_zoom" name="field_A" />
      </file>
    </file_definition>
@@ -19,5 +20,8 @@
 
    <axis_definition>
-     <axis id="axis_A" zoom_size="2" zoom_end="2" />
+     <axis id="axis_A"/>
+     <axis id="axis_A_zoom" axis_ref="axis_A">
+       <zoom_axis zoom_begin="1" zoom_size="2" />
+     </axis>
    </axis_definition>
 
@@ -26,6 +30,14 @@
    </domain_definition>
 
-   <grid_definition />
-
+   <grid_definition>
+     <grid id="grid_A">
+       <domain domain_ref="domain_A" />
+       <axis axis_ref="axis_A" />
+     </grid>
+     <grid id="grid_A_zoom">
+       <domain domain_ref="domain_A" />
+       <axis axis_ref="axis_A_zoom" />
+     </grid>
+   </grid_definition>
   </context>
 
Index: XIOS/trunk/src/client_server_mapping_distributed.cpp
===================================================================
--- XIOS/trunk/src/client_server_mapping_distributed.cpp	(revision 623)
+++ XIOS/trunk/src/client_server_mapping_distributed.cpp	(revision 624)
@@ -35,5 +35,4 @@
    Compute mapping global index of server which client sends to.
    \param [in] globalIndexOnClient global index client has
-   \param [in] localIndexOnClient local index on client
 */
 void CClientServerMappingDistributed::computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient)
@@ -61,10 +60,4 @@
       int indexClient = std::distance(itbClientHash, itClientHash)-1;
 
-      if (clientRank_ == indexClient)
-      {
-        (indexGlobalOnServer_[globalIndexToServerMapping_[globalIndexClient]]).push_back(globalIndexClient);
-        ++nbIndexAlreadyOnClient;
-      }
-      else
       {
         client2ClientIndexGlobal[indexClient].push_back(globalIndexClient);
@@ -88,11 +81,15 @@
 
   int nbDemandingClient = recvBuff[clientRank_], nbIndexServerReceived = 0;
+
   // Receiving demand as well as the responds from other clients
   // The demand message contains global index; meanwhile the responds have server index information
   // Buffer to receive demand from other clients, it can be allocated or not depending whether it has demand(s)
   unsigned long* recvBuffIndexGlobal = 0;
-  int maxNbIndexDemandedFromOthers = (nbIndexAlreadyOnClient >= globalIndexToServerMapping_.size())
-                                   ? 0 : (globalIndexToServerMapping_.size() - nbIndexAlreadyOnClient);
-  if (!isDataDistributed_) maxNbIndexDemandedFromOthers = nbDemandingClient * globalIndexToServerMapping_.size(); // Not very optimal but it's general
+//  int maxNbIndexDemandedFromOthers = (nbIndexAlreadyOnClient >= globalIndexToServerMapping_.size())
+//                                   ? 0 : (globalIndexToServerMapping_.size() - nbIndexAlreadyOnClient);
+  int maxNbIndexDemandedFromOthers = (globalIndexToServerMapping_.size() > nbIndexSendToOthers)
+                                      ? globalIndexToServerMapping_.size() : nbIndexSendToOthers;
+
+  if (!isDataDistributed_) maxNbIndexDemandedFromOthers = nbDemandingClient * nbIndexSendToOthers; //globalIndexToServerMapping_.size(); // Not very optimal but it's general
 
   if (0 != maxNbIndexDemandedFromOthers)
@@ -102,5 +99,4 @@
   int* recvBuffIndexServer = 0;
   int nbIndexReceivedFromOthers = nbIndexSendToOthers;
-//  int nbIndexReceivedFromOthers = globalIndexToServerMapping_.size() - nbIndexAlreadyOnClient;
   if (0 != nbIndexReceivedFromOthers)
     recvBuffIndexServer = new int[nbIndexReceivedFromOthers];
@@ -237,9 +233,4 @@
     {
       int indexClient = std::distance(itbClientHash, itClientHash)-1;
-      if (clientRank_ == indexClient)
-      {
-        globalIndexToServerMapping_.insert(std::make_pair<size_t,int>(it->first, it->second));
-      }
-      else
       {
         sendBuff[indexClient] = 1;
Index: XIOS/trunk/src/distribution_client.cpp
===================================================================
--- XIOS/trunk/src/distribution_client.cpp	(revision 623)
+++ XIOS/trunk/src/distribution_client.cpp	(revision 624)
@@ -148,5 +148,4 @@
     axisMasks_[i].resize(axisList[i]->mask.numElements());
     axisMasks_[i] = axisList[i]->mask;
-    std::cout << "axisMask " << axisMasks_[i] << std::endl;
   }
 
@@ -201,6 +200,6 @@
       nBeginLocal_.at(indexMap_[idx]+1) = 0;
       nBeginGlobal_.at(indexMap_[idx]+1) = domList[domIndex]->jbegin;
-//      nZoomBegin_.at((indexMap_[idx]+1)) = domList[domIndex]->zoom_jbegin;
-//      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->zoom_jbegin + domList[domIndex]->zoom_nj-1;
+      nZoomBegin_.at((indexMap_[idx]+1)) = domList[domIndex]->zoom_jbegin;
+      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->zoom_jbegin + domList[domIndex]->zoom_nj-1;
 
       dataBegin_.at(indexMap_[idx]+1) = (2 == domList[domIndex]->data_dim) ? domList[domIndex]->data_jbegin.getValue() : -1;
@@ -213,6 +212,6 @@
       nBeginLocal_.at(indexMap_[idx]) = 0;
       nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
-//      nZoomBegin_.at((indexMap_[idx])) = domList[domIndex]->zoom_ibegin;
-//      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->zoom_ibegin + domList[domIndex]->zoom_ni-1;
+      nZoomBegin_.at((indexMap_[idx])) = domList[domIndex]->zoom_ibegin;
+      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->zoom_ibegin + domList[domIndex]->zoom_ni-1;
 
       dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
Index: XIOS/trunk/src/filter/axis_algorithm_inverse.cpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_inverse.cpp	(revision 623)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#include "axis_algorithm_inverse.hpp"
-
-namespace xios {
-
-CAxisAlgorithmInverse::CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource)
- : CAxisAlgorithmTransformation(axisDestination, axisSource)
-{
-  if (axisDestination->size.getValue() != axisSource->size.getValue())
-  {
-    ERROR("CAxisAlgorithmInverse::CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource)",
-           << "Two axis have different size"
-           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
-           << "Size of axis destionation " <<axisDestination->getId() << " is " << axisDestination->size.getValue());
-  }
-
-
-  axisDestGlobalSize_ = axisDestination->size.getValue();
-  int niDest = axisDestination->ni.getValue();
-  int ibeginDest = axisDestination->ibegin.getValue();
-
-  for (int idx = 0; idx < niDest; ++idx)
-    if ((axisDestination->mask)(idx)) axisDestGlobalIndex_.push_back(ibeginDest+idx);
-  this->computeIndexSourceMapping();
-}
-
-void CAxisAlgorithmInverse::computeIndexSourceMapping()
-{
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-
-  int globalIndexSize = axisDestGlobalIndex_.size();
-  for (int idx = 0; idx < globalIndexSize; ++idx)
-    transMap[axisDestGlobalIndex_[idx]].push_back(axisDestGlobalSize_-axisDestGlobalIndex_[idx]-1);
-}
-
-}
Index: XIOS/trunk/src/filter/axis_algorithm_inverse.hpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_inverse.hpp	(revision 623)
+++ 	(revision )
@@ -1,20 +1,0 @@
-#ifndef __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
-#define __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
-
-#include "axis_algorithm_transformation.hpp"
-#include "axis.hpp"
-
-namespace xios {
-
-class CAxisAlgorithmInverse : public CAxisAlgorithmTransformation
-{
-public:
-  CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource);
-
-  virtual ~CAxisAlgorithmInverse() {}
-
-  virtual void computeIndexSourceMapping();
-};
-
-}
-#endif // __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
Index: XIOS/trunk/src/filter/axis_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_transformation.cpp	(revision 623)
+++ 	(revision )
@@ -1,166 +1,0 @@
-#include "axis_algorithm_transformation.hpp"
-#include "axis_inverse.hpp"
-#include "axis_zoom.hpp"
-
-namespace xios {
-
-CAxisAlgorithmTransformation::CAxisAlgorithmTransformation(CAxis* axisDestination, CAxis* axisSource)
- : CGenericAlgorithmTransformation()
-{
-//  if (axisDestination->size.getValue() != axisSource->size.getValue())
-//  {
-//    ERROR("CAxisZoom::CAxisZoom(CAxis* axisDestination, CAxis* axisSource)",
-//           << "Two axis have different size"
-//           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
-//           << "Size of axis destionation " <<axisDestination->getId() << " is " << axisDestination->size.getValue());
-//  }
-//
-//
-//  axisDestGlobalSize_ = axisDestination->size.getValue();
-//  int niDest = axisDestination->ni.getValue();
-//  int ibeginDest = axisDestination->ibegin.getValue();
-//
-//  for (int idx = 0; idx < niDest; ++idx) axisDestGlobalIndex_.push_back(ibeginDest+idx);
-}
-
-CAxisAlgorithmTransformation::~CAxisAlgorithmTransformation()
-{
-//  for (int idx = 0; idx < algosOfAnAxis_.size(); ++idx) delete algosOfAnAxis_[idx];
-}
-
-void CAxisAlgorithmTransformation::computeIndexSourceMapping()
-{
-//  if (!algosOfAnAxis_.empty())
-//  {
-//    algosOfAnAxis_[0]->computeIndexSourceMapping(this->transformationMapping_);
-//    for (int idx = 1; idx < algosOfAnAxis_.size(); ++idx)
-//    {
-//      algosOfAnAxis_[idx]->computeIndexSourceMapping(algosOfAnAxis_[idx-1]->getTransformationMapping());
-//    }
-//    this->transformationMapping_ = algosOfAnAxis_[algosOfAnAxis_.size()-1]->getTransformationMapping();
-//  }
-}
-
-/*!
-  Compute an array of global index from a global index on a axis
-  \param[in] axisDestGlobalIndex global index on an axis of destination grid
-  \param[in] axisSrcGlobalIndex global index on an axis of source grid (which are needed by one index on axis destination)
-  \param[in] axisPositionInGrid position of the axis in the grid
-  \param[in] gridDestGlobalDim dimension size of destination grid (it should share the same size for all dimension, maybe except the axis on which transformation is performed)
-  \param[in] globalIndexGridDestSendToServer global index of destination grid which are to be sent to server(s)
-  \param[in/out] globalIndexDestGrid array of global index (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
-  \param[in/out] globalIndexSrcGrid array of global index of source grid (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
-*/
-void CAxisAlgorithmTransformation::computeGlobalIndexFromGlobalIndexElement(int axisDestGlobalIndex,
-                                                                          const std::vector<int>& axisSrcGlobalIndex,
-                                                                          int axisPositionInGrid,
-                                                                          const std::vector<int>& gridDestGlobalDim,
-                                                                          const CArray<size_t,1>& globalIndexGridDestSendToServer,
-                                                                          CArray<size_t,1>& globalIndexDestGrid,
-                                                                          std::vector<CArray<size_t,1> >& globalIndexSrcGrid)
-{
-  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];
-  }
-
-  CArray<size_t,1>::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;
-    }
-
-    itArr = std::find(itbArr, iteArr, globIndex);
-    if (iteArr != itArr) ++realGlobalIndexSize;
-    ++idxLoop[0];
-    ++idx;
-  }
-
-  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
-    globalIndexDestGrid.resize(realGlobalIndexSize);
-
-  if (axisSrcGlobalIndex.size() != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(axisSrcGlobalIndex.size());
-  for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
-    if (globalIndexSrcGrid[i].numElements() != realGlobalIndexSize)
-      globalIndexSrcGrid[i].resize(realGlobalIndexSize);
-
-
-  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;
-    }
-
-    itArr = std::find(itbArr, iteArr, globIndex);
-    if (iteArr != itArr)
-    {
-      globalIndexDestGrid(realGlobalIndex) = globIndex;
-      for (int i = 0; i < globalIndexSrcGrid.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[i])(realGlobalIndex) = globIndex;
-      }
-      ++realGlobalIndex;
-    }
-
-    ++idxLoop[0];
-    ++idx;
-  }
-}
-
-
-}
Index: XIOS/trunk/src/filter/axis_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_transformation.hpp	(revision 623)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#ifndef __XIOS_AXIS_ALGORITHM_TRANSFORMATION_HPP__
-#define __XIOS_AXIS_ALGORITHM_TRANSFORMATION_HPP__
-
-#include "generic_algorithm_transformation.hpp"
-#include "axis.hpp"
-#include "concrete_algo.hpp"
-
-namespace xios {
-
-class CAxisAlgorithmTransformation : public virtual CGenericAlgorithmTransformation
-{
-public:
-  CAxisAlgorithmTransformation(CAxis* axisDestination, CAxis* axisSource);
-
-  virtual ~CAxisAlgorithmTransformation();
-
-protected:
-  virtual void computeGlobalIndexFromGlobalIndexElement(int axisDestGlobalIndex,
-                                                        const std::vector<int>& axisSrcGlobalIndex,
-                                                        int axisPositionInGrid,
-                                                        const std::vector<int>& gridDestGlobalDim,
-                                                        const CArray<size_t,1>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
-                                                        std::vector<CArray<size_t,1> >& globalIndexSrcGrid);
-  void computeIndexSourceMapping();
-protected:
-  std::vector<int> axisDestGlobalIndex_;
-  int axisDestGlobalSize_;
-
-};
-
-}
-#endif // __XIOS_AXIS_ALGORITHM_TRANSFORMATION_HPP__
Index: XIOS/trunk/src/filter/axis_algorithm_zoom.cpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_zoom.cpp	(revision 623)
+++ 	(revision )
@@ -1,66 +1,0 @@
-#include "axis_algorithm_zoom.hpp"
-
-namespace xios {
-
-CAxisAlgorithmZoom::CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)
-: CAxisAlgorithmTransformation(axisDestination, axisSource), axisDest_(axisDestination), axisSrc_(axisSource)
-{
-  zoomAxis->checkValid(axisSource);
-  zoomBegin_ = zoomAxis->zoom_begin.getValue();
-  zoomEnd_   = zoomAxis->zoom_end.getValue();
-  zoomSize_  = zoomAxis->zoom_size.getValue();
-
-  if (zoomSize_ > axisSource->size.getValue())
-  {
-    ERROR("CAxisAlgorithmZoom::CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)",
-           << "Zoom size is greater than size of axis source"
-           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
-           << "Zoom size is " << zoomSize_ );
-  }
-
-  computeIndexSourceMapping();
-}
-
-void CAxisAlgorithmZoom::computeIndexSourceMapping()
-{
-  StdSize niSource = axisSrc_->ni.getValue();
-  StdSize ibeginSource = axisSrc_->ibegin.getValue();
-  StdSize iendSource = ibeginSource + niSource - 1;
-
-  StdSize ibegin = std::max(ibeginSource, zoomBegin_);
-  StdSize iend = std::min(iendSource, zoomEnd_);
-  StdSize ni = iend + 1 - ibegin;
-  if (iend < ibegin) ni = 0;
-
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  for (StdSize idx = 0; idx < ni; ++idx)
-  {
-    transMap[ibegin+idx].push_back(ibegin+idx);
-  }
-
-  updateZoom();
-  updateAxisDestinationMask();
-}
-
-void CAxisAlgorithmZoom::updateZoom()
-{
-  axisDest_->global_zoom_begin = zoomBegin_;
-  axisDest_->global_zoom_size  = zoomSize_;
-}
-
-void CAxisAlgorithmZoom::updateAxisDestinationMask()
-{
-  StdSize niMask = axisDest_->mask.numElements();
-  StdSize iBeginMask = axisDest_->ibegin.getValue();
-  StdSize globalIndexMask = 0;
-  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
-  std::map<int, std::vector<int> >::const_iterator ite = (transMap).end();
-  for (StdSize idx = 0; idx < niMask; ++idx)
-  {
-    globalIndexMask = iBeginMask + idx;
-    if (transMap.find(globalIndexMask) == ite)
-      (axisDest_->mask)(idx) = false;
-  }
-}
-
-}
Index: XIOS/trunk/src/filter/axis_algorithm_zoom.hpp
===================================================================
--- XIOS/trunk/src/filter/axis_algorithm_zoom.hpp	(revision 623)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#ifndef __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
-#define __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
-
-#include "axis_algorithm_transformation.hpp"
-#include "axis.hpp"
-#include "zoom_axis.hpp"
-
-namespace xios {
-
-class CAxisAlgorithmZoom : public CAxisAlgorithmTransformation
-{
-public:
-  CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis);
-
-  virtual ~CAxisAlgorithmZoom() {}
-
-  virtual void computeIndexSourceMapping();
-
-private:
-  void updateAxisDestinationMask();
-  void updateZoom();
-private:
-  StdSize zoomBegin_;
-  StdSize zoomEnd_;
-  StdSize zoomSize_;
-
-private:
-  CAxis* axisDest_;
-  CAxis* axisSrc_;
-};
-
-}
-#endif // __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
Index: XIOS/trunk/src/filter/generic_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/filter/generic_algorithm_transformation.cpp	(revision 623)
+++ 	(revision )
@@ -1,51 +1,0 @@
-#include "generic_algorithm_transformation.hpp"
-
-namespace xios {
-
-CGenericAlgorithmTransformation::CGenericAlgorithmTransformation()
- : transformationMapping_()
-{
-}
-
-/*!
-  This function computes the global indexes of grid source, which the grid destination is in demand.
-  \param[in] elementPositionInGrid position of an element in a grid .E.g: if grid is composed of domain and axis (in order),
-                then position of axis in grid is 2 (since a domain is considered to contain 2 elements (axis)
-  \param[in] gridDestGlobalDim global size of each dimension of grid source (all dimension must have the same size except of the one on which transformation is performed)
-  \param[in] globalIndexGridDestSendToServer global index of grid destination on the current client to send to server
-  \param[in/out] globaIndexMapFromDestToSource mapping between transformed global index of grid destination
-                    and the demanded global index of grid source
-*/
-void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
-                                                             const std::vector<int>& gridDestGlobalDim,
-                                                             const CArray<size_t,1>& globalIndexGridDestSendToServer,
-                                                             std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource)
-{
-  std::map<int, std::vector<int> >::const_iterator itbTransMap = transformationMapping_.begin(),
-                                                   itTransMap = itbTransMap,
-                                                   iteTransMap = transformationMapping_.end();
-  std::vector<int>::const_iterator itbVec, itVec, iteVec;
-  std::vector<CArray<size_t,1> > globalIndexSrcGrid((itTransMap->second).size());
-  CArray<size_t,1> globalIndexDestGrid;
-
-  for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap)
-  {
-    this->computeGlobalIndexFromGlobalIndexElement(itTransMap->first,
-                                                   itTransMap->second,
-                                                   elementPositionInGrid,
-                                                   gridDestGlobalDim,
-                                                   globalIndexGridDestSendToServer,
-                                                   globalIndexDestGrid,
-                                                   globalIndexSrcGrid);
-    size_t globalIndexSize = globalIndexDestGrid.numElements();
-    for (size_t idx = 0; idx < globalIndexSize; ++idx)
-    {
-      for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
-      {
-        globaIndexMapFromDestToSource[globalIndexDestGrid(idx)].insert(globalIndexSrcGrid[i](idx));
-      }
-    }
-  }
-}
-
-}
Index: XIOS/trunk/src/filter/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/filter/generic_algorithm_transformation.hpp	(revision 623)
+++ 	(revision )
@@ -1,53 +1,0 @@
-#ifndef __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__
-#define __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__
-
-#include <map>
-#include <vector>
-#include "array_new.hpp"
-
-namespace xios {
-
-class CGenericAlgorithmTransformation
-{
-public:
-  CGenericAlgorithmTransformation();
-
-  virtual ~CGenericAlgorithmTransformation() {}
-
-  void computeGlobalSourceIndex(int elementPositionInGrid,
-                                const std::vector<int>& gridDestGlobalDim,
-                                const CArray<size_t,1>& globalIndexGridDestSendToServer,
-                                std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
-
-  /*!
-  Compute global index mapping from one element of destination grid to the corresponding element of source grid
-  */
-  virtual void computeIndexSourceMapping() = 0;
-
-protected:
-  /*!
-  Compute an array of global index from a global index on an element
-    \param[in] destGlobalIndex global index on an element of destination grid
-    \param[in] srcGlobalIndex global index(es) on an element of source grid (which are needed by one index on element destination)
-    \param[in] elementPositionInGrid position of the element in the grid (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
-    \param[in] gridDestGlobalDim dimension size of destination grid (it should share the same size for all dimension, maybe except the element on which transformation is performed)
-    \param[in] globalIndexGridDestSendToServer global index of destination grid which are to be sent to server(s)
-    \param[in/out] globalIndexDestGrid array of global index (for 2d grid, this array maybe a line, for 3d, this array may represent a plan). It should be preallocated
-    \param[in/out] globalIndexSrcGrid array of global index of source grid (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
-  */
-  virtual void computeGlobalIndexFromGlobalIndexElement(int destGlobalIndex,
-                                                        const std::vector<int>& srcGlobalIndex,
-                                                        int elementPositionInGrid,
-                                                        const std::vector<int>& gridDestGlobalDim,
-                                                        const CArray<size_t,1>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
-                                                        std::vector<CArray<size_t,1> >& globalIndexSrcGrid) = 0;
-
-
-
-protected:
-  std::map<int, std::vector<int> > transformationMapping_;
-};
-
-}
-#endif // __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__
Index: XIOS/trunk/src/filter/grid_transformation.cpp
===================================================================
--- XIOS/trunk/src/filter/grid_transformation.cpp	(revision 623)
+++ 	(revision )
@@ -1,560 +1,0 @@
-/*!
-   \file grid_transformation.cpp
-   \author Ha NGUYEN
-   \since 14 May 2015
-   \date 09 June 2015
-
-   \brief Interface for all transformations.
- */
-#include "grid_transformation.hpp"
-#include "axis_algorithm_inverse.hpp"
-#include "axis_algorithm_zoom.hpp"
-#include "context.hpp"
-#include "context_client.hpp"
-#include "transformation_mapping.hpp"
-
-#include "axis_algorithm_transformation.hpp"
-
-namespace xios {
-CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)
-: gridSource_(source), gridDestination_(destination), originalGridSource_(source),
-  globalIndexOfCurrentGridSource_(0), globalIndexOfOriginalGridSource_(0)
-{
-  //Verify the compatibity between two grids
-  int numElement = gridDestination_->axis_domain_order.numElements();
-  if (numElement != gridSource_->axis_domain_order.numElements())
-    ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
-       << "Two grids have different number of elements"
-       << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
-       << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
-
-  for (int i = 0; i < numElement; ++i)
-  {
-    if (gridDestination_->axis_domain_order(i) != gridSource_->axis_domain_order(i))
-      ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
-         << "Transformed grid and its grid source have incompatible elements"
-         << "Grid source " <<gridSource_->getId() << std::endl
-         << "Grid destination " <<gridDestination_->getId());
-  }
-
-  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->setAttributes(axisSrcTmp[idx]);
-    axisSrc.push_back(axis);
-  }
-
-  for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
-  {
-    CDomain* domain = CDomain::createDomain();
-    domain->setAttributes(domainSrcTmp[idx]);
-    domainSrc.push_back(domain);
-  }
-
-  gridSource_ = CGrid::createGrid(domainSrc, axisSrc, gridDestination_->axis_domain_order);
-  gridSourceDimensionSize_ = gridSource_->getGlobalDimension();
-  gridDestinationDimensionSize_ = gridDestination_->getGlobalDimension();
-
-  initializeMappingOfOriginalGridSource();
-  initializeAlgorithms();
-}
-
-void CGridTransformation::initializeMappingOfOriginalGridSource()
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client=context->client;
-
-  CDistributionClient distribution(client->clientRank, originalGridSource_);
-  const CArray<size_t,1>& globalIndexGridDestSendToServer = distribution.getGlobalDataIndexSendToServer();
-
-  globalIndexOfCurrentGridSource_   = new CArray<size_t,1>(globalIndexGridDestSendToServer.numElements());
-  globalIndexOfOriginalGridSource_  = new CArray<size_t,1>(globalIndexGridDestSendToServer.numElements());
-  *globalIndexOfCurrentGridSource_  = globalIndexGridDestSendToServer;
-  *globalIndexOfOriginalGridSource_ = globalIndexGridDestSendToServer;
-}
-
-CGridTransformation::~CGridTransformation()
-{
-  std::list<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
-                                                              ite = algoTransformation_.end();
-  for (it = itb; it != ite; ++it) delete (*it);
-
-  std::map<int, std::vector<CArray<int,1>* > >::const_iterator itMapRecv, iteMapRecv;
-  itMapRecv = localIndexToReceiveOnGridDest_.begin();
-  iteMapRecv = localIndexToReceiveOnGridDest_.end();
-  for (; itMapRecv != iteMapRecv; ++itMapRecv)
-  {
-    int numVec = (itMapRecv->second).size();
-    for (int idx = 0; idx < numVec; ++idx) delete (itMapRecv->second)[idx];
-  }
-
-  std::map<int, CArray<int,1>* >::const_iterator itMap, iteMap;
-  itMap = localIndexToSendFromGridSource_.begin();
-  iteMap = localIndexToSendFromGridSource_.end();
-  for (; itMap != iteMap; ++itMap) delete (itMap->second);
-
-  if (0 != globalIndexOfCurrentGridSource_) delete globalIndexOfCurrentGridSource_;
-  if (0 != globalIndexOfOriginalGridSource_) delete globalIndexOfOriginalGridSource_;
-}
-
-void CGridTransformation::initializeAlgorithms()
-{
-  initializeAxisAlgorithms();
-  initializeDomainAlgorithms();
-}
-
-/*!
-  Initialize the algorithms corresponding to transformation info contained in each axis.
-If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
-In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
-For now, one approach is to do these combinely but maybe this needs changing.
-*/
-void CGridTransformation::initializeAxisAlgorithms()
-{
-  std::vector<int> axisPositionInGrid;
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
-  if (!axisListDestP.empty())
-  {
-    int idx = 0;
-    for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
-    {
-      if (false == (gridDestination_->axis_domain_order)(i))
-      {
-        axisPositionInGrid.push_back(idx);
-        ++idx;
-      }
-      else idx += 2;
-    }
-
-    for (int i = 0; i < axisListDestP.size(); ++i)
-    {
-      elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
-      if (axisListDestP[i]->hasTransformation())
-      {
-        CAxis::TransMapTypes trans = axisListDestP[i]->getAllTransformations();
-        CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
-                                             ite = trans.end();
-        int transformationOrder = 0;
-        for (it = itb; it != ite; ++it)
-        {
-          listAlgos_.push_back(std::make_pair(axisPositionInGrid[i], std::make_pair(it->first, transformationOrder)));
-          ++transformationOrder;
-        }
-      }
-    }
-  }
-}
-
-void CGridTransformation::initializeDomainAlgorithms()
-{
-
-}
-
-void CGridTransformation::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
-{
-   selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
-}
-
-void CGridTransformation::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
-{
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
-
-  int axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
-  CAxis::TransMapTypes trans = axisListDestP[axisIndex]->getAllTransformations();
-  CAxis::TransMapTypes::const_iterator it = trans.begin();
-
-  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
-
-  CZoomAxis* zoomAxis = 0;
-  CGenericAlgorithmTransformation* algo = 0;
-  switch (transType)
-  {
-    case TRANS_ZOOM_AXIS:
-      zoomAxis = dynamic_cast<CZoomAxis*> (it->second);
-      algo = new CAxisAlgorithmZoom(axisListDestP[axisIndex], axisListSrcP[axisIndex], zoomAxis);
-      break;
-    case TRANS_INVERSE_AXIS:
-      algo = new CAxisAlgorithmInverse(axisListDestP[axisIndex], axisListSrcP[axisIndex]);
-      break;
-    default:
-      break;
-  }
-  algoTransformation_.push_back(algo);
-
-}
-
-void CGridTransformation::selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
-{
-
-}
-
-void CGridTransformation::setUpGrid(int elementPositionInGrid, ETranformationType transType)
-{
-  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
-  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
-
-  int axisIndex;
-  switch (transType)
-  {
-    case TRANS_ZOOM_AXIS:
-    case TRANS_INVERSE_AXIS:
-      axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
-      axisListSrcP[axisIndex]->duplicateAttributes(axisListDestP[axisIndex]);
-      break;
-    default:
-      break;
-  }
-}
-
-void CGridTransformation::computeAll()
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client=context->client;
-
-  ListAlgoType::const_iterator itb = listAlgos_.begin(),
-                               ite = listAlgos_.end(), it;
-  CGenericAlgorithmTransformation* algo = 0;
-  for (it = itb; it != ite; ++it)
-  {
-    std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource;
-    int elementPositionInGrid = it->first;
-    ETranformationType transType = (it->second).first;
-    int transformationOrder = (it->second).second;
-
-    // First of all, select an algorithm
-    selectAlgo(elementPositionInGrid, transType, transformationOrder);
-    algo = algoTransformation_.back();
-
-    // Recalculate the distribution of grid destination
-    CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
-    const CArray<size_t,1>& globalIndexGridDestSendToServer = distributionClientDest.getGlobalDataIndexSendToServer();
-
-   std::cout << "global index grid  dest send to server " << globalIndexGridDestSendToServer << std::endl;
-    // ComputeTransformation of global index of each element
-    std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension();
-    int elementPosition = it->first;
-    algo->computeGlobalSourceIndex(elementPosition,
-                                   gridDestinationDimensionSize,
-                                   globalIndexGridDestSendToServer,
-                                   globaIndexMapFromDestToSource);
-
-    // Compute transformation of global indexes among grids
-    computeTransformationFromOriginalGridSource(globaIndexMapFromDestToSource);
-
-    // Now grid destination becomes grid source in a new transformation
-    setUpGrid(elementPositionInGrid, transType);
-  }
-
- std::cout << "global index destination 0 final " << *globalIndexOfCurrentGridSource_ << std::endl;
- std::cout << "global index destination 1 final " << *globalIndexOfOriginalGridSource_ << std::endl;
-  updateFinalGridDestination();
-  computeFinalTransformationMapping();
-}
-
-
-/*!
-  After applying the algorithms, there are some informations on grid destination needing change, for now, there are:
-   +) mask
-*/
-void CGridTransformation::updateFinalGridDestination()
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client=context->client;
-
-  //First of all, retrieve info of local mask of grid destination
-  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
-  const CArray<int, 1>& localMaskIndexOnClientDest = distributionClientDest.getLocalMaskIndexOnClient();
-  std::cout << "local mask " << localMaskIndexOnClientDest << std::endl;
-
-  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
-  std::cout << "global index " << globalIndexOnClientDest <<  std::endl;
-  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
-  itbArr = globalIndexOnClientDest.begin();
-  iteArr = globalIndexOnClientDest.end();
-
-  // Then find out which index became invalid (become masked after being applied the algorithms, or demande some masked points from grid source)
-  int num = globalIndexOfOriginalGridSource_->numElements();
-  const size_t sfmax = NumTraits<unsigned long>::sfmax();
-  int maskIndexNum = 0;
-  for (int idx = 0; idx < num; ++idx)
-  {
-    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
-    {
-      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
-      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
-      if (iteArr != itArr) ++maskIndexNum;
-    }
-  }
-
-  CArray<int,1>* maskIndexToModify = new CArray<int,1>(maskIndexNum);
-  maskIndexNum = 0;
-  for (int idx = 0; idx < num; ++idx)
-  {
-    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
-    {
-      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
-      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
-      if (iteArr != itArr)
-      {
-        int localIdx = std::distance(itbArr, itArr);
-        (*maskIndexToModify)(maskIndexNum) = (localMaskIndexOnClientDest)(localIdx);
-        ++maskIndexNum;
-      }
-    }
-  }
-
-  std::cout << "index to modify " << *maskIndexToModify << std::endl;
-  gridDestination_->modifyMask(*maskIndexToModify);
-
-  delete maskIndexToModify;
-}
-
-/*!
-  A transformation from a grid source to grid destination often passes several intermediate grids, which play a role of
-temporary grid source and/or grid destination. This function makes sure that global index of original grid source are mapped correctly to
-the final grid destination
-*/
-void CGridTransformation::computeTransformationFromOriginalGridSource(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource)
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client=context->client;
-
-  CTransformationMapping transformationMap(gridDestination_, gridSource_);
-
-    // Then compute transformation mapping among clients
-  transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
-
-  const std::map<int,std::vector<std::vector<size_t> > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
-  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
-
- // Sending global index of original grid source
-  std::map<int,std::vector<size_t> >::const_iterator itbSend = globalIndexToSend.begin(), itSend,
-                                                     iteSend = globalIndexToSend.end();
-  CArray<size_t,1>::const_iterator itbArr = globalIndexOfCurrentGridSource_->begin(), itArr,
-                                   iteArr = globalIndexOfCurrentGridSource_->end();
- int sendBuffSize = 0;
- for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
-
- std::cout << "global index destination 0 before" << *globalIndexOfCurrentGridSource_ << std::endl;
- std::cout << "global index destination 1 before" << *globalIndexOfOriginalGridSource_ << std::endl;
-
- typedef unsigned long Scalar;
- unsigned long* sendBuff, *currentSendBuff;
- if (0 != sendBuffSize) sendBuff = new unsigned long [sendBuffSize];
- for (StdSize idx = 0; idx < sendBuffSize; ++idx) sendBuff[idx] = NumTraits<Scalar>::sfmax();
-
- int currentBuffPosition = 0;
- for (itSend = itbSend; itSend != iteSend; ++itSend)
- {
-   int destRank = itSend->first;
-   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
-   int countSize = globalIndexOfCurrentGridSourceToSend.size();
-   for (int idx = 0; idx < (countSize); ++idx)
-   {
-     itArr = std::find(itbArr, iteArr, globalIndexOfCurrentGridSourceToSend[idx]);
-     if (iteArr != itArr)
-     {
-       int index = std::distance(itbArr, itArr);
-       sendBuff[idx+currentBuffPosition] = (*globalIndexOfOriginalGridSource_)(index);
-     }
-   }
-   currentSendBuff = sendBuff + currentBuffPosition;
-   MPI_Send(currentSendBuff, countSize, MPI_UNSIGNED_LONG, destRank, 14, client->intraComm);
-   currentBuffPosition += countSize;
- }
-
- // Receiving global index of grid source sending from current grid source
- std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
-                                                                  iteRecv = globalIndexToReceive.end();
- int recvBuffSize = 0;
- for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size();
-
- unsigned long* recvBuff, *currentRecvBuff;
- if (0 != recvBuffSize) recvBuff = new unsigned long [recvBuffSize];
- for (StdSize idx = 0; idx < recvBuffSize; ++idx) recvBuff[idx] = NumTraits<Scalar>::sfmax();
-
- int currentRecvBuffPosition = 0;
- for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
- {
-   MPI_Status status;
-   int srcRank = itRecv->first;
-   int countSize = (itRecv->second).size();
-   currentRecvBuff = recvBuff + currentRecvBuffPosition;
-   MPI_Recv(currentRecvBuff, countSize, MPI_UNSIGNED_LONG, srcRank, 14, client->intraComm, &status);
-   currentRecvBuffPosition += countSize;
- }
-
- int nbCurrentGridSource = 0;
- for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
- {
-   int ssize = (itRecv->second).size();
-   for (int idx = 0; idx < ssize; ++idx)
-   {
-     nbCurrentGridSource += (itRecv->second)[idx].size();
-   }
- }
-
- if (globalIndexOfCurrentGridSource_->numElements()  != nbCurrentGridSource)
- {
-   if ((0 != nbCurrentGridSource) && (0 != globalIndexOfCurrentGridSource_))
-   {
-     delete globalIndexOfCurrentGridSource_;
-     globalIndexOfCurrentGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
-   }
- }
-
- if (globalIndexOfOriginalGridSource_->numElements() != nbCurrentGridSource)
- {
-   if ((0 != nbCurrentGridSource) && (0 != globalIndexOfOriginalGridSource_))
-   {
-     delete globalIndexOfOriginalGridSource_;
-     globalIndexOfOriginalGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
-   }
- }
-
- int k = 0;
- currentRecvBuff = recvBuff;
- for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
- {
-   int countSize = (itRecv->second).size();
-   for (int idx = 0; idx < countSize; ++idx, ++currentRecvBuff)
-   {
-     int ssize = (itRecv->second)[idx].size();
-     for (int i = 0; i < ssize; ++i)
-     {
-       (*globalIndexOfCurrentGridSource_)(k) = (itRecv->second)[idx][i];
-       (*globalIndexOfOriginalGridSource_)(k) = *currentRecvBuff;
-       ++k;
-     }
-   }
- }
-
- std::cout << "global index destination 0 after " << *globalIndexOfCurrentGridSource_ << std::endl;
- std::cout << "global index destination 1 after " << *globalIndexOfOriginalGridSource_ << std::endl;
- if (0 != sendBuffSize) delete [] sendBuff;
- if (0 != recvBuffSize) delete [] recvBuff;
-}
-
-/*!
-  Compute transformation mapping between grid source and grid destination
-  The transformation between grid source and grid destination is represented in form of mapping between global index
-of two grids. Then local index mapping between data on each grid will be found out thanks to these global indexes
-*/
-void CGridTransformation::computeFinalTransformationMapping()
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client=context->client;
-
-  CTransformationMapping transformationMap(gridDestination_, originalGridSource_);
-
-  std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource;
-
-  int nb = globalIndexOfCurrentGridSource_->numElements();
-  const size_t sfmax = NumTraits<unsigned long>::sfmax();
-  for (int idx = 0; idx < nb; ++idx)
-  {
-    if (sfmax != (*globalIndexOfOriginalGridSource_)(idx))
-      globaIndexMapFromDestToSource[(*globalIndexOfCurrentGridSource_)(idx)].insert((*globalIndexOfOriginalGridSource_)(idx));
-  }
-
-  // Then compute transformation mapping among clients
-  transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
-
-  const std::map<int,std::vector<std::vector<size_t> > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
-  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
-
-  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
-  CDistributionClient distributionClientSrc(client->clientRank, originalGridSource_);
-
-//  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexOnClient(); //gridDestination_->getDistributionClient()->getLocalDataIndexOnClient();
-  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexSendToServer();
-  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer(); //gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
-
- std::cout << "dest: local index " << localIndexOnClientDest << std::endl;
- std::cout << "dest: global index " << globalIndexOnClientDest << std::endl;
-  const CArray<int, 1>& localIndexOnClientSrc = distributionClientSrc.getLocalDataIndexOnClient(); //gridSource_->getDistributionClient()->getLocalDataIndexOnClient();
-  const CArray<size_t,1>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
- std::cout << "src: local index " << localIndexOnClientSrc << std::endl;
- std::cout << "src: global index " << globalIndexOnClientSrc << std::endl;
-  std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
-  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
-
-  std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
-
-  // Find out local index on grid destination (received)
-  itbMapRecv = globalIndexToReceive.begin();
-  iteMapRecv = globalIndexToReceive.end();
-  itbArr = globalIndexOnClientDest.begin();
-  iteArr = globalIndexOnClientDest.end();
-  for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv)
-  {
-    int sourceRank = itMapRecv->first;
-    int numGlobalIndex = (itMapRecv->second).size();
-    for (int i = 0; i < numGlobalIndex; ++i)
-    {
-      int vecSize = ((itMapRecv->second)[i]).size();
-      CArray<int,1>* ptr = new CArray<int,1>(vecSize);
-      localIndexToReceiveOnGridDest_[sourceRank].push_back(ptr);
-      for (int idx = 0; idx < vecSize; ++idx)
-      {
-        itArr = std::find(itbArr, iteArr, (itMapRecv->second)[i][idx]);
-        if (iteArr != itArr)
-        {
-          int localIdx = std::distance(itbArr, itArr);
-          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = localIndexOnClientDest(localIdx); // Local index of un-extracted data (only domain)
-//          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = (localIdx); // Local index of extracted data
-        }
-      }
-    }
-//    std::cout << "local index to receive from source Rank = " << sourceRank << (*localIndexToReceiveOnGridDest_[sourceRank][i]) << std::endl;
-  }
-
-  std::map<int,std::vector<size_t> >::const_iterator itbMap, itMap, iteMap;
-  // Find out local index on grid source (to send)
-  itbMap = globalIndexToSend.begin();
-  iteMap = globalIndexToSend.end();
-  itbArr = globalIndexOnClientSrc.begin();
-  iteArr = globalIndexOnClientSrc.end();
-  for (itMap = itbMap; itMap != iteMap; ++itMap)
-  {
-    CArray<int,1>* ptr = new CArray<int,1>((itMap->second).size());
-    localIndexToSendFromGridSource_[itMap->first] = ptr;
-    int destRank = itMap->first;
-    int vecSize = (itMap->second).size();
-    for (int idx = 0; idx < vecSize; ++idx)
-    {
-      itArr = std::find(itbArr, iteArr, (itMap->second)[idx]);
-      if (iteArr != itArr)
-      {
-        int localIdx = std::distance(itbArr, itArr);
-//        (*localIndexToSendFromGridSource_[destRank])(idx) = localIndexOnClientSrc(localIdx);
-        (*localIndexToSendFromGridSource_[destRank])(idx) = (localIdx);
-      }
-    }
-    std::cout << "local index to send to dest Rank = " << destRank << (*localIndexToSendFromGridSource_[destRank]) << std::endl;
-  }
-}
-
-/*!
-  Local index of data which need sending from the grid source
-  \return local index of data
-*/
-std::map<int, CArray<int,1>* > CGridTransformation::getLocalIndexToSendFromGridSource()
-{
-  return localIndexToSendFromGridSource_;
-}
-
-/*!
-  Local index of data which will be received on the grid destination
-  \return local index of data
-*/
-std::map<int, std::vector<CArray<int,1>* > > CGridTransformation::getLocalIndexToReceiveOnGridDest()
-{
-  return localIndexToReceiveOnGridDest_;
-}
-
-}
Index: XIOS/trunk/src/filter/grid_transformation.hpp
===================================================================
--- XIOS/trunk/src/filter/grid_transformation.hpp	(revision 623)
+++ 	(revision )
@@ -1,103 +1,0 @@
-/*!
-   \file grid_transformation.hpp
-   \author Ha NGUYEN
-   \since 14 May 2015
-   \date 09 June 2015
-
-   \brief Interface for all transformations.
- */
-#ifndef __XIOS_GRID_TRANSFORMATION_HPP__
-#define __XIOS_GRID_TRANSFORMATION_HPP__
-
-#include <map>
-#include <vector>
-#include "grid.hpp"
-#include "generic_algorithm_transformation.hpp"
-#include "transformation_enum.hpp"
-
-namespace xios {
-
-class CGrid;
-
-/*!
-  \class CGridTransformation
-  This class is an interface for all transformations to interact with the rest of XIOS.
-The class, firstly, tries to get all information relating to requested transformations by retrieving directly from grid.
-Then with all these information, all necessary transformations will be be created by generic class \class CGenericAlgorithmTransformation.
-Because there are information exchange among clients to accomplish the transformations (e.g: some index need retrieving from other clients),
-this class uses class \class CTransformationMapping to fulfill this demand.
-For each transformation, a new temporary grid source is created.
-For a consequential transformations (e.g: inversing -> zoom -> inversing -> ...),
-the grid destination of current transformation will be grid source of the next transformation
-*/
-class CGridTransformation
-{
-public:
-  /** Default constructor */
-  CGridTransformation(CGrid* destination, CGrid* source);
-  ~CGridTransformation();
-
-  void computeAll();
-
-
-  std::map<int, CArray<int,1>* > getLocalIndexToSendFromGridSource();
-  std::map<int, std::vector<CArray<int,1>* > > getLocalIndexToReceiveOnGridDest();
-
-private:
-  void computeTransformation();
-  void initializeAlgorithms();
-  void initializeAxisAlgorithms();
-  void initializeDomainAlgorithms();
-  void initializeMappingOfOriginalGridSource();
-
-  void selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
-  void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
-  void selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
-  void setUpGrid(int elementPositionInGrid, ETranformationType transType);
-  void computeFinalTransformationMapping();
-  void computeTransformationFromOriginalGridSource(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
-  void updateFinalGridDestination();
-
-private:
-  //! Grid source on transformation
-  CGrid* gridSource_;
-
-  //! Grid destination on transformation
-  CGrid* gridDestination_;
-
-  //! The grid source of the first transformation (original grid source)
-  CGrid* originalGridSource_;
-
-  //! Grid source dimension size
-  std::vector<int> gridSourceDimensionSize_;
-
-  //! Grid destination dimension size
-  std::vector<int> gridDestinationDimensionSize_;
-
-private:
-  typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
-  //! List of algorithm types and their order
-  ListAlgoType listAlgos_;
-
-  // Mapping between position of an element in grid and its transformation (if any)
-  std::list<CGenericAlgorithmTransformation*> algoTransformation_;
-
-  //! Mapping of (grid) global index representing tranformation.
-  std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource_;
-
-  //! Local index of data to send from grid source
-  std::map<int, CArray<int,1>* > localIndexToSendFromGridSource_;
-
-  //! Local index of data to receive on grid destination
-  std::map<int, std::vector<CArray<int,1>* > > localIndexToReceiveOnGridDest_;
-
-  //! Position of axis and domain in grid
-  std::map<int, int> elementPosition2AxisPositionInGrid_, elementPosition2DomainPositionInGrid_;
-
-  //! (Grid) Global index of grid source
-  CArray<size_t,1>* globalIndexOfCurrentGridSource_;
-  CArray<size_t,1>* globalIndexOfOriginalGridSource_;
-};
-
-}
-#endif // __XIOS_GRID_TRANSFORMATION_HPP__
Index: XIOS/trunk/src/filter/transformation_mapping.cpp
===================================================================
--- XIOS/trunk/src/filter/transformation_mapping.cpp	(revision 623)
+++ 	(revision )
@@ -1,183 +1,0 @@
-/*!
-   \file transformation_mapping.cpp
-   \author Ha NGUYEN
-   \since 14 May 2015
-   \date 09 June 2015
-
-   \brief Take charge of communication among clients to exchange transformed data.
- */
-
-#include "transformation_mapping.hpp"
-#include <boost/unordered_map.hpp>
-#include "context.hpp"
-#include "context_client.hpp"
-#include "distribution_client.hpp"
-
-namespace xios {
-
-CTransformationMapping::CTransformationMapping(CGrid* destination, CGrid* source)
-  : gridSource_(source), gridDestination_(destination)
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client=context->client;
-  int clientRank = client->clientRank;
-
-  CDistributionClient distributionClientSrc(client->clientRank, gridSource_);
-
-  const CArray<size_t,1>& globalIndexGridSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
-  boost::unordered_map<size_t,int> globalIndexOfServer;
-  int globalIndexSize = globalIndexGridSrc.numElements();
-  for (int idx = 0; idx < globalIndexSize; ++idx)
-  {
-    globalIndexOfServer[globalIndexGridSrc(idx)] = clientRank;
-  }
-
-  std::cout << "global index grid src " << globalIndexGridSrc << std::endl;
-  gridIndexClientClientMapping_ = new CClientServerMappingDistributed(globalIndexOfServer,
-                                                                      client->intraComm,
-                                                                      true);
-}
-
-CTransformationMapping::~CTransformationMapping()
-{
-  if (0 != gridIndexClientClientMapping_) delete gridIndexClientClientMapping_;
-}
-
-/*!
-  Suppose that we have transformations between two grids, which are represented in form of mapping between global indexes of these two grids,
-this function tries to find out which clients a client needs to send and receive these global indexes to accomplish the transformations.
-  The grid destination is the grid whose global indexes demande global indexes from the grid source
-  Grid destination and grid source are also distributed among clients but in different manners.
-  \param [in] globaIndexMapFromDestToSource mapping representing the transformations
-*/
-void CTransformationMapping::computeTransformationMapping(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource)
-{
-  CContext* context = CContext::getCurrent();
-  CContextClient* client=context->client;
-
-  int numMappingPoints = 0;
-  std::map<size_t, std::set<size_t> >::const_iterator itbMap = globaIndexMapFromDestToSource.begin(), itMap,
-                                                      iteMap = globaIndexMapFromDestToSource.end();
-  for (itMap = itbMap; itMap != iteMap; ++itMap)
-  {
-    numMappingPoints += (itMap->second).size();
-  }
-
-  // All global indexes of a client on grid destination
-  CArray<size_t,1> globalIndexMap(numMappingPoints);
-  // Not only one index on grid destination can demande two indexes from grid source
-  // but an index on grid destination have to be sent to two indexes of grid destination
-  std::map<size_t, std::vector<size_t> > globalIndexMapFromSrcToDest;
-  std::set<size_t>::const_iterator itbSet, itSet, iteSet;
-  int idx = 0;
-  for (itMap = itbMap; itMap != iteMap; ++itMap)
-  {
-    itbSet = (itMap->second).begin();
-    iteSet = (itMap->second).end();
-    for (itSet = itbSet; itSet != iteSet; ++itSet)
-    {
-      globalIndexMap(idx) = *itSet;
-      globalIndexMapFromSrcToDest[*itSet].push_back(itMap->first);
-      ++idx;
-    }
-  }
-
-  // Find out on which clients the necessary indexes of grid source are.
-  gridIndexClientClientMapping_->computeServerIndexMapping(globalIndexMap);
-  const std::map<int, std::vector<size_t> >& globalIndexSentFromGridSource = gridIndexClientClientMapping_->getGlobalIndexOnServer();
-  std::map<int, std::vector<size_t> >::const_iterator itbMapSrc = globalIndexSentFromGridSource.begin(), itMapSrc,
-                                                      iteMapSrc = globalIndexSentFromGridSource.end();
-  std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc)
-  {
-    int sourceRank = itMapSrc->first;
-    itbVec = (itMapSrc->second).begin();
-    iteVec = (itMapSrc->second).end();
-    for (itVec = itbVec; itVec != iteVec; ++itVec)
-    {
-       (globalIndexReceivedOnGridDestMapping_[sourceRank]).push_back(globalIndexMapFromSrcToDest[*itVec]);
-    }
-  }
-
-  // Inform client about the destination to which it needs to send global indexes
-  int nbClient = client->clientSize;
-  int* sendBuff = new int[nbClient];
-  int* recvBuff = new int[nbClient];
-  for (int i = 0; i < nbClient; ++i) sendBuff[i] = 0;
-
-  // First of all, inform the number of destination a client needs to send global index
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc) sendBuff[itMapSrc->first] = 1;
-  MPI_Allreduce(sendBuff, recvBuff, nbClient, MPI_INT, MPI_SUM, client->intraComm);
-  int numClientToReceive = recvBuff[client->clientRank];
-
-  // Then specify the size of receiving buffer, because we use synch send/receive so only necessary to know maximum size
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc) sendBuff[itMapSrc->first] = (itMapSrc->second).size();
-  MPI_Allreduce(sendBuff, recvBuff, nbClient, MPI_INT, MPI_MAX, client->intraComm);
-
-  int buffSize = recvBuff[client->clientRank];
-  unsigned long* recvBuffGlobalIndex;
-  if (0 != buffSize) recvBuffGlobalIndex = new unsigned long [buffSize];
-
-  // Inform all "source clients" about index that they need to send
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc)
-  {
-    MPI_Request request;
-    unsigned long* sendPtr = const_cast<unsigned long*>(&(itMapSrc->second)[0]);
-    MPI_Isend(sendPtr,
-              (itMapSrc->second).size(),
-              MPI_UNSIGNED_LONG,
-              itMapSrc->first,
-              11,
-              client->intraComm,
-              &request);
-  }
-
-  // Now all the "source clients" try listening messages from other "destination clients"
-  int numClientReceived = 0;  // number of client to which data has been already sent
-  int countBuff;
-  while (numClientReceived < numClientToReceive)
-  {
-    MPI_Status status;
-    MPI_Recv(recvBuffGlobalIndex,
-             buffSize,
-             MPI_UNSIGNED_LONG,
-             MPI_ANY_SOURCE,
-             11,
-             client->intraComm,
-             &status);
-
-    MPI_Get_count(&status, MPI_UNSIGNED_LONG, &countBuff);
-    int clientDestRank = status.MPI_SOURCE;
-    for (int idx = 0; idx < countBuff; ++idx)
-    {
-      globalIndexSendToGridDestMapping_[clientDestRank].push_back(recvBuffGlobalIndex[idx]);
-    }
-    ++numClientReceived;
-  }
-
-  delete [] sendBuff;
-  delete [] recvBuff;
-  if (0 != buffSize) delete [] recvBuffGlobalIndex;
-}
-
-/*!
-  Return (grid) global index on grid destination. This mapping contains the rank of client source (that sends info to grid destination)
-and the corresponding global index to write on grid destination.
-  \return global index mapping to receive on grid destination
-*/
-const std::map<int,std::vector<std::vector<size_t> > >& CTransformationMapping::getGlobalIndexReceivedOnGridDestMapping() const
-{
-  return globalIndexReceivedOnGridDestMapping_;
-}
-
-/*!
-  Return (grid) global index on grid source. This mapping contains the rank of client destination (which receives transformation info) and
-the corresponding global index to send
-  \return global index mapping to send on grid source
-*/
-const std::map<int,std::vector<size_t> >& CTransformationMapping::getGlobalIndexSendToGridDestMapping() const
-{
-  return globalIndexSendToGridDestMapping_;
-}
-
-}
Index: XIOS/trunk/src/filter/transformation_mapping.hpp
===================================================================
--- XIOS/trunk/src/filter/transformation_mapping.hpp	(revision 623)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*!
-   \file transformation_mapping.hpp
-   \author Ha NGUYEN
-   \since 14 May 2015
-   \date 09 June 2015
-
-   \brief Take charge of communication among clients to exchange transformed data.
- */
-#ifndef __XIOS_TRANSFORMATION_MAPPING_HPP__
-#define __XIOS_TRANSFORMATION_MAPPING_HPP__
-
-#include <map>
-#include <set>
-#include "grid.hpp"
-#include "array_new.hpp"
-#include "client_server_mapping_distributed.hpp"
-
-namespace xios {
-
-/*!
-  \class CTransformationMapping
-  This class is in charge of transfer the global index form grid from grid source to grid destination in a rather generic way.
-In order to make a transformation, the grid destination will make a request to grid source about the global indexes which it needs.
-The same discovering algorithm as the case of client-server is applied to find the corresponding client which contains the demanding global index.
-*/
-class CTransformationMapping
-{
-public:
-  /** Default constructor */
-  CTransformationMapping(CGrid* destination, CGrid* source);
-  ~CTransformationMapping();
-
-  void computeTransformationMapping(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
-  const std::map<int,std::vector<std::vector<size_t> > >& getGlobalIndexReceivedOnGridDestMapping() const;
-  const std::map<int,std::vector<size_t> >& getGlobalIndexSendToGridDestMapping() const;
-
-protected:
-  CGrid* gridSource_;  // Grid source
-  CGrid* gridDestination_; // Grid destination demande the necessary global index from grid source
-
-  //! Global index mapping of grid source and grid destination between two clients
-  CClientServerMappingDistributed* gridIndexClientClientMapping_;
-
-  //! Mapping of client rank of grid source and global index received in grid destination
-  std::map<int,std::vector<std::vector<size_t> > > globalIndexReceivedOnGridDestMapping_;
-
-  //! Mapping of client rank of grid destination and global index to send from grid source
-  std::map<int,std::vector<size_t> > globalIndexSendToGridDestMapping_;
-
-};
-
-}
-#endif // __XIOS_TRANSFORMATION_MAPPING_HPP__
Index: XIOS/trunk/src/node/axis.cpp
===================================================================
--- XIOS/trunk/src/node/axis.cpp	(revision 623)
+++ XIOS/trunk/src/node/axis.cpp	(revision 624)
@@ -95,5 +95,5 @@
       }
       else this->ni.setValue(size);
-      std::cout <<  "value " <<  value <<  std::endl;
+
 //      StdSize true_size = value.numElements();
 //      if (this->ni.getValue() != true_size)
@@ -135,25 +135,25 @@
    }
 
-   void CAxis::checkZoom(void)
-   {
-      StdSize zoom_begin,zoom_end, zoom_size, axisSize;
-
-      zoom_begin = this->zoom_begin.isEmpty() ? 0 : this->zoom_begin.getValue();
-      zoom_size  = this->zoom_size.isEmpty() ? size.getValue() : this->zoom_size.getValue();
-      zoom_end   = this->zoom_end.isEmpty() ? (size.getValue() - 1) : this->zoom_end.getValue();
-
-      if (this->zoom_begin.isEmpty()) zoom_begin = zoom_end - zoom_size + 1;
-      if (this->zoom_end.isEmpty()) zoom_end = zoom_begin + zoom_size - 1;
-      if (this->zoom_size.isEmpty()) zoom_size = zoom_end - zoom_begin + 1;
-      axisSize = size.getValue();
-
-      if ( (zoom_begin < 0) || (zoom_begin > axisSize-1) || (zoom_end<0) || (zoom_end>axisSize-1) || (zoom_size<1) || (zoom_size>axisSize) || (zoom_begin>zoom_end))
-        ERROR("CAxis::checkAttributes(void)",
-              << "One or more attributes among <zoom_begin>, <zoom_end>, <zoom_size> of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
-
-      this->zoom_begin.setValue(zoom_begin);
-      this->zoom_end.setValue(zoom_end);
-      this->zoom_size.setValue(zoom_size);
-   }
+//   void CAxis::checkZoom(void)
+//   {
+//      StdSize zoom_begin,zoom_end, zoom_size, axisSize;
+//
+//      zoom_begin = (this->zoom_begin.isEmpty()) ?  0 : this->zoom_begin.getValue() ;
+//      zoom_size  = (this->zoom_size.isEmpty()) ?  size.getValue() : this->zoom_size.getValue() ;
+//      zoom_end   = (this->zoom_end.isEmpty()) ?  (size.getValue() - 1) : this->zoom_end.getValue() ;
+//
+//      if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1 ;
+//      if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1 ;
+//      if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1 ;
+//      axisSize = size.getValue();
+//
+//      if ( (zoom_begin < 0) || (zoom_begin > axisSize-1) || (zoom_end<0) || (zoom_end>axisSize-1) || (zoom_size<1) || (zoom_size>axisSize) || (zoom_begin>zoom_end))
+//        ERROR("CAxis::checkAttributes(void)",
+//              << "One or more attributes among <zoom_begin>, <zoom_end>, <zoom_size> of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] are not well specified");
+//
+//      this->zoom_begin.setValue(zoom_begin) ;
+//      this->zoom_end.setValue(zoom_end) ;
+//      this->zoom_size.setValue(zoom_size) ;
+//   }
 
    void CAxis::checkMask()
Index: XIOS/trunk/src/node/axis.hpp
===================================================================
--- XIOS/trunk/src/node/axis.hpp	(revision 623)
+++ XIOS/trunk/src/node/axis.hpp	(revision 624)
@@ -107,5 +107,5 @@
          void checkData();
          void checkMask();
-         void checkZoom();
+//         void checkZoom();
          void checkTransformations();
          void computeServerIndex(const std::vector<int>& globalDim, int orderPositionInGrid,
Index: XIOS/trunk/src/node/field.cpp
===================================================================
--- XIOS/trunk/src/node/field.cpp	(revision 623)
+++ XIOS/trunk/src/node/field.cpp	(revision 624)
@@ -13,6 +13,4 @@
 #include "context_server.hpp"
 #include <set>
-#include "axis_filter.hpp"
-#include "invert_algorithm.hpp"
 
 namespace xios{
@@ -29,7 +27,7 @@
       , foperation(), hasInstantData(false), hasExpression(false)
       , active(false) , hasOutputFile(false),hasFieldOut(false), slotUpdateDate(NULL)
-      , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false), filter(0)
+      , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false)
       , isReadDataRequestPending(false)
-      , filterSources_(), algorithms_()
+      , filterSources_()
       { setVirtualVariableGroup(); }
 
@@ -43,7 +41,7 @@
       , foperation(), hasInstantData(false), hasExpression(false)
       , active(false), hasOutputFile(false), hasFieldOut(false), slotUpdateDate(NULL)
-      , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false), filter(0)
+      , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false)
       , isReadDataRequestPending(false)
-      , filterSources_(), algorithms_()
+      , filterSources_()
    { setVirtualVariableGroup(); }
 
@@ -55,5 +53,4 @@
       if (hasExpression) delete expression;
       if (slotUpdateDate != NULL) delete slotUpdateDate;
-      if (0 != filter) delete filter;
 
    }
@@ -177,6 +174,4 @@
             int rank=(*it).first ;
             CArray<int,1>& index = *(it->second) ;
-                       std::cout << "rank " << index << std::endl;
-                       std::cout << "data " << data << std::endl;
             CArray<double,1> data_tmp(index.numElements()) ;
             for(int n=0;n<data_tmp.numElements();n++) data_tmp(n)=data(index(n)) ;
@@ -784,5 +779,4 @@
            fieldRef->addReference(this);
            fieldRef->solveGridDomainAxisRef(false);
-//           fieldRef->solveCheckMaskIndex(false);
            break;
          }
@@ -798,5 +792,4 @@
          fieldRef->addReference(this);
          fieldRef->solveGridDomainAxisRef(false);
-//         fieldRef->solveCheckMaskIndex(false);
        }
 
@@ -826,5 +819,5 @@
           {
              const std::map<int, CArray<int,1>* >& localIndexToSend = (*itFilterSrc)->grid->getTransformations()->getLocalIndexToSendFromGridSource();
-             const std::map<int, std::vector<CArray<int,1>* > > localIndexToReceive = (*itFilterSrc)->grid->getTransformations()->getLocalIndexToReceiveOnGridDest();
+             const std::map<int, std::vector<CArray<int,1>* > >& localIndexToReceive = (*itFilterSrc)->grid->getTransformations()->getLocalIndexToReceiveOnGridDest();
 
              sendAndReceiveTransformedData(localIndexToSend, dataToSend,
@@ -857,5 +850,4 @@
        CArray<int,1>* localIndex_p = itSend->second;
        int countSize = localIndex_p->numElements();
-       std::cout << "Data Source " <<  dataSrc <<  std::endl;
        for (int idx = 0; idx < countSize; ++idx)
        {
@@ -888,5 +880,4 @@
          }
        }
-       std::cout << "Data Destination " <<  dataDest <<  std::endl;
      }
 
Index: XIOS/trunk/src/node/field.hpp
===================================================================
--- XIOS/trunk/src/node/field.hpp	(revision 623)
+++ XIOS/trunk/src/node/field.hpp	(revision 624)
@@ -15,5 +15,4 @@
 #include "expr_node.hpp"
 #include "declare_ref_func.hpp"
-#include "generic_filter.hpp"
 #include "transformation_enum.hpp"
 
@@ -231,5 +230,4 @@
          bool isReadDataRequestPending;
          std::vector<CField*> filterSources_;
-         std::vector<CGenericAlgorithm*> algorithms_;
          DECLARE_REF_FUNC(Field,field)
 
Index: XIOS/trunk/src/node/field_impl.hpp
===================================================================
--- XIOS/trunk/src/node/field_impl.hpp	(revision 623)
+++ XIOS/trunk/src/node/field_impl.hpp	(revision 624)
@@ -49,8 +49,7 @@
         {
           (*it)->setData(_data);
-          if (hasOutputFile || hasFieldOut) updateData(_data);
-        }
-      }
-
+        }
+      }
+      if (hasOutputFile || hasFieldOut) updateData(_data);
     }
   }
Index: XIOS/trunk/src/node/grid.cpp
===================================================================
--- XIOS/trunk/src/node/grid.cpp	(revision 623)
+++ XIOS/trunk/src/node/grid.cpp	(revision 624)
@@ -772,11 +772,12 @@
   bool CGrid::doGridHaveDataToWrite()
   {
-    size_t ssize = 0;
-    for (map<int, CArray<size_t, 1>* >::const_iterator it = outIndexFromClient.begin();
-                                                       it != outIndexFromClient.end(); ++it)
-    {
-      ssize += (it->second)->numElements();
-    }
-    return (0 != ssize);
+//    size_t ssize = 0;
+//    for (map<int, CArray<size_t, 1>* >::const_iterator it = outIndexFromClient.begin();
+//                                                       it != outIndexFromClient.end(); ++it)
+//    {
+//      ssize += (it->second)->numElements();
+//    }
+//    return (0 != ssize);
+     return (0 != writtenDataSize_);
   }
 
Index: XIOS/trunk/src/output/nc4_data_output.cpp
===================================================================
--- XIOS/trunk/src/output/nc4_data_output.cpp	(revision 623)
+++ XIOS/trunk/src/output/nc4_data_output.cpp	(revision 624)
@@ -1362,5 +1362,4 @@
            if (!field->prec.isEmpty() && field->prec==2) fieldData=round(fieldData) ;
 
-           std::cout << "fieldData "<< fieldData << std::endl;
            switch (SuperClass::type)
            {
Index: XIOS/trunk/src/test/test_client.f90
===================================================================
--- XIOS/trunk/src/test/test_client.f90	(revision 623)
+++ XIOS/trunk/src/test/test_client.f90	(revision 624)
@@ -88,5 +88,5 @@
   CALL xios_get_handle("output",file_hdl)
   CALL xios_add_child(file_hdl,field_hdl)
-  CALL xios_set_attr(field_hdl,field_ref="field_A",name="field_C")
+  CALL xios_set_attr(field_hdl,field_ref="field_A_zoom",name="field_C")
 
   dtime%second = 3600
Index: XIOS/trunk/src/test/test_complete.f90
===================================================================
--- XIOS/trunk/src/test/test_complete.f90	(revision 623)
+++ XIOS/trunk/src/test/test_complete.f90	(revision 624)
@@ -96,5 +96,5 @@
   CALL xios_set_domain_attr("domain_atm_zoom",data_dim=2, data_ibegin=-1, data_ni=ni+2, data_jbegin=-2, data_nj=nj+4)
   CALL xios_set_domain_attr("domain_atm_zoom",lonvalue=RESHAPE(lon,(/ni*nj/)),latvalue=RESHAPE(lat,(/ni*nj/)))
-  CALL xios_set_domain_attr("domain_atm_zoom",zoom_ibegin=39, zoom_ni=20, zoom_jbegin=39, zoom_nj=5)
+!  CALL xios_set_domain_attr("domain_atm_zoom",zoom_ibegin=39, zoom_ni=20, zoom_jbegin=39, zoom_nj=5)
 
 !!! Activation du groupe field_definition
@@ -109,5 +109,5 @@
 !!! Heritage des attributs d un autre champ
 
-  CALL xios_set_attr(field_hdl,field_ref="field_A_atm",name="field_B_atm")
+  CALL xios_set_attr(field_hdl,field_ref="field_A_atm_zoom",name="field_B_atm")
 
 !!! Affectation de ce nouveau champ au fichier avec un nouveau nom
Index: XIOS/trunk/src/test/test_new_features.f90
===================================================================
--- XIOS/trunk/src/test/test_new_features.f90	(revision 623)
+++ XIOS/trunk/src/test/test_new_features.f90	(revision 624)
@@ -15,7 +15,7 @@
   CHARACTER(len=15) :: calendar_type
   TYPE(xios_context) :: ctx_hdl
-  INTEGER,PARAMETER :: ni_glo=5
-  INTEGER,PARAMETER :: nj_glo=5
-  INTEGER,PARAMETER :: llm=2
+  INTEGER,PARAMETER :: ni_glo=100
+  INTEGER,PARAMETER :: nj_glo=100
+  INTEGER,PARAMETER :: llm=5
   DOUBLE PRECISION  :: lval(llm)=1, tsTemp
   TYPE(xios_field) :: field_hdl
@@ -68,10 +68,10 @@
   axisBegin = 0
   nAxis = llm
-  DO n=0, size -1
-    nAxis = llm/size
-    IF (n<MOD(llm,size)) nAxis=nAxis+1
-    IF (n==rank) exit
-    axisBegin=axisBegin+nAxis
-  ENDDO
+!  DO n=0, size -1
+!    nAxis = llm/size
+!    IF (n<MOD(llm,size)) nAxis=nAxis+1
+!    IF (n==rank) exit
+!    axisBegin=axisBegin+nAxis
+!  ENDDO
   axisEnd=axisBegin+nAxis-1
 
@@ -117,11 +117,11 @@
   CALL xios_set_fieldgroup_attr("field_definition",enabled=.TRUE.)
 
-!  CALL xios_get_handle("field_definition",fieldgroup_hdl)
-!  CALL xios_add_child(fieldgroup_hdl,field_hdl,"field_B")
-!  CALL xios_set_attr(field_hdl,field_ref="field_A",name="field_B")
-!
-!  CALL xios_get_handle("output",file_hdl)
-!  CALL xios_add_child(file_hdl,field_hdl)
-!  CALL xios_set_attr(field_hdl,field_ref="field_A",name="field_C")
+  CALL xios_get_handle("field_definition",fieldgroup_hdl)
+  CALL xios_add_child(fieldgroup_hdl,field_hdl,"field_B")
+  CALL xios_set_attr(field_hdl,field_ref="field_A",name="field_B")
+
+  CALL xios_get_handle("output",file_hdl)
+  CALL xios_add_child(file_hdl,field_hdl)
+  CALL xios_set_attr(field_hdl,field_ref="field_A",name="field_C")
 !
 !  CALL xios_get_handle("output_All_Axis",file_hdl)
Index: XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 624)
+++ XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 624)
@@ -0,0 +1,43 @@
+/*!
+   \file axis_algorithm_inverse.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Algorithm for inversing an axis..
+ */
+#include "axis_algorithm_inverse.hpp"
+
+namespace xios {
+
+CAxisAlgorithmInverse::CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource)
+ : CAxisAlgorithmTransformation(axisDestination, axisSource)
+{
+  if (axisDestination->size.getValue() != axisSource->size.getValue())
+  {
+    ERROR("CAxisAlgorithmInverse::CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource)",
+           << "Two axis have different size"
+           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
+           << "Size of axis destionation " <<axisDestination->getId() << " is " << axisDestination->size.getValue());
+  }
+
+
+  axisDestGlobalSize_ = axisDestination->size.getValue();
+  int niDest = axisDestination->ni.getValue();
+  int ibeginDest = axisDestination->ibegin.getValue();
+
+  for (int idx = 0; idx < niDest; ++idx)
+    if ((axisDestination->mask)(idx)) axisDestGlobalIndex_.push_back(ibeginDest+idx);
+  this->computeIndexSourceMapping();
+}
+
+void CAxisAlgorithmInverse::computeIndexSourceMapping()
+{
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+
+  int globalIndexSize = axisDestGlobalIndex_.size();
+  for (int idx = 0; idx < globalIndexSize; ++idx)
+    transMap[axisDestGlobalIndex_[idx]].push_back(axisDestGlobalSize_-axisDestGlobalIndex_[idx]-1);
+}
+
+}
Index: XIOS/trunk/src/transformation/axis_algorithm_inverse.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_inverse.hpp	(revision 624)
+++ XIOS/trunk/src/transformation/axis_algorithm_inverse.hpp	(revision 624)
@@ -0,0 +1,31 @@
+/*!
+   \file axis_algorithm_inverse.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Algorithm for inversing an axis..
+ */
+#ifndef __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
+#define __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
+
+#include "axis_algorithm_transformation.hpp"
+#include "axis.hpp"
+
+namespace xios {
+/*!
+  \class CAxisAlgorithmInverse
+  Inversing an axis
+*/
+class CAxisAlgorithmInverse : public CAxisAlgorithmTransformation
+{
+public:
+  CAxisAlgorithmInverse(CAxis* axisDestination, CAxis* axisSource);
+
+  virtual ~CAxisAlgorithmInverse() {}
+
+  virtual void computeIndexSourceMapping();
+};
+
+}
+#endif // __XIOS_AXIS_ALGORITHM_INVERSE_HPP__
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 624)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 624)
@@ -0,0 +1,149 @@
+/*!
+   \file axis_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Interface for all axis transformation algorithms.
+ */
+
+#include "axis_algorithm_transformation.hpp"
+#include "axis_algorithm_inverse.hpp"
+#include "axis_algorithm_zoom.hpp"
+
+namespace xios {
+
+CAxisAlgorithmTransformation::CAxisAlgorithmTransformation(CAxis* axisDestination, CAxis* axisSource)
+ : CGenericAlgorithmTransformation()
+{
+}
+
+CAxisAlgorithmTransformation::~CAxisAlgorithmTransformation()
+{
+}
+
+void CAxisAlgorithmTransformation::computeIndexSourceMapping()
+{
+}
+
+/*!
+  Compute an array of global index from a global index on a axis
+  \param[in] axisDestGlobalIndex global index on an axis of destination grid
+  \param[in] axisSrcGlobalIndex global index on an axis of source grid (which are needed by one index on axis destination)
+  \param[in] axisPositionInGrid position of the axis in the grid
+  \param[in] gridDestGlobalDim dimension size of destination grid (it should share the same size for all dimension, maybe except the axis on which transformation is performed)
+  \param[in] globalIndexGridDestSendToServer global index of destination grid which are to be sent to server(s)
+  \param[in/out] globalIndexDestGrid array of global index (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
+  \param[in/out] globalIndexSrcGrid array of global index of source grid (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
+*/
+void CAxisAlgorithmTransformation::computeGlobalIndexFromGlobalIndexElement(int axisDestGlobalIndex,
+                                                                          const std::vector<int>& axisSrcGlobalIndex,
+                                                                          int axisPositionInGrid,
+                                                                          const std::vector<int>& gridDestGlobalDim,
+                                                                          const CArray<size_t,1>& globalIndexGridDestSendToServer,
+                                                                          CArray<size_t,1>& globalIndexDestGrid,
+                                                                          std::vector<CArray<size_t,1> >& globalIndexSrcGrid)
+{
+  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];
+  }
+
+  CArray<size_t,1>::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;
+    }
+
+    itArr = std::find(itbArr, iteArr, globIndex);
+    if (iteArr != itArr) ++realGlobalIndexSize;
+    ++idxLoop[0];
+    ++idx;
+  }
+
+  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
+    globalIndexDestGrid.resize(realGlobalIndexSize);
+
+  if (axisSrcGlobalIndex.size() != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(axisSrcGlobalIndex.size());
+  for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
+    if (globalIndexSrcGrid[i].numElements() != realGlobalIndexSize)
+      globalIndexSrcGrid[i].resize(realGlobalIndexSize);
+
+
+  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;
+    }
+
+    itArr = std::find(itbArr, iteArr, globIndex);
+    if (iteArr != itArr)
+    {
+      globalIndexDestGrid(realGlobalIndex) = globIndex;
+      for (int i = 0; i < globalIndexSrcGrid.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[i])(realGlobalIndex) = globIndex;
+      }
+      ++realGlobalIndex;
+    }
+
+    ++idxLoop[0];
+    ++idx;
+  }
+}
+}
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 624)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 624)
@@ -0,0 +1,48 @@
+/*!
+   \file axis_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Interface for all axis transformation algorithms.
+ */
+#ifndef __XIOS_AXIS_ALGORITHM_TRANSFORMATION_HPP__
+#define __XIOS_AXIS_ALGORITHM_TRANSFORMATION_HPP__
+
+#include "generic_algorithm_transformation.hpp"
+#include "axis.hpp"
+
+namespace xios {
+
+/*!
+  \class CAxisAlgorithmTransformation
+  Algorithms for axis.
+*/
+class CAxisAlgorithmTransformation : public virtual CGenericAlgorithmTransformation
+{
+public:
+  CAxisAlgorithmTransformation(CAxis* axisDestination, CAxis* axisSource);
+
+  virtual ~CAxisAlgorithmTransformation();
+
+protected:
+  virtual void computeGlobalIndexFromGlobalIndexElement(int axisDestGlobalIndex,
+                                                        const std::vector<int>& axisSrcGlobalIndex,
+                                                        int axisPositionInGrid,
+                                                        const std::vector<int>& gridDestGlobalDim,
+                                                        const CArray<size_t,1>& globalIndexGridDestSendToServer,
+                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        std::vector<CArray<size_t,1> >& globalIndexSrcGrid);
+  void computeIndexSourceMapping();
+
+protected:
+  //! Global index of an axis on grid destination
+  std::vector<int> axisDestGlobalIndex_;
+
+  //! Size of
+  int axisDestGlobalSize_;
+
+};
+
+}
+#endif // __XIOS_AXIS_ALGORITHM_TRANSFORMATION_HPP__
Index: XIOS/trunk/src/transformation/axis_algorithm_zoom.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_zoom.cpp	(revision 624)
+++ XIOS/trunk/src/transformation/axis_algorithm_zoom.cpp	(revision 624)
@@ -0,0 +1,85 @@
+/*!
+   \file axis_algorithm_zoom.cpp
+   \author Ha NGUYEN
+   \since 03 June 2015
+   \date 12 June 2015
+
+   \brief Algorithm for zooming on an axis.
+ */
+#include "axis_algorithm_zoom.hpp"
+
+namespace xios {
+
+CAxisAlgorithmZoom::CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)
+: CAxisAlgorithmTransformation(axisDestination, axisSource), axisDest_(axisDestination), axisSrc_(axisSource)
+{
+  zoomAxis->checkValid(axisSource);
+  zoomBegin_ = zoomAxis->zoom_begin.getValue();
+  zoomEnd_   = zoomAxis->zoom_end.getValue();
+  zoomSize_  = zoomAxis->zoom_size.getValue();
+
+  if (zoomSize_ > axisSource->size.getValue())
+  {
+    ERROR("CAxisAlgorithmZoom::CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis)",
+           << "Zoom size is greater than size of axis source"
+           << "Size of axis source " <<axisSource->getId() << " is " << axisSource->size.getValue()  << std::endl
+           << "Zoom size is " << zoomSize_ );
+  }
+
+  computeIndexSourceMapping();
+}
+
+/*!
+  Compute the index mapping between axis on grid source and one on grid destination
+*/
+void CAxisAlgorithmZoom::computeIndexSourceMapping()
+{
+  StdSize niSource = axisSrc_->ni.getValue();
+  StdSize ibeginSource = axisSrc_->ibegin.getValue();
+  StdSize iendSource = ibeginSource + niSource - 1;
+
+  StdSize ibegin = std::max(ibeginSource, zoomBegin_);
+  StdSize iend = std::min(iendSource, zoomEnd_);
+  StdSize ni = iend + 1 - ibegin;
+  if (iend < ibegin) ni = 0;
+
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  for (StdSize idx = 0; idx < ni; ++idx)
+  {
+    transMap[ibegin+idx].push_back(ibegin+idx);
+  }
+
+  updateZoom();
+  updateAxisDestinationMask();
+}
+
+/*!
+  After a zoom on axis, it should be certain that (global) zoom begin and (global) zoom size are updated
+*/
+void CAxisAlgorithmZoom::updateZoom()
+{
+  axisDest_->global_zoom_begin = zoomBegin_;
+  axisDest_->global_zoom_size  = zoomSize_;
+}
+
+/*!
+  Update mask on axis
+  Because only zoomed region on axis is not masked, the remaining must be masked to make sure
+correct index be extracted
+*/
+void CAxisAlgorithmZoom::updateAxisDestinationMask()
+{
+  StdSize niMask = axisDest_->mask.numElements();
+  StdSize iBeginMask = axisDest_->ibegin.getValue();
+  StdSize globalIndexMask = 0;
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  std::map<int, std::vector<int> >::const_iterator ite = (transMap).end();
+  for (StdSize idx = 0; idx < niMask; ++idx)
+  {
+    globalIndexMask = iBeginMask + idx;
+    if (transMap.find(globalIndexMask) == ite)
+      (axisDest_->mask)(idx) = false;
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/axis_algorithm_zoom.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_zoom.hpp	(revision 624)
+++ XIOS/trunk/src/transformation/axis_algorithm_zoom.hpp	(revision 624)
@@ -0,0 +1,55 @@
+/*!
+   \file axis_algorithm_zoom.hpp
+   \author Ha NGUYEN
+   \since 03 June 2015
+   \date 12 June 2015
+
+   \brief Algorithm for zooming on an axis.
+ */
+#ifndef __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
+#define __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
+
+#include "axis_algorithm_transformation.hpp"
+#include "axis.hpp"
+#include "zoom_axis.hpp"
+
+namespace xios {
+/*!
+  \class CAxisAlgorithmZoom
+  Implementing zoom on axis
+  A zoomed region can be considered as region that isnt masked.
+  Only this zoomed region is extracted to write on Netcdf.
+*/
+class CAxisAlgorithmZoom : public CAxisAlgorithmTransformation
+{
+public:
+  CAxisAlgorithmZoom(CAxis* axisDestination, CAxis* axisSource, CZoomAxis* zoomAxis);
+
+  virtual ~CAxisAlgorithmZoom() {}
+
+  virtual void computeIndexSourceMapping();
+
+private:
+  void updateAxisDestinationMask();
+  void updateZoom();
+
+private:
+  //! Global zoom begin on axis
+  StdSize zoomBegin_;
+
+  //! Global zoom end on axis
+  StdSize zoomEnd_;
+
+  //! Global zoom size on axis
+  StdSize zoomSize_;
+
+private:
+  //! Axis on grid destination
+  CAxis* axisDest_;
+
+  //! Axis on grid source
+  CAxis* axisSrc_;
+};
+
+}
+#endif // __XIOS_AXIS_ALGORITHM_ZOOM_HPP__
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 624)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 624)
@@ -0,0 +1,59 @@
+/*!
+   \file generic_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Interface for all transformation algorithms.
+ */
+#include "generic_algorithm_transformation.hpp"
+
+namespace xios {
+
+CGenericAlgorithmTransformation::CGenericAlgorithmTransformation()
+ : transformationMapping_()
+{
+}
+
+/*!
+  This function computes the global indexes of grid source, which the grid destination is in demand.
+  \param[in] elementPositionInGrid position of an element in a grid .E.g: if grid is composed of domain and axis (in order),
+                then position of axis in grid is 2 (since a domain is considered to contain 2 elements (axis)
+  \param[in] gridDestGlobalDim global size of each dimension of grid source (all dimension must have the same size except of the one on which transformation is performed)
+  \param[in] globalIndexGridDestSendToServer global index of grid destination on the current client to send to server
+  \param[in/out] globaIndexMapFromDestToSource mapping between transformed global index of grid destination
+                    and the demanded global index of grid source
+*/
+void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
+                                                             const std::vector<int>& gridDestGlobalDim,
+                                                             const CArray<size_t,1>& globalIndexGridDestSendToServer,
+                                                             std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource)
+{
+  std::map<int, std::vector<int> >::const_iterator itbTransMap = transformationMapping_.begin(),
+                                                   itTransMap = itbTransMap,
+                                                   iteTransMap = transformationMapping_.end();
+  std::vector<int>::const_iterator itbVec, itVec, iteVec;
+  std::vector<CArray<size_t,1> > globalIndexSrcGrid; //((itTransMap->second).size());
+  CArray<size_t,1> globalIndexDestGrid;
+  for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap)
+  {
+
+    this->computeGlobalIndexFromGlobalIndexElement(itTransMap->first,
+                                                   itTransMap->second,
+                                                   elementPositionInGrid,
+                                                   gridDestGlobalDim,
+                                                   globalIndexGridDestSendToServer,
+                                                   globalIndexDestGrid,
+                                                   globalIndexSrcGrid);
+    size_t globalIndexSize = globalIndexDestGrid.numElements();
+    for (size_t idx = 0; idx < globalIndexSize; ++idx)
+    {
+      for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
+      {
+        globaIndexMapFromDestToSource[globalIndexDestGrid(idx)].insert(globalIndexSrcGrid[i](idx));
+      }
+    }
+  }
+}
+
+}
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 624)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 624)
@@ -0,0 +1,64 @@
+/*!
+   \file generic_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Interface for all transformation algorithms.
+ */
+#ifndef __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__
+#define __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__
+
+#include <map>
+#include <vector>
+#include "array_new.hpp"
+
+namespace xios {
+  /*!
+  \class CGenericAlgorithmTransformation
+  This class defines the interface for all other inherted algorithms class
+  */
+class CGenericAlgorithmTransformation
+{
+public:
+  CGenericAlgorithmTransformation();
+
+  virtual ~CGenericAlgorithmTransformation() {}
+
+  void computeGlobalSourceIndex(int elementPositionInGrid,
+                                const std::vector<int>& gridDestGlobalDim,
+                                const CArray<size_t,1>& globalIndexGridDestSendToServer,
+                                std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
+
+  /*!
+  Compute global index mapping from one element of destination grid to the corresponding element of source grid
+  */
+  virtual void computeIndexSourceMapping() = 0;
+
+protected:
+  /*!
+  Compute an array of global index from a global index on an element
+    \param[in] destGlobalIndex global index on an element of destination grid
+    \param[in] srcGlobalIndex global index(es) on an element of source grid (which are needed by one index on element destination)
+    \param[in] elementPositionInGrid position of the element in the grid (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
+    \param[in] gridDestGlobalDim dimension size of destination grid (it should share the same size for all dimension, maybe except the element on which transformation is performed)
+    \param[in] globalIndexGridDestSendToServer global index of destination grid which are to be sent to server(s)
+    \param[in/out] globalIndexDestGrid array of global index (for 2d grid, this array maybe a line, for 3d, this array may represent a plan). It should be preallocated
+    \param[in/out] globalIndexSrcGrid array of global index of source grid (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
+  */
+  virtual void computeGlobalIndexFromGlobalIndexElement(int destGlobalIndex,
+                                                        const std::vector<int>& srcGlobalIndex,
+                                                        int elementPositionInGrid,
+                                                        const std::vector<int>& gridDestGlobalDim,
+                                                        const CArray<size_t,1>& globalIndexGridDestSendToServer,
+                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        std::vector<CArray<size_t,1> >& globalIndexSrcGrid) = 0;
+
+
+
+protected:
+  std::map<int, std::vector<int> > transformationMapping_;
+};
+
+}
+#endif // __XIOS_GENERIC_ALGORITHM_TRANSFORMATION_HPP__
Index: XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 624)
+++ XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 624)
@@ -0,0 +1,582 @@
+/*!
+   \file grid_transformation.cpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 18 June 2015
+
+   \brief Interface for all transformations.
+ */
+#include "grid_transformation.hpp"
+#include "axis_algorithm_inverse.hpp"
+#include "axis_algorithm_zoom.hpp"
+#include "context.hpp"
+#include "context_client.hpp"
+#include "transformation_mapping.hpp"
+
+#include "axis_algorithm_transformation.hpp"
+
+namespace xios {
+CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)
+: gridSource_(source), gridDestination_(destination), originalGridSource_(source),
+  globalIndexOfCurrentGridSource_(0), globalIndexOfOriginalGridSource_(0)
+{
+  //Verify the compatibity between two grids
+  int numElement = gridDestination_->axis_domain_order.numElements();
+  if (numElement != gridSource_->axis_domain_order.numElements())
+    ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
+       << "Two grids have different number of elements"
+       << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
+       << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
+
+  for (int i = 0; i < numElement; ++i)
+  {
+    if (gridDestination_->axis_domain_order(i) != gridSource_->axis_domain_order(i))
+      ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
+         << "Transformed grid and its grid source have incompatible elements"
+         << "Grid source " <<gridSource_->getId() << std::endl
+         << "Grid destination " <<gridDestination_->getId());
+  }
+
+  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->setAttributes(axisSrcTmp[idx]);
+    axisSrc.push_back(axis);
+  }
+
+  for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
+  {
+    CDomain* domain = CDomain::createDomain();
+    domain->setAttributes(domainSrcTmp[idx]);
+    domainSrc.push_back(domain);
+  }
+
+  gridSource_ = CGrid::createGrid(domainSrc, axisSrc, gridDestination_->axis_domain_order);
+  gridSourceDimensionSize_ = gridSource_->getGlobalDimension();
+  gridDestinationDimensionSize_ = gridDestination_->getGlobalDimension();
+
+  initializeMappingOfOriginalGridSource();
+  initializeAlgorithms();
+}
+
+/*!
+  Initialize the mapping between the first grid source and the original one
+  In a series of transformation, for each step, there is a need to "create" a new grid that plays a role of "temporary" source.
+Because at the end of the series, we need to know about the index mapping between the final grid destination and original grid source,
+for each transformation, we need to make sure that the current "temporary source" maps its global index correctly to the original one.
+*/
+void CGridTransformation::initializeMappingOfOriginalGridSource()
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+
+  CDistributionClient distribution(client->clientRank, originalGridSource_);
+  const CArray<size_t,1>& globalIndexGridDestSendToServer = distribution.getGlobalDataIndexSendToServer();
+
+  globalIndexOfCurrentGridSource_   = new CArray<size_t,1>(globalIndexGridDestSendToServer.numElements());
+  globalIndexOfOriginalGridSource_  = new CArray<size_t,1>(globalIndexGridDestSendToServer.numElements());
+  *globalIndexOfCurrentGridSource_  = globalIndexGridDestSendToServer;
+  *globalIndexOfOriginalGridSource_ = globalIndexGridDestSendToServer;
+}
+
+CGridTransformation::~CGridTransformation()
+{
+  std::list<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
+                                                              ite = algoTransformation_.end();
+  for (it = itb; it != ite; ++it) delete (*it);
+
+  std::map<int, std::vector<CArray<int,1>* > >::const_iterator itMapRecv, iteMapRecv;
+  itMapRecv = localIndexToReceiveOnGridDest_.begin();
+  iteMapRecv = localIndexToReceiveOnGridDest_.end();
+  for (; itMapRecv != iteMapRecv; ++itMapRecv)
+  {
+    int numVec = (itMapRecv->second).size();
+    for (int idx = 0; idx < numVec; ++idx) delete (itMapRecv->second)[idx];
+  }
+
+  std::map<int, CArray<int,1>* >::const_iterator itMap, iteMap;
+  itMap = localIndexToSendFromGridSource_.begin();
+  iteMap = localIndexToSendFromGridSource_.end();
+  for (; itMap != iteMap; ++itMap) delete (itMap->second);
+
+  if (0 != globalIndexOfCurrentGridSource_) delete globalIndexOfCurrentGridSource_;
+  if (0 != globalIndexOfOriginalGridSource_) delete globalIndexOfOriginalGridSource_;
+}
+
+/*!
+  Initialize the algorithms (transformations)
+*/
+void CGridTransformation::initializeAlgorithms()
+{
+  initializeAxisAlgorithms();
+  initializeDomainAlgorithms();
+}
+
+/*!
+  Initialize the algorithms corresponding to transformation info contained in each axis.
+If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
+In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
+For now, one approach is to do these combinely but maybe this needs changing.
+*/
+void CGridTransformation::initializeAxisAlgorithms()
+{
+  std::vector<int> axisPositionInGrid;
+  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
+  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
+  if (!axisListDestP.empty())
+  {
+    int idx = 0;
+    for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
+    {
+      if (false == (gridDestination_->axis_domain_order)(i))
+      {
+        axisPositionInGrid.push_back(idx);
+        ++idx;
+      }
+      else idx += 2;
+    }
+
+    for (int i = 0; i < axisListDestP.size(); ++i)
+    {
+      elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
+      if (axisListDestP[i]->hasTransformation())
+      {
+        CAxis::TransMapTypes trans = axisListDestP[i]->getAllTransformations();
+        CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
+                                             ite = trans.end();
+        int transformationOrder = 0;
+        for (it = itb; it != ite; ++it)
+        {
+          listAlgos_.push_back(std::make_pair(axisPositionInGrid[i], std::make_pair(it->first, transformationOrder)));
+          ++transformationOrder;
+        }
+      }
+    }
+  }
+}
+
+void CGridTransformation::initializeDomainAlgorithms()
+{
+
+}
+
+/*!
+  Select algorithm correspoding to its transformation type and its position in each element
+  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
+                                             and position of axis is 2
+  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
+  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
+*/
+void CGridTransformation::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
+{
+   selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
+}
+
+/*!
+  Select algorithm of an axis correspoding to its transformation type and its position in each element
+  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
+                                             and position of axis is 2
+  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
+  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
+*/
+void CGridTransformation::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
+{
+  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
+  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
+
+  int axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
+  CAxis::TransMapTypes trans = axisListDestP[axisIndex]->getAllTransformations();
+  CAxis::TransMapTypes::const_iterator it = trans.begin();
+
+  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
+
+  CZoomAxis* zoomAxis = 0;
+  CGenericAlgorithmTransformation* algo = 0;
+  switch (transType)
+  {
+    case TRANS_ZOOM_AXIS:
+      zoomAxis = dynamic_cast<CZoomAxis*> (it->second);
+      algo = new CAxisAlgorithmZoom(axisListDestP[axisIndex], axisListSrcP[axisIndex], zoomAxis);
+      break;
+    case TRANS_INVERSE_AXIS:
+      algo = new CAxisAlgorithmInverse(axisListDestP[axisIndex], axisListSrcP[axisIndex]);
+      break;
+    default:
+      break;
+  }
+  algoTransformation_.push_back(algo);
+
+}
+
+/*!
+  Select algorithm of a domain correspoding to its transformation type and its position in each element
+  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
+                                             and position of axis is 2
+  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
+  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
+*/
+void CGridTransformation::selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
+{
+}
+
+/*!
+  Assign the current grid destination to the grid source in the new transformation.
+The current grid destination plays the role of grid source in next transformation (if any).
+Only element on which the transformation is performed is modified
+  \param [in] elementPositionInGrid position of element in grid
+  \param [in] transType transformation type
+*/
+void CGridTransformation::setUpGrid(int elementPositionInGrid, ETranformationType transType)
+{
+  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
+  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
+
+  int axisIndex;
+  switch (transType)
+  {
+    case TRANS_ZOOM_AXIS:
+    case TRANS_INVERSE_AXIS:
+      axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
+      axisListSrcP[axisIndex]->duplicateAttributes(axisListDestP[axisIndex]);
+      break;
+    default:
+      break;
+  }
+}
+
+/*!
+  Perform all transformations
+  For each transformation, there are some things to do:
+  -) Chose the correct algorithm by transformation type and position of element
+  -) Calculate the mapping of global index between the current grid source and grid destination
+  -) Calculate the mapping of global index between current grid DESTINATION and ORIGINAL grid SOURCE
+  -) Make current grid destination become grid source in the next transformation
+*/
+void CGridTransformation::computeAll()
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+
+  ListAlgoType::const_iterator itb = listAlgos_.begin(),
+                               ite = listAlgos_.end(), it;
+  CGenericAlgorithmTransformation* algo = 0;
+  for (it = itb; it != ite; ++it)
+  {
+    std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource;
+    int elementPositionInGrid = it->first;
+    ETranformationType transType = (it->second).first;
+    int transformationOrder = (it->second).second;
+
+    // First of all, select an algorithm
+    selectAlgo(elementPositionInGrid, transType, transformationOrder);
+    algo = algoTransformation_.back();
+
+    // Recalculate the distribution of grid destination
+    CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
+    const CArray<size_t,1>& globalIndexGridDestSendToServer = distributionClientDest.getGlobalDataIndexSendToServer();
+
+    // ComputeTransformation of global index of each element
+    std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension();
+    int elementPosition = it->first;
+    algo->computeGlobalSourceIndex(elementPosition,
+                                   gridDestinationDimensionSize,
+                                   globalIndexGridDestSendToServer,
+                                   globaIndexMapFromDestToSource);
+
+    // Compute transformation of global indexes among grids
+    computeTransformationFromOriginalGridSource(globaIndexMapFromDestToSource);
+
+    // Now grid destination becomes grid source in a new transformation
+    setUpGrid(elementPositionInGrid, transType);
+  }
+
+  updateFinalGridDestination();
+  computeFinalTransformationMapping();
+}
+
+
+/*!
+  After applying the algorithms, there are some informations on grid destination needing change, for now, there are:
+   +) mask
+*/
+void CGridTransformation::updateFinalGridDestination()
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+
+  //First of all, retrieve info of local mask of grid destination
+  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
+  const CArray<int, 1>& localMaskIndexOnClientDest = distributionClientDest.getLocalMaskIndexOnClient();
+  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
+
+  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
+  itbArr = globalIndexOnClientDest.begin();
+  iteArr = globalIndexOnClientDest.end();
+
+  // Then find out which index became invalid (become masked after being applied the algorithms, or demande some masked points from grid source)
+  int num = globalIndexOfOriginalGridSource_->numElements();
+  const size_t sfmax = NumTraits<unsigned long>::sfmax();
+  int maskIndexNum = 0;
+  for (int idx = 0; idx < num; ++idx)
+  {
+    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
+    {
+      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
+      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
+      if (iteArr != itArr) ++maskIndexNum;
+    }
+  }
+
+  CArray<int,1>* maskIndexToModify = new CArray<int,1>(maskIndexNum);
+  maskIndexNum = 0;
+  for (int idx = 0; idx < num; ++idx)
+  {
+    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
+    {
+      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
+      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
+      if (iteArr != itArr)
+      {
+        int localIdx = std::distance(itbArr, itArr);
+        (*maskIndexToModify)(maskIndexNum) = (localMaskIndexOnClientDest)(localIdx);
+        ++maskIndexNum;
+      }
+    }
+  }
+
+  gridDestination_->modifyMask(*maskIndexToModify);
+
+  delete maskIndexToModify;
+}
+
+/*!
+  A transformation from a grid source to grid destination often passes several intermediate grids, which play a role of
+temporary grid source and/or grid destination. This function makes sure that global index of original grid source are mapped correctly to
+the final grid destination
+*/
+void CGridTransformation::computeTransformationFromOriginalGridSource(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource)
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+
+  CTransformationMapping transformationMap(gridDestination_, gridSource_);
+
+    // Then compute transformation mapping among clients
+  transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
+
+  const std::map<int,std::vector<std::vector<size_t> > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+
+ // Sending global index of original grid source
+  std::map<int,std::vector<size_t> >::const_iterator itbSend = globalIndexToSend.begin(), itSend,
+                                                     iteSend = globalIndexToSend.end();
+  CArray<size_t,1>::const_iterator itbArr = globalIndexOfCurrentGridSource_->begin(), itArr,
+                                   iteArr = globalIndexOfCurrentGridSource_->end();
+ int sendBuffSize = 0;
+ for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
+
+ typedef unsigned long Scalar;
+ unsigned long* sendBuff, *currentSendBuff;
+ if (0 != sendBuffSize) sendBuff = new unsigned long [sendBuffSize];
+ for (StdSize idx = 0; idx < sendBuffSize; ++idx) sendBuff[idx] = NumTraits<Scalar>::sfmax();
+
+ int currentBuffPosition = 0;
+ for (itSend = itbSend; itSend != iteSend; ++itSend)
+ {
+   int destRank = itSend->first;
+   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
+   int countSize = globalIndexOfCurrentGridSourceToSend.size();
+   for (int idx = 0; idx < (countSize); ++idx)
+   {
+     itArr = std::find(itbArr, iteArr, globalIndexOfCurrentGridSourceToSend[idx]);
+     if (iteArr != itArr)
+     {
+       int index = std::distance(itbArr, itArr);
+       sendBuff[idx+currentBuffPosition] = (*globalIndexOfOriginalGridSource_)(index);
+     }
+   }
+   currentSendBuff = sendBuff + currentBuffPosition;
+   MPI_Send(currentSendBuff, countSize, MPI_UNSIGNED_LONG, destRank, 14, client->intraComm);
+   currentBuffPosition += countSize;
+ }
+
+ // Receiving global index of grid source sending from current grid source
+ std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
+                                                                  iteRecv = globalIndexToReceive.end();
+ int recvBuffSize = 0;
+ for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size();
+
+ unsigned long* recvBuff, *currentRecvBuff;
+ if (0 != recvBuffSize) recvBuff = new unsigned long [recvBuffSize];
+ for (StdSize idx = 0; idx < recvBuffSize; ++idx) recvBuff[idx] = NumTraits<Scalar>::sfmax();
+
+ int currentRecvBuffPosition = 0;
+ for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
+ {
+   MPI_Status status;
+   int srcRank = itRecv->first;
+   int countSize = (itRecv->second).size();
+   currentRecvBuff = recvBuff + currentRecvBuffPosition;
+   MPI_Recv(currentRecvBuff, countSize, MPI_UNSIGNED_LONG, srcRank, 14, client->intraComm, &status);
+   currentRecvBuffPosition += countSize;
+ }
+
+ int nbCurrentGridSource = 0;
+ for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
+ {
+   int ssize = (itRecv->second).size();
+   for (int idx = 0; idx < ssize; ++idx)
+   {
+     nbCurrentGridSource += (itRecv->second)[idx].size();
+   }
+ }
+
+ if (globalIndexOfCurrentGridSource_->numElements()  != nbCurrentGridSource)
+ {
+   delete globalIndexOfCurrentGridSource_;
+   globalIndexOfCurrentGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
+ }
+
+ if (globalIndexOfOriginalGridSource_->numElements() != nbCurrentGridSource)
+ {
+   delete globalIndexOfOriginalGridSource_;
+   globalIndexOfOriginalGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
+ }
+
+ int k = 0;
+ currentRecvBuff = recvBuff;
+ for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
+ {
+   int countSize = (itRecv->second).size();
+   for (int idx = 0; idx < countSize; ++idx, ++currentRecvBuff)
+   {
+     int ssize = (itRecv->second)[idx].size();
+     for (int i = 0; i < ssize; ++i)
+     {
+       (*globalIndexOfCurrentGridSource_)(k) = (itRecv->second)[idx][i];
+       (*globalIndexOfOriginalGridSource_)(k) = *currentRecvBuff;
+       ++k;
+     }
+   }
+ }
+
+ if (0 != sendBuffSize) delete [] sendBuff;
+ if (0 != recvBuffSize) delete [] recvBuff;
+}
+
+/*!
+  Compute transformation mapping between grid source and grid destination
+  The transformation between grid source and grid destination is represented in form of mapping between global index
+of two grids. Then local index mapping between data on each grid will be found out thanks to these global indexes
+*/
+void CGridTransformation::computeFinalTransformationMapping()
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+
+  CTransformationMapping transformationMap(gridDestination_, originalGridSource_);
+
+  std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource;
+
+  int nb = globalIndexOfCurrentGridSource_->numElements();
+  const size_t sfmax = NumTraits<unsigned long>::sfmax();
+  for (int idx = 0; idx < nb; ++idx)
+  {
+    if (sfmax != (*globalIndexOfOriginalGridSource_)(idx))
+      globaIndexMapFromDestToSource[(*globalIndexOfCurrentGridSource_)(idx)].insert((*globalIndexOfOriginalGridSource_)(idx));
+  }
+
+  // Then compute transformation mapping among clients
+  transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
+
+  const std::map<int,std::vector<std::vector<size_t> > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+
+  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
+  CDistributionClient distributionClientSrc(client->clientRank, originalGridSource_);
+
+//  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexOnClient(); //gridDestination_->getDistributionClient()->getLocalDataIndexOnClient();
+  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexSendToServer();
+  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer(); //gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
+
+  const CArray<int, 1>& localIndexOnClientSrc = distributionClientSrc.getLocalDataIndexOnClient(); //gridSource_->getDistributionClient()->getLocalDataIndexOnClient();
+  const CArray<size_t,1>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
+
+  std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
+  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
+
+  std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
+
+  // Find out local index on grid destination (received)
+  itbMapRecv = globalIndexToReceive.begin();
+  iteMapRecv = globalIndexToReceive.end();
+  itbArr = globalIndexOnClientDest.begin();
+  iteArr = globalIndexOnClientDest.end();
+  for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv)
+  {
+    int sourceRank = itMapRecv->first;
+    int numGlobalIndex = (itMapRecv->second).size();
+    for (int i = 0; i < numGlobalIndex; ++i)
+    {
+      int vecSize = ((itMapRecv->second)[i]).size();
+      CArray<int,1>* ptr = new CArray<int,1>(vecSize);
+      localIndexToReceiveOnGridDest_[sourceRank].push_back(ptr);
+      for (int idx = 0; idx < vecSize; ++idx)
+      {
+        itArr = std::find(itbArr, iteArr, (itMapRecv->second)[i][idx]);
+        if (iteArr != itArr)
+        {
+          int localIdx = std::distance(itbArr, itArr);
+//          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = localIndexOnClientDest(localIdx); // Local index of un-extracted data (only domain)
+          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = (localIdx); // Local index of extracted data
+        }
+      }
+    }
+  }
+
+  std::map<int,std::vector<size_t> >::const_iterator itbMap, itMap, iteMap;
+  // Find out local index on grid source (to send)
+  itbMap = globalIndexToSend.begin();
+  iteMap = globalIndexToSend.end();
+  itbArr = globalIndexOnClientSrc.begin();
+  iteArr = globalIndexOnClientSrc.end();
+  for (itMap = itbMap; itMap != iteMap; ++itMap)
+  {
+    CArray<int,1>* ptr = new CArray<int,1>((itMap->second).size());
+    localIndexToSendFromGridSource_[itMap->first] = ptr;
+    int destRank = itMap->first;
+    int vecSize = (itMap->second).size();
+    for (int idx = 0; idx < vecSize; ++idx)
+    {
+      itArr = std::find(itbArr, iteArr, (itMap->second)[idx]);
+      if (iteArr != itArr)
+      {
+        int localIdx = std::distance(itbArr, itArr);
+//        (*localIndexToSendFromGridSource_[destRank])(idx) = localIndexOnClientSrc(localIdx);
+        (*localIndexToSendFromGridSource_[destRank])(idx) = (localIdx);
+      }
+    }
+  }
+}
+
+/*!
+  Local index of data which need sending from the grid source
+  \return local index of data
+*/
+const std::map<int, CArray<int,1>* >& CGridTransformation::getLocalIndexToSendFromGridSource() const
+{
+  return localIndexToSendFromGridSource_;
+}
+
+/*!
+  Local index of data which will be received on the grid destination
+  \return local index of data
+*/
+const std::map<int, std::vector<CArray<int,1>* > >& CGridTransformation::getLocalIndexToReceiveOnGridDest() const
+{
+  return localIndexToReceiveOnGridDest_;
+}
+
+}
Index: XIOS/trunk/src/transformation/grid_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 624)
+++ XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 624)
@@ -0,0 +1,102 @@
+/*!
+   \file grid_transformation.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 18 June 2015
+
+   \brief Interface for all transformations.
+ */
+#ifndef __XIOS_GRID_TRANSFORMATION_HPP__
+#define __XIOS_GRID_TRANSFORMATION_HPP__
+
+#include <map>
+#include <vector>
+#include "grid.hpp"
+#include "generic_algorithm_transformation.hpp"
+#include "transformation_enum.hpp"
+
+namespace xios {
+
+class CGrid;
+
+/*!
+  \class CGridTransformation
+  This class is an interface for all transformations to interact with the rest of XIOS.
+The class, firstly, tries to get all information relating to requested transformations by retrieving directly from grid.
+Then with all these information, all necessary transformations will be be created by generic class \class CGenericAlgorithmTransformation.
+Because there are information exchange among clients to accomplish the transformations (e.g: some index need retrieving from other clients),
+this class uses class \class CTransformationMapping to fulfill this demand.
+For each transformation, a new temporary grid source is created.
+For a consequential transformations (e.g: inversing -> zoom -> inversing -> ...),
+the grid destination of current transformation will be grid source of the next transformation
+*/
+class CGridTransformation
+{
+public:
+  /** Default constructor */
+  CGridTransformation(CGrid* destination, CGrid* source);
+  ~CGridTransformation();
+
+  void computeAll();
+
+  const std::map<int, CArray<int,1>* >& getLocalIndexToSendFromGridSource() const;
+  const std::map<int, std::vector<CArray<int,1>* > >& getLocalIndexToReceiveOnGridDest() const;
+
+private:
+  void computeTransformation();
+  void initializeAlgorithms();
+  void initializeAxisAlgorithms();
+  void initializeDomainAlgorithms();
+  void initializeMappingOfOriginalGridSource();
+
+  void selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+  void selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+  void selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder);
+  void setUpGrid(int elementPositionInGrid, ETranformationType transType);
+  void computeFinalTransformationMapping();
+  void computeTransformationFromOriginalGridSource(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
+  void updateFinalGridDestination();
+
+private:
+  //! Grid source on transformation
+  CGrid* gridSource_;
+
+  //! Grid destination on transformation
+  CGrid* gridDestination_;
+
+  //! The grid source of the first transformation (original grid source)
+  CGrid* originalGridSource_;
+
+  //! Grid source dimension size
+  std::vector<int> gridSourceDimensionSize_;
+
+  //! Grid destination dimension size
+  std::vector<int> gridDestinationDimensionSize_;
+
+private:
+  typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
+  //! List of algorithm types and their order
+  ListAlgoType listAlgos_;
+
+  // Mapping between position of an element in grid and its transformation (if any)
+  std::list<CGenericAlgorithmTransformation*> algoTransformation_;
+
+  //! Mapping of (grid) global index representing tranformation.
+  std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource_;
+
+  //! Local index of data to send from grid source
+  std::map<int, CArray<int,1>* > localIndexToSendFromGridSource_;
+
+  //! Local index of data to receive on grid destination
+  std::map<int, std::vector<CArray<int,1>* > > localIndexToReceiveOnGridDest_;
+
+  //! Position of axis and domain in grid
+  std::map<int, int> elementPosition2AxisPositionInGrid_, elementPosition2DomainPositionInGrid_;
+
+  //! (Grid) Global index of grid source
+  CArray<size_t,1>* globalIndexOfCurrentGridSource_;
+  CArray<size_t,1>* globalIndexOfOriginalGridSource_;
+};
+
+}
+#endif // __XIOS_GRID_TRANSFORMATION_HPP__
Index: XIOS/trunk/src/transformation/transformation_mapping.cpp
===================================================================
--- XIOS/trunk/src/transformation/transformation_mapping.cpp	(revision 624)
+++ XIOS/trunk/src/transformation/transformation_mapping.cpp	(revision 624)
@@ -0,0 +1,182 @@
+/*!
+   \file transformation_mapping.cpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 18 June 2015
+
+   \brief Take charge of communication among clients to exchange transformed data.
+ */
+
+#include "transformation_mapping.hpp"
+#include <boost/unordered_map.hpp>
+#include "context.hpp"
+#include "context_client.hpp"
+#include "distribution_client.hpp"
+
+namespace xios {
+
+CTransformationMapping::CTransformationMapping(CGrid* destination, CGrid* source)
+  : gridSource_(source), gridDestination_(destination)
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+  int clientRank = client->clientRank;
+
+  CDistributionClient distributionClientSrc(client->clientRank, gridSource_);
+
+  const CArray<size_t,1>& globalIndexGridSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
+  boost::unordered_map<size_t,int> globalIndexOfServer;
+  int globalIndexSize = globalIndexGridSrc.numElements();
+  for (int idx = 0; idx < globalIndexSize; ++idx)
+  {
+    globalIndexOfServer[globalIndexGridSrc(idx)] = clientRank;
+  }
+
+  gridIndexClientClientMapping_ = new CClientServerMappingDistributed(globalIndexOfServer,
+                                                                      client->intraComm,
+                                                                      true);
+}
+
+CTransformationMapping::~CTransformationMapping()
+{
+  if (0 != gridIndexClientClientMapping_) delete gridIndexClientClientMapping_;
+}
+
+/*!
+  Suppose that we have transformations between two grids, which are represented in form of mapping between global indexes of these two grids,
+this function tries to find out which clients a client needs to send and receive these global indexes to accomplish the transformations.
+  The grid destination is the grid whose global indexes demande global indexes from the grid source
+  Grid destination and grid source are also distributed among clients but in different manners.
+  \param [in] globaIndexMapFromDestToSource mapping representing the transformations
+*/
+void CTransformationMapping::computeTransformationMapping(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource)
+{
+  CContext* context = CContext::getCurrent();
+  CContextClient* client=context->client;
+
+  int numMappingPoints = 0;
+  std::map<size_t, std::set<size_t> >::const_iterator itbMap = globaIndexMapFromDestToSource.begin(), itMap,
+                                                      iteMap = globaIndexMapFromDestToSource.end();
+  for (itMap = itbMap; itMap != iteMap; ++itMap)
+  {
+    numMappingPoints += (itMap->second).size();
+  }
+
+  // All global indexes of a client on grid destination
+  CArray<size_t,1> globalIndexMap(numMappingPoints);
+  // Not only one index on grid destination can demande two indexes from grid source
+  // but an index on grid destination have to be sent to two indexes of grid destination
+  std::map<size_t, std::vector<size_t> > globalIndexMapFromSrcToDest;
+  std::set<size_t>::const_iterator itbSet, itSet, iteSet;
+  int idx = 0;
+  for (itMap = itbMap; itMap != iteMap; ++itMap)
+  {
+    itbSet = (itMap->second).begin();
+    iteSet = (itMap->second).end();
+    for (itSet = itbSet; itSet != iteSet; ++itSet)
+    {
+      globalIndexMap(idx) = *itSet;
+      globalIndexMapFromSrcToDest[*itSet].push_back(itMap->first);
+      ++idx;
+    }
+  }
+
+  // Find out on which clients the necessary indexes of grid source are.
+  gridIndexClientClientMapping_->computeServerIndexMapping(globalIndexMap);
+  const std::map<int, std::vector<size_t> >& globalIndexSentFromGridSource = gridIndexClientClientMapping_->getGlobalIndexOnServer();
+  std::map<int, std::vector<size_t> >::const_iterator itbMapSrc = globalIndexSentFromGridSource.begin(), itMapSrc,
+                                                      iteMapSrc = globalIndexSentFromGridSource.end();
+  std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
+  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc)
+  {
+    int sourceRank = itMapSrc->first;
+    itbVec = (itMapSrc->second).begin();
+    iteVec = (itMapSrc->second).end();
+    for (itVec = itbVec; itVec != iteVec; ++itVec)
+    {
+       (globalIndexReceivedOnGridDestMapping_[sourceRank]).push_back(globalIndexMapFromSrcToDest[*itVec]);
+    }
+  }
+
+  // Inform client about the destination to which it needs to send global indexes
+  int nbClient = client->clientSize;
+  int* sendBuff = new int[nbClient];
+  int* recvBuff = new int[nbClient];
+  for (int i = 0; i < nbClient; ++i) sendBuff[i] = 0;
+
+  // First of all, inform the number of destination a client needs to send global index
+  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc) sendBuff[itMapSrc->first] = 1;
+  MPI_Allreduce(sendBuff, recvBuff, nbClient, MPI_INT, MPI_SUM, client->intraComm);
+  int numClientToReceive = recvBuff[client->clientRank];
+
+  // Then specify the size of receiving buffer, because we use synch send/receive so only necessary to know maximum size
+  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc) sendBuff[itMapSrc->first] = (itMapSrc->second).size();
+  MPI_Allreduce(sendBuff, recvBuff, nbClient, MPI_INT, MPI_MAX, client->intraComm);
+
+  int buffSize = recvBuff[client->clientRank];
+  unsigned long* recvBuffGlobalIndex;
+  if (0 != buffSize) recvBuffGlobalIndex = new unsigned long [buffSize];
+
+  // Inform all "source clients" about index that they need to send
+  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc)
+  {
+    MPI_Request request;
+    unsigned long* sendPtr = const_cast<unsigned long*>(&(itMapSrc->second)[0]);
+    MPI_Isend(sendPtr,
+              (itMapSrc->second).size(),
+              MPI_UNSIGNED_LONG,
+              itMapSrc->first,
+              11,
+              client->intraComm,
+              &request);
+  }
+
+  // Now all the "source clients" try listening messages from other "destination clients"
+  int numClientReceived = 0;  // number of client to which data has been already sent
+  int countBuff;
+  while (numClientReceived < numClientToReceive)
+  {
+    MPI_Status status;
+    MPI_Recv(recvBuffGlobalIndex,
+             buffSize,
+             MPI_UNSIGNED_LONG,
+             MPI_ANY_SOURCE,
+             11,
+             client->intraComm,
+             &status);
+
+    MPI_Get_count(&status, MPI_UNSIGNED_LONG, &countBuff);
+    int clientDestRank = status.MPI_SOURCE;
+    for (int idx = 0; idx < countBuff; ++idx)
+    {
+      globalIndexSendToGridDestMapping_[clientDestRank].push_back(recvBuffGlobalIndex[idx]);
+    }
+    ++numClientReceived;
+  }
+
+  delete [] sendBuff;
+  delete [] recvBuff;
+  if (0 != buffSize) delete [] recvBuffGlobalIndex;
+}
+
+/*!
+  Return (grid) global index on grid destination. This mapping contains the rank of client source (that sends info to grid destination)
+and the corresponding global index to write on grid destination.
+  \return global index mapping to receive on grid destination
+*/
+const std::map<int,std::vector<std::vector<size_t> > >& CTransformationMapping::getGlobalIndexReceivedOnGridDestMapping() const
+{
+  return globalIndexReceivedOnGridDestMapping_;
+}
+
+/*!
+  Return (grid) global index on grid source. This mapping contains the rank of client destination (which receives transformation info) and
+the corresponding global index to send
+  \return global index mapping to send on grid source
+*/
+const std::map<int,std::vector<size_t> >& CTransformationMapping::getGlobalIndexSendToGridDestMapping() const
+{
+  return globalIndexSendToGridDestMapping_;
+}
+
+}
Index: XIOS/trunk/src/transformation/transformation_mapping.hpp
===================================================================
--- XIOS/trunk/src/transformation/transformation_mapping.hpp	(revision 624)
+++ XIOS/trunk/src/transformation/transformation_mapping.hpp	(revision 624)
@@ -0,0 +1,52 @@
+/*!
+   \file transformation_mapping.hpp
+   \author Ha NGUYEN
+   \since 14 May 2015
+   \date 09 June 2015
+
+   \brief Take charge of communication among clients to exchange transformed data.
+ */
+#ifndef __XIOS_TRANSFORMATION_MAPPING_HPP__
+#define __XIOS_TRANSFORMATION_MAPPING_HPP__
+
+#include <map>
+#include <set>
+#include "grid.hpp"
+#include "array_new.hpp"
+#include "client_server_mapping_distributed.hpp"
+
+namespace xios {
+
+/*!
+  \class CTransformationMapping
+  This class is in charge of transfer the global index form grid from grid source to grid destination in a rather generic way.
+In order to make a transformation, the grid destination will make a request to grid source about the global indexes which it needs.
+The same discovering algorithm as the case of client-server is applied to find the corresponding client which contains the demanding global index.
+*/
+class CTransformationMapping
+{
+public:
+  /** Default constructor */
+  CTransformationMapping(CGrid* destination, CGrid* source);
+  ~CTransformationMapping();
+
+  void computeTransformationMapping(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource);
+  const std::map<int,std::vector<std::vector<size_t> > >& getGlobalIndexReceivedOnGridDestMapping() const;
+  const std::map<int,std::vector<size_t> >& getGlobalIndexSendToGridDestMapping() const;
+
+protected:
+  CGrid* gridSource_;  // Grid source
+  CGrid* gridDestination_; // Grid destination demande the necessary global index from grid source
+
+  //! Global index mapping of grid source and grid destination between two clients
+  CClientServerMappingDistributed* gridIndexClientClientMapping_;
+
+  //! Mapping of client rank of grid source and global index received in grid destination
+  std::map<int,std::vector<std::vector<size_t> > > globalIndexReceivedOnGridDestMapping_;
+
+  //! Mapping of client rank of grid destination and global index to send from grid source
+  std::map<int,std::vector<size_t> > globalIndexSendToGridDestMapping_;
+};
+
+}
+#endif // __XIOS_TRANSFORMATION_MAPPING_HPP__
Index: XIOS/trunk/src/visitable.hpp
===================================================================
--- XIOS/trunk/src/visitable.hpp	(revision 623)
+++ 	(revision )
@@ -1,103 +1,0 @@
-#ifndef __XIOS_VISITABLE_HPP
-#define __XIOS_VISITABLE_HPP
-
-#include "visitor.hpp"
-#include <vector>
-
-namespace xios {
-
-template <typename R, typename ParamType>
-struct DefaultCatchAll
-{
-  static R OnUnknownVisitor(ParamType&, CBaseVisitor&)
-  { return R(); }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// class template CBaseVisitable
-////////////////////////////////////////////////////////////////////////////////
-template
-<
-  typename R = void,
-  template <typename, class> class CatchAll = DefaultCatchAll,
-  bool ConstVisitable = false
->
-class CBaseVisitable;
-
-template<typename R,template <typename, class> class CatchAll>
-class CBaseVisitable<R, CatchAll, false>
-{
-public:
-  typedef R ReturnType;
-  virtual ~CBaseVisitable() {}
-  virtual ReturnType apply(CBaseVisitor&) = 0;
-  virtual void apply(std::vector<CBaseVisitor*>&) = 0;
-
-protected: // give access only to the hierarchy
-  template <class T>
-  static ReturnType applyImpl(T& visited, CBaseVisitor& guest)
-  {
-    // Apply the CVisitor
-    if (CVisitor<T,R>* p = dynamic_cast<CVisitor<T,R>*>(&guest))
-    {
-        return p->operate(visited);
-    }
-    return CatchAll<R, T>::OnUnknownVisitor(visited, guest);
-  }
-};
-
-template<typename R,template <typename, class> class CatchAll>
-class CBaseVisitable<R, CatchAll, true>
-{
-public:
-  typedef R ReturnType;
-  virtual ~CBaseVisitable() {}
-  virtual ReturnType apply(CBaseVisitor&) const = 0;
-  virtual void apply(std::vector<CBaseVisitor*>&) const = 0;
-
-protected: // give access only to the hierarchy
-  template <class T>
-  static ReturnType applyImpl(const T& visited, CBaseVisitor& guest)
-  {
-    // Apply the CVisitor
-    if (CVisitor<T,R>* p = dynamic_cast<CVisitor<T,R, true>*>(&guest))
-    {
-      return p->operate(visited);
-    }
-    return CatchAll<R, T>::OnUnknownVisitor(const_cast<T&>(visited), guest);
-  }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// Put it in every class that you want to make guest
-/// functions (in addition to deriving it from CBaseVisitable<R>)
-////////////////////////////////////////////////////////////////////////////////
-#define DEFINE_VISITABLE() \
-    virtual ReturnType apply(::xios::CBaseVisitor& guest) \
-    { return applyImpl(*this, guest); }                   \
-    virtual void apply(std::vector<CBaseVisitor*>& guests) \
-    {                                                             \
-      for (std::vector<CBaseVisitor*>::iterator it = guests.begin(); it != guests.end(); ++it) \
-        apply(*(*it));                                                                                \
-    }
-////////////////////////////////////////////////////////////////////////////////
-/// Put it in every class that you want to make guest by const member
-/// functions (in addition to deriving it from CBaseVisitable<R>)
-////////////////////////////////////////////////////////////////////////////////
-#define DEFINE_CONST_VISITABLE() \
-    virtual ReturnType apply(::xios::CBaseVisitor& guest) const \
-    { return applyImpl(*this, guest); }                         \
-    virtual void apply(std::vector<CBaseVisitor*>& guests) const \
-    {                                                             \
-      for (std::vector<CBaseVisitor*>::iterator it = guests.begin(); it != guests.end(); ++it) \
-        apply(*(*it));                                                                                \
-    }
-
-class CGenericTransformation : public virtual CBaseVisitable<>
-{
-public:
-  DEFINE_VISITABLE()
-};
-
-}
-#endif // __XIOS_VISITABLE_HPP
Index: XIOS/trunk/src/visitor.hpp
===================================================================
--- XIOS/trunk/src/visitor.hpp	(revision 623)
+++ 	(revision )
@@ -1,38 +1,0 @@
-#ifndef __XIOS_VISITOR_HPP__
-#define __XIOS_VISITOR_HPP__
-
-namespace xios {
-
-class CBaseVisitor
-{
-public:
-    virtual ~CBaseVisitor() {}
-};
-
-typedef CBaseVisitor CGenericAlgorithm;
-
-template <class T, typename R = void, bool ConstVisitor = false>
-class CVisitor;
-
-template<typename T, typename R>
-class CVisitor<T, R, false>
-{
-public:
-    typedef R ReturnType;
-    typedef T ParamType;
-    virtual ~CVisitor() {}
-    virtual ReturnType operate(ParamType&) = 0;
-};
-
-template<typename T, typename R>
-class CVisitor<T, R, true>
-{
-public:
-    typedef R ReturnType;
-    typedef const T ParamType;
-    virtual ~CVisitor() {}
-    virtual ReturnType operate(ParamType&) = 0;
-};
-
-}
-#endif // __XIOS_VISITOR_HPP__
