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

Last change on this file since 369 was 369, checked in by ymipsl, 12 years ago

Major Update

  • redesign Type and attribute manipulation
  • add enumerate type and attribute
  • use blitz class array instead of boost class array

YM

File size: 17.0 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), axis(), domain()
22      , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1)
23   { /* Ne rien faire de plus */ }
24
25   CGrid::CGrid(const StdString & id)
26      : CObjectTemplate<CGrid>(id), CGridAttributes()
27      , withAxis(false), isChecked(false), axis(), domain()
28      , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1)
29   { /* Ne rien faire de plus */ }
30
31   CGrid::~CGrid(void)
32   { 
33 //     this->axis.reset() ;
34//      this->domain.reset() ;
35    deque< CArray<int, 1>* >::iterator it ;
36   
37    for(deque< CArray<int,1>* >::iterator it=storeIndex.begin(); it!=storeIndex.end();it++)  delete *it ;
38    for(deque< CArray<int,1>* >::iterator it=out_i_index.begin();it!=out_i_index.end();it++) delete *it ;
39    for(deque< CArray<int,1>* >::iterator it=out_j_index.begin();it!=out_j_index.end();it++) delete *it ;
40    for(deque< CArray<int,1>* >::iterator it=out_l_index.begin();it!=out_l_index.end();it++) delete *it ;
41
42    for(map<int,CArray<int,1>* >::iterator it=out_i_fromClient.begin();it!=out_i_fromClient.end();it++) delete it->second ;
43    for(map<int,CArray<int,1>* >::iterator it=out_j_fromClient.begin();it!=out_j_fromClient.end();it++) delete it->second ;
44    for(map<int,CArray<int,1>* >::iterator it=out_l_fromClient.begin();it!=out_l_fromClient.end();it++) delete it->second ;
45
46   }
47
48   ///---------------------------------------------------------------
49
50   StdString CGrid::GetName(void)    { return (StdString("grid")); }
51   StdString CGrid::GetDefName(void) { return (CGrid::GetName()); }
52   ENodeType CGrid::GetType(void)    { return (eGrid); }
53
54   //----------------------------------------------------------------
55
56   const std::deque< CArray<int,1>* > & CGrid::getStoreIndex(void) const
57   { 
58      return (this->storeIndex );
59   }
60
61   //---------------------------------------------------------------
62
63   const std::deque< CArray<int,1>* > & CGrid::getOutIIndex(void)  const
64   { 
65      return (this->out_i_index ); 
66   }
67
68   //---------------------------------------------------------------
69
70   const std::deque< CArray<int,1>* > & CGrid::getOutJIndex(void)  const
71   { 
72      return (this->out_j_index ); 
73   }
74
75   //---------------------------------------------------------------
76
77   const std::deque< CArray<int,1>* > & CGrid::getOutLIndex(void)  const
78   { 
79      return (this->out_l_index ); 
80   }
81
82   //---------------------------------------------------------------
83
84   const CAxis*   CGrid::getRelAxis  (void) const
85   { 
86      return (this->axis ); 
87   }
88
89   //---------------------------------------------------------------
90
91   const CDomain* CGrid::getRelDomain(void) const
92   { 
93      return (this->domain ); 
94   }
95
96   //---------------------------------------------------------------
97
98   bool CGrid::hasAxis(void) const 
99   { 
100      return (this->withAxis); 
101   }
102
103   //---------------------------------------------------------------
104
105   StdSize CGrid::getDimension(void) const
106   {
107      return ((this->withAxis)?3:2);
108   }
109
110   //---------------------------------------------------------------
111
112/*
113   std::vector<StdSize> CGrid::getLocalShape(void) const
114   {
115      std::vector<StdSize> retvalue;
116      retvalue.push_back(domain->zoom_ni_loc.getValue());
117      retvalue.push_back(domain->zoom_nj_loc.getValue());
118      if (this->withAxis)
119         retvalue.push_back(this->axis->zoom_size.getValue());
120      return (retvalue);
121   }
122*/
123   //---------------------------------------------------------------
124   
125/*
126   StdSize CGrid::getLocalSize(void) const
127   {
128      StdSize retvalue = 1;
129      std::vector<StdSize> shape_ = this->getLocalShape();
130      for (StdSize s = 0; s < shape_.size(); s++)
131         retvalue *= shape_[s];
132      return (retvalue);
133   }
134*/
135   //---------------------------------------------------------------
136/*
137   std::vector<StdSize> CGrid::getGlobalShape(void) const
138   {
139      std::vector<StdSize> retvalue;
140      retvalue.push_back(domain->ni.getValue());
141      retvalue.push_back(domain->nj.getValue());
142      if (this->withAxis)
143         retvalue.push_back(this->axis->size.getValue());
144      return (retvalue);
145   }
146*/
147   //---------------------------------------------------------------
148
149/*   
150   StdSize CGrid::getGlobalSize(void) const
151   {
152      StdSize retvalue = 1;
153      std::vector<StdSize> shape_ = this->getGlobalShape();
154      for (StdSize s = 0; s < shape_.size(); s++)
155         retvalue *= shape_[s];
156      return (retvalue);
157   }
158*/
159   StdSize CGrid::getDataSize(void) const
160   {
161      StdSize retvalue=domain->data_ni.getValue() ;
162      if (domain->data_dim.getValue()==2) retvalue*=domain->data_nj.getValue() ;
163      if (this->withAxis) retvalue*=this->axis->size.getValue() ;
164
165      return (retvalue);
166   }
167
168   //---------------------------------------------------------------
169
170   void CGrid::solveReference(void)
171   {
172      if (this->isChecked) return;
173      CContext* context = CContext::getCurrent() ;
174      CContextClient* client=context->client ;
175     
176      this->solveDomainRef() ;
177      this->solveAxisRef() ;
178      if (context->hasClient)
179      {
180         
181         this->computeIndex() ;
182
183         this->storeIndex.push_front(new CArray<int,1>() );
184         this->out_i_index.push_front(new CArray<int,1>());
185         this->out_j_index.push_front(new CArray<int,1>());
186         this->out_l_index.push_front(new CArray<int,1>());
187      }
188//      this->computeIndexServer();
189      this->isChecked = true;
190   }
191
192   //---------------------------------------------------------------
193
194   void CGrid::solveDomainRef(void)
195   {
196      if (!domain_ref.isEmpty())
197      {
198         if (CDomain::has(domain_ref.getValue()))
199         {
200            this->domain = CDomain::get(domain_ref.getValue()) ;
201            domain->checkAttributes() ;
202         }
203         else ERROR("CGrid::solveDomainRef(void)",
204                     << "Référence au domaine incorrecte") ;
205      }
206      else ERROR("CGrid::solveDomainRef(void)",
207                  << "Domaine non défini") ;
208   }
209
210   //---------------------------------------------------------------
211
212   void CGrid::solveAxisRef(void)
213   {
214      if (!axis_ref.isEmpty())
215      {
216         this->withAxis = true ;
217         if (CAxis::get(axis_ref.getValue()))
218         {
219            this->axis = CAxis::get(axis_ref.getValue()) ;
220            axis->checkAttributes() ;
221         }
222         else ERROR("CGrid::solveAxisRef(void)",
223                    << "Référence a l'axe incorrecte") ;
224      }
225      else withAxis = false ;
226   }
227
228   //---------------------------------------------------------------
229
230   void CGrid::computeIndex(void)
231   {   
232   
233      const int ni   = domain->ni.getValue() ,
234                nj   = domain->nj.getValue() ,
235                size = (this->hasAxis()) ? axis->size.getValue() : 1 ,
236                lbegin = (this->hasAxis()) ? axis->zoom_begin.getValue()-1 : 0 ,
237                lend = (this->hasAxis()) ? axis->zoom_end.getValue()-1 : 0 ;
238
239
240      const int data_dim     = domain->data_dim.getValue() ,
241                data_n_index = domain->data_n_index.getValue() ,
242                data_ibegin  = domain->data_ibegin.getValue() ,
243                data_jbegin  = (data_dim == 2)
244                             ? domain->data_jbegin.getValue() : -1;
245
246      CArray<int,1> data_i_index = domain->data_i_index ;
247      CArray<int,1> data_j_index = domain->data_j_index ;
248     
249
250      CArray<bool,2>& mask = domain->mask ;
251      CArray<int,2>& local_mask = domain->local_mask ;
252     
253
254      int indexCount = 0;
255
256      for(int l = 0; l < size ; l++)
257      {
258         for(int n = 0, i = 0, j = 0; n < data_n_index; n++)
259         {
260            int temp_i = data_i_index(n) + data_ibegin,
261                temp_j = (data_dim == 1) ? -1
262                       : data_j_index(n) + data_jbegin;
263            i = (data_dim == 1) ? (temp_i - 1) % ni
264                                : (temp_i - 1) ;
265            j = (data_dim == 1) ? (temp_i - 1) / ni
266                                : (temp_j - 1) ;
267
268            if ((l >=lbegin && l<= lend) &&
269                (i >= 0 && i < ni) &&
270                (j >= 0 && j < nj) && mask(i,j))
271               indexCount++ ;
272         }
273      }
274     
275      storeIndex[0]  = new CArray<int,1>(indexCount) ;
276      out_i_index[0] = new CArray<int,1>(indexCount) ;
277      out_j_index[0] = new CArray<int,1>(indexCount) ;
278      out_l_index[0] = new CArray<int,1>(indexCount) ;
279     
280      storeIndex_client.resize(indexCount) ;
281      out_i_client.resize(indexCount) ;
282      out_j_client.resize(indexCount) ;
283      out_l_client.resize(indexCount) ;
284     
285     
286      for(int count = 0, indexCount = 0,  l = 0; l < size; l++)
287      {
288         for(int n = 0, i = 0, j = 0; n < data_n_index; n++, count++)
289         {
290            int temp_i = data_i_index(n) + data_ibegin,
291                temp_j = (data_dim == 1) ? -1
292                       : data_j_index(n) + data_jbegin;
293            i = (data_dim == 1) ? (temp_i - 1) % ni
294                                : (temp_i - 1) ;
295            j = (data_dim == 1) ? (temp_i - 1) / ni
296                                : (temp_j - 1) ;
297
298            if ((l >= lbegin && l <= lend) &&
299                (i >= 0 && i < ni) &&
300                (j >= 0 && j < nj) && mask(i,j))
301            {
302               (*storeIndex[0])(indexCount) = count ;
303               (*out_l_index[0])(indexCount) = l ;
304               (*out_i_index[0])(indexCount) = i ;
305               (*out_j_index[0])(indexCount) = j ;
306               
307               storeIndex_client(indexCount) = count ;
308               out_i_client(indexCount)=i+domain->ibegin_client-1 ;
309               out_j_client(indexCount)=j+domain->jbegin_client-1 ;
310               out_l_client(indexCount)=l-lbegin ;
311               indexCount++ ;
312            }
313         }
314      }
315      sendIndex() ;
316
317
318   }
319
320   //----------------------------------------------------------------
321
322   CGrid* CGrid::createGrid(CDomain* domain)
323   {
324      StdString new_id = StdString("__") + domain->getId() + StdString("__") ;
325      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
326      grid->domain_ref.setValue(domain->getId());
327      return (grid);
328   }
329
330   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
331   {
332      StdString new_id = StdString("__") + domain->getId() +
333                         StdString("_") + axis->getId() + StdString("__") ;
334      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
335      grid->domain_ref.setValue(domain->getId());
336      grid->axis_ref.setValue(axis->getId());
337      return (grid);
338   }
339
340   //----------------------------------------------------------------
341
342   void CGrid::outputField(int rank, const CArray<double, 1>& stored,  CArray<double, 3>& field) 
343   {
344      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
345      CArray<int,1>& out_j=*out_j_fromClient[rank] ;
346      CArray<int,1>& out_l=*out_l_fromClient[rank] ;
347     
348      for(StdSize n = 0; n < stored.numElements(); n++)
349         field(out_i(n), out_j(n), out_l(n)) = stored(n) ;
350   }
351
352   void CGrid::outputField(int rank, const CArray<double, 1>& stored,  CArray<double, 2>& field) 
353   {
354      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
355      CArray<int,1>& out_j=*out_j_fromClient[rank] ;
356     
357      for(StdSize n = 0; n < stored.numElements(); n++)
358         field(out_i(n), out_j(n)) = stored(n) ;   }
359
360   //---------------------------------------------------------------
361
362   void CGrid::outputField(int rank,const CArray<double, 1>& stored,  CArray<double, 1>& field)
363   {
364      CArray<int,1>& out_i=*out_i_fromClient[rank] ;
365 
366      for(StdSize n = 0; n < stored.numElements(); n++)
367         field(out_i(n)) = stored(n) ;
368   }
369
370   //----------------------------------------------------------------
371 
372
373   void CGrid::storeField_arr
374      (const double * const data, CArray<double, 1>& stored) const
375   {
376      const StdSize size = storeIndex_client.numElements() ;
377
378      stored.resize(size) ;
379      for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)] ;
380   }
381   
382   //---------------------------------------------------------------
383
384  void CGrid::sendIndex(void)
385  {
386    CContext* context = CContext::getCurrent() ;
387    CContextClient* client=context->client ;
388   
389    CEventClient event(getType(),EVENT_ID_INDEX) ;
390    int rank ;
391    list<shared_ptr<CMessage> > list_msg ;
392    list< CArray<int,1>* > list_out_i,list_out_j,list_out_l ;
393     
394    for(int ns=0;ns<domain->connectedServer.size();ns++)
395    {
396       rank=domain->connectedServer[ns] ;
397       int ib=domain->ib_srv[ns] ;
398       int ie=domain->ie_srv[ns] ;
399       int jb=domain->jb_srv[ns] ;
400       int je=domain->je_srv[ns] ;
401       
402       int i,j ;
403       int nb=0 ;
404       for(int k=0;k<storeIndex_client.numElements();k++)
405       {
406         i=out_i_client(k) ;
407         j=out_j_client(k) ;
408         if (i>=ib-1 && i<=ie-1 && j>=jb-1 && j<=je-1) nb++ ; 
409       }
410       
411       CArray<int,1> storeIndex(nb) ;
412       CArray<int,1> out_i(nb) ;
413       CArray<int,1> out_j(nb) ;
414       CArray<int,1> out_l(nb) ;
415 
416       
417       nb=0 ;
418       for(int k=0;k<storeIndex_client.numElements();k++)
419       {
420         i=out_i_client(k) ;
421         j=out_j_client(k) ;
422         if (i>=ib-1 && i<=ie-1 && j>=jb-1 && j<=je-1) 
423         {
424            storeIndex(nb)=k ;
425            out_i(nb)=out_i_client(k) ;
426            out_j(nb)=out_j_client(k) ;
427            out_l(nb)=out_l_client(k) ;
428            nb++ ;
429         }
430       }
431       
432       storeIndex_toSrv.insert( pair<int,CArray<int,1>* >(rank,new CArray<int,1>(storeIndex) )) ;
433       nbSenders.insert(pair<int,int>(rank,domain->nbSenders[ns])) ;
434       list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ;
435       list_out_i.push_back(new CArray<int,1>(out_i)) ;
436       list_out_j.push_back(new CArray<int,1>(out_j)) ;
437       list_out_l.push_back(new CArray<int,1>(out_l)) ;
438
439       *list_msg.back()<<getId()<<*list_out_i.back()<<*list_out_j.back()<<*list_out_l.back() ;
440       event.push(rank,domain->nbSenders[ns],*list_msg.back()) ;
441    }
442    client->sendEvent(event) ;
443
444    for(list<CArray<int,1>* >::iterator it=list_out_i.begin();it!=list_out_i.end();it++) delete *it ;
445    for(list<CArray<int,1>* >::iterator it=list_out_j.begin();it!=list_out_j.end();it++) delete *it ;
446    for(list<CArray<int,1>* >::iterator it=list_out_l.begin();it!=list_out_l.end();it++) delete *it ;
447   
448  }
449 
450  void CGrid::recvIndex(CEventServer& event)
451  {
452    list<CEventServer::SSubEvent>::iterator it ;
453    for (it=event.subEvents.begin();it!=event.subEvents.end();++it)
454    {
455      int rank=it->rank;
456      CBufferIn* buffer=it->buffer;
457      string domainId ;
458      *buffer>>domainId ;
459      get(domainId)->recvIndex(rank,*buffer) ;
460    }
461  }
462 
463  void CGrid::recvIndex(int rank, CBufferIn& buffer)
464  {
465    CArray<int,1> out_i ;
466    CArray<int,1> out_j ;
467    CArray<int,1> out_l ;
468   
469    buffer>>out_i>>out_j>>out_l ;
470   
471    out_i -= domain->zoom_ibegin_srv-1 ;
472    out_j -= domain->zoom_jbegin_srv-1 ;
473   
474    out_i_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_i) )) ;
475    out_j_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_j) )) ;
476    out_l_fromClient.insert(pair< int,CArray<int,1>* >(rank,new CArray<int,1>(out_l) )) ;
477  }
478
479  bool CGrid::dispatchEvent(CEventServer& event)
480  {
481     
482    if (SuperClass::dispatchEvent(event)) return true ;
483    else
484    {
485      switch(event.type)
486      {
487        case EVENT_ID_INDEX :
488          recvIndex(event) ;
489          return true ;
490          break ;
491 
492        default :
493          ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
494                <<"Unknown Event") ;
495          return false ;
496      }
497    }
498  }
499
500   void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const
501   {
502      if ((this->storeIndex.size()-1 ) != storedClient.size())
503         ERROR("void CGrid::inputFieldServer(const std::deque< CArray<double, 1>* > storedClient, CArray<double, 1>&  storedServer) const",
504                << "[ Nombre de tableau attendu = " << (this->storeIndex.size()-1) << ", "
505                << "[ Nombre de tableau reçu = "    << storedClient.size() << "] "
506                << "Les données d'un client sont manquantes !") ;
507      storedServer.resize(storeIndex[0]->numElements());
508         
509      for (StdSize i = 0, n = 0; i < storedClient.size(); i++)
510         for (StdSize j = 0; j < storedClient[i]->numElements(); j++)
511            storedServer(n++) = (*storedClient[i])(j);
512   }
513
514   void CGrid::outputFieldToServer(CArray<double,1>& fieldIn, int rank, CArray<double,1>& fieldOut)
515   {
516     CArray<int,1>& index = *storeIndex_toSrv[rank] ;
517     int nb=index.numElements() ;
518     fieldOut.resize(nb) ;
519     
520     for(int k=0;k<nb;k++) fieldOut(k)=fieldIn(index(k)) ;
521    }
522   ///---------------------------------------------------------------
523
524} // namespace xios
Note: See TracBrowser for help on using the repository browser.