deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
function_cspline.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2016 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
14#include <deal.II/base/point.h>
15
16#ifdef DEAL_II_WITH_GSL
17# include <gsl/gsl_spline.h>
18
19# include <algorithm>
20# include <cmath>
21
22
23
24#endif
25
27
28#ifdef DEAL_II_WITH_GSL
29namespace Functions
30{
31 template <int dim>
32 CSpline<dim>::CSpline(const std::vector<double> &x_,
33 const std::vector<double> &y_)
34 : interpolation_points(x_)
35 , interpolation_values(y_)
36 , acc(gsl_interp_accel_alloc(),
37 [](gsl_interp_accel *p) { gsl_interp_accel_free(p); })
38 , cspline(gsl_spline_alloc(gsl_interp_cspline, interpolation_points.size()),
39 [](gsl_spline *p) { gsl_spline_free(p); })
40 {
41 Assert(interpolation_points.size() > 0,
42 ExcCSplineEmpty(interpolation_points.size()));
43
44 Assert(interpolation_points.size() == interpolation_values.size(),
45 ExcCSplineSizeMismatch(interpolation_points.size(),
46 interpolation_values.size()));
47
48 // check that input vector @p interpolation_points is provided in ascending order:
49 for (unsigned int i = 0; i < interpolation_points.size() - 1; ++i)
50 AssertThrow(interpolation_points[i] < interpolation_points[i + 1],
52 interpolation_points[i],
53 interpolation_points[i + 1]));
54
55 const unsigned int n = interpolation_points.size();
56 // gsl_spline_init returns something but it seems nobody knows what
57 gsl_spline_init(cspline.get(),
58 interpolation_points.data(),
59 interpolation_values.data(),
60 n);
61 }
62
63
64
65 template <int dim>
66 double
67 CSpline<dim>::value(const Point<dim> &p, const unsigned int) const
68 {
69 // GSL functions may modify gsl_interp_accel *acc object (last argument).
70 // This can only work in multithreaded applications if we lock the data
71 // structures via a mutex.
72 std::scoped_lock lock(acc_mutex);
73
74 const double x = p[0];
75 Assert(x >= interpolation_points.front() &&
76 x <= interpolation_points.back(),
78 interpolation_points.front(),
79 interpolation_points.back()));
80
81 return gsl_spline_eval(cspline.get(), x, acc.get());
82 }
83
84
85
86 template <int dim>
88 CSpline<dim>::gradient(const Point<dim> &p, const unsigned int) const
89 {
90 // GSL functions may modify gsl_interp_accel *acc object (last argument).
91 // This can only work in multithreaded applications if we lock the data
92 // structures via a mutex.
93 std::scoped_lock lock(acc_mutex);
94
95 const double x = p[0];
96 Assert(x >= interpolation_points.front() &&
97 x <= interpolation_points.back(),
99 interpolation_points.front(),
100 interpolation_points.back()));
101
102 const double deriv = gsl_spline_eval_deriv(cspline.get(), x, acc.get());
103 Tensor<1, dim> res;
104 res[0] = deriv;
105 return res;
106 }
107
108
109
110 template <int dim>
111 double
112 CSpline<dim>::laplacian(const Point<dim> &p, const unsigned int) const
113 {
114 // GSL functions may modify gsl_interp_accel *acc object (last argument).
115 // This can only work in multithreaded applications if we lock the data
116 // structures via a mutex.
117 std::scoped_lock lock(acc_mutex);
118
119 const double x = p[0];
120 Assert(x >= interpolation_points.front() &&
121 x <= interpolation_points.back(),
123 interpolation_points.front(),
124 interpolation_points.back()));
125
126 return gsl_spline_eval_deriv2(cspline.get(), x, acc.get());
127 }
128
129
130
131 template <int dim>
133 CSpline<dim>::hessian(const Point<dim> &p, const unsigned int) const
134 {
136 res[0][0] = laplacian(p);
137 return res;
138 }
139
140
141
142 template <int dim>
143 std::size_t
145 {
146 // only simple data elements, so
147 // use sizeof operator
148 return sizeof(*this) + 2 * sizeof(double) * interpolation_values.size();
149 }
150
151
152 // explicit instantiations
153 template class CSpline<1>;
154
155} // namespace Functions
156
157
158#endif
159
virtual SymmetricTensor< 2, dim > hessian(const Point< dim > &p, const unsigned int component=0) const override
virtual double value(const Point< dim > &point, const unsigned int component=0) const override
CSpline(const std::vector< double > &interpolation_points, const std::vector< double > &interpolation_values)
virtual std::size_t memory_consumption() const override
virtual double laplacian(const Point< dim > &p, const unsigned int component=0) const override
virtual Tensor< 1, dim > gradient(const Point< dim > &p, const unsigned int component=0) const override
Definition point.h:111
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcCSplineSizeMismatch(int arg1, int arg2)
#define Assert(cond, exc)
static ::ExceptionBase & ExcCSplineRange(double arg1, double arg2, double arg3)
static ::ExceptionBase & ExcCSplineOrder(int arg1, double arg2, double arg3)
static ::ExceptionBase & ExcCSplineEmpty(int arg1)
#define AssertThrow(cond, exc)