PDRlegacyMeshSpec.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 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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\*---------------------------------------------------------------------------*/
28
29// Read spec that resemble this:
30//
31// xmesh
32// (
33// ( -8.18 14 0.83 )
34// ( -0.69 11 1.00 )
35// ( 0.69 14 1.20 )
36// ( 8.18 0 )
37// )
38//
39// ymesh
40// (
41// ...
42// )
43
44#include "PDRlegacy.H"
45
46// OpenFOAM includes
47#include "error.H"
48#include "IFstream.H"
49#include "stringOps.H"
50#include "OSspecific.H"
51
52#define XMESH_TAG "xmesh"
53#define YMESH_TAG "ymesh"
54#define ZMESH_TAG "zmesh"
55
56
57// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
58
59namespace Foam
60{
61namespace PDRlegacy
62{
63namespace Detail
64{
65
66//- Simple structure for processing a mesh spec entry
67// Handles an entry with (float), (float int), or (float int float)
68//
69// This is for handling a sub-spec that resembles this:
70//
71// (
72// ( -8.18 14 0.83 )
73// ( -0.69 11 1.00 )
74// ( 0.69 14 1.20 )
75// ( 8.18 0 )
76// )
77struct pdrMeshSpecLine
78{
79 scalar knot;
80 label ndiv;
81 scalar factor;
82
83 pdrMeshSpecLine() : knot(0), ndiv(0), factor(0) {}
84
85 //- Cheap means to avoid uniform list output
86 bool operator!=(const pdrMeshSpecLine&) const
87 {
88 return false;
89 }
90};
91
92
93// Read mesh-spec entry
94Istream& operator>>(Istream& is, pdrMeshSpecLine& spec)
95{
96 spec.knot = 0;
97 spec.ndiv = 0;
98 spec.factor = 0;
99
100 is.readBegin("pdrMeshSpecLine");
101
102 // Must have a point
103 is >> spec.knot;
104
105 token tok(is);
106 if (tok.isLabel())
107 {
108 spec.ndiv = tok.labelToken();
109
110 if (spec.ndiv)
111 {
112 is >> spec.factor;
113 }
114 }
115 else
116 {
117 is.putBack(tok);
118 }
119
120 is.readEnd("pdrMeshSpecLine");
121
122 is.check(FUNCTION_NAME);
123 return is;
124}
125
126#ifdef FULLDEBUG
127// Write mesh-spec entry
128Ostream& operator<<(Ostream& os, const pdrMeshSpecLine& spec)
129{
130 os << token::BEGIN_LIST << spec.knot;
131
132 if (spec.ndiv)
133 {
134 os << token::SPACE << spec.ndiv
135 << token::SPACE << spec.factor;
136 }
137
138 os << token::END_LIST;
139
140 return os;
141}
142#endif
143
144
145void read_spec(ISstream& is, const direction cmpt, List<scalar>& gridPoint)
146{
147 if (!gridPoint.empty())
148 {
150 << "Duplicate specification of "
151 << vector::componentNames[cmpt]
152 << " grid"
153 << exit(FatalError);
154 }
155
156 List<pdrMeshSpecLine> specs(is);
157
158 if (specs.size() < 2)
159 {
161 << "Grid specification for " << vector::componentNames[cmpt]
162 << " is too small. Need at least two points!" << nl
163 << exit(FatalError);
164 }
165
166 specs.last().ndiv = 0; // safety
167
168
169 DynamicList<scalar> knots;
170 DynamicList<label> divisions;
171 DynamicList<scalar> factors;
172
173 for (const auto& spec : specs)
174 {
175 knots.append(spec.knot);
176
177 if (spec.ndiv < 1)
178 {
179 break;
180 }
181 divisions.append(spec.ndiv);
182 factors.append(spec.factor);
183 }
184
185 label nPoints = 1;
186 for (const label nDiv : divisions)
187 {
188 nPoints += nDiv;
189 }
190
191 if (nPoints < 2)
192 {
194 << "No cells defined for direction "
195 << vector::componentNames[cmpt] << nl
196 << exit(FatalError);
197 }
198
199
200 // Define the grid points
201 gridPoint.resize(nPoints);
202
203 const label nSegments = divisions.size();
204
205 label start = 0;
206
207 for (label segmenti=0; segmenti < nSegments; ++segmenti)
208 {
209 const label nDiv = divisions[segmenti];
210 const scalar factor = factors[segmenti];
211
212 SubList<scalar> subPoint(gridPoint, nDiv+1, start);
213 start += nDiv;
214
215 subPoint[0] = knots[segmenti];
216 subPoint[nDiv] = knots[segmenti+1];
217
218 const scalar dist = (subPoint.last() - subPoint.first());
219
220 if (equal(factor, scalar(1)))
221 {
222 for (label i=1; i < nDiv; ++i)
223 {
224 subPoint[i] = (subPoint[0] + (dist * i)/nDiv);
225 }
226 }
227 else
228 {
229 scalar delta = dist * (1.0 - factor) / (1.0 - ::pow(factor, nDiv));
230
231 scalar xyz = subPoint[0];
232
233 for (label i=0; i < nDiv; ++i)
234 {
235 subPoint[i] = xyz;
236 xyz += delta;
237 delta *= factor;
238 }
239 }
240 }
241}
242
243
244} // End namespace Detail
245} // End namespace PDRlegacy
246} // End namespace Foam
247
248
249// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
250
251void Foam::PDRlegacy::print_info(const PDRblock& block)
252{
253 Info<< "PDRblock" << nl
254 << " nCells: " << block.sizes() << nl
255 << " Box: " << block.bounds() << nl
256 << "x " << flatOutput(block.grid().x()) << nl
257 << "y " << flatOutput(block.grid().y()) << nl
258 << "z " << flatOutput(block.grid().z()) << nl
259 << endl;
260}
261
262
263void Foam::PDRlegacy::read_mesh_spec(const fileName& casepath, PDRblock& block)
264{
265 Info<< "Reading pdrMeshSpec (legacy format)" << nl;
266
267 bool processed = false;
268
269 for (const fileName dirName : { "system", "constant/polyMesh" })
270 {
271 fileName path
272 (
273 casepath / dirName / "pdrMeshSpec"
274 );
275
276 if (Foam::isFile(path))
277 {
278 IFstream is(path);
279
280 read_mesh_spec(is, block);
281 processed = true;
282 break;
283 }
284 }
285
286 if (!processed)
287 {
289 << "Did not process pdrMeshSpec" << nl
290 << exit(FatalError);
291 }
292}
293
294
295void Foam::PDRlegacy::read_mesh_spec(ISstream& is, PDRblock& block)
296{
297 Vector<scalarList> grid;
298
299 string line;
300
301 while (is.good())
302 {
303 is.getLine(line);
304 stringOps::inplaceTrim(line);
305
306 if (line == XMESH_TAG)
307 {
308 Detail::read_spec(is, vector::X, grid.x());
309 }
310 else if (line == YMESH_TAG)
311 {
312 Detail::read_spec(is, vector::Y, grid.y());
313 }
314 else if (line == ZMESH_TAG)
315 {
316 Detail::read_spec(is, vector::Z, grid.z());
317 }
318 }
319
320 for (direction cmpt=0; cmpt < vector::nComponents; ++cmpt)
321 {
322 if (grid[cmpt].empty())
323 {
325 << "No specification for "
327 << " grid" << nl
328 << exit(FatalError);
329 }
330 }
331
332 block.reset(grid.x(), grid.y(), grid.z());
333
334 #ifdef FULLDEBUG
335 print_info(block);
336 #endif
337}
338
339
340// ************************************************************************* //
scalar delta
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
bool readBegin(const char *funcName)
Begin read of data chunk, starts with '('.
Definition: Istream.C:111
static const char *const componentNames[]
Definition: bool.H:104
static constexpr direction nComponents
Number of components in bool is 1.
Definition: bool.H:98
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
label nPoints
#define FUNCTION_NAME
bool equal(const Matrix< Form1, Type > &A, const Matrix< Form2, Type > &B, const bool verbose=false, const label maxDiffs=10, const scalar relTol=1e-5, const scalar absTol=1e-8)
Compare matrix elements for absolute or relative equality.
Definition: MatrixTools.C:34
void read_mesh_spec(const fileName &casepath, PDRblock &pdrBlock)
void print_info(const PDRblock &block)
Ostream & operator<<(Ostream &os, const interfaceEntry &entry)
tmp< GeometricField< Type, faPatchField, areaMesh > > ndiv(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
Definition: facNDiv.C:50
Namespace for OpenFOAM.
bool operator!=(const eddy &a, const eddy &b)
Definition: eddy.H:239
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
Istream & operator>>(Istream &, directionInfo &)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition: MSwindows.C:666
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53