LagrangianPatchField.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 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 "LagrangianPatch.H"
27 #include "LagrangianPatchField.H"
28 #include "LagrangianMesh.H"
29 #include "LagrangianSubFields.H"
30 #include "dictionary.H"
31 
32 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
33 
34 template<class Type>
36 (
37  const LagrangianPatch& p,
38  const regIOobject& iIo
39 )
40 :
41  patch_(p),
42  internalIo_(iIo),
43  internalField_
44  (
46  ),
47  internalNonDynamicField_
48  (
49  refCastNull<const LagrangianInternalField<Type>>(iIo)
50  )
51 {}
52 
53 
54 template<class Type>
56 (
57  const LagrangianPatch& p,
58  const regIOobject& iIo,
59  const dictionary&
60 )
61 :
62  patch_(p),
63  internalIo_(iIo),
64  internalField_
65  (
67  ),
68  internalNonDynamicField_
69  (
70  refCastNull<const LagrangianInternalField<Type>>(iIo)
71  )
72 {}
73 
74 
75 template<class Type>
77 (
79 )
80 :
81  patch_(ptf.patch_),
82  internalIo_(ptf.internalIo_),
83  internalField_(ptf.internalField_),
84  internalNonDynamicField_(ptf.internalNonDynamicField_)
85 {}
86 
87 
88 template<class Type>
90 (
91  const LagrangianPatchField<Type>& ptf,
92  const regIOobject& iIo
93 )
94 :
95  patch_(ptf.patch_),
96  internalIo_(iIo),
97  internalField_
98  (
100  ),
101  internalNonDynamicField_
102  (
103  refCastNull<const LagrangianInternalField<Type>>(iIo)
104  )
105 {}
106 
107 
108 template<class Type>
110 (
111  const LagrangianPatchField<Type>& ptf,
112  const LagrangianPatch& p,
113  const regIOobject& iIo
114 )
115 :
116  patch_(p),
117  internalIo_(iIo),
118  internalField_
119  (
121  ),
122  internalNonDynamicField_
123  (
124  refCastNull<const LagrangianInternalField<Type>>(iIo)
125  )
126 {}
127 
128 
129 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
130 
131 template<class Type>
134 (
135  const word& patchFieldType,
136  const word& actualPatchType,
137  const LagrangianPatch& p,
138  const regIOobject& iIo
139 )
140 {
141  if (debug)
142  {
143  InfoInFunction << "Constructing LagrangianPatchField<Type>" << endl;
144  }
145 
146  typename LagrangianPatchConstructorTable::iterator cstrIter =
147  LagrangianPatchConstructorTablePtr_->find(patchFieldType);
148 
149  if (cstrIter == LagrangianPatchConstructorTablePtr_->end())
150  {
152  << "Unknown patchField type "
153  << patchFieldType << nl << nl
154  << "Valid patchField types are :" << endl
155  << LagrangianPatchConstructorTablePtr_->sortedToc()
156  << exit(FatalError);
157  }
158 
159  if
160  (
161  actualPatchType == word::null
162  || actualPatchType != p.type()
163  )
164  {
165  typename LagrangianPatchConstructorTable::iterator patchTypeCstrIter =
166  LagrangianPatchConstructorTablePtr_->find(p.type());
167 
168  if (patchTypeCstrIter != LagrangianPatchConstructorTablePtr_->end())
169  {
170  return patchTypeCstrIter()(p, iIo);
171  }
172  else
173  {
174  return cstrIter()(p, iIo);
175  }
176  }
177  else
178  {
179  return cstrIter()(p, iIo);
180  }
181 }
182 
183 
184 template<class Type>
187 (
188  const word& patchFieldType,
189  const LagrangianPatch& p,
190  const regIOobject& iIo
191 )
192 {
193  return New(patchFieldType, word::null, p, iIo);
194 }
195 
196 
197 template<class Type>
200 (
201  const LagrangianPatch& p,
202  const regIOobject& iIo,
203  const dictionary& dict
204 )
205 {
206  if (debug)
207  {
208  InfoInFunction << "Constructing fvsPatchField<Type>" << endl;
209  }
210 
211  const word patchFieldType(dict.lookup("type"));
212 
213  typename dictionaryConstructorTable::iterator cstrIter
214  = dictionaryConstructorTablePtr_->find(patchFieldType);
215 
216  if (cstrIter == dictionaryConstructorTablePtr_->end())
217  {
218  if (!disallowGenericLagrangianPatchField)
219  {
220  cstrIter = dictionaryConstructorTablePtr_->find("generic");
221  }
222 
223  if (cstrIter == dictionaryConstructorTablePtr_->end())
224  {
226  << "Unknown patchField type " << patchFieldType
227  << " for patch type " << p.type() << nl << nl
228  << "Valid patchField types are :" << endl
229  << dictionaryConstructorTablePtr_->sortedToc()
230  << exit(FatalIOError);
231  }
232  }
233 
234  if
235  (
236  !dict.found("patchType")
237  || word(dict.lookup("patchType")) != p.type()
238  )
239  {
240  typename dictionaryConstructorTable::iterator patchTypeCstrIter
241  = dictionaryConstructorTablePtr_->find(p.type());
242 
243  if
244  (
245  patchTypeCstrIter != dictionaryConstructorTablePtr_->end()
246  && patchTypeCstrIter() != cstrIter()
247  )
248  {
250  (
251  dict
252  ) << "inconsistent patch and patchField types for \n"
253  " patch type " << p.type()
254  << " and patchField type " << patchFieldType
255  << exit(FatalIOError);
256  }
257  }
258 
259  return cstrIter()(p, iIo, dict);
260 }
261 
262 
263 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
264 
265 template<class Type>
267 {}
268 
269 
270 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
271 
272 template<class Type>
274 {
275  return patch_.boundaryMesh().mesh();
276 }
277 
278 
279 template<class Type>
281 {
282  return patch_;
283 }
284 
285 
286 template<class Type>
287 const Foam::dimensionSet&
289 {
290  if (notNull(internalField_))
291  {
292  return internalField_.dimensions();
293  }
294 
295  if (notNull(internalNonDynamicField_))
296  {
297  return internalNonDynamicField_.dimensions();
298  }
299 
301  << "Dimensions of internal object " << internalIo_.name()
302  << " could not be determined"
303  << exit(FatalError);
304 
305  return NullObjectRef<dimensionSet>();
306 }
307 
308 
309 template<class Type>
312 {
313  if (notNull(internalField_))
314  {
315  return internalField_;
316  }
317 
319  << "Internal field " << internalIo_.name() << " is not of type "
321  << exit(FatalError);
322 
323  return NullObjectRef<LagrangianInternalDynamicField<Type>>();
324 }
325 
326 
327 template<class Type>
330 {
331  if (notNull(internalField_))
332  {
333  return patch_.mesh().sub(internalField_);
334  }
335 
336  if (notNull(internalNonDynamicField_))
337  {
338  return patch_.mesh().sub(internalNonDynamicField_);
339  }
340 
342  << "Internal field " << internalIo_.name() << " is not of type "
344  << exit(FatalError);
345 
346  return tmp<LagrangianSubSubField<Type>>(nullptr);
347 }
348 
349 
350 template<class Type>
352 {
353  if (notNull(internalField_))
354  {
355  return patch_.mesh().sub(internalField_.primitiveField());
356  }
357 
358  if (notNull(internalNonDynamicField_))
359  {
360  return patch_.mesh().sub(internalNonDynamicField_.primitiveField());
361  }
362 
364  << "Internal field " << internalIo_.name() << " is not of type "
366  << exit(FatalError);
367 
368  return SubField<Type>(NullObjectRef<UList<Type>>(), 0, 0);
369 }
370 
371 
372 template<class Type>
374 {}
375 
376 
377 template<class Type>
379 (
382 )
383 {}
384 
385 
386 template<class Type>
388 (
391 )
392 {}
393 
394 
395 template<class Type>
397 {
398  writeEntry(os, "type", type());
399 }
400 
401 
402 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
403 
404 template<class Type>
407 {
408  return internalSubField();
409 }
410 
411 
412 #define MEMBER_OPERATOR(MemberOp, FieldOp, OtherType, OtherDimensions) \
413  \
414 template<class Type> \
415 void Foam::LagrangianPatchField<Type>::operator MemberOp \
416 ( \
417  const LagrangianPatchField<OtherType>& ptf \
418 ) \
419 { \
420  if (&patch_ != &(ptf.patch_)) \
421  { \
422  FatalErrorInFunction \
423  << "different patches for LagrangianPatchField<Type>s" \
424  << abort(FatalError); \
425  } \
426  \
427  if (!patch_.boundaryMesh().mesh().changing()) return; \
428  \
429  OtherDimensions == ptf.internalDimensions(); \
430  \
431  LagrangianSubSubField<Type> thisSsf(internalSubField()); \
432  thisSsf FieldOp ptf.internalSubField(); \
433 } \
434  \
435 template<class Type> \
436 void Foam::LagrangianPatchField<Type>::operator MemberOp \
437 ( \
438  const LagrangianSubField<OtherType>& sf \
439 ) \
440 { \
441  if (!patch_.boundaryMesh().mesh().changing()) return; \
442  \
443  OtherDimensions == sf.dimensions(); \
444  \
445  SubField<Type> thisSf(primitiveSubField()); \
446  thisSf FieldOp sf.primitiveField(); \
447 } \
448  \
449 template<class Type> \
450 void Foam::LagrangianPatchField<Type>::operator MemberOp \
451 ( \
452  const LagrangianSubSubField<OtherType>& ssf \
453 ) \
454 { \
455  if (!patch_.boundaryMesh().mesh().changing()) return; \
456  \
457  OtherDimensions == ssf.dimensions(); \
458  \
459  SubField<Type> thisSf(primitiveSubField()); \
460  thisSf FieldOp ssf.primitiveField(); \
461 } \
462  \
463 template<class Type> \
464 void Foam::LagrangianPatchField<Type>::operator MemberOp \
465 ( \
466  const UList<OtherType>& f \
467 ) \
468 { \
469  if (!patch_.boundaryMesh().mesh().changing()) return; \
470  \
471  SubField<Type> thisSf(primitiveSubField()); \
472  thisSf FieldOp f; \
473 } \
474  \
475 template<class Type> \
476 void Foam::LagrangianPatchField<Type>::operator MemberOp(const OtherType& t) \
477 { \
478  if (!patch_.boundaryMesh().mesh().changing()) return; \
479  \
480  SubField<Type> thisSf(primitiveSubField()); \
481  thisSf FieldOp t; \
482 }
483 
484 MEMBER_OPERATOR(=, =, Type, internalDimensions());
485 MEMBER_OPERATOR(==, =, Type, internalDimensions());
486 MEMBER_OPERATOR(+=, +=, Type, internalDimensions());
487 MEMBER_OPERATOR(-=, -=, Type, internalDimensions());
488 MEMBER_OPERATOR(*=, *=, scalar, dimless);
489 MEMBER_OPERATOR(/=, /=, scalar, dimless);
490 
491 #undef MEMBER_OPERATOR
492 
493 
494 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
495 
496 template<class Type>
497 Foam::Ostream& Foam::operator<<
498 (
499  Ostream& os,
500  const LagrangianPatchField<Type>& ptf
501 )
502 {
503  ptf.write(os);
504 
505  os.check
506  (
507  "Ostream& operator<<(Ostream&, const LagrangianPatchField<Type>&)"
508  );
509 
510  return os;
511 }
512 
513 
514 // ************************************************************************* //
#define MEMBER_OPERATOR(MemberOp, FieldOp, OtherType, OtherDimensions)
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:92
Base class for Lagrangian boundary conditions.
virtual ~LagrangianPatchField()
Destructor.
static autoPtr< LagrangianPatchField< Type > > New(const word &patchFieldType, const word &actualPatchType, const LagrangianPatch &p, const regIOobject &)
Return a pointer to a new LagrangianPatchField with a given type.
const dimensionSet & internalDimensions() const
Return internal dimensions reference.
tmp< LagrangianSubSubField< Type > > operator()() const
Generate a sub-sub field corresponding to this patch.
virtual void write(Ostream &) const
Write.
virtual void reset(const LagrangianPatchField< Type > &)
Reset to the given LagrangianPatchField.
const LagrangianPatch & patch() const
Return patch.
const objectRegistry & db() const
Return local objectRegistry.
virtual void initEvaluate(PstreamBuffers &, const LagrangianScalarInternalDynamicField &fraction)
Initialise evaluation of the patch field.
friend class LagrangianPatchField
Declare friendship with patch fields of different types.
tmp< LagrangianSubSubField< Type > > internalSubField() const
Generate an internal sub field corresponding to this patch.
SubField< Type > primitiveSubField() const
Generate a primitive sub field corresponding to this patch.
const LagrangianInternalDynamicField< Type > & internalField() const
Return internal field reference.
virtual void evaluate(PstreamBuffers &, const LagrangianScalarInternalDynamicField &fraction)
Evaluate the patch field.
Base class for Lagrangian patches.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
virtual Ostream & write(const char)=0
Write character.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Pre-declare related SubField type.
Definition: SubField.H:63
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:740
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:539
Dimension set for the base types.
Definition: dimensionSet.H:125
Registry of regIOobjects.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:55
A class for managing temporary objects.
Definition: tmp.H:55
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
#define InfoInFunction
Report an information message using Foam::Info.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
To & refCastNull(From &r)
Reference type cast template function,.
Definition: typeInfo.H:155
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
const dimensionSet dimless
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:64
const T & NullObjectRef()
Return const reference to the nullObject of type T.
Definition: nullObjectI.H:27
word patchFieldType(const PatchField &pf)
IOerror FatalIOError
error FatalError
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
static const char nl
Definition: Ostream.H:267
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
dictionary dict
volScalarField & p