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

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

New feature : when can now use the syntax :
fieldId:domainId[n], in domain reference inside the workflow (XML). Same for axis and scalar.

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: 79.9 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_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   
1430    vector<CLocalView*> localViews ;
1431    vector<CDistributedView*> remoteViews ;
1432
1433    for(int i=0 ; i<elements.size() ; i++)
1434    {
1435      if (elements[i].type==TYPE_DOMAIN) 
1436      { 
1437         CDomain* domain = (CDomain*) elements[i].ptr ;
1438         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
1439         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ;
1440         localViews.push_back(domain->getLocalView(CElementView::FULL)) ;
1441      }
1442      else if (elements[i].type==TYPE_AXIS)
1443      {
1444        CAxis* axis = (CAxis*) elements[i].ptr ;
1445        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
1446        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ;
1447        localViews.push_back(axis->getLocalView(CElementView::FULL)) ;
1448      }
1449      else if (elements[i].type==TYPE_SCALAR)
1450      {
1451        CScalar* scalar = (CScalar*) elements[i].ptr ;
1452        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ;
1453        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ;
1454        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ;
1455      }
1456    }
1457    CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm(), client->getRemoteSize()) ;
1458    gridRemoteConnector.computeConnector() ;
1459   
1460    vector<CScattererConnector*> scattererConnectors ;
1461    CScattererConnector* scattererConnector;
1462    for(int i=0 ; i<elements.size() ; i++)
1463    {
1464      if (elements[i].type==TYPE_DOMAIN) 
1465      { 
1466        CDomain* domain = (CDomain*) elements[i].ptr ;
1467        if (isCoupling) domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector,  domain->getCouplingAlias(fieldId,i)) ;
1468        else 
1469        {
1470          sendAddDomain(domain->getId(),client) ;
1471          domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ;
1472        }
1473        scattererConnectors.push_back(scattererConnector) ;
1474      }
1475      else if (elements[i].type==TYPE_AXIS)
1476      {
1477        CAxis* axis = (CAxis*) elements[i].ptr ;
1478        if (isCoupling) axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector,  axis->getCouplingAlias(fieldId,i)) ;
1479        else 
1480        {
1481          sendAddAxis(axis->getId(),client) ;
1482          axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ;
1483        }
1484        scattererConnectors.push_back(scattererConnector) ;
1485      }
1486      else if (elements[i].type==TYPE_SCALAR)
1487      {
1488        CScalar* scalar = (CScalar*) elements[i].ptr ;
1489        if (isCoupling) scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector,  scalar->getCouplingAlias(fieldId,i)) ;
1490        else 
1491        {
1492          sendAddScalar(scalar->getId(),client) ;
1493          scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ;
1494        }
1495        scattererConnectors.push_back(scattererConnector) ;
1496      }
1497    }
1498
1499    CGridScattererConnector gridScattererConnector(scattererConnectors) ;
1500    CGridLocalConnector* workflowToFull = getGridLocalElements()->getConnector(CElementView::WORKFLOW, CElementView::FULL) ;
1501    CArray<bool,1> maskIn(workflowToFull->getSrcSize()) ;
1502    CArray<bool,1> maskOut(workflowToFull->getDstSize()) ;
1503    maskIn = true ;
1504    workflowToFull->transfer(maskIn,maskOut,false) ;
1505
1506    CEventClient event(getType(), EVENT_ID_SEND_MASK);
1507    CMessage message ;
1508    if (isCoupling) message<<getCouplingAlias(fieldId) ;
1509    else message<<getId() ; 
1510    gridScattererConnector.transfer(maskOut, client, event, message) ;
1511    for(auto& it : scattererConnectors) delete it ;
1512
1513    vector<CScattererConnector*> clientToServerConnectors ;
1514    vector<CGathererConnector*>  clientFromServerConnectors ;
1515    for(auto& element : elements)
1516    {
1517      if (element.type==TYPE_DOMAIN) 
1518      { 
1519         clientToServerConnectors.push_back(element.domain->getClientToServerConnector(client)) ;
1520         clientFromServerConnectors.push_back(element.domain->getClientFromServerConnector(client)) ;
1521      }
1522      else if (element.type==TYPE_AXIS)
1523      {
1524        clientToServerConnectors.push_back(element.axis->getClientToServerConnector(client)) ;
1525        clientFromServerConnectors.push_back(element.axis->getClientFromServerConnector(client)) ;
1526
1527      }
1528      else if (element.type==TYPE_SCALAR)
1529      {
1530        clientToServerConnectors.push_back(element.scalar->getClientToServerConnector(client)) ;
1531        clientFromServerConnectors.push_back(element.scalar->getClientFromServerConnector(client)) ;
1532      }
1533    }
1534   
1535    // compute the grid clientToServerConnector to send flux from client to servers
1536    clientToServerConnector_[client] = new CGridScattererConnector(clientToServerConnectors) ;
1537    clientFromServerConnector_[client] = new CGridGathererConnector(clientFromServerConnectors) ;
1538
1539  }
1540
1541
1542  void CGrid::recvMask(CEventServer& event)
1543  {
1544    string gridId;
1545    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> gridId  ;
1546    get(gridId)->receiveMask(event);
1547  }
1548 
1549  void CGrid::receiveMask(CEventServer& event)
1550  {
1551    vector<CGathererConnector*> gathererConnectors ;
1552    vector<CLocalView*> fullViews ;
1553
1554    for(auto& element : getElements())
1555    {
1556      if (element.type==TYPE_DOMAIN) 
1557      {
1558        gathererConnectors.push_back(element.domain->getGathererConnector());
1559        fullViews.push_back(element.domain->getLocalElement()->getView(CElementView::FULL));
1560       
1561      }
1562      else if (element.type==TYPE_AXIS)
1563      {
1564       gathererConnectors.push_back(element.axis->getGathererConnector());
1565       fullViews.push_back(element.axis->getLocalElement()->getView(CElementView::FULL));
1566      }
1567      else if (element.type==TYPE_SCALAR) 
1568      {
1569        gathererConnectors.push_back(element.scalar->getGathererConnector());
1570        fullViews.push_back(element.scalar->getLocalElement()->getView(CElementView::FULL));
1571      }
1572    }
1573    CGridGathererConnector gridGathererConnector(gathererConnectors) ;
1574    CGridMaskConnector gridMaskConnector(fullViews) ;
1575
1576    CArray<bool,1> maskOut ;
1577    gridGathererConnector.transfer_or(event,maskOut) ;
1578    gridMaskConnector.computeConnector(maskOut) ;
1579
1580    CContextClient* client = event.getContextServer()->getAssociatedClient() ;
1581    int i=0 ;
1582    for(auto& element : getElements())
1583    {
1584      if (element.type==TYPE_DOMAIN) element.domain->setServerMask(gridMaskConnector.getElementMask(i),client);
1585      else if (element.type==TYPE_AXIS) element.axis->setServerMask(gridMaskConnector.getElementMask(i),client);
1586      else if (element.type==TYPE_SCALAR) element.scalar->setServerMask(gridMaskConnector.getElementMask(i),client);
1587      i++ ;
1588    }
1589  }
1590
1591  string CGrid::getCouplingAlias(const string& fieldId)
1592  {
1593    return "_grid_of_"+fieldId;
1594  }
1595
1596  void CGrid::makeAliasForCoupling(const string& fieldId)
1597  {
1598    string gridId=getCouplingAlias(fieldId) ;
1599    createAlias(gridId) ;
1600
1601    auto& elements = getElements() ;
1602    for(int i=0 ; i<elements.size() ; i++)
1603    {
1604      if (elements[i].type==TYPE_DOMAIN) elements[i].domain->makeAliasForCoupling(fieldId, i);
1605      else if (elements[i].type==TYPE_AXIS) elements[i].axis->makeAliasForCoupling(fieldId, i);
1606      else if (elements[i].type==TYPE_SCALAR) elements[i].scalar->makeAliasForCoupling(fieldId, i);
1607    }
1608  }
1609
1610   /*!
1611   \brief Send a message to create a domain on server side
1612   \param[in] id String identity of domain that will be created on server
1613   */
1614   void CGrid::sendAddDomain(const string& id, CContextClient* contextClient)
1615   TRY
1616  {
1617      sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN, contextClient);
1618   }
1619   CATCH_DUMP_ATTR
1620
1621   /*!
1622   \brief Send a message to create an axis on server side
1623   \param[in] id String identity of axis that will be created on server
1624   */
1625   void CGrid::sendAddAxis(const string& id, CContextClient* contextClient)
1626   TRY
1627   {
1628      sendAddItem(id, (int)EVENT_ID_ADD_AXIS, contextClient);
1629   }
1630   CATCH_DUMP_ATTR
1631
1632   /*!
1633   \brief Send a message to create a scalar on server side
1634   \param[in] id String identity of scalar that will be created on server
1635   */
1636   void CGrid::sendAddScalar(const string& id, CContextClient* contextClient)
1637   TRY
1638   {
1639      sendAddItem(id, (int)EVENT_ID_ADD_SCALAR, contextClient);
1640   }
1641   CATCH_DUMP_ATTR
1642
1643   /*!
1644   \brief Receive a message annoucing the creation of a domain on server side
1645   \param[in] event Received event
1646   */
1647   void CGrid::recvAddDomain(CEventServer& event)
1648   TRY
1649   {
1650
1651      CBufferIn* buffer = event.subEvents.begin()->buffer;
1652      string id;
1653      *buffer >> id;
1654      get(id)->recvAddDomain(*buffer);
1655   }
1656   CATCH
1657
1658   /*!
1659   \brief Receive a message annoucing the creation of a domain on server side
1660   \param[in] buffer Buffer containing message
1661   */
1662   void CGrid::recvAddDomain(CBufferIn& buffer)
1663   TRY
1664   {
1665      string id;
1666      buffer >> id;
1667      addDomain(id);
1668   }
1669   CATCH_DUMP_ATTR
1670
1671   /*!
1672   \brief Receive a message annoucing the creation of an axis on server side
1673   \param[in] event Received event
1674   */
1675   void CGrid::recvAddAxis(CEventServer& event)
1676   TRY
1677   {
1678
1679      CBufferIn* buffer = event.subEvents.begin()->buffer;
1680      string id;
1681      *buffer >> id;
1682      get(id)->recvAddAxis(*buffer);
1683   }
1684   CATCH
1685
1686   /*!
1687   \brief Receive a message annoucing the creation of an axis on server side
1688   \param[in] buffer Buffer containing message
1689   */
1690   void CGrid::recvAddAxis(CBufferIn& buffer)
1691   TRY
1692   {
1693      string id;
1694      buffer >> id;
1695      addAxis(id);
1696   }
1697   CATCH_DUMP_ATTR
1698
1699   /*!
1700   \brief Receive a message annoucing the creation of an scalar on server side
1701   \param[in] event Received event
1702   */
1703   void CGrid::recvAddScalar(CEventServer& event)
1704   TRY
1705   {
1706
1707      CBufferIn* buffer = event.subEvents.begin()->buffer;
1708      string id;
1709      *buffer >> id;
1710      get(id)->recvAddScalar(*buffer);
1711   }
1712   CATCH
1713
1714   /*!
1715   \brief Receive a message annoucing the creation of an scalar on server side
1716   \param[in] buffer Buffer containing message
1717   */
1718   void CGrid::recvAddScalar(CBufferIn& buffer)
1719   TRY
1720   {
1721      string id;
1722      buffer >> id;
1723      addScalar(id);
1724   }
1725   CATCH_DUMP_ATTR
1726
1727  /*!
1728  \brief Check if all elements of the grid are complete
1729  Before make any grid processing, we must be sure that all grid information elements have
1730  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
1731  other context (coupling)
1732  */
1733  bool CGrid::isCompleted(void)
1734  {
1735    setDomainList();
1736    for (auto domainId : domList_) if (!CDomain::get(domainId)->isCompleted()) return false ;
1737    setAxisList() ;
1738    for (auto axisId : axisList_) if (!CAxis::get(axisId)->isCompleted()) return false ;
1739    setScalarList() ;
1740    for (auto scalarId : scalarList_) if (!CScalar::get(scalarId)->isCompleted()) return false ;
1741    return true ;
1742  }
1743
1744  /*!
1745  \brief impose that all elements of the grid are complete
1746  Before make any grid processing, we must be sure that all grid information elements have
1747  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
1748  other context (coupling)
1749  */
1750  void CGrid::setCompleted(void)
1751  {
1752    setDomainList();
1753    for (auto domainId : domList_) CDomain::get(domainId)->setCompleted() ;
1754    setAxisList() ;
1755    for (auto axisId : axisList_) CAxis::get(axisId)->setCompleted() ;
1756    setScalarList() ;
1757    for (auto scalarId : scalarList_) CScalar::get(scalarId)->setCompleted() ;
1758  }
1759
1760/*!
1761  \brief impose that all elements of the grid are incomplete
1762  Before make any grid processing, we must be sure that all grid information elements have
1763  been sent, for exemple when reading a grid in a file or when grid elements are sent by an
1764  other context (coupling)
1765  */
1766  void CGrid::unsetCompleted(void)
1767  {
1768    setDomainList();
1769    for (auto domainId : domList_) CDomain::get(domainId)->unsetCompleted() ;
1770    setAxisList() ;
1771    for (auto axisId : axisList_) CAxis::get(axisId)->unsetCompleted() ;
1772    setScalarList() ;
1773    for (auto scalarId : scalarList_) CScalar::get(scalarId)->unsetCompleted() ;
1774  }
1775
1776  /*!
1777  \brief Solve domain and axis references
1778  As field, domain and axis can refer to other domains or axis. In order to inherit correctly
1779  all attributes from their parents, they should be processed with this function
1780  \param[in] apply inherit all attributes of parents (true)
1781  */
1782  void CGrid::solveElementsRefInheritance(bool apply)
1783  TRY
1784  {
1785    setDomainList();
1786    for (auto domainId : domList_)
1787    {
1788      CDomain* pDom = CDomain::get(domainId);
1789      pDom->solveRefInheritance(apply);
1790      pDom->solveInheritanceTransformation();
1791    }
1792
1793    setAxisList();
1794    for (auto axisId : axisList_)
1795    {
1796      CAxis* pAxis = CAxis::get(axisId);
1797      pAxis->solveRefInheritance(apply);
1798      pAxis->solveInheritanceTransformation();
1799    }
1800
1801    setScalarList();
1802    for (auto scalarId : scalarList_)
1803    {
1804      CScalar* pScalar = CScalar::get(scalarId);
1805      pScalar->solveRefInheritance(apply);
1806      pScalar->solveInheritanceTransformation();
1807    }
1808  }
1809  CATCH_DUMP_ATTR
1810
1811  bool CGrid::activateFieldWorkflow(CGarbageCollector& gc)
1812  TRY
1813  {
1814    setDomainList();
1815    for (auto domainId : domList_)
1816    {
1817      CDomain* pDom = CDomain::get(domainId);
1818      bool ret = pDom->activateFieldWorkflow(gc);
1819      if (!ret) return false ;
1820    }
1821
1822    setAxisList();
1823    for (auto axisId : axisList_)
1824    {
1825      CAxis* pAxis = CAxis::get(axisId);
1826      bool ret = pAxis->activateFieldWorkflow(gc);
1827      if (!ret) return false ;
1828    }
1829
1830    setScalarList();
1831    for (auto scalarId : scalarList_)
1832    {
1833      CScalar* pScalar = CScalar::get(scalarId);
1834      bool ret = pScalar->activateFieldWorkflow(gc);
1835      if (!ret) return false ;
1836    }
1837    return true ;
1838  }
1839  CATCH_DUMP_ATTR
1840
1841 /*!
1842  \brief check attributes of all elements of the grid
1843  */
1844  void CGrid::checkElementsAttributes(void)
1845  TRY
1846  {
1847    setDomainList();
1848    for (auto domainId : domList_) CDomain::get(domainId)->checkAttributes();
1849
1850    setAxisList();
1851    for (auto axisId : axisList_) CAxis::get(axisId)->checkAttributes();
1852   
1853    setScalarList();
1854    for (auto scalarId : scalarList_) CScalar::get(scalarId)->checkAttributes();
1855  }
1856  CATCH_DUMP_ATTR
1857
1858
1859
1860//**********************************************************
1861//**************   New transformation method  **************
1862//**********************************************************
1863
1864  std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > 
1865  CGrid::buildTransformationGraph(CGarbageCollector& gc, bool isSource, CGrid* gridSrc, double detectMissingValues, double defaultValue, CGrid*& newGrid, bool graphEnabled, CField* field)
1866  TRY
1867  {
1868    static bool transformationGoing = false;
1869    registerAlgorithmTransformation() ; // needed to enable self-registration of the transformations
1870                                        // big mystery why it doesn't work witout that...
1871                                        // problem with the linker ??
1872
1873    std::shared_ptr<CFilter> inputFilter = std::shared_ptr<CPassThroughFilter>(new CPassThroughFilter(gc));
1874    std::shared_ptr<CFilter> outputFilter = inputFilter ;
1875
1876
1877    string newId ;
1878    if (gridSrc!=nullptr) newId = gridSrc->getId() + " --> " + this->getId()  ;
1879    else newId = " --> " + this->getId()  ;
1880    bool isNewGrid ;
1881    if (CGrid::has(newId))
1882    {
1883      cout<<"Retrive existing grid : "<<newId<<endl ;
1884      newGrid = CGrid::get(newId);
1885      isNewGrid = false ;
1886    }
1887    else 
1888    {
1889      cout<<"Create new grid : "<<newId<<endl ;
1890      newGrid = CGrid::create(newId) ;
1891      isNewGrid = true ;
1892    }
1893
1894    bool hadTransform=false ;
1895    bool hasTransform=false ;
1896    bool hasRemainTransform=false ;
1897    CGenericAlgorithmTransformation* algo ;
1898    int pos ;
1899
1900    for(int i=0 ; i<elements_.size(); i++)
1901    {
1902      CTransformationPaths transformationPath ;
1903      auto dstElement = elements_[i] ;
1904
1905      if (dstElement.type==TYPE_DOMAIN)      transformationPath = dstElement.domain->getTransformationPaths() ;
1906      else if (dstElement.type==TYPE_AXIS)   transformationPath = dstElement.axis->getTransformationPaths() ;
1907      else if (dstElement.type==TYPE_SCALAR) transformationPath = dstElement.scalar->getTransformationPaths() ;
1908
1909      SElement srcElement  ;
1910      if (gridSrc==nullptr) srcElement = this->elements_[i] ;
1911      else srcElement = gridSrc->elements_[i] ;
1912
1913      if (gridSrc==nullptr) transformationPath.mergePaths() ;
1914      else
1915      { 
1916        if (srcElement.type==TYPE_DOMAIN)      transformationPath.mergePaths(srcElement.domain->getTransformationPaths()) ;
1917        else if (srcElement.type==TYPE_AXIS)   transformationPath.mergePaths(srcElement.axis->getTransformationPaths()) ;
1918        else if (srcElement.type==TYPE_SCALAR) transformationPath.mergePaths(srcElement.scalar->getTransformationPaths()) ;
1919      }
1920
1921      hasTransform=transformationPath.hasTransform()  ;
1922     
1923      if (hasTransform && !hadTransform)
1924      {
1925        pos=i ;
1926        EElement dstElementType=transformationPath.getNextElementType() ;
1927        string dstElementId=transformationPath.getNextElementId() ;
1928        string srcElementId=transformationPath.getNextElementSrcId() ;
1929        auto transType = transformationPath.getNextTransformationType() ;
1930        auto transId = transformationPath.getNextTransformationId() ;
1931
1932        CGrid* tmpGridSrc=CGrid::create(); // source grid
1933        if (srcElement.type==TYPE_DOMAIN)      tmpGridSrc->addDomain(srcElement.domain->getId()) ;
1934        else if (srcElement.type==TYPE_AXIS)   tmpGridSrc->addAxis(srcElement.axis->getId()) ;
1935        else if (srcElement.type==TYPE_SCALAR) tmpGridSrc->addScalar(srcElement.scalar->getId()) ;
1936        // WARNING -> suppress checkElement attribute ? What append ?
1937        // tmpGridSrc->checkElementsAttributes() ;
1938        CGrid* tmpGridDst=CGrid::create(); // destination Grid
1939        map<int,int> posInGrid={{0,0}} ;
1940               
1941        cout<<"--> New transform from "<<srcElementId<<" to "<<dstElementId<<endl ;
1942        if (dstElementType==EElement::DOMAIN)
1943        {
1944          CDomain* dstDomain ;
1945          CDomain* lastDstDomain ;
1946          bool isGenerate=false ;
1947   
1948          do 
1949          {
1950
1951            if (CDomain::has(dstElementId)) 
1952            {
1953              dstDomain = CDomain::get(dstElementId) ;
1954              cout<<"Retrive existing domain : "<<dstElementId<<endl ;
1955            }
1956            else
1957            {
1958              dstDomain = CDomain::create() ;
1959              dstDomain->createAlias(dstElementId) ;
1960              cout<<"Create new domain : "<<dstDomain->getId()<<" with alias : "<<dstElementId<<endl ;
1961
1962              if (isGenerate) 
1963              {
1964                dstDomain->duplicateAttributes(lastDstDomain) ;
1965                dstDomain->setTemplateId(lastDstDomain) ;
1966              }
1967              else if (srcElementId=="" && srcElement.type==TYPE_DOMAIN) 
1968              {
1969                dstDomain->duplicateAttributes(srcElement.domain) ; // make a copy
1970                dstDomain->setTemplateId(srcElement.domain) ;
1971              }
1972              else 
1973              {
1974                dstDomain->duplicateAttributes(dstElement.domain) ; // make a copy
1975                dstDomain->setTemplateId(dstElement.domain) ;
1976              }
1977              CTransformation<CDomain>* transformation = CTransformation<CDomain>::createTransformation(transType,"") ;
1978              auto srcTransform = CTransformation<CDomain>::getTransformation(transType, transId) ;
1979              transformation->inheritFrom(srcTransform) ;
1980              CGrid* tmpGridDst=CGrid::create(); // destination Grid
1981              tmpGridDst->addDomain(dstDomain->getId()) ;
1982
1983              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 
1984                                                       posInGrid,posInGrid,posInGrid,
1985                                                       posInGrid,posInGrid,posInGrid );
1986
1987
1988              dstDomain->setTransformationAlgorithm(algo) ;
1989              dstDomain->setTransformationPaths(transformationPath) ;
1990            }
1991            algo=dstDomain->getTransformationAlgorithm() ;
1992            isGenerate = algo->isGenerateTransformation() ;
1993            transformationPath.removeNextTransform() ;
1994            dstElementId=transformationPath.getNextElementId() ;
1995            srcElementId=transformationPath.getNextElementSrcId() ;
1996            transType = transformationPath.getNextTransformationType() ;
1997            transId = transformationPath.getNextTransformationId() ;
1998            lastDstDomain=dstDomain ;
1999            dstDomain->setTransformationPaths(transformationPath) ;
2000          } while(transformationPath.hasTransform() && isGenerate) ;
2001
2002          if (isNewGrid) newGrid->addDomain(dstDomain->getId()) ;
2003          algo = dstDomain->getTransformationAlgorithm() ;
2004        }
2005        else if (dstElementType==EElement::AXIS)
2006        {
2007          CAxis* dstAxis ;
2008          CAxis* lastDstAxis ;
2009          bool isGenerate=false ;
2010
2011          do 
2012          {
2013            if (CAxis::has(dstElementId)) 
2014            {
2015              dstAxis = CAxis::get(dstElementId) ;
2016              cout<<"Retrive existing axis : "<<dstElementId<<endl ;
2017            }
2018            else
2019            {
2020              dstAxis = CAxis::create() ;
2021              dstAxis->createAlias(dstElementId) ;
2022              cout<<"Create new axis : "<<dstAxis->getId()<<" with alias : "<<dstElementId<<endl ;
2023             
2024              if (isGenerate) 
2025              {
2026                dstAxis->duplicateAttributes(lastDstAxis) ;
2027                dstAxis->setTemplateId(lastDstAxis) ;
2028              }
2029              else if (srcElementId=="" && srcElement.type==TYPE_AXIS) 
2030              { 
2031                dstAxis->duplicateAttributes(srcElement.axis) ; // make a copy
2032                dstAxis->setTemplateId(srcElement.axis) ;
2033              }
2034              else 
2035              {
2036                dstAxis->duplicateAttributes(dstElement.axis) ; // make a copy$
2037                dstAxis->setTemplateId(dstElement.axis) ;
2038              }
2039              CTransformation<CAxis>* transformation = CTransformation<CAxis>::createTransformation(transType,"") ;
2040              auto srcTransform = CTransformation<CAxis>::getTransformation(transType, transId) ;
2041              transformation->inheritFrom(srcTransform) ;
2042              tmpGridDst->addAxis(dstAxis->getId()) ;
2043
2044              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 
2045                                                      posInGrid,posInGrid,posInGrid,
2046                                                      posInGrid,posInGrid,posInGrid );
2047
2048              dstAxis->setTransformationAlgorithm(algo) ;
2049              dstAxis->setTransformationPaths(transformationPath) ;
2050            }
2051           
2052            algo=dstAxis->getTransformationAlgorithm() ;
2053            isGenerate = algo->isGenerateTransformation() ;
2054            transformationPath.removeNextTransform() ;
2055            dstElementId=transformationPath.getNextElementId() ;
2056            srcElementId=transformationPath.getNextElementSrcId() ;
2057            transType = transformationPath.getNextTransformationType() ;
2058            transId = transformationPath.getNextTransformationId() ;
2059            lastDstAxis=dstAxis ;
2060            dstAxis->setTransformationPaths(transformationPath) ;
2061          } while(transformationPath.hasTransform() && isGenerate) ;
2062           
2063          if (isNewGrid) newGrid->addAxis(dstAxis->getId()) ;
2064          algo = dstAxis->getTransformationAlgorithm() ;
2065        }
2066        else if (dstElementType==EElement::SCALAR)
2067        {
2068          CScalar* dstScalar ;
2069          CScalar* lastDstScalar ;
2070          bool isGenerate=false ;
2071
2072          do 
2073          {
2074            if (CScalar::has(dstElementId)) 
2075            {
2076              dstScalar = CScalar::get(dstElementId) ;
2077              cout<<"Retrive existing scalar : "<<dstElementId<<endl ;
2078            }
2079            else
2080            {
2081              dstScalar = CScalar::create() ;
2082              dstScalar->createAlias(dstElementId) ;
2083              cout<<"Create new scalar : "<<dstScalar->getId()<<" with alias : "<<dstElementId<<endl ;
2084             
2085              if (isGenerate) 
2086              {
2087                dstScalar->duplicateAttributes(lastDstScalar) ;
2088                dstScalar->setTemplateId(lastDstScalar) ;
2089              }
2090              else if (srcElementId=="" && srcElement.type==TYPE_SCALAR)
2091              {
2092                dstScalar->duplicateAttributes(srcElement.scalar) ; // make a copy
2093                dstScalar->setTemplateId(srcElement.scalar) ;
2094              }
2095              else 
2096              {
2097                dstScalar->duplicateAttributes(dstElement.scalar) ; // make a copy
2098                dstScalar->setTemplateId(dstElement.scalar) ;
2099              }
2100              CTransformation<CScalar>* transformation = CTransformation<CScalar>::createTransformation(transType,"") ;
2101              auto srcTransform = CTransformation<CScalar>::getTransformation(transType, transId) ;
2102              transformation->inheritFrom(srcTransform) ;
2103              tmpGridDst->addScalar(dstScalar->getId()) ;
2104
2105              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0, 
2106                                                       posInGrid,posInGrid,posInGrid,
2107                                                       posInGrid,posInGrid,posInGrid );
2108             
2109              dstScalar->setTransformationAlgorithm(algo) ;
2110              dstScalar->setTransformationPaths(transformationPath) ;
2111            }
2112            algo=dstScalar->getTransformationAlgorithm() ;
2113            isGenerate = algo->isGenerateTransformation() ;
2114            transformationPath.removeNextTransform() ;
2115            dstElementId=transformationPath.getNextElementId() ;
2116            srcElementId=transformationPath.getNextElementSrcId() ;
2117            transType = transformationPath.getNextTransformationType() ;
2118            transId = transformationPath.getNextTransformationId() ;
2119            lastDstScalar=dstScalar ;
2120            dstScalar->setTransformationPaths(transformationPath) ;
2121          } while(transformationPath.hasTransform() && isGenerate) ;
2122
2123          if (isNewGrid) newGrid->addScalar(dstScalar->getId()) ;
2124          algo = dstScalar->getTransformationAlgorithm() ;         
2125        }
2126        // here create a new spatial filter with algo
2127       
2128        hadTransform=true ;
2129        hasTransform=false ; 
2130      }
2131      else
2132      {
2133        string srcElementId=transformationPath.getNextElementSrcId() ;
2134
2135        if (srcElement.type==TYPE_DOMAIN)     
2136        {
2137          CDomain* domain ;
2138          if (srcElementId=="") srcElementId=srcElement.domain->getId() ; 
2139          if (!CDomain::has(srcElementId)) 
2140          {
2141            domain=srcElement.domain ;
2142            domain->createAlias(srcElementId) ;
2143          }
2144          else domain = CDomain::get(srcElementId) ;
2145          domain->checkAttributes() ;
2146         
2147          if (isNewGrid) newGrid->addDomain(srcElementId) ;
2148        }
2149        else if (srcElement.type==TYPE_AXIS)
2150        {   
2151          CAxis* axis ;
2152          if (srcElementId=="") srcElementId=srcElement.axis->getId() ; 
2153          if (!CAxis::has(srcElementId)) 
2154          {
2155            axis=srcElement.axis ;
2156            axis->createAlias(srcElementId) ;
2157          }
2158          else axis = CAxis::get(srcElementId) ;
2159          axis->checkAttributes() ;
2160         
2161          if (isNewGrid) newGrid->addAxis(srcElementId) ;
2162        }
2163        else if (srcElement.type==TYPE_SCALAR)
2164        {
2165          CScalar* scalar ;
2166          if (srcElementId=="") srcElementId=srcElement.scalar->getId() ; 
2167          if (!CScalar::has(srcElementId)) 
2168          {
2169            scalar=srcElement.scalar ;
2170            scalar->createAlias(srcElementId) ;
2171          }
2172          else scalar = CScalar::get(srcElementId) ;
2173          scalar->checkAttributes() ;
2174         
2175          if (isNewGrid) newGrid->addScalar(srcElementId) ;
2176        }
2177      }
2178     
2179      if (transformationPath.hasTransform() && hadTransform) hasRemainTransform=true ;
2180    } 
2181   
2182
2183    if (hadTransform)
2184    {
2185     
2186      if (!isSource)
2187      {
2188        CGridAlgorithm* gridAlgorithm  ;
2189        if (isNewGrid)
2190        { 
2191          gridAlgorithm = algo->createGridAlgorithm(gridSrc, newGrid, pos) ;
2192          newGrid->setGridAlgorithm(gridAlgorithm);
2193        }
2194        else gridAlgorithm = newGrid->getGridAlgorithm() ;
2195
2196        shared_ptr<CTransformFilter> transformFilter = shared_ptr<CTransformFilter>(gridAlgorithm->createTransformFilter(gc, detectMissingValues, defaultValue)) ;
2197        outputFilter->connectOutput(transformFilter,0) ;
2198        if(graphEnabled)
2199        {
2200          transformFilter->graphEnabled=true;
2201          transformFilter->graphPackage = new CGraphPackage;
2202          transformFilter->graphPackage->inFields.push_back(field);
2203          transformFilter->graphPackage->show = !transformationGoing;
2204        }
2205       
2206        vector<string> auxFieldId = algo->getAuxFieldId() ; // better to do that at transformation not algo ??
2207        int i=1; 
2208        for (auto& it : auxFieldId)
2209        {
2210          CField* auxField = CField::get(it) ;
2211          auxField->buildWorkflowGraph(gc) ;
2212          auxField->getInstantDataFilter()->connectOutput(transformFilter,i) ;
2213          i++ ;
2214        }
2215        outputFilter = transformFilter ;
2216      }
2217
2218      if (hasRemainTransform)
2219      {
2220        transformationGoing = true;
2221        gridSrc=newGrid ;
2222        CField *field_bis = field;
2223        pair<shared_ptr<CFilter>, shared_ptr<CFilter> > filters = this->buildTransformationGraph(gc, isSource, gridSrc, detectMissingValues, defaultValue, newGrid, graphEnabled, field_bis) ;
2224        outputFilter->connectOutput(filters.first,0) ;
2225        outputFilter=filters.second ;
2226      }
2227      transformationGoing = false;
2228    }
2229     
2230    return {inputFilter,outputFilter} ;
2231  }
2232  CATCH_DUMP_ATTR
2233
2234
2235//****************************************************************
2236//****************************************************************
2237
2238//----------------------------------------------------------------
2239
2240  CGrid* CGrid::duplicateSentGrid(void)
2241  {
2242    CGrid* newGrid ;
2243    string sentGridId="sent__"+getId() ;
2244    if (has(sentGridId)) newGrid = get(sentGridId) ;
2245    else
2246    {
2247      newGrid = CGrid::create(sentGridId) ;
2248      for(auto element : elements_)
2249      {
2250        if (element.type==TYPE_DOMAIN)     
2251        {
2252          CDomain* domain = CDomain::create();
2253          domain->duplicateAttributes(element.domain) ;
2254          domain->setTemplateId(element.domain) ;
2255          domain->name = element.domain->getId() ;
2256          newGrid->addDomain(domain->getId()) ;
2257        }
2258        else if (element.type==TYPE_AXIS)     
2259        {
2260          CAxis* axis = CAxis::create();
2261          axis->duplicateAttributes(element.axis) ;
2262          axis->setTemplateId(element.axis) ;
2263          axis->name = element.axis->getId() ;
2264          newGrid->addAxis(axis->getId()) ;
2265        }
2266        else if (element.type==TYPE_SCALAR)     
2267        {
2268          CScalar* scalar = CScalar::create();
2269          scalar->duplicateAttributes(element.scalar) ;
2270          scalar->setTemplateId(element.scalar) ;
2271          scalar->name = element.scalar->getId() ;
2272          newGrid->addScalar(scalar->getId()) ;
2273        }
2274      }
2275      newGrid->checkElementsAttributes() ;
2276    }
2277    return newGrid ;
2278  }
2279
2280
2281  void CGrid::setContextClient(CContextClient* contextClient)
2282  TRY
2283  {
2284    if (clientsSet.find(contextClient)==clientsSet.end())
2285    {
2286      clients.push_back(contextClient) ;
2287      clientsSet.insert(contextClient);
2288    }
2289    for (auto domain : getDomains()) domain->setContextClient(contextClient);
2290    for (auto axis : getAxis()) axis->setContextClient(contextClient);
2291    for (auto scalar : getScalars()) scalar->setContextClient(contextClient);
2292   
2293  }
2294  CATCH_DUMP_ATTR
2295
2296 
2297  void CGrid::computeGridLocalElements()
2298  {
2299    std::vector<CDomain*> domainList = this->getDomains();
2300    std::vector<CAxis*> axisList = this->getAxis();
2301    std::vector<CScalar*> scalarList = this->getScalars();
2302    auto domain=domainList.begin() ;
2303    auto axis=axisList.begin() ;
2304    auto scalar=scalarList.begin() ;
2305    vector<CLocalElement*> elements;
2306    for(auto order : order_)
2307    {
2308      if (order==2) 
2309      {
2310        elements.push_back((*domain)->getLocalElement());
2311        domain++ ;
2312      }
2313      else if (order==1)
2314      {
2315        elements.push_back((*axis)->getLocalElement());
2316        axis++ ;
2317      }
2318      else if (order==0)
2319      { 
2320        elements.push_back((*scalar)->getLocalElement());
2321        scalar++ ;
2322      }
2323    }
2324    if (hasMask()) 
2325    {
2326      vector<bool> mask(getMask().getVector()) ;
2327      gridLocalElements_ = new CGridLocalElements(elements, mask) ; 
2328    }
2329    else gridLocalElements_ = new CGridLocalElements(elements) ; 
2330  }
2331
2332  void CGrid::computeModelToWorkflowConnector(void)
2333  {
2334    modelToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::MODEL,CElementView::WORKFLOW,true) ;
2335  }
2336
2337  void CGrid::computeWorkflowToFullConnector(void)
2338  {
2339    workflowToFullConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::FULL) ;
2340  }
2341
2342  void CGrid::computeWorkflowToModelConnector(void)
2343  {
2344    workflowToModelConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::MODEL,true) ;
2345  }
2346
2347  void CGrid::computeFullToWorkflowConnector(void)
2348  {
2349    fullToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::FULL,CElementView::WORKFLOW) ;
2350  }
2351
2352  void CGrid::computeServerFromClientConnector(void)
2353  {
2354    vector<CGathererConnector*> connectors ;
2355    for(auto& element : getElements())
2356    {
2357      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ;
2358      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 
2359      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 
2360    }
2361    serverFromClientConnector_ = new CGridGathererConnector(connectors) ;
2362  }
2363
2364  void CGrid::computeServerToClientConnector(void)
2365  {
2366    vector<CScattererConnector*> connectors ;
2367    for(auto& element : getElements())
2368    {
2369      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerToClientConnector()) ;
2370      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerToClientConnector()) ; 
2371      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerToClientConnector()) ; 
2372    }
2373    serverToClientConnector_ = new CGridScattererConnector(connectors) ;
2374  }
2375
2376  void CGrid::computeClientFromClientConnector(void)
2377  {
2378    vector<CGathererConnector*> connectors ;
2379    for(auto& element : getElements())
2380    {
2381      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ;
2382      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ; 
2383      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ; 
2384    }
2385    clientFromClientConnector_ = new CGridGathererConnector(connectors) ;
2386  }
2387
2388 
2389} // namespace xios
Note: See TracBrowser for help on using the repository browser.