linearInterpolationWeights.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-2020 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"
32#include "Pair.H"
33
34// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35
36namespace Foam
37{
40 (
43 word
44 );
45} // End namespace Foam
46
47
48// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49
50Foam::Pair<Foam::scalar> Foam::linearInterpolationWeights::integrationWeights
51(
52 const label i,
53 const scalar t
54) const
55{
56 // t is in range samples_[i] .. samples_[i+1]
57
58 const scalar s = (t-samples_[i])/(samples_[i+1]-samples_[i]);
59
60 if (s < -SMALL || s > 1+SMALL)
61 {
63 << "Value " << t << " outside range " << samples_[i]
64 << " .. " << samples_[i+1]
65 << exit(FatalError);
66 }
67
68 const scalar d = samples_[i+1]-t;
69
70 return Pair<scalar>(d*0.5*(1-s), d*0.5*(1+s));
71}
72
73
74// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
75
77(
78 const scalarField& samples
79)
80:
82 index_(-1)
83{}
84
85
86// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
87
89(
90 const scalar t,
91 labelList& indices,
92 scalarField& weights
93) const
94{
95 bool indexChanged = false;
96
97 // Check if current timeIndex is still valid
98 if
99 (
100 index_ >= 0
101 && index_ < samples_.size()
102 && (
103 samples_[index_] <= t
104 && (index_ == samples_.size()-1 || t <= samples_[index_+1])
105 )
106 )
107 {
108 // index_ still at correct slot
109 }
110 else
111 {
112 // search for correct index
113 index_ = findLower(samples_, t);
114 indexChanged = true;
115 }
116
117
118 if (index_ == -1)
119 {
120 // Use first element only
121 indices.setSize(1);
122 weights.setSize(1);
123 indices[0] = 0;
124 weights[0] = 1.0;
125 }
126 else if (index_ == samples_.size()-1)
127 {
128 // Use last element only
129 indices.setSize(1);
130 weights.setSize(1);
131 indices[0] = samples_.size()-1;
132 weights[0] = 1.0;
133 }
134 else
135 {
136 // Interpolate
137 indices.setSize(2);
138 weights.setSize(2);
139
140 indices[0] = index_;
141 indices[1] = index_+1;
142
143 scalar t0 = samples_[indices[0]];
144 scalar t1 = samples_[indices[1]];
145 scalar deltaT = t1-t0;
146
147 weights[0] = (t1-t)/deltaT;
148 weights[1] = 1.0-weights[0];
149 }
150
151 return indexChanged;
152}
153
154
155bool Foam::linearInterpolationWeights::integrationWeights
156(
157 const scalar t1,
158 const scalar t2,
159 labelList& indices,
160 scalarField& weights
161) const
162{
163 if (t2 < t1 - ROOTVSMALL)
164 {
166 << "Integration should be in positive direction."
167 << " t1:" << t1 << " t2:" << t2
168 << exit(FatalError);
169 }
170
171 // Currently no fancy logic on cached index like in value
172
173 //- Find lower or equal index
174 const label i1 = findLower(samples_, t1, 0, lessEqualOp<scalar>());
175
176 if (t2 <= t1 + ROOTVSMALL)
177 {
178 // Early exit if 1 and t2 are approximately equal
179
180 bool anyChanged = (indices.size() != 1 || indices[0] != i1);
181
182 indices.setSize(1);
183 weights.setSize(1);
184 indices[0] = i1;
185 weights[0] = scalar(0);
186
187 return anyChanged;
188 }
189
190 //- Find lower index
191 const label i2 = findLower(samples_, t2);
192
193 // For now just fail if any outside table
194 if (i1 == -1 || i2 == samples_.size()-1)
195 {
197 << "Integrating outside table " << samples_[0] << ".."
198 << samples_.last() << " not implemented."
199 << " t1:" << t1 << " t2:" << t2 << exit(FatalError);
200 }
201
202 const label nIndices = i2-i1+2;
203
204
205 // Determine if indices already correct
206 bool anyChanged = false;
207
208 if (nIndices != indices.size())
209 {
210 anyChanged = true;
211 }
212 else
213 {
214 // Closer check
215
216 label index = i1;
217 forAll(indices, i)
218 {
219 if (indices[i] != index)
220 {
221 anyChanged = true;
222 break;
223 }
224 index++;
225 }
226 }
227
228 indices.setSize(nIndices);
229 weights.setSize(nIndices);
230 weights = 0.0;
231
232 // Sum from i1+1 to i2+1
233 for (label i = i1+1; i <= i2; i++)
234 {
235 const scalar d = samples_[i+1]-samples_[i];
236 indices[i-i1] = i;
237 weights[i-i1] += 0.5*d;
238 indices[i+1-i1] = i+1;
239 weights[i+1-i1] += 0.5*d;
240 }
241
242 // Add from i1 to t1
243 {
244 const Pair<scalar> i1Tot1 = integrationWeights(i1, t1);
245 indices[0] = i1;
246 indices[1] = i1+1;
247 weights[0] += i1Tot1.first();
248 weights[1] += i1Tot1.second();
249 }
250
251 // Subtract from t2 to i2+1
252 {
253 const Pair<scalar> wghts = integrationWeights(i2, t2);
254 indices[i2-i1] = i2;
255 indices[i2-i1+1] = i2+1;
256 weights[i2-i1] += -wghts.first();
257 weights[i2-i1+1] += -wghts.second();
258 }
259
260 return anyChanged;
261}
262
263
264// ************************************************************************* //
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.
T & first() noexcept
The first element of the list, position [0].
Definition: FixedListI.H:207
void setSize(const label n)
Alias for resize()
Definition: List.H:218
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:69
const T & second() const noexcept
Return second element, which is also the last element.
Definition: PairI.H:120
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.
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
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Namespace for OpenFOAM.
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
scalarField samples(nIntervals, Zero)