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

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

Adapt transformation algorithm to new infrastructure (on going...)

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