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

Last change on this file since 960 was 960, checked in by mhnguyen, 5 years ago

New transformation: Extract a point on axis to a scalar

+) Add new node and new transformation algorithm

Test
+) On Curie
+) Work

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