source: XIOS/dev/branch_openmp/src/transformation/generic_algorithm_transformation.cpp @ 1482

Last change on this file since 1482 was 1482, checked in by yushan, 3 years ago

Branch EP merged with Dev_cmip6 @r1481

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