regionFaModel.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-2025 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 "regionFaModel.H"
29 #include "faMesh.H"
30 #include "Time.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36 namespace regionModels
37 {
38  defineTypeNameAndDebug(regionFaModel, 0);
39 }
40 }
41 
42 const Foam::word
44 
45 
46 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
47 
48 namespace
49 {
50 
51 // Return IOobject with name qualified with region and area names
52 Foam::IOobject createModelIOobject
53 (
54  const Foam::polyMesh& mesh,
55  // const Foam::word& baseName, <- always regionFaModelName
56  const Foam::word& regionName,
57  const Foam::word& areaName
58 )
59 {
60  using namespace Foam;
61 
62  // Default: regionFaModel.<regionName>
63  word objName = IOobject::groupName
64  (
67  );
68 
69  // Append '.<area-name>' or nothing
70  objName.ext(polyMesh::regionName(areaName));
71 
72  return IOobject
73  (
74  objName,
75  mesh.time().constant(),
80  );
81 }
82 
83 
84 // Return IOobject with name qualified with region and area names
85 Foam::IOobject createPropertiesIOobject
86 (
87  const Foam::polyMesh& mesh,
88  // const Foam::word& baseName, <- always regionFaModelName
89  const Foam::word& regionName,
90  const Foam::word& areaName
91 )
92 {
93  using namespace Foam;
94 
95  const fileName uniformPath
96  (
97  word("uniform")
99  );
100 
101  const word objName
102  (
104  (
105  (regionName + "OutputProperties"),
106  polyMesh::regionName(areaName)
107  )
108  );
109 
110  // NOTE (2025-10-01):
111  // Cannot hold the OutputProperties within
112  // - faMeshesRegistry::New(mesh).thisDb()
113  // since this produces a uniform path that we do not yet handle
114  //
115  // -> "<time>/finite-area/uniform/regionFaModel/<model-region>"
116  // vs: "<time>/uniform/regionFaModel/<model-region>"
117  //
118  // The difference being that we only look for 'uniform' at the
119  // first sub-level within the time directory when decomposing etc.
120 
121  IOobject legacy
122  (
123  objName,
124  mesh.time().timeName(),
125  uniformPath/regionName,
126 
127  // Not possible: faMeshesRegistry::New(mesh).thisDb(),
128  mesh, // Registered on volume mesh!
129 
133  );
134 
135  return legacy;
136 }
137 
138 } // End anonymous namespace
139 
140 
141 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
142 
143 void Foam::regionModels::regionFaModel::constructMeshObjects
144 (
145  // Just for error reference
146  const dictionary& dict
147 )
148 {
149  regionMeshPtr_.reset(nullptr);
150 
151  #if 1
152  regionMeshPtr_.reset
153  (
155  );
156 
157  #else
158 
159  // With try/catch and error messages
160 
161  // DIY
162  // regionMeshPtr_ = faMesh::TryNew(areaName_, primaryMesh_);
163 
164  // More heavy handed, but gives a better chance of locating
165  // the source of the error.
166  {
167  const bool oldThrowingError = FatalError.throwing(true);
168  const bool oldThrowingIOerr = FatalIOError.throwing(true);
169 
170  try
171  {
172  regionMeshPtr_.reset
173  (
175  );
176  }
177  catch (const Foam::error& err)
178  {
179  Warning << err << nl << endl;
180 
181  // Trickery to get original message
182  err.write(Warning, false);
183  }
184  catch (const Foam::IOerror& err)
185  {
186  Warning << err << nl << endl;
187 
188  // Trickery to get original message
189  err.write(Warning, false);
190  }
191 
192  FatalError.throwing(oldThrowingError);
193  FatalIOError.throwing(oldThrowingIOerr);
194  }
195 
196  if (!regionMeshPtr_)
197  {
198  FatalError
199  << "Failed to create finite-area mesh [" << areaName_
200  << "] for model: "<< modelName_ << nl
201  << "A common cause is an incorrect or "
202  "missing 'area' entry in the setup" << nl
203  << ">>>>" << nl
204  << dict.relativeName() << dict << "<<<<" << endl
205  << exit(FatalError);
206  }
207  #endif
208 }
209 
210 
211 void Foam::regionModels::regionFaModel::initialise()
212 {
213  if (debug)
214  {
215  Pout<< "regionFaModel::initialise()" << endl;
216  }
217 
218  vsmPtr_.reset(new volSurfaceMapping(regionMeshPtr_()));
219 
220  if (!outputPropertiesPtr_)
221  {
222  outputPropertiesPtr_.reset
223  (
224  new IOdictionary
225  (
226  createPropertiesIOobject
227  (
228  primaryMesh_,
229  // regionFaModelName,
230  regionName_,
231  areaName_
232  )
233  )
234  );
235  }
236 }
237 
238 
239 bool Foam::regionModels::regionFaModel::init(const dictionary& dict)
240 {
241  if (active_)
242  {
243  if (const dictionary* dictptr = dict.findDict(modelName_ + "Coeffs"))
244  {
245  coeffs_ <<= *dictptr;
246  }
247 
248  infoOutput_.readIfPresent("infoOutput", dict);
249 
250  return true;
251  }
253  return false;
254 }
255 
256 
257 // * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
258 
260 {
261  return vsmPtr_();
262 }
263 
264 
265 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
266 
268 (
269  const fvMesh& mesh,
270  const word& regionType,
271  const word& modelName,
272  const dictionary& dict,
273  bool readFields
274 )
275 :
277  (
278  createModelIOobject
279  (
280  mesh,
281  // regionFaModelName,
282  dict.get<word>("region"),
283  dict.getOrDefault<word>("area", polyMesh::defaultRegion)
284  )
285  ),
286  primaryMesh_(mesh),
287  time_(mesh.time()),
288  active_(dict.get<Switch>("active")),
289  infoOutput_(false),
290  modelName_(modelName),
291  areaName_(dict.getOrDefault<word>("area", polyMesh::defaultRegion)),
292  regionName_(dict.get<word>("region")),
293  coeffs_(dict.subOrEmptyDict(modelName + "Coeffs"))
294 {
295  // Suffix hint for variable names
296  if
297  (
298  coeffs_.readIfPresent("suffixing", suffixHint_)
299  || dict.readIfPresent("suffixing", suffixHint_)
300  )
301  {
303 
304  if (sw.good())
305  {
306  if (!sw) // No suffix
307  {
308  suffixHint_.clear();
309  }
310  }
311  else if (suffixHint_ == "default")
312  {
313  sw = true;
314  }
315 
316  if (sw) // Default (region) suffix
317  {
318  suffixHint_ = '_' + regionName_;
319  }
320  }
321 
322  constructMeshObjects(dict);
323  initialise();
324 
325  if (readFields)
326  {
327  init(dict);
328  }
329 }
330 
331 
332 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
333 
335 {
336  if (active_)
337  {
338  Info<< "\nEvolving " << modelName_
339  << " for region " << regionMesh().name();
340 
341  if (!polyMesh::regionName(areaName_).empty())
342  {
343  Info<< " [" << areaName_ << "]";
344  }
345  Info<< endl;
346 
347  preEvolveRegion();
348 
349  evolveRegion();
350 
351  postEvolveRegion();
352 
353  // Provide some feedback
354  if (infoOutput_)
355  {
356  Info<< incrIndent;
357  info();
358  Info<< decrIndent << endl;
359  }
360  }
361 }
362 
363 
365 {}
366 
367 
369 {}
370 
371 
373 {}
374 
375 
377 {
378  return 0;
379 }
380 
381 
382 // ************************************************************************* //
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Definition: faMesh.H:133
dictionary dict
bool good() const noexcept
True if the Switch represents a valid enumeration.
Definition: Switch.H:307
A class for handling file names.
Definition: fileName.H:72
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...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:130
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:832
const volSurfaceMapping & vsm() const
Return mapping between surface and volume fields.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
bool throwing() const noexcept
Return the current exception throwing state (on or off)
Definition: error.H:227
static Switch find(const char *s)
Find switchType for the given string, returning a Switch that can be tested for good() or bad()...
virtual void postEvolveRegion()
Post-evolve region.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:518
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, any/none. Also accepts 0/1 as a string and shortcuts t/f, y/n.
Definition: Switch.H:80
Ignore writing from objectRegistry::writeObject()
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
Volume to surface and surface to volume mapping.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:74
autoPtr< faMesh > regionMeshPtr_
Pointer to the region mesh database.
word ext() const
Return file name extension (part after last .)
Definition: wordI.H:171
static word groupName(StringType base, const word &group)
Create dot-delimited name.group string.
static const objectRegistry & Registry(const polyMesh &pMesh)
Return the singleton parent registry (on the polyMesh) that contains all objects related to finite-ar...
Definition: faMesh.C:157
word areaName_
The finite-area mesh name (default: region0)
dynamicFvMesh & mesh
const word modelName_
Model name.
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const NameMatchPredicate &selectedFields, DynamicList< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type and store on the objectRegistry.
constexpr T & get(FixedList< T, N > &list) noexcept
Definition: FixedList.H:887
A class for handling words, derived from Foam::string.
Definition: word.H:63
regionFaModel(const fvMesh &mesh, const word &regionType, const word &modelName, const dictionary &dict, bool readFields=true)
Construct from mesh and name and dict.
virtual void write(Ostream &os, const bool withTitle=true) const
Print error message.
Definition: error.C:495
dictionary coeffs_
Model coefficients dictionary.
Reading is optional [identical to LAZY_READ].
virtual scalar CourantNumber() const
Courant number of the region.
Report an I/O error.
Definition: error.H:405
virtual void preEvolveRegion()
Pre-evolve region.
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:713
const word & constant() const noexcept
Return constant name.
Definition: TimePathsI.H:131
int debug
Static debugging option.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:498
fileName relativeName(const bool caseTag=false) const
The dictionary name relative to the case.
Definition: dictionary.C:179
const fvMesh & primaryMesh_
Reference to the primary mesh database.
virtual void write(Ostream &os, const bool withTitle=true) const
Print error message.
Definition: IOerror.C:253
messageStream Warning
Warning stream (stdout output on master, null elsewhere), with additional &#39;FOAM Warning&#39; header text...
decomposeUsingBbs false
Use bounding boxes (default) or unique decomposition of triangles (i.e. do not duplicate triangles) ...
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
static const word regionFaModelName
Default name regionFaModel.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Nothing to be read.
virtual void evolveRegion()
Evolve the region.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual void evolve()
Main driver routing to evolve the region - calls other evolves.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:76
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:489
word suffixHint_
Suffix hint for automatic model variable names (default: "")
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:188
Request registration (bool: true)
defineTypeNameAndDebug(KirchhoffShell, 0)
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Namespace for OpenFOAM.
const dictionary * findDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary pointer if present (and it is a dictionary) otherwise return nullptr...
Definition: dictionaryI.H:124
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...