source: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp @ 1787

Last change on this file since 1787 was 1787, checked in by ymipsl, 2 years ago

More cleaning : replace contextClient rank and size by context rank and size.
Because for couling it will have more than one contextClient.

YM

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