source: XIOS/trunk/src/node/grid.cpp @ 1622

Last change on this file since 1622 was 1622, checked in by oabramkina, 5 years ago

Exception handling on trunk.

To activate it, compilation flag -DXIOS_EXCEPTION should be added.

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