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

Last change on this file since 1136 was 1136, checked in by mhnguyen, 6 years ago

Reading for two-level server

+) Update reading with the changes of grid distribution
+) Correct a minor bug on modification grid mask
+) Do some code cleaning

Test
+) On Curie
+) Work in both mode: classical and two-level
+) Push some *.nc for test_remap

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