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

Last change on this file since 1568 was 1568, checked in by oabramkina, 3 years ago

Grid mask is now applied in the source filter of clients: unmasked values are replaced by NaN. It is not reconstructed any more by servers.

This needs to be tested more rigorously before commiting to trunk.

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