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

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

Making changes in domain to make sure unstructed grid work with new method of index distribution

+) Change the way define i_index and j_index of a domain
+) Remove some redundant attributes of domain
+) Adjust the way to calculate index distribution on server side

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