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 -------------------------------------------------------------------------------
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"
32 #include "Pair.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  defineTypeNameAndDebug(linearInterpolationWeights, 0);
40  (
41  interpolationWeights,
42  linearInterpolationWeights,
43  word
44  );
45 } // End namespace Foam
46 
47 
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 
50 Foam::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 
155 bool 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, lessEqOp<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 // ************************************************************************* //
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::Pair::second
const T & second() const noexcept
Return second element, which is also the last element.
Definition: PairI.H:122
s
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))
Definition: gmvOutputSpray.H:25
Pair.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
linearInterpolationWeights.H
Foam::linearInterpolationWeights::linearInterpolationWeights
linearInterpolationWeights(const scalarField &samples)
Construct from components.
Definition: linearInterpolationWeights.C:77
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::FatalError
error FatalError
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
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
Foam::List< label >
Foam::interpolationWeights::samples_
const scalarField & samples_
Definition: interpolationWeights.H:64
ListOps.H
Various functions to operate on Lists.
Foam::lessEqOp
Definition: ops.H:239
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)