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

Last change on this file since 968 was 968, checked in by mhnguyen, 5 years ago

Improvements: Tighten checking transformation type in xml

+) A not-supported transformation will cause error message

Test
+) On Curie
+) OK

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