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

Last change on this file since 583 was 575, checked in by rlacroix, 9 years ago

Rename axisDomainOrder attribute to axis_domain_order.

"Snake case" is used everywhere else and camel case seems to confuse PGI compilers.

  • 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
File size: 31.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 "xmlioserver_spl.hpp"
10#include "type.hpp"
11#include "context.hpp"
12#include "context_client.hpp"
13#include "context_server.hpp"
14#include "array_new.hpp"
15#include "client_server_mapping_distributed.hpp"
16
17namespace xios {
18
19   /// ////////////////////// Définitions ////////////////////// ///
20
21   CGrid::CGrid(void)
22      : CObjectTemplate<CGrid>(), CGridAttributes()
23      , isChecked(false), isDomainAxisChecked(false), storeIndex(1)
24      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
25      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_(0), writtenDataSize_(0), globalDim_()
26   {
27     setVirtualDomainGroup();
28     setVirtualAxisGroup();
29   }
30
31   CGrid::CGrid(const StdString & id)
32      : CObjectTemplate<CGrid>(id), CGridAttributes()
33      , isChecked(false), isDomainAxisChecked(false), storeIndex(1)
34      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
35      , serverDistribution_(0), serverDistributionDescription_(0), clientServerMap_(0), writtenDataSize_(0), globalDim_()
36   {
37     setVirtualDomainGroup();
38     setVirtualAxisGroup();
39   }
40
41   CGrid::~CGrid(void)
42   {
43    deque< CArray<int, 1>* >::iterator it ;
44
45    for(deque< CArray<int,1>* >::iterator it=storeIndex.begin(); it!=storeIndex.end();it++)  delete *it ;
46    for(map<int,CArray<size_t,1>* >::iterator it=outIndexFromClient.begin();it!=outIndexFromClient.end();++it) delete (it->second);
47
48    if (0 != clientDistribution_) delete clientDistribution_;
49    if (0 != serverDistribution_) delete serverDistribution_;
50    if (0 != serverDistributionDescription_) delete serverDistributionDescription_;
51   }
52
53   ///---------------------------------------------------------------
54
55   StdString CGrid::GetName(void)    { return (StdString("grid")); }
56   StdString CGrid::GetDefName(void) { return (CGrid::GetName()); }
57   ENodeType CGrid::GetType(void)    { return (eGrid); }
58
59   //----------------------------------------------------------------
60
61   const std::deque< CArray<int,1>* > & CGrid::getStoreIndex(void) const
62   {
63      return (this->storeIndex );
64   }
65
66   //---------------------------------------------------------------
67//
68//   const std::deque< CArray<int,1>* > & CGrid::getOutIIndex(void)  const
69//   {
70//      return (this->out_i_index );
71//   }
72//
73//   //---------------------------------------------------------------
74//
75//   const std::deque< CArray<int,1>* > & CGrid::getOutJIndex(void)  const
76//   {
77//      return (this->out_j_index );
78//   }
79//
80//   //---------------------------------------------------------------
81//
82//   const std::deque< CArray<int,1>* > & CGrid::getOutLIndex(void)  const
83//   {
84//      return (this->out_l_index );
85//   }
86//
87//   //---------------------------------------------------------------
88//
89//   const CAxis*   CGrid::getRelAxis  (void) const
90//   {
91//      return (this->axis );
92//   }
93
94//   //---------------------------------------------------------------
95//
96//   const CDomain* CGrid::getRelDomain(void) const
97//   {
98//      return (this->domain );
99//   }
100
101   //---------------------------------------------------------------
102
103//   bool CGrid::hasAxis(void) const
104//   {
105//      return (this->withAxis);
106//   }
107
108   //---------------------------------------------------------------
109
110   StdSize CGrid::getDimension(void) const
111   {
112      return (globalDim_.size());
113   }
114
115   //---------------------------------------------------------------
116
117/*
118   std::vector<StdSize> CGrid::getLocalShape(void) const
119   {
120      std::vector<StdSize> retvalue;
121      retvalue.push_back(domain->zoom_ni_loc.getValue());
122      retvalue.push_back(domain->zoom_nj_loc.getValue());
123      if (this->withAxis)
124         retvalue.push_back(this->axis->zoom_size.getValue());
125      return (retvalue);
126   }
127*/
128   //---------------------------------------------------------------
129
130/*
131   StdSize CGrid::getLocalSize(void) const
132   {
133      StdSize retvalue = 1;
134      std::vector<StdSize> shape_ = this->getLocalShape();
135      for (StdSize s = 0; s < shape_.size(); s++)
136         retvalue *= shape_[s];
137      return (retvalue);
138   }
139*/
140   //---------------------------------------------------------------
141/*
142   std::vector<StdSize> CGrid::getGlobalShape(void) const
143   {
144      std::vector<StdSize> retvalue;
145      retvalue.push_back(domain->ni.getValue());
146      retvalue.push_back(domain->nj.getValue());
147      if (this->withAxis)
148         retvalue.push_back(this->axis->size.getValue());
149      return (retvalue);
150   }
151*/
152   //---------------------------------------------------------------
153
154/*
155   StdSize CGrid::getGlobalSize(void) const
156   {
157      StdSize retvalue = 1;
158      std::vector<StdSize> shape_ = this->getGlobalShape();
159      for (StdSize s = 0; s < shape_.size(); s++)
160         retvalue *= shape_[s];
161      return (retvalue);
162   }
163*/
164   StdSize CGrid::getDataSize(void) const
165   {
166      std::vector<int> dataNindex = clientDistribution_->getDataNIndex();
167      StdSize retvalue = 1;
168      for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];
169      return (retvalue);
170   }
171
172   std::map<int, StdSize> CGrid::getConnectedServerDataSize()
173   {
174     double secureFactor = 2.5 * sizeof(double) * CXios::bufferServerFactorSize;
175     StdSize retVal;
176     std::map<int, StdSize> ret;
177     const std::map<int, std::vector<int> >& distribution = clientServerMap_->getLocalIndexSendToServer();
178     std::map<int, std::vector<int> >::const_iterator it = distribution.begin(), itE = distribution.end();
179     for (; it != itE; ++it)
180     {
181        retVal = it->second.size();
182        retVal *= secureFactor;
183        ret.insert(std::make_pair<int,StdSize>(it->first, retVal));
184     }
185
186     return ret;
187   }
188
189
190   void CGrid::solveDomainAxisRef(bool areAttributesChecked)
191   {
192     if (this->isDomainAxisChecked) return;
193
194     this->solveDomainRef(areAttributesChecked);
195     this->solveAxisRef(areAttributesChecked);
196
197     this->isDomainAxisChecked = areAttributesChecked;
198   }
199
200   void CGrid::checkMaskIndex(bool doSendingIndex)
201   {
202     CContext* context = CContext::getCurrent() ;
203     CContextClient* client=context->client ;
204
205     if (context->hasClient)
206      if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
207
208     if (this->isChecked) return;
209
210     if (context->hasClient)
211     {
212        checkMask() ;
213        this->computeIndex() ;
214        this->storeIndex.push_front(new CArray<int,1>() );
215     }
216     this->isChecked = true;
217   }
218
219   void CGrid::checkMask(void)
220   {
221      using namespace std;
222      std::vector<CDomain*> domainP = this->getDomains();
223      std::vector<CAxis*> axisP = this->getAxis();
224      int dim = domainP.size() * 2 + axisP.size();
225
226      std::vector<CArray<bool,2>* > domainMasks(domainP.size());
227      for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->mask);
228      std::vector<CArray<bool,1>* > axisMasks(axisP.size());
229      for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask);
230
231      switch (dim) {
232        case 1:
233          checkGridMask(mask1, domainMasks, axisMasks, axis_domain_order);
234          break;
235        case 2:
236          checkGridMask(mask2, domainMasks, axisMasks, axis_domain_order);
237          break;
238        case 3:
239          checkGridMask(mask3, domainMasks, axisMasks, axis_domain_order);
240          break;
241//        case 4:
242//          checkGridMask(mask4, domainMasks, axisMasks, axis_domain_order);
243//          break;
244//        case 5:
245//          checkGridMask(mask5, domainMasks, axisMasks, axis_domain_order);
246//          break;
247//        case 6:
248//          checkGridMask(mask6, domainMasks, axisMasks, axis_domain_order);
249//          break;
250//        case 7:
251//          checkGridMask(mask7, domainMasks, axisMasks, axis_domain_order);
252//          break;
253        default:
254          break;
255      }
256   }
257   //---------------------------------------------------------------
258
259   void CGrid::solveDomainRef(bool sendAtt)
260   {
261      setDomainList();
262      std::vector<CDomain*> domListP = this->getDomains();
263      if (!domListP.empty())
264      {
265        computeGridGlobalDimension(getDomains(), getAxis(), axis_domain_order);
266        for (int i = 0; i < domListP.size(); ++i)
267        {
268          if (sendAtt) domListP[i]->sendCheckedAttributes();
269          else domListP[i]->checkAttributesOnClient();
270        }
271      }
272   }
273
274   //---------------------------------------------------------------
275
276   void CGrid::solveAxisRef(bool sendAtt)
277   {
278      setAxisList();
279      std::vector<CAxis*> axisListP = this->getAxis();
280      if (!axisListP.empty())
281      {
282        int idx = 0;
283        std::vector<int> axisPositionMap;
284        for (int i = 0; i < axis_domain_order.numElements(); ++i)
285        {
286          if (false == axis_domain_order(i))
287          {
288            axisPositionMap.push_back(idx);
289            ++idx;
290          }
291          else idx += 2;
292        }
293
294        computeGridGlobalDimension(getDomains(), getAxis(), axis_domain_order);
295        for (int i = 0; i < axisListP.size(); ++i)
296        {
297          if (sendAtt)
298            axisListP[i]->sendCheckedAttributes(globalDim_,axisPositionMap[i]);
299          else
300            axisListP[i]->checkAttributesOnClient(globalDim_,axisPositionMap[i]);
301          ++idx;
302        }
303
304      }
305   }
306
307   //---------------------------------------------------------------
308
309   void CGrid::computeIndex(void)
310   {
311     CContext* context = CContext::getCurrent() ;
312     CContextClient* client=context->client ;
313
314     // First of all, compute distribution on client side
315     clientDistribution_ = new CDistributionClient(client->clientRank, this);
316     size_t globalSizeIndex = 1, indexBegin, indexEnd;
317     int range, clientSize = client->clientSize;
318     for (int i = 0; i < globalDim_.size(); ++i) globalSizeIndex *= globalDim_[i];
319     indexBegin = 0;
320     for (int i = 0; i < clientSize; ++i)
321     {
322       range = globalSizeIndex / clientSize;
323       if (i < (globalSizeIndex%clientSize)) ++range;
324       if (i == client->clientRank) break;
325       indexBegin += range;
326     }
327     indexEnd = indexBegin + range - 1;
328
329     // Then compute distribution on server side
330     serverDistributionDescription_ = new CServerDistributionDescription(clientDistribution_->getNGlob());
331     serverDistributionDescription_->computeServerDistribution(client->serverSize, true);
332     serverDistributionDescription_->computeServerGlobalIndexInRange(client->serverSize,
333                                                                     std::make_pair<size_t,size_t>(indexBegin, indexEnd));
334
335     // Finally, compute index mapping between client(s) and server(s)
336     clientServerMap_ = new CClientServerMappingDistributed(serverDistributionDescription_->getGlobalIndexRange(),
337                                                            client->intraComm);
338
339     clientServerMap_->computeServerIndexMapping(clientDistribution_->getGlobalIndex(),
340                                                 clientDistribution_->getLocalDataIndexSendToServerOnClient());
341
342     const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
343     std::vector<int> connectedServerRank;
344     for (std::map<int, std::vector<size_t> >::const_iterator it = globalIndexOnServer.begin(); it != globalIndexOnServer.end(); ++it) {
345       connectedServerRank.push_back(it->first);
346     }
347     nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank);
348
349     // Get local data index on client
350     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().numElements());
351     storeIndex_client = (clientDistribution_->getLocalDataIndexOnClient());
352   }
353
354   //----------------------------------------------------------------
355
356   CGrid* CGrid::createGrid(CDomain* domain)
357   {
358      std::vector<CDomain*> vecDom(1,domain);
359      std::vector<CAxis*> vecAxis;
360
361      CGrid* grid = createGrid(vecDom, vecAxis);
362
363      return (grid);
364   }
365
366   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
367   {
368      std::vector<CDomain*> vecDom(1,domain);
369      std::vector<CAxis*> vecAxis(1,axis);
370      CGrid* grid = createGrid(vecDom, vecAxis);
371
372      return (grid);
373   }
374
375   CGrid* CGrid::createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis)
376   {
377      StdString new_id = StdString("__");
378      if (!domains.empty()) for (int i = 0; i < domains.size(); ++i) new_id += domains[i]->getId() + StdString("_");
379      if (!axis.empty()) for (int i = 0; i < axis.size(); ++i) new_id += axis[i]->getId() + StdString("_") ;
380      new_id += StdString("_");
381
382      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
383      grid->setDomainList(domains);
384      grid->setAxisList(axis);
385
386      //By default, domains are always the first ones of a grid
387      if (grid->axis_domain_order.isEmpty())
388      {
389        int size = domains.size()+axis.size();
390        grid->axis_domain_order.resize(size);
391        for (int i = 0; i < size; ++i)
392        {
393          if (i < domains.size()) grid->axis_domain_order(i) = true;
394          else grid->axis_domain_order(i) = false;
395        }
396      }
397
398      grid->computeGridGlobalDimension(domains, axis, grid->axis_domain_order);
399
400      return (grid);
401   }
402
403   CDomainGroup* CGrid::getVirtualDomainGroup() const
404   {
405     return (this->vDomainGroup_);
406   }
407
408   CAxisGroup* CGrid::getVirtualAxisGroup() const
409   {
410     return (this->vAxisGroup_);
411   }
412
413   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
414   {
415     CArray<size_t,1>& out_i=*outIndexFromClient[rank];
416     StdSize numElements = stored.numElements();
417     for (StdSize n = 0; n < numElements; ++n)
418     {
419       *(field+out_i(n)) = stored(n);
420     }
421   }
422
423   //----------------------------------------------------------------
424
425
426   void CGrid::storeField_arr
427      (const double * const data, CArray<double, 1>& stored) const
428   {
429      const StdSize size = storeIndex_client.numElements() ;
430
431      stored.resize(size) ;
432      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)] ;
433   }
434
435  void CGrid::sendIndex(void)
436  {
437    CContext* context = CContext::getCurrent() ;
438    CContextClient* client=context->client ;
439
440    CEventClient event(getType(),EVENT_ID_INDEX) ;
441    int rank ;
442    list<shared_ptr<CMessage> > list_msg ;
443    list< CArray<size_t,1>* > listOutIndex;
444    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
445    const std::map<int, std::vector<int> >& localIndexSendToServer  = clientServerMap_->getLocalIndexSendToServer();
446
447    std::map<int, std::vector<size_t> >::const_iterator iteMap, itbMap, itGlobal;
448    std::map<int, std::vector<int> >::const_iterator itLocal;
449    itbMap = itGlobal = globalIndexOnServer.begin();
450    iteMap = globalIndexOnServer.end();
451    itLocal = localIndexSendToServer.begin();
452
453    if (!doGridHaveDataDistributed())
454    {
455      if (0 == client->clientRank)
456      {
457       for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
458        {
459          rank = itGlobal->first;
460          int nb = (itGlobal->second).size();
461
462          CArray<size_t, 1> outGlobalIndexOnServer(nb);
463          CArray<int, 1> outLocalIndexToServer(nb);
464          for (int k = 0; k < nb; ++k)
465          {
466            outGlobalIndexOnServer(k) = itGlobal->second.at(k);
467            outLocalIndexToServer(k)  = itLocal->second.at(k);
468          }
469
470          storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
471          listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
472
473          list_msg.push_back(shared_ptr<CMessage>(new CMessage));
474          *list_msg.back()<<getId()<<*listOutIndex.back();
475          event.push(rank, 1, *list_msg.back());
476        }
477        client->sendEvent(event);
478      } else client->sendEvent(event);
479    }
480    else
481    {
482      for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
483      {
484        rank = itGlobal->first;
485        int nb = (itGlobal->second).size();
486
487        CArray<size_t, 1> outGlobalIndexOnServer(nb);
488        CArray<int, 1> outLocalIndexToServer(nb);
489        for (int k = 0; k < nb; ++k)
490        {
491          outGlobalIndexOnServer(k) = itGlobal->second.at(k);
492          outLocalIndexToServer(k)  = itLocal->second.at(k);
493        }
494
495        storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
496        listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
497
498        list_msg.push_back(shared_ptr<CMessage>(new CMessage));
499        *list_msg.back()<<getId()<<*listOutIndex.back();
500        event.push(rank, nbSenders[rank], *list_msg.back());
501      }
502      client->sendEvent(event);
503    }
504
505    for(list<CArray<size_t,1>* >::iterator it=listOutIndex.begin();it!=listOutIndex.end();++it) delete *it ;
506  }
507
508  void CGrid::recvIndex(CEventServer& event)
509  {
510    list<CEventServer::SSubEvent>::iterator it ;
511    for (it=event.subEvents.begin();it!=event.subEvents.end();++it)
512    {
513      int rank=it->rank;
514      CBufferIn* buffer=it->buffer;
515      string gridId ;
516      *buffer>>gridId ;
517      get(gridId)->recvIndex(rank,*buffer) ;
518    }
519  }
520
521  void CGrid::computeGridGlobalDimension(const std::vector<CDomain*>& domains,
522                                         const std::vector<CAxis*>& axis,
523                                         const CArray<bool,1>& axisDomainOrder)
524  {
525    globalDim_.resize(domains.size()*2+axis.size());
526    int idx = 0, idxDomain = 0, idxAxis = 0;
527    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
528    {
529      if (axisDomainOrder(i))
530      {
531        globalDim_[idx]   = domains[idxDomain]->ni_glo.getValue();
532        globalDim_[idx+1] = domains[idxDomain]->nj_glo.getValue();
533        ++idxDomain;
534        idx += 2;
535      }
536      else
537      {
538        globalDim_[idx] = axis[idxAxis]->size.getValue();
539        ++idxAxis;
540        ++idx;
541      }
542    }
543  }
544
545  std::vector<int> CGrid::getGlobalDimension()
546  {
547    return globalDim_;
548  }
549
550  /*!
551    Verify whether one server need to write data
552    There are some cases on which one server has nodata to write. For example, when we
553  just only want to zoom on a domain.
554  */
555  bool CGrid::doGridHaveDataToWrite()
556  {
557    return (0 != serverDistribution_);
558  }
559
560  /*!
561    Return size of data which is written on each server
562    Whatever dimension of a grid, data which are written on server must be presented as
563  an one dimension array.
564  \return size of data written on server
565  */
566  size_t CGrid::getWrittenDataSize() const
567  {
568    return writtenDataSize_;
569  }
570
571
572  const CDistributionServer* CGrid::getDistributionServer() const
573  {
574    return serverDistribution_;
575  }
576
577  bool CGrid::doGridHaveDataDistributed()
578  {
579    return clientDistribution_->isDataDistributed();
580  }
581
582  void CGrid::recvIndex(int rank, CBufferIn& buffer)
583  {
584     if (0 == serverDistribution_)
585     {
586       CContext* context = CContext::getCurrent() ;
587       CContextServer* server=context->server ;
588       int idx = 0, numElement = axis_domain_order.numElements();
589       int ssize = numElement;
590       std::vector<int> indexMap(numElement);
591       for (int i = 0; i < numElement; ++i)
592       {
593         indexMap[i] = idx;
594         if (true == axis_domain_order(i))
595         {
596            ++ssize;
597            idx += 2;
598         }
599         else
600          ++idx;
601       }
602
603       int axisId = 0, domainId = 0;
604       std::vector<CDomain*> domainList = getDomains();
605       std::vector<CAxis*> axisList = getAxis();
606       std::vector<int> nZoomBegin(ssize), nZoomSize(ssize), nGlob(ssize), nZoomBeginGlobal(ssize);
607       for (int i = 0; i < numElement; ++i)
608       {
609         if (axis_domain_order(i))
610         {
611            nZoomBegin[indexMap[i]]   = domainList[domainId]->zoom_ibegin_srv;
612            nZoomSize[indexMap[i]]    = domainList[domainId]->zoom_ni_srv;
613            nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->zoom_ibegin;
614            nGlob[indexMap[i]]    = domainList[domainId]->ni_glo;
615
616            nZoomBegin[indexMap[i]+1] = domainList[domainId]->zoom_jbegin_srv;
617            nZoomSize[indexMap[i]+1]  = domainList[domainId]->zoom_nj_srv;
618            nZoomBeginGlobal[indexMap[i]+1] = domainList[domainId]->zoom_jbegin;
619            nGlob[indexMap[i]+1]    = domainList[domainId]->nj_glo;
620            ++domainId;
621         }
622         else
623         {
624            nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin_srv;
625            nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_size_srv;
626            nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->zoom_begin;
627            nGlob[indexMap[i]]      = axisList[axisId]->size;
628            ++axisId;
629         }
630       }
631       writtenDataSize_ = 1;
632       for (int i = 0; i < nZoomSize.size(); ++i)
633        writtenDataSize_ *= nZoomSize[i];
634
635       serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
636                                                     nZoomBeginGlobal, nGlob);
637     }
638
639     CArray<size_t,1> outIndex;
640     buffer>>outIndex;
641     serverDistribution_->computeLocalIndex(outIndex);
642     outIndexFromClient.insert(std::pair<int, CArray<size_t,1>* >(rank, new CArray<size_t,1>(outIndex)));
643  }
644
645   /*!
646   \brief Dispatch event received from client
647      Whenever a message is received in buffer of server, it will be processed depending on
648   its event type. A new event type should be added in the switch list to make sure
649   it processed on server side.
650   \param [in] event: Received message
651   */
652  bool CGrid::dispatchEvent(CEventServer& event)
653  {
654
655    if (SuperClass::dispatchEvent(event)) return true ;
656    else
657    {
658      switch(event.type)
659      {
660        case EVENT_ID_INDEX :
661          recvIndex(event) ;
662          return true ;
663          break ;
664
665         case EVENT_ID_ADD_DOMAIN :
666           recvAddDomain(event) ;
667           return true ;
668           break ;
669
670         case EVENT_ID_ADD_AXIS :
671           recvAddAxis(event) ;
672           return true ;
673           break ;
674        default :
675          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
676                <<"Unknown Event") ;
677          return false ;
678      }
679    }
680  }
681
682   void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const
683   {
684      if ((this->storeIndex.size()-1 ) != storedClient.size())
685         ERROR("void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const",
686                << "[ Expected received field = " << (this->storeIndex.size()-1) << ", "
687                << "[ received fiedl = "    << storedClient.size() << "] "
688                << "Data from clients are missing!") ;
689      storedServer.resize(storeIndex[0]->numElements());
690
691      for (StdSize i = 0, n = 0; i < storedClient.size(); i++)
692         for (StdSize j = 0; j < storedClient[i]->numElements(); j++)
693            storedServer(n++) = (*storedClient[i])(j);
694   }
695
696   void CGrid::outputFieldToServer(CArray<double,1>& fieldIn, int rank, CArray<double,1>& fieldOut)
697   {
698     CArray<int,1>& index = *storeIndex_toSrv[rank] ;
699     int nb=index.numElements() ;
700     fieldOut.resize(nb) ;
701
702     for(int k=0;k<nb;k++) fieldOut(k)=fieldIn(index(k)) ;
703    }
704   ///---------------------------------------------------------------
705
706   CDomain* CGrid::addDomain(const std::string& id)
707   {
708     return vDomainGroup_->createChild(id) ;
709   }
710
711   CAxis* CGrid::addAxis(const std::string& id)
712   {
713     return vAxisGroup_->createChild(id) ;
714   }
715
716   //! Change virtual field group to a new one
717   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
718   {
719      this->vDomainGroup_ = newVDomainGroup;
720   }
721
722   //! Change virtual variable group to new one
723   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
724   {
725      this->vAxisGroup_ = newVAxisGroup;
726   }
727
728   //----------------------------------------------------------------
729   //! Create virtual field group, which is done normally on initializing file
730   void CGrid::setVirtualDomainGroup(void)
731   {
732      this->setVirtualDomainGroup(CDomainGroup::create());
733   }
734
735   //! Create virtual variable group, which is done normally on initializing file
736   void CGrid::setVirtualAxisGroup(void)
737   {
738      this->setVirtualAxisGroup(CAxisGroup::create());
739   }
740
741   /*!
742   \brief Send a message to create a domain on server side
743   \param[in] id String identity of domain that will be created on server
744   */
745   void CGrid::sendAddDomain(const string& id)
746   {
747    CContext* context=CContext::getCurrent() ;
748
749    if (! context->hasServer )
750    {
751       CContextClient* client=context->client ;
752
753       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN) ;
754       if (client->isServerLeader())
755       {
756         CMessage msg ;
757         msg<<this->getId() ;
758         msg<<id ;
759         event.push(client->getServerLeader(),1,msg) ;
760         client->sendEvent(event) ;
761       }
762       else client->sendEvent(event) ;
763    }
764   }
765
766   /*!
767   \brief Send a message to create an axis on server side
768   \param[in] id String identity of axis that will be created on server
769   */
770   void CGrid::sendAddAxis(const string& id)
771   {
772    CContext* context=CContext::getCurrent() ;
773
774    if (! context->hasServer )
775    {
776       CContextClient* client=context->client ;
777
778       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS) ;
779       if (client->isServerLeader())
780       {
781         CMessage msg ;
782         msg<<this->getId() ;
783         msg<<id ;
784         event.push(client->getServerLeader(),1,msg) ;
785         client->sendEvent(event) ;
786       }
787       else client->sendEvent(event) ;
788    }
789   }
790
791   /*!
792   \brief Receive a message annoucing the creation of a domain on server side
793   \param[in] event Received event
794   */
795   void CGrid::recvAddDomain(CEventServer& event)
796   {
797
798      CBufferIn* buffer=event.subEvents.begin()->buffer;
799      string id;
800      *buffer>>id ;
801      get(id)->recvAddDomain(*buffer) ;
802   }
803
804   /*!
805   \brief Receive a message annoucing the creation of a domain on server side
806   \param[in] buffer Buffer containing message
807   */
808   void CGrid::recvAddDomain(CBufferIn& buffer)
809   {
810      string id ;
811      buffer>>id ;
812      addDomain(id) ;
813   }
814
815   /*!
816   \brief Receive a message annoucing the creation of an axis on server side
817   \param[in] event Received event
818   */
819   void CGrid::recvAddAxis(CEventServer& event)
820   {
821
822      CBufferIn* buffer=event.subEvents.begin()->buffer;
823      string id;
824      *buffer>>id ;
825      get(id)->recvAddAxis(*buffer) ;
826   }
827
828   /*!
829   \brief Receive a message annoucing the creation of an axis on server side
830   \param[in] buffer Buffer containing message
831   */
832   void CGrid::recvAddAxis(CBufferIn& buffer)
833   {
834      string id ;
835      buffer>>id ;
836      addAxis(id) ;
837   }
838
839  /*!
840  \brief Solve domain and axis references
841  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
842  all attributes from their parents, they should be processed with this function
843  \param[in] apply inherit all attributes of parents (true)
844  */
845  void CGrid::solveDomainAxisRefInheritance(bool apply)
846  {
847    CContext* context = CContext::getCurrent();
848    unsigned int vecSize, i;
849    std::vector<StdString>::iterator it, itE;
850    setDomainList();
851    it = domList_.begin(); itE = domList_.end();
852    for (; it != itE; ++it)
853    {
854      CDomain* pDom = CDomain::get(*it);
855      if (context->hasClient)
856      {
857        pDom->solveRefInheritance(apply);
858        pDom->solveBaseReference();
859        if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
860          pDom->name.setValue(pDom->getBaseDomainReference()->getId());
861      }
862    }
863
864    setAxisList();
865    it = axisList_.begin(); itE = axisList_.end();
866    for (; it != itE; ++it)
867    {
868      CAxis* pAxis = CAxis::get(*it);
869      if (context->hasClient)
870      {
871        pAxis->solveRefInheritance(apply);
872        pAxis->solveBaseReference();
873        if ((!pAxis->axis_ref.isEmpty()) && (pAxis->name.isEmpty()))
874          pAxis->name.setValue(pAxis->getBaseAxisReference()->getId());
875      }
876    }
877  }
878
879  /*!
880  \brief Get the list of domain pointers
881  \return list of domain pointers
882  */
883  std::vector<CDomain*> CGrid::getDomains()
884  {
885    std::vector<CDomain*> domList;
886    if (!domList_.empty())
887    {
888      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
889    }
890    return domList;
891  }
892
893  /*!
894  \brief Get the list of  axis pointers
895  \return list of axis pointers
896  */
897  std::vector<CAxis*> CGrid::getAxis()
898  {
899    std::vector<CAxis*> aList;
900    if (!axisList_.empty())
901      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
902
903    return aList;
904  }
905
906  /*!
907  \brief Set domain(s) of a grid from a list
908  \param[in] domains list of domains
909  */
910  void CGrid::setDomainList(const std::vector<CDomain*> domains)
911  {
912    if (isDomListSet) return;
913    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
914    if (!domains.empty() && domList.empty()) domList = domains;
915    if (!domList.empty())
916    {
917      int sizeDom = domList.size();
918      domList_.resize(sizeDom);
919      for (int i = 0 ; i < sizeDom; ++i)
920      {
921        domList_[i] = domList[i]->getId();
922      }
923      isDomListSet = true;
924    }
925
926  }
927
928  /*!
929  \brief Set axis(s) of a grid from a list
930  \param[in] axis list of axis
931  */
932  void CGrid::setAxisList(const std::vector<CAxis*> axis)
933  {
934    if (isAxisListSet) return;
935    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
936    if (!axis.empty() && aList.empty()) aList = axis;
937    if (!aList.empty())
938    {
939      int sizeAxis = aList.size();
940      axisList_.resize(sizeAxis);
941      for (int i = 0; i < sizeAxis; ++i)
942      {
943        axisList_[i] = aList[i]->getId();
944      }
945      isAxisListSet = true;
946    }
947  }
948
949  /*!
950  \brief Get list of id of domains
951  \return id list of domains
952  */
953  std::vector<StdString> CGrid::getDomainList()
954  {
955    setDomainList();
956    return domList_;
957  }
958
959  /*!
960  \brief Get list of id of axis
961  \return id list of axis
962  */
963  std::vector<StdString> CGrid::getAxisList()
964  {
965    setAxisList();
966    return axisList_;
967  }
968
969  void CGrid::sendAllDomains()
970  {
971    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
972    int dSize = domList.size();
973    for (int i = 0; i < dSize; ++i)
974    {
975      sendAddDomain(domList[i]->getId());
976      domList[i]->sendAllAttributesToServer();
977    }
978  }
979
980  void CGrid::sendAllAxis()
981  {
982    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
983    int aSize = aList.size();
984
985    for (int i = 0; i < aSize; ++i)
986    {
987      sendAddAxis(aList[i]->getId());
988      aList[i]->sendAllAttributesToServer();
989    }
990  }
991
992  void CGrid::parse(xml::CXMLNode & node)
993  {
994    SuperClass::parse(node);
995
996    // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
997    std::vector<bool> order;
998
999    if (node.goToChildElement())
1000    {
1001      StdString domainName("domain");
1002      StdString axisName("axis");
1003      do
1004      {
1005        if (node.getElementName() == domainName) {
1006          order.push_back(true);
1007          this->getVirtualDomainGroup()->parseChild(node);
1008        }
1009        if (node.getElementName() == axisName) {
1010          order.push_back(false);
1011          this->getVirtualAxisGroup()->parseChild(node);
1012        }
1013      } while (node.goToNextElement()) ;
1014      node.goToParentElement();
1015    }
1016
1017    if (!order.empty())
1018    {
1019      int sizeOrd = order.size();
1020      axis_domain_order.resize(sizeOrd);
1021      for (int i = 0; i < sizeOrd; ++i)
1022      {
1023        axis_domain_order(i) = order[i];
1024      }
1025    }
1026
1027    setDomainList();
1028    setAxisList();
1029   }
1030
1031} // namespace xios
Note: See TracBrowser for help on using the repository browser.