source: XIOS/trunk/src/node/grid.cpp @ 1078

Last change on this file since 1078 was 1078, checked in by mhnguyen, 5 years ago

Adding rectilinear and curvilinear domain for expand_domain transformation
-) Rectilinear/curvilinear is expanded not only locally but also globally, its global size ni_glo, nj_glo become ni_glo+2 and nj_glo+2
-) Two attributes i_periodic, j_periodic are only used for rectilinear/curvilinear to process priodic condition

+) Do some minor modification

Test
+) Add test_connectivity_expand
+) On Curie
+) Work (but need more real tests)

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
  • Property svn:executable set to *
File size: 69.8 KB
Line 
1
2#include "grid.hpp"
3
4#include "attribute_template.hpp"
5#include "object_template.hpp"
6#include "group_template.hpp"
7#include "message.hpp"
8#include <iostream>
9#include "xios_spl.hpp"
10#include "type.hpp"
11#include "context.hpp"
12#include "context_client.hpp"
13#include "context_server.hpp"
14#include "array_new.hpp"
15#include "server_distribution_description.hpp"
16#include "client_server_mapping_distributed.hpp"
17#include "distribution_client.hpp"
18#include "grid_transformation.hpp"
19#include "grid_generate.hpp"
20
21namespace xios {
22
23   /// ////////////////////// Dfinitions ////////////////////// ///
24
25   CGrid::CGrid(void)
26      : CObjectTemplate<CGrid>(), CGridAttributes()
27      , isChecked(false), isDomainAxisChecked(false)
28      , vDomainGroup_(), domList_(), isDomListSet(false)
29      , vAxisGroup_(), axisList_(), isAxisListSet(false)
30      , vScalarGroup_(), scalarList_(), isScalarListSet(false)
31      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
32      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
33      , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false)
34      , transformations_(0), isTransformed_(false)
35      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
36      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_()
37   {
38     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
39     setVirtualAxisGroup(CAxisGroup::create(getId() + "_virtual_axis_group"));
40     setVirtualScalarGroup(CScalarGroup::create(getId() + "_virtual_scalar_group"));
41   }
42
43   CGrid::CGrid(const StdString& id)
44      : CObjectTemplate<CGrid>(id), CGridAttributes()
45      , isChecked(false), isDomainAxisChecked(false)
46      , vDomainGroup_(), domList_(), isDomListSet(false)
47      , vAxisGroup_(), axisList_(), isAxisListSet(false)
48      , vScalarGroup_(), scalarList_(), isScalarListSet(false)
49      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
50      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
51      , connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false)
52      , transformations_(0), isTransformed_(false)
53      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
54      , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_()
55   {
56     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
57     setVirtualAxisGroup(CAxisGroup::create(getId() + "_virtual_axis_group"));
58     setVirtualScalarGroup(CScalarGroup::create(getId() + "_virtual_scalar_group"));
59   }
60
61   CGrid::~CGrid(void)
62   {
63    if (0 != clientDistribution_) delete clientDistribution_;
64    if (0 != serverDistribution_) delete serverDistribution_;
65    if (0 != clientServerMap_) delete clientServerMap_;
66    if (0 != transformations_) delete transformations_;
67   }
68
69   ///---------------------------------------------------------------
70
71   StdString CGrid::GetName(void)    { return StdString("grid"); }
72   StdString CGrid::GetDefName(void) { return CGrid::GetName(); }
73   ENodeType CGrid::GetType(void)    { return eGrid; }
74
75
76   StdSize CGrid::getDimension(void)
77   {
78      return getGlobalDimension().size();
79   }
80
81   //---------------------------------------------------------------
82
83   StdSize CGrid::getDataSize(void) const
84   {
85     StdSize retvalue = 1;
86     if (!isScalarGrid())
87     {
88       std::vector<int> dataNindex = clientDistribution_->getDataNIndex();
89       for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];
90     }
91     return retvalue;
92   }
93
94   /*!
95    * Compute the minimum buffer size required to send the attributes to the server(s).
96    *
97    * \return A map associating the server rank with its minimum buffer size.
98    */
99   std::map<int, StdSize> CGrid::getAttributesBufferSize()
100   {
101     std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes();
102
103     // The grid indexes require a similar size as the actual data
104     std::map<int, StdSize> dataSizes = getDataBufferSize();
105     std::map<int, StdSize>::iterator it, itE = dataSizes.end();
106     for (it = dataSizes.begin(); it != itE; ++it)
107     {
108       it->second += 2 * sizeof(bool);
109       if (it->second > attributesSizes[it->first])
110         attributesSizes[it->first] = it->second;
111     }
112
113     // Account for the axis attributes
114     std::vector<CAxis*> axisList = getAxis();
115     for (size_t i = 0; i < axisList.size(); ++i)
116     {
117       std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize();
118       for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it)
119       {
120         if (it->second > attributesSizes[it->first])
121           attributesSizes[it->first] = it->second;
122       }
123     }
124
125     // Account for the domain attributes
126     std::vector<CDomain*> domList = getDomains();
127     for (size_t i = 0; i < domList.size(); ++i)
128     {
129       std::map<int, StdSize> domAttBuffSize = domList[i]->getAttributesBufferSize();
130       for (it = domAttBuffSize.begin(), itE = domAttBuffSize.end(); it != itE; ++it)
131       {
132         if (it->second > attributesSizes[it->first])
133           attributesSizes[it->first] = it->second;
134       }
135     }
136
137     return attributesSizes;
138   }
139
140   /*!
141    * Compute the minimum buffer size required to send the data to the server(s).
142    *
143    * \param id the id used to tag the data
144    * \return A map associating the server rank with its minimum buffer size.
145    */
146   std::map<int, StdSize> CGrid::getDataBufferSize(const std::string& id /*= ""*/)
147   {
148     std::map<int, StdSize> dataSizes;
149     // The record index is sometimes sent along with the data but we always
150     // include it in the size calculation for the sake of simplicity
151     const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size() + 2 * sizeof(size_t);
152
153     std::map<int, size_t>::const_iterator itEnd = connectedDataSize_.end();
154     for (size_t k = 0; k < connectedServerRank_.size(); ++k)
155     {
156       int rank = connectedServerRank_[k];
157       std::map<int, size_t>::const_iterator it = connectedDataSize_.find(rank);
158       size_t count = (it != itEnd) ? it->second : 0;
159
160       dataSizes.insert(std::make_pair(rank, extraSize + CArray<double,1>::size(count)));
161     }
162
163     return dataSizes;
164   }
165
166   void CGrid::checkAttributesAfterTransformation()
167   {
168      setAxisList();
169      std::vector<CAxis*> axisListP = this->getAxis();
170      if (!axisListP.empty())
171      {
172        int idx = 0;
173        axisPositionInGrid_.resize(0);
174        for (int i = 0; i < axis_domain_order.numElements(); ++i)
175        {
176          int elementDimension = axis_domain_order(i);
177          if (1 == elementDimension)
178          {
179            axisPositionInGrid_.push_back(idx);
180            ++idx;
181          }
182          else if (2 == elementDimension) idx += 2;
183        }
184
185        for (int i = 0; i < axisListP.size(); ++i)
186        {
187          axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(),axisPositionInGrid_[i]);
188        }
189      }
190
191      setDomainList();
192      std::vector<CDomain*> domListP = this->getDomains();
193      if (!domListP.empty())
194      {
195        for (int i = 0; i < domListP.size(); ++i)
196        {
197          domListP[i]->checkAttributesOnClientAfterTransformation();
198        }
199      }
200   }
201
202   //---------------------------------------------------------------
203
204   /*!
205    * Test whether the data defined on the grid can be outputted in a compressed way.
206    *
207    * \return true if and only if a mask was defined for this grid
208    */
209   bool CGrid::isCompressible(void) const
210   {
211      return isCompressible_;
212   }
213
214   //---------------------------------------------------------------
215
216   void CGrid::addRelFileCompressed(const StdString& filename)
217   {
218      this->relFilesCompressed.insert(filename);
219   }
220
221   bool CGrid::isWrittenCompressed(const StdString& filename) const
222   {
223      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
224   }
225
226   //---------------------------------------------------------------
227
228   void CGrid::solveDomainAxisRef(bool areAttributesChecked)
229   {
230     if (this->isDomainAxisChecked) return;
231
232     this->solveScalarRef(areAttributesChecked);
233     this->solveAxisRef(areAttributesChecked);
234     this->solveDomainRef(areAttributesChecked);     
235     this->isDomainAxisChecked = areAttributesChecked;
236   }
237
238   void CGrid::solveDomainAxisBaseRef()
239   {
240     if (this->hasDomainAxisBaseRef_) return;
241     // Account for the scalar attributes
242     std::vector<CScalar*> scalarList = getScalars();
243     for (size_t i = 0; i < scalarList.size(); ++i)
244     {
245       scalarList[i]->setAttributesReference();
246     }
247
248     // Account for the axis attributes
249     std::vector<CAxis*> axisList = getAxis();
250     for (size_t i = 0; i < axisList.size(); ++i)
251     {
252       axisList[i]->setAttributesReference();
253     }
254
255     // Account for the domain attributes
256     std::vector<CDomain*> domList = getDomains();
257     for (size_t i = 0; i < domList.size(); ++i)
258     {
259       domList[i]->setAttributesReference();
260     }
261
262     this->hasDomainAxisBaseRef_ = true;
263   }
264
265   void CGrid::checkEligibilityForCompressedOutput()
266   {
267     // We don't check if the mask is valid here, just if a mask has been defined at this point.
268     isCompressible_ = !mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty();
269   }
270
271   void CGrid::checkMaskIndex(bool doSendingIndex)
272   {
273     CContext* context = CContext::getCurrent();
274     CContextClient* client=context->client;
275
276     if (isScalarGrid())
277     {
278       if (context->hasClient)
279          if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; }
280
281       if (this->isChecked) return;
282
283       if (context->hasClient)
284       {
285          this->computeIndexScalarGrid();
286       }
287
288       if (!(this->hasTransform() && !this->isTransformed()))
289        this->isChecked = true;
290       return;
291     }
292
293     if (context->hasClient)
294      if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
295
296     if (this->isChecked) return;
297
298     if (context->hasClient)
299     {
300        this->checkAttributesAfterTransformation();
301        this->checkMask();
302        this->computeIndex();
303     }
304
305     if (!(this->hasTransform() && !this->isTransformed())) 
306      this->isChecked = true;
307
308     if (!(this->hasTransform() && (!this->isGenerated())))
309      this->isChecked = true; 
310   }
311
312   void CGrid::createMask(void)
313   {
314      using namespace std;
315      std::vector<CDomain*> domainP = this->getDomains();
316      std::vector<CAxis*> axisP = this->getAxis();
317      int dim = domainP.size() * 2 + axisP.size();
318
319      std::vector<CArray<bool,1>* > domainMasks(domainP.size());
320      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask_1d);
321      std::vector<CArray<bool,1>* > axisMasks(axisP.size());
322      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
323
324      switch (dim) {
325        case 1:
326          checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order, true);
327          break;
328        case 2:
329          checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order, true);
330          break;
331        case 3:
332          checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order, true);
333          break;
334        case 4:
335          checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order, true);
336          break;
337        case 5:
338          checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order, true);
339          break;
340        case 6:
341          checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order, true);
342          break;
343        case 7:
344          checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order, true);
345          break;
346        default:
347          break;
348      }
349   }
350
351   void CGrid::checkMask(void)
352   {
353      using namespace std;
354      std::vector<CDomain*> domainP = this->getDomains();
355      std::vector<CAxis*> axisP = this->getAxis();
356      int dim = domainP.size() * 2 + axisP.size();
357
358      std::vector<CArray<bool,1>* > domainMasks(domainP.size());
359      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask_1d);
360      std::vector<CArray<bool,1>* > axisMasks(axisP.size());
361      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
362
363      switch (dim) {
364        case 1:
365          checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order);
366          break;
367        case 2:
368          checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order);
369          break;
370        case 3:
371          checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order);
372          break;
373        case 4:
374          checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order);
375          break;
376        case 5:
377          checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order);
378          break;
379        case 6:
380          checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order);
381          break;
382        case 7:
383          checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order);
384          break;
385        default:
386          break;
387      }
388   }
389
390   void CGrid::modifyMask(const CArray<int,1>& indexToModify)
391   {
392      using namespace std;
393      std::vector<CDomain*> domainP = this->getDomains();
394      std::vector<CAxis*> axisP = this->getAxis();
395      int dim = domainP.size() * 2 + axisP.size();
396
397      switch (dim) {
398        case 1:
399          modifyGridMask(mask_1d, indexToModify);
400          break;
401        case 2:
402          modifyGridMask(mask_2d, indexToModify);
403          break;
404        case 3:
405          modifyGridMask(mask_3d, indexToModify);
406          break;
407        case 4:
408          modifyGridMask(mask_1d, indexToModify);
409          break;
410        case 5:
411          modifyGridMask(mask_2d, indexToModify);
412          break;
413        case 6:
414          modifyGridMask(mask_3d, indexToModify);
415          break;
416        case 7:
417          modifyGridMask(mask_3d, indexToModify);
418          break;
419        default:
420          break;
421      }
422   }
423
424   //---------------------------------------------------------------
425
426   void CGrid::solveDomainRef(bool sendAtt)
427   {
428      setDomainList();
429      std::vector<CDomain*> domListP = this->getDomains();
430      if (!domListP.empty())
431      {
432        for (int i = 0; i < domListP.size(); ++i)
433        {
434          if (sendAtt) domListP[i]->sendCheckedAttributes();
435          else domListP[i]->checkAttributesOnClient();
436        }
437      }
438   }
439
440   //---------------------------------------------------------------
441
442   void CGrid::solveAxisRef(bool sendAtt)
443   {
444      setAxisList();
445      std::vector<CAxis*> axisListP = this->getAxis();
446      if (!axisListP.empty())
447      {
448        int idx = 0;
449        axisPositionInGrid_.resize(0);
450        for (int i = 0; i < axis_domain_order.numElements(); ++i)
451        {
452          int elementDimension = axis_domain_order(i);
453          if (1 == elementDimension)
454          {
455            axisPositionInGrid_.push_back(idx);
456            ++idx;
457          }
458          else if (2 == elementDimension) idx += 2;
459        }
460
461        for (int i = 0; i < axisListP.size(); ++i)
462        {
463          if (sendAtt)
464            axisListP[i]->sendCheckedAttributes(getGlobalDimension(),axisPositionInGrid_[i]);
465          else
466            axisListP[i]->checkAttributesOnClient();
467        }
468      }
469   }
470
471   //---------------------------------------------------------------
472
473   void CGrid::solveScalarRef(bool sendAtt)
474   {
475      setScalarList();
476      std::vector<CScalar*> scalarListP = this->getScalars();
477      if (!scalarListP.empty())
478      {
479        for (int i = 0; i < scalarListP.size(); ++i)
480        {
481          /*Nothing to do for now */
482//          if (sendAtt) scalarListP[i]->sendCheckedAttributes();
483//          else scalarListP[i]->checkAttributesOnClient();
484        }
485      }
486   }
487
488   std::vector<int> CGrid::getAxisPositionInGrid() const
489   {
490     return axisPositionInGrid_;
491   }
492
493   //---------------------------------------------------------------
494
495   /*!
496     Compute the global index of grid to send to server as well as the connected server of the current client.
497     First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know
498     their global index. We can have a map of global index of grid and local index that each client holds
499     Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s)
500     of the current client.
501   */
502   void CGrid::computeIndex(void)
503   {
504     CContext* context = CContext::getCurrent();
505     CContextClient* client = context->client;
506
507     // First of all, compute distribution on client side
508     clientDistribution_ = new CDistributionClient(client->clientRank, this);
509     // Get local data index on client
510     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size());
511     int nbStoreIndex = storeIndex_client.numElements();
512     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
513     isDataDistributed_= clientDistribution_->isDataDistributed();
514
515     connectedServerRank_.clear();
516
517     if (!doGridHaveDataDistributed())
518     {
519        if (client->isServerLeader())
520        {
521          size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size();
522          const std::list<int>& ranks = client->getRanksServerLeader();
523          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
524          {
525            connectedServerRank_.push_back(*itRank);
526            connectedDataSize_[*itRank] = ssize;
527          }
528        }
529        return;
530     }
531
532     // Compute mapping between client and server
533     std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement;
534     CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize);
535     serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement,
536                                                                client->clientRank,
537                                                                client->clientSize,
538                                                                axis_domain_order,
539                                                                getDistributedDimension());
540     computeIndexByElement(indexServerOnElement, globalIndexOnServer_);
541
542     const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
543     CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
544     CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
545     itGlobalMap  = itbGlobalMap = globalIndexOnServer_.begin();
546     iteGlobalMap = globalIndexOnServer_.end();
547
548     for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
549     {
550       int serverRank = itGlobalMap->first;
551       int indexSize = itGlobalMap->second.size();
552       const std::vector<size_t>& indexVec = itGlobalMap->second;
553       for (int idx = 0; idx < indexSize; ++idx)
554       {
555          itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]);
556          if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap)
557          {
558             if (connectedDataSize_.end() == connectedDataSize_.find(serverRank))
559               connectedDataSize_[serverRank] = 1;
560             else
561               ++connectedDataSize_[serverRank];
562          }
563       }
564     }
565
566     for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) {
567       connectedServerRank_.push_back(itGlobalMap->first);
568     }
569
570     nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
571   }
572
573   /*!
574      Compute the global of (client) grid to send to server with the global index of each element of grid
575      Each element of grid has its own global index associated to a groups of server. We only search for the global index of each element whose
576      server is the same, then calculate the global index of grid. This way can reduce so much the time for executing DHT, which only needs to run
577      on each element whose size is much smaller than one of whole grid.
578      \param [in] indexServerOnElement global index of each element and the rank of server associated with these index
579      \param [out] globalIndexOnServer global index of grid and its corresponding rank of server.
580   */
581   void CGrid::computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,
582                                     CClientServerMapping::GlobalIndexMap& globalIndexOnServer)
583   {
584     CContext* context = CContext::getCurrent();
585     CContextClient* client = context->client;
586     int serverSize = client->serverSize;
587     std::vector<CDomain*> domList = getDomains();
588     std::vector<CAxis*> axisList = getAxis();
589
590     // Some pre-calculations of global index on each element of current grid.
591     int nbElement = axis_domain_order.numElements();
592     std::vector<CArray<size_t,1> > globalIndexElement(nbElement);
593     int domainIdx = 0, axisIdx = 0, scalarIdx = 0;
594     std::vector<size_t> elementNGlobal(nbElement);
595     elementNGlobal[0] = 1;
596     size_t globalSize = 1;
597     for (int idx = 0; idx < nbElement; ++idx)
598     {
599       elementNGlobal[idx] = globalSize;
600       size_t elementSize;
601       size_t elementGlobalSize = 1;
602       if (2 == axis_domain_order(idx)) // This is domain
603       {
604         elementSize = domList[domainIdx]->i_index.numElements();
605         globalIndexElement[idx].resize(elementSize);
606         for (int jdx = 0; jdx < elementSize; ++jdx)
607         {
608           globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx);
609         }
610         elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue();
611         ++domainIdx;
612       }
613       else if (1 == axis_domain_order(idx))  // This is axis
614       {
615         elementSize = axisList[axisIdx]->index.numElements();
616         globalIndexElement[idx].resize(elementSize);
617         for (int jdx = 0; jdx < elementSize; ++jdx)
618         {
619           globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx);
620         }
621         elementGlobalSize = axisList[axisIdx]->n_glo.getValue();
622         ++axisIdx;
623       }
624       else  // Of course, this is scalar
625       {
626         globalIndexElement[idx].resize(1);
627         globalIndexElement[idx](0) = 0;
628         elementGlobalSize = 1;
629       }
630       globalSize *= elementGlobalSize;
631     }
632
633     std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false));
634     std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement);
635     CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server
636     // Number of temporary distributed global index held by each client for each server
637     // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank
638     CArray<int,1> nbIndexOnServerTmp(serverSize);
639     for (int idx = 0; idx < nbElement; ++idx)
640     {
641       nbIndexOnServer = 0;
642       const boost::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx];
643       const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx];
644       CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm);
645       clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient);
646       const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap();
647       CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(),
648                                                                    ite = globalIndexElementOnServerMap.end(), it;
649       for (it = itb; it != ite; ++it)
650       {
651         const std::vector<int>& tmp = it->second;
652         nbIndexOnServerTmp = 0;
653         for (int i = 0; i < tmp.size(); ++i)
654         {
655           if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]);
656         }
657         nbIndexOnServer += nbIndexOnServerTmp;
658       }
659
660       for (int i = 0; i < serverSize; ++i)
661       {
662         if (0 != nbIndexOnServer(i))
663         {
664           globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i));
665           elementOnServer[idx][i] = true;
666         }
667       }
668
669       nbIndexOnServer = 0;
670       for (it = itb; it != ite; ++it)
671       {
672         const std::vector<int>& tmp = it->second;
673         nbIndexOnServerTmp = 0;
674         for (int i = 0; i < tmp.size(); ++i)
675         {
676           if (0 == nbIndexOnServerTmp(tmp[i]))
677           {
678             globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first;
679             ++nbIndexOnServerTmp(tmp[i]);
680           }
681         }
682         nbIndexOnServer += nbIndexOnServerTmp;
683       }
684     }
685
686    // Determine server which contain global source index
687    std::vector<bool> intersectedProc(serverSize, true);
688    for (int idx = 0; idx < nbElement; ++idx)
689    {
690      std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(),
691                     intersectedProc.begin(), intersectedProc.begin(),
692                     std::logical_and<bool>());
693    }
694
695    std::vector<int> srcRank;
696    for (int idx = 0; idx < serverSize; ++idx)
697    {
698      if (intersectedProc[idx]) srcRank.push_back(idx);
699    }
700
701    // Compute the global index of grid from global index of each element.
702    for (int i = 0; i < srcRank.size(); ++i)
703    {
704      size_t ssize = 1;
705      int rankSrc = srcRank[i];
706      std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement);
707      std::vector<size_t> currentIndex(nbElement,0);
708      for (int idx = 0; idx < nbElement; ++idx)
709      {
710        ssize *= (globalElementIndexOnServer[idx][rankSrc]).size();
711        globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]);
712      }
713      globalIndexOnServer[rankSrc].resize(ssize);
714
715      std::vector<int> idxLoop(nbElement,0);
716      int innnerLoopSize = (globalIndexOfElementTmp[0])->size();
717      size_t idx = 0;
718      while (idx < ssize)
719      {
720        for (int ind = 0; ind < nbElement; ++ind)
721        {
722          if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size())
723          {
724            idxLoop[ind] = 0;
725            ++idxLoop[ind+1];
726          }
727
728          currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]];
729        }
730
731        for (int ind = 0; ind < innnerLoopSize; ++ind)
732        {
733          currentIndex[0] = (*globalIndexOfElementTmp[0])[ind];
734          size_t globalSrcIndex = 0;
735          for (int idxElement = 0; idxElement < nbElement; ++idxElement)
736          {
737            globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement];
738          }
739          globalIndexOnServer[rankSrc][idx] = globalSrcIndex;
740          ++idx;
741          ++idxLoop[0];
742        }
743      }
744    }
745   }
746   //----------------------------------------------------------------
747
748   CGrid* CGrid::createGrid(CDomain* domain)
749   {
750      std::vector<CDomain*> vecDom(1, domain);
751      std::vector<CAxis*> vecAxis;
752
753      return createGrid(vecDom, vecAxis);
754   }
755
756   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
757   {
758      std::vector<CDomain*> vecDom(1, domain);
759      std::vector<CAxis*> vecAxis(1, axis);
760
761      return createGrid(vecDom, vecAxis);
762   }
763
764   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
765                            const CArray<int,1>& axisDomainOrder)
766   {
767     std::vector<CScalar*> vecScalar;
768     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder);
769   }
770
771   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
772                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
773   {
774     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder);
775   }
776
777   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
778                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
779   {
780      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
781        ERROR("CGrid* CGrid::createGrid(...)",
782              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
783              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
784
785      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id);
786      grid->setDomainList(domains);
787      grid->setAxisList(axis);
788      grid->setScalarList(scalars);
789
790      // By default, domains are always the first elements of a grid
791      if (0 == axisDomainOrder.numElements())
792      {
793        int size = domains.size() + axis.size() + scalars.size();
794        int nb = 0;
795        grid->axis_domain_order.resize(size);
796        for (int i = 0; i < size; ++i)
797        {
798          if (i < domains.size()) {
799            grid->axis_domain_order(i) = 2;
800
801          }
802          else if ((scalars.size() < (size-nb)) < size) {
803            grid->axis_domain_order(i) = 1;
804          }
805          else
806            grid->axis_domain_order(i) = 0;
807          ++nb;
808        }
809      }
810      else
811      {
812        grid->axis_domain_order.resize(axisDomainOrder.numElements());
813        grid->axis_domain_order = axisDomainOrder;
814      }
815
816      grid->solveDomainAxisRefInheritance(true);
817
818      return grid;
819   }
820
821   CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc)
822   {
823     std::vector<CDomain*> domainSrcTmp = gridSrc->getDomains(), domainSrc;
824     std::vector<CAxis*> axisSrcTmp = gridSrc->getAxis(), axisSrc;
825     std::vector<CScalar*> scalarSrcTmp = gridSrc->getScalars(), scalarSrc;
826
827     for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
828     {
829       CDomain* domain = CDomain::createDomain();
830       domain->duplicateAttributes(domainSrcTmp[idx]);
831       domain->duplicateTransformation(domainSrcTmp[idx]);
832       domain->solveRefInheritance(true);
833       domain->solveInheritanceTransformation();
834       domainSrc.push_back(domain);
835     }
836
837     for (int idx = 0; idx < axisSrcTmp.size(); ++idx)
838     {
839       CAxis* axis = CAxis::createAxis();
840       axis->duplicateAttributes(axisSrcTmp[idx]);
841       axis->duplicateTransformation(axisSrcTmp[idx]);
842       axis->solveRefInheritance(true);
843       axis->solveInheritanceTransformation();
844       axisSrc.push_back(axis);
845     }
846
847     for (int idx = 0; idx < scalarSrcTmp.size(); ++idx)
848     {
849       CScalar* scalar = CScalar::createScalar();
850       scalar->duplicateAttributes(scalarSrcTmp[idx]);
851       scalar->duplicateTransformation(scalarSrcTmp[idx]);
852       scalar->solveRefInheritance(true);
853       scalar->solveInheritanceTransformation();
854       scalarSrc.push_back(scalar);
855     }
856
857      CGrid* grid = CGrid::createGrid(idNewGrid, domainSrc, axisSrc, scalarSrc, gridSrc->axis_domain_order);
858
859      return grid;
860   }
861
862   StdString CGrid::generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
863                               const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
864   {
865      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
866        ERROR("CGrid* CGrid::generateId(...)",
867              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
868              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
869
870      std::ostringstream id;
871
872      if (domains.empty() && axis.empty() && !scalars.empty())
873        id << "__scalar_";
874
875      if (0 != (domains.size() + axis.size() + scalars.size()))
876      {
877        id << "__grid";
878
879        if (0 == axisDomainOrder.numElements())
880        {
881          for (size_t i = 0; i < domains.size(); ++i) id << "_" << domains[i]->getId();
882          for (size_t i = 0; i < axis.size(); ++i) id << "_" << axis[i]->getId();
883          for (size_t i = 0; i < scalars.size(); ++i) id << "_" << scalars[i]->getId();
884        }
885        else
886        {
887          size_t iDomain = 0, iAxis = 0, iScalar = 0;
888          for (size_t i = 0; i < axisDomainOrder.numElements(); ++i)
889          {
890            if (2 == axisDomainOrder(i))
891              id << "_" << domains[iDomain++]->getId();
892            else if (1 == axisDomainOrder(i))
893              id << "_" << axis[iAxis++]->getId();
894            else
895              id << "_" << scalars[iScalar++]->getId();
896          }
897        }
898
899        id << "__";
900      }
901
902      return id.str();
903   }
904
905   StdString CGrid::generateId(const CGrid* gridSrc, const CGrid* gridDest)
906   {
907     StdString idSrc  = gridSrc->getId();
908     StdString idDest = gridDest->getId();
909
910     std::ostringstream id;
911     id << idSrc << "__" << idDest;
912
913     return id.str();
914   }
915
916   //----------------------------------------------------------------
917
918   CDomainGroup* CGrid::getVirtualDomainGroup() const
919   {
920     return this->vDomainGroup_;
921   }
922
923   CAxisGroup* CGrid::getVirtualAxisGroup() const
924   {
925     return this->vAxisGroup_;
926   }
927
928   CScalarGroup* CGrid::getVirtualScalarGroup() const
929   {
930     return this->vScalarGroup_;
931   }
932
933   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
934   {
935     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
936     StdSize numElements = stored.numElements();
937     for (StdSize n = 0; n < numElements; ++n)
938     {
939       field[out_i(n)] = stored(n);
940     }
941   }
942
943   void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored)
944   {
945     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
946     StdSize numElements = stored.numElements();
947     for (StdSize n = 0; n < numElements; ++n)
948     {
949       stored(n) = field[out_i(n)];
950     }
951   }
952
953   void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field)
954   {
955     const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank];
956     StdSize numElements = stored.numElements();
957     for (StdSize n = 0; n < numElements; ++n)
958     {
959       field[out_i(n)] = stored(n);
960     }
961   }
962
963   //----------------------------------------------------------------
964
965   void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const
966   {
967      const StdSize size = storeIndex_client.numElements();
968
969      stored.resize(size);
970      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
971   }
972
973   void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const
974   {
975      const StdSize size = storeIndex_client.numElements();
976
977      for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i);
978   }
979
980  void CGrid::computeIndexScalarGrid()
981  {
982    CContext* context = CContext::getCurrent();
983    CContextClient* client=context->client;
984
985    storeIndex_client.resize(1);
986    storeIndex_client(0) = 0;
987
988    connectedServerRank_.clear();
989
990    if (0 == client->clientRank)
991    {
992      for (int rank = 0; rank < client->serverSize; ++rank)
993      {
994        connectedServerRank_.push_back(rank);
995        connectedDataSize_[rank] = 1;
996        nbSenders[rank] = 1;
997      }
998    }
999    isDataDistributed_ = false;
1000  }
1001
1002  void CGrid::computeCompressedIndex()
1003  {
1004    compressedOutIndexFromClient = outIndexFromClient;
1005
1006    std::map<size_t, size_t> indexes;
1007
1008    {
1009      std::map<int, CArray<size_t,1> >::const_iterator it = compressedOutIndexFromClient.begin();
1010      std::map<int, CArray<size_t,1> >::const_iterator itEnd = compressedOutIndexFromClient.end();
1011      for (; it != itEnd; ++it)
1012      {
1013        for (int i = 0; i < it->second.numElements(); ++i)
1014          indexes.insert(std::make_pair(it->second(i), 0));
1015      }
1016    }
1017
1018    {
1019      std::map<size_t, size_t>::iterator it = indexes.begin();
1020      std::map<size_t, size_t>::iterator itEnd = indexes.end();
1021      for (size_t i = 0; it != itEnd; ++it, ++i)
1022        it->second = i;
1023    }
1024
1025    {
1026      std::map<int, CArray<size_t,1> >::iterator it = compressedOutIndexFromClient.begin();
1027      std::map<int, CArray<size_t,1> >::iterator itEnd = compressedOutIndexFromClient.end();
1028      for (; it != itEnd; ++it)
1029      {
1030        for (int i = 0; i < it->second.numElements(); ++i)
1031          it->second(i) = indexes[it->second(i)];
1032      }
1033    }
1034  }
1035
1036  void CGrid::sendIndexScalarGrid()
1037  {
1038    CContext* context = CContext::getCurrent();
1039    CContextClient* client = context->client;
1040
1041    CEventClient event(getType(), EVENT_ID_INDEX);
1042    list<CMessage> listMsg;
1043    list<CArray<size_t,1> > listOutIndex;
1044
1045    if (client->isServerLeader())
1046    {
1047      const std::list<int>& ranks = client->getRanksServerLeader();
1048      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1049      {
1050        int rank = *itRank;
1051        int nb = 1;
1052        storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));       
1053        listOutIndex.push_back(CArray<size_t,1>(nb));
1054
1055        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
1056        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
1057
1058        for (int k = 0; k < nb; ++k)
1059        {
1060          outGlobalIndexOnServer(k) = 0;
1061          outLocalIndexToServer(k)  = 0;
1062        }
1063
1064        storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1065        listMsg.push_back(CMessage());
1066        listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
1067
1068        event.push(rank, 1, listMsg.back());
1069      }
1070      client->sendEvent(event);
1071    }
1072    else
1073    {
1074      const std::list<int>& ranks = client->getRanksServerNotLeader();
1075      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1076      {
1077        int rank = *itRank;
1078        int nb = 1;       
1079        storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));
1080        CArray<int, 1>& outLocalIndexToServer = storeIndex_fromSrv[rank];
1081        for (int k = 0; k < nb; ++k)
1082        {         
1083          outLocalIndexToServer(k)  = 0;
1084        }
1085      }
1086      client->sendEvent(event);
1087    }
1088  }
1089
1090  void CGrid::sendIndex(void)
1091  {
1092    CContext* context = CContext::getCurrent();
1093    CContextClient* client = context->client;
1094
1095    CEventClient event(getType(), EVENT_ID_INDEX);
1096    int rank;
1097    list<CMessage> listMsg;
1098    list<CArray<size_t,1> > listOutIndex;
1099    const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
1100    CDistributionClient::GlobalLocalDataMap::const_iterator itIndex = globalLocalIndexSendToServer.begin(),
1101                                                           iteIndex = globalLocalIndexSendToServer.end();
1102
1103    if (!doGridHaveDataDistributed())
1104    {
1105      if (client->isServerLeader())
1106      {
1107        int indexSize = globalLocalIndexSendToServer.size();
1108        CArray<size_t,1> outGlobalIndexOnServer(indexSize);
1109        CArray<int,1> outLocalIndexToServer(indexSize);
1110        for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
1111        {
1112          outGlobalIndexOnServer(idx) = itIndex->first;
1113          outLocalIndexToServer(idx) = itIndex->second;
1114        }
1115       
1116        const std::list<int>& ranks = client->getRanksServerLeader();
1117        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1118        {
1119          storeIndex_toSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1120          storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1121          listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));
1122
1123          listMsg.push_back(CMessage());
1124          listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
1125
1126          event.push(*itRank, 1, listMsg.back());
1127        }
1128        client->sendEvent(event);
1129      }
1130      else 
1131      {
1132        int indexSize = globalLocalIndexSendToServer.size();       
1133        CArray<int,1> outLocalIndexToServer(indexSize);
1134        for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
1135        {         
1136          outLocalIndexToServer(idx) = itIndex->second;
1137        }
1138       
1139        const std::list<int>& ranks = client->getRanksServerNotLeader();
1140        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1141        {         
1142          storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1143        }
1144        client->sendEvent(event);
1145      }
1146    }
1147    else
1148    {
1149      CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;
1150      itGlobalMap = globalIndexOnServer_.begin();
1151      iteGlobalMap = globalIndexOnServer_.end();
1152
1153      std::map<int,std::vector<int> >localIndexTmp;
1154      std::map<int,std::vector<size_t> > globalIndexTmp;
1155      for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
1156      {
1157        int serverRank = itGlobalMap->first;
1158        int indexSize = itGlobalMap->second.size();
1159        const std::vector<size_t>& indexVec = itGlobalMap->second;
1160        for (int idx = 0; idx < indexSize; ++idx)
1161        {
1162          itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
1163          if (iteIndex != itIndex)
1164          {
1165            globalIndexTmp[serverRank].push_back(itIndex->first);
1166            localIndexTmp[serverRank].push_back(itIndex->second);
1167          }
1168        }
1169      }
1170
1171      for (int ns = 0; ns < connectedServerRank_.size(); ++ns)
1172      {
1173        rank = connectedServerRank_[ns];
1174        int nb = 0;
1175        if (globalIndexTmp.end() != globalIndexTmp.find(rank))
1176          nb = globalIndexTmp[rank].size();
1177
1178        storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));       
1179        listOutIndex.push_back(CArray<size_t,1>(nb));
1180
1181        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
1182        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
1183
1184        for (int k = 0; k < nb; ++k)
1185        {
1186          outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
1187          outLocalIndexToServer(k)  = localIndexTmp[rank].at(k);
1188        }
1189
1190        storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1191        listMsg.push_back(CMessage());
1192        listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
1193
1194        event.push(rank, nbSenders[rank], listMsg.back());
1195      }
1196
1197      client->sendEvent(event);
1198    }
1199  }
1200
1201  void CGrid::recvIndex(CEventServer& event)
1202  {
1203    string gridId;
1204    vector<int> ranks;
1205    vector<CBufferIn*> buffers;
1206
1207    list<CEventServer::SSubEvent>::iterator it;
1208    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1209    {
1210      ranks.push_back(it->rank);
1211      CBufferIn* buffer = it->buffer;
1212      *buffer >> gridId;
1213      buffers.push_back(buffer);
1214    }
1215    get(gridId)->recvIndex(ranks, buffers);
1216  }
1217
1218  void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers)
1219  {
1220    CContext* context = CContext::getCurrent();
1221    CContextServer* server = context->server;
1222    numberWrittenIndexes_ = totalNumberWrittenIndexes_ = offsetWrittenIndexes_ = 0;
1223    connectedServerRank_ = ranks;
1224
1225    for (int n = 0; n < ranks.size(); n++)
1226    {
1227      int rank = ranks[n];
1228      CBufferIn& buffer = *buffers[n];
1229
1230      buffer >> isDataDistributed_ >> isCompressible_;
1231      size_t dataSize = 0;
1232
1233      if (0 == serverDistribution_)
1234      {
1235        int idx = 0, numElement = axis_domain_order.numElements();
1236        int ssize = numElement;
1237        std::vector<int> indexMap(numElement);
1238        for (int i = 0; i < numElement; ++i)
1239        {
1240          indexMap[i] = idx;
1241          if (2 == axis_domain_order(i))
1242          {
1243            ++ssize;
1244            idx += 2;
1245          }
1246          else
1247            ++idx;
1248        }
1249
1250        int axisId = 0, domainId = 0, scalarId = 0;
1251        std::vector<CDomain*> domainList = getDomains();
1252        std::vector<CAxis*> axisList = getAxis();
1253        std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);
1254        for (int i = 0; i < numElement; ++i)
1255        {
1256          if (2 == axis_domain_order(i)) //domain
1257          {
1258            nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin_srv;
1259            nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni_srv;
1260            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;
1261            nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
1262
1263            nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin_srv;
1264            nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj_srv;
1265            nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;
1266            nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
1267            ++domainId;
1268          }
1269          else if (1 == axis_domain_order(i)) // axis
1270          {
1271            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
1272            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
1273            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;
1274            nGlob[indexMap[i]] = axisList[axisId]->n_glo;
1275            ++axisId;
1276          }
1277          else // scalar
1278          {
1279            nZoomBegin[indexMap[i]] = 0;
1280            nZoomSize[indexMap[i]]  = 1;
1281            nZoomBeginGlobal[indexMap[i]] = 0;
1282            nGlob[indexMap[i]] = 1;
1283            ++scalarId;
1284          }
1285        }
1286        dataSize = 1;
1287        for (int i = 0; i < nZoomSize.size(); ++i)
1288          dataSize *= nZoomSize[i];
1289
1290        serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
1291                                                      nZoomBeginGlobal, nGlob);
1292      }
1293
1294      CArray<size_t,1> outIndex;
1295      buffer >> outIndex;
1296      if (isDataDistributed_)
1297        serverDistribution_->computeLocalIndex(outIndex);
1298      else
1299      {
1300        dataSize = outIndex.numElements();
1301        for (int i = 0; i < outIndex.numElements(); ++i) outIndex(i) = i;
1302      }
1303      writtenDataSize_ += dataSize;
1304     
1305      outIndexFromClient.insert(std::make_pair(rank, outIndex));
1306      connectedDataSize_[rank] = outIndex.numElements();
1307      numberWrittenIndexes_ += outIndex.numElements();
1308    }
1309
1310    // if (isScalarGrid()) return;
1311
1312    if (isDataDistributed_)
1313    {
1314      MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
1315      MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
1316      offsetWrittenIndexes_ -= numberWrittenIndexes_;
1317    }
1318    else
1319      totalNumberWrittenIndexes_ = numberWrittenIndexes_;
1320
1321    nbSenders = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks);
1322  }
1323
1324  /*
1325     Compute on the fly the global dimension of a grid with its elements
1326     \param[in/out] globalDim global dimension of grid
1327     \param[in] domains list of its domains
1328     \param[in] axiss list of its axis
1329     \param[in] scalars list of its scalars
1330     \param[in] axisDomainOrder the order of element in a grid (e.g: scalar then axis)
1331     \return The dimension of which we do distribution (often for server)
1332  */
1333  int CGrid::computeGridGlobalDimension(std::vector<int>& globalDim,
1334                                        const std::vector<CDomain*> domains,
1335                                        const std::vector<CAxis*> axis,
1336                                        const std::vector<CScalar*> scalars,
1337                                        const CArray<int,1>& axisDomainOrder)
1338  {
1339    globalDim.resize(domains.size()*2+axis.size()+scalars.size());
1340    int positionDimensionDistributed = 1;
1341    int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0;
1342    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
1343    {
1344      if (2 == axisDomainOrder(i))
1345      {
1346        if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured))
1347        {
1348          positionDimensionDistributed = idx;
1349        }
1350        else
1351        {
1352          positionDimensionDistributed = idx +1;
1353        }
1354
1355        globalDim[idx]   = domains[idxDomain]->ni_glo.getValue();
1356        globalDim[idx+1] = domains[idxDomain]->nj_glo.getValue();
1357
1358        ++idxDomain;
1359        idx += 2;
1360      }
1361      else if (1 == axisDomainOrder(i))
1362      {
1363        globalDim[idx] = axis[idxAxis]->n_glo.getValue();
1364        ++idxAxis;
1365        ++idx;
1366      }
1367      else
1368      {
1369        globalDim[idx] = 1;
1370        ++idxScalar;
1371        ++idx;
1372      }
1373    }
1374
1375    return positionDimensionDistributed;
1376  }
1377
1378  // Retrieve the global dimension of grid
1379  std::vector<int> CGrid::getGlobalDimension()
1380  {
1381    std::vector<int> globalDim;
1382    computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);
1383
1384    return globalDim;
1385  }
1386
1387  // Retrieve dimension on which we do distribution (Very often, it should be 2nd dimension)
1388  int CGrid::getDistributedDimension()
1389  {
1390    std::vector<int> globalDim;
1391    return computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);   
1392  }
1393
1394  bool CGrid::isScalarGrid() const
1395  {
1396    return (axisList_.empty() && domList_.empty());
1397  }
1398
1399  /*!
1400    Verify whether one server need to write data
1401    There are some cases on which one server has nodata to write. For example, when we
1402    just only want to zoom on a domain.
1403  */
1404  bool CGrid::doGridHaveDataToWrite()
1405  {
1406     return (0 != writtenDataSize_);
1407  }
1408
1409  /*!
1410    Return size of data which is written on each server
1411    Whatever dimension of a grid, data which are written on server must be presented as
1412    an one dimension array.
1413    \return size of data written on server
1414  */
1415  size_t CGrid::getWrittenDataSize() const
1416  {
1417    return writtenDataSize_;
1418  }
1419
1420  /*!
1421    Returns the number of indexes written by each server.
1422    \return the number of indexes written by each server
1423  */
1424  int CGrid::getNumberWrittenIndexes() const
1425  {
1426    return numberWrittenIndexes_;
1427  }
1428
1429  /*!
1430    Returns the total number of indexes written by the servers.
1431    \return the total number of indexes written by the servers
1432  */
1433  int CGrid::getTotalNumberWrittenIndexes() const
1434  {
1435    return totalNumberWrittenIndexes_;
1436  }
1437
1438  /*!
1439    Returns the offset of indexes written by each server.
1440    \return the offset of indexes written by each server
1441  */
1442  int CGrid::getOffsetWrittenIndexes() const
1443  {
1444    return offsetWrittenIndexes_;
1445  }
1446
1447  CDistributionServer* CGrid::getDistributionServer()
1448  {
1449    return serverDistribution_;
1450  }
1451
1452  CDistributionClient* CGrid::getDistributionClient()
1453  {
1454    return clientDistribution_;
1455  }
1456
1457  bool CGrid::doGridHaveDataDistributed()
1458  {
1459    if (isScalarGrid()) return false;
1460    else
1461      return isDataDistributed_;
1462  }
1463
1464   /*!
1465   \brief Dispatch event received from client
1466      Whenever a message is received in buffer of server, it will be processed depending on
1467   its event type. A new event type should be added in the switch list to make sure
1468   it processed on server side.
1469   \param [in] event: Received message
1470   */
1471  bool CGrid::dispatchEvent(CEventServer& event)
1472  {
1473
1474    if (SuperClass::dispatchEvent(event)) return true;
1475    else
1476    {
1477      switch(event.type)
1478      {
1479        case EVENT_ID_INDEX :
1480          recvIndex(event);
1481          return true;
1482          break;
1483
1484         case EVENT_ID_ADD_DOMAIN :
1485           recvAddDomain(event);
1486           return true;
1487           break;
1488
1489         case EVENT_ID_ADD_AXIS :
1490           recvAddAxis(event);
1491           return true;
1492           break;
1493
1494         case EVENT_ID_ADD_SCALAR :
1495           recvAddScalar(event);
1496           return true;
1497           break;
1498        default :
1499          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
1500                << "Unknown Event");
1501          return false;
1502      }
1503    }
1504  }
1505
1506   ///---------------------------------------------------------------
1507
1508   CDomain* CGrid::addDomain(const std::string& id)
1509   {
1510     order_.push_back(2);
1511     axis_domain_order.resize(order_.size());
1512     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
1513     return vDomainGroup_->createChild(id);
1514   }
1515
1516   CAxis* CGrid::addAxis(const std::string& id)
1517   {
1518     order_.push_back(1);
1519     axis_domain_order.resize(order_.size());
1520     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
1521     return vAxisGroup_->createChild(id);
1522   }
1523
1524   CScalar* CGrid::addScalar(const std::string& id)
1525   {
1526     order_.push_back(0);
1527     axis_domain_order.resize(order_.size());
1528     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
1529     return vScalarGroup_->createChild(id);
1530   }
1531
1532   //! Change virtual field group to a new one
1533   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
1534   {
1535      this->vDomainGroup_ = newVDomainGroup;
1536   }
1537
1538   //! Change virtual variable group to new one
1539   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
1540   {
1541      this->vAxisGroup_ = newVAxisGroup;
1542   }
1543
1544   //! Change virtual variable group to new one
1545   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup)
1546   {
1547      this->vScalarGroup_ = newVScalarGroup;
1548   }
1549
1550   /*!
1551   \brief Send a message to create a domain on server side
1552   \param[in] id String identity of domain that will be created on server
1553   */
1554   void CGrid::sendAddDomain(const string& id)
1555   {
1556    CContext* context=CContext::getCurrent();
1557
1558    if (! context->hasServer )
1559    {
1560       CContextClient* client=context->client;
1561
1562       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN);
1563       if (client->isServerLeader())
1564       {
1565         CMessage msg;
1566         msg<<this->getId();
1567         msg<<id;
1568         const std::list<int>& ranks = client->getRanksServerLeader();
1569         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1570           event.push(*itRank,1,msg);
1571         client->sendEvent(event);
1572       }
1573       else client->sendEvent(event);
1574    }
1575   }
1576
1577   /*!
1578   \brief Send a message to create an axis on server side
1579   \param[in] id String identity of axis that will be created on server
1580   */
1581   void CGrid::sendAddAxis(const string& id)
1582   {
1583    CContext* context=CContext::getCurrent();
1584
1585    if (! context->hasServer )
1586    {
1587       CContextClient* client=context->client;
1588
1589       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS);
1590       if (client->isServerLeader())
1591       {
1592         CMessage msg;
1593         msg<<this->getId();
1594         msg<<id;
1595         const std::list<int>& ranks = client->getRanksServerLeader();
1596         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1597           event.push(*itRank,1,msg);
1598         client->sendEvent(event);
1599       }
1600       else client->sendEvent(event);
1601    }
1602   }
1603
1604   /*!
1605   \brief Send a message to create a scalar on server side
1606   \param[in] id String identity of scalar that will be created on server
1607   */
1608   void CGrid::sendAddScalar(const string& id)
1609   {
1610    CContext* context=CContext::getCurrent();
1611
1612    if (! context->hasServer )
1613    {
1614       CContextClient* client=context->client;
1615
1616       CEventClient event(this->getType(),EVENT_ID_ADD_SCALAR);
1617       if (client->isServerLeader())
1618       {
1619         CMessage msg;
1620         msg<<this->getId();
1621         msg<<id;
1622         const std::list<int>& ranks = client->getRanksServerLeader();
1623         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1624           event.push(*itRank,1,msg);
1625         client->sendEvent(event);
1626       }
1627       else client->sendEvent(event);
1628    }
1629   }
1630
1631   /*!
1632   \brief Receive a message annoucing the creation of a domain on server side
1633   \param[in] event Received event
1634   */
1635   void CGrid::recvAddDomain(CEventServer& event)
1636   {
1637
1638      CBufferIn* buffer = event.subEvents.begin()->buffer;
1639      string id;
1640      *buffer >> id;
1641      get(id)->recvAddDomain(*buffer);
1642   }
1643
1644   /*!
1645   \brief Receive a message annoucing the creation of a domain on server side
1646   \param[in] buffer Buffer containing message
1647   */
1648   void CGrid::recvAddDomain(CBufferIn& buffer)
1649   {
1650      string id;
1651      buffer >> id;
1652      addDomain(id);
1653   }
1654
1655   /*!
1656   \brief Receive a message annoucing the creation of an axis on server side
1657   \param[in] event Received event
1658   */
1659   void CGrid::recvAddAxis(CEventServer& event)
1660   {
1661
1662      CBufferIn* buffer = event.subEvents.begin()->buffer;
1663      string id;
1664      *buffer >> id;
1665      get(id)->recvAddAxis(*buffer);
1666   }
1667
1668   /*!
1669   \brief Receive a message annoucing the creation of an axis on server side
1670   \param[in] buffer Buffer containing message
1671   */
1672   void CGrid::recvAddAxis(CBufferIn& buffer)
1673   {
1674      string id;
1675      buffer >> id;
1676      addAxis(id);
1677   }
1678
1679   /*!
1680   \brief Receive a message annoucing the creation of an scalar on server side
1681   \param[in] event Received event
1682   */
1683   void CGrid::recvAddScalar(CEventServer& event)
1684   {
1685
1686      CBufferIn* buffer = event.subEvents.begin()->buffer;
1687      string id;
1688      *buffer >> id;
1689      get(id)->recvAddScalar(*buffer);
1690   }
1691
1692   /*!
1693   \brief Receive a message annoucing the creation of an scalar on server side
1694   \param[in] buffer Buffer containing message
1695   */
1696   void CGrid::recvAddScalar(CBufferIn& buffer)
1697   {
1698      string id;
1699      buffer >> id;
1700      addScalar(id);
1701   }
1702
1703  /*!
1704  \brief Solve domain and axis references
1705  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
1706  all attributes from their parents, they should be processed with this function
1707  \param[in] apply inherit all attributes of parents (true)
1708  */
1709  void CGrid::solveDomainAxisRefInheritance(bool apply)
1710  {
1711    CContext* context = CContext::getCurrent();
1712    unsigned int vecSize, i;
1713    std::vector<StdString>::iterator it, itE;
1714    setDomainList();
1715    it = domList_.begin(); itE = domList_.end();
1716    for (; it != itE; ++it)
1717    {
1718      CDomain* pDom = CDomain::get(*it);
1719      if (context->hasClient)
1720      {
1721        pDom->solveRefInheritance(apply);
1722        pDom->solveInheritanceTransformation();
1723      }
1724    }
1725
1726    setAxisList();
1727    it = axisList_.begin(); itE = axisList_.end();
1728    for (; it != itE; ++it)
1729    {
1730      CAxis* pAxis = CAxis::get(*it);
1731      if (context->hasClient)
1732      {
1733        pAxis->solveRefInheritance(apply);
1734        pAxis->solveInheritanceTransformation();
1735      }
1736    }
1737
1738    setScalarList();
1739    it = scalarList_.begin(); itE = scalarList_.end();
1740    for (; it != itE; ++it)
1741    {
1742      CScalar* pScalar = CScalar::get(*it);
1743      if (context->hasClient)
1744      {
1745        pScalar->solveRefInheritance(apply);
1746        pScalar->solveInheritanceTransformation();
1747      }
1748    }
1749  }
1750
1751  bool CGrid::isTransformed()
1752  {
1753    return isTransformed_;
1754  }
1755
1756  void CGrid::setTransformed()
1757  {
1758    isTransformed_ = true;
1759  }
1760
1761  CGridTransformation* CGrid::getTransformations()
1762  {
1763    return transformations_;
1764  }
1765
1766  void CGrid::addTransGridSource(CGrid* gridSrc)
1767  {
1768    if (gridSrc_.end() == gridSrc_.find(gridSrc))
1769      gridSrc_.insert(make_pair(gridSrc,make_pair(false,"")));
1770  }
1771
1772  std::map<CGrid*,std::pair<bool,StdString> >& CGrid::getTransGridSource()
1773  {
1774    return gridSrc_;
1775  }
1776
1777  /*!
1778     Complete all the necessary (and lacking) attributes of a grid
1779     This function is similar to gridTransformation but works only (till now) on generate_rectilinear_domain transformation
1780  */
1781  void CGrid::completeGrid(CGrid* transformGridSrc)
1782  {
1783    if (0 != transformGridSrc)
1784    {
1785      if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
1786      {
1787        ERROR("CGrid::completeGrid(CGrid* transformGridSrc)",
1788             << "Two grids have different number of elements. " << std::endl
1789             << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
1790             << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
1791      }
1792    }
1793
1794    if (isGenerated()) return;
1795    setGenerated();
1796
1797    CGridGenerate gridGenerate(this, transformGridSrc);
1798    gridGenerate.completeGrid();
1799  }
1800
1801  bool CGrid::isGenerated()
1802  {
1803    return isGenerated_;
1804  }
1805
1806  void CGrid::setGenerated()
1807  {
1808    isGenerated_ = true;
1809  }
1810
1811  void CGrid::transformGrid(CGrid* transformGridSrc)
1812  {
1813    if (!transformGridSrc)
1814      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1815            << "Impossible to transform grid '" << getId() << "', the source grid is null.");
1816
1817    if (isTransformed()) return;
1818    setTransformed();
1819    if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
1820    {
1821      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1822           << "Two grids have different number of elements. " << std::endl
1823           << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
1824           << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
1825    }
1826    else
1827    {
1828    }
1829
1830    transformations_ = new CGridTransformation(this, transformGridSrc);
1831    transformations_->computeAll();
1832    if (0 < transformations_->getNbAlgo()) hasTransform_ = true;
1833
1834    // Ok, now need to compute index of grid source
1835    transformGridSrc->checkMaskIndex(false);
1836  }
1837
1838  bool CGrid::hasTransform()
1839  {
1840    if (hasTransform_) return hasTransform_;
1841
1842    std::vector<CDomain*> domList = getDomains();
1843    std::vector<CAxis*> axisList = getAxis();
1844    std::vector<CScalar*> scalarList = getScalars();
1845
1846    for (int idx = 0; idx < domList.size(); ++idx) hasTransform_ |= domList[idx]->hasTransformation();
1847    for (int idx = 0; idx < axisList.size(); ++idx) hasTransform_ |= axisList[idx]->hasTransformation();
1848    for (int idx = 0; idx < scalarList.size(); ++idx) hasTransform_ |= scalarList[idx]->hasTransformation();
1849
1850    return hasTransform_;
1851  }
1852
1853  /*!
1854  \brief Get the list of domain pointers
1855  \return list of domain pointers
1856  */
1857  std::vector<CDomain*> CGrid::getDomains()
1858  {
1859    std::vector<CDomain*> domList;
1860    if (!domList_.empty())
1861    {
1862      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
1863    }
1864    return domList;
1865  }
1866
1867  /*!
1868  \brief Get the list of  axis pointers
1869  \return list of axis pointers
1870  */
1871  std::vector<CAxis*> CGrid::getAxis()
1872  {
1873    std::vector<CAxis*> aList;
1874    if (!axisList_.empty())
1875      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
1876
1877    return aList;
1878  }
1879
1880  /*!
1881  \brief Get the list of  axis pointers
1882  \return list of axis pointers
1883  */
1884  std::vector<CScalar*> CGrid::getScalars()
1885  {
1886    std::vector<CScalar*> sList;
1887    if (!scalarList_.empty())
1888      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i]));
1889
1890    return sList;
1891  }
1892
1893  /*!
1894  \brief Get domain pointer with index
1895  \return domain pointer
1896  */
1897  CDomain* CGrid::getDomain(int domainIndex)
1898  {
1899    std::vector<CDomain*> domainListP = this->getDomains();
1900    if (domainListP.empty())
1901    {
1902      ERROR("CGrid::getDomain(int domainIndex)",
1903            << "No domain associated to this grid. " << std::endl
1904            << "Grid id = " << this->getId());
1905    }
1906
1907    if (domainIndex >= domainListP.size() || (domainIndex < 0))
1908      ERROR("CGrid::getDomain(int domainIndex)",
1909            << "Domain with the index doesn't exist " << std::endl
1910            << "Grid id = " << this->getId() << std::endl
1911            << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl);
1912
1913    return domainListP[domainIndex];
1914  }
1915
1916  /*!
1917  \brief Get the axis pointer with index
1918  \return axis pointer
1919  */
1920  CAxis* CGrid::getAxis(int axisIndex)
1921  {
1922    std::vector<CAxis*> axisListP = this->getAxis();
1923    if (axisListP.empty())
1924    {
1925      ERROR("CGrid::getDomain(int axisIndex)",
1926            << "No axis associated to this grid. " << std::endl
1927            << "Grid id = " << this->getId());
1928    }
1929
1930    if (axisIndex >= axisListP.size() || (axisIndex < 0))
1931      ERROR("CGrid::getDomain(int axisIndex)",
1932            << "Domain with the index doesn't exist " << std::endl
1933            << "Grid id = " << this->getId() << std::endl
1934            << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl);
1935
1936    return axisListP[axisIndex];
1937  }
1938
1939  /*!
1940  \brief Get the a scalar pointer
1941  \return scalar pointer
1942  */
1943  CScalar* CGrid::getScalar(int scalarIndex)
1944  {
1945    std::vector<CScalar*> scalarListP = this->getScalars();
1946    if (scalarListP.empty())
1947    {
1948      ERROR("CGrid::getScalar(int scalarIndex)",
1949            << "No scalar associated to this grid. " << std::endl
1950            << "Grid id = " << this->getId());
1951    }
1952
1953    if (scalarIndex >= scalarListP.size() || (scalarIndex < 0))
1954      ERROR("CGrid::getScalar(int scalarIndex)",
1955            << "Scalar with the index doesn't exist " << std::endl
1956            << "Grid id = " << this->getId() << std::endl
1957            << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl);
1958
1959    return scalarListP[scalarIndex];
1960  }
1961
1962  /*!
1963  \brief Set domain(s) of a grid from a list
1964  \param[in] domains list of domains
1965  */
1966  void CGrid::setDomainList(const std::vector<CDomain*> domains)
1967  {
1968    if (isDomListSet) return;
1969    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1970    if (!domains.empty() && domList.empty())
1971    {
1972      for (int i = 0; i < domains.size(); ++i)
1973        this->getVirtualDomainGroup()->addChild(domains[i]);
1974      domList = this->getVirtualDomainGroup()->getAllChildren();
1975    }
1976
1977    if (!domList.empty())
1978    {
1979      int sizeDom = domList.size();
1980      domList_.resize(sizeDom);
1981      for (int i = 0; i < sizeDom; ++i)
1982      {
1983        domList_[i] = domList[i]->getId();
1984      }
1985      isDomListSet = true;
1986    }
1987
1988  }
1989
1990  /*!
1991  \brief Set axis(s) of a grid from a list
1992  \param[in] axis list of axis
1993  */
1994  void CGrid::setAxisList(const std::vector<CAxis*> axis)
1995  {
1996    if (isAxisListSet) return;
1997    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1998    if (!axis.empty() && aList.empty())
1999    {
2000      for (int i = 0; i < axis.size(); ++i)
2001        this->getVirtualAxisGroup()->addChild(axis[i]);
2002      aList = this->getVirtualAxisGroup()->getAllChildren();
2003    }
2004
2005    if (!aList.empty())
2006    {
2007      int sizeAxis = aList.size();
2008      axisList_.resize(sizeAxis);
2009      for (int i = 0; i < sizeAxis; ++i)
2010      {
2011        axisList_[i] = aList[i]->getId();
2012      }
2013      isAxisListSet = true;
2014    }
2015  }
2016
2017  /*!
2018  \brief Set scalar(s) of a grid from a list
2019  \param[in] scalars list of scalars
2020  */
2021  void CGrid::setScalarList(const std::vector<CScalar*> scalars)
2022  {
2023    if (isScalarListSet) return;
2024    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
2025    if (!scalars.empty() && sList.empty())
2026    {
2027      for (int i = 0; i < scalars.size(); ++i)
2028        this->getVirtualScalarGroup()->addChild(scalars[i]);
2029      sList = this->getVirtualScalarGroup()->getAllChildren();
2030    }
2031
2032    if (!sList.empty())
2033    {
2034      int sizeScalar = sList.size();
2035      scalarList_.resize(sizeScalar);
2036      for (int i = 0; i < sizeScalar; ++i)
2037      {
2038        scalarList_[i] = sList[i]->getId();
2039      }
2040      isScalarListSet = true;
2041    }
2042  }
2043
2044  /*!
2045  \brief Get list of id of domains
2046  \return id list of domains
2047  */
2048  std::vector<StdString> CGrid::getDomainList()
2049  {
2050    setDomainList();
2051    return domList_;
2052  }
2053
2054  /*!
2055  \brief Get list of id of axis
2056  \return id list of axis
2057  */
2058  std::vector<StdString> CGrid::getAxisList()
2059  {
2060    setAxisList();
2061    return axisList_;
2062  }
2063
2064  /*!
2065  \brief Get list of id of scalar
2066  \return id list of scalar
2067  */
2068  std::vector<StdString> CGrid::getScalarList()
2069  {
2070    setScalarList();
2071    return scalarList_;
2072  }
2073
2074  /*!
2075    Send all attributes of domains from client to server
2076  */
2077  void CGrid::sendAllDomains()
2078  {
2079    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
2080    int dSize = domList.size();
2081    for (int i = 0; i < dSize; ++i)
2082    {
2083      sendAddDomain(domList[i]->getId());
2084      domList[i]->sendAllAttributesToServer();
2085    }
2086  }
2087
2088  /*!
2089    Send all attributes of axis from client to server
2090  */
2091  void CGrid::sendAllAxis()
2092  {
2093    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
2094    int aSize = aList.size();
2095
2096    for (int i = 0; i < aSize; ++i)
2097    {
2098      sendAddAxis(aList[i]->getId());
2099      aList[i]->sendAllAttributesToServer();
2100    }
2101  }
2102
2103  /*!
2104    Send all attributes of scalars from client to server
2105  */
2106  void CGrid::sendAllScalars()
2107  {
2108    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
2109    int sSize = sList.size();
2110
2111    for (int i = 0; i < sSize; ++i)
2112    {
2113      sendAddScalar(sList[i]->getId());
2114      sList[i]->sendAllAttributesToServer();
2115    }
2116  }
2117
2118  /*!
2119    Parse a grid, for now, it contains only domain, axis and scalar
2120  */
2121  void CGrid::parse(xml::CXMLNode& node)
2122  {
2123    SuperClass::parse(node);
2124
2125    if (node.goToChildElement())
2126    {
2127      StdString domainName("domain");
2128      StdString axisName("axis");
2129      StdString scalarName("scalar");
2130      do
2131      {
2132        if (node.getElementName() == domainName) {
2133          order_.push_back(2);
2134          this->getVirtualDomainGroup()->parseChild(node);
2135        }
2136        if (node.getElementName() == axisName) {
2137          order_.push_back(1);
2138          this->getVirtualAxisGroup()->parseChild(node);
2139        }
2140        if (node.getElementName() == scalarName) {
2141          order_.push_back(0);
2142          this->getVirtualScalarGroup()->parseChild(node);
2143        }
2144      } while (node.goToNextElement());
2145      node.goToParentElement();
2146    }
2147
2148    if (!order_.empty())
2149    {
2150      int sizeOrd = order_.size();
2151      axis_domain_order.resize(sizeOrd);
2152      for (int i = 0; i < sizeOrd; ++i)
2153      {
2154        axis_domain_order(i) = order_[i];
2155      }
2156    }
2157
2158    setDomainList();
2159    setAxisList();
2160    setScalarList();
2161   }
2162} // namespace xios
Note: See TracBrowser for help on using the repository browser.