source: XIOS/dev/dev_ym/XIOS_SERVICES/src/node/grid.cpp @ 2197

Last change on this file since 2197 was 1761, checked in by ymipsl, 5 years ago

implementing first guess for service functionnalities.

YM

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