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  ),
161  funcName_(funcName),
162  internalFuncPtr_(),
163  patchFieldPtrs_(mesh.boundary().size()),
164  patchFuncPtrs_(mesh.boundary().size()),
165  defaultValue_
166  (
167  readFuncs(dict)
168  ? pTraits<Type>::nan
169  : dimensioned<Type>(funcName, dimensions, dict).value()
170  )
171 {
172  if (internalFuncPtr_.valid())
173  {
174  if (mesh.time().completeCase())
175  {
176  internalFuncPtr_->evaluate();
177 
178  forAll(this->mesh().boundary(), patchi)
179  {
180  if (!this->mesh().boundary()[patchi].constraint())
181  {
182  patchFuncPtrs_[patchi].evaluate();
183  }
184  }
185 
187  }
188  }
189  else
190  {
191  *this == dimensioned<Type>(dimensions, defaultValue_);
192  }
193 }
194 
195 
196 template<class Type, class GeoMesh>
198 (
199  const word& name,
200  const word& funcName,
201  const GeoMesh& mesh,
202  const dimensionSet& dimensions,
203  const dictionary& dict,
204  const Type& defaultValue
205 )
206 :
207  GeometricField<Type, GeoMesh>
208  (
209  IOobject
210  (
211  name,
212  mesh.time().name(),
213  mesh.db(),
214  IOobject::NO_READ,
215  IOobject::NO_WRITE,
216  false
217  ),
218  mesh,
219  dimensions,
220  defaultValue
221  ),
222  funcName_(funcName),
223  internalFuncPtr_(),
224  patchFieldPtrs_(mesh.boundary().size()),
225  patchFuncPtrs_(mesh.boundary().size()),
226  defaultValue_
227  (
228  readFuncs(dict)
229  ? pTraits<Type>::nan
230  : dict.found(funcName)
231  ? dimensioned<Type>(funcName, dimensions, dict).value()
232  : defaultValue_
233  )
234 {
235  if (internalFuncPtr_.valid())
236  {
237  if (mesh.time().completeCase())
238  {
239  internalFuncPtr_->evaluate();
240 
241  forAll(this->mesh().boundary(), patchi)
242  {
243  if (!this->mesh().boundary()[patchi].constraint())
244  {
245  patchFuncPtrs_[patchi].evaluate();
246  }
247  }
248 
250  }
251  }
252  else
253  {
254  *this == dimensioned<Type>(dimensions, defaultValue_);
255  }
256 }
257 
258 
259 template<class Type, class GeoMesh>
261 (
263  const GeoMesh& mesh
264 )
265 :
266  GeometricField<Type, GeoMesh>(udff, mesh, udff.dimensions()),
267  funcName_(udff.funcName_),
268  internalFuncPtr_(),
269  patchFieldPtrs_(mesh.boundary().size()),
270  patchFuncPtrs_(mesh.boundary().size()),
271  defaultValue_(udff.defaultValue_)
272 {
273  cloneFuncs(udff);
274 }
275 
276 
277 template<class Type, class GeoMesh>
279 (
281 )
282 :
283  GeometricField<Type, GeoMesh>(udff),
284  funcName_(udff.funcName_),
285  internalFuncPtr_(),
286  patchFieldPtrs_(this->mesh().boundary().size()),
287  patchFuncPtrs_(this->mesh().boundary().size()),
288  defaultValue_(udff.defaultValue_)
289 {
290  cloneFuncs(udff);
291 }
292 
293 
294 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
295 
296 template<class Type, class GeoMesh>
298 {
300  (
302  (
303  static_cast<IOobject>(*this),
304  this->mesh(),
305  dimensioned<Type>("NaN", this->dimensions(), pTraits<Type>::nan)
306  )
307  );
308 
309  setPatchFields();
310 
311  if (internalFuncPtr_.valid())
312  {
313  internalFuncPtr_->reset();
314 
315  forAll(this->mesh().boundary(), patchi)
316  {
317  if (!this->mesh().boundary()[patchi].constraint())
318  {
319  patchFuncPtrs_[patchi].reset();
320  }
321  }
322 
324  }
325  else
326  {
327  *this == dimensioned<Type>(this->dimensions(), defaultValue_);
328  }
329 }
330 
331 
332 template<class Type, class GeoMesh>
334 {
335  if (internalFuncPtr_.valid())
336  {
337  bool result = false;
338 
339  result = internalFuncPtr_->update() || result;
340 
341  forAll(this->mesh().boundary(), patchi)
342  {
343  if (!this->mesh().boundary()[patchi].constraint())
344  {
345  result = patchFuncPtrs_[patchi].update() || result;
346  }
347  }
348 
349  if (result) this->correctBoundaryConditions();
350 
351  return result;
352  }
353  else
354  {
355  return false;
356  }
357 }
358 
359 
360 template<class Type, class GeoMesh>
362 {
363  if (internalFuncPtr_.valid())
364  {
365  internalFuncPtr_->write(os);
366  }
367 }
368 
369 
370 template<class Type, class GeoMesh>
372 (
373  Ostream& os,
375 )
376 {
377  if (udff.internalFuncPtr_.valid())
378  {
379  writeEntry(os, udff.funcName_, udff.internalFuncPtr_());
380  }
381  else
382  {
383  writeEntry(os, udff.funcName_, udff.defaultValue_);
384  }
385 }
386 
387 
388 // ************************************************************************* //
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.
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