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

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

Some cleaning of old transformation dead code

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