source: XIOS2/trunk/src/transformation/domain_algorithm_zoom.cpp @ 2442

Last change on this file since 2442 was 2442, checked in by jderouillat, 19 months ago

Fix bounds management in transformations. Disabled temporarily bounds settings in the rectilinear case of the generic_testcase

File size: 10.8 KB
Line 
1#include "domain_algorithm_zoom.hpp"
2#include "zoom_domain.hpp"
3#include "domain.hpp"
4#include "grid.hpp"
5#include "grid_transformation_factory_impl.hpp"
6#include "attribute_template.hpp"
7#include "type.hpp"
8
9namespace xios {
10CGenericAlgorithmTransformation* CDomainAlgorithmZoom::create(CGrid* gridDst, CGrid* gridSrc,
11                                                             CTransformation<CDomain>* transformation,
12                                                             int elementPositionInGrid,
13                                                             std::map<int, int>& elementPositionInGridSrc2ScalarPosition,
14                                                             std::map<int, int>& elementPositionInGridSrc2AxisPosition,
15                                                             std::map<int, int>& elementPositionInGridSrc2DomainPosition,
16                                                             std::map<int, int>& elementPositionInGridDst2ScalarPosition,
17                                                             std::map<int, int>& elementPositionInGridDst2AxisPosition,
18                                                             std::map<int, int>& elementPositionInGridDst2DomainPosition)
19TRY
20{
21  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
22  std::vector<CDomain*> domainListSrcP  = gridSrc->getDomains();
23
24  CZoomDomain* zoomDomain = dynamic_cast<CZoomDomain*> (transformation);
25  int domainDstIndex = elementPositionInGridDst2DomainPosition[elementPositionInGrid];
26  int domainSrcIndex = elementPositionInGridSrc2DomainPosition[elementPositionInGrid];
27
28  return (new CDomainAlgorithmZoom(domainListDestP[domainDstIndex], domainListSrcP[domainSrcIndex], zoomDomain));
29}
30CATCH
31
32bool CDomainAlgorithmZoom::registerTrans()
33TRY
34{
35  return CGridTransformationFactory<CDomain>::registerTransformation(TRANS_ZOOM_DOMAIN, create);
36}
37CATCH
38
39CDomainAlgorithmZoom::CDomainAlgorithmZoom(CDomain* domainDestination, CDomain* domainSource, CZoomDomain* zoomDomain)
40: CDomainAlgorithmTransformation(domainDestination, domainSource)
41TRY
42{
43  zoomDomain->checkValid(domainSource);
44  zoomIBegin_ = zoomDomain->ibegin.getValue();
45  zoomJBegin_ = zoomDomain->jbegin.getValue();
46
47  zoomNi_  = zoomDomain->ni.getValue();
48  zoomNj_  = zoomDomain->nj.getValue();
49
50  zoomIEnd_ = zoomIBegin_ + zoomNi_ - 1;
51  zoomJEnd_ = zoomJBegin_ + zoomNj_ - 1;
52
53  if (zoomNi_ > domainSource->ni_glo.getValue())
54  {
55    ERROR("CDomainAlgorithmZoom::CDomainAlgorithmZoom(CDomain* domainDestination, CDomain* domainSource, CZoomDomain* zoomDomain)",
56           << "Zoom size is greater than size of domain source"
57           << "Size ni_glo of domain source " <<domainSource->getId() << " is " << domainSource->ni_glo.getValue()  << std::endl
58           << "Zoom size is " << zoomNi_ );
59  }
60
61  if (zoomNj_ > domainSource->nj_glo.getValue())
62  {
63    ERROR("CDomainAlgorithmZoom::CDomainAlgorithmZoom(CDomain* domainDestination, CDomain* domainSource, CZoomDomain* zoomDomain)",
64           << "Zoom size is greater than size of domain source"
65           << "Size nj_glo of domain source " <<domainSource->getId() << " is " << domainSource->nj_glo.getValue()  << std::endl
66           << "Zoom size is " << zoomNj_ );
67  }
68
69  // Calculate the size of local domain
70  int ind, indLocSrc, indLocDest, iIdxSrc, jIdxSrc, destIBegin = -1, destJBegin = -1, niDest = 0, njDest = 0, ibeginDest, jbeginDest ;
71  int indGloDest, indGloSrc, niGloSrc = domainSrc_->ni_glo, iSrc, jSrc, nvertex = 0;
72  for (int j = 0; j < domainSrc_->nj.getValue(); j++)
73  {
74    for (int i = 0; i < domainSrc_->ni.getValue(); i++)
75    {
76      ind = j*domainSrc_->ni + i;
77      iIdxSrc = domainSrc_->i_index(ind);
78      if ((iIdxSrc >= zoomIBegin_) && (iIdxSrc <= zoomIEnd_))
79      {
80        jIdxSrc = domainSrc_->j_index(ind);
81        if ((jIdxSrc >= zoomJBegin_) && (jIdxSrc <= zoomJEnd_))
82        {
83          if ((niDest == 0) && (njDest == 0))
84          {
85            destIBegin = i;
86            destJBegin = j;
87          }
88          if (i == destIBegin) ++njDest;
89        }
90        if (j == destJBegin) ++niDest;
91
92      }
93    }
94  }
95  ibeginDest = destIBegin + domainSrc_->ibegin - zoomIBegin_;
96  jbeginDest = destJBegin + domainSrc_->jbegin - zoomJBegin_;
97  domainDest_->ni_glo.setValue(zoomNi_);
98  domainDest_->nj_glo.setValue(zoomNj_);
99  domainDest_->ni.setValue(niDest);
100  domainDest_->nj.setValue(njDest);
101  if ( (niDest==0) || (njDest==0))
102  {
103    domainDest_->ibegin.setValue(0);
104    domainDest_->jbegin.setValue(0);
105  }
106  else
107  {
108    domainDest_->ibegin.setValue(ibeginDest);
109    domainDest_->jbegin.setValue(jbeginDest);
110  }
111  domainDest_->i_index.resize(niDest*njDest);
112  domainDest_->j_index.resize(niDest*njDest);
113
114  domainDest_->data_ni.setValue(niDest);
115  domainDest_->data_nj.setValue(njDest);
116  domainDest_->data_ibegin.setValue(0);
117  domainDest_->data_jbegin.setValue(0);
118  domainDest_->data_i_index.resize(niDest*njDest);
119  domainDest_->data_j_index.resize(niDest*njDest);
120
121  domainDest_->domainMask.resize(niDest*njDest);
122
123  if (!domainSrc_->lonvalue_1d.isEmpty())
124  {
125    if (domainDest_->type == CDomain::type_attr::rectilinear)
126    {
127      domainDest_->lonvalue_1d.resize(niDest);
128      domainDest_->latvalue_1d.resize(njDest);
129    }
130    else if (domainDest_->type == CDomain::type_attr::unstructured)
131    {
132      domainDest_->lonvalue_1d.resize(niDest);
133      domainDest_->latvalue_1d.resize(niDest);
134    }
135    else if (domainDest_->type == CDomain::type_attr::curvilinear)
136    {
137      domainDest_->lonvalue_1d.resize(niDest*njDest);
138      domainDest_->latvalue_1d.resize(niDest*njDest);
139    }
140  }
141  else if (!domainSrc_->lonvalue_2d.isEmpty())
142  {
143    domainDest_->lonvalue_2d.resize(niDest,njDest);
144    domainDest_->latvalue_2d.resize(niDest,njDest);
145  }
146
147  if (domainSrc_->hasBounds)
148  {
149    nvertex = ( domainSrc_->type==CDomain::type_attr::rectilinear || domainSrc_->type==CDomain::type_attr::curvilinear) ? 4 : domainSrc_->nvertex ;
150    domainDest_->nvertex.setValue(nvertex);
151    if (!domainSrc_->bounds_lon_1d.isEmpty())
152    {
153      if (domainDest_->type == CDomain::type_attr::rectilinear)
154      {
155        domainDest_->bounds_lon_1d.resize(nvertex, niDest);
156        domainDest_->bounds_lat_1d.resize(nvertex, njDest);
157      }
158      else if (domainDest_->type == CDomain::type_attr::unstructured)
159      {
160        domainDest_->bounds_lon_1d.resize(nvertex, niDest);
161        domainDest_->bounds_lat_1d.resize(nvertex, niDest);
162      }
163      else if (domainDest_->type == CDomain::type_attr::curvilinear)
164      {
165        domainDest_->bounds_lon_1d.resize(nvertex, niDest*njDest);
166        domainDest_->bounds_lat_1d.resize(nvertex, niDest*njDest);
167      }
168    }
169    else if (!domainSrc_->bounds_lon_2d.isEmpty())
170    {
171      domainDest_->bounds_lon_2d.resize(nvertex, niDest, njDest);
172      domainDest_->bounds_lat_2d.resize(nvertex, niDest, njDest);
173    }
174  }
175  if (domainSrc_->hasArea) domainDest_->area.resize(niDest,njDest);
176
177  this->transformationMapping_.resize(1);
178  this->transformationWeight_.resize(1);
179  TransformationIndexMap& transMap = this->transformationMapping_[0];
180  TransformationWeightMap& transWeight = this->transformationWeight_[0];
181
182  for (int iDest = 0; iDest < niDest; iDest++)
183  {
184    iSrc = iDest + destIBegin;
185    for (int jDest = 0; jDest < njDest; jDest++)
186    {
187      jSrc = jDest + destJBegin;
188      ind = jSrc * domainSrc_->ni + iSrc;
189      iIdxSrc = domainSrc_->i_index(ind);
190      jIdxSrc = domainSrc_->j_index(ind);
191      indLocDest = jDest*niDest + iDest;
192      indGloDest = (jDest + jbeginDest)*zoomNi_ + (iDest + ibeginDest);
193      indLocSrc = (jDest+destJBegin)*domainSrc_->ni + (iDest+destIBegin);
194      indGloSrc = (jIdxSrc )* niGloSrc + iIdxSrc;
195      domainDest_->i_index(indLocDest) = iDest + ibeginDest;                                             // i_index contains global positions
196      domainDest_->j_index(indLocDest) = jDest + jbeginDest;                                             // i_index contains global positions
197      domainDest_->data_i_index(indLocDest) = (domainSrc_->data_dim == 1) ? indLocDest : iDest;          // data_i_index contains local positions
198      domainDest_->data_j_index(indLocDest) = (domainSrc_->data_dim == 1) ? 0 :jDest;                    // data_i_index contains local positions
199      domainDest_->domainMask(indLocDest) = domainSrc_->domainMask(indLocSrc);
200
201      if (domainSrc_->hasArea)
202        domainDest_->area(iDest,jDest) = domainSrc_->area(iSrc,jSrc);
203
204      if (domainSrc_->hasLonLat)
205      {
206        if (!domainSrc_->latvalue_1d.isEmpty())
207        {
208          if (domainDest_->type == CDomain::type_attr::rectilinear)
209          {
210            domainDest_->latvalue_1d(jDest) = domainSrc_->latvalue_1d(jSrc);
211          }
212          else
213          {
214            domainDest_->lonvalue_1d(indLocDest) = domainSrc_->lonvalue_1d(ind);
215            domainDest_->latvalue_1d(indLocDest) = domainSrc_->latvalue_1d(ind);
216          }
217        }
218        else if (!domainSrc_->latvalue_2d.isEmpty())
219        {
220          domainDest_->lonvalue_2d(iDest,jDest) = domainSrc_->lonvalue_2d(iSrc,jSrc);
221          domainDest_->latvalue_2d(iDest,jDest) = domainSrc_->latvalue_2d(iSrc,jSrc);
222        }
223      }
224
225      if (domainSrc_->hasBounds)
226      {
227        if (!domainSrc_->bounds_lon_1d.isEmpty())
228        {
229          if (domainDest_->type == CDomain::type_attr::rectilinear)
230          {
231            for (int n = 0; n < nvertex; ++n)
232              domainDest_->bounds_lat_1d(n,jDest) = domainSrc_->bounds_lat_1d(n,jSrc);
233          }
234          else
235          {
236            for (int n = 0; n < nvertex; ++n)
237            {
238              domainDest_->bounds_lon_1d(n,indLocDest) = domainSrc_->bounds_lon_1d(n,ind);
239              domainDest_->bounds_lat_1d(n,indLocDest) = domainSrc_->bounds_lat_1d(n,ind);
240            }
241          }
242        }
243        else if (!domainSrc_->bounds_lon_2d.isEmpty())
244        {
245          for (int n = 0; n < nvertex; ++n)
246          {
247            domainDest_->bounds_lon_2d(n,iDest,jDest) = domainSrc_->bounds_lon_2d(n,iSrc,jSrc);
248            domainDest_->bounds_lat_2d(n,iDest,jDest) = domainSrc_->bounds_lat_2d(n,iSrc,jSrc);
249          }
250        }
251
252      }
253
254      transMap[indGloDest].push_back(indGloSrc);
255      transWeight[indGloDest].push_back(1.0);
256    }
257
258    if (domainSrc_->hasLonLat && !domainSrc_->latvalue_1d.isEmpty())
259    {
260      if (domainDest_->type == CDomain::type_attr::rectilinear)
261      {
262        domainDest_->lonvalue_1d(iDest) = domainSrc_->lonvalue_1d(iSrc);
263      }
264    }
265
266    if (domainSrc_->hasBounds && !domainSrc_->bounds_lon_1d.isEmpty())
267    {
268      if (domainDest_->type == CDomain::type_attr::rectilinear)
269      {
270        for (int n = 0; n < nvertex; ++n)
271          domainDest_->bounds_lon_1d(n,iDest) = domainSrc_->bounds_lon_1d(n,iSrc);
272      }
273    }
274  }
275  domainDest_->computeLocalMask();
276}
277CATCH
278
279/*!
280  Compute the index mapping between domain on grid source and one on grid destination
281*/
282void CDomainAlgorithmZoom::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
283{
284}
285
286
287}
Note: See TracBrowser for help on using the repository browser.