Index: XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 827)
+++ XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 829)
@@ -72,19 +72,21 @@
   std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[0];
 
-  std::map<size_t, std::vector<std::pair<size_t,double> > > globaIndexMapFromDestToSource;
+  CTransformationMapping::DestinationIndexMap globaIndexMapFromDestToSource;
   std::map<int, std::vector<int> >::const_iterator it = transMap.begin(), ite = transMap.end();
+  int localIndex = 0;
   for (; it != ite; ++it)
   {
-    globaIndexMapFromDestToSource[it->first].push_back(make_pair((it->second)[0], (transWeight[it->first])[0]));
+    globaIndexMapFromDestToSource[it->first].push_back(make_pair(localIndex,make_pair((it->second)[0], (transWeight[it->first])[0])));
+    ++localIndex;
   }
 
   transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
 
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
-  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const CTransformationMapping::SentIndexMap& 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();
+  CTransformationMapping::SentIndexMap::const_iterator itbSend = globalIndexToSend.begin(), itSend,
+                                                       iteSend = globalIndexToSend.end();
  int sendBuffSize = 0;
  for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
@@ -99,9 +101,9 @@
  {
    int destRank = itSend->first;
-   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
+   const std::vector<std::pair<int,size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second;
    int countSize = globalIndexOfCurrentGridSourceToSend.size();
    for (int idx = 0; idx < (countSize); ++idx)
    {
-     int index = globalIndexOfCurrentGridSourceToSend[idx] - ibeginSrc;
+     int index = globalIndexOfCurrentGridSourceToSend[idx].first;
      sendBuff[idx+currentBuffPosition] = (axisSrc_->value)(index);
    }
@@ -112,6 +114,6 @@
 
  // Receiving global index of grid source sending from current grid source
- std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
-                                                                                     iteRecv = globalIndexToReceive.end();
+ CTransformationMapping::ReceivedIndexMap::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
+                                                          iteRecv = globalIndexToReceive.end();
  int recvBuffSize = 0;
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size();
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 827)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 829)
@@ -49,6 +49,6 @@
                                                                           const std::vector<int>& gridDestGlobalDim,
                                                                           const std::vector<int>& gridSrcGlobalDim,
-                                                                          const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                                          CArray<size_t,1>& globalIndexDestGrid,
+                                                                          const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                                          std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                                           std::vector<std::vector<size_t> >& globalIndexSrcGrid)
 {
@@ -72,6 +72,5 @@
   }
 
-  std::vector<size_t>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
-                                      iteArr = globalIndexGridDestSendToServer.end();
+  GlobalLocalMap::const_iterator iteArr = globalLocalIndexDestSendToServerMap.end(), it;
 
   while (idx < ssize)
@@ -111,11 +110,11 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex)) ++realGlobalIndexSize;
+    if (iteArr != globalLocalIndexDestSendToServerMap.find(globIndex)) ++realGlobalIndexSize;
     ++idxLoop[0];
     ++idx;
   }
 
-  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
-    globalIndexDestGrid.resize(realGlobalIndexSize);
+  if (globalLocalIndexDestMap.size() != realGlobalIndexSize)
+    globalLocalIndexDestMap.resize(realGlobalIndexSize);
 
   if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
@@ -162,7 +161,8 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex))
+    it = globalLocalIndexDestSendToServerMap.find(globIndex);
+    if (iteArr != it)
     {
-      globalIndexDestGrid(realGlobalIndex) = globIndex;
+      globalLocalIndexDestMap[realGlobalIndex] = (std::make_pair(it->first,it->second));
       for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
       {
@@ -183,105 +183,4 @@
     ++idx;
   }
-
-
-
-//  int globalDim = gridDestGlobalDim.size();
-//
-//  std::vector<size_t> currentIndex(globalDim);
-//  std::vector<int> gridAxisGlobalDim(globalDim);
-//  std::vector<int> idxLoop(globalDim, 0);
-//
-//  size_t ssize = 1, idx = 0, realGlobalIndexSize = 0;
-//  for (int i = 0; i< globalDim; ++i)
-//  {
-//    if (axisPositionInGrid == i) gridAxisGlobalDim[i] = 1;
-//    else gridAxisGlobalDim[i] = gridDestGlobalDim[i];
-//    ssize *= gridAxisGlobalDim[i];
-//  }
-//
-//  std::vector<size_t>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
-//                                      iteArr = globalIndexGridDestSendToServer.end();
-//
-//  while (idx < ssize)
-//  {
-//    for (int i = 0; i < globalDim-1; ++i)
-//    {
-//      if (idxLoop[i] == gridAxisGlobalDim[i])
-//      {
-//        idxLoop[i] = 0;
-//        ++idxLoop[i+1];
-//      }
-//    }
-//
-//    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
-//    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
-//
-//    size_t globIndex = currentIndex[0];
-//    size_t mulDim = 1;
-//    for (int k = 1; k < globalDim; ++k)
-//    {
-//      mulDim *= gridDestGlobalDim[k-1];
-//      globIndex += (currentIndex[k])*mulDim;
-//    }
-//
-//    if (std::binary_search(itbArr, iteArr, globIndex)) ++realGlobalIndexSize;
-//    ++idxLoop[0];
-//    ++idx;
-//  }
-//
-//  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
-//    globalIndexDestGrid.resize(realGlobalIndexSize);
-//
-//  if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
-//  for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
-//    if (globalIndexSrcGrid[i].size() != axisSrcGlobalIndex.size())
-//      globalIndexSrcGrid[i].resize(axisSrcGlobalIndex.size());
-//
-//  size_t realGlobalIndex = 0;
-//  idx = 0;
-//  idxLoop.assign(globalDim, 0);
-//  while (idx < ssize)
-//  {
-//    for (int i = 0; i < globalDim-1; ++i)
-//    {
-//      if (idxLoop[i] == gridAxisGlobalDim[i])
-//      {
-//        idxLoop[i] = 0;
-//        ++idxLoop[i+1];
-//      }
-//    }
-//
-//    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
-//    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
-//
-//    size_t globIndex = currentIndex[0];
-//    size_t mulDim = 1;
-//    for (int k = 1; k < globalDim; ++k)
-//    {
-//      mulDim *= gridDestGlobalDim[k-1];
-//      globIndex += (currentIndex[k])*mulDim;
-//    }
-//
-//    if (std::binary_search(itbArr, iteArr, globIndex))
-//    {
-//      globalIndexDestGrid(realGlobalIndex) = globIndex;
-//      for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
-//      {
-//        currentIndex[axisPositionInGrid] = axisSrcGlobalIndex[i];
-//        globIndex = currentIndex[0];
-//        mulDim = 1;
-//        for (int k = 1; k < globalDim; ++k)
-//        {
-//          mulDim *= gridDestGlobalDim[k-1];
-//          globIndex += (currentIndex[k])*mulDim;
-//        }
-//        (globalIndexSrcGrid[realGlobalIndex])[i] = globIndex;
-//      }
-//      ++realGlobalIndex;
-//    }
-//
-//    ++idxLoop[0];
-//    ++idx;
-//  }
 }
 }
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 827)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 829)
@@ -33,6 +33,6 @@
                                                         const std::vector<int>& gridDestGlobalDim,
                                                         const std::vector<int>& gridSrcGlobalDim,
