source: XIOS/dev/XIOS_DEV_CMIP6/src/node/grid.cpp @ 1330

Last change on this file since 1330 was 1330, checked in by oabramkina, 4 years ago

Adding buffer evaluation in case of reading.

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