Index: /XIOS/trunk/inputs/Version2/iodef.xml
===================================================================
--- /XIOS/trunk/inputs/Version2/iodef.xml	(revision 630)
+++ /XIOS/trunk/inputs/Version2/iodef.xml	(revision 631)
@@ -54,6 +54,6 @@
      </axis>
      <axis id="axis_H" axis_ref="axis_C">
-<!--       <inverse_axis />-->
-       <zoom_axis zoom_begin="0" zoom_size="3" />
+       <inverse_axis />
+       <zoom_axis zoom_begin="0" zoom_size="1" />
      </axis>
    </axis_definition>
@@ -61,4 +61,8 @@
    <domain_definition>
      <domain id="domain_A" />
+     <domain id="domain_A_zoom" domain_ref="domain_A">
+       <zoom_domain zoom_ibegin="1" zoom_ni="3" zoom_jbegin="0" zoom_nj="4"/>
+       <zoom_domain zoom_ibegin="0" zoom_ni="2" zoom_jbegin="0" zoom_nj="2"/>
+     </domain>
    </domain_definition>
 
@@ -82,6 +86,7 @@
        </grid>
        <grid id="grid_Axis_tranformed">
-         <domain domain_ref="domain_A" />
-            <axis axis_ref="axis_H" />
+<!--         <domain domain_ref="domain_A" />-->
+         <domain domain_ref="domain_A_zoom" />
+         <axis axis_ref="axis_H" />
 <!--         <axis axis_ref="axis_E" />-->
 <!--         <axis axis_ref="axis_F" />-->
Index: /XIOS/trunk/src/config/node_type.conf
===================================================================
--- /XIOS/trunk/src/config/node_type.conf	(revision 630)
+++ /XIOS/trunk/src/config/node_type.conf	(revision 631)
@@ -43,4 +43,8 @@
 #endif //__XIOS_CInterpolateAxis__
 
+#ifdef __XIOS_CZoomDomain__
+   DECLARE_NODE(ZoomDomain, zoom_domain)
+#endif //__XIOS_CZoomDomain__
+
 #ifdef __XIOS_CContext__
    DECLARE_NODE_PAR(Context, context)
Index: /XIOS/trunk/src/config/zoom_domain_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/zoom_domain_attribute.conf	(revision 631)
+++ /XIOS/trunk/src/config/zoom_domain_attribute.conf	(revision 631)
@@ -0,0 +1,11 @@
+/* GLOBAL */
+DECLARE_ATTRIBUTE(int             , zoom_ni)
+DECLARE_ATTRIBUTE(int             , zoom_nj)
+DECLARE_ATTRIBUTE(int             , zoom_ibegin)
+DECLARE_ATTRIBUTE(int             , zoom_jbegin)
+
+/* LOCAL */
+DECLARE_ATTRIBUTE(int             , zoom_ni_loc)
+DECLARE_ATTRIBUTE(int             , zoom_nj_loc)
+DECLARE_ATTRIBUTE(int             , zoom_ibegin_loc)
+DECLARE_ATTRIBUTE(int             , zoom_jbegin_loc)
Index: /XIOS/trunk/src/distribution_client.cpp
===================================================================
--- /XIOS/trunk/src/distribution_client.cpp	(revision 630)
+++ /XIOS/trunk/src/distribution_client.cpp	(revision 631)
@@ -200,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]->global_zoom_jbegin;
+      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->global_zoom_jbegin + domList[domIndex]->global_zoom_nj-1;
 
       dataBegin_.at(indexMap_[idx]+1) = (2 == domList[domIndex]->data_dim) ? domList[domIndex]->data_jbegin.getValue() : -1;
@@ -212,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]->global_zoom_ibegin;
+      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->global_zoom_ibegin + domList[domIndex]->global_zoom_ni-1;
 
       dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
Index: /XIOS/trunk/src/group_factory_decl.cpp
===================================================================
--- /XIOS/trunk/src/group_factory_decl.cpp	(revision 630)
+++ /XIOS/trunk/src/group_factory_decl.cpp	(revision 631)
@@ -28,3 +28,4 @@
   macro(CZoomAxisGroup)
   macro(CInterpolateAxisGroup)
+  macro(CZoomDomainGroup)
 }
Index: /XIOS/trunk/src/group_template_decl.cpp
===================================================================
--- /XIOS/trunk/src/group_template_decl.cpp	(revision 630)
+++ /XIOS/trunk/src/group_template_decl.cpp	(revision 631)
@@ -17,4 +17,5 @@
   macro(ZoomAxis)
   macro(InterpolateAxis)
+  macro(ZoomDomain)
 
 }
Index: /XIOS/trunk/src/node/axis.cpp
===================================================================
--- /XIOS/trunk/src/node/axis.cpp	(revision 630)
+++ /XIOS/trunk/src/node/axis.cpp	(revision 631)
@@ -104,8 +104,8 @@
 //               << "The array \'value\' of axis [ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] has a different size that the one defined by the \'size\' attribute");
 
-      if (0 == global_zoom_size) global_zoom_size = size;
+
       this->checkData();
       this->checkMask();
-//      this->checkZoom();
+      this->checkZoom();
 
       if (!bounds.isEmpty())
@@ -138,25 +138,8 @@
    }
 
-//   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)
+   {
+     if (0 == global_zoom_size) global_zoom_size = this->size.getValue();
+   }
 
    void CAxis::checkMask()
Index: /XIOS/trunk/src/node/axis.hpp
===================================================================
--- /XIOS/trunk/src/node/axis.hpp	(revision 630)
+++ /XIOS/trunk/src/node/axis.hpp	(revision 631)
@@ -105,5 +105,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/domain.cpp
===================================================================
--- /XIOS/trunk/src/node/domain.cpp	(revision 630)
+++ /XIOS/trunk/src/node/domain.cpp	(revision 631)
@@ -16,4 +16,5 @@
 #include "server_distribution_description.hpp"
 #include "client_server_mapping_distributed.hpp"
