Index: XIOS/trunk/src/node/grid.cpp
===================================================================
--- XIOS/trunk/src/node/grid.cpp	(revision 540)
+++ XIOS/trunk/src/node/grid.cpp	(revision 551)
@@ -21,5 +21,5 @@
       , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
       , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
-      , vDomainGroup_(), vAxisGroup_(), axisOrder_(), axisList_(), isAxisListSet(false), isDomListSet(false)
+      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
    {
      setVirtualDomainGroup();
@@ -31,5 +31,5 @@
       , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
       , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
-      , vDomainGroup_(), vAxisGroup_(), axisOrder_(), axisList_(), isAxisListSet(false), isDomListSet(false)
+      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
    {
      setVirtualDomainGroup();
@@ -51,4 +51,8 @@
     for(map<int,CArray<int,1>* >::iterator it=out_j_fromClient.begin();it!=out_j_fromClient.end();it++) delete it->second ;
     for(map<int,CArray<int,1>* >::iterator it=out_l_fromClient.begin();it!=out_l_fromClient.end();it++) delete it->second ;
+
+    for(map<int,CArray<size_t,1>* >::iterator it=outIndexFromClient.begin();it!=outIndexFromClient.end();++it) delete (it->second);
+
+    if (0 != clientDistribution_) delete clientDistribution_;
 
    }
@@ -176,18 +180,16 @@
    std::map<int, StdSize> CGrid::getConnectedServerDataSize()
    {
+     double secureFactor = 2.5 * sizeof(double) * CXios::bufferServerFactorSize;
+     StdSize retVal;
      std::map<int, StdSize> ret;
-     std::map<int, int>::const_iterator it = domConnectedServerSide_.begin(),
-                                       itE = domConnectedServerSide_.end();
-     std::vector<int> nData = domain->nbDataSrv;
-     std::vector<int>::const_iterator itData = nData.begin();
-     StdSize retVal = StdSize(0.0);
-     for (; it != itE; ++it, ++itData)
+     const std::map<int, std::vector<int> >& distribution = clientDistribution_->getLocalIndexSendToServer();
+     std::map<int, std::vector<int> >::const_iterator it = distribution.begin(), itE = distribution.end();
+     for (; it != itE; ++it)
      {
-       retVal = (it->second < *itData) ? *itData : it->second;
-       if (this->withAxis) retVal *= this->axis->size.getValue();
-       retVal *= sizeof(double);
-       retVal *= 2.5 * CXios::bufferServerFactorSize; // Secure factor, myterious number
-       ret.insert(make_pair(it->first, retVal));
+        retVal = it->second.size();
+        retVal *= secureFactor;
+        ret.insert(std::make_pair<int,StdSize>(it->first, retVal));
      }
+
      return ret;
    }
@@ -235,5 +237,5 @@
 
      if (context->hasClient)
-      if (this->isChecked && doSendingIndex) sendIndex();
+      if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
 
      if (this->isChecked) return;
@@ -397,5 +399,14 @@
    void CGrid::computeIndex(void)
    {
-
+     CContext* context = CContext::getCurrent() ;
+     CContextClient* client=context->client ;
+     clientDistribution_ = new CDistributionClient(client->clientRank, this);
+     clientDistribution_->computeServerIndexMapping(client->serverSize);
+     nbSenders = clientDistribution_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm);
+
+     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().numElements());
+     storeIndex_client = (clientDistribution_->getLocalDataIndexOnClient());
+
+/*
       const int ni   = domain->ni.getValue() ,
                 nj   = domain->nj.getValue() ,
@@ -476,5 +487,6 @@
          }
       }
-      computeDomConServer();
+*/
+//      computeDomConServer();
 //      sendIndex() ;
 
@@ -520,4 +532,17 @@
       grid->setDomainList(domains);
       grid->setAxisList(axis);
+
+      //By default, domains are always the first ones of a grid
+      if (grid->axisDomainOrder.isEmpty())
+      {
+        int size = domains.size()+axis.size();
+        grid->axisDomainOrder.resize(size);
+        for (int i = 0; i < size; ++i)
+        {
+          if (i < domains.size()) grid->axisDomainOrder(i) = true;
+          else grid->axisDomainOrder(i) = false;
+        }
+      }
+
       return (grid);
    }
@@ -561,4 +586,14 @@
       for(StdSize n = 0; n < stored.numElements(); n++)
          field(out_i(n)) = stored(n) ;
+   }
+
+   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
+   {
+     CArray<size_t,1>& out_i=*outIndexFromClient[rank];
+     StdSize numElements = stored.numElements();
+     for (StdSize n = 0; n < numElements; ++n)
+     {
+       *(field+out_i(n)) = stored(n);
+     }
    }
 
@@ -599,5 +634,4 @@
 //         if (domain->mapConnectedServer(i,j)==ns)  nb++ ;
 //       }
-//
 //       CArray<int,1> storeIndex(nb) ;
 //       CArray<int,1> out_i(nb) ;
@@ -676,6 +710,40 @@
     int rank ;
     list<shared_ptr<CMessage> > list_msg ;
