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

Last change on this file since 2007 was 2007, checked in by ymipsl, 3 years ago
  • fix some problem in transformation
  • implement new temporal splitting transformation

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