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 -------------------------------------------------------------------------------
11 License
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 
33 namespace Foam
34 {
35 
36 #ifdef FULLDEBUG
37 
38 template<template<class> class Field, class Type1, class Type2>
39 void checkFields
40 (
41  const FieldField<Field, Type1>& f1,
42  const FieldField<Field, Type2>& f2,
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 
58 template<template<class> class Field, class Type1, class Type2, class Type3>
59 void checkFields
60 (
61  const FieldField<Field, Type1>& f1,
62  const FieldField<Field, Type2>& f2,
63  const FieldField<Field, Type3>& f3,
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
77  << abort(FatalError);
78  }
79 }
80 
81 #else
82 
83 template<template<class> class Field, class Type1, class Type2>
84 void checkFields
85 (
86  const FieldField<Field, Type1>&,
88  const char* op
89 )
90 {}
91 
92 template<template<class> class Field, class Type1, class Type2, class Type3>
93 void checkFields
94 (
95  const FieldField<Field, Type1>&,
96  const FieldField<Field, Type2>&,
97  const FieldField<Field, Type3>&,
98  const char* op
99 )
100 {}
102 #endif
103 
104 
105 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
106 
107 template<template<class> class Field, class Type>
109 :
110  PtrList<Field<Type>>()
111 {}
112 
113 
114 template<template<class> class Field, class Type>
115 FieldField<Field, Type>::FieldField(const label size)
116 :
117  PtrList<Field<Type>>(size)
118 {}
119 
120 
121 template<template<class> class Field, class Type>
123 (
124  const word& type,
126 )
127 :
128  PtrList<Field<Type>>(ff.size())
129 {
130  forAll(*this, i)
131  {
132  set(i, Field<Type>::New(type, ff[i]));
133  }
134 }
135 
136 
137 template<template<class> class Field, class Type>
139 :
140  PtrList<Field<Type>>(ff)
141 {}
142 
143 
144 template<template<class> class Field, class Type>
146 :
147  PtrList<Field<Type>>(std::move(ff))
148 {}
149 
150 
151 template<template<class> class Field, class Type>
153 :
154  PtrList<Field<Type>>(ff, reuse)
155 {}
156 
157 
158 template<template<class> class Field, class Type>
160 :
161  PtrList<Field<Type>>(list)
162 {}
163 
164 
165 template<template<class> class Field, class Type>
167 :
168  PtrList<Field<Type>>(std::move(list))
169 {}
170 
171 
172 template<template<class> class Field, class Type>
174 :
175  PtrList<Field<Type>>(tf.constCast(), tf.movable())
176 {
177  tf.clear();
178 }
179 
180 
181 template<template<class> class Field, class Type>
183 :
184  PtrList<Field<Type>>(is)
185 {}
186 
187 
188 template<template<class> class Field, class Type>
190 {
192 }
193 
194 
195 template<template<class> class Field, class Type>
196 template<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  }
211 
212  return tresult;
213 }
214 
215 
216 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
217 
218 template<template<class> class Field, class Type>
220 {
221  forAll(*this, i)
222  {
223  this->operator[](i).negate();
224  }
225 }
226 
227 
228 template<template<class> class Field, class Type>
229 void FieldField<Field, Type>::normalise()
230 {
231  forAll(*this, i)
232  {
233  this->operator[](i).normalise();
234  }
235 }
236 
237 
238 template<template<class> class Field, class Type>
239 tmp<FieldField<Field, typename FieldField<Field, Type>::cmptType>>
241 (
242  const direction d
243 ) const
244 {
245  auto tres =
246  FieldField
247  <
248  Field, typename FieldField<Field, Type>::cmptType
249  >::NewCalculatedType(*this);
250 
251  ::Foam::component(tres.ref(), *this, d);
253  return tres;
254 }
255 
256 
257 template<template<class> class Field, class Type>
259 (
260  const direction d,
262 )
263 {
264  forAll(*this, i)
265  {
266  this->operator[](i).replace(d, sf[i]);
267  }
268 }
269 
270 
271 template<template<class> class Field, class Type>
272 void FieldField<Field, Type>::replace
273 (
274  const direction d,
275  const cmptType& s
276 )
277 {
278  forAll(*this, i)
279  {
280  this->operator[](i).replace(d, s);
281  }
282 }
283 
284 
285 template<template<class> class Field, class Type>
287 (
288  const Type& lower
289 )
290 {
291  for (auto& ff : *this)
292  {
293  ff.clamp_min(lower);
294  }
295 }
296 
297 
298 template<template<class> class Field, class Type>
299 void FieldField<Field, Type>::clamp_max
300 (
301  const Type& upper
302 )
303 {
304  for (auto& ff : *this)
305  {
306  ff.clamp_max(upper);
307  }
308 }
309 
310 
311 template<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)
320  {
321  (*this)[i].clamp_min(lower[i]);
322  }
323 }
324 
325 
326 template<template<class> class Field, class Type>
327 void FieldField<Field, Type>::clamp_max
328 (
329  const FieldField<Field, Type>& upper
330 )
331 {
332  const label loopLen = this->size();
333 
334  for (label i = 0; i < loopLen; ++i)
335  {
336  (*this)[i].clamp_max(upper[i]);
337  }
338 }
339 
340 
341 template<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)
351  {
352  ff.clamp_range(lower, upper);
353  }
354 }
355 
356 
357 template<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)
366  {
367  ff.clamp_range(range.min(), range.max());
368  }
369 }
370 
371 
372 template<template<class> class Field, class Type>
373 tmp<FieldField<Field, Type>> FieldField<Field, Type>::T() const
374 {
375  auto tres
376  (
377  FieldField<Field, Type>::NewCalculatedType(*this)
378  );
379 
380  ::Foam::T(tres.ref(), *this);
381  return tres;
382 }
383 
384 
385 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
386 
387 template<template<class> class Field, class Type>
388 const Type& FieldField<Field, Type>::operator[](const labelPair& index) const
389 {
390  return this->operator[](index.first())[index.second()];
391 }
392 
393 
394 template<template<class> class Field, class Type>
396 {
397  return this->operator[](index.first())[index.second()];
398 }
399 
400 
401 template<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)
412  {
413  this->operator[](i) = ff[i];
414  }
415 }
416 
417 
418 template<template<class> class Field, class Type>
419 void 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 
430 template<template<class> class Field, class Type>
431 void FieldField<Field, Type>::operator=(const tmp<FieldField>& tf)
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 
439  PtrList<Field<Type>>::clear();
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();
445  PtrList<Field<Type>>::transfer(*tptr);
446  delete tptr;
447 }
448 
449 
450 template<template<class> class Field, class Type>
451 void FieldField<Field, Type>::operator=(const Type& val)
452 {
453  forAll(*this, i)
454  {
455  this->operator[](i) = val;
456  }
457 }
458 
459 
460 template<template<class> class Field, class Type>
461 void FieldField<Field, Type>::operator=(Foam::zero)
462 {
463  forAll(*this, i)
464  {
465  this->operator[](i) = Foam::zero{};
466  }
467 }
468 
469 
470 #define COMPUTED_ASSIGNMENT(TYPE, op) \
471  \
472 template<template<class> class Field, class Type> \
473 void 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  \
481 template<template<class> class Field, class Type> \
482 void FieldField<Field, Type>::operator op \
483 ( \
484  const tmp<FieldField<Field, TYPE>>& tf \
485 ) \
486 { \
487  operator op(tf()); \
488  tf.clear(); \
489 } \
490  \
491 template<template<class> class Field, class Type> \
492 void FieldField<Field, Type>::operator op(const TYPE& t) \
493 { \
494  forAll(*this, i) \
495  { \
496  this->operator[](i) op t; \
497  } \
498 }
499 
500 COMPUTED_ASSIGNMENT(Type, +=)
501 COMPUTED_ASSIGNMENT(Type, -=)
502 COMPUTED_ASSIGNMENT(scalar, *=)
503 COMPUTED_ASSIGNMENT(scalar, /=)
505 #undef COMPUTED_ASSIGNMENT
506 
507 
508 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
509 
510 template<template<class> class Field, class Type>
511 Ostream& operator<<(Ostream& os, const FieldField<Field, Type>& f)
512 {
513  os << static_cast<const PtrList<Field<Type>>&>(f);
514  return os;
515 }
516 
517 
518 template<template<class> class Field, class Type>
519 Ostream& 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 // ************************************************************************* //
rho clamp_range(rhoMin[i], rhoMax[i])
const T & first() const noexcept
Access the first element.
Definition: Pair.H:137
type
Types of root.
Definition: Roots.H:52
uint8_t direction
Definition: direction.H:46
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define COMPUTED_ASSIGNMENT(TYPE, op)
Definition: FieldField.C:463
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
Y [inertIndex] clamp_min(0)
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:529
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.
scalar range
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:51
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:801
Generic templated field type.
Definition: Field.H:63
void checkFields(const FieldField< Field, Type1 > &, const FieldField< Field, Type2 > &, const char *op)
Definition: FieldField.C:78
A class for handling words, derived from Foam::string.
Definition: word.H:63
void negate(DimensionedField< Type, GeoMesh > &result, const DimensionedField< Type, GeoMesh > &f1)
errorManip< error > abort(error &err)
Definition: errorManip.H:139
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: scalarImpl.H:255
OBJstream os(runTime.globalPath()/outputName)
labelList f(nPoints)
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
const volScalarField & T
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:54
surface1 clear()
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
constexpr FieldField() noexcept
Construct null.
Definition: FieldField.C:101
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
void clear() const noexcept
If object pointer points to valid object: delete object and set pointer to nullptr.
Definition: tmpI.H:289
A class for managing temporary objects.
Definition: HashPtrTable.H:50
const T & second() const noexcept
Access the second element.
Definition: Pair.H:147
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))
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
const FieldField< fvPatchField, Type > & ff(const FieldField< fvPatchField, Type > &bf)
Namespace for OpenFOAM.