source: XIOS/dev/dev_olga/src/node/grid.cpp @ 1570

Last change on this file since 1570 was 1570, checked in by oabramkina, 3 years ago

Further simplifications on sending data/grid indexes.

(1) Domain/axis mask is not sent anymore. It has been incorporated into data index.

(2) Creating a map that holds grid mask only in case if grid mask is defined.

Still to fix: a hole in a domain or axis.

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