source: XIOS/dev/XIOS_DEV_CMIP6/src/node/grid.cpp @ 1250

Last change on this file since 1250 was 1250, checked in by mhnguyen, 7 years ago

Fixing bug on mask grid

+) Add mask_0d for scalar grid
+) Transmit grid's attributes (mask) from client and reconstruct them correctly on server
+) Rebuild data in the input of data flow on the server side

Test
+) On Curie
+) Simple test

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