-    list< CArray<int,1>* > list_out_i,list_out_j,list_out_l ;
-
+    list< CArray<size_t,1>* > listOutIndex;
+
+    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientDistribution_->getGlobalIndexOnServer();
+    const std::map<int, std::vector<int> >& localIndexSendToServer  = clientDistribution_->getLocalIndexSendToServer();
+
+    std::map<int, std::vector<size_t> >::const_iterator iteMap, itbMap, itGlobal;
+    std::map<int, std::vector<int> >::const_iterator itLocal;
+    itbMap = itGlobal = globalIndexOnServer.begin();
+    iteMap = globalIndexOnServer.end();
+    itLocal = localIndexSendToServer.begin();
+
+
+    for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
+    {
+      rank = itGlobal->first;
+      int nb = (itGlobal->second).size();
+
+      CArray<size_t, 1> outGlobalIndexOnServer(nb);
+      CArray<int, 1> outLocalIndexToServer(nb);
+      for (int k = 0; k < nb; ++k)
+      {
+        outGlobalIndexOnServer(k) = itGlobal->second.at(k);
+        outLocalIndexToServer(k)  = itLocal->second.at(k);
+      }
+
+      storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
+      listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
+
+      list_msg.push_back(shared_ptr<CMessage>(new CMessage));
+      *list_msg.back()<<getId()<<*listOutIndex.back();
+      event.push(rank, nbSenders[rank], *list_msg.back());
+    }
+    client->sendEvent(event);
+    for(list<CArray<size_t,1>* >::iterator it=listOutIndex.begin();it!=listOutIndex.end();++it) delete *it ;
+
+/*
     if (!isDomConServerComputed_) computeDomConServer();
 
@@ -721,5 +789,5 @@
     for(list<CArray<int,1>* >::iterator it=list_out_j.begin();it!=list_out_j.end();it++) delete *it ;
     for(list<CArray<int,1>* >::iterator it=list_out_l.begin();it!=list_out_l.end();it++) delete *it ;
-
+*/
   }
 
@@ -731,7 +799,7 @@
       int rank=it->rank;
       CBufferIn* buffer=it->buffer;
-      string domainId ;
-      *buffer>>domainId ;
-      get(domainId)->recvIndex(rank,*buffer) ;
+      string gridId ;
+      *buffer>>gridId ;
+      get(gridId)->recvIndex(rank,*buffer) ;
     }
   }
@@ -739,4 +807,9 @@
   void CGrid::recvIndex(int rank, CBufferIn& buffer)
   {
+     CArray<size_t,1> outIndex;
+     buffer>>outIndex;
+     outIndexFromClient.insert(std::pair<int, CArray<size_t,1>* >(rank, new CArray<size_t,1>(outIndex)));
+
+    /*
     CArray<int,1> out_i ;
     CArray<int,1> out_j ;
@@ -751,4 +824,5 @@
     out_j_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_j) )) ;
     out_l_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_l) )) ;
+    */
   }
 
@@ -947,4 +1021,10 @@
    }
 
+  /*!
+  \brief Solve domain and axis references
+  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
+  all attributes from their parents, they should be processed with this function
+  \param[in] apply inherit all attributes of parents (true)
+  */
   void CGrid::solveDomainAxisRefInheritance(bool apply)
   {
@@ -963,5 +1043,4 @@
         if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
           pDom->name.setValue(pDom->getBaseDomainReference()->getId());
-
       }
     }
@@ -982,4 +1061,8 @@
   }
 
+  /*!
+  \brief Get the list of domain pointers
+  \return list of domain pointers
+  */
   std::vector<CDomain*> CGrid::getDomains()
   {
@@ -992,4 +1075,8 @@
   }
 
+  /*!
+  \brief Get the list of  axis pointers
+  \return list of axis pointers
+  */
   std::vector<CAxis*> CGrid::getAxis()
   {
@@ -1001,4 +1088,8 @@
   }
 
+  /*!
+  \brief Set domain(s) of a grid from a list
+  \param[in] domains list of domains
+  */
   void CGrid::setDomainList(const std::vector<CDomain*> domains)
   {
@@ -1019,4 +1110,8 @@
   }
 
+  /*!
+  \brief Set axis(s) of a grid from a list
+  \param[in] axis list of axis
+  */
   void CGrid::setAxisList(const std::vector<CAxis*> axis)
   {
@@ -1036,4 +1131,8 @@
   }
 
+  /*!
+  \brief Get list of id of domains
+  \return id list of domains
+  */
   std::vector<StdString> CGrid::getDomainList()
   {
@@ -1042,4 +1141,8 @@
   }
 
+  /*!
+  \brief Get list of id of axis
+  \return id list of axis
+  */
   std::vector<StdString> CGrid::getAxisList()
   {
@@ -1074,9 +1177,10 @@
   {
     SuperClass::parse(node);
+    // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
+//    std::vector<int> axisOrder;
+    std::vector<bool> order;
 
     if (node.goToChildElement())
     {
-      int domainIdx = -1;
-      int posAxis = 0;
       StdString domainName("domain");
       StdString axisName("axis");
@@ -1084,10 +1188,9 @@
       {
         if (node.getElementName() == domainName) {
-          axisOrder_.push_back(domainIdx);
+          order.push_back(true);
           this->getVirtualDomainGroup()->parseChild(node);
         }
         if (node.getElementName() == axisName) {
-          axisOrder_.push_back(posAxis);
-          ++posAxis;
+          order.push_back(false);
           this->getVirtualAxisGroup()->parseChild(node);
         }
@@ -1096,11 +1199,11 @@
     }
 
-    if (!axisOrder_.empty())
-    {
-      int sizeOrd = axisOrder_.size();
-      axisDomOrder.resize(sizeOrd);
+    if (!order.empty())
+    {
+      int sizeOrd = order.size();
+      axisDomainOrder.resize(sizeOrd);
       for (int i = 0; i < sizeOrd; ++i)
       {
-        axisDomOrder(i) = axisOrder_[i];
+        axisDomainOrder(i) = order[i];
       }
     }
