PDRobstacleIO.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-2021 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 "PDRsetFields.H"
29 #include "PDRobstacle.H"
30 #include "volumeType.H"
31 
32 using namespace Foam;
33 using namespace Foam::constant;
34 
35 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
36 
38 {
39  this->clear();
40 
41  const word obsType(is);
42  const dictionary dict(is);
43 
44  auto* mfuncPtr = readdictionaryMemberFunctionTable(obsType);
45 
46  if (!mfuncPtr)
47  {
49  (
50  is,
51  "obstacle",
52  obsType,
53  *readdictionaryMemberFunctionTablePtr_
54  ) << exit(FatalIOError);
55  }
56 
57  mfuncPtr(*this, dict);
58 
59  return true;
60 }
61 
62 
64 (
65  const fileName& obsFileDir,
66  const wordList& obsFileNames,
67  const boundBox& meshBb,
68 
70  DynamicList<PDRobstacle>& cylinders
71 )
72 {
73  blocks.clear();
74  cylinders.clear();
75 
76  scalar totVolume = 0;
77  label nOutside = 0;
78  label nProtruding = 0;
79 
80  scalar shift = pars.obs_expand;
81 
82  if (!obsFileNames.empty())
83  {
84  Info<< "Reading obstacle files" << nl;
85  }
86 
87  label maxGroup = -1;
88 
89  for (const word& inputFile : obsFileNames)
90  {
91  Info<< " file: " << inputFile << nl;
92 
93  fileName path = (obsFileDir / inputFile);
94 
95  IFstream is(path);
96  dictionary inputDict(is);
97 
98  const scalar scaleFactor = inputDict.getOrDefault<scalar>("scale", 0);
99 
100  const label verbose = inputDict.getOrDefault<label>("verbose", 0);
101 
102  for (const entry& dEntry : inputDict)
103  {
104  if (!dEntry.isDict())
105  {
106  // ignore non-dictionary entry
107  continue;
108  }
109 
110  const dictionary& dict = dEntry.dict();
111 
112  if (!dict.getOrDefault("enabled", true))
113  {
114  continue;
115  }
116 
117  label obsGroupId = 0;
118  if (dict.readIfPresent("groupId", obsGroupId))
119  {
120  maxGroup = max(maxGroup, obsGroupId);
121  }
122  else
123  {
124  obsGroupId = ++maxGroup;
125  }
126 
127 
128  pointField pts;
129  dict.readIfPresent("locations", pts);
130  if (pts.empty())
131  {
132  pts.resize(1, Zero);
133  }
134 
135  List<PDRobstacle> obsInput;
136  dict.readEntry("obstacles", obsInput);
137 
138  label nCyl = 0; // The number of cylinders vs blocks
139 
140  for (PDRobstacle& obs : obsInput)
141  {
142  obs.groupId = obsGroupId;
143  obs.scale(scaleFactor);
144 
145  if (obs.isCylinder())
146  {
147  ++nCyl;
148  }
149  }
150 
151  const label nBlock = (obsInput.size() - nCyl);
152 
153  blocks.reserve(blocks.size() + nBlock*pts.size());
154  cylinders.reserve(cylinders.size() + nCyl*pts.size());
155 
156  if (verbose)
157  {
158  Info<< "Read " << obsInput.size() << " obstacles ("
159  << nCyl << " cylinders) with "
160  << pts.size() << " locations" << nl;
161 
162  if (verbose > 1)
163  {
164  Info<< "locations " << pts << nl
165  << "obstacles " << obsInput << nl;
166  }
167  }
168 
169  for (const PDRobstacle& scanObs : obsInput)
170  {
171  // Reject anything below minimum width
172  if (scanObs.tooSmall(pars.min_width))
173  {
174  continue;
175  }
176 
177  for (const point& origin : pts)
178  {
179  // A different (very small) shift for each obstacle
180  // so that faces cannot be coincident
181 
182  shift += floatSMALL;
183  const scalar shift2 = shift * 2.0;
184 
185 
186  switch (scanObs.typeId)
187  {
189  {
190  // Make a copy
191  PDRobstacle obs(scanObs);
192 
193  // Offset for the group position
194  obs.pt += origin;
195 
196  // Shift the end outwards so, if exactly on
197  // cell boundary, now overlap cell.
198  // So included in Aw.
199  obs.pt -= point::uniform(shift);
200  obs.len() += shift2;
201  obs.dia() -= floatSMALL;
202 
203 
204  // Trim against the mesh bounds.
205  // Ignore if it doesn't overlap, or bounds are invalid
206  const volumeType vt = obs.trim(meshBb);
207 
208  switch (vt)
209  {
210  case volumeType::OUTSIDE:
211  ++nOutside;
212  continue; // Can ignore the rest
213  break;
214 
215  case volumeType::MIXED:
216  ++nProtruding;
217  break;
218 
219  default:
220  break;
221  }
222 
223  // Later for position sorting
224  switch (obs.orient)
225  {
226  case vector::X:
227  obs.sortBias = obs.len();
228  break;
229  case vector::Y:
230  obs.sortBias = 0.5*obs.dia();
231  break;
232  case vector::Z:
233  obs.sortBias = 0.5*obs.dia();
234  break;
235  }
236 
237  totVolume += obs.volume();
238  cylinders.append(obs);
239 
240  break;
241  }
242 
244  {
245  // Make a copy
246  PDRobstacle obs(scanObs);
247 
248  // Offset for the group position
249  obs.pt += origin;
250 
251  // Shift the end outwards so, if exactly on
252  // cell boundary, now overlap cell.
253  // So included in Aw.
254  obs.pt -= point::uniform(shift);
255  obs.len() += shift2;
256  obs.wa += shift2;
257  obs.wb += shift2;
258 
259  totVolume += obs.volume();
260  cylinders.append(obs);
261 
262  break;
263  }
264 
267  case PDRobstacle::CUBOID:
271  {
272  // Make a copy
273  PDRobstacle obs(scanObs);
274 
275  // Offset for the position of the group
276  obs.pt += origin;
277 
278  if (obs.typeId == PDRobstacle::GRATING)
279  {
280  if (obs.slat_width <= 0)
281  {
283  }
284  }
285 
286  // Shift the end outwards so, if exactly on
287  // cell boundary, now overlap cell.
288  // So included in Aw.
289  obs.pt -= point::uniform(shift);
290  obs.span += point::uniform(shift2);
291 
292 
293  // Trim against the mesh bounds.
294  // Ignore if it doesn't overlap, or bounds are invalid
295  const volumeType vt = obs.trim(meshBb);
296 
297  switch (vt)
298  {
299  case volumeType::OUTSIDE:
300  ++nOutside;
301  continue; // Can ignore the rest
302  break;
303 
304  case volumeType::MIXED:
305  ++nProtruding;
306  break;
307 
308  default:
309  break;
310  }
311 
312  totVolume += obs.volume();
313 
314  blocks.append(obs);
315 
316  break;
317  }
318  }
319  }
320  }
321 
322  // Info<< "Cylinders: " << cylinders << nl;
323  }
324 
325  if (nOutside || nProtruding)
326  {
327  Info<< "Warning: " << nOutside << " obstacles outside domain, "
328  << nProtruding << " obstacles partly outside domain" << nl;
329  }
330  }
331 
332  // #ifdef FULLDEBUG
333  // Info<< blocks << nl << cylinders << nl;
334  // #endif
335 
336 
337  Info<< "Number of obstacles: "
338  << (blocks.size() + cylinders.size()) << " ("
339  << cylinders.size() << " cylinders)" << nl;
340 
341  return totVolume;
342 }
343 
344 
345 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
346 
348 {
349  obs.read(is);
350 
351  return is;
352 }
353 
354 
355 // ************************************************************************* //
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:63
PDRsetFields.H
Preparation of fields for PDRFoam.
PDRobstacle.H
Foam::Vector< scalar >::Z
@ Z
Definition: Vector.H:77
Foam::Vector< scalar >::Y
@ Y
Definition: Vector.H:77
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:63
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::uniform
static Form uniform(const Cmpt &s)
Definition: VectorSpaceI.H:157
Foam::fileName
A class for handling file names.
Definition: fileName.H:71
Foam::PDRobstacle::RECT_PATCH
@ RECT_PATCH
Definition: PDRobstacle.H:88
Foam::Zero
static constexpr const zero Zero
Definition: zero.H:131
Foam::IFstream
Input from file stream, using an ISstream.
Definition: IFstream.H:49
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:51
Foam::constant
Different types of constants.
Definition: atomicConstants.C:31
Foam::pars
Foam::PDRparams pars
Globals for program parameters (ugly hack)
Foam::PDRobstacle::dia
scalar dia() const
Definition: PDRobstacle.H:126
Foam::PDRobstacle::len
scalar len() const
Definition: PDRobstacle.H:128
Foam::FatalIOError
IOerror FatalIOError
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:223
Foam::DynamicList::reserve
void reserve(const label len)
Definition: DynamicListI.H:326
meshBb
List< treeBoundBox > meshBb(1, treeBoundBox(boundBox(coarseMesh.points(), false)).extend(rndGen, 1e-3))
Foam::PDRobstacle::trim
volumeType trim(const boundBox &bb)
Foam::DynamicList::clear
void clear() noexcept
Definition: DynamicListI.H:384
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::CUBOID_1
@ CUBOID_1
Definition: PDRobstacle.H:78
Foam::PDRobstacle::typeId
int typeId
Definition: PDRobstacle.H:109
volumeType.H
FatalIOErrorInLookup
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Definition: error.H:502
Foam::volumeType
An enumeration wrapper for classification of a location as being inside/outside of a volume.
Definition: volumeType.H:56
Foam::Field
Generic templated field type.
Definition: Field.H:59
Foam::PDRobstacle::span
vector span
Definition: PDRobstacle.H:122
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:57
Foam::Info
messageStream Info
Foam::PDRobstacle::pt
point pt
Definition: PDRobstacle.H:119
Foam::Vector< scalar >::X
@ X
Definition: Vector.H:77
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Definition: DynamicListI.H:504
Foam::volumeType::MIXED
@ MIXED
A location that is partly inside and outside.
Definition: volumeType.H:66
Foam::dictionary::readEntry
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
Definition: dictionaryTemplates.C:295
Foam::PDRparams::obs_expand
scalar obs_expand
Definition: PDRparams.H:117
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Definition: hashSets.C:40
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::PDRparams::min_width
scalar min_width
Definition: PDRparams.H:109
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:119
Foam::PDRobstacle::CYLINDER
@ CYLINDER
Definition: PDRobstacle.H:79
Foam::PDRobstacle::readFiles
static scalar readFiles(const fileName &obsFileDir, const wordList &obsFileNames, const boundBox &meshBb, DynamicList< PDRobstacle > &blocks, DynamicList< PDRobstacle > &cylinders)
Foam::PDRobstacle::slat_width
scalar slat_width
Definition: PDRobstacle.H:137
Foam
Definition: atmBoundaryLayer.C:26
Foam::PDRobstacle::WALL_BEAM
@ WALL_BEAM
Definition: PDRobstacle.H:83
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
Foam::PDRobstacle::read
bool read(Istream &is)
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:424
Foam::PDRobstacle::isCylinder
static bool isCylinder(const label id)
Definition: PDRobstacleI.H:23
Foam::PDRobstacle::wb
scalar wb
Definition: PDRobstacle.H:142
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:58
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
Obstacle definitions for PDR.
Definition: PDRobstacle.H:70
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::boundBox
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:57
Foam::PDRobstacle::scale
void scale(const scalar factor)
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:141
Foam::PDRobstacle::GRATING
@ GRATING
Definition: PDRobstacle.H:84
floatSMALL
#define floatSMALL
Definition: PDRsetFields.H:48
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:398
Foam::volumeType::OUTSIDE
@ OUTSIDE
A location outside the volume.
Definition: volumeType.H:65
Foam::PDRobstacle::volume
scalar volume() const
Foam::PDRparams::def_grating_slat_w
scalar def_grating_slat_w
Definition: PDRparams.H:120
Foam::PDRobstacle::groupId
label groupId
Definition: PDRobstacle.H:106