CarrierField.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) 2025-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 
26 #include "CarrierField.H"
27 #include "carried.H"
28 #include "volFields.H"
29 
30 /*---------------------------------------------------------------------------*\
31  Class CloudDerivedField::Functor Declaration
32 \*---------------------------------------------------------------------------*/
33 
34 template<class Type>
36 {
37 public:
38 
39  // Constructors
40 
41  //- Construct null
43  {}
44 
45 
46  //- Destructor
47  virtual ~Functor()
48  {}
49 
50 
51  // Member Operators
52 
53  //- Evaluate the field
54  virtual tmp<VolField<Type>> operator()() const = 0;
55 };
56 
57 
58 /*---------------------------------------------------------------------------*\
59  Class CloudDerivedField::Function Declaration
60 \*---------------------------------------------------------------------------*/
61 
62 template<class Type>
63 template<class F>
65 :
66  public Functor
67 {
68  // Private Data
69 
70  //- The name
71  const word& name_;
72 
73  //- The function
74  F f_;
75 
76 
77 public:
78 
79  // Constructors
80 
81  //- Construct from a name and a function
82  Function(const word& name, const F& f)
83  :
84  Functor(),
85  name_(name),
86  f_(f)
87  {}
88 
89 
90  //- Destructor
91  virtual ~Function()
92  {}
93 
94 
95  // Member Operators
96 
97  //- Evaluate the field
98  virtual tmp<VolField<Type>> operator()() const
99  {
100  tmp<VolField<Type>> tpsi = f_();
101  return tpsi.isTmp() ? VolField<Type>::New(name_, tpsi()) : tpsi;
102  }
103 };
104 
105 
106 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
107 
108 template<class Type>
111 (
112  const LagrangianModelRef&,
113  const LagrangianSubMesh& subMesh
114 ) const
115 {
116  const LagrangianMesh& mesh = subMesh.mesh();
117 
118  tmp<Field<Type>> tpsic =
119  psiInterpolation(mesh).interpolate
120  (
121  subMesh.sub(mesh.coordinates()),
122  subMesh.sub(mesh.celli()),
123  subMesh.sub(mesh.facei()),
124  subMesh.sub(mesh.faceTrii())
125  );
126 
127  // If using old-time values, interpolate them also, and combine with the
128  // current-time values using the current tracking fraction
129  if (useOldTime(mesh))
130  {
131  tmp<Field<Type>> tpsi0c =
132  psi0Interpolation(mesh).interpolate
133  (
134  subMesh.sub(mesh.coordinates()),
135  subMesh.sub(mesh.celli()),
136  subMesh.sub(mesh.facei()),
137  subMesh.sub(mesh.faceTrii())
138  );
139 
140  const SubField<scalar> fraction =
141  subMesh.sub
142  (
144  (
145  LagrangianMesh::fractionName
146  ).primitiveField()
147  );
148 
149  tpsic = (1 - fraction)*tpsi0c + fraction*tpsic;
150  }
151 
152  // Build the dimensioned field and return
153  return tmp<LagrangianSubField<Type>>
154  (
155  new LagrangianSubField<Type>
156  (
157  IOobject
158  (
159  subMesh.sub(this->name_),
160  mesh.time().name(),
161  mesh,
162  IOobject::NO_READ,
163  IOobject::NO_WRITE,
164  false
165  ),
166  subMesh,
167  psi().dimensions(),
168  tpsic
169  )
170  );
171 }
172 
173 
174 template<class Type>
175 Foam::tmp
176 <
178  <
179  typename Foam::CarrierFieldGradBase<Type>::GradType
180  >
181 >
183 (
184  const LagrangianModelRef&,
185  const LagrangianSubMesh& subMesh
186 ) const
187 {
188  const LagrangianMesh& mesh = subMesh.mesh();
189 
190  // Interpolate the values
191  tmp<Field<GradType>> tpsic =
192  this->psiInterpolation(mesh).interpolateGrad
193  (
194  subMesh.sub(mesh.coordinates()),
195  subMesh.sub(mesh.celli()),
196  subMesh.sub(mesh.facei()),
197  subMesh.sub(mesh.faceTrii())
198  );
199 
200  // If using old-time values, interpolate them also, and combine with the
201  // current-time values using the current tracking fraction
202  if (this->useOldTime(mesh))
203  {
204  tmp<Field<GradType>> tpsi0c =
205  this->psi0Interpolation(mesh).interpolateGrad
206  (
207  subMesh.sub(mesh.coordinates()),
208  subMesh.sub(mesh.celli()),
209  subMesh.sub(mesh.facei()),
210  subMesh.sub(mesh.faceTrii())
211  );
212 
213  const SubField<scalar> fraction =
214  subMesh.sub
215  (
216  mesh
217  .lookupObject<LagrangianInternalScalarDynamicField>
218  (
219  LagrangianMesh::fractionName
220  ).primitiveField()
221  );
222 
223  tpsic = (1 - fraction)*tpsi0c + fraction*tpsic;
224  }
225 
226  // Build the dimensioned field and return
227  return tmp<LagrangianSubField<GradType>>
228  (
229  new LagrangianSubField<GradType>
230  (
231  IOobject
232  (
233  subMesh.sub("grad(" + this->name_ + ')'),
234  mesh.time().name(),
235  mesh,
236  IOobject::NO_READ,
237  IOobject::NO_WRITE,
238  false
239  ),
240  subMesh,
241  this->psi().dimensions()/dimLength,
242  tpsic
243  )
244  );
245 }
246 
247 
248 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
249 
250 template<class Type>
252 {
253  return
254  psi().hasStoredOldTimes()
255  && psi().nOldTimes(false)
257  (
258  LagrangianMesh::fractionName
259  );
260 }
261 
262 
263 template<class Type>
265 (
266  const LagrangianMesh& mesh
267 ) const
268 {
269  if (!psiInterpolationPtr_.valid())
270  {
271  psiInterpolationPtr_ =
273  (
274  word(mesh.schemes().interpolation(this->name_)),
275  psi()
276  );
277  }
278 
279  return psiInterpolationPtr_();
280 }
281 
282 
283 template<class Type>
285 (
286  const LagrangianMesh& mesh
287 ) const
288 {
289  if (!psi0InterpolationPtr_.valid())
290  {
291  psi0InterpolationPtr_ =
293  (
294  word(mesh.schemes().interpolation(this->name_)),
295  psi().oldTime()
296  );
297  }
298 
299  return psi0InterpolationPtr_();
300 }
301 
302 
303 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
304 
305 template<class Type>
307 :
308  CloudDerivedField<Type>
309  (
310  clouds::carried::nameToCarrierName(psi.name()),
311  *this,
313  ),
314  functorPtr_(nullptr),
315  tpsi_(psi),
316  psiInterpolationPtr_(nullptr),
317  psi0InterpolationPtr_(nullptr)
318 {}
319 
320 
321 template<class Type>
323 (
324  const word& name,
325  const VolField<Type>& psi
326 )
327 :
329  functorPtr_(nullptr),
330  tpsi_(psi),
331  psiInterpolationPtr_(nullptr),
332  psi0InterpolationPtr_(nullptr)
333 {}
334 
335 
336 template<class Type>
337 template<class F>
339 :
341  functorPtr_(new Function<F>(this->name_, f)),
342  tpsi_(nullptr),
343  psiInterpolationPtr_(nullptr),
344  psi0InterpolationPtr_(nullptr)
345 {}
346 
347 
348 template<class Type>
349 template<class ... Args>
351 :
352  CarrierFieldBase<Type>(args ...),
353  grad(*this, &CarrierFieldGradBase::interpolateGrad)
354 {}
355 
356 
357 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
358 
359 template<class Type>
361 {
362  if (!tpsi_.valid())
363  {
364  tpsi_ = functorPtr_->operator()();
365  }
366 
367  return tpsi_();
368 }
369 
370 
371 template<class Type>
372 void Foam::CarrierFieldBase<Type>::reset(const bool initial)
373 {
375 
376  if (tpsi_.valid() && tpsi_.isTmp())
377  {
378  if (initial)
379  {
380  tpsi_.ref().nullOldestTime();
381  }
382  else
383  {
384  tpsi_.ref().oldTime();
385  tpsi_.ref() = functorPtr_->operator()();
386  }
387  }
388 
389  psiInterpolationPtr_.clear();
390  psi0InterpolationPtr_.clear();
391 }
392 
393 
394 template<class Type>
396 {
398 
399  grad.clear(true);
400 }
401 
402 
403 // ************************************************************************* //
Class to store an evaluation function.
Definition: CarrierField.C:67
Function(const word &name, const F &f)
Construct from a name and a function.
Definition: CarrierField.C:82
virtual tmp< VolField< Type > > operator()() const
Evaluate the field.
Definition: CarrierField.C:98
virtual ~Function()
Destructor.
Definition: CarrierField.C:91
virtual ~Functor()
Destructor.
Definition: CarrierField.C:47
virtual tmp< VolField< Type > > operator()() const =0
Evaluate the field.
const VolField< Type > & psi() const
Access the carrier field.
Definition: CarrierField.C:360
bool useOldTime(const LagrangianMesh &) const
Return whether or not to interpolate in time as well as space.
Definition: CarrierField.C:251
const interpolation< Type > & psi0Interpolation(const LagrangianMesh &) const
Return the old-time interpolation engine.
Definition: CarrierField.C:285
void reset(const bool initial)
Reset.
Definition: CarrierField.C:372
CarrierFieldBase(const VolField< Type > &)
Construct from a reference to a carrier field.
Definition: CarrierField.C:306
const interpolation< Type > & psiInterpolation(const LagrangianMesh &) const
Return the interpolation engine.
Definition: CarrierField.C:265
void reset(const bool initial)
Reset.
Definition: CarrierField.C:395
CarrierFieldGradBase(const Args &... args)
Construct from arguments passed to the base class.
Definition: CarrierField.C:350
A field derived from other state fields of the cloud. Stores and virtualises a function or a method w...
void clear(const bool final)
Clear.
const word & name() const
Field name.
const word name_
The name. May be word::null, in which case the name is.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
const PrimitiveField< Type > & primitiveField() const
Return a const-reference to the primitive field.
Generic GeometricField class.
static tmp< GeometricField< Type, GeoMesh, PrimitiveField > > New(const word &name, const Internal &, const PtrList< Patch > &, const HashPtrTable< Source > &=HashPtrTable< Source >())
Return a temporary field constructed from name,.
Class containing Lagrangian geometry and topology.
Simple wrapper to provide an optional reference to a Lagrangian model.
Mesh that relates to a sub-section of a Lagrangian mesh. This is used to construct fields that relate...
const LagrangianMesh & mesh() const
Return the mesh.
word sub(const word &fieldName) const
Return the name of a field corresponding to this sub-mesh.
Pre-declare related SubField type.
Definition: SubField.H:63
const word & name() const
Return const reference to name.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:433
const fvSchemes & schemes() const
Return the fvSchemes.
Definition: fvMesh.C:1792
ITstream & interpolation(const word &name) const
Definition: fvSchemes.C:399
Abstract base class for interpolation.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type and name.
bool foundObject(const word &name) const
Is the named Type in registry.
A class for managing temporary objects.
Definition: tmp.H:55
bool isTmp() const
Return true if this is really a temporary object.
Definition: tmpI.H:169
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)
const volScalarField & psi
const dimensionedScalar F
Faraday constant: default SI units: [C/mol].
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
tmp< VolField< typename outerProduct< vector, Type >::type > > grad(const SurfaceField< Type > &ssf)
Definition: fvcGrad.C:46
const unitSet fraction
const dimensionSet & dimLength
Definition: dimensions.C:141
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)
labelList f(nPoints)
Foam::argList args(argc, argv)