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

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

First implementation of hierarchical distributed hashed table

+) Implement dht for int with index of type size_t

Test
+) Local
+) Work correctly

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