source: XIOS/trunk/src/transformation/grid_generate.cpp @ 752

Last change on this file since 752 was 687, checked in by mhnguyen, 9 years ago

Implementing auto-generate rectilinear domain

+) Add a new special transformation to generate (complete) rectilinear domain

Test
+) On Curie
+) test_new_feature passed

File size: 10.2 KB
Line 
1/*!
2   \file grid_generate.cpp
3   \author Ha NGUYEN
4   \since 28 Aug 2015
5   \date 28 Aug 2015
6
7   \brief A special transformation to generate a grid.
8 */
9#include "grid_generate.hpp"
10#include "domain_algorithm_generate_rectilinear.hpp"
11#include "context.hpp"
12#include "context_client.hpp"
13#include "generate_rectilinear_domain.hpp"
14
15namespace xios {
16CGridGenerate::CGridGenerate(CGrid* destination, CGrid* source)
17: gridSource_(source), gridDestination_(destination), algoTypes_()
18{
19  //Verify the compatibity between two grids
20  int numElement = gridDestination_->axis_domain_order.numElements();
21  if (numElement != gridSource_->axis_domain_order.numElements())
22    ERROR("CGridGenerate::CGridGenerate(CGrid* destination, CGrid* source)",
23       << "Two grids have different number of elements"
24       << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
25       << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
26
27  for (int i = 0; i < numElement; ++i)
28  {
29    if (gridDestination_->axis_domain_order(i) != gridSource_->axis_domain_order(i))
30      ERROR("CGridGenerate::CGridGenerate(CGrid* destination, CGrid* source)",
31         << "Transformed grid and its grid source have incompatible elements"
32         << "Grid source " <<gridSource_->getId() << std::endl
33         << "Grid destination " <<gridDestination_->getId());
34  }
35
36  initializeAlgorithms();
37}
38
39CGridGenerate::~CGridGenerate()
40{
41  std::list<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
42                                                              ite = algoTransformation_.end();
43  for (it = itb; it != ite; ++it) delete (*it);
44}
45
46/*!
47  Initialize the algorithms (transformations)
48*/
49void CGridGenerate::initializeAlgorithms()
50{
51  std::vector<int> axisPositionInGrid;
52  std::vector<int> domPositionInGrid;
53  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
54  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
55
56  int idx = 0;
57  for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
58  {
59    if (false == (gridDestination_->axis_domain_order)(i))
60    {
61      axisPositionInGrid.push_back(idx);
62      ++idx;
63    }
64    else
65    {
66      ++idx;
67      domPositionInGrid.push_back(idx);
68      ++idx;
69    }
70  }
71
72  for (int i = 0; i < axisListDestP.size(); ++i)
73  {
74    elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
75  }
76
77  for (int i = 0; i < domListDestP.size(); ++i)
78  {
79    elementPosition2DomainPositionInGrid_[domPositionInGrid[i]] = i;
80  }
81
82  idx = 0;
83  for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
84  {
85    if (false == (gridDestination_->axis_domain_order)(i))
86    {
87      initializeAxisAlgorithms(idx);
88      ++idx;
89    }
90    else
91    {
92      ++idx;
93      initializeDomainAlgorithms(idx);
94      ++idx;
95    }
96  }
97}
98
99
100
101/*!
102  Initialize the algorithms corresponding to transformation info contained in each axis.
103If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
104In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
105For now, one approach is to do these combinely but maybe this needs changing.
106\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)
107*/
108void CGridGenerate::initializeAxisAlgorithms(int axisPositionInGrid)
109{
110  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
111  if (!axisListDestP.empty())
112  {
113    if (axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->hasTransformation())
114    {
115      CAxis::TransMapTypes trans = axisListDestP[elementPosition2AxisPositionInGrid_[axisPositionInGrid]]->getAllTransformations();
116      CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
117                                           ite = trans.end();
118      int transformationOrder = 0;
119      for (it = itb; it != ite; ++it)
120      {
121        listAlgos_.push_back(std::make_pair(axisPositionInGrid, std::make_pair(it->first, transformationOrder)));
122        algoTypes_.push_back(false);
123        ++transformationOrder;
124      }
125    }
126  }
127}
128
129/*!
130  Initialize the algorithms corresponding to transformation info contained in each domain.
131If a domain has transformations, they will be represented in form of vector of CTransformation pointers
132In general, each domain can have several transformations performed on itself.
133\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)
134*/
135void CGridGenerate::initializeDomainAlgorithms(int domPositionInGrid)
136{
137  std::vector<CDomain*> domListDestP = gridDestination_->getDomains();
138  if (!domListDestP.empty())
139  {
140    if (domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->hasTransformation())
141    {
142      CDomain::TransMapTypes trans = domListDestP[elementPosition2DomainPositionInGrid_[domPositionInGrid]]->getAllTransformations();
143      CDomain::TransMapTypes::const_iterator itb = trans.begin(), it,
144                                             ite = trans.end();
145      int transformationOrder = 0;
146      for (it = itb; it != ite; ++it)
147      {
148        listAlgos_.push_back(std::make_pair(domPositionInGrid, std::make_pair(it->first, transformationOrder)));
149        algoTypes_.push_back(true);
150        ++transformationOrder;
151      }
152    }
153  }
154
155}
156
157/*!
158  Select algorithm correspoding to its transformation type and its position in each element
159  \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)
160                                             and position of axis is 2
161  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
162  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
163  \param [in] isDomainAlgo flag to specify type of algorithm (for domain or axis)
164*/
165void CGridGenerate::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder, bool isDomainAlgo)
166{
167   if (isDomainAlgo) selectDomainAlgo(elementPositionInGrid, transType, transformationOrder);
168   else selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
169}
170
171/*!
172  Select algorithm of an axis correspoding to its transformation type and its position in each element
173  \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)
174                                             and position of axis is 2
175  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
176  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
177*/
178void CGridGenerate::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
179{
180  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
181  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
182
183  int axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
184  CAxis::TransMapTypes trans = axisListDestP[axisIndex]->getAllTransformations();
185  CAxis::TransMapTypes::const_iterator it = trans.begin();
186
187  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
188
189  CGenericAlgorithmTransformation* algo = 0;
190  switch (transType)
191  {
192    default:
193    break;
194  }
195  algoTransformation_.push_back(algo);
196
197}
198
199/*!
200  Select algorithm of a domain correspoding to its transformation type and its position in each element
201  \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)
202                                             and position of axis is 2
203  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
204  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
205*/
206void CGridGenerate::selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
207{
208  std::vector<CDomain*> domainListDestP = gridDestination_->getDomains();
209  std::vector<CDomain*> domainListSrcP = gridSource_->getDomains();
210
211  int domainIndex =  elementPosition2DomainPositionInGrid_[elementPositionInGrid];
212  CDomain::TransMapTypes trans = domainListDestP[domainIndex]->getAllTransformations();
213  CDomain::TransMapTypes::const_iterator it = trans.begin();
214
215  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
216
217  CGenerateRectilinearDomain* genRectDomain = 0;
218  CGenericAlgorithmTransformation* algo = 0;
219  switch (transType)
220  {
221    case TRANS_GENERATE_RECTILINEAR_DOMAIN:
222      if (0 == transformationOrder)
223      {
224        genRectDomain = dynamic_cast<CGenerateRectilinearDomain*> (it->second);
225        algo = new CDomainAlgorithmGenerateRectilinear(domainListDestP[domainIndex], domainListSrcP[domainIndex], gridSource_, genRectDomain);
226      }
227      else
228      {
229         ERROR("CGridGenerate::selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)",
230           << "Generate rectilinear domain must be the first transformation");
231      }
232      break;
233    default:
234      break;
235  }
236  algoTransformation_.push_back(algo);
237}
238
239/*!
240
241*/
242void CGridGenerate::completeGrid()
243{
244  CContext* context = CContext::getCurrent();
245  CContextClient* client = context->client;
246
247  ListAlgoType::const_iterator itb = listAlgos_.begin(),
248                               ite = listAlgos_.end(), it;
249  CGenericAlgorithmTransformation* algo = 0;
250
251  for (it = itb; it != ite; ++it)
252  {
253    int elementPositionInGrid = it->first;
254    ETranformationType transType = (it->second).first;
255    int transformationOrder = (it->second).second;
256
257    // First of all, select an algorithm
258    selectAlgo(elementPositionInGrid, transType, transformationOrder, algoTypes_[std::distance(itb, it)]);
259  }
260}
261
262}
Note: See TracBrowser for help on using the repository browser.