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

Last change on this file since 667 was 667, checked in by mhnguyen, 6 years ago

Clearing some redundant codes and add some comments

Test
No

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