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 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-VSMALL)
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  //- Find lower index
177  const label i2 = findLower(samples_, t2);
178 
179  // For now just fail if any outside table
180  if (i1 == -1 || i2 == samples_.size()-1)
181  {
183  << "Integrating outside table " << samples_[0] << ".."
184  << samples_.last() << " not implemented."
185  << " t1:" << t1 << " t2:" << t2 << exit(FatalError);
186  }
187 
188  const label nIndices = i2-i1+2;
189 
190 
191  // Determine if indices already correct
192  bool anyChanged = false;
193 
194  if (nIndices != indices.size())
195  {
196  anyChanged = true;
197  }
198  else
199  {
200  // Closer check
201 
202  label index = i1;
203  forAll(indices, i)
204  {
205  if (indices[i] != index)
206  {
207  anyChanged = true;
208  break;
209  }
210  index++;
211  }
212  }
213 
214  indices.setSize(nIndices);
215  weights.setSize(nIndices);
216  weights = 0.0;
217 
218  // Sum from i1+1 to i2+1
219  for (label i = i1+1; i <= i2; i++)
220  {
221  const scalar d = samples_[i+1]-samples_[i];
222  indices[i-i1] = i;
223  weights[i-i1] += 0.5*d;
224  indices[i+1-i1] = i+1;
225  weights[i+1-i1] += 0.5*d;
226  }
227 
228  // Add from i1 to t1
229  {
230  const Pair<scalar> i1Tot1 = integrationWeights(i1, t1);
231  indices[0] = i1;
232  indices[1] = i1+1;
233  weights[0] += i1Tot1.first();
234  weights[1] += i1Tot1.second();
235  }
236 
237  // Subtract from t2 to i2+1
238  {
239  const Pair<scalar> wghts = integrationWeights(i2, t2);
240  indices[i2-i1] = i2;
241  indices[i2-i1+1] = i2+1;
242  weights[i2-i1] += -wghts.first();
243  weights[i2-i1+1] += -wghts.second();
244  }
245 
246  return anyChanged;
247 }
248 
249 
250 // ************************************************************************* //
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:290
linearInterpolationWeights.H
Foam::label
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:62
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)
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:355
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::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)