Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2016-2018 The VES code team 3 : (see the PEOPLE-VES file at the root of this folder for a list of names) 4 : 5 : See http://www.ves-code.org for more information. 6 : 7 : This file is part of VES code module. 8 : 9 : The VES code module is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : The VES code module is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with the VES code module. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : 23 : #include "GridLinearInterpolation.h" 24 : 25 : #include "tools/Grid.h" 26 : #include "tools/Exception.h" 27 : #include "tools/Tools.h" 28 : 29 : 30 : namespace PLMD { 31 : namespace ves { 32 : 33 : 34 1869 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_1D(Grid* grid_pntr, const std::vector<double>& arg) { 35 : 36 1869 : plumed_massert(grid_pntr->getDimension()==1,"The grid is of the wrong dimension, should be one-dimensional"); 37 1869 : plumed_massert(arg.size()==1,"input value is of the wrong size"); 38 : 39 1869 : double x = arg[0]; 40 5607 : double grid_dx = grid_pntr->getDx()[0]; 41 3738 : double grid_min; Tools::convert( grid_pntr->getMin()[0], grid_min); 42 3738 : std::vector<unsigned int> i0(1); i0[0] = unsigned( std::floor( (x-grid_min)/grid_dx ) ); 43 3738 : std::vector<unsigned int> i1(1); i1[0] = unsigned( std::ceil( (x-grid_min)/grid_dx ) ); 44 : // 45 5607 : double x0 = grid_pntr->getPoint(i0)[0]; 46 5607 : double x1 = grid_pntr->getPoint(i1)[0]; 47 1869 : double y0 = grid_pntr->getValue(i0); 48 1869 : double y1 = grid_pntr->getValue(i1); 49 : // 50 1869 : return linearInterpolation(x,x0,x1,y0,y1); 51 : } 52 : 53 : 54 47164 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_2D(Grid* grid_pntr, const std::vector<double>& arg) { 55 47164 : plumed_massert(grid_pntr->getDimension()==2,"The grid is of the wrong dimension, should be two-dimensional"); 56 47164 : plumed_massert(arg.size()==2,"input value is of the wrong size"); 57 : 58 47164 : std::vector<double> grid_delta = grid_pntr->getDx(); 59 47164 : std::vector<double> grid_min(2); 60 94328 : Tools::convert( grid_pntr->getMin()[0], grid_min[0]); 61 94328 : Tools::convert( grid_pntr->getMin()[1], grid_min[1]); 62 : 63 47164 : std::vector<unsigned int> i00(2); 64 47164 : std::vector<unsigned int> i01(2); 65 47164 : std::vector<unsigned int> i10(2); 66 47164 : std::vector<unsigned int> i11(2); 67 : 68 235820 : i00[0] = i01[0] = unsigned( std::floor( (arg[0]-grid_min[0])/grid_delta[0] ) ); 69 235820 : i10[0] = i11[0] = unsigned( std::ceil( (arg[0]-grid_min[0])/grid_delta[0] ) ); 70 : 71 235820 : i00[1] = i10[1] = unsigned( std::floor( (arg[1]-grid_min[1])/grid_delta[1] ) ); 72 235820 : i01[1] = i11[1] = unsigned( std::ceil( (arg[1]-grid_min[1])/grid_delta[1] ) ); 73 : 74 : // https://en.wikipedia.org/wiki/Bilinear_interpolation 75 47164 : double x = arg[0]; 76 47164 : double y = arg[1]; 77 : 78 141492 : double x0 = grid_pntr->getPoint(i00)[0]; 79 141492 : double x1 = grid_pntr->getPoint(i10)[0]; 80 141492 : double y0 = grid_pntr->getPoint(i00)[1]; 81 141492 : double y1 = grid_pntr->getPoint(i11)[1]; 82 : 83 47164 : double f00 = grid_pntr->getValue(i00); 84 47164 : double f01 = grid_pntr->getValue(i01); 85 47164 : double f10 = grid_pntr->getValue(i10); 86 47164 : double f11 = grid_pntr->getValue(i11); 87 : 88 : // linear interpolation in x-direction 89 : double fx0 = linearInterpolation(x,x0,x1,f00,f10); 90 : double fx1 = linearInterpolation(x,x0,x1,f01,f11); 91 : // linear interpolation in y-direction 92 : double fxy = linearInterpolation(y,y0,y1,fx0,fx1); 93 : // 94 47164 : return fxy; 95 : } 96 : 97 : 98 49033 : double GridLinearInterpolation::getGridValueWithLinearInterpolation(Grid* grid_pntr, const std::vector<double>& arg) { 99 49033 : unsigned int dim = grid_pntr->getDimension(); 100 49033 : if(dim==1) { 101 1869 : return getGridValueWithLinearInterpolation_1D(grid_pntr,arg); 102 : } 103 47164 : else if(dim==2) { 104 47164 : return getGridValueWithLinearInterpolation_2D(grid_pntr,arg); 105 : } 106 : else { 107 0 : plumed_merror("GridLinearInterpolation::getGridValueWithLinearInterpolation only defined for 1D or 2D grids"); 108 : } 109 : } 110 : 111 : 112 : 113 : } 114 : }