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

Last change on this file since 1021 was 1021, checked in by oabramkina, 7 years ago

Intermeadiate version for merging with new server functionalities.

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