Virtual Testbed
Ship dynamics simulator for extreme conditions
grid_interpolation.hh
1 #ifndef VTESTBED_CORE_GRID_INTERPOLATION_HH
2 #define VTESTBED_CORE_GRID_INTERPOLATION_HH
3 
4 #include <vtestbed/core/grid.hh>
5 
6 namespace vtb {
7 
8  namespace core {
9 
10  template <class T, int N, class Function, class Return=T>
12 
13  public:
14  using vertex_type = blitz::TinyVector<T,N>;
15  using grid_type = Grid<T,N>;
16  using index_type = blitz::TinyVector<int,N>;
17  using function_type = Function;
18  using return_type = Return;
19 
20  private:
21  grid_type _grid;
22  function_type _function;
23 
24  public:
25 
26  inline explicit
27  Grid_interpolation(const grid_type& grid, function_type function):
28  _grid(grid), _function(function) {}
29 
30  inline return_type
31  operator()(const vertex_type& x) {
32  #if defined(VTB_DEBUG_INTERPOLATION)
33  this->detect_extrapolation(x);
34  #endif
35  const auto& grid = this->_grid;
36  index_type idx_max{grid.shape()-1};
37  index_type i00{floor(grid.index(x))};
38  i00 = blitz::clamp(i00, grid.begin(), index_type(idx_max-1));
39  return this->_function(x, i00);
40  }
41 
42  inline const grid_type& grid() const { return this->_grid; }
43  inline const function_type& function() const { return this->_function; }
44 
45  private:
46 
47  #if defined(VTB_DEBUG_INTERPOLATION)
48  inline void
49  detect_extrapolation(const vertex_type& x) {
50  const auto& grid = this->_grid;
51  if (!grid.contains(x)) {
52  bool success = true;
53  for (int i=0; i<2; ++i) {
54  using std::abs;
55  T x_min = grid.lbound(i);
56  T x_max = grid.ubound(i);
57  if (x(i) < x_min && std::abs(x(i)-x_min) > T{1e-3}) {
58  success = false;
59  }
60  if (x(i) > x_max && std::abs(x(i)-x_max) > T{1e-3}) {
61  success = false;
62  }
63  }
64  if (!success) {
65  std::clog << "_grid=" << _grid << std::endl;
66  std::clog << "x=" << x << std::endl;
67  throw std::runtime_error("extrapolation");
68  }
69  }
70  }
71  #endif
72 
73  };
74 
75  template <class T>
77 
78  public:
79  using vec3 = blitz::TinyVector<T,3>;
80  using vec2 = blitz::TinyVector<T,2>;
81  using vertex_matrix = blitz::Array<vec3,2>;
82  using index_type = blitz::TinyVector<int,2>;
83 
84  private:
85  vertex_matrix _points;
86 
87  public:
88 
89  inline explicit
90  Barycentric_function(const vertex_matrix& points): _points(points) {}
91 
92  T operator()(const vec2& x, const index_type& i00);
93 
94  };
95 
96  template <class T,int N>
98 
99  public:
100  using array_type = blitz::Array<T,N>;
101  using vertex_type = blitz::TinyVector<T,N>;
102  using index_type = blitz::TinyVector<int,N>;
103  using grid_type = Grid<T,N>;
104 
105  private:
106  array_type _func;
107  grid_type _grid;
108 
109  public:
110 
111  inline explicit
112  Linear_function(array_type func, const grid_type& grid):
113  _func(func), _grid(grid) {}
114 
115  T operator()(const vertex_type& x, const index_type& i00);
116 
117  };
118 
125  template <class T>
127 
128  public:
129  using vec3 = blitz::TinyVector<T,3>;
130  using vec2 = blitz::TinyVector<T,2>;
131  using vertex_matrix = blitz::Array<vec3,2>;
132  using index_type = blitz::TinyVector<int,2>;
133 
134  private:
135  vertex_matrix _points;
136  T _order{1};
137  T _sigma{1};
138 
139  public:
140  inline explicit
142  const vertex_matrix& points,
143  T order = T{1},
144  T sigma = T{1}
145  ): _points(points), _order(order), _sigma(sigma) {}
146 
147  T operator()(const vec2& x, const index_type& i00);
148 
149  };
150 
151  template <class T, int N>
153  public Grid_interpolation<T,N,Linear_function<T,N>> {
154 
155  public:
157  using array_type = blitz::Array<T,N>;
158  using grid_type = Grid<T,N>;
159 
160  private:
162 
163  public:
164  using base_type::base_type;
165  using base_type::operator();
166 
167  inline explicit
168  Linear_interpolation(array_type points, const grid_type& grid):
169  base_type(grid, function_type(points,grid)) {}
170 
171  };
172 
179  template <class T, class Return=T>
181 
182  public:
183  using return_type = Return;
184  using vec3 = blitz::TinyVector<T,3>;
185  using vertex_field = blitz::Array<return_type,3>;
186  using index_type = blitz::TinyVector<int,3>;
187  using grid_type = Grid<T,3>;
188 
189  private:
190  vertex_field _points;
191  grid_type _grid;
192 
193  public:
194  inline explicit
195  Linear_function_irregular(const vertex_field& points, const grid_type& grid):
196  _points(points), _grid(grid) {}
197 
198  return_type operator()(const vec3& x, const index_type& i00);
199 
200  };
201 
202  }
203 
204 }
205 
206 #endif // vim:filetype=cpp
const vec & lbound() const noexcept
Lower bound of the region.
Definition: core/grid.hh:168
Nearest neighbour weighted interpolation for 3-d fields.
const int_n shape() const noexcept
The number of points for all dimensions.
Definition: core/grid.hh:108
A region defined by start and end index and lower and upper bound for each dimension.
Definition: core/grid.hh:25
Radial basis function interpolation.
const int_n & begin() const noexcept
Start indices (inclusive).
Definition: core/grid.hh:120
Main namespace.
Definition: convert.hh:9
const vec & ubound() const noexcept
Upper bound of the region.
Definition: core/grid.hh:190