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 | Copyright (C) 2012 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
28 #include "ListOps.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 defineTypeNameAndDebug(splineInterpolationWeights, 0);
40 (
41  interpolationWeights,
42  splineInterpolationWeights,
43  word
44 );
45 
46 
47 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
48 
50 (
51  const scalarField& samples,
52  const bool checkEqualDistance
53 )
54 :
55  interpolationWeights(samples),
56  index_(-1)
57 {
58  if (checkEqualDistance && samples_.size() > 2)
59  {
60  const scalar interval = samples_[1]-samples[0];
61  for (label i = 2; i < samples_.size(); i++)
62  {
63  scalar d = samples_[i]-samples[i-1];
64 
65  if (mag(d-interval) > SMALL)
66  {
67  WarningIn
68  (
69  "splineInterpolationWeights::splineInterpolationWeights"
70  "(const scalarField&)"
71  ) << "Spline interpolation only valid for constant intervals."
72  << nl
73  << "Interval 0-1 : " << interval << nl
74  << "Interval " << i-1 << '-' << i << " : "
75  << d << endl;
76  }
77  }
78  }
79 }
80 
81 
82 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
83 
85 (
86  const scalar t,
87  labelList& indices,
88  scalarField& weights
89 ) const
90 {
91  bool indexChanged = false;
92 
93  // linear interpolation
94  if (samples_.size() <= 2)
95  {
97  (
98  t,
99  indices,
100  weights
101  );
102  }
103 
104  // Check if current timeIndex is still valid
105  if
106  (
107  index_ >= 0
108  && index_ < samples_.size()
109  && (
110  samples_[index_] <= t
111  && (index_ == samples_.size()-1 || t <= samples_[index_+1])
112  )
113  )
114  {
115  // index_ still at correct slot
116  }
117  else
118  {
119  // search for correct index
120  index_ = findLower(samples_, t);
121  indexChanged = true;
122  }
123 
124 
125  // Clamp if outside table
126  if (index_ == -1)
127  {
128  indices.setSize(1);
129  weights.setSize(1);
130 
131  indices[0] = 0;
132  weights[0] = 1;
133  return indexChanged;
134  }
135  else if (index_ == samples_.size()-1)
136  {
137  indices.setSize(1);
138  weights.setSize(1);
139 
140  indices[0] = samples_.size()-1;
141  weights[0] = 1;
142  return indexChanged;
143  }
144 
145 
146 
147  label lo = index_;
148  label hi = index_+1;
149 
150  // weighting
151  scalar mu = (t - samples_[lo])/(samples_[hi] - samples_[lo]);
152 
153  scalar w0 = 0.5*(mu*(-1+mu*(2-mu))); // coeff of lo-1
154  scalar w1 = 0.5*(2+mu*(mu*(-5 + mu*(3)))); // coeff of lo
155  scalar w2 = 0.5*(mu*(1 + mu*(4 + mu*(-3)))); // coeff of hi
156  scalar w3 = 0.5*(mu*mu*(-1 + mu)); // coeff of hi+1
157 
158  if (lo > 0)
159  {
160  if (hi < samples_.size()-1)
161  {
162  // Four points available
163  indices.setSize(4);
164  weights.setSize(4);
165 
166  indices[0] = lo-1;
167  indices[1] = lo;
168  indices[2] = hi;
169  indices[3] = hi+1;
170 
171  weights[0] = w0;
172  weights[1] = w1;
173  weights[2] = w2;
174  weights[3] = w3;
175  }
176  else
177  {
178  // No y3 available. Extrapolate: y3=3*y2-y1
179  indices.setSize(3);
180  weights.setSize(3);
181 
182  indices[0] = lo-1;
183  indices[1] = lo;
184  indices[2] = hi;
185 
186  weights[0] = w0;
187  weights[1] = w1 - w3;
188  weights[2] = w2 + 2*w3;
189  }
190  }
191  else
192  {
193  // No y0 available. Extrapolate: y0=2*y1-y2;
194  if (hi < samples_.size()-1)
195  {
196  indices.setSize(3);
197  weights.setSize(3);
198 
199  indices[0] = lo;
200  indices[1] = hi;
201  indices[2] = hi+1;
202 
203  weights[0] = w1 + 2*w0;
204  weights[1] = w2 - w0;
205  weights[2] = w3;
206  }
207  else
208  {
209  indices.setSize(2);
210  weights.setSize(2);
211 
212  indices[0] = lo;
213  indices[1] = hi;
214 
215  weights[0] = w1 + 2*w0 - w3;
216  weights[1] = w2 - w0 + 2*w3;
217  }
218  }
219 
220  return indexChanged;
221 }
222 
223 
224 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
225 
226 } // End namespace Foam
227 
228 // ************************************************************************* //
const dimensionedScalar mu
Atomic mass unit.
Definition: createFields.H:13
virtual bool valueWeights(const scalar t, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate t from samples.
dimensioned< scalar > mag(const dimensioned< Type > &)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
Various functions to operate on Lists.
Namespace for OpenFOAM.
virtual bool valueWeights(const scalar t, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate t from samples.
static const char nl
Definition: Ostream.H:260
void setSize(const label)
Reset size of List.
Definition: List.C:318
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
#define WarningIn(functionName)
Report a warning using Foam::Warning.
Macros for easy insertion into run-time selection tables.
label findLower(const ListType &, typename ListType::const_reference, const label stary, const BinaryOp &bop)
Find last element < given value in sorted list and return index,.
Abstract base class for interpolating in 1D.
splineInterpolationWeights(const scalarField &samples, const bool checkEqualDistance=true)
Construct from components. By default make sure samples are.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
defineTypeNameAndDebug(combustionModel, 0)