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

Last change on this file since 663 was 663, checked in by mhnguyen, 8 years ago

Correcting minor bugs on processing domain transformation

+) Correct domain index calculation in domain transformation
+) Offset index of weight file to make test_remap work correctly

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