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

Last change on this file since 633 was 633, checked in by mhnguyen, 6 years ago

Correcting value written on an distributed axis

+) Seperate writing value on axis in multiple file and one file case

Test
+) On curie
+) test_complet and test_client pass

  • 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
File size: 38.3 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
20namespace xios {
21
22   /// ////////////////////// Définitions ////////////////////// ///
23
24   CDomain::CDomain(void)
25      : CObjectTemplate<CDomain>(), CDomainAttributes()
26      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
27      , hasBounds(false), hasArea(false), isDistributed_(false)
28   { /* Ne rien faire de plus */ }
29
30   CDomain::CDomain(const StdString & id)
31      : CObjectTemplate<CDomain>(id), CDomainAttributes()
32      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
33      , hasBounds(false), hasArea(false), isDistributed_(false)
34         { /* Ne rien faire de plus */ }
35
36   CDomain::~CDomain(void)
37   {
38   }
39
40   ///---------------------------------------------------------------
41
42   CDomain* CDomain::createDomain()
43   {
44     CDomain* domain = CDomainGroup::get("domain_definition")->createChild();
45     return domain;
46   }
47
48   void CDomain::duplicateAttributes(CDomain* domain)
49   {
50     domain->setAttributes(this);
51   }
52
53   const std::set<StdString> & CDomain::getRelFiles(void) const
54   {
55      return (this->relFiles);
56   }
57
58   //----------------------------------------------------------------
59
60   bool CDomain::hasZoom(void) const
61   {
62      return ((this->zoom_ni.getValue() != this->ni_glo.getValue()) &&
63              (this->zoom_nj.getValue() != this->nj_glo.getValue()));
64   }
65
66   //----------------------------------------------------------------
67
68   bool CDomain::isEmpty(void) const
69   {
70      return ((this->zoom_ni_srv == 0) ||
71              (this->zoom_nj_srv == 0));
72   }
73
74   //----------------------------------------------------------------
75
76   bool CDomain::IsWritten(const StdString & filename) const
77   {
78      return (this->relFiles.find(filename) != this->relFiles.end());
79   }
80
81   //----------------------------------------------------------------
82
83   bool CDomain::isDistributed(void) const
84   {
85      return isDistributed_;
86   }
87
88   //----------------------------------------------------------------
89
90   void CDomain::addRelFile(const StdString & filename)
91   {
92      this->relFiles.insert(filename);
93   }
94
95
96   StdString CDomain::GetName(void)   { return (StdString("domain")); }
97   StdString CDomain::GetDefName(void){ return (CDomain::GetName()); }
98   ENodeType CDomain::GetType(void)   { return (eDomain); }
99
100   //----------------------------------------------------------------
101
102   void CDomain::checkDomain(void)
103   {
104      if (!type.isEmpty() && type==type_attr::unstructured)
105      {
106         if (ni_glo.isEmpty() || ni_glo <= 0 )
107         {
108            ERROR("CDomain::checkAttributes(void)",
109               << "[ Id = " << this->getId() << " ] "
110               << "The global domain is badly defined,"
111               << " check the \'ni_glo\'  value !")
112         }
113         nj_glo=ni_glo ;
114         ni_glo=1 ;
115         if (!ni.isEmpty()) nj=ni ;
116         if (!ibegin.isEmpty()) jbegin=ibegin ;
117         if (!iend.isEmpty()) jend=iend ;
118         if (!i_index.isEmpty())
119         {
120          j_index.resize(1,nj) ;
121          for(int i=0;i<ni;i++) j_index(0,i)=i_index(i,0) ;
122          i_index.resize(1,nj) ;
123          for(int j=0;j<nj;j++) i_index(0,j)=0 ;
124         }
125
126         if (!mask.isEmpty())
127         {
128          CArray<int,2> mask_tmp(nj,1) ;
129          mask_tmp = mask ;
130          mask.resize(1,nj) ;
131          for(int j=0;j<nj;j++) mask(0,j)=mask_tmp(j,0) ;
132         }
133
134         if (!area.isEmpty())
135           area.transposeSelf(1, 0);
136
137         ni=1 ;
138         ibegin=0 ;
139         iend=0 ;
140
141      }
142      else if ((ni_glo.isEmpty() || ni_glo.getValue() <= 0 ) ||
143          (nj_glo.isEmpty() || nj_glo.getValue() <= 0 ))
144      {
145         ERROR("CDomain::checkAttributes(void)",
146               << "[ Id = " << this->getId() << " ] "
147               << "The global domain is badly defined,"
148               << " check the \'ni_glo\' et \'nj_glo\' values !")
149      }
150
151      isDistributed_ = !ibegin.isEmpty() || !iend.isEmpty() || !ni.isEmpty() || !jbegin.isEmpty() || !jend.isEmpty() || !nj.isEmpty();
152
153      checkLocalIDomain();
154      checkLocalJDomain();
155
156      ibegin_client = ibegin; iend_client = iend; ni_client = ni;
157      jbegin_client = jbegin; jend_client = jend; nj_client = nj;
158
159      if (i_index.isEmpty())
160      {
161        i_index.resize(ni,nj);
162        for (int j = 0; j < nj; j++)
163          for (int i = 0; i < ni; i++) i_index(i,j) = i;
164      }
165
166      if (j_index.isEmpty())
167      {
168        j_index.resize(ni,nj);
169        for (int j = 0; j < nj; j++)
170          for (int i = 0; i < ni; i++) j_index(i,j) = j;
171      }
172   }
173
174   //----------------------------------------------------------------
175
176   void CDomain::checkLocalIDomain(void)
177   {
178      if (!ni.isEmpty() && !ibegin.isEmpty() && iend.isEmpty())
179        iend.setValue(ibegin.getValue() + ni.getValue() - 1);
180      else if (!ni.isEmpty() && !iend.isEmpty() && ibegin.isEmpty())
181        ibegin.setValue(iend.getValue() - ni.getValue()  + 1);
182      else if (!ibegin.isEmpty() && !iend.isEmpty() && ni.isEmpty())
183        ni.setValue(iend.getValue() - ibegin.getValue() + 1);
184      else if (!ibegin.isEmpty() && !iend.isEmpty() && !ni.isEmpty())
185      {
186        if (iend.getValue() != ibegin.getValue() + ni.getValue() - 1)
187          ERROR("CDomain::checkLocalIDomain(void)",
188                << "[ Id = " << this->getId() << " ] "
189                << "The local domain is wrongly defined,"
190                << " iend is different from (ibegin + ni - 1)");
191      }
192      else if (ibegin.isEmpty() && iend.isEmpty() && ni.isEmpty())
193      {
194        ibegin = 0;
195        iend = ni_glo - 1;
196        ni = ni_glo;
197      }
198      else
199      {
200        ERROR("CDomain::checkLocalIDomain(void)",
201              << "[ Id = " << this->getId() << " ] "
202              << "The local domain is wrongly defined,"
203              << " defining just one attribute among 'ibegin', 'iend' or 'ni' is invalid");
204      }
205
206      if (ni.getValue() < 0 || ibegin.getValue() > iend.getValue() ||
207          ibegin.getValue() < 0 || iend.getValue() > (ni_glo.getValue() - 1))
208      {
209        ERROR("CDomain::checkLocalIDomain(void)",
210              << "[ Id = " << this->getId() << " ] "
211              << "The local domain is wrongly defined,"
212              << " check the attributes 'ni_glo', 'ni', 'ibegin' and 'iend'");
213      }
214   }
215
216   //----------------------------------------------------------------
217
218   void CDomain::checkLocalJDomain(void)
219   {
220      if (!nj.isEmpty() && !jbegin.isEmpty() && jend.isEmpty())
221        jend.setValue(jbegin.getValue() + nj.getValue() - 1);
222      else if (!nj.isEmpty() && !jend.isEmpty() && jbegin.isEmpty())
223        jbegin.setValue(jend.getValue() - nj.getValue() + 1);
224      else if (!jbegin.isEmpty() && !jend.isEmpty() && nj.isEmpty())
225        nj.setValue(jend.getValue() - jbegin.getValue() + 1);
226      else if (!jbegin.isEmpty() && !jend.isEmpty() && !nj.isEmpty())
227      {
228        if (jend.getValue() != jbegin.getValue() + nj.getValue() - 1)
229          ERROR("CDomain::checkLocalJDomain(void)",
230                << "[ Id = " << this->getId() << " ] "
231                << "The local domain is wrongly defined,"
232                << " jend is different from (jbegin + nj - 1)");
233      }
234      else if (jbegin.isEmpty() && jend.isEmpty() && nj.isEmpty())
235      {
236        jbegin = 0;
237        jend = nj_glo - 1;
238        nj = nj_glo;
239      }
240      else
241      {
242        ERROR("CDomain::checkLocalJDomain(void)",
243              << "[ Id = " << this->getId() << " ] "
244              << "The local domain is wrongly defined,"
245              << " defining just one attribute among 'jbegin', 'jend' or 'nj' is invalid");
246      }
247
248      if (nj.getValue() < 0 || jbegin.getValue() > jend.getValue() ||
249          jbegin.getValue() < 0 || jend.getValue() > (nj_glo.getValue() - 1))
250      {
251        ERROR("CDomain::checkLocalJDomain(void)",
252              << "[ Id = " << this->getId() << " ] "
253              << "The local domain is wrongly defined,"
254              << " check the attributes 'nj_glo', 'nj', 'jbegin' and 'jend'");
255      }
256   }
257
258   //----------------------------------------------------------------
259
260   void CDomain::checkMask(void)
261   {
262      using namespace std;
263
264      int ibegin_mask = 0,
265          jbegin_mask = 0,
266          iend_mask = iend.getValue() - ibegin.getValue(),
267          jend_mask = jend.getValue() - jbegin.getValue();
268
269      if (!zoom_ibegin.isEmpty())
270      {
271         int zoom_iend = zoom_ibegin.getValue() + zoom_ni.getValue() - 1;
272         int zoom_jend = zoom_jbegin.getValue() + zoom_nj.getValue() - 1;
273
274         ibegin_mask = max (ibegin.getValue(), zoom_ibegin.getValue());
275         jbegin_mask = max (jbegin.getValue(), zoom_jbegin.getValue());
276         iend_mask   = min (iend.getValue(), zoom_iend);
277         jend_mask   = min (jend.getValue(), zoom_jend);
278
279         ibegin_mask -= ibegin.getValue();
280         jbegin_mask -= jbegin.getValue();
281         iend_mask   -= ibegin.getValue();
282         jend_mask   -= jbegin.getValue();
283      }
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      // Résolution et vérification des données globales de zoom.
521      if (!this->zoom_ni.isEmpty() || !this->zoom_nj.isEmpty() ||
522          !this->zoom_ibegin.isEmpty() || !this->zoom_jbegin.isEmpty())
523      {
524         if (this->zoom_ni.isEmpty()     || this->zoom_nj.isEmpty() ||
525             this->zoom_ibegin.isEmpty() || this->zoom_jbegin.isEmpty())
526         {
527            ERROR("CDomain::checkZoom(void)",
528                  <<"if one of zoom attributes is defined then all zoom attributes must be defined") ;
529         }
530         else
531         {
532            int zoom_iend = zoom_ibegin + zoom_ni - 1;
533            int zoom_jend = zoom_jbegin + zoom_nj - 1;
534
535            if (zoom_ibegin < 0  || zoom_jbegin < 0 || zoom_iend > (ni_glo-1) || zoom_jend > (nj_glo-1))
536               ERROR("CDomain::checkZoom(void)",
537                     << "Zoom is wrongly defined,"
538                     << " Check the values : zoom_ni, zoom_nj, zoom_ibegin, zoom_jbegin") ;
539         }
540      }
541      else
542      {
543         zoom_ni = ni_glo;
544         zoom_nj = nj_glo;
545         zoom_ibegin = 0;
546         zoom_jbegin = 0;
547      }
548
549      // compute client zoom indices
550      // compute client zoom indices
551      if (0 == global_zoom_ni) global_zoom_ni = ni_glo;
552      if (0 == global_zoom_nj) global_zoom_nj = nj_glo;
553
554      int global_zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
555      zoom_ibegin_client = ibegin_client > global_zoom_ibegin ? ibegin_client : global_zoom_ibegin ;
556      zoom_iend_client = iend_client < global_zoom_iend ? iend_client : global_zoom_iend ;
557      zoom_ni_client=zoom_iend_client-zoom_ibegin_client+1 ;
558      if (zoom_ni_client<0) zoom_ni_client=0 ;
559
560
561      int global_zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
562      zoom_jbegin_client = jbegin_client > global_zoom_jbegin ? jbegin_client : global_zoom_jbegin ;
563      zoom_jend_client = jend_client < global_zoom_jend ? jend_client : global_zoom_jend ;
564      zoom_nj_client=zoom_jend_client-zoom_jbegin_client+1 ;
565      if (zoom_nj_client<0) zoom_nj_client=0;
566   }
567
568   void CDomain::checkBounds(void)
569   {
570     if (!nvertex.isEmpty() && !bounds_lon.isEmpty() && !bounds_lat.isEmpty())
571     {
572       hasBounds=true ;
573     }
574     else
575     {
576       hasBounds=false;
577       nvertex=0 ;
578     }
579   }
580
581   void CDomain::checkArea(void)
582   {
583     hasArea = !area.isEmpty();
584     if (hasArea)
585     {
586       if (area.extent(0) != ni || area.extent(1) != nj)
587       {
588         ERROR("void CDomain::checkArea(void)",
589               "The area attribute must be of size ni x nj.");
590       }
591     }
592   }
593
594   //----------------------------------------------------------------
595   // Divide function checkAttributes into 2 seperate ones
596   // This function only checks all attributes of current domain
597   void CDomain::checkAttributesOnClient()
598   {
599     if (this->isClientChecked) return;
600     CContext* context=CContext::getCurrent();
601
602      this->checkDomain();
603      this->checkBounds();
604      this->checkArea();
605
606      if (context->hasClient)
607      { // CÃŽté client uniquement
608         this->checkMask();
609         this->checkDomainData();
610         this->checkCompression();
611      }
612      else
613      { // CÃŽté serveur uniquement
614//         if (!this->isEmpty())
615// ne sert plus //   this->completeLonLatServer();
616      }
617
618      this->isClientChecked = true;
619   }
620
621   // Send all checked attributes to server
622   void CDomain::sendCheckedAttributes()
623   {
624     if (!this->isClientChecked) checkAttributesOnClient();
625     CContext* context=CContext::getCurrent() ;
626
627     this->checkZoom();
628     if (this->isChecked) return;
629     if (context->hasClient)
630     {
631       this->computeConnectedServer();
632       this->completeLonLatClient();
633
634       sendServerAttribut() ;
635       sendLonLatArea() ;
636     }
637
638     this->isChecked = true;
639   }
640
641   void CDomain::checkAttributes(void)
642   {
643      if (this->isChecked) return;
644      CContext* context=CContext::getCurrent() ;
645
646      this->checkDomain();
647      this->checkZoom();
648      this->checkBounds();
649      this->checkArea();
650
651      if (context->hasClient)
652      { // CÃŽté client uniquement
653         this->checkMask();
654         this->checkDomainData();
655         this->checkCompression();
656         this->completeLonLatClient();
657      }
658      else
659      { // CÃŽté serveur uniquement
660//         if (!this->isEmpty())
661// ne sert plus //   this->completeLonLatServer();
662      }
663
664      if (context->hasClient)
665      {
666        computeConnectedServer() ;
667        sendServerAttribut() ;
668        sendLonLatArea() ;
669      }
670
671      this->isChecked = true;
672   }
673
674  void CDomain::sendServerAttribut(void)
675  {
676    std::vector<int> nGlobDomain(2);
677    nGlobDomain[0] = ni_glo.getValue();
678    nGlobDomain[1] = nj_glo.getValue();
679    CServerDistributionDescription serverDescription(nGlobDomain);
680
681    CContext* context = CContext::getCurrent();
682    CContextClient* client = context->client;
683    int nbServer = client->serverSize;
684
685    serverDescription.computeServerDistribution(nbServer);
686    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
687    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
688
689    CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
690    if (client->isServerLeader())
691    {
692      std::list<CMessage> msgs;
693
694      const std::list<int>& ranks = client->getRanksServerLeader();
695      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
696      {
697        // Use const int to ensure CMessage holds a copy of the value instead of just a reference
698        const int ibegin_srv = serverIndexBegin[*itRank][0];
699        const int jbegin_srv = serverIndexBegin[*itRank][1];
700        const int ni_srv = serverDimensionSizes[*itRank][0];
701        const int nj_srv = serverDimensionSizes[*itRank][1];
702        const int iend_srv = ibegin_srv + ni_srv - 1;
703        const int jend_srv = jbegin_srv + nj_srv - 1;
704
705        msgs.push_back(CMessage());
706        CMessage& msg = msgs.back();
707        msg << this->getId() ;
708        msg << ni_srv << ibegin_srv << iend_srv << nj_srv << jbegin_srv << jend_srv;
709        msg << global_zoom_ni << global_zoom_ibegin << global_zoom_nj << global_zoom_jbegin;
710
711        event.push(*itRank,1,msg);
712      }
713      client->sendEvent(event);
714    }
715    else client->sendEvent(event);
716  }
717
718  void CDomain::computeConnectedServer(void)
719  {
720    ibegin_client=ibegin ; iend_client=iend ; ni_client=ni ;
721    jbegin_client=jbegin ; jend_client=jend ; nj_client=nj ;
722
723    CContext* context=CContext::getCurrent() ;
724    CContextClient* client=context->client ;
725    int nbServer=client->serverSize;
726    bool doComputeGlobalIndexServer = true;
727
728    int i,j,i_ind,j_ind ;
729    int zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
730    int zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
731
732    // Precompute number of index
733    int globalIndexCountZoom = 0;
734    for(j=0;j<nj;j++)
735      for(i=0;i<ni;i++)
736      {
737        i_ind=ibegin+i_index(i,j) ;
738        j_ind=jbegin+j_index(i,j) ;
739
740        if (i_ind >= global_zoom_ibegin && i_ind <= zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= zoom_jend)
741        {
742          ++globalIndexCountZoom;
743        }
744      }
745
746    // Fill in index
747    CArray<size_t,1> globalIndexDomainZoom(globalIndexCountZoom);
748    CArray<size_t,1> globalIndexDomain(ni*nj);
749    size_t globalIndex;
750    int globalIndexCount = 0;
751    globalIndexCountZoom = 0;
752
753    for(j=0;j<nj;j++)
754      for(i=0;i<ni;i++)
755      {
756        i_ind=ibegin+i_index(i,j) ;
757        j_ind=jbegin+j_index(i,j) ;
758
759        globalIndex = i_ind + j_ind * ni_glo;
760        globalIndexDomain(globalIndexCount) = globalIndex;
761        ++globalIndexCount;
762        if (i_ind >= global_zoom_ibegin && i_ind <= zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= zoom_jend)
763        {
764          globalIndexDomainZoom(globalIndexCountZoom) = globalIndex;
765          ++globalIndexCountZoom;
766        }
767      }
768
769     std::vector<int> nGlobDomain(2);
770     nGlobDomain[0] = ni_glo.getValue();
771     nGlobDomain[1] = nj_glo.getValue();
772     size_t globalSizeIndex = 1, indexBegin, indexEnd;
773     int range, clientSize = client->clientSize;
774     for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i];
775     indexBegin = 0;
776     for (int i = 0; i < clientSize; ++i)
777     {
778       range = globalSizeIndex / clientSize;
779       if (i < (globalSizeIndex%clientSize)) ++range;
780       if (i == client->clientRank) break;
781       indexBegin += range;
782     }
783     indexEnd = indexBegin + range - 1;
784
785    CServerDistributionDescription serverDescription(nGlobDomain);
786    serverDescription.computeServerGlobalIndexInRange(nbServer, std::make_pair<size_t,size_t>(indexBegin, indexEnd));
787    CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(),
788                                                                                client->intraComm);
789    clientServerMap->computeServerIndexMapping(globalIndexDomain);
790    const std::map<int, std::vector<size_t> >& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
791
792    std::map<int, std::vector<size_t> >::const_iterator it = globalIndexDomainOnServer.begin(),
793                                                       ite = globalIndexDomainOnServer.end();
794    indSrv_.clear();
795    for (; it != ite; ++it)
796    {
797      int rank = it->first;
798      std::vector<size_t>::const_iterator itbVec  = (it->second).begin(),
799                                           iteVec = (it->second).end();
800      int nb = globalIndexDomainZoom.numElements();
801      for (int i = 0; i < nb; ++i)
802      {
803        if (iteVec != std::find(itbVec, iteVec, globalIndexDomainZoom(i)))
804        {
805          indSrv_[rank].push_back(globalIndexDomainZoom(i));
806        }
807      }
808    }
809
810    connectedServerRank_.clear();
811    for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) {
812      connectedServerRank_.push_back(it->first);
813    }
814
815    if (!indSrv_.empty())
816    {
817      connectedServerRank_.clear();
818      for (it = indSrv_.begin(); it != indSrv_.end(); ++it)
819        connectedServerRank_.push_back(it->first);
820    }
821    nbConnectedClients_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
822
823    delete clientServerMap;
824  }
825
826  void CDomain::sendLonLatArea(void)
827  {
828    int ns, n, i, j, ind, nv, idx;
829    CContext* context = CContext::getCurrent();
830    CContextClient* client=context->client;
831
832    // send lon lat for each connected server
833    CEventClient eventIndex(getType(), EVENT_ID_INDEX);
834    CEventClient eventLon(getType(), EVENT_ID_LON);
835    CEventClient eventLat(getType(), EVENT_ID_LAT);
836    CEventClient eventArea(getType(), EVENT_ID_AREA);
837
838    list<CMessage> list_msgsIndex, list_msgsLon, list_msgsLat, list_msgsArea;
839    list<CArray<int,1> > list_indi, list_indj;
840    list<CArray<double,1> > list_lon, list_lat;
841    list<CArray<double,2> > list_boundslon, list_boundslat;
842    list<CArray<double,1> > list_area;
843
844    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
845    iteMap = indSrv_.end();
846    for (int k = 0; k < connectedServerRank_.size(); ++k)
847    {
848      int nbData = 0;
849      int rank = connectedServerRank_[k];
850      it = indSrv_.find(rank);
851      if (iteMap != it)
852        nbData = it->second.size();
853
854      list_indi.push_back(CArray<int,1>(nbData));
855      list_indj.push_back(CArray<int,1>(nbData));
856      list_lon.push_back(CArray<double,1>(nbData));
857      list_lat.push_back(CArray<double,1>(nbData));
858
859      if (hasBounds)
860      {
861        list_boundslon.push_back(CArray<double,2>(nvertex, nbData));
862        list_boundslat.push_back(CArray<double,2>(nvertex, nbData));
863      }
864      if (hasArea)
865        list_area.push_back(CArray<double,1>(nbData));
866
867      CArray<int,1>& indi = list_indi.back();
868      CArray<int,1>& indj = list_indj.back();
869      CArray<double,1>& lon = list_lon.back();
870      CArray<double,1>& lat = list_lat.back();
871
872      for (n = 0; n < nbData; ++n)
873      {
874        idx = static_cast<int>(it->second[n]);
875        i = idx % ni_glo;
876        j = idx / ni_glo;
877        ind = (i - zoom_ibegin_client) + (j - zoom_jbegin_client) * zoom_ni_client;
878
879        lon(n) = lonvalue(ind);
880        lat(n) = latvalue(ind);
881
882        if (hasBounds)
883        {
884          CArray<double,2>& boundslon = list_boundslon.back();
885          CArray<double,2>& boundslat = list_boundslat.back();
886
887          for (nv = 0; nv < nvertex; nv++)
888          {
889            boundslon(nv, n) = bounds_lon(nv, ind);
890            boundslat(nv, n) = bounds_lat(nv, ind);
891          }
892        }
893
894        indi(n) = ibegin + i_index(i - ibegin, j - jbegin);
895        indj(n) = jbegin + j_index(i - ibegin, j - jbegin);
896
897        if (hasArea)
898          list_area.back()(n) = area(i - ibegin, j - jbegin);
899      }
900
901      list_msgsIndex.push_back(CMessage());
902
903      list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix
904      list_msgsIndex.back() << isCurvilinear;
905      list_msgsIndex.back() << list_indi.back() << list_indj.back();
906
907      list_msgsLon.push_back(CMessage());
908      list_msgsLat.push_back(CMessage());
909
910      list_msgsLon.back() << this->getId() << list_lon.back();
911      list_msgsLat.back() << this->getId() << list_lat.back();
912
913      if (hasBounds)
914      {
915        list_msgsLon.back() << list_boundslon.back();
916        list_msgsLat.back() << list_boundslat.back();
917      }
918
919      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
920      eventLon.push(rank, nbConnectedClients_[rank], list_msgsLon.back());
921      eventLat.push(rank, nbConnectedClients_[rank], list_msgsLat.back());
922
923      if (hasArea)
924      {
925        list_msgsArea.push_back(CMessage());
926        list_msgsArea.back() << this->getId() << list_area.back();
927        eventArea.push(rank, nbConnectedClients_[rank], list_msgsArea.back());
928      }
929    }
930
931    client->sendEvent(eventIndex);
932    client->sendEvent(eventLon);
933    client->sendEvent(eventLat);
934    if (hasArea)
935      client->sendEvent(eventArea);
936  }
937
938  bool CDomain::dispatchEvent(CEventServer& event)
939  {
940    if (SuperClass::dispatchEvent(event)) return true;
941    else
942    {
943      switch(event.type)
944      {
945        case EVENT_ID_SERVER_ATTRIBUT:
946          recvServerAttribut(event);
947          return true;
948          break;
949        case EVENT_ID_INDEX:
950          recvIndex(event);
951          return true;
952          break;
953        case EVENT_ID_LON:
954          recvLon(event);
955          return true;
956          break;
957        case EVENT_ID_LAT:
958          recvLat(event);
959          return true;
960          break;
961        case EVENT_ID_AREA:
962          recvArea(event);
963          return true;
964          break;
965        default:
966          ERROR("bool CContext::dispatchEvent(CEventServer& event)",
967                << "Unknown Event");
968          return false;
969       }
970    }
971  }
972
973  void CDomain::recvServerAttribut(CEventServer& event)
974  {
975    CBufferIn* buffer=event.subEvents.begin()->buffer;
976    string domainId ;
977    *buffer>>domainId ;
978    get(domainId)->recvServerAttribut(*buffer) ;
979  }
980
981  void CDomain::recvServerAttribut(CBufferIn& buffer)
982  {
983    buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv
984           >> global_zoom_ni >> global_zoom_ibegin >> global_zoom_nj >> global_zoom_jbegin;
985
986    int zoom_iend = global_zoom_ibegin + global_zoom_ni - 1;
987    int zoom_jend = global_zoom_jbegin + global_zoom_nj - 1;
988
989    zoom_ibegin_srv = global_zoom_ibegin > ibegin_srv ? global_zoom_ibegin : ibegin_srv ;
990    zoom_iend_srv = zoom_iend < iend_srv ? zoom_iend : iend_srv ;
991    zoom_ni_srv=zoom_iend_srv-zoom_ibegin_srv+1 ;
992
993    zoom_jbegin_srv = global_zoom_jbegin > jbegin_srv ? global_zoom_jbegin : jbegin_srv ;
994    zoom_jend_srv = zoom_jend < jend_srv ? zoom_jend : jend_srv ;
995    zoom_nj_srv=zoom_jend_srv-zoom_jbegin_srv+1 ;
996
997    if (zoom_ni_srv<=0 || zoom_nj_srv<=0)
998    {
999      zoom_ibegin_srv=0 ; zoom_iend_srv=0 ; zoom_ni_srv=0 ;
1000      zoom_jbegin_srv=0 ; zoom_jend_srv=0 ; zoom_nj_srv=0 ;
1001    }
1002    lonvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
1003    lonvalue_srv = 0. ;
1004    latvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
1005    latvalue_srv = 0. ;
1006    if (hasBounds)
1007    {
1008      bounds_lon_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
1009      bounds_lon_srv = 0. ;
1010      bounds_lat_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
1011      bounds_lat_srv = 0. ;
1012    }
1013
1014    if (hasArea)
1015      area_srv.resize(zoom_ni_srv * zoom_nj_srv);
1016  }
1017
1018  void CDomain::recvIndex(CEventServer& event)
1019  {
1020    list<CEventServer::SSubEvent>::iterator it;
1021    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1022    {
1023      CBufferIn* buffer = it->buffer;
1024      string domainId;
1025      *buffer >> domainId;
1026      get(domainId)->recvIndex(it->rank, *buffer);
1027    }
1028  }
1029
1030  void CDomain::recvIndex(int rank, CBufferIn& buffer)
1031  {
1032    int type_int;
1033    buffer >> type_int >> isCurvilinear >> indiSrv[rank] >> indjSrv[rank];
1034    type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix
1035  }
1036
1037  void CDomain::recvLon(CEventServer& event)
1038  {
1039    list<CEventServer::SSubEvent>::iterator it;
1040    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1041    {
1042      CBufferIn* buffer = it->buffer;
1043      string domainId;
1044      *buffer >> domainId;
1045      get(domainId)->recvLon(it->rank, *buffer);
1046    }
1047  }
1048
1049  void CDomain::recvLon(int rank, CBufferIn& buffer)
1050  {
1051    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1052    CArray<double,1> lon;
1053    CArray<double,2> boundslon;
1054
1055    buffer >> lon;
1056    if (hasBounds) buffer >> boundslon;
1057
1058    int i, j, ind_srv;
1059    for (int ind = 0; ind < indi.numElements(); ind++)
1060    {
1061      i = indi(ind); j = indj(ind);
1062      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1063      lonvalue_srv(ind_srv) = lon(ind);
1064      if (hasBounds)
1065      {
1066        for (int nv = 0; nv < nvertex; nv++)
1067          bounds_lon_srv(nv, ind_srv) = boundslon(nv, ind);
1068      }
1069    }
1070  }
1071
1072  void CDomain::recvLat(CEventServer& event)
1073  {
1074    list<CEventServer::SSubEvent>::iterator it;
1075    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1076    {
1077      CBufferIn* buffer = it->buffer;
1078      string domainId;
1079      *buffer >> domainId;
1080      get(domainId)->recvLat(it->rank, *buffer);
1081    }
1082  }
1083
1084  void CDomain::recvLat(int rank, CBufferIn& buffer)
1085  {
1086    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1087    CArray<double,1> lat;
1088    CArray<double,2> boundslat;
1089
1090    buffer >> lat;
1091    if (hasBounds) buffer >> boundslat;
1092
1093    int i, j, ind_srv;
1094    for (int ind = 0; ind < indi.numElements(); ind++)
1095    {
1096      i = indi(ind); j = indj(ind);
1097      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1098      latvalue_srv(ind_srv) = lat(ind);
1099      if (hasBounds)
1100      {
1101        for (int nv = 0; nv < nvertex; nv++)
1102          bounds_lat_srv(nv, ind_srv) = boundslat(nv, ind);
1103      }
1104    }
1105  }
1106
1107  void CDomain::recvArea(CEventServer& event)
1108  {
1109    list<CEventServer::SSubEvent>::iterator it;
1110    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
1111    {
1112      CBufferIn* buffer = it->buffer;
1113      string domainId;
1114      *buffer >> domainId;
1115      get(domainId)->recvArea(it->rank, *buffer);
1116    }
1117  }
1118
1119  void CDomain::recvArea(int rank, CBufferIn& buffer)
1120  {
1121    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
1122    CArray<double,1> clientArea;
1123
1124    buffer >> clientArea;
1125
1126    int i, j, ind_srv;
1127    for (int ind = 0; ind < indi.numElements(); ind++)
1128    {
1129      i = indi(ind); j = indj(ind);
1130      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
1131      area_srv(ind_srv) = clientArea(ind);
1132    }
1133  }
1134
1135  bool CDomain::hasTransformation()
1136  {
1137    return (!transformationMap_.empty());
1138  }
1139
1140  void CDomain::setTransformations(const TransMapTypes& domTrans)
1141  {
1142    transformationMap_ = domTrans;
1143  }
1144
1145  CDomain::TransMapTypes CDomain::getAllTransformations(void)
1146  {
1147    return transformationMap_;
1148  }
1149
1150  /*!
1151    Check the validity of all transformations applied on domain
1152  This functions is called AFTER all inherited attributes are solved
1153  */
1154  void CDomain::checkTransformations()
1155  {
1156    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
1157                                  ite = transformationMap_.end();
1158    for (it = itb; it != ite; ++it)
1159    {
1160      (it->second)->checkValid(this);
1161    }
1162  }
1163
1164  void CDomain::solveInheritanceTransformation()
1165  {
1166    if (this->hasTransformation()) return;
1167
1168    std::vector<CDomain*> refDomain;
1169    CDomain* refer_sptr;
1170    CDomain* refer_ptr = this;
1171    while (refer_ptr->hasDirectDomainReference())
1172    {
1173      refDomain.push_back(refer_ptr);
1174      refer_sptr = refer_ptr->getDirectDomainReference();
1175      refer_ptr  = refer_sptr;
1176      if (refer_ptr->hasTransformation()) break;
1177    }
1178
1179    if (refer_ptr->hasTransformation())
1180      for (int idx = 0; idx < refDomain.size(); ++idx)
1181        refDomain[idx]->setTransformations(refer_ptr->getAllTransformations());
1182  }
1183
1184  void CDomain::parse(xml::CXMLNode & node)
1185  {
1186    SuperClass::parse(node);
1187
1188    if (node.goToChildElement())
1189    {
1190      StdString zoomDomainDefRoot("zoom_domain_definition");
1191      StdString zoom("zoom_domain");
1192      do
1193      {
1194        if (node.getElementName() == zoom) {
1195          CZoomDomain* tmp = (CZoomDomainGroup::get(zoomDomainDefRoot))->createChild();
1196          tmp->parse(node);
1197          transformationMap_.push_back(std::make_pair(TRANS_ZOOM_DOMAIN,tmp));
1198        }
1199      } while (node.goToNextElement()) ;
1200      node.goToParentElement();
1201    }
1202  }
1203   //----------------------------------------------------------------
1204
1205   DEFINE_REF_FUNC(Domain,domain)
1206
1207   ///---------------------------------------------------------------
1208
1209} // namespace xios
Note: See TracBrowser for help on using the repository browser.