source: XIOS/dev/branch_openmp/src/node/grid.cpp @ 1460

Last change on this file since 1460 was 1460, checked in by yushan, 6 years ago

branch_openmp merged with XIOS_DEV_CMIP6@1459

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