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

Last change on this file since 2311 was 2311, checked in by ymipsl, 2 years ago

Add possibility to refer to a grid using the field which is attached to, using notation : "fieldId::"

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