Ignore:
Timestamp:
01/22/21 12:00:29 (3 years ago)
Author:
yushan
Message:

Graph intermedia commit to a tmp branch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/dev/dev_trunk_graph/src/node/grid.cpp

    r1612 r2019  
    1616#include "client_server_mapping_distributed.hpp" 
    1717#include "distribution_client.hpp" 
    18 #include "grid_transformation.hpp" 
    19 #include "grid_generate.hpp" 
    2018#include "server.hpp" 
    21  
    22 namespace xios { 
     19#include "distribution_type.hpp" 
     20#include "grid_remote_connector.hpp" 
     21#include "grid_elements.hpp" 
     22#include "grid_local_view.hpp" 
     23#include "grid_mask_connector.hpp" 
     24#include "transformation_path.hpp" 
     25#include "grid_transformation_factory_impl.hpp" 
     26#include "transform_filter.hpp" 
     27#include "grid_algorithm.hpp" 
     28#include "grid_algorithm_generic.hpp" 
     29#include "generic_algorithm_transformation.hpp" 
     30#include "algo_types.hpp" 
     31 
     32 
     33namespace xios 
     34{ 
    2335 
    2436   /// ////////////////////// Dfinitions ////////////////////// /// 
     
    3042      , vAxisGroup_(), axisList_(), isAxisListSet(false) 
    3143      , vScalarGroup_(), scalarList_(), isScalarListSet(false) 
    32       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    33       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
     44      , clientDistribution_(0), isIndexSent(false) 
    3445      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
    35           , isDataDistributed_(true), isCompressible_(false) 
    36       , transformations_(0), isTransformed_(false) 
     46            , isCompressible_(false) 
    3747      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    38       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    39       , computedWrittenIndex_(false) 
     48      , gridSrc_(), order_() 
    4049      , clients() 
    4150   { 
     
    5160      , vAxisGroup_(), axisList_(), isAxisListSet(false) 
    5261      , vScalarGroup_(), scalarList_(), isScalarListSet(false) 
    53       , clientDistribution_(0), isIndexSent(false) , serverDistribution_(0), clientServerMap_(0) 
    54       , writtenDataSize_(0), numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0) 
     62      , clientDistribution_(0), isIndexSent(false) 
    5563      , connectedDataSize_(), connectedServerRank_(), connectedServerRankRead_(), connectedDataSizeRead_() 
    56           , isDataDistributed_(true), isCompressible_(false) 
    57       , transformations_(0), isTransformed_(false) 
     64            , isCompressible_(false) 
    5865      , axisPositionInGrid_(), hasDomainAxisBaseRef_(false) 
    59       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_() 
    60       , computedWrittenIndex_(false) 
     66      , gridSrc_(), order_() 
    6167      , clients() 
    6268   { 
     
    6975   { 
    7076    if (0 != clientDistribution_) delete clientDistribution_; 
    71     if (0 != serverDistribution_) delete serverDistribution_; 
    72     if (0 != clientServerMap_) delete clientServerMap_; 
    73     if (0 != transformations_) delete transformations_; 
    7477   } 
    7578 
     
    8184 
    8285 
     86  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     87  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     88  /////////              MEMBER FUNCTION RELATED TO GRID CONSTRUCTION by ELEMNTS AND MANAGEMENT                      ///// 
     89  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     90  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     91 
     92 
     93   CGrid* CGrid::createGrid(CDomain* domain) 
     94   TRY 
     95   { 
     96     std::vector<CDomain*> vecDom(1, domain); 
     97     std::vector<CAxis*> vecAxis; 
     98     return createGrid(vecDom, vecAxis); 
     99   } 
     100   CATCH 
     101 
     102   CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis) 
     103   TRY 
     104  { 
     105      std::vector<CDomain*> vecDom(1, domain); 
     106      std::vector<CAxis*> vecAxis(1, axis); 
     107 
     108      return createGrid(vecDom, vecAxis); 
     109   } 
     110   CATCH 
     111 
     112   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
     113                            const CArray<int,1>& axisDomainOrder) 
     114   TRY 
     115   { 
     116     std::vector<CScalar*> vecScalar; 
     117     return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder); 
     118   } 
     119   CATCH 
     120 
     121   CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
     122                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
     123   TRY 
     124   { 
     125     return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder); 
     126   } 
     127   CATCH 
     128 
     129   CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
     130                            const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
     131   TRY 
     132   { 
     133      if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size())) 
     134        ERROR("CGrid* CGrid::createGrid(...)", 
     135              << "The size of axisDomainOrder (" << axisDomainOrder.numElements() 
     136              << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<")."); 
     137 
     138      CGrid* grid = CGridGroup::get("grid_definition")->createChild(id); 
     139      grid->setDomainList(domains); 
     140      grid->setAxisList(axis); 
     141      grid->setScalarList(scalars); 
     142 
     143      // By default, domains are always the first elements of a grid 
     144      if (0 == axisDomainOrder.numElements()) 
     145      { 
     146        int size = domains.size() + axis.size() + scalars.size(); 
     147        int nb = 0; 
     148        grid->axis_domain_order.resize(size); 
     149        for (int i = 0; i < size; ++i) 
     150        { 
     151          if (i < domains.size()) 
     152          { 
     153            grid->axis_domain_order(i) = 2; 
     154            grid->order_.push_back(2) ; 
     155          } 
     156          else if ((scalars.size() < (size-nb)) < size) 
     157          { 
     158            grid->axis_domain_order(i) = 1; 
     159            grid->order_.push_back(1) ; 
     160          } 
     161          else 
     162          { 
     163            grid->axis_domain_order(i) = 0; 
     164            grid->order_.push_back(0) ; 
     165          } 
     166          ++nb; 
     167        } 
     168      } 
     169      else 
     170      { 
     171        grid->axis_domain_order.resize(axisDomainOrder.numElements()); 
     172        grid->axis_domain_order = axisDomainOrder; 
     173        grid->order_.clear() ; 
     174        for(int i=0; i<axisDomainOrder.numElements();i++) grid->order_.push_back(axisDomainOrder(i)) ; 
     175 
     176      } 
     177       
     178 //     grid->solveElementsRefInheritance(true); 
     179      grid->computeElements() ; 
     180      return grid; 
     181   } 
     182   CATCH 
     183 
     184   //---------------------------------------------------------------- 
     185 
     186   //! Change virtual field group to a new one 
     187   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup) 
     188   TRY 
     189   { 
     190      this->vDomainGroup_ = newVDomainGroup; 
     191   } 
     192   CATCH_DUMP_ATTR 
     193 
     194   //! Change virtual variable group to new one 
     195   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup) 
     196   TRY 
     197   { 
     198      this->vAxisGroup_ = newVAxisGroup; 
     199   } 
     200   CATCH_DUMP_ATTR 
     201 
     202   //! Change virtual variable group to new one 
     203   void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup) 
     204   TRY 
     205   { 
     206      this->vScalarGroup_ = newVScalarGroup; 
     207   } 
     208   CATCH_DUMP_ATTR 
     209 
     210   //---------------------------------------------------------------- 
     211 
     212   CDomainGroup* CGrid::getVirtualDomainGroup() const 
     213   TRY 
     214   { 
     215     return this->vDomainGroup_; 
     216   } 
     217   CATCH 
     218 
     219   CAxisGroup* CGrid::getVirtualAxisGroup() const 
     220   TRY 
     221   { 
     222     return this->vAxisGroup_; 
     223   } 
     224   CATCH 
     225 
     226   CScalarGroup* CGrid::getVirtualScalarGroup() const 
     227   TRY 
     228   { 
     229     return this->vScalarGroup_; 
     230   } 
     231   CATCH 
     232 
     233  ///--------------------------------------------------------------- 
     234 
     235   CDomain* CGrid::addDomain(const std::string& id) 
     236   TRY 
     237   { 
     238     order_.push_back(2); 
     239     axis_domain_order.resize(order_.size()); 
     240     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
     241     CDomain* domain = vDomainGroup_->createChild(id); 
     242     isDomListSet=false ; 
     243     computeElements(); 
     244     return domain ; 
     245   } 
     246   CATCH_DUMP_ATTR 
     247 
     248   CAxis* CGrid::addAxis(const std::string& id) 
     249   TRY 
     250   { 
     251     order_.push_back(1); 
     252     axis_domain_order.resize(order_.size()); 
     253     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
     254     CAxis* axis=vAxisGroup_->createChild(id); 
     255     isAxisListSet=false ; 
     256     computeElements();  
     257     return axis ; 
     258   } 
     259   CATCH_DUMP_ATTR 
     260 
     261   CScalar* CGrid::addScalar(const std::string& id) 
     262   TRY 
     263   { 
     264     order_.push_back(0); 
     265     axis_domain_order.resize(order_.size()); 
     266     for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
     267     CScalar* scalar =  vScalarGroup_->createChild(id); 
     268     isScalarListSet=false ; 
     269     computeElements(); 
     270     return scalar; 
     271   } 
     272   CATCH_DUMP_ATTR 
     273 
     274 
     275 
     276 
     277  /*! 
     278  \brief Get the list of domain pointers 
     279  \return list of domain pointers 
     280  */ 
     281  std::vector<CDomain*> CGrid::getDomains() 
     282  TRY 
     283  { 
     284    setDomainList(); 
     285    std::vector<CDomain*> domList; 
     286    if (!domList_.empty()) 
     287    { 
     288      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i])); 
     289    } 
     290    return domList; 
     291  } 
     292  CATCH_DUMP_ATTR 
     293 
     294  /*! 
     295  \brief Get the list of  axis pointers 
     296  \return list of axis pointers 
     297  */ 
     298  std::vector<CAxis*> CGrid::getAxis() 
     299  TRY 
     300  { 
     301    setAxisList(); 
     302    std::vector<CAxis*> aList; 
     303    if (!axisList_.empty()) 
     304      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i])); 
     305 
     306    return aList; 
     307  } 
     308  CATCH_DUMP_ATTR 
     309 
     310  /*! 
     311  \brief Get the list of  axis pointers 
     312  \return list of axis pointers 
     313  */ 
     314  std::vector<CScalar*> CGrid::getScalars() 
     315  TRY 
     316  { 
     317    setScalarList() ; 
     318    std::vector<CScalar*> sList; 
     319    if (!scalarList_.empty()) 
     320      for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i])); 
     321 
     322    return sList; 
     323  } 
     324  CATCH_DUMP_ATTR 
     325 
     326  /*! 
     327  \brief Get domain pointer with index 
     328  \return domain pointer 
     329  */ 
     330  CDomain* CGrid::getDomain(int domainIndex) 
     331  TRY 
     332  { 
     333    std::vector<CDomain*> domainListP = this->getDomains(); 
     334    if (domainListP.empty()) 
     335    { 
     336      ERROR("CGrid::getDomain(int domainIndex)", 
     337            << "No domain associated to this grid. " << std::endl 
     338            << "Grid id = " << this->getId()); 
     339    } 
     340 
     341    if (domainIndex >= domainListP.size() || (domainIndex < 0)) 
     342      ERROR("CGrid::getDomain(int domainIndex)", 
     343            << "Domain with the index doesn't exist " << std::endl 
     344            << "Grid id = " << this->getId() << std::endl 
     345            << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl); 
     346 
     347    return domainListP[domainIndex]; 
     348  } 
     349  CATCH_DUMP_ATTR 
     350 
     351  /*! 
     352  \brief Get the axis pointer with index 
     353  \return axis pointer 
     354  */ 
     355  CAxis* CGrid::getAxis(int axisIndex) 
     356  TRY 
     357  { 
     358    std::vector<CAxis*> axisListP = this->getAxis(); 
     359    if (axisListP.empty()) 
     360    { 
     361      ERROR("CGrid::getDomain(int axisIndex)", 
     362            << "No axis associated to this grid. " << std::endl 
     363            << "Grid id = " << this->getId()); 
     364    } 
     365 
     366    if (axisIndex >= axisListP.size() || (axisIndex < 0)) 
     367      ERROR("CGrid::getDomain(int axisIndex)", 
     368            << "Domain with the index doesn't exist " << std::endl 
     369            << "Grid id = " << this->getId() << std::endl 
     370            << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl); 
     371 
     372    return axisListP[axisIndex]; 
     373  } 
     374  CATCH_DUMP_ATTR 
     375 
     376  /*! 
     377  \brief Get the a scalar pointer 
     378  \return scalar pointer 
     379  */ 
     380  CScalar* CGrid::getScalar(int scalarIndex) 
     381  TRY 
     382  { 
     383    std::vector<CScalar*> scalarListP = this->getScalars(); 
     384    if (scalarListP.empty()) 
     385    { 
     386      ERROR("CGrid::getScalar(int scalarIndex)", 
     387            << "No scalar associated to this grid. " << std::endl 
     388            << "Grid id = " << this->getId()); 
     389    } 
     390 
     391    if (scalarIndex >= scalarListP.size() || (scalarIndex < 0)) 
     392      ERROR("CGrid::getScalar(int scalarIndex)", 
     393            << "Scalar with the index doesn't exist " << std::endl 
     394            << "Grid id = " << this->getId() << std::endl 
     395            << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl); 
     396 
     397    return scalarListP[scalarIndex]; 
     398  } 
     399  CATCH_DUMP_ATTR 
     400 
     401  /*! 
     402  \brief Set domain(s) of a grid from a list 
     403  \param[in] domains list of domains 
     404  */ 
     405  void CGrid::setDomainList(const std::vector<CDomain*> domains) 
     406  TRY 
     407  { 
     408    if (isDomListSet) return; 
     409    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 
     410    if (!domains.empty() && domList.empty()) 
     411    { 
     412      for (int i = 0; i < domains.size(); ++i) 
     413        this->getVirtualDomainGroup()->addChild(domains[i]); 
     414      domList = this->getVirtualDomainGroup()->getAllChildren(); 
     415    } 
     416 
     417    if (!domList.empty()) 
     418    { 
     419      int sizeDom = domList.size(); 
     420      domList_.resize(sizeDom); 
     421      for (int i = 0; i < sizeDom; ++i) 
     422      { 
     423        domList_[i] = domList[i]->getId(); 
     424      } 
     425      isDomListSet = true; 
     426    } 
     427  } 
     428  CATCH_DUMP_ATTR 
     429 
     430  /*! 
     431  \brief Set axis(s) of a grid from a list 
     432  \param[in] axis list of axis 
     433  */ 
     434  void CGrid::setAxisList(const std::vector<CAxis*> axis) 
     435  TRY 
     436  { 
     437    if (isAxisListSet) return; 
     438    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 
     439    if (!axis.empty() && aList.empty()) 
     440    { 
     441      for (int i = 0; i < axis.size(); ++i) 
     442        this->getVirtualAxisGroup()->addChild(axis[i]); 
     443      aList = this->getVirtualAxisGroup()->getAllChildren(); 
     444    } 
     445 
     446    if (!aList.empty()) 
     447    { 
     448      int sizeAxis = aList.size(); 
     449      axisList_.resize(sizeAxis); 
     450      for (int i = 0; i < sizeAxis; ++i) 
     451      { 
     452        axisList_[i] = aList[i]->getId(); 
     453      } 
     454      isAxisListSet = true; 
     455    } 
     456  } 
     457  CATCH_DUMP_ATTR 
     458 
     459  /*! 
     460  \brief Set scalar(s) of a grid from a list 
     461  \param[in] scalars list of scalars 
     462  */ 
     463  void CGrid::setScalarList(const std::vector<CScalar*> scalars) 
     464  TRY 
     465  { 
     466    if (isScalarListSet) return; 
     467    std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 
     468    if (!scalars.empty() && sList.empty()) 
     469    { 
     470      for (int i = 0; i < scalars.size(); ++i) 
     471        this->getVirtualScalarGroup()->addChild(scalars[i]); 
     472      sList = this->getVirtualScalarGroup()->getAllChildren(); 
     473    } 
     474 
     475    if (!sList.empty()) 
     476    { 
     477      int sizeScalar = sList.size(); 
     478      scalarList_.resize(sizeScalar); 
     479      for (int i = 0; i < sizeScalar; ++i) 
     480      { 
     481        scalarList_[i] = sList[i]->getId(); 
     482      } 
     483      isScalarListSet = true; 
     484    } 
     485  } 
     486  CATCH_DUMP_ATTR 
     487 
     488  /*! 
     489  \brief Get list of id of domains 
     490  \return id list of domains 
     491  */ 
     492  std::vector<StdString> CGrid::getDomainList() 
     493  TRY 
     494  { 
     495    setDomainList(); 
     496    return domList_; 
     497  } 
     498  CATCH 
     499 
     500  /*! 
     501  \brief Get list of id of axis 
     502  \return id list of axis 
     503  */ 
     504  std::vector<StdString> CGrid::getAxisList() 
     505  TRY 
     506  { 
     507    setAxisList(); 
     508    return axisList_; 
     509  } 
     510  CATCH 
     511 
     512  /*! 
     513  \brief Get list of id of scalar 
     514  \return id list of scalar 
     515  */ 
     516  std::vector<StdString> CGrid::getScalarList() 
     517  TRY 
     518  { 
     519    setScalarList(); 
     520    return scalarList_; 
     521  } 
     522  CATCH 
     523 
     524 
     525  void CGrid::computeElements(void) 
     526  { 
     527    const auto& domains = getDomains() ; 
     528    const auto& axis = getAxis() ; 
     529    const auto& scalars = getScalars() ; 
     530    int idxDomain = 0, idxAxis=0 , idxScalar=0 ;  
     531  
     532    elements_.clear() ; 
     533    for(auto type : order_) 
     534    { 
     535      if      (type == 0) { elements_.push_back({scalars[idxScalar], TYPE_SCALAR, scalars[idxScalar], nullptr, nullptr } ) ; idxScalar++;} 
     536      else if (type == 1) { elements_.push_back({axis[idxAxis], TYPE_AXIS, nullptr, axis[idxAxis], nullptr}) ; idxAxis++;} 
     537      else if (type == 2) { elements_.push_back({domains[idxDomain], TYPE_DOMAIN, nullptr, nullptr, domains[idxDomain] }) ; idxDomain++;}         
     538    } 
     539    elementsComputed_ = true ; 
     540  } 
     541   
     542   
     543 /*! 
     544    Parse a grid, for now, it contains only domain, axis and scalar 
     545  */ 
     546  void CGrid::parse(xml::CXMLNode& node) 
     547  TRY 
     548  { 
     549    SuperClass::parse(node); 
     550 
     551    if (node.goToChildElement()) 
     552    { 
     553      StdString domainName("domain"); 
     554      StdString axisName("axis"); 
     555      StdString scalarName("scalar"); 
     556      do 
     557      { 
     558        if (node.getElementName() == domainName) { 
     559          order_.push_back(2); 
     560          this->getVirtualDomainGroup()->parseChild(node); 
     561        } 
     562        if (node.getElementName() == axisName) { 
     563          order_.push_back(1); 
     564          this->getVirtualAxisGroup()->parseChild(node); 
     565        } 
     566        if (node.getElementName() == scalarName) { 
     567          order_.push_back(0); 
     568          this->getVirtualScalarGroup()->parseChild(node); 
     569        } 
     570      } while (node.goToNextElement()); 
     571      node.goToParentElement(); 
     572    } 
     573 
     574    if (!order_.empty()) 
     575    { 
     576      int sizeOrd = order_.size(); 
     577      axis_domain_order.resize(sizeOrd); 
     578      for (int i = 0; i < sizeOrd; ++i) 
     579      { 
     580        axis_domain_order(i) = order_[i]; 
     581      } 
     582    } 
     583 
     584    setDomainList(); 
     585    setAxisList(); 
     586    setScalarList(); 
     587    computeElements() ; 
     588   } 
     589   CATCH_DUMP_ATTR 
     590 
     591 
     592  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     593  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     594  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     595  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
     596 
     597 
     598 
    83599   StdSize CGrid::getDimension(void) 
    84600   TRY 
     
    90606   //--------------------------------------------------------------- 
    91607 
    92    StdSize CGrid::getDataSize(void) const 
     608   StdSize CGrid::getDataSize(void)  
    93609   TRY 
    94610   { 
     
    96612     if (!isScalarGrid()) 
    97613     { 
    98        std::vector<int> dataNindex = clientDistribution_->getDataNIndex(); 
     614       std::vector<int> dataNindex = getClientDistribution()->getDataNIndex(); 
    99615       for (int i = 0; i < dataNindex.size(); ++i) retvalue *= dataNindex[i];        
    100616     } 
     
    102618   } 
    103619   CATCH 
     620    
     621   /*! 
     622    * Get the local data grid size, ie the size of the compressed grid (inside the workflow) 
     623    * \return The size od the compressed grid 
     624    */ 
     625    StdSize  CGrid::getLocalDataSize(void) { return getClientDistribution()->getLocalDataSize();} 
     626 
    104627 
    105628   /*! 
     
    128651     for (size_t i = 0; i < axisList.size(); ++i) 
    129652     { 
    130        std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),axisPositionInGrid_[i]); 
     653       std::map<int, StdSize> axisAttBuffSize = axisList[i]->getAttributesBufferSize(client, getGlobalDimension(),getAxisPositionInGrid()[i]); 
    131654       for (it = axisAttBuffSize.begin(), itE = axisAttBuffSize.end(); it != itE; ++it) 
    132655       { 
     
    202725   CATCH_DUMP_ATTR 
    203726    
    204    void CGrid::checkAttributesAfterTransformation() 
    205    TRY 
    206    { 
    207       setAxisList(); 
    208       std::vector<CAxis*> axisListP = this->getAxis(); 
    209       if (!axisListP.empty()) 
    210       { 
    211         int idx = 0; 
    212         axisPositionInGrid_.resize(0); 
    213         for (int i = 0; i < axis_domain_order.numElements(); ++i) 
    214         { 
    215           int elementDimension = axis_domain_order(i); 
    216           if (1 == elementDimension) 
    217           { 
    218             axisPositionInGrid_.push_back(idx); 
    219             ++idx; 
    220           } 
    221           else if (2 == elementDimension) idx += 2; 
    222         } 
    223  
    224         for (int i = 0; i < axisListP.size(); ++i) 
    225         { 
    226           axisListP[i]->checkAttributesOnClientAfterTransformation(getGlobalDimension(),axisPositionInGrid_[i]); 
    227         } 
    228       } 
    229  
    230       setDomainList(); 
    231       std::vector<CDomain*> domListP = this->getDomains(); 
    232       if (!domListP.empty()) 
    233       { 
    234         for (int i = 0; i < domListP.size(); ++i) 
    235         { 
    236           domListP[i]->checkAttributesOnClientAfterTransformation(); 
    237         } 
    238       } 
    239    } 
    240    CATCH_DUMP_ATTR 
    241  
    242    //--------------------------------------------------------------- 
    243  
     727 
     728   void CGrid::computeAxisPositionInGrid(void) 
     729   { 
     730     axisPositionInGrid_.resize(0); 
     731     int idx = 0; 
     732     for (int i = 0; i < axis_domain_order.numElements(); ++i) 
     733     { 
     734       int elementDimension = axis_domain_order(i); 
     735       if (1 == elementDimension) 
     736       { 
     737         axisPositionInGrid_.push_back(idx); 
     738         ++idx; 
     739       } 
     740       else if (2 == elementDimension) idx += 2; 
     741     } 
     742   } 
     743 
     744   
    244745   /*! 
    245746    * Test whether the data defined on the grid can be outputted in a compressed way. 
     
    327828   CATCH_DUMP_ATTR 
    328829 
     830   //ym obsolete -> to be removed later 
    329831   void CGrid::checkMaskIndex(bool doSendingIndex) 
    330832   TRY 
    331833   { 
    332834     CContext* context = CContext::getCurrent(); 
    333      int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;    
    334      nbSrvPools = 1;   
    335      for (int p = 0; p < nbSrvPools; ++p) 
    336      {     
    337        if (context->hasClient && this->isChecked && doSendingIndex && !isIndexSent)  
    338        {  
    339          if (isScalarGrid()) 
    340            sendIndexScalarGrid(); 
    341          else 
    342            sendIndex(); 
    343          this->isIndexSent = true;  
    344        } 
    345  
    346        // Not sure about this 
    347        //if (!(this->hasTransform() && !this->isTransformed())) 
    348        // this->isChecked = true; 
    349        //return; 
    350      } 
    351      
     835      
    352836     if (this->isChecked) return; 
    353      this->checkAttributesAfterTransformation(); 
    354  
    355      // TODO: Transfer grid attributes 
    356      //if (!context->hasClient && context->hasServer) this->createMask(); 
    357      this->computeIndex(); 
    358  
    359      if (!(this->hasTransform() && !this->isTransformed())) 
    360       this->isChecked = true; 
    361  
    362      if (!(this->hasTransform() && (!this->isGenerated()))) 
    363       this->isChecked = true; 
    364    } 
    365    CATCH_DUMP_ATTR 
     837     this->checkElementsAttributes(); 
     838     this->isChecked = true; 
     839   } 
     840   CATCH_DUMP_ATTR 
     841 
     842 
    366843   bool CGrid::hasMask() const 
    367844   TRY 
     
    372849   CATCH 
    373850 
    374    /* 
    375      Create mask of grid from mask of its components 
    376    */ 
    377    void CGrid::createMask(void) 
    378    TRY 
    379    { 
    380       using namespace std; 
    381       std::vector<CDomain*> domainP = this->getDomains(); 
    382       std::vector<CAxis*> axisP = this->getAxis(); 
    383       int dim = domainP.size() * 2 + axisP.size(); 
    384  
    385       std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    386       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    387       std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    388       for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
    389  
    390       switch (dim) { 
    391         case 1: 
    392           checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order, true); 
    393           break; 
    394         case 2: 
    395           checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order, true); 
    396           break; 
    397         case 3: 
    398           checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order, true); 
    399           break; 
    400         case 4: 
    401           checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order, true); 
    402           break; 
    403         case 5: 
    404           checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order, true); 
    405           break; 
    406         case 6: 
    407           checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order, true); 
    408           break; 
    409         case 7: 
    410           checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order, true); 
    411           break; 
    412         default: 
    413           break; 
    414       } 
    415    } 
    416    CATCH_DUMP_ATTR 
    417  
    418    /* 
    419      Check validity of grid's mask by using the masks of its components 
    420    */ 
    421    void CGrid::checkMask(void) 
    422    TRY 
    423    { 
    424       using namespace std; 
    425       std::vector<CDomain*> domainP = this->getDomains(); 
    426       std::vector<CAxis*> axisP = this->getAxis(); 
    427       int dim = domainP.size() * 2 + axisP.size(); 
    428  
    429       std::vector<CArray<bool,1>* > domainMasks(domainP.size()); 
    430       for (int i = 0; i < domainMasks.size(); ++i) domainMasks[i] = &(domainP[i]->domainMask); 
    431       std::vector<CArray<bool,1>* > axisMasks(axisP.size()); 
    432       for (int i = 0; i < axisMasks.size(); ++i) axisMasks[i] = &(axisP[i]->mask); 
    433  
    434       switch (dim) { 
    435         case 1: 
    436           checkGridMask(mask_1d, domainMasks, axisMasks, axis_domain_order); 
    437           break; 
    438         case 2: 
    439           checkGridMask(mask_2d, domainMasks, axisMasks, axis_domain_order); 
    440           break; 
    441         case 3: 
    442           checkGridMask(mask_3d, domainMasks, axisMasks, axis_domain_order); 
    443           break; 
    444         case 4: 
    445           checkGridMask(mask_4d, domainMasks, axisMasks, axis_domain_order); 
    446           break; 
    447         case 5: 
    448           checkGridMask(mask_5d, domainMasks, axisMasks, axis_domain_order); 
    449           break; 
    450         case 6: 
    451           checkGridMask(mask_6d, domainMasks, axisMasks, axis_domain_order); 
    452           break; 
    453         case 7: 
    454           checkGridMask(mask_7d, domainMasks, axisMasks, axis_domain_order); 
    455           break; 
    456         default: 
    457           break; 
    458       } 
    459    } 
    460    CATCH_DUMP_ATTR 
    461  
    462    /* 
    463      Modify value of mask in a certain index 
    464      This function can be used to correct the mask of grid after being constructed with createMask 
    465      \param [in] indexToModify 
    466      \param [in] modifyValue 
    467    */ 
    468    void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue) 
    469    TRY 
    470    { 
    471       using namespace std; 
    472       std::vector<CDomain*> domainP = this->getDomains(); 
    473       std::vector<CAxis*> axisP = this->getAxis(); 
    474       int dim = domainP.size() * 2 + axisP.size(); 
    475  
    476       switch (dim) { 
    477         case 0: 
    478           modifyGridMask(mask_0d, indexToModify, modifyValue); 
    479           break; 
    480         case 1: 
    481           modifyGridMask(mask_1d, indexToModify, modifyValue); 
    482           break; 
    483         case 2: 
    484           modifyGridMask(mask_2d, indexToModify, modifyValue); 
    485           break; 
    486         case 3: 
    487           modifyGridMask(mask_3d, indexToModify, modifyValue); 
    488           break; 
    489         case 4: 
    490           modifyGridMask(mask_4d, indexToModify, modifyValue); 
    491           break; 
    492         case 5: 
    493           modifyGridMask(mask_5d, indexToModify, modifyValue); 
    494           break; 
    495         case 6: 
    496           modifyGridMask(mask_6d, indexToModify, modifyValue); 
    497           break; 
    498         case 7: 
    499           modifyGridMask(mask_7d, indexToModify, modifyValue); 
    500           break; 
    501         default: 
    502           break; 
    503       } 
    504    } 
    505    CATCH_DUMP_ATTR 
    506  
    507    /* 
    508      Change the mask size. This function is used on reconstructing mask in server side 
    509      \param [in] newDimensionSize 
    510      \param [in] newValue  
    511    */ 
    512    void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue) 
    513    TRY 
    514    {       
    515       std::vector<CDomain*> domainP = this->getDomains(); 
    516       std::vector<CAxis*> axisP = this->getAxis();             
    517       int dim = domainP.size() * 2 + axisP.size(); 
    518  
    519       switch (dim) { 
    520         case 0: 
    521           modifyGridMaskSize(mask_0d, newDimensionSize, newValue); 
    522           break; 
    523         case 1: 
    524           modifyGridMaskSize(mask_1d, newDimensionSize, newValue); 
    525           break; 
    526         case 2: 
    527           modifyGridMaskSize(mask_2d, newDimensionSize, newValue); 
    528           break; 
    529         case 3: 
    530           modifyGridMaskSize(mask_3d, newDimensionSize, newValue); 
    531           break; 
    532         case 4: 
    533           modifyGridMaskSize(mask_4d, newDimensionSize, newValue); 
    534           break; 
    535         case 5: 
    536           modifyGridMaskSize(mask_5d, newDimensionSize, newValue); 
    537           break; 
    538         case 6: 
    539           modifyGridMaskSize(mask_6d, newDimensionSize, newValue); 
    540           break; 
    541         case 7: 
    542           modifyGridMaskSize(mask_7d, newDimensionSize, newValue); 
    543           break; 
    544         default: 
    545           break; 
    546       } 
    547    } 
    548    CATCH_DUMP_ATTR 
    549  
     851    
     852   CArray<bool,1>& CGrid::getMask(void) 
     853   { 
     854       
     855      if (mask_.isEmpty()) 
     856      {   
     857        if (!mask_0d.isEmpty()) mask_.reference(CArray<bool,1>(mask_0d.dataFirst(),shape(mask_0d.numElements()), neverDeleteData)) ; 
     858        if (!mask_1d.isEmpty()) mask_.reference(CArray<bool,1>(mask_1d.dataFirst(),shape(mask_1d.numElements()), neverDeleteData)) ; 
     859        if (!mask_2d.isEmpty()) mask_.reference(CArray<bool,1>(mask_2d.dataFirst(),shape(mask_2d.numElements()), neverDeleteData)) ; 
     860        if (!mask_3d.isEmpty()) mask_.reference(CArray<bool,1>(mask_3d.dataFirst(),shape(mask_3d.numElements()), neverDeleteData)) ; 
     861        if (!mask_4d.isEmpty()) mask_.reference(CArray<bool,1>(mask_4d.dataFirst(),shape(mask_4d.numElements()), neverDeleteData)) ; 
     862        if (!mask_5d.isEmpty()) mask_.reference(CArray<bool,1>(mask_5d.dataFirst(),shape(mask_5d.numElements()), neverDeleteData)) ; 
     863        if (!mask_6d.isEmpty()) mask_.reference(CArray<bool,1>(mask_6d.dataFirst(),shape(mask_6d.numElements()), neverDeleteData)) ; 
     864        if (!mask_7d.isEmpty()) mask_.reference(CArray<bool,1>(mask_7d.dataFirst(),shape(mask_7d.numElements()), neverDeleteData)) ; 
     865      } 
     866      return mask_ ; 
     867   } 
     868 
     869   
    550870   //--------------------------------------------------------------- 
    551871 
     
    556876      std::vector<CDomain*> domListP = this->getDomains(); 
    557877      if (!domListP.empty()) 
    558       { 
    559         for (int i = 0; i < domListP.size(); ++i) 
    560         { 
    561           if (sendAtt) domListP[i]->sendCheckedAttributes(); 
    562           else domListP[i]->checkAttributesOnClient(); 
    563         } 
    564       } 
     878        for (int i = 0; i < domListP.size(); ++i) domListP[i]->checkAttributes(); 
    565879   } 
    566880   CATCH_DUMP_ATTR 
     
    574888      std::vector<CAxis*> axisListP = this->getAxis(); 
    575889      if (!axisListP.empty()) 
    576       { 
    577         int idx = 0; 
    578         axisPositionInGrid_.resize(0); 
    579         for (int i = 0; i < axis_domain_order.numElements(); ++i) 
    580         { 
    581           int elementDimension = axis_domain_order(i); 
    582           if (1 == elementDimension) 
    583           { 
    584             axisPositionInGrid_.push_back(idx); 
    585             ++idx; 
    586           } 
    587           else if (2 == elementDimension) idx += 2; 
    588         } 
    589  
    590         for (int i = 0; i < axisListP.size(); ++i) 
    591         { 
    592           if (sendAtt) 
    593             axisListP[i]->sendCheckedAttributes(getGlobalDimension(),axisPositionInGrid_[i]); 
    594           else 
    595             axisListP[i]->checkAttributesOnClient(); 
    596         } 
    597       } 
     890        for (int i = 0; i < axisListP.size(); ++i)  axisListP[i]->checkAttributes(); 
    598891   } 
    599892   CATCH_DUMP_ATTR 
     
    607900      std::vector<CScalar*> scalarListP = this->getScalars(); 
    608901      if (!scalarListP.empty()) 
    609       { 
    610         for (int i = 0; i < scalarListP.size(); ++i) 
    611         { 
    612           /*Nothing to do for now */ 
    613 //          if (sendAtt) scalarListP[i]->sendCheckedAttributes(); 
    614 //          else scalarListP[i]->checkAttributesOnClient(); 
    615         } 
    616       } 
    617    } 
    618    CATCH_DUMP_ATTR 
    619  
    620    /*! 
    621       Compute the index to for write data into a file 
    622    */ 
    623    void CGrid::computeWrittenIndex() 
    624    TRY 
    625    {       
    626       if (computedWrittenIndex_) return; 
    627       computedWrittenIndex_ = true; 
    628  
    629       if (isScalarGrid()) 
    630       { 
    631         size_t nbWritten = 1; 
    632         int writtenIndex = 0; 
    633  
    634         localIndexToWriteOnClient.resize(nbWritten);   
    635         localIndexToWriteOnServer.resize(nbWritten); 
    636         localIndexToWriteOnServer(0) = writtenIndex; 
    637         localIndexToWriteOnClient(0) = writtenIndex; 
    638          
    639         return; 
    640       } 
    641  
    642       size_t nbWritten = 0, indGlo; 
    643       CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
    644       CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(), 
    645                                                               ite = globalDataIndex.end(), it;     
    646       const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex();                                                               
    647       CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(), 
    648                                                           itSrve = globalLocalIndex.end(), itSrv; 
    649       for (it = itb; it != ite; ++it) 
    650       { 
    651         indGlo = it->first; 
    652         if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten;                 
    653       } 
    654  
    655       localIndexToWriteOnClient.resize(nbWritten);   
    656       localIndexToWriteOnServer.resize(nbWritten); 
    657        
    658       { 
    659         numberWrittenIndexes_ = nbWritten; 
    660         if (isDataDistributed_) 
    661         { 
    662           CContextServer* server = CContext::getCurrent()->server;       
    663           MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    664           MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm); 
    665           offsetWrittenIndexes_ -= numberWrittenIndexes_; 
    666         } 
    667         else 
    668           totalNumberWrittenIndexes_ = numberWrittenIndexes_; 
    669       } 
    670  
    671       nbWritten = 0;  
    672       for (it = itb; it != ite; ++it) 
    673       { 
    674         indGlo = it->first; 
    675         itSrv = globalLocalIndex.find(indGlo); 
    676         if (itSrve != itSrv) 
    677         { 
    678           localIndexToWriteOnServer(nbWritten) = itSrv->second; 
    679           localIndexToWriteOnClient(nbWritten) = it->second; 
    680           ++nbWritten;                 
    681         }  
    682       } 
    683    } 
    684    CATCH_DUMP_ATTR 
    685  
    686    //--------------------------------------------------------------- 
    687  
    688    /* 
    689      Compute the global index and its local index taking account mask and data index. 
    690      These global indexes will be used to compute the connection of this client (sender) to its servers (receivers) 
    691      (via function computeConnectedClient) 
    692      These global indexes also correspond to data sent to servers (if any) 
    693    */ 
    694    void CGrid::computeClientIndex() 
    695    TRY 
    696    { 
     902        for (int i = 0; i < scalarListP.size(); ++i) scalarListP[i]->checkAttributes() ; 
     903   } 
     904   CATCH_DUMP_ATTR 
     905 
     906 
     907    //--------------------------------------------------------------- 
     908   CDistributionClient* CGrid::getClientDistribution() 
     909   TRY 
     910   { 
     911     if (!computeClientDistribution_done_) computeClientDistribution() ; 
     912     return clientDistribution_; 
     913   } 
     914   CATCH_DUMP_ATTR 
     915    
     916   void CGrid::computeClientDistribution(void) 
     917   { 
     918     if (computeClientDistribution_done_) return ; 
     919     else computeClientDistribution_done_ = true ; 
     920 
    697921     CContext* context = CContext::getCurrent(); 
    698  
    699      CContextClient* client = context->client; 
    700      int rank = client->clientRank; 
    701  
     922     int rank = context-> getIntraCommRank(); 
    702923     clientDistribution_ = new CDistributionClient(rank, this); 
    703      // Get local data index on client 
    704      int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size(); 
    705      int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size(); 
    706      // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise 
    707      storeIndex_client.resize(nbStoreIndex); 
    708      storeMask_client.resize(nbStoreGridMask); 
    709      for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx]; 
    710      for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client(idx) = (clientDistribution_->getLocalMaskIndexOnClient())[idx]; 
    711  
    712      if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed(); 
    713      else 
    714      { 
    715         // Mapping global index received from clients to the storeIndex_client 
    716         CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient(); 
    717         CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end(); 
    718         map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
    719                                                ite = outGlobalIndexFromClient.end(), it; 
    720  
    721         for (it = itb; it != ite; ++it) 
    722         { 
    723           int rank = it->first; 
    724           CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
    725           outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    726           CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
    727           size_t nbIndex = 0; 
    728  
    729           // Keep this code for this moment but it should be removed (or moved to DEBUG) to improve performance 
    730           for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    731           { 
    732             if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    733             { 
    734               ++nbIndex; 
    735             } 
    736           } 
    737  
    738           if (doGridHaveDataDistributed(client) && (nbIndex != localIndex.numElements())) 
    739                ERROR("void CGrid::computeClientIndex()", 
    740                   << "Number of local index on client is different from number of received global index" 
    741                   << "Rank of sent client " << rank <<"." 
    742                   << "Number of local index " << nbIndex << ". " 
    743                   << "Number of received global index " << localIndex.numElements() << "."); 
    744  
    745           nbIndex = 0; 
    746           for (size_t idx = 0; idx < globalIndex.numElements(); ++idx) 
    747           { 
    748             if (itGloe != globalDataIndex.find(globalIndex(idx))) 
    749             { 
    750               localIndex(idx) = globalDataIndex[globalIndex(idx)]; 
    751             } 
    752           } 
    753         } 
    754       } 
    755    } 
    756    CATCH_DUMP_ATTR 
    757  
    758    /*! 
    759      Compute connected receivers and indexes to be sent to these receivers. 
    760    */ 
    761    void CGrid::computeConnectedClients() 
    762    TRY 
    763    { 
    764      CContext* context = CContext::getCurrent(); 
    765      int nbSrvPools = (context->clientPrimServer.size() == 0) ? 1 : context->clientPrimServer.size(); 
    766      connectedServerRank_.clear(); 
    767      connectedDataSize_.clear(); 
    768      globalIndexOnServer_.clear(); 
    769      nbSenders.clear(); 
    770  
    771      for (int p = 0; p < nbSrvPools; ++p) 
    772      { 
    773        CContextClient* client = (context->clientPrimServer.size() == 0) ? context->client : context->clientPrimServer[p]; 
    774        int receiverSize = client->serverSize; 
    775 //       connectedServerRank_[client].clear(); 
    776  
    777        if (connectedServerRank_.find(receiverSize) == connectedServerRank_.end()) 
    778        { 
    779         if (!doGridHaveDataDistributed(client)) 
    780          { 
    781             if (client->isServerLeader()) 
    782             { 
    783               size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size(); 
    784               const std::list<int>& ranks = client->getRanksServerLeader(); 
    785               for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    786               { 
    787                 connectedServerRank_[receiverSize].push_back(*itRank); 
    788                 connectedDataSize_[receiverSize][*itRank] = ssize; 
    789               } 
    790             } 
    791             return; 
    792          } 
    793  
    794          // Compute mapping between client and server 
    795          std::vector<std::unordered_map<size_t,std::vector<int> > > indexServerOnElement; 
    796          CServerDistributionDescription serverDistributionDescription(getGlobalDimension(), client->serverSize); 
    797          std::vector<int> serverZeroIndex = serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement, 
    798                                                                                                     client->clientRank, 
    799                                                                                                     client->clientSize, 
    800                                                                                                     axis_domain_order, 
    801                                                                                                     getDistributedDimension()); 
    802  
    803          // Even if servers have no index, they must received something from client 
    804          // We only use several client to send "empty" message to these servers 
    805          std::list<int> serverZeroIndexLeader; 
    806          std::list<int> serverZeroIndexNotLeader; 
    807          CContextClient::computeLeader(client->clientRank, client->clientSize, serverZeroIndex.size(), serverZeroIndexLeader, serverZeroIndexNotLeader); 
    808          for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    809            *it = serverZeroIndex[*it]; 
    810  
    811          if (globalIndexOnServer_.find(receiverSize) == globalIndexOnServer_.end()) 
    812            computeIndexByElement(indexServerOnElement, client, globalIndexOnServer_[receiverSize]); 
    813  
    814          const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    815          CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap; 
    816          CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap; 
    817          itbGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
    818          iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
    819  
    820          for (itGlobalMap  = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    821          { 
    822            int serverRank = itGlobalMap->first; 
    823            int indexSize = itGlobalMap->second.size(); 
    824            const std::vector<size_t>& indexVec = itGlobalMap->second; 
    825            for (int idx = 0; idx < indexSize; ++idx) 
    826            { 
    827               itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]); 
    828               if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap) 
    829               { 
    830                 if (connectedDataSize_[receiverSize].end() == connectedDataSize_[receiverSize].find(serverRank)) 
    831                   connectedDataSize_[receiverSize][serverRank] = 1; 
    832                 else 
    833                   ++connectedDataSize_[receiverSize][serverRank]; 
    834               } 
    835            } 
    836          } 
    837  
    838          // Connected servers which really have index 
    839          for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) { 
    840            connectedServerRank_[receiverSize].push_back(itGlobalMap->first); 
    841          } 
    842  
    843          // Connected servers which have no index at all 
    844          for (std::list<int>::iterator it = serverZeroIndexLeader.begin(); it != serverZeroIndexLeader.end(); ++it) 
    845            connectedServerRank_[receiverSize].push_back(*it); 
    846  
    847          // Even if a client has no index, it must connect to at least one server and 
    848          // send an "empty" data to this server 
    849          if (connectedServerRank_[receiverSize].empty()) 
    850           connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize); 
    851  
    852          // Now check if all servers have data to receive. If not, master client will send empty data. 
    853          // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive. 
    854          std::vector<int> counts (client->clientSize); 
    855          std::vector<int> displs (client->clientSize); 
    856          displs[0] = 0; 
    857          int localCount = connectedServerRank_[receiverSize].size() ; 
    858          MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ; 
    859          for (int i = 0; i < client->clientSize-1; ++i) 
    860          { 
    861            displs[i+1] = displs[i] + counts[i]; 
    862          } 
    863          std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]); 
    864          MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm); 
    865  
    866          if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0)) 
    867          { 
    868            std::vector<bool> isSrvConnected (receiverSize, false); 
    869            for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true; 
    870            for (int i = 0; i < receiverSize; ++i) 
    871            { 
    872              if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i); 
    873            } 
    874          } 
    875  
    876          nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]); 
    877        } 
    878      } 
    879    } 
    880    CATCH_DUMP_ATTR 
    881  
    882    /*! 
    883      Compute the global index of grid to send to server as well as the connected server of the current client. 
    884      First of all, from the local data on each element of grid, we can calculate their local index which also allows us to know 
    885      their global index. We can have a map of global index of grid and local index that each client holds 
    886      Then, each client holds a piece of information about the distribution of servers, which permits to compute the connected server(s) 
    887      of the current client. 
    888    */ 
    889    void CGrid::computeIndex(void) 
    890    TRY 
    891    { 
    892      CContext* context = CContext::getCurrent(); 
    893      if (isScalarGrid()) 
    894      { 
    895        computeClientIndexScalarGrid(); 
    896        if (context->hasClient) 
    897        { 
    898          computeConnectedClientsScalarGrid(); 
    899        } 
    900      } 
    901      else 
    902      { 
    903        computeClientIndex(); 
    904        if (context->hasClient) 
    905        { 
    906          computeConnectedClients(); 
    907        } 
    908      } 
    909      if (CServer::serverLevel==2) 
    910      { 
    911        computeWrittenIndex() ; 
    912        if (serverDistribution_!=0) serverDistribution_->partialClear() ; 
    913        if (clientDistribution_!=0) clientDistribution_->partialClear() ; 
    914        outGlobalIndexFromClient.clear() ; 
    915      } 
    916    } 
    917    CATCH_DUMP_ATTR 
    918  
    919    /*! 
    920       Compute the global of (client) grid to send to server with the global index of each element of grid 
    921       Each element of grid has its own global index associated to a groups of server. We only search for the global index of each element whose 
    922       server is the same, then calculate the global index of grid. This way can reduce so much the time for executing DHT, which only needs to run 
    923       on each element whose size is much smaller than one of whole grid. 
    924       \param [in] indexServerOnElement global index of each element and the rank of server associated with these index 
    925       \param [in] client contextClient 
    926       \param [out] globalIndexOnServer global index of grid and its corresponding rank of server. 
    927    */ 
    928    void CGrid::computeIndexByElement(const std::vector<std::unordered_map<size_t,std::vector<int> > >& indexServerOnElement, 
    929                                      const CContextClient* client, 
    930                                      CClientServerMapping::GlobalIndexMap& globalIndexOnServer) 
    931    TRY 
    932    { 
    933      int serverSize = client->serverSize; 
    934  
    935      std::vector<CDomain*> domList = getDomains(); 
    936      std::vector<CAxis*> axisList = getAxis(); 
    937  
    938      // Some pre-calculations of global index on each element of current grid. 
    939      int nbElement = axis_domain_order.numElements(); 
    940      std::vector<CArray<size_t,1> > globalIndexElement(nbElement); 
    941      int domainIdx = 0, axisIdx = 0, scalarIdx = 0; 
    942      std::vector<size_t> elementNGlobal(nbElement); 
    943      elementNGlobal[0] = 1; 
    944      size_t globalSize = 1; 
    945      for (int idx = 0; idx < nbElement; ++idx) 
    946      { 
    947        elementNGlobal[idx] = globalSize; 
    948        size_t elementSize; 
    949        size_t elementGlobalSize = 1; 
    950        if (2 == axis_domain_order(idx)) // This is domain 
    951        { 
    952          elementSize = domList[domainIdx]->i_index.numElements(); 
    953          globalIndexElement[idx].resize(elementSize); 
    954          for (int jdx = 0; jdx < elementSize; ++jdx) 
    955          { 
    956            globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx); 
    957          } 
    958          elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue(); 
    959          ++domainIdx; 
    960        } 
    961        else if (1 == axis_domain_order(idx))  // This is axis 
    962        { 
    963          elementSize = axisList[axisIdx]->index.numElements(); 
    964          globalIndexElement[idx].resize(elementSize); 
    965          for (int jdx = 0; jdx < elementSize; ++jdx) 
    966          { 
    967            globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx); 
    968          } 
    969          elementGlobalSize = axisList[axisIdx]->n_glo.getValue(); 
    970          ++axisIdx; 
    971        } 
    972        else  // Of course, this is scalar 
    973        { 
    974          globalIndexElement[idx].resize(1); 
    975          globalIndexElement[idx](0) = 0; 
    976          elementGlobalSize = 1; 
    977        } 
    978        globalSize *= elementGlobalSize; 
    979      } 
    980  
    981      std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false)); 
    982      std::vector<std::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement); 
    983      CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server 
    984      // Number of temporary distributed global index held by each client for each server 
    985      // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank 
    986      CArray<int,1> nbIndexOnServerTmp(serverSize); 
    987      for (int idx = 0; idx < nbElement; ++idx) 
    988      { 
    989        nbIndexOnServer = 0; 
    990        const std::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx]; 
    991        const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx]; 
    992        CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm); 
    993        clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient); 
    994        const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap(); 
    995        CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(), 
    996                                                                     ite = globalIndexElementOnServerMap.end(), it; 
    997        for (it = itb; it != ite; ++it) 
    998        { 
    999          const std::vector<int>& tmp = it->second; 
    1000          nbIndexOnServerTmp = 0; 
    1001          for (int i = 0; i < tmp.size(); ++i) 
    1002          { 
    1003            if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]); 
    1004          } 
    1005          nbIndexOnServer += nbIndexOnServerTmp; 
    1006        } 
    1007  
    1008        for (int i = 0; i < serverSize; ++i) 
    1009        { 
    1010          if (0 != nbIndexOnServer(i)) 
    1011          { 
    1012            globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i)); 
    1013            elementOnServer[idx][i] = true; 
    1014          } 
    1015        } 
    1016  
    1017      nbIndexOnServer = 0; 
    1018      for (size_t j = 0; j < globalIndexElementOnServerMap.size(); ++j) 
    1019      { 
    1020        it = globalIndexElementOnServerMap.find(globalIndexElementOnClient(j)); 
    1021        if (it != ite) 
    1022        { 
    1023          const std::vector<int>& tmp = it->second; 
    1024          nbIndexOnServerTmp = 0; 
    1025          for (int i = 0; i < tmp.size(); ++i) 
    1026          { 
    1027            if (0 == nbIndexOnServerTmp(tmp[i])) 
    1028            { 
    1029              globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first; 
    1030              ++nbIndexOnServerTmp(tmp[i]); 
    1031            } 
    1032          } 
    1033          nbIndexOnServer += nbIndexOnServerTmp; 
    1034        } 
    1035      } 
    1036    } 
    1037  
    1038     // Determine server which contain global source index 
    1039     std::vector<bool> intersectedProc(serverSize, true); 
    1040     for (int idx = 0; idx < nbElement; ++idx) 
    1041     { 
    1042       std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(), 
    1043                      intersectedProc.begin(), intersectedProc.begin(), 
    1044                      std::logical_and<bool>()); 
    1045     } 
    1046  
    1047     std::vector<int> srcRank; 
    1048     for (int idx = 0; idx < serverSize; ++idx) 
    1049     { 
    1050       if (intersectedProc[idx]) srcRank.push_back(idx); 
    1051     } 
    1052  
    1053     // Compute the global index of grid from global index of each element. 
    1054     for (int i = 0; i < srcRank.size(); ++i) 
    1055     { 
    1056       size_t ssize = 1; 
    1057       int rankSrc = srcRank[i]; 
    1058       std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement); 
    1059       std::vector<size_t> currentIndex(nbElement,0); 
    1060       for (int idx = 0; idx < nbElement; ++idx) 
    1061       { 
    1062         ssize *= (globalElementIndexOnServer[idx][rankSrc]).size(); 
    1063         globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]); 
    1064       } 
    1065       globalIndexOnServer[rankSrc].resize(ssize); 
    1066  
    1067       std::vector<int> idxLoop(nbElement,0); 
    1068       int innnerLoopSize = (globalIndexOfElementTmp[0])->size(); 
    1069       size_t idx = 0; 
    1070       while (idx < ssize) 
    1071       { 
    1072         for (int ind = 0; ind < nbElement; ++ind) 
    1073         { 
    1074           if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size()) 
    1075           { 
    1076             idxLoop[ind] = 0; 
    1077             ++idxLoop[ind+1]; 
    1078           } 
    1079  
    1080           currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]]; 
    1081         } 
    1082  
    1083         for (int ind = 0; ind < innnerLoopSize; ++ind) 
    1084         { 
    1085           currentIndex[0] = (*globalIndexOfElementTmp[0])[ind]; 
    1086           size_t globalSrcIndex = 0; 
    1087           for (int idxElement = 0; idxElement < nbElement; ++idxElement) 
    1088           { 
    1089             globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement]; 
    1090           } 
    1091           globalIndexOnServer[rankSrc][idx] = globalSrcIndex; 
    1092           ++idx; 
    1093           ++idxLoop[0]; 
    1094         } 
    1095       } 
    1096     } 
    1097    } 
    1098    CATCH_DUMP_ATTR 
    1099 //---------------------------------------------------------------- 
    1100  
    1101    CGrid* CGrid::createGrid(CDomain* domain) 
    1102    TRY 
    1103    { 
    1104       std::vector<CDomain*> vecDom(1, domain); 
    1105       std::vector<CAxis*> vecAxis; 
    1106  
    1107       return createGrid(vecDom, vecAxis); 
    1108    } 
    1109    CATCH 
    1110  
    1111    CGrid* CGrid::createGrid(CDomain* domain, CAxis* axis) 
    1112    TRY 
    1113   { 
    1114       std::vector<CDomain*> vecDom(1, domain); 
    1115       std::vector<CAxis*> vecAxis(1, axis); 
    1116  
    1117       return createGrid(vecDom, vecAxis); 
    1118    } 
    1119    CATCH 
    1120  
    1121    CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
    1122                             const CArray<int,1>& axisDomainOrder) 
    1123    TRY 
    1124    { 
    1125      std::vector<CScalar*> vecScalar; 
    1126      return createGrid(generateId(domains, axis, vecScalar, axisDomainOrder), domains, axis, vecScalar, axisDomainOrder); 
    1127    } 
    1128    CATCH 
    1129  
    1130    CGrid* CGrid::createGrid(const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
    1131                             const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
    1132    TRY 
    1133    { 
    1134      return createGrid(generateId(domains, axis, scalars, axisDomainOrder), domains, axis, scalars, axisDomainOrder); 
    1135    } 
    1136    CATCH 
    1137  
    1138    CGrid* CGrid::createGrid(StdString id, const std::vector<CDomain*>& domains, const std::vector<CAxis*>& axis, 
    1139                             const std::vector<CScalar*>& scalars, const CArray<int,1>& axisDomainOrder) 
    1140    TRY 
    1141    { 
    1142       if (axisDomainOrder.numElements() > 0 && axisDomainOrder.numElements() != (domains.size() + axis.size() + scalars.size())) 
    1143         ERROR("CGrid* CGrid::createGrid(...)", 
    1144               << "The size of axisDomainOrder (" << axisDomainOrder.numElements() 
    1145               << ") is not coherent with the number of elements (" << domains.size() + axis.size() <<")."); 
    1146  
    1147       CGrid* grid = CGridGroup::get("grid_definition")->createChild(id); 
    1148       grid->setDomainList(domains); 
    1149       grid->setAxisList(axis); 
    1150       grid->setScalarList(scalars); 
    1151  
    1152       // By default, domains are always the first elements of a grid 
    1153       if (0 == axisDomainOrder.numElements()) 
    1154       { 
    1155         int size = domains.size() + axis.size() + scalars.size(); 
    1156         int nb = 0; 
    1157         grid->axis_domain_order.resize(size); 
    1158         for (int i = 0; i < size; ++i) 
    1159         { 
    1160           if (i < domains.size()) { 
    1161             grid->axis_domain_order(i) = 2; 
    1162  
    1163           } 
    1164           else if ((scalars.size() < (size-nb)) < size) { 
    1165             grid->axis_domain_order(i) = 1; 
    1166           } 
    1167           else 
    1168             grid->axis_domain_order(i) = 0; 
    1169           ++nb; 
    1170         } 
    1171       } 
    1172       else 
    1173       { 
    1174         grid->axis_domain_order.resize(axisDomainOrder.numElements()); 
    1175         grid->axis_domain_order = axisDomainOrder; 
    1176       } 
    1177  
    1178       grid->solveDomainAxisRefInheritance(true); 
    1179  
    1180       return grid; 
    1181    } 
    1182    CATCH 
     924   } 
     925 
     926 
     927  bool CGrid::isDataDistributed(void)  
     928  {  
     929    return getClientDistribution()->isDataDistributed() ; 
     930  } 
     931 
     932   
    1183933 
    1184934   CGrid* CGrid::cloneGrid(const StdString& idNewGrid, CGrid* gridSrc) 
     
    12831033   CATCH 
    12841034 
     1035 
    12851036   //---------------------------------------------------------------- 
    12861037 
    1287    CDomainGroup* CGrid::getVirtualDomainGroup() const 
    1288    TRY 
    1289    { 
    1290      return this->vDomainGroup_; 
    1291    } 
    1292    CATCH 
    1293  
    1294    CAxisGroup* CGrid::getVirtualAxisGroup() const 
    1295    TRY 
    1296    { 
    1297      return this->vAxisGroup_; 
    1298    } 
    1299    CATCH 
    1300  
    1301    CScalarGroup* CGrid::getVirtualScalarGroup() const 
    1302    TRY 
    1303    { 
    1304      return this->vScalarGroup_; 
    1305    } 
    1306    CATCH 
    1307  
    1308 /* 
    1309    void CGrid::outputField(int rank, const CArray<double, 1>& stored, double* field) 
    1310    { 
    1311      const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 
    1312      StdSize numElements = stored.numElements(); 
    1313      for (StdSize n = 0; n < numElements; ++n) 
    1314      { 
    1315        field[out_i(n)] = stored(n); 
    1316      } 
    1317    } 
    1318  
    1319    void CGrid::inputField(int rank, const double* const field, CArray<double,1>& stored) 
    1320    { 
    1321      const CArray<size_t,1>& out_i = outIndexFromClient[rank]; 
    1322      StdSize numElements = stored.numElements(); 
    1323      for (StdSize n = 0; n < numElements; ++n) 
    1324      { 
    1325        stored(n) = field[out_i(n)]; 
    1326      } 
    1327    } 
    1328  
    1329    void CGrid::outputCompressedField(int rank, const CArray<double,1>& stored, double* field) 
    1330    { 
    1331      const CArray<size_t,1>& out_i = compressedOutIndexFromClient[rank]; 
    1332      StdSize numElements = stored.numElements(); 
    1333      for (StdSize n = 0; n < numElements; ++n) 
    1334      { 
    1335        field[out_i(n)] = stored(n); 
    1336      } 
    1337    } 
    1338 */ 
    1339    //---------------------------------------------------------------- 
    1340  
    1341    void CGrid::storeField_arr(const double* const data, CArray<double, 1>& stored) const 
    1342    TRY 
    1343    { 
    1344       const StdSize size = storeIndex_client.numElements(); 
    1345  
    1346       stored.resize(size); 
    1347       for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 
    1348    } 
    1349    CATCH 
    1350  
    1351    void CGrid::restoreField_arr(const CArray<double, 1>& stored, double* const data) const 
    1352    TRY 
    1353    { 
    1354       const StdSize size = storeIndex_client.numElements(); 
    1355  
    1356       for(StdSize i = 0; i < size; i++) data[storeIndex_client(i)] = stored(i); 
    1357    } 
    1358    CATCH 
    1359  
    1360    void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const 
    1361    { 
    1362       const StdSize size = storeIndex_client.numElements(); 
    1363       stored.resize(size); 
    1364       const double nanValue = std::numeric_limits<double>::quiet_NaN(); 
    1365  
    1366       if (storeMask_client.numElements() != 0) 
    1367         for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue; 
    1368       else 
    1369         for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)]; 
    1370    } 
    1371  
    1372    void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const 
    1373    TRY 
    1374    { 
    1375       const std::vector<int>& localMaskedDataIndex = clientDistribution_->getLocalMaskedDataIndexOnClient(); 
    1376       const int size = localMaskedDataIndex.size(); 
    1377       for(int i = 0; i < size; ++i) out(localMaskedDataIndex[i]) = data[i]; 
    1378    } 
    1379    CATCH 
    1380  
    1381   void CGrid::computeClientIndexScalarGrid() 
    1382   TRY 
    1383   { 
    1384     CContext* context = CContext::getCurrent();     
    1385     { 
    1386       CContextClient* client = context->client; 
    1387  
    1388       int rank = client->clientRank; 
    1389  
    1390       clientDistribution_ = new CDistributionClient(rank, this); 
    1391  
    1392       storeIndex_client.resize(1); 
    1393       storeIndex_client(0) = 0;       
    1394  
    1395       if (0 != serverDistribution_) 
    1396       { 
    1397         map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(), 
    1398                                                ite = outGlobalIndexFromClient.end(), it; 
    1399         for (it = itb; it != ite; ++it) 
    1400         { 
    1401           int rank = it->first; 
    1402           CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank]; 
    1403           outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements()))); 
    1404           CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank]; 
    1405           if (1 != globalIndex.numElements()) 
    1406             ERROR("void CGrid::computeClientIndexScalarGrid()", 
    1407               << "Something wrong happened. " 
    1408               << "Number of received global index on scalar grid should equal to 1"  
    1409               << "Number of received global index " << globalIndex.numElements() << "."); 
    1410  
    1411           localIndex(0) = globalIndex(0); 
    1412         } 
    1413       } 
    1414     } 
    1415   } 
    1416   CATCH_DUMP_ATTR 
    1417  
    1418   void CGrid::computeConnectedClientsScalarGrid() 
    1419   TRY 
    1420   { 
    1421     CContext* context = CContext::getCurrent();     
    1422     int nbSrvPools = (context->clientPrimServer.size()==0) ? 1 : context->clientPrimServer.size(); 
    1423     connectedServerRank_.clear(); 
    1424     connectedDataSize_.clear(); 
    1425     nbSenders.clear(); 
    1426  
    1427     for (int p = 0; p < nbSrvPools; ++p) 
    1428     { 
    1429       CContextClient* client = (context->clientPrimServer.size()==0) ? context->client : context->clientPrimServer[p]; 
    1430       int receiverSize = client->serverSize; 
    1431  
    1432 //      connectedServerRank_[client].clear(); 
    1433  
    1434       if (connectedServerRank_.find(receiverSize)==connectedServerRank_.end()) 
    1435       { 
    1436         if (client->isServerLeader()) 
    1437         { 
    1438           const std::list<int>& ranks = client->getRanksServerLeader(); 
    1439           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1440           { 
    1441             int rank = *itRank; 
    1442             int nb = 1; 
    1443             connectedServerRank_[receiverSize].push_back(rank); 
    1444             connectedDataSize_[receiverSize][rank] = nb; 
    1445             nbSenders[receiverSize][rank] = nb; 
    1446           } 
    1447         } 
    1448         else 
    1449         { 
    1450           const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1451           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1452           { 
    1453             int rank = *itRank; 
    1454             int nb = 1; 
    1455             connectedServerRank_[receiverSize].push_back(rank); 
    1456             connectedDataSize_[receiverSize][rank] = nb; 
    1457             nbSenders[receiverSize][rank] = nb; 
    1458           } 
    1459         } 
    1460       } 
    1461       isDataDistributed_ = false; 
    1462     } 
    1463   } 
    1464   CATCH_DUMP_ATTR 
    1465  
    1466   void CGrid::sendIndexScalarGrid() 
    1467   TRY 
    1468   { 
    1469     CContext* context = CContext::getCurrent(); 
    1470     storeIndex_toSrv.clear(); 
    1471     std::list<CContextClient*>::iterator it; 
    1472  
    1473     for (it=clients.begin(); it!=clients.end(); ++it) 
    1474     { 
    1475       CContextClient* client = *it; 
    1476       int receiverSize = client->serverSize; 
    1477  
    1478       CEventClient event(getType(), EVENT_ID_INDEX); 
    1479       list<CMessage> listMsg; 
    1480       list<CArray<size_t,1> > listOutIndex; 
    1481  
    1482       if (client->isServerLeader()) 
    1483       { 
    1484         const std::list<int>& ranks = client->getRanksServerLeader(); 
    1485         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1486         { 
    1487           int rank = *itRank; 
    1488           int nb = 1; 
    1489           storeIndex_toSrv[client].insert(std::make_pair(rank, CArray<int,1>(nb))); 
    1490           listOutIndex.push_back(CArray<size_t,1>(nb)); 
    1491  
    1492           CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 
    1493           CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    1494  
    1495           for (int k = 0; k < nb; ++k) 
    1496           { 
    1497             outGlobalIndexOnServer(k) = 0; 
    1498             outLocalIndexToServer(k)  = 0; 
    1499           } 
    1500  
    1501           if (context->hasClient && !context->hasServer) 
    1502             storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1503  
    1504           listMsg.push_back(CMessage()); 
    1505           listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1506  
    1507           event.push(rank, 1, listMsg.back()); 
    1508         } 
    1509         client->sendEvent(event); 
    1510       } 
    1511       else 
    1512       { 
    1513         const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1514         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1515         { 
    1516           int rank = *itRank; 
    1517           int nb = 1;           
    1518           CArray<int, 1> outLocalIndexToServer(nb); 
    1519           for (int k = 0; k < nb; ++k) 
    1520           { 
    1521             outLocalIndexToServer(k)  = 0; 
    1522           } 
    1523  
    1524           if (context->hasClient && !context->hasServer) 
    1525             storeIndex_fromSrv.insert(std::make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1526         } 
    1527         client->sendEvent(event); 
    1528       } 
    1529     } 
    1530   } 
    1531   CATCH_DUMP_ATTR 
    1532  
    1533   void CGrid::sendIndex(void) 
    1534   TRY 
    1535   { 
    1536     CContext* context = CContext::getCurrent(); 
    1537     storeIndex_toSrv.clear(); 
    1538     std::list<CContextClient*>::iterator it; 
    1539  
    1540     for (it=clients.begin(); it!=clients.end(); ++it) 
    1541     { 
    1542       CContextClient* client = *it; 
    1543       int receiverSize = client->serverSize; 
    1544  
    1545       CEventClient event(getType(), EVENT_ID_INDEX); 
    1546       int rank; 
    1547       list<CMessage> listMsg; 
    1548       list<CArray<size_t,1> > listOutIndex; 
    1549       const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer(); 
    1550       CDistributionClient::GlobalLocalDataMap::const_iterator itbIndex = globalLocalIndexSendToServer.begin(), itIndex, 
    1551                                                               iteIndex = globalLocalIndexSendToServer.end(); 
    1552       itIndex = itbIndex;                                                               
    1553  
    1554       if (!doGridHaveDataDistributed(client)) 
    1555       { 
    1556         if (client->isServerLeader()) 
    1557         { 
    1558           int indexSize = globalLocalIndexSendToServer.size(); 
    1559           CArray<size_t,1> outGlobalIndexOnServer(indexSize); 
    1560           CArray<int,1> outLocalIndexToServer(indexSize); 
    1561           for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1562           { 
    1563             outGlobalIndexOnServer(idx) = itIndex->first; 
    1564             outLocalIndexToServer(idx) = itIndex->second; 
    1565           } 
    1566  
    1567           const std::list<int>& ranks = client->getRanksServerLeader(); 
    1568           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1569           { 
    1570             storeIndex_toSrv[client].insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1571             if (context->hasClient && !context->hasServer) 
    1572               storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1573              
    1574             listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer)); 
    1575  
    1576             listMsg.push_back(CMessage()); 
    1577             listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1578  
    1579             event.push(*itRank, 1, listMsg.back()); 
    1580           } 
    1581           client->sendEvent(event); 
    1582         } 
    1583         else 
    1584         { 
    1585            int indexSize = globalLocalIndexSendToServer.size(); 
    1586            CArray<int,1> outLocalIndexToServer(indexSize); 
    1587            for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx) 
    1588            { 
    1589              outLocalIndexToServer(idx) = itIndex->second; 
    1590            } 
    1591  
    1592            const std::list<int>& ranks = client->getRanksServerNotLeader(); 
    1593            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) 
    1594            { 
    1595              storeIndex_fromSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer))); 
    1596            } 
    1597            client->sendEvent(event); 
    1598          } 
    1599       } 
    1600       else 
    1601       { 
    1602         CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap; 
    1603         itGlobalMap = globalIndexOnServer_[receiverSize].begin(); 
    1604         iteGlobalMap = globalIndexOnServer_[receiverSize].end(); 
    1605  
    1606         std::map<int,std::vector<int> >localIndexTmp; 
    1607         std::map<int,std::vector<size_t> > globalIndexTmp; 
    1608         for (; itGlobalMap != iteGlobalMap; ++itGlobalMap) 
    1609         { 
    1610           int serverRank = itGlobalMap->first; 
    1611           int indexSize = itGlobalMap->second.size(); 
    1612           const std::vector<size_t>& indexVec = itGlobalMap->second; 
    1613           for (int idx = 0; idx < indexSize; ++idx) 
    1614           { 
    1615             itIndex = globalLocalIndexSendToServer.find(indexVec[idx]); 
    1616             if (iteIndex != itIndex) 
    1617             { 
    1618               globalIndexTmp[serverRank].push_back(itIndex->first); 
    1619               localIndexTmp[serverRank].push_back(itIndex->second); 
    1620             } 
    1621           } 
    1622         } 
    1623  
    1624         for (int ns = 0; ns < connectedServerRank_[receiverSize].size(); ++ns) 
    1625         { 
    1626           rank = connectedServerRank_[receiverSize][ns]; 
    1627           int nb = 0; 
    1628           if (globalIndexTmp.end() != globalIndexTmp.find(rank)) 
    1629             nb = globalIndexTmp[rank].size(); 
    1630  
    1631           storeIndex_toSrv[client].insert(make_pair(rank, CArray<int,1>(nb))); 
    1632           listOutIndex.push_back(CArray<size_t,1>(nb)); 
    1633  
    1634           CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[client][rank]; 
    1635           CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back(); 
    1636  
    1637           for (int k = 0; k < nb; ++k) 
    1638           { 
    1639             outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k); 
    1640             outLocalIndexToServer(k)  = localIndexTmp[rank].at(k); 
    1641           } 
    1642  
    1643           storeIndex_fromSrv.insert(make_pair(rank, CArray<int,1>(outLocalIndexToServer))); 
    1644           listMsg.push_back(CMessage()); 
    1645           listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back(); 
    1646  
    1647           event.push(rank, nbSenders[receiverSize][rank], listMsg.back()); 
    1648         } 
    1649  
    1650         client->sendEvent(event); 
    1651       } 
    1652     } 
    1653   } 
    1654   CATCH_DUMP_ATTR 
    1655  
    1656   void CGrid::recvIndex(CEventServer& event) 
    1657   TRY 
    1658   { 
    1659     string gridId; 
    1660     vector<int> ranks; 
    1661     vector<CBufferIn*> buffers; 
    1662  
    1663     list<CEventServer::SSubEvent>::iterator it; 
    1664     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) 
    1665     { 
    1666       ranks.push_back(it->rank); 
    1667       CBufferIn* buffer = it->buffer; 
    1668       *buffer >> gridId; 
    1669       buffers.push_back(buffer); 
    1670     } 
    1671     get(gridId)->recvIndex(ranks, buffers); 
    1672   } 
    1673   CATCH 
    1674  
    1675   void CGrid::recvIndex(vector<int> ranks, vector<CBufferIn*> buffers) 
    1676   TRY 
    1677   { 
    1678     CContext* context = CContext::getCurrent(); 
    1679     connectedServerRankRead_ = ranks; 
    1680  
    1681     int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 1) : 1; 
    1682     nbSrvPools = 1;     
    1683     nbReadSenders.clear(); 
    1684     for (int p = 0; p < nbSrvPools; ++p) 
    1685     { 
    1686       CContextServer* server = (!context->hasClient) ? context->server : context->serverPrimServer[p]; 
    1687       CContextClient* client = context->client;   //(!context->hasClient) ? context->client : context->clientPrimServer[p]; 
    1688        
    1689       int idx = 0, numElement = axis_domain_order.numElements(); 
    1690       int ssize = numElement; 
    1691       std::vector<int> indexMap(numElement); 
    1692       for (int i = 0; i < numElement; ++i) 
    1693       { 
    1694         indexMap[i] = idx; 
    1695         if (2 == axis_domain_order(i)) 
    1696         { 
    1697           ++ssize; 
    1698           idx += 2; 
    1699         } 
    1700         else 
    1701           ++idx; 
    1702       } 
    1703  
    1704       for (int n = 0; n < ranks.size(); n++) 
    1705       { 
    1706         int rank = ranks[n]; 
    1707         CBufferIn& buffer = *buffers[n]; 
    1708  
    1709         buffer >> isDataDistributed_ >> isCompressible_; 
    1710         size_t dataSize = 0; 
    1711  
    1712         if (0 == serverDistribution_) 
    1713         { 
    1714           int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    1715           std::vector<CDomain*> domainList = getDomains(); 
    1716           std::vector<CAxis*> axisList = getAxis(); 
    1717           std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize), nGlobElement(numElement); 
    1718           std::vector<CArray<int,1> > globalIndex(numElement); 
    1719           for (int i = 0; i < numElement; ++i) 
    1720           { 
    1721             nGlobElement[i] = globalSize; 
    1722             if (2 == axis_domain_order(i)) //domain 
    1723             { 
    1724               nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
    1725               nSize[indexMap[i]]  = domainList[domainId]->ni; 
    1726               nBeginGlobal[indexMap[i]] = 0; 
    1727               nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    1728  
    1729               nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
    1730               nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
    1731               nBeginGlobal[indexMap[i] + 1] = 0; 
    1732               nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    1733  
    1734               { 
    1735                 int count = 0; 
    1736                 globalIndex[i].resize(nSize[indexMap[i]]*nSize[indexMap[i]+1]); 
    1737                 for (int jdx = 0; jdx < nSize[indexMap[i]+1]; ++jdx) 
    1738                   for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    1739                   { 
    1740                     globalIndex[i](count) = (nBegin[indexMap[i]] + idx) + (nBegin[indexMap[i]+1] + jdx) * nGlob[indexMap[i]]; 
    1741                     ++count; 
    1742                   } 
    1743               } 
    1744  
    1745               ++domainId; 
    1746             } 
    1747             else if (1 == axis_domain_order(i)) // axis 
    1748             { 
    1749               nBegin[indexMap[i]] = axisList[axisId]->begin; 
    1750               nSize[indexMap[i]]  = axisList[axisId]->n; 
    1751               nBeginGlobal[indexMap[i]] = 0; 
    1752               nGlob[indexMap[i]] = axisList[axisId]->n_glo;      
    1753               globalIndex[i].resize(nSize[indexMap[i]]); 
    1754               for (int idx = 0; idx < nSize[indexMap[i]]; ++idx) 
    1755                 globalIndex[i](idx) = nBegin[indexMap[i]] + idx; 
    1756  
    1757               ++axisId; 
    1758             } 
    1759             else // scalar 
    1760             {  
    1761               nBegin[indexMap[i]] = 0; 
    1762               nSize[indexMap[i]]  = 1; 
    1763               nBeginGlobal[indexMap[i]] = 0; 
    1764               nGlob[indexMap[i]] = 1; 
    1765               globalIndex[i].resize(1); 
    1766               globalIndex[i](0) = 0; 
    1767               ++scalarId; 
    1768             } 
    1769           } 
    1770           dataSize = 1; 
    1771  
    1772           for (int i = 0; i < nSize.size(); ++i) 
    1773             dataSize *= nSize[i]; 
    1774           serverDistribution_ = new CDistributionServer(server->intraCommRank,  
    1775                                                         globalIndex, axis_domain_order, 
    1776                                                         nBegin, nSize, nBeginGlobal, nGlob); 
    1777         } 
    1778  
    1779         CArray<size_t,1> outIndex; 
    1780         buffer >> outIndex; 
    1781         outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex)); 
    1782         connectedDataSizeRead_[rank] = outIndex.numElements(); 
    1783  
    1784         if (doGridHaveDataDistributed(client)) 
    1785         {} 
    1786         else 
    1787         { 
    1788           // THE PROBLEM HERE IS THAT DATA CAN BE NONDISTRIBUTED ON CLIENT AND DISTRIBUTED ON SERVER 
    1789           // BELOW IS THE TEMPORARY FIX only for a single type of element (domain, asix, scalar) 
    1790           dataSize = serverDistribution_->getGridSize(); 
    1791         } 
    1792         writtenDataSize_ += dataSize; 
    1793       } 
    1794  
    1795  
    1796       // Compute mask of the current grid 
    1797       { 
    1798         int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1; 
    1799         std::vector<CDomain*> domainList = getDomains(); 
    1800         std::vector<CAxis*> axisList = getAxis(); 
    1801         int dimSize = 2 * domainList.size() + axisList.size(); 
    1802         std::vector<int> nBegin(dimSize), nSize(dimSize), nGlob(dimSize), nBeginGlobal(dimSize);         
    1803         for (int i = 0; i < numElement; ++i) 
    1804         {           
    1805           if (2 == axis_domain_order(i)) //domain 
    1806           { 
    1807             nBegin[indexMap[i]] = domainList[domainId]->ibegin; 
    1808             nSize[indexMap[i]]  = domainList[domainId]->ni; 
    1809             nBeginGlobal[indexMap[i]] = 0;               
    1810             nGlob[indexMap[i]] = domainList[domainId]->ni_glo; 
    1811  
    1812             nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin; 
    1813             nSize[indexMap[i] + 1] = domainList[domainId]->nj; 
    1814             nBeginGlobal[indexMap[i] + 1] = 0;               
    1815             nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo; 
    1816  
    1817             ++domainId; 
    1818           } 
    1819           else if (1 == axis_domain_order(i)) // axis 
    1820           { 
    1821             nBegin[indexMap[i]] = axisList[axisId]->begin; 
    1822             nSize[indexMap[i]]  = axisList[axisId]->n; 
    1823             nBeginGlobal[indexMap[i]] = 0;               
    1824             nGlob[indexMap[i]] = axisList[axisId]->n_glo;               
    1825             ++axisId; 
    1826           } 
    1827           else // scalar 
    1828           {   
    1829           } 
    1830         } 
    1831          
    1832         if (nSize.empty()) // Scalar grid 
    1833         { 
    1834           nBegin.push_back(0); 
    1835           nSize.push_back(1); 
    1836           nBeginGlobal.push_back(0);               
    1837           nGlob.push_back(1);   
    1838         } 
    1839       } 
    1840  
    1841       if (isScalarGrid()) return; 
    1842  
    1843       nbReadSenders[client] = CClientServerMappingDistributed::computeConnectedClients(context->client->serverSize, context->client->clientSize, context->client->intraComm, ranks); 
    1844     } 
    1845   } 
    1846   CATCH_DUMP_ATTR 
    1847  
     1038     
     1039   
     1040   
    18481041  /* 
    18491042     Compute on the fly the global dimension of a grid with its elements 
     
    19381131  TRY 
    19391132  { 
    1940      return (0 != writtenDataSize_); 
     1133     return (0 != getGridLocalElements()->getView(CElementView::FULL)->getSize()); 
    19411134  } 
    19421135  CATCH_DUMP_ATTR 
    19431136 
    1944   /*! 
    1945     Return size of data which is written on each server 
    1946     Whatever dimension of a grid, data which are written on server must be presented as 
    1947     an one dimension array. 
    1948     \return size of data written on server 
    1949   */ 
    1950   size_t CGrid::getWrittenDataSize() const 
    1951   TRY 
    1952   { 
    1953     return writtenDataSize_; 
    1954   } 
    1955   CATCH 
    1956  
    1957   /*! 
    1958     Returns the number of indexes written by each server. 
    1959     \return the number of indexes written by each server 
    1960   */ 
    1961   int CGrid::getNumberWrittenIndexes() const 
    1962   TRY 
    1963   { 
    1964     return numberWrittenIndexes_; 
    1965   } 
    1966   CATCH 
    1967  
    1968   /*! 
    1969     Returns the total number of indexes written by the servers. 
    1970     \return the total number of indexes written by the servers 
    1971   */ 
    1972   int CGrid::getTotalNumberWrittenIndexes() const 
    1973   TRY 
    1974   { 
    1975     return totalNumberWrittenIndexes_; 
    1976   } 
    1977   CATCH 
    1978  
    1979   /*! 
    1980     Returns the offset of indexes written by each server. 
    1981     \return the offset of indexes written by each server 
    1982   */ 
    1983   int CGrid::getOffsetWrittenIndexes() const 
    1984   TRY 
    1985   { 
    1986     return offsetWrittenIndexes_; 
    1987   } 
    1988   CATCH 
    1989  
    1990   CDistributionServer* CGrid::getDistributionServer() 
    1991   TRY 
    1992   { 
    1993     return serverDistribution_; 
    1994   } 
    1995   CATCH_DUMP_ATTR 
    1996  
    1997   CDistributionClient* CGrid::getDistributionClient() 
    1998   TRY 
    1999   { 
    2000     return clientDistribution_; 
    2001   } 
    2002   CATCH_DUMP_ATTR 
    2003  
     1137  
    20041138  bool CGrid::doGridHaveDataDistributed(CContextClient* client) 
    20051139  TRY 
    20061140  { 
     1141    // This function is now useless because it will return false only if server and client size are equal to 1 
     1142    // to be seriously check in future  
     1143 
    20071144    if (isScalarGrid()) return false; 
    20081145    else if (0 != client) 
    20091146    { 
    2010       return  (isDataDistributed_ ||  (1 != client->clientSize) || (1 != client->serverSize)); 
     1147      return  (isDataDistributed() ||  (1 != client->clientSize) || (1 != client->serverSize)); 
    20111148    } 
    20121149    else 
    2013       return isDataDistributed_;     
     1150      return isDataDistributed();     
    20141151  } 
    20151152  CATCH_DUMP_ATTR 
     
    20311168      switch(event.type) 
    20321169      { 
    2033         case EVENT_ID_INDEX : 
    2034           recvIndex(event); 
    2035           return true; 
    2036           break; 
    2037  
    20381170         case EVENT_ID_ADD_DOMAIN : 
    20391171           recvAddDomain(event); 
     
    20501182           return true; 
    20511183           break; 
     1184 
     1185         case EVENT_ID_SEND_MASK : 
     1186           recvMask(event); 
     1187           return true; 
     1188           break; 
    20521189        default : 
    2053           ERROR("bool CDomain::dispatchEvent(CEventServer& event)", 
     1190          ERROR("bool CGrid::dispatchEvent(CEventServer& event)", 
    20541191                << "Unknown Event"); 
    20551192          return false; 
     
    20591196  CATCH 
    20601197 
    2061    ///--------------------------------------------------------------- 
    2062  
    2063    CDomain* CGrid::addDomain(const std::string& id) 
    2064    TRY 
    2065    { 
    2066      order_.push_back(2); 
    2067      axis_domain_order.resize(order_.size()); 
    2068      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
    2069      return vDomainGroup_->createChild(id); 
    2070    } 
    2071    CATCH_DUMP_ATTR 
    2072  
    2073    CAxis* CGrid::addAxis(const std::string& id) 
    2074    TRY 
    2075    { 
    2076      order_.push_back(1); 
    2077      axis_domain_order.resize(order_.size()); 
    2078      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
    2079      return vAxisGroup_->createChild(id); 
    2080    } 
    2081    CATCH_DUMP_ATTR 
    2082  
    2083    CScalar* CGrid::addScalar(const std::string& id) 
    2084    TRY 
    2085    { 
    2086      order_.push_back(0); 
    2087      axis_domain_order.resize(order_.size()); 
    2088      for (int idx = 0; idx < order_.size(); ++idx) axis_domain_order(idx)=order_[idx]; 
    2089      return vScalarGroup_->createChild(id); 
    2090    } 
    2091    CATCH_DUMP_ATTR 
    2092  
    2093    //! Change virtual field group to a new one 
    2094    void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup) 
    2095    TRY 
    2096    { 
    2097       this->vDomainGroup_ = newVDomainGroup; 
    2098    } 
    2099    CATCH_DUMP_ATTR 
    2100  
    2101    //! Change virtual variable group to new one 
    2102    void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup) 
    2103    TRY 
    2104    { 
    2105       this->vAxisGroup_ = newVAxisGroup; 
    2106    } 
    2107    CATCH_DUMP_ATTR 
    2108  
    2109    //! Change virtual variable group to new one 
    2110    void CGrid::setVirtualScalarGroup(CScalarGroup* newVScalarGroup) 
    2111    TRY 
    2112    { 
    2113       this->vScalarGroup_ = newVScalarGroup; 
    2114    } 
    2115    CATCH_DUMP_ATTR 
     1198  
     1199 
     1200  void CGrid::sendGridToFileServer(CContextClient* client) 
     1201  { 
     1202    if (sendGridToFileServer_done_.count(client)!=0) return ; 
     1203    else sendGridToFileServer_done_.insert(client) ; 
     1204 
     1205    StdString gridDefRoot("grid_definition"); 
     1206    CGridGroup* gridPtr = CGridGroup::get(gridDefRoot); 
     1207    gridPtr->sendCreateChild(this->getId(),client); 
     1208    this->sendAllAttributesToServer(client); 
     1209    distributeGridToFileServer(client) ; 
     1210  } 
     1211 
     1212 
     1213  void CGrid::distributeGridToFileServer(CContextClient* client) 
     1214  { 
     1215    CContext* context = CContext::getCurrent(); 
     1216    // simple Distribution for now  
     1217    // distribute over the fisrt element except if it is a scalar 
     1218    auto& elements = getElements() ; 
     1219    int posDistributed = 0 ; 
     1220    for(auto& element : elements) 
     1221    { 
     1222      if (element.type==TYPE_DOMAIN) break ; 
     1223      else if (element.type==TYPE_AXIS) break ; 
     1224      else if (element.type==TYPE_SCALAR) posDistributed++ ; 
     1225    } 
     1226     
     1227    vector<CLocalView*> localViews ; 
     1228    vector<CDistributedView*> remoteViews ; 
     1229 
     1230    for(int i=0 ; i<elements.size() ; i++) 
     1231    { 
     1232      if (elements[i].type==TYPE_DOMAIN)  
     1233      {  
     1234         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1235         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1236         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1237         localViews.push_back(domain->getLocalView(CElementView::FULL)) ; 
     1238      } 
     1239      else if (elements[i].type==TYPE_AXIS) 
     1240      { 
     1241        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1242        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1243        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1244        localViews.push_back(axis->getLocalView(CElementView::FULL)) ; 
     1245      } 
     1246      else if (elements[i].type==TYPE_SCALAR) 
     1247      { 
     1248        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1249        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1250        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1251        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ; 
     1252      } 
     1253    } 
     1254    CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm(), client->getRemoteSize()) ; 
     1255    gridRemoteConnector.computeConnector() ; 
     1256     
     1257    vector<CScattererConnector*> scattererConnectors ; 
     1258    CScattererConnector* scattererConnector; 
     1259    for(int i=0 ; i<elements.size() ; i++) 
     1260    { 
     1261      if (elements[i].type==TYPE_DOMAIN)  
     1262      {  
     1263         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1264         sendAddDomain(domain->getId(),client) ; 
     1265         domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 
     1266         scattererConnectors.push_back(scattererConnector) ; 
     1267      } 
     1268      else if (elements[i].type==TYPE_AXIS) 
     1269      { 
     1270        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1271        sendAddAxis(axis->getId(),client) ; 
     1272        axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 
     1273        scattererConnectors.push_back(scattererConnector) ; 
     1274      } 
     1275      else if (elements[i].type==TYPE_SCALAR) 
     1276      { 
     1277        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1278        sendAddScalar(scalar->getId(),client) ; 
     1279        scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i), scattererConnector) ; 
     1280        scattererConnectors.push_back(scattererConnector) ; 
     1281      } 
     1282    } 
     1283 
     1284    CGridScattererConnector gridScattererConnector(scattererConnectors) ; 
     1285    CGridLocalConnector* workflowToFull = getGridLocalElements()->getConnector(CElementView::WORKFLOW, CElementView::FULL) ; 
     1286    CArray<bool,1> maskIn(workflowToFull->getSrcSize()) ; 
     1287    CArray<bool,1> maskOut(workflowToFull->getDstSize()) ; 
     1288    maskIn = true ; 
     1289    workflowToFull->transfer(maskIn,maskOut,false) ; 
     1290 
     1291    CEventClient event(getType(), EVENT_ID_SEND_MASK); 
     1292    CMessage message ; 
     1293    message<<getId() ;  
     1294    gridScattererConnector.transfer(maskOut, client, event, message) ; 
     1295    for(auto& it : scattererConnectors) delete it ; 
     1296 
     1297    vector<CScattererConnector*> clientToServerConnectors ; 
     1298    vector<CGathererConnector*>  clientFromServerConnectors ; 
     1299    for(auto& element : elements) 
     1300    { 
     1301      if (element.type==TYPE_DOMAIN)  
     1302      {  
     1303         clientToServerConnectors.push_back(element.domain->getClientToServerConnector(client)) ; 
     1304         clientFromServerConnectors.push_back(element.domain->getClientFromServerConnector(client)) ; 
     1305      } 
     1306      else if (element.type==TYPE_AXIS) 
     1307      { 
     1308        clientToServerConnectors.push_back(element.axis->getClientToServerConnector(client)) ; 
     1309        clientFromServerConnectors.push_back(element.axis->getClientFromServerConnector(client)) ; 
     1310 
     1311      } 
     1312      else if (element.type==TYPE_SCALAR) 
     1313      { 
     1314        clientToServerConnectors.push_back(element.scalar->getClientToServerConnector(client)) ; 
     1315        clientFromServerConnectors.push_back(element.scalar->getClientFromServerConnector(client)) ; 
     1316      } 
     1317    } 
     1318     
     1319    // compute the grid clientToServerConnector to send flux from client to servers 
     1320    clientToServerConnector_[client] = new CGridScattererConnector(clientToServerConnectors) ; 
     1321    clientFromServerConnector_[client] = new CGridGathererConnector(clientFromServerConnectors) ; 
     1322 
     1323 
     1324  } 
     1325 
     1326  void CGrid::recvMask(CEventServer& event) 
     1327  { 
     1328    string gridId; 
     1329    for (auto& subEvent : event.subEvents) (*subEvent.buffer) >> gridId  ; 
     1330    get(gridId)->receiveMask(event); 
     1331  } 
     1332   
     1333  void CGrid::receiveMask(CEventServer& event) 
     1334  { 
     1335    vector<CGathererConnector*> gathererConnectors ; 
     1336    vector<CLocalView*> fullViews ; 
     1337 
     1338    for(auto& element : getElements()) 
     1339    { 
     1340      if (element.type==TYPE_DOMAIN)  
     1341      { 
     1342        gathererConnectors.push_back(element.domain->getGathererConnector()); 
     1343        fullViews.push_back(element.domain->getLocalElement()->getView(CElementView::FULL)); 
     1344         
     1345      } 
     1346      else if (element.type==TYPE_AXIS) 
     1347      { 
     1348       gathererConnectors.push_back(element.axis->getGathererConnector()); 
     1349       fullViews.push_back(element.axis->getLocalElement()->getView(CElementView::FULL)); 
     1350      } 
     1351      else if (element.type==TYPE_SCALAR)  
     1352      { 
     1353        gathererConnectors.push_back(element.scalar->getGathererConnector()); 
     1354        fullViews.push_back(element.scalar->getLocalElement()->getView(CElementView::FULL)); 
     1355      } 
     1356    } 
     1357    CGridGathererConnector gridGathererConnector(gathererConnectors) ; 
     1358    CGridMaskConnector gridMaskConnector(fullViews) ; 
     1359 
     1360    CArray<bool,1> maskOut ; 
     1361    gridGathererConnector.transfer_or(event,maskOut) ; 
     1362    gridMaskConnector.computeConnector(maskOut) ; 
     1363 
     1364    CContextClient* client = event.getContextServer()->getAssociatedClient() ; 
     1365    int i=0 ; 
     1366    for(auto& element : getElements()) 
     1367    { 
     1368      if (element.type==TYPE_DOMAIN) element.domain->setServerMask(gridMaskConnector.getElementMask(i),client); 
     1369      else if (element.type==TYPE_AXIS) element.axis->setServerMask(gridMaskConnector.getElementMask(i),client); 
     1370      else if (element.type==TYPE_SCALAR) element.scalar->setServerMask(gridMaskConnector.getElementMask(i),client); 
     1371      i++ ; 
     1372    } 
     1373  } 
     1374 
     1375 
     1376  void CGrid::sendGridToCouplerOut(CContextClient* client, const string& fieldId) 
     1377  { 
     1378/*    if (sendGridToCouplerOut_done_.count(client)!=0) return ; 
     1379    else sendGridToCouplerOut_done_.insert(client) ; 
     1380  
     1381    CContext* context = CContext::getCurrent(); 
     1382    // simple Distribution for now  
     1383    // distribute over the fisrt element except if it is a scalar 
     1384    auto& elements = getElements() ; 
     1385    int posDistributed = 0 ; 
     1386    for(auto& element : elements) 
     1387    { 
     1388      if (element.type==TYPE_DOMAIN) break ; 
     1389      else if (element.type==TYPE_AXIS) break ; 
     1390      else if (element.type==TYPE_SCALAR) posDistributed++ ; 
     1391    } 
     1392     
     1393    vector<CLocalView*> localViews ; 
     1394    vector<CDistributedView*> remoteViews ; 
     1395 
     1396    for(int i=0 ; i<elements.size() ; i++) 
     1397    { 
     1398      if (elements[i].type==TYPE_DOMAIN)  
     1399      {  
     1400         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1401         domain->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1402         remoteViews.push_back(domain->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1403         localViews.push_back(domain->getLocalView(CElementView::FULL)) ; 
     1404      } 
     1405      else if (elements[i].type==TYPE_AXIS) 
     1406      { 
     1407        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1408        axis->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1409        remoteViews.push_back(axis->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1410        localViews.push_back(axis->getLocalView(CElementView::FULL)) ; 
     1411      } 
     1412      else if (elements[i].type==TYPE_SCALAR) 
     1413      { 
     1414        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1415        scalar->computeRemoteElement(client, posDistributed==i ? EDistributionType::BANDS : EDistributionType::NONE) ; 
     1416        remoteViews.push_back(scalar->getRemoteElement(client)->getView(CElementView::FULL)) ; 
     1417        localViews.push_back(scalar->getLocalView(CElementView::FULL)) ; 
     1418      } 
     1419    } 
     1420    CGridRemoteConnector gridRemoteConnector(localViews, remoteViews, context->getIntraComm(), client->getRemoteSize()) ; 
     1421    gridRemoteConnector.computeConnector() ; 
     1422     
     1423    vector<CScattererConnector*> clientToClientConnectors ; 
     1424    for(int i=0 ; i<elements.size() ; i++) 
     1425    { 
     1426      if (elements[i].type==TYPE_DOMAIN)  
     1427      {  
     1428         CDomain* domain = (CDomain*) elements[i].ptr ; 
     1429         sendAddDomain(domain->getId(),client) ; 
     1430         domain->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 
     1431         clientToClientConnectors.push_back(domain->getClientToServerConnector(client)) ; 
     1432      } 
     1433      else if (elements[i].type==TYPE_AXIS) 
     1434      { 
     1435        CAxis* axis = (CAxis*) elements[i].ptr ; 
     1436        sendAddAxis(axis->getId(),client) ; 
     1437        axis->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 
     1438        clientToClientConnectors.push_back(axis->getClientToServerConnector(client)) ; 
     1439      } 
     1440      else if (elements[i].type==TYPE_SCALAR) 
     1441      { 
     1442        CScalar* scalar = (CScalar*) elements[i].ptr ; 
     1443        sendAddScalar(scalar->getId(),client) ; 
     1444        scalar->distributeToServer(client, gridRemoteConnector.getDistributedGlobalIndex(i)) ; 
     1445        clientToClientConnectors.push_back(scalar->getClientToServerConnector(client)) ; 
     1446      } 
     1447    } 
     1448     
     1449    // compute the grid clientToServerConnector to send flux from client to servers 
     1450    clientToClientConnector_[client] = new CGridScattererConnector(clientToClientConnectors) ;*/ 
     1451  } 
     1452 
     1453  void CGrid::makeAliasForCoupling(const string& fieldId) 
     1454  { 
     1455    string gridId="_grid_of_"+fieldId ; 
     1456    createAlias(gridId) ; 
     1457     
     1458    const auto& domVect = getDomains() ; 
     1459    for (int pos=0; pos<domVect.size();pos++) domVect[pos]->makeAliasForCoupling(fieldId, pos); 
     1460 
     1461    const auto& axisVect=getAxis() ; 
     1462    for (int pos=0; pos<axisVect.size();pos++) axisVect[pos]->makeAliasForCoupling(fieldId, pos); 
     1463 
     1464    const auto& scalVect=getScalars() ; 
     1465    for (int pos=0; pos<scalVect.size();pos++) scalVect[pos]->makeAliasForCoupling(fieldId, pos); 
     1466  } 
    21161467 
    21171468   /*! 
     
    21191470   \param[in] id String identity of domain that will be created on server 
    21201471   */ 
    2121    void CGrid::sendAddDomain(const string& id) 
    2122    TRY 
    2123   { 
    2124       sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN); 
     1472   void CGrid::sendAddDomain(const string& id, CContextClient* contextClient) 
     1473   TRY 
     1474  { 
     1475      sendAddItem(id, (int)EVENT_ID_ADD_DOMAIN, contextClient); 
    21251476   } 
    21261477   CATCH_DUMP_ATTR 
     
    21301481   \param[in] id String identity of axis that will be created on server 
    21311482   */ 
    2132    void CGrid::sendAddAxis(const string& id) 
    2133    TRY 
    2134    { 
    2135       sendAddItem(id, (int)EVENT_ID_ADD_AXIS); 
     1483   void CGrid::sendAddAxis(const string& id, CContextClient* contextClient) 
     1484   TRY 
     1485   { 
     1486      sendAddItem(id, (int)EVENT_ID_ADD_AXIS, contextClient); 
    21361487   } 
    21371488   CATCH_DUMP_ATTR 
     
    21411492   \param[in] id String identity of scalar that will be created on server 
    21421493   */ 
    2143    void CGrid::sendAddScalar(const string& id) 
    2144    TRY 
    2145    { 
    2146       sendAddItem(id, (int)EVENT_ID_ADD_SCALAR); 
     1494   void CGrid::sendAddScalar(const string& id, CContextClient* contextClient) 
     1495   TRY 
     1496   { 
     1497      sendAddItem(id, (int)EVENT_ID_ADD_SCALAR, contextClient); 
    21471498   } 
    21481499   CATCH_DUMP_ATTR 
     
    22311582   } 
    22321583   CATCH_DUMP_ATTR 
     1584 
     1585  /*! 
     1586  \brief Check if all elements of the grid are complete 
     1587  Before make any grid processing, we must be sure that all grid information elements have 
     1588  been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     1589  other context (coupling) 
     1590  */ 
     1591  bool CGrid::isCompleted(void) 
     1592  { 
     1593    setDomainList(); 
     1594    for (auto domainId : domList_) if (!CDomain::get(domainId)->isCompleted()) return false ; 
     1595    setAxisList() ; 
     1596    for (auto axisId : axisList_) if (!CAxis::get(axisId)->isCompleted()) return false ; 
     1597    setScalarList() ; 
     1598    for (auto scalarId : scalarList_) if (!CScalar::get(scalarId)->isCompleted()) return false ; 
     1599    return true ; 
     1600  } 
     1601 
     1602  /*! 
     1603  \brief impose that all elements of the grid are complete 
     1604  Before make any grid processing, we must be sure that all grid information elements have 
     1605  been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     1606  other context (coupling) 
     1607  */ 
     1608  void CGrid::setCompleted(void) 
     1609  { 
     1610    setDomainList(); 
     1611    for (auto domainId : domList_) CDomain::get(domainId)->setCompleted() ; 
     1612    setAxisList() ; 
     1613    for (auto axisId : axisList_) CAxis::get(axisId)->setCompleted() ; 
     1614    setScalarList() ; 
     1615    for (auto scalarId : scalarList_) CScalar::get(scalarId)->setCompleted() ; 
     1616  } 
     1617 
     1618/*! 
     1619  \brief impose that all elements of the grid are incomplete 
     1620  Before make any grid processing, we must be sure that all grid information elements have 
     1621  been sent, for exemple when reading a grid in a file or when grid elements are sent by an 
     1622  other context (coupling) 
     1623  */ 
     1624  void CGrid::unsetCompleted(void) 
     1625  { 
     1626    setDomainList(); 
     1627    for (auto domainId : domList_) CDomain::get(domainId)->unsetCompleted() ; 
     1628    setAxisList() ; 
     1629    for (auto axisId : axisList_) CAxis::get(axisId)->unsetCompleted() ; 
     1630    setScalarList() ; 
     1631    for (auto scalarId : scalarList_) CScalar::get(scalarId)->unsetCompleted() ; 
     1632  } 
    22331633 
    22341634  /*! 
     
    22381638  \param[in] apply inherit all attributes of parents (true) 
    22391639  */ 
    2240   void CGrid::solveDomainAxisRefInheritance(bool apply) 
    2241   TRY 
    2242   { 
    2243     CContext* context = CContext::getCurrent(); 
    2244     unsigned int vecSize, i; 
    2245     std::vector<StdString>::iterator it, itE; 
     1640  void CGrid::solveElementsRefInheritance(bool apply) 
     1641  TRY 
     1642  { 
    22461643    setDomainList(); 
    2247     it = domList_.begin(); itE = domList_.end(); 
    2248     for (; it != itE; ++it) 
    2249     { 
    2250       CDomain* pDom = CDomain::get(*it); 
    2251       if (context->hasClient && !context->hasServer)       
    2252       { 
    2253         pDom->solveRefInheritance(apply); 
    2254         pDom->solveInheritanceTransformation(); 
    2255       } 
     1644    for (auto domainId : domList_) 
     1645    { 
     1646      CDomain* pDom = CDomain::get(domainId); 
     1647      pDom->solveRefInheritance(apply); 
     1648      pDom->solveInheritanceTransformation(); 
    22561649    } 
    22571650 
    22581651    setAxisList(); 
    2259     it = axisList_.begin(); itE = axisList_.end(); 
    2260     for (; it != itE; ++it) 
    2261     { 
    2262       CAxis* pAxis = CAxis::get(*it); 
    2263       if (context->hasClient && !context->hasServer) 
    2264       { 
    2265         pAxis->solveRefInheritance(apply); 
    2266         pAxis->solveInheritanceTransformation(); 
    2267       } 
     1652    for (auto axisId : axisList_) 
     1653    { 
     1654      CAxis* pAxis = CAxis::get(axisId); 
     1655      pAxis->solveRefInheritance(apply); 
     1656      pAxis->solveInheritanceTransformation(); 
    22681657    } 
    22691658 
    22701659    setScalarList(); 
    2271     it = scalarList_.begin(); itE = scalarList_.end(); 
    2272     for (; it != itE; ++it) 
    2273     { 
    2274       CScalar* pScalar = CScalar::get(*it); 
    2275       if (context->hasClient && !context->hasServer) 
    2276       { 
    2277         pScalar->solveRefInheritance(apply); 
    2278         pScalar->solveInheritanceTransformation(); 
    2279       } 
     1660    for (auto scalarId : scalarList_) 
     1661    { 
     1662      CScalar* pScalar = CScalar::get(scalarId); 
     1663      pScalar->solveRefInheritance(apply); 
     1664      pScalar->solveInheritanceTransformation(); 
    22801665    } 
    22811666  } 
    22821667  CATCH_DUMP_ATTR 
    22831668 
    2284   bool CGrid::isTransformed() 
    2285   TRY 
    2286   { 
    2287     return isTransformed_; 
     1669 /*! 
     1670  \brief check attributes of all elements of the grid 
     1671  */ 
     1672  void CGrid::checkElementsAttributes(void) 
     1673  TRY 
     1674  { 
     1675    setDomainList(); 
     1676    for (auto domainId : domList_) CDomain::get(domainId)->checkAttributes(); 
     1677 
     1678    setAxisList(); 
     1679    for (auto axisId : axisList_) CAxis::get(axisId)->checkAttributes(); 
     1680     
     1681    setScalarList(); 
     1682    for (auto scalarId : scalarList_) CScalar::get(scalarId)->checkAttributes(); 
    22881683  } 
    22891684  CATCH_DUMP_ATTR 
    22901685 
    2291   void CGrid::setTransformed() 
    2292   TRY 
    2293   { 
    2294     isTransformed_ = true; 
     1686 
     1687 
     1688//********************************************************** 
     1689//**************   New transformation method  ************** 
     1690//********************************************************** 
     1691 
     1692  std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> >  
     1693  CGrid::buildTransformationGraph(CGarbageCollector& gc, bool isSource, CGrid* gridSrc, double detectMissingValues, double defaultValue, CGrid*& newGrid, bool graphEnabled) 
     1694  TRY 
     1695  { 
     1696    registerAlgorithmTransformation() ; // needed to enable self-registration of the transformations 
     1697                                        // big mystery why it doesn't work witout that... 
     1698                                        // problem with the linker ??  
     1699 
     1700    std::shared_ptr<CFilter> inputFilter = std::shared_ptr<CPassThroughFilter>(new CPassThroughFilter(gc)); 
     1701    std::shared_ptr<CFilter> outputFilter = inputFilter ; 
     1702 
     1703 
     1704    string newId ; 
     1705    if (gridSrc!=nullptr) newId = gridSrc->getId() + " --> " + this->getId()  ; 
     1706    else newId = " --> " + this->getId()  ; 
     1707    bool isNewGrid ; 
     1708    if (CGrid::has(newId)) 
     1709    { 
     1710      cout<<"Retrive existing grid : "<<newId<<endl ; 
     1711      newGrid = CGrid::get(newId); 
     1712      isNewGrid = false ; 
     1713    } 
     1714    else   
     1715    { 
     1716      cout<<"Create new grid : "<<newId<<endl ; 
     1717      newGrid = CGrid::create(newId) ; 
     1718      isNewGrid = true ; 
     1719    } 
     1720 
     1721    bool hadTransform=false ; 
     1722    bool hasTransform=false ; 
     1723    bool hasRemainTransform=false ; 
     1724    CGenericAlgorithmTransformation* algo ; 
     1725    int pos ; 
     1726 
     1727    for(int i=0 ; i<elements_.size(); i++) 
     1728    { 
     1729      CTransformationPaths transformationPath ; 
     1730      auto dstElement = elements_[i] ; 
     1731 
     1732      if (dstElement.type==TYPE_DOMAIN)      transformationPath = dstElement.domain->getTransformationPaths() ; 
     1733      else if (dstElement.type==TYPE_AXIS)   transformationPath = dstElement.axis->getTransformationPaths() ; 
     1734      else if (dstElement.type==TYPE_SCALAR) transformationPath = dstElement.scalar->getTransformationPaths() ; 
     1735 
     1736      SElement srcElement  ; 
     1737      if (gridSrc==nullptr) srcElement = this->elements_[i] ; 
     1738      else srcElement = gridSrc->elements_[i] ; 
     1739 
     1740      if (gridSrc==nullptr) transformationPath.mergePaths() ; 
     1741      else 
     1742      {   
     1743        if (srcElement.type==TYPE_DOMAIN)      transformationPath.mergePaths(srcElement.domain->getTransformationPaths()) ; 
     1744        else if (srcElement.type==TYPE_AXIS)   transformationPath.mergePaths(srcElement.axis->getTransformationPaths()) ; 
     1745        else if (srcElement.type==TYPE_SCALAR) transformationPath.mergePaths(srcElement.scalar->getTransformationPaths()) ; 
     1746      } 
     1747 
     1748      hasTransform=transformationPath.hasTransform()  ; 
     1749       
     1750      if (hasTransform && !hadTransform) 
     1751      { 
     1752        pos=i ; 
     1753        EElement dstElementType=transformationPath.getNextElementType() ; 
     1754        string dstElementId=transformationPath.getNextElementId() ; 
     1755        string srcElementId=transformationPath.getNextElementSrcId() ; 
     1756        auto transType = transformationPath.getNextTransformationType() ; 
     1757        auto transId = transformationPath.getNextTransformationId() ; 
     1758 
     1759        CGrid* tmpGridSrc=CGrid::create(); // source grid  
     1760        if (srcElement.type==TYPE_DOMAIN)      tmpGridSrc->addDomain(srcElement.domain->getId()) ; 
     1761        else if (srcElement.type==TYPE_AXIS)   tmpGridSrc->addAxis(srcElement.axis->getId()) ; 
     1762        else if (srcElement.type==TYPE_SCALAR) tmpGridSrc->addScalar(srcElement.scalar->getId()) ; 
     1763        tmpGridSrc->checkElementsAttributes() ; 
     1764        CGrid* tmpGridDst=CGrid::create(); // destination Grid 
     1765        map<int,int> posInGrid={{0,0}} ; 
     1766                
     1767        cout<<"--> New transform from "<<srcElementId<<" to "<<dstElementId<<endl ; 
     1768        if (dstElementType==EElement::DOMAIN) 
     1769        { 
     1770          CDomain* dstDomain ; 
     1771          CDomain* lastDstDomain ; 
     1772          bool isGenerate=false ; 
     1773    
     1774          do  
     1775          { 
     1776 
     1777            if (CDomain::has(dstElementId))  
     1778            { 
     1779              dstDomain = CDomain::get(dstElementId) ; 
     1780              cout<<"Retrive existing domain : "<<dstElementId<<endl ; 
     1781            } 
     1782            else 
     1783            { 
     1784              dstDomain = CDomain::create() ; 
     1785              dstDomain->createAlias(dstElementId) ; 
     1786              cout<<"Create new domain : "<<dstDomain->getId()<<" with alias : "<<dstElementId<<endl ; 
     1787 
     1788              if (isGenerate) dstDomain->duplicateAttributes(lastDstDomain) ; 
     1789              else if (srcElementId=="" && srcElement.type==TYPE_DOMAIN)  dstDomain->duplicateAttributes(srcElement.domain) ; // make a copy 
     1790              else dstDomain->duplicateAttributes(dstElement.domain) ; // make a copy 
     1791              CTransformation<CDomain>* transformation = CTransformation<CDomain>::createTransformation(transType,"") ; 
     1792              auto srcTransform = CTransformation<CDomain>::getTransformation(transType, transId) ; 
     1793              transformation->inheritFrom(srcTransform) ; 
     1794              CGrid* tmpGridDst=CGrid::create(); // destination Grid 
     1795              tmpGridDst->addDomain(dstDomain->getId()) ; 
     1796 
     1797              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0,  
     1798                                                       posInGrid,posInGrid,posInGrid, 
     1799                                                       posInGrid,posInGrid,posInGrid ); 
     1800 
     1801 
     1802              dstDomain->setTransformationAlgorithm(algo) ; 
     1803              dstDomain->setTransformationPaths(transformationPath) ; 
     1804            } 
     1805            algo=dstDomain->getTransformationAlgorithm() ; 
     1806            isGenerate = algo->isGenerateTransformation() ; 
     1807            transformationPath.removeNextTransform() ; 
     1808            dstElementId=transformationPath.getNextElementId() ; 
     1809            srcElementId=transformationPath.getNextElementSrcId() ; 
     1810            transType = transformationPath.getNextTransformationType() ; 
     1811            transId = transformationPath.getNextTransformationId() ; 
     1812            lastDstDomain=dstDomain ; 
     1813            dstDomain->setTransformationPaths(transformationPath) ; 
     1814          } while(transformationPath.hasTransform() && isGenerate) ; 
     1815 
     1816          if (isNewGrid) newGrid->addDomain(dstDomain->getId()) ; 
     1817          algo = dstDomain->getTransformationAlgorithm() ; 
     1818        } 
     1819        else if (dstElementType==EElement::AXIS) 
     1820        { 
     1821          CAxis* dstAxis ; 
     1822          CAxis* lastDstAxis ; 
     1823          bool isGenerate=false ; 
     1824 
     1825          do  
     1826          { 
     1827            if (CAxis::has(dstElementId))  
     1828            { 
     1829              dstAxis = CAxis::get(dstElementId) ; 
     1830              cout<<"Retrive existing axis : "<<dstElementId<<endl ; 
     1831            } 
     1832            else 
     1833            { 
     1834              dstAxis = CAxis::create() ; 
     1835              dstAxis->createAlias(dstElementId) ; 
     1836              cout<<"Create new axis : "<<dstAxis->getId()<<" with alias : "<<dstElementId<<endl ; 
     1837               
     1838              if (isGenerate) dstAxis->duplicateAttributes(lastDstAxis) ; 
     1839              else if (srcElementId=="" && srcElement.type==TYPE_AXIS)  dstAxis->duplicateAttributes(srcElement.axis) ; // make a copy 
     1840              else dstAxis->duplicateAttributes(dstElement.axis) ; // make a copy 
     1841              CTransformation<CAxis>* transformation = CTransformation<CAxis>::createTransformation(transType,"") ; 
     1842              auto srcTransform = CTransformation<CAxis>::getTransformation(transType, transId) ; 
     1843              transformation->inheritFrom(srcTransform) ; 
     1844              tmpGridDst->addAxis(dstAxis->getId()) ; 
     1845 
     1846              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0,  
     1847                                                      posInGrid,posInGrid,posInGrid, 
     1848                                                      posInGrid,posInGrid,posInGrid ); 
     1849 
     1850              dstAxis->setTransformationAlgorithm(algo) ; 
     1851              dstAxis->setTransformationPaths(transformationPath) ; 
     1852            } 
     1853            
     1854            algo=dstAxis->getTransformationAlgorithm() ; 
     1855            isGenerate = algo->isGenerateTransformation() ; 
     1856            transformationPath.removeNextTransform() ; 
     1857            dstElementId=transformationPath.getNextElementId() ; 
     1858            srcElementId=transformationPath.getNextElementSrcId() ; 
     1859            transType = transformationPath.getNextTransformationType() ; 
     1860            transId = transformationPath.getNextTransformationId() ; 
     1861            lastDstAxis=dstAxis ; 
     1862            dstAxis->setTransformationPaths(transformationPath) ; 
     1863          } while(transformationPath.hasTransform() && isGenerate) ; 
     1864            
     1865          if (isNewGrid) newGrid->addAxis(dstAxis->getId()) ; 
     1866          algo = dstAxis->getTransformationAlgorithm() ; 
     1867        } 
     1868        else if (dstElementType==EElement::SCALAR) 
     1869        { 
     1870          CScalar* dstScalar ; 
     1871          CScalar* lastDstScalar ; 
     1872          bool isGenerate=false ; 
     1873 
     1874          do  
     1875          { 
     1876            if (CScalar::has(dstElementId))  
     1877            { 
     1878              dstScalar = CScalar::get(dstElementId) ; 
     1879              cout<<"Retrive existing scalar : "<<dstElementId<<endl ; 
     1880            } 
     1881            else 
     1882            { 
     1883              dstScalar = CScalar::create() ; 
     1884              dstScalar->createAlias(dstElementId) ; 
     1885              cout<<"Create new scalar : "<<dstScalar->getId()<<" with alias : "<<dstElementId<<endl ; 
     1886               
     1887              if (isGenerate) dstScalar->duplicateAttributes(lastDstScalar) ; 
     1888              else if (srcElementId=="" && srcElement.type==TYPE_SCALAR)  dstScalar->duplicateAttributes(srcElement.scalar) ; // make a copy 
     1889              else dstScalar->duplicateAttributes(dstElement.scalar) ; // make a copy 
     1890              CTransformation<CScalar>* transformation = CTransformation<CScalar>::createTransformation(transType,"") ; 
     1891              auto srcTransform = CTransformation<CScalar>::getTransformation(transType, transId) ; 
     1892              transformation->inheritFrom(srcTransform) ; 
     1893              tmpGridDst->addScalar(dstScalar->getId()) ; 
     1894 
     1895              algo = transformation -> createAlgorithm(false, tmpGridDst, tmpGridSrc, 0,  
     1896                                                       posInGrid,posInGrid,posInGrid, 
     1897                                                       posInGrid,posInGrid,posInGrid ); 
     1898               
     1899              dstScalar->setTransformationAlgorithm(algo) ; 
     1900              dstScalar->setTransformationPaths(transformationPath) ; 
     1901            } 
     1902            algo=dstScalar->getTransformationAlgorithm() ; 
     1903            isGenerate = algo->isGenerateTransformation() ; 
     1904            transformationPath.removeNextTransform() ; 
     1905            dstElementId=transformationPath.getNextElementId() ; 
     1906            srcElementId=transformationPath.getNextElementSrcId() ; 
     1907            transType = transformationPath.getNextTransformationType() ; 
     1908            transId = transformationPath.getNextTransformationId() ; 
     1909            lastDstScalar=dstScalar ; 
     1910            dstScalar->setTransformationPaths(transformationPath) ; 
     1911          } while(transformationPath.hasTransform() && isGenerate) ; 
     1912 
     1913          if (isNewGrid) newGrid->addScalar(dstScalar->getId()) ; 
     1914          algo = dstScalar->getTransformationAlgorithm() ;           
     1915        } 
     1916        // here create a new spatial filter with algo 
     1917         
     1918        hadTransform=true ; 
     1919        hasTransform=false ;  
     1920      } 
     1921      else 
     1922      { 
     1923        string srcElementId=transformationPath.getNextElementSrcId() ; 
     1924 
     1925        if (srcElement.type==TYPE_DOMAIN)       
     1926        { 
     1927          CDomain* domain ; 
     1928          if (srcElementId=="") srcElementId=srcElement.domain->getId() ;  
     1929          if (!CDomain::has(srcElementId))  
     1930          { 
     1931            domain=srcElement.domain ; 
     1932            domain->createAlias(srcElementId) ; 
     1933          } 
     1934          else domain = CDomain::get(srcElementId) ; 
     1935          domain->checkAttributes() ; 
     1936          
     1937          if (isNewGrid) newGrid->addDomain(srcElementId) ; 
     1938        } 
     1939        else if (srcElement.type==TYPE_AXIS) 
     1940        {    
     1941          CAxis* axis ; 
     1942          if (srcElementId=="") srcElementId=srcElement.axis->getId() ;  
     1943          if (!CAxis::has(srcElementId))  
     1944          { 
     1945            axis=srcElement.axis ; 
     1946            axis->createAlias(srcElementId) ; 
     1947          } 
     1948          else axis = CAxis::get(srcElementId) ; 
     1949          axis->checkAttributes() ; 
     1950          
     1951          if (isNewGrid) newGrid->addAxis(srcElementId) ; 
     1952        } 
     1953        else if (srcElement.type==TYPE_SCALAR) 
     1954        { 
     1955          CScalar* scalar ; 
     1956          if (srcElementId=="") srcElementId=srcElement.scalar->getId() ;  
     1957          if (!CScalar::has(srcElementId))  
     1958          { 
     1959            scalar=srcElement.scalar ; 
     1960            scalar->createAlias(srcElementId) ; 
     1961          } 
     1962          else scalar = CScalar::get(srcElementId) ; 
     1963          scalar->checkAttributes() ; 
     1964          
     1965          if (isNewGrid) newGrid->addScalar(srcElementId) ; 
     1966        } 
     1967      } 
     1968       
     1969      if (transformationPath.hasTransform() && hadTransform) hasRemainTransform=true ; 
     1970    }   
     1971     
     1972 
     1973    if (hadTransform) 
     1974    { 
     1975       
     1976      if (!isSource) 
     1977      { 
     1978        CGridAlgorithm* gridAlgorithm  ; 
     1979        if (isNewGrid) 
     1980        {  
     1981          gridAlgorithm = algo->createGridAlgorithm(gridSrc, newGrid, pos) ; 
     1982          newGrid->setGridAlgorithm(gridAlgorithm); 
     1983        } 
     1984        else gridAlgorithm = newGrid->getGridAlgorithm() ; 
     1985 
     1986        shared_ptr<CTransformFilter> transformFilter = shared_ptr<CTransformFilter>(gridAlgorithm->createTransformFilter(gc, detectMissingValues, defaultValue)) ; 
     1987        outputFilter->connectOutput(transformFilter,0) ; 
     1988        vector<string> auxFieldId = algo->getAuxFieldId() ; // better to do that at transformation not algo ?? 
     1989        int i=1;  
     1990        for (auto& it : auxFieldId) 
     1991        { 
     1992          CField* auxField = CField::get(it) ; 
     1993          auxField->buildWorkflowGraph(gc) ; 
     1994          auxField->getInstantDataFilter()->connectOutput(transformFilter,i) ; 
     1995          i++ ; 
     1996        } 
     1997        outputFilter = transformFilter ; 
     1998      } 
     1999 
     2000      if (hasRemainTransform) 
     2001      { 
     2002        gridSrc=newGrid ; 
     2003        pair<shared_ptr<CFilter>, shared_ptr<CFilter> > filters = this->buildTransformationGraph(gc, isSource, gridSrc, detectMissingValues, defaultValue, newGrid) ; 
     2004        outputFilter->connectOutput(filters.first,0) ; 
     2005        outputFilter=filters.second ; 
     2006      } 
     2007    } 
     2008      
     2009    return {inputFilter,outputFilter} ; 
    22952010  } 
    22962011  CATCH_DUMP_ATTR 
    22972012 
    2298   CGridTransformation* CGrid::getTransformations() 
    2299   TRY 
    2300   { 
    2301     return transformations_; 
    2302   } 
    2303   CATCH_DUMP_ATTR 
    2304  
    2305   void CGrid::addTransGridSource(CGrid* gridSrc) 
    2306   TRY 
    2307   { 
    2308     if (gridSrc_.end() == gridSrc_.find(gridSrc)) 
    2309       gridSrc_.insert(make_pair(gridSrc,make_pair(false,""))); 
    2310   } 
    2311   CATCH_DUMP_ATTR 
    2312  
    2313   std::map<CGrid*,std::pair<bool,StdString> >& CGrid::getTransGridSource() 
    2314   TRY 
    2315   { 
    2316     return gridSrc_; 
    2317   } 
    2318   CATCH_DUMP_ATTR 
    2319  
    2320   /*! 
    2321      Complete all the necessary (and lacking) attributes of a grid 
    2322      This function is similar to gridTransformation but works only (till now) on generate_rectilinear_domain transformation 
    2323   */ 
    2324   void CGrid::completeGrid(CGrid* transformGridSrc) 
    2325   TRY 
    2326   { 
    2327     if (0 != transformGridSrc) 
    2328     { 
    2329       if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements()) 
    2330       { 
    2331         ERROR("CGrid::completeGrid(CGrid* transformGridSrc)", 
    2332              << "Two grids have different number of elements. " << std::endl 
    2333              << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl 
    2334              << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements()); 
    2335       } 
    2336     } 
    2337  
    2338     if (isGenerated()) return; 
    2339     setGenerated(); 
    2340  
    2341     CGridGenerate gridGenerate(this, transformGridSrc); 
    2342     gridGenerate.completeGrid(); 
    2343   } 
    2344   CATCH_DUMP_ATTR 
    2345  
    2346   bool CGrid::isGenerated() 
    2347   TRY 
    2348   { 
    2349     return isGenerated_; 
    2350   } 
    2351   CATCH 
    2352  
    2353   void CGrid::setGenerated() 
    2354   TRY 
    2355   { 
    2356     isGenerated_ = true; 
    2357   } 
    2358   CATCH_DUMP_ATTR 
    2359  
    2360   void CGrid::transformGrid(CGrid* transformGridSrc) 
    2361   TRY 
    2362   { 
    2363     if (!transformGridSrc) 
    2364       ERROR("CGrid::transformGrid(CGrid* transformGridSrc)", 
    2365             << "Impossible to transform grid '" << getId() << "', the source grid is null."); 
    2366  
    2367     if (isTransformed()) return; 
    2368     setTransformed(); 
    2369     if (axis_domain_order.numElements() != transformGridSrc->axis_domain_order.numElements()) 
    2370     { 
    2371       ERROR("CGrid::transformGrid(CGrid* transformGridSrc)", 
    2372            << "Two grids have different number of elements. " << std::endl 
    2373            << "Number of element of grid destination " << this->getId() << " is " << axis_domain_order.numElements() << std::endl 
    2374            << "Number of element of grid source " << transformGridSrc->getId() << " is " << transformGridSrc->axis_domain_order.numElements()); 
    2375     } 
     2013 
     2014//**************************************************************** 
     2015//**************************************************************** 
     2016 
     2017//---------------------------------------------------------------- 
     2018 
     2019  CGrid* CGrid::duplicateSentGrid(void) 
     2020  { 
     2021    CGrid* newGrid ; 
     2022    string sentGridId="sent__"+getId() ; 
     2023    if (has(sentGridId)) newGrid = get(sentGridId) ; 
    23762024    else 
    23772025    { 
    2378     } 
    2379  
    2380     transformations_ = new CGridTransformation(this, transformGridSrc); 
    2381     transformations_->computeAll(); 
    2382     if (0 < transformations_->getNbAlgo()) hasTransform_ = true; 
    2383  
    2384     // Ok, now need to compute index of grid source 
    2385     transformGridSrc->checkMaskIndex(false); 
    2386   } 
    2387   CATCH_DUMP_ATTR 
    2388  
    2389   bool CGrid::hasTransform() 
    2390   TRY 
    2391   { 
    2392     if (hasTransform_) return hasTransform_; 
    2393  
    2394     std::vector<CDomain*> domList = getDomains(); 
    2395     std::vector<CAxis*> axisList = getAxis(); 
    2396     std::vector<CScalar*> scalarList = getScalars(); 
    2397  
    2398     for (int idx = 0; idx < domList.size(); ++idx) hasTransform_ |= domList[idx]->hasTransformation(); 
    2399     for (int idx = 0; idx < axisList.size(); ++idx) hasTransform_ |= axisList[idx]->hasTransformation(); 
    2400     for (int idx = 0; idx < scalarList.size(); ++idx) hasTransform_ |= scalarList[idx]->hasTransformation(); 
    2401  
    2402     return hasTransform_; 
    2403   } 
    2404   CATCH_DUMP_ATTR 
    2405  
    2406   /*! 
    2407   \brief Get the list of domain pointers 
    2408   \return list of domain pointers 
    2409   */ 
    2410   std::vector<CDomain*> CGrid::getDomains() 
    2411   TRY 
    2412   { 
    2413     std::vector<CDomain*> domList; 
    2414     if (!domList_.empty()) 
    2415     { 
    2416       for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i])); 
    2417     } 
    2418     return domList; 
    2419   } 
    2420   CATCH_DUMP_ATTR 
    2421  
    2422   /*! 
    2423   \brief Get the list of  axis pointers 
    2424   \return list of axis pointers 
    2425   */ 
    2426   std::vector<CAxis*> CGrid::getAxis() 
    2427   TRY 
    2428   { 
    2429     std::vector<CAxis*> aList; 
    2430     if (!axisList_.empty()) 
    2431       for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i])); 
    2432  
    2433     return aList; 
    2434   } 
    2435   CATCH_DUMP_ATTR 
    2436  
    2437   /*! 
    2438   \brief Get the list of  axis pointers 
    2439   \return list of axis pointers 
    2440   */ 
    2441   std::vector<CScalar*> CGrid::getScalars() 
    2442   TRY 
    2443   { 
    2444     std::vector<CScalar*> sList; 
    2445     if (!scalarList_.empty()) 
    2446       for (int i =0; i < scalarList_.size(); ++i) sList.push_back(CScalar::get(scalarList_[i])); 
    2447  
    2448     return sList; 
    2449   } 
    2450   CATCH_DUMP_ATTR 
    2451  
    2452   /*! 
    2453   \brief Get domain pointer with index 
    2454   \return domain pointer 
    2455   */ 
    2456   CDomain* CGrid::getDomain(int domainIndex) 
    2457   TRY 
    2458   { 
    2459     std::vector<CDomain*> domainListP = this->getDomains(); 
    2460     if (domainListP.empty()) 
    2461     { 
    2462       ERROR("CGrid::getDomain(int domainIndex)", 
    2463             << "No domain associated to this grid. " << std::endl 
    2464             << "Grid id = " << this->getId()); 
    2465     } 
    2466  
    2467     if (domainIndex >= domainListP.size() || (domainIndex < 0)) 
    2468       ERROR("CGrid::getDomain(int domainIndex)", 
    2469             << "Domain with the index doesn't exist " << std::endl 
    2470             << "Grid id = " << this->getId() << std::endl 
    2471             << "Grid has only " << domainListP.size() << " domain but domain index required is " << domainIndex << std::endl); 
    2472  
    2473     return domainListP[domainIndex]; 
    2474   } 
    2475   CATCH_DUMP_ATTR 
    2476  
    2477   /*! 
    2478   \brief Get the axis pointer with index 
    2479   \return axis pointer 
    2480   */ 
    2481   CAxis* CGrid::getAxis(int axisIndex) 
    2482   TRY 
    2483   { 
    2484     std::vector<CAxis*> axisListP = this->getAxis(); 
    2485     if (axisListP.empty()) 
    2486     { 
    2487       ERROR("CGrid::getDomain(int axisIndex)", 
    2488             << "No axis associated to this grid. " << std::endl 
    2489             << "Grid id = " << this->getId()); 
    2490     } 
    2491  
    2492     if (axisIndex >= axisListP.size() || (axisIndex < 0)) 
    2493       ERROR("CGrid::getDomain(int axisIndex)", 
    2494             << "Domain with the index doesn't exist " << std::endl 
    2495             << "Grid id = " << this->getId() << std::endl 
    2496             << "Grid has only " << axisListP.size() << " axis but axis index required is " << axisIndex << std::endl); 
    2497  
    2498     return axisListP[axisIndex]; 
    2499   } 
    2500   CATCH_DUMP_ATTR 
    2501  
    2502   /*! 
    2503   \brief Get the a scalar pointer 
    2504   \return scalar pointer 
    2505   */ 
    2506   CScalar* CGrid::getScalar(int scalarIndex) 
    2507   TRY 
    2508   { 
    2509     std::vector<CScalar*> scalarListP = this->getScalars(); 
    2510     if (scalarListP.empty()) 
    2511     { 
    2512       ERROR("CGrid::getScalar(int scalarIndex)", 
    2513             << "No scalar associated to this grid. " << std::endl 
    2514             << "Grid id = " << this->getId()); 
    2515     } 
    2516  
    2517     if (scalarIndex >= scalarListP.size() || (scalarIndex < 0)) 
    2518       ERROR("CGrid::getScalar(int scalarIndex)", 
    2519             << "Scalar with the index doesn't exist " << std::endl 
    2520             << "Grid id = " << this->getId() << std::endl 
    2521             << "Grid has only " << scalarListP.size() << " scalar but scalar index required is " << scalarIndex << std::endl); 
    2522  
    2523     return scalarListP[scalarIndex]; 
    2524   } 
    2525   CATCH_DUMP_ATTR 
    2526  
    2527   /*! 
    2528   \brief Set domain(s) of a grid from a list 
    2529   \param[in] domains list of domains 
    2530   */ 
    2531   void CGrid::setDomainList(const std::vector<CDomain*> domains) 
    2532   TRY 
    2533   { 
    2534     if (isDomListSet) return; 
    2535     std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 
    2536     if (!domains.empty() && domList.empty()) 
    2537     { 
    2538       for (int i = 0; i < domains.size(); ++i) 
    2539         this->getVirtualDomainGroup()->addChild(domains[i]); 
    2540       domList = this->getVirtualDomainGroup()->getAllChildren(); 
    2541     } 
    2542  
    2543     if (!domList.empty()) 
    2544     { 
    2545       int sizeDom = domList.size(); 
    2546       domList_.resize(sizeDom); 
    2547       for (int i = 0; i < sizeDom; ++i) 
    2548       { 
    2549         domList_[i] = domList[i]->getId(); 
    2550       } 
    2551       isDomListSet = true; 
    2552     } 
    2553   } 
    2554   CATCH_DUMP_ATTR 
    2555  
    2556   /*! 
    2557   \brief Set axis(s) of a grid from a list 
    2558   \param[in] axis list of axis 
    2559   */ 
    2560   void CGrid::setAxisList(const std::vector<CAxis*> axis) 
    2561   TRY 
    2562   { 
    2563     if (isAxisListSet) return; 
    2564     std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 
    2565     if (!axis.empty() && aList.empty()) 
    2566     { 
    2567       for (int i = 0; i < axis.size(); ++i) 
    2568         this->getVirtualAxisGroup()->addChild(axis[i]); 
    2569       aList = this->getVirtualAxisGroup()->getAllChildren(); 
    2570     } 
    2571  
    2572     if (!aList.empty()) 
    2573     { 
    2574       int sizeAxis = aList.size(); 
    2575       axisList_.resize(sizeAxis); 
    2576       for (int i = 0; i < sizeAxis; ++i) 
    2577       { 
    2578         axisList_[i] = aList[i]->getId(); 
    2579       } 
    2580       isAxisListSet = true; 
    2581     } 
    2582   } 
    2583   CATCH_DUMP_ATTR 
    2584  
    2585   /*! 
    2586   \brief Set scalar(s) of a grid from a list 
    2587   \param[in] scalars list of scalars 
    2588   */ 
    2589   void CGrid::setScalarList(const std::vector<CScalar*> scalars) 
    2590   TRY 
    2591   { 
    2592     if (isScalarListSet) return; 
    2593     std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 
    2594     if (!scalars.empty() && sList.empty()) 
    2595     { 
    2596       for (int i = 0; i < scalars.size(); ++i) 
    2597         this->getVirtualScalarGroup()->addChild(scalars[i]); 
    2598       sList = this->getVirtualScalarGroup()->getAllChildren(); 
    2599     } 
    2600  
    2601     if (!sList.empty()) 
    2602     { 
    2603       int sizeScalar = sList.size(); 
    2604       scalarList_.resize(sizeScalar); 
    2605       for (int i = 0; i < sizeScalar; ++i) 
    2606       { 
    2607         scalarList_[i] = sList[i]->getId(); 
    2608       } 
    2609       isScalarListSet = true; 
    2610     } 
    2611   } 
    2612   CATCH_DUMP_ATTR 
    2613  
    2614   /*! 
    2615   \brief Get list of id of domains 
    2616   \return id list of domains 
    2617   */ 
    2618   std::vector<StdString> CGrid::getDomainList() 
    2619   TRY 
    2620   { 
    2621     setDomainList(); 
    2622     return domList_; 
    2623   } 
    2624   CATCH 
    2625  
    2626   /*! 
    2627   \brief Get list of id of axis 
    2628   \return id list of axis 
    2629   */ 
    2630   std::vector<StdString> CGrid::getAxisList() 
    2631   TRY 
    2632   { 
    2633     setAxisList(); 
    2634     return axisList_; 
    2635   } 
    2636   CATCH 
    2637  
    2638   /*! 
    2639   \brief Get list of id of scalar 
    2640   \return id list of scalar 
    2641   */ 
    2642   std::vector<StdString> CGrid::getScalarList() 
    2643   TRY 
    2644   { 
    2645     setScalarList(); 
    2646     return scalarList_; 
    2647   } 
    2648   CATCH 
    2649  
    2650   /*! 
    2651     Send all attributes of domains from client to server 
    2652   */ 
    2653   void CGrid::sendAllDomains() 
    2654   TRY 
    2655   { 
    2656     std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren(); 
    2657     int dSize = domList.size(); 
    2658     for (int i = 0; i < dSize; ++i) 
    2659     { 
    2660       sendAddDomain(domList[i]->getId()); 
    2661       domList[i]->sendAllAttributesToServer(); 
    2662     } 
    2663   } 
    2664   CATCH_DUMP_ATTR 
    2665  
    2666   /*! 
    2667     Send all attributes of axis from client to server 
    2668   */ 
    2669   void CGrid::sendAllAxis() 
    2670   TRY 
    2671   { 
    2672     std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren(); 
    2673     int aSize = aList.size(); 
    2674  
    2675     for (int i = 0; i < aSize; ++i) 
    2676     { 
    2677       sendAddAxis(aList[i]->getId()); 
    2678       aList[i]->sendAllAttributesToServer(); 
    2679     } 
    2680   } 
    2681   CATCH_DUMP_ATTR 
    2682  
    2683   /*! 
    2684     Send all attributes of scalars from client to server 
    2685   */ 
    2686   void CGrid::sendAllScalars() 
    2687   TRY 
    2688   { 
    2689     std::vector<CScalar*> sList = this->getVirtualScalarGroup()->getAllChildren(); 
    2690     int sSize = sList.size(); 
    2691  
    2692     for (int i = 0; i < sSize; ++i) 
    2693     { 
    2694       sendAddScalar(sList[i]->getId()); 
    2695       sList[i]->sendAllAttributesToServer(); 
    2696     } 
    2697   } 
    2698   CATCH_DUMP_ATTR 
     2026      newGrid = CGrid::create(sentGridId) ; 
     2027      for(auto element : elements_) 
     2028      { 
     2029        if (element.type==TYPE_DOMAIN)       
     2030        { 
     2031          CDomain* domain = CDomain::create(); 
     2032          domain->duplicateAttributes(element.domain) ; 
     2033          domain->name = element.domain->getId() ; 
     2034          newGrid->addDomain(domain->getId()) ; 
     2035        } 
     2036        else if (element.type==TYPE_AXIS)       
     2037        { 
     2038          CAxis* axis = CAxis::create(); 
     2039          axis->duplicateAttributes(element.axis) ; 
     2040          axis->name = element.axis->getId() ; 
     2041          newGrid->addAxis(axis->getId()) ; 
     2042        } 
     2043        else if (element.type==TYPE_SCALAR)       
     2044        { 
     2045          CScalar* scalar = CScalar::create(); 
     2046          scalar->duplicateAttributes(element.scalar) ; 
     2047          scalar->name = element.scalar->getId() ; 
     2048          newGrid->addScalar(scalar->getId()) ; 
     2049        } 
     2050      } 
     2051      newGrid->checkElementsAttributes() ; 
     2052    } 
     2053    return newGrid ; 
     2054  } 
     2055 
    26992056 
    27002057  void CGrid::setContextClient(CContextClient* contextClient) 
     
    27062063      clientsSet.insert(contextClient); 
    27072064    } 
    2708     for (int i=0; i<this->getDomains().size(); i++) 
    2709         this->getDomains()[i]->setContextClient(contextClient); 
    2710     for (int i=0; i<this->getAxis().size(); i++) 
    2711         this->getAxis()[i]->setContextClient(contextClient); 
     2065    for (auto domain : getDomains()) domain->setContextClient(contextClient); 
     2066    for (auto axis : getAxis()) axis->setContextClient(contextClient); 
     2067    for (auto scalar : getScalars()) scalar->setContextClient(contextClient); 
     2068    
    27122069  } 
    27132070  CATCH_DUMP_ATTR 
    27142071 
    2715   /*! 
    2716     Parse a grid, for now, it contains only domain, axis and scalar 
    2717   */ 
    2718   void CGrid::parse(xml::CXMLNode& node) 
    2719   TRY 
    2720   { 
    2721     SuperClass::parse(node); 
    2722  
    2723     if (node.goToChildElement()) 
    2724     { 
    2725       StdString domainName("domain"); 
    2726       StdString axisName("axis"); 
    2727       StdString scalarName("scalar"); 
    2728       do 
    2729       { 
    2730         if (node.getElementName() == domainName) { 
    2731           order_.push_back(2); 
    2732           this->getVirtualDomainGroup()->parseChild(node); 
    2733         } 
    2734         if (node.getElementName() == axisName) { 
    2735           order_.push_back(1); 
    2736           this->getVirtualAxisGroup()->parseChild(node); 
    2737         } 
    2738         if (node.getElementName() == scalarName) { 
    2739           order_.push_back(0); 
    2740           this->getVirtualScalarGroup()->parseChild(node); 
    2741         } 
    2742       } while (node.goToNextElement()); 
    2743       node.goToParentElement(); 
    2744     } 
    2745  
    2746     if (!order_.empty()) 
    2747     { 
    2748       int sizeOrd = order_.size(); 
    2749       axis_domain_order.resize(sizeOrd); 
    2750       for (int i = 0; i < sizeOrd; ++i) 
    2751       { 
    2752         axis_domain_order(i) = order_[i]; 
    2753       } 
    2754     } 
    2755  
    2756     setDomainList(); 
    2757     setAxisList(); 
    2758     setScalarList(); 
    2759    } 
    2760   CATCH_DUMP_ATTR 
    2761  
     2072  
     2073  void CGrid::computeGridLocalElements() 
     2074  { 
     2075    std::vector<CDomain*> domainList = this->getDomains(); 
     2076    std::vector<CAxis*> axisList = this->getAxis(); 
     2077    std::vector<CScalar*> scalarList = this->getScalars(); 
     2078    auto domain=domainList.begin() ; 
     2079    auto axis=axisList.begin() ; 
     2080    auto scalar=scalarList.begin() ; 
     2081    vector<CLocalElement*> elements; 
     2082    for(auto order : order_) 
     2083    { 
     2084      if (order==2)  
     2085      { 
     2086        elements.push_back((*domain)->getLocalElement()); 
     2087        domain++ ; 
     2088      } 
     2089      else if (order==1) 
     2090      { 
     2091        elements.push_back((*axis)->getLocalElement()); 
     2092        axis++ ; 
     2093      } 
     2094      else if (order==0) 
     2095      {  
     2096        elements.push_back((*scalar)->getLocalElement()); 
     2097        scalar++ ; 
     2098      } 
     2099    } 
     2100    if (hasMask())  
     2101    { 
     2102      vector<bool> mask(getMask().getVector()) ; 
     2103      gridLocalElements_ = new CGridLocalElements(elements, mask) ;   
     2104    } 
     2105    else gridLocalElements_ = new CGridLocalElements(elements) ;   
     2106  } 
     2107 
     2108  void CGrid::computeModelToWorkflowConnector(void) 
     2109  { 
     2110    modelToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::MODEL,CElementView::WORKFLOW,true) ; 
     2111  } 
     2112 
     2113  void CGrid::computeWorkflowToFullConnector(void) 
     2114  { 
     2115    workflowToFullConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::FULL) ; 
     2116  } 
     2117 
     2118  void CGrid::computeWorkflowToModelConnector(void) 
     2119  { 
     2120    workflowToModelConnector_ = getGridLocalElements()->getConnector(CElementView::WORKFLOW,CElementView::MODEL,true) ; 
     2121  } 
     2122 
     2123  void CGrid::computeFullToWorkflowConnector(void) 
     2124  { 
     2125    fullToWorkflowConnector_ = getGridLocalElements()->getConnector(CElementView::FULL,CElementView::WORKFLOW) ; 
     2126  } 
     2127 
     2128  void CGrid::computeServerFromClientConnector(void) 
     2129  { 
     2130    vector<CGathererConnector*> connectors ; 
     2131    for(auto& element : getElements()) 
     2132    { 
     2133      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ; 
     2134      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ;  
     2135      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ;  
     2136    } 
     2137    serverFromClientConnector_ = new CGridGathererConnector(connectors) ; 
     2138  } 
     2139 
     2140  void CGrid::computeServerToClientConnector(void) 
     2141  { 
     2142    vector<CScattererConnector*> connectors ; 
     2143    for(auto& element : getElements()) 
     2144    { 
     2145      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerToClientConnector()) ; 
     2146      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerToClientConnector()) ;  
     2147      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerToClientConnector()) ;  
     2148    } 
     2149    serverToClientConnector_ = new CGridScattererConnector(connectors) ; 
     2150  } 
     2151 
     2152  void CGrid::computeClientFromClientConnector(void) 
     2153  { 
     2154    vector<CGathererConnector*> connectors ; 
     2155    for(auto& element : getElements()) 
     2156    { 
     2157      if (element.type==TYPE_DOMAIN) connectors.push_back(element.domain->getServerFromClientConnector()) ; 
     2158      else if (element.type==TYPE_AXIS) connectors.push_back(element.axis->getServerFromClientConnector()) ;  
     2159      else if (element.type==TYPE_SCALAR) connectors.push_back(element.scalar->getServerFromClientConnector()) ;  
     2160    } 
     2161    clientFromClientConnector_ = new CGridGathererConnector(connectors) ; 
     2162  } 
     2163 
     2164   
    27622165} // namespace xios 
Note: See TracChangeset for help on using the changeset viewer.