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

Last change on this file since 887 was 887, checked in by mhnguyen, 8 years ago

Adding a new type of element into grid: Scalar

+) Add a new node Scalar for xml
+) Make some change on writing scalar value
+) Reorganize some codes
+) Remove some redundant codes

Test
+) On Curie
+) All tests pass

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