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

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

Redesigning grid structure

+) Add an intermediate class to calculate distribution on client and servers
+) Change all index of attributes to zero (0), instead of one(1)

Test
+) On Curie
+) Test new features passes but some data are still shifted

  • 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: 37.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 "array_new.hpp"
14
15namespace xios {
16
17   /// ////////////////////// Définitions ////////////////////// ///
18
19   CGrid::CGrid(void)
20      : CObjectTemplate<CGrid>(), CGridAttributes()
21      , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
22      , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
23      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
24   {
25     setVirtualDomainGroup();
26     setVirtualAxisGroup();
27   }
28
29   CGrid::CGrid(const StdString & id)
30      : CObjectTemplate<CGrid>(id), CGridAttributes()
31      , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
32      , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
33      , vDomainGroup_(), vAxisGroup_(), axisList_(), isAxisListSet(false), isDomListSet(false), clientDistribution_(0), isIndexSent(false)
34   {
35     setVirtualDomainGroup();
36     setVirtualAxisGroup();
37   }
38
39   CGrid::~CGrid(void)
40   {
41 //     this->axis.reset() ;
42//      this->domain.reset() ;
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(deque< CArray<int,1>* >::iterator it=out_i_index.begin();it!=out_i_index.end();it++) delete *it ;
47    for(deque< CArray<int,1>* >::iterator it=out_j_index.begin();it!=out_j_index.end();it++) delete *it ;
48    for(deque< CArray<int,1>* >::iterator it=out_l_index.begin();it!=out_l_index.end();it++) delete *it ;
49
50    for(map<int,CArray<int,1>* >::iterator it=out_i_fromClient.begin();it!=out_i_fromClient.end();it++) delete it->second ;
51    for(map<int,CArray<int,1>* >::iterator it=out_j_fromClient.begin();it!=out_j_fromClient.end();it++) delete it->second ;
52    for(map<int,CArray<int,1>* >::iterator it=out_l_fromClient.begin();it!=out_l_fromClient.end();it++) delete it->second ;
53
54    for(map<int,CArray<size_t,1>* >::iterator it=outIndexFromClient.begin();it!=outIndexFromClient.end();++it) delete (it->second);
55
56    if (0 != clientDistribution_) delete clientDistribution_;
57
58   }
59
60   ///---------------------------------------------------------------
61
62   StdString CGrid::GetName(void)    { return (StdString("grid")); }
63   StdString CGrid::GetDefName(void) { return (CGrid::GetName()); }
64   ENodeType CGrid::GetType(void)    { return (eGrid); }
65
66   //----------------------------------------------------------------
67
68   const std::deque< CArray<int,1>* > & CGrid::getStoreIndex(void) const
69   {
70      return (this->storeIndex );
71   }
72
73   //---------------------------------------------------------------
74
75   const std::deque< CArray<int,1>* > & CGrid::getOutIIndex(void)  const
76   {
77      return (this->out_i_index );
78   }
79
80   //---------------------------------------------------------------
81
82   const std::deque< CArray<int,1>* > & CGrid::getOutJIndex(void)  const
83   {
84      return (this->out_j_index );
85   }
86
87   //---------------------------------------------------------------
88
89   const std::deque< CArray<int,1>* > & CGrid::getOutLIndex(void)  const
90   {
91      return (this->out_l_index );
92   }
93
94   //---------------------------------------------------------------
95
96   const CAxis*   CGrid::getRelAxis  (void) const
97   {
98      return (this->axis );
99   }
100
101   //---------------------------------------------------------------
102
103   const CDomain* CGrid::getRelDomain(void) const
104   {
105      return (this->domain );
106   }
107
108   //---------------------------------------------------------------
109
110   bool CGrid::hasAxis(void) const
111   {
112      return (this->withAxis);
113   }
114
115   //---------------------------------------------------------------
116
117   StdSize CGrid::getDimension(void) const
118   {
119      return ((this->withAxis)?3:2);
120   }
121
122   //---------------------------------------------------------------
123
124/*
125   std::vector<StdSize> CGrid::getLocalShape(void) const
126   {
127      std::vector<StdSize> retvalue;
128      retvalue.push_back(domain->zoom_ni_loc.getValue());
129      retvalue.push_back(domain->zoom_nj_loc.getValue());
130      if (this->withAxis)
131         retvalue.push_back(this->axis->zoom_size.getValue());
132      return (retvalue);
133   }
134*/
135   //---------------------------------------------------------------
136
137/*
138   StdSize CGrid::getLocalSize(void) const
139   {
140      StdSize retvalue = 1;
141      std::vector<StdSize> shape_ = this->getLocalShape();
142      for (StdSize s = 0; s < shape_.size(); s++)
143         retvalue *= shape_[s];
144      return (retvalue);
145   }
146*/
147   //---------------------------------------------------------------
148/*
149   std::vector<StdSize> CGrid::getGlobalShape(void) const
150   {
151      std::vector<StdSize> retvalue;
152      retvalue.push_back(domain->ni.getValue());
153      retvalue.push_back(domain->nj.getValue());
154      if (this->withAxis)
155         retvalue.push_back(this->axis->size.getValue());
156      return (retvalue);
157   }
158*/
159   //---------------------------------------------------------------
160
161/*
162   StdSize CGrid::getGlobalSize(void) const
163   {
164      StdSize retvalue = 1;
165      std::vector<StdSize> shape_ = this->getGlobalShape();
166      for (StdSize s = 0; s < shape_.size(); s++)
167         retvalue *= shape_[s];
168      return (retvalue);
169   }
170*/
171   StdSize CGrid::getDataSize(void) const
172   {
173      StdSize retvalue=domain->data_ni.getValue() ;
174      if (domain->data_dim.getValue()==2) retvalue*=domain->data_nj.getValue() ;
175      if (this->withAxis) retvalue*=this->axis->size.getValue() ;
176
177      return (retvalue);
178   }
179
180   std::map<int, StdSize> CGrid::getConnectedServerDataSize()
181   {
182     double secureFactor = 2.5 * sizeof(double) * CXios::bufferServerFactorSize;
183     StdSize retVal;
184     std::map<int, StdSize> ret;
185     const std::map<int, std::vector<int> >& distribution = clientDistribution_->getLocalIndexSendToServer();
186     std::map<int, std::vector<int> >::const_iterator it = distribution.begin(), itE = distribution.end();
187     for (; it != itE; ++it)
188     {
189        retVal = it->second.size();
190        retVal *= secureFactor;
191        ret.insert(std::make_pair<int,StdSize>(it->first, retVal));
192     }
193
194     return ret;
195   }
196
197
198   //---------------------------------------------------------------
199
200//   void CGrid::solveReference(void)
201//   {
202//      if (this->isChecked) return;
203//      CContext* context = CContext::getCurrent() ;
204//      CContextClient* client=context->client ;
205//
206//      this->solveDomainRef() ;
207//      this->solveAxisRef() ;
208//
209//      if (context->hasClient)
210//      {
211//         checkMask() ;
212//         this->computeIndex() ;
213//
214//         this->storeIndex.push_front(new CArray<int,1>() );
215//         this->out_i_index.push_front(new CArray<int,1>());
216//         this->out_j_index.push_front(new CArray<int,1>());
217//         this->out_l_index.push_front(new CArray<int,1>());
218//      }
219////      this->computeIndexServer();
220//      this->isChecked = true;
221//   }
222
223   void CGrid::solveDomainAxisRef(bool areAttributesChecked)
224   {
225     if (this->isDomainAxisChecked) return;
226
227     this->solveDomainRef(areAttributesChecked);
228     this->solveAxisRef(areAttributesChecked);
229
230     this->isDomainAxisChecked = areAttributesChecked;
231   }
232
233   void CGrid::checkMaskIndex(bool doSendingIndex)
234   {
235     CContext* context = CContext::getCurrent() ;
236     CContextClient* client=context->client ;
237
238     if (context->hasClient)
239      if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
240
241     if (this->isChecked) return;
242
243     if (context->hasClient)
244     {
245        checkMask() ;
246        this->computeIndex() ;
247
248        this->storeIndex.push_front(new CArray<int,1>() );
249        this->out_i_index.push_front(new CArray<int,1>());
250        this->out_j_index.push_front(new CArray<int,1>());
251        this->out_l_index.push_front(new CArray<int,1>());
252     }
253//      this->computeIndexServer();
254     this->isChecked = true;
255   }
256
257
258   void CGrid::checkMask(void)
259   {
260      using namespace std;
261
262      unsigned int niu = domain->ni, nju = domain->nj;
263      unsigned int nlu = 1 ;
264      if (hasAxis()) nlu=axis->size ;
265
266      if (!mask.isEmpty())
267      {
268         if ((mask.extent(0) != niu) ||
269             (mask.extent(1) != nju) ||
270             (mask.extent(2) != nlu))
271             ERROR("CGrid::checkAttributes(void)",
272                  <<"The mask has not the same size than the local grid"<<endl
273                  <<"Local size is "<<niu<<"x"<<nju<<"x"<<nlu<<endl
274                  <<"Mask size is "<<mask.extent(0)<<"x"<<mask.extent(1)<<"x"<<mask.extent(2));
275      }
276      else
277      {
278        mask.resize(niu,nju,nlu) ;
279        mask=true  ;
280      }
281
282      CArray<bool,2>& domainMask = domain->mask ;
283      for (int l=0; l < nlu ; l++)
284        for (int j=0; j < nju ; j++)
285          for(int i=0; i<niu ; i++) mask(i,j,l) = mask(i,j,l) && domainMask(i,j) ;
286
287
288   }
289
290   //---------------------------------------------------------------
291
292//   void CGrid::solveDomainRef(void)
293//   {
294//      if (!domain_ref.isEmpty())
295//      {
296//         if (CDomain::has(domain_ref.getValue()))
297//         {
298//            this->domain = CDomain::get(domain_ref.getValue()) ;
299//            domain->checkAttributes() ;
300//         }
301//         else ERROR("CGrid::solveDomainRef(void)",
302//                     << "Wrong domain reference") ;
303//      }
304//      else ERROR("CGrid::solveDomainRef(void)",
305//                  << "Domain reference is not defined") ;
306//   }
307//
308//   //---------------------------------------------------------------
309//
310//   void CGrid::solveAxisRef(void)
311//   {
312//      if (!axis_ref.isEmpty())
313//      {
314//         this->withAxis = true ;
315//         if (CAxis::get(axis_ref.getValue()))
316//         {
317//            this->axis = CAxis::get(axis_ref.getValue()) ;
318//            axis->checkAttributes() ;
319//         }
320//         else ERROR("CGrid::solveAxisRef(void)",
321//                    << "Wrong axis reference") ;
322//      }
323//      else withAxis = false ;
324//   }
325
326
327   void CGrid::solveDomainRef(bool sendAtt)
328   {
329//      if (!domain_ref.isEmpty())
330//      {
331//         if (CDomain::has(domain_ref.getValue()))
332//         {
333//            this->domain = CDomain::get(domain_ref.getValue()) ;
334//            if (sendAtt) domain->sendCheckedAttributes();
335//            else domain->checkAttributesOnClient() ;
336//         }
337//         else ERROR("CGrid::solveDomainRef(void)",
338//                     << "Wrong domain reference") ;
339//      }
340//      else ERROR("CGrid::solveDomainRef(void)",
341//                  << "Domain reference is not defined") ;
342      setDomainList();
343      this->domain = CDomain::get(domList_.at(0));
344      if (0 != this->domain)
345      {
346//        this->domain = this->getDomain();
347        if (sendAtt) domain->sendCheckedAttributes();
348        else domain->checkAttributesOnClient() ;
349      }
350      else ERROR("CGrid::solveDomainRef(void)",
351                  << "Domain reference is not defined") ;
352   }
353
354   //---------------------------------------------------------------
355
356   void CGrid::solveAxisRef(bool checkAtt)
357   {
358//      if (!axis_ref.isEmpty())
359//      {
360//         this->withAxis = true ;
361//         if (CAxis::get(axis_ref.getValue()))
362//         {
363//            this->axis = CAxis::get(axis_ref.getValue()) ;
364//            axis->checkAttributes() ;
365//         }
366//         else ERROR("CGrid::solveAxisRef(void)",
367//                    << "Wrong axis reference") ;
368//      }
369//      else withAxis = false ;
370//      getAllAxis();
371      setAxisList();
372      if (!axisList_.empty())
373      {
374        int sizeList = axisList_.size();
375        for (int i = 0; i < sizeList; ++i)
376        {
377          CAxis::get(axisList_.at(i))->checkAttributes();
378          this->axis = CAxis::get(axisList_.at(i));
379        }
380        withAxis = true;
381
382      }
383//      if (!axis_ref.isEmpty())
384//      {
385//         this->withAxis = true ;
386//         if (CAxis::get(axis_ref.getValue()))
387//         {
388//            this->axis = CAxis::get(axis_ref.getValue()) ;
389//            axis->checkAttributes() ;
390//         }
391//         else ERROR("CGrid::solveAxisRef(void)",
392//                    << "Wrong axis reference") ;
393//      }
394      else withAxis = false ;
395   }
396
397   //---------------------------------------------------------------
398
399   void CGrid::computeIndex(void)
400   {
401     CContext* context = CContext::getCurrent() ;
402     CContextClient* client=context->client ;
403     clientDistribution_ = new CDistributionClient(client->clientRank, this);
404     clientDistribution_->computeServerIndexMapping(client->serverSize);
405     nbSenders = clientDistribution_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm);
406
407     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().numElements());
408     storeIndex_client = (clientDistribution_->getLocalDataIndexOnClient());
409
410/*
411      const int ni   = domain->ni.getValue() ,
412                nj   = domain->nj.getValue() ,
413                size = (this->hasAxis()) ? axis->size.getValue() : 1 ,
414                lbegin = (this->hasAxis()) ? axis->zoom_begin.getValue()-1 : 0 ,
415                lend = (this->hasAxis()) ? axis->zoom_end.getValue()-1 : 0 ;
416
417
418      const int data_dim     = domain->data_dim.getValue() ,
419                data_n_index = domain->data_n_index.getValue() ,
420                data_ibegin  = domain->data_ibegin.getValue() ,
421                data_jbegin  = (data_dim == 2)
422                             ? domain->data_jbegin.getValue() : -1;
423
424      CArray<int,1> data_i_index = domain->data_i_index ;
425      CArray<int,1> data_j_index = domain->data_j_index ;
426
427
428      int indexCount = 0;
429
430      for(int l = 0; l < size ; l++)
431      {
432         for(int n = 0, i = 0, j = 0; n < data_n_index; n++)
433         {
434            int temp_i = data_i_index(n) + data_ibegin,
435                temp_j = (data_dim == 1) ? -1
436                       : data_j_index(n) + data_jbegin;
437            i = (data_dim == 1) ? (temp_i - 1) % ni
438                                : (temp_i - 1) ;
439            j = (data_dim == 1) ? (temp_i - 1) / ni
440                                : (temp_j - 1) ;
441
442            if ((l >=lbegin && l<= lend) &&
443                (i >= 0 && i < ni) &&
444                (j >= 0 && j < nj) && mask(i,j,l))
445               indexCount++ ;
446         }
447      }
448
449      storeIndex[0]  = new CArray<int,1>(indexCount) ;
450      out_i_index[0] = new CArray<int,1>(indexCount) ;
451      out_j_index[0] = new CArray<int,1>(indexCount) ;
452      out_l_index[0] = new CArray<int,1>(indexCount) ;
453
454      storeIndex_client.resize(indexCount) ;
455      out_i_client.resize(indexCount) ;
456      out_j_client.resize(indexCount) ;
457      out_l_client.resize(indexCount) ;
458
459
460      for(int count = 0, indexCount = 0,  l = 0; l < size; l++)
461      {
462         for(int n = 0, i = 0, j = 0; n < data_n_index; n++, count++)
463         {
464            int temp_i = data_i_index(n) + data_ibegin,
465                temp_j = (data_dim == 1) ? -1
466                       : data_j_index(n) + data_jbegin;
467            i = (data_dim == 1) ? (temp_i - 1) % ni
468                                : (temp_i - 1) ;
469            j = (data_dim == 1) ? (temp_i - 1) / ni
470                                : (temp_j - 1) ;
471
472            if ((l >= lbegin && l <= lend) &&
473                (i >= 0 && i < ni) &&
474                (j >= 0 && j < nj) && mask(i,j,l))
475            {
476               (*storeIndex[0])(indexCount) = count ;
477               (*out_l_index[0])(indexCount) = l ;
478               (*out_i_index[0])(indexCount) = i ;
479               (*out_j_index[0])(indexCount) = j ;
480
481               storeIndex_client(indexCount) = count ;
482               out_i_client(indexCount)=i+domain->ibegin_client-1 ;
483               out_j_client(indexCount)=j+domain->jbegin_client-1 ;
484               out_l_client(indexCount)=l-lbegin ;
485               indexCount++ ;
486            }
487         }
488      }
489*/
490//      computeDomConServer();
491//      sendIndex() ;
492
493
494   }
495
496   //----------------------------------------------------------------
497
498   CGrid* CGrid::createGrid(CDomain* domain)
499   {
500      StdString new_id = StdString("__") + domain->getId() + StdString("__") ;
501      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
502
503      std::vector<CDomain*> vecDom(1,domain);
504      grid->setDomainList(vecDom);
505//      grid->domain_ref.setValue(domain->getId());
506      return (grid);
507   }
508
509   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
510   {
511      StdString new_id = StdString("__") + domain->getId() +
512                         StdString("_") + axis->getId() + StdString("__") ;
513      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
514
515      std::vector<CDomain*> vecDom(1,domain);
516      std::vector<CAxis*> vecAxis(1,axis);
517      grid->setDomainList(vecDom);
518      grid->setAxisList(vecAxis);
519//      grid->domain_ref.setValue(domain->getId());
520//      grid->axis_ref.setValue(axis->getId());
521      return (grid);
522   }
523
524   CGrid* CGrid::createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis)
525   {
526      StdString new_id = StdString("__");
527      if (!domains.empty()) for (int i = 0; i < domains.size(); ++i) new_id += domains[i]->getId() + StdString("_");
528      if (!axis.empty()) for (int i = 0; i < axis.size(); ++i) new_id += axis[i]->getId() + StdString("_") ;
529      new_id += StdString("_");
530
531      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
532      grid->setDomainList(domains);
533      grid->setAxisList(axis);
534
535      //By default, domains are always the first ones of a grid
536      if (grid->axisDomainOrder.isEmpty())
537      {
538        int size = domains.size()+axis.size();
539        grid->axisDomainOrder.resize(size);
540        for (int i = 0; i < size; ++i)
541        {
542          if (i < domains.size()) grid->axisDomainOrder(i) = true;
543          else grid->axisDomainOrder(i) = false;
544        }
545      }
546
547      return (grid);
548   }
549
550   CDomainGroup* CGrid::getVirtualDomainGroup() const
551   {
552     return (this->vDomainGroup_);
553   }
554
555   CAxisGroup* CGrid::getVirtualAxisGroup() const
556   {
557     return (this->vAxisGroup_);
558   }
559
560   //----------------------------------------------------------------
561
562   void CGrid::outputField(int rank, const CArray<double, 1>& stored,  CArray<double, 3>& field)
563   {
564      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
565      CArray<int,1>& out_j=*out_j_fromClient[rank] ;
566      CArray<int,1>& out_l=*out_l_fromClient[rank] ;
567
568      for(StdSize n = 0; n < stored.numElements(); n++)
569         field(out_i(n), out_j(n), out_l(n)) = stored(n) ;
570   }
571
572   void CGrid::outputField(int rank, const CArray<double, 1>& stored,  CArray<double, 2>& field)
573   {
574      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
575      CArray<int,1>& out_j=*out_j_fromClient[rank] ;
576
577      for(StdSize n = 0; n < stored.numElements(); n++)
578         field(out_i(n), out_j(n)) = stored(n) ;   }
579
580   //---------------------------------------------------------------
581
582   void CGrid::outputField(int rank,const CArray<double, 1>& stored,  CArray<double, 1>& field)
583   {
584      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
585
586      for(StdSize n = 0; n < stored.numElements(); n++)
587         field(out_i(n)) = stored(n) ;
588   }
589
590   void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field)
591   {
592     CArray<size_t,1>& out_i=*outIndexFromClient[rank];
593     StdSize numElements = stored.numElements();
594     for (StdSize n = 0; n < numElements; ++n)
595     {
596       *(field+out_i(n)) = stored(n);
597     }
598   }
599
600   //----------------------------------------------------------------
601
602
603   void CGrid::storeField_arr
604      (const double * const data, CArray<double, 1>& stored) const
605   {
606      const StdSize size = storeIndex_client.numElements() ;
607
608      stored.resize(size) ;
609      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)] ;
610   }
611
612   //---------------------------------------------------------------
613
614//  void CGrid::sendIndex(void)
615//  {
616//    CContext* context = CContext::getCurrent() ;
617//    CContextClient* client=context->client ;
618//
619//    CEventClient event(getType(),EVENT_ID_INDEX) ;
620//    int rank ;
621//    list<shared_ptr<CMessage> > list_msg ;
622//    list< CArray<int,1>* > list_out_i,list_out_j,list_out_l ;
623//
624//    for(int ns=0;ns<domain->connectedServer.size();ns++)
625//    {
626//       rank=domain->connectedServer[ns] ;
627//
628//       int i,j ;
629//       int nb=0 ;
630//       for(int k=0;k<storeIndex_client.numElements();k++)
631//       {
632//         i=out_i_client(k)- domain->ibegin +1;
633//         j=out_j_client(k)- domain->jbegin +1;
634//         if (domain->mapConnectedServer(i,j)==ns)  nb++ ;
635//       }
636//       CArray<int,1> storeIndex(nb) ;
637//       CArray<int,1> out_i(nb) ;
638//       CArray<int,1> out_j(nb) ;
639//       CArray<int,1> out_l(nb) ;
640//
641//
642//       nb=0 ;
643//       for(int k=0;k<storeIndex_client.numElements();k++)
644//       {
645//         i=out_i_client(k)- domain->ibegin +1 ;
646//         j=out_j_client(k)- domain->jbegin +1 ;
647//         if (domain->mapConnectedServer(i,j)==ns)
648//         {
649//            storeIndex(nb)=k ;
650//            out_i(nb)=domain->i_index(i,j) + domain->ibegin-1;
651//            out_j(nb)=domain->j_index(i,j) + domain->jbegin-1;
652//            out_l(nb)=out_l_client(k) ;
653//            nb++ ;
654//         }
655//       }
656//
657//       storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(storeIndex) )) ;
658//       nbSenders.insert(pair<int,int>(rank,domain->nbSenders[ns])) ;
659//       list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
660//       list_out_i.push_back(new CArray<int,1>(out_i)) ;
661//       list_out_j.push_back(new CArray<int,1>(out_j)) ;
662//       list_out_l.push_back(new CArray<int,1>(out_l)) ;
663//
664//       *list_msg.back()<<getId()<<*list_out_i.back()<<*list_out_j.back()<<*list_out_l.back() ;
665//       event.push(rank,domain->nbSenders[ns],*list_msg.back()) ;
666//    }
667//    client->sendEvent(event) ;
668//
669//    for(list<CArray<int,1>* >::iterator it=list_out_i.begin();it!=list_out_i.end();it++) delete *it ;
670//    for(list<CArray<int,1>* >::iterator it=list_out_j.begin();it!=list_out_j.end();it++) delete *it ;
671//    for(list<CArray<int,1>* >::iterator it=list_out_l.begin();it!=list_out_l.end();it++) delete *it ;
672//
673//  }
674
675  void CGrid::computeDomConServer()
676  {
677    if (!isDomConServerComputed_)
678    {
679      for(int ns=0;ns<domain->connectedServer.size(); ++ns)
680      {
681         int rank=domain->connectedServer[ns] ;
682
683         int i,j ;
684         int nb=0 ;
685         for(int k=0;k<storeIndex_client.numElements();++k)
686         {
687           i=out_i_client(k)- domain->ibegin +1;
688           j=out_j_client(k)- domain->jbegin +1;
689           if (domain->mapConnectedServer(i,j)==ns)  ++nb ;
690         }
691
692         domConnectedServerSide_.insert(std::make_pair(rank, nb));
693      }
694      isDomConServerComputed_ = true;
695    }
696  }
697
698
699  std::map<int, int> CGrid::getDomConServerSide()
700  {
701    return domConnectedServerSide_;
702  }
703
704  void CGrid::sendIndex(void)
705  {
706    CContext* context = CContext::getCurrent() ;
707    CContextClient* client=context->client ;
708
709    CEventClient event(getType(),EVENT_ID_INDEX) ;
710    int rank ;
711    list<shared_ptr<CMessage> > list_msg ;
712    list< CArray<size_t,1>* > listOutIndex;
713
714    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientDistribution_->getGlobalIndexOnServer();
715    const std::map<int, std::vector<int> >& localIndexSendToServer  = clientDistribution_->getLocalIndexSendToServer();
716
717    std::map<int, std::vector<size_t> >::const_iterator iteMap, itbMap, itGlobal;
718    std::map<int, std::vector<int> >::const_iterator itLocal;
719    itbMap = itGlobal = globalIndexOnServer.begin();
720    iteMap = globalIndexOnServer.end();
721    itLocal = localIndexSendToServer.begin();
722
723
724    for (int ns = 0; itGlobal != iteMap; ++itGlobal, ++itLocal, ++ns)
725    {
726      rank = itGlobal->first;
727      int nb = (itGlobal->second).size();
728
729      CArray<size_t, 1> outGlobalIndexOnServer(nb);
730      CArray<int, 1> outLocalIndexToServer(nb);
731      for (int k = 0; k < nb; ++k)
732      {
733        outGlobalIndexOnServer(k) = itGlobal->second.at(k);
734        outLocalIndexToServer(k)  = itLocal->second.at(k);
735      }
736
737      storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(outLocalIndexToServer) ));
738      listOutIndex.push_back(new CArray<size_t,1>(outGlobalIndexOnServer));
739
740      list_msg.push_back(shared_ptr<CMessage>(new CMessage));
741      *list_msg.back()<<getId()<<*listOutIndex.back();
742      event.push(rank, nbSenders[rank], *list_msg.back());
743    }
744    client->sendEvent(event);
745    for(list<CArray<size_t,1>* >::iterator it=listOutIndex.begin();it!=listOutIndex.end();++it) delete *it ;
746
747/*
748    if (!isDomConServerComputed_) computeDomConServer();
749
750    for(int ns=0;ns<domain->connectedServer.size();ns++)
751    {
752       rank=domain->connectedServer[ns] ;
753
754       int nb = domConnectedServerSide_.find(rank)->second;
755       CArray<int,1> storeIndex(nb) ;
756       CArray<int,1> out_i(nb) ;
757       CArray<int,1> out_j(nb) ;
758       CArray<int,1> out_l(nb) ;
759
760       int i, j;
761       nb=0 ;
762       for(int k=0;k<storeIndex_client.numElements();k++)
763       {
764         i=out_i_client(k)- domain->ibegin +1 ;
765         j=out_j_client(k)- domain->jbegin +1 ;
766         if (domain->mapConnectedServer(i,j)==ns)
767         {
768            storeIndex(nb)=k ;
769            out_i(nb)=domain->i_index(i,j) + domain->ibegin-1;
770            out_j(nb)=domain->j_index(i,j) + domain->jbegin-1;
771            out_l(nb)=out_l_client(k) ;
772            nb++ ;
773         }
774       }
775
776       storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(storeIndex) )) ;
777       nbSenders.insert(pair<int,int>(rank,domain->nbSenders[ns])) ;
778       list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
779       list_out_i.push_back(new CArray<int,1>(out_i)) ;
780       list_out_j.push_back(new CArray<int,1>(out_j)) ;
781       list_out_l.push_back(new CArray<int,1>(out_l)) ;
782
783       *list_msg.back()<<getId()<<*list_out_i.back()<<*list_out_j.back()<<*list_out_l.back() ;
784       event.push(rank,domain->nbSenders[ns],*list_msg.back()) ;
785    }
786    client->sendEvent(event) ;
787
788    for(list<CArray<int,1>* >::iterator it=list_out_i.begin();it!=list_out_i.end();it++) delete *it ;
789    for(list<CArray<int,1>* >::iterator it=list_out_j.begin();it!=list_out_j.end();it++) delete *it ;
790    for(list<CArray<int,1>* >::iterator it=list_out_l.begin();it!=list_out_l.end();it++) delete *it ;
791*/
792  }
793
794  void CGrid::recvIndex(CEventServer& event)
795  {
796    list<CEventServer::SSubEvent>::iterator it ;
797    for (it=event.subEvents.begin();it!=event.subEvents.end();++it)
798    {
799      int rank=it->rank;
800      CBufferIn* buffer=it->buffer;
801      string gridId ;
802      *buffer>>gridId ;
803      get(gridId)->recvIndex(rank,*buffer) ;
804    }
805  }
806
807  void CGrid::recvIndex(int rank, CBufferIn& buffer)
808  {
809     CArray<size_t,1> outIndex;
810     buffer>>outIndex;
811     outIndexFromClient.insert(std::pair<int, CArray<size_t,1>* >(rank, new CArray<size_t,1>(outIndex)));
812
813    /*
814    CArray<int,1> out_i ;
815    CArray<int,1> out_j ;
816    CArray<int,1> out_l ;
817
818    buffer>>out_i>>out_j>>out_l ;
819
820    out_i -= domain->zoom_ibegin_srv-1 ;
821    out_j -= domain->zoom_jbegin_srv-1 ;
822
823    out_i_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_i) )) ;
824    out_j_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_j) )) ;
825    out_l_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_l) )) ;
826    */
827  }
828
829   /*!
830   \brief Dispatch event received from client
831      Whenever a message is received in buffer of server, it will be processed depending on
832   its event type. A new event type should be added in the switch list to make sure
833   it processed on server side.
834   \param [in] event: Received message
835   */
836  bool CGrid::dispatchEvent(CEventServer& event)
837  {
838
839    if (SuperClass::dispatchEvent(event)) return true ;
840    else
841    {
842      switch(event.type)
843      {
844        case EVENT_ID_INDEX :
845          recvIndex(event) ;
846          return true ;
847          break ;
848
849         case EVENT_ID_ADD_DOMAIN :
850           recvAddDomain(event) ;
851           return true ;
852           break ;
853
854         case EVENT_ID_ADD_AXIS :
855           recvAddAxis(event) ;
856           return true ;
857           break ;
858        default :
859          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
860                <<"Unknown Event") ;
861          return false ;
862      }
863    }
864  }
865
866   void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const
867   {
868      if ((this->storeIndex.size()-1 ) != storedClient.size())
869         ERROR("void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const",
870                << "[ Expected received field = " << (this->storeIndex.size()-1) << ", "
871                << "[ received fiedl = "    << storedClient.size() << "] "
872                << "Data from clients are missing!") ;
873      storedServer.resize(storeIndex[0]->numElements());
874
875      for (StdSize i = 0, n = 0; i < storedClient.size(); i++)
876         for (StdSize j = 0; j < storedClient[i]->numElements(); j++)
877            storedServer(n++) = (*storedClient[i])(j);
878   }
879
880   void CGrid::outputFieldToServer(CArray<double,1>& fieldIn, int rank, CArray<double,1>& fieldOut)
881   {
882     CArray<int,1>& index = *storeIndex_toSrv[rank] ;
883     int nb=index.numElements() ;
884     fieldOut.resize(nb) ;
885
886     for(int k=0;k<nb;k++) fieldOut(k)=fieldIn(index(k)) ;
887    }
888   ///---------------------------------------------------------------
889
890   CDomain* CGrid::addDomain(const std::string& id)
891   {
892     return vDomainGroup_->createChild(id) ;
893   }
894
895   CAxis* CGrid::addAxis(const std::string& id)
896   {
897     return vAxisGroup_->createChild(id) ;
898   }
899
900   //! Change virtual field group to a new one
901   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
902   {
903      this->vDomainGroup_ = newVDomainGroup;
904   }
905
906   //! Change virtual variable group to new one
907   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
908   {
909      this->vAxisGroup_ = newVAxisGroup;
910   }
911
912   //----------------------------------------------------------------
913   //! Create virtual field group, which is done normally on initializing file
914   void CGrid::setVirtualDomainGroup(void)
915   {
916      this->setVirtualDomainGroup(CDomainGroup::create());
917   }
918
919   //! Create virtual variable group, which is done normally on initializing file
920   void CGrid::setVirtualAxisGroup(void)
921   {
922      this->setVirtualAxisGroup(CAxisGroup::create());
923   }
924
925   /*!
926   \brief Send a message to create a domain on server side
927   \param[in] id String identity of domain that will be created on server
928   */
929   void CGrid::sendAddDomain(const string& id)
930   {
931    CContext* context=CContext::getCurrent() ;
932
933    if (! context->hasServer )
934    {
935       CContextClient* client=context->client ;
936
937       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN) ;
938       if (client->isServerLeader())
939       {
940         CMessage msg ;
941         msg<<this->getId() ;
942         msg<<id ;
943         event.push(client->getServerLeader(),1,msg) ;
944         client->sendEvent(event) ;
945       }
946       else client->sendEvent(event) ;
947    }
948   }
949
950   /*!
951   \brief Send a message to create an axis on server side
952   \param[in] id String identity of axis that will be created on server
953   */
954   void CGrid::sendAddAxis(const string& id)
955   {
956    CContext* context=CContext::getCurrent() ;
957
958    if (! context->hasServer )
959    {
960       CContextClient* client=context->client ;
961
962       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS) ;
963       if (client->isServerLeader())
964       {
965         CMessage msg ;
966         msg<<this->getId() ;
967         msg<<id ;
968         event.push(client->getServerLeader(),1,msg) ;
969         client->sendEvent(event) ;
970       }
971       else client->sendEvent(event) ;
972    }
973   }
974
975   /*!
976   \brief Receive a message annoucing the creation of a domain on server side
977   \param[in] event Received event
978   */
979   void CGrid::recvAddDomain(CEventServer& event)
980   {
981
982      CBufferIn* buffer=event.subEvents.begin()->buffer;
983      string id;
984      *buffer>>id ;
985      get(id)->recvAddDomain(*buffer) ;
986   }
987
988   /*!
989   \brief Receive a message annoucing the creation of a domain on server side
990   \param[in] buffer Buffer containing message
991   */
992   void CGrid::recvAddDomain(CBufferIn& buffer)
993   {
994      string id ;
995      buffer>>id ;
996      addDomain(id) ;
997   }
998
999   /*!
1000   \brief Receive a message annoucing the creation of an axis on server side
1001   \param[in] event Received event
1002   */
1003   void CGrid::recvAddAxis(CEventServer& event)
1004   {
1005
1006      CBufferIn* buffer=event.subEvents.begin()->buffer;
1007      string id;
1008      *buffer>>id ;
1009      get(id)->recvAddAxis(*buffer) ;
1010   }
1011
1012   /*!
1013   \brief Receive a message annoucing the creation of an axis on server side
1014   \param[in] buffer Buffer containing message
1015   */
1016   void CGrid::recvAddAxis(CBufferIn& buffer)
1017   {
1018      string id ;
1019      buffer>>id ;
1020      addAxis(id) ;
1021   }
1022
1023  /*!
1024  \brief Solve domain and axis references
1025  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
1026  all attributes from their parents, they should be processed with this function
1027  \param[in] apply inherit all attributes of parents (true)
1028  */
1029  void CGrid::solveDomainAxisRefInheritance(bool apply)
1030  {
1031    CContext* context = CContext::getCurrent();
1032    unsigned int vecSize, i;
1033    std::vector<StdString>::iterator it, itE;
1034    setDomainList();
1035    it = domList_.begin(); itE = domList_.end();
1036    for (; it != itE; ++it)
1037    {
1038      CDomain* pDom = CDomain::get(*it);
1039      if (context->hasClient)
1040      {
1041        pDom->solveRefInheritance(apply);
1042        pDom->solveBaseReference();
1043        if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
1044          pDom->name.setValue(pDom->getBaseDomainReference()->getId());
1045      }
1046    }
1047
1048    setAxisList();
1049    it = axisList_.begin(); itE = axisList_.end();
1050    for (; it != itE; ++it)
1051    {
1052      CAxis* pAxis = CAxis::get(*it);
1053      if (context->hasClient)
1054      {
1055        pAxis->solveRefInheritance(apply);
1056        pAxis->solveBaseReference();
1057        if ((!pAxis->axis_ref.isEmpty()) && (pAxis->name.isEmpty()))
1058          pAxis->name.setValue(pAxis->getBaseAxisReference()->getId());
1059      }
1060    }
1061  }
1062
1063  /*!
1064  \brief Get the list of domain pointers
1065  \return list of domain pointers
1066  */
1067  std::vector<CDomain*> CGrid::getDomains()
1068  {
1069    std::vector<CDomain*> domList;
1070    if (!domList_.empty())
1071    {
1072      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
1073    }
1074    return domList;
1075  }
1076
1077  /*!
1078  \brief Get the list of  axis pointers
1079  \return list of axis pointers
1080  */
1081  std::vector<CAxis*> CGrid::getAxis()
1082  {
1083    std::vector<CAxis*> aList;
1084    if (!axisList_.empty())
1085      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
1086
1087    return aList;
1088  }
1089
1090  /*!
1091  \brief Set domain(s) of a grid from a list
1092  \param[in] domains list of domains
1093  */
1094  void CGrid::setDomainList(const std::vector<CDomain*> domains)
1095  {
1096    if (isDomListSet) return;
1097    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1098    if (!domains.empty() && domList.empty()) domList = domains;
1099    if (!domList.empty())
1100    {
1101      int sizeDom = domList.size();
1102      domList_.resize(sizeDom);
1103      for (int i = 0 ; i < sizeDom; ++i)
1104      {
1105        domList_[i] = domList[i]->getId();
1106      }
1107      isDomListSet = true;
1108    }
1109
1110  }
1111
1112  /*!
1113  \brief Set axis(s) of a grid from a list
1114  \param[in] axis list of axis
1115  */
1116  void CGrid::setAxisList(const std::vector<CAxis*> axis)
1117  {
1118    if (isAxisListSet) return;
1119    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1120    if (!axis.empty() && aList.empty()) aList = axis;
1121    if (!aList.empty())
1122    {
1123      int sizeAxis = aList.size();
1124      axisList_.resize(sizeAxis);
1125      for (int i = 0; i < sizeAxis; ++i)
1126      {
1127        axisList_[i] = aList[i]->getId();
1128      }
1129      isAxisListSet = true;
1130    }
1131  }
1132
1133  /*!
1134  \brief Get list of id of domains
1135  \return id list of domains
1136  */
1137  std::vector<StdString> CGrid::getDomainList()
1138  {
1139    setDomainList();
1140    return domList_;
1141  }
1142
1143  /*!
1144  \brief Get list of id of axis
1145  \return id list of axis
1146  */
1147  std::vector<StdString> CGrid::getAxisList()
1148  {
1149    setAxisList();
1150    return axisList_;
1151  }
1152
1153  void CGrid::sendAllDomains()
1154  {
1155    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
1156    int dSize = domList.size();
1157    for (int i = 0; i < dSize; ++i)
1158    {
1159      sendAddDomain(domList[i]->getId());
1160      domList[i]->sendAllAttributesToServer();
1161    }
1162  }
1163
1164  void CGrid::sendAllAxis()
1165  {
1166    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
1167    int aSize = aList.size();
1168
1169    for (int i = 0; i < aSize; ++i)
1170    {
1171      sendAddAxis(aList[i]->getId());
1172      aList[i]->sendAllAttributesToServer();
1173    }
1174  }
1175
1176  void CGrid::parse(xml::CXMLNode & node)
1177  {
1178    SuperClass::parse(node);
1179    // List order of axis and domain in a grid, if there is a domain, it will take value 1 (true), axis 0 (false)
1180//    std::vector<int> axisOrder;
1181    std::vector<bool> order;
1182
1183    if (node.goToChildElement())
1184    {
1185      StdString domainName("domain");
1186      StdString axisName("axis");
1187      do
1188      {
1189        if (node.getElementName() == domainName) {
1190          order.push_back(true);
1191          this->getVirtualDomainGroup()->parseChild(node);
1192        }
1193        if (node.getElementName() == axisName) {
1194          order.push_back(false);
1195          this->getVirtualAxisGroup()->parseChild(node);
1196        }
1197      } while (node.goToNextElement()) ;
1198      node.goToParentElement();
1199    }
1200
1201    if (!order.empty())
1202    {
1203      int sizeOrd = order.size();
1204      axisDomainOrder.resize(sizeOrd);
1205      for (int i = 0; i < sizeOrd; ++i)
1206      {
1207        axisDomainOrder(i) = order[i];
1208      }
1209    }
1210
1211    setDomainList();
1212    setAxisList();
1213   }
1214
1215} // namespace xios
Note: See TracBrowser for help on using the repository browser.