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

Last change on this file since 1847 was 1847, checked in by ymipsl, 21 months ago

XIOS_COUPLING branch : more comments and cleaning

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