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

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

branch_openmp merged with trunk r1597

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