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

Last change on this file since 2203 was 2203, checked in by ymipsl, 3 years ago

New functionnality : domain, axis and scalar can now be retrieve with new syntax id :
ex. for domain :

id="domainId" : old syntax, working as before
id="fieldId::domainId" : get the domain related to "domainId" associated to the field "fieldId", work if only 1 domain related to domainId is associated to the field.
id="fieldId::domainId[n]" : get the nth domain related to "domainId" associated to the field "fieldId"
id="fieldId::" : get the domain associated the the field "fieldId, work if grid associated to th field is composed with exactly 1 domain (and possibly other components axis or scalars)
id="fieldId::[n] : get the nth domain composing the grid associated to the field

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