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

Last change on this file since 827 was 775, checked in by mhnguyen, 8 years ago

Implementing the reading of attributes of an axis from a file

+) 3d grid can be read directly from a file
+) Clean some redundant codes
+) Add new attribute declaration that allows to output only desired attributes

Test
+) On Curie
+) test_remap passes and result is correct

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