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

Last change on this file since 983 was 983, checked in by oabramkina, 7 years ago

My branch

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