PDRsetFields.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) 2016 Shell Research Ltd.
9  Copyright (C) 2019-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Applications
28  PDRsetFields
29 
30 Description
31  Preparation of fields for PDRFoam
32 
33 SourceFiles
34  PDRsetFields.C
35 
36 \*---------------------------------------------------------------------------*/
37 
38 #include "argList.H"
39 #include "Time.H"
40 #include "IOdictionary.H"
41 
42 #include "PDRsetFields.H"
43 #include "PDRlegacy.H"
44 #include "PDRutils.H"
45 #include "IOmanip.H"
46 
47 using namespace Foam;
48 
49 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 // Main program:
51 
52 int main(int argc, char* argv[])
53 {
55  (
56  "Processes a set of geometrical obstructions to determine the"
57  " equivalent blockage effects when setting cases for PDRFoam"
58  );
61 
63  (
64  "time",
65  "time",
66  "Specify a time"
67  );
68 
69  argList::addOption("dict", "file", "Alternative PDRsetFieldsDict");
70 
72  (
73  "legacy",
74  "Force use of legacy obstacles table"
75  );
76 
78  (
79  "Read obstacles and write VTK only"
80  );
81 
82  #include "setRootCase.H"
83  #include "createTime.H"
84 
85  const word dictName("PDRsetFieldsDict");
87 
88  Info<< "Reading " << dictIO.name() << nl << endl;
89 
90  IOdictionary setFieldsDict(dictIO);
91 
92  const fileName& casepath = runTime.globalPath();
93 
94  pars.timeName = "0";
96 
97  // Program parameters (globals)
98  pars.read(setFieldsDict);
99 
100  if (args.found("legacy"))
101  {
102  pars.legacyObsSpec = true;
103  }
104 
105  // Always have the following:
106  // 0 = blockedFaces patch (no wall functions)
107  // 1 = mergingFaces patch
108  // 2 = wallFaces patch
109 
112 
113  for
114  (
115  PDRpatchDef::predefined predef :
116  {
120  }
121  )
122  {
123  patches[predef] = PDRpatchDef::names[predef];
124  }
125 
126 
127  // Dimensions and grid points for i-j-k domain
128  PDRblock pdrBlock;
129 
130  if (pars.legacyMeshSpec)
131  {
132  PDRlegacy::read_mesh_spec(casepath, pdrBlock);
133  }
134  else
135  {
136  IOdictionary iodict
137  (
138  IOobject
139  (
140  "PDRblockMeshDict",
141  runTime.system(),
142  runTime,
145  )
146  );
147 
148  pdrBlock.read(iodict);
149 
150  #ifdef FULLDEBUG
151  PDRlegacy::print_info(pdrBlock);
152  #endif
153  }
154 
155  // Storage for obstacles and cylinder-like obstacles
156  DynamicList<PDRobstacle> obstacles, cylinders;
157 
158  // Read in obstacles
159  const scalar volObstacles =
160  (
163  (
165  pdrBlock.bounds(),
166  obstacles,
167  cylinders
168  )
170  (
172  pdrBlock.bounds(),
173  obstacles,
174  cylinders
175  )
176  );
177 
178 
179  PDRobstacle::generateVtk(casepath/"VTK", obstacles, cylinders);
180 
181  if (args.dryRun())
182  {
183  Info<< nl
184  << "dry-run: stopping after reading/writing obstacles" << nl
185  << "\nEnd\n" << nl;
186  return 0;
187  }
188 
189 
190  // Bookkeeping of the ranges within the obstacle list
191 
192  // Original blockage at the start
193  const labelRange origBlocks(0, obstacles.size());
194 
195  // Intersection blockage
196  labelRange interBlocks(origBlocks.end_value(), 0);
197 
198  scalar volSubtract = 0;
199 
200  // Do binary intersections between blocks and cylinders (or diag-beam)
201  // by creating -ve blocks at the overlap
202 
203  labelRange int1Blocks(origBlocks.end_value(), 0);
204 
205  if (pars.overlaps % 2 > 0)
206  {
207  Info<< " block/cylinder intersections" << endl;
208 
209  label nblocked = obstacles.size();
210 
211  volSubtract += block_cylinder_overlap(obstacles, origBlocks, cylinders);
212 
213  nblocked = (obstacles.size() - nblocked);
214 
215  interBlocks += nblocked;
216  int1Blocks += nblocked;
217  }
218 
219  // Do binary intersections between blocks
220  // by creating -ve blocks at the overlap
221 
222  labelRange int2Blocks(int1Blocks.end_value(), 0);
223  if (pars.overlaps % 4 > 1)
224  {
225  Info<< " block/block intersections" << endl;
226 
227  label nblocked = obstacles.size();
228 
229  volSubtract += block_overlap(obstacles, origBlocks, 1.0);
230 
231  nblocked = (obstacles.size() - nblocked);
232 
233  interBlocks += nblocked;
234  int2Blocks += nblocked;
235  }
236 
237  // Correct for triple intersections
238  // by looking for overlaps between the -ve blocks just created
239 
240  labelRange int3Blocks(int2Blocks.end_value(), 0);
241  if (pars.overlaps % 8 > 3)
242  {
243  Info<< " triple intersections" << endl;
244 
245  label nblocked = obstacles.size();
246 
247  volSubtract += block_overlap(obstacles, interBlocks, 1.0/3.0);
248 
249  nblocked = (obstacles.size() - nblocked);
250 
251  interBlocks += nblocked;
252  int3Blocks += nblocked;
253  }
254 
255 
256  // The field arrays, in one structure pass around easily
257  PDRarrays arr(pdrBlock);
258 
259  Info<< "Apply blockage" << endl;
260 
261  // Create blockage and count arrays by working through
262  // real and extra blocks and cylinders
263 
264  // User-defined negative blocks. Use "sign" to distinguish
265  if (origBlocks.size())
266  {
267  Info<< " negative blocks: " << origBlocks.size() << nl;
268 
269  for (const PDRobstacle& obs : obstacles.slice(origBlocks))
270  {
271  arr.addBlockage(obs, patches, -1);
272  }
273  }
274 
275  // Do the intersection blocks positive and negative
276  // These are done first so that negative area blockage cancels positive
277 
278  if (interBlocks.size())
279  {
280  Info<< " blocks " << interBlocks.size() << nl;
281 
282  for (const PDRobstacle& obs : obstacles.slice(interBlocks))
283  {
284  arr.addBlockage(obs, patches, 0);
285  }
286  }
287 
288  // The positive real bocks
289  if (origBlocks.size())
290  {
291  Info<< " positive blocks: " << origBlocks.size() << nl;
292 
293  for (const PDRobstacle& obs : obstacles.slice(origBlocks))
294  {
295  arr.addBlockage(obs, patches, 1);
296  }
297  }
298 
299  // The cylinders
300  if (cylinders.size())
301  {
302  Info<< " cylinders: " << cylinders.size() << nl;
303 
304  for (const PDRobstacle& obs : cylinders)
305  {
306  arr.addCylinder(obs);
307  }
308  }
309 
310  // Calculation of the fields of drag, turbulence
311  // generation and combustion enhancement
312 
313  arr.blockageSummary();
314 
315  // Mapping of OpenFOAM cells/faces to i-j-k indices
316  PDRmeshArrays meshIdx;
318 
319  meshIdx.read(runTime, pdrBlock);
320 
321  PDRarrays::calculateAndWrite(arr, meshIdx, casepath, patches);
322 
323  Info<< nl
324  << setw(6) << origBlocks.size() << " blocks and "
325  << cylinders.size() << " cylinders/diagonal blocks" << nl;
326 
327  Info<< setw(6) << int2Blocks.size()
328  << " intersections amongst blocks" << nl;
329 
330  Info<< setw(6) << int1Blocks.size()
331  << " intersections between blocks and cyl/beams" << nl;
332 
333  Info<< setw(6) << int1Blocks.size()
334  << "/3 triple intersections" << nl;
335 
336  Info<< "Volume of obstacles read in: " << volObstacles
337  << ", volume of intersections: " << volSubtract << nl;
338 
339  Info<< nl << "After corrections:" << nl;
340  arr.blockageSummary();
341 
342  Info<< nl << "\nEnd\n" << endl;
343 
344  return 0;
345 }
346 
347 
348 // ************************************************************************* //
static void noFunctionObjects(bool addWithOption=false)
Remove &#39;-noFunctionObjects&#39; option and ignore any occurrences.
Definition: argList.C:547
static const Enum< predefined > names
Names for predefined types.
Definition: PDRpatchDef.H:68
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:462
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
bool legacyObsSpec
Definition: PDRparams.H:74
A class for handling file names.
Definition: fileName.H:72
bool legacyMeshSpec
Definition: PDRparams.H:73
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
static scalar legacyReadFiles(const fileName &obsFileDir, const wordList &obsFileNames, const boundBox &meshBb, DynamicList< PDRobstacle > &blocks, DynamicList< PDRobstacle > &cylinders)
Read obstacle files and add to the lists.
static void calculateAndWrite(PDRarrays &arr, const PDRmeshArrays &meshIndexing, const fileName &casepath, const UList< PDRpatchDef > &patches)
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:52
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
static scalar gridPointRelTol
Relative tolerance when matching grid points. Default = 0.02.
Definition: PDRmeshArrays.H:68
void read(const dictionary &dict)
Read program parameters from dictionary.
const word dictName("faMeshDefinition")
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
scalar block_cylinder_overlap(DynamicList< PDRobstacle > &blocks, const labelRange &range, const UList< PDRobstacle > &cylinders)
Calculate block/cylinder overlaps.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:374
static void noParallel()
Remove the parallel options.
Definition: argList.C:584
Ignore writing from objectRegistry::writeObject()
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
bool read(const dictionary &dict)
Read dictionary.
Definition: PDRblock.C:563
void read_mesh_spec(const fileName &casepath, PDRblock &pdrBlock)
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
SubList< T > slice(const label pos, label len=-1)
Return SubList slice (non-const access) - no range checking.
Definition: SubList.H:250
void read(const Time &runTime, const PDRblock &pdrBlock)
Read OpenFOAM mesh and determine i-j-k indices for faces/cells.
fileName globalPath() const
Return global path for the case = rootPath/globalCaseName. Same as TimePaths::globalPath() ...
Definition: Time.H:512
A class for handling words, derived from Foam::string.
Definition: word.H:63
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a &#39;dry-run&#39; bool option, with usage information.
Definition: argList.C:504
int overlaps
Flag to control which overlap calculations are performed.
Definition: PDRparams.H:103
int dryRun() const noexcept
Return the dry-run flag.
Definition: argListI.H:109
const word & system() const noexcept
Return system name.
Definition: TimePathsI.H:118
A single block x-y-z rectilinear mesh addressable as i,j,k with simplified creation. Some of the input is similar to blockMeshDict, but since this specialization is for a single-block that is aligned with the x-y-z directions, it provides a different means of specifying the mesh.
Definition: PDRblock.H:149
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:385
Preparation of fields for PDRFoam.
static void generateVtk(const fileName &outputDir, const UList< PDRobstacle > &obslist, const UList< PDRobstacle > &cyllist)
Generate multi-piece VTK (vtp) file of obstacles.
Istream and Ostream manipulators taking arguments.
void resize(const label newLen)
Adjust size of PtrList.
Definition: PtrList.C:95
predefined
Patch predefines.
Definition: PDRpatchDef.H:56
OpenFOAM/PDRblock addressing information.
Definition: PDRmeshArrays.H:61
const polyBoundaryMesh & patches
Foam::PDRparams pars
Globals for program parameters (ugly hack)
messageStream Info
Information stream (stdout output on master, null elsewhere)
scalar block_overlap(DynamicList< PDRobstacle > &blocks, const labelRange &range, const scalar multiplier=1.0)
Calculate block/block overlaps.
static scalar readFiles(const fileName &obsFileDir, const wordList &obsFileNames, const boundBox &meshBb, DynamicList< PDRobstacle > &blocks, DynamicList< PDRobstacle > &cylinders)
Read obstacle files and set the lists.
IOobject dictIO
fileName obsfile_dir
Definition: PDRparams.H:57
void print_info(const PDRblock &block)
Work array definitions for PDR fields.
Definition: PDRarrays.H:59
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:316
Foam::argList args(argc, argv)
scalar gridPointTol
Definition: PDRparams.H:105
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
Obstacle definitions for PDR.
Definition: PDRobstacle.H:70
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
Namespace for OpenFOAM.
wordList obsfile_names
Definition: PDRparams.H:58