2D example – scalar field

Besides the generation of splines of arbitrary dimension, another core feature of this library is the support for various boundary conditions in different dimensions.

In the following, a 2-dimensional case is discussed in detail. The data is prepared in the same manner as before. However, the boundary conditions are different. In this case, we use clamped and natural boundary conditions in the \(x\)-direction at \(x=0\) and \(x=1\), respectively, and periodicity in the \(y\)-direction:

bc = (
    ("first_derivative", "second_derivative"), 
    ("periodic", "periodic"),
    )

The following values are specified:

bc_value = (
    (1.0, -2.0), 
    (0.0, 0.0),
    )

Note

In case of a periodic boundary constraint, both edges of the domain are periodic. This is checked inside Spline1D and corrected if necessary, i.e., all values inside the tuple of the corresponding dimension are set to "periodic". The boundary condition values are not of any meaning in this case.

In addition to the differing boundary conditions, the dummy data has to be periodic in the dimension where periodicity is imposed. This is done by setting the first and last value of the dummy data to be equal:

dummy_data[:, 0] = dummy_data[:, -1]
dummy_data = dummy_data.ravel()

The Spline1D class raises an error if the dummy data is not periodic. The resulting spline surface should look similar to the following:

2d_spline_first-second-peri

In addition to the 3-dimensional view of the spline surface, the boundary conditions are checked by inspecting the gradient and Hessian along the edges of the domain. The partial derivative w.r.t. the \(x\)-axis \(\partial f/\partial x\) along the left edge \(x\equiv 0 \cap y \in [0, 0.8]\) should be equal to the first boundary condition value, and the second order partial derivative w.r.t. the \(x\)-axis \(\partial^2 f/\partial x^2\) along the right edge \(x\equiv 1 \cap y \in [0, 0.8]\) should be equal to the second boundary condition value. This is indeed the case.

The periodic edges \(y = \lbrace 0, 0.8 \rbrace \cap x \in [0, 1]\) are inspected by means of the values along the left and right edge of the domain – they are equal as required by periodicity. The first and second derivative along the \(y\)-direction (normal to the periodic edges) are checked separately:

# checking first and second derivative along periodic edges
dy_vals = dvals[:, 1].reshape(x_spline_eval_grid.shape)
ddy_vals = ddvals[:, 1, 1].reshape(x_spline_eval_grid.shape)

assert np.allclose(dy_vals[:, 0], dy_vals[:, -1])
assert np.allclose(ddy_vals[:, 0], ddy_vals[:, -1])