source: XIOS/trunk/src/filter/grid_transformation.cpp @ 621

Last change on this file since 621 was 621, checked in by mhnguyen, 6 years ago

Implementing generic transformation algorithm (local commit)

+) Change a little bit to make sure everything work in order

Test
+) test_new_features passe with inverse

File size: 9.6 KB
Line 
1#include "grid_transformation.hpp"
2#include "axis_inverse.hpp"
3#include "transformation_mapping.hpp"
4#include "transformation_enum.hpp"
5#include "axis_algorithm_transformation.hpp"
6
7namespace xios {
8CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)
9: gridSource_(source), gridDestination_(destination)
10{
11  //Verify the compatibity between two grids
12  int numElement = gridDestination_->axis_domain_order.numElements();
13  if (numElement != gridSource_->axis_domain_order.numElements())
14    ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
15       << "Two grids have different number of elements"
16       << "Number of elements of grid source " <<gridSource_->getId() << " is " << gridSource_->axis_domain_order.numElements()  << std::endl
17       << "Number of elements of grid destination " <<gridDestination_->getId() << " is " << numElement);
18
19  for (int i = 0; i < numElement; ++i)
20  {
21    if (gridDestination_->axis_domain_order(i) != gridSource_->axis_domain_order(i))
22      ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
23         << "Transformed grid and its grid source have incompatible elements"
24         << "Grid source " <<gridSource_->getId() << std::endl
25         << "Grid destination " <<gridDestination_->getId());
26  }
27
28  gridSourceDimensionSize_ = gridSource_->getGlobalDimension();
29  gridDestinationDimensionSize_ = gridDestination_->getGlobalDimension();
30  initializeAlgorithms();
31}
32
33CGridTransformation::~CGridTransformation()
34{
35  std::map<int, std::vector<CGenericAlgorithmTransformation*> >::const_iterator itb = algoTransformation_.begin(), it,
36                                                                                ite = algoTransformation_.end();
37  for (it = itb; it != ite; ++it)
38    for (int idx = 0; idx < (it->second).size(); ++idx)
39      delete (it->second)[idx];
40
41  std::map<int, std::vector<CArray<int,1>* > >::const_iterator itMapRecv, iteMapRecv;
42  itMapRecv = localIndexToReceiveOnGridDest_.begin();
43  iteMapRecv = localIndexToReceiveOnGridDest_.end();
44  for (; itMapRecv != iteMapRecv; ++itMapRecv)
45  {
46    int numVec = (itMapRecv->second).size();
47    for (int idx = 0; idx < numVec; ++idx) delete (itMapRecv->second)[idx];
48  }
49
50  std::map<int, CArray<int,1>* >::const_iterator itMap, iteMap;
51  itMap = localIndexToSendFromGridSource_.begin();
52  iteMap = localIndexToSendFromGridSource_.end();
53  for (; itMap != iteMap; ++itMap) delete (itMap->second);
54}
55
56void CGridTransformation::initializeAlgorithms()
57{
58  initializeAxisAlgorithms();
59  initializeDomainAlgorithms();
60}
61
62/*!
63  Initialize the algorithms corresponding to transformation info contained in each axis.
64If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
65In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
66For now, one approach is to do these combinely but maybe this needs changing.
67*/
68void CGridTransformation::initializeAxisAlgorithms()
69{
70  std::vector<int> axisPositionInGrid;
71  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
72  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
73  if (!axisListDestP.empty())
74  {
75    int idx = 0;
76    for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
77    {
78      if (false == (gridDestination_->axis_domain_order)(i))
79      {
80        axisPositionInGrid.push_back(idx);
81        ++idx;
82      }
83      else idx += 2;
84    }
85
86    for (int i = 0; i < axisListDestP.size(); ++i)
87    {
88      if (axisListDestP[i]->hasTransformation())
89      {
90        CGenericAlgorithmTransformation* algo = 0;
91        CAxis::TransMapTypes trans = axisListDestP[i]->getAllTransformations();
92        CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
93                                             ite = trans.end();
94        std::vector<ETranformationType> algoAxis;
95        for (it = itb; it != ite; ++it)
96        {
97          algoAxis.push_back(it->first);
98        }
99        algo = new CAxisAlgorithmTransformation(axisListDestP[i], axisListSrcP[i], algoAxis);
100        algoTransformation_[axisPositionInGrid[i]].push_back(algo);
101      }
102    }
103  }
104}
105
106void CGridTransformation::initializeDomainAlgorithms()
107{
108
109}
110
111/*!
112  Compute index mapping representing transformation between two grids
113  Each domain and each axis can contain some information of transformation, these information are then converted into
114form of global index mapping reprensenting transformation between two grids.
115*/
116void CGridTransformation::computeTransformation()
117{
118  const CArray<size_t,1>& globalIndexGridDestSendToServer = gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
119  std::map<int, std::vector<CGenericAlgorithmTransformation*> >::const_iterator itbMap, itMap, iteMap;
120  itbMap = algoTransformation_.begin();
121  iteMap = algoTransformation_.end();
122
123  std::vector<CGenericAlgorithmTransformation*>::const_iterator itbVec, itVec, iteVec;
124
125  for (itMap = itbMap; itMap != iteMap; ++itMap)
126  {
127    int elementPosition = itMap->first;
128    itbVec = (itMap->second).begin();
129    iteVec = (itMap->second).end();
130    for (itVec = itbVec; itVec != iteVec; ++itVec)
131    {
132      (*itVec)->computeGlobalSourceIndex(elementPosition,
133                                         gridDestinationDimensionSize_,
134                                         globalIndexGridDestSendToServer,
135                                         globaIndexMapFromDestToSource_);
136    }
137  }
138}
139
140/*!
141  Compute transformation mapping between grid source and grid destination
142  The transformation between grid source and grid destination is represented in form of mapping between global index
143of two grids. Then local index mapping between data on each grid will be found out thanks to these global indexes
144*/
145void CGridTransformation::computeTransformationMapping()
146{
147  CTransformationMapping transformationMap(gridDestination_, gridSource_);
148
149  // First of all, need to compute global index mapping representing transformation algorithms
150  computeTransformation();
151
152  // Then compute transformation mapping among clients
153  transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource_);
154
155  const std::map<int,std::vector<std::vector<size_t> > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
156  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
157
158  CArray<int, 1> localIndexOnClientDest = gridDestination_->getDistributionClient()->getLocalDataIndexOnClient();
159  CArray<size_t,1> globalIndexOnClientDest = gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
160
161  CArray<int, 1> localIndexOnClientSrc = gridSource_->getDistributionClient()->getLocalDataIndexOnClient();
162  CArray<size_t,1> globalIndexOnClientSrc = gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
163
164  std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
165  CArray<size_t, 1>::iterator itbArr, itArr, iteArr;
166
167  std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
168
169  // Find out local index on grid destination (received)
170  itbMapRecv = globalIndexToReceive.begin();
171  iteMapRecv = globalIndexToReceive.end();
172  itbArr = globalIndexOnClientDest.begin();
173  iteArr = globalIndexOnClientDest.end();
174  for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv)
175  {
176    int sourceRank = itMapRecv->first;
177    int numGlobalIndex = (itMapRecv->second).size();
178    for (int i = 0; i < numGlobalIndex; ++i)
179    {
180      int vecSize = ((itMapRecv->second)[i]).size();
181      CArray<int,1>* ptr = new CArray<int,1>(vecSize);
182      localIndexToReceiveOnGridDest_[sourceRank].push_back(ptr);
183      for (int idx = 0; idx < vecSize; ++idx)
184      {
185        itArr = std::find(itbArr, iteArr, (itMapRecv->second)[i][idx]);
186        if (iteArr != itArr)
187        {
188          int localIdx = std::distance(itbArr, itArr);
189//          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = localIndexOnClientDest(localIdx); // Local index of un-extracted data (only domain)
190          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = (localIdx); // Local index of extracted data
191        }
192      }
193    }
194  }
195
196  std::map<int,std::vector<size_t> >::const_iterator itbMap, itMap, iteMap;
197  // Find out local index on grid source (to send)
198  itbMap = globalIndexToSend.begin();
199  iteMap = globalIndexToSend.end();
200  itbArr = globalIndexOnClientSrc.begin();
201  iteArr = globalIndexOnClientSrc.end();
202  for (itMap = itbMap; itMap != iteMap; ++itMap)
203  {
204    CArray<int,1>* ptr = new CArray<int,1>((itMap->second).size());
205    localIndexToSendFromGridSource_[itMap->first] = ptr;
206    int destRank = itMap->first;
207    int vecSize = (itMap->second).size();
208    for (int idx = 0; idx < vecSize; ++idx)
209    {
210      itArr = std::find(itbArr, iteArr, (itMap->second)[idx]);
211      if (iteArr != itArr)
212      {
213        int localIdx = std::distance(itbArr, itArr);
214//        (*localIndexToSendFromGridSource_[destRank])(idx) = localIndexOnClientSrc(localIdx);
215        (*localIndexToSendFromGridSource_[destRank])(idx) = (localIdx);
216      }
217    }
218  }
219}
220
221/*!
222  Local index of data which need sending from the grid source
223  \return local index of data
224*/
225std::map<int, CArray<int,1>* > CGridTransformation::getLocalIndexToSendFromGridSource()
226{
227  return localIndexToSendFromGridSource_;
228}
229
230/*!
231  Local index of data which will be received on the grid destination
232  \return local index of data
233*/
234std::map<int, std::vector<CArray<int,1>* > > CGridTransformation::getLocalIndexToReceiveOnGridDest()
235{
236  return localIndexToReceiveOnGridDest_;
237}
238
239}
Note: See TracBrowser for help on using the repository browser.