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

Last change on this file since 1562 was 1562, checked in by oabramkina, 6 years ago

Some cleaning related to zoom.

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