PDRblockLocation.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) 2019-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "PDRblock.H"
29 #include "gradingDescriptors.H"
30 
31 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 
36 // Prepend a value by shifting contents
37 template<class T>
38 static void prependList(List<T>& list, const T& val)
39 {
40  const label oldLen = list.size();
41  list.resize(oldLen + 1);
42 
43  for (label i = oldLen; i > 0; --i)
44  {
45  list[i] = std::move(list[i-1]);
46  }
47 
48  list[0] = val;
49 }
50 
51 } // End namespace Foam
52 
53 
54 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
55 
57 (
58  const scalarList& x,
59  const scalarList& y,
60  const scalarList& z
61 )
62 {
63  return boundBox
64  (
65  point(x.first(), y.first(), z.first()),
66  point(x.last(), y.last(), z.last())
67  );
68 }
69 
70 
72 Foam::PDRblock::grading(const Vector<gridControl>& ctrl)
73 {
74  return Vector<gradingDescriptors>
75  (
76  ctrl.x().grading(),
77  ctrl.y().grading(),
78  ctrl.z().grading()
79  );
80 }
81 
83 Foam::PDRblock::sizes(const Vector<gridControl>& ctrl)
84 {
85  return labelVector
86  (
87  ctrl.x().nCells(),
88  ctrl.y().nCells(),
89  ctrl.z().nCells()
90  );
91 }
92 
93 
94 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
95 
96 Foam::label Foam::PDRblock::gridControl::nCells() const
97 {
98  label nTotal = 0;
99  for (const label nDiv : divisions_)
100  {
101  nTotal += nDiv;
102  }
103 
104  return nTotal;
105 }
106 
107 
109 {
110  // Begin/end nodes for each segment
111  const scalarList& knots = *this;
112 
113  gradingDescriptors gds(divisions_.size());
114 
115  forAll(gds, i)
116  {
117  //- Construct from components
118  gds[i] = gradingDescriptor
119  (
120  knots[i+1] - knots[i], // blockFraction from delta
121  divisions_[i], // nDivFraction from nDivs
122  expansion_[i]
123  );
124  }
125 
126  gds.normalise();
128  return gds;
129 }
130 
131 
133 {
134  // Begin/end nodes for each segment
135  scalarList& knots = *this;
136 
137  knots.resize(len, Zero);
138 
139  len = Foam::max(0, len-1);
140 
141  divisions_.resize(len, Zero);
142  expansion_.resize(len, Zero);
143 }
144 
145 
147 (
148  const scalar p,
149  const label nDiv,
150  scalar expRatio
151 )
152 {
153  // Begin/end nodes for each segment
154  scalarList& knots = *this;
155 
156  // Is monotonic?
157  if (knots.size() && (p <= knots.last()))
158  {
160  << "Cannot append point " << p
161  << " which is <= last value " << knots.last() << endl;
162  return;
163  }
164 
165  if (nDiv < 1)
166  {
168  << "Negative or zero divisions " << nDiv << endl;
169  return;
170  }
171 
172  // Correct expansion ratios - negative is the same as inverse.
173  if (expRatio < 0)
174  {
175  expRatio = 1.0/(-expRatio);
176  }
177  else if (equal(expRatio, 0))
178  {
179  expRatio = 1;
180  }
181 
182  // Now append (push_back)
183  knots.append(p);
184  divisions_.append(nDiv);
185  expansion_.append(expRatio);
186 }
187 
188 
190 (
191  const scalar p,
192  const label nDiv,
193  scalar expRatio
194 )
195 {
196  // Begin/end nodes for each segment
197  scalarList& knots = static_cast<scalarList&>(*this);
198 
199  // Is monotonic?
200  if (knots.size() && (p >= knots.first()))
201  {
203  << "Cannot prepend point " << p
204  << " which is >= first value " << knots.first() << endl;
205  return;
206  }
207 
208  if (nDiv < 1)
209  {
211  << "Negative or zero divisions " << nDiv << endl;
212  return;
213  }
214 
215  // Correct expansion ratios - negative is the same as inverse.
216  if (expRatio < 0)
217  {
218  expRatio = 1.0/(-expRatio);
219  }
220  else if (equal(expRatio, 0))
221  {
222  expRatio = 1;
223  }
224 
225  // Now prepend (push_front)
226  prependList(knots, p);
227  prependList(divisions_, nDiv);
228  prependList(expansion_, expRatio);
229 }
230 
231 
233 (
234  Ostream& os,
235  const direction cmpt
236 ) const
237 {
238  if (cmpt < vector::nComponents)
239  {
240  os.beginBlock(vector::componentNames[cmpt]);
241  }
242 
243 
244  const scalarList& knots = *this;
245 
246  os << indent << "points "
247  << flatOutput(knots) << token::END_STATEMENT << nl;
248 
249  os << indent << "nCells "
250  << flatOutput(divisions_) << token::END_STATEMENT << nl;
251 
252  os << indent << "ratios "
253  << flatOutput(expansion_) << token::END_STATEMENT << nl;
254 
255  if (cmpt < vector::nComponents)
256  {
257  os.endBlock();
258  }
259  os << nl;
260 }
261 
262 
264 {
265  scalarMinMax limits;
266 
267  for (label edgei = 0; edgei < this->nCells(); ++edgei)
268  {
269  limits.add(width(edgei));
270  }
272  return limits;
273 }
274 
275 
276 Foam::label Foam::PDRblock::location::findCell(const scalar p) const
277 {
278  if (scalarList::empty() || p < first() || p > last())
279  {
280  return -1;
281  }
282  else if (equal(p, first()))
283  {
284  return 0;
285  }
286  else if (equal(p, last()))
287  {
288  return nCells()-1;
289  }
290  else if (p < first() || p > last())
291  {
292  // The point is out-of-bounds
293  return -1;
294  }
295 
296  // Binary search, finds lower index and thus corresponds to the
297  // cell in which the point is found
298  return findLower(*this, p);
299 }
300 
301 
303 (
304  const scalar p,
305  const scalar tol
306 ) const
307 {
308  if (scalarList::empty())
309  {
310  return -1;
311  }
312  else if (Foam::mag(p - first()) <= tol)
313  {
314  return 0;
315  }
316  else if (Foam::mag(p - last()) <= tol)
317  {
318  return scalarList::size()-1;
319  }
320  else if (p < first() || p > last())
321  {
322  // The point is out-of-bounds
323  return -1;
324  }
325 
326  // Linear search
327  label i = 0;
328  scalar delta = GREAT;
329 
330  for (const scalar& val : *this)
331  {
332  const scalar diff = mag(p - val);
333 
334  if (diff <= tol)
335  {
336  return i;
337  }
338  else if (delta < diff)
339  {
340  // Moving further away
341  break;
342  }
343 
344  delta = diff;
345  ++i;
346  }
347 
348  // This point is within bounds, but not near a grid-point
349  return -2;
350 }
351 
352 
353 // ************************************************************************* //
scalar delta
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:373
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
uint8_t direction
Definition: direction.H:46
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:449
label findIndex(const scalar p, const scalar tol) const
Find the grid index, within the given tolerance.
void resize(label len)
Resize lists.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:132
void prepend(const scalar p, label nDiv, scalar expRatio=1)
Add point/divisions/expand to front of list (push_front)
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:491
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:420
T & first()
Access first element of the list, position [0].
Definition: UList.H:798
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
End entry [isseparator].
Definition: token.H:157
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
scalar y
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:98
const labelVector & sizes() const
The (i,j,k) addressing dimensions.
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:61
Handles the specification for grading within a section of a block.
Templated 3D Vector derived from VectorSpace adding construction from 3 components, element access using x(), y() and z() member functions and the inner-product (dot-product) and cross-product operators.
Definition: Vector.H:58
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
Vector< gradingDescriptors > grading() const
Equivalent edge grading descriptors in (x,y,z) directions.
Definition: PDRblock.C:706
MinMax< T > & add(const MinMax &other)
Extend the range to include the other min/max range.
Definition: MinMaxI.H:271
void append(const scalar p, label nDiv, scalar expRatio=1)
Add point/divisions/expand to end of list (push_back)
OBJstream os(runTime.globalPath()/outputName)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
T & last()
Access last element of the list, position [size()-1].
Definition: UList.H:812
scalarMinMax edgeLimits() const
Return min/max edge lengths.
label findCell(const scalar p) const
Find the cell index enclosing this location.
bool equal(const T &s1, const T &s2)
Compare two values for equality.
Definition: doubleFloat.H:41
vector point
Point is a vector.
Definition: point.H:37
#define WarningInFunction
Report a warning using Foam::Warning.
static void prependList(List< T > &list, const T &val)
label nCells() const
Total number of cells in this direction.
void writeDict(Ostream &os, const direction cmpt) const
Write as dictionary contents for specified vector direction.
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:80
label size() const noexcept
The number of elements in the UList.
Definition: UListI.H:413
Vector< label > labelVector
Vector of labels.
Definition: labelVector.H:47
gradingDescriptors grading() const
Return edge grading descriptors for the locations.
const boundBox & bounds() const
The mesh bounding box.
Definition: PDRblockI.H:153
volScalarField & p
List of gradingDescriptor for the sections of a block with additional IO functionality.
Namespace for OpenFOAM.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157