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

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

Correcting a bug in transformation_selector

+) Make sure transformation selector chose a correct transformation
+) Correct a bug of updating transformation value

Test
+) On Curie
+) All test pass

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