source: XIOS3/dev/XIOS_ATTACHED/src/node/grid.cpp @ 2482

Last change on this file since 2482 was 2482, checked in by ymipsl, 15 months ago

First guess in supression of attached mode replaced by online reader and write filters

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