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

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

Change name of several axis attributes and remove some redundant variable of domain

+) Change name of axis attributes to make them consistent with ones of domain
+) Remove zoom_client_* of domain

Test
+) On Curie
+) All tests pass and are correct

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