Ignore:
Timestamp:
03/23/16 16:10:45 (8 years ago)
Author:
mhnguyen
Message:

Implementing dynamic interpolation on axis

+) Change grid transformation to make it more flexible
+) Make some small improvements

Test
+) On Curie
+) All test pass

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/transformation/axis_algorithm_interpolate.cpp

    r668 r827  
    1212#include "context_client.hpp" 
    1313#include "utils.hpp" 
     14#include "grid.hpp" 
     15#include "distribution_client.hpp" 
    1416 
    1517namespace xios { 
    1618 
    1719CAxisAlgorithmInterpolate::CAxisAlgorithmInterpolate(CAxis* axisDestination, CAxis* axisSource, CInterpolateAxis* interpAxis) 
    18 : CAxisAlgorithmTransformation(axisDestination, axisSource) 
     20: CAxisAlgorithmTransformation(axisDestination, axisSource), coordinate_(), transPosition_() 
    1921{ 
    2022  interpAxis->checkValid(axisSource); 
    2123  order_ = interpAxis->order.getValue(); 
    22   if (order_ >= axisSource->n_glo.getValue()) 
    23   { 
    24     ERROR("CAxisAlgorithmInterpolate::CAxisAlgorithmInterpolate(CAxis* axisDestination, CAxis* axisSource, CInterpolateAxis* interpAxis)", 
    25            << "Order of interpolation is greater than global size of axis source" 
    26            << "Size of axis source " <<axisSource->getId() << " is " << axisSource->n_glo.getValue()  << std::endl 
    27            << "Order of interpolation is " << order_ ); 
    28   } 
    29  
    30   computeIndexSourceMapping(); 
     24  if (!interpAxis->coordinate.isEmpty()) 
     25  { 
     26    coordinate_ = interpAxis->coordinate.getValue(); 
     27    this->idAuxInputs_.resize(1); 
     28    this->idAuxInputs_[0] = coordinate_; 
     29  } 
     30 
     31//  computeIndexSourceMapping(); 
    3132} 
    3233 
     
    3435  Compute the index mapping between axis on grid source and one on grid destination 
    3536*/ 
    36 void CAxisAlgorithmInterpolate::computeIndexSourceMapping() 
    37 { 
    38   CArray<double,1>& axisValue = axisSrc_->value; 
    39   CArray<bool,1>& axisMask = axisSrc_->mask; 
    40  
     37void CAxisAlgorithmInterpolate::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs) 
     38{ 
    4139  CContext* context = CContext::getCurrent(); 
    4240  CContextClient* client=context->client; 
    4341  int nbClient = client->clientSize; 
    44  
     42  CArray<bool,1>& axisMask = axisSrc_->mask; 
    4543  int srcSize  = axisSrc_->n_glo.getValue(); 
    46   int numValue = axisValue.numElements(); 
    47  
    48   std::vector<double> recvBuff(srcSize); 
    49   std::vector<int> indexVec(srcSize); 
    50  
    51   retrieveAllAxisValue(recvBuff, indexVec); 
    52   XIOSAlgorithms::sortWithIndex<double, CVectorStorage>(recvBuff, indexVec); 
    53   computeInterpolantPoint(recvBuff, indexVec); 
     44  std::vector<CArray<double,1> > vecAxisValue; 
     45 
     46  // Fill in axis value from coordinate 
     47  fillInAxisValue(vecAxisValue, dataAuxInputs); 
     48 
     49  for (int idx = 0; idx < vecAxisValue.size(); ++idx) 
     50  { 
     51    CArray<double,1>& axisValue = vecAxisValue[idx]; 
     52    std::vector<double> recvBuff(srcSize); 
     53    std::vector<int> indexVec(srcSize); 
     54    retrieveAllAxisValue(axisValue, axisMask, recvBuff, indexVec); 
     55    XIOSAlgorithms::sortWithIndex<double, CVectorStorage>(recvBuff, indexVec); 
     56    computeInterpolantPoint(recvBuff, indexVec, idx); 
     57  } 
    5458} 
    5559 
     
    6064  \param [in] indexVec permutation index of axisValue 
    6165*/ 
    62 void CAxisAlgorithmInterpolate::computeInterpolantPoint(const std::vector<double>& axisValue, const std::vector<int>& indexVec) 
     66void CAxisAlgorithmInterpolate::computeInterpolantPoint(const std::vector<double>& axisValue, const std::vector<int>& indexVec, int transPos) 
    6367{ 
    6468  std::vector<double>::const_iterator itb = axisValue.begin(), ite = axisValue.end(); 
     
    7882    itUpperBound = std::upper_bound(itb, ite, destValue); 
    7983    if ((ite != itUpperBound) && (sfmax == *itUpperBound)) itUpperBound = ite; 
    80  
    8184 
    8285    // If the value is not in the range, that means we'll do extra-polation 
     
    118121    } 
    119122  } 
    120   computeWeightedValueAndMapping(interpolatingIndexValues); 
     123  computeWeightedValueAndMapping(interpolatingIndexValues, transPos); 
    121124} 
    122125 
     
    125128  \param [in] interpolatingIndexValues the necessary axis value to calculate the coeffs 
    126129*/ 
    127 void CAxisAlgorithmInterpolate::computeWeightedValueAndMapping(const std::map<int, std::vector<std::pair<int,double> > >& interpolatingIndexValues) 
    128 { 
    129   std::map<int, std::vector<int> >& transMap = this->transformationMapping_; 
    130   std::map<int, std::vector<double> >& transWeight = this->transformationWeight_; 
     130void CAxisAlgorithmInterpolate::computeWeightedValueAndMapping(const std::map<int, std::vector<std::pair<int,double> > >& interpolatingIndexValues, int transPos) 
     131{ 
     132  std::map<int, std::vector<int> >& transMap = this->transformationMapping_[transPos]; 
     133  std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[transPos]; 
    131134  std::map<int, std::vector<std::pair<int,double> > >::const_iterator itb = interpolatingIndexValues.begin(), it, 
    132135                                                                      ite = interpolatingIndexValues.end(); 
     
    138141    const std::vector<std::pair<int,double> >& interpVal = it->second; 
    139142    int interpSize = interpVal.size(); 
     143    transMap[globalIndexDest].resize(interpSize); 
     144    transWeight[globalIndexDest].resize(interpSize); 
    140145    for (int idx = 0; idx < interpSize; ++idx) 
    141146    { 
     
    149154        weight /= (interpVal[idx].second - interpVal[k].second); 
    150155      } 
    151       transMap[globalIndexDest].push_back(index); 
    152       transWeight[globalIndexDest].push_back(weight); 
     156      transMap[globalIndexDest][idx] = index; 
     157      transWeight[globalIndexDest][idx] = weight; 
     158      if (!transPosition_.empty()) 
     159      { 
     160        (this->transformationPosition_[transPos])[globalIndexDest] = transPosition_[transPos]; 
     161      } 
    153162    } 
    154163  } 
     
    160169  \param [in/out] indexVec mapping between values and global index of axis 
    161170*/ 
    162 void CAxisAlgorithmInterpolate::retrieveAllAxisValue(std::vector<double>& recvBuff, std::vector<int>& indexVec) 
    163 { 
    164   CArray<double,1>& axisValue = axisSrc_->value; 
    165   CArray<bool,1>& axisMask = axisSrc_->mask; 
    166  
     171void CAxisAlgorithmInterpolate::retrieveAllAxisValue(const CArray<double,1>& axisValue, const CArray<bool,1>& axisMask, 
     172                                                     std::vector<double>& recvBuff, std::vector<int>& indexVec) 
     173{ 
    167174  CContext* context = CContext::getCurrent(); 
    168175  CContextClient* client=context->client; 
     
    230237} 
    231238 
    232 } 
     239/*! 
     240  Fill in axis value dynamically from a field whose grid is composed of a domain and an axis 
     241  \param [in/out] vecAxisValue vector axis value filled in from input field 
     242*/ 
     243void CAxisAlgorithmInterpolate::fillInAxisValue(std::vector<CArray<double,1> >& vecAxisValue, 
     244                                                const std::vector<CArray<double,1>* >& dataAuxInputs) 
     245{ 
     246  if (coordinate_.empty()) 
     247  { 
     248    vecAxisValue.resize(1); 
     249    vecAxisValue[0].resize(axisSrc_->value.numElements()); 
     250    vecAxisValue[0] = axisSrc_->value; 
     251    this->transformationMapping_.resize(1); 
     252    this->transformationWeight_.resize(1); 
     253  } 
     254  else 
     255  { 
     256    CField* field = CField::get(coordinate_); 
     257    CGrid* grid = field->grid; 
     258 
     259    std::vector<CDomain*> domListP = grid->getDomains(); 
     260    std::vector<CAxis*> axisListP = grid->getAxis(); 
     261    if (domListP.empty() || axisListP.empty() || (1 < domListP.size()) || (1 < axisListP.size())) 
     262      ERROR("CAxisAlgorithmInterpolate::fillInAxisValue(std::vector<CArray<double,1> >& vecAxisValue)", 
     263             << "XIOS only supports dynamic interpolation with coordinate (field) associated with grid composed of a domain and an axis" 
     264             << "Coordinate (field) id = " <<field->getId() << std::endl 
     265             << "Associated grid id = " << grid->getId()); 
     266 
     267    CDomain* dom = domListP[0]; 
     268    size_t vecAxisValueSize = dom->i_index.numElements(); 
     269    vecAxisValue.resize(vecAxisValueSize); 
     270    if (transPosition_.empty()) 
     271    { 
     272      transPosition_.resize(vecAxisValueSize); 
     273      for (size_t idx = 0; idx < vecAxisValueSize; ++idx) 
     274      { 
     275        transPosition_[idx].resize(2); 
     276        transPosition_[idx][0] = (dom->i_index)(idx); 
     277        transPosition_[idx][1] = (dom->j_index)(idx); 
     278      } 
     279    } 
     280    this->transformationMapping_.resize(vecAxisValueSize); 
     281    this->transformationWeight_.resize(vecAxisValueSize); 
     282    this->transformationPosition_.resize(vecAxisValueSize); 
     283 
     284    const std::vector<size_t>& globalIndexSendToServer = grid->getDistributionClient()->getGlobalDataIndexSendToServer(); 
     285    const std::vector<int>& localDataSendToServer = grid->getDistributionClient()->getLocalDataIndexSendToServer(); 
     286    std::vector<int> permutIndex(globalIndexSendToServer.size()); 
     287    std::vector<int>::iterator itVec; 
     288    XIOSAlgorithms::fillInIndex(globalIndexSendToServer.size(), permutIndex); 
     289    XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexSendToServer, permutIndex); 
     290    size_t axisSrcSize = axisSrc_->index.numElements(); 
     291    std::vector<int> globalDimension = grid->getGlobalDimension(); 
     292    XIOSBinarySearchWithIndex<size_t> binSearch(globalIndexSendToServer); 
     293    for (size_t idx = 0; idx < vecAxisValueSize; ++idx) 
     294    { 
     295      size_t axisValueSize = 0; 
     296      for (size_t jdx = 0; jdx < axisSrcSize; ++jdx) 
     297      { 
     298        size_t globalIndex = ((dom->i_index)(idx) + (dom->j_index)(idx)*globalDimension[0]) + (axisSrc_->index)(jdx)*globalDimension[0]*globalDimension[1]; 
     299        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndex, itVec)) 
     300        { 
     301          ++axisValueSize; 
     302        } 
     303      } 
     304 
     305      vecAxisValue[idx].resize(axisValueSize); 
     306      axisValueSize = 0; 
     307      for (size_t jdx = 0; jdx < axisSrcSize; ++jdx) 
     308      { 
     309        size_t globalIndex = ((dom->i_index)(idx) + (dom->j_index)(idx)*globalDimension[0]) + (axisSrc_->index)(jdx)*globalDimension[0]*globalDimension[1]; 
     310        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndex, itVec)) 
     311        { 
     312          vecAxisValue[idx](axisValueSize) = (*dataAuxInputs[0])(localDataSendToServer[*itVec]); 
     313          ++axisValueSize; 
     314        } 
     315      } 
     316    } 
     317  } 
     318} 
     319 
     320} 
Note: See TracChangeset for help on using the changeset viewer.