-                                                        const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                        std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid);
 
Index: XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp	(revision 827)
+++ XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp	(revision 829)
@@ -417,5 +417,5 @@
 
   domainIndexClientClientMapping.computeServerIndexMapping(globalIndexInterp);
-  const std::map<int, std::vector<size_t> >& globalIndexInterpSendToClient = domainIndexClientClientMapping.getGlobalIndexOnServer();
+  const CClientServerMapping::GlobalIndexMap& globalIndexInterpSendToClient = domainIndexClientClientMapping.getGlobalIndexOnServer();
 
   //Inform each client number of index they will receive
@@ -429,6 +429,6 @@
   }
   int sendBuffSize = 0;
-  std::map<int, std::vector<size_t> >::const_iterator itbMap = globalIndexInterpSendToClient.begin(), itMap,
-                                                      iteMap = globalIndexInterpSendToClient.end();
+  CClientServerMapping::GlobalIndexMap::const_iterator itbMap = globalIndexInterpSendToClient.begin(), itMap,
+                                                       iteMap = globalIndexInterpSendToClient.end();
   for (itMap = itbMap; itMap != iteMap; ++itMap)
   {
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 827)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 829)
@@ -42,6 +42,6 @@
                                                                           const std::vector<int>& gridDestGlobalDim,
                                                                           const std::vector<int>& gridSrcGlobalDim,
-                                                                          const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                                          CArray<size_t,1>& globalIndexDestGrid,
+                                                                          const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                                          std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                                           std::vector<std::vector<size_t> >& globalIndexSrcGrid)
 {
@@ -79,6 +79,6 @@
   for (int i = 0; i< numElement; ++i) ssize *= gridDomainGlobalDim[i];
 
-  std::vector<size_t>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
-                                      iteArr = globalIndexGridDestSendToServer.end();
+  GlobalLocalMap::const_iterator iteArr = globalLocalIndexDestSendToServerMap.end(), it;
+
   idx = 0;
   while (idx < ssize)
@@ -112,11 +112,11 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex)) ++realGlobalIndexSize;
+    if (iteArr != globalLocalIndexDestSendToServerMap.find(globIndex)) ++realGlobalIndexSize;
     ++idxLoop[0];
     ++idx;
   }
 
-  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
-    globalIndexDestGrid.resize(realGlobalIndexSize);
+  if (globalLocalIndexDestMap.size() != realGlobalIndexSize)
+    globalLocalIndexDestMap.resize(realGlobalIndexSize);
 
   if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
@@ -158,7 +158,8 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex))
+    it = globalLocalIndexDestSendToServerMap.find(globIndex);
+    if (iteArr != it)
     {
-      globalIndexDestGrid(realGlobalIndex) = globIndex;
+      globalLocalIndexDestMap[realGlobalIndex] = (std::make_pair(it->first,it->second));
       for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
       {
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 827)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 829)
@@ -33,6 +33,6 @@
                                                         const std::vector<int>& gridDestGlobalDim,
                                                         const std::vector<int>& gridSrcGlobalDim,
-                                                        const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                        std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid);
 
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 827)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 829)
@@ -3,5 +3,5 @@
    \author Ha NGUYEN
    \since 14 May 2015
-   \date 29 June 2015
+   \date 21 Mars 2016
 
    \brief Interface for all transformation algorithms.
@@ -23,6 +23,7 @@
   \param[in] gridSrcGlobalDim dimension size of source grid (it should share the same size for all dimension, maybe except the domain on which transformation is performed)
   \param[in] globalIndexGridDestSendToServer global index of grid destination on the current client to send to server
+  \param[in] localIndexGridSendToServer local index of grid destination on the current client to send to server
   \param[in/out] globaIndexWeightFromDestToSource mapping between transformed global index of grid destination
-             and the weighted value as long as global index from grid index source
+             and the weighted value as well as global index from grid index source
 */
 void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
@@ -30,9 +31,15 @@
                                                              const std::vector<int>& gridSrcGlobalDim,
                                                              const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                             std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource)
