source: XIOS/dev/dev_trunk_omp/src/transformation/grid_transformation_selector.cpp @ 1646

Last change on this file since 1646 was 1646, checked in by yushan, 5 years ago

branch merged with trunk @1645. arch file (ep&mpi) added for ADA

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