+#include "zoom_domain.hpp"
 
 namespace xios {
@@ -547,17 +548,33 @@
 
       // compute client zoom indices
-
-      int zoom_iend=zoom_ibegin+zoom_ni-1 ;
-      zoom_ibegin_client = ibegin_client > zoom_ibegin ? ibegin_client : zoom_ibegin ;
-      zoom_iend_client = iend_client < zoom_iend ? iend_client : zoom_iend ;
+      // compute client zoom indices
+      if (0 == global_zoom_ni) global_zoom_ni = ni_glo;
+      if (0 == global_zoom_nj) global_zoom_nj = nj_glo;
+
+      int global_zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
+      zoom_ibegin_client = ibegin_client > global_zoom_ibegin ? ibegin_client : global_zoom_ibegin ;
+      zoom_iend_client = iend_client < global_zoom_iend ? iend_client : global_zoom_iend ;
       zoom_ni_client=zoom_iend_client-zoom_ibegin_client+1 ;
       if (zoom_ni_client<0) zoom_ni_client=0 ;
 
 
-      int zoom_jend=zoom_jbegin+zoom_nj-1 ;
-      zoom_jbegin_client = jbegin_client > zoom_jbegin ? jbegin_client : zoom_jbegin ;
-      zoom_jend_client = jend_client < zoom_jend ? jend_client : zoom_jend ;
+      int global_zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
+      zoom_jbegin_client = jbegin_client > global_zoom_jbegin ? jbegin_client : global_zoom_jbegin ;
+      zoom_jend_client = jend_client < global_zoom_jend ? jend_client : global_zoom_jend ;
       zoom_nj_client=zoom_jend_client-zoom_jbegin_client+1 ;
       if (zoom_nj_client<0) zoom_nj_client=0 ;
+
+//      int zoom_iend=zoom_ibegin+zoom_ni-1 ;
+//      zoom_ibegin_client = ibegin_client > zoom_ibegin ? ibegin_client : zoom_ibegin ;
+//      zoom_iend_client = iend_client < zoom_iend ? iend_client : zoom_iend ;
+//      zoom_ni_client=zoom_iend_client-zoom_ibegin_client+1 ;
+//      if (zoom_ni_client<0) zoom_ni_client=0 ;
+//
+//
+//      int zoom_jend=zoom_jbegin+zoom_nj-1 ;
+//      zoom_jbegin_client = jbegin_client > zoom_jbegin ? jbegin_client : zoom_jbegin ;
+//      zoom_jend_client = jend_client < zoom_jend ? jend_client : zoom_jend ;
+//      zoom_nj_client=zoom_jend_client-zoom_jbegin_client+1 ;
+//      if (zoom_nj_client<0) zoom_nj_client=0 ;
 
    }
@@ -598,5 +615,5 @@
 
       this->checkDomain();
-      this->checkZoom();
+//      this->checkZoom();
       this->checkBounds();
       this->checkArea();
@@ -607,6 +624,6 @@
          this->checkDomainData();
          this->checkCompression();
-         this->completeLonLatClient();
-         this->computeConnectedServer() ;
+//         this->completeLonLatClient();
+//         this->computeConnectedServer() ;
       }
       else
@@ -625,7 +642,11 @@
      CContext* context=CContext::getCurrent() ;
 