+                                                             const std::vector<int>& localIndexGridSendToServer,
+                                                             DestinationIndexMap& globaIndexWeightFromDestToSource)
 {
   bool isTransPosEmpty = transformationPosition_.empty();
-  std::vector<size_t> vecGlobalIndexGridSendToServer(globalIndexGridDestSendToServer.begin(), globalIndexGridDestSendToServer.end());
-  std::sort(vecGlobalIndexGridSendToServer.begin(), vecGlobalIndexGridSendToServer.end());
+  boost::unordered_map<size_t,int> globalLocalIndexDestSendToServerMap;
+  size_t nbGlobalIndexDest = globalIndexGridDestSendToServer.size();
+  for (size_t idx = 0; idx < nbGlobalIndexDest; ++idx)
+  {
+    globalLocalIndexDestSendToServerMap[globalIndexGridDestSendToServer[idx]] = localIndexGridSendToServer[idx];
+  }
+
   for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
   {
@@ -51,20 +58,19 @@
 
     std::vector<std::vector<size_t> > globalIndexSrcGrid;
-    CArray<size_t,1> globalIndexDestGrid;
-//    std::vector<size_t> vecGlobalIndexGridSendToServer(globalIndexGridDestSendToServer.begin(), globalIndexGridDestSendToServer.end());
-//    std::sort(vecGlobalIndexGridSendToServer.begin(), vecGlobalIndexGridSendToServer.end());
+    std::vector<std::pair<size_t,int> > globalLocalIndexDest;
     for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
     {
+      boost::unordered_map<size_t,int> globalLocalIndexDestMap;
       if (!isTransPosEmpty)
       {
         this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
-                                                       itTransMap->second,
-                                                       itTransPos->second,
-                                                       elementPositionInGrid,
-                                                       gridDestGlobalDim,
-                                                       gridSrcGlobalDim,
-                                                       vecGlobalIndexGridSendToServer,
-                                                       globalIndexDestGrid,
-                                                       globalIndexSrcGrid);
+                                                           itTransMap->second,
+                                                           itTransPos->second,
+                                                           elementPositionInGrid,
+                                                           gridDestGlobalDim,
+                                                           gridSrcGlobalDim,
+                                                           globalLocalIndexDestSendToServerMap,
+                                                           globalLocalIndexDest,
+                                                           globalIndexSrcGrid);
         ++itTransPos;
       }
@@ -72,21 +78,23 @@
       {
         this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
-                                                       itTransMap->second,
-                                                       emptyTransPos,
-                                                       elementPositionInGrid,
-                                                       gridDestGlobalDim,
-                                                       gridSrcGlobalDim,
-                                                       vecGlobalIndexGridSendToServer,
-                                                       globalIndexDestGrid,
-                                                       globalIndexSrcGrid);
+                                                           itTransMap->second,
+                                                           emptyTransPos,
+                                                           elementPositionInGrid,
+                                                           gridDestGlobalDim,
+                                                           gridSrcGlobalDim,
+                                                           globalLocalIndexDestSendToServerMap,
+                                                           globalLocalIndexDest,
+                                                           globalIndexSrcGrid);
       }
-      size_t globalIndexSize = globalIndexDestGrid.numElements();
+      std::vector<std::pair<size_t,int> >::const_iterator it = globalLocalIndexDest.begin(), ite = globalLocalIndexDest.end();
       const std::vector<double>& currentVecWeight = itTransWeight->second;
-      for (size_t idx = 0; idx < globalIndexSize; ++idx)
+
+      for (size_t idx = 0; it != ite; ++it, ++idx)
       {
-        size_t globalIndex = globalIndexDestGrid(idx);
-        for (int i = 0; i < globalIndexSrcGrid[idx].size(); ++i)
+        size_t srcGridSize = globalIndexSrcGrid[idx].size();
+        globaIndexWeightFromDestToSource[(it->first)].reserve(srcGridSize);
+        for (int i = 0; i < srcGridSize; ++i)
         {
-          globaIndexWeightFromDestToSource[globalIndex].push_back(make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]));
+          globaIndexWeightFromDestToSource[(it->first)].push_back(make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i])));
         }
       }
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 827)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 829)
@@ -22,4 +22,11 @@
 {
 public:
+  // Stupid global index map, it must be replaced by tuple
+  // Mapping between global index map of DESTINATION and its local index with pair of global index of SOURCE and weights
+  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap;
+protected:
+  typedef boost::unordered_map<size_t,int> GlobalLocalMap;
+
+public:
   CGenericAlgorithmTransformation();
 
@@ -30,5 +37,6 @@
                                 const std::vector<int>& gridSrcGlobalDim,
                                 const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource);
+                                const std::vector<int>& localIndexGridSendToServer,
+                                DestinationIndexMap& globaIndexWeightFromDestToSource);
 
   std::vector<StdString> getIdAuxInputs();
@@ -46,6 +54,6 @@
     \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), this array is already acsending sorted
-    \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] globalLocalIndexDestSendToServerMap pair of global index and local index of destination grid which are to be sent to server(s), this array is already acsending sorted
+    \param[in/out] globalLocalIndexDestMap 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
   */
@@ -56,6 +64,6 @@
                                                         const std::vector<int>& gridDestGlobalDim,
                                                         const std::vector<int>& gridSrcGlobalDim,
-                                                        const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                        std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid) = 0;
 
Index: XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 827)
+++ XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 829)
@@ -19,4 +19,5 @@
 #include "distribution_client.hpp"
 #include "mpi_tag.hpp"
+#include <boost/unordered_map.hpp>
 
 namespace xios {
@@ -359,5 +360,5 @@
   if (nbAlgos_ < 1) return;
   if (!auxInputs_.empty() && !dynamicalTransformation_) { dynamicalTransformation_ = true; return; }
-  if (dynamicalTransformation_) GlobalIndexMap().swap(currentGridIndexToOriginalGridIndex_);  // Reset map
+  if (dynamicalTransformation_) DestinationIndexMap().swap(currentGridIndexToOriginalGridIndex_);  // Reset map
 
   CContext* context = CContext::getCurrent();
@@ -374,5 +375,5 @@
     ETranformationType transType = (it->second).first;
     int transformationOrder = (it->second).second;
-    std::map<size_t, std::vector<std::pair<size_t,double> > > globaIndexWeightFromDestToSource;
+    DestinationIndexMap globaIndexWeightFromDestToSource;
 
     // First of all, select an algorithm
@@ -392,4 +393,5 @@
       CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
       const std::vector<size_t>& globalIndexGridDestSendToServer = distributionClientDest.getGlobalDataIndexSendToServer();
+      const std::vector<int>& localIndexGridDestSendToServer = distributionClientDest.getLocalDataIndexSendToServer();
 
       // ComputeTransformation of global index of each element
@@ -401,4 +403,5 @@
                                      gridSrcDimensionSize,
                                      globalIndexGridDestSendToServer,
+                                     localIndexGridDestSendToServer,
                                      globaIndexWeightFromDestToSource);
 
@@ -446,5 +449,5 @@
   iteArr = globalIndexOnClientDest.end();
 
-  GlobalIndexMap::const_iterator iteGlobalMap = currentGridIndexToOriginalGridIndex_.end();
+  DestinationIndexMap::const_iterator iteGlobalMap = currentGridIndexToOriginalGridIndex_.end();
   const size_t sfmax = NumTraits<unsigned long>::sfmax();
   int maskIndexNum = 0;
