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

Last change on this file since 1129 was 1129, checked in by mhnguyen, 7 years ago

Updating two-level server.
Each client now can play the role of server: It can forward data to other clients or write data like a server.
Each client must combine all data received from other client(s) before forward them or write them on files

+) Correct some bugs of exchange data_index in domain and axis
+) Reorder some functions in context.cpp to make sure that all necessary attributes are available before computing index
+) Add the mapping index for client to write data.

Test
+) On Curie
+) test_client and test_complete
+) Mode:

  • Only one level: Correct
  • Two levels: Work if using ddt (bug)

+) Only zoom is tested but other transformations should work
+) No reading test

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