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

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

Cleaning up some redundant codes

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