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

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

Try committing with rapidSvn

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