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

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

Implementing the first prototype of filter

+) Create new class filter
+) Implement class for specific algorithm
+) Implement inversing algorithm

Test
+) On Curie
+) Grid with one axis: passed

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