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

Last change on this file since 1215 was 1215, checked in by ymipsl, 7 years ago

Distribute files on servers 2 -> Ok test_dcmip2

YM

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