source: XIOS3/dev/XIOS_ATTACHED/src/transformation/domain_algorithm/domain_algorithm_extract.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:eol-style set to native
  • Property svn:executable set to *
File size: 13.0 KB
Line 
1#include "domain_algorithm_extract.hpp"
2#include "extract_domain.hpp"
3#include "domain.hpp"
4#include "grid.hpp"
5#include "grid_transformation_factory_impl.hpp"
6#include "attribute_template.hpp"
7
8namespace xios {
9shared_ptr<CGenericAlgorithmTransformation> CDomainAlgorithmExtract::create(bool isSource, CGrid* gridDst, CGrid* gridSrc,
10                                                             CTransformation<CDomain>* transformation,
11                                                             int elementPositionInGrid,
12                                                             std::map<int, int>& elementPositionInGridSrc2ScalarPosition,
13                                                             std::map<int, int>& elementPositionInGridSrc2AxisPosition,
14                                                             std::map<int, int>& elementPositionInGridSrc2DomainPosition,
15                                                             std::map<int, int>& elementPositionInGridDst2ScalarPosition,
16                                                             std::map<int, int>& elementPositionInGridDst2AxisPosition,
17                                                             std::map<int, int>& elementPositionInGridDst2DomainPosition)
18TRY
19{
20  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
21  std::vector<CDomain*> domainListSrcP  = gridSrc->getDomains();
22
23  CExtractDomain* extractDomain = dynamic_cast<CExtractDomain*> (transformation);
24  int domainDstIndex = elementPositionInGridDst2DomainPosition[elementPositionInGrid];
25  int domainSrcIndex = elementPositionInGridSrc2DomainPosition[elementPositionInGrid];
26
27  return make_shared<CDomainAlgorithmExtract>(isSource, domainListDestP[domainDstIndex], domainListSrcP[domainSrcIndex], extractDomain);
28}
29CATCH
30
31bool CDomainAlgorithmExtract::dummyRegistered_ = CDomainAlgorithmExtract::registerTrans();
32bool CDomainAlgorithmExtract::registerTrans()
33TRY
34{
35  return CGridTransformationFactory<CDomain>::registerTransformation(TRANS_EXTRACT_DOMAIN, create);
36}
37CATCH
38
39CDomainAlgorithmExtract::CDomainAlgorithmExtract(bool isSource, CDomain* domainDestination, CDomain* domainSource, CExtractDomain* extractDomain)
40: CAlgorithmTransformationTransfer(isSource), domainSrc_(domainSource), domainDest_(domainDestination)
41TRY
42{
43   // Reset geometrical attributes to avoid incompatible (user/domainSource) attributs
44   //   attributs will be defined using domainSource and/or transformation attributs
45   domainDestination->type.reset();
46   domainDestination->ni_glo.reset();
47   domainDestination->nj_glo.reset();
48   
49   domainDestination->i_index.reset();   // defined using domainSource->getLocalElement()
50   domainDestination->j_index.reset();   // "
51   domainDestination->ibegin.reset();    // will be computed in domainDestination->checkDomain() (from checkAttributes())
52   domainDestination->ni.reset();        // "
53   domainDestination->jbegin.reset();    // "
54   domainDestination->nj.reset();        // "
55   
56   domainDestination->mask_1d.reset();   // defined scanning domainSource->getFullView() & domainSource->getWorkflowView() differencies
57   domainDestination->mask_2d.reset();   //   in all case domainDestination->mask_1d used as reference 
58
59   // domainDestination->data_* attributes will be computed in :
60   domainDestination->data_dim.reset();     // domainDestination->checkDomainData() (from checkAttributes())
61   domainDestination->data_ni.reset();
62   domainDestination->data_nj.reset();
63   domainDestination->data_ibegin.reset();
64   domainDestination->data_jbegin.reset();
65   domainDestination->data_i_index.reset(); // domainDestination->checkCompression() (from checkAttributes())
66   domainDestination->data_j_index.reset();
67
68   // Next attributes will be set using domainSource->attributes
69   domainDestination->lonvalue_1d.reset();
70   domainDestination->latvalue_1d.reset();
71   domainDestination->lonvalue_2d.reset();
72   domainDestination->latvalue_2d.reset();
73   domainDestination->nvertex.reset();
74   domainDestination->bounds_lon_1d.reset();
75   domainDestination->bounds_lat_1d.reset();
76   domainDestination->bounds_lon_2d.reset();
77   domainDestination->bounds_lat_2d.reset();
78   domainDestination->area_1d.reset();
79   domainDestination->area_2d.reset();
80   domainDestination->radius.reset();
81   
82 
83  extractDomain->checkValid(domainSource);
84  extractIBegin_ = extractDomain->ibegin.getValue();
85  extractJBegin_ = extractDomain->jbegin.getValue();
86
87  extractNi_  = extractDomain->ni.getValue();
88  extractNj_  = extractDomain->nj.getValue();
89
90  extractIEnd_ = extractIBegin_ + extractNi_ - 1;
91  extractJEnd_ = extractJBegin_ + extractNj_ - 1;
92
93  if (extractNi_ > domainSource->ni_glo.getValue())
94  {
95    ERROR("CDomainAlgorithmExtract::CDomainAlgorithmExtract(CDomain* domainDestination, CDomain* domainSource, CExtractDomain* extractDomain)",
96           << "Extract size is greater than size of domain source"
97           << "Size ni_glo of domain source " <<domainSource->getId() << " is " << domainSource->ni_glo.getValue()  << std::endl
98           << "Extract size is " << extractNi_ );
99  }
100
101  if (extractNj_ > domainSource->nj_glo.getValue())
102  {
103    ERROR("CDomainAlgorithmExtract::CDomainAlgorithmExtract(CDomain* domainDestination, CDomain* domainSource, CExtractDomain* extractDomain)",
104           << "Extract size is greater than size of domain source"
105           << "Size nj_glo of domain source " <<domainSource->getId() << " is " << domainSource->nj_glo.getValue()  << std::endl
106           << "Extract size is " << extractNj_ );
107  }
108
109  // Calculate the size of local domain
110  int ind, indLocSrc, indLocDest, iIdxSrc, jIdxSrc, destIBegin = -1, destJBegin = -1, niDest = 0, njDest = 0 ;
111  int indGloDest, indGloSrc, niGloSrc = domainSrc_->ni_glo, iSrc, jSrc;
112  for (int j = 0; j < domainSrc_->nj.getValue(); j++)
113  {
114    for (int i = 0; i < domainSrc_->ni.getValue(); i++)
115    {
116      ind = j*domainSrc_->ni + i;
117      iIdxSrc = domainSrc_->i_index(ind);
118      if ((iIdxSrc >= extractIBegin_) && (iIdxSrc <= extractIEnd_))
119      {
120        jIdxSrc = domainSrc_->j_index(ind);
121        if ((jIdxSrc >= extractJBegin_) && (jIdxSrc <= extractJEnd_))
122        {
123          if ((niDest == 0) && (njDest == 0))
124          {
125            destIBegin = i;
126            destJBegin = j;
127          }
128          if (i == destIBegin) ++njDest;
129        }
130        if (j == destJBegin) ++niDest;
131
132      }
133    }
134  }
135
136   
137  // Set attributes for this transformation
138  domainDest_->type = domainSrc_ -> type ;
139  domainDest_->ni_glo.setValue(extractNi_);
140  domainDest_->nj_glo.setValue(extractNj_);
141  domainDest_->i_index.resize(niDest*njDest);
142  domainDest_->j_index.resize(niDest*njDest);
143
144  if (!domainSrc_->nvertex.isEmpty()) domainDest_->nvertex = domainSrc_->nvertex ;
145
146  // Resize lon/lat, bounds, area arrays to local domain dimensions
147  if (!domainSrc_->lonvalue_1d.isEmpty())
148  {
149    if (domainDest_->type == CDomain::type_attr::rectilinear)
150    {
151      domainDest_->lonvalue_1d.resize(niDest);
152      domainDest_->latvalue_1d.resize(njDest);
153    }
154    else 
155    {
156      domainDest_->lonvalue_1d.resize(niDest*njDest);
157      domainDest_->latvalue_1d.resize(niDest*njDest);
158    }
159  }
160  else if (!domainSrc_->lonvalue_2d.isEmpty())
161  {
162    domainDest_->lonvalue_2d.resize(niDest,njDest);
163    domainDest_->latvalue_2d.resize(niDest,njDest);
164  }
165  if (domainSrc_->hasBounds)
166  {
167    if (!domainSrc_->bounds_lon_2d.isEmpty())
168    {
169      domainDest_->bounds_lon_2d.resize(domainDest_->nvertex, niDest, njDest);
170      domainDest_->bounds_lat_2d.resize(domainDest_->nvertex, niDest, njDest);
171    }
172    else if (!domainSrc_->bounds_lon_1d.isEmpty())
173    {
174      domainDest_->bounds_lon_1d.resize(domainDest_->nvertex, niDest);
175      domainDest_->bounds_lat_1d.resize(domainDest_->nvertex, niDest);
176    }
177  }
178  if (domainSrc_->hasArea) 
179  {
180    if (!domainSrc_->area_2d.isEmpty()) domainDest_->area_2d.resize(niDest,njDest);
181    else if (!domainSrc_->area_1d.isEmpty()) domainDest_->area_1d.resize(niDest*njDest);
182  }
183  // Set attributes required to define domainDestination->localElement_ and associated views, full and workflow)
184  CArray<size_t,1> sourceGlobalIdx = domainSource->getLocalElement()->getGlobalIndex();
185  int indexSize = sourceGlobalIdx.numElements();
186  domainDest_->data_i_index.resize(niDest*njDest);
187  domainDestination->data_i_index = -1; 
188  domainDest_->data_j_index.resize(niDest*njDest);
189  domainDestination->data_j_index = 0; 
190
191  CArray<int,1> sourceWorkflowIdx = domainSource->getLocalView(CElementView::WORKFLOW)->getIndex();
192  int srcWorkflowSize = sourceWorkflowIdx.numElements();
193
194  int iIdxSrcMin = INT_MAX;
195  int jIdxSrcMin = INT_MAX;
196  int IdxMin = INT_MAX;
197  for (int countSrc = 0; countSrc < indexSize ; ++countSrc)
198  {
199    if ( sourceGlobalIdx(countSrc)%domainSource->ni_glo < iIdxSrcMin )
200      iIdxSrcMin = sourceGlobalIdx(countSrc)%domainSource->ni_glo;
201    if ( sourceGlobalIdx(countSrc)/domainSource->ni_glo < jIdxSrcMin )
202      jIdxSrcMin = sourceGlobalIdx(countSrc)/domainSource->ni_glo;
203    if ( sourceGlobalIdx(countSrc) < IdxMin )
204      IdxMin = sourceGlobalIdx(countSrc);
205  }
206  int countDest(0); // increment of the position in destination domain
207  for (int countSrc = 0; countSrc < indexSize ; ++countSrc)
208  {
209    int iIdxSrc = sourceGlobalIdx(countSrc)%domainSource->ni_glo;
210    int jIdxSrc = sourceGlobalIdx(countSrc)/domainSource->ni_glo;
211    // check that point countSrc concerned by extract
212    if ( (iIdxSrc >= extractIBegin_) && (iIdxSrc <= extractIEnd_)
213         && (jIdxSrc >= extractJBegin_) && (jIdxSrc <= extractJEnd_) )
214    {
215      // if concerned, convert source the global indexation in the extracted frame
216      domainDest_->i_index(countDest) = iIdxSrc-extractIBegin_;
217      domainDest_->j_index(countDest) = jIdxSrc-extractJBegin_;
218
219      // ------------------ define transformation only if in the WF ------------------
220      // countSrc+IdxMin is the global position (not index) considering the distributed memory
221      //     - can be compared to the workflow view
222      int iIdxSrc2 = (countSrc%domainSource->ni)+(IdxMin)%domainSource->ni_glo;
223      int jIdxSrc2 = (countSrc/domainSource->ni)+(IdxMin)/domainSource->ni_glo;
224      int convert_locally_global_idx = (jIdxSrc2-jIdxSrcMin)*domainSource->ni + (iIdxSrc2-iIdxSrcMin) ;
225      bool concerned_by_WF(false);
226      for ( int i = 0 ; i<sourceWorkflowIdx.numElements() ; ++i )
227      {
228        if (sourceWorkflowIdx(i)==convert_locally_global_idx)
229        {     
230          concerned_by_WF = true;
231          break;
232        }
233      }
234      if (concerned_by_WF)
235      {
236        transformationMapping_[extractNi_*(jIdxSrc-extractJBegin_)+iIdxSrc-extractIBegin_]=sourceGlobalIdx(countSrc);
237        domainDest_->data_i_index( countDest ) = countDest;
238      }
239      // -----------------------------------------------------------------------------
240
241      int iIdxDestLocal = countDest%niDest;
242      int jIdxDestLocal = countDest/niDest;
243      int iIdxSrcLocal  = countSrc%domainSource->ni;
244      int jIdxSrcLocal  = countSrc/domainSource->ni;
245
246      // area
247      if (!domainSrc_->area_2d.isEmpty()) domainDest_->area_2d(iIdxDestLocal,jIdxDestLocal) = domainSrc_->area_2d(iIdxSrcLocal,jIdxSrcLocal);
248      else if (!domainSrc_->area_1d.isEmpty())  domainDest_->area_1d(countDest) = domainSrc_->area_1d(countSrc);
249
250      // bounds
251      if (!domainDest_->bounds_lon_1d.isEmpty())
252      {
253        for (int n = 0; n < domainSrc_->nvertex; ++n)
254        {
255          domainDest_->bounds_lon_1d(n, countDest) = domainSrc_->bounds_lon_1d(n,countSrc);
256          domainDest_->bounds_lat_1d(n, countDest) = domainSrc_->bounds_lat_1d(n,countSrc);
257        }
258      }
259      else if (!domainDest_->bounds_lon_2d.isEmpty())
260      {
261        for (int n = 0; n < domainSrc_->nvertex; ++n)
262        {
263          domainDest_->bounds_lon_2d(n, iIdxDestLocal, jIdxDestLocal) = domainSrc_->bounds_lon_2d(n, iIdxSrcLocal, jIdxSrcLocal);
264          domainDest_->bounds_lat_2d(n, iIdxDestLocal, jIdxDestLocal) = domainSrc_->bounds_lat_2d(n, iIdxSrcLocal, jIdxSrcLocal);
265        }
266      }
267
268      // lon/lat
269      if (!domainDest_->lonvalue_1d.isEmpty())
270      {
271        if (domainDest_->type == CDomain::type_attr::rectilinear)
272        {
273          // i : scan nbr of points in src
274          domainDest_->lonvalue_1d(iIdxDestLocal) = domainSrc_->lonvalue_1d(iIdxSrcLocal);
275          domainDest_->latvalue_1d(jIdxDestLocal) = domainSrc_->latvalue_1d(jIdxSrcLocal);
276        }
277        else
278        {
279          domainDest_->lonvalue_1d(countDest) = domainSrc_->lonvalue_1d(countSrc);
280          domainDest_->latvalue_1d(countDest) = domainSrc_->latvalue_1d(countSrc);
281        }
282      }
283      else if (!domainDest_->lonvalue_2d.isEmpty())
284      {
285        domainDest_->lonvalue_2d(iIdxDestLocal, jIdxDestLocal) = domainSrc_->lonvalue_2d(iIdxSrcLocal,jIdxSrcLocal);
286        domainDest_->latvalue_2d(iIdxDestLocal, jIdxDestLocal) = domainSrc_->latvalue_2d(iIdxSrcLocal,jIdxSrcLocal);
287      }
288     
289      // if point i has been identified as extracted, increment position in destination domain for the next point
290      countDest++;
291    }
292
293  }
294 
295  domainDestination->checkAttributes() ;
296  this->computeAlgorithm(domainSource->getLocalView(CElementView::WORKFLOW), domainDestination->getLocalView(CElementView::WORKFLOW)) ;
297}
298CATCH
299
300
301}
Note: See TracBrowser for help on using the repository browser.