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

Last change on this file since 934 was 934, checked in by mhnguyen, 4 years ago

Adding new transformation: Compute_connectivity_domain

Test
+) On Curie
+) Test passes

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