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-2023 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>
312 void FieldField<Field, Type>::clamp_range
313 (
314  const Type& lower,
315  const Type& upper
316 )
317 {
318  // Note: no checks for bad/invalid clamping ranges
319 
320  for (auto& ff : *this)
321  {
322  ff.clamp_range(lower, upper);
323  }
324 }
325 
326 
327 template<template<class> class Field, class Type>
328 void FieldField<Field, Type>::clamp_range
329 (
330  const MinMax<Type>& range
331 )
332 {
333  // Note: no checks for bad/invalid clamping ranges
334 
335  for (auto& ff : *this)
336  {
337  ff.clamp_range(range.min(), range.max());
338  }
339 }
340 
341 
342 template<template<class> class Field, class Type>
343 tmp<FieldField<Field, Type>> FieldField<Field, Type>::T() const
344 {
345  auto tres
346  (
347  FieldField<Field, Type>::NewCalculatedType(*this)
348  );
349 
350  ::Foam::T(tres.ref(), *this);
351  return tres;
352 }
353 
354 
355 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
356 
357 template<template<class> class Field, class Type>
358 const Type& FieldField<Field, Type>::operator[](const labelPair& index) const
359 {
360  return this->operator[](index.first())[index.second()];
361 }
362 
363 
364 template<template<class> class Field, class Type>
366 {
367  return this->operator[](index.first())[index.second()];
368 }
369 
370 
371 template<template<class> class Field, class Type>
373 {
374  if (this == &ff)
375  {
376  return; // Self-assignment is a no-op
377  }
378 
379  // No size checking done
380 
381  forAll(*this, i)
382  {
383  this->operator[](i) = ff[i];
384  }
385 }
386 
387 
388 template<template<class> class Field, class Type>
389 void FieldField<Field, Type>::operator=(FieldField<Field, Type>&& ff)
390 {
391  if (this == &ff)
392  {
393  return; // Self-assignment is a no-op
394  }
395 
396  PtrList<Field<Type>>::transfer(ff);
397 }
398 
399 
400 template<template<class> class Field, class Type>
401 void FieldField<Field, Type>::operator=(const tmp<FieldField>& tf)
402 {
403  // The cref() method also checks that tmp is not nullptr.
404  if (this == &(tf.cref()))
405  {
406  return; // Self-assignment is a no-op
407  }
408 
409  PtrList<Field<Type>>::clear();
410 
411  // Release the tmp pointer, or clone const reference for a new pointer.
412  // Error potential when tmp is non-unique.
413 
414  auto* tptr = tf.ptr();
415  PtrList<Field<Type>>::transfer(*tptr);
416  delete tptr;
417 }
418 
419 
420 template<template<class> class Field, class Type>
421 void FieldField<Field, Type>::operator=(const Type& val)
422 {
423  forAll(*this, i)
424  {
425  this->operator[](i) = val;
426  }
427 }
428 
429 
430 template<template<class> class Field, class Type>
431 void FieldField<Field, Type>::operator=(const Foam::zero)
432 {
433  forAll(*this, i)
434  {
435  this->operator[](i) = Foam::zero{};
436  }
437 }
438 
439 
440 #define COMPUTED_ASSIGNMENT(TYPE, op) \
441  \
442 template<template<class> class Field, class Type> \
443 void FieldField<Field, Type>::operator op(const FieldField<Field, TYPE>& f) \
444 { \
445  forAll(*this, i) \
446  { \
447  this->operator[](i) op f[i]; \
448  } \
449 } \
450  \
451 template<template<class> class Field, class Type> \
452 void FieldField<Field, Type>::operator op \
453 ( \
454  const tmp<FieldField<Field, TYPE>>& tf \
455 ) \
456 { \
457  operator op(tf()); \
458  tf.clear(); \
459 } \
460  \
461 template<template<class> class Field, class Type> \
462 void FieldField<Field, Type>::operator op(const TYPE& t) \
463 { \
464  forAll(*this, i) \
465  { \
466  this->operator[](i) op t; \
467  } \
468 }
469 
470 COMPUTED_ASSIGNMENT(Type, +=)
471 COMPUTED_ASSIGNMENT(Type, -=)
472 COMPUTED_ASSIGNMENT(scalar, *=)
473 COMPUTED_ASSIGNMENT(scalar, /=)
475 #undef COMPUTED_ASSIGNMENT
476 
477 
478 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
479 
480 template<template<class> class Field, class Type>
481 Ostream& operator<<(Ostream& os, const FieldField<Field, Type>& f)
482 {
483  os << static_cast<const PtrList<Field<Type>>&>(f);
484  return os;
485 }
486 
487 
488 template<template<class> class Field, class Type>
489 Ostream& operator<<(Ostream& os, const tmp<FieldField<Field, Type>>& tf)
490 {
491  os << tf();
492  tf.clear();
493  return os;
494 }
495 
496 
497 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
498 
499 } // End namespace Foam
500 
501 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
502 
503 #include "FieldFieldFunctions.C"
504 
505 // ************************************************************************* //
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:433
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
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:531
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.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1187
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:421
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
Generic templated field type.
Definition: Field.H:62
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
patchWriters clear()
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: Scalar.H:258
OBJstream os(runTime.globalPath()/outputName)
labelList f(nPoints)
const volScalarField & T
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Definition: stringOps.C:1171
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
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.