@@ -453,8 +456,8 @@
     if (iteGlobalMap != currentGridIndexToOriginalGridIndex_.find(*itArr))
     {
-      const std::vector<std::pair<size_t,double> >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
+      const std::vector<std::pair<int, std::pair<size_t,double> > >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
       for (int idx = 0; idx < vecIndex.size(); ++idx)
       {
-        if (sfmax == vecIndex[idx].first)
+        if (sfmax == (vecIndex[idx].second).first)
         {
           ++maskIndexNum;
@@ -471,8 +474,8 @@
     if (iteGlobalMap != currentGridIndexToOriginalGridIndex_.find(*itArr))
     {
-      const std::vector<std::pair<size_t,double> >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
+      const std::vector<std::pair<int, std::pair<size_t,double> > >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
       for (int idx = 0; idx < vecIndex.size(); ++idx)
       {
-        if (sfmax == vecIndex[idx].first)
+        if (sfmax == (vecIndex[idx].second).first)
         {
           int localIdx = std::distance(itbArr, itArr);
@@ -493,5 +496,5 @@
 the final grid destination
 */
-void CGridTransformation::computeTransformationFromOriginalGridSource(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexMapFromDestToSource)
+void CGridTransformation::computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource)
 {
   CContext* context = CContext::getCurrent();
@@ -509,10 +512,10 @@
   transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
 
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
-  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const CTransformationMapping::SentIndexMap& 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();
+  CTransformationMapping::SentIndexMap::const_iterator itbSend = globalIndexToSend.begin(), itSend,
+                                                       iteSend = globalIndexToSend.end();
  int sendBuffSize = 0;
  for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
@@ -526,6 +529,6 @@
  for (StdSize idx = 0; idx < sendBuffSize; ++idx) sendBuff[idx] = NumTraits<Scalar>::sfmax();
 
- std::map<int, MPI_Request> requestsCurrentGrid, requestsOriginalGrid, requestsWeightGrid;
- GlobalIndexMap::const_iterator iteGlobalIndex = currentGridIndexToOriginalGridIndex_.end();
+ std::map<int, MPI_Request> requestsCurrentGrid, requestsOriginalGridGlobalIndex, requestsOriginalGridLocalIndex, requestsWeightGrid;
+ DestinationIndexMap::const_iterator iteGlobalIndex = currentGridIndexToOriginalGridIndex_.end();
 
   // Only send global index of original source corresponding to non-masked index
@@ -536,11 +539,11 @@
  {
    int destRank = itSend->first;
-   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
+   const std::vector<std::pair<int, size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second;
    int countSize  = globalIndexOfCurrentGridSourceToSend.size();
    size_t countBlock = 0;
    for (int idx = 0; idx < countSize; ++idx)
    {
-     size_t index = globalIndexOfCurrentGridSourceToSend[idx];
-     if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index))// searchCurrentSrc.search(itbIndex, iteIndex, globalIndexOfCurrentGridSourceToSend[idx], itIndex))
+     size_t index = globalIndexOfCurrentGridSourceToSend[idx].second;
+     if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index))
      {
        globalIndexOriginalSrcSendBuffSize += currentGridIndexToOriginalGridIndex_[index].size() + 1; // 1 for number of elements in this block
@@ -555,6 +558,6 @@
  }
 
- Scalar* sendOriginalIndexBuff, *currentOriginalIndexSendBuff;
- if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalIndexBuff = new Scalar [globalIndexOriginalSrcSendBuffSize];
+ Scalar* sendOriginalGlobalIndexBuff, *currentOriginalGlobalIndexSendBuff;
+ if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalGlobalIndexBuff = new Scalar [globalIndexOriginalSrcSendBuffSize];
  double* sendOriginalWeightBuff, *currentOriginalWeightSendBuff;
  if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalWeightBuff = new double [globalIndexOriginalSrcSendBuffSize];
@@ -564,21 +567,21 @@
  {
    int destRank = itSend->first;
-   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
+   const std::vector<std::pair<int, size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second;
    int countSize = globalIndexOfCurrentGridSourceToSend.size();
    int increaseStep = 0;
    for (int idx = 0; idx < countSize; ++idx)
    {
-     size_t index = globalIndexOfCurrentGridSourceToSend[idx];
+     size_t index = globalIndexOfCurrentGridSourceToSend[idx].second;
      if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index))
      {
        size_t vectorSize = currentGridIndexToOriginalGridIndex_[index].size();
-       sendOriginalIndexBuff[currentBuffPosition+increaseStep]  = vectorSize;
+       sendOriginalGlobalIndexBuff[currentBuffPosition+increaseStep]  = vectorSize;
        sendOriginalWeightBuff[currentBuffPosition+increaseStep] = (double)vectorSize;
-       const std::vector<std::pair<size_t,double> >& indexWeightPair = currentGridIndexToOriginalGridIndex_[index];
+       const std::vector<std::pair<int, std::pair<size_t,double> > >& indexWeightPair = currentGridIndexToOriginalGridIndex_[index];
        for (size_t i = 0; i < vectorSize; ++i)
        {
          ++increaseStep;
-         sendOriginalIndexBuff[currentBuffPosition+increaseStep]  = indexWeightPair[i].first;
-         sendOriginalWeightBuff[currentBuffPosition+increaseStep] = indexWeightPair[i].second;
+         sendOriginalGlobalIndexBuff[currentBuffPosition+increaseStep]  = (indexWeightPair[i].second).first;
+         sendOriginalWeightBuff[currentBuffPosition+increaseStep] = (indexWeightPair[i].second).second;
        }
        ++increaseStep;
@@ -586,10 +589,12 @@
    }
 
-   currentOriginalIndexSendBuff = sendOriginalIndexBuff + currentBuffPosition;
+   currentOriginalGlobalIndexSendBuff = sendOriginalGlobalIndexBuff + currentBuffPosition;
    currentOriginalWeightSendBuff = sendOriginalWeightBuff + currentBuffPosition;
    if (0 != increaseStep)
    {
-     MPI_Isend(currentOriginalIndexSendBuff, increaseStep, MPI_UNSIGNED_LONG, destRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_INDEX, client->intraComm, &requestsOriginalGrid[destRank]);
-     MPI_Isend(currentOriginalWeightSendBuff, increaseStep, MPI_DOUBLE, destRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &requestsWeightGrid[destRank]);
+     MPI_Isend(currentOriginalGlobalIndexSendBuff, increaseStep, MPI_UNSIGNED_LONG, destRank,
+               MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_GLOBAL_INDEX, client->intraComm, &requestsOriginalGridGlobalIndex[destRank]);
+     MPI_Isend(currentOriginalWeightSendBuff, increaseStep, MPI_DOUBLE, destRank,
+               MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &requestsWeightGrid[destRank]);
    }
    currentBuffPosition += increaseStep;
@@ -598,6 +603,6 @@
 
  // Receiving global index of grid source sending from current grid source
- std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
-                                                                                     iteRecv = globalIndexToReceive.end();
+ CTransformationMapping::ReceivedIndexMap::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
+                                                          iteRecv = globalIndexToReceive.end();
  int recvBuffSize = 0;
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size();
@@ -623,6 +628,6 @@
  }
 
- Scalar* recvOriginalIndexBuff, *currentOriginalIndexRecvBuff;
- if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalIndexBuff = new Scalar [globalIndexOriginalSrcRecvBuffSize];
+ Scalar* recvOriginalGlobalIndexBuff, *currentOriginalGlobalIndexRecvBuff;
+ if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalGlobalIndexBuff = new Scalar [globalIndexOriginalSrcRecvBuffSize];
  double* recvOriginalWeightBuff, *currentOriginalWeightRecvBuff;
  if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalWeightBuff = new double [globalIndexOriginalSrcRecvBuffSize];
@@ -633,12 +638,12 @@
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
  {
-   MPI_Status statusIndex, statusWeight;
+   MPI_Status statusGlobalIndex, statusLocalIndex, statusWeight;
    int srcRank = itRecv->first;
    countBlock = countBlockMap[srcRank];
-   currentOriginalIndexRecvBuff = recvOriginalIndexBuff + currentBuffPosition;
+   currentOriginalGlobalIndexRecvBuff = recvOriginalGlobalIndexBuff + currentBuffPosition;
    currentOriginalWeightRecvBuff = recvOriginalWeightBuff + currentBuffPosition;
    if (0 != countBlock)
    {
-     MPI_Recv(currentOriginalIndexRecvBuff, countBlock, MPI_UNSIGNED_LONG, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_INDEX, client->intraComm, &statusIndex);
+     MPI_Recv(currentOriginalGlobalIndexRecvBuff, countBlock, MPI_UNSIGNED_LONG, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_GLOBAL_INDEX, client->intraComm, &statusGlobalIndex);
      MPI_Recv(currentOriginalWeightRecvBuff, countBlock, MPI_DOUBLE, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &statusWeight);
    }
@@ -649,9 +654,9 @@
  // The way to process masked index needs discussing
  const size_t sfmax = NumTraits<unsigned long>::sfmax();
- GlobalIndexMap currentToOriginalTmp;
+ DestinationIndexMap currentToOriginalTmp;
 
  currentRecvBuffPosition = 0;
  currentRecvBuff = recvBuff;
- currentOriginalIndexRecvBuff  = recvOriginalIndexBuff;
+ currentOriginalGlobalIndexRecvBuff  = recvOriginalGlobalIndexBuff;
  currentOriginalWeightRecvBuff = recvOriginalWeightBuff;
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
@@ -669,12 +674,13 @@
        if (0 != countBlockRank)
        {
-         countBlock = *(currentOriginalIndexRecvBuff+currentRecvBuffPosition);
+         countBlock = *(currentOriginalGlobalIndexRecvBuff+currentRecvBuffPosition);
          for (int i = 0; i < ssize; ++i)
          {
            for (int j = 0; j < countBlock; ++j)
            {
-             size_t globalOriginalIndex = *(currentOriginalIndexRecvBuff+currentRecvBuffPosition+j+1);
-             double weightGlobal = *(currentOriginalWeightRecvBuff+currentRecvBuffPosition+j+1) * (itRecv->second)[idx][i].second;
-             currentToOriginalTmp[(itRecv->second)[idx][i].first].push_back(make_pair(globalOriginalIndex,weightGlobal));
+             size_t globalOriginalIndex = *(currentOriginalGlobalIndexRecvBuff+currentRecvBuffPosition+j+1);
+             int currentGridLocalIndex = (itRecv->second)[idx][i].first;
+             double weightGlobal = *(currentOriginalWeightRecvBuff+currentRecvBuffPosition+j+1) * (itRecv->second)[idx][i].second.second;
+             currentToOriginalTmp[(itRecv->second)[idx][i].second.first].push_back(make_pair(currentGridLocalIndex,make_pair(globalOriginalIndex,weightGlobal)));
            }
          }
@@ -697,5 +703,5 @@
  for (itRequest = requestsCurrentGrid.begin(); itRequest != requestsCurrentGrid.end(); ++itRequest)
    MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE);
- for (itRequest = requestsOriginalGrid.begin(); itRequest != requestsOriginalGrid.end(); ++itRequest)
+ for (itRequest = requestsOriginalGridGlobalIndex.begin(); itRequest != requestsOriginalGridGlobalIndex.end(); ++itRequest)
    MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE);
  for (itRequest = requestsWeightGrid.begin(); itRequest != requestsWeightGrid.end(); ++itRequest)
@@ -704,7 +710,7 @@
  if (0 != sendBuffSize) delete [] sendBuff;
  if (0 != recvBuffSize) delete [] recvBuff;
- if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalIndexBuff;
+ if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalGlobalIndexBuff;
  if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalWeightBuff;
- if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalIndexBuff;
+ if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalGlobalIndexBuff;
  if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalWeightBuff;
 }
@@ -724,26 +730,26 @@
   transformationMap.computeTransformationMapping(currentGridIndexToOriginalGridIndex_);
 
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& 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 std::vector<size_t>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
-  const std::vector<size_t>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer();
-
-  std::vector<size_t>::const_iterator itbArr, itArr, iteArr;
-  std::vector<int>::const_iterator itIndex, itbIndex, iteIndex;
-  std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
-
-  std::vector<int> permutIndex;
-  typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
-
-  // Find out local index on grid destination (received)
-  XIOSAlgorithms::fillInIndex(globalIndexOnClientDest.size(), permutIndex);
-  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientDest, permutIndex);
-  itbIndex = permutIndex.begin();
-  iteIndex = permutIndex.end();
-  BinarySearch searchClientDest(globalIndexOnClientDest);
+  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+
+//  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
+//  CDistributionClient distributionClientSrc(client->clientRank, originalGridSource_);
+//
+//  const std::vector<size_t>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
+//  const std::vector<size_t>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer();
+
+//  std::vector<size_t>::const_iterator itbArr, itArr, iteArr;
+//  std::vector<int>::const_iterator itIndex, itbIndex, iteIndex;
+  CTransformationMapping::ReceivedIndexMap::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
+
+//  std::vector<int> permutIndex;
+//  typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
+//
+//  // Find out local index on grid destination (received)
+//  XIOSAlgorithms::fillInIndex(globalIndexOnClientDest.size(), permutIndex);
+//  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientDest, permutIndex);
+//  itbIndex = permutIndex.begin();
+//  iteIndex = permutIndex.end();
+//  BinarySearch searchClientDest(globalIndexOnClientDest);
   itbMapRecv = globalIndexToReceive.begin();
   iteMapRecv = globalIndexToReceive.end();
@@ -756,25 +762,27 @@
     {
       int vecSize = ((itMapRecv->second)[i]).size();
-      std::vector<std::pair<int,double> > tmpVec;
+//      std::vector<std::pair<int,double> > tmpVec;
       for (int idx = 0; idx < vecSize; ++idx)
       {
-        size_t globalIndex = (itMapRecv->second)[i][idx].first;
-        double weight = (itMapRecv->second)[i][idx].second;
-        if (searchClientDest.search(itbIndex, iteIndex, globalIndex, itIndex))
-        {
-          tmpVec.push_back(make_pair(*itIndex, weight));
-        }
+        const std::pair<int, std::pair<size_t,double> >& tmpPair = (itMapRecv->second)[i][idx];
+        localIndexToReceiveOnGridDest_[sourceRank][i].push_back(make_pair(tmpPair.first, tmpPair.second.second));
+//        size_t globalIndex = (itMapRecv->second)[i][idx].first;
+//        double weight = (itMapRecv->second)[i][idx].second;
+//        if (searchClientDest.search(itbIndex, iteIndex, globalIndex, itIndex))
+//        {
+//          tmpVec.push_back(make_pair(*itIndex, weight));
+//        }
       }
-      localIndexToReceiveOnGridDest_[sourceRank][i] = tmpVec;
+//      localIndexToReceiveOnGridDest_[sourceRank][i] = tmpVec;
     }
   }
 
   // Find out local index on grid source (to send)
