source: XIOS3/trunk/src/node/grid.cpp @ 2405

Last change on this file since 2405 was 2397, checked in by ymipsl, 22 months ago
  • Optimize remote connector computation in case of read (reverse way).
  • don't compute anymore clientFromServerConnector (and all intermediate computation) for non reading case.

YM

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