FunctionalGeometricField.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 
28 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
29 
30 template<class Type, class GeoMesh>
32 {
33  forAll(this->mesh().boundary(), patchi)
34  {
35  if (!this->mesh().boundary()[patchi].constraint())
36  {
37  patchFieldPtrs_.set
38  (
39  patchi,
40  new SlicedDimensionedField<Type, GeoPatch>
41  (
42  IOobject
43  (
44  this->name(),
45  this->mesh().time().name(),
46  this->mesh().db(),
47  IOobject::NO_READ,
48  IOobject::NO_WRITE,
49  false
50  ),
51  this->mesh().boundary()[patchi],
52  this->dimensions(),
53  this->boundaryFieldRef()[patchi]
54  )
55  );
56  }
57  }
58 }
59 
60 
61 template<class Type, class GeoMesh>
63 (
64  const dictionary& dict
65 )
66 {
67  if (!dict.isDict(funcName_)) return false;
68 
69  internalFuncPtr_.set
70  (
71  DimensionedFieldFunction<DimensionedField<Type, GeoMesh>>::New
72  (
73  dict.subDict(funcName_),
74  this->internalFieldRef()
75  ).ptr()
76  );
77 
78  setPatchFields();
79 
80  forAll(this->mesh().boundary(), patchi)
81  {
82  if (!this->mesh().boundary()[patchi].constraint())
83  {
84  patchFuncPtrs_.set
85  (
86  patchi,
87  DimensionedFieldFunction<DimensionedField<Type, GeoPatch>>::New
88  (
89  dict.subDict(funcName_),
90  patchFieldPtrs_[patchi]
91  ).ptr()
92  );
93  }
94  }
95 
96  return true;
97 }
98 
99 
100 template<class Type, class GeoMesh>
102 (
103  const FunctionalGeometricField<Type, GeoMesh>& udff
104 )
105 {
106  if (!udff.internalFuncPtr_.valid()) return;
107 
108  internalFuncPtr_.set
109  (
110  udff.internalFuncPtr_.clone
111  (
112  this->internalFieldRef()
113  ).ptr()
114  );
115 
116  setPatchFields();
117 
118  forAll(this->mesh().boundary(), patchi)
119  {
120  if (!this->mesh().boundary()[patchi].constraint())
121  {
122  patchFuncPtrs_.set
123  (
124  patchi,
125  udff.boundaryFuncPtrs_[patchi].clone
126  (
127  patchFieldPtrs_[patchi]
128  ).ptr()
129  );
130  }
131  }
132 }
133 
134 
135 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
136 
137 template<class Type, class GeoMesh>
139 (
140  const word& name,
141  const word& funcName,
142  const GeoMesh& mesh,
143  const dimensionSet& dimensions,
144  const dictionary& dict
145 )
146 :
147  GeometricField<Type, GeoMesh>
148  (
149  IOobject
150  (
151  name,
152  mesh.time().name(),
153  mesh.db(),
154  IOobject::NO_READ,
155  IOobject::NO_WRITE,
156  false
157  ),
158  mesh,
159  dimensions,
160  GeometricField<Type, GeoMesh>::Patch::calculatedType()
161  ),
162  funcName_(funcName),
163  internalFuncPtr_(),
164  patchFieldPtrs_(mesh.boundary().size()),
165  patchFuncPtrs_(mesh.boundary().size()),
166  defaultValue_
167  (
168  readFuncs(dict)
169  ? pTraits<Type>::nan
170  : dimensioned<Type>(funcName, dimensions, dict).value()
171  )
172 {
173  if (internalFuncPtr_.valid())
174  {
175  if (mesh.time().completeCase())
176  {
177  internalFuncPtr_->evaluate();
178 
179  forAll(this->mesh().boundary(), patchi)
180  {
181  if (!this->mesh().boundary()[patchi].constraint())
182  {
183  patchFuncPtrs_[patchi].evaluate();
184  }
185  }
186 
188  }
189  }
190  else
191  {
192  *this == dimensioned<Type>(dimensions, defaultValue_);
193  }
194 }
195 
196 
197 template<class Type, class GeoMesh>
199 (
200  const word& name,
201  const word& funcName,
202  const GeoMesh& mesh,
203  const dimensionSet& dimensions,
204  const dictionary& dict,
205  const Type& defaultValue
206 )
207 :
208  GeometricField<Type, GeoMesh>
209  (
210  IOobject
211  (
212  name,
213  mesh.time().name(),
214  mesh.db(),
215  IOobject::NO_READ,
216  IOobject::NO_WRITE,
217  false
218  ),
219  mesh,
220  dimensions,
221  defaultValue
222  ),
223  funcName_(funcName),
224  internalFuncPtr_(),
225  patchFieldPtrs_(mesh.boundary().size()),
226  patchFuncPtrs_(mesh.boundary().size()),
227  defaultValue_
228  (
229  readFuncs(dict)
230  ? pTraits<Type>::nan
231  : dict.found(funcName)
232  ? dimensioned<Type>(funcName, dimensions, dict).value()
233  : defaultValue_
234  )
235 {
236  if (internalFuncPtr_.valid())
237  {
238  if (mesh.time().completeCase())
239  {
240  internalFuncPtr_->evaluate();
241 
242  forAll(this->mesh().boundary(), patchi)
243  {
244  if (!this->mesh().boundary()[patchi].constraint())
245  {
246  patchFuncPtrs_[patchi].evaluate();
247  }
248  }
249 
251  }
252  }
253  else
254  {
255  *this == dimensioned<Type>(dimensions, defaultValue_);
256  }
257 }
258 
259 
260 template<class Type, class GeoMesh>
262 (
264  const GeoMesh& mesh
265 )
266 :
267  GeometricField<Type, GeoMesh>(udff, mesh, udff.dimensions()),
268  funcName_(udff.funcName_),
269  internalFuncPtr_(),
270  patchFieldPtrs_(mesh.boundary().size()),
271  patchFuncPtrs_(mesh.boundary().size()),
272  defaultValue_(udff.defaultValue_)
273 {
274  cloneFuncs(udff);
275 }
276 
277 
278 template<class Type, class GeoMesh>
280 (
282 )
283 :
284  GeometricField<Type, GeoMesh>(udff),
285  funcName_(udff.funcName_),
286  internalFuncPtr_(),
287  patchFieldPtrs_(this->mesh().boundary().size()),
288  patchFuncPtrs_(this->mesh().boundary().size()),
289  defaultValue_(udff.defaultValue_)
290 {
291  cloneFuncs(udff);
292 }
293 
294 
295 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
296 
297 template<class Type, class GeoMesh>
299 {
301  (
303  (
304  static_cast<IOobject>(*this),
305  this->mesh(),
306  dimensioned<Type>("NaN", this->dimensions(), pTraits<Type>::nan)
307  )
308  );
309 
310  setPatchFields();
311 
312  if (internalFuncPtr_.valid())
313  {
314  internalFuncPtr_->reset();
315 
316  forAll(this->mesh().boundary(), patchi)
317  {
318  if (!this->mesh().boundary()[patchi].constraint())
319  {
320  patchFuncPtrs_[patchi].reset();
321  }
322  }
323 
325  }
326  else
327  {
328  *this == dimensioned<Type>(this->dimensions(), defaultValue_);
329  }
330 }
331 
332 
333 template<class Type, class GeoMesh>
335 {
336  if (internalFuncPtr_.valid())
337  {
338  bool result = false;
339 
340  result = internalFuncPtr_->update() || result;
341 
342  forAll(this->mesh().boundary(), patchi)
343  {
344  if (!this->mesh().boundary()[patchi].constraint())
345  {
346  result = patchFuncPtrs_[patchi].update() || result;
347  }
348  }
349 
350  if (result) this->correctBoundaryConditions();
351 
352  return result;
353  }
354  else
355  {
356  return false;
357  }
358 }
359 
360 
361 template<class Type, class GeoMesh>
363 {
364  if (internalFuncPtr_.valid())
365  {
366  internalFuncPtr_->write(os);
367  }
368 }
369 
370 
371 template<class Type, class GeoMesh>
373 (
374  Ostream& os,
376 )
377 {
378  if (udff.internalFuncPtr_.valid())
379  {
380  writeEntry(os, udff.funcName_, udff.internalFuncPtr_());
381  }
382  else
383  {
384  writeEntry(os, udff.funcName_, udff.defaultValue_);
385  }
386 }
387 
388 
389 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
const dimensionSet & dimensions() const
Return dimensions.
const GeoMesh & mesh() const
Return mesh.
GeometricField with a corresponding run-time selected function to evaluate and update the field.
virtual bool write(const bool write=true) const
Write using setting from DB.
FunctionalGeometricField(const word &name, const word &funcName, const GeoMesh &, const dimensionSet &dimensions, const dictionary &)
Construct from name, mesh, dimensions, field and dictionary.
Generic GeometricField class.
void reset(const GeometricField< Type, GeoMesh, PrimitiveField2 > &)
Reset the field contents to the given field.
void correctBoundaryConditions()
Correct boundary field.
GeoMesh::template PatchField< Type > Patch
Type of the patch field of which the Boundary is composed.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Dimension set for the base types.
Definition: dimensionSet.H:125
Generic dimensioned Type class.
Traits class for primitives.
Definition: pTraits.H:53
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
label patchi
U correctBoundaryConditions()
const dimensionSet time
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
void writeEntry(Ostream &os, const word &key, const DimensionedFieldFunction< DimensionedFieldType > &f)
faceListList boundary(nPatches)
dictionary dict