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

Last change on this file since 1853 was 1853, checked in by ymipsl, 4 years ago

Coupling branch : replace hasServer and hasClient combination by the name of correct service : CLIENT, GATHERER or OUT_SERVER.

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