-  std::map<int,std::vector<size_t> >::const_iterator itbMap, itMap, iteMap;
-  XIOSAlgorithms::fillInIndex(globalIndexOnClientSrc.size(), permutIndex);
-  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientSrc, permutIndex);
-  itbIndex = permutIndex.begin();
-  iteIndex = permutIndex.end();
-  BinarySearch searchClientSrc(globalIndexOnClientSrc);
+  CTransformationMapping::SentIndexMap::const_iterator itbMap, itMap, iteMap;
+//  XIOSAlgorithms::fillInIndex(globalIndexOnClientSrc.size(), permutIndex);
+//  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientSrc, permutIndex);
+//  itbIndex = permutIndex.begin();
+//  iteIndex = permutIndex.end();
+//  BinarySearch searchClientSrc(globalIndexOnClientSrc);
   itbMap = globalIndexToSend.begin();
   iteMap = globalIndexToSend.end();
@@ -786,8 +794,8 @@
     for (int idx = 0; idx < vecSize; ++idx)
     {
-      if (searchClientSrc.search(itbIndex, iteIndex, itMap->second[idx], itIndex))
-      {
-        localIndexToSendFromGridSource_[destRank](idx) = *itIndex;
-      }
+//      if (searchClientSrc.search(itbIndex, iteIndex, itMap->second[idx], itIndex))
+//      {
+        localIndexToSendFromGridSource_[destRank](idx) = itMap->second[idx].first; //*itIndex;
+//      }
     }
   }