+     this->checkZoom();
      if (this->isChecked) return;
      if (context->hasClient)
      {
+       this->computeConnectedServer();
+       this->completeLonLatClient();
+
        sendServerAttribut() ;
        sendLonLatArea() ;
@@ -703,4 +724,5 @@
         msg << this->getId() ;
         msg << ni_srv << ibegin_srv << iend_srv << nj_srv << jbegin_srv << jend_srv;
+        msg << global_zoom_ni << global_zoom_ibegin << global_zoom_nj << global_zoom_jbegin;
 
         event.push(*itRank,1,msg);
@@ -722,6 +744,6 @@
 
     int i,j,i_ind,j_ind ;
-    int zoom_iend=zoom_ibegin+zoom_ni-1 ;
-    int zoom_jend=zoom_jbegin+zoom_nj-1 ;
+    int zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
+    int zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
 
     // Precompute number of index
@@ -733,5 +755,5 @@
         j_ind=jbegin+j_index(i,j) ;
 
-        if (i_ind >= zoom_ibegin && i_ind <= zoom_iend && j_ind >= zoom_jbegin && j_ind <= zoom_jend)
+        if (i_ind >= global_zoom_ibegin && i_ind <= zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= zoom_jend)
         {
           ++globalIndexCountZoom;
@@ -755,5 +777,5 @@
         globalIndexDomain(globalIndexCount) = globalIndex;
         ++globalIndexCount;
-        if (i_ind >= zoom_ibegin && i_ind <= zoom_iend && j_ind >= zoom_jbegin && j_ind <= zoom_jend)
+        if (i_ind >= global_zoom_ibegin && i_ind <= zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= zoom_jend)
         {
           globalIndexDomainZoom(globalIndexCountZoom) = globalIndex;
@@ -976,14 +998,15 @@
   void CDomain::recvServerAttribut(CBufferIn& buffer)
   {
-    int zoom_iend = zoom_ibegin.getValue() + zoom_ni.getValue() - 1;
-    int zoom_jend = zoom_jbegin.getValue() + zoom_nj.getValue() - 1;
-
-    buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv;
-
-    zoom_ibegin_srv = zoom_ibegin.getValue() > ibegin_srv ? zoom_ibegin.getValue() : ibegin_srv ;
+    buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv
+           >> global_zoom_ni >> global_zoom_ibegin >> global_zoom_nj >> global_zoom_jbegin;
+
+    int zoom_iend = global_zoom_ibegin + global_zoom_ni - 1;
+    int zoom_jend = global_zoom_jbegin + global_zoom_nj - 1;
+
+    zoom_ibegin_srv = global_zoom_ibegin > ibegin_srv ? global_zoom_ibegin : ibegin_srv ;
     zoom_iend_srv = zoom_iend < iend_srv ? zoom_iend : iend_srv ;
     zoom_ni_srv=zoom_iend_srv-zoom_ibegin_srv+1 ;
 
-    zoom_jbegin_srv = zoom_jbegin.getValue() > jbegin_srv ? zoom_jbegin.getValue() : jbegin_srv ;
+    zoom_jbegin_srv = global_zoom_jbegin > jbegin_srv ? global_zoom_jbegin : jbegin_srv ;
     zoom_jend_srv = zoom_jend < jend_srv ? zoom_jend : jend_srv ;
     zoom_nj_srv=zoom_jend_srv-zoom_jbegin_srv+1 ;
@@ -1127,4 +1150,72 @@
   }
 
+  bool CDomain::hasTransformation()
+  {
+    return (!transformationMap_.empty());
+  }
+
+  void CDomain::setTransformations(const TransMapTypes& domTrans)
+  {
+    transformationMap_ = domTrans;
+  }
+
+  CDomain::TransMapTypes CDomain::getAllTransformations(void)
+  {
+    return transformationMap_;
+  }
+
+  /*!
+    Check the validity of all transformations applied on domain
+  This functions is called AFTER all inherited attributes are solved
+  */
+  void CDomain::checkTransformations()
+  {
+    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
+                                  ite = transformationMap_.end();
+    for (it = itb; it != ite; ++it)
+    {
+      (it->second)->checkValid(this);
+    }
+  }
+
+  void CDomain::solveInheritanceTransformation()
+  {
+    if (this->hasTransformation()) return;
+
+    std::vector<CDomain*> refDomain;
+    CDomain* refer_sptr;
+    CDomain* refer_ptr = this;
+    while (refer_ptr->hasDirectDomainReference())
+    {
+      refDomain.push_back(refer_ptr);
+      refer_sptr = refer_ptr->getDirectDomainReference();
+      refer_ptr  = refer_sptr;
+      if (refer_ptr->hasTransformation()) break;
+    }
+
+    if (refer_ptr->hasTransformation())
+      for (int idx = 0; idx < refDomain.size(); ++idx)
+        refDomain[idx]->setTransformations(refer_ptr->getAllTransformations());
+  }
+
+  void CDomain::parse(xml::CXMLNode & node)
+  {
+    SuperClass::parse(node);
+
+    if (node.goToChildElement())
+    {
+      StdString zoomDomainDefRoot("zoom_domain_definition");
+      StdString zoom("zoom_domain");
+      do
+      {
+        if (node.getElementName() == zoom) {
+          CZoomDomain* tmp = (CZoomDomainGroup::get(zoomDomainDefRoot))->createChild();
+          tmp->parse(node);
+          transformationMap_.push_back(std::make_pair(TRANS_ZOOM_DOMAIN,tmp));
+        }
+      } while (node.goToNextElement()) ;
+      node.goToParentElement();
+    }
+  }
    //----------------------------------------------------------------
 
Index: /XIOS/trunk/src/node/domain.hpp
===================================================================
--- /XIOS/trunk/src/node/domain.hpp	(revision 630)
+++ /XIOS/trunk/src/node/domain.hpp	(revision 631)
@@ -14,4 +14,6 @@
 #include "attribute_array.hpp"
 #include "attribute_enum.hpp"
+#include "transformation.hpp"
+#include "transformation_enum.hpp"
 
 namespace xios {
@@ -49,4 +51,5 @@
          typedef CDomainAttributes RelAttributes;
          typedef CDomainGroup      RelGroup;
+         typedef CTransformation<CDomain>::TransformationMapTypes TransMapTypes;
 
          /// Constructeurs ///
@@ -59,4 +62,6 @@
          void duplicateAttributes(CDomain* domain);
 
+         virtual void parse(xml::CXMLNode & node);
+
          /// VÃ©rifications ///
          void checkAttributes(void);
@@ -65,4 +70,8 @@
 
          void sendCheckedAttributes();
+
+         bool hasTransformation();
+         void solveInheritanceTransformation();
+         TransMapTypes getAllTransformations();
 
       private :
@@ -122,5 +131,6 @@
         CArray<int,2> mapConnectedServer ;  // (ni,nj) => mapped to connected server number, -1 if no server is target
 
-
+        int global_zoom_ibegin, global_zoom_ni;
+        int global_zoom_jbegin, global_zoom_nj;
 //        vector<int> ib_srv, ie_srv, in_srv ;
 //        vector<int> jb_srv, je_srv, jn_srv ;
@@ -160,7 +170,9 @@
          bool hasBounds ;
          bool hasArea;
+      private:
+         void checkTransformations();
+         void setTransformations(const TransMapTypes&);
+
        private :
-
-         /// ProriÃ©tÃ©s protÃ©gÃ©es ///
          bool isChecked;
          std::set<StdString> relFiles;
@@ -171,4 +183,5 @@
          std::vector<int> connectedServerRank_;
          bool isDistributed_;
+         TransMapTypes transformationMap_;
 
          DECLARE_REF_FUNC(Domain,domain)
Index: /XIOS/trunk/src/node/grid.cpp
===================================================================
--- /XIOS/trunk/src/node/grid.cpp	(revision 630)
+++ /XIOS/trunk/src/node/grid.cpp	(revision 631)
@@ -862,10 +862,10 @@
             nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin_srv;
             nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni_srv;
-            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->zoom_ibegin;
+            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;
             nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
 
             nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin_srv;
             nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj_srv;
-            nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin;
+            nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;
             nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
             ++domainId;
@@ -1124,4 +1124,5 @@
         pDom->solveRefInheritance(apply);
         pDom->solveBaseReference();
+        pDom->solveInheritanceTransformation();
         if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
           pDom->name.setValue(pDom->getBaseDomainReference()->getId());
Index: /XIOS/trunk/src/node/node_enum.hpp
===================================================================
--- /XIOS/trunk/src/node/node_enum.hpp	(revision 630)
+++ /XIOS/trunk/src/node/node_enum.hpp	(revision 631)
@@ -22,5 +22,6 @@
          eInverseAxis,
          eZoomAxis,
-         eInterpolateAxis
+         eInterpolateAxis,
+         eZoomDomain
 
       } ENodeType;
Index: /XIOS/trunk/src/node/node_type.hpp
===================================================================
--- /XIOS/trunk/src/node/node_type.hpp	(revision 630)
+++ /XIOS/trunk/src/node/node_type.hpp	(revision 631)
@@ -13,4 +13,5 @@
 #include "zoom_axis.hpp"
 #include "interpolate_axis.hpp"
+#include "zoom_domain.hpp"
 
 #endif // __XIOS_NODE_TYPE__
Index: /XIOS/trunk/src/node/transformation_enum.hpp
===================================================================
--- /XIOS/trunk/src/node/transformation_enum.hpp	(revision 630)
+++ /XIOS/trunk/src/node/transformation_enum.hpp	(revision 631)
@@ -9,5 +9,6 @@
         TRANS_ZOOM_AXIS,
         TRANS_INVERSE_AXIS,
-        TRANS_INTERPOLATE_AXIS
+        TRANS_INTERPOLATE_AXIS,
+        TRANS_ZOOM_DOMAIN
       } ETranformationType;
 
Index: /XIOS/trunk/src/node/zoom_domain.cpp
===================================================================
--- /XIOS/trunk/src/node/zoom_domain.cpp	(revision 631)
+++ /XIOS/trunk/src/node/zoom_domain.cpp	(revision 631)
@@ -0,0 +1,60 @@
+#include "zoom_domain.hpp"
+#include "type.hpp"
+
+namespace xios {
+
+  /// ////////////////////// DÃ©finitions ////////////////////// ///
+
+  CZoomDomain::CZoomDomain(void)
+    : CObjectTemplate<CZoomDomain>(), CZoomDomainAttributes(), CTransformation<CDomain>()
+  { /* Ne rien faire de plus */ }
+
+  CZoomDomain::CZoomDomain(const StdString & id)
+    : CObjectTemplate<CZoomDomain>(id), CZoomDomainAttributes(), CTransformation<CDomain>()
+  { /* Ne rien faire de plus */ }
+
+  CZoomDomain::~CZoomDomain(void)
+  {}
+
+  //----------------------------------------------------------------
+
+  StdString CZoomDomain::GetName(void)    { return StdString("zoom_domain"); }
+  StdString CZoomDomain::GetDefName(void) { return StdString("zoom_domain"); }
+  ENodeType CZoomDomain::GetType(void)    { return eZoomDomain; }
+
+  void CZoomDomain::checkValid(CDomain* domainSrc)
+  {
+    int ni_glo = domainSrc->ni_glo.getValue();
+    int nj_glo = domainSrc->nj_glo.getValue();
+
+    // RÃ©solution et vÃ©rification des donnÃ©es globales de zoom.
+    if (!this->zoom_ni.isEmpty() || !this->zoom_nj.isEmpty() ||
+        !this->zoom_ibegin.isEmpty() || !this->zoom_jbegin.isEmpty())
+    {
+       if (this->zoom_ni.isEmpty()     || this->zoom_nj.isEmpty() ||
+           this->zoom_ibegin.isEmpty() || this->zoom_jbegin.isEmpty())
+       {
+          ERROR("CZoomDomain::checkValid(void)",
+                <<"if one of zoom attributes is defined then all zoom attributes must be defined") ;
+       }
+       else
+       {
+          int zoom_iend = zoom_ibegin + zoom_ni - 1;
+          int zoom_jend = zoom_jbegin + zoom_nj - 1;
+
+          if (zoom_ibegin < 0  || zoom_jbegin < 0 || zoom_iend > (ni_glo-1) || zoom_jend > (nj_glo-1))
+             ERROR("CZoomDomain::checkValid(void)",
+                   << "Zoom is wrongly defined,"
+                   << " Check the values : zoom_ni, zoom_nj, zoom_ibegin, zoom_jbegin") ;
+       }
+    }
+    else
+    {
+       zoom_ni = ni_glo;
+       zoom_nj = nj_glo;
+       zoom_ibegin = 0;
+       zoom_jbegin = 0;
+    }
+  }
+
+}
Index: /XIOS/trunk/src/node/zoom_domain.hpp
===================================================================
--- /XIOS/trunk/src/node/zoom_domain.hpp	(revision 631)
+++ /XIOS/trunk/src/node/zoom_domain.hpp	(revision 631)
@@ -0,0 +1,65 @@
+#ifndef __XIOS_CZoomDomain__
+#define __XIOS_CZoomDomain__
+
+/// xios headers ///
+#include "xios_spl.hpp"
+#include "attribute_enum.hpp"
+#include "attribute_enum_impl.hpp"
+#include "attribute_array.hpp"
+#include "declare_attribute.hpp"
+#include "object_template.hpp"
+#include "group_factory.hpp"
+#include "declare_group.hpp"
+#include "transformation.hpp"
+#include "domain.hpp"
+
+namespace xios {
+  /// ////////////////////// DÃ©clarations ////////////////////// ///
+  class CZoomDomainGroup;
+  class CZoomDomainAttributes;
+  class CZoomDomain;
+  class CDomain;
+
+  ///--------------------------------------------------------------
+
+  // Declare/Define CFileAttribute
+  BEGIN_DECLARE_ATTRIBUTE_MAP(CZoomDomain)
+#include "zoom_domain_attribute.conf"
+  END_DECLARE_ATTRIBUTE_MAP(CZoomDomain)
+
+  ///--------------------------------------------------------------
+  /*!
+    \class CZoomDomain
+    This class describes zoom_domain in xml file.
+  */
+  class CZoomDomain
+    : public CObjectTemplate<CZoomDomain>
+    , public CZoomDomainAttributes
+    , public CTransformation<CDomain>
+  {
+    public :
+      typedef CObjectTemplate<CZoomDomain> SuperClass;
+      typedef CZoomDomainAttributes SuperClassAttribute;
+
+    public :
+      /// Constructeurs ///
+      CZoomDomain(void);
+      explicit CZoomDomain(const StdString& id);
+
+      /// Destructeur ///
+      virtual ~CZoomDomain(void);
+
+      virtual void checkValid(CDomain* axisDest);
+
+      /// Accesseurs statiques ///
+      static StdString GetName(void);
+      static StdString GetDefName(void);
+      static ENodeType GetType(void);
+    private:
+
+  }; // class CZoomDomain
+
+  DECLARE_GROUP(CZoomDomain);
+} // namespace xios
+
+#endif // __XIOS_CZoomDomain__
Index: /XIOS/trunk/src/object_factory_decl.cpp
===================================================================
--- /XIOS/trunk/src/object_factory_decl.cpp	(revision 630)
+++ /XIOS/trunk/src/object_factory_decl.cpp	(revision 631)
@@ -27,4 +27,5 @@
   macro(CZoomAxis)
   macro(CInterpolateAxis)
+  macro(CZoomDomain)
 
   macro(CFieldGroup)
@@ -38,3 +39,4 @@
   macro(CZoomAxisGroup)
   macro(CInterpolateAxisGroup)
+  macro(CZoomDomainGroup)
 }
Index: /XIOS/trunk/src/object_template_decl.cpp
===================================================================
--- /XIOS/trunk/src/object_template_decl.cpp	(revision 630)
+++ /XIOS/trunk/src/object_template_decl.cpp	(revision 631)
@@ -12,4 +12,5 @@
 #include "zoom_axis.hpp"
 #include "interpolate_axis.hpp"
+#include "zoom_domain.hpp"
 
 namespace xios
@@ -26,4 +27,5 @@
   template class CObjectTemplate<CZoomAxis>;
   template class CObjectTemplate<CInterpolateAxis>;
+  template class CObjectTemplate<CZoomDomain>;
 
   template class CObjectTemplate<CContextGroup>;
@@ -37,3 +39,4 @@
   template class CObjectTemplate<CZoomAxisGroup>;
   template class CObjectTemplate<CInterpolateAxisGroup>;
+  template class CObjectTemplate<CZoomDomainGroup>;
 }
