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

Last change on this file since 980 was 980, checked in by mhnguyen, 4 years ago

Minor improvements:

+) Change some type of variable to avoid some error-prone inputs
+) Change some class name to make it meaningful

Test
+) On Curie
+) Okie

  • Property svn:executable set to *
File size: 13.2 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) &&
205        (scalarListDestP[scalarDstPos] == scalarListSrcP[scalarSrcPos]) && !isSameGrid_) return;
206
207    if (scalarListDestP[scalarDstPos]->hasTransformation())
208    {
209      CScalar::TransMapTypes trans = scalarListDestP[scalarDstPos]->getAllTransformations();
210      CScalar::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(scalarPositionInGrid, std::make_pair(it->first, std::make_pair(transformationOrder,0))));       
216        ++transformationOrder;
217        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
218        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
219      }
220    }
221  }
222}
223
224/*!
225  Initialize the algorithms corresponding to transformation info contained in each axis.
226If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
227In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
228For now, one approach is to do these combinely but maybe this needs changing.
229\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)
230*/
231void CGridTransformationSelector::initializeAxisAlgorithms(int axisPositionInGrid)
232{
233  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
234  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
235  if (!axisListDestP.empty())
236  {
237    int axisDstPos = -1, axisSrcPos = -1;
238    if (0 < elementPositionInGridDst2AxisPosition_.count(axisPositionInGrid))
239      axisDstPos = elementPositionInGridDst2AxisPosition_[axisPositionInGrid];
240    if (0 < elementPositionInGridSrc2AxisPosition_.count(axisPositionInGrid))
241      axisSrcPos = elementPositionInGridSrc2AxisPosition_[axisPositionInGrid];
242
243    // If source and destination grid share the same axis
244    if ((-1 != axisDstPos) && (-1 != axisSrcPos) &&
245        (axisListDestP[axisDstPos] == axisListSrcP[axisSrcPos]) && !isSameGrid_) return;
246
247    if (axisListDestP[axisDstPos]->hasTransformation())
248    {
249      CAxis::TransMapTypes trans = axisListDestP[axisDstPos]->getAllTransformations();
250      CAxis::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(axisPositionInGrid, std::make_pair(it->first, std::make_pair(transformationOrder,1))));       
256        ++transformationOrder;
257        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
258        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
259      }
260    }
261  }
262}
263
264/*!
265  Initialize the algorithms corresponding to transformation info contained in each domain.
266If a domain has transformations, they will be represented in form of vector of CTransformation pointers
267In general, each domain can have several transformations performed on itself.
268\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)
269*/
270void CGridTransformationSelector::initializeDomainAlgorithms(int domPositionInGrid)
271{
272  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
273  std::vector<CDomain*> domListSrcP = gridSource_->getDomains();
274  if (!domListDestP.empty())
275  {
276    int domDstPos = -1, domSrcPos = -1;
277    if (0 < elementPositionInGridDst2DomainPosition_.count(domPositionInGrid))
278      domDstPos = elementPositionInGridDst2DomainPosition_[domPositionInGrid];
279    if (0 < elementPositionInGridSrc2DomainPosition_.count(domPositionInGrid))
280      domSrcPos = elementPositionInGridSrc2DomainPosition_[domPositionInGrid];
281
282    // If source and destination grid share the same domain
283    if ((-1 != domDstPos) && (-1 != domSrcPos) &&
284        (domListDestP[domDstPos] == domListSrcP[domSrcPos]) && !isSameGrid_) return;
285
286    if (domListDestP[domDstPos]->hasTransformation())
287    {
288      CDomain::TransMapTypes trans = domListDestP[domDstPos]->getAllTransformations();
289      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
290                                             ite = trans.end();
291      int transformationOrder = 0;
292      for (it = itb; it != ite; ++it)
293      {
294        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, std::make_pair(transformationOrder,2))));       
295        ++transformationOrder;
296        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
297        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
298      }
299    }
300  }
301
302}
303
304/*!
305  Select algorithm correspoding to its transformation type and its position in each element
306  \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)
307                                             and position of axis is 2
308  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
309  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
310  \param [in] algoType flag to specify type of algorithm (2 for domain, 1 for axis and 0 for scalar)
311*/
312void CGridTransformationSelector::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, int algoType)
313{
314  updateElementPosition();
315  switch (algoType)
316  {
317  case 0:
318    selectScalarAlgo(elementPositionInGrid, transType, transformationOrder);
319    break;
320  case 1:
321    selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
322    break;
323  case 2:
324    selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
325    break;
326  default:
327    break;
328  }
329}
330
331bool CGridTransformationSelector::isSpecialTransformation(ETranformationType transType)
332{
333  bool res = false;
334  switch (transType)
335  {
336    case TRANS_GENERATE_RECTILINEAR_DOMAIN:
337     res = true;
338     break;
339    default:
340     break;
341  }
342
343  return res;
344}
345
346}
Note: See TracBrowser for help on using the repository browser.