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

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

Ticket 110: Implementing domain reduction to scalar

+) Add xml node for this new transformation
+) Add algorithm for this new transformation

Test
+) On Curie
+) Work

  • Property svn:executable set to *
File size: 12.5 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  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  Initialize the algorithms (transformations)
105*/
106void CGridTransformationSelector::initializeAlgorithms()
107{
108  int idxScalar = 0, idxAxis = 0, idxDomain = 0;
109  CArray<int,1> axisDomainOrderDst = gridDestination_->axis_domain_order;
110  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
111  {
112    int dimElement = axisDomainOrderDst(i);
113    if (2 == dimElement)
114    {
115      elementPositionInGridDst2DomainPosition_[i] = idxDomain;
116      ++idxDomain;
117    }
118    else if (1 == dimElement)
119    {
120      elementPositionInGridDst2AxisPosition_[i] = idxAxis;
121      ++idxAxis;
122    }
123    else
124    {
125      elementPositionInGridDst2ScalarPosition_[i] = idxScalar;
126      ++idxScalar;
127    }
128  }
129
130  idxScalar = idxAxis = idxDomain = 0;
131  CArray<int,1> axisDomainOrderSrc = gridSource_->axis_domain_order;
132  for (int i = 0; i < axisDomainOrderSrc.numElements(); ++i)
133  {
134    int dimElement = axisDomainOrderSrc(i);
135    if (2 == dimElement)
136    {
137      elementPositionInGridSrc2DomainPosition_[i] = idxDomain;
138      ++idxDomain;
139    }
140    else if (1 == dimElement)
141    {
142      elementPositionInGridSrc2AxisPosition_[i] = idxAxis;
143      ++idxAxis;
144    }
145    else
146    {
147      elementPositionInGridSrc2ScalarPosition_[i] = idxScalar;
148      ++idxScalar;
149    }
150  }
151
152  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
153  {
154    int dimElement = axisDomainOrderDst(i);
155    if (2 == dimElement)
156    {
157      initializeDomainAlgorithms(i);
158    }
159    else if (1 == dimElement)
160    {
161      initializeAxisAlgorithms(i);
162    }
163    else
164    {
165      initializeScalarAlgorithms(i);
166    }
167  }
168}
169
170/*!
171  Initialize the algorithms corresponding to transformation info contained in each scalar.
172If an scalar has transformations, these transformations will be represented in form of vector of CTransformation pointers
173In general, each scalar can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
174For now, one approach is to do these combinely but maybe this needs changing.
175\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)
176*/
177void CGridTransformationSelector::initializeScalarAlgorithms(int scalarPositionInGrid)
178{
179  std::vector<CScalar*> scalarListDestP = gridDestination_->getScalars();
180  std::vector<CScalar*> scalarListSrcP = gridSource_->getScalars();
181  if (!scalarListDestP.empty())
182  {
183    int scalarDstPos = -1, scalarSrcPos = -1;
184    if (0 < elementPositionInGridDst2ScalarPosition_.count(scalarPositionInGrid))
185      scalarDstPos = elementPositionInGridDst2AxisPosition_[scalarPositionInGrid];
186    if (0 < elementPositionInGridSrc2ScalarPosition_.count(scalarPositionInGrid))
187      scalarSrcPos = elementPositionInGridSrc2AxisPosition_[scalarPositionInGrid];
188
189    // If source and destination grid share the same scalar
190    if ((-1 != scalarDstPos) && (-1 != scalarSrcPos) &&
191        (scalarListDestP[scalarDstPos] == scalarListSrcP[scalarSrcPos]) && !isSameGrid_) return;
192
193    if (scalarListDestP[scalarDstPos]->hasTransformation())
194    {
195      CScalar::TransMapTypes trans = scalarListDestP[scalarDstPos]->getAllTransformations();
196      CScalar::TransMapTypes::const_iterator itb = trans.begin(), it,
197                                           ite = trans.end();
198      int transformationOrder = 0;
199      for (it = itb; it != ite; ++it)
200      {
201        listAlgos_.push_back(std::make_pair(scalarPositionInGrid, std::make_pair(it->first, transformationOrder)));
202        algoTypes_.push_back(scalarType);
203        ++transformationOrder;
204        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
205        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
206      }
207    }
208  }
209}
210
211/*!
212  Initialize the algorithms corresponding to transformation info contained in each axis.
213If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
214In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
215For now, one approach is to do these combinely but maybe this needs changing.
216\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)
217*/
218void CGridTransformationSelector::initializeAxisAlgorithms(int axisPositionInGrid)
219{
220  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
221  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
222  if (!axisListDestP.empty())
223  {
224    int axisDstPos = -1, axisSrcPos = -1;
225    if (0 < elementPositionInGridDst2AxisPosition_.count(axisPositionInGrid))
226      axisDstPos = elementPositionInGridDst2AxisPosition_[axisPositionInGrid];
227    if (0 < elementPositionInGridSrc2AxisPosition_.count(axisPositionInGrid))
228      axisSrcPos = elementPositionInGridSrc2AxisPosition_[axisPositionInGrid];
229
230    // If source and destination grid share the same axis
231    if ((-1 != axisDstPos) && (-1 != axisSrcPos) &&
232        (axisListDestP[axisDstPos] == axisListSrcP[axisSrcPos]) && !isSameGrid_) return;
233
234    if (axisListDestP[axisDstPos]->hasTransformation())
235    {
236      CAxis::TransMapTypes trans = axisListDestP[axisDstPos]->getAllTransformations();
237      CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
238                                           ite = trans.end();
239      int transformationOrder = 0;
240      for (it = itb; it != ite; ++it)
241      {
242        listAlgos_.push_back(std::make_pair(axisPositionInGrid, std::make_pair(it->first, transformationOrder)));
243        algoTypes_.push_back(axisType);
244        ++transformationOrder;
245        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
246        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
247      }
248    }
249  }
250}
251
252/*!
253  Initialize the algorithms corresponding to transformation info contained in each domain.
254If a domain has transformations, they will be represented in form of vector of CTransformation pointers
255In general, each domain can have several transformations performed on itself.
256\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)
257*/
258void CGridTransformationSelector::initializeDomainAlgorithms(int domPositionInGrid)
259{
260  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
261  std::vector<CDomain*> domListSrcP = gridSource_->getDomains();
262  if (!domListDestP.empty())
263  {
264    int domDstPos = -1, domSrcPos = -1;
265    if (0 < elementPositionInGridDst2DomainPosition_.count(domPositionInGrid))
266      domDstPos = elementPositionInGridDst2AxisPosition_[domPositionInGrid];
267    if (0 < elementPositionInGridSrc2DomainPosition_.count(domPositionInGrid))
268      domSrcPos = elementPositionInGridSrc2AxisPosition_[domPositionInGrid];
269
270    // If source and destination grid share the same domain
271    if ((-1 != domDstPos) && (-1 != domSrcPos) &&
272        (domListDestP[domDstPos] == domListSrcP[domSrcPos]) && !isSameGrid_) return;
273
274    if (domListDestP[domDstPos]->hasTransformation())
275    {
276      CDomain::TransMapTypes trans = domListDestP[domDstPos]->getAllTransformations();
277      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
278                                             ite = trans.end();
279      int transformationOrder = 0;
280      for (it = itb; it != ite; ++it)
281      {
282        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, transformationOrder)));
283        algoTypes_.push_back(domainType);
284        ++transformationOrder;
285        std::vector<StdString> auxInput = (it->second)->checkAuxInputs();
286        for (int idx = 0; idx < auxInput.size(); ++idx) auxInputs_.push_back(auxInput[idx]);
287      }
288    }
289  }
290
291}
292
293/*!
294  Select algorithm correspoding to its transformation type and its position in each element
295  \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)
296                                             and position of axis is 2
297  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
298  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
299  \param [in] isDomainAlgo flag to specify type of algorithm (for domain or axis)
300*/
301void CGridTransformationSelector::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, AlgoType algoType)
302{
303  switch (algoType)
304  {
305  case scalarType:
306    selectScalarAlgo(elementPositionInGrid, transType, transformationOrder);
307    break;
308  case axisType:
309    selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
310    break;
311  case domainType:
312    selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
313    break;
314  default:
315    break;
316  }
317}
318
319bool CGridTransformationSelector::isSpecialTransformation(ETranformationType transType)
320{
321  bool res = false;
322  switch (transType)
323  {
324    case TRANS_GENERATE_RECTILINEAR_DOMAIN:
325     res = true;
326     break;
327    default:
328     break;
329  }
330
331  return res;
332}
333
334}
Note: See TracBrowser for help on using the repository browser.