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

Last change on this file since 2284 was 2282, checked in by jderouillat, 2 years ago

Add missing return statements detected using -fsanitize=return. Return errors at runtime if reached.

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