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

Last change on this file since 594 was 594, checked in by rlacroix, 10 years ago

Change the definition of non distributed axis and domain.

Axis and domain were considered non distributed if the local domain matched the full domain. Instead allow the local domain definition to be ommited and consider the axis or domain to be non distributed in this case.

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