source: XIOS/branchs/xios-2.5/src/node/grid.cpp @ 1627

Last change on this file since 1627 was 1624, checked in by oabramkina, 5 years ago

Bugfix for NEMO-like land processes elimination.

Values describing a domain (latitude, longitude, bounds,...) are set to -1 on land processes.

  • 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: 88.7 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;  // Here it's not important which contextClient to recuperate
696     int rank = client->clientRank;
697
698     clientDistribution_ = new CDistributionClient(rank, this);
699     // Get local data index on client
700     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size());
701     int nbStoreIndex = storeIndex_client.numElements();
702     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
703
704     if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed();
705     else
706     {
707        // Mapping global index received from clients to the storeIndex_client
708        CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient();
709        CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end();
710        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),
711                                               ite = outGlobalIndexFromClient.end(), it;
712
713        for (it = itb; it != ite; ++it)
714        {
715          int rank = it->first;
716          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];
717          outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));
718          CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank];
719          size_t nbIndex = 0;
720
721          // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance
722          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
723          {
724            if (itGloe != globalDataIndex.find(globalIndex(idx)))
725            {
726              ++nbIndex;
727            }
728          }
729
730          if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements()))
731               ERROR("void CGrid::computeClientIndex()",
732                  << "Number of local index on client is different from number of received global index"
733                  << "Rank of sent client " << rank <<"."
734                  << "Number of local index " << nbIndex << ". "
735                  << "Number of received global index " << localIndex.numElements() << ".");
736
737          nbIndex = 0;
738          for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
739          {
740            if (itGloe != globalDataIndex.find(globalIndex(idx)))
741            {
742              localIndex(idx) = globalDataIndex[globalIndex(idx)];
743            }
744          }
745        }
746      }
747   }
748
749   /*!
750     Compute connected receivers and indexes to be sent to these receivers.
751   */
752   void CGrid::computeConnectedClients()
753   {
754     CContext* context = CContext::getCurrent();
755     int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size();
756     connectedServerRank_.clear();
757     connectedDataSize_.clear();
758     globalIndexOnServer_.clear();
759     nbSenders.clear();
760
761     for (int p = 0; p < nbSrvPools; ++p)
762     {
763       CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p];
764       int receiverSize = client->serverSize;
765//       connectedServerRank_[client].clear();
766
767       if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end())
768       {
769        if (!doGridHaveDataDistributed(client))
770         {
771            if (client->isServerLeader())
772            {
773              size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size();
774              const std::list<int>& ranks = client->getRanksServerLeader();
775              for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
776              {
777                connectedServerRank_[receiverSize].push_back(*itRank);
778                connectedDataSize_[receiverSize][*itRank] = ssize;
779              }
780            }
781            return;
782         }
783
784         // Compute mapping between client and server
785         std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement;
786         CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize);
787         std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement,
788                                                                                                    client->clientRank,
789                                                                                                    client->clientSize,
790                                                                                                    axis_domain_order,
791                                                                                                    getDistributedDimension());
792
793         // Even if servers have no index, they must received something from client
794         // We only use several client to send "empty" message to these servers
795         std::list<int> serverZeroIndexLeader;
796         std::list<int> serverZeroIndexNotLeader;
797         CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader);
798         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
799           *it = serverZeroIndex[*it];
800
801         if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end())
802           computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]);
803
804         const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
805         CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
806         CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
807         itbGlobalMap = globalIndexOnServer_[receiverSize].begin();
808         iteGlobalMap = globalIndexOnServer_[receiverSize].end();
809
810         for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
811         {
812           int serverRank = itGlobalMap->first;
813           int indexSize = itGlobalMap->second.size();
814           const std::vector<size_t>& indexVec = itGlobalMap->second;
815           for (int idx = 0; idx < indexSize; ++idx)
816           {
817              itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]);
818              if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap)
819              {
820                if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank))
821                  connectedDataSize_[receiverSize][serverRank] = 1;
822                else
823                  ++connectedDataSize_[receiverSize][serverRank];
824              }
825           }
826         }
827
828         // Connected servers which really have index
829         for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) {
830           connectedServerRank_[receiverSize].push_back(itGlobalMap->first);
831         }
832
833         // Connected servers which have no index at all
834         for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it)
835           connectedServerRank_[receiverSize].push_back(*it);
836
837         // Even if a client has no index, it must connect to at least one server and
838         // send an "empty" data to this server
839         if (connectedServerRank_[receiverSize].empty())
840          connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize);
841
842         nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]);
843       }
844     }
845   }
846
847   /*!
848     Compute the global index of grid to send to server as well as the connected server of the current client.
849     First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know
850     their global index. We can have a map of global index of grid and local index that each client holds
851     Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s)
852     of the current client.
853   */
854   void CGrid::computeIndex(void)
855   {
856     CContext* context = CContext::getCurrent();
857     if (isScalarGrid())
858     {
859       computeClientIndexScalarGrid();
860       if (context->hasClient)
861       {
862         computeConnectedClientsScalarGrid();
863       }
864     }
865     else
866     {
867       computeClientIndex();
868       if (context->hasClient)
869       {
870         computeConnectedClients();
871       }
872     }
873     if (CServer::serverLevel==2)
874     {
875       computeWrittenIndex() ;
876       if (serverDistribution_!=0) serverDistribution_->partialClear() ;
877       if (clientDistribution_!=0) clientDistribution_->partialClear() ;
878       outGlobalIndexFromClient.clear() ;
879     }
880   }
881
882   /*!
883      Compute the global of (client) grid to send to server with the global index of each element of grid
884      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
885      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
886      on each element whose size is much smaller than one of whole grid.
887      \param [in] indexServerOnElement global index of each element and the rank of server associated with these index
888      \param [in] client contextClient
889      \param [out] globalIndexOnServer global index of grid and its corresponding rank of server.
890   */
891   void CGrid::computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,
892                                     const CContextClient* client,
893                                     CClientServerMapping::GlobalIndexMap& globalIndexOnServer)
894   {
895     int serverSize = client->serverSize;
896
897     std::vector<CDomain*> domList = getDomains();
898     std::vector<CAxis*> axisList = getAxis();
899
900     // Some pre-calculations of global index on each element of current grid.
901     int nbElement = axis_domain_order.numElements();
902     std::vector<CArray<size_t,1> > globalIndexElement(nbElement);
903     int domainIdx = 0, axisIdx = 0, scalarIdx = 0;
904     std::vector<size_t> elementNGlobal(nbElement);
905     elementNGlobal[0] = 1;
906     size_t globalSize = 1;
907     for (int idx = 0; idx < nbElement; ++idx)
908     {
909       elementNGlobal[idx] = globalSize;
910       size_t elementSize;
911       size_t elementGlobalSize = 1;
912       if (2 == axis_domain_order(idx)) // This is domain
913       {
914         elementSize = domList[domainIdx]->i_index.numElements();
915         globalIndexElement[idx].resize(elementSize);
916         for (int jdx = 0; jdx < elementSize; ++jdx)
917         {
918           globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx);
919         }
920         elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue();
921         ++domainIdx;
922       }
923       else if (1 == axis_domain_order(idx))  // This is axis
924       {
925         elementSize = axisList[axisIdx]->index.numElements();
926         globalIndexElement[idx].resize(elementSize);
927         for (int jdx = 0; jdx < elementSize; ++jdx)
928         {
929           globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx);
930         }
931         elementGlobalSize = axisList[axisIdx]->n_glo.getValue();
932         ++axisIdx;
933       }
934       else  // Of course, this is scalar
935       {
936         globalIndexElement[idx].resize(1);
937         globalIndexElement[idx](0) = 0;
938         elementGlobalSize = 1;
939       }
940       globalSize *= elementGlobalSize;
941     }
942
943     std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false));
944     std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement);
945     CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server
946     // Number of temporary distributed global index held by each client for each server
947     // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank
948     CArray<int,1> nbIndexOnServerTmp(serverSize);
949     for (int idx = 0; idx < nbElement; ++idx)
950     {
951       nbIndexOnServer = 0;
952       const boost::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx];
953       const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx];
954       CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm);
955       clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient);
956       const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap();
957       CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(),
958                                                                    ite = globalIndexElementOnServerMap.end(), it;
959       for (it = itb; it != ite; ++it)
960       {
961         const std::vector<int>& tmp = it->second;
962         nbIndexOnServerTmp = 0;
963         for (int i = 0; i < tmp.size(); ++i)
964         {
965           if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]);
966         }
967         nbIndexOnServer += nbIndexOnServerTmp;
968       }
969
970       for (int i = 0; i < serverSize; ++i)
971       {
972         if (0 != nbIndexOnServer(i))
973         {
974           globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i));
975           elementOnServer[idx][i] = true;
976         }
977       }
978
979     nbIndexOnServer = 0;
980//     for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j)
981     for (size_t j = 0; j < globalIndexElementOnClient.numElements(); ++j)
982     {
983       it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j));
984       if (it != ite)
985       {
986         const std::vector<int>& tmp = it->second;
987         nbIndexOnServerTmp = 0;
988         for (int i = 0; i < tmp.size(); ++i)
989         {
990           if (0 == nbIndexOnServerTmp(tmp[i]))
991           {
992             globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first;
993             ++nbIndexOnServerTmp(tmp[i]);
994           }
995         }
996         nbIndexOnServer += nbIndexOnServerTmp;
997       }
998     }
999   }
1000
1001    // Determine server which contain global source index
1002    std::vector<bool> intersectedProc(serverSize, true);
1003    for (int idx = 0; idx < nbElement; ++idx)
1004    {
1005      std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(),
1006                     intersectedProc.begin(), intersectedProc.begin(),
1007                     std::logical_and<bool>());
1008    }
1009
1010    std::vector<int> srcRank;
1011    for (int idx = 0; idx < serverSize; ++idx)
1012    {
1013      if (intersectedProc[idx]) srcRank.push_back(idx);
1014    }
1015
1016    // Compute the global index of grid from global index of each element.
1017    for (int i = 0; i < srcRank.size(); ++i)
1018    {
1019      size_t ssize = 1;
1020      int rankSrc = srcRank[i];
1021      std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement);
1022      std::vector<size_t> currentIndex(nbElement,0);
1023      for (int idx = 0; idx < nbElement; ++idx)
1024      {
1025        ssize *= (globalElementIndexOnServer[idx][rankSrc]).size();
1026        globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]);
1027      }
1028      globalIndexOnServer[rankSrc].resize(ssize);
1029
1030      std::vector<int> idxLoop(nbElement,0);
1031      int innnerLoopSize = (globalIndexOfElementTmp[0])->size();
1032      size_t idx = 0;
1033      while (idx < ssize)
1034      {
1035        for (int ind = 0; ind < nbElement; ++ind)
1036        {
1037          if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size())
1038          {
1039            idxLoop[ind] = 0;
1040            ++idxLoop[ind+1];
1041          }
1042
1043          currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]];
1044        }
1045
1046        for (int ind = 0; ind < innnerLoopSize; ++ind)
1047        {
1048          currentIndex[0] = (*globalIndexOfElementTmp[0])[ind];
1049          size_t globalSrcIndex = 0;
1050          for (int idxElement = 0; idxElement < nbElement; ++idxElement)
1051          {
1052            globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement];
1053          }
1054          globalIndexOnServer[rankSrc][idx] = globalSrcIndex;
1055          ++idx;
1056          ++idxLoop[0];
1057        }
1058      }
1059    }
1060   }
1061   //----------------------------------------------------------------
1062
1063   CGrid* CGrid::createGrid(CDomain* domain)
1064   {
1065      std::vector<CDomain*> vecDom(1, domain);
1066      std::vector<CAxis*> vecAxis;
1067
1068      return createGrid(vecDom, vecAxis);
1069   }
1070
1071   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
1072   {
1073      std::vector<CDomain*> vecDom(1, domain);
1074      std::vector<CAxis*> vecAxis(1, axis);
1075
1076      return createGrid(vecDom, vecAxis);
1077   }
1078
1079   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1080                            const CArray<int,1>& axisDomainOrder)
1081   {
1082     std::vector<CScalar*> vecScalar;
1083     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder);
1084   }
1085
1086   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1087                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
1088   {
1089     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder);
1090   }
1091
1092   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1093                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
1094   {
1095      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
1096        ERROR("CGrid* CGrid::createGrid(...)",
1097              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
1098              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
1099
1100      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id);
1101      grid->setDomainList(domains);
1102      grid->setAxisList(axis);
1103      grid->setScalarList(scalars);
1104
1105      // By default, domains are always the first elements of a grid
1106      if (0 == axisDomainOrder.numElements())
1107      {
1108        int size = domains.size() + axis.size() + scalars.size();
1109        int nb = 0;
1110        grid->axis_domain_order.resize(size);
1111        for (int i = 0; i < size; ++i)
1112        {
1113          if (i < domains.size()) {
1114            grid->axis_domain_order(i) = 2;
1115
1116          }
1117          else if ((scalars.size() < (size-nb)) < size) {
1118            grid->axis_domain_order(i) = 1;
1119          }
1120          else
1121            grid->axis_domain_order(i) = 0;
1122          ++nb;
1123        }
1124      }
1125      else
1126      {
1127        grid->axis_domain_order.resize(axisDomainOrder.numElements());
1128        grid->axis_domain_order = axisDomainOrder;
1129      }
1130
1131      grid->solveDomainAxisRefInheritance(true);
1132
1133      return grid;
1134   }
1135
1136   CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc)
1137   {
1138     std::vector<CDomain*> domainSrcTmp = gridSrc->getDomains(), domainSrc;
1139     std::vector<CAxis*> axisSrcTmp = gridSrc->getAxis(), axisSrc;
1140     std::vector<CScalar*> scalarSrcTmp = gridSrc->getScalars(), scalarSrc;
1141
1142     for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
1143     {
1144       CDomain* domain = CDomain::createDomain();
1145       domain->duplicateAttributes(domainSrcTmp[idx]);
1146       domain->duplicateTransformation(domainSrcTmp[idx]);
1147       domain->solveRefInheritance(true);
1148       domain->solveInheritanceTransformation();
1149       domainSrc.push_back(domain);
1150     }
1151
1152     for (int idx = 0; idx < axisSrcTmp.size(); ++idx)
1153     {
1154       CAxis* axis = CAxis::createAxis();
1155       axis->duplicateAttributes(axisSrcTmp[idx]);
1156       axis->duplicateTransformation(axisSrcTmp[idx]);
1157       axis->solveRefInheritance(true);
1158       axis->solveInheritanceTransformation();
1159       axisSrc.push_back(axis);
1160     }
1161
1162     for (int idx = 0; idx < scalarSrcTmp.size(); ++idx)
1163     {
1164       CScalar* scalar = CScalar::createScalar();
1165       scalar->duplicateAttributes(scalarSrcTmp[idx]);
1166       scalar->duplicateTransformation(scalarSrcTmp[idx]);
1167       scalar->solveRefInheritance(true);
1168       scalar->solveInheritanceTransformation();
1169       scalarSrc.push_back(scalar);
1170     }
1171
1172      CGrid* grid = CGrid::createGrid(idNewGrid, domainSrc, axisSrc, scalarSrc, gridSrc->axis_domain_order);
1173
1174      return grid;
1175   }
1176
1177   StdString CGrid::generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1178                               const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
1179   {
1180      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
1181        ERROR("CGrid* CGrid::generateId(...)",
1182              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
1183              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
1184
1185      std::ostringstream id;
1186
1187      if (domains.empty() && axis.empty() && !scalars.empty())
1188        id << "__scalar_";
1189
1190      if (0 != (domains.size() + axis.size() + scalars.size()))
1191      {
1192        id << "__grid";
1193
1194        if (0 == axisDomainOrder.numElements())
1195        {
1196          for (size_t i = 0; i < domains.size(); ++i) id << "_" << domains[i]->getId();
1197          for (size_t i = 0; i < axis.size(); ++i) id << "_" << axis[i]->getId();
1198          for (size_t i = 0; i < scalars.size(); ++i) id << "_" << scalars[i]->getId();
1199        }
1200        else
1201        {
1202          size_t iDomain = 0, iAxis = 0, iScalar = 0;
1203          for (size_t i = 0; i < axisDomainOrder.numElements(); ++i)
1204          {
1205            if (2 == axisDomainOrder(i))
1206              id << "_" << domains[iDomain++]->getId();
1207            else if (1 == axisDomainOrder(i))
1208              id << "_" << axis[iAxis++]->getId();
1209            else
1210              id << "_" << scalars[iScalar++]->getId();
1211          }
1212        }
1213
1214        id << "__";
1215      }
1216
1217      return id.str();
1218   }
1219
1220   StdString CGrid::generateId(const CGrid* gridSrc, const CGrid* gridDest)
1221   {
1222     StdString idSrc  = gridSrc->getId();
1223     StdString idDest = gridDest->getId();
1224
1225     std::ostringstream id;
1226     id << idSrc << "__" << idDest;
1227
1228     return id.str();
1229   }
1230
1231   //----------------------------------------------------------------
1232
1233   CDomainGroup* CGrid::getVirtualDomainGroup() const
1234   {
1235     return this->vDomainGroup_;
1236   }
1237
1238   CAxisGroup* CGrid::getVirtualAxisGroup() const
1239   {
1240     return this->vAxisGroup_;
1241   }
1242
1243   CScalarGroup* CGrid::getVirtualScalarGroup() const
1244   {
1245     return this->vScalarGroup_;
1246   }
1247
1248/*
1249   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
1250   {
1251     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
1252     StdSize numElements = stored.numElements();
1253     for (StdSize n = 0; n < numElements; ++n)
1254     {
1255       field[out_i(n)] = stored(n);
1256     }
1257   }
1258
1259   void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored)
1260   {
1261     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
1262     StdSize numElements = stored.numElements();
1263     for (StdSize n = 0; n < numElements; ++n)
1264     {
1265       stored(n) = field[out_i(n)];
1266     }
1267   }
1268
1269   void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field)
1270   {
1271     const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank];
1272     StdSize numElements = stored.numElements();
1273     for (StdSize n = 0; n < numElements; ++n)
1274     {
1275       field[out_i(n)] = stored(n);
1276     }
1277   }
1278*/
1279   //----------------------------------------------------------------
1280
1281   void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const
1282   {
1283      const StdSize size = storeIndex_client.numElements();
1284
1285      stored.resize(size);
1286      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
1287   }
1288
1289   void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const
1290   {
1291      const StdSize size = storeIndex_client.numElements();
1292
1293      for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i);
1294   }
1295
1296   void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const
1297   {
1298      const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient();
1299      const int size = localMaskedDataIndex.size();
1300     
1301      for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i];
1302   }
1303
1304
1305  void CGrid::computeClientIndexScalarGrid()
1306  {
1307    CContext* context = CContext::getCurrent();   
1308    {
1309      CContextClient* client = context->client;
1310
1311      int rank = client->clientRank;
1312
1313      clientDistribution_ = new CDistributionClient(rank, this);
1314
1315      storeIndex_client.resize(1);
1316      storeIndex_client(0) = 0;     
1317
1318      if (0 != serverDistribution_)
1319      {
1320        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),
1321                                               ite = outGlobalIndexFromClient.end(), it;
1322        for (it = itb; it != ite; ++it)
1323        {
1324          int rank = it->first;
1325          CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];
1326          outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));
1327          CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank];
1328          if (1 != globalIndex.numElements())
1329            ERROR("void CGrid::computeClientIndexScalarGrid()",
1330              << "Something wrong happened. "
1331              << "Number of received global index on scalar grid should equal to 1" 
1332              << "Number of received global index " << globalIndex.numElements() << ".");
1333
1334          localIndex(0) = globalIndex(0);
1335        }
1336      }
1337    }
1338  }
1339
1340  void CGrid::computeConnectedClientsScalarGrid()
1341  {
1342    CContext* context = CContext::getCurrent();   
1343    int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size();
1344    connectedServerRank_.clear();
1345    connectedDataSize_.clear();
1346    nbSenders.clear();
1347
1348    for (int p = 0; p < nbSrvPools; ++p)
1349    {
1350      CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p];
1351      int receiverSize = client->serverSize;
1352
1353//      connectedServerRank_[client].clear();
1354
1355      if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end())
1356      {
1357        if (client->isServerLeader())
1358        {
1359          const std::list<int>& ranks = client->getRanksServerLeader();
1360          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1361          {
1362            int rank = *itRank;
1363            int nb = 1;
1364            connectedServerRank_[receiverSize].push_back(rank);
1365            connectedDataSize_[receiverSize][rank] = nb;
1366            nbSenders[receiverSize][rank] = nb;
1367          }
1368        }
1369        else
1370        {
1371          const std::list<int>& ranks = client->getRanksServerNotLeader();
1372          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1373          {
1374            int rank = *itRank;
1375            int nb = 1;
1376            connectedServerRank_[receiverSize].push_back(rank);
1377            connectedDataSize_[receiverSize][rank] = nb;
1378            nbSenders[receiverSize][rank] = nb;
1379          }
1380        }
1381      }
1382      isDataDistributed_ = false;
1383    }
1384  }
1385
1386  void CGrid::sendIndexScalarGrid()
1387  {
1388    CContext* context = CContext::getCurrent();
1389    storeIndex_toSrv.clear();
1390    std::list<CContextClient*>::iterator it;
1391
1392    for (it=clients.begin(); it!=clients.end(); ++it)
1393    {
1394      CContextClient* client = *it;
1395      int receiverSize = client->serverSize;
1396
1397      CEventClient event(getType(), EVENT_ID_INDEX);
1398      list<CMessage> listMsg;
1399      list<CArray<size_t,1> > listOutIndex;
1400
1401      if (client->isServerLeader())
1402      {
1403        const std::list<int>& ranks = client->getRanksServerLeader();
1404        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1405        {
1406          int rank = *itRank;
1407          int nb = 1;
1408          storeIndex_toSrv[client].insert(std::make_pair(rank, CArray<int,1>(nb)));
1409          listOutIndex.push_back(CArray<size_t,1>(nb));
1410
1411          CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank];
1412          CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
1413
1414          for (int k = 0; k < nb; ++k)
1415          {
1416            outGlobalIndexOnServer(k) = 0;
1417            outLocalIndexToServer(k)  = 0;
1418          }
1419
1420          if (context->hasClient && !context->hasServer)
1421            storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1422
1423          listMsg.push_back(CMessage());
1424          listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
1425
1426          event.push(rank, 1, listMsg.back());
1427        }
1428        client->sendEvent(event);
1429      }
1430      else
1431      {
1432        const std::list<int>& ranks = client->getRanksServerNotLeader();
1433        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1434        {
1435          int rank = *itRank;
1436          int nb = 1;         
1437          CArray<int, 1> outLocalIndexToServer(nb);
1438          for (int k = 0; k < nb; ++k)
1439          {
1440            outLocalIndexToServer(k)  = 0;
1441          }
1442
1443          if (context->hasClient && !context->hasServer)
1444            storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1445        }
1446        client->sendEvent(event);
1447      }
1448    }
1449  }
1450
1451  void CGrid::sendIndex(void)
1452  {
1453    CContext* context = CContext::getCurrent();
1454    storeIndex_toSrv.clear();
1455    std::list<CContextClient*>::iterator it;
1456
1457    for (it=clients.begin(); it!=clients.end(); ++it)
1458    {
1459      CContextClient* client = *it;
1460      int receiverSize = client->serverSize;
1461
1462      CEventClient event(getType(), EVENT_ID_INDEX);
1463      int rank;
1464      list<CMessage> listMsg;
1465      list<CArray<size_t,1> > listOutIndex;
1466      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
1467      CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex,
1468                                                              iteIndex = globalLocalIndexSendToServer.end();
1469      itIndex = itbIndex;                                                             
1470
1471      if (!doGridHaveDataDistributed(client))
1472      {
1473        if (client->isServerLeader())
1474        {
1475          int indexSize = globalLocalIndexSendToServer.size();
1476          CArray<size_t,1> outGlobalIndexOnServer(indexSize);
1477          CArray<int,1> outLocalIndexToServer(indexSize);
1478          for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
1479          {
1480            outGlobalIndexOnServer(idx) = itIndex->first;
1481            outLocalIndexToServer(idx) = itIndex->second;
1482          }
1483
1484          const std::list<int>& ranks = client->getRanksServerLeader();
1485          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1486          {
1487            storeIndex_toSrv[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1488            if (context->hasClient && !context->hasServer)
1489              storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1490           
1491            listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));
1492
1493            listMsg.push_back(CMessage());
1494            listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
1495
1496            event.push(*itRank, 1, listMsg.back());
1497          }
1498          client->sendEvent(event);
1499        }
1500        else
1501        {
1502           int indexSize = globalLocalIndexSendToServer.size();
1503           CArray<int,1> outLocalIndexToServer(indexSize);
1504           for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
1505           {
1506             outLocalIndexToServer(idx) = itIndex->second;
1507           }
1508
1509           const std::list<int>& ranks = client->getRanksServerNotLeader();
1510           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1511           {
1512             storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
1513           }
1514           client->sendEvent(event);
1515         }
1516      }
1517      else
1518      {
1519        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;
1520        itGlobalMap = globalIndexOnServer_[receiverSize].begin();
1521        iteGlobalMap = globalIndexOnServer_[receiverSize].end();
1522
1523        std::map<int,std::vector<int> >localIndexTmp;
1524        std::map<int,std::vector<size_t> > globalIndexTmp;
1525        for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
1526        {
1527          int serverRank = itGlobalMap->first;
1528          int indexSize = itGlobalMap->second.size();
1529          const std::vector<size_t>& indexVec = itGlobalMap->second;
1530          for (int idx = 0; idx < indexSize; ++idx)
1531          {
1532            itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
1533            if (iteIndex != itIndex)
1534            {
1535              globalIndexTmp[serverRank].push_back(itIndex->first);
1536              localIndexTmp[serverRank].push_back(itIndex->second);
1537            }
1538          }
1539        }
1540
1541        for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns)
1542        {
1543          rank = connectedServerRank_[receiverSize][ns];
1544          int nb = 0;
1545          if (globalIndexTmp.end() != globalIndexTmp.find(rank))
1546            nb = globalIndexTmp[rank].size();
1547
1548          storeIndex_toSrv[client].insert(make_pair(rank, CArray<int,1>(nb)));
1549          listOutIndex.push_back(CArray<size_t,1>(nb));
1550
1551          CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank];
1552          CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
1553
1554          for (int k = 0; k < nb; ++k)
1555          {
1556            outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
1557            outLocalIndexToServer(k)  = localIndexTmp[rank].at(k);
1558          }
1559
1560          storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
1561          listMsg.push_back(CMessage());
1562          listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
1563
1564          event.push(rank, nbSenders[receiverSize][rank], listMsg.back());
1565        }
1566
1567        client->sendEvent(event);
1568      }
1569    }
1570  }
1571
1572  void CGrid::recvIndex(CEventServer& event)
1573  {
1574    string gridId;
1575    vector<int> ranks;
1576    vector<CBufferIn*> buffers;
1577
1578    list<CEventServer::SSubEvent>::iterator it;
1579    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1580    {
1581      ranks.push_back(it->rank);
1582      CBufferIn* buffer = it->buffer;
1583      *buffer >> gridId;
1584      buffers.push_back(buffer);
1585    }
1586    get(gridId)->recvIndex(ranks, buffers);
1587  }
1588
1589  void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers)
1590  {
1591    CContext* context = CContext::getCurrent();
1592    connectedServerRankRead_ = ranks;
1593
1594    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1;
1595    nbSrvPools = 1;   
1596    nbReadSenders.clear();
1597    for (int p = 0; p < nbSrvPools; ++p)
1598    {
1599      CContextServer* server = (!context->hasClient) ? context->server : context->serverPrimServer[p];
1600      CContextClient* client = context->client;   //(!context->hasClient) ? context->client : context->clientPrimServer[p];
1601     
1602      int idx = 0, numElement = axis_domain_order.numElements();
1603      int ssize = numElement;
1604      std::vector<int> indexMap(numElement);
1605      for (int i = 0; i < numElement; ++i)
1606      {
1607        indexMap[i] = idx;
1608        if (2 == axis_domain_order(i))
1609        {
1610          ++ssize;
1611          idx += 2;
1612        }
1613        else
1614          ++idx;
1615      }
1616
1617      for (int n = 0; n < ranks.size(); n++)
1618      {
1619        int rank = ranks[n];
1620        CBufferIn& buffer = *buffers[n];
1621
1622        buffer >> isDataDistributed_ >> isCompressible_;
1623        size_t dataSize = 0;
1624
1625        if (0 == serverDistribution_)
1626        {
1627          int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;
1628          std::vector<CDomain*> domainList = getDomains();
1629          std::vector<CAxis*> axisList = getAxis();
1630          std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize), nGlobElement(numElement);
1631          std::vector<CArray<int,1> > globalZoomIndex(numElement);
1632          for (int i = 0; i < numElement; ++i)
1633          {
1634            nGlobElement[i] = globalSize;
1635            if (2 == axis_domain_order(i)) //domain
1636            {
1637              nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin;
1638              nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni;
1639              nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;             
1640              nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
1641
1642              nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin;
1643              nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj;
1644              nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;             
1645              nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
1646
1647              {
1648                int count = 0;
1649                globalZoomIndex[i].resize(nZoomSize[indexMap[i]]*nZoomSize[indexMap[i]+1]);
1650                for (int jdx = 0; jdx < nZoomSize[indexMap[i]+1]; ++jdx)
1651                  for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx)               
1652                  {
1653                    globalZoomIndex[i](count) = (nZoomBegin[indexMap[i]] + idx) + (nZoomBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]];
1654                    ++count;
1655                  }
1656              }
1657
1658              ++domainId;
1659            }
1660            else if (1 == axis_domain_order(i)) // axis
1661            {
1662              nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin;
1663              nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_n;
1664              nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;             
1665              nGlob[indexMap[i]] = axisList[axisId]->n_glo;     
1666              if (axisList[axisId]->zoomByIndex())
1667              {
1668                globalZoomIndex[i].reference(axisList[axisId]->zoom_index);               
1669              }
1670              else
1671              {
1672                globalZoomIndex[i].resize(nZoomSize[indexMap[i]]);
1673                for (int idx = 0; idx < nZoomSize[indexMap[i]]; ++idx)
1674                  globalZoomIndex[i](idx) = nZoomBegin[indexMap[i]] + idx;
1675              }
1676
1677              ++axisId;
1678            }
1679            else // scalar
1680            { 
1681              nZoomBegin[indexMap[i]] = 0;
1682              nZoomSize[indexMap[i]]  = 1;
1683              nZoomBeginGlobal[indexMap[i]] = 0;             
1684              nGlob[indexMap[i]] = 1;
1685              globalZoomIndex[i].resize(1);
1686              globalZoomIndex[i](0) = 0;
1687              ++scalarId;
1688            }
1689          }
1690          dataSize = 1;
1691
1692          for (int i = 0; i < nZoomSize.size(); ++i)
1693            dataSize *= nZoomSize[i];
1694          serverDistribution_ = new CDistributionServer(server->intraCommRank, 
1695                                                        globalZoomIndex, axis_domain_order,
1696                                                        nZoomBegin, nZoomSize, nZoomBeginGlobal, nGlob);
1697        }
1698
1699        CArray<size_t,1> outIndex;
1700        buffer >> outIndex;
1701        outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex));
1702        connectedDataSizeRead_[rank] = outIndex.numElements();
1703
1704        if (doGridHaveDataDistributed(client))
1705        {}
1706        else
1707        {
1708          // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER
1709          // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar)
1710          dataSize = serverDistribution_->getGridSize();
1711        }
1712        writtenDataSize_ += dataSize;
1713      }
1714
1715
1716      // Compute mask of the current grid
1717      {
1718        int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;
1719        std::vector<CDomain*> domainList = getDomains();
1720        std::vector<CAxis*> axisList = getAxis();
1721        int dimSize = 2 * domainList.size() + axisList.size();
1722        std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize);       
1723        for (int i = 0; i < numElement; ++i)
1724        {         
1725          if (2 == axis_domain_order(i)) //domain
1726          {
1727            nBegin[indexMap[i]] = domainList[domainId]->ibegin;
1728            nSize[indexMap[i]]  = domainList[domainId]->ni;
1729            nBeginGlobal[indexMap[i]] = 0;             
1730            nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
1731
1732            nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin;
1733            nSize[indexMap[i] + 1] = domainList[domainId]->nj;
1734            nBeginGlobal[indexMap[i] + 1] = 0;             
1735            nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
1736
1737            ++domainId;
1738          }
1739          else if (1 == axis_domain_order(i)) // axis
1740          {
1741            nBegin[indexMap[i]] = axisList[axisId]->begin;
1742            nSize[indexMap[i]]  = axisList[axisId]->n;
1743            nBeginGlobal[indexMap[i]] = 0;             
1744            nGlob[indexMap[i]] = axisList[axisId]->n_glo;             
1745            ++axisId;
1746          }
1747          else // scalar
1748          { 
1749          }
1750        }
1751       
1752        if (nSize.empty()) // Scalar grid
1753        {
1754          nBegin.push_back(0);
1755          nSize.push_back(1);
1756          nBeginGlobal.push_back(0);             
1757          nGlob.push_back(1); 
1758        }
1759
1760        modifyMaskSize(nSize, false);
1761
1762        // These below codes are reserved for future
1763        CDistributionServer srvDist(server->intraCommRank, nBegin, nSize, nBeginGlobal, nGlob); 
1764        map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),
1765                                               ite = outGlobalIndexFromClient.end(), it; 
1766        const CDistributionServer::GlobalLocalMap&  globalLocalMask = srvDist.getGlobalLocalIndex();
1767        CDistributionServer::GlobalLocalMap::const_iterator itSrv;
1768        size_t nb = 0;
1769        for (it = itb; it != ite; ++it)
1770        {
1771          CArray<size_t,1>& globalInd = it->second;
1772          for (size_t idx = 0; idx < globalInd.numElements(); ++idx)
1773          {
1774            if (globalLocalMask.end() != globalLocalMask.find(globalInd(idx))) ++nb;
1775          }
1776        }
1777       
1778        CArray<int,1> indexToModify(nb);
1779        nb = 0;   
1780        for (it = itb; it != ite; ++it)
1781        {
1782          CArray<size_t,1>& globalInd = it->second;
1783          for (size_t idx = 0; idx < globalInd.numElements(); ++idx)
1784          {
1785            itSrv = globalLocalMask.find(globalInd(idx));
1786            if (globalLocalMask.end() != itSrv) 
1787            {
1788              indexToModify(nb) = itSrv->second;
1789              ++nb;
1790            }
1791          }
1792        }
1793
1794        modifyMask(indexToModify, true);
1795      }
1796
1797      if (isScalarGrid()) return;
1798
1799      nbReadSenders[client] = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks);
1800    }
1801  }
1802
1803  /*
1804     Compute on the fly the global dimension of a grid with its elements
1805     \param[in/out] globalDim global dimension of grid
1806     \param[in] domains list of its domains
1807     \param[in] axiss list of its axis
1808     \param[in] scalars list of its scalars
1809     \param[in] axisDomainOrder the order of element in a grid (e.g: scalar then axis)
1810     \return The dimension of which we do distribution (often for server)
1811  */
1812  int CGrid::computeGridGlobalDimension(std::vector<int>& globalDim,
1813                                        const std::vector<CDomain*> domains,
1814                                        const std::vector<CAxis*> axis,
1815                                        const std::vector<CScalar*> scalars,
1816                                        const CArray<int,1>& axisDomainOrder)
1817  {
1818 //   globalDim.resize(domains.size()*2+axis.size()+scalars.size());
1819    globalDim.resize(domains.size()*2+axis.size());
1820    int positionDimensionDistributed = 1;
1821    int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0;
1822    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
1823    {
1824      if (2 == axisDomainOrder(i))
1825      {
1826        if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured))
1827        {
1828          positionDimensionDistributed = idx;
1829        }
1830        else
1831        {
1832          positionDimensionDistributed = idx +1;
1833        }
1834
1835        globalDim[idx]   = domains[idxDomain]->ni_glo.getValue();
1836        globalDim[idx+1] = domains[idxDomain]->nj_glo.getValue();
1837
1838        ++idxDomain;
1839        idx += 2;
1840      }
1841      else if (1 == axisDomainOrder(i))
1842      {
1843        globalDim[idx] = axis[idxAxis]->n_glo.getValue();
1844        ++idxAxis;
1845        ++idx;
1846      }
1847      else
1848      {
1849//        globalDim[idx] = 1;
1850        ++idxScalar;
1851//        ++idx;
1852      }
1853    }
1854
1855    return positionDimensionDistributed;
1856  }
1857
1858  // Retrieve the global dimension of grid
1859  std::vector<int> CGrid::getGlobalDimension()
1860  {
1861    std::vector<int> globalDim;
1862    computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);
1863
1864    return globalDim;
1865  }
1866
1867  // Retrieve dimension on which we do distribution (Very often, it should be 2nd dimension)
1868  int CGrid::getDistributedDimension()
1869  {
1870    std::vector<int> globalDim;
1871    return computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);   
1872  }
1873
1874  bool CGrid::isScalarGrid() const
1875  {
1876    return (axisList_.empty() && domList_.empty());
1877  }
1878
1879  /*!
1880    Verify whether one server need to write data
1881    There are some cases on which one server has nodata to write. For example, when we
1882    just only want to zoom on a domain.
1883  */
1884  bool CGrid::doGridHaveDataToWrite()
1885  {
1886     return (0 != writtenDataSize_);
1887  }
1888
1889  /*!
1890    Return size of data which is written on each server
1891    Whatever dimension of a grid, data which are written on server must be presented as
1892    an one dimension array.
1893    \return size of data written on server
1894  */
1895  size_t CGrid::getWrittenDataSize() const
1896  {
1897    return writtenDataSize_;
1898  }
1899
1900  /*!
1901    Returns the number of indexes written by each server.
1902    \return the number of indexes written by each server
1903  */
1904  int CGrid::getNumberWrittenIndexes() const
1905  {
1906    return numberWrittenIndexes_;
1907  }
1908
1909  /*!
1910    Returns the total number of indexes written by the servers.
1911    \return the total number of indexes written by the servers
1912  */
1913  int CGrid::getTotalNumberWrittenIndexes() const
1914  {
1915    return totalNumberWrittenIndexes_;
1916  }
1917
1918  /*!
1919    Returns the offset of indexes written by each server.
1920    \return the offset of indexes written by each server
1921  */
1922  int CGrid::getOffsetWrittenIndexes() const
1923  {
1924    return offsetWrittenIndexes_;
1925  }
1926
1927  CDistributionServer* CGrid::getDistributionServer()
1928  {
1929    return serverDistribution_;
1930  }
1931
1932  CDistributionClient* CGrid::getDistributionClient()
1933  {
1934    return clientDistribution_;
1935  }
1936
1937  bool CGrid::doGridHaveDataDistributed(CContextClient* client)
1938  {
1939    if (isScalarGrid()) return false;
1940    else if (0 != client)
1941    {
1942      return  (isDataDistributed_ ||  (1 != client->clientSize) || (1 != client->serverSize));
1943    }
1944    else
1945      return isDataDistributed_;   
1946  }
1947
1948   /*!
1949   \brief Dispatch event received from client
1950      Whenever a message is received in buffer of server, it will be processed depending on
1951   its event type. A new event type should be added in the switch list to make sure
1952   it processed on server side.
1953   \param [in] event: Received message
1954   */
1955  bool CGrid::dispatchEvent(CEventServer& event)
1956  {
1957
1958    if (SuperClass::dispatchEvent(event)) return true;
1959    else
1960    {
1961      switch(event.type)
1962      {
1963        case EVENT_ID_INDEX :
1964          recvIndex(event);
1965          return true;
1966          break;
1967
1968         case EVENT_ID_ADD_DOMAIN :
1969           recvAddDomain(event);
1970           return true;
1971           break;
1972
1973         case EVENT_ID_ADD_AXIS :
1974           recvAddAxis(event);
1975           return true;
1976           break;
1977
1978         case EVENT_ID_ADD_SCALAR :
1979           recvAddScalar(event);
1980           return true;
1981           break;
1982        default :
1983          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
1984                << "Unknown Event");
1985          return false;
1986      }
1987    }
1988  }
1989
1990   ///---------------------------------------------------------------
1991
1992   CDomain* CGrid::addDomain(const std::string& id)
1993   {
1994     order_.push_back(2);
1995     axis_domain_order.resize(order_.size());
1996     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
1997     return vDomainGroup_->createChild(id);
1998   }
1999
2000   CAxis* CGrid::addAxis(const std::string& id)
2001   {
2002     order_.push_back(1);
2003     axis_domain_order.resize(order_.size());
2004     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
2005     return vAxisGroup_->createChild(id);
2006   }
2007
2008   CScalar* CGrid::addScalar(const std::string& id)
2009   {
2010     order_.push_back(0);
2011     axis_domain_order.resize(order_.size());
2012     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
2013     return vScalarGroup_->createChild(id);
2014   }
2015
2016   //! Change virtual field group to a new one
2017   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
2018   {
2019      this->vDomainGroup_ = newVDomainGroup;
2020   }
2021
2022   //! Change virtual variable group to new one
2023   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
2024   {
2025      this->vAxisGroup_ = newVAxisGroup;
2026   }
2027
2028   //! Change virtual variable group to new one
2029   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup)
2030   {
2031      this->vScalarGroup_ = newVScalarGroup;
2032   }
2033
2034   /*!
2035   \brief Send a message to create a domain on server side
2036   \param[in] id String identity of domain that will be created on server
2037   */
2038   void CGrid::sendAddDomain(const string& id)
2039   {
2040      sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN);
2041   }
2042
2043   /*!
2044   \brief Send a message to create an axis on server side
2045   \param[in] id String identity of axis that will be created on server
2046   */
2047   void CGrid::sendAddAxis(const string& id)
2048   {
2049      sendAddItem(id, (int)EVENT_ID_ADD_AXIS);
2050   }
2051
2052   /*!
2053   \brief Send a message to create a scalar on server side
2054   \param[in] id String identity of scalar that will be created on server
2055   */
2056   void CGrid::sendAddScalar(const string& id)
2057   {
2058      sendAddItem(id, (int)EVENT_ID_ADD_SCALAR);
2059   }
2060
2061   /*!
2062   \brief Receive a message annoucing the creation of a domain on server side
2063   \param[in] event Received event
2064   */
2065   void CGrid::recvAddDomain(CEventServer& event)
2066   {
2067
2068      CBufferIn* buffer = event.subEvents.begin()->buffer;
2069      string id;
2070      *buffer >> id;
2071      get(id)->recvAddDomain(*buffer);
2072   }
2073
2074   /*!
2075   \brief Receive a message annoucing the creation of a domain on server side
2076   \param[in] buffer Buffer containing message
2077   */
2078   void CGrid::recvAddDomain(CBufferIn& buffer)
2079   {
2080      string id;
2081      buffer >> id;
2082      addDomain(id);
2083   }
2084
2085   /*!
2086   \brief Receive a message annoucing the creation of an axis on server side
2087   \param[in] event Received event
2088   */
2089   void CGrid::recvAddAxis(CEventServer& event)
2090   {
2091
2092      CBufferIn* buffer = event.subEvents.begin()->buffer;
2093      string id;
2094      *buffer >> id;
2095      get(id)->recvAddAxis(*buffer);
2096   }
2097
2098   /*!
2099   \brief Receive a message annoucing the creation of an axis on server side
2100   \param[in] buffer Buffer containing message
2101   */
2102   void CGrid::recvAddAxis(CBufferIn& buffer)
2103   {
2104      string id;
2105      buffer >> id;
2106      addAxis(id);
2107   }
2108
2109   /*!
2110   \brief Receive a message annoucing the creation of an scalar on server side
2111   \param[in] event Received event
2112   */
2113   void CGrid::recvAddScalar(CEventServer& event)
2114   {
2115
2116      CBufferIn* buffer = event.subEvents.begin()->buffer;
2117      string id;
2118      *buffer >> id;
2119      get(id)->recvAddScalar(*buffer);
2120   }
2121
2122   /*!
2123   \brief Receive a message annoucing the creation of an scalar on server side
2124   \param[in] buffer Buffer containing message
2125   */
2126   void CGrid::recvAddScalar(CBufferIn& buffer)
2127   {
2128      string id;
2129      buffer >> id;
2130      addScalar(id);
2131   }
2132
2133  /*!
2134  \brief Solve domain and axis references
2135  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
2136  all attributes from their parents, they should be processed with this function
2137  \param[in] apply inherit all attributes of parents (true)
2138  */
2139  void CGrid::solveDomainAxisRefInheritance(bool apply)
2140  {
2141    CContext* context = CContext::getCurrent();
2142    unsigned int vecSize, i;
2143    std::vector<StdString>::iterator it, itE;
2144    setDomainList();
2145    it = domList_.begin(); itE = domList_.end();
2146    for (; it != itE; ++it)
2147    {
2148      CDomain* pDom = CDomain::get(*it);
2149      if (context->hasClient && !context->hasServer)     
2150      {
2151        pDom->solveRefInheritance(apply);
2152        pDom->solveInheritanceTransformation();
2153      }
2154    }
2155
2156    setAxisList();
2157    it = axisList_.begin(); itE = axisList_.end();
2158    for (; it != itE; ++it)
2159    {
2160      CAxis* pAxis = CAxis::get(*it);
2161      if (context->hasClient && !context->hasServer)
2162      {
2163        pAxis->solveRefInheritance(apply);
2164        pAxis->solveInheritanceTransformation();
2165      }
2166    }
2167
2168    setScalarList();
2169    it = scalarList_.begin(); itE = scalarList_.end();
2170    for (; it != itE; ++it)
2171    {
2172      CScalar* pScalar = CScalar::get(*it);
2173      if (context->hasClient && !context->hasServer)
2174      {
2175        pScalar->solveRefInheritance(apply);
2176        pScalar->solveInheritanceTransformation();
2177      }
2178    }
2179  }
2180
2181  bool CGrid::isTransformed()
2182  {
2183    return isTransformed_;
2184  }
2185
2186  void CGrid::setTransformed()
2187  {
2188    isTransformed_ = true;
2189  }
2190
2191  CGridTransformation* CGrid::getTransformations()
2192  {
2193    return transformations_;
2194  }
2195
2196  void CGrid::addTransGridSource(CGrid* gridSrc)
2197  {
2198    if (gridSrc_.end() == gridSrc_.find(gridSrc))
2199      gridSrc_.insert(make_pair(gridSrc,make_pair(false,"")));
2200  }
2201
2202  std::map<CGrid*,std::pair<bool,StdString> >& CGrid::getTransGridSource()
2203  {
2204    return gridSrc_;
2205  }
2206
2207  /*!
2208     Complete all the necessary (and lacking) attributes of a grid
2209     This function is similar to gridTransformation but works only (till now) on generate_rectilinear_domain transformation
2210  */
2211  void CGrid::completeGrid(CGrid* transformGridSrc)
2212  {
2213    if (0 != transformGridSrc)
2214    {
2215      if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
2216      {
2217        ERROR("CGrid::completeGrid(CGrid* transformGridSrc)",
2218             << "Two grids have different number of elements. " << std::endl
2219             << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
2220             << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
2221      }
2222    }
2223
2224    if (isGenerated()) return;
2225    setGenerated();
2226
2227    CGridGenerate gridGenerate(this, transformGridSrc);
2228    gridGenerate.completeGrid();
2229  }
2230
2231  bool CGrid::isGenerated()
2232  {
2233    return isGenerated_;
2234  }
2235
2236  void CGrid::setGenerated()
2237  {
2238    isGenerated_ = true;
2239  }
2240
2241  void CGrid::transformGrid(CGrid* transformGridSrc)
2242  {
2243    if (!transformGridSrc)
2244      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
2245            << "Impossible to transform grid '" << getId() << "', the source grid is null.");
2246
2247    if (isTransformed()) return;
2248    setTransformed();
2249    if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
2250    {
2251      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
2252           << "Two grids have different number of elements. " << std::endl
2253           << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
2254           << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
2255    }
2256    else
2257    {
2258    }
2259
2260    transformations_ = new CGridTransformation(this, transformGridSrc);
2261    transformations_->computeAll();
2262    if (0 < transformations_->getNbAlgo()) hasTransform_ = true;
2263
2264    // Ok, now need to compute index of grid source
2265    transformGridSrc->checkMaskIndex(false);
2266  }
2267
2268  bool CGrid::hasTransform()
2269  {
2270    if (hasTransform_) return hasTransform_;
2271
2272    std::vector<CDomain*> domList = getDomains();
2273    std::vector<CAxis*> axisList = getAxis();
2274    std::vector<CScalar*> scalarList = getScalars();
2275
2276    for (int idx = 0; idx < domList.size(); ++idx) hasTransform_ |= domList[idx]->hasTransformation();
2277    for (int idx = 0; idx < axisList.size(); ++idx) hasTransform_ |= axisList[idx]->hasTransformation();
2278    for (int idx = 0; idx < scalarList.size(); ++idx) hasTransform_ |= scalarList[idx]->hasTransformation();
2279
2280    return hasTransform_;
2281  }
2282
2283  /*!
2284  \brief Get the list of domain pointers
2285  \return list of domain pointers
2286  */
2287  std::vector<CDomain*> CGrid::getDomains()
2288  {
2289    std::vector<CDomain*> domList;
2290    if (!domList_.empty())
2291    {
2292      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
2293    }
2294    return domList;
2295  }
2296
2297  /*!
2298  \brief Get the list of  axis pointers
2299  \return list of axis pointers
2300  */
2301  std::vector<CAxis*> CGrid::getAxis()
2302  {
2303    std::vector<CAxis*> aList;
2304    if (!axisList_.empty())
2305      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
2306
2307    return aList;
2308  }
2309
2310  /*!
2311  \brief Get the list of  axis pointers
2312  \return list of axis pointers
2313  */
2314  std::vector<CScalar*> CGrid::getScalars()
2315  {
2316    std::vector<CScalar*> sList;
2317    if (!scalarList_.empty())
2318      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i]));
2319
2320    return sList;
2321  }
2322
2323  /*!
2324  \brief Get domain pointer with index
2325  \return domain pointer
2326  */
2327  CDomain* CGrid::getDomain(int domainIndex)
2328  {
2329    std::vector<CDomain*> domainListP = this->getDomains();
2330    if (domainListP.empty())
2331    {
2332      ERROR("CGrid::getDomain(int domainIndex)",
2333            << "No domain associated to this grid. " << std::endl
2334            << "Grid id = " << this->getId());
2335    }
2336
2337    if (domainIndex >= domainListP.size() || (domainIndex < 0))
2338      ERROR("CGrid::getDomain(int domainIndex)",
2339            << "Domain with the index doesn't exist " << std::endl
2340            << "Grid id = " << this->getId() << std::endl
2341            << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl);
2342
2343    return domainListP[domainIndex];
2344  }
2345
2346  /*!
2347  \brief Get the axis pointer with index
2348  \return axis pointer
2349  */
2350  CAxis* CGrid::getAxis(int axisIndex)
2351  {
2352    std::vector<CAxis*> axisListP = this->getAxis();
2353    if (axisListP.empty())
2354    {
2355      ERROR("CGrid::getDomain(int axisIndex)",
2356            << "No axis associated to this grid. " << std::endl
2357            << "Grid id = " << this->getId());
2358    }
2359
2360    if (axisIndex >= axisListP.size() || (axisIndex < 0))
2361      ERROR("CGrid::getDomain(int axisIndex)",
2362            << "Domain with the index doesn't exist " << std::endl
2363            << "Grid id = " << this->getId() << std::endl
2364            << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl);
2365
2366    return axisListP[axisIndex];
2367  }
2368
2369  /*!
2370  \brief Get the a scalar pointer
2371  \return scalar pointer
2372  */
2373  CScalar* CGrid::getScalar(int scalarIndex)
2374  {
2375    std::vector<CScalar*> scalarListP = this->getScalars();
2376    if (scalarListP.empty())
2377    {
2378      ERROR("CGrid::getScalar(int scalarIndex)",
2379            << "No scalar associated to this grid. " << std::endl
2380            << "Grid id = " << this->getId());
2381    }
2382
2383    if (scalarIndex >= scalarListP.size() || (scalarIndex < 0))
2384      ERROR("CGrid::getScalar(int scalarIndex)",
2385            << "Scalar with the index doesn't exist " << std::endl
2386            << "Grid id = " << this->getId() << std::endl
2387            << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl);
2388
2389    return scalarListP[scalarIndex];
2390  }
2391
2392  /*!
2393  \brief Set domain(s) of a grid from a list
2394  \param[in] domains list of domains
2395  */
2396  void CGrid::setDomainList(const std::vector<CDomain*> domains)
2397  {
2398    if (isDomListSet) return;
2399    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
2400    if (!domains.empty() && domList.empty())
2401    {
2402      for (int i = 0; i < domains.size(); ++i)
2403        this->getVirtualDomainGroup()->addChild(domains[i]);
2404      domList = this->getVirtualDomainGroup()->getAllChildren();
2405    }
2406
2407    if (!domList.empty())
2408    {
2409      int sizeDom = domList.size();
2410      domList_.resize(sizeDom);
2411      for (int i = 0; i < sizeDom; ++i)
2412      {
2413        domList_[i] = domList[i]->getId();
2414      }
2415      isDomListSet = true;
2416    }
2417
2418  }
2419
2420  /*!
2421  \brief Set axis(s) of a grid from a list
2422  \param[in] axis list of axis
2423  */
2424  void CGrid::setAxisList(const std::vector<CAxis*> axis)
2425  {
2426    if (isAxisListSet) return;
2427    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
2428    if (!axis.empty() && aList.empty())
2429    {
2430      for (int i = 0; i < axis.size(); ++i)
2431        this->getVirtualAxisGroup()->addChild(axis[i]);
2432      aList = this->getVirtualAxisGroup()->getAllChildren();
2433    }
2434
2435    if (!aList.empty())
2436    {
2437      int sizeAxis = aList.size();
2438      axisList_.resize(sizeAxis);
2439      for (int i = 0; i < sizeAxis; ++i)
2440      {
2441        axisList_[i] = aList[i]->getId();
2442      }
2443      isAxisListSet = true;
2444    }
2445  }
2446
2447  /*!
2448  \brief Set scalar(s) of a grid from a list
2449  \param[in] scalars list of scalars
2450  */
2451  void CGrid::setScalarList(const std::vector<CScalar*> scalars)
2452  {
2453    if (isScalarListSet) return;
2454    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
2455    if (!scalars.empty() && sList.empty())
2456    {
2457      for (int i = 0; i < scalars.size(); ++i)
2458        this->getVirtualScalarGroup()->addChild(scalars[i]);
2459      sList = this->getVirtualScalarGroup()->getAllChildren();
2460    }
2461
2462    if (!sList.empty())
2463    {
2464      int sizeScalar = sList.size();
2465      scalarList_.resize(sizeScalar);
2466      for (int i = 0; i < sizeScalar; ++i)
2467      {
2468        scalarList_[i] = sList[i]->getId();
2469      }
2470      isScalarListSet = true;
2471    }
2472  }
2473
2474  /*!
2475  \brief Get list of id of domains
2476  \return id list of domains
2477  */
2478  std::vector<StdString> CGrid::getDomainList()
2479  {
2480    setDomainList();
2481    return domList_;
2482  }
2483
2484  /*!
2485  \brief Get list of id of axis
2486  \return id list of axis
2487  */
2488  std::vector<StdString> CGrid::getAxisList()
2489  {
2490    setAxisList();
2491    return axisList_;
2492  }
2493
2494  /*!
2495  \brief Get list of id of scalar
2496  \return id list of scalar
2497  */
2498  std::vector<StdString> CGrid::getScalarList()
2499  {
2500    setScalarList();
2501    return scalarList_;
2502  }
2503
2504  /*!
2505    Send all attributes of domains from client to server
2506  */
2507  void CGrid::sendAllDomains()
2508  {
2509    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
2510    int dSize = domList.size();
2511    for (int i = 0; i < dSize; ++i)
2512    {
2513      sendAddDomain(domList[i]->getId());
2514      domList[i]->sendAllAttributesToServer();
2515    }
2516  }
2517
2518  /*!
2519    Send all attributes of axis from client to server
2520  */
2521  void CGrid::sendAllAxis()
2522  {
2523    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
2524    int aSize = aList.size();
2525
2526    for (int i = 0; i < aSize; ++i)
2527    {
2528      sendAddAxis(aList[i]->getId());
2529      aList[i]->sendAllAttributesToServer();
2530    }
2531  }
2532
2533  /*!
2534    Send all attributes of scalars from client to server
2535  */
2536  void CGrid::sendAllScalars()
2537  {
2538    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
2539    int sSize = sList.size();
2540
2541    for (int i = 0; i < sSize; ++i)
2542    {
2543      sendAddScalar(sList[i]->getId());
2544      sList[i]->sendAllAttributesToServer();
2545    }
2546  }
2547
2548  void CGrid::setContextClient(CContextClient* contextClient)
2549  {
2550    if (clientsSet.find(contextClient)==clientsSet.end())
2551    {
2552      clients.push_back(contextClient) ;
2553      clientsSet.insert(contextClient);
2554    }
2555    for (int i=0; i<this->getDomains().size(); i++)
2556        this->getDomains()[i]->setContextClient(contextClient);
2557    for (int i=0; i<this->getAxis().size(); i++)
2558        this->getAxis()[i]->setContextClient(contextClient);
2559  }
2560
2561  /*!
2562    Parse a grid, for now, it contains only domain, axis and scalar
2563  */
2564  void CGrid::parse(xml::CXMLNode& node)
2565  {
2566    SuperClass::parse(node);
2567
2568    if (node.goToChildElement())
2569    {
2570      StdString domainName("domain");
2571      StdString axisName("axis");
2572      StdString scalarName("scalar");
2573      do
2574      {
2575        if (node.getElementName() == domainName) {
2576          order_.push_back(2);
2577          this->getVirtualDomainGroup()->parseChild(node);
2578        }
2579        if (node.getElementName() == axisName) {
2580          order_.push_back(1);
2581          this->getVirtualAxisGroup()->parseChild(node);
2582        }
2583        if (node.getElementName() == scalarName) {
2584          order_.push_back(0);
2585          this->getVirtualScalarGroup()->parseChild(node);
2586        }
2587      } while (node.goToNextElement());
2588      node.goToParentElement();
2589    }
2590
2591    if (!order_.empty())
2592    {
2593      int sizeOrd = order_.size();
2594      axis_domain_order.resize(sizeOrd);
2595      for (int i = 0; i < sizeOrd; ++i)
2596      {
2597        axis_domain_order(i) = order_[i];
2598      }
2599    }
2600
2601    setDomainList();
2602    setAxisList();
2603    setScalarList();
2604   }
2605} // namespace xios
Note: See TracBrowser for help on using the repository browser.