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

Last change on this file since 643 was 635, checked in by rlacroix, 9 years ago

Domain: Fix the initialization of some member variables.

This could cause XIOS to randomly misbehave.

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