Index: /XIOS/trunk/src/output/nc4_data_output.cpp
===================================================================
--- /XIOS/trunk/src/output/nc4_data_output.cpp	(revision 630)
+++ /XIOS/trunk/src/output/nc4_data_output.cpp	(revision 631)
@@ -250,6 +250,6 @@
               case (ONE_FILE) :
               {
-                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni.getValue());
-                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj.getValue());
+                 SuperClassWriter::addDimension(dimXid, domain->global_zoom_ni);
+                 SuperClassWriter::addDimension(dimYid, domain->global_zoom_nj);
 
                  if (domain->hasBounds)
@@ -322,5 +322,6 @@
                      else
                      {
-                       start[1]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ; start [0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
+                       start[1]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                       start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
                        count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
                      }
@@ -339,13 +340,14 @@
                        count[0]=0 ;
                        SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
-                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);                 }
+                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
+                     }
                      else
                      {
-                       start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin.getValue() ;
+                       start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
                        count[0]=domain->zoom_nj_srv ;
                        CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
                        SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
 
-                       start[0]=domain->zoom_ibegin_srv-domain->zoom_ibegin.getValue() ;
+                       start[0]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
                        count[0]=domain->zoom_ni_srv ;
                        CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
@@ -368,6 +370,6 @@
                    {
                      start[2] = 0;
-                     start[1] = domain->zoom_ibegin_srv - domain->zoom_ibegin.getValue();
-                     start[0] = domain->zoom_jbegin_srv - domain->zoom_jbegin.getValue();
+                     start[1] = domain->zoom_ibegin_srv - domain->global_zoom_ibegin;
+                     start[0] = domain->zoom_jbegin_srv - domain->global_zoom_jbegin;
                      count[2] = domain->nvertex;
                      count[1] = domain->zoom_ni_srv;
@@ -391,6 +393,6 @@
                    else
                    {
-                     start[1] = domain->zoom_ibegin_srv - domain->zoom_ibegin.getValue();
-                     start[0] = domain->zoom_jbegin_srv - domain->zoom_jbegin.getValue();
+                     start[1] = domain->zoom_ibegin_srv - domain->global_zoom_ibegin;
+                     start[0] = domain->zoom_jbegin_srv - domain->global_zoom_jbegin;
                      count[1] = domain->zoom_ni_srv;
                      count[0] = domain->zoom_nj_srv;
@@ -554,7 +556,7 @@
                  else
                  {
-                   start[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
+                   start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
                    count[0]=domain->zoom_nj_srv ;
-                   startBounds[0]=domain->zoom_jbegin_srv-domain->zoom_jbegin ;
+                   startBounds[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
                    startBounds[1]=0 ;
                    countBounds[0]=domain->zoom_nj_srv ;
Index: /XIOS/trunk/src/test/test_new_features.f90
===================================================================
--- /XIOS/trunk/src/test/test_new_features.f90	(revision 630)
+++ /XIOS/trunk/src/test/test_new_features.f90	(revision 631)
@@ -124,8 +124,4 @@
 !  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)
-!  CALL xios_add_child(file_hdl,field_hdl)
-!  CALL xios_set_attr(field_hdl,field_ref="field_All_Axis",name="field_C")
 
   dtime%second = 3600
Index: /XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 630)
+++ /XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 631)
@@ -47,4 +47,5 @@
                                                                           int axisPositionInGrid,
                                                                           const std::vector<int>& gridDestGlobalDim,
+                                                                          const std::vector<int>& gridSrcGlobalDim,
                                                                           const CArray<size_t,1>& globalIndexGridDestSendToServer,
                                                                           CArray<size_t,1>& globalIndexDestGrid,
Index: /XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp
===================================================================
--- /XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 630)
+++ /XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 631)
@@ -31,4 +31,5 @@
                                                         int axisPositionInGrid,
                                                         const std::vector<int>& gridDestGlobalDim,
+                                                        const std::vector<int>& gridSrcGlobalDim,
                                                         const CArray<size_t,1>& globalIndexGridDestSendToServer,
                                                         CArray<size_t,1>& globalIndexDestGrid,
Index: /XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 631)
+++ /XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 631)
@@ -0,0 +1,193 @@
+/*!
+   \file domain_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 02 Jul 2015
+   \date 02 Jul 2015
+
+   \brief Interface for all domain transformation algorithms.
+ */
+
+#include "domain_algorithm_transformation.hpp"
+
+namespace xios {
+
+CDomainAlgorithmTransformation::CDomainAlgorithmTransformation(CDomain* domainDestination, CDomain* domainSource)
+ : CGenericAlgorithmTransformation(), domainDest_(domainDestination), domainSrc_(domainSource)
+{
+}
+
+CDomainAlgorithmTransformation::~CDomainAlgorithmTransformation()
+{
+}
+
+void CDomainAlgorithmTransformation::computeIndexSourceMapping()
+{
+}
+
+/*!
+  Compute an array of global index from a global index on a domain
+  \param[in] domainDestGlobalIndex global index on an domain of destination grid
+  \param[in] domainSrcGlobalIndex global index on an domain of source grid (which are needed by one index on domain destination)
+  \param[in] domainPositionInGrid position of the domain in the grid
+  \param[in] gridDestGlobalDim dimension size of destination grid (it should share the same size for all dimension, maybe except the domain on which transformation is performed)
+  \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 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 CDomainAlgorithmTransformation::computeGlobalGridIndexFromGlobalIndexElement(int domainDestGlobalIndex,
+                                                                          const std::vector<int>& domainSrcGlobalIndex,
+                                                                          int domainPositionInGrid,
+                                                                          const std::vector<int>& gridDestGlobalDim,
+                                                                          const std::vector<int>& gridSrcGlobalDim,
+                                                                          const CArray<size_t,1>& globalIndexGridDestSendToServer,
+                                                                          CArray<size_t,1>& globalIndexDestGrid,
+                                                                          std::vector<std::vector<size_t> >& globalIndexSrcGrid)
+{
+  int globalDim = gridDestGlobalDim.size();
+  int numElement = globalDim - 1;
+  int domainElementPosition = 0;
+  std::vector<int> currentIndex(globalDim);
+  std::vector<int> gridDomainGlobalDim(numElement), indexMap(numElement);
+  std::vector<int> idxLoop(numElement, 0), domainSrcGlobalDim(2), domainDestGlobalDim(2);
+
+
+  size_t ssize = 1, idx = 0, realGlobalIndexSize = 0;
+  for (int i = 0; i< globalDim; ++i)
+  {
+    if (domainPositionInGrid == i) continue;
+    if (domainPositionInGrid == (i+1))
+    {
+      domainDestGlobalDim[0] = gridDestGlobalDim[i];
+      domainDestGlobalDim[1] = gridDestGlobalDim[i+1];
+      domainSrcGlobalDim[0] = gridSrcGlobalDim[i];
+      domainSrcGlobalDim[1] = gridSrcGlobalDim[i+1];
+      gridDomainGlobalDim[idx] = 1;
+      domainElementPosition = idx;
+    }
+    else
+    {
+      gridDomainGlobalDim[idx] = gridDestGlobalDim[i];
+    }
+    indexMap[idx] = i;
+    ++idx;
+  }
+  int iIndex = domainDestGlobalIndex % domainDestGlobalDim[1];
+  int jIndex = domainDestGlobalIndex / domainDestGlobalDim[0];
+
+  for (int i = 0; i< numElement; ++i) ssize *= gridDomainGlobalDim[i];
+
+  CArray<size_t,1>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
+                                   iteArr = globalIndexGridDestSendToServer.end();
+  idx = 0;
+  while (idx < ssize)
+  {
+    for (int i = 0; i < numElement; ++i)
+    {
+      if (idxLoop[i] == gridDomainGlobalDim[i])
+      {
+        idxLoop[i] = 0;
+        ++idxLoop[i+1];
+      }
+    }
+
+    for (int i = 0; i < numElement; ++i)
+    {
+      if (domainElementPosition == i)
+      {
+        currentIndex[indexMap[i]]   = iIndex;
+        currentIndex[indexMap[i]+1] = jIndex;
+      }
+      else
+        currentIndex[indexMap[i]] = idxLoop[i];
+    }
+
+    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 (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
+  for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
+    if (globalIndexSrcGrid[i].size() != domainSrcGlobalIndex.size())
+      globalIndexSrcGrid[i].resize(domainSrcGlobalIndex.size());
+
+  size_t realGlobalIndex = 0;
+  idx = 0;
+  idxLoop.assign(globalDim, 0);
+  while (idx < ssize)
+  {
+    for (int i = 0; i < numElement; ++i)
+    {
+      if (idxLoop[i] == gridDomainGlobalDim[i])
+      {
+        idxLoop[i] = 0;
+        ++idxLoop[i+1];
+      }
+    }
+
+    for (int i = 0; i < numElement; ++i)
+    {
+      if (domainElementPosition == i)
+      {
+        currentIndex[indexMap[i]]   = iIndex;
+        currentIndex[indexMap[i]+1] = jIndex;
+      }
+      else
+        currentIndex[indexMap[i]] = idxLoop[i];
+    }
+
+    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[realGlobalIndex].size(); ++i)
+      {
+        domainGlobalIndex(domainSrcGlobalIndex[i], domainSrcGlobalDim[0], domainSrcGlobalDim[1],
+                          currentIndex[indexMap[domainElementPosition]],
+                          currentIndex[indexMap[domainElementPosition]+1]);
+
+        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;
+  }
+}
+
+void CDomainAlgorithmTransformation::domainGlobalIndex(const int& index, const int& niGlob, const int& njGlob,
+                                                       int& iIndex, int& jIndex)
+{
+   iIndex = index % njGlob;
+   jIndex = index / niGlob;
+}
+}
Index: /XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp
===================================================================
--- /XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 631)
+++ /XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 631)
@@ -0,0 +1,52 @@
+/*!
+   \file domain_algorithm_transformation.hpp
+   \author Ha NGUYEN
+   \since 02 Jul 2015
+   \date 02 Jul 2015
+
+   \brief Interface for all domain transformation algorithms.
+ */
+#ifndef __XIOS_DOMAIN_ALGORITHM_TRANSFORMATION_HPP__
+#define __XIOS_DOMAIN_ALGORITHM_TRANSFORMATION_HPP__
+
+#include "generic_algorithm_transformation.hpp"
+#include "domain.hpp"
+
+namespace xios {
+
+/*!
+  \class CDomainAlgorithmTransformation
+  Algorithms for domain.
+*/
+class CDomainAlgorithmTransformation : public virtual CGenericAlgorithmTransformation
+{
+public:
+  CDomainAlgorithmTransformation(CDomain* domainDestination, CDomain* domainSource);
+
+  virtual ~CDomainAlgorithmTransformation();
+
+protected:
+  virtual void computeGlobalGridIndexFromGlobalIndexElement(int domainDestGlobalIndex,
+                                                        const std::vector<int>& domainSrcGlobalIndex,
+                                                        int domainPositionInGrid,
+                                                        const std::vector<int>& gridDestGlobalDim,
+                                                        const std::vector<int>& gridSrcGlobalDim,
+                                                        const CArray<size_t,1>& globalIndexGridDestSendToServer,
+                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        std::vector<std::vector<size_t> >& globalIndexSrcGrid);
+  void computeIndexSourceMapping();
+
+protected:
+  inline void domainGlobalIndex(const int& index, const int& niGlob, const int& njGlob,
+                                int& iIndex, int& jIndex);
+
+protected:
+    //! Domain on grid destination
+  CDomain* domainDest_;
+
+  //! Domain on grid source
+  CDomain* domainSrc_;
+};
+
+}
+#endif // __XIOS_DOMAIN_ALGORITHM_TRANSFORMATION_HPP__
Index: /XIOS/trunk/src/transformation/domain_algorithm_zoom.cpp
===================================================================
--- /XIOS/trunk/src/transformation/domain_algorithm_zoom.cpp	(revision 631)
+++ /XIOS/trunk/src/transformation/domain_algorithm_zoom.cpp	(revision 631)
@@ -0,0 +1,125 @@
+/*!
+   \file domain_algorithm_zoom.cpp
+   \author Ha NGUYEN
+   \since 02 Jul 2015
+   \date 02 Jul 2015
+
+   \brief Algorithm for zooming on an domain.
+ */
+#include "domain_algorithm_zoom.hpp"
+
+namespace xios {
+
+CDomainAlgorithmZoom::CDomainAlgorithmZoom(CDomain* domainDestination, CDomain* domainSource, CZoomDomain* zoomDomain)
+: CDomainAlgorithmTransformation(domainDestination, domainSource)
+{
+  zoomDomain->checkValid(domainSource);
+  zoomIBegin_ = zoomDomain->zoom_ibegin.getValue();
+  zoomJBegin_ = zoomDomain->zoom_jbegin.getValue();
+
+  zoomNi_  = zoomDomain->zoom_ni.getValue();
+  zoomNj_  = zoomDomain->zoom_nj.getValue();
+
+  zoomIEnd_ = zoomIBegin_ + zoomNi_ - 1;
+  zoomJEnd_ = zoomJBegin_ + zoomNj_ - 1;
+
+  if (zoomNi_ > domainSource->ni_glo.getValue())
+  {
+    ERROR("CDomainAlgorithmZoom::CDomainAlgorithmZoom(CDomain* domainDestination, CDomain* domainSource, CZoomDomain* zoomDomain)",
+           << "Zoom size is greater than size of domain source"
+           << "Size ni_glo of domain source " <<domainSource->getId() << " is " << domainSource->ni_glo.getValue()  << std::endl
+           << "Zoom size is " << zoomNi_ );
+  }
+
+  if (zoomNj_ > domainSource->nj_glo.getValue())
+  {
+    ERROR("CDomainAlgorithmZoom::CDomainAlgorithmZoom(CDomain* domainDestination, CDomain* domainSource, CZoomDomain* zoomDomain)",
+           << "Zoom size is greater than size of domain source"
+           << "Size nj_glo of domain source " <<domainSource->getId() << " is " << domainSource->nj_glo.getValue()  << std::endl
+           << "Zoom size is " << zoomNj_ );
+  }
+
+  computeIndexSourceMapping();
+}
+
+/*!
+  Compute the index mapping between domain on grid source and one on grid destination
+*/
+void CDomainAlgorithmZoom::computeIndexSourceMapping()
+{
+  int niSource = domainSrc_->ni.getValue();
+  int ibeginSource = domainSrc_->ibegin.getValue();
+  int iendSource = ibeginSource + niSource - 1;
+
+  int ibegin = std::max(ibeginSource, zoomIBegin_);
+  int iend = std::min(iendSource, zoomIEnd_);
+  int ni = iend + 1 - ibegin;
+  if (iend < ibegin) ni = 0;
+
+  int njSource = domainSrc_->nj.getValue();
+  int jbeginSource = domainSrc_->jbegin.getValue();
+  int jendSource = jbeginSource + njSource - 1;
+
+  int jbegin = std::max(jbeginSource, zoomJBegin_);
+  int jend = std::min(jendSource, zoomJEnd_);
+  int nj = jend + 1 - jbegin;
+  if (jend < jbegin) nj = 0;
+
+  int niGlob = domainSrc_->ni_glo.getValue();
+  int njGlob = domainSrc_->nj_glo.getValue();
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_;
+  int domainGlobalIndex;
+  for (int j = 0; j < nj; ++j)
+  {
+    for (int i = 0; i < ni; ++i)
+    {
+      domainGlobalIndex = (j+jbegin) * niGlob + (i+ibegin);
+      transMap[domainGlobalIndex].push_back(domainGlobalIndex);
+      transWeight[domainGlobalIndex].push_back(1.0);
+    }
+  }
+
+  updateZoom();
+  updateDomainDestinationMask();
+}
+
+/*!
+  After a zoom on domain, it should be certain that (global) zoom begin and (global) zoom size are updated
+*/
+void CDomainAlgorithmZoom::updateZoom()
+{
+  domainDest_->global_zoom_ibegin = zoomIBegin_;
+  domainDest_->global_zoom_jbegin = zoomJBegin_;
+  domainDest_->global_zoom_ni  = zoomNi_;
+  domainDest_->global_zoom_nj  = zoomNj_;
+}
+
+/*!
+  Update mask on domain
+  Because only zoomed region on domain is not masked, the remaining must be masked to make sure
+correct index be extracted
+*/
+void CDomainAlgorithmZoom::updateDomainDestinationMask()
+{
+  int niMask     = domainDest_->ni.getValue();
+  int iBeginMask = domainDest_->ibegin.getValue();
+  int njMask     = domainDest_->nj.getValue();
+  int jBeginMask = domainDest_->jbegin.getValue();
+  int niGlob = domainDest_->ni_glo.getValue();
+  int globalIndexMask = 0;
+
+  std::map<int, std::vector<int> >& transMap = this->transformationMapping_;
+  std::map<int, std::vector<int> >::const_iterator ite = (transMap).end();
+  for (int j = 0; j < njMask; ++j)
+  {
+    for (int i = 0; i < niMask; ++i)
+    {
+      globalIndexMask = (j+jBeginMask) * niGlob + (i + iBeginMask);
+      if (transMap.find(globalIndexMask) == ite)
+        (domainDest_->mask)(i,j) = false;
+    }
+  }
+}
+
+}
Index: /XIOS/trunk/src/transformation/domain_algorithm_zoom.hpp
===================================================================
--- /XIOS/trunk/src/transformation/domain_algorithm_zoom.hpp	(revision 631)
+++ /XIOS/trunk/src/transformation/domain_algorithm_zoom.hpp	(revision 631)
@@ -0,0 +1,51 @@
+/*!
+   \file domain_algorithm_zoom.hpp
+   \author Ha NGUYEN
+   \since 03 June 2015
+   \date 12 June 2015
+
+   \brief Algorithm for zooming on an domain.
+ */
+#ifndef __XIOS_DOMAIN_ALGORITHM_ZOOM_HPP__
+#define __XIOS_DOMAIN_ALGORITHM_ZOOM_HPP__
+
+#include "domain_algorithm_transformation.hpp"
+#include "zoom_domain.hpp"
+#include "domain.hpp"
+
+namespace xios {
+/*!
+  \class CDomainAlgorithmZoom
+  Implementing zoom on domain
+  A zoomed region can be considered as region that isnt masked.
+  Only this zoomed region is extracted to write on Netcdf.
+*/
+class CDomainAlgorithmZoom : public CDomainAlgorithmTransformation
+{
+public:
+  CDomainAlgorithmZoom(CDomain* domainDestination, CDomain* domainSource, CZoomDomain* zoomDomain);
+
+  virtual ~CDomainAlgorithmZoom() {}
+
+  virtual void computeIndexSourceMapping();
+
+private:
+  void updateDomainDestinationMask();
+  void updateZoom();
+
+private:
+  //! Global zoom begin on domain
+  int zoomIBegin_;
+  int zoomJBegin_;
+
+  //! Global zoom end on domain
+  int zoomIEnd_;
+  int zoomJEnd_;
+
+  //! Global zoom size on domain
+  int zoomNi_;
+  int zoomNj_;
+};
+
+}
+#endif // __XIOS_DOMAIN_ALGORITHM_ZOOM_HPP__
Index: /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 630)
+++ /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 631)
@@ -21,4 +21,5 @@
                 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] 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/out] globaIndexWeightFromDestToSource mapping between transformed global index of grid destination
