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 -------------------------------------------------------------------------------
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 
31 #include "ListOps.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  defineTypeNameAndDebug(splineInterpolationWeights, 0);
40  (
41  interpolationWeights,
42  splineInterpolationWeights,
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 // ************************************************************************* //
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::constant::physicoChemical::mu
const dimensionedScalar mu
Atomic mass unit.
Definition: createFieldRefs.H:4
w1
#define w1
Definition: blockCreate.C:34
splineInterpolationWeights.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
w3
#define w3
Definition: blockCreate.C:36
linearInterpolationWeights.H
Foam::Field< scalar >
Foam::findLower
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
samples
scalarField samples(nIntervals, Zero)
Foam::splineInterpolationWeights::splineInterpolationWeights
splineInterpolationWeights(const scalarField &samples, const bool checkEqualDistance=true)
Construct from components. By default make sure samples are.
Definition: splineInterpolationWeights.C:51
Foam::splineInterpolationWeights::valueWeights
virtual bool valueWeights(const scalar t, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate t from samples.
Definition: splineInterpolationWeights.C:83
Foam::interpolationWeights
Abstract base class for interpolating in 1D.
Definition: interpolationWeights.H:58
Foam::linearInterpolationWeights::valueWeights
virtual bool valueWeights(const scalar t, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate t from samples.
Definition: linearInterpolationWeights.C:89
w2
#define w2
Definition: blockCreate.C:35
Foam::linearInterpolationWeights
Definition: linearInterpolationWeights.H:50
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::List< label >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
ListOps.H
Various functions to operate on Lists.
w0
#define w0
Definition: blockCreate.C:33
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328