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 -------------------------------------------------------------------------------
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 \*---------------------------------------------------------------------------*/
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 
59 namespace Foam
60 {
61 namespace PDRlegacy
62 {
63 namespace 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 // )
77 struct 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
94 Istream& 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
128 Ostream& 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 
145 void 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 
251 void 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 
263 void 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 
295 void 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);
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 "
326  << vector::componentNames[cmpt]
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
uint8_t direction
Definition: direction.H:46
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
void inplaceTrim(std::string &s)
Trim leading and trailing whitespace inplace.
Definition: stringOps.C:1054
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
Begin list [isseparator].
Definition: token.H:158
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
void read_mesh_spec(const fileName &casepath, PDRblock &pdrBlock)
label nPoints
Istream & operator>>(Istream &, directionInfo &)
Space [isspace].
Definition: token.H:128
End list [isseparator].
Definition: token.H:159
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
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: POSIX.C:830
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:76
bool equal(const T &s1, const T &s2)
Compare two values for equality.
Definition: doubleFloat.H:41
PtrList< volScalarField > & Y
messageStream Info
Information stream (stdout output on master, null elsewhere)
bool operator!=(const eddy &a, const eddy &b)
Definition: eddy.H:299
void print_info(const PDRblock &block)
tmp< GeometricField< Type, faPatchField, areaMesh > > ndiv(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
Definition: facNDiv.C:43
Namespace for OpenFOAM.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225