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

Last change on this file since 718 was 718, checked in by rlacroix, 6 years ago

Rename "buffer_factor_size" to "buffer_size_factor" to clarify its meaning.

  • 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     const std::vector<size_t>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
400     std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
401     itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
402     iteGlobalMap = globalIndexOnServer.end();
403
404     typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
405     std::vector<int>::iterator itVec;
406     int nbGlobalIndex = globalIndexSendToServer.size();
407     for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
408     {
409       int serverRank = itGlobalMap->first;
410       int indexSize = itGlobalMap->second.size();
411       std::vector<int> permutIndex(indexSize);
412       XIOSAlgorithms::fillInIndex(indexSize, permutIndex);
413       XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(itGlobalMap->second, permutIndex);
414       BinarySearch binSearch(itGlobalMap->second);
415       for (int i = 0; i < nbGlobalIndex; ++i)
416       {
417         if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexSendToServer[i], itVec))
418         {
419           if (connectedDataSize_.end() == connectedDataSize_.find(serverRank))
420             connectedDataSize_[serverRank] = 1;
421           else
422             ++connectedDataSize_[serverRank];
423         }
424       }
425     }
426
427     connectedServerRank_.clear();
428     for (std::map<int, std::vector<size_t> >::const_iterator it = globalIndexOnServer.begin(); it != globalIndexOnServer.end(); ++it) {
429       connectedServerRank_.push_back(it->first);
430     }
431     if (!connectedDataSize_.empty())
432     {
433       connectedServerRank_.clear();
434       for (std::map<int,size_t>::const_iterator it = connectedDataSize_.begin(); it != connectedDataSize_.end(); ++it)
435         connectedServerRank_.push_back(it->first);
436     }
437
438     nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
439   }
440
441   //----------------------------------------------------------------
442
443   CGrid* CGrid::createGrid(CDomain* domain)
444   {
445      std::vector<CDomain*> vecDom(1,domain);
446      std::vector<CAxis*> vecAxis;
447      CArray<bool,1> axisDomainOrder;
448      CGrid* grid = createGrid(vecDom, vecAxis, axisDomainOrder);
449
450      return grid;
451   }
452
453   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
454   {
455      std::vector<CDomain*> vecDom(1,domain);
456      std::vector<CAxis*> vecAxis(1,axis);
457      CArray<bool,1> axisDomainOrder;
458      CGrid* grid = createGrid(vecDom, vecAxis, axisDomainOrder);
459
460      return grid;
461   }
462
463   CGrid* CGrid::createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis, CArray<bool,1> axisDomainOrder)
464   {
465      StdString new_id = StdString("__");
466      if (!domains.empty()) for (int i = 0; i < domains.size(); ++i) new_id += domains[i]->getId() + StdString("_");
467      if (!axis.empty()) for (int i = 0; i < axis.size(); ++i) new_id += axis[i]->getId() + StdString("_");
468      if (domains.empty() && axis.empty()) new_id += StdString("scalar_grid");
469      new_id += StdString("_");
470
471      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id);
472      grid->setDomainList(domains);
473      grid->setAxisList(axis);
474
475      //By default, domains are always the first ones of a grid
476      if (0 == axisDomainOrder.numElements())
477      {
478        int size = domains.size()+axis.size();
479        grid->axis_domain_order.resize(size);
480        for (int i = 0; i < size; ++i)
481        {
482          if (i < domains.size()) grid->axis_domain_order(i) = true;
483          else grid->axis_domain_order(i) = false;
484        }
485      }
486      else
487      {
488        grid->axis_domain_order.resize(axisDomainOrder.numElements());
489        grid->axis_domain_order = axisDomainOrder;
490      }
491
492      grid->computeGridGlobalDimension(domains, axis, grid->axis_domain_order);
493
494      return grid;
495   }
496
497   CDomainGroup* CGrid::getVirtualDomainGroup() const
498   {
499     return this->vDomainGroup_;
500   }
501
502   CAxisGroup* CGrid::getVirtualAxisGroup() const
503   {
504     return this->vAxisGroup_;
505   }
506
507   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
508   {
509     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
510     StdSize numElements = stored.numElements();
511     for (StdSize n = 0; n < numElements; ++n)
512     {
513       field[out_i(n)] = stored(n);
514     }
515   }
516
517   void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored)
518   {
519     const CArray<size_t,1>& out_i = outIndexFromClient[rank];
520     StdSize numElements = stored.numElements();
521     for (StdSize n = 0; n < numElements; ++n)
522     {
523       stored(n) = field[out_i(n)];
524     }
525   }
526
527   void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field)
528   {
529     const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank];
530     StdSize numElements = stored.numElements();
531     for (StdSize n = 0; n < numElements; ++n)
532     {
533       field[out_i(n)] = stored(n);
534     }
535   }
536
537   //----------------------------------------------------------------
538
539   void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const
540   {
541      const StdSize size = storeIndex_client.numElements();
542
543      stored.resize(size);
544      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
545   }
546
547   void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const
548   {
549      const StdSize size = storeIndex_client.numElements();
550
551      for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i);
552   }
553
554  void CGrid::computeIndexScalarGrid()
555  {
556    CContext* context = CContext::getCurrent();
557    CContextClient* client=context->client;
558
559    storeIndex_client.resize(1);
560    storeIndex_client[0] = 0;
561    if (0 == client->clientRank)
562    {
563      for (int rank = 0; rank < client->serverSize; ++rank)
564        connectedDataSize_[rank] = 1;
565    }
566    isDataDistributed_ = false;
567  }
568
569  void CGrid::computeCompressedIndex()
570  {
571    compressedOutIndexFromClient = outIndexFromClient;
572
573    std::map<size_t, size_t> indexes;
574
575    {
576      std::map<int, CArray<size_t,1> >::const_iterator it = compressedOutIndexFromClient.begin();
577      std::map<int, CArray<size_t,1> >::const_iterator itEnd = compressedOutIndexFromClient.end();
578      for (; it != itEnd; ++it)
579      {
580        for (int i = 0; i < it->second.numElements(); ++i)
581          indexes.insert(std::make_pair(it->second(i), 0));
582      }
583    }
584
585    {
586      std::map<size_t, size_t>::iterator it = indexes.begin();
587      std::map<size_t, size_t>::iterator itEnd = indexes.end();
588      for (size_t i = 0; it != itEnd; ++it, ++i)
589        it->second = i;
590    }
591
592    {
593      std::map<int, CArray<size_t,1> >::iterator it = compressedOutIndexFromClient.begin();
594      std::map<int, CArray<size_t,1> >::iterator itEnd = compressedOutIndexFromClient.end();
595      for (; it != itEnd; ++it)
596      {
597        for (int i = 0; i < it->second.numElements(); ++i)
598          it->second(i) = indexes[it->second(i)];
599      }
600    }
601  }
602
603  void CGrid::sendIndexScalarGrid()
604  {
605    CContext* context = CContext::getCurrent();
606    CContextClient* client = context->client;
607
608    CEventClient event(getType(), EVENT_ID_INDEX);
609    list<CMessage> listMsg;
610    list<CArray<size_t,1> > listOutIndex;
611
612    if (0 == client->clientRank)
613    {
614      for (int rank = 0; rank < client->serverSize; ++rank)
615      {
616        int nb = 1;
617        storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));
618        listOutIndex.push_back(CArray<size_t,1>(nb));
619
620        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
621        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
622
623        for (int k = 0; k < nb; ++k)
624        {
625          outGlobalIndexOnServer(k) = 0;
626          outLocalIndexToServer(k)  = 0;
627        }
628
629        listMsg.push_back(CMessage());
630        listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
631
632        event.push(rank, 1, listMsg.back());
633      }
634
635      client->sendEvent(event);
636    }
637    else
638      client->sendEvent(event);
639  }
640
641  void CGrid::sendIndex(void)
642  {
643    CContext* context = CContext::getCurrent();
644    CContextClient* client = context->client;
645
646    CEventClient event(getType(), EVENT_ID_INDEX);
647    int rank;
648    list<CMessage> listMsg;
649    list<CArray<size_t,1> > listOutIndex;
650    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
651    const std::vector<int>& localIndexSendToServer = clientDistribution_->getLocalDataIndexSendToServer();
652    const std::vector<size_t>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
653
654    if (!doGridHaveDataDistributed())
655    {
656      if (0 == client->clientRank)
657      {
658        CArray<size_t,1> outGlobalIndexOnServer(globalIndexSendToServer.size());
659        for (int idx = 0; idx < globalIndexSendToServer.size();++idx)
660          outGlobalIndexOnServer(idx) = globalIndexSendToServer[idx];
661
662        CArray<int,1> outLocalIndexToServer(localIndexSendToServer.size());
663        for (int idx = 0; idx < localIndexSendToServer.size();++idx)
664          outLocalIndexToServer(idx) = localIndexSendToServer[idx];
665
666        for (rank = 0; rank < client->serverSize; ++rank)
667        {
668          storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer)));
669          listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));
670
671          listMsg.push_back(CMessage());
672          listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
673
674          event.push(rank, 1, listMsg.back());
675        }
676
677        client->sendEvent(event);
678      }
679      else
680        client->sendEvent(event);
681    }
682    else
683    {
684      std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
685      itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
686      iteGlobalMap = globalIndexOnServer.end();
687
688      int nbGlobalIndex = globalIndexSendToServer.size();
689      std::map<int,std::vector<int> >localIndexTmp;
690      std::map<int,std::vector<size_t> > globalIndexTmp;
691
692      typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
693      std::vector<int>::iterator itVec;
694      for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
695      {
696        int serverRank = itGlobalMap->first;
697        int indexSize = itGlobalMap->second.size();
698        std::vector<int> permutIndex(indexSize);
699        XIOSAlgorithms::fillInIndex(indexSize, permutIndex);
700        XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(itGlobalMap->second, permutIndex);
701        BinarySearch binSearch(itGlobalMap->second);
702
703        for (int i = 0; i < nbGlobalIndex; ++i)
704        {
705          if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexSendToServer[i], itVec))
706          {
707            globalIndexTmp[serverRank].push_back(globalIndexSendToServer[i]);
708            localIndexTmp[serverRank].push_back(localIndexSendToServer[i]);
709          }
710        }
711      }
712
713      for (int ns = 0; ns < connectedServerRank_.size(); ++ns)
714      {
715        rank = connectedServerRank_[ns];
716        int nb = 0;
717        if (globalIndexTmp.end() != globalIndexTmp.find(rank))
718          nb = globalIndexTmp[rank].size();
719
720        storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));
721        listOutIndex.push_back(CArray<size_t,1>(nb));
722
723        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
724        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
725
726        for (int k = 0; k < nb; ++k)
727        {
728          outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
729          outLocalIndexToServer(k)  = localIndexTmp[rank].at(k);
730        }
731
732        listMsg.push_back(CMessage());
733        listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
734
735        event.push(rank, nbSenders[rank], listMsg.back());
736      }
737
738      client->sendEvent(event);
739    }
740  }
741
742  void CGrid::recvIndex(CEventServer& event)
743  {
744    string gridId;
745    vector<int> ranks;
746    vector<CBufferIn*> buffers;
747
748    list<CEventServer::SSubEvent>::iterator it;
749    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
750    {
751      ranks.push_back(it->rank);
752      CBufferIn* buffer = it->buffer;
753      *buffer >> gridId;
754      buffers.push_back(buffer);
755    }
756    get(gridId)->recvIndex(ranks, buffers);
757  }
758
759  void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains,
760                                         const std::vector<CAxis*>& axis,
761                                         const CArray<bool,1>& axisDomainOrder)
762  {
763    globalDim_.resize(domains.size()*2+axis.size());
764    int idx = 0, idxDomain = 0, idxAxis = 0;
765    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
766    {
767      if (axisDomainOrder(i))
768      {
769        if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured))
770        {
771          positionDimensionDistributed_ = idx;
772        }
773        else
774        {
775          positionDimensionDistributed_ = idx +1;
776        }
777
778        globalDim_[idx]   = domains[idxDomain]->ni_glo.getValue();
779        globalDim_[idx+1] = domains[idxDomain]->nj_glo.getValue();
780
781        ++idxDomain;
782        idx += 2;
783      }
784      else
785      {
786        globalDim_[idx] = axis[idxAxis]->n_glo.getValue();
787        ++idxAxis;
788        ++idx;
789      }
790    }
791  }
792
793  std::vector<int> CGrid::getGlobalDimension()
794  {
795    return globalDim_;
796  }
797
798  bool CGrid::isScalarGrid() const
799  {
800    return (axisList_.empty() && domList_.empty());
801  }
802
803  /*!
804    Verify whether one server need to write data
805    There are some cases on which one server has nodata to write. For example, when we
806    just only want to zoom on a domain.
807  */
808  bool CGrid::doGridHaveDataToWrite()
809  {
810     return (0 != writtenDataSize_);
811  }
812
813  /*!
814    Return size of data which is written on each server
815    Whatever dimension of a grid, data which are written on server must be presented as
816    an one dimension array.
817    \return size of data written on server
818  */
819  size_t CGrid::getWrittenDataSize() const
820  {
821    return writtenDataSize_;
822  }
823
824  /*!
825    Returns the number of indexes written by each server.
826    \return the number of indexes written by each server
827  */
828  int CGrid::getNumberWrittenIndexes() const
829  {
830    return numberWrittenIndexes_;
831  }
832
833  /*!
834    Returns the total number of indexes written by the servers.
835    \return the total number of indexes written by the servers
836  */
837  int CGrid::getTotalNumberWrittenIndexes() const
838  {
839    return totalNumberWrittenIndexes_;
840  }
841
842  /*!
843    Returns the offset of indexes written by each server.
844    \return the offset of indexes written by each server
845  */
846  int CGrid::getOffsetWrittenIndexes() const
847  {
848    return offsetWrittenIndexes_;
849  }
850
851  const CDistributionServer* CGrid::getDistributionServer() const
852  {
853    return serverDistribution_;
854  }
855
856  const CDistributionClient* CGrid::getDistributionClient() const
857  {
858    return clientDistribution_;
859  }
860
861  bool CGrid::doGridHaveDataDistributed()
862  {
863    if (isScalarGrid()) return false;
864    else
865      return isDataDistributed_;
866  }
867
868  void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers)
869  {
870    CContext* context = CContext::getCurrent();
871    CContextServer* server = context->server;
872    numberWrittenIndexes_ = totalNumberWrittenIndexes_ = offsetWrittenIndexes_ = 0;
873
874    for (int n = 0; n < ranks.size(); n++)
875    {
876      int rank = ranks[n];
877      CBufferIn& buffer = *buffers[n];
878
879      buffer >> isDataDistributed_ >> isCompressible_;
880      size_t dataSize = 0;
881
882      if (isScalarGrid())
883      {
884        writtenDataSize_ = numberWrittenIndexes_ = totalNumberWrittenIndexes_ = 1;
885        CArray<size_t,1> outIndex;
886        buffer >> outIndex;
887        outIndexFromClient.insert(std::make_pair(rank, outIndex));
888        std::vector<int> nZoomBegin(1,0), nZoomSize(1,1), nGlob(1,1), nZoomBeginGlobal(1,0);
889        serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
890                                                      nZoomBeginGlobal, nGlob);
891        return;
892      }
893
894      if (0 == serverDistribution_)
895      {
896        int idx = 0, numElement = axis_domain_order.numElements();
897        int ssize = numElement;
898        std::vector<int> indexMap(numElement);
899        for (int i = 0; i < numElement; ++i)
900        {
901          indexMap[i] = idx;
902          if (true == axis_domain_order(i))
903          {
904            ++ssize;
905            idx += 2;
906          }
907          else
908            ++idx;
909        }
910
911        int axisId = 0, domainId = 0;
912        std::vector<CDomain*> domainList = getDomains();
913        std::vector<CAxis*> axisList = getAxis();
914        std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);
915        for (int i = 0; i < numElement; ++i)
916        {
917          if (axis_domain_order(i))
918          {
919            nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin_srv;
920            nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni_srv;
921            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;
922            nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
923
924            nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin_srv;
925            nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj_srv;
926            nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;
927            nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
928            ++domainId;
929          }
930          else
931          {
932            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
933            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
934            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;
935            nGlob[indexMap[i]] = axisList[axisId]->n_glo;
936            ++axisId;
937          }
938        }
939        dataSize = 1;
940        for (int i = 0; i < nZoomSize.size(); ++i)
941          dataSize *= nZoomSize[i];
942
943        serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
944                                                      nZoomBeginGlobal, nGlob);
945      }
946
947      CArray<size_t,1> outIndex;
948      buffer >> outIndex;
949      if (isDataDistributed_)
950        serverDistribution_->computeLocalIndex(outIndex);
951      else
952      {
953        dataSize = outIndex.numElements();
954        for (int i = 0; i < outIndex.numElements(); ++i) outIndex(i) = i;
955      }
956      writtenDataSize_ += dataSize;
957
958      outIndexFromClient.insert(std::make_pair(rank, outIndex));
959      connectedDataSize_[rank] = outIndex.numElements();
960      numberWrittenIndexes_ += outIndex.numElements();
961    }
962
963    if (isDataDistributed_)
964    {
965      MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
966      MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
967      offsetWrittenIndexes_ -= numberWrittenIndexes_;
968    }
969    else
970      totalNumberWrittenIndexes_ = numberWrittenIndexes_;
971
972    nbSenders = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks);
973  }
974
975   /*!
976   \brief Dispatch event received from client
977      Whenever a message is received in buffer of server, it will be processed depending on
978   its event type. A new event type should be added in the switch list to make sure
979   it processed on server side.
980   \param [in] event: Received message
981   */
982  bool CGrid::dispatchEvent(CEventServer& event)
983  {
984
985    if (SuperClass::dispatchEvent(event)) return true;
986    else
987    {
988      switch(event.type)
989      {
990        case EVENT_ID_INDEX :
991          recvIndex(event);
992          return true;
993          break;
994
995         case EVENT_ID_ADD_DOMAIN :
996           recvAddDomain(event);
997           return true;
998           break;
999
1000         case EVENT_ID_ADD_AXIS :
1001           recvAddAxis(event);
1002           return true;
1003           break;
1004        default :
1005          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
1006                << "Unknown Event");
1007          return false;
1008      }
1009    }
1010  }
1011
1012   ///---------------------------------------------------------------
1013
1014   CDomain* CGrid::addDomain(const std::string& id)
1015   {
1016     return vDomainGroup_->createChild(id);
1017   }
1018
1019   CAxis* CGrid::addAxis(const std::string& id)
1020   {
1021     return vAxisGroup_->createChild(id);
1022   }
1023
1024   //! Change virtual field group to a new one
1025   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
1026   {
1027      this->vDomainGroup_ = newVDomainGroup;
1028   }
1029
1030   //! Change virtual variable group to new one
1031   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
1032   {
1033      this->vAxisGroup_ = newVAxisGroup;
1034   }
1035
1036   //----------------------------------------------------------------
1037   //! Create virtual field group, which is done normally on initializing file
1038   void CGrid::setVirtualDomainGroup(void)
1039   {
1040      this->setVirtualDomainGroup(CDomainGroup::create());
1041   }
1042
1043   //! Create virtual variable group, which is done normally on initializing file
1044   void CGrid::setVirtualAxisGroup(void)
1045   {
1046      this->setVirtualAxisGroup(CAxisGroup::create());
1047   }
1048
1049   /*!
1050   \brief Send a message to create a domain on server side
1051   \param[in] id String identity of domain that will be created on server
1052   */
1053   void CGrid::sendAddDomain(const string& id)
1054   {
1055    CContext* context=CContext::getCurrent();
1056
1057    if (! context->hasServer )
1058    {
1059       CContextClient* client=context->client;
1060
1061       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN);
1062       if (client->isServerLeader())
1063       {
1064         CMessage msg;
1065         msg<<this->getId();
1066         msg<<id;
1067         const std::list<int>& ranks = client->getRanksServerLeader();
1068         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1069           event.push(*itRank,1,msg);
1070         client->sendEvent(event);
1071       }
1072       else client->sendEvent(event);
1073    }
1074   }
1075
1076   /*!
1077   \brief Send a message to create an axis on server side
1078   \param[in] id String identity of axis that will be created on server
1079   */
1080   void CGrid::sendAddAxis(const string& id)
1081   {
1082    CContext* context=CContext::getCurrent();
1083
1084    if (! context->hasServer )
1085    {
1086       CContextClient* client=context->client;
1087
1088       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS);
1089       if (client->isServerLeader())
1090       {
1091         CMessage msg;
1092         msg<<this->getId();
1093         msg<<id;
1094         const std::list<int>& ranks = client->getRanksServerLeader();
1095         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
1096           event.push(*itRank,1,msg);
1097         client->sendEvent(event);
1098       }
1099       else client->sendEvent(event);
1100    }
1101   }
1102
1103   /*!
1104   \brief Receive a message annoucing the creation of a domain on server side
1105   \param[in] event Received event
1106   */
1107   void CGrid::recvAddDomain(CEventServer& event)
1108   {
1109
1110      CBufferIn* buffer = event.subEvents.begin()->buffer;
1111      string id;
1112      *buffer >> id;
1113      get(id)->recvAddDomain(*buffer);
1114   }
1115
1116   /*!
1117   \brief Receive a message annoucing the creation of a domain on server side
1118   \param[in] buffer Buffer containing message
1119   */
1120   void CGrid::recvAddDomain(CBufferIn& buffer)
1121   {
1122      string id;
1123      buffer >> id;
1124      addDomain(id);
1125   }
1126
1127   /*!
1128   \brief Receive a message annoucing the creation of an axis on server side
1129   \param[in] event Received event
1130   */
1131   void CGrid::recvAddAxis(CEventServer& event)
1132   {
1133
1134      CBufferIn* buffer = event.subEvents.begin()->buffer;
1135      string id;
1136      *buffer >> id;
1137      get(id)->recvAddAxis(*buffer);
1138   }
1139
1140   /*!
1141   \brief Receive a message annoucing the creation of an axis on server side
1142   \param[in] buffer Buffer containing message
1143   */
1144   void CGrid::recvAddAxis(CBufferIn& buffer)
1145   {
1146      string id;
1147      buffer >> id;
1148      addAxis(id);
1149   }
1150
1151  /*!
1152  \brief Solve domain and axis references
1153  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
1154  all attributes from their parents, they should be processed with this function
1155  \param[in] apply inherit all attributes of parents (true)
1156  */
1157  void CGrid::solveDomainAxisRefInheritance(bool apply)
1158  {
1159    CContext* context = CContext::getCurrent();
1160    unsigned int vecSize, i;
1161    std::vector<StdString>::iterator it, itE;
1162    setDomainList();
1163    it = domList_.begin(); itE = domList_.end();
1164    for (; it != itE; ++it)
1165    {
1166      CDomain* pDom = CDomain::get(*it);
1167      if (context->hasClient)
1168      {
1169        pDom->solveRefInheritance(apply);
1170        pDom->solveBaseReference();
1171        pDom->solveSrcInheritance();
1172        pDom->solveInheritanceTransformation();
1173        if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
1174          pDom->name.setValue(pDom->getBaseDomainReference()->getId());
1175      }
1176    }
1177
1178    setAxisList();
1179    it = axisList_.begin(); itE = axisList_.end();
1180    for (; it != itE; ++it)
1181    {
1182      CAxis* pAxis = CAxis::get(*it);
1183      if (context->hasClient)
1184      {
1185        pAxis->solveRefInheritance(apply);
1186        pAxis->solveBaseReference();
1187        pAxis->solveInheritanceTransformation();
1188        if ((!pAxis->axis_ref.isEmpty()) && (pAxis->name.isEmpty()))
1189          pAxis->name.setValue(pAxis->getBaseAxisReference()->getId());
1190      }
1191    }
1192  }
1193
1194  bool CGrid::isTransformed()
1195  {
1196    return isTransformed_;
1197  }
1198
1199  void CGrid::setTransformed()
1200  {
1201    isTransformed_ = true;
1202  }
1203
1204  CGridTransformation* CGrid::getTransformations()
1205  {
1206    return transformations_;
1207  }
1208
1209  /*!
1210     Complete all the necessary (and lacking) attributes of a grid
1211     This function is similar to gridTransformation but works only (till now) on generate_rectilinear_domain transformation
1212  */
1213  void CGrid::completeGrid(CGrid* transformGridSrc)
1214  {
1215    if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
1216    {
1217      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1218           << "Two grids have different dimension size"
1219           << "Dimension of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
1220           << "Dimension of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
1221    }
1222    else
1223    {
1224      int ssize = axis_domain_order.numElements();
1225      for (int i = 0; i < ssize; ++i)
1226        if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
1227          ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1228                << "Grids " << this->getId() << " and " << transformGridSrc->getId()
1229                << " don't have elements in the same order");
1230    }
1231
1232    CGridGenerate gridGenerate(this, transformGridSrc);
1233    gridGenerate.completeGrid();
1234  }
1235
1236  void CGrid::transformGrid(CGrid* transformGridSrc)
1237  {
1238    if (isTransformed()) return;
1239    setTransformed();
1240    if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements())
1241    {
1242      ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1243           << "Two grids have different dimension size"
1244           << "Dimension of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl
1245           << "Dimension of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements());
1246    }
1247    else
1248    {
1249      int ssize = axis_domain_order.numElements();
1250      for (int i = 0; i < ssize; ++i)
1251        if (axis_domain_order(i) != (transformGridSrc->axis_domain_order)(i))
1252          ERROR("CGrid::transformGrid(CGrid* transformGridSrc)",
1253                << "Grids " << this->getId() << " and " << transformGridSrc->getId()
1254                << " don't have elements in the same order");
1255    }
1256
1257    transformations_ = new CGridTransformation(this, transformGridSrc);
1258    transformations_->computeAll();
1259
1260    // Ok, now need to compute index of grid source
1261    transformGridSrc->checkMaskIndex(false);
1262  }
1263
1264  /*!
1265  \brief Get the list of domain pointers
1266  \return list of domain pointers
1267  */
1268  std::vector<CDomain*> CGrid::getDomains()
1269  {
1270    std::vector<CDomain*> domList;
1271    if (!domList_.empty())
1272    {
1273      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
1274    }
1275    return domList;
1276  }
1277
1278  /*!
1279  \brief Get the list of  axis pointers
1280  \return list of axis pointers
1281  */
1282  std::vector<CAxis*> CGrid::getAxis()
1283  {
1284    std::vector<CAxis*> aList;
1285    if (!axisList_.empty())
1286      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
1287
1288    return aList;
1289  }
1290
1291  /*!
1292  \brief Set domain(s) of a grid from a list
1293  \param[in] domains list of domains
1294  */
1295  void CGrid::setDomainList(const std::vector<CDomain*> domains)
1296  {
1297    if (isDomListSet) return;
1298    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1299    if (!domains.empty() && domList.empty()) domList = domains;
1300    if (!domList.empty())
1301    {
1302      int sizeDom = domList.size();
1303      domList_.resize(sizeDom);
1304      for (int i = 0; i < sizeDom; ++i)
1305      {
1306        domList_[i] = domList[i]->getId();
1307      }
1308      isDomListSet = true;
1309    }
1310
1311  }
1312
1313  /*!
1314  \brief Set axis(s) of a grid from a list
1315  \param[in] axis list of axis
1316  */
1317  void CGrid::setAxisList(const std::vector<CAxis*> axis)
1318  {
1319    if (isAxisListSet) return;
1320    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1321    if (!axis.empty() && aList.empty()) aList = axis;
1322    if (!aList.empty())
1323    {
1324      int sizeAxis = aList.size();
1325      axisList_.resize(sizeAxis);
1326      for (int i = 0; i < sizeAxis; ++i)
1327      {
1328        axisList_[i] = aList[i]->getId();
1329      }
1330      isAxisListSet = true;
1331    }
1332  }
1333
1334  /*!
1335  \brief Get list of id of domains
1336  \return id list of domains
1337  */
1338  std::vector<StdString> CGrid::getDomainList()
1339  {
1340    setDomainList();
1341    return domList_;
1342  }
1343
1344  /*!
1345  \brief Get list of id of axis
1346  \return id list of axis
1347  */
1348  std::vector<StdString> CGrid::getAxisList()
1349  {
1350    setAxisList();
1351    return axisList_;
1352  }
1353
1354  void CGrid::sendAllDomains()
1355  {
1356    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1357    int dSize = domList.size();
1358    for (int i = 0; i < dSize; ++i)
1359    {
1360      sendAddDomain(domList[i]->getId());
1361      domList[i]->sendAllAttributesToServer();
1362    }
1363  }
1364
1365  void CGrid::sendAllAxis()
1366  {
1367    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1368    int aSize = aList.size();
1369
1370    for (int i = 0; i < aSize; ++i)
1371    {
1372      sendAddAxis(aList[i]->getId());
1373      aList[i]->sendAllAttributesToServer();
1374    }
1375  }
1376
1377  void CGrid::parse(xml::CXMLNode& node)
1378  {
1379    SuperClass::parse(node);
1380
1381    // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
1382    std::vector<bool> order;
1383
1384    if (node.goToChildElement())
1385    {
1386      StdString domainName("domain");
1387      StdString axisName("axis");
1388      do
1389      {
1390        if (node.getElementName() == domainName) {
1391          order.push_back(true);
1392          this->getVirtualDomainGroup()->parseChild(node);
1393        }
1394        if (node.getElementName() == axisName) {
1395          order.push_back(false);
1396          this->getVirtualAxisGroup()->parseChild(node);
1397        }
1398      } while (node.goToNextElement());
1399      node.goToParentElement();
1400    }
1401
1402    if (!order.empty())
1403    {
1404      int sizeOrd = order.size();
1405      axis_domain_order.resize(sizeOrd);
1406      for (int i = 0; i < sizeOrd; ++i)
1407      {
1408        axis_domain_order(i) = order[i];
1409      }
1410    }
1411
1412    setDomainList();
1413    setAxisList();
1414   }
1415} // namespace xios
Note: See TracBrowser for help on using the repository browser.