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

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

Implement direct transformation with domain_ref and axis_ref

+) Add a new case in which transformations among fields can be done via domain_ref and axis_ref (not only grid_ref)
+) Fix a minor bug relating to baseFieldReference

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