source: XIOS/trunk/src/node/domain.cpp @ 631

Last change on this file since 631 was 631, checked in by mhnguyen, 9 years ago

Implementing zooming on a domain

+) Add algorithm to do zooming on a domain
+) Remove some redundant codes

Test
+) On Curie
+) test_complete and test_client 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: 39.1 KB
Line 
1#include "domain.hpp"
2
3#include "attribute_template.hpp"
4#include "object_template.hpp"
5#include "group_template.hpp"
6
7#include "xios_spl.hpp"
8#include "event_client.hpp"
9#include "event_server.hpp"
10#include "buffer_in.hpp"
11#include "message.hpp"
12#include "type.hpp"
13#include "context.hpp"
14#include "context_client.hpp"
15#include "array_new.hpp"
16#include "server_distribution_description.hpp"
17#include "client_server_mapping_distributed.hpp"
18#include "zoom_domain.hpp"
19
20namespace xios {
21
22   /// ////////////////////// Définitions ////////////////////// ///
23
24   CDomain::CDomain(void)
25      : CObjectTemplate<CDomain>(), CDomainAttributes()
26      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
27      , hasBounds(false), hasArea(false), isDistributed_(false)
28   { /* Ne rien faire de plus */ }
29
30   CDomain::CDomain(const StdString & id)
31      : CObjectTemplate<CDomain>(id), CDomainAttributes()
32      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
33      , hasBounds(false), hasArea(false), isDistributed_(false)
34         { /* Ne rien faire de plus */ }
35
36   CDomain::~CDomain(void)
37   {
38   }
39
40   ///---------------------------------------------------------------
41
42   CDomain* CDomain::createDomain()
43   {
44     CDomain* domain = CDomainGroup::get("domain_definition")->createChild();
45     return domain;
46   }
47
48   void CDomain::duplicateAttributes(CDomain* domain)
49   {
50     domain->setAttributes(this);
51   }
52
53   const std::set<StdString> & CDomain::getRelFiles(void) const
54   {
55      return (this->relFiles);
56   }
57
58   //----------------------------------------------------------------
59
60   bool CDomain::hasZoom(void) const
61   {
62      return ((this->zoom_ni.getValue() != this->ni_glo.getValue()) &&
63              (this->zoom_nj.getValue() != this->nj_glo.getValue()));
64   }
65
66   //----------------------------------------------------------------
67
68   bool CDomain::isEmpty(void) const
69   {
70      return ((this->zoom_ni_srv == 0) ||
71              (this->zoom_nj_srv == 0));
72   }
73
74   //----------------------------------------------------------------
75
76   bool CDomain::IsWritten(const StdString & filename) const
77   {
78      return (this->relFiles.find(filename) != this->relFiles.end());
79   }
80
81   //----------------------------------------------------------------
82
83   bool CDomain::isDistributed(void) const
84   {
85      return isDistributed_;
86   }
87
88   //----------------------------------------------------------------
89
90   void CDomain::addRelFile(const StdString & filename)
91   {
92      this->relFiles.insert(filename);
93   }
94
95
96   StdString CDomain::GetName(void)   { return (StdString("domain")); }
97   StdString CDomain::GetDefName(void){ return (CDomain::GetName()); }
98   ENodeType CDomain::GetType(void)   { return (eDomain); }
99
100   //----------------------------------------------------------------
101
102   void CDomain::checkDomain(void)
103   {
104      if (!type.isEmpty() && type==type_attr::unstructured)
105      {
106         if (ni_glo.isEmpty() || ni_glo <= 0 )
107         {
108            ERROR("CDomain::checkAttributes(void)",
109               << "[ Id = " << this->getId() << " ] "
110               << "The global domain is badly defined,"
111               << " check the \'ni_glo\'  value !")
112         }
113         nj_glo=ni_glo ;
114         ni_glo=1 ;
115         if (!ni.isEmpty()) nj=ni ;
116         if (!ibegin.isEmpty()) jbegin=ibegin ;
117         if (!iend.isEmpty()) jend=iend ;
118         if (!i_index.isEmpty())
119         {
120          j_index.resize(1,nj) ;
121          for(int i=0;i<ni;i++) j_index(0,i)=i_index(i,0) ;
122          i_index.resize(1,nj) ;
123          for(int j=0;j<nj;j++) i_index(0,j)=0 ;
124         }
125
126         if (!mask.isEmpty())
127         {
128          CArray<int,2> mask_tmp(nj,1) ;
129          mask_tmp = mask ;
130          mask.resize(1,nj) ;
131          for(int j=0;j<nj;j++) mask(0,j)=mask_tmp(j,0) ;
132         }
133
134         if (!area.isEmpty())
135           area.transposeSelf(1, 0);
136
137         ni=1 ;
138         ibegin=0 ;
139         iend=0 ;
140
141      }
142      else if ((ni_glo.isEmpty() || ni_glo.getValue() <= 0 ) ||
143          (nj_glo.isEmpty() || nj_glo.getValue() <= 0 ))
144      {
145         ERROR("CDomain::checkAttributes(void)",
146               << "[ Id = " << this->getId() << " ] "
147               << "The global domain is badly defined,"
148               << " check the \'ni_glo\' et \'nj_glo\' values !")
149      }
150
151      isDistributed_ = !ibegin.isEmpty() || !iend.isEmpty() || !ni.isEmpty() || !jbegin.isEmpty() || !jend.isEmpty() || !nj.isEmpty();
152
153      checkLocalIDomain();
154      checkLocalJDomain();
155
156      ibegin_client = ibegin; iend_client = iend; ni_client = ni;
157      jbegin_client = jbegin; jend_client = jend; nj_client = nj;
158
159      if (i_index.isEmpty())
160      {
161        i_index.resize(ni,nj);
162        for (int j = 0; j < nj; j++)
163          for (int i = 0; i < ni; i++) i_index(i,j) = i;
164      }
165
166      if (j_index.isEmpty())
167      {
168        j_index.resize(ni,nj);
169        for (int j = 0; j < nj; j++)
170          for (int i = 0; i < ni; i++) j_index(i,j) = j;
171      }
172   }
173
174   //----------------------------------------------------------------
175
176   void CDomain::checkLocalIDomain(void)
177   {
178      if (!ni.isEmpty() && !ibegin.isEmpty() && iend.isEmpty())
179        iend.setValue(ibegin.getValue() + ni.getValue() - 1);
180      else if (!ni.isEmpty() && !iend.isEmpty() && ibegin.isEmpty())
181        ibegin.setValue(iend.getValue() - ni.getValue()  + 1);
182      else if (!ibegin.isEmpty() && !iend.isEmpty() && ni.isEmpty())
183        ni.setValue(iend.getValue() - ibegin.getValue() + 1);
184      else if (!ibegin.isEmpty() && !iend.isEmpty() && !ni.isEmpty())
185      {
186        if (iend.getValue() != ibegin.getValue() + ni.getValue() - 1)
187          ERROR("CDomain::checkLocalIDomain(void)",
188                << "[ Id = " << this->getId() << " ] "
189                << "The local domain is wrongly defined,"
190                << " iend is different from (ibegin + ni - 1)");
191      }
192      else if (ibegin.isEmpty() && iend.isEmpty() && ni.isEmpty())
193      {
194        ibegin = 0;
195        iend = ni_glo - 1;
196        ni = ni_glo;
197      }
198      else
199      {
200        ERROR("CDomain::checkLocalIDomain(void)",
201              << "[ Id = " << this->getId() << " ] "
202              << "The local domain is wrongly defined,"
203              << " defining just one attribute among 'ibegin', 'iend' or 'ni' is invalid");
204      }
205
206      if (ni.getValue() < 0 || ibegin.getValue() > iend.getValue() ||
207          ibegin.getValue() < 0 || iend.getValue() > (ni_glo.getValue() - 1))
208      {
209        ERROR("CDomain::checkLocalIDomain(void)",
210              << "[ Id = " << this->getId() << " ] "
211              << "The local domain is wrongly defined,"
212              << " check the attributes 'ni_glo', 'ni', 'ibegin' and 'iend'");
213      }
214   }
215
216   //----------------------------------------------------------------
217
218   void CDomain::checkLocalJDomain(void)
219   {
220      if (!nj.isEmpty() && !jbegin.isEmpty() && jend.isEmpty())
221        jend.setValue(jbegin.getValue() + nj.getValue() - 1);
222      else if (!nj.isEmpty() && !jend.isEmpty() && jbegin.isEmpty())
223        jbegin.setValue(jend.getValue() - nj.getValue() + 1);
224      else if (!jbegin.isEmpty() && !jend.isEmpty() && nj.isEmpty())
225        nj.setValue(jend.getValue() - jbegin.getValue() + 1);
226      else if (!jbegin.isEmpty() && !jend.isEmpty() && !nj.isEmpty())
227      {
228        if (jend.getValue() != jbegin.getValue() + nj.getValue() - 1)
229          ERROR("CDomain::checkLocalJDomain(void)",
230                << "[ Id = " << this->getId() << " ] "
231                << "The local domain is wrongly defined,"
232                << " jend is different from (jbegin + nj - 1)");
233      }
234      else if (jbegin.isEmpty() && jend.isEmpty() && nj.isEmpty())
235      {
236        jbegin = 0;
237        jend = nj_glo - 1;
238        nj = nj_glo;
239      }
240      else
241      {
242        ERROR("CDomain::checkLocalJDomain(void)",
243              << "[ Id = " << this->getId() << " ] "
244              << "The local domain is wrongly defined,"
245              << " defining just one attribute among 'jbegin', 'jend' or 'nj' is invalid");
246      }
247
248      if (nj.getValue() < 0 || jbegin.getValue() > jend.getValue() ||
249          jbegin.getValue() < 0 || jend.getValue() > (nj_glo.getValue() - 1))
250      {
251        ERROR("CDomain::checkLocalJDomain(void)",
252              << "[ Id = " << this->getId() << " ] "
253              << "The local domain is wrongly defined,"
254              << " check the attributes 'nj_glo', 'nj', 'jbegin' and 'jend'");
255      }
256   }
257
258   //----------------------------------------------------------------
259
260   void CDomain::checkMask(void)
261   {
262      using namespace std;
263
264      int ibegin_mask = 0,
265          jbegin_mask = 0,
266          iend_mask = iend.getValue() - ibegin.getValue(),
267          jend_mask = jend.getValue() - jbegin.getValue();
268
269      if (!zoom_ibegin.isEmpty())
270      {
271         int zoom_iend = zoom_ibegin.getValue() + zoom_ni.getValue() - 1;
272         int zoom_jend = zoom_jbegin.getValue() + zoom_nj.getValue() - 1;
273
274         ibegin_mask = max (ibegin.getValue(), zoom_ibegin.getValue());
275         jbegin_mask = max (jbegin.getValue(), zoom_jbegin.getValue());
276         iend_mask   = min (iend.getValue(), zoom_iend);
277         jend_mask   = min (jend.getValue(), zoom_jend);
278
279         ibegin_mask -= ibegin.getValue();
280         jbegin_mask -= jbegin.getValue();
281         iend_mask   -= ibegin.getValue();
282         jend_mask   -= jbegin.getValue();
283      }
284
285
286      if (!mask.isEmpty())
287      {
288         if ((mask.extent(0) != ni) ||
289             (mask.extent(1) != nj))
290            ERROR("CDomain::checkAttributes(void)",
291                  <<"the mask has not the same size than the local domain"<<endl
292                   <<"Local size is "<<ni<<"x"<<nj<<endl
293                  <<"Mask size is "<<mask.extent(0)<<"x"<<mask.extent(1));
294         for (int i = 0; i < ni; i++)
295         {
296            for (int j = 0; j < nj; j++)
297            {
298               if (i < ibegin_mask && i > iend_mask &&
299                   j < jbegin_mask && j > jend_mask )
300                     mask(i,j) = false;
301            }
302         }
303      }
304      else // (!mask.hasValue())
305      { // Si aucun masque n'est défini,
306        // on en crée un nouveau qui valide l'intégralité du domaine.
307         mask.resize(ni,nj) ;
308         for (int i = 0; i < ni.getValue(); i++)
309         {
310            for (int j = 0; j < nj.getValue(); j++)
311            {
312               if (i >= ibegin_mask && i <= iend_mask &&
313                   j >= jbegin_mask && j <= jend_mask )
314                     mask(i,j) = true;
315               else  mask(i,j) = false;
316            }
317         }
318      }
319   }
320
321
322   //----------------------------------------------------------------
323
324   void CDomain::checkDomainData(void)
325   {
326      if (!data_dim.isEmpty() &&
327         !(data_dim.getValue() == 1 || data_dim.getValue() == 2))
328      {
329         ERROR("CDomain::checkAttributes(void)",
330               << "Data dimension incompatible (must be 1 or 2) !") ;
331      }
332      else if (data_dim.isEmpty())
333      {
334         ERROR("CDomain::checkAttributes(void)",
335               << "Data dimension undefined !") ;
336      }
337
338      if (data_ibegin.isEmpty())
339         data_ibegin.setValue(0) ;
340      if (data_jbegin.isEmpty() && (data_dim.getValue() == 2))
341         data_jbegin.setValue(0) ;
342
343      if (!data_ni.isEmpty() && (data_ni.getValue() <= 0))
344      {
345         ERROR("CDomain::checkAttributes(void)",
346               << "Data dimension is negative (data_ni).") ;
347      }
348      else if (data_ni.isEmpty())
349      {
350         data_ni.setValue((data_dim.getValue() == 1)
351                           ? (ni.getValue() * nj.getValue())
352                           : ni.getValue());
353      }
354
355      if (data_dim.getValue() == 2)
356      {
357         if (!data_nj.isEmpty() && (data_nj.getValue() <= 0) )
358         {
359            ERROR("CDomain::checkAttributes(void)",
360                  << "Data dimension is negative (data_nj).") ;
361         }
362         else if (data_nj.isEmpty())
363            data_nj.setValue(nj.getValue()) ;
364      }
365
366   }
367
368   //----------------------------------------------------------------
369
370   void CDomain::checkCompression(void)
371   {
372      if (!data_i_index.isEmpty())
373      {
374         int ssize = data_i_index.numElements();
375         if (!data_n_index.isEmpty() &&
376            (data_n_index.getValue() != ssize))
377         {
378            ERROR("CDomain::checkAttributes(void)",
379                  <<"Dimension data_i_index incompatible with data_n_index.") ;
380         }
381         else if (data_n_index.isEmpty())
382            data_n_index.setValue(ssize) ;
383
384         if (data_dim.getValue() == 2)
385         {
386            if (!data_j_index.isEmpty() &&
387               (data_j_index.numElements() != data_i_index.numElements()))
388            {
389               ERROR("CDomain::checkAttributes(void)",
390                     <<"Dimension data_j_index incompatible with data_i_index.") ;
391            }
392            else if (data_j_index.isEmpty())
393            {
394               ERROR("CDomain::checkAttributes(void)",
395                     <<"data_j_index must be defined !") ;
396            }
397         }
398      }
399      else
400      {
401         if (!data_n_index.isEmpty() ||
402            ((data_dim.getValue() == 2) && (!data_j_index.isEmpty())))
403            ERROR("CDomain::checkAttributes(void)", << "data_i_index undefined") ;
404      }
405
406      if (data_n_index.isEmpty())
407      { // -> bloc re-vérifié OK
408         if (data_dim.getValue() == 1)
409         {
410            const int dni = data_ni.getValue();
411            data_i_index.resize(dni) ;
412            data_n_index.setValue(dni);
413            for (int i = 0; i < dni; i++) data_i_index(i) = i+1 ;
414         }
415         else   // (data_dim == 2)
416         {
417            const int dni = data_ni.getValue() * data_nj.getValue();
418            data_i_index.resize(dni) ;
419            data_j_index.resize(dni) ;
420
421            data_n_index.setValue(dni);
422
423            for(int count = 0, j = 0; j  < data_nj.getValue(); j++)
424            {
425               for(int i = 0; i < data_ni.getValue(); i++, count++)
426               {
427                  data_i_index(count) = i+1 ;
428                  data_j_index(count) = j+1 ;
429               }
430            }
431         }
432      }
433   }
434
435   //----------------------------------------------------------------
436
437   void CDomain::completeLonLatClient(void)
438   {
439      int i,j,k ;
440      CArray<double,1> lonvalue_temp(ni*nj) ;
441      CArray<double,1> latvalue_temp(ni*nj) ;
442      CArray<double,2> bounds_lon_temp(nvertex,ni*nj) ;
443      CArray<double,2> bounds_lat_temp(nvertex,ni*nj) ;
444
445      if (type.isEmpty())
446      {
447        if ( lonvalue.numElements() == ni*nj && latvalue.numElements() == ni*nj )
448        {
449          type.setValue(type_attr::curvilinear) ;
450          isCurvilinear=true ;
451        }
452        else if ( lonvalue.numElements() == ni && latvalue.numElements() == nj )
453        {
454          type.setValue(type_attr::regular) ;
455          isCurvilinear=false ;
456        }
457        else ERROR("void CDomain::completeLonLatClient(void)",<<"the grid is nor curvilinear, nor cartesian, because the size of longitude and latitude array is not coherent with the domain size"<<endl
458                                                              <<"lonvalue size = " << lonvalue.numElements() << "different of ni or ni*nj"<<endl
459                                                              <<"latvalue size = " << latvalue.numElements() << "different of nj or ni*nj" ) ;
460      }
461      if (type==type_attr::curvilinear || type==type_attr::unstructured)
462      {
463        lonvalue_temp=lonvalue ;
464        latvalue_temp=latvalue ;
465        if (hasBounds) bounds_lon_temp=bounds_lon ;
466        if (hasBounds) bounds_lat_temp=bounds_lat ;
467      }
468      else
469      {
470        for(j=0;j<nj;j++)
471          for(i=0;i<ni;i++)
472          {
473            k=j*ni+i ;
474            lonvalue_temp(k)=lonvalue(i) ;
475            latvalue_temp(k)=latvalue(j) ;
476            if (hasBounds)
477            {
478              for(int n=0;n<nvertex;n++)
479              {
480                bounds_lon_temp(n,k)=bounds_lon(n,i) ;
481                bounds_lat_temp(n,k)=bounds_lat(n,j) ;
482              }
483            }
484          }
485      }
486
487      StdSize dm = zoom_ni_client * zoom_nj_client;
488
489      // Make sure that this attribute is non-empty for every client.
490      if (0 != dm)
491      {
492        lonvalue.resize(dm);
493        latvalue.resize(dm);
494      }
495
496
497      for (int i = 0; i < zoom_ni_client; i++)
498      {
499        for (int j = 0; j < zoom_nj_client; j++)
500        {
501          lonvalue(i + j * zoom_ni_client) = lonvalue_temp( (i + zoom_ibegin_client-ibegin) + (j + zoom_jbegin_client -jbegin)*ni );
502          latvalue(i + j * zoom_ni_client) = latvalue_temp( (i + zoom_ibegin_client - ibegin)+(j + zoom_jbegin_client - jbegin)*ni );
503          if (hasBounds)
504          {
505            for(int n=0;n<nvertex;n++)
506            {
507              bounds_lon(n,i + j * zoom_ni_client) = bounds_lon_temp( n, (i + zoom_ibegin_client - ibegin) + (j + zoom_jbegin_client -jbegin)*ni );
508              bounds_lat(n,i + j * zoom_ni_client) = bounds_lat_temp( n, (i + zoom_ibegin_client - ibegin)+(j + zoom_jbegin_client -jbegin)*ni );
509            }
510          }
511        }
512      }
513    }
514
515
516   //----------------------------------------------------------------
517
518   void CDomain::checkZoom(void)
519   {
520      // Résolution et vérification des données globales de zoom.
521      if (!this->zoom_ni.isEmpty() || !this->zoom_nj.isEmpty() ||
522          !this->zoom_ibegin.isEmpty() || !this->zoom_jbegin.isEmpty())
523      {
524         if (this->zoom_ni.isEmpty()     || this->zoom_nj.isEmpty() ||
525             this->zoom_ibegin.isEmpty() || this->zoom_jbegin.isEmpty())
526         {
527            ERROR("CDomain::checkZoom(void)",
528                  <<"if one of zoom attributes is defined then all zoom attributes must be defined") ;
529         }
530         else
531         {
532            int zoom_iend = zoom_ibegin + zoom_ni - 1;
533            int zoom_jend = zoom_jbegin + zoom_nj - 1;
534
535            if (zoom_ibegin < 0  || zoom_jbegin < 0 || zoom_iend > (ni_glo-1) || zoom_jend > (nj_glo-1))
536               ERROR("CDomain::checkZoom(void)",
537                     << "Zoom is wrongly defined,"
538                     << " Check the values : zoom_ni, zoom_nj, zoom_ibegin, zoom_jbegin") ;
539         }
540      }
541      else
542      {
543         zoom_ni = ni_glo;
544         zoom_nj = nj_glo;
545         zoom_ibegin = 0;
546         zoom_jbegin = 0;
547      }
548
549      // compute client zoom indices
550      // compute client zoom indices
551      if (0 == global_zoom_ni) global_zoom_ni = ni_glo;
552      if (0 == global_zoom_nj) global_zoom_nj = nj_glo;
553
554      int global_zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
555      zoom_ibegin_client = ibegin_client > global_zoom_ibegin ? ibegin_client : global_zoom_ibegin ;
556      zoom_iend_client = iend_client < global_zoom_iend ? iend_client : global_zoom_iend ;
557      zoom_ni_client=zoom_iend_client-zoom_ibegin_client+1 ;
558      if (zoom_ni_client<0) zoom_ni_client=0 ;
559
560
561      int global_zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
562      zoom_jbegin_client = jbegin_client > global_zoom_jbegin ? jbegin_client : global_zoom_jbegin ;
563      zoom_jend_client = jend_client < global_zoom_jend ? jend_client : global_zoom_jend ;
564      zoom_nj_client=zoom_jend_client-zoom_jbegin_client+1 ;
565      if (zoom_nj_client<0) zoom_nj_client=0 ;
566
567//      int zoom_iend=zoom_ibegin+zoom_ni-1 ;
568//      zoom_ibegin_client = ibegin_client > zoom_ibegin ? ibegin_client : zoom_ibegin ;
569//      zoom_iend_client = iend_client < zoom_iend ? iend_client : zoom_iend ;
570//      zoom_ni_client=zoom_iend_client-zoom_ibegin_client+1 ;
571//      if (zoom_ni_client<0) zoom_ni_client=0 ;
572//
573//
574//      int zoom_jend=zoom_jbegin+zoom_nj-1 ;
575//      zoom_jbegin_client = jbegin_client > zoom_jbegin ? jbegin_client : zoom_jbegin ;
576//      zoom_jend_client = jend_client < zoom_jend ? jend_client : zoom_jend ;
577//      zoom_nj_client=zoom_jend_client-zoom_jbegin_client+1 ;
578//      if (zoom_nj_client<0) zoom_nj_client=0 ;
579
580   }
581
582   void CDomain::checkBounds(void)
583   {
584     if (!nvertex.isEmpty() && !bounds_lon.isEmpty() && !bounds_lat.isEmpty())
585     {
586       hasBounds=true ;
587     }
588     else
589     {
590       hasBounds=false;
591       nvertex=0 ;
592     }
593   }
594
595   void CDomain::checkArea(void)
596   {
597     hasArea = !area.isEmpty();
598     if (hasArea)
599     {
600       if (area.extent(0) != ni || area.extent(1) != nj)
601       {
602         ERROR("void CDomain::checkArea(void)",
603               "The area attribute must be of size ni x nj.");
604       }
605     }
606   }
607
608   //----------------------------------------------------------------
609   // Divide function checkAttributes into 2 seperate ones
610   // This function only checks all attributes of current domain
611   void CDomain::checkAttributesOnClient()
612   {
613     if (this->isClientChecked) return;
614     CContext* context=CContext::getCurrent();
615
616      this->checkDomain();
617//      this->checkZoom();
618      this->checkBounds();
619      this->checkArea();
620
621      if (context->hasClient)
622      { // CÃŽté client uniquement
623         this->checkMask();
624         this->checkDomainData();
625         this->checkCompression();
626//         this->completeLonLatClient();
627//         this->computeConnectedServer() ;
628      }
629      else
630      { // CÃŽté serveur uniquement
631//         if (!this->isEmpty())
632// ne sert plus //   this->completeLonLatServer();
633      }
634
635      this->isClientChecked = true;
636   }
637
638   // Send all checked attributes to server
639   void CDomain::sendCheckedAttributes()
640   {
641     if (!this->isClientChecked) checkAttributesOnClient();
642     CContext* context=CContext::getCurrent() ;
643
644     this->checkZoom();
645     if (this->isChecked) return;
646     if (context->hasClient)
647     {
648       this->computeConnectedServer();
649       this->completeLonLatClient();
650
651       sendServerAttribut() ;
652       sendLonLatArea() ;
653     }
654
655     this->isChecked = true;
656   }
657
658   void CDomain::checkAttributes(void)
659   {
660      if (this->isChecked) return;
661      CContext* context=CContext::getCurrent() ;
662
663      this->checkDomain();
664      this->checkZoom();
665      this->checkBounds();
666      this->checkArea();
667
668      if (context->hasClient)
669      { // CÃŽté client uniquement
670         this->checkMask();
671         this->checkDomainData();
672         this->checkCompression();
673         this->completeLonLatClient();
674      }
675      else
676      { // CÃŽté serveur uniquement
677//         if (!this->isEmpty())
678// ne sert plus //   this->completeLonLatServer();
679      }
680
681      if (context->hasClient)
682      {
683        computeConnectedServer() ;
684        sendServerAttribut() ;
685        sendLonLatArea() ;
686      }
687
688      this->isChecked = true;
689   }
690
691  void CDomain::sendServerAttribut(void)
692  {
693    std::vector<int> nGlobDomain(2);
694    nGlobDomain[0] = ni_glo.getValue();
695    nGlobDomain[1] = nj_glo.getValue();
696    CServerDistributionDescription serverDescription(nGlobDomain);
697
698    CContext* context = CContext::getCurrent();
699    CContextClient* client = context->client;
700    int nbServer = client->serverSize;
701
702    serverDescription.computeServerDistribution(nbServer);
703    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
704    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
705
706    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
707    if (client->isServerLeader())
708    {
709      std::list<CMessage> msgs;
710
711      const std::list<int>& ranks = client->getRanksServerLeader();
712      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
713      {
714        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
715        const int ibegin_srv = serverIndexBegin[*itRank][0];
716        const int jbegin_srv = serverIndexBegin[*itRank][1];
717        const int ni_srv = serverDimensionSizes[*itRank][0];
718        const int nj_srv = serverDimensionSizes[*itRank][1];
719        const int iend_srv = ibegin_srv + ni_srv - 1;
720        const int jend_srv = jbegin_srv + nj_srv - 1;
721
722        msgs.push_back(CMessage());
723        CMessage& msg = msgs.back();
724        msg << this->getId() ;
725        msg << ni_srv << ibegin_srv << iend_srv << nj_srv << jbegin_srv << jend_srv;
726        msg << global_zoom_ni << global_zoom_ibegin << global_zoom_nj << global_zoom_jbegin;
727
728        event.push(*itRank,1,msg);
729      }
730      client->sendEvent(event);
731    }
732    else client->sendEvent(event);
733  }
734
735  void CDomain::computeConnectedServer(void)
736  {
737    ibegin_client=ibegin ; iend_client=iend ; ni_client=ni ;
738    jbegin_client=jbegin ; jend_client=jend ; nj_client=nj ;
739
740    CContext* context=CContext::getCurrent() ;
741    CContextClient* client=context->client ;
742    int nbServer=client->serverSize;
743    bool doComputeGlobalIndexServer = true;
744
745    int i,j,i_ind,j_ind ;
746    int zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
747    int zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
748
749    // Precompute number of index
750    int globalIndexCountZoom = 0;
751    for(j=0;j<nj;j++)
752      for(i=0;i<ni;i++)
753      {
754        i_ind=ibegin+i_index(i,j) ;
755        j_ind=jbegin+j_index(i,j) ;
756
757        if (i_ind >= global_zoom_ibegin && i_ind <= zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= zoom_jend)
758        {
759          ++globalIndexCountZoom;
760        }
761      }
762
763    // Fill in index
764    CArray<size_t,1> globalIndexDomainZoom(globalIndexCountZoom);
765    CArray<size_t,1> globalIndexDomain(ni*nj);
766    size_t globalIndex;
767    int globalIndexCount = 0;
768    globalIndexCountZoom = 0;
769
770    for(j=0;j<nj;j++)
771      for(i=0;i<ni;i++)
772      {
773        i_ind=ibegin+i_index(i,j) ;
774        j_ind=jbegin+j_index(i,j) ;
775
776        globalIndex = i_ind + j_ind * ni_glo;
777        globalIndexDomain(globalIndexCount) = globalIndex;
778        ++globalIndexCount;
779        if (i_ind >= global_zoom_ibegin && i_ind <= zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= zoom_jend)
780        {
781          globalIndexDomainZoom(globalIndexCountZoom) = globalIndex;
782          ++globalIndexCountZoom;
783        }
784      }
785
786     std::vector<int> nGlobDomain(2);
787     nGlobDomain[0] = ni_glo.getValue();
788     nGlobDomain[1] = nj_glo.getValue();
789     size_t globalSizeIndex = 1, indexBegin, indexEnd;
790     int range, clientSize = client->clientSize;
791     for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i];
792     indexBegin = 0;
793     for (int i = 0; i < clientSize; ++i)
794     {
795       range = globalSizeIndex / clientSize;
796       if (i < (globalSizeIndex%clientSize)) ++range;
797       if (i == client->clientRank) break;
798       indexBegin += range;
799     }
800     indexEnd = indexBegin + range - 1;
801
802    CServerDistributionDescription serverDescription(nGlobDomain);
803    serverDescription.computeServerGlobalIndexInRange(nbServer, std::make_pair<size_t,size_t>(indexBegin, indexEnd));
804    CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(),
805                                                                                client->intraComm);
806    clientServerMap->computeServerIndexMapping(globalIndexDomain);
807    const std::map<int, std::vector<size_t> >& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
808
809    std::map<int, std::vector<size_t> >::const_iterator it = globalIndexDomainOnServer.begin(),
810                                                       ite = globalIndexDomainOnServer.end();
811    indSrv_.clear();
812    for (; it != ite; ++it)
813    {
814      int rank = it->first;
815      std::vector<size_t>::const_iterator itbVec  = (it->second).begin(),
816                                           iteVec = (it->second).end();
817      int nb = globalIndexDomainZoom.numElements();
818      for (int i = 0; i < nb; ++i)
819      {
820        if (iteVec != std::find(itbVec, iteVec, globalIndexDomainZoom(i)))
821        {
822          indSrv_[rank].push_back(globalIndexDomainZoom(i));
823        }
824      }
825    }
826
827    connectedServerRank_.clear();
828    for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) {
829      connectedServerRank_.push_back(it->first);
830    }
831
832    if (!indSrv_.empty())
833    {
834      connectedServerRank_.clear();
835      for (it = indSrv_.begin(); it != indSrv_.end(); ++it)
836        connectedServerRank_.push_back(it->first);
837    }
838    nbConnectedClients_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
839
840    delete clientServerMap;
841  }
842
843  void CDomain::sendLonLatArea(void)
844  {
845    int ns, n, i, j, ind, nv, idx;
846    CContext* context = CContext::getCurrent();
847    CContextClient* client=context->client;
848
849    // send lon lat for each connected server
850    CEventClient eventIndex(getType(), EVENT_ID_INDEX);
851    CEventClient eventLon(getType(), EVENT_ID_LON);
852    CEventClient eventLat(getType(), EVENT_ID_LAT);
853    CEventClient eventArea(getType(), EVENT_ID_AREA);
854
855    list<CMessage> list_msgsIndex, list_msgsLon, list_msgsLat, list_msgsArea;
856    list<CArray<int,1> > list_indi, list_indj;
857    list<CArray<double,1> > list_lon, list_lat;
858    list<CArray<double,2> > list_boundslon, list_boundslat;
859    list<CArray<double,1> > list_area;
860
861    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
862    iteMap = indSrv_.end();
863    for (int k = 0; k < connectedServerRank_.size(); ++k)
864    {
865      int nbData = 0;
866      int rank = connectedServerRank_[k];
867      it = indSrv_.find(rank);
868      if (iteMap != it)
869        nbData = it->second.size();
870
871      list_indi.push_back(CArray<int,1>(nbData));
872      list_indj.push_back(CArray<int,1>(nbData));
873      list_lon.push_back(CArray<double,1>(nbData));
874      list_lat.push_back(CArray<double,1>(nbData));
875
876      if (hasBounds)
877      {
878        list_boundslon.push_back(CArray<double,2>(nvertex, nbData));
879        list_boundslat.push_back(CArray<double,2>(nvertex, nbData));
880      }
881      if (hasArea)
882        list_area.push_back(CArray<double,1>(nbData));
883
884      CArray<int,1>& indi = list_indi.back();
885      CArray<int,1>& indj = list_indj.back();
886      CArray<double,1>& lon = list_lon.back();
887      CArray<double,1>& lat = list_lat.back();
888
889      for (n = 0; n < nbData; ++n)
890      {
891        idx = static_cast<int>(it->second[n]);
892        i = idx % ni_glo;
893        j = idx / ni_glo;
894        ind = (i - zoom_ibegin_client) + (j - zoom_jbegin_client) * zoom_ni_client;
895
896        lon(n) = lonvalue(ind);
897        lat(n) = latvalue(ind);
898
899        if (hasBounds)
900        {
901          CArray<double,2>& boundslon = list_boundslon.back();
902          CArray<double,2>& boundslat = list_boundslat.back();
903
904          for (nv = 0; nv < nvertex; nv++)
905          {
906            boundslon(nv, n) = bounds_lon(nv, ind);
907            boundslat(nv, n) = bounds_lat(nv, ind);
908          }
909        }
910
911        indi(n) = ibegin + i_index(i - ibegin, j - jbegin);
912        indj(n) = jbegin + j_index(i - ibegin, j - jbegin);
913
914        if (hasArea)
915          list_area.back()(n) = area(i - ibegin, j - jbegin);
916      }
917
918      list_msgsIndex.push_back(CMessage());
919
920      list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix
921      list_msgsIndex.back() << isCurvilinear;
922      list_msgsIndex.back() << list_indi.back() << list_indj.back();
923
924      list_msgsLon.push_back(CMessage());
925      list_msgsLat.push_back(CMessage());
926
927      list_msgsLon.back() << this->getId() << list_lon.back();
928      list_msgsLat.back() << this->getId() << list_lat.back();
929
930      if (hasBounds)
931      {
932        list_msgsLon.back() << list_boundslon.back();
933        list_msgsLat.back() << list_boundslat.back();
934      }
935
936      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
937      eventLon.push(rank, nbConnectedClients_[rank], list_msgsLon.back());
938      eventLat.push(rank, nbConnectedClients_[rank], list_msgsLat.back());
939
940      if (hasArea)
941      {
942        list_msgsArea.push_back(CMessage());
943        list_msgsArea.back() << this->getId() << list_area.back();
944        eventArea.push(rank, nbConnectedClients_[rank], list_msgsArea.back());
945      }
946    }
947
948    client->sendEvent(eventIndex);
949    client->sendEvent(eventLon);
950    client->sendEvent(eventLat);
951    if (hasArea)
952      client->sendEvent(eventArea);
953  }
954
955  bool CDomain::dispatchEvent(CEventServer& event)
956  {
957    if (SuperClass::dispatchEvent(event)) return true;
958    else
959    {
960      switch(event.type)
961      {
962        case EVENT_ID_SERVER_ATTRIBUT:
963          recvServerAttribut(event);
964          return true;
965          break;
966        case EVENT_ID_INDEX:
967          recvIndex(event);
968          return true;
969          break;
970        case EVENT_ID_LON:
971          recvLon(event);
972          return true;
973          break;
974        case EVENT_ID_LAT:
975          recvLat(event);
976          return true;
977          break;
978        case EVENT_ID_AREA:
979          recvArea(event);
980          return true;
981          break;
982        default:
983          ERROR("bool CContext::dispatchEvent(CEventServer& event)",
984                << "Unknown Event");
985          return false;
986       }
987    }
988  }
989
990  void CDomain::recvServerAttribut(CEventServer& event)
991  {
992    CBufferIn* buffer=event.subEvents.begin()->buffer;
993    string domainId ;
994    *buffer>>domainId ;
995    get(domainId)->recvServerAttribut(*buffer) ;
996  }
997
998  void CDomain::recvServerAttribut(CBufferIn& buffer)
999  {
1000    buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv
1001           >> global_zoom_ni >> global_zoom_ibegin >> global_zoom_nj >> global_zoom_jbegin;
1002
1003    int zoom_iend = global_zoom_ibegin + global_zoom_ni - 1;
1004    int zoom_jend = global_zoom_jbegin + global_zoom_nj - 1;
1005
1006    zoom_ibegin_srv = global_zoom_ibegin > ibegin_srv ? global_zoom_ibegin : ibegin_srv ;
1007    zoom_iend_srv = zoom_iend < iend_srv ? zoom_iend : iend_srv ;
1008    zoom_ni_srv=zoom_iend_srv-zoom_ibegin_srv+1 ;
1009
1010    zoom_jbegin_srv = global_zoom_jbegin > jbegin_srv ? global_zoom_jbegin : jbegin_srv ;
1011    zoom_jend_srv = zoom_jend < jend_srv ? zoom_jend : jend_srv ;
1012    zoom_nj_srv=zoom_jend_srv-zoom_jbegin_srv+1 ;
1013
1014    if (zoom_ni_srv<=0 || zoom_nj_srv<=0)
1015    {
1016      zoom_ibegin_srv=0 ; zoom_iend_srv=0 ; zoom_ni_srv=0 ;
1017      zoom_jbegin_srv=0 ; zoom_jend_srv=0 ; zoom_nj_srv=0 ;
1018    }
1019    lonvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
1020    lonvalue_srv = 0. ;
1021    latvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
1022    latvalue_srv = 0. ;
1023    if (hasBounds)
1024    {
1025      bounds_lon_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
1026      bounds_lon_srv = 0. ;
1027      bounds_lat_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
1028      bounds_lat_srv = 0. ;
1029    }
1030
1031    if (hasArea)
1032      area_srv.resize(zoom_ni_srv * zoom_nj_srv);
1033  }
1034
1035  void CDomain::recvIndex(CEventServer& event)
1036  {
1037    list<CEventServer::SSubEvent>::iterator it;
1038    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1039    {
1040      CBufferIn* buffer = it->buffer;
1041      string domainId;
1042      *buffer >> domainId;
1043      get(domainId)->recvIndex(it->rank, *buffer);
1044    }
1045  }
1046
1047  void CDomain::recvIndex(int rank, CBufferIn& buffer)
1048  {
1049    int type_int;
1050    buffer >> type_int >> isCurvilinear >> indiSrv[rank] >> indjSrv[rank];
1051    type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix
1052  }
1053
1054  void CDomain::recvLon(CEventServer& event)
1055  {
1056    list<CEventServer::SSubEvent>::iterator it;
1057    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1058    {
1059      CBufferIn* buffer = it->buffer;
1060      string domainId;
1061      *buffer >> domainId;
1062      get(domainId)->recvLon(it->rank, *buffer);
1063    }
1064  }
1065
1066  void CDomain::recvLon(int rank, CBufferIn& buffer)
1067  {
1068    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1069    CArray<double,1> lon;
1070    CArray<double,2> boundslon;
1071
1072    buffer >> lon;
1073    if (hasBounds) buffer >> boundslon;
1074
1075    int i, j, ind_srv;
1076    for (int ind = 0; ind < indi.numElements(); ind++)
1077    {
1078      i = indi(ind); j = indj(ind);
1079      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1080      lonvalue_srv(ind_srv) = lon(ind);
1081      if (hasBounds)
1082      {
1083        for (int nv = 0; nv < nvertex; nv++)
1084          bounds_lon_srv(nv, ind_srv) = boundslon(nv, ind);
1085      }
1086    }
1087  }
1088
1089  void CDomain::recvLat(CEventServer& event)
1090  {
1091    list<CEventServer::SSubEvent>::iterator it;
1092    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1093    {
1094      CBufferIn* buffer = it->buffer;
1095      string domainId;
1096      *buffer >> domainId;
1097      get(domainId)->recvLat(it->rank, *buffer);
1098    }
1099  }
1100
1101  void CDomain::recvLat(int rank, CBufferIn& buffer)
1102  {
1103    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1104    CArray<double,1> lat;
1105    CArray<double,2> boundslat;
1106
1107    buffer >> lat;
1108    if (hasBounds) buffer >> boundslat;
1109
1110    int i, j, ind_srv;
1111    for (int ind = 0; ind < indi.numElements(); ind++)
1112    {
1113      i = indi(ind); j = indj(ind);
1114      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1115      latvalue_srv(ind_srv) = lat(ind);
1116      if (hasBounds)
1117      {
1118        for (int nv = 0; nv < nvertex; nv++)
1119          bounds_lat_srv(nv, ind_srv) = boundslat(nv, ind);
1120      }
1121    }
1122  }
1123
1124  void CDomain::recvArea(CEventServer& event)
1125  {
1126    list<CEventServer::SSubEvent>::iterator it;
1127    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1128    {
1129      CBufferIn* buffer = it->buffer;
1130      string domainId;
1131      *buffer >> domainId;
1132      get(domainId)->recvArea(it->rank, *buffer);
1133    }
1134  }
1135
1136  void CDomain::recvArea(int rank, CBufferIn& buffer)
1137  {
1138    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1139    CArray<double,1> clientArea;
1140
1141    buffer >> clientArea;
1142
1143    int i, j, ind_srv;
1144    for (int ind = 0; ind < indi.numElements(); ind++)
1145    {
1146      i = indi(ind); j = indj(ind);
1147      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1148      area_srv(ind_srv) = clientArea(ind);
1149    }
1150  }
1151
1152  bool CDomain::hasTransformation()
1153  {
1154    return (!transformationMap_.empty());
1155  }
1156
1157  void CDomain::setTransformations(const TransMapTypes& domTrans)
1158  {
1159    transformationMap_ = domTrans;
1160  }
1161
1162  CDomain::TransMapTypes CDomain::getAllTransformations(void)
1163  {
1164    return transformationMap_;
1165  }
1166
1167  /*!
1168    Check the validity of all transformations applied on domain
1169  This functions is called AFTER all inherited attributes are solved
1170  */
1171  void CDomain::checkTransformations()
1172  {
1173    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
1174                                  ite = transformationMap_.end();
1175    for (it = itb; it != ite; ++it)
1176    {
1177      (it->second)->checkValid(this);
1178    }
1179  }
1180
1181  void CDomain::solveInheritanceTransformation()
1182  {
1183    if (this->hasTransformation()) return;
1184
1185    std::vector<CDomain*> refDomain;
1186    CDomain* refer_sptr;
1187    CDomain* refer_ptr = this;
1188    while (refer_ptr->hasDirectDomainReference())
1189    {
1190      refDomain.push_back(refer_ptr);
1191      refer_sptr = refer_ptr->getDirectDomainReference();
1192      refer_ptr  = refer_sptr;
1193      if (refer_ptr->hasTransformation()) break;
1194    }
1195
1196    if (refer_ptr->hasTransformation())
1197      for (int idx = 0; idx < refDomain.size(); ++idx)
1198        refDomain[idx]->setTransformations(refer_ptr->getAllTransformations());
1199  }
1200
1201  void CDomain::parse(xml::CXMLNode & node)
1202  {
1203    SuperClass::parse(node);
1204
1205    if (node.goToChildElement())
1206    {
1207      StdString zoomDomainDefRoot("zoom_domain_definition");
1208      StdString zoom("zoom_domain");
1209      do
1210      {
1211        if (node.getElementName() == zoom) {
1212          CZoomDomain* tmp = (CZoomDomainGroup::get(zoomDomainDefRoot))->createChild();
1213          tmp->parse(node);
1214          transformationMap_.push_back(std::make_pair(TRANS_ZOOM_DOMAIN,tmp));
1215        }
1216      } while (node.goToNextElement()) ;
1217      node.goToParentElement();
1218    }
1219  }
1220   //----------------------------------------------------------------
1221
1222   DEFINE_REF_FUNC(Domain,domain)
1223
1224   ///---------------------------------------------------------------
1225
1226} // namespace xios
Note: See TracBrowser for help on using the repository browser.