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

Last change on this file since 1875 was 1875, checked in by ymipsl, 4 years ago

XIOS coupling branch
Some updates.

First coupling test is beginning to work...

YM

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