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

Last change on this file since 1620 was 1542, checked in by oabramkina, 6 years ago

Replacing Boost's unordered_map and shared_pointer by its STL counterparts.

Two notes for Curie:

  • one can see the content of unordered_map with ddt only if XIOS has been compiled with gnu
  • XIOS will not compile any more with pgi (all available versions use old STL which are not up to the c++11 norms)
File size: 42.8 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#include "utils.hpp"
14#include "timer.hpp"
15#include "mpi.hpp"
16
17namespace xios {
18
19CGenericAlgorithmTransformation::CGenericAlgorithmTransformation()
20 : transformationMapping_(), transformationWeight_(), transformationPosition_(),
21   idAuxInputs_(), type_(ELEMENT_NO_MODIFICATION_WITH_DATA), indexElementSrc_(),
22   computedProcSrcNonTransformedElement_(false), eliminateRedondantSrc_(true), isDistributedComputed_(false)
23{
24}
25
26void CGenericAlgorithmTransformation::updateData(CArray<double,1>& dataOut)
27{
28
29}
30
31void CGenericAlgorithmTransformation::apply(const std::vector<std::pair<int,double> >& localIndex,
32                                            const double* dataInput,
33                                            CArray<double,1>& dataOut,
34                                            std::vector<bool>& flagInitial,
35                                            bool ignoreMissingValue, bool firstPass  )
36{
37  int nbLocalIndex = localIndex.size();   
38  double defaultValue = std::numeric_limits<double>::quiet_NaN();
39   
40  if (ignoreMissingValue)
41  {
42    if (firstPass) dataOut=defaultValue ;
43   
44    for (int idx = 0; idx < nbLocalIndex; ++idx)
45    {
46      if (! NumTraits<double>::isNan(*(dataInput + idx)))
47      {
48        if (flagInitial[localIndex[idx].first]) dataOut(localIndex[idx].first) = *(dataInput + idx) * localIndex[idx].second;
49        else dataOut(localIndex[idx].first) += *(dataInput + idx) * localIndex[idx].second;
50        flagInitial[localIndex[idx].first] = false; // Reset flag to indicate not all data source are nan
51      }
52    }
53
54  }
55  else
56  {
57    for (int idx = 0; idx < nbLocalIndex; ++idx)
58    {
59      dataOut(localIndex[idx].first) += *(dataInput + idx) * localIndex[idx].second;
60    }
61  }
62}
63
64void CGenericAlgorithmTransformation::computePositionElements(CGrid* dst, CGrid* src)
65{
66  int idxScalar = 0, idxAxis = 0, idxDomain = 0;
67  CArray<int,1> axisDomainOrderDst = dst->axis_domain_order;
68  for (int i = 0; i < axisDomainOrderDst.numElements(); ++i)
69  {
70    int dimElement = axisDomainOrderDst(i);
71    if (2 == dimElement)
72    {
73      elementPositionInGridDst2DomainPosition_[i] = idxDomain;
74      ++idxDomain;
75    }
76    else if (1 == dimElement)
77    {
78      elementPositionInGridDst2AxisPosition_[i] = idxAxis;
79      ++idxAxis;
80    }
81    else
82    {
83      elementPositionInGridDst2ScalarPosition_[i] = idxScalar;
84      ++idxScalar;
85    }
86  }
87
88  idxScalar = idxAxis = idxDomain = 0;
89  CArray<int,1> axisDomainOrderSrc = src->axis_domain_order;
90  for (int i = 0; i < axisDomainOrderSrc.numElements(); ++i)
91  {
92    int dimElement = axisDomainOrderSrc(i);
93    if (2 == dimElement)
94    {
95      elementPositionInGridSrc2DomainPosition_[i] = idxDomain;
96      ++idxDomain;
97    }
98    else if (1 == dimElement)
99    {
100      elementPositionInGridSrc2AxisPosition_[i] = idxAxis;
101      ++idxAxis;
102    }
103    else
104    {
105      elementPositionInGridSrc2ScalarPosition_[i] = idxScalar;
106      ++idxScalar;
107    }
108  }
109}
110
111bool CGenericAlgorithmTransformation::isDistributedTransformation(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst)
112{
113
114  if (!isDistributedComputed_)
115  {
116    isDistributedComputed_=true ;
117    if (!eliminateRedondantSrc_) isDistributed_=true ;
118    else
119    {
120      CContext* context = CContext::getCurrent();
121      CContextClient* client = context->client;
122 
123      computePositionElements(gridSrc, gridDst);
124      std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars();
125      std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
126      std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
127      int distributed, distributed_glo ;
128 
129      CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;
130      if (2 == axisDomainSrcOrder(elementPositionInGrid)) // It's domain
131      {
132        distributed=domainListSrcP[elementPositionInGridSrc2DomainPosition_[elementPositionInGrid]]->isDistributed() ;
133        MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ;
134   
135      }
136      else if (1 == axisDomainSrcOrder(elementPositionInGrid))//it's an axis
137      {
138        distributed=axisListSrcP[elementPositionInGridSrc2AxisPosition_[elementPositionInGrid]]->isDistributed() ;
139        MPI_Allreduce(&distributed,&distributed_glo, 1, MPI_INT, MPI_LOR, client->intraComm) ;
140      }
141      else //it's a scalar
142      {
143        distributed_glo=false ;
144      } 
145      isDistributed_=distributed_glo ;
146    }
147  }
148  return isDistributed_ ;
149} 
150/*!
151  This function computes the global indexes of grid source, which the grid destination is in demand.
152  \param[in] elementPositionInGrid position of an element in a grid .E.g: if grid is composed of domain and axis (in order),
153                then position of axis in grid is 1 and domain is positioned at 0.
154  \param[in] gridSrc Grid source
155  \param[in] gridDst Grid destination
156  \param[in\out] globaIndexWeightFromSrcToDst mapping of each global index source and weight to index destination
157*/
158void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
159                                                               CGrid* gridSrc,
160                                                               CGrid* gridDst,
161                                                               SourceDestinationIndexMap& globaIndexWeightFromSrcToDst)
162 {
163  CContext* context = CContext::getCurrent();
164  CContextClient* client = context->client;
165  int nbClient = client->clientSize;
166
167  typedef std::unordered_map<int, std::vector<std::pair<int,double> > > SrcToDstMap;
168  int idx;
169
170  // compute position of elements on grids
171  computePositionElements(gridDst, gridSrc);
172  std::vector<CScalar*> scalarListDestP = gridDst->getScalars();
173  std::vector<CAxis*> axisListDestP = gridDst->getAxis();
174  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
175  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
176  std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars();
177  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
178  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
179  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 
180 
181  bool isTransPosEmpty = transformationPosition_.empty();
182  CArray<size_t,1> transPos;
183  if (!isTransPosEmpty) transPos.resize(transformationMapping_.size());
184  std::set<size_t> allIndexSrc; // All index of source, which can be scattered among processes, need for doing transformation
185 
186  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
187  {
188    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
189                                           iteTransMap = transformationMapping_[idxTrans].end();
190    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
191
192    // Build mapping between global source element index and global destination element index.
193    itTransWeight = itbTransWeight;
194    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
195    {
196      const std::vector<int>& srcIndex = itTransMap->second;
197      for (idx = 0; idx < srcIndex.size(); ++idx)
198        allIndexSrc.insert(srcIndex[idx]);
199    }
200
201    if (!isTransPosEmpty)
202    {
203      TransformationPositionMap::const_iterator itPosMap = transformationPosition_[idxTrans].begin();
204      transPos(idxTrans) = itPosMap->second[0];
205    }
206  }
207
208  size_t indexSrcSize = 0;
209  CArray<size_t,1> indexSrc(allIndexSrc.size());
210  for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it, ++indexSrcSize)
211    indexSrc(indexSrcSize) = *it;
212
213  // Flag to indicate whether we will recompute distribution of source global index  on processes
214  bool computeGlobalIndexOnProc = false; 
215  if (indexElementSrc_.size() != allIndexSrc.size())
216    computeGlobalIndexOnProc = true; 
217  else
218  {
219    for (std::set<size_t>::iterator it = allIndexSrc.begin(); it != allIndexSrc.end(); ++it)
220      if (0 == indexElementSrc_.count(*it))
221      {
222        computeGlobalIndexOnProc = true;
223        break;       
224      }
225  }
226
227  if (computeGlobalIndexOnProc)
228    indexElementSrc_.swap(allIndexSrc);
229     
230  int sendValue = (computeGlobalIndexOnProc) ? 1 : 0;
231  int recvValue = 0;
232  MPI_Allreduce(&sendValue, &recvValue, 1, MPI_INT, MPI_SUM, client->intraComm);
233  computeGlobalIndexOnProc = (0 < recvValue);
234
235//  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndexOfTransformedElementOnProc;
236
237  if (computeGlobalIndexOnProc || !computedProcSrcNonTransformedElement_)
238  {   
239    {
240      CClientClientDHTInt::Index2VectorInfoTypeMap tmp ;
241      globalIndexOfTransformedElementOnProc_.swap(tmp) ;
242    }
243    // Find out global index source of transformed element on corresponding process.   
244    if (globalElementIndexOnProc_.empty())
245      globalElementIndexOnProc_.resize(axisDomainDstOrder.numElements());
246   
247    for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)
248    {
249     
250      if (idx == elementPositionInGrid)
251        computeExchangeGlobalIndex(indexSrc, axisDomainSrcOrder(idx), globalIndexOfTransformedElementOnProc_); //globalElementIndexOnProc[idx]);
252      if (!computedProcSrcNonTransformedElement_)
253      {
254        if (2 == axisDomainDstOrder(idx)) // It's domain
255        {
256          if (idx != elementPositionInGrid)
257            computeExchangeDomainIndex(domainListDestP[elementPositionInGridDst2DomainPosition_[idx]],
258                                       domainListSrcP[elementPositionInGridSrc2DomainPosition_[idx]],
259                                       transPos,
260                                       globalElementIndexOnProc_[idx]);     
261
262        }
263        else if (1 == axisDomainDstOrder(idx))//it's an axis
264        {
265          if (idx != elementPositionInGrid)
266            computeExchangeAxisIndex(axisListDestP[elementPositionInGridDst2AxisPosition_[idx]],
267                                     axisListSrcP[elementPositionInGridSrc2AxisPosition_[idx]],
268                                     transPos,
269                                     globalElementIndexOnProc_[idx]);
270        }
271        else //it's a scalar
272        {
273          if (idx != elementPositionInGrid)
274            computeExchangeScalarIndex(scalarListDestP[elementPositionInGridDst2ScalarPosition_[idx]],
275                                       scalarListSrcP[elementPositionInGridSrc2ScalarPosition_[idx]],
276                                       transPos,
277                                       globalElementIndexOnProc_[idx]);
278
279        }
280      }
281    }
282
283    if (!isTransPosEmpty && !computedProcSrcNonTransformedElement_)
284    {
285      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx)
286      {
287        if (idx != elementPositionInGrid)
288        {
289          std::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it,
290                                                                   ite = globalElementIndexOnProc_[idx].end();
291          for (it = itb; it != ite; ++it) it->second.resize(1);
292        }
293      }
294    }
295
296/*     
297    if (!computedProcSrcNonTransformedElement_)
298    {
299      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx)
300      {
301        if (idx != elementPositionInGrid)
302        {
303          std::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it,
304                                                                   ite = globalElementIndexOnProc_[idx].end();
305          for (it = itb; it != ite; ++it) procOfNonTransformedElements_.insert(it->first);
306          if (procOfNonTransformedElements_.size() == nbClient)
307            break;
308        }
309      }
310    }
311   
312    // Processes contain the source index of transformed element
313    std::set<int> procOfTransformedElement;
314    CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc.begin(),
315                                                           itIdxe = globalIndexOfTransformedElementOnProc.end(), itIdx;
316    for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx)
317    {
318      std::vector<int>& tmp = itIdx->second;
319      for (int i = 0; i < tmp.size(); ++i)
320        procOfTransformedElement.insert(tmp[i]);
321      if (tmp.size() == nbClient)
322        break;
323    }                                                           
324   
325    std::set<int>& commonProc = (procOfTransformedElement.size() < procOfNonTransformedElements_.size()) ? procOfTransformedElement
326                              : (!procOfNonTransformedElements_.empty() ? procOfNonTransformedElements_ : procOfTransformedElement);
327   
328    std::vector<int> procContainSrcElementIdx(commonProc.size());
329    int count = 0;
330    for (std::set<int>::iterator it = commonProc.begin(); it != commonProc.end(); ++it)
331      procContainSrcElementIdx[count++] = *it;
332
333    procContainSrcElementIdx_.swap(procContainSrcElementIdx);   
334*/
335   
336    if (procElementList_.empty()) procElementList_.resize(axisDomainDstOrder.numElements()) ;
337    for (idx = 0; idx < axisDomainDstOrder.numElements(); ++idx)
338    {
339      std::set<int>& procList=procElementList_[idx] ;
340      std::set<int> commonTmp ;
341      if (idx == elementPositionInGrid)
342      {
343          set<int> tmpSet ; 
344          procList.swap(tmpSet) ;
345          CClientClientDHTInt::Index2VectorInfoTypeMap::iterator itIdxb = globalIndexOfTransformedElementOnProc_.begin(),
346                                                                 itIdxe = globalIndexOfTransformedElementOnProc_.end(), itIdx;
347          for (itIdx = itIdxb; itIdx != itIdxe; ++itIdx)
348          {
349             std::vector<int>& tmp = itIdx->second;
350             for (int i = 0; i < tmp.size(); ++i) procList.insert(tmp[i]);
351             if (tmp.size() == nbClient)
352             break;
353          }
354      }
355      else
356      {
357        if (!computedProcSrcNonTransformedElement_)
358        {
359          set<int> tmpSet ; 
360          procList.swap(tmpSet) ;
361          std::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it,
362                                                                   ite = globalElementIndexOnProc_[idx].end();
363          for (it = itb; it != ite; ++it)
364          {
365            procList.insert(it->first);
366            if (procList.size() == nbClient)  break;
367          }
368        }
369      }
370
371      if (idx==0) commonProc_= procList ;
372      else
373      {
374        for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it)
375          if (procList.count(*it)==1) commonTmp.insert(*it) ;
376        commonProc_.swap(commonTmp) ;
377      }
378    }
379    std::vector<int> procContainSrcElementIdx(commonProc_.size());
380    int count = 0;
381    for (std::set<int>::iterator it = commonProc_.begin(); it != commonProc_.end(); ++it) procContainSrcElementIdx[count++] = *it;
382    procContainSrcElementIdx_.swap(procContainSrcElementIdx);
383   
384        // For the first time, surely we calculate proc containing non transformed elements
385    if (!computedProcSrcNonTransformedElement_) computedProcSrcNonTransformedElement_ = true;
386  }
387 
388  for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
389  {
390    TransformationIndexMap::const_iterator itbTransMap = transformationMapping_[idxTrans].begin(), itTransMap,
391                                           iteTransMap = transformationMapping_[idxTrans].end();
392    TransformationWeightMap::const_iterator itbTransWeight = transformationWeight_[idxTrans].begin(), itTransWeight;
393    SrcToDstMap src2DstMap;
394    src2DstMap.rehash(std::ceil(transformationMapping_[idxTrans].size()/src2DstMap.max_load_factor()));
395
396    // Build mapping between global source element index and global destination element index.
397    std::unordered_map<int,std::vector<size_t> >().swap(globalElementIndexOnProc_[elementPositionInGrid]);
398    std::set<int> tmpCounter;
399    itTransWeight = itbTransWeight;
400    for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
401    {
402      const std::vector<int>& srcIndex = itTransMap->second;
403      const std::vector<double>& weight = itTransWeight->second;
404      for (idx = 0; idx < srcIndex.size(); ++idx)
405      {
406        src2DstMap[srcIndex[idx]].push_back(make_pair(itTransMap->first, weight[idx]));
407        if (0 == tmpCounter.count(srcIndex[idx]))
408        {         
409          tmpCounter.insert(srcIndex[idx]);
410       
411          vector<int>& rankSrc = globalIndexOfTransformedElementOnProc_[srcIndex[idx]] ;
412          for (int n=0;n<rankSrc.size();++n)
413          {
414            if (commonProc_.count(rankSrc[n])==1) globalElementIndexOnProc_[elementPositionInGrid][rankSrc[n]].push_back(srcIndex[idx]);
415          }
416//          for (int j = 0; j < procContainSrcElementIdx_.size(); ++j)
417//            globalElementIndexOnProc_[elementPositionInGrid][procContainSrcElementIdx_[j]].push_back(srcIndex[idx]);
418        }
419      }
420    }
421 
422    if (!isTransPosEmpty)
423    {
424      for (idx = 0; idx < globalElementIndexOnProc_.size(); ++idx)
425      {
426        if (idx != elementPositionInGrid)
427        {
428          std::unordered_map<int,std::vector<size_t> >::iterator itb = globalElementIndexOnProc_[idx].begin(), it,
429                                                                   ite = globalElementIndexOnProc_[idx].end();
430          for (it = itb; it != ite; ++it) it->second[0] = transPos(idxTrans);
431        }
432      }
433    }
434
435    // Ok, now compute global index of grid source and ones of grid destination
436    computeGlobalGridIndexMapping(elementPositionInGrid,
437                                  procContainSrcElementIdx_, //srcRank,
438                                  src2DstMap,
439                                  gridSrc,
440                                  gridDst,
441                                  globalElementIndexOnProc_,
442                                  globaIndexWeightFromSrcToDst);
443  } 
444 }
445
446/*!
447  Compute mapping of global index of grid source and grid destination
448  \param [in] elementPositionInGrid position of element in grid. E.x: grid composed of domain and axis, domain has position 0 and axis 1.
449  \param [in] srcRank rank of client from which we demand global index of element source
450  \param [in] src2DstMap mapping of global index of element source and global index of element destination
451  \param [in] gridSrc Grid source
452  \param [in] gridDst Grid destination
453  \param [in] globalElementIndexOnProc Global index of element source on different client rank
454  \param [out] globaIndexWeightFromSrcToDst Mapping of global index of grid source and grid destination
455*/
456void CGenericAlgorithmTransformation::computeGlobalGridIndexMapping(int elementPositionInGrid,
457                                                                   const std::vector<int>& srcRank,
458                                                                   std::unordered_map<int, std::vector<std::pair<int,double> > >& src2DstMap,
459                                                                   CGrid* gridSrc,
460                                                                   CGrid* gridDst,
461                                                                   std::vector<std::unordered_map<int,std::vector<size_t> > >& globalElementIndexOnProc,
462                                                                   SourceDestinationIndexMap& globaIndexWeightFromSrcToDst)
463{
464  SourceDestinationIndexMap globaIndexWeightFromSrcToDst_tmp ;
465 
466  CContext* context = CContext::getCurrent();
467  CContextClient* client=context->client;
468  int clientRank = client->clientRank;
469 
470  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
471  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
472  std::vector<CScalar*> scalarListSrcP = gridSrc->getScalars();
473  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order;
474
475  size_t nbElement = axisDomainSrcOrder.numElements();
476  std::vector<size_t> nGlobSrc(nbElement);
477  size_t globalSrcSize = 1;
478  int domainIndex = 0, axisIndex = 0, scalarIndex = 0;
479  for (int idx = 0; idx < nbElement; ++idx)
480  {
481    nGlobSrc[idx] = globalSrcSize;
482    int elementDimension = axisDomainSrcOrder(idx);
483
484    // If this is a domain
485    if (2 == elementDimension)
486    {
487      globalSrcSize *= domainListSrcP[domainIndex]->nj_glo.getValue() * domainListSrcP[domainIndex]->ni_glo.getValue();
488      ++domainIndex;
489    }
490    else if (1 == elementDimension) // So it's an axis
491    {
492      globalSrcSize *= axisListSrcP[axisIndex]->n_glo.getValue();
493      ++axisIndex;
494    }
495    else
496    {
497      globalSrcSize *= 1;
498      ++scalarIndex;
499    }
500  }
501
502  std::vector<CDomain*> domainListDestP = gridDst->getDomains();
503  std::vector<CAxis*> axisListDestP = gridDst->getAxis();
504  std::vector<CScalar*> scalarListDestP = gridDst->getScalars();
505  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
506
507  std::vector<size_t> nGlobDst(nbElement);
508  size_t globalDstSize = 1;
509  domainIndex = axisIndex = scalarIndex = 0;
510  set<size_t>  globalSrcStoreIndex ;
511 
512  for (int idx = 0; idx < nbElement; ++idx)
513  {
514    nGlobDst[idx] = globalDstSize;
515    int elementDimension = axisDomainDstOrder(idx);
516
517    // If this is a domain
518    if (2 == elementDimension)
519    {
520      globalDstSize *= domainListDestP[domainIndex]->nj_glo.getValue() * domainListDestP[domainIndex]->ni_glo.getValue();
521      ++domainIndex;
522    }
523    else if (1 == elementDimension) // So it's an axis
524    {
525      globalDstSize *= axisListDestP[axisIndex]->n_glo.getValue();
526      ++axisIndex;
527    }
528    else
529    {
530      globalDstSize *= 1;
531      ++scalarIndex;
532    }
533  }
534
535  std::map< std::pair<size_t,size_t>, int > rankMap ;
536  std::map< std::pair<size_t,size_t>, int >:: iterator rankMapIt ;
537 
538  for (int i = 0; i < srcRank.size(); ++i)
539  {
540    size_t ssize = 1;
541    int rankSrc = srcRank[i];
542    for (int idx = 0; idx < nbElement; ++idx)
543    {
544      ssize *= (globalElementIndexOnProc[idx][rankSrc]).size();
545    }
546
547    std::vector<int> idxLoop(nbElement,0);
548    std::vector<int> currentIndexSrc(nbElement, 0);
549    std::vector<int> currentIndexDst(nbElement, 0);
550    int innnerLoopSize = (globalElementIndexOnProc[0])[rankSrc].size();
551    size_t idx = 0;
552    while (idx < ssize)
553    {
554      for (int ind = 0; ind < nbElement; ++ind)
555      {
556        if (idxLoop[ind] == (globalElementIndexOnProc[ind])[rankSrc].size())
557        {
558          idxLoop[ind] = 0;
559          ++idxLoop[ind+1];
560        }
561
562        currentIndexDst[ind] = currentIndexSrc[ind] = (globalElementIndexOnProc[ind])[rankSrc][idxLoop[ind]];
563      }
564
565      for (int ind = 0; ind < innnerLoopSize; ++ind)
566      {
567        currentIndexDst[0] = currentIndexSrc[0] = (globalElementIndexOnProc[0])[rankSrc][ind];
568        int globalElementDstIndexSize = 0;
569        if (1 == src2DstMap.count(currentIndexSrc[elementPositionInGrid]))
570        {
571          globalElementDstIndexSize = src2DstMap[currentIndexSrc[elementPositionInGrid]].size();
572        }
573
574        std::vector<size_t> globalDstVecIndex(globalElementDstIndexSize,0);
575        size_t globalSrcIndex = 0;
576        for (int idxElement = 0; idxElement < nbElement; ++idxElement)
577        {
578          if (idxElement == elementPositionInGrid)
579          {
580            for (int k = 0; k < globalElementDstIndexSize; ++k)
581            {
582              globalDstVecIndex[k] += src2DstMap[currentIndexSrc[elementPositionInGrid]][k].first * nGlobDst[idxElement];
583            }
584          }
585          else
586          {
587            for (int k = 0; k < globalElementDstIndexSize; ++k)
588            {
589              globalDstVecIndex[k] += currentIndexDst[idxElement] * nGlobDst[idxElement];
590            }
591          }
592          globalSrcIndex += currentIndexSrc[idxElement] * nGlobSrc[idxElement];
593        }
594
595        for (int k = 0; k < globalElementDstIndexSize; ++k)
596        {
597         
598          globaIndexWeightFromSrcToDst_tmp[rankSrc][globalSrcIndex].push_back(make_pair(globalDstVecIndex[k],src2DstMap[currentIndexSrc[elementPositionInGrid]][k].second ));
599          rankMapIt=rankMap.find(make_pair(globalSrcIndex,globalDstVecIndex[k])) ;
600          if (rankMapIt==rankMap.end()) rankMap[make_pair(globalSrcIndex,globalDstVecIndex[k])] = rankSrc ;
601          else if (rankSrc==clientRank) rankMapIt->second = rankSrc ;
602        }
603        ++idxLoop[0];
604      }
605      idx += innnerLoopSize;
606    }
607  }
608
609  // eliminate redondant global src point owned by differrent processes.
610  // Avoid as possible to tranfer data from an other process if the src point is also owned by current process
611      int rankSrc ;
612      size_t globalSrcIndex ;
613      size_t globalDstIndex ;
614      double weight ;
615 
616      SourceDestinationIndexMap::iterator rankIt,rankIte ;
617      std::unordered_map<size_t, std::vector<std::pair<size_t,double> > >::iterator globalSrcIndexIt, globalSrcIndexIte ;
618      std::vector<std::pair<size_t,double> >::iterator vectIt,vectIte ;
619   
620      rankIt=globaIndexWeightFromSrcToDst_tmp.begin() ; rankIte=globaIndexWeightFromSrcToDst_tmp.end() ;
621      for(;rankIt!=rankIte;++rankIt)
622      {
623        rankSrc = rankIt->first ;
624        globalSrcIndexIt = rankIt->second.begin() ; globalSrcIndexIte = rankIt->second.end() ;
625        for(;globalSrcIndexIt!=globalSrcIndexIte;++globalSrcIndexIt)
626        { 
627          globalSrcIndex = globalSrcIndexIt->first ;
628          vectIt = globalSrcIndexIt->second.begin() ; vectIte = globalSrcIndexIt->second.end() ;
629          for(vectIt; vectIt!=vectIte; vectIt++)
630          {
631            globalDstIndex = vectIt->first ;
632            weight = vectIt->second ;
633            if (eliminateRedondantSrc_)
634            {
635              if (rankMap[make_pair(globalSrcIndex,globalDstIndex)] == rankSrc) 
636                globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstIndex,weight)) ;
637            }
638            else globaIndexWeightFromSrcToDst[rankSrc][globalSrcIndex].push_back(make_pair(globalDstIndex,weight)) ;
639         }
640       }
641     }
642
643}
644
645/*!
646  Find out proc and global index of axis source which axis destination is on demande
647  \param[in] scalar Scalar destination
648  \param[in] scalar Scalar source
649  \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid.
650  \param[out] globalScalarIndexOnProc Global index of axis source on different procs
651*/
652void CGenericAlgorithmTransformation::computeExchangeScalarIndex(CScalar* scalarDst,
653                                                                 CScalar* scalarSrc,
654                                                                 CArray<size_t,1>& destGlobalIndexPositionInGrid,
655                                                                 std::unordered_map<int,std::vector<size_t> >& globalScalarIndexOnProc)
656{
657  CContext* context = CContext::getCurrent();
658  CContextClient* client=context->client;
659  int clientRank = client->clientRank;
660  int clientSize = client->clientSize;
661
662  globalScalarIndexOnProc.rehash(std::ceil(clientSize/globalScalarIndexOnProc.max_load_factor()));
663  for (int idx = 0; idx < clientSize; ++idx)
664  {
665    globalScalarIndexOnProc[idx].push_back(0);
666  }
667}
668
669/*!
670  Find out proc and global index of axis source which axis destination is on demande
671  \param[in] axisDst Axis destination
672  \param[in] axisSrc Axis source
673  \param[in] destGlobalIndexPositionInGrid Relative position of axis corresponds to other element of grid.
674  \param[out] globalAxisIndexOnProc Global index of axis source on different procs
675*/
676void CGenericAlgorithmTransformation::computeExchangeAxisIndex(CAxis* axisDst,
677                                                               CAxis* axisSrc,
678                                                               CArray<size_t,1>& destGlobalIndexPositionInGrid,
679                                                               std::unordered_map<int,std::vector<size_t> >& globalAxisIndexOnProc)
680{
681  CContext* context = CContext::getCurrent();
682  CContextClient* client=context->client;
683  int clientRank = client->clientRank;
684  int clientSize = client->clientSize;
685
686  size_t globalIndex;
687  int nIndexSize = axisSrc->index.numElements();
688  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
689  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
690  for (int idx = 0; idx < nIndexSize; ++idx)
691  {
692    if (axisSrc->mask(idx))
693    {
694      globalIndex = axisSrc->index(idx);
695      globalIndex2ProcRank[globalIndex].push_back(clientRank);
696    }
697  }
698
699  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
700  CArray<size_t,1> globalAxisIndex(axisDst->index.numElements());
701  for (int idx = 0; idx < globalAxisIndex.numElements(); ++idx)
702  {
703    globalAxisIndex(idx) = axisDst->index(idx);
704  }
705  dhtIndexProcRank.computeIndexInfoMapping(globalAxisIndex);
706
707  std::vector<int> countIndex(clientSize,0);
708  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
709  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it,
710                                                               ite = computedGlobalIndexOnProc.end();
711  for (it = itb; it != ite; ++it)
712  {
713    const std::vector<int>& procList = it->second;
714    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]];
715  }
716
717  globalAxisIndexOnProc.rehash(std::ceil(clientSize/globalAxisIndexOnProc.max_load_factor()));
718  for (int idx = 0; idx < clientSize; ++idx)
719  {
720    if (0 != countIndex[idx])
721    {
722      globalAxisIndexOnProc[idx].resize(countIndex[idx]);
723      countIndex[idx] = 0;
724    }
725  }
726
727  for (it = itb; it != ite; ++it)
728  {
729    const std::vector<int>& procList = it->second;
730    for (int idx = 0; idx < procList.size(); ++idx)
731    {
732      globalAxisIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first;
733      ++countIndex[procList[idx]];
734    }
735  }
736}
737
738/*!
739  Find out proc and global index of domain source which domain destination is on demande
740  \param[in] domainDst Domain destination
741  \param[in] domainSrc Domain source
742  \param[in] destGlobalIndexPositionInGrid Relative position of domain corresponds to other element of grid.
743  \param[out] globalDomainIndexOnProc Global index of domain source on different procs
744*/
745void CGenericAlgorithmTransformation::computeExchangeDomainIndex(CDomain* domainDst,
746                                                                 CDomain* domainSrc,
747                                                                 CArray<size_t,1>& destGlobalIndexPositionInGrid,
748                                                                 std::unordered_map<int,std::vector<size_t> >& globalDomainIndexOnProc)
749{
750  CContext* context = CContext::getCurrent();
751  CContextClient* client=context->client;
752  int clientRank = client->clientRank;
753  int clientSize = client->clientSize;
754
755  int niGlobSrc = domainSrc->ni_glo.getValue();
756  size_t globalIndex;
757  int i_ind, j_ind;
758  int nIndexSize = (destGlobalIndexPositionInGrid.isEmpty()) ? domainSrc->i_index.numElements()
759                                                             : destGlobalIndexPositionInGrid.numElements();
760  CClientClientDHTInt::Index2VectorInfoTypeMap globalIndex2ProcRank;
761  globalIndex2ProcRank.rehash(std::ceil(nIndexSize/globalIndex2ProcRank.max_load_factor()));
762 
763  if (destGlobalIndexPositionInGrid.isEmpty())
764  {
765    for (int idx = 0; idx < nIndexSize; ++idx)
766    {
767      i_ind=domainSrc->i_index(idx) ;
768      j_ind=domainSrc->j_index(idx) ;
769
770      if (domainSrc->localMask(idx))
771      {
772        globalIndex = i_ind + j_ind * niGlobSrc;
773        globalIndex2ProcRank[globalIndex].resize(1);
774        globalIndex2ProcRank[globalIndex][0] = clientRank;
775      }
776    }
777  }
778  else
779  {
780    for (int idx = 0; idx < nIndexSize; ++idx)
781    {
782//      if (domainSrc->localMask(idx)) -> not necessairy, mask seem to be included in  destGlobalIndexPositionInGrid(idx)    (ym)
783        globalIndex2ProcRank[destGlobalIndexPositionInGrid(idx)].push_back(clientRank);
784    }
785  }
786
787  CArray<size_t,1> globalDomainIndex;
788  if (destGlobalIndexPositionInGrid.isEmpty())
789  {
790    int niGlobDst = domainDst->ni_glo.getValue();
791    globalDomainIndex.resize(domainDst->i_index.numElements());
792    nIndexSize = domainDst->i_index.numElements();
793
794    for (int idx = 0; idx < nIndexSize; ++idx)
795    {
796      i_ind=domainDst->i_index(idx) ;
797      j_ind=domainDst->j_index(idx) ;
798
799      globalDomainIndex(idx) = i_ind + j_ind * niGlobDst;
800    }
801  }
802  else
803  {
804    globalDomainIndex.reference(destGlobalIndexPositionInGrid);
805  }
806
807  CClientClientDHTInt dhtIndexProcRank(globalIndex2ProcRank, client->intraComm);
808  dhtIndexProcRank.computeIndexInfoMapping(globalDomainIndex);
809
810  std::vector<int> countIndex(clientSize,0);
811  const CClientClientDHTInt::Index2VectorInfoTypeMap& computedGlobalIndexOnProc = dhtIndexProcRank.getInfoIndexMap();
812  CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = computedGlobalIndexOnProc.begin(), it,
813                                                               ite = computedGlobalIndexOnProc.end();
814  for (it = itb; it != ite; ++it)
815  {
816    const std::vector<int>& procList = it->second;
817    for (int idx = 0; idx < procList.size(); ++idx) ++countIndex[procList[idx]];
818  }
819
820  globalDomainIndexOnProc.rehash(std::ceil(clientSize/globalDomainIndexOnProc.max_load_factor()));
821  for (int idx = 0; idx < clientSize; ++idx)
822  {
823    if (0 != countIndex[idx])
824    {
825      globalDomainIndexOnProc[idx].resize(countIndex[idx]);
826      countIndex[idx] = 0;
827    }
828  }
829
830  for (it = itb; it != ite; ++it)
831  {
832    const std::vector<int>& procList = it->second;
833    for (int idx = 0; idx < procList.size(); ++idx)
834    {
835      globalDomainIndexOnProc[procList[idx]][countIndex[procList[idx]]] = it->first;
836      ++countIndex[procList[idx]];
837    }
838  }
839}
840
841
842
843
844
845
846void CGenericAlgorithmTransformation::computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst,
847                                                                                 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest)
848{
849
850  CContext* context = CContext::getCurrent();
851  CContextClient* client = context->client;
852  int nbClient = client->clientSize;
853
854  computePositionElements(gridDst, gridSrc);
855  std::vector<CScalar*> scalarListDstP = gridDst->getScalars();
856  std::vector<CAxis*> axisListDstP = gridDst->getAxis();
857  std::vector<CDomain*> domainListDstP = gridDst->getDomains();
858  CArray<int,1> axisDomainDstOrder = gridDst->axis_domain_order;
859  std::vector<CScalar*> scalarListSrcP  = gridSrc->getScalars();
860  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
861  std::vector<CDomain*> domainListSrcP = gridSrc->getDomains();
862  CArray<int,1> axisDomainSrcOrder = gridSrc->axis_domain_order; 
863
864  int nElement=axisDomainSrcOrder.numElements() ;
865  int indSrc=1 ;
866  int indDst=1 ;
867  vector<int> nIndexSrc(nElement) ;
868  vector<int> nIndexDst(nElement) ;
869  vector< CArray<bool,1>* > maskSrc(nElement) ;
870  vector< CArray<bool,1>* > maskDst(nElement) ;
871   
872  int nlocalIndexSrc=1 ;
873  int nlocalIndexDest=1 ;
874  CArray<bool,1> maskScalar(1) ;
875  maskScalar  = true ;
876 
877 
878  for(int i=0 ; i<nElement; i++)
879  {
880    int dimElement = axisDomainSrcOrder(i);
881    if (2 == dimElement) //domain
882    {
883      CDomain* domain=domainListSrcP[elementPositionInGridSrc2DomainPosition_[i]] ;
884      nIndexSrc[i] = domain->i_index.numElements() ;
885      maskSrc[i]=&domain->localMask ;
886    }
887    else if (1 == dimElement) //axis
888    {
889      CAxis* axis=axisListSrcP[elementPositionInGridSrc2AxisPosition_[i]] ;
890      nIndexSrc[i] = axis->index.numElements() ;
891      maskSrc[i]=&axis->mask ;
892    }
893    else  //scalar
894    {
895      nIndexSrc[i]=1 ;
896      maskSrc[i]=&maskScalar ;
897    }
898    nlocalIndexSrc=nlocalIndexSrc*nIndexSrc[i] ;
899  }
900
901
902
903  int offset=1 ;
904  for(int i=0 ; i<nElement; i++)
905  {
906    int dimElement = axisDomainDstOrder(i);
907    if (2 == dimElement) //domain
908    {
909      CDomain* domain=domainListDstP[elementPositionInGridDst2DomainPosition_[i]] ;
910      int nIndex=domain->i_index.numElements() ;
911      CArray<bool,1>& localMask=domain->localMask ;
912      int nbInd=0 ;
913      for(int j=0;j<nIndex;j++) if (localMask(j)) nbInd++ ;
914      nIndexDst[i] = nbInd ;
915      maskDst[i]=&domain->localMask ;
916    }
917    else if (1 == dimElement) //axis
918    {
919      CAxis* axis = axisListDstP[elementPositionInGridDst2AxisPosition_[i]] ;
920      int nIndex=axis->index.numElements() ;
921      CArray<bool,1>& localMask=axis->mask ;
922      int nbInd=0 ;
923      for(int j=0;j<nIndex;j++) if (localMask(j)) nbInd++ ;
924      nIndexDst[i] = nbInd ;
925      maskDst[i]=&axis->mask ;
926    }
927    else  //scalar
928    {
929      nIndexDst[i]=1 ;
930      maskDst[i]=&maskScalar ;
931    }
932    if (i<elementPositionInGrid) offset=offset*nIndexDst[i] ;
933    nlocalIndexDest=nlocalIndexDest*nIndexDst[i] ;
934  }
935
936
937
938
939
940
941  vector<int> dstLocalInd ;
942  int dimElement = axisDomainDstOrder(elementPositionInGrid);
943  if (2 == dimElement) //domain
944  {
945    CDomain* domain = domainListDstP[elementPositionInGridDst2DomainPosition_[elementPositionInGrid]] ;
946    int ni_glo=domain->ni_glo ;
947    int nj_glo=domain->nj_glo ;
948    int nindex_glo=ni_glo*nj_glo ;
949    dstLocalInd.resize(nindex_glo,-1) ;
950    int nIndex=domain->i_index.numElements() ;
951    CArray<bool,1>& localMask=domain->localMask ;
952    int unmaskedInd=0 ;
953    int globIndex ;
954    for(int i=0;i<nIndex;i++)
955    {
956      if (localMask(i))
957      {
958        globIndex=domain->j_index(i)*ni_glo+domain->i_index(i) ;
959        dstLocalInd[globIndex]=unmaskedInd ;
960        unmaskedInd++ ;
961      }
962    }
963  }
964  else if (1 == dimElement) //axis
965  {
966    CAxis* axis = axisListDstP[elementPositionInGridDst2AxisPosition_[elementPositionInGrid]] ;
967    int nindex_glo=axis->n_glo ;
968    dstLocalInd.resize(nindex_glo,-1) ;
969    int nIndex=axis->index.numElements() ;
970    CArray<bool,1>& localMask=axis->mask ; // axis mask must include later data_index
971    int unmaskedInd=0 ;
972    for(int i=0;i<nIndex;i++)
973    {
974      if (localMask(i))
975      {
976        dstLocalInd[axis->index(i)]=unmaskedInd ;
977        unmaskedInd++ ;
978      }
979    }
980  }
981  else  //scalar
982  {
983    dstLocalInd.resize(1) ; 
984    dstLocalInd[0]=0 ; 
985  }
986
987// just get the local src mask
988  CArray<bool,1> localMaskOnSrcGrid;
989  gridSrc->getLocalMask(localMaskOnSrcGrid) ;
990// intermediate grid, mask is not initialized => set up mask to true
991  if (localMaskOnSrcGrid.isEmpty())
992  {
993    localMaskOnSrcGrid.resize(nlocalIndexSrc) ;
994    localMaskOnSrcGrid=true ;
995  }
996 
997
998  localMaskOnGridDest.resize(nlocalIndexDest,false) ;
999
1000  vector<vector<vector<pair<int,double> > > > dstIndWeight(transformationMapping_.size()) ;
1001   
1002  for(int t=0;t<transformationMapping_.size();++t)
1003  {
1004    TransformationIndexMap::const_iterator   itTransMap = transformationMapping_[t].begin(),
1005                                             iteTransMap = transformationMapping_[t].end();
1006    TransformationWeightMap::const_iterator itTransWeight = transformationWeight_[t].begin();
1007    dstIndWeight[t].resize(nIndexSrc[elementPositionInGrid]) ;
1008   
1009    for(;itTransMap!=iteTransMap;++itTransMap,++itTransWeight)
1010    {
1011      int dst=dstLocalInd[itTransMap->first] ;
1012      if (dst!=-1)
1013      {
1014        const vector<int>& srcs=itTransMap->second;
1015        const vector<double>& weights=itTransWeight->second;
1016        for(int i=0;i<srcs.size() ;i++) dstIndWeight[t][srcs[i]].push_back(pair<int,double>(dst*offset+t,weights[i])) ;
1017      }
1018    }
1019  }
1020  int srcInd=0 ; 
1021  int currentInd ;
1022  int t=0 ; 
1023  int srcIndCompressed=0 ;
1024 
1025  nonDistributedrecursiveFunct(nElement-1,true,elementPositionInGrid,maskSrc,maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, 
1026                               currentInd,localSrc,localDst,weight, localMaskOnSrcGrid, localMaskOnGridDest );
1027               
1028}
1029
1030
1031void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd,
1032                    vector<int>& localSrc, vector<int>& localDst, vector<double>& weight,  CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest )
1033{
1034  int masked_ ;
1035  if (currentPos!=elementPositionInGrid)
1036  {
1037    if (currentPos!=0)
1038    {
1039      CArray<bool,1>& mask = *maskSrc[currentPos] ;
1040     
1041      for(int i=0;i<nIndexSrc[currentPos];i++)
1042      {
1043        masked_=masked ;
1044        if (!mask(i)) masked_=false ;
1045        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, currentInd, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ;
1046      }
1047    }
1048    else
1049    {
1050      CArray<bool,1>& mask = *maskSrc[currentPos] ;
1051      for(int i=0;i<nIndexSrc[currentPos];i++)
1052      {
1053        if (masked && mask(i))
1054        {
1055          if (dstIndWeight[t][currentInd].size()>0)
1056          {
1057            for(vector<pair<int,double> >::iterator it = dstIndWeight[t][currentInd].begin(); it!=dstIndWeight[t][currentInd].end(); ++it)
1058            {
1059              if (localMaskOnGridSrc(srcInd))
1060              {
1061                localSrc.push_back(srcIndCompressed) ;
1062                localDst.push_back(it->first) ;
1063                weight.push_back(it->second) ;
1064                localMaskOnGridDest[it->first]=true ;
1065              }
1066              (it->first)++ ;
1067            }
1068          }
1069          if (t < dstIndWeight.size()-1) t++ ;
1070          if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ;
1071        }
1072        srcInd++ ;
1073      }
1074    }
1075  }
1076  else
1077  {
1078 
1079    if (currentPos!=0)
1080    {
1081
1082      CArray<bool,1>& mask = *maskSrc[currentPos] ;
1083      for(int i=0;i<nIndexSrc[currentPos];i++)
1084      {
1085        t=0 ;
1086        masked_=masked ;
1087        if (!mask(i)) masked_=false ; 
1088        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight , i,  localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ;
1089      }
1090    }
1091    else
1092    {
1093      for(int i=0;i<nIndexSrc[currentPos];i++)
1094      {
1095        if (masked)
1096        {
1097          t=0 ;       
1098          if (dstIndWeight[t][i].size()>0)
1099          {
1100            for(vector<pair<int,double> >::iterator it = dstIndWeight[t][i].begin(); it!=dstIndWeight[t][i].end(); ++it)
1101            {
1102              if (localMaskOnGridSrc(srcInd))
1103              {
1104                localSrc.push_back(srcIndCompressed) ;
1105                localDst.push_back(it->first) ;
1106                weight.push_back(it->second) ;
1107                localMaskOnGridDest[it->first]=true ;
1108              }
1109              (it->first)++ ;
1110            }
1111           }
1112          if (t < dstIndWeight.size()-1) t++ ;
1113          if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ;
1114        }
1115        srcInd++ ;
1116      }
1117    }
1118  }
1119
1120}
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132/*!
1133  Compute index mapping between element source and element destination with an auxiliary inputs which determine
1134position of each mapped index in global index of grid destination.
1135  \param [in] dataAuxInputs auxiliary inputs
1136*/
1137void CGenericAlgorithmTransformation::computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs)
1138{
1139  computeIndexSourceMapping_(dataAuxInputs);
1140}
1141
1142std::vector<StdString> CGenericAlgorithmTransformation::getIdAuxInputs()
1143{
1144  return idAuxInputs_;
1145}
1146
1147CGenericAlgorithmTransformation::AlgoTransType CGenericAlgorithmTransformation::type()
1148{
1149  return type_;
1150}
1151
1152}
Note: See TracBrowser for help on using the repository browser.