source: XIOS/dev/dev_olga/src/node/grid.cpp @ 1132

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

Correcting a minor bug on writting unstructured grid

+) Correct the mapping between received data and written data.
+) Clean some redundant codes

Test
+) On Curie
+) Writing on unstructured grid works correctly

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