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

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

Fixing bug: Writting scalar into file

+) Update writing scalar with new grid distribution system

Test
+) On Curie
+) Work

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