source: XIOS/trunk/src/node/grid.cpp @ 721

Last change on this file since 721 was 721, checked in by mhnguyen, 9 years ago

Templated version of distributed hashed table

+) Implement DHT in more generic way to work with different type of information
+) Some old codes of DHT are kept to be a reference (they will be deleted soon)

Test
+) On local, mode attached, 8 processes
+) test_remap passes and result is correct

  • 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: 44.2 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   /// ////////////////////// Définitions ////////////////////// ///
24
25   CGrid::CGrid(void)
26      : CObjectTemplate<CGrid>(), CGridAttributes()
27      , isChecked(false), isDomainAxisChecked(false)
28      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false)
29      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
30      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
31      , globalDim_(), connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false)
32      , transformations_(0), isTransformed_(false)
33      , axisPositionInGrid_(), positionDimensionDistributed_(1)
34   {
35     setVirtualDomainGroup();
36     setVirtualAxisGroup();
37   }
38
39   CGrid::CGrid(const StdString& id)
40      : CObjectTemplate<CGrid>(id), CGridAttributes()
41      , isChecked(false), isDomainAxisChecked(false)
42      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false)
43      , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0)
44      , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
45      , globalDim_(), connectedDataSize_(), connectedServerRank_(), isDataDistributed_(true), isCompressible_(false)
46      , transformations_(0), isTransformed_(false)
47      , axisPositionInGrid_(), positionDimensionDistributed_(1)
48   {
49     setVirtualDomainGroup();
50     setVirtualAxisGroup();
51   }
52
53   CGrid::~CGrid(void)
54   {
55    if (0 != clientDistribution_) delete clientDistribution_;
56    if (0 != serverDistribution_) delete serverDistribution_;
57    if (0 != clientServerMap_) delete clientServerMap_;
58    if (0 != transformations_) delete transformations_;
59   }
60
61   ///---------------------------------------------------------------
62
63   StdString CGrid::GetName(void)    { return StdString("grid"); }
64   StdString CGrid::GetDefName(void) { return CGrid::GetName(); }
65   ENodeType CGrid::GetType(void)    { return eGrid; }
66
67
68   StdSize CGrid::getDimension(void) const
69   {
70      return globalDim_.size();
71   }
72
73   //---------------------------------------------------------------
74
75   StdSize CGrid::getDataSize(void) const
76   {
77     StdSize retvalue = 1;
78     if (!isScalarGrid())
79     {
80       std::vector<int> dataNindex = clientDistribution_->getDataNIndex();
81       for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];
82     }
83     return retvalue;
84   }
85
86   std::map<int, StdSize> CGrid::getConnectedServerDataSize()
87   {
88     double secureFactor = 2.5 * sizeof(double) * CXios::bufferSizeFactor;
89     StdSize retVal = 1;
90     std::map<int, StdSize> ret;
91     std::map<int, size_t >::const_iterator itb = connectedDataSize_.begin(), it, itE = connectedDataSize_.end();
92
93     if (isScalarGrid())
94     {
95       for (it = itb; it != itE; ++it)
96       {
97         retVal *= secureFactor;
98         ret.insert(std::make_pair(it->first, retVal));
99       }
100       return ret;
101     }
102
103     for (it = itb; it != itE; ++it)
104     {
105        retVal = it->second;
106        retVal *= secureFactor;
107        ret.insert(std::make_pair<int,StdSize>(it->first, retVal));
108     }
109
110     if (connectedDataSize_.empty())
111     {
112       for (int i = 0; i < connectedServerRank_.size(); ++i)
113       {
114         retVal = 1;
115         retVal *= secureFactor;
116         ret.insert(std::make_pair<int,StdSize>(connectedServerRank_[i], retVal));
117       }
118     }
119
120     // In some cases in which domain is masked, we need to count for connected server for longitude and latitude
121     std::vector<CDomain*> domListP = this->getDomains();
122     if (!domListP.empty())
123     {
124       for (int i = 0; i < domListP.size(); ++i)
125       {
126         const std::map<int, vector<size_t> >& indexDomainServer = domListP[i]->getIndexServer();
127         std::map<int, vector<size_t> >::const_iterator itDom = indexDomainServer.begin(), iteDom = indexDomainServer.end();
128         for (; itDom != iteDom; ++itDom)
129         {
130           if (ret.end() == ret.find(itDom->first))
131           {
132              retVal = (itDom->second).size();
133              retVal *= secureFactor;
134              ret.insert(std::make_pair<int,StdSize>(itDom->first, retVal));
135           }
136         }
137       }
138     }
139
140     return ret;
141   }
142
143   void CGrid::checkAttributesAfterTransformation()
144   {
145     setDomainList();
146     std::vector<CDomain*> domListP = this->getDomains();
147     if (!domListP.empty())
148     {
149       for (int i = 0; i < domListP.size(); ++i)
150       {
151         domListP[i]->checkAttributesOnClientAfterTransformation();
152       }
153     }
154   }
155
156   //---------------------------------------------------------------
157
158   /*!
159    * Test whether the data defined on the grid can be outputted in a compressed way.
160    *
161    * \return true if and only if a mask was defined for this grid
162    */
163   bool CGrid::isCompressible(void) const
164   {
165      return isCompressible_;
166   }
167
168   //---------------------------------------------------------------
169
170   void CGrid::addRelFileCompressed(const StdString& filename)
171   {
172      this->relFilesCompressed.insert(filename);
173   }
174
175   bool CGrid::isWrittenCompressed(const StdString& filename) const
176   {
177      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
178   }
179
180   //---------------------------------------------------------------
181
182   void CGrid::solveDomainAxisRef(bool areAttributesChecked)
183   {
184     if (this->isDomainAxisChecked) return;
185
186     this->solveAxisRef(areAttributesChecked);
187     this->solveDomainRef(areAttributesChecked);
188     computeGridGlobalDimension(getDomains(), getAxis(), axis_domain_order);
189     this->isDomainAxisChecked = areAttributesChecked;
190   }
191
192   void CGrid::checkEligibilityForCompressedOutput()
193   {
194     // We don't check if the mask is valid here, just if a mask has been defined at this point.
195     isCompressible_ = !mask1.isEmpty() || !mask2.isEmpty() || !mask3.isEmpty();
196   }
197
198   void CGrid::checkMaskIndex(bool doSendingIndex)
199   {
200     CContext* context = CContext::getCurrent();
201     CContextClient* client=context->client;
202
203     if (isScalarGrid())
204     {
205       if (context->hasClient)
206          if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; }
207
208       if (this->isChecked) return;
209       if (context->hasClient)
210       {
211          this->computeIndexScalarGrid();
212       }
213
214       this->isChecked = true;
215       return;
216     }
217
218     if (context->hasClient)
219      if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
220
221     if (this->isChecked) return;
222
223     if (context->hasClient)
224     {
225        this->checkAttributesAfterTransformation();
226        this->checkMask();
227        this->computeIndex();
228     }
229     this->isChecked = true;
230   }
231
232   void CGrid::checkMask(void)
233   {
234      using namespace std;
235      std::vector<CDomain*> domainP = this->getDomains();
236      std::vector<CAxis*> axisP = this->getAxis();
237      int dim = domainP.size() * 2 + axisP.size();
238
239      std::vector<CArray<bool,1>* > domainMasks(domainP.size());
240      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask_1d);
241      std::vector<CArray<bool,1>* > axisMasks(axisP.size());
242      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
243
244      switch (dim) {
245        case 1:
246          checkGridMask(mask1, domainMasks, axisMasks, axis_domain_order);
247          break;
248        case 2:
249          checkGridMask(mask2, domainMasks, axisMasks, axis_domain_order);
250          break;
251        case 3:
252          checkGridMask(mask3, domainMasks, axisMasks, axis_domain_order);
253          break;
254//        case 4:
255//          checkGridMask(mask4, domainMasks, axisMasks, axis_domain_order);
256//          break;
257//        case 5:
258//          checkGridMask(mask5, domainMasks, axisMasks, axis_domain_order);
259//          break;
260//        case 6:
261//          checkGridMask(mask6, domainMasks, axisMasks, axis_domain_order);
262//          break;
263//        case 7:
264//          checkGridMask(mask7, domainMasks, axisMasks, axis_domain_order);
265//          break;
266        default:
267          break;
268      }
269   }
270
271   void CGrid::modifyMask(const CArray<int,1>& indexToModify)
272   {
273      using namespace std;
274      std::vector<CDomain*> domainP = this->getDomains();
275      std::vector<CAxis*> axisP = this->getAxis();
276      int dim = domainP.size() * 2 + axisP.size();
277
278      switch (dim) {
279        case 1:
280          modifyGridMask(mask1, indexToModify);
281          break;
282        case 2:
283          modifyGridMask(mask2, indexToModify);
284          break;
285        case 3:
286          modifyGridMask(mask3, indexToModify);
287          break;
288
289        default:
290          break;
291      }
292   }
293
294   //---------------------------------------------------------------
295
296   void CGrid::solveDomainRef(bool sendAtt)
297   {
298      setDomainList();
299      std::vector<CDomain*> domListP = this->getDomains();
300      if (!domListP.empty())
301      {
302        for (int i = 0; i < domListP.size(); ++i)
303        {
304          if (sendAtt) domListP[i]->sendCheckedAttributes();
305          else domListP[i]->checkAttributesOnClient();
306        }
307      }
308   }
309
310   //---------------------------------------------------------------
311
312   void CGrid::solveAxisRef(bool sendAtt)
313   {
314      setAxisList();
315      std::vector<CAxis*> axisListP = this->getAxis();
316      if (!axisListP.empty())
317      {
318        int idx = 0;
319        axisPositionInGrid_.resize(0);
320        for (int i = 0; i < axis_domain_order.numElements(); ++i)
321        {
322          if (false == axis_domain_order(i))
323          {
324            axisPositionInGrid_.push_back(idx);
325            ++idx;
326          }
327          else idx += 2;
328        }
329
330        for (int i = 0; i < axisListP.size(); ++i)
331        {
332          if (sendAtt)
333            axisListP[i]->sendCheckedAttributes(globalDim_,axisPositionInGrid_[i]);
334          else
335            axisListP[i]->checkAttributesOnClient(globalDim_,axisPositionInGrid_[i]);
336          ++idx;
337        }
338      }
339   }
340
341   std::vector<int> CGrid::getAxisPositionInGrid() const
342   {
343     return axisPositionInGrid_;
344   }
345
346   //---------------------------------------------------------------
347
348   void CGrid::computeIndex(void)
349   {
350     CContext* context = CContext::getCurrent();
351     CContextClient* client = context->client;
352
353     // First of all, compute distribution on client side
354     clientDistribution_ = new CDistributionClient(client->clientRank, this);
355     // Get local data index on client
356     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size());
357     int nbStoreIndex = storeIndex_client.numElements();
358     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
359     isDataDistributed_= clientDistribution_->isDataDistributed();
360
361     if (!doGridHaveDataDistributed())
362     {
363        if (0 == client->clientRank)
364        {
365          size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size();
366          for (int rank = 0; rank < client->serverSize; ++rank)
367            connectedDataSize_[rank] = ssize;
368        }
369        return;
370     }
371
372     // Compute mapping between client and server
373     size_t globalSizeIndex = 1, indexBegin, indexEnd;
374     int range, clientSize = client->clientSize;
375     for (int i = 0; i < globalDim_.size(); ++i) globalSizeIndex *= globalDim_[i];
376     indexBegin = 0;
377     for (int i = 0; i < clientSize; ++i)
378     {
379       range = globalSizeIndex / clientSize;
380       if (i < (globalSizeIndex%clientSize)) ++range;
381       if (i == client->clientRank) break;
382       indexBegin += range;
383     }
384     indexEnd = indexBegin + range - 1;
385
386     // Then compute distribution on server side
387     CServerDistributionDescription serverDistributionDescription(globalDim_);
388     serverDistributionDescription.computeServerGlobalIndexInRange(client->serverSize,
389                                                                   std::make_pair<size_t,size_t>(indexBegin, indexEnd),
390                                                                   positionDimensionDistributed_);
391
392     // Finally, compute index mapping between client(s) and server(s)
393     clientServerMap_ = new CClientServerMappingDistributed(serverDistributionDescription.getGlobalIndexRange(),
394                                                            client->intraComm,
395                                                            clientDistribution_->isDataDistributed());
396
397     clientServerMap_->computeServerIndexMapping(clientDistribution_->getGlobalIndex());
398     const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
399
400     const std::vector<size_t>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
401     std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
402     itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
403     iteGlobalMap = globalIndexOnServer.end();
404
405     typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
406     std::vector<int>::iterator itVec;
407     int nbGlobalIndex = globalIndexSendToServer.size();
408     for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
409     {
410       int serverRank = itGlobalMap->first;
411       int indexSize = itGlobalMap->second.size();
412       std::vector<int> permutIndex(indexSize);
413       XIOSAlgorithms::fillInIndex(indexSize, permutIndex);
414       XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(itGlobalMap->second, permutIndex);
415       BinarySearch binSearch(itGlobalMap->second);
416       for (int i = 0; i < nbGlobalIndex; ++i)
417       {
418         if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexSendToServer[i], itVec))
419         {
420           if (connectedDataSize_.end() == connectedDataSize_.find(serverRank))
421             connectedDataSize_[serverRank] = 1;
422           else
423             ++connectedDataSize_[serverRank];
424         }
425       }
426     }
427
428     connectedServerRank_.clear();
429     for (std::map<int, std::vector<size_t> >::const_iterator it = globalIndexOnServer.begin(); it != globalIndexOnServer.end(); ++it) {
430       connectedServerRank_.push_back(it->first);
431     }
432     if (!connectedDataSize_.empty())
433     {
434       connectedServerRank_.clear();
435       for (std::map<int,size_t>::const_iterator it = connectedDataSize_.begin(); it != connectedDataSize_.end(); ++it)
436         connectedServerRank_.push_back(it->first);
437     }
438
439     nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
440   }
441
442   //----------------------------------------------------------------
443
444   CGrid* CGrid::createGrid(CDomain* domain)
445   {
446      std::vector<CDomain*> vecDom(1,domain);
447      std::vector<CAxis*> vecAxis;
448      CArray<bool,1> axisDomainOrder;
449      CGrid* grid = createGrid(vecDom, vecAxis, axisDomainOrder);
450
451      return grid;
452   }
453
454   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
455   {
456      std::vector<CDomain*> vecDom(1,domain);
457      std::vector<CAxis*> vecAxis(1,axis);
458      CArray<bool,1> axisDomainOrder;
459      CGrid* grid = createGrid(vecDom, vecAxis, axisDomainOrder);
460
461      return grid;
462   }
463
464   CGrid* CGrid::createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis, CArray<bool,1> axisDomainOrder)
465   {
466      StdString new_id = StdString("__");
467      if (!domains.empty()) for (int i = 0; i < domains.size(); ++i) new_id += domains[i]->getId() + StdString("_");
468      if (!axis.empty()) for (int i = 0; i < axis.size(); ++i) new_id += axis[i]->getId() + StdString("_");
469      if (domains.empty() && axis.empty()) new_id += StdString("scalar_grid");
470      new_id += StdString("_");
471
472      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id);
473      grid->setDomainList(domains);
474      grid->setAxisList(axis);
475
476      //By default, domains are always the first ones of a grid
477      if (0 == axisDomainOrder.numElements())
478      {
479        int size = domains.size()+axis.size();
480        grid->axis_domain_order.resize(size);
481        for (int i = 0; i < size; ++i)
482        {
483          if (i < domains.size()) grid->axis_domain_order(i) = true;
484          else grid->axis_domain_order(i) = false;
485        }
486      }
487      else
488      {
489        grid->axis_domain_order.resize(axisDomainOrder.numElements());
490        grid->axis_domain_order = axisDomainOrder;
491      }
492
493      grid->computeGridGlobalDimension(domains, axis, grid->axis_domain_order);
494
495      return grid;
496   }
497
498   CDomainGroup* CGrid::getVirtualDomainGroup() const
499   {
500     return this->vDomainGroup_;
501   }
502
503   CAxisGroup* CGrid::getVirtualAxisGroup() const
504   {
505     return this->vAxisGroup_;
506   }
507
508   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
509   {
510     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
511     StdSize numElements = stored.numElements();
512     for (StdSize n = 0; n < numElements; ++n)
513     {
514       field[out_i(n)] = stored(n);
515     }
516   }
517
518   void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored)
519   {
520     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
521     StdSize numElements = stored.numElements();
522     for (StdSize n = 0; n < numElements; ++n)
523     {
524       stored(n) = field[out_i(n)];
525     }
526   }
527
528   void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field)
529   {
530     const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank];
531     StdSize numElements = stored.numElements();
532     for (StdSize n = 0; n < numElements; ++n)
533     {
534       field[out_i(n)] = stored(n);
535     }
536   }
537
538   //----------------------------------------------------------------
539
540   void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const
541   {
542      const StdSize size = storeIndex_client.numElements();
543
544      stored.resize(size);
545      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
546   }
547
548   void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const
549   {
550      const StdSize size = storeIndex_client.numElements();
551
552      for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i);
553   }
554
555  void CGrid::computeIndexScalarGrid()
556  {
557    CContext* context = CContext::getCurrent();
558    CContextClient* client=context->client;
559
560    storeIndex_client.resize(1);
561    storeIndex_client[0] = 0;
562    if (0 == client->clientRank)
563    {
564      for (int rank = 0; rank < client->serverSize; ++rank)
565        connectedDataSize_[rank] = 1;
566    }
567    isDataDistributed_ = false;
568  }
569
570  void CGrid::computeCompressedIndex()
571  {
572    compressedOutIndexFromClient = outIndexFromClient;
573
574    std::map<size_t, size_t> indexes;
575
576    {
577      std::map<int, CArray<size_t,1> >::const_iterator it = compressedOutIndexFromClient.begin();
578      std::map<int, CArray<size_t,1> >::const_iterator itEnd = compressedOutIndexFromClient.end();
579      for (; it != itEnd; ++it)
580      {
581        for (int i = 0; i < it->second.numElements(); ++i)
582          indexes.insert(std::make_pair(it->second(i), 0));
583      }
584    }
585
586    {
587      std::map<size_t, size_t>::iterator it = indexes.begin();
588      std::map<size_t, size_t>::iterator itEnd = indexes.end();
589      for (size_t i = 0; it != itEnd; ++it, ++i)
590        it->second = i;
591    }
592
593    {
594      std::map<int, CArray<size_t,1> >::iterator it = compressedOutIndexFromClient.begin();
595      std::map<int, CArray<size_t,1> >::iterator itEnd = compressedOutIndexFromClient.end();
596      for (; it != itEnd; ++it)
597      {
598        for (int i = 0; i < it->second.numElements(); ++i)
599          it->second(i) = indexes[it->second(i)];
600      }
601    }
602  }
603
604  void CGrid::sendIndexScalarGrid()
605  {
606    CContext* context = CContext::getCurrent();
607    CContextClient* client = context->client;
608
609    CEventClient event(getType(), EVENT_ID_INDEX);
610    list<CMessage> listMsg;
611    list<CArray<size_t,1> > listOutIndex;
612
613    if (0 == client->clientRank)
614    {
615      for (int rank = 0; rank < client->serverSize; ++rank)
616      {
617        int nb = 1;
618        storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));
619        listOutIndex.push_back(CArray<size_t,1>(nb));
620
621        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
622        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
623
624        for (int k = 0; k < nb; ++k)
625        {
626          outGlobalIndexOnServer(k) = 0;
627          outLocalIndexToServer(k)  = 0;
628        }
629
630        listMsg.push_back(CMessage());
631        listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
632
633        event.push(rank, 1, listMsg.back());
634      }
635
636      client->sendEvent(event);
637    }
638    else
639      client->sendEvent(event);
640  }
641
642  void CGrid::sendIndex(void)
643  {
644    CContext* context = CContext::getCurrent();
645    CContextClient* client = context->client;
646
647    CEventClient event(getType(), EVENT_ID_INDEX);
648    int rank;
649    list<CMessage> listMsg;
650    list<CArray<size_t,1> > listOutIndex;
651    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
652    const std::vector<int>& localIndexSendToServer = clientDistribution_->getLocalDataIndexSendToServer();
653    const std::vector<size_t>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
654
655    if (!doGridHaveDataDistributed())
656    {
657      if (0 == client->clientRank)
658      {
659        CArray<size_t,1> outGlobalIndexOnServer(globalIndexSendToServer.size());
660        for (int idx = 0; idx < globalIndexSendToServer.size();++idx)
661          outGlobalIndexOnServer(idx) = globalIndexSendToServer[idx];
662
663        CArray<int,1> outLocalIndexToServer(localIndexSendToServer.size());
664        for (int idx = 0; idx < localIndexSendToServer.size();++idx)
665          outLocalIndexToServer(idx) = localIndexSendToServer[idx];
666
667        for (rank = 0; rank < client->serverSize; ++rank)
668        {
669          storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
670          listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));
671
672          listMsg.push_back(CMessage());
673          listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
674
675          event.push(rank, 1, listMsg.back());
676        }
677
678        client->sendEvent(event);
679      }
680      else
681        client->sendEvent(event);
682    }
683    else
684    {
685      std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
686      itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
687      iteGlobalMap = globalIndexOnServer.end();
688
689      int nbGlobalIndex = globalIndexSendToServer.size();
690      std::map<int,std::vector<int> >localIndexTmp;
691      std::map<int,std::vector<size_t> > globalIndexTmp;
692
693      typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
694      std::vector<int>::iterator itVec;
695      for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
696      {
697        int serverRank = itGlobalMap->first;
698        int indexSize = itGlobalMap->second.size();
699        std::vector<int> permutIndex(indexSize);
700        XIOSAlgorithms::fillInIndex(indexSize, permutIndex);
701        XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(itGlobalMap->second, permutIndex);
702        BinarySearch binSearch(itGlobalMap->second);
703
704        for (int i = 0; i < nbGlobalIndex; ++i)
705        {
706          if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexSendToServer[i], itVec))
707          {
708            globalIndexTmp[serverRank].push_back(globalIndexSendToServer[i]);
709            localIndexTmp[serverRank].push_back(localIndexSendToServer[i]);
710          }
711        }
712      }
713
714      for (int ns = 0; ns < connectedServerRank_.size(); ++ns)
715      {
716        rank = connectedServerRank_[ns];
717        int nb = 0;
718        if (globalIndexTmp.end() != globalIndexTmp.find(rank))
719          nb = globalIndexTmp[rank].size();
720
721        storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));
722        listOutIndex.push_back(CArray<size_t,1>(nb));
723
724        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
725        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
726
727        for (int k = 0; k < nb; ++k)
728        {
729          outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
730          outLocalIndexToServer(k)  = localIndexTmp[rank].at(k);
731        }
732
733        listMsg.push_back(CMessage());
734        listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
735
736        event.push(rank, nbSenders[rank], listMsg.back());
737      }
738
739      client->sendEvent(event);
740    }
741  }
742
743  void CGrid::recvIndex(CEventServer& event)
744  {
745    string gridId;
746    vector<int> ranks;
747    vector<CBufferIn*> buffers;
748
749    list<CEventServer::SSubEvent>::iterator it;
750    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
751    {
752      ranks.push_back(it->rank);
753      CBufferIn* buffer = it->buffer;
754      *buffer >> gridId;
755      buffers.push_back(buffer);
756    }
757    get(gridId)->recvIndex(ranks, buffers);
758  }
759
760  void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains,
761                                         const std::vector<CAxis*>& axis,
762                                         const CArray<bool,1>& axisDomainOrder)
763  {
764    globalDim_.resize(domains.size()*2+axis.size());
765    int idx = 0, idxDomain = 0, idxAxis = 0;
766    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
767    {
768      if (axisDomainOrder(i))
769      {
770        if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured))
771        {
772          positionDimensionDistributed_ = idx;
773        }
774        else
775        {
776          positionDimensionDistributed_ = idx +1;
777        }
778
779        globalDim_[idx]   = domains[idxDomain]->ni_glo.getValue();
780        globalDim_[idx+1] = domains[idxDomain]->nj_glo.getValue();
781
782        ++idxDomain;
783        idx += 2;
784      }
785      else
786      {
787        globalDim_[idx] = axis[idxAxis]->n_glo.getValue();
788        ++idxAxis;
789        ++idx;
790      }
791    }
792  }
793
794  std::vector<int> CGrid::getGlobalDimension()
795  {
796    return globalDim_;
797  }
798
799  bool CGrid::isScalarGrid() const
800  {
801    return (axisList_.empty() && domList_.empty());
802  }
803
804  /*!
805    Verify whether one server need to write data
806    There are some cases on which one server has nodata to write. For example, when we
807    just only want to zoom on a domain.
808  */
809  bool CGrid::doGridHaveDataToWrite()
810  {
811     return (0 != writtenDataSize_);
812  }
813
814  /*!
815    Return size of data which is written on each server
816    Whatever dimension of a grid, data which are written on server must be presented as
817    an one dimension array.
818    \return size of data written on server
819  */
820  size_t CGrid::getWrittenDataSize() const
821  {
822    return writtenDataSize_;
823  }
824
825  /*!
826    Returns the number of indexes written by each server.
827    \return the number of indexes written by each server
828  */
829  int CGrid::getNumberWrittenIndexes() const
830  {
831    return numberWrittenIndexes_;
832  }
833
834  /*!
835    Returns the total number of indexes written by the servers.
836    \return the total number of indexes written by the servers
837  */
838  int CGrid::getTotalNumberWrittenIndexes() const
839  {
840    return totalNumberWrittenIndexes_;
841  }
842
843  /*!
844    Returns the offset of indexes written by each server.
845    \return the offset of indexes written by each server
846  */
847  int CGrid::getOffsetWrittenIndexes() const
848  {
849    return offsetWrittenIndexes_;
850  }
851
852  const CDistributionServer* CGrid::getDistributionServer() const
853  {
854    return serverDistribution_;
855  }
856
857  const CDistributionClient* CGrid::getDistributionClient() const
858  {
859    return clientDistribution_;
860  }
861
862  bool CGrid::doGridHaveDataDistributed()
863  {
864    if (isScalarGrid()) return false;
865    else
866      return isDataDistributed_;
867  }
868
869  void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers)
870  {
871    CContext* context = CContext::getCurrent();
872    CContextServer* server = context->server;
873    numberWrittenIndexes_ = totalNumberWrittenIndexes_ = offsetWrittenIndexes_ = 0;
874
875    for (int n = 0; n < ranks.size(); n++)
876    {
877      int rank = ranks[n];
878      CBufferIn& buffer = *buffers[n];
879
880      buffer >> isDataDistributed_ >> isCompressible_;
881      size_t dataSize = 0;
882
883      if (isScalarGrid())
884      {
885        writtenDataSize_ = numberWrittenIndexes_ = totalNumberWrittenIndexes_ = 1;
886        CArray<size_t,1> outIndex;
887        buffer >> outIndex;
888        outIndexFromClient.insert(std::make_pair(rank, outIndex));
889        std::vector<int> nZoomBegin(1,0), nZoomSize(1,1), nGlob(1,1), nZoomBeginGlobal(1,0);
890        serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
891                                                      nZoomBeginGlobal, nGlob);
892        return;
893      }
894
895      if (0 == serverDistribution_)
896      {
897        int idx = 0, numElement = axis_domain_order.numElements();
898        int ssize = numElement;
899        std::vector<int> indexMap(numElement);
900        for (int i = 0; i < numElement; ++i)
901        {
902          indexMap[i] = idx;
903          if (true == axis_domain_order(i))
904          {
905            ++ssize;
906            idx += 2;
907          }
908          else
909            ++idx;
910        }
911
912        int axisId = 0, domainId = 0;
913        std::vector<CDomain*> domainList = getDomains();
914        std::vector<CAxis*> axisList = getAxis();
915        std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);
916        for (int i = 0; i < numElement; ++i)
917        {
918          if (axis_domain_order(i))
919          {
920            nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin_srv;
921            nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni_srv;
922            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;
923            nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
924
925            nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin_srv;
926            nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj_srv;
927            nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;
928            nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
929            ++domainId;
930          }
931          else
932          {
933            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
934            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
935            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;
936            nGlob[indexMap[i]] = axisList[axisId]->n_glo;
937            ++axisId;
938          }
939        }
940        dataSize = 1;
941        for (int i = 0; i < nZoomSize.size(); ++i)
942          dataSize *= nZoomSize[i];
943
944        serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
945                                                      nZoomBeginGlobal, nGlob);
946      }
947
948      CArray<size_t,1> outIndex;
949      buffer >> outIndex;
950      if (isDataDistributed_)
951        serverDistribution_->computeLocalIndex(outIndex);
952      else
953      {
954        dataSize = outIndex.numElements();
955        for (int i = 0; i < outIndex.numElements(); ++i) outIndex(i) = i;
956      }
957      writtenDataSize_ += dataSize;
958
959      outIndexFromClient.insert(std::make_pair(rank, outIndex));
960      connectedDataSize_[rank] = outIndex.numElements();
961      numberWrittenIndexes_ += outIndex.numElements();
962    }
963
964    if (isDataDistributed_)
965    {
966      MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
967      MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
968      offsetWrittenIndexes_ -= numberWrittenIndexes_;
969    }
970    else
971      totalNumberWrittenIndexes_ = numberWrittenIndexes_;
972
973    nbSenders = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks);
974  }
975
976   /*!
977   \brief Dispatch event received from client
978      Whenever a message is received in buffer of server, it will be processed depending on
979   its event type. A new event type should be added in the switch list to make sure
980   it processed on server side.
981   \param [in] event: Received message
982   */
983  bool CGrid::dispatchEvent(CEventServer& event)
984  {
985
986    if (SuperClass::dispatchEvent(event)) return true;
987    else
988    {
989      switch(event.type)
990      {
991        case EVENT_ID_INDEX :
992          recvIndex(event);
993          return true;
994          break;
995
996         case EVENT_ID_ADD_DOMAIN :
997           recvAddDomain(event);
998           return true;
999           break;
1000
1001         case EVENT_ID_ADD_AXIS :
1002           recvAddAxis(event);
1003           return true;
1004           break;
1005        default :
1006          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
1007                << "Unknown Event");
1008          return false;
1009      }
1010    }
1011  }
1012
1013   ///---------------------------------------------------------------
1014
1015   CDomain* CGrid::addDomain(const std::string& id)
1016   {
1017     return vDomainGroup_->createChild(id);
1018   }
1019
1020   CAxis* CGrid::addAxis(const std::string& id)
1021   {
1022     return vAxisGroup_->createChild(id);
1023   }
1024
1025   //! Change virtual field group to a new one
1026   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
1027   {
1028      this->vDomainGroup_ = newVDomainGroup;
1029   }
1030
1031   //! Change virtual variable group to new one
1032   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
1033   {
1034      this->vAxisGroup_ = newVAxisGroup;
1035   }
1036
1037   //----------------------------------------------------------------
1038   //! Create virtual field group, which is done normally on initializing file
1039   void CGrid::setVirtualDomainGroup(void)
1040   {
1041      this->setVirtualDomainGroup(CDomainGroup::create());
1042   }
1043
1044   //! Create virtual variable group, which is done normally on initializing file
1045   void CGrid::setVirtualAxisGroup(void)
1046   {
1047      this->setVirtualAxisGroup(CAxisGroup::create());
1048   }
1049
1050   /*!
1051   \brief Send a message to create a domain on server side
1052   \param[in] id String identity of domain that will be created on server
1053   */
1054   void CGrid::sendAddDomain(const string& id)
1055   {
1056    CContext* context=CContext::getCurrent();
1057
1058    if (! context->hasServer )
1059    {
1060       CContextClient* client=context->client;
1061
1062       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN);
1063       if (client->isServerLeader())
1064       {
1065         CMessage msg;
1066         msg<<this->getId();
1067         msg<<id;
1068         const std::list<int>& ranks = client->getRanksServerLeader();
1069         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1070           event.push(*itRank,1,msg);
1071         client->sendEvent(event);
1072       }
1073       else client->sendEvent(event);
1074    }
1075   }
1076
1077   /*!
1078   \brief Send a message to create an axis on server side
1079   \param[in] id String identity of axis that will be created on server
1080   */
1081   void CGrid::sendAddAxis(const string& id)
1082   {
1083    CContext* context=CContext::getCurrent();
1084
1085    if (! context->hasServer )
1086    {
1087       CContextClient* client=context->client;
1088
1089       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS);
1090       if (client->isServerLeader())
1091       {
1092         CMessage msg;
1093         msg<<this->getId();
1094         msg<<id;
1095         const std::list<int>& ranks = client->getRanksServerLeader();
1096         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1097           event.push(*itRank,1,msg);
1098         client->sendEvent(event);
1099       }
1100       else client->sendEvent(event);
1101    }
1102   }
1103
1104   /*!
1105   \brief Receive a message annoucing the creation of a domain on server side
1106   \param[in] event Received event
1107   */
1108   void CGrid::recvAddDomain(CEventServer& event)
1109   {
1110
1111      CBufferIn* buffer = event.subEvents.begin()->buffer;
1112      string id;
1113      *buffer >> id;
1114      get(id)->recvAddDomain(*buffer);
1115   }
1116
1117   /*!
1118   \brief Receive a message annoucing the creation of a domain on server side
1119   \param[in] buffer Buffer containing message
1120   */
1121   void CGrid::recvAddDomain(CBufferIn& buffer)
1122   {
1123      string id;
1124      buffer >> id;
1125      addDomain(id);
1126   }
1127
1128   /*!
1129   \brief Receive a message annoucing the creation of an axis on server side
1130   \param[in] event Received event
1131   */
1132   void CGrid::recvAddAxis(CEventServer& event)
1133   {
1134
1135      CBufferIn* buffer = event.subEvents.begin()->buffer;
1136      string id;
1137      *buffer >> id;
1138      get(id)->recvAddAxis(*buffer);
1139   }
1140
1141   /*!
1142   \brief Receive a message annoucing the creation of an axis on server side
1143   \param[in] buffer Buffer containing message
1144   */
1145   void CGrid::recvAddAxis(CBufferIn& buffer)
1146   {
1147      string id;
1148      buffer >> id;
1149      addAxis(id);
1150   }
1151
1152  /*!
1153  \brief Solve domain and axis references
1154  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
1155  all attributes from their parents, they should be processed with this function
1156  \param[in] apply inherit all attributes of parents (true)
1157  */
1158  void CGrid::solveDomainAxisRefInheritance(bool apply)
1159  {
1160    CContext* context = CContext::getCurrent();
1161    unsigned int vecSize, i;
1162    std::vector<StdString>::iterator it, itE;
1163    setDomainList();
1164    it = domList_.begin(); itE = domList_.end();
1165    for (; it != itE; ++it)
1166    {
1167      CDomain* pDom = CDomain::get(*it);
1168      if (context->hasClient)
1169      {
1170        pDom->solveRefInheritance(apply);
1171        pDom->solveBaseReference();
1172        pDom->solveSrcInheritance();
1173        pDom->solveInheritanceTransformation();
1174        if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
1175          pDom->name.setValue(pDom->getBaseDomainReference()->getId());
1176      }
1177    }
1178
1179    setAxisList();
1180    it = axisList_.begin(); itE = axisList_.end();
1181    for (; it != itE; ++it)
1182    {
1183      CAxis* pAxis = CAxis::get(*it);
1184      if (context->hasClient)
1185      {
1186        pAxis->solveRefInheritance(apply);
1187        pAxis->solveBaseReference();
1188        pAxis->solveInheritanceTransformation();
1189        if ((!pAxis->axis_ref.isEmpty()) && (pAxis->name.isEmpty()))
1190          pAxis->name.setValue(pAxis->getBaseAxisReference()->getId());
1191      }
1192    }
1193  }
1194
1195  bool CGrid::isTransformed()
1196  {
1197    return isTransformed_;
1198  }
1199
1200  void CGrid::setTransformed()
1201  {
1202    isTransformed_ = true;
1203  }
1204
1205  CGridTransformation* CGrid::getTransformations()
1206  {
1207    return transformations_;
1208  }
1209
1210  /*!
1211     Complete all the necessary (and lacking) attributes of a grid
1212     This function is similar to gridTransformation but works only (till now) on generate_rectilinear_domain transformation
1213  */
1214  void CGrid::completeGrid(CGrid* transformGridSrc)
1215  {
1216    if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
1217    {
1218      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1219           << "Two grids have different dimension size"
1220           << "Dimension of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
1221           << "Dimension of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
1222    }
1223    else
1224    {
1225      int ssize = axis_domain_order.numElements();
1226      for (int i = 0; i < ssize; ++i)
1227        if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
1228          ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1229                << "Grids " << this->getId() << " and " << transformGridSrc->getId()
1230                << " don't have elements in the same order");
1231    }
1232
1233    CGridGenerate gridGenerate(this, transformGridSrc);
1234    gridGenerate.completeGrid();
1235  }
1236
1237  void CGrid::transformGrid(CGrid* transformGridSrc)
1238  {
1239    if (isTransformed()) return;
1240    setTransformed();
1241    if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
1242    {
1243      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1244           << "Two grids have different dimension size"
1245           << "Dimension of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
1246           << "Dimension of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
1247    }
1248    else
1249    {
1250      int ssize = axis_domain_order.numElements();
1251      for (int i = 0; i < ssize; ++i)
1252        if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
1253          ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1254                << "Grids " << this->getId() << " and " << transformGridSrc->getId()
1255                << " don't have elements in the same order");
1256    }
1257
1258    transformations_ = new CGridTransformation(this, transformGridSrc);
1259    transformations_->computeAll();
1260
1261    // Ok, now need to compute index of grid source
1262    transformGridSrc->checkMaskIndex(false);
1263  }
1264
1265  /*!
1266  \brief Get the list of domain pointers
1267  \return list of domain pointers
1268  */
1269  std::vector<CDomain*> CGrid::getDomains()
1270  {
1271    std::vector<CDomain*> domList;
1272    if (!domList_.empty())
1273    {
1274      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
1275    }
1276    return domList;
1277  }
1278
1279  /*!
1280  \brief Get the list of  axis pointers
1281  \return list of axis pointers
1282  */
1283  std::vector<CAxis*> CGrid::getAxis()
1284  {
1285    std::vector<CAxis*> aList;
1286    if (!axisList_.empty())
1287      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
1288
1289    return aList;
1290  }
1291
1292  /*!
1293  \brief Set domain(s) of a grid from a list
1294  \param[in] domains list of domains
1295  */
1296  void CGrid::setDomainList(const std::vector<CDomain*> domains)
1297  {
1298    if (isDomListSet) return;
1299    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1300    if (!domains.empty() && domList.empty()) domList = domains;
1301    if (!domList.empty())
1302    {
1303      int sizeDom = domList.size();
1304      domList_.resize(sizeDom);
1305      for (int i = 0; i < sizeDom; ++i)
1306      {
1307        domList_[i] = domList[i]->getId();
1308      }
1309      isDomListSet = true;
1310    }
1311
1312  }
1313
1314  /*!
1315  \brief Set axis(s) of a grid from a list
1316  \param[in] axis list of axis
1317  */
1318  void CGrid::setAxisList(const std::vector<CAxis*> axis)
1319  {
1320    if (isAxisListSet) return;
1321    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1322    if (!axis.empty() && aList.empty()) aList = axis;
1323    if (!aList.empty())
1324    {
1325      int sizeAxis = aList.size();
1326      axisList_.resize(sizeAxis);
1327      for (int i = 0; i < sizeAxis; ++i)
1328      {
1329        axisList_[i] = aList[i]->getId();
1330      }
1331      isAxisListSet = true;
1332    }
1333  }
1334
1335  /*!
1336  \brief Get list of id of domains
1337  \return id list of domains
1338  */
1339  std::vector<StdString> CGrid::getDomainList()
1340  {
1341    setDomainList();
1342    return domList_;
1343  }
1344
1345  /*!
1346  \brief Get list of id of axis
1347  \return id list of axis
1348  */
1349  std::vector<StdString> CGrid::getAxisList()
1350  {
1351    setAxisList();
1352    return axisList_;
1353  }
1354
1355  void CGrid::sendAllDomains()
1356  {
1357    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1358    int dSize = domList.size();
1359    for (int i = 0; i < dSize; ++i)
1360    {
1361      sendAddDomain(domList[i]->getId());
1362      domList[i]->sendAllAttributesToServer();
1363    }
1364  }
1365
1366  void CGrid::sendAllAxis()
1367  {
1368    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1369    int aSize = aList.size();
1370
1371    for (int i = 0; i < aSize; ++i)
1372    {
1373      sendAddAxis(aList[i]->getId());
1374      aList[i]->sendAllAttributesToServer();
1375    }
1376  }
1377
1378  void CGrid::parse(xml::CXMLNode& node)
1379  {
1380    SuperClass::parse(node);
1381
1382    // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
1383    std::vector<bool> order;
1384
1385    if (node.goToChildElement())
1386    {
1387      StdString domainName("domain");
1388      StdString axisName("axis");
1389      do
1390      {
1391        if (node.getElementName() == domainName) {
1392          order.push_back(true);
1393          this->getVirtualDomainGroup()->parseChild(node);
1394        }
1395        if (node.getElementName() == axisName) {
1396          order.push_back(false);
1397          this->getVirtualAxisGroup()->parseChild(node);
1398        }
1399      } while (node.goToNextElement());
1400      node.goToParentElement();
1401    }
1402
1403    if (!order.empty())
1404    {
1405      int sizeOrd = order.size();
1406      axis_domain_order.resize(sizeOrd);
1407      for (int i = 0; i < sizeOrd; ++i)
1408      {
1409        axis_domain_order(i) = order[i];
1410      }
1411    }
1412
1413    setDomainList();
1414    setAxisList();
1415   }
1416} // namespace xios
Note: See TracBrowser for help on using the repository browser.