Loading...
Searching...
No Matches
FieldField.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2019-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "FieldField.H"
30
31// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32
33namespace Foam
34{
35
36#ifdef FULLDEBUG
37
38template<template<class> class Field, class Type1, class Type2>
39void checkFields
40(
43 const char* op
44)
45{
46 if (f1.size() != f2.size())
47 {
49 << " FieldField<" << pTraits<Type1>::typeName
50 << "> f1(" << f1.size() << ')'
51 << " and FieldField<" << pTraits<Type2>::typeName
52 << "> f2(" << f2.size() << ')'
53 << endl << " for operation " << op
54 << abort(FatalError);
55 }
56}
57
58template<template<class> class Field, class Type1, class Type2, class Type3>
59void checkFields
60(
64 const char* op
65)
66{
67 if (f1.size() != f2.size() || f1.size() != f3.size())
68 {
70 << " FieldField<" << pTraits<Type1>::typeName
71 << "> f1(" << f1.size() << ')'
72 << ", FieldField<" <<pTraits<Type2>::typeName
73 << "> f2(" << f2.size() << ')'
74 << " and FieldField<"<<pTraits<Type3>::typeName
75 << "> f3("<<f3.size() << ')'
76 << endl << " for operation " << op
78 }
79}
80
81#else
82
83template<template<class> class Field, class Type1, class Type2>
84void checkFields
85(
88 const char* op
89)
90{}
91
92template<template<class> class Field, class Type1, class Type2, class Type3>
94(
98 const char* op
99)
100{}
102#endif
103
104
105// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
106
107template<template<class> class Field, class Type>
109:
110 PtrList<Field<Type>>()
111{}
112
113
114template<template<class> class Field, class Type>
116:
117 PtrList<Field<Type>>(size)
118{}
119
120
121template<template<class> class Field, class Type>
123(
124 const word& type,
126)
127:
128 PtrList<Field<Type>>(ff.size())
129{
130 forAll(*this, i)
132 set(i, Field<Type>::New(type, ff[i]));
133 }
134}
135
136
137template<template<class> class Field, class Type>
142
143
144template<template<class> class Field, class Type>
146:
147 PtrList<Field<Type>>(std::move(ff))
148{}
149
150
151template<template<class> class Field, class Type>
154 PtrList<Field<Type>>(ff, reuse)
155{}
156
157
158template<template<class> class Field, class Type>
160:
161 PtrList<Field<Type>>(list)
162{}
163
165template<template<class> class Field, class Type>
167:
168 PtrList<Field<Type>>(std::move(list))
170
171
172template<template<class> class Field, class Type>
175 PtrList<Field<Type>>(tf.constCast(), tf.movable())
176{
177 tf.clear();
178}
180
181template<template<class> class Field, class Type>
186
187
188template<template<class> class Field, class Type>
192}
193
194
195template<template<class> class Field, class Type>
196template<class Type2>
198(
200)
201{
202 const label len = ff.size();
203
204 auto tresult = tmp<FieldField<Field, Type>>::New(len);
205 auto& result = tresult.ref();
206
207 for (label i=0; i<len; ++i)
208 {
209 result.set(i, Field<Type>::NewCalculatedType(ff[i]).ptr());
210 }
212 return tresult;
213}
214
215
216// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
217
218template<template<class> class Field, class Type>
220{
221 forAll(*this, i)
223 this->operator[](i).negate();
224 }
225}
226
227
228template<template<class> class Field, class Type>
230{
231 forAll(*this, i)
232 {
233 this->operator[](i).normalise();
234 }
235}
237
238template<template<class> class Field, class Type>
241(
242 const direction d
243) const
244{
245 auto tres =
247 <
249 >::NewCalculatedType(*this);
250
251 ::Foam::component(tres.ref(), *this, d);
252
253 return tres;
254}
255
256
257template<template<class> class Field, class Type>
259(
260 const direction d,
262)
263{
264 forAll(*this, i)
266 this->operator[](i).replace(d, sf[i]);
267 }
269
270
271template<template<class> class Field, class Type>
273(
274 const direction d,
275 const cmptType& s
276)
278 forAll(*this, i)
280 this->operator[](i).replace(d, s);
281 }
282}
283
284
285template<template<class> class Field, class Type>
287(
288 const Type& lower
289)
290{
291 for (auto& ff : *this)
293 ff.clamp_min(lower);
294 }
295}
296
297
298template<template<class> class Field, class Type>
300(
301 const Type& upper
302)
303{
304 for (auto& ff : *this)
306 ff.clamp_max(upper);
307 }
308}
309
310
311template<template<class> class Field, class Type>
313(
314 const FieldField<Field, Type>& lower
315)
316{
317 const label loopLen = this->size();
318
319 for (label i = 0; i < loopLen; ++i)
321 (*this)[i].clamp_min(lower[i]);
322 }
323}
324
325
326template<template<class> class Field, class Type>
328(
329 const FieldField<Field, Type>& upper
330)
331{
332 const label loopLen = this->size();
333
334 for (label i = 0; i < loopLen; ++i)
336 (*this)[i].clamp_max(upper[i]);
337 }
338}
339
340
341template<template<class> class Field, class Type>
343(
344 const Type& lower,
345 const Type& upper
346)
347{
348 // Note: no checks for bad/invalid clamping ranges
349
350 for (auto& ff : *this)
352 ff.clamp_range(lower, upper);
353 }
354}
355
356
357template<template<class> class Field, class Type>
359(
360 const MinMax<Type>& range
361)
362{
363 // Note: no checks for bad/invalid clamping ranges
364
365 for (auto& ff : *this)
367 ff.clamp_range(range.min(), range.max());
368 }
369}
370
371
372template<template<class> class Field, class Type>
373tmp<FieldField<Field, Type>> FieldField<Field, Type>::T() const
374{
375 auto tres
376 (
378 );
379
380 ::Foam::T(tres.ref(), *this);
381 return tres;
382}
383
384
385// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
386
387template<template<class> class Field, class Type>
388const Type& FieldField<Field, Type>::operator[](const labelPair& index) const
389{
390 return this->operator[](index.first())[index.second()];
391}
392
393
394template<template<class> class Field, class Type>
396{
397 return this->operator[](index.first())[index.second()];
398}
399
400
401template<template<class> class Field, class Type>
403{
404 if (this == &ff)
405 {
406 return; // Self-assignment is a no-op
407 }
408
409 // No size checking done
410
411 forAll(*this, i)
413 this->operator[](i) = ff[i];
414 }
415}
416
417
418template<template<class> class Field, class Type>
419void FieldField<Field, Type>::operator=(FieldField<Field, Type>&& ff)
420{
421 if (this == &ff)
422 {
423 return; // Self-assignment is a no-op
424 }
425
426 PtrList<Field<Type>>::transfer(ff);
427}
428
429
430template<template<class> class Field, class Type>
432{
433 // The cref() method also checks that tmp is not nullptr.
434 if (this == &(tf.cref()))
435 {
436 return; // Self-assignment is a no-op
437 }
438
440
441 // Release the tmp pointer, or clone const reference for a new pointer.
442 // Error potential when tmp is non-unique.
443
444 auto* tptr = tf.ptr();
446 delete tptr;
447}
448
449
450template<template<class> class Field, class Type>
451void FieldField<Field, Type>::operator=(const Type& val)
452{
453 for (auto& pfld : *this)
455 pfld = val;
456 }
457}
458
459
460template<template<class> class Field, class Type>
462{
463 for (auto& pfld : *this)
464 {
465 pfld = Foam::zero{};
466 }
467}
468
469
470#define COMPUTED_ASSIGNMENT(TYPE, op) \
471 \
472template<template<class> class Field, class Type> \
473void FieldField<Field, Type>::operator op(const FieldField<Field, TYPE>& f) \
474{ \
475 forAll(*this, i) \
476 { \
477 this->operator[](i) op f[i]; \
478 } \
479} \
480 \
481template<template<class> class Field, class Type> \
482void FieldField<Field, Type>::operator op \
483( \
484 const tmp<FieldField<Field, TYPE>>& tf \
485) \
486{ \
487 operator op(tf()); \
488 tf.clear(); \
489} \
490 \
491template<template<class> class Field, class Type> \
492void FieldField<Field, Type>::operator op(const TYPE& val) \
493{ \
494 for (auto& pfld : *this) \
495 { \
496 pfld op val; \
497 } \
498}
499
500COMPUTED_ASSIGNMENT(Type, +=)
501COMPUTED_ASSIGNMENT(Type, -=)
502COMPUTED_ASSIGNMENT(scalar, *=)
503COMPUTED_ASSIGNMENT(scalar, /=)
505#undef COMPUTED_ASSIGNMENT
506
507
508// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
509
510template<template<class> class Field, class Type>
514 return os;
515}
516
517
518template<template<class> class Field, class Type>
519Ostream& operator<<(Ostream& os, const tmp<FieldField<Field, Type>>& tf)
520{
521 os << tf();
522 tf.clear();
523 return os;
524}
525
526
527// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
528
529} // End namespace Foam
530
531// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
532
533#include "FieldFieldFunctions.C"
534
535// ************************************************************************* //
#define COMPUTED_ASSIGNMENT(TYPE, op)
scalar range
A field of fields is a PtrList of fields with reference counting.
Definition FieldField.H:77
tmp< FieldField< Field, Type > > T() const
Return the field transpose (only defined for second rank tensors).
Definition FieldField.C:366
constexpr FieldField() noexcept
Construct null.
Definition FieldField.C:101
void clamp_range(const Type &lower, const Type &upper)
Clamp field values (in-place) to the specified range.
Definition FieldField.C:336
tmp< FieldField< Field, Type > > clone() const
Clone.
Definition FieldField.C:182
static tmp< FieldField< Field, Type > > NewCalculatedType(const FieldField< Field, Type2 > &ff)
Return a pointer to a new calculatedFvPatchFieldField created on.
Definition FieldField.C:191
const Type & operator[](const labelPair &index) const
Const access to a single field element via (fieldi, elemi).
Definition FieldField.C:381
void clamp_min(const Type &lower)
Impose lower (floor) clamp on the field values (in-place).
Definition FieldField.C:280
void replace(const direction, const FieldField< Field, cmptType > &)
Replace a component field of the field.
Definition FieldField.C:252
pTraits< Type >::cmptType cmptType
Component type.
Definition FieldField.H:83
void operator=(const FieldField< Field, Type > &)
Copy assignment.
Definition FieldField.C:395
void negate()
Negate this field. See notes in Field.
Definition FieldField.C:212
void clamp_max(const Type &upper)
Impose upper (ceiling) clamp on the field values (in-place).
Definition FieldField.C:293
void normalise()
Normalise this field. See notes in Field.
Definition FieldField.C:222
tmp< FieldField< Field, cmptType > > component(const direction) const
Return a component field of the field.
Definition FieldField.C:234
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
static tmp< Field< Type > > NewCalculatedType(const Field< Type2 > &f)
Return a pointer to a new calculatedFvPatchFieldField created on freestore without setting patchField...
Definition Field.H:431
static autoPtr< Field< Type > > New(Istream &is)
Return a pointer to a new Field created on freestore.
Definition Field.H:421
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
void clear()
Clear the list, i.e. set size to zero.
Definition ListI.H:133
A min/max value pair with additional methods. In addition to conveniently storing values,...
Definition MinMax.H:106
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
const T & first() const noexcept
Access the first element.
Definition Pair.H:137
const T & second() const noexcept
Access the second element.
Definition Pair.H:147
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition PtrList.H:67
void transfer(PtrList< Field< Type > > &list)
Definition PtrListI.H:289
const Field< Type > * set(const label i) const
Definition PtrList.H:171
constexpr PtrList() noexcept
Definition PtrListI.H:29
label size() const noexcept
Definition UPtrListI.H:106
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
A class for managing temporary objects.
Definition tmp.H:75
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
Definition tmpI.H:221
void clear() const noexcept
If object pointer points to valid object: delete object and set pointer to nullptr.
Definition tmpI.H:289
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition tmpI.H:256
A class for handling words, derived from Foam::string.
Definition word.H:66
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
surface1 clear()
Namespace for OpenFOAM.
Pair< label > labelPair
A pair of labels.
Definition Pair.H:54
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
void checkFields(const FieldField< Field, Type1 > &, const FieldField< Field, Type2 > &, const char *op)
Definition FieldField.C:78
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces).
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
errorManip< error > abort(error &err)
Definition errorManip.H:139
uint8_t direction
Definition direction.H:49
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299