- Timestamp:
- 03/23/16 16:10:45 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
XIOS/trunk/src/transformation/axis_algorithm_interpolate.cpp
r668 r827 12 12 #include "context_client.hpp" 13 13 #include "utils.hpp" 14 #include "grid.hpp" 15 #include "distribution_client.hpp" 14 16 15 17 namespace xios { 16 18 17 19 CAxisAlgorithmInterpolate::CAxisAlgorithmInterpolate(CAxis* axisDestination, CAxis* axisSource, CInterpolateAxis* interpAxis) 18 : CAxisAlgorithmTransformation(axisDestination, axisSource) 20 : CAxisAlgorithmTransformation(axisDestination, axisSource), coordinate_(), transPosition_() 19 21 { 20 22 interpAxis->checkValid(axisSource); 21 23 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(); 31 32 } 32 33 … … 34 35 Compute the index mapping between axis on grid source and one on grid destination 35 36 */ 36 void CAxisAlgorithmInterpolate::computeIndexSourceMapping() 37 { 38 CArray<double,1>& axisValue = axisSrc_->value; 39 CArray<bool,1>& axisMask = axisSrc_->mask; 40 37 void CAxisAlgorithmInterpolate::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs) 38 { 41 39 CContext* context = CContext::getCurrent(); 42 40 CContextClient* client=context->client; 43 41 int nbClient = client->clientSize; 44 42 CArray<bool,1>& axisMask = axisSrc_->mask; 45 43 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 } 54 58 } 55 59 … … 60 64 \param [in] indexVec permutation index of axisValue 61 65 */ 62 void CAxisAlgorithmInterpolate::computeInterpolantPoint(const std::vector<double>& axisValue, const std::vector<int>& indexVec )66 void CAxisAlgorithmInterpolate::computeInterpolantPoint(const std::vector<double>& axisValue, const std::vector<int>& indexVec, int transPos) 63 67 { 64 68 std::vector<double>::const_iterator itb = axisValue.begin(), ite = axisValue.end(); … … 78 82 itUpperBound = std::upper_bound(itb, ite, destValue); 79 83 if ((ite != itUpperBound) && (sfmax == *itUpperBound)) itUpperBound = ite; 80 81 84 82 85 // If the value is not in the range, that means we'll do extra-polation … … 118 121 } 119 122 } 120 computeWeightedValueAndMapping(interpolatingIndexValues );123 computeWeightedValueAndMapping(interpolatingIndexValues, transPos); 121 124 } 122 125 … … 125 128 \param [in] interpolatingIndexValues the necessary axis value to calculate the coeffs 126 129 */ 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_ ;130 void 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]; 131 134 std::map<int, std::vector<std::pair<int,double> > >::const_iterator itb = interpolatingIndexValues.begin(), it, 132 135 ite = interpolatingIndexValues.end(); … … 138 141 const std::vector<std::pair<int,double> >& interpVal = it->second; 139 142 int interpSize = interpVal.size(); 143 transMap[globalIndexDest].resize(interpSize); 144 transWeight[globalIndexDest].resize(interpSize); 140 145 for (int idx = 0; idx < interpSize; ++idx) 141 146 { … … 149 154 weight /= (interpVal[idx].second - interpVal[k].second); 150 155 } 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 } 153 162 } 154 163 } … … 160 169 \param [in/out] indexVec mapping between values and global index of axis 161 170 */ 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 171 void CAxisAlgorithmInterpolate::retrieveAllAxisValue(const CArray<double,1>& axisValue, const CArray<bool,1>& axisMask, 172 std::vector<double>& recvBuff, std::vector<int>& indexVec) 173 { 167 174 CContext* context = CContext::getCurrent(); 168 175 CContextClient* client=context->client; … … 230 237 } 231 238 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 */ 243 void 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.