source: XIOS/dev/XIOS_DEV_CMIP6/src/transformation/grid_transformation_selector.cpp @ 1260

Last change on this file since 1260 was 1158, checked in by oabramkina, 7 years ago

Two server levels: merging with trunk r1137.
There are bugs.

  • Property svn:executable set to *
File size: 13.4 KB
Line 
1/*!
2   \file grid_transformation.cpp
3   \author Ha NGUYEN
4   \since 14 May 2015
5   \date 02 Jul 2015
6
7   \brief Interface for all transformations.
8 */
9#include "grid_transformation_selector.hpp"
10#include "grid.hpp"
11#include "algo_types.hpp"
12
13namespace xios {
14
15/*!
16  Register transformation to the framework
17*/
18void CGridTransformationSelector::registerTransformations()
19{
20  //! Scalar
21  CScalarAlgorithmReduceAxis::registerTrans();
22  CScalarAlgorithmExtractAxis::registerTrans();
23  CScalarAlgorithmReduceDomain::registerTrans();
24
25  //! Axis
26  CAxisAlgorithmZoom::registerTrans();
27  CAxisAlgorithmExtractDomain::registerTrans();
28  CAxisAlgorithmInterpolate::registerTrans();
29  CAxisAlgorithmInverse::registerTrans();
30  CAxisAlgorithmReduceDomain::registerTrans();
31
32  //! Domain
33  CDomainAlgorithmComputeConnectivity::registerTrans();
34  CDomainAlgorithmInterpolate::registerTrans();
35  CDomainAlgorithmZoom::registerTrans();
36  CDomainAlgorithmExpand::registerTrans();
37}
38
39CGridTransformationSelector::CGridTransformationSelector(CGrid* destination, CGrid* source, TransformationType type)
40 : gridSource_(source), gridDestination_(destination), isSameGrid_(false),
41  listAlgos_(), algoTypes_(), nbNormalAlgos_(0), nbSpecialAlgos_(0), auxInputs_()
42{
43  if (0 == source)
44  {  gridSource_ = gridDestination_; }
45  if (gridSource_ == gridDestination_) isSameGrid_ = true;
46
47  //Verify the compatibity between two grids
48  int numElement = gridDestination_->axis_domain_order.numElements();
49  if (numElement != gridSource_->axis_domain_order.numElements())
50    ERROR("CGridTransformationSelector::CGridTransformationSelector(CGrid* destination, CGrid* source)",
51       << "Two grids have different number of elements"
52       << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
53       << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
54  registerTransformations();
55  initializeTransformations(type);
56}
57
58/*!
59  Initialize the mapping between the first grid source and the original one
60  In a series of transformation, for each step, there is a need to "create" a new grid that plays a role of "temporary" source.
61Because at the end of the series, we need to know about the index mapping between the final grid destination and original grid source,
62for each transformation, we need to make sure that the current "temporary source" maps its global index correctly to the original one.
63*/
64void CGridTransformationSelector::initializeTransformations(TransformationType type)
65{
66  // Initialize algorithms
67  initializeAlgorithms();
68  ListAlgoType::iterator itb = listAlgos_.begin(),
69                         ite = listAlgos_.end(), it;
70
71  for (it = itb; it != ite; ++it)
72  {
73    ETranformationType transType = (it->second).first;
74    if (!isSpecialTransformation(transType))
75    {
76      ++nbNormalAlgos_;
77      if (special == type)
78      {
79        it = listAlgos_.erase(it);
80        --it;
81      }
82    }
83    else
84    {
85      ++nbSpecialAlgos_;
86      if (normal == type)
87      {
88        it = listAlgos_.erase(it);
89        --it;
90      }
91    }
92
93  }
94}
95
96CGridTransformationSelector::~CGridTransformationSelector()
97{
98  std::vector<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
99                                                                ite = algoTransformation_.end();
100  for (it = itb; it != ite; ++it) delete (*it);
101}
102
103/*!
104  Update position of elements in grid source and grid destination as well as their positions in element list
105*/
106void CGridTransformationSelector::updateElementPosition()
107{
108  int idxScalar = 0, idxAxis = 0, idxDomain = 0;
109  CArray<int,1> axisDomainOrderDst = gridDestination_->axis_domain_order;
110  std::map<int, int>().swap(elementPositionInGridDst2DomainPosition_);
111  std::map<int, int>().swap(elementPositionInGridDst2AxisPosition_);
112  std::map<int, int>().swap(elementPositionInGridDst2ScalarPosition_);
113  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
114  {
115    int dimElement = axisDomainOrderDst(i);
116    if (2 == dimElement)
117    {
118      elementPositionInGridDst2DomainPosition_[i] = idxDomain;
119      ++idxDomain;
120    }
121    else if (1 == dimElement)
122    {
123      elementPositionInGridDst2AxisPosition_[i] = idxAxis;
124      ++idxAxis;
125    }
126    else
127    {
128      elementPositionInGridDst2ScalarPosition_[i] = idxScalar;
129      ++idxScalar;
130    }
131  }
132
133  idxScalar = idxAxis = idxDomain = 0;
134  CArray<int,1> axisDomainOrderSrc = gridSource_->axis_domain_order;
135  std::map<int, int>().swap(elementPositionInGridSrc2DomainPosition_);
136  std::map<int, int>().swap(elementPositionInGridSrc2AxisPosition_);
137  std::map<int, int>().swap(elementPositionInGridSrc2ScalarPosition_);
138  for (int i = 0; i < axisDomainOrderSrc.numElements(); ++i)
139  {
140    int dimElement = axisDomainOrderSrc(i);
141    if (2 == dimElement)
142    {
143      elementPositionInGridSrc2DomainPosition_[i] = idxDomain;
144      ++idxDomain;
145    }
146    else if (1 == dimElement)
147    {
148      elementPositionInGridSrc2AxisPosition_[i] = idxAxis;
149      ++idxAxis;
150    }
151    else
152    {
153      elementPositionInGridSrc2ScalarPosition_[i] = idxScalar;
154      ++idxScalar;
155    }
156  }
157}
158
159/*!
160  Initialize the algorithms (transformations)
161*/
162void CGridTransformationSelector::initializeAlgorithms()
163{
164  updateElementPosition();
165  CArray<int,1> axisDomainOrderDst = gridDestination_->axis_domain_order;
166  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
167  {
168    int dimElement = axisDomainOrderDst(i);
169    if (2 == dimElement)
170    {
171      initializeDomainAlgorithms(i);
172    }
173    else if (1 == dimElement)
174    {
175      initializeAxisAlgorithms(i);
176    }
177    else
178    {
179      initializeScalarAlgorithms(i);
180    }
181  }
182}
183
184/*!
185  Initialize the algorithms corresponding to transformation info contained in each scalar.
186If an scalar has transformations, these transformations will be represented in form of vector of CTransformation pointers
187In general, each scalar can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
188For now, one approach is to do these combinely but maybe this needs changing.
189\param [in] axisPositionInGrid position of an axis in grid. (for example: a grid with one domain and one scalar, position of domain is 0, position of axis is 1)
190*/
191void CGridTransformationSelector::initializeScalarAlgorithms(int scalarPositionInGrid)
192{
193  std::vector<CScalar*> scalarListDestP = gridDestination_->getScalars();
194  std::vector<CScalar*> scalarListSrcP = gridSource_->getScalars();
195  if (!scalarListDestP.empty())
196  {
197    int scalarDstPos = -1, scalarSrcPos = -1;
198    if (0 < elementPositionInGridDst2ScalarPosition_.count(scalarPositionInGrid))
199      scalarDstPos = elementPositionInGridDst2ScalarPosition_[scalarPositionInGrid];
200    if (0 < elementPositionInGridSrc2ScalarPosition_.count(scalarPositionInGrid))
201      scalarSrcPos = elementPositionInGridSrc2ScalarPosition_[scalarPositionInGrid];
202
203    // If source and destination grid share the same scalar
204    if ((-1 != scalarDstPos) && (-1 != scalarSrcPos)  && !isSameGrid_ &&
205        ((scalarListDestP[scalarDstPos] == scalarListSrcP[scalarSrcPos]) ||
206         (scalarListDestP[scalarDstPos]->isEqual(scalarListSrcP[scalarSrcPos])))) return;
207
208    if (scalarListDestP[scalarDstPos]->hasTransformation())
209    {
210      CScalar::TransMapTypes trans = scalarListDestP[scalarDstPos]->getAllTransformations();
211      CScalar::TransMapTypes::const_iterator itb = trans.begin(), it,
212                                           ite = trans.end();
213      int transformationOrder = 0;
214      for (it = itb; it != ite; ++it)
215      {
216        listAlgos_.push_back(std::make_pair(scalarPositionInGrid, std::make_pair(it->first, std::make_pair(transformationOrder,0))));       
217        ++transformationOrder;
218        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
219        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
220      }
221    }
222  }
223}
224
225/*!
226  Initialize the algorithms corresponding to transformation info contained in each axis.
227If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
228In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
229For now, one approach is to do these combinely but maybe this needs changing.
230\param [in] axisPositionInGrid position of an axis in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
231*/
232void CGridTransformationSelector::initializeAxisAlgorithms(int axisPositionInGrid)
233{
234  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
235  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
236  if (!axisListDestP.empty())
237  {
238    int axisDstPos = -1, axisSrcPos = -1;
239    if (0 < elementPositionInGridDst2AxisPosition_.count(axisPositionInGrid))
240      axisDstPos = elementPositionInGridDst2AxisPosition_[axisPositionInGrid];
241    if (0 < elementPositionInGridSrc2AxisPosition_.count(axisPositionInGrid))
242      axisSrcPos = elementPositionInGridSrc2AxisPosition_[axisPositionInGrid];
243
244    // If source and destination grid share the same axis
245    if ((-1 != axisDstPos) && (-1 != axisSrcPos) && !isSameGrid_ &&
246        ((axisListDestP[axisDstPos] == axisListSrcP[axisSrcPos]) ||
247         (axisListDestP[axisDstPos]->isEqual(axisListSrcP[axisSrcPos]))) ) return;
248
249    if (axisListDestP[axisDstPos]->hasTransformation())
250    {
251      CAxis::TransMapTypes trans = axisListDestP[axisDstPos]->getAllTransformations();
252      CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
253                                           ite = trans.end();
254      int transformationOrder = 0;
255      for (it = itb; it != ite; ++it)
256      {
257        listAlgos_.push_back(std::make_pair(axisPositionInGrid, std::make_pair(it->first, std::make_pair(transformationOrder,1))));       
258        ++transformationOrder;
259        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
260        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
261      }
262    }
263  }
264}
265
266/*!
267  Initialize the algorithms corresponding to transformation info contained in each domain.
268If a domain has transformations, they will be represented in form of vector of CTransformation pointers
269In general, each domain can have several transformations performed on itself.
270\param [in] domPositionInGrid position of a domain in grid. (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
271*/
272void CGridTransformationSelector::initializeDomainAlgorithms(int domPositionInGrid)
273{
274  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
275  std::vector<CDomain*> domListSrcP = gridSource_->getDomains();
276  if (!domListDestP.empty())
277  {
278    int domDstPos = -1, domSrcPos = -1;
279    if (0 < elementPositionInGridDst2DomainPosition_.count(domPositionInGrid))
280      domDstPos = elementPositionInGridDst2DomainPosition_[domPositionInGrid];
281    if (0 < elementPositionInGridSrc2DomainPosition_.count(domPositionInGrid))
282      domSrcPos = elementPositionInGridSrc2DomainPosition_[domPositionInGrid];
283
284    // If source and destination grid share the same domain
285    if ((-1 != domDstPos) && (-1 != domSrcPos) && !isSameGrid_ &&
286        ((domListDestP[domDstPos] == domListSrcP[domSrcPos]) ||
287         (domListDestP[domDstPos]->isEqual(domListSrcP[domSrcPos])))) return;
288
289    if (domListDestP[domDstPos]->hasTransformation())
290    {
291      CDomain::TransMapTypes trans = domListDestP[domDstPos]->getAllTransformations();
292      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
293                                             ite = trans.end();
294      int transformationOrder = 0;
295      for (it = itb; it != ite; ++it)
296      {
297        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, std::make_pair(transformationOrder,2))));       
298        ++transformationOrder;
299        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
300        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
301      }
302    }
303  }
304
305}
306
307/*!
308  Select algorithm correspoding to its transformation type and its position in each element
309  \param [in] elementPositionInGrid position of element in grid. e.g: a grid has 1 domain and 1 axis, then position of domain is 1 (because it contains 2 basic elements)
310                                             and position of axis is 2
311  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
312  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
313  \param [in] algoType flag to specify type of algorithm (2 for domain, 1 for axis and 0 for scalar)
314*/
315void CGridTransformationSelector::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, int algoType)
316{
317  updateElementPosition();
318  switch (algoType)
319  {
320  case 0:
321    selectScalarAlgo(elementPositionInGrid, transType, transformationOrder);
322    break;
323  case 1:
324    selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
325    break;
326  case 2:
327    selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
328    break;
329  default:
330    break;
331  }
332}
333
334bool CGridTransformationSelector::isSpecialTransformation(ETranformationType transType)
335{
336  bool res = false;
337  switch (transType)
338  {
339    case TRANS_GENERATE_RECTILINEAR_DOMAIN:
340     res = true;
341     break;
342    default:
343     break;
344  }
345
346  return res;
347}
348
349}
Note: See TracBrowser for help on using the repository browser.