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

Last change on this file 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.