source: XIOS3/dev/XIOS_ATTACHED/src/transformation/domain_algorithm/domain_algorithm_extract.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: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.