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

Last change on this file since 675 was 675, checked in by rlacroix, 6 years ago

Fix mask for domains after r664.

Using 2D mask caused an incorrect error message to be triggered and 1D mask was ignored.

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