source: XIOS/trunk/src/transformation/grid_transformation_selector.cpp @ 1558

Last change on this file since 1558 was 1558, checked in by oabramkina, 6 years ago

Adding transformation "extract" for axis.

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