source: XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp @ 918

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

Modifying vertical interpolation

+) Only process interpolation, the extrapolation will be ignored (value will be unidentified (masked))
+) Make sure even unidenfitified from one transformation can be known in the next transformation

Test
+) On Curie
+) Vertical interpolation: Correct
+) Vertical interpolation + horizontal interpolation: Correct

File size: 25.5 KB
Line 
1/*!
2   \file generic_algorithm_transformation.hpp
3   \author Ha NGUYEN
4   \since 14 May 2015
5   \date 21 Mars 2016
6
7   \brief Interface for all transformation algorithms.
8 */
9#include "generic_algorithm_transformation.hpp"
10#include "context.hpp"
11#include "context_client.hpp"
12#include "client_client_dht_template.hpp"
13
14namespace xios {
15
16CGenericAlgorithmTransformation::CGenericAlgorithmTransformation()
17 : transformationMapping_(), transformationWeight_(), transformationPosition_(), idAuxInputs_()
18{
19}
20
21void CGenericAlgorithmTransformation::apply(const std::vector<std::pair<int,double> >& localIndex,
22                                            const double* dataInput,
23                                            CArray<double,1>& dataOut,
24                                            std::vector<bool>& flagInitial,
25                                            const double& defaultValue)
26{
27  int nbLocalIndex = localIndex.size();
28  bool hasMissingValue = (0.0 != defaultValue) ? true : false;
29  if (hasMissingValue)
30  {
31    for (int idx = 0; idx < nbLocalIndex; ++idx)
32    {
33      if (defaultValue == *(dataInput + idx))
34      {
35        flagInitial[localIndex[idx].first] = false;
36      }
37      else
38      {
39        dataOut(localIndex[idx].first) += *(dataInput + idx) * localIndex[idx].second;
40      }
41    }
42
43    for (int idx = 0; idx < nbLocalIndex; ++idx)
44    {
45      if (!flagInitial[localIndex[idx].first])
46        dataOut(localIndex[idx].first) = defaultValue;
47    }
48  }
49  else
50  {
51    for (int idx = 0; idx < nbLocalIndex; ++idx)
52    {
53      dataOut(localIndex[idx].first) += *(dataInput + idx) * localIndex[idx].second;
54    }
55  }
56}
57
58void CGenericAlgorithmTransformation::computePositionElements(CGrid* dst, CGrid* src)
59{
60  int idxScalar = 0, idxAxis = 0, idxDomain = 0;
61  CArray<int,1> axisDomainOrderDst = dst->axis_domain_order;
62  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
63  {
64    int dimElement = axisDomainOrderDst(i);
65    if (2 == dimElement)
66    {
67      elementPositionInGridDst2DomainPosition_[i] = idxDomain;
68      ++idxDomain;
69    }
70    else if (1 == dimElement)
71    {
72      elementPositionInGridDst2AxisPosition_[i] = idxAxis;
73      ++idxAxis;
74    }
75    else
76    {
77      elementPositionInGridDst2ScalarPosition_[i] = idxScalar;
78      ++idxScalar;
79    }
80  }
81
82  idxScalar = idxAxis = idxDomain = 0;
83  CArray<int,1> axisDomainOrderSrc = src->axis_domain_order;
84  for (int i = 0; i < axisDomainOrderSrc.numElements(); ++i)
85  {
86    int dimElement = axisDomainOrderSrc(i);
87    if (2 == dimElement)
88    {
89      elementPositionInGridSrc2DomainPosition_[i] = idxDomain;
90      ++idxDomain;
91    }
92    else if (1 == dimElement)
93    {
94      elementPositionInGridSrc2AxisPosition_[i] = idxAxis;
95      ++idxAxis;
96    }
97    else
98    {
99      elementPositionInGridSrc2ScalarPosition_[i] = idxScalar;
100      ++idxScalar;
101    }
102  }
103}
104
105/*!
106  This function computes the global indexes of grid source, which the grid destination is in demand.
107  \param[in] elementPositionInGrid position of an element in a grid .E.g: if grid is composed of domain and axis (in order),
108                then position of axis in grid is 1 and domain is positioned at 0.
109  \param[in] gridSrc Grid source
110  \param[in] gridDst Grid destination
111  \param[in\out] globaIndexWeightFromSrcToDst mapping of each global index source and weight to index destination
112*/
113void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
114                                                               CGrid* gridSrc,
115                                                               CGrid* gridDst,
116                                                               SourceDestinationIndexMap& globaIndexWeightFromSrcToDst)
117 {
118  CContext* context = CContext::getCurrent();
119  CContextClient* client = context->client;
120  int nbClient = client->clientSize;
121
122  typedef boost::unordered_map<int, std::vector<std::pair<int,double> > > SrcToDstMap;
123
124  size_t indexSrcSize = 0;
125  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
126  {
127    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
128                                           iteTransMap = transformationMapping_[idxTrans].end();
129    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
130
131    itTransWeight = itbTransWeight;
132    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
133    {
134       indexSrcSize += (itTransMap->second).size();
135    }
136  }
137
138  bool isTransPosEmpty = transformationPosition_.empty();
139  CArray<size_t,1> transPos;
140  if (!isTransPosEmpty) transPos.resize(transformationMapping_.size());
141  CArray<size_t,1> indexSrc(indexSrcSize);
142  indexSrcSize = 0;
143  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
144  {
145    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
146                                           iteTransMap = transformationMapping_[idxTrans].end();
147    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
148
149    // Build mapping between global source element index and global destination element index.
150    itTransWeight = itbTransWeight;
151    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
152    {
153      const std::vector<int>& srcIndex = itTransMap->second;
154      for (int idx = 0; idx < srcIndex.size(); ++idx)
155      {
156        indexSrc(indexSrcSize) = srcIndex[idx];
157        ++indexSrcSize;
158      }
159    }
160
161    if (!isTransPosEmpty)
162    {
163      TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin();
164      transPos(idxTrans) = itPosMap->second[0];
165    }
166  }
167
168  // compute position of elements on grids
169  computePositionElements(gridDst, gridSrc);
170  std::vector<CScalar*> scalarListDestP = gridDst->getScalars();
171  std::vector<CAxis*> axisListDestP = gridDst->getAxis();
172  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
173  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
174  std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars();
175  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
176  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
177  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;
178
179  // Find out global index source of transformed element on corresponding process.
180  std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnProc(axisDomainDstOrder.numElements());
181  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc;
182  int axisIndex = 0, domainIndex = 0;
183  for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)
184  {
185    if (idx == elementPositionInGrid)
186      computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc); //globalElementIndexOnProc[idx]);
187    if (2 == axisDomainDstOrder(idx)) // It's domain
188    {
189      if (idx != elementPositionInGrid)
190        computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]],
191                                   domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]],
192                                   transPos,
193                                   globalElementIndexOnProc[idx]);
194      ++domainIndex;
195
196    }
197    else if (1 == axisDomainDstOrder(idx))//it's an axis
198    {
199      if (idx != elementPositionInGrid)
200        computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]],
201                                 axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]],
202                                 transPos,
203                                 globalElementIndexOnProc[idx]);
204      ++axisIndex;
205
206    }
207    else //it's a scalar
208    {
209      if (idx != elementPositionInGrid)
210        computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]],
211                                   scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]],
212                                   transPos,
213                                   globalElementIndexOnProc[idx]);
214
215    }
216  }
217
218  if (!isTransPosEmpty)
219  {
220    for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)
221    {
222      if (idx != elementPositionInGrid)
223      {
224        boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it,
225                                                                 ite = globalElementIndexOnProc[idx].end();
226        for (it = itb; it != ite; ++it) it->second.resize(1);
227      }
228    }
229  }
230
231  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
232  {
233    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
234                                           iteTransMap = transformationMapping_[idxTrans].end();
235    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
236    SrcToDstMap src2DstMap;
237    src2DstMap.rehash(std::ceil(transformationMapping_[idxTrans].size()/src2DstMap.max_load_factor()));
238
239    // Build mapping between global source element index and global destination element index.
240    boost::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc[elementPositionInGrid]);
241    boost::unordered_map<int,int> tmpCounter;
242    itTransWeight = itbTransWeight;
243    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
244    {
245      const std::vector<int>& srcIndex = itTransMap->second;
246      const std::vector<double>& weight = itTransWeight->second;
247      for (int idx = 0; idx < srcIndex.size(); ++idx)
248      {
249        src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx]));
250        if (1 == globalIndexOfTransformedElementOnProc.count(srcIndex[idx]) && (0 == tmpCounter.count(srcIndex[idx])))
251        {
252          tmpCounter[srcIndex[idx]] = 1;
253          std::vector<int>& srcProc = globalIndexOfTransformedElementOnProc[srcIndex[idx]];
254          for (int j = 0; j < srcProc.size(); ++j)
255            globalElementIndexOnProc[elementPositionInGrid][srcProc[j]].push_back(srcIndex[idx]);
256        }
257      }
258    }
259
260    if (!isTransPosEmpty)
261    {
262      for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)
263      {
264        if (idx != elementPositionInGrid)
265        {
266          boost::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc[idx].begin(), it,
267                                                                   ite = globalElementIndexOnProc[idx].end();
268          for (it = itb; it != ite; ++it) it->second[0] = transPos(idxTrans);
269        }
270      }
271    }
272
273    std::vector<std::vector<bool> > elementOnProc(axisDomainDstOrder.numElements(), std::vector<bool>(nbClient, false));
274    boost::unordered_map<int,std::vector<size_t> >::const_iterator it, itb, ite;
275    for (int idx = 0; idx < globalElementIndexOnProc.size(); ++idx)
276    {
277      itb = globalElementIndexOnProc[idx].begin();
278      ite = globalElementIndexOnProc[idx].end();
279      for (it = itb; it != ite; ++it) elementOnProc[idx][it->first] = true;
280    }
281
282    // Determine procs which contain global source index
283    std::vector<bool> intersectedProc(nbClient, true);
284    for (int idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)
285    {
286      std::transform(elementOnProc[idx].begin(), elementOnProc[idx].end(),
287                     intersectedProc.begin(), intersectedProc.begin(),
288                     std::logical_and<bool>());
289    }
290
291    std::vector<int> srcRank;
292    for (int idx = 0; idx < nbClient; ++idx)
293    {
294      if (intersectedProc[idx]) srcRank.push_back(idx);
295    }
296
297    // Ok, now compute global index of grid source and ones of grid destination
298    computeGlobalGridIndexMapping(elementPositionInGrid,
299                                  srcRank,
300                                  src2DstMap,
301                                  gridSrc,
302                                  gridDst,
303                                  globalElementIndexOnProc,
304                                  globaIndexWeightFromSrcToDst);
305  }
306 }
307
308/*!
309  Compute mapping of global index of grid source and grid destination
310  \param [in] elementPositionInGrid position of element in grid. E.x: grid composed of domain and axis, domain has position 0 and axis 1.
311  \param [in] srcRank rank of client from which we demand global index of element source
312  \param [in] src2DstMap mapping of global index of element source and global index of element destination
313  \param[in] gridSrc Grid source
314  \param[in] gridDst Grid destination
315  \param[in] globalElementIndexOnProc Global index of element source on different client rank
316  \param[out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination
317*/
318void CGenericAlgorithmTransformation::computeGlobalGridIndexMapping(int elementPositionInGrid,
319                                                                   const std::vector<int>& srcRank,
320                                                                   boost::unordered_map<int, std::vector<std::pair<int,double> > >& src2DstMap,
321                                                                   CGrid* gridSrc,
322                                                                   CGrid* gridDst,
323                                                                   std::vector<boost::unordered_map<int,std::vector<size_t> > >& globalElementIndexOnProc,
324                                                                   SourceDestinationIndexMap& globaIndexWeightFromSrcToDst)
325{
326  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
327  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
328  std::vector<CScalar*> scalarListSrcP = gridSrc->getScalars();
329  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;
330
331  size_t nbElement = axisDomainSrcOrder.numElements();
332  std::vector<size_t> nGlobSrc(nbElement);
333  size_t globalSrcSize = 1;
334  int domainIndex = 0, axisIndex = 0, scalarIndex = 0;
335  for (int idx = 0; idx < nbElement; ++idx)
336  {
337    nGlobSrc[idx] = globalSrcSize;
338    int elementDimension = axisDomainSrcOrder(idx);
339
340    // If this is a domain
341    if (2 == elementDimension)
342    {
343      globalSrcSize *= domainListSrcP[domainIndex]->nj_glo.getValue() * domainListSrcP[domainIndex]->ni_glo.getValue();
344      ++domainIndex;
345    }
346    else if (1 == elementDimension) // So it's an axis
347    {
348      globalSrcSize *= axisListSrcP[axisIndex]->n_glo.getValue();
349      ++axisIndex;
350    }
351    else
352    {
353      globalSrcSize *= 1;
354      ++scalarIndex;
355    }
356  }
357
358  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
359  std::vector<CAxis*> axisListDestP = gridDst->getAxis();
360  std::vector<CScalar*> scalarListDestP = gridDst->getScalars();
361  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
362
363  std::vector<size_t> nGlobDst(nbElement);
364  size_t globalDstSize = 1;
365  domainIndex = axisIndex = scalarIndex = 0;
366  for (int idx = 0; idx < nbElement; ++idx)
367  {
368    nGlobDst[idx] = globalDstSize;
369    int elementDimension = axisDomainDstOrder(idx);
370
371    // If this is a domain
372    if (2 == elementDimension)
373    {
374      globalDstSize *= domainListDestP[domainIndex]->nj_glo.getValue() * domainListDestP[domainIndex]->ni_glo.getValue();
375      ++domainIndex;
376    }
377    else if (1 == elementDimension) // So it's an axis
378    {
379      globalDstSize *= axisListDestP[axisIndex]->n_glo.getValue();
380      ++axisIndex;
381    }
382    else
383    {
384      globalDstSize *= 1;
385      ++scalarIndex;
386    }
387  }
388
389  for (int i = 0; i < srcRank.size(); ++i)
390  {
391    size_t ssize = 1;
392    int rankSrc = srcRank[i];
393    for (int idx = 0; idx < nbElement; ++idx)
394    {
395      ssize *= (globalElementIndexOnProc[idx][rankSrc]).size();
396    }
397
398    std::vector<int> idxLoop(nbElement,0);
399    std::vector<int> currentIndexSrc(nbElement, 0);
400    std::vector<int> currentIndexDst(nbElement, 0);
401    int innnerLoopSize = (globalElementIndexOnProc[0])[rankSrc].size();
402    size_t idx = 0;
403    while (idx < ssize)
404    {
405      for (int ind = 0; ind < nbElement; ++ind)
406      {
407        if (idxLoop[ind] == (globalElementIndexOnProc[ind])[rankSrc].size())
408        {
409          idxLoop[ind] = 0;
410          ++idxLoop[ind+1];
411        }
412
413        currentIndexDst[ind] = currentIndexSrc[ind] = (globalElementIndexOnProc[ind])[rankSrc][idxLoop[ind]];
414      }
415
416      for (int ind = 0; ind < innnerLoopSize; ++ind)
417      {
418        currentIndexDst[0] = currentIndexSrc[0] = (globalElementIndexOnProc[0])[rankSrc][ind];
419        int globalElementDstIndexSize = 0;
420        if (1 == src2DstMap.count(currentIndexSrc[elementPositionInGrid]))
421        {
422          globalElementDstIndexSize = src2DstMap[currentIndexSrc[elementPositionInGrid]].size();
423        }
424
425        std::vector<size_t> globalDstVecIndex(globalElementDstIndexSize,0);
426        size_t globalSrcIndex = 0;
427        for (int idxElement = 0; idxElement < nbElement; ++idxElement)
428        {
429          if (idxElement == elementPositionInGrid)
430          {
431            for (int k = 0; k < globalElementDstIndexSize; ++k)
432            {
433              globalDstVecIndex[k] += src2DstMap[currentIndexSrc[elementPositionInGrid]][k].first * nGlobDst[idxElement];
434            }
435          }
436          else
437          {
438            for (int k = 0; k < globalElementDstIndexSize; ++k)
439            {
440              globalDstVecIndex[k] += currentIndexDst[idxElement] * nGlobDst[idxElement];
441            }
442          }
443          globalSrcIndex += currentIndexSrc[idxElement] * nGlobSrc[idxElement];
444        }
445
446        for (int k = 0; k < globalElementDstIndexSize; ++k)
447        {
448          globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second ));
449        }
450        ++idxLoop[0];
451      }
452      idx += innnerLoopSize;
453    }
454  }
455}
456
457/*!
458  Find out proc and global index of axis source which axis destination is on demande
459  \param[in] scalar Scalar destination
460  \param[in] scalar Scalar source
461  \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid.
462  \param[out] globalScalarIndexOnProc Global index of axis source on different procs
463*/
464void CGenericAlgorithmTransformation::computeExchangeScalarIndex(CScalar* scalarDst,
465                                                                 CScalar* scalarSrc,
466                                                                 CArray<size_t,1>& destGlobalIndexPositionInGrid,
467                                                                 boost::unordered_map<int,std::vector<size_t> >& globalScalarIndexOnProc)
468{
469  CContext* context = CContext::getCurrent();
470  CContextClient* client=context->client;
471  int clientRank = client->clientRank;
472  int clientSize = client->clientSize;
473
474  globalScalarIndexOnProc.rehash(std::ceil(clientSize/globalScalarIndexOnProc.max_load_factor()));
475  for (int idx = 0; idx < clientSize; ++idx)
476  {
477    globalScalarIndexOnProc[idx].push_back(0);
478  }
479}
480
481/*!
482  Find out proc and global index of axis source which axis destination is on demande
483  \param[in] axisDst Axis destination
484  \param[in] axisSrc Axis source
485  \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid.
486  \param[out] globalAxisIndexOnProc Global index of axis source on different procs
487*/
488void CGenericAlgorithmTransformation::computeExchangeAxisIndex(CAxis* axisDst,
489                                                               CAxis* axisSrc,
490                                                               CArray<size_t,1>& destGlobalIndexPositionInGrid,
491                                                               boost::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc)
492{
493  CContext* context = CContext::getCurrent();
494  CContextClient* client=context->client;
495  int clientRank = client->clientRank;
496  int clientSize = client->clientSize;
497
498  size_t globalIndex;
499  int nIndexSize = axisSrc->index.numElements();
500  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
501  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
502  for (int idx = 0; idx < nIndexSize; ++idx)
503  {
504    globalIndex = axisSrc->index(idx);
505    globalIndex2ProcRank[globalIndex].push_back(clientRank);
506  }
507
508  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
509  CArray<size_t,1> globalAxisIndex(axisDst->index.numElements());
510  for (int idx = 0; idx < globalAxisIndex.numElements(); ++idx)
511  {
512    globalAxisIndex(idx) = axisDst->index(idx);
513  }
514  dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex);
515
516  std::vector<int> countIndex(clientSize,0);
517  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
518  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it,
519                                                               ite = computedGlobalIndexOnProc.end();
520  for (it = itb; it != ite; ++it)
521  {
522    const std::vector<int>& procList = it->second;
523    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]];
524  }
525
526  globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor()));
527  for (int idx = 0; idx < clientSize; ++idx)
528  {
529    if (0 != countIndex[idx])
530    {
531      globalAxisIndexOnProc[idx].resize(countIndex[idx]);
532      countIndex[idx] = 0;
533    }
534  }
535
536  for (it = itb; it != ite; ++it)
537  {
538    const std::vector<int>& procList = it->second;
539    for (int idx = 0; idx < procList.size(); ++idx)
540    {
541      globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first;
542      ++countIndex[procList[idx]];
543    }
544  }
545}
546
547/*!
548  Find out proc and global index of domain source which domain destination is on demande
549  \param[in] domainDst Domain destination
550  \param[in] domainSrc Domain source
551  \param[in] destGlobalIndexPositionInGrid Relative position of domain corresponds to other element of grid.
552  \param[out] globalDomainIndexOnProc Global index of domain source on different procs
553*/
554void CGenericAlgorithmTransformation::computeExchangeDomainIndex(CDomain* domainDst,
555                                                                 CDomain* domainSrc,
556                                                                 CArray<size_t,1>& destGlobalIndexPositionInGrid,
557                                                                 boost::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc)
558{
559  CContext* context = CContext::getCurrent();
560  CContextClient* client=context->client;
561  int clientRank = client->clientRank;
562  int clientSize = client->clientSize;
563
564  int niGlobSrc = domainSrc->ni_glo.getValue();
565  size_t globalIndex;
566  int i_ind, j_ind;
567  int nIndexSize = (destGlobalIndexPositionInGrid.isEmpty()) ? domainSrc->i_index.numElements()
568                                                             : destGlobalIndexPositionInGrid.numElements();
569  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
570  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
571  if (destGlobalIndexPositionInGrid.isEmpty())
572  {
573    for (int idx = 0; idx < nIndexSize; ++idx)
574    {
575      i_ind=domainSrc->i_index(idx) ;
576      j_ind=domainSrc->j_index(idx) ;
577
578      globalIndex = i_ind + j_ind * niGlobSrc;
579      globalIndex2ProcRank[globalIndex].resize(1);
580      globalIndex2ProcRank[globalIndex][0] = clientRank;
581    }
582  }
583  else
584  {
585    for (int idx = 0; idx < nIndexSize; ++idx)
586    {
587      globalIndex2ProcRank[destGlobalIndexPositionInGrid(idx)].push_back(clientRank);
588    }
589  }
590
591  CArray<size_t,1> globalDomainIndex;
592  if (destGlobalIndexPositionInGrid.isEmpty())
593  {
594    int niGlobDst = domainDst->ni_glo.getValue();
595    globalDomainIndex.resize(domainDst->i_index.numElements());
596    nIndexSize = domainDst->i_index.numElements();
597
598    for (int idx = 0; idx < nIndexSize; ++idx)
599    {
600      i_ind=domainDst->i_index(idx) ;
601      j_ind=domainDst->j_index(idx) ;
602
603      globalDomainIndex(idx) = i_ind + j_ind * niGlobDst;
604    }
605  }
606  else
607  {
608    globalDomainIndex.reference(destGlobalIndexPositionInGrid);
609  }
610
611  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
612  dhtIndexProcRank.computeIndexInfoMapping(globalDomainIndex);
613
614  std::vector<int> countIndex(clientSize,0);
615  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
616  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it,
617                                                               ite = computedGlobalIndexOnProc.end();
618  for (it = itb; it != ite; ++it)
619  {
620    const std::vector<int>& procList = it->second;
621    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]];
622  }
623
624  globalDomainIndexOnProc.rehash(std::ceil(clientSize/globalDomainIndexOnProc.max_load_factor()));
625  for (int idx = 0; idx < clientSize; ++idx)
626  {
627    if (0 != countIndex[idx])
628    {
629      globalDomainIndexOnProc[idx].resize(countIndex[idx]);
630      countIndex[idx] = 0;
631    }
632  }
633
634  for (it = itb; it != ite; ++it)
635  {
636    const std::vector<int>& procList = it->second;
637    for (int idx = 0; idx < procList.size(); ++idx)
638    {
639      globalDomainIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first;
640      ++countIndex[procList[idx]];
641    }
642  }
643}
644
645/*!
646  Compute index mapping between element source and element destination with an auxiliary inputs which determine
647position of each mapped index in global index of grid destination.
648  \param [in] dataAuxInputs auxiliary inputs
649*/
650void CGenericAlgorithmTransformation::computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs)
651{
652  computeIndexSourceMapping_(dataAuxInputs);
653}
654
655std::vector<StdString> CGenericAlgorithmTransformation::getIdAuxInputs()
656{
657  return idAuxInputs_;
658}
659
660}
Note: See TracBrowser for help on using the repository browser.