source: XIOS3/dev/XIOS_ATTACHED/src/transformation/domain_algorithm/domain_algorithm_redistribute.cpp @ 2482

Last change on this file since 2482 was 2482, checked in by ymipsl, 15 months ago

First guess in supression of attached mode replaced by online reader and write filters

YM

  • Property svn:executable set to *
File size: 11.4 KB
Line 
1/*!
2   \file domain_algorithm_redistribute.cpp
3   \brief Algorithm for redistribute a domain.
4 */
5#include "domain_algorithm_redistribute.hpp"
6#include "redistribute_domain.hpp"
7#include "domain.hpp"
8#include "grid.hpp"
9#include "grid_transformation_factory_impl.hpp"
10#include "context.hpp"
11
12namespace xios
13{
14
15  shared_ptr<CGenericAlgorithmTransformation> CDomainAlgorithmRedistribute::create(bool isSource, CGrid* gridDst, CGrid* gridSrc,
16                                                               CTransformation<CDomain>* transformation,
17                                                               int elementPositionInGrid,
18                                                               std::map<int, int>& elementPositionInGridSrc2ScalarPosition,
19                                                               std::map<int, int>& elementPositionInGridSrc2AxisPosition,
20                                                               std::map<int, int>& elementPositionInGridSrc2DomainPosition, 
21                                                               std::map<int, int>& elementPositionInGridDst2ScalarPosition,
22                                                               std::map<int, int>& elementPositionInGridDst2AxisPosition,
23                                                               std::map<int, int>& elementPositionInGridDst2DomainPosition)
24  TRY
25  {
26    std::vector<CDomain*> domainListDestP = gridDst->getDomains();
27    std::vector<CDomain*> domainListSrcP  = gridSrc->getDomains();
28
29    CRedistributeDomain* redistributeDomain = dynamic_cast<CRedistributeDomain*> (transformation);
30    int domainDstIndex = elementPositionInGridDst2DomainPosition[elementPositionInGrid];
31    int domainSrcIndex = elementPositionInGridSrc2DomainPosition[elementPositionInGrid];
32
33    return make_shared<CDomainAlgorithmRedistribute>(isSource, domainListDestP[domainDstIndex], domainListSrcP[domainSrcIndex], redistributeDomain);
34  }
35  CATCH
36
37  bool CDomainAlgorithmRedistribute::dummyRegistered_ = CDomainAlgorithmRedistribute::registerTrans();
38  bool CDomainAlgorithmRedistribute::registerTrans()
39  TRY
40  {
41    return CGridTransformationFactory<CDomain>::registerTransformation(TRANS_REDISTRIBUTE_DOMAIN, create);
42  }
43  CATCH
44
45  CDomainAlgorithmRedistribute::CDomainAlgorithmRedistribute(bool isSource, CDomain* domainDestination, CDomain* domainSource, CRedistributeDomain* redistributeDomain)
46  : CAlgorithmTransformationTransfer(isSource)
47  TRY
48  {
49     CContext* context = CContext::getCurrent(); 
50   // Reset geometrical attributes to avoid incompatible (user/domainSource) attributs
51   //   attributs will be defined using domainSource and/or transformation attributs
52    domainDestination->type.reset();
53    domainDestination->ni_glo.reset();
54    domainDestination->nj_glo.reset();
55   
56    domainDestination->i_index.reset();   // defined using domainSource->getLocalElement()
57    domainDestination->j_index.reset();   // "
58    domainDestination->ibegin.reset();    // will be computed in domainDestination->checkDomain() (from checkAttributes())
59    domainDestination->ni.reset();        // "
60    domainDestination->jbegin.reset();    // "
61    domainDestination->nj.reset();        // "
62   
63    domainDestination->mask_1d.reset();   // defined scanning domainSource->getFullView() & domainSource->getWorkflowView() differencies
64    domainDestination->mask_2d.reset();   //   in all case domainDestination->mask_1d used as reference 
65
66    // domainDestination->data_* attributes will be computed in :
67    domainDestination->data_dim.reset();     // domainDestination->checkDomainData() (from checkAttributes())
68    domainDestination->data_ni.reset();
69    domainDestination->data_nj.reset();
70    domainDestination->data_ibegin.reset();
71    domainDestination->data_jbegin.reset();
72    domainDestination->data_i_index.reset(); // domainDestination->checkCompression() (from checkAttributes())
73    domainDestination->data_j_index.reset();
74
75    // Next attributes will be set using domainSource->attributes
76    domainDestination->lonvalue_1d.reset();
77    domainDestination->latvalue_1d.reset();
78    domainDestination->lonvalue_2d.reset();
79    domainDestination->latvalue_2d.reset();
80    domainDestination->nvertex.reset();
81    domainDestination->bounds_lon_1d.reset();
82    domainDestination->bounds_lat_1d.reset();
83    domainDestination->bounds_lon_2d.reset();
84    domainDestination->bounds_lat_2d.reset();
85    domainDestination->area.reset();
86    domainDestination->radius.reset();
87
88    auto& index = redistributeDomain-> index ;
89   
90    domainDestination->type = domainSource->type ;
91    domainDestination-> ni_glo = domainSource-> ni_glo ;
92    domainDestination-> nj_glo = domainSource-> nj_glo ;
93   
94    CArray<size_t,1> globalIndex ;
95    int start_i, start_j ;
96    int size_i, size_j ;
97    int ni_glo = domainDestination-> ni_glo ;
98    int nj_glo = domainDestination-> nj_glo ;
99   
100       
101    if (redistributeDomain->type == CRedistributeDomain::type_attr::index)
102    {   
103      globalIndex.resize(index.numElements()) ;
104      globalIndex=index ;
105    }
106    else
107    {
108     
109      auto distType = CRedistributeDomain::type_attr::column ;
110     
111      if (redistributeDomain->type == CRedistributeDomain::type_attr::bands && domainDestination->type == CDomain::type_attr::unstructured) 
112        distType = CRedistributeDomain::type_attr::column ;
113      else  distType=redistributeDomain->type;
114
115      if (distType==CRedistributeDomain::type_attr::bands) // Bands distribution to send to file server
116      {
117        int nbClient = context->getIntraCommSize() ;
118        int rankClient = context->getIntraCommRank() ;
119     
120        int size = nj_glo/nbClient ;
121        int start ;
122        if (rankClient < nj_glo % nbClient)
123        {
124         size++ ;
125         start = rankClient*size ;
126        }
127        else start = (nj_glo % nbClient)*(size+1) + (rankClient-(nj_glo % nbClient)) * size ;
128
129        size_i=ni_glo ; start_i=0 ;
130        size_j=size ; start_j=start ;
131      }
132      else if (distType==CRedistributeDomain::type_attr::column) // Bands distribution to send to file server
133      {
134        int nbClient = context->getIntraCommSize() ;
135        int rankClient = context->getIntraCommRank() ;
136     
137        int size = ni_glo/nbClient ;
138        int start ;
139
140        if (rankClient < ni_glo % nbClient)
141        {
142         size++ ;
143         start = rankClient*size ;
144        }
145        else start = (ni_glo % nbClient)*(size+1) + (rankClient-(ni_glo % nbClient)) * size ;
146
147        size_i=size ; start_i=start ;
148        size_j=nj_glo ; start_j=0 ;
149      }
150      else if (distType==CRedistributeDomain::type_attr::full) // domain is not distributed ie all servers get the same local domain
151      {
152        size_i=ni_glo ; start_i=0 ;
153        size_j=nj_glo ; start_j=0 ;
154      }
155      else if (distType==CRedistributeDomain::type_attr::root) // domain is not distributed ie all servers get the same local domain
156      {
157        if (context->getIntraCommRank()==0)
158        {
159          size_i=ni_glo ; start_i=0 ;
160          size_j=nj_glo ; start_j=0 ;
161        }
162        else
163        {
164          size_i=0 ; start_i=0 ;
165          size_j=0 ; start_j=0 ;
166        } 
167      }
168      globalIndex.resize(size_i*size_j) ;
169      size_t ind ;
170      ind=0 ;
171      for(int j=start_j;j<start_j+size_j;j++)
172        for(int i=start_i;i<start_i+size_i;i++)
173        {
174         globalIndex(ind) =  j*ni_glo+i ;
175         ind++ ;
176        }
177    }
178
179
180    //domainDestination->ni = globalIndex.numElements() ;
181    //domainDestination->nj = 1 ;
182    domainDestination->i_index.resize(globalIndex.numElements()) ;
183    domainDestination->i_index = globalIndex ;
184    domainDestination->j_index.resize(globalIndex.numElements()) ;
185    domainDestination->j_index = 0 ;
186   
187    if (!domainSource->nvertex.isEmpty()) domainDestination->nvertex=domainSource->nvertex ;
188    if (!domainSource->radius.isEmpty()) domainDestination->radius = domainSource->radius ;
189   
190
191    auto& transMap = this->transformationMapping_;
192    for(int i=0; i<globalIndex.numElements(); i++) transMap[globalIndex(i)]=globalIndex(i) ;
193   
194    auto elementDst=shared_ptr<CLocalElement>(new CLocalElement(context->getIntraCommRank(),domainDestination-> ni_glo*domainDestination->nj_glo, globalIndex)) ;
195    elementDst->addFullView() ;
196
197    auto transformConnector = make_shared<CTransformConnector>(domainSource->getLocalView(CElementView::FULL), elementDst->getView(CElementView::FULL),context->getIntraComm()) ;
198    transformConnector->computeConnector() ;
199
200    if (domainSource->hasLonLat)
201    {
202      transformConnector->transfer(domainSource->lonvalue, domainDestination->lonvalue_1d) ;
203      transformConnector->transfer(domainSource->latvalue, domainDestination->latvalue_1d) ;
204    }
205
206    if (domainSource->hasBounds)
207    {
208      int nv ;
209      if (domainDestination->type == CDomain::type_attr::rectilinear) nv=2 ;
210      else if (domainDestination->type == CDomain::type_attr::curvilinear) nv=4 ;
211      else if (domainDestination->type == CDomain::type_attr::unstructured) nv=domainDestination->nvertex ;
212
213      { // bounds_lon
214        CArray<double,1> boundsSrc(domainSource->bounds_lonvalue.dataFirst(),shape(domainSource->bounds_lonvalue.numElements()),neverDeleteData) ;
215        CArray<double,1> boundsDst ; 
216        transformConnector->transfer(nv, boundsSrc, boundsDst) ;
217        domainDestination->bounds_lon_1d.resize(nv,globalIndex.numElements()) ;
218        domainDestination->bounds_lon_1d = CArray<double,2>(boundsDst.dataFirst(), shape(nv,globalIndex.numElements()),neverDeleteData) ;
219      }
220      {  // bounds_lat
221        CArray<double,1> boundsSrc(domainSource->bounds_latvalue.dataFirst(),shape(domainSource->bounds_latvalue.numElements()),neverDeleteData) ;
222        CArray<double,1> boundsDst ; 
223        transformConnector->transfer(nv, boundsSrc, boundsDst) ;
224        domainDestination->bounds_lat_1d.resize(nv,globalIndex.numElements()) ;
225        domainDestination->bounds_lat_1d = CArray<double,2>(boundsDst.dataFirst(), shape(nv,globalIndex.numElements()),neverDeleteData) ;
226      }
227    }
228   
229    if (domainSource->hasArea) transformConnector->transfer(domainSource->areavalue, domainDestination->area_1d) ; 
230
231    // transfer the mask
232     auto transformMask = make_shared<CTransformConnector>(domainSource->getLocalView(CElementView::WORKFLOW), elementDst->getView(CElementView::FULL),context->getIntraComm()) ;
233    transformMask->computeConnector() ;
234
235    CArray<bool,1> workflow(domainSource->getLocalView(CElementView::WORKFLOW)->getSize()) ;
236    domainDestination->mask_1d.resize(domainSource->getLocalView(CElementView::FULL)->getSize()) ;
237    workflow=true ;
238   
239    transformMask->transfer(workflow,domainDestination->mask_1d,false) ;   
240/*
241    CArray<int,1> workflow(domainSource->getLocalView(CElementView::WORKFLOW)->getSize()) ;
242    CArray<int,1> mask(domainSource->getLocalView(CElementView::FULL)->getSize()) ;
243    workflow=1 ;
244   
245    transformMask->transfer(workflow,mask,0) ;
246    domainDestination->mask_1d.resize(mask.numElements()) ;
247    for(int i=0 ; i<mask.numElements() ; i++)
248      if (mask(i)==1) domainDestination->mask_1d(i)=true ;
249      else domainDestination->mask_1d(i)=false ;
250*/ 
251
252    domainDestination->checkAttributes() ;
253    this->computeAlgorithm(domainSource->getLocalView(CElementView::WORKFLOW), domainDestination->getLocalView(CElementView::WORKFLOW)) ;
254  }
255  CATCH
256
257
258}
Note: See TracBrowser for help on using the repository browser.