Loading [MathJax]/extensions/tex2jax.js
PISM, A Parallel Ice Sheet Model 2.2.2-d6b3a29ca committed by Constantine Khrulev on 2025-03-28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Interpolation1D.hh
Go to the documentation of this file.
1/* Copyright (C) 2015, 2017, 2018, 2019, 2021, 2022, 2023, 2024 PISM Authors
2 *
3 * This file is part of PISM.
4 *
5 * PISM is free software; you can redistribute it and/or modify it under the
6 * terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 3 of the License, or (at your option) any later
8 * version.
9 *
10 * PISM is distributed in the hope that it will be useful, but WITHOUT ANY
11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with PISM; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifndef PISM_INTERPOLATION_H
21#define PISM_INTERPOLATION_H
22
23#include <cstddef> // size_t
24#include <vector>
25#include <map>
26
27namespace pism {
28
30
31/**
32 * Class encapsulating linear and piece-wise constant interpolation indexes and weights.
33 *
34 * Most library interpolation routines (GSL's, for example) assume that we are working with a fixed
35 * function given on an input grid; these libraries support evaluating this function at arbitrary
36 * points. In this case an interpolation routine may use values on the input grid to create an
37 * interpolant, but has no knowledge of an "output grid."
38 *
39 * In PISM we have a slightly different situation: we need to transfer several gridded functions
40 * between two *fixed* grids, so we can use both grids to compute interpolation weights, but cannot
41 * use values on the input grid.
42 *
43 * If a point on the output grid is outside the interval defined by the input grid this code uses
44 * *constant extrapolation*.
45 *
46 * This class isolates the code computing interpolation weights so that we can use these 1D weights
47 * in a 2D or 3D regridding code. This avoids code duplication: in bilinear (trilinear)
48 * interpolation X and Y (and Z) grid dimensions are treated the same. This also makes it possible
49 * to test the code computing interpolation weights in isolation.
50 *
51 * We provide getters `left()`, `right()` and `alpha()`.
52 *
53 * Here `left[i]` is the index in the input grid (`x_input`) such that
54 * ~~~ c++
55 * input_x[left[i]] < output_x[i]
56 * ~~~
57 * similar for `right[i]`:
58 * ~~~ c++
59 * input_x[right[i]] >= output_x[i]
60 * ~~~
61 * When `output_x[i]` is outside the input interval `left[i]` and `right[i]` are adjusted so that
62 * the interpolation formula below corresponds to constant extrapolation.
63 *
64 * `alpha[i]` is the linear interpolation weight used like this:
65 * ~~~ c++
66 * const int
67 * L = m_left[k],
68 * R = m_right[k];
69 * const double Alpha = m_alpha[k];
70 * result[k] = input_values[L] + Alpha * (input_values[R] - input_values[L]);
71 * ~~~
72 *
73 * Piecewise constant 1D interpolation used for time-dependent forcing (fluxes that should
74 * be interpreted as piecewise-constant to simplify accounting of mass conservation).
75 *
76 * Here `input_x` defines left end-points of intervals, For example, [0, 1] defines two
77 * intervals: [0, 1) and [1, x_e). Here the value x_e is irrelevant because we use
78 * constant extrapolation for points outside the interval covered by input data.
79 *
80 */
82public:
83 Interpolation1D(InterpolationType type, const std::vector<double> &input_x,
84 const std::vector<double> &output_x);
85 Interpolation1D(InterpolationType type, const double *input_x, unsigned int input_x_size,
86 const double *output_x, unsigned int output_x_size);
87
88 const std::vector<int>& left() const;
89 const std::vector<int>& right() const;
90 const std::vector<double>& alpha() const;
91
92 int left(size_t j) const;
93 int right(size_t j) const;
94 double alpha(size_t j) const;
95
96 /*!
97 * Number of grid points in the output grid.
98 */
99 int n_output() const;
100
101 //! Return interpolated values (on the output grid) given `input_values` on the input grid.
102 /** This is used for testing. (Regular code calls left(), right(), and alpha().)
103 */
104 std::vector<double> interpolate(const std::vector<double> &input_values) const;
105
106 /*!
107 * Compute interpolated values on the output grid given values on the input grid.
108 */
109 void interpolate(const double *input, double *output) const;
110
111private:
112 //! Interpolation indexes
113 std::vector<int> m_left, m_right;
114 //! Interpolation weights
115 std::vector<double> m_alpha;
116
117 void init_linear(const double *input_x, unsigned int input_x_size,
118 const double *output_x, unsigned int output_x_size);
119 void init_nearest(const double *input_x, unsigned int input_x_size,
120 const double *output_x, unsigned int output_x_size);
121 void init_piecewise_constant(const double *input_x, unsigned int input_x_size,
122 const double *output_x, unsigned int output_x_size);
123};
124
125std::map<size_t, double> integration_weights(const double *x,
126 size_t x_size,
128 double a,
129 double b);
130
131std::map<size_t, double> integration_weights(const std::vector<double> &x,
133 double a,
134 double b);
135
136} // end of namespace pism
137
138#endif /* PISM_INTERPOLATION_H */
void init_linear(const double *input_x, unsigned int input_x_size, const double *output_x, unsigned int output_x_size)
void init_piecewise_constant(const double *input_x, unsigned int input_x_size, const double *output_x, unsigned int output_x_size)
std::vector< int > m_right
std::vector< double > m_alpha
Interpolation weights.
const std::vector< double > & alpha() const
const std::vector< int > & right() const
void init_nearest(const double *input_x, unsigned int input_x_size, const double *output_x, unsigned int output_x_size)
const std::vector< int > & left() const
std::vector< int > m_left
Interpolation indexes.
std::vector< double > interpolate(const std::vector< double > &input_values) const
Return interpolated values (on the output grid) given input_values on the input grid.
@ PIECEWISE_CONSTANT
std::map< size_t, double > integration_weights(const double *x, size_t x_size, InterpolationType type, double a, double b)