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

Last change on this file since 680 was 676, checked in by rlacroix, 9 years ago

Add support for indexed output.

If the new field attribute "indexed_output" is set to true and a mask is defined (either at grid, domain or axis level), the indexed data will be outputed instead of the full data with missing values.

See http://cfconventions.org/Data/cf-conventions/cf-conventions-1.5/build/cf-conventions.html#compression-by-gathering for more information.

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