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

Last change on this file since 664 was 664, checked in by mhnguyen, 8 years ago

Changing some domain attributes

+) Longitude and latitude from now on can be 2 dimension array

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