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

Last change on this file since 660 was 660, checked in by mhnguyen, 7 years ago

Adding interpolation test_remap

+) Add new test case for domain interpolation
+) Resolve circular dependence
+) Add function to read weigh file

Test
+) On Curie
+) test_remap can print out .nc

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