@@ -27,4 +28,5 @@
 void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
                                                              const std::vector<int>& gridDestGlobalDim,
+                                                             const std::vector<int>& gridSrcGlobalDim,
                                                              const CArray<size_t,1>& globalIndexGridDestSendToServer,
                                                              std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource)
@@ -45,4 +47,5 @@
                                                    elementPositionInGrid,
                                                    gridDestGlobalDim,
+                                                   gridSrcGlobalDim,
                                                    globalIndexGridDestSendToServer,
                                                    globalIndexDestGrid,
Index: /XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- /XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 630)
+++ /XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 631)
@@ -28,4 +28,5 @@
   void computeGlobalSourceIndex(int elementPositionInGrid,
                                 const std::vector<int>& gridDestGlobalDim,
+                                const std::vector<int>& gridSrcGlobalDim,
                                 const CArray<size_t,1>& globalIndexGridDestSendToServer,
                                 std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource);
@@ -51,4 +52,5 @@
                                                         int elementPositionInGrid,
                                                         const std::vector<int>& gridDestGlobalDim,
+                                                        const std::vector<int>& gridSrcGlobalDim,
                                                         const CArray<size_t,1>& globalIndexGridDestSendToServer,
                                                         CArray<size_t,1>& globalIndexDestGrid,
