source: XIOS/dev/dev_ym/XIOS_COUPLING/src/node/grid.cpp @ 2264

Last change on this file since 2264 was 2264, checked in by ymipsl, 3 years ago

Scalar can be now distributed on server side, avoiding incorrect result coming from redondant nature of scalar grid.
YM

  • Property copyright set to
    Software name : XIOS (Xml I/O Server)
    http://forge.ipsl.jussieu.fr/ioserver
    Creation date : January 2009
    Licence : CeCCIL version2
    see license file in root directory : Licence_CeCILL_V2-en.txt
    or http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
    Holder : CEA/LSCE (Laboratoire des Sciences du CLimat et de l'Environnement)
    CNRS/IPSL (Institut Pierre Simon Laplace)
    Project Manager : Yann Meurdesoif
    yann.meurdesoif@cea.fr
  • Property svn:executable set to *
File size: 80.4 KB
Line 
1
2#include "grid.hpp"
3
4#include "attribute_template.hpp"
5#include "object_template.hpp"
6#include "group_template.hpp"
7#include "message.hpp"
8#include <iostream>
9#include "xios_spl.hpp"
10#include "type.hpp"
11#include "context.hpp"
12#include "context_client.hpp"
13#include "context_server.hpp"
14#include "array_new.hpp"
15#include "server_distribution_description.hpp"
16#include "client_server_mapping_distributed.hpp"
17#include "distribution_client.hpp"
18#include "server.hpp"
19#include "distribution_type.hpp"
20#include "grid_client_server_remote_connector.hpp"
21#include "grid_elements.hpp"
22#include "grid_local_view.hpp"
23#include "grid_mask_connector.hpp"
24#include "transformation_path.hpp"
25#include "grid_transformation_factory_impl.hpp"
26#include "transform_filter.hpp"
27#include "grid_algorithm.hpp"
28#include "grid_algorithm_generic.hpp"
29#include "generic_algorithm_transformation.hpp"
30#include "algo_types.hpp"
31
32#include <regex>
33
34namespace xios
35{
36
37   /// ////////////////////// Dfinitions ////////////////////// ///
38
39   CGrid::CGrid(void)
40      : CObjectTemplate<CGrid>(), CGridAttributes()
41      , isChecked(false), isDomainAxisChecked(false)
42      , vDomainGroup_(), domList_(), isDomListSet(false)
43      , vAxisGroup_(), axisList_(), isAxisListSet(false)
44      , vScalarGroup_(), scalarList_(), isScalarListSet(false)
45      , clientDistribution_(0), isIndexSent(false)
46      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_()
47            , isCompressible_(false)
48      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
49      , gridSrc_(), order_()
50      , clients()
51   {
52     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
53     setVirtualAxisGroup(CAxisGroup::create(getId() + "_virtual_axis_group"));
54     setVirtualScalarGroup(CScalarGroup::create(getId() + "_virtual_scalar_group"));
55   }
56
57   CGrid::CGrid(const StdString& id)
58      : CObjectTemplate<CGrid>(id), CGridAttributes()
59      , isChecked(false), isDomainAxisChecked(false)
60      , vDomainGroup_(), domList_(), isDomListSet(false)
61      , vAxisGroup_(), axisList_(), isAxisListSet(false)
62      , vScalarGroup_(), scalarList_(), isScalarListSet(false)
63      , clientDistribution_(0), isIndexSent(false)
64      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_()
65            , isCompressible_(false)
66      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false)
67      , gridSrc_(), order_()
68      , clients()
69   {
70     setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
71     setVirtualAxisGroup(CAxisGroup::create(getId() + "_virtual_axis_group"));
72     setVirtualScalarGroup(CScalarGroup::create(getId() + "_virtual_scalar_group"));
73   }
74
75   CGrid::~CGrid(void)
76   {
77    if (0 != clientDistribution_) delete clientDistribution_;
78   }
79
80   ///---------------------------------------------------------------
81
82   StdString CGrid::GetName(void)    { return StdString("grid"); }
83   StdString CGrid::GetDefName(void) { return CGrid::GetName(); }
84   ENodeType CGrid::GetType(void)    { return eGrid; }
85
86
87  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
88  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
89  /////////              MEMBER FUNCTION RELATED TO GRID CONSTRUCTION by ELEMNTS AND MANAGEMENT                      /////
90  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
92
93
94   CGrid* CGrid::createGrid(CDomain* domain)
95   TRY
96   {
97     std::vector<CDomain*> vecDom(1, domain);
98     std::vector<CAxis*> vecAxis;
99     return createGrid(vecDom, vecAxis);
100   }
101   CATCH
102
103   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis)
104   TRY
105  {
106      std::vector<CDomain*> vecDom(1, domain);
107      std::vector<CAxis*> vecAxis(1, axis);
108
109      return createGrid(vecDom, vecAxis);
110   }
111   CATCH
112
113   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
114                            const CArray<int,1>& axisDomainOrder)
115   TRY
116   {
117     std::vector<CScalar*> vecScalar;
118     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder);
119   }
120   CATCH
121
122   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
123                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
124   TRY
125   {
126     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder);
127   }
128   CATCH
129
130   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
131                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
132   TRY
133   {
134      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
135        ERROR("CGrid* CGrid::createGrid(...)",
136              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
137              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
138
139      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id);
140      grid->setDomainList(domains);
141      grid->setAxisList(axis);
142      grid->setScalarList(scalars);
143
144      // By default, domains are always the first elements of a grid
145      if (0 == axisDomainOrder.numElements())
146      {
147        int size = domains.size() + axis.size() + scalars.size();
148        int nb = 0;
149        grid->axis_domain_order.resize(size);
150        for (int i = 0; i < size; ++i)
151        {
152          if (i < domains.size())
153          {
154            grid->axis_domain_order(i) = 2;
155            grid->order_.push_back(2) ;
156          }
157          else if ((scalars.size() < (size-nb)) < size)
158          {
159            grid->axis_domain_order(i) = 1;
160            grid->order_.push_back(1) ;
161          }
162          else
163          {
164            grid->axis_domain_order(i) = 0;
165            grid->order_.push_back(0) ;
166          }
167          ++nb;
168        }
169      }
170      else
171      {
172        grid->axis_domain_order.resize(axisDomainOrder.numElements());
173        grid->axis_domain_order = axisDomainOrder;
174        grid->order_.clear() ;
175        for(int i=0; i<axisDomainOrder.numElements();i++) grid->order_.push_back(axisDomainOrder(i)) ;
176
177      }
178     
179 //     grid->solveElementsRefInheritance(true);
180      grid->computeElements() ;
181      return grid;
182   }
183   CATCH
184
185   //----------------------------------------------------------------
186
187   //! Change virtual field group to a new one
188   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
189   TRY
190   {
191      this->vDomainGroup_ = newVDomainGroup;
192   }
193   CATCH_DUMP_ATTR
194
195   //! Change virtual variable group to new one
196   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
197   TRY
198   {
199      this->vAxisGroup_ = newVAxisGroup;
200   }
201   CATCH_DUMP_ATTR
202
203   //! Change virtual variable group to new one
204   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup)
205   TRY
206   {
207      this->vScalarGroup_ = newVScalarGroup;
208   }
209   CATCH_DUMP_ATTR
210
211   //----------------------------------------------------------------
212
213   CDomainGroup* CGrid::getVirtualDomainGroup() const
214   TRY
215   {
216     return this->vDomainGroup_;
217   }
218   CATCH
219
220   CAxisGroup* CGrid::getVirtualAxisGroup() const
221   TRY
222   {
223     return this->vAxisGroup_;
224   }
225   CATCH
226
227   CScalarGroup* CGrid::getVirtualScalarGroup() const
228   TRY
229   {
230     return this->vScalarGroup_;
231   }
232   CATCH
233
234  ///---------------------------------------------------------------
235
236   CDomain* CGrid::addDomain(const std::string& id)
237   TRY
238   {
239     order_.push_back(2);
240     axis_domain_order.resize(order_.size());
241     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
242     CDomain* domain = vDomainGroup_->createChild(id);
243     isDomListSet=false ;
244     computeElements();
245     return domain ;
246   }
247   CATCH_DUMP_ATTR
248
249   CAxis* CGrid::addAxis(const std::string& id)
250   TRY
251   {
252     order_.push_back(1);
253     axis_domain_order.resize(order_.size());
254     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
255     CAxis* axis=vAxisGroup_->createChild(id);
256     isAxisListSet=false ;
257     computeElements(); 
258     return axis ;
259   }
260   CATCH_DUMP_ATTR
261
262   CScalar* CGrid::addScalar(const std::string& id)
263   TRY
264   {
265     order_.push_back(0);
266     axis_domain_order.resize(order_.size());
267     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx];
268     CScalar* scalar =  vScalarGroup_->createChild(id);
269     isScalarListSet=false ;
270     computeElements();
271     return scalar;
272   }
273   CATCH_DUMP_ATTR
274
275
276
277
278  /*!
279  \brief Get the list of domain pointers
280  \return list of domain pointers
281  */
282  std::vector<CDomain*> CGrid::getDomains()
283  TRY
284  {
285    setDomainList();
286    std::vector<CDomain*> domList;
287    if (!domList_.empty())
288    {
289      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
290    }
291    return domList;
292  }
293  CATCH_DUMP_ATTR
294
295  /*!
296  \brief Get the list of  axis pointers
297  \return list of axis pointers
298  */
299  std::vector<CAxis*> CGrid::getAxis()
300  TRY
301  {
302    setAxisList();
303    std::vector<CAxis*> aList;
304    if (!axisList_.empty())
305      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
306
307    return aList;
308  }
309  CATCH_DUMP_ATTR
310
311  /*!
312  \brief Get the list of  axis pointers
313  \return list of axis pointers
314  */
315  std::vector<CScalar*> CGrid::getScalars()
316  TRY
317  {
318    setScalarList() ;
319    std::vector<CScalar*> sList;
320    if (!scalarList_.empty())
321      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i]));
322
323    return sList;
324  }
325  CATCH_DUMP_ATTR
326
327  /*!
328  \brief Get domain pointer with index
329  \return domain pointer
330  */
331  CDomain* CGrid::getDomain(int domainIndex)
332  TRY
333  {
334    std::vector<CDomain*> domainListP = this->getDomains();
335    if (domainListP.empty())
336    {
337      ERROR("CGrid::getDomain(int domainIndex)",
338            << "No domain associated to this grid. " << std::endl
339            << "Grid id = " << this->getId());
340    }
341
342    if (domainIndex >= domainListP.size() || (domainIndex < 0))
343      ERROR("CGrid::getDomain(int domainIndex)",
344            << "Domain with the index doesn't exist " << std::endl
345            << "Grid id = " << this->getId() << std::endl
346            << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl);
347
348    return domainListP[domainIndex];
349  }
350  CATCH_DUMP_ATTR
351
352  /*!
353  \brief Get the axis pointer with index
354  \return axis pointer
355  */
356  CAxis* CGrid::getAxis(int axisIndex)
357  TRY
358  {
359    std::vector<CAxis*> axisListP = this->getAxis();
360    if (axisListP.empty())
361    {
362      ERROR("CGrid::getDomain(int axisIndex)",
363            << "No axis associated to this grid. " << std::endl
364            << "Grid id = " << this->getId());
365    }
366
367    if (axisIndex >= axisListP.size() || (axisIndex < 0))
368      ERROR("CGrid::getDomain(int axisIndex)",
369            << "Domain with the index doesn't exist " << std::endl
370            << "Grid id = " << this->getId() << std::endl
371            << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl);
372
373    return axisListP[axisIndex];
374  }
375  CATCH_DUMP_ATTR
376
377  /*!
378  \brief Get the a scalar pointer
379  \return scalar pointer
380  */
381  CScalar* CGrid::getScalar(int scalarIndex)
382  TRY
383  {
384    std::vector<CScalar*> scalarListP = this->getScalars();
385    if (scalarListP.empty())
386    {
387      ERROR("CGrid::getScalar(int scalarIndex)",
388            << "No scalar associated to this grid. " << std::endl
389            << "Grid id = " << this->getId());
390    }
391
392    if (scalarIndex >= scalarListP.size() || (scalarIndex < 0))
393      ERROR("CGrid::getScalar(int scalarIndex)",
394            << "Scalar with the index doesn't exist " << std::endl
395            << "Grid id = " << this->getId() << std::endl
396            << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl);
397
398    return scalarListP[scalarIndex];
399  }
400  CATCH_DUMP_ATTR
401
402  CDomain* CGrid::getAssociatedDomain(const string& domainId, bool noError)
403  {
404    const regex r("\\[[0-9]*\\]");
405    smatch m;
406    string id=domainId ;
407    int pos=-1 ;
408    if (regex_search(domainId, m, r))
409    {
410        if (m.size()!=1) ERROR("CGrid::getAssociatedDomain(const string& domainId)", <<" domainId = "<<domainId<< "  -> bad format id, separator [] append more than one time");
411        id=m.prefix() ;
412        pos = stoi(m.str(0).substr(1,m.str(0).size()-2)) ;
413    }
414    std::vector<CDomain*> domainList = this->getDomains();
415    if (domainList.empty()) 
416      if (noError) return nullptr ;
417      else ERROR("CGrid::getAssociatedDomain(const string& domainId)", <<"no domain is composing the grid");
418    if (id.empty())
419    {
420      if (pos==-1)
421      {
422        if (domainList.size()==1) return domainList[0] ;
423        else 
424          if (noError) return nullptr ;
425          else ERROR("CGrid::getAssociatedDomain(const string& domainId)", <<"the grid contain more than 1 domain, use [#n] to specify which one must be retrieved");
426      }
427      else
428      {
429        if (domainList.size()>pos) return domainList[pos] ;
430        else if (noError) return nullptr ;
431        else ERROR("CGrid::getAssociatedDomain(const string& domainId)", <<"the position of the requested domain [ pos = "<<pos
432                   <<" ] is greater than the number of domain composing the grid  [ numDomain = "<<domainList.size()<<" ]");
433      }
434    }
435    else
436    {
437      if (pos==-1) 
438      {
439        int nbDomain=0 ;
440        for(int i=0; i<domainList.size();i++) if (domainList[i]->getTemplateId()==id) nbDomain++ ;
441        if (nbDomain>1) 
442          if (noError) return nullptr ;
443          else ERROR("CGrid::getAssociatedDomain(const string& domainId)", <<"no domain with the id = "<<id
444                              <<" is composing the grid") ;
445        if (nbDomain==0) 
446          if (noError) return nullptr ;
447          else ERROR("CGrid::getAssociatedDomain(const string& domainId)", <<"the grid contain more than 1 domain with the id = "
448                               <<id<<" , use [#n] to specify which one must be retrieved") ;
449        for(int i=0; i<domainList.size();i++) if (domainList[i]->getTemplateId()==id) return domainList[i]  ;
450      }
451      else
452      {
453        int currentPos=0 ;
454        for(int i=0; i<domainList.size();i++) 
455        {
456          if (domainList[i]->getTemplateId()==id && pos==currentPos) return domainList[i] ;
457          currentPos++ ;
458        }
459        if (noError) return nullptr ; 
460        else ERROR("CGrid::getAssociatedDomain(const string& domainId)",<<"Cannot find domain with [ id = "<< id <<" ] at [ pos = "<<pos<<" ] in the grid");
461      } 
462    }
463  } 
464
465  CAxis* CGrid::getAssociatedAxis(const string& axisId, bool noError)
466  {
467    const regex r("\\[[0-9]*\\]");
468    smatch m;
469    string id=axisId ;
470    int pos=-1 ;
471    if (regex_search(axisId, m, r))
472    {
473        if (m.size()!=1) ERROR("CGrid::getAssociatedAxis(const string& axisId)", <<" axisId = "<<axisId<< "  -> bad format id, separator [] append more than one time");
474        id=m.prefix() ;
475        pos = stoi(m.str(0).substr(1,m.str(0).size()-2)) ;
476    }
477    std::vector<CAxis*> axisList = this->getAxis();
478    if (axisList.empty())
479      if (noError) return nullptr;
480      else ERROR("CGrid::getAssociatedAxis(const string& AxisId)", <<"no axis is composing the grid");
481    if (id.empty())
482    {
483      if (pos==-1)
484      {
485        if (axisList.size()==1) return axisList[0] ;
486        else 
487          if (noError) return nullptr;
488          else ERROR("CGrid::getAssociatedAxis(const string& axisId)", <<"the grid contain more than 1 axis, use [#n] to specify which one must be retrieved");
489      }
490      else
491      {
492        if (axisList.size()>pos) return axisList[pos] ;
493        else
494          if (noError) return nullptr;
495          else ERROR("CGrid::getAssociatedAxis(const string& axisId)", <<"the position of the requested axis [ pos = "<<pos
496                   <<" ] is greater than the number of axis composing the grid  [ numAxis = "<<axisList.size()<<" ]");
497      }
498    }
499    else
500    {
501      if (pos==-1) 
502      {
503        int nbAxis=0 ;
504        for(int i=0; i<axisList.size();i++) if (axisList[i]->getTemplateId()==id) nbAxis++ ;
505        if (nbAxis>1) 
506          if (noError) return nullptr;
507          else ERROR("CGrid::getAssociatedAxis(const string& axisId)", <<"no axis with the id = "<<id
508                              <<" is composing the grid") ;
509        if (nbAxis==0) 
510          if (noError) return nullptr;
511          else ERROR("CGrid::getAssociatedAxis(const string& axisId)", <<"the grid contain more than 1 axis with the id = "
512                               <<id<<" , use [#n] to specify which one must be retrieved") ;
513        for(int i=0; i<axisList.size();i++) if (axisList[i]->getTemplateId()==id) return axisList[i]  ;
514      }
515      else
516      {
517        int currentPos=0 ;
518        for(int i=0; i<axisList.size();i++) 
519        {
520          if (axisList[i]->getTemplateId()==id && pos==currentPos) return axisList[i] ;
521          currentPos++ ;
522        }
523        if (noError) return nullptr;
524        else ERROR("CGrid::getAssociatedAxis(const string& axisId)",<<"Cannot find axis with [ id = "<< id <<" ] at [ pos = "<<pos<<" ] in the grid");
525      } 
526    }
527  } 
528
529  CScalar* CGrid::getAssociatedScalar(const string& scalarId, bool noError)
530  {
531    const regex r("\\[[0-9]*\\]");
532    smatch m;
533    string id=scalarId ;
534    int pos=-1 ;
535    if (regex_search(scalarId, m, r))
536    {
537        if (m.size()!=1) ERROR("CGrid::getAssociatedScalar(const string& scalarId)", <<" scalarId = "<<scalarId<< "  -> bad format id, separator [] append more than one time");
538        id=m.prefix() ;
539        pos = stoi(m.str(0).substr(1,m.str(0).size()-2)) ;
540    }
541    std::vector<CScalar*> scalarList = this->getScalars();
542    if (scalarList.empty()) 
543      if (noError) return nullptr;
544      else ERROR("CGrid::getAssociatedScalar(const string& scalarId)", <<"no scalar is composing the grid");
545    if (id.empty())
546    {
547      if (pos==-1)
548      {
549        if (scalarList.size()==1) return scalarList[0] ;
550        else 
551          if (noError) return nullptr;
552          else ERROR("CGrid::getAssociatedScalar(const string& scalarId)", <<"the grid contain more than 1 scalar, use [#n] to specify which one must be retrieved");
553      }
554      else
555      {
556        if (scalarList.size()>pos) return scalarList[pos] ;
557        else 
558          if (noError) return nullptr;
559          else ERROR("CGrid::getAssociatedScalar(const string& scalarId)", <<"the position of the requested scalar [ pos = "<<pos
560                   <<" ] is greater than the number of scalar composing the grid  [ numScalar = "<<scalarList.size()<<" ]");
561      }
562    }
563    else
564    {
565      if (pos==-1) 
566      {
567        int nbScalar=0 ;
568        for(int i=0; i<scalarList.size();i++) if (scalarList[i]->getTemplateId()==id) nbScalar++ ;
569        if (nbScalar>1) 
570          if (noError) return nullptr;
571          else ERROR("CGrid::getAssociatedScalar(const string& scalarId)", <<"no scalar with the id = "<<id
572                              <<" is composing the grid") ;
573        if (nbScalar==0) 
574          if (noError) return nullptr;
575          else ERROR("CGrid::getAssociatedScalar(const string& scalarId)", <<"the grid contain more than 1 scalar with the id = "
576                               <<id<<" , use [#n] to specify which one must be retrieved") ;
577        for(int i=0; i<scalarList.size();i++) if (scalarList[i]->getTemplateId()==id) return scalarList[i]  ;
578      }
579      else
580      {
581        int currentPos=0 ;
582        for(int i=0; i<scalarList.size();i++) 
583        {
584          if (scalarList[i]->getTemplateId()==id && pos==currentPos) return scalarList[i] ;
585          currentPos++ ;
586        }
587        if (noError) return nullptr;
588        else ERROR("CGrid::getAssociatedScalar(const string& scalarId)",<<"Cannot find scalar with [ id = "<< id <<" ] at [ pos = "<<pos<<" ] in the grid");
589      } 
590    }
591  } 
592
593
594  /*!
595  \brief Set domain(s) of a grid from a list
596  \param[in] domains list of domains
597  */
598  void CGrid::setDomainList(const std::vector<CDomain*> domains)
599  TRY
600  {
601    if (isDomListSet) return;
602    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
603    if (!domains.empty() && domList.empty())
604    {
605      for (int i = 0; i < domains.size(); ++i)
606        this->getVirtualDomainGroup()->addChild(domains[i]);
607      domList = this->getVirtualDomainGroup()->getAllChildren();
608    }
609
610    if (!domList.empty())
611    {
612      int sizeDom = domList.size();
613      domList_.resize(sizeDom);
614      for (int i = 0; i < sizeDom; ++i)
615      {
616        domList_[i] = domList[i]->getId();
617      }
618      isDomListSet = true;
619    }
620  }
621  CATCH_DUMP_ATTR
622
623  /*!
624  \brief Set axis(s) of a grid from a list
625  \param[in] axis list of axis
626  */
627  void CGrid::setAxisList(const std::vector<CAxis*> axis)
628  TRY
629  {
630    if (isAxisListSet) return;
631    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
632    if (!axis.empty() && aList.empty())
633    {
634      for (int i = 0; i < axis.size(); ++i)
635        this->getVirtualAxisGroup()->addChild(axis[i]);
636      aList = this->getVirtualAxisGroup()->getAllChildren();
637    }
638
639    if (!aList.empty())
640    {
641      int sizeAxis = aList.size();
642      axisList_.resize(sizeAxis);
643      for (int i = 0; i < sizeAxis; ++i)
644      {
645        axisList_[i] = aList[i]->getId();
646      }
647      isAxisListSet = true;
648    }
649  }
650  CATCH_DUMP_ATTR
651
652  /*!
653  \brief Set scalar(s) of a grid from a list
654  \param[in] scalars list of scalars
655  */
656  void CGrid::setScalarList(const std::vector<CScalar*> scalars)
657  TRY
658  {
659    if (isScalarListSet) return;
660    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren();
661    if (!scalars.empty() && sList.empty())
662    {
663      for (int i = 0; i < scalars.size(); ++i)
664        this->getVirtualScalarGroup()->addChild(scalars[i]);
665      sList = this->getVirtualScalarGroup()->getAllChildren();
666    }
667
668    if (!sList.empty())
669    {
670      int sizeScalar = sList.size();
671      scalarList_.resize(sizeScalar);
672      for (int i = 0; i < sizeScalar; ++i)
673      {
674        scalarList_[i] = sList[i]->getId();
675      }
676      isScalarListSet = true;
677    }
678  }
679  CATCH_DUMP_ATTR
680
681  /*!
682  \brief Get list of id of domains
683  \return id list of domains
684  */
685  std::vector<StdString> CGrid::getDomainList()
686  TRY
687  {
688    setDomainList();
689    return domList_;
690  }
691  CATCH
692
693  /*!
694  \brief Get list of id of axis
695  \return id list of axis
696  */
697  std::vector<StdString> CGrid::getAxisList()
698  TRY
699  {
700    setAxisList();
701    return axisList_;
702  }
703  CATCH
704
705  /*!
706  \brief Get list of id of scalar
707  \return id list of scalar
708  */
709  std::vector<StdString> CGrid::getScalarList()
710  TRY
711  {
712    setScalarList();
713    return scalarList_;
714  }
715  CATCH
716
717
718  void CGrid::computeElements(void)
719  {
720    const auto& domains = getDomains() ;
721    const auto& axis = getAxis() ;
722    const auto& scalars = getScalars() ;
723    int idxDomain = 0, idxAxis=0 , idxScalar=0 ; 
724 
725    elements_.clear() ;
726    for(auto type : order_)
727    {
728      if      (type == 0) { elements_.push_back({scalars[idxScalar], TYPE_SCALAR, scalars[idxScalar], nullptr, nullptr } ) ; idxScalar++;}
729      else if (type == 1) { elements_.push_back({axis[idxAxis], TYPE_AXIS, nullptr, axis[idxAxis], nullptr}) ; idxAxis++;}
730      else if (type == 2) { elements_.push_back({domains[idxDomain], TYPE_DOMAIN, nullptr, nullptr, domains[idxDomain] }) ; idxDomain++;}       
731    }
732    elementsComputed_ = true ;
733  }
734 
735 
736 /*!
737    Parse a grid, for now, it contains only domain, axis and scalar
738  */
739  void CGrid::parse(xml::CXMLNode& node)
740  TRY
741  {
742    SuperClass::parse(node);
743
744    if (node.goToChildElement())
745    {
746      StdString domainName("domain");
747      StdString axisName("axis");
748      StdString scalarName("scalar");
749      do
750      {
751        if (node.getElementName() == domainName) {
752          order_.push_back(2);
753          this->getVirtualDomainGroup()->parseChild(node);
754        }
755        if (node.getElementName() == axisName) {
756          order_.push_back(1);
757          this->getVirtualAxisGroup()->parseChild(node);
758        }
759        if (node.getElementName() == scalarName) {
760          order_.push_back(0);
761          this->getVirtualScalarGroup()->parseChild(node);
762        }
763      } while (node.goToNextElement());
764      node.goToParentElement();
765    }
766
767    if (!order_.empty())
768    {
769      int sizeOrd = order_.size();
770      axis_domain_order.resize(sizeOrd);
771      for (int i = 0; i < sizeOrd; ++i)
772      {
773        axis_domain_order(i) = order_[i];
774      }
775    }
776
777    setDomainList();
778    setAxisList();
779    setScalarList();
780    computeElements() ;
781   }
782   CATCH_DUMP_ATTR
783
784
785  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
786  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
787  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
788  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
789
790
791
792   StdSize CGrid::getDimension(void)
793   TRY
794   {
795      return getGlobalDimension().size();
796   }
797   CATCH_DUMP_ATTR
798
799   //---------------------------------------------------------------
800
801   StdSize CGrid::getDataSize(void) 
802   TRY
803   {
804     StdSize retvalue = 1;
805     if (!isScalarGrid())
806     {
807       std::vector<int> dataNindex = getClientDistribution()->getDataNIndex();
808       for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];       
809     }
810     return retvalue;
811   }
812   CATCH
813   
814   /*!
815    * Get the local data grid size, ie the size of the compressed grid (inside the workflow)
816    * \return The size od the compressed grid
817    */
818    StdSize  CGrid::getLocalDataSize(void) { return getClientDistribution()->getLocalDataSize();}
819
820
821   /*!
822    * Compute the minimum buffer size required to send the attributes to the server(s).
823    *
824    * \return A map associating the server rank with its minimum buffer size.
825    * TODO: Refactor code
826    */
827   std::map<int, StdSize> CGrid::getAttributesBufferSize(CContextClient* client, bool bufferForWriting)
828   TRY
829   {
830     std::map<int, StdSize> attributesSizes = getMinimumBufferSizeForAttributes(client);
831
832     // The grid indexes require a similar size as the actual data
833     std::map<int, StdSize> dataSizes = getDataBufferSize(client, "", bufferForWriting);
834     std::map<int, StdSize>::iterator it, itE = dataSizes.end();
835     for (it = dataSizes.begin(); it != itE; ++it)
836     {
837       it->second += 2 * sizeof(bool);
838       if (it->second > attributesSizes[it->first])
839         attributesSizes[it->first] = it->second;
840     }
841     
842     // Account for the axis attributes
843     std::vector<CAxis*> axisList = getAxis();
844     for (size_t i = 0; i < axisList.size(); ++i)
845     {
846       std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),getAxisPositionInGrid()[i]);
847       for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it)
848       {
849         it->second += 2 * sizeof(bool);
850         if (it->second > attributesSizes[it->first])
851           attributesSizes[it->first] = it->second;
852       }
853     }
854
855     // Account for the domain attributes
856     std::vector<CDomain*> domList = getDomains();
857     for (size_t i = 0; i < domList.size(); ++i)
858     {
859       std::map<int, StdSize> domAttBuffSize = domList[i]->getAttributesBufferSize(client);
860       for (it = domAttBuffSize.begin(), itE = domAttBuffSize.end(); it != itE; ++it)
861       {
862         it->second += 2 * sizeof(bool);
863         if (it->second > attributesSizes[it->first])
864           attributesSizes[it->first] = it->second;
865       }
866     }
867
868     return attributesSizes;
869  }
870   CATCH_DUMP_ATTR
871
872   /*!
873    * Compute the minimum buffer size required to send the data.
874    * \param client contextClient used to determine the size of connected receivers
875    * \param id the id used to tag the data
876    * \param bufferForWriting flag indicating if a buffer is used to send data for writing
877    * \return A map associating the sender rank with its minimum buffer size.
878    */
879   std::map<int, StdSize> CGrid::getDataBufferSize(CContextClient* client, const std::string& id /*= ""*/, bool bufferForWriting /*= "false"*/)
880   TRY
881   {     
882     // The record index is sometimes sent along with the data but we always
883     // include it in the size calculation for the sake of simplicity
884     const size_t extraSize = CEventClient::headerSize + (id.empty() ? getId() : id).size() 
885                                                       + 2 * sizeof(size_t) 
886                                                       + sizeof(size_t);
887
888     std::map<int, StdSize> dataSizes;
889     int receiverSize = client->serverSize;
890     std::map<int,size_t>& dataSizeMap = bufferForWriting ? connectedDataSize_[receiverSize]: connectedDataSizeRead_;
891     std::vector<int>& connectedServerRanks = bufferForWriting ? connectedServerRank_[receiverSize] : connectedServerRankRead_;
892
893     std::map<int, size_t>::const_iterator itEnd = dataSizeMap.end();
894     for (size_t k = 0; k < connectedServerRanks.size(); ++k)
895     {
896       int rank = connectedServerRanks[k];
897       std::map<int, size_t>::const_iterator it = dataSizeMap.find(rank);
898       size_t count = (it != itEnd) ? it->second : 0;
899
900       dataSizes.insert(std::make_pair(rank, extraSize + CArray<double,1>::size(count)));
901     }
902
903     return dataSizes;
904   }
905   CATCH_DUMP_ATTR
906
907   size_t CGrid::getGlobalWrittenSize(void)
908   TRY
909   {
910         std::vector<CDomain*> domainP = this->getDomains();
911     std::vector<CAxis*> axisP = this->getAxis();
912     
913     size_t globalGridSize=1 ;
914     for (std::vector<CDomain*>::iterator it=domainP.begin(); it!=domainP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ;
915     for (std::vector<CAxis*>::iterator it=axisP.begin(); it!=axisP.end();++it) globalGridSize*=(*it)->getGlobalWrittenSize() ;
916     return globalGridSize ;
917   }
918   CATCH_DUMP_ATTR
919   
920
921   void CGrid::computeAxisPositionInGrid(void)
922   {
923     axisPositionInGrid_.resize(0);
924     int idx = 0;
925     for (int i = 0; i < axis_domain_order.numElements(); ++i)
926     {
927       int elementDimension = axis_domain_order(i);
928       if (1 == elementDimension)
929       {
930         axisPositionInGrid_.push_back(idx);
931         ++idx;
932       }
933       else if (2 == elementDimension) idx += 2;
934     }
935   }
936
937 
938   /*!
939    * Test whether the data defined on the grid can be outputted in a compressed way.
940    *
941    * \return true if and only if a mask was defined for this grid
942    */
943   bool CGrid::isCompressible(void) const
944   TRY
945   {
946      return isCompressible_;
947   }
948   CATCH
949
950   //---------------------------------------------------------------
951
952   void CGrid::addRelFileCompressed(const StdString& filename)
953   TRY
954   {
955      this->relFilesCompressed.insert(filename);
956   }
957   CATCH_DUMP_ATTR
958
959   bool CGrid::isWrittenCompressed(const StdString& filename) const
960   TRY
961   {
962      return (this->relFilesCompressed.find(filename) != this->relFilesCompressed.end());
963   }
964   CATCH
965
966   //---------------------------------------------------------------
967   /*
968     Find all reference of grid's components and inherite attributes if necessary
969   */
970   void CGrid::solveDomainAxisRef(bool areAttributesChecked)
971   TRY
972   {
973     if (this->isDomainAxisChecked) return;
974
975     this->solveScalarRef(areAttributesChecked);
976     this->solveAxisRef(areAttributesChecked);
977     this->solveDomainRef(areAttributesChecked);     
978     this->isDomainAxisChecked = areAttributesChecked;
979   }
980   CATCH_DUMP_ATTR
981
982   /*
983     Go up hierachy reference and fill in the base reference with attributes of the children
984     This function should be only used after reading component's attributes from file
985   */
986   void CGrid::solveDomainAxisBaseRef()
987   TRY
988   {
989     if (this->hasDomainAxisBaseRef_) return;
990     // Account for the scalar attributes
991     std::vector<CScalar*> scalarList = getScalars();
992     for (size_t i = 0; i < scalarList.size(); ++i)
993     {
994       scalarList[i]->setAttributesReference();
995     }
996
997     // Account for the axis attributes
998     std::vector<CAxis*> axisList = getAxis();
999     for (size_t i = 0; i < axisList.size(); ++i)
1000     {
1001       axisList[i]->setAttributesReference();
1002     }
1003
1004     // Account for the domain attributes
1005     std::vector<CDomain*> domList = getDomains();
1006     for (size_t i = 0; i < domList.size(); ++i)
1007     {
1008       domList[i]->setAttributesReference();
1009     }
1010
1011     this->hasDomainAxisBaseRef_ = true;
1012   }
1013   CATCH_DUMP_ATTR
1014
1015   void CGrid::checkEligibilityForCompressedOutput()
1016   TRY
1017   {
1018     // We don't check if the mask is valid here, just if a mask has been defined at this point.
1019     isCompressible_ = !mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty();
1020   }
1021   CATCH_DUMP_ATTR
1022
1023   //ym obsolete -> to be removed later
1024   void CGrid::checkMaskIndex(bool doSendingIndex)
1025   TRY
1026   {
1027     CContext* context = CContext::getCurrent();
1028     
1029     if (this->isChecked) return;
1030     this->checkElementsAttributes();
1031     this->isChecked = true;
1032   }
1033   CATCH_DUMP_ATTR
1034
1035
1036   bool CGrid::hasMask() const
1037   TRY
1038   {
1039     return (!mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty() ||
1040             !mask_4d.isEmpty() || !mask_5d.isEmpty() || !mask_6d.isEmpty() || !mask_7d.isEmpty());
1041   }
1042   CATCH
1043
1044   
1045   CArray<bool,1>& CGrid::getMask(void)
1046   {
1047     
1048      if (mask_.isEmpty())
1049      { 
1050        if (!mask_0d.isEmpty()) mask_.reference(CArray<bool,1>(mask_0d.dataFirst(),shape(mask_0d.numElements()), neverDeleteData)) ;
1051        if (!mask_1d.isEmpty()) mask_.reference(CArray<bool,1>(mask_1d.dataFirst(),shape(mask_1d.numElements()), neverDeleteData)) ;
1052        if (!mask_2d.isEmpty()) mask_.reference(CArray<bool,1>(mask_2d.dataFirst(),shape(mask_2d.numElements()), neverDeleteData)) ;
1053        if (!mask_3d.isEmpty()) mask_.reference(CArray<bool,1>(mask_3d.dataFirst(),shape(mask_3d.numElements()), neverDeleteData)) ;
1054        if (!mask_4d.isEmpty()) mask_.reference(CArray<bool,1>(mask_4d.dataFirst(),shape(mask_4d.numElements()), neverDeleteData)) ;
1055        if (!mask_5d.isEmpty()) mask_.reference(CArray<bool,1>(mask_5d.dataFirst(),shape(mask_5d.numElements()), neverDeleteData)) ;
1056        if (!mask_6d.isEmpty()) mask_.reference(CArray<bool,1>(mask_6d.dataFirst(),shape(mask_6d.numElements()), neverDeleteData)) ;
1057        if (!mask_7d.isEmpty()) mask_.reference(CArray<bool,1>(mask_7d.dataFirst(),shape(mask_7d.numElements()), neverDeleteData)) ;
1058      }
1059      return mask_ ;
1060   }
1061
1062 
1063   //---------------------------------------------------------------
1064
1065   void CGrid::solveDomainRef(bool sendAtt)
1066   TRY
1067   {
1068      setDomainList();
1069      std::vector<CDomain*> domListP = this->getDomains();
1070      if (!domListP.empty())
1071        for (int i = 0; i < domListP.size(); ++i) domListP[i]->checkAttributes();
1072   }
1073   CATCH_DUMP_ATTR
1074
1075   //---------------------------------------------------------------
1076
1077   void CGrid::solveAxisRef(bool sendAtt)
1078   TRY
1079   {
1080      setAxisList();
1081      std::vector<CAxis*> axisListP = this->getAxis();
1082      if (!axisListP.empty())
1083        for (int i = 0; i < axisListP.size(); ++i)  axisListP[i]->checkAttributes();
1084   }
1085   CATCH_DUMP_ATTR
1086
1087   //---------------------------------------------------------------
1088
1089   void CGrid::solveScalarRef(bool sendAtt)
1090   TRY
1091   {
1092      setScalarList();
1093      std::vector<CScalar*> scalarListP = this->getScalars();
1094      if (!scalarListP.empty())
1095        for (int i = 0; i < scalarListP.size(); ++i) scalarListP[i]->checkAttributes() ;
1096   }
1097   CATCH_DUMP_ATTR
1098
1099
1100    //---------------------------------------------------------------
1101   CDistributionClient* CGrid::getClientDistribution()
1102   TRY
1103   {
1104     if (!computeClientDistribution_done_) computeClientDistribution() ;
1105     return clientDistribution_;
1106   }
1107   CATCH_DUMP_ATTR
1108   
1109   void CGrid::computeClientDistribution(void)
1110   {
1111     if (computeClientDistribution_done_) return ;
1112     else computeClientDistribution_done_ = true ;
1113
1114     CContext* context = CContext::getCurrent();
1115     int rank = context-> getIntraCommRank();
1116     clientDistribution_ = new CDistributionClient(rank, this);
1117   }
1118
1119
1120  bool CGrid::isDataDistributed(void) 
1121  { 
1122    return getClientDistribution()->isDataDistributed() ;
1123  }
1124
1125 
1126
1127   CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc)
1128   TRY
1129   {
1130     std::vector<CDomain*> domainSrcTmp = gridSrc->getDomains(), domainSrc;
1131     std::vector<CAxis*> axisSrcTmp = gridSrc->getAxis(), axisSrc;
1132     std::vector<CScalar*> scalarSrcTmp = gridSrc->getScalars(), scalarSrc;
1133
1134     for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
1135     {
1136       CDomain* domain = CDomain::createDomain();
1137       domain->duplicateAttributes(domainSrcTmp[idx]);
1138       domain->duplicateTransformation(domainSrcTmp[idx]);
1139       domain->solveRefInheritance(true);
1140       domain->solveInheritanceTransformation();
1141       domainSrc.push_back(domain);
1142     }
1143
1144     for (int idx = 0; idx < axisSrcTmp.size(); ++idx)
1145     {
1146       CAxis* axis = CAxis::createAxis();
1147       axis->duplicateAttributes(axisSrcTmp[idx]);
1148       axis->duplicateTransformation(axisSrcTmp[idx]);
1149       axis->solveRefInheritance(true);
1150       axis->solveInheritanceTransformation();
1151       axisSrc.push_back(axis);
1152     }
1153
1154     for (int idx = 0; idx < scalarSrcTmp.size(); ++idx)
1155     {
1156       CScalar* scalar = CScalar::createScalar();
1157       scalar->duplicateAttributes(scalarSrcTmp[idx]);
1158       scalar->duplicateTransformation(scalarSrcTmp[idx]);
1159       scalar->solveRefInheritance(true);
1160       scalar->solveInheritanceTransformation();
1161       scalarSrc.push_back(scalar);
1162     }
1163
1164      CGrid* grid = CGrid::createGrid(idNewGrid, domainSrc, axisSrc, scalarSrc, gridSrc->axis_domain_order);
1165
1166      return grid;
1167   }
1168   CATCH
1169
1170   StdString CGrid::generateId(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis,
1171                               const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder)
1172   TRY
1173   {
1174      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size()))
1175        ERROR("CGrid* CGrid::generateId(...)",
1176              << "The size of axisDomainOrder (" << axisDomainOrder.numElements()
1177              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<").");
1178
1179      std::ostringstream id;
1180
1181      if (domains.empty() && axis.empty() && !scalars.empty())
1182        id << "__scalar_";
1183
1184      if (0 != (domains.size() + axis.size() + scalars.size()))
1185      {
1186        id << "__grid";
1187
1188        if (0 == axisDomainOrder.numElements())
1189        {
1190          for (size_t i = 0; i < domains.size(); ++i) id << "_" << domains[i]->getId();
1191          for (size_t i = 0; i < axis.size(); ++i) id << "_" << axis[i]->getId();
1192          for (size_t i = 0; i < scalars.size(); ++i) id << "_" << scalars[i]->getId();
1193        }
1194        else
1195        {
1196          size_t iDomain = 0, iAxis = 0, iScalar = 0;
1197          for (size_t i = 0; i < axisDomainOrder.numElements(); ++i)
1198          {
1199            if (2 == axisDomainOrder(i))
1200              id << "_" << domains[iDomain++]->getId();
1201            else if (1 == axisDomainOrder(i))
1202              id << "_" << axis[iAxis++]->getId();
1203            else
1204              id << "_" << scalars[iScalar++]->getId();
1205          }
1206        }
1207
1208        id << "__";
1209      }
1210
1211      return id.str();
1212   }
1213   CATCH
1214
1215   StdString CGrid::generateId(const CGrid* gridSrc, const CGrid* gridDest)
1216   TRY
1217   {
1218     StdString idSrc  = gridSrc->getId();
1219     StdString idDest = gridDest->getId();
1220
1221     std::ostringstream id;
1222     id << idSrc << "__" << idDest;
1223
1224     return id.str();
1225   }
1226   CATCH
1227
1228
1229   //----------------------------------------------------------------
1230
1231   
1232 
1233 
1234  /*
1235     Compute on the fly the global dimension of a grid with its elements
1236     \param[in/out] globalDim global dimension of grid
1237     \param[in] domains list of its domains
1238     \param[in] axiss list of its axis
1239     \param[in] scalars list of its scalars
1240     \param[in] axisDomainOrder the order of element in a grid (e.g: scalar then axis)
1241     \return The dimension of which we do distribution (often for server)
1242  */
1243  int CGrid::computeGridGlobalDimension(std::vector<int>& globalDim,
1244                                        const std::vector<CDomain*> domains,
1245                                        const std::vector<CAxis*> axis,
1246                                        const std::vector<CScalar*> scalars,
1247                                        const CArray<int,1>& axisDomainOrder)
1248  TRY
1249 {
1250 //   globalDim.resize(domains.size()*2+axis.size()+scalars.size());
1251    globalDim.resize(domains.size()*2+axis.size());
1252    int positionDimensionDistributed = 1;
1253    int idx = 0, idxDomain = 0, idxAxis = 0, idxScalar = 0;
1254    for (int i = 0; i < axisDomainOrder.numElements(); ++i)
1255    {
1256      if (2 == axisDomainOrder(i))
1257      {
1258        if (!(domains[idxDomain]->type.isEmpty()) && (domains[idxDomain]->type==CDomain::type_attr::unstructured))
1259        {
1260          positionDimensionDistributed = idx;
1261        }
1262        else
1263        {
1264          positionDimensionDistributed = idx +1;
1265        }
1266
1267        globalDim[idx]   = domains[idxDomain]->ni_glo.getValue();
1268        globalDim[idx+1] = domains[idxDomain]->nj_glo.getValue();
1269
1270        ++idxDomain;
1271        idx += 2;
1272      }
1273      else if (1 == axisDomainOrder(i))
1274      {
1275        globalDim[idx] = axis[idxAxis]->n_glo.getValue();
1276        ++idxAxis;
1277        ++idx;
1278      }
1279      else
1280      {
1281//        globalDim[idx] = 1;
1282        ++idxScalar;
1283//        ++idx;
1284      }
1285    }
1286
1287    return positionDimensionDistributed;
1288  }
1289  CATCH_DUMP_ATTR
1290
1291  // Retrieve the global dimension of grid
1292  std::vector<int> CGrid::getGlobalDimension()
1293  TRY
1294  {
1295    std::vector<int> globalDim;
1296    computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);
1297
1298    return globalDim;
1299  }
1300  CATCH_DUMP_ATTR
1301
1302  // Retrieve dimension on which we do distribution (Very often, it should be 2nd dimension)
1303  int CGrid::getDistributedDimension()
1304  TRY
1305  {
1306    std::vector<int> globalDim;
1307    return computeGridGlobalDimension(globalDim, getDomains(), getAxis(), getScalars(), axis_domain_order);   
1308  }
1309  CATCH_DUMP_ATTR
1310
1311  bool CGrid::isScalarGrid() const
1312  TRY
1313  {
1314    return (axisList_.empty() && domList_.empty());
1315  }
1316  CATCH
1317
1318  /*!
1319    Verify whether one server need to write data
1320    There are some cases on which one server has nodata to write. For example, when we
1321    just only want to zoom on a domain.
1322  */
1323  bool CGrid::doGridHaveDataToWrite()
1324  TRY
1325  {
1326     return (0 != getGridLocalElements()->getView(CElementView::FULL)->getSize());
1327  }
1328  CATCH_DUMP_ATTR
1329
1330 
1331  bool CGrid::doGridHaveDataDistributed(CContextClient* client)
1332  TRY
1333  {
1334    // This function is now useless because it will return false only if server and client size are equal to 1
1335    // to be seriously check in future
1336
1337    if (isScalarGrid()) return false;
1338    else if (0 != client)
1339    {
1340      return  (isDataDistributed() ||  (1 != client->clientSize) || (1 != client->serverSize));
1341    }
1342    else
1343      return isDataDistributed();   
1344  }
1345  CATCH_DUMP_ATTR
1346
1347   /*!
1348   \brief Dispatch event received from client
1349      Whenever a message is received in buffer of server, it will be processed depending on
1350   its event type. A new event type should be added in the switch list to make sure
1351   it processed on server side.
1352   \param [in] event: Received message
1353   */
1354  bool CGrid::dispatchEvent(CEventServer& event)
1355  TRY
1356  {
1357
1358    if (SuperClass::dispatchEvent(event)) return true;
1359    else
1360    {
1361      switch(event.type)
1362      {
1363         case EVENT_ID_ADD_DOMAIN :
1364           recvAddDomain(event);
1365           return true;
1366           break;
1367
1368         case EVENT_ID_ADD_AXIS :
1369           recvAddAxis(event);
1370           return true;
1371           break;
1372
1373         case EVENT_ID_ADD_SCALAR :
1374           recvAddScalar(event);
1375           return true;
1376           break;
1377
1378         case EVENT_ID_SEND_MASK :
1379           recvMask(event);
1380           return true;
1381           break;
1382        default :
1383          ERROR("bool CGrid::dispatchEvent(CEventServer& event)",
1384                << "Unknown Event");
1385          return false;
1386      }
1387    }
1388  }
1389  CATCH
1390
1391 
1392
1393  void CGrid::sendGridToFileServer(CContextClient* client)
1394  {
1395    if (sendGridToFileServer_done_.count(client)!=0) return ;
1396    else sendGridToFileServer_done_.insert(client) ;
1397
1398    StdString gridDefRoot("grid_definition");
1399    CGridGroup* gridPtr = CGridGroup::get(gridDefRoot);
1400    gridPtr->sendCreateChild(this->getId(),client);
1401    this->sendAllAttributesToServer(client);
1402    distributeGridToServer(client) ;
1403  }
1404
1405
1406  void CGrid::sendGridToCouplerOut(CContextClient* client, const string& fieldId)
1407  {
1408    if (sendGridToCouplerOut_done_.count(client)!=0) return ;
1409    else sendGridToCouplerOut_done_.insert(client) ;
1410    this->sendAllAttributesToServer(client, getCouplingAlias(fieldId));
1411    distributeGridToServer(client,fieldId) ;
1412  }
1413
1414
1415  void CGrid::distributeGridToServer(CContextClient* client, const string& fieldId)
1416  {
1417    CContext* context = CContext::getCurrent();
1418    bool isCoupling = !fieldId.empty() ;
1419    // simple Distribution for now
1420    // distribute over the fisrt element except if it is a scalar
1421    auto& elements = getElements() ;
1422    int posDistributed = 0 ;
1423    for(auto& element : elements)
1424    {
1425      if (element.type==TYPE_DOMAIN) break ;
1426      else if (element.type==TYPE_AXIS) break ;
1427      else if (element.type==TYPE_SCALAR) posDistributed++ ;
1428    }
1429    if (posDistributed==elements.size()) posDistributed=0 ; // grid composed only of scalar
1430   
1431    vector<CLocalView*> localViews ;
1432    vector<CLocalView*> workflowView ;
1433    vector<CDistributedView*> remoteViews ;
1434
1435    for(int i=0 ; i<elements.size() ; i++)
1436    {
1437      if (elements[i].type==TYPE_DOMAIN) 
1438      { 
1439         CDomain* domain = (CDomain*) elements[i].ptr ;
1440         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
1441         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ;
1442         localViews.push_back(domain->getLocalView(CElementView::FULL)) ;
1443         workflowView.push_back(domain->getLocalView(CElementView::WORKFLOW)) ;
1444      }
1445      else if (elements[i].type==TYPE_AXIS)
1446      {
1447        CAxis* axis = (CAxis*) elements[i].ptr ;
1448        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
1449        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ;
1450        localViews.push_back(axis->getLocalView(CElementView::FULL)) ;
1451        workflowView.push_back(axis->getLocalView(CElementView::WORKFLOW)) ;
1452      }
1453      else if (elements[i].type==TYPE_SCALAR)
1454      {
1455        CScalar* scalar = (CScalar*) elements[i].ptr ;
1456        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::ROOT : EDistributionType::NONE) ;
1457        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ;
1458        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ;
1459        workflowView.push_back(scalar->getLocalView(CElementView::WORKFLOW)) ;
1460      }
1461    }
1462   
1463    // CGridClientServerRemoteConnector : workflowView is added to avoid spurious optimisation with only the fullview
1464    CGridClientServerRemoteConnector gridRemoteConnector(localViews, workflowView, remoteViews, context->getIntraComm(), client->getRemoteSize()) ;
1465    gridRemoteConnector.computeConnector() ;
1466   
1467    vector<CScattererConnector*> scattererConnectors ;
1468    CScattererConnector* scattererConnector;
1469    for(int i=0 ; i<elements.size() ; i++)
1470    {
1471      if (elements[i].type==TYPE_DOMAIN) 
1472      { 
1473        CDomain* domain = (CDomain*) elements[i].ptr ;
1474        if (isCoupling) domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector,  domain->getCouplingAlias(fieldId,i)) ;
1475        else 
1476        {
1477          sendAddDomain(domain->getId(),client) ;
1478          domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ;
1479        }
1480        scattererConnectors.push_back(scattererConnector) ;
1481      }
1482      else if (elements[i].type==TYPE_AXIS)
1483      {
1484        CAxis* axis = (CAxis*) elements[i].ptr ;
1485        if (isCoupling) axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector,  axis->getCouplingAlias(fieldId,i)) ;
1486        else 
1487        {
1488          sendAddAxis(axis->getId(),client) ;
1489          axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ;
1490        }
1491        scattererConnectors.push_back(scattererConnector) ;
1492      }
1493      else if (elements[i].type==TYPE_SCALAR)
1494      {
1495        CScalar* scalar = (CScalar*) elements[i].ptr ;
1496        if (isCoupling) scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector,  scalar->getCouplingAlias(fieldId,i)) ;
1497        else 
1498        {
1499          sendAddScalar(scalar->getId(),client) ;
1500          scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ;
1501        }
1502        scattererConnectors.push_back(scattererConnector) ;
1503      }
1504    }
1505
1506    CGridScattererConnector gridScattererConnector(scattererConnectors) ;
1507    CGridLocalConnector* workflowToFull = getGridLocalElements()->getConnector(CElementView::WORKFLOW, CElementView::FULL) ;
1508    CArray<bool,1> maskIn(workflowToFull->getSrcSize()) ;
1509    CArray<bool,1> maskOut(workflowToFull->getDstSize()) ;
1510    maskIn = true ;
1511    workflowToFull->transfer(maskIn,maskOut,false) ;
1512
1513    CEventClient event(getType(), EVENT_ID_SEND_MASK);
1514    CMessage message ;
1515    if (isCoupling) message<<getCouplingAlias(fieldId) ;
1516    else message<<getId() ; 
1517    gridScattererConnector.transfer(maskOut, client, event, message) ;
1518    for(auto& it : scattererConnectors) delete it ;
1519
1520    vector<CScattererConnector*> clientToServerConnectors ;
1521    vector<CGathererConnector*>  clientFromServerConnectors ;
1522    for(auto& element : elements)
1523    {
1524      if (element.type==TYPE_DOMAIN) 
1525      { 
1526         clientToServerConnectors.push_back(element.domain->getClientToServerConnector(client)) ;
1527         clientFromServerConnectors.push_back(element.domain->getClientFromServerConnector(client)) ;
1528      }
1529      else if (element.type==TYPE_AXIS)
1530      {
1531        clientToServerConnectors.push_back(element.axis->getClientToServerConnector(client)) ;
1532        clientFromServerConnectors.push_back(element.axis->getClientFromServerConnector(client)) ;
1533
1534      }
1535      else if (element.type==TYPE_SCALAR)
1536      {
1537        clientToServerConnectors.push_back(element.scalar->getClientToServerConnector(client)) ;
1538        clientFromServerConnectors.push_back(element.scalar->getClientFromServerConnector(client)) ;
1539      }
1540    }
1541   
1542    // compute the grid clientToServerConnector to send flux from client to servers
1543    clientToServerConnector_[client] = new CGridScattererConnector(clientToServerConnectors) ;
1544    clientFromServerConnector_[client] = new CGridGathererConnector(clientFromServerConnectors) ;
1545
1546  }
1547
1548
1549  void CGrid::recvMask(CEventServer& event)
1550  {
1551    string gridId;
1552    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> gridId  ;
1553    get(gridId)->receiveMask(event);
1554  }
1555 
1556  void CGrid::receiveMask(CEventServer& event)
1557  {
1558    vector<CGathererConnector*> gathererConnectors ;
1559    vector<CLocalView*> fullViews ;
1560
1561    for(auto& element : getElements())
1562    {
1563      if (element.type==TYPE_DOMAIN) 
1564      {
1565        gathererConnectors.push_back(element.domain->getGathererConnector());
1566        fullViews.push_back(element.domain->getLocalElement()->getView(CElementView::FULL));
1567       
1568      }
1569      else if (element.type==TYPE_AXIS)
1570      {
1571       gathererConnectors.push_back(element.axis->getGathererConnector());
1572       fullViews.push_back(element.axis->getLocalElement()->getView(CElementView::FULL));
1573      }
1574      else if (element.type==TYPE_SCALAR) 
1575      {
1576        gathererConnectors.push_back(element.scalar->getGathererConnector());
1577        fullViews.push_back(element.scalar->getLocalElement()->getView(CElementView::FULL));
1578      }
1579    }
1580    CGridGathererConnector gridGathererConnector(gathererConnectors) ;
1581    CGridMaskConnector gridMaskConnector(fullViews) ;
1582
1583    CArray<bool,1> maskOut ;
1584    gridGathererConnector.transfer_or(event,maskOut) ;
1585    gridMaskConnector.computeConnector(maskOut) ;
1586
1587    CContextClient* client = event.getContextServer()->getAssociatedClient() ;
1588    int i=0 ;
1589    for(auto& element : getElements())
1590    {
1591      if (element.type==TYPE_DOMAIN) element.domain->setServerMask(gridMaskConnector.getElementMask(i),client);
1592      else if (element.type==TYPE_AXIS) element.axis->setServerMask(gridMaskConnector.getElementMask(i),client);
1593      else if (element.type==TYPE_SCALAR) element.scalar->setServerMask(gridMaskConnector.getElementMask(i),client);
1594      i++ ;
1595    }
1596  }
1597
1598  string CGrid::getCouplingAlias(const string& fieldId)
1599  {
1600    return "_grid_of_"+fieldId;
1601  }
1602
1603  void CGrid::makeAliasForCoupling(const string& fieldId)
1604  {
1605    string gridId=getCouplingAlias(fieldId) ;
1606    createAlias(gridId) ;
1607
1608    auto& elements = getElements() ;
1609    for(int i=0 ; i<elements.size() ; i++)
1610    {
1611      if (elements[i].type==TYPE_DOMAIN) elements[i].domain->makeAliasForCoupling(fieldId, i);
1612      else if (elements[i].type==TYPE_AXIS) elements[i].axis->makeAliasForCoupling(fieldId, i);
1613      else if (elements[i].type==TYPE_SCALAR) elements[i].scalar->makeAliasForCoupling(fieldId, i);
1614    }
1615  }
1616
1617   /*!
1618   \brief Send a message to create a domain on server side
1619   \param[in] id String identity of domain that will be created on server
1620   */
1621   void CGrid::sendAddDomain(const string& id, CContextClient* contextClient)
1622   TRY
1623  {
1624      sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN, contextClient);
1625   }
1626   CATCH_DUMP_ATTR
1627
1628   /*!
1629   \brief Send a message to create an axis on server side
1630   \param[in] id String identity of axis that will be created on server
1631   */
1632   void CGrid::sendAddAxis(const string& id, CContextClient* contextClient)
1633   TRY
1634   {
1635      sendAddItem(id, (int)EVENT_ID_ADD_AXIS, contextClient);
1636   }
1637   CATCH_DUMP_ATTR
1638
1639   /*!
1640   \brief Send a message to create a scalar on server side
1641   \param[in] id String identity of scalar that will be created on server
1642   */
1643   void CGrid::sendAddScalar(const string& id, CContextClient* contextClient)
1644   TRY
1645   {
1646      sendAddItem(id, (int)EVENT_ID_ADD_SCALAR, contextClient);
1647   }
1648   CATCH_DUMP_ATTR
1649
1650   /*!
1651   \brief Receive a message annoucing the creation of a domain on server side
1652   \param[in] event Received event
1653   */
1654   void CGrid::recvAddDomain(CEventServer& event)
1655   TRY
1656   {
1657
1658      CBufferIn* buffer = event.subEvents.begin()->buffer;
1659      string id;
1660      *buffer >> id;
1661      get(id)->recvAddDomain(*buffer);
1662   }
1663   CATCH
1664
1665   /*!
1666   \brief Receive a message annoucing the creation of a domain on server side
1667   \param[in] buffer Buffer containing message
1668   */
1669   void CGrid::recvAddDomain(CBufferIn& buffer)
1670   TRY
1671   {
1672      string id;
1673      buffer >> id;
1674      addDomain(id);
1675   }
1676   CATCH_DUMP_ATTR
1677
1678   /*!
1679   \brief Receive a message annoucing the creation of an axis on server side
1680   \param[in] event Received event
1681   */
1682   void CGrid::recvAddAxis(CEventServer& event)
1683   TRY
1684   {
1685
1686      CBufferIn* buffer = event.subEvents.begin()->buffer;
1687      string id;
1688      *buffer >> id;
1689      get(id)->recvAddAxis(*buffer);
1690   }
1691   CATCH
1692
1693   /*!
1694   \brief Receive a message annoucing the creation of an axis on server side
1695   \param[in] buffer Buffer containing message
1696   */
1697   void CGrid::recvAddAxis(CBufferIn& buffer)
1698   TRY
1699   {
1700      string id;
1701      buffer >> id;
1702      addAxis(id);
1703   }
1704   CATCH_DUMP_ATTR
1705
1706   /*!
1707   \brief Receive a message annoucing the creation of an scalar on server side
1708   \param[in] event Received event
1709   */
1710   void CGrid::recvAddScalar(CEventServer& event)
1711   TRY
1712   {
1713
1714      CBufferIn* buffer = event.subEvents.begin()->buffer;
1715      string id;
1716      *buffer >> id;
1717      get(id)->recvAddScalar(*buffer);
1718   }
1719   CATCH
1720
1721   /*!
1722   \brief Receive a message annoucing the creation of an scalar on server side
1723   \param[in] buffer Buffer containing message
1724   */
1725   void CGrid::recvAddScalar(CBufferIn& buffer)
1726   TRY
1727   {
1728      string id;
1729      buffer >> id;
1730      addScalar(id);
1731   }
1732   CATCH_DUMP_ATTR
1733
1734  /*!
1735  \brief Check if all elements of the grid are complete
1736  Before make any grid processing, we must be sure that all grid information elements have
1737  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
1738  other context (coupling)
1739  */
1740  bool CGrid::isCompleted(void)
1741  {
1742    setDomainList();
1743    for (auto domainId : domList_) if (!CDomain::get(domainId)->isCompleted()) return false ;
1744    setAxisList() ;
1745    for (auto axisId : axisList_) if (!CAxis::get(axisId)->isCompleted()) return false ;
1746    setScalarList() ;
1747    for (auto scalarId : scalarList_) if (!CScalar::get(scalarId)->isCompleted()) return false ;
1748    return true ;
1749  }
1750
1751  /*!
1752  \brief impose that all elements of the grid are complete
1753  Before make any grid processing, we must be sure that all grid information elements have
1754  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
1755  other context (coupling)
1756  */
1757  void CGrid::setCompleted(void)
1758  {
1759    setDomainList();
1760    for (auto domainId : domList_) CDomain::get(domainId)->setCompleted() ;
1761    setAxisList() ;
1762    for (auto axisId : axisList_) CAxis::get(axisId)->setCompleted() ;
1763    setScalarList() ;
1764    for (auto scalarId : scalarList_) CScalar::get(scalarId)->setCompleted() ;
1765  }
1766
1767/*!
1768  \brief impose that all elements of the grid are incomplete
1769  Before make any grid processing, we must be sure that all grid information elements have
1770  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
1771  other context (coupling)
1772  */
1773  void CGrid::unsetCompleted(void)
1774  {
1775    setDomainList();
1776    for (auto domainId : domList_) CDomain::get(domainId)->unsetCompleted() ;
1777    setAxisList() ;
1778    for (auto axisId : axisList_) CAxis::get(axisId)->unsetCompleted() ;
1779    setScalarList() ;
1780    for (auto scalarId : scalarList_) CScalar::get(scalarId)->unsetCompleted() ;
1781  }
1782
1783  /*!
1784  \brief Solve domain and axis references
1785  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
1786  all attributes from their parents, they should be processed with this function
1787  \param[in] apply inherit all attributes of parents (true)
1788  */
1789  void CGrid::solveElementsRefInheritance(bool apply)
1790  TRY
1791  {
1792    setDomainList();
1793    for (auto domainId : domList_)
1794    {
1795      CDomain* pDom = CDomain::get(domainId);
1796      pDom->solveRefInheritance(apply);
1797      pDom->solveInheritanceTransformation();
1798    }
1799
1800    setAxisList();
1801    for (auto axisId : axisList_)
1802    {
1803      CAxis* pAxis = CAxis::get(axisId);
1804      pAxis->solveRefInheritance(apply);
1805      pAxis->solveInheritanceTransformation();
1806    }
1807
1808    setScalarList();
1809    for (auto scalarId : scalarList_)
1810    {
1811      CScalar* pScalar = CScalar::get(scalarId);
1812      pScalar->solveRefInheritance(apply);
1813      pScalar->solveInheritanceTransformation();
1814    }
1815  }
1816  CATCH_DUMP_ATTR
1817
1818  bool CGrid::activateFieldWorkflow(CGarbageCollector& gc)
1819  TRY
1820  {
1821    setDomainList();
1822    for (auto domainId : domList_)
1823    {
1824      CDomain* pDom = CDomain::get(domainId);
1825      bool ret = pDom->activateFieldWorkflow(gc);
1826      if (!ret) return false ;
1827    }
1828
1829    setAxisList();
1830    for (auto axisId : axisList_)
1831    {
1832      CAxis* pAxis = CAxis::get(axisId);
1833      bool ret = pAxis->activateFieldWorkflow(gc);
1834      if (!ret) return false ;
1835    }
1836
1837    setScalarList();
1838    for (auto scalarId : scalarList_)
1839    {
1840      CScalar* pScalar = CScalar::get(scalarId);
1841      bool ret = pScalar->activateFieldWorkflow(gc);
1842      if (!ret) return false ;
1843    }
1844    return true ;
1845  }
1846  CATCH_DUMP_ATTR
1847
1848 /*!
1849  \brief check attributes of all elements of the grid
1850  */
1851  void CGrid::checkElementsAttributes(void)
1852  TRY
1853  {
1854    setDomainList();
1855    for (auto domainId : domList_) CDomain::get(domainId)->checkAttributes();
1856
1857    setAxisList();
1858    for (auto axisId : axisList_) CAxis::get(axisId)->checkAttributes();
1859   
1860    setScalarList();
1861    for (auto scalarId : scalarList_) CScalar::get(scalarId)->checkAttributes();
1862  }
1863  CATCH_DUMP_ATTR
1864
1865
1866
1867//**********************************************************
1868//**************   New transformation method  **************
1869//**********************************************************
1870
1871  std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > 
1872  CGrid::buildTransformationGraph(CGarbageCollector& gc, bool isSource, CGrid* gridSrc, double detectMissingValues, double defaultValue, CGrid*& newGrid, bool graphEnabled, CField* field)
1873  TRY
1874  {
1875    static bool transformationGoing = false;
1876    registerAlgorithmTransformation() ; // needed to enable self-registration of the transformations
1877                                        // big mystery why it doesn't work witout that...
1878                                        // problem with the linker ??
1879
1880    std::shared_ptr<CFilter> inputFilter = std::shared_ptr<CPassThroughFilter>(new CPassThroughFilter(gc));
1881    std::shared_ptr<CFilter> outputFilter = inputFilter ;
1882
1883
1884    string newId ;
1885    if (gridSrc!=nullptr) newId = gridSrc->getId() + " --> " + this->getId()  ;
1886    else newId = " --> " + this->getId()  ;
1887    bool isNewGrid ;
1888    if (CGrid::has(newId))
1889    {
1890      cout<<"Retrive existing grid : "<<newId<<endl ;
1891      newGrid = CGrid::get(newId);
1892      isNewGrid = false ;
1893    }
1894    else 
1895    {
1896      cout<<"Create new grid : "<<newId<<endl ;
1897      newGrid = CGrid::create(newId) ;
1898      isNewGrid = true ;
1899    }
1900
1901    bool hadTransform=false ;
1902    bool hasTransform=false ;
1903    bool hasRemainTransform=false ;
1904    CGenericAlgorithmTransformation* algo ;
1905    int pos ;
1906
1907    for(int i=0 ; i<elements_.size(); i++)
1908    {
1909      CTransformationPaths transformationPath ;
1910      auto dstElement = elements_[i] ;
1911
1912      if (dstElement.type==TYPE_DOMAIN)      transformationPath = dstElement.domain->getTransformationPaths() ;
1913      else if (dstElement.type==TYPE_AXIS)   transformationPath = dstElement.axis->getTransformationPaths() ;
1914      else if (dstElement.type==TYPE_SCALAR) transformationPath = dstElement.scalar->getTransformationPaths() ;
1915
1916      SElement srcElement  ;
1917      if (gridSrc==nullptr) srcElement = this->elements_[i] ;
1918      else srcElement = gridSrc->elements_[i] ;
1919
1920      if (gridSrc==nullptr) transformationPath.mergePaths() ;
1921      else
1922      { 
1923        if (srcElement.type==TYPE_DOMAIN)      transformationPath.mergePaths(srcElement.domain->getTransformationPaths()) ;
1924        else if (srcElement.type==TYPE_AXIS)   transformationPath.mergePaths(srcElement.axis->getTransformationPaths()) ;
1925        else if (srcElement.type==TYPE_SCALAR) transformationPath.mergePaths(srcElement.scalar->getTransformationPaths()) ;
1926      }
1927
1928      hasTransform=transformationPath.hasTransform()  ;
1929     
1930      if (hasTransform && !hadTransform)
1931      {
1932        pos=i ;
1933        EElement dstElementType=transformationPath.getNextElementType() ;
1934        string dstElementId=transformationPath.getNextElementId() ;
1935        string srcElementId=transformationPath.getNextElementSrcId() ;
1936        auto transType = transformationPath.getNextTransformationType() ;
1937        auto transId = transformationPath.getNextTransformationId() ;
1938
1939        CGrid* tmpGridSrc=CGrid::create(); // source grid
1940        if (srcElement.type==TYPE_DOMAIN)      tmpGridSrc->addDomain(srcElement.domain->getId()) ;
1941        else if (srcElement.type==TYPE_AXIS)   tmpGridSrc->addAxis(srcElement.axis->getId()) ;
1942        else if (srcElement.type==TYPE_SCALAR) tmpGridSrc->addScalar(srcElement.scalar->getId()) ;
1943        // WARNING -> suppress checkElement attribute ? What append ?
1944        // tmpGridSrc->checkElementsAttributes() ;
1945        CGrid* tmpGridDst=CGrid::create(); // destination Grid
1946        map<int,int> posInGrid={{0,0}} ;
1947               
1948        cout<<"--> New transform from "<<srcElementId<<" to "<<dstElementId<<endl ;
1949        if (dstElementType==EElement::DOMAIN)
1950        {
1951          CDomain* dstDomain ;
1952          CDomain* lastDstDomain ;
1953          bool isGenerate=false ;
1954   
1955          do 
1956          {
1957
1958            if (CDomain::has(dstElementId)) 
1959            {
1960              dstDomain = CDomain::get(dstElementId) ;
1961              cout<<"Retrive existing domain : "<<dstElementId<<endl ;
1962            }
1963            else
1964            {
1965              dstDomain = CDomain::create() ;
1966              dstDomain->createAlias(dstElementId) ;
1967              cout<<"Create new domain : "<<dstDomain->getId()<<" with alias : "<<dstElementId<<endl ;
1968
1969              if (isGenerate) 
1970              {
1971                dstDomain->duplicateAttributes(lastDstDomain) ;
1972                dstDomain->setTemplateId(lastDstDomain) ;
1973              }
1974              else if (srcElementId=="" && srcElement.type==TYPE_DOMAIN) 
1975              {
1976                dstDomain->duplicateAttributes(srcElement.domain) ; // make a copy
1977                dstDomain->setTemplateId(srcElement.domain) ;
1978              }
1979              else 
1980              {
1981                dstDomain->duplicateAttributes(dstElement.domain) ; // make a copy
1982                dstDomain->setTemplateId(dstElement.domain) ;
1983              }
1984              CTransformation<CDomain>* transformation = CTransformation<CDomain>::createTransformation(transType,"") ;
1985              auto srcTransform = CTransformation<CDomain>::getTransformation(transType, transId) ;
1986              transformation->inheritFrom(srcTransform) ;
1987              CGrid* tmpGridDst=CGrid::create(); // destination Grid
1988              tmpGridDst->addDomain(dstDomain->getId()) ;
1989
1990              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 
1991                                                       posInGrid,posInGrid,posInGrid,
1992                                                       posInGrid,posInGrid,posInGrid );
1993
1994
1995              dstDomain->setTransformationAlgorithm(algo) ;
1996              dstDomain->setTransformationPaths(transformationPath) ;
1997            }
1998            algo=dstDomain->getTransformationAlgorithm() ;
1999            isGenerate = algo->isGenerateTransformation() ;
2000            transformationPath.removeNextTransform() ;
2001            dstElementId=transformationPath.getNextElementId() ;
2002            srcElementId=transformationPath.getNextElementSrcId() ;
2003            transType = transformationPath.getNextTransformationType() ;
2004            transId = transformationPath.getNextTransformationId() ;
2005            lastDstDomain=dstDomain ;
2006            dstDomain->setTransformationPaths(transformationPath) ;
2007          } while(transformationPath.hasTransform() && isGenerate) ;
2008
2009          if (isNewGrid) newGrid->addDomain(dstDomain->getId()) ;
2010          algo = dstDomain->getTransformationAlgorithm() ;
2011        }
2012        else if (dstElementType==EElement::AXIS)
2013        {
2014          CAxis* dstAxis ;
2015          CAxis* lastDstAxis ;
2016          bool isGenerate=false ;
2017
2018          do 
2019          {
2020            if (CAxis::has(dstElementId)) 
2021            {
2022              dstAxis = CAxis::get(dstElementId) ;
2023              cout<<"Retrive existing axis : "<<dstElementId<<endl ;
2024            }
2025            else
2026            {
2027              dstAxis = CAxis::create() ;
2028              dstAxis->createAlias(dstElementId) ;
2029              cout<<"Create new axis : "<<dstAxis->getId()<<" with alias : "<<dstElementId<<endl ;
2030             
2031              if (isGenerate) 
2032              {
2033                dstAxis->duplicateAttributes(lastDstAxis) ;
2034                dstAxis->setTemplateId(lastDstAxis) ;
2035              }
2036              else if (srcElementId=="" && srcElement.type==TYPE_AXIS) 
2037              { 
2038                dstAxis->duplicateAttributes(srcElement.axis) ; // make a copy
2039                dstAxis->setTemplateId(srcElement.axis) ;
2040              }
2041              else 
2042              {
2043                dstAxis->duplicateAttributes(dstElement.axis) ; // make a copy$
2044                dstAxis->setTemplateId(dstElement.axis) ;
2045              }
2046              CTransformation<CAxis>* transformation = CTransformation<CAxis>::createTransformation(transType,"") ;
2047              auto srcTransform = CTransformation<CAxis>::getTransformation(transType, transId) ;
2048              transformation->inheritFrom(srcTransform) ;
2049              tmpGridDst->addAxis(dstAxis->getId()) ;
2050
2051              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 
2052                                                      posInGrid,posInGrid,posInGrid,
2053                                                      posInGrid,posInGrid,posInGrid );
2054
2055              dstAxis->setTransformationAlgorithm(algo) ;
2056              dstAxis->setTransformationPaths(transformationPath) ;
2057            }
2058           
2059            algo=dstAxis->getTransformationAlgorithm() ;
2060            isGenerate = algo->isGenerateTransformation() ;
2061            transformationPath.removeNextTransform() ;
2062            dstElementId=transformationPath.getNextElementId() ;
2063            srcElementId=transformationPath.getNextElementSrcId() ;
2064            transType = transformationPath.getNextTransformationType() ;
2065            transId = transformationPath.getNextTransformationId() ;
2066            lastDstAxis=dstAxis ;
2067            dstAxis->setTransformationPaths(transformationPath) ;
2068          } while(transformationPath.hasTransform() && isGenerate) ;
2069           
2070          if (isNewGrid) newGrid->addAxis(dstAxis->getId()) ;
2071          algo = dstAxis->getTransformationAlgorithm() ;
2072        }
2073        else if (dstElementType==EElement::SCALAR)
2074        {
2075          CScalar* dstScalar ;
2076          CScalar* lastDstScalar ;
2077          bool isGenerate=false ;
2078
2079          do 
2080          {
2081            if (CScalar::has(dstElementId)) 
2082            {
2083              dstScalar = CScalar::get(dstElementId) ;
2084              cout<<"Retrive existing scalar : "<<dstElementId<<endl ;
2085            }
2086            else
2087            {
2088              dstScalar = CScalar::create() ;
2089              dstScalar->createAlias(dstElementId) ;
2090              cout<<"Create new scalar : "<<dstScalar->getId()<<" with alias : "<<dstElementId<<endl ;
2091             
2092              if (isGenerate) 
2093              {
2094                dstScalar->duplicateAttributes(lastDstScalar) ;
2095                dstScalar->setTemplateId(lastDstScalar) ;
2096              }
2097              else if (srcElementId=="" && srcElement.type==TYPE_SCALAR)
2098              {
2099                dstScalar->duplicateAttributes(srcElement.scalar) ; // make a copy
2100                dstScalar->setTemplateId(srcElement.scalar) ;
2101              }
2102              else 
2103              {
2104                dstScalar->duplicateAttributes(dstElement.scalar) ; // make a copy
2105                dstScalar->setTemplateId(dstElement.scalar) ;
2106              }
2107              CTransformation<CScalar>* transformation = CTransformation<CScalar>::createTransformation(transType,"") ;
2108              auto srcTransform = CTransformation<CScalar>::getTransformation(transType, transId) ;
2109              transformation->inheritFrom(srcTransform) ;
2110              tmpGridDst->addScalar(dstScalar->getId()) ;
2111
2112              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 
2113                                                       posInGrid,posInGrid,posInGrid,
2114                                                       posInGrid,posInGrid,posInGrid );
2115             
2116              dstScalar->setTransformationAlgorithm(algo) ;
2117              dstScalar->setTransformationPaths(transformationPath) ;
2118            }
2119            algo=dstScalar->getTransformationAlgorithm() ;
2120            isGenerate = algo->isGenerateTransformation() ;
2121            transformationPath.removeNextTransform() ;
2122            dstElementId=transformationPath.getNextElementId() ;
2123            srcElementId=transformationPath.getNextElementSrcId() ;
2124            transType = transformationPath.getNextTransformationType() ;
2125            transId = transformationPath.getNextTransformationId() ;
2126            lastDstScalar=dstScalar ;
2127            dstScalar->setTransformationPaths(transformationPath) ;
2128          } while(transformationPath.hasTransform() && isGenerate) ;
2129
2130          if (isNewGrid) newGrid->addScalar(dstScalar->getId()) ;
2131          algo = dstScalar->getTransformationAlgorithm() ;         
2132        }
2133        // here create a new spatial filter with algo
2134       
2135        hadTransform=true ;
2136        hasTransform=false ; 
2137      }
2138      else
2139      {
2140        string srcElementId=transformationPath.getNextElementSrcId() ;
2141
2142        if (srcElement.type==TYPE_DOMAIN)     
2143        {
2144          CDomain* domain ;
2145          if (srcElementId=="") srcElementId=srcElement.domain->getId() ; 
2146          if (!CDomain::has(srcElementId)) 
2147          {
2148            domain=srcElement.domain ;
2149            domain->createAlias(srcElementId) ;
2150          }
2151          else domain = CDomain::get(srcElementId) ;
2152          domain->checkAttributes() ;
2153         
2154          if (isNewGrid) newGrid->addDomain(srcElementId) ;
2155        }
2156        else if (srcElement.type==TYPE_AXIS)
2157        {   
2158          CAxis* axis ;
2159          if (srcElementId=="") srcElementId=srcElement.axis->getId() ; 
2160          if (!CAxis::has(srcElementId)) 
2161          {
2162            axis=srcElement.axis ;
2163            axis->createAlias(srcElementId) ;
2164          }
2165          else axis = CAxis::get(srcElementId) ;
2166          axis->checkAttributes() ;
2167         
2168          if (isNewGrid) newGrid->addAxis(srcElementId) ;
2169        }
2170        else if (srcElement.type==TYPE_SCALAR)
2171        {
2172          CScalar* scalar ;
2173          if (srcElementId=="") srcElementId=srcElement.scalar->getId() ; 
2174          if (!CScalar::has(srcElementId)) 
2175          {
2176            scalar=srcElement.scalar ;
2177            scalar->createAlias(srcElementId) ;
2178          }
2179          else scalar = CScalar::get(srcElementId) ;
2180          scalar->checkAttributes() ;
2181         
2182          if (isNewGrid) newGrid->addScalar(srcElementId) ;
2183        }
2184      }
2185     
2186      if (transformationPath.hasTransform() && hadTransform) hasRemainTransform=true ;
2187    } 
2188   
2189
2190    if (hadTransform)
2191    {
2192     
2193      if (!isSource)
2194      {
2195        CGridAlgorithm* gridAlgorithm  ;
2196        if (isNewGrid)
2197        { 
2198          gridAlgorithm = algo->createGridAlgorithm(gridSrc, newGrid, pos) ;
2199          newGrid->setGridAlgorithm(gridAlgorithm);
2200        }
2201        else gridAlgorithm = newGrid->getGridAlgorithm() ;
2202
2203        shared_ptr<CTransformFilter> transformFilter = shared_ptr<CTransformFilter>(gridAlgorithm->createTransformFilter(gc, detectMissingValues, defaultValue)) ;
2204        outputFilter->connectOutput(transformFilter,0) ;
2205        if(graphEnabled)
2206        {
2207          transformFilter->graphEnabled=true;
2208          transformFilter->graphPackage = new CGraphPackage;
2209          transformFilter->graphPackage->inFields.push_back(field);
2210          transformFilter->graphPackage->show = !transformationGoing;
2211        }
2212       
2213        vector<string> auxFieldId = algo->getAuxFieldId() ; // better to do that at transformation not algo ??
2214        int i=1; 
2215        for (auto& it : auxFieldId)
2216        {
2217          CField* auxField = CField::get(it) ;
2218          auxField->buildWorkflowGraph(gc) ;
2219          auxField->getInstantDataFilter()->connectOutput(transformFilter,i) ;
2220          i++ ;
2221        }
2222        outputFilter = transformFilter ;
2223      }
2224
2225      if (hasRemainTransform)
2226      {
2227        transformationGoing = true;
2228        gridSrc=newGrid ;
2229        CField *field_bis = field;
2230        pair<shared_ptr<CFilter>, shared_ptr<CFilter> > filters = this->buildTransformationGraph(gc, isSource, gridSrc, detectMissingValues, defaultValue, newGrid, graphEnabled, field_bis) ;
2231        outputFilter->connectOutput(filters.first,0) ;
2232        outputFilter=filters.second ;
2233      }
2234      transformationGoing = false;
2235    }
2236     
2237    return {inputFilter,outputFilter} ;
2238  }
2239  CATCH_DUMP_ATTR
2240
2241
2242//****************************************************************
2243//****************************************************************
2244
2245//----------------------------------------------------------------
2246
2247  CGrid* CGrid::duplicateSentGrid(void)
2248  {
2249    CGrid* newGrid ;
2250    string sentGridId="sent__"+getId() ;
2251    if (has(sentGridId)) newGrid = get(sentGridId) ;
2252    else
2253    {
2254      newGrid = CGrid::create(sentGridId) ;
2255      for(auto element : elements_)
2256      {
2257        if (element.type==TYPE_DOMAIN)     
2258        {
2259          CDomain* domain = CDomain::create();
2260          domain->duplicateAttributes(element.domain) ;
2261          domain->setTemplateId(element.domain) ;
2262          domain->name = element.domain->getId() ;
2263          newGrid->addDomain(domain->getId()) ;
2264        }
2265        else if (element.type==TYPE_AXIS)     
2266        {
2267          CAxis* axis = CAxis::create();
2268          axis->duplicateAttributes(element.axis) ;
2269          axis->setTemplateId(element.axis) ;
2270          axis->name = element.axis->getId() ;
2271          newGrid->addAxis(axis->getId()) ;
2272        }
2273        else if (element.type==TYPE_SCALAR)     
2274        {
2275          CScalar* scalar = CScalar::create();
2276          scalar->duplicateAttributes(element.scalar) ;
2277          scalar->setTemplateId(element.scalar) ;
2278          scalar->name = element.scalar->getId() ;
2279          newGrid->addScalar(scalar->getId()) ;
2280        }
2281      }
2282      newGrid->checkElementsAttributes() ;
2283    }
2284    return newGrid ;
2285  }
2286
2287
2288  void CGrid::setContextClient(CContextClient* contextClient)
2289  TRY
2290  {
2291    if (clientsSet.find(contextClient)==clientsSet.end())
2292    {
2293      clients.push_back(contextClient) ;
2294      clientsSet.insert(contextClient);
2295    }
2296    for (auto domain : getDomains()) domain->setContextClient(contextClient);
2297    for (auto axis : getAxis()) axis->setContextClient(contextClient);
2298    for (auto scalar : getScalars()) scalar->setContextClient(contextClient);
2299   
2300  }
2301  CATCH_DUMP_ATTR
2302
2303 
2304  void CGrid::computeGridLocalElements()
2305  {
2306    std::vector<CDomain*> domainList = this->getDomains();
2307    std::vector<CAxis*> axisList = this->getAxis();
2308    std::vector<CScalar*> scalarList = this->getScalars();
2309    auto domain=domainList.begin() ;
2310    auto axis=axisList.begin() ;
2311    auto scalar=scalarList.begin() ;
2312    vector<CLocalElement*> elements;
2313    for(auto order : order_)
2314    {
2315      if (order==2) 
2316      {
2317        elements.push_back((*domain)->getLocalElement());
2318        domain++ ;
2319      }
2320      else if (order==1)
2321      {
2322        elements.push_back((*axis)->getLocalElement());
2323        axis++ ;
2324      }
2325      else if (order==0)
2326      { 
2327        elements.push_back((*scalar)->getLocalElement());
2328        scalar++ ;
2329      }
2330    }
2331    if (hasMask()) 
2332    {
2333      vector<bool> mask(getMask().getVector()) ;
2334      gridLocalElements_ = new CGridLocalElements(elements, mask) ; 
2335    }
2336    else gridLocalElements_ = new CGridLocalElements(elements) ; 
2337  }
2338
2339  void CGrid::computeModelToWorkflowConnector(void)
2340  {
2341    modelToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::MODEL,CElementView::WORKFLOW,true) ;
2342  }
2343
2344  void CGrid::computeWorkflowToFullConnector(void)
2345  {
2346    workflowToFullConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::FULL) ;
2347  }
2348
2349  void CGrid::computeWorkflowToModelConnector(void)
2350  {
2351    workflowToModelConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::MODEL,true) ;
2352  }
2353
2354  void CGrid::computeFullToWorkflowConnector(void)
2355  {
2356    fullToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::FULL,CElementView::WORKFLOW) ;
2357  }
2358
2359  void CGrid::computeServerFromClientConnector(void)
2360  {
2361    vector<CGathererConnector*> connectors ;
2362    for(auto& element : getElements())
2363    {
2364      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ;
2365      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 
2366      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 
2367    }
2368    serverFromClientConnector_ = new CGridGathererConnector(connectors) ;
2369  }
2370
2371  void CGrid::computeServerToClientConnector(void)
2372  {
2373    vector<CScattererConnector*> connectors ;
2374    for(auto& element : getElements())
2375    {
2376      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerToClientConnector()) ;
2377      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerToClientConnector()) ; 
2378      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerToClientConnector()) ; 
2379    }
2380    serverToClientConnector_ = new CGridScattererConnector(connectors) ;
2381  }
2382
2383  void CGrid::computeClientFromClientConnector(void)
2384  {
2385    vector<CGathererConnector*> connectors ;
2386    for(auto& element : getElements())
2387    {
2388      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ;
2389      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 
2390      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 
2391    }
2392    clientFromClientConnector_ = new CGridGathererConnector(connectors) ;
2393  }
2394
2395 
2396} // namespace xios
Note: See TracBrowser for help on using the repository browser.