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