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

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

bug fix in chaining transformations

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