stepInterpolationWeights.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2023 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 
29 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
38 (
41  word
42 );
43 
44 
45 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
46 
48 (
49  const scalarField& samples
50 )
51 :
53  index_(-1)
54 {}
55 
56 
57 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
58 
60 (
61  const scalar t,
62  labelList& indices,
63  scalarField& weights
64 ) const
65 {
66  // Check if current index is still valid
67  bool changed = false;
68  if
69  (
70  (
71  index_ == -1
72  && t <= samples_.first()
73  )
74  || (
75  index_ >= 0
76  && index_ < samples_.size() - 1
77  && t >= samples_[index_]
78  && t <= samples_[index_ + 1]
79  )
80  || (
81  index_ == samples_.size() - 1
82  && t >= samples_.last()
83  )
84  )
85  {
86  // The index is still in the correct slot
87  }
88  else
89  {
90  // The index is no longer in the correct slot, so search for a new one
91  index_ = findLower(samples_, t, 0, lessEqOp<scalar>());
92  changed = true;
93  }
94 
95  // Calculate the number of indices and weights and resize the result
96  const label n = index_ == -1 || index_ == samples_.size() - 1 ? 1 : 2;
97  indices.resize(n);
98  weights.resize(n);
99 
100  // Compute the value
101  if (index_ == -1)
102  {
103  // Use the first value
104  indices[0] = 0;
105  weights[0] = 1;
106  }
107  else if (index_ == samples_.size() - 1)
108  {
109  // Use the last value
110  indices[0] = samples_.size() - 1;
111  weights[0] = 1;
112  }
113  else
114  {
115  indices[0] = index_;
116  weights[0] = 1;
117  indices[1] = index_ + 1;
118  weights[1] = 0;
119  }
120 
121  return changed;
122 }
123 
124 
126 (
127  scalar t1,
128  scalar t2,
129  labelList& indices,
130  scalarField& weights
131 ) const
132 {
133  // If the arguments are in descending order, then swap them and set the
134  // weights' sign negative
135  label sign = +1;
136  if (t1 > t2)
137  {
138  Swap(t1, t2);
139  sign = -1;
140  }
141 
142  //- Search for lower indices
143  // Note: currently there is no caching of this search like in valueWeights
144  const label i1 = findLower(samples_, t1, 0, lessEqOp<scalar>());
145  const label i2 = findLower(samples_, t2, 0, lessEqOp<scalar>());
146  const label iClip1 = min(max(i1, 0), samples_.size() - 2);
147  const label iClip2 = min(max(i2, 0), samples_.size() - 2);
148  const label n = max(i2 - i1 + (i1 == iClip1) + (i2 == iClip2), 1);
149 
150  // Check if anything changed
151  bool changed = false;
152  if (indices.size() != n)
153  {
154  changed = true;
155  }
156  else
157  {
158  forAll(indices, indexi)
159  {
160  if (indices[indexi] == indexi + max(i1, 0))
161  {
162  changed = true;
163  break;
164  }
165  }
166  }
167 
168  // Resize the result arrays
169  indices.resize(n);
170  indices = -1;
171  weights.resize(n);
172  weights = 0;
173 
174  // Add out of bounds interval below the table
175  if (i1 == -1)
176  {
177  indices[0] = 0;
178  weights[0] += sign*(samples_[0] - t1);
179  }
180  if (i2 == -1)
181  {
182  indices[0] = 0;
183  weights[0] -= sign*(samples_[0] - t2);
184  }
185 
186  // Add partial interval from t1 to i1 + 1
187  if (i1 == iClip1)
188  {
189  const scalar d = samples_[i1 + 1] - t1;
190  indices[0] = i1;
191  weights[0] += sign*d;
192  indices[1] = i1 + 1;
193  }
194 
195  // Sum whole intervals from i1 + 1 to i2
196  if (i1 != i2) for (label i = i1 + 1; i <= iClip2; i ++)
197  {
198  const scalar d = samples_[i + 1] - samples_[i];
199  indices[i - iClip1] = i;
200  weights[i - iClip1] += sign*d;
201  indices[i - iClip1 + 1] = i + 1;
202  }
203 
204  // Subtract partial interval from t2 to i2 + 1
205  if (i2 == iClip2)
206  {
207  const scalar d = samples_[i2 + 1] - t2;
208  indices[n - 2] = i2;
209  weights[n - 2] -= sign*d;
210  indices[n - 1] = i2 + 1;
211  }
212 
213  // Add out of bounds interval above the table
214  if (i1 == samples_.size() - 1)
215  {
216  indices[n - 1] = samples_.size() - 1;
217  weights[n - 1] -= sign*(t1 - samples_.last());
218  }
219  if (i2 == samples_.size() - 1)
220  {
221  indices[n - 1] = samples_.size() - 1;
222  weights[n - 1] += sign*(t2 - samples_.last());
223  }
224 
225  return changed;
226 }
227 
228 
229 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
230 
231 } // End namespace Foam
232 
233 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Macros for easy insertion into run-time selection tables.
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
T & first()
Return the first element of the list.
Definition: UListI.H:114
T & last()
Return the last element of the list.
Definition: UListI.H:128
Abstract base class for interpolating in 1D.
const scalarField & samples_
Cached samples.
Generates the weight for step-wise interpolation and integration.
stepInterpolationWeights(const scalarField &samples)
Construct from components.
virtual bool integrationWeights(scalar t1, scalar t2, labelList &indices, scalarField &weights) const
Calculate weights and indices to calculate integrand of t1..t2.
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 string.
Definition: word.H:62
Namespace for OpenFOAM.
dimensionedScalar sign(const dimensionedScalar &ds)
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
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
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,.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
defineTypeNameAndDebug(combustionModel, 0)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
void Swap(T &a, T &b)
Definition: Swap.H:43
scalarField samples(nIntervals, 0)