source: XIOS/dev/dev_olga/src/transformation/grid_transformation_selector.cpp @ 1620

Last change on this file since 1620 was 1612, checked in by oabramkina, 5 years ago

Dev: adding exception handling.

To activate it, compilation flag -DXIOS_EXCEPTION should be added.

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