CloudDerivedField.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 "CloudDerivedField.H"
28 #include "Time.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
54  virtual tmp<LagrangianSubField<Type>> operator()
55  (
56  const LagrangianModelRef& model,
57  const LagrangianSubMesh& subMesh
58  ) const = 0;
59 };
60 
61 
62 /*---------------------------------------------------------------------------*\
63  Class CloudDerivedField::Function Declaration
64 \*---------------------------------------------------------------------------*/
65 
66 template<class Type>
67 template<class F>
69 :
70  public Functor
71 {
72  // Private Data
73 
74  //- The function
75  F f_;
76 
77 
78 public:
79 
80  // Constructors
81 
82  //- Construct from a function
83  Function(const F& f)
84  :
85  Functor(),
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<LagrangianSubField<Type>> operator()
99  (
100  const LagrangianModelRef& model,
101  const LagrangianSubMesh& subMesh
102  ) const
103  {
104  return f_(model, subMesh);
105  }
106 };
107 
108 
109 /*---------------------------------------------------------------------------*\
110  Class CloudDerivedField::Method Declaration
111 \*---------------------------------------------------------------------------*/
112 
113 template<class Type>
114 template<class C>
116 :
117  public Functor
118 {
119  // Private Data
120 
121  //- The class
122  const C& c_;
123 
124  //- The method
126  (
127  const LagrangianModelRef&,
129  ) const;
130 
131 
132 public:
133 
134  // Constructors
135 
136  //- Construct from a class and a method
138  (
139  const C& c,
141  (
142  const LagrangianModelRef&,
143  const LagrangianSubMesh&
144  ) const
145  )
146  :
147  Functor(),
148  c_(c),
149  m_(m)
150  {}
151 
152 
153  //- Destructor
154  virtual ~Method()
155  {}
156 
157 
158  // Member Operators
159 
160  //- Evaluate the field
161  virtual tmp<LagrangianSubField<Type>> operator()
162  (
163  const LagrangianModelRef& model,
164  const LagrangianSubMesh& subMesh
165  ) const
166  {
167  return (c_.*m_)(model, subMesh);
168  }
169 };
170 
171 
172 /*---------------------------------------------------------------------------*\
173  Class CloudDerivedField::AllFieldToField Declaration
174 \*---------------------------------------------------------------------------*/
175 
176 template<class Type>
178 :
179  public LagrangianInternalField<Type>
180 {
181 public:
182 
183  // Constructors
184 
185  //- Construct from a sub-all-field reference
187  :
189  (
190  IOobject
191  (
192  allField.name(),
193  allField.mesh().mesh().time().name(),
194  allField.mesh().mesh(),
195  IOobject::NO_READ,
196  IOobject::NO_WRITE,
197  false
198  ),
199  allField.mesh().mesh(),
200  allField.dimensions(),
201  NullObjectRef<Field<Type>>()
202  )
203  {
204  this->UList<Type>::shallowCopy(allField);
205  }
206 
207 
208  //- Destructor
210  {
211  this->UList<Type>::shallowCopy(UList<Type>(nullptr, 0));
212  }
213 };
214 
215 
216 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
217 
218 template<class Type>
219 template<class F>
221 :
222  name_(name),
223  functorPtr_(new Function<F>(f))
224 {}
225 
226 
227 template<class Type>
228 template<class F>
230 :
231  name_(word::null),
232  functorPtr_(new Function<F>(f))
233 {}
234 
235 
236 template<class Type>
237 template<class C>
239 (
240  const word& name,
241  const C& c,
243  (
244  const LagrangianModelRef&,
245  const LagrangianSubMesh&
246  ) const
247 )
248 :
249  name_(name),
250  functorPtr_(new Method<C>(c, m))
251 {}
252 
253 
254 template<class Type>
255 template<class C>
257 (
258  const C& c,
260  (
261  const LagrangianModelRef&,
262  const LagrangianSubMesh&
263  ) const
264 )
265 :
266  name_(word::null),
267  functorPtr_(new Method<C>(c, m))
268 {}
269 
270 
271 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
272 
273 template<class Type>
275 {
276  if (name_ == word::null)
277  {
278  FatalErrorInFunction << "Name requested for un-named derived field ";
279 
280  if (psiAllPtr_.valid())
281  {
282  FatalError << psiAllPtr_->name();
283  }
284  else if (psiSubPtr_.valid())
285  {
286  FatalError << psiSubPtr_->mesh().complete(psiSubPtr_->name());
287  }
288  else if (psiSubSubPtr_.valid())
289  {
290  FatalError << psiSubSubPtr_->mesh().complete(psiSubSubPtr_->name());
291  }
292 
294  }
295 
296  return name_;
297 }
298 
299 
300 template<class Type>
303 {
304  const LagrangianSubField<Type>& allField =
305  operator()(LagrangianModelRef(), mesh.subAll());
306 
309  (
310  allField.name(),
311  mesh,
312  allField.dimensions()
313  );
314 
315  tResult.ref().primitiveFieldRef() = allField.primitiveField();
316 
317  return tResult;
318 }
319 
320 
321 template<class Type>
323 (
324  const LagrangianSubMesh& subMesh
325 ) const
326 {
327  // Error if this is the all-mesh
328  if (&subMesh == &subMesh.mesh().subAll())
329  {
331  << "Non-constant access is not provided to the all-mesh sub-field"
332  << exit(FatalError);
333  }
334 
335  // Evaluate and store if it doesn't already exist for the sub-mesh
336  if (!psiSubSubPtr_.valid() || psiSubSubMeshIndex_ != subMesh.index())
337  {
338  psiSubSubPtr_.reset
339  (
340  new LagrangianSubSubField<Type>(operator()(subMesh))
341  );
342 
343  psiSubSubUpToDate_ = true;
344  psiSubSubMeshIndex_ = subMesh.index();
345  }
346 
347  // Update the field in-place if the up-to-date flag is not set
348  if (!psiSubSubUpToDate_)
349  {
350  psiSubSubPtr_->UList<Type>::shallowCopy(operator()(subMesh));
351 
352  psiSubSubUpToDate_ = true;
353  }
354 
355  return psiSubSubPtr_();
356 }
357 
358 
359 template<class Type>
361 {
362  psiAllPtr_.clear();
363 
364  // If this is not the final iteration, then retain the fields to be
365  // modified in-place. This is more efficient, and it ensures that old-time
366  // fields are maintained.
367  if (!final)
368  {
369  psiSubUpToDate_ = false;
370  psiSubSubUpToDate_ = false;
371  }
372  else
373  {
374  psiSubPtr_.clear();
375  psiSubSubPtr_.clear();
376  }
377 }
378 
379 
380 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
381 
382 template<class Type>
385 {
386  return
388  (
389  new AllFieldToField
390  (
391  operator()(LagrangianModelRef(), mesh.subAll())
392  ),
393  true
394  );
395 }
396 
397 
398 template<class Type>
401 (
402  const LagrangianSubMesh& subMesh
403 ) const
404 {
405  return operator()(LagrangianModelRef(), subMesh);
406 }
407 
408 
409 template<class Type>
412 (
413  const LagrangianModelRef& model,
414  const LagrangianSubMesh& subMesh
415 ) const
416 {
417  // Evaluate and store if it doesn't already exist for the all-mesh
418  if (&subMesh == &subMesh.mesh().subAll())
419  {
420  if (!psiAllPtr_.valid())
421  {
422  if (name_ != word::null)
423  {
425  functorPtr_()(model, subMesh);
426 
427  const IOobject io
428  (
429  name_,
430  tf().instance(),
431  tf().local(),
432  tf().db(),
435  false
436  );
437 
438  psiAllPtr_.reset(new Foam::LagrangianSubField<Type>(io, tf));
439  }
440  else
441  {
442  psiAllPtr_.reset(functorPtr_()(model, subMesh).ptr());
443  }
444  }
445 
446  return psiAllPtr_();
447  }
448 
449  // Evaluate and store if it doesn't already exist for the sub-mesh
450  if (!psiSubPtr_.valid() || psiSubMeshIndex_ != subMesh.index())
451  {
452  if (name_ != word::null)
453  {
455  functorPtr_()(model, subMesh);
456 
457  const IOobject io
458  (
459  subMesh.sub(name_),
460  tf().instance(),
461  tf().local(),
462  tf().db(),
465  false
466  );
467 
468  psiSubPtr_.reset(new Foam::LagrangianSubField<Type>(io, tf));
469  }
470  else
471  {
472  psiSubPtr_.reset(functorPtr_()(model, subMesh).ptr());
473  }
474 
475  psiSubUpToDate_ = true;
476  psiSubMeshIndex_ = subMesh.index();
477  }
478 
479  // Update the field in-place if the up-to-date flag is not set
480  if (!psiSubUpToDate_)
481  {
482  psiSubPtr_() = functorPtr_()(model, subMesh);
483 
484  psiSubUpToDate_ = true;
485  }
486 
487  return psiSubPtr_();
488 }
489 
490 
491 // ************************************************************************* //
Graphite solid properties.
Definition: C.H:51
AllFieldToField(const LagrangianSubField< Type > &allField)
Construct from a sub-all-field reference.
Class to store an evaluation function.
Function(const F &f)
Construct from a function.
Class to store an evaluation method.
Method(const C &c, tmp< LagrangianSubField< Type >>(C::*m)(const LagrangianModelRef &, const LagrangianSubMesh &) const)
Construct from a class and a method.
A field derived from other state fields of the cloud. Stores and virtualises a function or a method w...
tmp< LagrangianInternalField< Type > > operator()(const LagrangianMesh &mesh) const
Compute and return the entire field. This will be a slice of the.
CloudDerivedField(const word &name, const F &f)
Construct from a name and a function.
void clear(const bool final)
Clear.
LagrangianSubSubField< Type > & ref(const LagrangianSubMesh &) const
Access a part of the field.
const word & name() const
Field name.
tmp< LagrangianInternalField< Type > > field(const LagrangianMesh &mesh) const
Compute and return an independent copy of the entire field.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
static tmp< DimensionedField< Type, GeoMesh, PrimitiveField > > New(const word &name, const GeoMesh &mesh, const dimensionSet &, const PrimitiveField< Type > &)
Return a temporary field constructed from name, mesh,.
const dimensionSet & dimensions() const
Return dimensions.
const PrimitiveField< Type > & primitiveField() const
Return a const-reference to the primitive field.
Pre-declare SubField and related Field type.
Definition: Field.H:83
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const word & name() const
Return name.
Definition: IOobject.H:307
Class containing Lagrangian geometry and topology.
const LagrangianSubMesh & subAll() const
Return a sub-mesh for all elements.
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...
uint64_t index() const
Return the index.
const LagrangianMesh & mesh() const
Return the mesh.
void shallowCopy(const UList< T > &)
Copy the pointer held by the given UList.
Definition: UListI.H:156
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
A class for handling words, derived from string.
Definition: word.H:63
static const word null
An empty word.
Definition: word.H:78
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
const tensorField & tf
const dimensionedScalar F
Faraday constant: default SI units: [C/mol].
const dimensionedScalar c
Speed of light in a vacuum.
const dimensionSet time
static const coefficient C("C", dimTemperature, 234.5)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
const T & NullObjectRef()
Return const reference to the nullObject of type T.
Definition: nullObjectI.H:27
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError
labelList f(nPoints)