source: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/generic_algorithm_transformation.cpp @ 1853

Last change on this file since 1853 was 1784, checked in by ymipsl, 4 years ago
  • Preparing coupling functionalities.
  • Make some cleaner things

YM

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