Loading...
Searching...
No Matches
genericPatchFieldBase.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) 2021-2023 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
29#include "error.H"
30
31// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32
33bool Foam::genericPatchFieldBase::checkFieldSize
34(
35 const label fieldSize,
36 const label patchSize,
37 const word& patchName,
38 const keyType& key,
39 const IOobject& io
40) const
41{
42 const bool ok = (fieldSize == patchSize);
43
44 if (!ok)
45 {
47 << "\n size of field " << key
48 << " (" << fieldSize << ") != patch size (" << patchSize << ')'
49 << "\n on patch " << patchName
50 << " of field " << io.name() << " in file "
51 << io.objectPath() << nl
53 }
55 return ok;
56}
57
58
59// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
60
62(
63 const dictionary& dict
65:
66 actualTypeName_(dict.get<word>("type")),
67 dict_(dict)
68{}
69
70
72(
73 const Foam::zero,
75)
76:
77 actualTypeName_(rhs.actualTypeName_),
78 dict_(rhs.dict_)
79{}
80
81
82// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
83
85(
86 const word& patchName,
87 const IOobject& io
88) const
89{
91 << " (Actual type " << actualTypeName_ << ')'
92 << "\n on patch " << patchName
93 << " of field " << io.name() << " in file " << io.objectPath() << nl
94 << nl
95 << " You are probably trying to solve for a field with a "
96 "generic boundary condition." << nl;
97}
98
99
101(
102 const word& entryName,
103 const word& patchName,
104 const IOobject& io
105) const
106{
108 << nl
109 << " Missing required '" << entryName << "' entry"
110 << " on patch " << patchName
111 << " of field " << io.name() << " in file " << io.objectPath() << nl
112 << " (Actual type " << actualTypeName_ << ')' << nl << nl
113 << " Please add the '" << entryName << "' entry to the"
114 " write function of the user-defined boundary-condition" << nl
115 << exit(FatalIOError);
116}
117
118
120(
121 const label patchSize,
122 const word& patchName,
123 const IOobject& io,
124 const bool separateValue
125)
126{
127 for (const entry& dEntry : dict_)
128 {
129 const keyType& key = dEntry.keyword();
130
131 if (key == "type" || (separateValue && key == "value"))
132 {
133 // "type" and possibly "value" handled differently
134 }
135 else
137 processEntry(dEntry, patchSize, patchName, io);
138 }
139 }
140}
141
142
144(
145 const entry& dEntry,
146 const label patchSize,
147 const word& patchName,
148 const IOobject& io
149)
150{
151 if (!dEntry.isStream())
152 {
153 return false;
154 }
155
156 const keyType& key = dEntry.keyword();
157 ITstream& is = dEntry.stream();
158
159 if (is.empty())
160 {
161 return false;
162 }
163
164
165 // First token
166 token tok(is);
167
168 if (tok.isWord("nonuniform"))
169 {
170 is >> tok;
171
172 if (tok.isLabel(0))
173 {
174 // For v2006 and earlier, could have a plain untyped 0
175 // without a compound type.
176 // Just treat as scalar and hope for the best.
177 scalarFields_.insert(key, autoPtr<scalarField>::New());
178 return true;
179 }
180 else if (!tok.isCompound())
181 {
183 << "\n non-compound token following 'nonuniform'"
184 << "\n on patch " << patchName << " field "
185 << io.name() << " in file "
186 << io.objectPath() << nl
187 << exit(FatalIOError);
188 return false;
189 }
190
191 #undef doLocalCode
192 #define doLocalCode(ValueType, Member) \
193 if (tok.isCompound<List<ValueType>>()) \
194 { \
195 auto fPtr = autoPtr<Field<ValueType>>::New(); \
196 \
197 fPtr->transfer \
198 ( \
199 tok.transferCompoundToken<List<ValueType>>(is) \
200 ); \
201 \
202 if (!checkFieldSize(fPtr->size(), patchSize, patchName, key, io)) \
203 { \
204 return false; \
205 } \
206 \
207 this->Member.insert(key, fPtr); \
208 return true; \
209 }
210
211 //doLocalCode(label, labelFields_);
212 doLocalCode(scalar, scalarFields_);
213 doLocalCode(vector, vectorFields_);
214 doLocalCode(sphericalTensor, sphTensorFields_);
215 doLocalCode(symmTensor, symmTensorFields_);
216 doLocalCode(tensor, tensorFields_);
217 #undef doLocalCode
218
219 // Fall-through
221 << "\n unsupported compound " << tok.compoundToken() << nl
222 << "\n on patch " << patchName << " of field "
223 << io.name() << " in file "
224 << io.objectPath() << nl
225 << exit(FatalIOError);
226 return false;
227 }
228 else if (tok.isWord("uniform"))
229 {
230 is >> tok;
231
232 if (!tok.isPunctuation())
233 {
234 // Unfortunately cannot distinguish between
235 // labelField and scalarField...
236
237 scalarFields_.insert
238 (
239 key,
240 autoPtr<scalarField>::New(patchSize, tok.number())
241 );
242 }
243 else
244 {
245 // Read vector-space as list of scalars
246 is.putBack(tok);
247
248 scalarList list(is);
249
250 if (list.size() == vector::nComponents)
251 {
252 vector vs(list[0], list[1], list[2]);
253
254 vectorFields_.insert
255 (
256 key,
258 (
259 patchSize,
260 vs
261 )
262 );
263 }
264 else if (list.size() == sphericalTensor::nComponents)
265 {
266 sphericalTensor vs(list[0]);
267
268 sphTensorFields_.insert
269 (
270 key,
272 (
273 patchSize,
274 vs
275 )
276 );
277 }
278 else if (list.size() == symmTensor::nComponents)
279 {
280 symmTensor vs
281 (
282 list[0], list[1], list[2],
283 list[3], list[4],
284 list[5]
285 );
286
287 symmTensorFields_.insert
288 (
289 key,
291 (
292 patchSize,
293 vs
294 )
295 );
296 }
297 else if (list.size() == tensor::nComponents)
298 {
299 tensor vs
300 (
301 list[0], list[1], list[2],
302 list[3], list[4], list[5],
303 list[6], list[7], list[8]
304 );
305
306 tensorFields_.insert
307 (
308 key,
310 (
311 patchSize,
312 vs
313 )
314 );
315 }
316 else
317 {
319 << "\n unrecognised native type " << flatOutput(list)
320 << "\n on patch " << patchName << " of field "
321 << io.name() << " in file "
322 << io.objectPath() << nl
323 << exit(FatalIOError);
324 return false;
325 }
327 }
328
329 return true;
330}
331
332
334(
335 const entry& e,
336 Ostream& os
337) const
338{
339 const keyType& key = e.keyword();
340
341 if
342 (
343 e.isStream()
344 && e.stream().peek().isWord("nonuniform")
345 )
346 {
347 #undef doLocalCode
348 #define doLocalCode(ValueType, Member) \
349 { \
350 const auto iter = this->Member.cfind(key); \
351 if (iter.good()) \
352 { \
353 iter.val()->writeEntry(key, os); \
354 return; \
355 } \
356 }
357
358 //doLocalCode(label, labelFields_);
359 doLocalCode(scalar, scalarFields_);
360 doLocalCode(vector, vectorFields_);
361 doLocalCode(sphericalTensor, sphTensorFields_);
362 doLocalCode(symmTensor, symmTensorFields_);
363 doLocalCode(tensor, tensorFields_);
364 #undef doLocalCode
365 }
366 else
367 {
368 e.write(os);
369 }
370}
371
372
374(
375 Ostream& os,
376 const bool separateValue
377) const
378{
379 os.writeEntry("type", actualTypeName_);
380
381 for (const entry& dEntry : dict_)
382 {
383 const keyType& key = dEntry.keyword();
384
385 if (key == "type" || (separateValue && key == "value"))
386 {
387 // NB: "type" written first, "value" possibly separately
388 }
389 else
391 putEntry(dEntry, os);
392 }
393 }
394}
395
396
398(
400 const labelList& addr
401)
402{
403 #undef doLocalCode
404 #define doLocalCode(ValueType, Member) \
405 forAllIters(this->Member, iter) \
406 { \
407 const auto iter2 = rhs.Member.cfind(iter.key()); \
408 \
409 if (iter2.good()) \
410 { \
411 iter.val()->rmap(*iter2.val(), addr); \
412 } \
413 }
414
415 //doLocalCode(label, labelFields_);
416 doLocalCode(scalar, scalarFields_);
417 doLocalCode(vector, vectorFields_);
418 doLocalCode(sphericalTensor, sphTensorFields_);
419 doLocalCode(symmTensor, symmTensorFields_);
420 doLocalCode(tensor, tensorFields_);
421 #undef doLocalCode
422}
423
424
425// ************************************************************************* //
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
An input stream of tokens.
Definition ITstream.H:56
void putBack(const token &tok)
Put back a token (copy). Only a single put back is permitted.
Definition Istream.C:71
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static constexpr direction nComponents
Number of components in this vector space.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition autoPtr.H:178
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66
virtual ITstream & stream() const =0
Return token stream, if entry is a primitive entry.
virtual bool isStream() const noexcept
True if this entry is a stream.
Definition entry.H:267
const keyType & keyword() const noexcept
Return keyword.
Definition entry.H:231
Generic infrastructure for reading/writing unknown patch types.
void writeGeneric(Ostream &os, const bool separateValue) const
Write all generic entries from dictionary, optionally treating the "value" entry separately.
genericPatchFieldBase()=default
Default construct, generally not useful.
void rmapGeneric(const genericPatchFieldBase &rhs, const labelList &addr)
Implementation for reverse map given patch field onto this patch field.
void reportMissingEntry(const word &entryName, const word &patchName, const IOobject &io) const
FatalError for missing entry.
void putEntry(const entry &e, Ostream &os) const
Write a single entry, with lookup of hashed values.
genericPatchFieldBase(const Foam::zero, const genericPatchFieldBase &)
Partial copy construct. Only copy type and dictionary.
void genericFatalSolveError(const word &patchName, const IOobject &io) const
Add error message to FatalError about solving with generic condition.
void processGeneric(const label patchSize, const word &patchName, const IOobject &io, const bool separateValue)
bool processEntry(const entry &dEntry, const label patchSize, const word &patchName, const IOobject &io)
A class for handling keywords in dictionaries.
Definition keyType.H:69
A token holds an item read from Istream.
Definition token.H:70
bool isWord() const noexcept
Token is word-variant (WORD, DIRECTIVE).
Definition tokenI.H:1004
A class for handling words, derived from Foam::string.
Definition word.H:66
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
OBJstream os(runTime.globalPath()/outputName)
const auto & io
#define doLocalCode(FieldType, Variable)
constexpr auto key(const Type &t) noexcept
Helper function to return the enum value.
List< label > labelList
A List of labels.
Definition List.H:62
Tensor< scalar > tensor
Definition symmTensor.H:57
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition FlatOutput.H:217
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
Vector< scalar > vector
Definition vector.H:57
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
SphericalTensor< scalar > sphericalTensor
SphericalTensor of scalars, i.e. SphericalTensor<scalar>.
List< scalar > scalarList
List of scalar.
Definition scalarList.H:32
SymmTensor< scalar > symmTensor
SymmTensor of scalars, i.e. SymmTensor<scalar>.
Definition symmTensor.H:55
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
volScalarField & e