Index: XIOS/trunk/src/transformation/grid_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 827)
+++ XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 829)
@@ -35,4 +35,5 @@
 public:
   typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
+  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap;
 
 public:
@@ -63,5 +64,5 @@
   void setUpGrid(int elementPositionInGrid, ETranformationType transType, int nbTransformation);
   void computeFinalTransformationMapping();
-  void computeTransformationFromOriginalGridSource(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexMapFromDestToSource);
+  void computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource);
   void updateFinalGridDestination();
   bool isSpecialTransformation(ETranformationType transType);
@@ -84,6 +85,4 @@
   int nbAlgos_;
 
-  typedef std::map<size_t, std::vector<std::pair<size_t,double> > > GlobalIndexMap;
-
   // true if domain algorithm and false if axis algorithm (can be replaced by tuple with listAlgos_
   std::vector<bool> algoTypes_;
@@ -105,5 +104,5 @@
 
   //! (Grid) Global index of grid source
-  GlobalIndexMap currentGridIndexToOriginalGridIndex_;
+  DestinationIndexMap currentGridIndexToOriginalGridIndex_;
 
   std::vector<CGrid*> tempGrids_;
Index: XIOS/trunk/src/transformation/transformation_mapping.cpp
===================================================================
--- XIOS/trunk/src/transformation/transformation_mapping.cpp	(revision 827)
+++ XIOS/trunk/src/transformation/transformation_mapping.cpp	(revision 829)
@@ -13,4 +13,7 @@
 #include "context_client.hpp"
 #include "distribution_client.hpp"