Index: /XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 630)
+++ /XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 631)
@@ -11,4 +11,5 @@
 #include "axis_algorithm_zoom.hpp"
 #include "axis_algorithm_interpolate.hpp"
+#include "domain_algorithm_zoom.hpp"
 #include "context.hpp"
 #include "context_client.hpp"
@@ -19,5 +20,5 @@
 CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)
 : gridSource_(source), gridDestination_(destination), originalGridSource_(source),
-  globalIndexOfCurrentGridSource_(0), globalIndexOfOriginalGridSource_(0), weightOfGlobalIndexOfOriginalGridSource_(0)
+  globalIndexOfCurrentGridSource_(0), globalIndexOfOriginalGridSource_(0), weightOfGlobalIndexOfOriginalGridSource_(0), algoTypes_()
 {
   //Verify the compatibity between two grids
@@ -105,7 +106,53 @@
 void CGridTransformation::initializeAlgorithms()
 {
-  initializeAxisAlgorithms();
-  initializeDomainAlgorithms();
-}
+  std::vector<int> axisPositionInGrid;
+  std::vector<int> domPositionInGrid;
+  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
+  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
+
+  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;
+      domPositionInGrid.push_back(idx);
+      ++idx;
+    }
+  }
+
+  for (int i = 0; i < axisListDestP.size(); ++i)
+  {
+    elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
+  }
+
+  for (int i = 0; i < domListDestP.size(); ++i)
+  {
+    elementPosition2DomainPositionInGrid_[domPositionInGrid[i]] = i;
+  }
+
+  idx = 0;
+  for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
+  {
+    if (false == (gridDestination_->axis_domain_order)(i))
+    {
+      initializeAxisAlgorithms(idx);
+      ++idx;
+    }
+    else
+    {
+      ++idx;
+      initializeDomainAlgorithms(idx);
+      ++idx;
+    }
+  }
+}
+
+
 
 /*!
@@ -114,44 +161,52 @@
 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;
+\param [in] axisPositionInGrid position of an axis in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
+*/
+void CGridTransformation::initializeAxisAlgorithms(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))
+    if (axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->hasTransformation())
+    {
+      CAxis::TransMapTypes trans = axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->getAllTransformations();
+      CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
+                                           ite = trans.end();
+      int transformationOrder = 0;
+      for (it = itb; it != ite; ++it)
       {
-        axisPositionInGrid.push_back(idx);
-        ++idx;
+        listAlgos_.push_back(std::make_pair(axisPositionInGrid, std::make_pair(it->first, transformationOrder)));
+        algoTypes_.push_back(false);
+        ++transformationOrder;
       }
-      else idx += 2;
-    }
-
-    for (int i = 0; i < axisListDestP.size(); ++i)
-    {
-      elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
-      if (axisListDestP[i]->hasTransformation())
+    }
+  }
+}
+
+/*!
+  Initialize the algorithms corresponding to transformation info contained in each domain.
+If a domain has transformations, they will be represented in form of vector of CTransformation pointers
+In general, each domain can have several transformations performed on itself.
+\param [in] domPositionInGrid position of a domain in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
+*/
+void CGridTransformation::initializeDomainAlgorithms(int domPositionInGrid)
+{
+  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
+  if (!domListDestP.empty())
+  {
+    if (domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->hasTransformation())
+    {
+      CDomain::TransMapTypes trans = domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->getAllTransformations();
+      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
+                                             ite = trans.end();
+      int transformationOrder = 0;
+      for (it = itb; it != ite; ++it)
       {
-        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;
-        }
+        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, transformationOrder)));
+        algoTypes_.push_back(true);
+        ++transformationOrder;
       }
     }
   }
