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

Last change on this file since 2351 was 2351, checked in by ymipsl, 2 years ago
  • Solve inheritance problem when referenced field is not on the same grid that current field and no transformation is involved (grid casting).
  • Solve name inheritance problem for axis, domain or scalar elements in ouput files. Now name is determided folowing id or names of inherited element if current id is automatically generated.

YM

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