+#include "client_client_dht_template.hpp"
+#include "dht_data_types.hpp"
+#include "mpi_tag.hpp"
 
 namespace xios {
@@ -26,14 +29,20 @@
 
   const std::vector<size_t>& globalIndexGridSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
-  boost::unordered_map<size_t,int> globalIndexOfServer;
+  const std::vector<int>& localIndexGridSrc = distributionClientSrc.getLocalDataIndexSendToServer();
+
+  // Mapping of global index and pair containing rank and local index
+  CClientClientDHTPairIntInt::Index2InfoTypeMap globalIndexOfServer;
   int globalIndexSize = globalIndexGridSrc.size();
+  PairIntInt pii;
   for (int idx = 0; idx < globalIndexSize; ++idx)
   {
-    globalIndexOfServer[globalIndexGridSrc[idx]] = clientRank;
-  }
-
-  gridIndexClientClientMapping_ = new CClientServerMappingDistributed(globalIndexOfServer,
-                                                                      client->intraComm,
-                                                                      true);
+    pii.first  = clientRank;
+    pii.second = localIndexGridSrc[idx];
+    globalIndexOfServer[globalIndexGridSrc[idx]] = pii; //std::make_pair(clientRank, localIndexGridSrc[idx]);
+  }
+
+  gridIndexClientClientMapping_ = new CClientClientDHTPairIntInt(globalIndexOfServer,
+                                                                 client->intraComm,
+                                                                 true);
 }
 
@@ -48,13 +57,16 @@
   int ibeginSrc = source->begin.getValue();
 
-  boost::unordered_map<size_t,int> globalIndexOfAxisSource;
+  CClientClientDHTPairIntInt::Index2InfoTypeMap globalIndexOfAxisSource;
+  PairIntInt pii;
   for (int idx = 0; idx < niSrc; ++idx)
   {
-    globalIndexOfAxisSource[idx+ibeginSrc] = clientRank;
-  }
-
-  gridIndexClientClientMapping_ = new CClientServerMappingDistributed(globalIndexOfAxisSource,
-                                                                      client->intraComm,
-                                                                      true);
+    pii.first  = clientRank;
+    pii.second = idx;
+    globalIndexOfAxisSource[idx+ibeginSrc] = pii; //std::make_pair(clientRank,idx);
+  }
+
+  gridIndexClientClientMapping_ = new CClientClientDHTPairIntInt(globalIndexOfAxisSource,
+                                                                 client->intraComm,
+                                                                 true);
 }
 
@@ -71,16 +83,17 @@
   \param [in] globaIndexWeightFromDestToSource mapping representing the transformations
 */
-void CTransformationMapping::computeTransformationMapping(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource)
+void CTransformationMapping::computeTransformationMapping(const DestinationIndexMap& globaIndexWeightFromDestToSource)
 {
   CContext* context = CContext::getCurrent();
   CContextClient* client=context->client;
 
-  std::map<size_t, std::vector<std::pair<size_t,double> > >::const_iterator itbMap = globaIndexWeightFromDestToSource.begin(), itMap,
-                                                                            iteMap = globaIndexWeightFromDestToSource.end();
+  DestinationIndexMap::const_iterator itbMap = globaIndexWeightFromDestToSource.begin(), itMap,
+                                      iteMap = globaIndexWeightFromDestToSource.end();
 
   // Not only one index on grid destination can demande two indexes from grid source
   // but an index on grid source has to be sent to two indexes of grid destination
-  std::map<size_t, std::vector<std::pair<size_t,double> > > globalIndexMapFromSrcToDest;
-  std::vector<std::pair<size_t,double> >::const_iterator itbVecPair, itVecPair, iteVecPair;
+  DestinationIndexMap globalIndexMapFromSrcToDest;
+  boost::unordered_map<size_t, int> nbGlobalIndexMapFromSrcToDest;
+  std::vector<std::pair<int, std::pair<size_t,double> > >::const_iterator itbVecPair, itVecPair, iteVecPair;
   for (itMap = itbMap; itMap != iteMap; ++itMap)
   {
@@ -89,5 +102,21 @@
     for (itVecPair = itbVecPair; itVecPair != iteVecPair; ++itVecPair)
     {
-      globalIndexMapFromSrcToDest[itVecPair->first].push_back(std::make_pair(itMap->first, itVecPair->second));
+      ++nbGlobalIndexMapFromSrcToDest[(itVecPair->second).first];
+    }
+  }
+
+  for (boost::unordered_map<size_t, int>::const_iterator it = nbGlobalIndexMapFromSrcToDest.begin();
+                                                         it != nbGlobalIndexMapFromSrcToDest.end(); ++it)
+  {
+    globalIndexMapFromSrcToDest[it->first].reserve(it->second);
+  }
+
+  for (itMap = itbMap; itMap != iteMap; ++itMap)
+  {
+    itbVecPair = (itMap->second).begin();
+    iteVecPair = (itMap->second).end();
+    for (itVecPair = itbVecPair; itVecPair != iteVecPair; ++itVecPair)
+    {
+      globalIndexMapFromSrcToDest[(itVecPair->second).first].push_back(std::make_pair(itVecPair->first, std::make_pair(itMap->first, (itVecPair->second).second)));
     }
   }
@@ -95,46 +124,42 @@
   // All global indexes of a client on grid destination
   CArray<size_t,1> globalIndexMap(globalIndexMapFromSrcToDest.size());
-  itbMap = globalIndexMapFromSrcToDest.begin();
-  iteMap = globalIndexMapFromSrcToDest.end();
+  DestinationIndexMap::const_iterator itbMapBoost = globalIndexMapFromSrcToDest.begin(), itMapBoost;
+  DestinationIndexMap::const_iterator iteMapBoost = globalIndexMapFromSrcToDest.end();
   int idx = 0;
-  for (itMap = itbMap; itMap != iteMap; ++itMap)
-  {
-    globalIndexMap(idx) = itMap->first;
+  for (itMapBoost = itbMapBoost; itMapBoost != iteMapBoost; ++itMapBoost)
+  {
+    globalIndexMap(idx) = itMapBoost->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();
+  gridIndexClientClientMapping_->computeIndexInfoMapping(globalIndexMap);
+  const CClientClientDHTPairIntInt::Index2InfoTypeMap& globalIndexSentFromGridSource = gridIndexClientClientMapping_->getInfoIndexMap();
+  CClientClientDHTPairIntInt::Index2InfoTypeMap::const_iterator itbMapSrc = globalIndexSentFromGridSource.begin(), itMapSrc,
+                                                                iteMapSrc = globalIndexSentFromGridSource.end();
   std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
+    // Inform client about the destination to which it needs to send global indexes
+  int nbClient = client->clientSize;
+  std::vector<int> sendNbClientBuff(nbClient,0);
+  std::vector<int> recvNbClientBuff(nbClient,0);
+  std::vector<int> sendIndexBuff(nbClient,0);
+  std::vector<int> recvIndexBuff(nbClient,0);
+  boost::unordered_map<int,std::vector<size_t> > sendIndexMap;
   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];
+    int sourceRank = (itMapSrc->second).first;
+    (globalIndexReceivedOnGridDestMapping_[sourceRank]).push_back(globalIndexMapFromSrcToDest[itMapSrc->first]);
+    sendIndexMap[sourceRank].push_back((itMapSrc->second).second);
+    sendIndexMap[sourceRank].push_back(itMapSrc->first);
+    sendNbClientBuff[sourceRank] = 1;
+    ++sendIndexBuff[sourceRank];
+  }
+
+  MPI_Allreduce(&sendNbClientBuff[0], &recvNbClientBuff[0], nbClient, MPI_INT, MPI_SUM, client->intraComm);
+  int numClientToReceive = recvNbClientBuff[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];
+  MPI_Allreduce(&sendIndexBuff[0], &recvIndexBuff[0], nbClient, MPI_INT, MPI_MAX, client->intraComm);
+  int buffSize = 2*recvIndexBuff[client->clientRank]; // we send global as well as local index
   unsigned long* recvBuffGlobalIndex;
   if (0 != buffSize) recvBuffGlobalIndex = new unsigned long [buffSize];
@@ -143,14 +168,16 @@
 
   // Inform all "source clients" about index that they need to send
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc)
-  {
-    unsigned long* sendPtr = const_cast<unsigned long*>(&(itMapSrc->second)[0]);
+  boost::unordered_map<int,std::vector<size_t> >::const_iterator itSendIndex = sendIndexMap.begin(),
+                                                                 iteSendIndex= sendIndexMap.end();
+  for (; itSendIndex != iteSendIndex; ++itSendIndex)
+  {
+    unsigned long* sendPtr = const_cast<unsigned long*>(&(itSendIndex->second)[0]);
     MPI_Isend(sendPtr,
-              (itMapSrc->second).size(),
+              (itSendIndex->second).size(),
               MPI_UNSIGNED_LONG,
-              itMapSrc->first,
-              11,
+              (itSendIndex->first),
+              MPI_TRANSFORMATION_MAPPING_INDEX,
               client->intraComm,
-              &requests[itMapSrc->first]);
+              &requests[(itSendIndex->first)]);
   }
 
