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

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

Updating compressed index output on using 2-level server

+) Update compressed index output with new grid distribution

Test
+) On Curie
+) test_complete:

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