-}
-
-void CGridTransformation::initializeDomainAlgorithms()
-{
 
 }
@@ -163,8 +218,10 @@
   \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);
+  \param [in] isDomainAlgo flag to specify type of algorithm (for domain or axis)
+*/
+void CGridTransformation::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo)
+{
+   if (isDomainAlgo) selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
+   else selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
 }
 
@@ -219,4 +276,25 @@
 void CGridTransformation::selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
 {
+  std::vector<CDomain*> domainListDestP = gridDestination_->getDomains();
+  std::vector<CDomain*> domainListSrcP = gridSource_->getDomains();
+
+  int domainIndex =  elementPosition2DomainPositionInGrid_[elementPositionInGrid];
+  CDomain::TransMapTypes trans = domainListDestP[domainIndex]->getAllTransformations();
+  CDomain::TransMapTypes::const_iterator it = trans.begin();
+
+  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
+
+  CZoomDomain* zoomDomain = 0;
+  CGenericAlgorithmTransformation* algo = 0;
+  switch (transType)
+  {
+    case TRANS_ZOOM_DOMAIN:
+      zoomDomain = dynamic_cast<CZoomDomain*> (it->second);
+      algo = new CDomainAlgorithmZoom(domainListDestP[domainIndex], domainListSrcP[domainIndex], zoomDomain);
+      break;
+    default:
+      break;
+  }
+  algoTransformation_.push_back(algo);
 }
 
