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

Last change on this file since 567 was 567, checked in by mhnguyen, 7 years ago

Implementing a grid formed by only one axis or group of axis

+) Add several new attributes to axis. From now on, each axis can be distributed on client side
+) Modify mask of grid to make it more flexible to different dimension
+) Fix some bugs relating to calculation of local data index on client
+) Clean some redundant codes

Test
+) On Curie, only test_new_features.f90
+) Test cases:

  • Grid composed of: 1 domain and 1 axis, 3 axis, 1 axis
  • Mode: Attached and connected
  • No of client-server: 6-2(Connected), 2 (Attached)

+) All tests passed and results are correct

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