source: XIOS/dev/branch_yushan/src/node/grid.cpp @ 1070

Last change on this file since 1070 was 1070, checked in by yushan, 7 years ago

Preperation for merge from trunk

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