@@ -165,5 +192,5 @@
              MPI_UNSIGNED_LONG,
              MPI_ANY_SOURCE,
-             11,
+             MPI_TRANSFORMATION_MAPPING_INDEX,
              client->intraComm,
              &status);
@@ -171,7 +198,7 @@
     MPI_Get_count(&status, MPI_UNSIGNED_LONG, &countBuff);
     int clientDestRank = status.MPI_SOURCE;
-    for (int idx = 0; idx < countBuff; ++idx)
+    for (int idx = 0; idx < countBuff; idx += 2)
     {
-      globalIndexSendToGridDestMapping_[clientDestRank].push_back(recvBuffGlobalIndex[idx]);
+      globalIndexSendToGridDestMapping_[clientDestRank].push_back(std::make_pair<int,size_t>(recvBuffGlobalIndex[idx], recvBuffGlobalIndex[idx+1]));
     }
     ++numClientReceived;
@@ -182,6 +209,4 @@
     MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE);
 
-  delete [] sendBuff;
-  delete [] recvBuff;
   if (0 != buffSize) delete [] recvBuffGlobalIndex;
 }
@@ -192,5 +217,5 @@
   \return global index mapping to receive on grid destination
 */
-const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& CTransformationMapping::getGlobalIndexReceivedOnGridDestMapping() const
+const CTransformationMapping::ReceivedIndexMap& CTransformationMapping::getGlobalIndexReceivedOnGridDestMapping() const
 {
   return globalIndexReceivedOnGridDestMapping_;
@@ -202,5 +227,5 @@
   \return global index mapping to send on grid source
 */
-const std::map<int,std::vector<size_t> >& CTransformationMapping::getGlobalIndexSendToGridDestMapping() const
+const CTransformationMapping::SentIndexMap& CTransformationMapping::getGlobalIndexSendToGridDestMapping() const
 {
   return globalIndexSendToGridDestMapping_;
Index: XIOS/trunk/src/transformation/transformation_mapping.hpp
===================================================================
--- XIOS/trunk/src/transformation/transformation_mapping.hpp	(revision 827)
+++ XIOS/trunk/src/transformation/transformation_mapping.hpp	(revision 829)
@@ -28,4 +28,9 @@
 {
 public:
+  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap;
+  typedef boost::unordered_map<int,std::vector<std::vector<std::pair<int, std::pair<size_t,double> > > > > ReceivedIndexMap;
+  typedef boost::unordered_map<int,std::vector<std::pair<int, size_t> > > SentIndexMap;
+
+public:
   /** Default constructor */
   CTransformationMapping(CGrid* destination, CGrid* source);
@@ -34,7 +39,7 @@
   ~CTransformationMapping();
 
-  void computeTransformationMapping(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexMapFromDestToSource);
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& getGlobalIndexReceivedOnGridDestMapping() const;
-  const std::map<int,std::vector<size_t> >& getGlobalIndexSendToGridDestMapping() const;
+  void computeTransformationMapping(const DestinationIndexMap& globaIndexMapFromDestToSource);
+  const ReceivedIndexMap& getGlobalIndexReceivedOnGridDestMapping() const;
+  const SentIndexMap& getGlobalIndexSendToGridDestMapping() const;
 
 protected:
@@ -43,11 +48,11 @@
 
   //! Global index mapping of grid source and grid destination between two clients
-  CClientServerMappingDistributed* gridIndexClientClientMapping_;
+  CClientClientDHTPairIntInt* gridIndexClientClientMapping_;
 
   //! Mapping of client rank of grid source and global index received in grid destination
-  std::map<int,std::vector<std::vector<std::pair<size_t,double> > > > globalIndexReceivedOnGridDestMapping_;
+  ReceivedIndexMap globalIndexReceivedOnGridDestMapping_;
 
   //! Mapping of client rank of grid destination and global index to send from grid source
-  std::map<int,std::vector<size_t> > globalIndexSendToGridDestMapping_;
+  SentIndexMap globalIndexSendToGridDestMapping_;
 };
 
