source: XIOS/dev/dev_trunk_graph/src/node/grid.cpp @ 2026

Last change on this file since 2026 was 2026, checked in by yushan, 9 months ago

Graph intermediate commit to a tmp branch.

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