@@ -233,7 +311,15 @@
   std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
 
-  int axisIndex;
+  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
+  std::vector<CDomain*> domListSrcP = gridSource_->getDomains();
+
+  int axisIndex, domainIndex;
   switch (transType)
   {
+    case TRANS_ZOOM_DOMAIN:
+      domainIndex = elementPosition2DomainPositionInGrid_[elementPositionInGrid];
+      domListSrcP[domainIndex]->duplicateAttributes(domListDestP[domainIndex]);
+      break;
+
     case TRANS_INTERPOLATE_AXIS:
     case TRANS_ZOOM_AXIS:
@@ -272,5 +358,5 @@
 
     // First of all, select an algorithm
-    selectAlgo(elementPositionInGrid, transType, transformationOrder);
+    selectAlgo(elementPositionInGrid, transType, transformationOrder, algoTypes_[std::distance(itb, it)]);
     algo = algoTransformation_.back();
 
@@ -281,7 +367,9 @@
     // ComputeTransformation of global index of each element
     std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension();
+    std::vector<int> gridSrcDimensionSize = gridSource_->getGlobalDimension();
     int elementPosition = it->first;
     algo->computeGlobalSourceIndex(elementPosition,
                                    gridDestinationDimensionSize,
+                                   gridSrcDimensionSize,
                                    globalIndexGridDestSendToServer,
                                    globaIndexWeightFromDestToSource);
Index: /XIOS/trunk/src/transformation/grid_transformation.hpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 630)
+++ /XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 631)
@@ -46,11 +46,11 @@
   void computeTransformation();
   void initializeAlgorithms();
-  void initializeAxisAlgorithms();
-  void initializeDomainAlgorithms();
+  void initializeAxisAlgorithms(int axisPositionInGrid);
+  void initializeDomainAlgorithms(int domPositionInGrid);
   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 selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo);
   void setUpGrid(int elementPositionInGrid, ETranformationType transType);
   void computeFinalTransformationMapping();
@@ -78,4 +78,6 @@
   //! List of algorithm types and their order
   ListAlgoType listAlgos_;
+  // true if domain algorithm and false if axis algorithm (can be replaced by tuple with listAlgos_
+  std::vector<bool> algoTypes_;
 
   // Mapping between position of an element in grid and its transformation (if any)
Index: /XIOS/trunk/src/type/type_util.hpp
===================================================================
--- /XIOS/trunk/src/type/type_util.hpp	(revision 630)
+++ /XIOS/trunk/src/type/type_util.hpp	(revision 631)
@@ -26,4 +26,6 @@
     class CInterpolateAxis;
     class CInterpolateAxisGroup;
+    class CZoomDomain;
+    class CZoomDomainGroup;
 
   template <typename T> inline string getStrType(void);
@@ -68,4 +70,6 @@
   macro(CInterpolateAxis)
   macro(CInterpolateAxisGroup)
+  macro(CZoomDomain)
+  macro(CZoomDomainGroup)
 #undef macro
 }
Index: /XIOS/trunk/src/xml_parser_decl.cpp
===================================================================
--- /XIOS/trunk/src/xml_parser_decl.cpp	(revision 630)
+++ /XIOS/trunk/src/xml_parser_decl.cpp	(revision 631)
@@ -7,8 +7,8 @@
 #include "file.hpp"
 #include "variable.hpp"
-//#include "transformation.hpp"
 #include "inverse_axis.hpp"
 #include "zoom_axis.hpp"
 #include "interpolate_axis.hpp"
+#include "zoom_domain.hpp"
 
 namespace xios
@@ -31,4 +31,5 @@
     macro( ZoomAxis )
     macro( InterpolateAxis )
+    macro( ZoomDomain )
   }
 }
