PDRobstacleLegacyIO.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 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 "PDRobstacle.H"
29 #include "vector.H"
30 #include "doubleVector.H"
31 #include "stringOps.H"
32 #include "unitConversion.H"
33 #include <cmath>
34 
35 #define ReportLineInfo(line, file) \
36  if (line >= 0 && !file.empty()) \
37  { \
38  Info<< " Line " << line << " of file '" << file << '\''; \
39  } \
40  Info<< nl;
41 
42 
43 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
44 
46 (
47  const int groupTypeId,
48  const string& buffer,
49  const label lineNo,
50  const word& inputFile
51 )
52 {
53  // Handling the optional identifier string can be a pain.
54  // Generally can only say that it exists if there are 15 or
55  // more columns.
56  //
57  // Cylinder has 8 normal entries
58  // Cuboid, diagonal beam etc have 14 normal entries
59  // However, reject anything that looks like a slipped numeric
60 
61  double dummy1;
62 
63  string in_ident;
64 
65  const auto columns = stringOps::splitSpace(buffer);
66 
67  for (std::size_t coli = 14; coli < columns.size(); ++coli)
68  {
69  // See if it can parse into a numerical value
70  if (!readDouble(columns[coli].str(), dummy1))
71  {
72  // Not a numeric value. This must be our identifier
73  in_ident = buffer.substr(columns[coli].first - buffer.begin());
74 
75  #ifdef FULLDEBUG
76  Info<< "Identifier: " << in_ident << nl;
77  #endif
78  break;
79  }
80  }
81 
82  // Strip off group number
83  groupId = groupTypeId / 100;
84  typeId = groupTypeId % 100;
85 
86  // This is a safe value
87  orient = vector::X;
88 
89  switch (typeId)
90  {
92  {
93  // 8 Tokens
94  // "%d %lf %lf %lf %lf %lf %d %lf"
95  // USP 13/8/14 Read vbkge in case a negative cyl to punch a circular hole
96 
97  int in_typeId;
98  double in_x, in_y, in_z;
99  double in_len, in_dia;
100  int in_orient;
101  double in_poro;
102 
103  int nread =
104  sscanf
105  (
106  buffer.c_str(),
107  "%d %lf %lf %lf %lf %lf %d %lf",
108  &in_typeId, &in_x, &in_y, &in_z,
109  &in_len, &in_dia, &in_orient,
110  &in_poro
111  );
112 
113  if (nread < 8)
114  {
115  Info<< "Expected 8 items, but read in " << nread;
116  ReportLineInfo(lineNo, inputFile);
117  }
118 
119  identifier = in_ident;
120  pt = point(in_x, in_y, in_z);
121 
122  len() = in_len;
123  dia() = in_dia;
124 
125  orient = vector::X; // Check again later
126 
127  // Read porosity. Convert to blockage.
128  vbkge = 1.0 - in_poro;
129 
130  // Orientation (1,2,3) on input -> (0,1,2)
131  // - sortBias for later position sorting
132  switch (in_orient)
133  {
134  case 1:
135  orient = vector::X;
136  sortBias = len();
137  break;
138  case 2:
139  orient = vector::Y;
140  sortBias = 0.5*dia();
141  break;
142  case 3:
143  orient = vector::Z;
144  sortBias = 0.5*dia();
145  break;
146  default:
147  sortBias = len();
148  Info<< "Unexpected orientation " << in_orient;
149  ReportLineInfo(lineNo, inputFile);
150  break;
151  }
152  }
153  break;
154 
156  {
157  // A diagonal block
158 
159  // 14 columns + identifier
160  // "%d %lf %lf %lf %lf %lf %d %lf %lf %lf %lf %lf %d %lf %s"
161  // vbkge (porosity at this stage) should be 0. Not used (yet)
162 
163  int in_typeId;
164  double in_x, in_y, in_z;
165  double in_len, in_theta;
166  int in_orient;
167  double in_wa, in_wb, in_poro;
168  double col_11, col_12, col_14;
169  int col_13;
170 
171  int nread =
172  sscanf
173  (
174  buffer.c_str(),
175  "%d %lf %lf %lf %lf %lf %d %lf %lf %lf %lf %lf %d %lf",
176  &in_typeId, &in_x, &in_y, &in_z,
177  &in_len, &in_theta, &in_orient,
178  &in_wa, &in_wb, &in_poro,
179  &col_11, &col_12, &col_13, &col_14
180  );
181 
182  if (nread < 14)
183  {
184  Info<< "Expected min 10 items, but read in " << nread;
185  ReportLineInfo(lineNo, inputFile);
186  }
187 
188  identifier = in_ident;
189  pt = point(in_x, in_y, in_z);
190 
191  len() = in_len;
192  dia() = 0;
193  theta() = 0; // Fix later on
194 
195  orient = vector::X; // Check again later
196 
197  wa = in_wa;
198  wb = in_wb;
199 
200  // Degrees on input, limit to range [0, PI]
201  while (in_theta > 180) in_theta -= 180;
202  while (in_theta < 0) in_theta += 180;
203 
204  // Swap axes when theta > PI/2
205  // For 89-90 degrees it becomes -ve, which is picked up
206  // in next section
207  if (in_theta > 89)
208  {
209  in_theta -= 90;
210  // Swap wa <-> wb
211  wa = in_wb;
212  wb = in_wa;
213  }
214 
215  theta() = degToRad(in_theta);
216 
217  // Orientation (1,2,3) on input -> (0,1,2)
218  // - sortBias for later position sorting
219  switch (in_orient)
220  {
221  case 1:
222  orient = vector::X;
223  sortBias = len();
224  break;
225 
226  case 2:
227  orient = vector::Y;
228  sortBias = 0.5*(wa * sin(theta()) + wb * cos(theta()));
229  break;
230 
231  case 3:
232  orient = vector::Z;
233  sortBias = 0.5*(wa * cos(theta()) + wb * sin(theta()));
234  break;
235 
236  default:
237  sortBias = len();
238  Info<< "Unexpected orientation " << in_orient;
239  ReportLineInfo(lineNo, inputFile);
240  break;
241  }
242 
243 
244  // If very nearly aligned with axis, turn it into normal block,
245  // to avoid 1/tan(theta) blowing up
246  if (in_theta < 1)
247  {
248  switch (orient)
249  {
250  case vector::X:
251  span = vector(len(), wa, wb);
252  // Was end center, now lower corner
253  pt.y() = pt.y() - 0.5 * span.y();
254  pt.z() = pt.z() - 0.5 * span.z();
255  break;
256 
257  case vector::Y:
258  span = vector(wb, len(), wa);
259  // Was end center, now lower corner
260  pt.z() = pt.z() - 0.5 * span.z();
261  pt.x() = pt.x() - 0.5 * span.x();
262  break;
263 
264  case vector::Z:
265  span = vector(wa, wb, len());
266  // Was end center, now lower corner
267  pt.x() = pt.x() - 0.5 * span.x();
268  pt.y() = pt.y() - 0.5 * span.y();
269  break;
270  }
271 
273  sortBias = 0;
274  xbkge = ybkge = zbkge = vbkge = 1.0;
275  blowoff_type = 0;
276 
277  Info<< "... changed to type cuboid" << nl;
278  break;
279  }
280  }
281  break;
282 
283  case PDRobstacle::CUBOID_1: // Cuboid "Type 1"
284  case PDRobstacle::LOUVRE_BLOWOFF: // Louvred wall or blow-off panel
285  case PDRobstacle::CUBOID: // Cuboid
286  case PDRobstacle::WALL_BEAM: // Beam against wall (treated here as normal cuboid)
287  case PDRobstacle::GRATING: // Grating
288  case PDRobstacle::RECT_PATCH: // Inlet, outlet, other b.c. (rectangular)
289  {
290  // 14 columns + identifier
291  // "%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %d %lf"
292 
293  int in_typeId;
294  double in_x, in_y, in_z;
295  double in_delx, in_dely, in_delz;
296  double in_poro, in_porox, in_poroy, in_poroz;
297  double col_12;
298  int col_13;
299  double in_blowoff_time = 0;
300 
301  int nread =
302  sscanf
303  (
304  buffer.c_str(),
305  "%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %d %lf",
306  &in_typeId, &in_x, &in_y, &in_z,
307  &in_delx, &in_dely, &in_delz,
308  &in_poro, &in_porox, &in_poroy, &in_poroz,
309  &col_12, &col_13, &in_blowoff_time
310  );
311 
312  blowoff_time = scalar(in_blowoff_time);
313 
314  if (nread < 14)
315  {
316  Info<< "Expected 14 items, but read in " << nread;
317  ReportLineInfo(lineNo, inputFile);
318  }
319 
320  identifier = in_ident;
321  pt = point(in_x, in_y, in_z);
322 
323  span = vector(in_delx, in_dely, in_delz);
324 
325  // Read porosity. Convert to blockage.
326  vbkge = 1.0 - in_poro;
327  xbkge = 1.0 - in_porox;
328  ybkge = 1.0 - in_poroy;
329  zbkge = 1.0 - in_poroz;
330 
331  if
332  (
336  )
337  {
338  // Check for invalid input
339 
340  if (vbkge != 1.0 || xbkge != 1.0 || ybkge != 1.0 || zbkge != 1.0)
341  {
342  Info<< "Type " << typeId << " is porous (setting to blockage).";
343  ReportLineInfo(lineNo, inputFile);
344 
345  vbkge = 1;
346  xbkge = 1;
347  ybkge = 1;
348  zbkge = 1;
349  }
351  {
352  // Correct interpretation of column 13
353  inlet_dirn = col_13;
354 
355  if (identifier.empty())
356  {
358  << "RECT_PATCH without a patch name"
359  << exit(FatalError);
360  }
361  }
362  }
363  else if (typeId == PDRobstacle::CUBOID)
364  {
365  }
366  else
367  {
368  if (!equal(cmptProduct(span), 0))
369  {
370  Info<< "Type " << typeId << " has non-zero thickness.";
371  ReportLineInfo(lineNo, inputFile);
372  }
373  }
374 
376  {
377  // Blowoff panel
378  blowoff_press = barToPa(col_12);
379  blowoff_type = col_13;
380 
381  if (blowoff_type == 1)
382  {
383  Info<< "Type " << typeId
384  << ": blowoff-type 1 not yet implemented.";
385  ReportLineInfo(lineNo, inputFile);
386 
387  if (blowoff_time != 0)
388  {
389  Info<< "Type " << typeId << " has blowoff time set,"
390  << " not set to blow off cell-by-cell";
391  ReportLineInfo(lineNo, inputFile);
392  }
393  }
394  else
395  {
396  if
397  (
398  (blowoff_type == 1 || blowoff_type == 2)
399  && (col_12 > 0)
400  )
401  {
402  if (col_12 > maxBlowoffPressure)
403  {
404  Info<< "Blowoff pressure (" << col_12
405  << ") too high for blowoff type "
406  << blowoff_type;
407  ReportLineInfo(lineNo, inputFile);
408  }
409  }
410  else
411  {
412  Info<< "Problem with blowoff parameters";
413  ReportLineInfo(lineNo, inputFile);
414  Info<< "Col12 " << col_12
415  << " Blowoff type " << blowoff_type
416  << ", blowoff pressure " << blowoff_press << nl;
417  }
418  }
419  }
420  else if (typeId == PDRobstacle::WALL_BEAM)
421  {
422  // WALL_BEAM against walls only contribute half to drag
423  // if ((col_12 == 1) || (col_12 == -1)) { against_wall_fac = 0.5; }
424  }
425  else if (typeId == PDRobstacle::GRATING)
426  {
427  if (col_12 > 0)
428  {
429  slat_width = col_12;
430  }
431  else
432  {
433  slat_width = 0;
434  }
435 
436  // Set orientation
437  if (equal(span.x(), 0))
438  {
439  orient = vector::X;
440  }
441  else if (equal(span.y(), 0))
442  {
443  orient = vector::Y;
444  }
445  else
446  {
447  orient = vector::Z;
448  }
449  }
450  }
451  break;
452 
453  case 0: // Group location
454  case PDRobstacle::OLD_INLET: // Ventilation source only
455  return false;
456  break;
457 
458  case PDRobstacle::IGNITION: // Ignition (now ignored. 2019-04)
459  Info<< "Ignition cell type ignored";
460  ReportLineInfo(lineNo, inputFile);
461  return false;
462  break;
463 
464  default:
465  Info<< "Unexpected type " << typeId;
466  ReportLineInfo(lineNo, inputFile);
467  return false;
468  break;
469  }
470 
471  return true;
472 }
473 
474 
475 // ************************************************************************* //
Foam::PDRobstacle::maxBlowoffPressure
static constexpr int maxBlowoffPressure
Definition: PDRobstacle.H:100
PDRobstacle.H
Foam::Vector< scalar >::Z
@ Z
Definition: Vector.H:77
Foam::Vector< scalar >::Y
@ Y
Definition: Vector.H:77
Foam::PDRobstacle::RECT_PATCH
@ RECT_PATCH
Definition: PDRobstacle.H:88
Foam::PDRobstacle::zbkge
scalar zbkge
Definition: PDRobstacle.H:148
Foam::sin
dimensionedScalar sin(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:257
Foam::PDRobstacle::xbkge
scalar xbkge
Definition: PDRobstacle.H:146
Foam::PDRobstacle::setFromLegacy
bool setFromLegacy(const int groupTypeId, const string &buffer, const label lineNo=-1, const word &inputFile=word::null)
Foam::cmptProduct
Cmpt cmptProduct(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:589
unitConversion.H
Unit conversion functions.
Foam::PDRobstacle::dia
scalar dia() const
Definition: PDRobstacle.H:126
Foam::PDRobstacle::len
scalar len() const
Definition: PDRobstacle.H:128
Foam::stringOps::splitSpace
Foam::SubStrings< StringType > splitSpace(const StringType &str)
Definition: stringOpsTemplates.C:239
Foam::PDRobstacle::wa
scalar wa
Definition: PDRobstacle.H:136
Foam::PDRobstacle::orient
direction orient
Definition: PDRobstacle.H:112
Foam::PDRobstacle::DIAG_BEAM
@ DIAG_BEAM
Definition: PDRobstacle.H:89
Foam::PDRobstacle::ybkge
scalar ybkge
Definition: PDRobstacle.H:147
Foam::PDRobstacle::IGNITION
@ IGNITION
ignored (old)
Definition: PDRobstacle.H:90
Foam::PDRobstacle::CUBOID_1
@ CUBOID_1
Definition: PDRobstacle.H:78
Foam::PDRobstacle::typeId
int typeId
Definition: PDRobstacle.H:109
Foam::PDRobstacle::span
vector span
Definition: PDRobstacle.H:122
Foam::Info
messageStream Info
Foam::PDRobstacle::pt
point pt
Definition: PDRobstacle.H:119
Foam::Vector< scalar >::X
@ X
Definition: Vector.H:77
Foam::PDRobstacle::blowoff_press
scalar blowoff_press
Definition: PDRobstacle.H:138
Foam::PDRobstacle::blowoff_type
int blowoff_type
Definition: PDRobstacle.H:152
Foam::PDRobstacle::identifier
string identifier
Definition: PDRobstacle.H:156
Foam::Vector::x
const Cmpt & x() const
Definition: VectorI.H:66
Foam::FatalError
error FatalError
Foam::PDRobstacle::CYLINDER
@ CYLINDER
Definition: PDRobstacle.H:79
Foam::PDRobstacle::slat_width
scalar slat_width
Definition: PDRobstacle.H:137
Foam::Vector::z
const Cmpt & z() const
Definition: VectorI.H:78
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:47
Foam::PDRobstacle::WALL_BEAM
@ WALL_BEAM
Definition: PDRobstacle.H:83
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Definition: unitConversion.H:44
Foam::PDRobstacle::theta
scalar theta() const
Definition: PDRobstacle.H:127
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
doubleVector.H
Foam::PDRobstacle::inlet_dirn
int inlet_dirn
Definition: PDRobstacle.H:153
Foam::barToPa
constexpr scalar barToPa(const scalar bar) noexcept
Definition: unitConversion.H:118
FatalErrorInFunction
#define FatalErrorInFunction
Definition: error.H:465
Foam::nl
constexpr char nl
Definition: Ostream.H:424
Foam::PDRobstacle::wb
scalar wb
Definition: PDRobstacle.H:142
Foam::PDRobstacle::OLD_INLET
@ OLD_INLET
ignored (old)
Definition: PDRobstacle.H:85
Foam::PDRobstacle::CUBOID
@ CUBOID
Definition: PDRobstacle.H:82
Foam::PDRobstacle::sortBias
scalar sortBias
Definition: PDRobstacle.H:115
Foam::PDRobstacle::LOUVRE_BLOWOFF
@ LOUVRE_BLOWOFF
Definition: PDRobstacle.H:81
Foam::PDRobstacle::blowoff_time
scalar blowoff_time
Definition: PDRobstacle.H:143
vector.H
Foam::Vector::y
const Cmpt & y() const
Definition: VectorI.H:72
Foam::point
vector point
Point is a vector.
Definition: point.H:37
stringOps.H
Foam::equal
bool equal(const T &s1, const T &s2)
Definition: doubleFloat.H:41
Foam::PDRobstacle::GRATING
@ GRATING
Definition: PDRobstacle.H:84
Foam::PDRobstacle::vbkge
scalar vbkge
Definition: PDRobstacle.H:145
Foam::PDRobstacle::groupId
label groupId
Definition: PDRobstacle.H:106
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:258