source: XIOS/trunk/src/transformation/grid_transformation.cpp @ 624

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

Final tests of zoom and inverse on axis

+) Modify test_client and test_complete to work with new grid definition
+) Correct some bugs causing memory leak
+) Clean abundant code
+) Add more comments to new files

Test
+) On Curie
+) test_client and test_complete pass with correct results

File size: 24.1 KB
Line 
1/*!
2   \file grid_transformation.cpp
3   \author Ha NGUYEN
4   \since 14 May 2015
5   \date 18 June 2015
6
7   \brief Interface for all transformations.
8 */
9#include "grid_transformation.hpp"
10#include "axis_algorithm_inverse.hpp"
11#include "axis_algorithm_zoom.hpp"
12#include "context.hpp"
13#include "context_client.hpp"
14#include "transformation_mapping.hpp"
15
16#include "axis_algorithm_transformation.hpp"
17
18namespace xios {
19CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)
20: gridSource_(source), gridDestination_(destination), originalGridSource_(source),
21  globalIndexOfCurrentGridSource_(0), globalIndexOfOriginalGridSource_(0)
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("CGridTransformation::CGridTransformation(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
31  for (int i = 0; i < numElement; ++i)
32  {
33    if (gridDestination_->axis_domain_order(i) != gridSource_->axis_domain_order(i))
34      ERROR("CGridTransformation::CGridTransformation(CGrid* destination, CGrid* source)",
35         << "Transformed grid and its grid source have incompatible elements"
36         << "Grid source " <<gridSource_->getId() << std::endl
37         << "Grid destination " <<gridDestination_->getId());
38  }
39
40  std::vector<CAxis*> axisSrcTmp = gridSource_->getAxis(), axisSrc;
41  std::vector<CDomain*> domainSrcTmp = gridSource_->getDomains(), domainSrc;
42  for (int idx = 0; idx < axisSrcTmp.size(); ++idx)
43  {
44    CAxis* axis = CAxis::createAxis();
45    axis->setAttributes(axisSrcTmp[idx]);
46    axisSrc.push_back(axis);
47  }
48
49  for (int idx = 0; idx < domainSrcTmp.size(); ++idx)
50  {
51    CDomain* domain = CDomain::createDomain();
52    domain->setAttributes(domainSrcTmp[idx]);
53    domainSrc.push_back(domain);
54  }
55
56  gridSource_ = CGrid::createGrid(domainSrc, axisSrc, gridDestination_->axis_domain_order);
57  gridSourceDimensionSize_ = gridSource_->getGlobalDimension();
58  gridDestinationDimensionSize_ = gridDestination_->getGlobalDimension();
59
60  initializeMappingOfOriginalGridSource();
61  initializeAlgorithms();
62}
63
64/*!
65  Initialize the mapping between the first grid source and the original one
66  In a series of transformation, for each step, there is a need to "create" a new grid that plays a role of "temporary" source.
67Because at the end of the series, we need to know about the index mapping between the final grid destination and original grid source,
68for each transformation, we need to make sure that the current "temporary source" maps its global index correctly to the original one.
69*/
70void CGridTransformation::initializeMappingOfOriginalGridSource()
71{
72  CContext* context = CContext::getCurrent();
73  CContextClient* client=context->client;
74
75  CDistributionClient distribution(client->clientRank, originalGridSource_);
76  const CArray<size_t,1>& globalIndexGridDestSendToServer = distribution.getGlobalDataIndexSendToServer();
77
78  globalIndexOfCurrentGridSource_   = new CArray<size_t,1>(globalIndexGridDestSendToServer.numElements());
79  globalIndexOfOriginalGridSource_  = new CArray<size_t,1>(globalIndexGridDestSendToServer.numElements());
80  *globalIndexOfCurrentGridSource_  = globalIndexGridDestSendToServer;
81  *globalIndexOfOriginalGridSource_ = globalIndexGridDestSendToServer;
82}
83
84CGridTransformation::~CGridTransformation()
85{
86  std::list<CGenericAlgorithmTransformation*>::const_iterator itb = algoTransformation_.begin(), it,
87                                                              ite = algoTransformation_.end();
88  for (it = itb; it != ite; ++it) delete (*it);
89
90  std::map<int, std::vector<CArray<int,1>* > >::const_iterator itMapRecv, iteMapRecv;
91  itMapRecv = localIndexToReceiveOnGridDest_.begin();
92  iteMapRecv = localIndexToReceiveOnGridDest_.end();
93  for (; itMapRecv != iteMapRecv; ++itMapRecv)
94  {
95    int numVec = (itMapRecv->second).size();
96    for (int idx = 0; idx < numVec; ++idx) delete (itMapRecv->second)[idx];
97  }
98
99  std::map<int, CArray<int,1>* >::const_iterator itMap, iteMap;
100  itMap = localIndexToSendFromGridSource_.begin();
101  iteMap = localIndexToSendFromGridSource_.end();
102  for (; itMap != iteMap; ++itMap) delete (itMap->second);
103
104  if (0 != globalIndexOfCurrentGridSource_) delete globalIndexOfCurrentGridSource_;
105  if (0 != globalIndexOfOriginalGridSource_) delete globalIndexOfOriginalGridSource_;
106}
107
108/*!
109  Initialize the algorithms (transformations)
110*/
111void CGridTransformation::initializeAlgorithms()
112{
113  initializeAxisAlgorithms();
114  initializeDomainAlgorithms();
115}
116
117/*!
118  Initialize the algorithms corresponding to transformation info contained in each axis.
119If an axis has transformations, these transformations will be represented in form of vector of CTransformation pointers
120In general, each axis can have several transformations performed on itself. However, should they be done seperately or combinely (of course in order)?
121For now, one approach is to do these combinely but maybe this needs changing.
122*/
123void CGridTransformation::initializeAxisAlgorithms()
124{
125  std::vector<int> axisPositionInGrid;
126  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
127  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
128  if (!axisListDestP.empty())
129  {
130    int idx = 0;
131    for (int i = 0; i < gridDestination_->axis_domain_order.numElements(); ++i)
132    {
133      if (false == (gridDestination_->axis_domain_order)(i))
134      {
135        axisPositionInGrid.push_back(idx);
136        ++idx;
137      }
138      else idx += 2;
139    }
140
141    for (int i = 0; i < axisListDestP.size(); ++i)
142    {
143      elementPosition2AxisPositionInGrid_[axisPositionInGrid[i]] = i;
144      if (axisListDestP[i]->hasTransformation())
145      {
146        CAxis::TransMapTypes trans = axisListDestP[i]->getAllTransformations();
147        CAxis::TransMapTypes::const_iterator itb = trans.begin(), it,
148                                             ite = trans.end();
149        int transformationOrder = 0;
150        for (it = itb; it != ite; ++it)
151        {
152          listAlgos_.push_back(std::make_pair(axisPositionInGrid[i], std::make_pair(it->first, transformationOrder)));
153          ++transformationOrder;
154        }
155      }
156    }
157  }
158}
159
160void CGridTransformation::initializeDomainAlgorithms()
161{
162
163}
164
165/*!
166  Select algorithm correspoding to its transformation type and its position in each element
167  \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)
168                                             and position of axis is 2
169  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
170  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
171*/
172void CGridTransformation::selectAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
173{
174   selectAxisAlgo(elementPositionInGrid, transType, transformationOrder);
175}
176
177/*!
178  Select algorithm of an axis correspoding to its transformation type and its position in each element
179  \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)
180                                             and position of axis is 2
181  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
182  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
183*/
184void CGridTransformation::selectAxisAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
185{
186  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
187  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
188
189  int axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
190  CAxis::TransMapTypes trans = axisListDestP[axisIndex]->getAllTransformations();
191  CAxis::TransMapTypes::const_iterator it = trans.begin();
192
193  for (int i = 0; i < transformationOrder; ++i, ++it) {}  // Find the correct transformation
194
195  CZoomAxis* zoomAxis = 0;
196  CGenericAlgorithmTransformation* algo = 0;
197  switch (transType)
198  {
199    case TRANS_ZOOM_AXIS:
200      zoomAxis = dynamic_cast<CZoomAxis*> (it->second);
201      algo = new CAxisAlgorithmZoom(axisListDestP[axisIndex], axisListSrcP[axisIndex], zoomAxis);
202      break;
203    case TRANS_INVERSE_AXIS:
204      algo = new CAxisAlgorithmInverse(axisListDestP[axisIndex], axisListSrcP[axisIndex]);
205      break;
206    default:
207      break;
208  }
209  algoTransformation_.push_back(algo);
210
211}
212
213/*!
214  Select algorithm of a domain correspoding to its transformation type and its position in each element
215  \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)
216                                             and position of axis is 2
217  \param [in] transType transformation type, for now we have Zoom_axis, inverse_axis
218  \param [in] transformationOrder position of the transformation in an element (an element can have several transformation)
219*/
220void CGridTransformation::selectDomainAlgo(int elementPositionInGrid, ETranformationType transType, int transformationOrder)
221{
222}
223
224/*!
225  Assign the current grid destination to the grid source in the new transformation.
226The current grid destination plays the role of grid source in next transformation (if any).
227Only element on which the transformation is performed is modified
228  \param [in] elementPositionInGrid position of element in grid
229  \param [in] transType transformation type
230*/
231void CGridTransformation::setUpGrid(int elementPositionInGrid, ETranformationType transType)
232{
233  std::vector<CAxis*> axisListDestP = gridDestination_->getAxis();
234  std::vector<CAxis*> axisListSrcP = gridSource_->getAxis();
235
236  int axisIndex;
237  switch (transType)
238  {
239    case TRANS_ZOOM_AXIS:
240    case TRANS_INVERSE_AXIS:
241      axisIndex =  elementPosition2AxisPositionInGrid_[elementPositionInGrid];
242      axisListSrcP[axisIndex]->duplicateAttributes(axisListDestP[axisIndex]);
243      break;
244    default:
245      break;
246  }
247}
248
249/*!
250  Perform all transformations
251  For each transformation, there are some things to do:
252  -) Chose the correct algorithm by transformation type and position of element
253  -) Calculate the mapping of global index between the current grid source and grid destination
254  -) Calculate the mapping of global index between current grid DESTINATION and ORIGINAL grid SOURCE
255  -) Make current grid destination become grid source in the next transformation
256*/
257void CGridTransformation::computeAll()
258{
259  CContext* context = CContext::getCurrent();
260  CContextClient* client=context->client;
261
262  ListAlgoType::const_iterator itb = listAlgos_.begin(),
263                               ite = listAlgos_.end(), it;
264  CGenericAlgorithmTransformation* algo = 0;
265  for (it = itb; it != ite; ++it)
266  {
267    std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource;
268    int elementPositionInGrid = it->first;
269    ETranformationType transType = (it->second).first;
270    int transformationOrder = (it->second).second;
271
272    // First of all, select an algorithm
273    selectAlgo(elementPositionInGrid, transType, transformationOrder);
274    algo = algoTransformation_.back();
275
276    // Recalculate the distribution of grid destination
277    CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
278    const CArray<size_t,1>& globalIndexGridDestSendToServer = distributionClientDest.getGlobalDataIndexSendToServer();
279
280    // ComputeTransformation of global index of each element
281    std::vector<int> gridDestinationDimensionSize = gridDestination_->getGlobalDimension();
282    int elementPosition = it->first;
283    algo->computeGlobalSourceIndex(elementPosition,
284                                   gridDestinationDimensionSize,
285                                   globalIndexGridDestSendToServer,
286                                   globaIndexMapFromDestToSource);
287
288    // Compute transformation of global indexes among grids
289    computeTransformationFromOriginalGridSource(globaIndexMapFromDestToSource);
290
291    // Now grid destination becomes grid source in a new transformation
292    setUpGrid(elementPositionInGrid, transType);
293  }
294
295  updateFinalGridDestination();
296  computeFinalTransformationMapping();
297}
298
299
300/*!
301  After applying the algorithms, there are some informations on grid destination needing change, for now, there are:
302   +) mask
303*/
304void CGridTransformation::updateFinalGridDestination()
305{
306  CContext* context = CContext::getCurrent();
307  CContextClient* client=context->client;
308
309  //First of all, retrieve info of local mask of grid destination
310  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
311  const CArray<int, 1>& localMaskIndexOnClientDest = distributionClientDest.getLocalMaskIndexOnClient();
312  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
313
314  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
315  itbArr = globalIndexOnClientDest.begin();
316  iteArr = globalIndexOnClientDest.end();
317
318  // Then find out which index became invalid (become masked after being applied the algorithms, or demande some masked points from grid source)
319  int num = globalIndexOfOriginalGridSource_->numElements();
320  const size_t sfmax = NumTraits<unsigned long>::sfmax();
321  int maskIndexNum = 0;
322  for (int idx = 0; idx < num; ++idx)
323  {
324    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
325    {
326      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
327      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
328      if (iteArr != itArr) ++maskIndexNum;
329    }
330  }
331
332  CArray<int,1>* maskIndexToModify = new CArray<int,1>(maskIndexNum);
333  maskIndexNum = 0;
334  for (int idx = 0; idx < num; ++idx)
335  {
336    if (sfmax == (*globalIndexOfOriginalGridSource_)(idx))
337    {
338      size_t maskedGlobalIndex = (*globalIndexOfCurrentGridSource_)(idx);
339      itArr = std::find(itbArr, iteArr, maskedGlobalIndex);
340      if (iteArr != itArr)
341      {
342        int localIdx = std::distance(itbArr, itArr);
343        (*maskIndexToModify)(maskIndexNum) = (localMaskIndexOnClientDest)(localIdx);
344        ++maskIndexNum;
345      }
346    }
347  }
348
349  gridDestination_->modifyMask(*maskIndexToModify);
350
351  delete maskIndexToModify;
352}
353
354/*!
355  A transformation from a grid source to grid destination often passes several intermediate grids, which play a role of
356temporary grid source and/or grid destination. This function makes sure that global index of original grid source are mapped correctly to
357the final grid destination
358*/
359void CGridTransformation::computeTransformationFromOriginalGridSource(const std::map<size_t, std::set<size_t> >& globaIndexMapFromDestToSource)
360{
361  CContext* context = CContext::getCurrent();
362  CContextClient* client=context->client;
363
364  CTransformationMapping transformationMap(gridDestination_, gridSource_);
365
366    // Then compute transformation mapping among clients
367  transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
368
369  const std::map<int,std::vector<std::vector<size_t> > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
370  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
371
372 // Sending global index of original grid source
373  std::map<int,std::vector<size_t> >::const_iterator itbSend = globalIndexToSend.begin(), itSend,
374                                                     iteSend = globalIndexToSend.end();
375  CArray<size_t,1>::const_iterator itbArr = globalIndexOfCurrentGridSource_->begin(), itArr,
376                                   iteArr = globalIndexOfCurrentGridSource_->end();
377 int sendBuffSize = 0;
378 for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
379
380 typedef unsigned long Scalar;
381 unsigned long* sendBuff, *currentSendBuff;
382 if (0 != sendBuffSize) sendBuff = new unsigned long [sendBuffSize];
383 for (StdSize idx = 0; idx < sendBuffSize; ++idx) sendBuff[idx] = NumTraits<Scalar>::sfmax();
384
385 int currentBuffPosition = 0;
386 for (itSend = itbSend; itSend != iteSend; ++itSend)
387 {
388   int destRank = itSend->first;
389   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
390   int countSize = globalIndexOfCurrentGridSourceToSend.size();
391   for (int idx = 0; idx < (countSize); ++idx)
392   {
393     itArr = std::find(itbArr, iteArr, globalIndexOfCurrentGridSourceToSend[idx]);
394     if (iteArr != itArr)
395     {
396       int index = std::distance(itbArr, itArr);
397       sendBuff[idx+currentBuffPosition] = (*globalIndexOfOriginalGridSource_)(index);
398     }
399   }
400   currentSendBuff = sendBuff + currentBuffPosition;
401   MPI_Send(currentSendBuff, countSize, MPI_UNSIGNED_LONG, destRank, 14, client->intraComm);
402   currentBuffPosition += countSize;
403 }
404
405 // Receiving global index of grid source sending from current grid source
406 std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
407                                                                  iteRecv = globalIndexToReceive.end();
408 int recvBuffSize = 0;
409 for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size();
410
411 unsigned long* recvBuff, *currentRecvBuff;
412 if (0 != recvBuffSize) recvBuff = new unsigned long [recvBuffSize];
413 for (StdSize idx = 0; idx < recvBuffSize; ++idx) recvBuff[idx] = NumTraits<Scalar>::sfmax();
414
415 int currentRecvBuffPosition = 0;
416 for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
417 {
418   MPI_Status status;
419   int srcRank = itRecv->first;
420   int countSize = (itRecv->second).size();
421   currentRecvBuff = recvBuff + currentRecvBuffPosition;
422   MPI_Recv(currentRecvBuff, countSize, MPI_UNSIGNED_LONG, srcRank, 14, client->intraComm, &status);
423   currentRecvBuffPosition += countSize;
424 }
425
426 int nbCurrentGridSource = 0;
427 for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
428 {
429   int ssize = (itRecv->second).size();
430   for (int idx = 0; idx < ssize; ++idx)
431   {
432     nbCurrentGridSource += (itRecv->second)[idx].size();
433   }
434 }
435
436 if (globalIndexOfCurrentGridSource_->numElements()  != nbCurrentGridSource)
437 {
438   delete globalIndexOfCurrentGridSource_;
439   globalIndexOfCurrentGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
440 }
441
442 if (globalIndexOfOriginalGridSource_->numElements() != nbCurrentGridSource)
443 {
444   delete globalIndexOfOriginalGridSource_;
445   globalIndexOfOriginalGridSource_ = new CArray<size_t,1>(nbCurrentGridSource);
446 }
447
448 int k = 0;
449 currentRecvBuff = recvBuff;
450 for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
451 {
452   int countSize = (itRecv->second).size();
453   for (int idx = 0; idx < countSize; ++idx, ++currentRecvBuff)
454   {
455     int ssize = (itRecv->second)[idx].size();
456     for (int i = 0; i < ssize; ++i)
457     {
458       (*globalIndexOfCurrentGridSource_)(k) = (itRecv->second)[idx][i];
459       (*globalIndexOfOriginalGridSource_)(k) = *currentRecvBuff;
460       ++k;
461     }
462   }
463 }
464
465 if (0 != sendBuffSize) delete [] sendBuff;
466 if (0 != recvBuffSize) delete [] recvBuff;
467}
468
469/*!
470  Compute transformation mapping between grid source and grid destination
471  The transformation between grid source and grid destination is represented in form of mapping between global index
472of two grids. Then local index mapping between data on each grid will be found out thanks to these global indexes
473*/
474void CGridTransformation::computeFinalTransformationMapping()
475{
476  CContext* context = CContext::getCurrent();
477  CContextClient* client=context->client;
478
479  CTransformationMapping transformationMap(gridDestination_, originalGridSource_);
480
481  std::map<size_t, std::set<size_t> > globaIndexMapFromDestToSource;
482
483  int nb = globalIndexOfCurrentGridSource_->numElements();
484  const size_t sfmax = NumTraits<unsigned long>::sfmax();
485  for (int idx = 0; idx < nb; ++idx)
486  {
487    if (sfmax != (*globalIndexOfOriginalGridSource_)(idx))
488      globaIndexMapFromDestToSource[(*globalIndexOfCurrentGridSource_)(idx)].insert((*globalIndexOfOriginalGridSource_)(idx));
489  }
490
491  // Then compute transformation mapping among clients
492  transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
493
494  const std::map<int,std::vector<std::vector<size_t> > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
495  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
496
497  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
498  CDistributionClient distributionClientSrc(client->clientRank, originalGridSource_);
499
500//  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexOnClient(); //gridDestination_->getDistributionClient()->getLocalDataIndexOnClient();
501  const CArray<int, 1>& localIndexOnClientDest = distributionClientDest.getLocalDataIndexSendToServer();
502  const CArray<size_t,1>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer(); //gridDestination_->getDistributionClient()->getGlobalDataIndexSendToServer();
503
504  const CArray<int, 1>& localIndexOnClientSrc = distributionClientSrc.getLocalDataIndexOnClient(); //gridSource_->getDistributionClient()->getLocalDataIndexOnClient();
505  const CArray<size_t,1>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
506
507  std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
508  CArray<size_t, 1>::const_iterator itbArr, itArr, iteArr;
509
510  std::map<int,std::vector<std::vector<size_t> > >::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
511
512  // Find out local index on grid destination (received)
513  itbMapRecv = globalIndexToReceive.begin();
514  iteMapRecv = globalIndexToReceive.end();
515  itbArr = globalIndexOnClientDest.begin();
516  iteArr = globalIndexOnClientDest.end();
517  for (itMapRecv = itbMapRecv; itMapRecv != iteMapRecv; ++itMapRecv)
518  {
519    int sourceRank = itMapRecv->first;
520    int numGlobalIndex = (itMapRecv->second).size();
521    for (int i = 0; i < numGlobalIndex; ++i)
522    {
523      int vecSize = ((itMapRecv->second)[i]).size();
524      CArray<int,1>* ptr = new CArray<int,1>(vecSize);
525      localIndexToReceiveOnGridDest_[sourceRank].push_back(ptr);
526      for (int idx = 0; idx < vecSize; ++idx)
527      {
528        itArr = std::find(itbArr, iteArr, (itMapRecv->second)[i][idx]);
529        if (iteArr != itArr)
530        {
531          int localIdx = std::distance(itbArr, itArr);
532//          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = localIndexOnClientDest(localIdx); // Local index of un-extracted data (only domain)
533          (*localIndexToReceiveOnGridDest_[sourceRank][i])(idx) = (localIdx); // Local index of extracted data
534        }
535      }
536    }
537  }
538
539  std::map<int,std::vector<size_t> >::const_iterator itbMap, itMap, iteMap;
540  // Find out local index on grid source (to send)
541  itbMap = globalIndexToSend.begin();
542  iteMap = globalIndexToSend.end();
543  itbArr = globalIndexOnClientSrc.begin();
544  iteArr = globalIndexOnClientSrc.end();
545  for (itMap = itbMap; itMap != iteMap; ++itMap)
546  {
547    CArray<int,1>* ptr = new CArray<int,1>((itMap->second).size());
548    localIndexToSendFromGridSource_[itMap->first] = ptr;
549    int destRank = itMap->first;
550    int vecSize = (itMap->second).size();
551    for (int idx = 0; idx < vecSize; ++idx)
552    {
553      itArr = std::find(itbArr, iteArr, (itMap->second)[idx]);
554      if (iteArr != itArr)
555      {
556        int localIdx = std::distance(itbArr, itArr);
557//        (*localIndexToSendFromGridSource_[destRank])(idx) = localIndexOnClientSrc(localIdx);
558        (*localIndexToSendFromGridSource_[destRank])(idx) = (localIdx);
559      }
560    }
561  }
562}
563
564/*!
565  Local index of data which need sending from the grid source
566  \return local index of data
567*/
568const std::map<int, CArray<int,1>* >& CGridTransformation::getLocalIndexToSendFromGridSource() const
569{
570  return localIndexToSendFromGridSource_;
571}
572
573/*!
574  Local index of data which will be received on the grid destination
575  \return local index of data
576*/
577const std::map<int, std::vector<CArray<int,1>* > >& CGridTransformation::getLocalIndexToReceiveOnGridDest() const
578{
579  return localIndexToReceiveOnGridDest_;
580}
581
582}
Note: See TracBrowser for help on using the repository browser.