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

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

Avoid using C++11 feature for now.

  • 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.0 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    typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
835    std::vector<int>::iterator itVec;
836
837    indSrv_.clear();
838    for (; it != ite; ++it)
839    {
840      int rank = it->first;
841      int indexSize = it->second.size();
842      std::vector<int> permutIndex(indexSize);
843      XIOSAlgorithms::fillInIndex(indexSize, permutIndex);
844      XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(it->second, permutIndex);
845      BinarySearch binSearch(it->second);
846      int nb = globalIndexDomainZoom.numElements();
847      for (int i = 0; i < nb; ++i)
848      {
849        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexDomainZoom(i), itVec))
850        {
851          indSrv_[rank].push_back(localIndexDomainZoom(i));
852        }
853      }
854    }
855
856    connectedServerRank_.clear();
857    for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) {
858      connectedServerRank_.push_back(it->first);
859    }
860
861    if (!indSrv_.empty())
862    {
863      connectedServerRank_.clear();
864      for (it = indSrv_.begin(); it != indSrv_.end(); ++it)
865        connectedServerRank_.push_back(it->first);
866    }
867    nbConnectedClients_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
868
869    delete clientServerMap;
870  }
871
872  const std::map<int, vector<size_t> >& CDomain::getIndexServer() const
873  {
874    return indSrv_;
875  }
876
877  /*!
878    Send index from client to server(s)
879  */
880  void CDomain::sendIndex()
881  {
882    int ns, n, i, j, ind, nv, idx;
883    CContext* context = CContext::getCurrent();
884    CContextClient* client=context->client;
885
886    CEventClient eventIndex(getType(), EVENT_ID_INDEX);
887
888    list<CMessage> list_msgsIndex;
889    list<CArray<int,1> > list_indi, list_indj;
890
891    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
892    iteMap = indSrv_.end();
893    for (int k = 0; k < connectedServerRank_.size(); ++k)
894    {
895      int nbData = 0;
896      int rank = connectedServerRank_[k];
897      it = indSrv_.find(rank);
898      if (iteMap != it)
899        nbData = it->second.size();
900
901      list_indi.push_back(CArray<int,1>(nbData));
902      list_indj.push_back(CArray<int,1>(nbData));
903
904      CArray<int,1>& indi = list_indi.back();
905      CArray<int,1>& indj = list_indj.back();
906      const std::vector<size_t>& temp = it->second;
907      for (n = 0; n < nbData; ++n)
908      {
909        idx = static_cast<int>(it->second[n]);
910        indi(n) = i_index(idx);
911        indj(n) = j_index(idx);
912      }
913
914      list_msgsIndex.push_back(CMessage());
915
916      list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix
917      list_msgsIndex.back() << isCurvilinear;
918      list_msgsIndex.back() << list_indi.back() << list_indj.back();
919
920      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
921    }
922
923    client->sendEvent(eventIndex);
924  }
925
926  /*!
927    Send area from client to server(s)
928  */
929  void CDomain::sendArea()
930  {
931    if (!hasArea) return;
932
933    int ns, n, i, j, ind, nv, idx;
934    CContext* context = CContext::getCurrent();
935    CContextClient* client=context->client;
936
937    // send area for each connected server
938    CEventClient eventArea(getType(), EVENT_ID_AREA);
939
940    list<CMessage> list_msgsArea;
941    list<CArray<double,1> > list_area;
942
943    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
944    iteMap = indSrv_.end();
945    for (int k = 0; k < connectedServerRank_.size(); ++k)
946    {
947      int nbData = 0;
948      int rank = connectedServerRank_[k];
949      it = indSrv_.find(rank);
950      if (iteMap != it)
951        nbData = it->second.size();
952      list_area.push_back(CArray<double,1>(nbData));
953
954      const std::vector<size_t>& temp = it->second;
955      for (n = 0; n < nbData; ++n)
956      {
957        idx = static_cast<int>(it->second[n]);
958        i = i_index(idx);
959        j = j_index(idx);
960        if (hasArea)
961          list_area.back()(n) = area(i - ibegin, j - jbegin);
962      }
963
964      list_msgsArea.push_back(CMessage());
965      list_msgsArea.back() << this->getId() << list_area.back();
966      eventArea.push(rank, nbConnectedClients_[rank], list_msgsArea.back());
967    }
968    client->sendEvent(eventArea);
969  }
970
971  /*!
972    Send longitude and latitude from client to servers
973    Each client send long and lat information to corresponding connected server(s).
974    Because longitude and latitude are optional, this function only called if latitude and longitude exist
975  */
976  void CDomain::sendLonLat()
977  {
978    if (!hasLonLat) return;
979
980    int ns, n, i, j, ind, nv, idx;
981    CContext* context = CContext::getCurrent();
982    CContextClient* client=context->client;
983
984    // send lon lat for each connected server
985    CEventClient eventLon(getType(), EVENT_ID_LON);
986    CEventClient eventLat(getType(), EVENT_ID_LAT);
987
988    list<CMessage> list_msgsLon, list_msgsLat;
989    list<CArray<double,1> > list_lon, list_lat;
990    list<CArray<double,2> > list_boundslon, list_boundslat;
991
992    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
993    iteMap = indSrv_.end();
994    for (int k = 0; k < connectedServerRank_.size(); ++k)
995    {
996      int nbData = 0;
997      int rank = connectedServerRank_[k];
998      it = indSrv_.find(rank);
999      if (iteMap != it)
1000        nbData = it->second.size();
1001
1002      list_lon.push_back(CArray<double,1>(nbData));
1003      list_lat.push_back(CArray<double,1>(nbData));
1004
1005      if (hasBounds)
1006      {
1007        list_boundslon.push_back(CArray<double,2>(nvertex, nbData));
1008        list_boundslat.push_back(CArray<double,2>(nvertex, nbData));
1009      }
1010
1011      CArray<double,1>& lon = list_lon.back();
1012      CArray<double,1>& lat = list_lat.back();
1013      const std::vector<size_t>& temp = it->second;
1014      for (n = 0; n < nbData; ++n)
1015      {
1016        idx = static_cast<int>(it->second[n]);
1017        lon(n) = lonvalue_client(idx);
1018        lat(n) = latvalue_client(idx);
1019
1020        if (hasBounds)
1021        {
1022          CArray<double,2>& boundslon = list_boundslon.back();
1023          CArray<double,2>& boundslat = list_boundslat.back();
1024
1025          for (nv = 0; nv < nvertex; ++nv)
1026          {
1027            boundslon(nv, n) = bounds_lon_client(nv, idx);
1028            boundslat(nv, n) = bounds_lat_client(nv, idx);
1029          }
1030        }
1031      }
1032
1033      list_msgsLon.push_back(CMessage());
1034      list_msgsLat.push_back(CMessage());
1035
1036      list_msgsLon.back() << this->getId() << list_lon.back();
1037      list_msgsLat.back() << this->getId() << list_lat.back();
1038
1039      if (hasBounds)
1040      {
1041        list_msgsLon.back() << list_boundslon.back();
1042        list_msgsLat.back() << list_boundslat.back();
1043      }
1044
1045      eventLon.push(rank, nbConnectedClients_[rank], list_msgsLon.back());
1046      eventLat.push(rank, nbConnectedClients_[rank], list_msgsLat.back());
1047    }
1048
1049    client->sendEvent(eventLon);
1050    client->sendEvent(eventLat);
1051  }
1052
1053  /*!
1054    Send some optional information to server(s)
1055    In the future, this function can be extended with more optional information to send
1056  */
1057  void CDomain::sendLonLatArea(void)
1058  {
1059    sendIndex();
1060    sendLonLat();
1061    sendArea();
1062  }
1063
1064  bool CDomain::dispatchEvent(CEventServer& event)
1065  {
1066    if (SuperClass::dispatchEvent(event)) return true;
1067    else
1068    {
1069      switch(event.type)
1070      {
1071        case EVENT_ID_SERVER_ATTRIBUT:
1072          recvServerAttribut(event);
1073          return true;
1074          break;
1075        case EVENT_ID_INDEX:
1076          recvIndex(event);
1077          return true;
1078          break;
1079        case EVENT_ID_LON:
1080          recvLon(event);
1081          return true;
1082          break;
1083        case EVENT_ID_LAT:
1084          recvLat(event);
1085          return true;
1086          break;
1087        case EVENT_ID_AREA:
1088          recvArea(event);
1089          return true;
1090          break;
1091        default:
1092          ERROR("bool CContext::dispatchEvent(CEventServer& event)",
1093                << "Unknown Event");
1094          return false;
1095       }
1096    }
1097  }
1098
1099  /*!
1100    Receive attributes event from clients(s)
1101    \param[in] event event contain info about rank and associated attributes
1102  */
1103  void CDomain::recvServerAttribut(CEventServer& event)
1104  {
1105    CBufferIn* buffer=event.subEvents.begin()->buffer;
1106    string domainId ;
1107    *buffer>>domainId ;
1108    get(domainId)->recvServerAttribut(*buffer) ;
1109  }
1110
1111  /*!
1112    Receive attributes from client(s): zoom info and begin and n of each server
1113    \param[in] rank rank of client source
1114    \param[in] buffer message containing attributes info
1115  */
1116  void CDomain::recvServerAttribut(CBufferIn& buffer)
1117  {
1118    buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv
1119           >> global_zoom_ni >> global_zoom_ibegin >> global_zoom_nj >> global_zoom_jbegin;
1120
1121    int zoom_iend = global_zoom_ibegin + global_zoom_ni - 1;
1122    int zoom_jend = global_zoom_jbegin + global_zoom_nj - 1;
1123
1124    zoom_ibegin_srv = global_zoom_ibegin > ibegin_srv ? global_zoom_ibegin : ibegin_srv ;
1125    zoom_iend_srv = zoom_iend < iend_srv ? zoom_iend : iend_srv ;
1126    zoom_ni_srv=zoom_iend_srv-zoom_ibegin_srv+1 ;
1127
1128    zoom_jbegin_srv = global_zoom_jbegin > jbegin_srv ? global_zoom_jbegin : jbegin_srv ;
1129    zoom_jend_srv = zoom_jend < jend_srv ? zoom_jend : jend_srv ;
1130    zoom_nj_srv=zoom_jend_srv-zoom_jbegin_srv+1 ;
1131
1132    if (zoom_ni_srv<=0 || zoom_nj_srv<=0)
1133    {
1134      zoom_ibegin_srv=0 ; zoom_iend_srv=0 ; zoom_ni_srv=0 ;
1135      zoom_jbegin_srv=0 ; zoom_jend_srv=0 ; zoom_nj_srv=0 ;
1136    }
1137    lonvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
1138    lonvalue_srv = 0. ;
1139    latvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
1140    latvalue_srv = 0. ;
1141    if (hasBounds)
1142    {
1143      bounds_lon_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
1144      bounds_lon_srv = 0. ;
1145      bounds_lat_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
1146      bounds_lat_srv = 0. ;
1147    }
1148
1149    if (hasArea)
1150      area_srv.resize(zoom_ni_srv * zoom_nj_srv);
1151  }
1152
1153  /*!
1154    Receive index event from clients(s)
1155    \param[in] event event contain info about rank and associated index
1156  */
1157  void CDomain::recvIndex(CEventServer& event)
1158  {
1159    list<CEventServer::SSubEvent>::iterator it;
1160    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1161    {
1162      CBufferIn* buffer = it->buffer;
1163      string domainId;
1164      *buffer >> domainId;
1165      get(domainId)->recvIndex(it->rank, *buffer);
1166    }
1167  }
1168
1169  /*!
1170    Receive index information from client(s)
1171    \param[in] rank rank of client source
1172    \param[in] buffer message containing index info
1173  */
1174  void CDomain::recvIndex(int rank, CBufferIn& buffer)
1175  {
1176    int type_int;
1177    buffer >> type_int >> isCurvilinear >> indiSrv[rank] >> indjSrv[rank];
1178    type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix
1179  }
1180
1181  /*!
1182    Receive longitude event from clients(s)
1183    \param[in] event event contain info about rank and associated longitude
1184  */
1185  void CDomain::recvLon(CEventServer& event)
1186  {
1187    list<CEventServer::SSubEvent>::iterator it;
1188    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1189    {
1190      CBufferIn* buffer = it->buffer;
1191      string domainId;
1192      *buffer >> domainId;
1193      get(domainId)->recvLon(it->rank, *buffer);
1194    }
1195  }
1196
1197  /*!
1198    Receive longitude information from client(s)
1199    \param[in] rank rank of client source
1200    \param[in] buffer message containing longitude info
1201  */
1202  void CDomain::recvLon(int rank, CBufferIn& buffer)
1203  {
1204    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1205    CArray<double,1> lon;
1206    CArray<double,2> boundslon;
1207
1208    buffer >> lon;
1209    if (hasBounds) buffer >> boundslon;
1210
1211    int i, j, ind_srv;
1212    for (int ind = 0; ind < indi.numElements(); ind++)
1213    {
1214      i = indi(ind); j = indj(ind);
1215      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1216      lonvalue_srv(ind_srv) = lon(ind);
1217      if (hasBounds)
1218      {
1219        for (int nv = 0; nv < nvertex; ++nv)
1220          bounds_lon_srv(nv, ind_srv) = boundslon(nv, ind);
1221      }
1222    }
1223  }
1224
1225  /*!
1226    Receive latitude event from clients(s)
1227    \param[in] event event contain info about rank and associated latitude
1228  */
1229  void CDomain::recvLat(CEventServer& event)
1230  {
1231    list<CEventServer::SSubEvent>::iterator it;
1232    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1233    {
1234      CBufferIn* buffer = it->buffer;
1235      string domainId;
1236      *buffer >> domainId;
1237      get(domainId)->recvLat(it->rank, *buffer);
1238    }
1239  }
1240
1241  /*!
1242    Receive latitude information from client(s)
1243    \param[in] rank rank of client source
1244    \param[in] buffer message containing latitude info
1245  */
1246  void CDomain::recvLat(int rank, CBufferIn& buffer)
1247  {
1248    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1249    CArray<double,1> lat;
1250    CArray<double,2> boundslat;
1251
1252    buffer >> lat;
1253    if (hasBounds) buffer >> boundslat;
1254
1255    int i, j, ind_srv;
1256    for (int ind = 0; ind < indi.numElements(); ind++)
1257    {
1258      i = indi(ind); j = indj(ind);
1259      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1260      latvalue_srv(ind_srv) = lat(ind);
1261      if (hasBounds)
1262      {
1263        for (int nv = 0; nv < nvertex; nv++)
1264          bounds_lat_srv(nv, ind_srv) = boundslat(nv, ind);
1265      }
1266    }
1267  }
1268
1269  /*!
1270    Receive area event from clients(s)
1271    \param[in] event event contain info about rank and associated area
1272  */
1273  void CDomain::recvArea(CEventServer& event)
1274  {
1275    list<CEventServer::SSubEvent>::iterator it;
1276    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1277    {
1278      CBufferIn* buffer = it->buffer;
1279      string domainId;
1280      *buffer >> domainId;
1281      get(domainId)->recvArea(it->rank, *buffer);
1282    }
1283  }
1284
1285  /*!
1286    Receive area information from client(s)
1287    \param[in] rank rank of client source
1288    \param[in] buffer message containing area info
1289  */
1290  void CDomain::recvArea(int rank, CBufferIn& buffer)
1291  {
1292    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1293    CArray<double,1> clientArea;
1294
1295    buffer >> clientArea;
1296
1297    int i, j, ind_srv;
1298    for (int ind = 0; ind < indi.numElements(); ind++)
1299    {
1300      i = indi(ind); j = indj(ind);
1301      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1302      area_srv(ind_srv) = clientArea(ind);
1303    }
1304  }
1305
1306  /*!
1307    Check whether a domain has transformation
1308    \return true if domain has transformation
1309  */
1310  bool CDomain::hasTransformation()
1311  {
1312    return (!transformationMap_.empty());
1313  }
1314
1315  /*!
1316    Set transformation for current domain. It's the method to move transformation in hierarchy
1317    \param [in] domTrans transformation on domain
1318  */
1319  void CDomain::setTransformations(const TransMapTypes& domTrans)
1320  {
1321    transformationMap_ = domTrans;
1322  }
1323
1324  /*!
1325    Get all transformation current domain has
1326    \return all transformation
1327  */
1328  CDomain::TransMapTypes CDomain::getAllTransformations(void)
1329  {
1330    return transformationMap_;
1331  }
1332
1333  /*!
1334    Check the validity of all transformations applied on domain
1335  This functions is called AFTER all inherited attributes are solved
1336  */
1337  void CDomain::checkTransformations()
1338  {
1339    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
1340                                  ite = transformationMap_.end();
1341    for (it = itb; it != ite; ++it)
1342    {
1343      (it->second)->checkValid(this);
1344    }
1345  }
1346
1347  /*!
1348    A current domain will go up the hierarchy to find out the domain from which it has transformation
1349  */
1350  void CDomain::solveInheritanceTransformation()
1351  {
1352    if (this->hasTransformation()) return;
1353
1354    std::vector<CDomain*> refDomain;
1355    CDomain* refer_sptr;
1356    CDomain* refer_ptr = this;
1357    while (refer_ptr->hasDirectDomainReference())
1358    {
1359      refDomain.push_back(refer_ptr);
1360      refer_sptr = refer_ptr->getDirectDomainReference();
1361      refer_ptr  = refer_sptr;
1362      if (refer_ptr->hasTransformation()) break;
1363    }
1364
1365    if (refer_ptr->hasTransformation())
1366      for (int idx = 0; idx < refDomain.size(); ++idx)
1367        refDomain[idx]->setTransformations(refer_ptr->getAllTransformations());
1368  }
1369
1370  /*!
1371    Parse children nodes of a domain in xml file.
1372    Whenver there is a new transformation, its type and name should be added into this function
1373    \param node child node to process
1374  */
1375  void CDomain::parse(xml::CXMLNode & node)
1376  {
1377    SuperClass::parse(node);
1378
1379    if (node.goToChildElement())
1380    {
1381      StdString zoomDomainDefRoot("zoom_domain_definition");
1382      StdString zoom("zoom_domain");
1383      StdString interpFromFileDomainDefRoot("interpolate_from_file_domain_definition");
1384      StdString interpFromFile("interpolate_from_file_domain");
1385      do
1386      {
1387        if (node.getElementName() == zoom) {
1388          CZoomDomain* tmp = (CZoomDomainGroup::get(zoomDomainDefRoot))->createChild();
1389          tmp->parse(node);
1390          transformationMap_.push_back(std::make_pair(TRANS_ZOOM_DOMAIN,tmp));
1391        }
1392        else if (node.getElementName() == interpFromFile)
1393        {
1394          CInterpolateFromFileDomain* tmp = (CInterpolateFromFileDomainGroup::get(interpFromFileDomainDefRoot))->createChild();
1395          tmp->parse(node);
1396          transformationMap_.push_back(std::make_pair(TRANS_INTERPOLATE_DOMAIN_FROM_FILE,tmp));
1397        }
1398      } while (node.goToNextElement()) ;
1399      node.goToParentElement();
1400    }
1401  }
1402   //----------------------------------------------------------------
1403
1404   DEFINE_REF_FUNC(Domain,domain)
1405
1406   ///---------------------------------------------------------------
1407
1408} // namespace xios
Note: See TracBrowser for help on using the repository browser.