splineInterpolationWeights.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) 2012-2015 OpenFOAM Foundation
9 Copyright (C) 2019 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
31#include "ListOps.H"
33
34// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35
36namespace Foam
37{
40 (
43 word
44 );
45} // End namespace Foam
46
47
48// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49
51(
52 const scalarField& samples,
53 const bool checkEqualDistance
54)
55:
57 index_(-1)
58{
59 if (checkEqualDistance && samples_.size() > 2)
60 {
61 const scalar interval = samples_[1]-samples[0];
62 for (label i = 2; i < samples_.size(); i++)
63 {
64 scalar d = samples_[i]-samples[i-1];
65
66 if (mag(d-interval) > SMALL)
67 {
69 << "Spline interpolation only valid for constant intervals."
70 << nl
71 << "Interval 0-1 : " << interval << nl
72 << "Interval " << i-1 << '-' << i << " : "
73 << d << endl;
74 }
75 }
76 }
77}
78
79
80// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
81
83(
84 const scalar t,
85 labelList& indices,
86 scalarField& weights
87) const
88{
89 bool indexChanged = false;
90
91 // linear interpolation
92 if (samples_.size() <= 2)
93 {
95 (
96 t,
97 indices,
98 weights
99 );
100 }
101
102 // Check if current timeIndex is still valid
103 if
104 (
105 index_ >= 0
106 && index_ < samples_.size()
107 && (
108 samples_[index_] <= t
109 && (index_ == samples_.size()-1 || t <= samples_[index_+1])
110 )
111 )
112 {
113 // index_ still at correct slot
114 }
115 else
116 {
117 // search for correct index
118 index_ = findLower(samples_, t);
119 indexChanged = true;
120 }
121
122
123 // Clamp if outside table
124 if (index_ == -1)
125 {
126 indices.setSize(1);
127 weights.setSize(1);
128
129 indices[0] = 0;
130 weights[0] = 1;
131 return indexChanged;
132 }
133 else if (index_ == samples_.size()-1)
134 {
135 indices.setSize(1);
136 weights.setSize(1);
137
138 indices[0] = samples_.size()-1;
139 weights[0] = 1;
140 return indexChanged;
141 }
142
143
144
145 label lo = index_;
146 label hi = index_+1;
147
148 // weighting
149 scalar mu = (t - samples_[lo])/(samples_[hi] - samples_[lo]);
150
151 scalar w0 = 0.5*(mu*(-1+mu*(2-mu))); // coeff of lo-1
152 scalar w1 = 0.5*(2+mu*(mu*(-5 + mu*(3)))); // coeff of lo
153 scalar w2 = 0.5*(mu*(1 + mu*(4 + mu*(-3)))); // coeff of hi
154 scalar w3 = 0.5*(mu*mu*(-1 + mu)); // coeff of hi+1
155
156 if (lo > 0)
157 {
158 if (hi < samples_.size()-1)
159 {
160 // Four points available
161 indices.setSize(4);
162 weights.setSize(4);
163
164 indices[0] = lo-1;
165 indices[1] = lo;
166 indices[2] = hi;
167 indices[3] = hi+1;
168
169 weights[0] = w0;
170 weights[1] = w1;
171 weights[2] = w2;
172 weights[3] = w3;
173 }
174 else
175 {
176 // No y3 available. Extrapolate: y3=3*y2-y1
177 indices.setSize(3);
178 weights.setSize(3);
179
180 indices[0] = lo-1;
181 indices[1] = lo;
182 indices[2] = hi;
183
184 weights[0] = w0;
185 weights[1] = w1 - w3;
186 weights[2] = w2 + 2*w3;
187 }
188 }
189 else
190 {
191 // No y0 available. Extrapolate: y0=2*y1-y2;
192 if (hi < samples_.size()-1)
193 {
194 indices.setSize(3);
195 weights.setSize(3);
196
197 indices[0] = lo;
198 indices[1] = hi;
199 indices[2] = hi+1;
200
201 weights[0] = w1 + 2*w0;
202 weights[1] = w2 - w0;
203 weights[2] = w3;
204 }
205 else
206 {
207 indices.setSize(2);
208 weights.setSize(2);
209
210 indices[0] = lo;
211 indices[1] = hi;
212
213 weights[0] = w1 + 2*w0 - w3;
214 weights[1] = w2 - w0 + 2*w3;
215 }
216 }
217
218 return indexChanged;
219}
220
221
222// ************************************************************************* //
Various functions to operate on Lists.
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
#define w2
Definition: blockCreate.C:35
#define w1
Definition: blockCreate.C:34
#define w3
Definition: blockCreate.C:36
#define w0
Definition: blockCreate.C:33
void setSize(const label n)
Alias for resize()
Definition: List.H:218
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Abstract base class for interpolating in 1D.
virtual bool valueWeights(const scalar t, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate t from samples.
Catmull-Rom spline interpolation.
virtual bool valueWeights(const scalar t, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate t from samples.
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
const volScalarField & mu
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
scalarField samples(nIntervals, Zero)