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

Last change on this file since 1780 was 1761, checked in by ymipsl, 5 years ago

implementing first guess for service functionnalities.

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