interpolateSplineXY.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011 OpenFOAM Foundation
9  Copyright (C) 2024 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "interpolateSplineXY.H"
30 #include "primitiveFields.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 template<class Type>
36 (
37  const scalarField& xNew,
38  const scalarField& xOld,
39  const Field<Type>& yOld
40 )
41 {
42  Field<Type> yNew(xNew.size());
43 
44  forAll(xNew, i)
45  {
46  yNew[i] = interpolateSplineXY(xNew[i], xOld, yOld);
47  }
48 
49  return yNew;
50 }
51 
52 
53 template<class Type>
55 (
56  const scalar x,
57  const scalarField& xOld,
58  const Field<Type>& yOld
59 )
60 {
61  label n = xOld.size();
62 
63  // early exit if out of bounds or only one value
64  if (n == 1 || x <= xOld[0])
65  {
66  return yOld[0];
67  }
68  if (x >= xOld[n - 1])
69  {
70  return yOld[n - 1];
71  }
72 
73  // linear interpolation if only two values
74  if (n == 2)
75  {
76  return (x - xOld[0])/(xOld[1] - xOld[0])*(yOld[1] - yOld[0]) + yOld[0];
77  }
78 
79  // find bounding knots
80  label hi = 0;
81  while (hi < n && xOld[hi] < x)
82  {
83  hi++;
84  }
85 
86  label lo = hi - 1;
87 
88  const Type& y1 = yOld[lo];
89  const Type& y2 = yOld[hi];
90 
91  Type y0;
92  if (lo == 0)
93  {
94  y0 = 2*y1 - y2;
95  }
96  else
97  {
98  y0 = yOld[lo - 1];
99  }
100 
101  Type y3;
102  if (hi + 1 == n)
103  {
104  y3 = 2*y2 - y1;
105  }
106  else
107  {
108  y3 = yOld[hi + 1];
109  }
110 
111  // weighting
112  scalar mu = (x - xOld[lo])/(xOld[hi] - xOld[lo]);
113 
114  // interpolate
115  return
116  0.5
117  *(
118  2*y1
119  + mu
120  *(
121  -y0 + y2
122  + mu*((2*y0 - 5*y1 + 4*y2 - y3) + mu*(-y0 + 3*y1 - 3*y2 + y3))
123  )
124  );
125 }
126 
127 
128 // ************************************************************************* //
Interpolates y values from one curve to another with a different x distribution.
dimensionedScalar y0(const dimensionedScalar &ds)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
Field< Type > interpolateSplineXY(const scalarField &xNew, const scalarField &xOld, const Field< Type > &yOld)
Generic templated field type.
Definition: Field.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar y1(const dimensionedScalar &ds)
const dimensionedScalar mu
Atomic mass unit.
Specialisations of Field<T> for scalar, vector and tensor.
label n