Field.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) 2011-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 "Field.H"
27 #include "FieldM.H"
28 #include "unitConversions.H"
29 #include "dictionary.H"
30 #include "contiguous.H"
31 
32 // * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
33 
34 template<class Type>
35 const char* const Foam::Field<Type>::typeName("Field");
36 
37 
38 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
39 
40 template<class Type>
42 :
43  List<Type>()
44 {}
45 
46 
47 template<class Type>
49 :
50  List<Type>(size)
51 {}
52 
53 
54 template<class Type>
55 Foam::Field<Type>::Field(const label size, const Type& t)
56 :
57  List<Type>(size, t)
58 {}
59 
60 
61 template<class Type>
63 :
64  List<Type>(size, Zero)
65 {}
66 
67 
68 template<class Type>
70 :
71  List<Type>(list)
72 {}
73 
74 
75 template<class Type>
77 :
78  List<Type>(move(f))
79 {}
80 
81 
82 template<class Type>
84 :
85  List<Type>(list)
86 {}
87 
88 
89 template<class Type>
91 :
92  tmp<Field<Type>>::refCount(),
93  List<Type>(f)
94 {}
95 
96 
97 template<class Type>
99 :
100  List<Type>(f, reuse)
101 {}
102 
103 
104 template<class Type>
106 :
107  tmp<Field<Type>>::refCount(),
108  List<Type>(move(f))
109 {}
110 
111 
112 template<class Type>
114 :
115  List<Type>(const_cast<Field<Type>&>(tf()), tf.isTmp())
116 {
117  tf.clear();
118 }
119 
120 
121 template<class Type>
123 (
124  const UList<Type>& mapF,
125  const labelUList& mapAddressing
126 )
127 :
128  List<Type>(mapAddressing.size())
129 {
130  map(mapF, mapAddressing);
131 }
132 
133 
134 template<class Type>
136 (
137  const tmp<Field<Type>>& tmapF,
138  const labelUList& mapAddressing
139 )
140 :
141  List<Type>(mapAddressing.size())
142 {
143  map(tmapF, mapAddressing);
144 }
145 
146 
147 template<class Type>
149 (
150  const UList<Type>& mapF,
151  const labelListList& mapAddressing,
152  const scalarListList& mapWeights
153 )
154 :
155  List<Type>(mapAddressing.size())
156 {
157  map(mapF, mapAddressing, mapWeights);
158 }
159 
160 
161 template<class Type>
163 (
164  const tmp<Field<Type>>& tmapF,
165  const labelListList& mapAddressing,
166  const scalarListList& mapWeights
167 )
168 :
169  List<Type>(mapAddressing.size())
170 {
171  map(tmapF, mapAddressing, mapWeights);
172 }
173 
174 
175 template<class Type>
177 :
178  List<Type>(is)
179 {}
180 
181 
182 template<class Type>
184 (
185  const word& keyword,
186  const dictionary& dict,
187  const label s
188 )
189 :
190  Field<Type>(keyword, unitAny, dict, s)
191 {}
192 
193 
194 template<class Type>
196 (
197  const word& keyword,
198  const unitConversion& defaultUnits,
199  const dictionary& dict,
200  const label s
201 )
202 {
203  if (s)
204  {
205  ITstream& is = dict.lookup(keyword);
206 
207  // Read first token
208  token firstToken(is);
209 
210  // Read the units if they are before the values
211  unitConversion units(defaultUnits);
212  const bool haveUnits = units.readIfPresent(keyword, dict, is);
213 
214  // Read the values
215  if (firstToken.isWord())
216  {
217  if (firstToken.wordToken() == "uniform")
218  {
219  this->setSize(s);
220 
221  operator=(pTraits<Type>(is));
222  }
223  else if (firstToken.wordToken() == "nonuniform")
224  {
225  is >> static_cast<List<Type>&>(*this);
226 
227  if (this->size() != s)
228  {
230  << "size " << this->size()
231  << " is not equal to the given value of " << s
232  << exit(FatalIOError);
233  }
234  }
235  else
236  {
238  << "expected keyword 'uniform' or 'nonuniform', found "
239  << firstToken.wordToken()
240  << exit(FatalIOError);
241  }
242  }
243  else
244  {
246  << "expected keyword 'uniform' or 'nonuniform', found "
247  << firstToken.info()
248  << exit(FatalIOError);
249  }
250 
251  // Read the units if they are after the value
252  if (!haveUnits && !is.eof())
253  {
254  units.readIfPresent(keyword, dict, is);
255  }
256 
257  // Modify the values by the unit conversion
258  units.makeStandard(*this);
259  }
260 }
261 
262 
263 template<class Type>
265 {
266  return tmp<Field<Type>>(new Field<Type>(*this));
267 }
268 
269 
270 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
271 
272 template<class Type>
274 (
275  const UList<Type>& mapF,
276  tmp<Field<Type>>& tmapF
277 ) const
278 {
279  if (static_cast<const UList<Type>*>(this) == &mapF)
280  {
281  tmapF = clone();
282  }
283  return tmapF.valid() ? tmapF() : mapF;
284 }
285 
286 
287 template<class Type>
289 (
290  const UList<Type>& mapF0,
291  const labelUList& mapAddressing
292 )
293 {
294  Field<Type>& f = *this;
295 
296  tmp<Field<Type>> tmapF;
297  const UList<Type>& mapF = copySelf(mapF0, tmapF);
298 
299  if (f.size() != mapAddressing.size())
300  {
301  f.setSize(mapAddressing.size());
302  }
303 
304  if (mapF.size() > 0)
305  {
306  forAll(f, i)
307  {
308  const label mapi = mapAddressing[i];
309 
310  if (mapi >= 0)
311  {
312  f[i] = mapF[mapi];
313  }
314  }
315  }
316 }
317 
318 
319 template<class Type>
321 (
322  const tmp<Field<Type>>& tmapF,
323  const labelUList& mapAddressing
324 )
325 {
326  map(tmapF(), mapAddressing);
327  tmapF.clear();
328 }
329 
330 
331 template<class Type>
333 (
334  const UList<Type>& mapF0,
335  const labelListList& mapAddressing,
336  const scalarListList& mapWeights
337 )
338 {
339  if (mapWeights.size() != mapAddressing.size())
340  {
342  << mapWeights.size() << " map size: " << mapAddressing.size()
343  << abort(FatalError);
344  }
345 
346  Field<Type>& f = *this;
347 
348  tmp<Field<Type>> tmapF;
349  const UList<Type>& mapF = copySelf(mapF0, tmapF);
350 
351  if (this->size() != mapAddressing.size())
352  {
353  this->setSize(mapAddressing.size());
354  }
355 
356  forAll(f, i)
357  {
358  const labelList& localAddrs = mapAddressing[i];
359  const scalarList& localWeights = mapWeights[i];
360 
361  f[i] = Zero;
362 
363  forAll(localAddrs, j)
364  {
365  f[i] += localWeights[j]*mapF[localAddrs[j]];
366  }
367  }
368 }
369 
370 
371 template<class Type>
373 (
374  const tmp<Field<Type>>& tmapF,
375  const labelListList& mapAddressing,
376  const scalarListList& mapWeights
377 )
378 {
379  map(tmapF(), mapAddressing, mapWeights);
380  tmapF.clear();
381 }
382 
383 
384 template<class Type>
386 (
387  const UList<Type>& mapF0,
388  const labelUList& mapAddressing
389 )
390 {
391  Field<Type>& f = *this;
392 
393  tmp<Field<Type>> tmapF;
394  const UList<Type>& mapF = copySelf(mapF0, tmapF);
395 
396  forAll(mapF, i)
397  {
398  const label mapi = mapAddressing[i];
399 
400  if (mapi >= 0)
401  {
402  f[mapi] = mapF[i];
403  }
404  }
405 }
406 
407 
408 template<class Type>
410 (
411  const tmp<Field<Type>>& tmapF,
412  const labelUList& mapAddressing
413 )
414 {
415  rmap(tmapF(), mapAddressing);
416  tmapF.clear();
417 }
418 
419 
420 template<class Type>
422 (
423  const UList<Type>& mapF0,
424  const labelUList& mapAddressing,
425  const UList<scalar>& mapWeights
426 )
427 {
428  Field<Type>& f = *this;
429 
430  tmp<Field<Type>> tmapF;
431  const UList<Type>& mapF = copySelf(mapF0, tmapF);
432 
433  f = Zero;
434 
435  forAll(mapF, i)
436  {
437  f[mapAddressing[i]] += mapF[i]*mapWeights[i];
438  }
439 }
440 
441 
442 template<class Type>
444 (
445  const tmp<Field<Type>>& tmapF,
446  const labelUList& mapAddressing,
447  const UList<scalar>& mapWeights
448 )
449 {
450  rmap(tmapF(), mapAddressing, mapWeights);
451  tmapF.clear();
452 }
453 
454 
455 template<class Type>
457 {
458  if (this == &rhs)
459  {
461  << "attempted assignment to self"
462  << abort(FatalError);
463  }
464 
466 }
467 
468 
469 template<class Type>
471 {
473 }
474 
475 
476 template<class Type>
478 {
479  TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
480 }
481 
482 
483 template<class Type>
486 (
487  const direction d
488 ) const
489 {
490  tmp<Field<cmptType>> Component(new Field<cmptType>(this->size()));
491  ::Foam::component(Component.ref(), *this, d);
492  return Component;
493 }
494 
495 
496 template<class Type>
498 (
499  const direction d,
500  const UList<cmptType>& sf
501 )
502 {
503  TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
504  cmptType, sf)
505 }
506 
507 
508 template<class Type>
510 (
511  const direction d,
512  const tmp<Field<cmptType>>& tsf
513 )
514 {
515  replace(d, tsf());
516  tsf.clear();
517 }
518 
519 
520 template<class Type>
522 (
523  const direction d,
524  const cmptType& c
525 )
526 {
527  TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
528  cmptType, c)
529 }
530 
531 
532 template<class Type>
533 template<class VSForm>
534 VSForm Foam::Field<Type>::block(const label start) const
535 {
536  VSForm vs;
537  for (direction i=0; i<VSForm::nComponents; i++)
538  {
539  vs[i] = this->operator[](start + i);
540  }
541  return vs;
542 }
543 
544 
545 template<class Type>
547 {
548  tmp<Field<Type>> transpose(new Field<Type>(this->size()));
549  ::Foam::T(transpose.ref(), *this);
550  return transpose;
551 }
552 
553 
554 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
555 
556 template<class Type>
558 {
559  if (this == &rhs)
560  {
562  << "attempted assignment to self"
563  << abort(FatalError);
564  }
565 
567 }
568 
569 
570 template<class Type>
572 {
573  if (this == &rhs)
574  {
576  << "attempted assignment to self"
577  << abort(FatalError);
578  }
579 
580  List<Type>::operator=(move(rhs));
581 }
582 
583 
584 template<class Type>
586 {
588 }
589 
590 
591 template<class Type>
593 {
594  List<Type>::operator=(move(rhs));
595 }
596 
597 
598 template<class Type>
600 {
601  if (this == &(rhs()))
602  {
604  << "attempted assignment to self"
605  << abort(FatalError);
606  }
607 
608  List<Type>::operator=(rhs());
609 }
610 
611 
612 template<class Type>
613 void Foam::Field<Type>::operator=(const Type& t)
614 {
616 }
617 
618 
619 template<class Type>
621 {
623 }
624 
625 
626 template<class Type>
627 template<class Form, class Cmpt, Foam::direction nCmpt>
629 {
630  TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
631 }
632 
633 
634 #define COMPUTED_ASSIGNMENT(TYPE, op) \
635  \
636 template<class Type> \
637 void Foam::Field<Type>::operator op(const UList<TYPE>& f) \
638 { \
639  TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
640 } \
641  \
642 template<class Type> \
643 void Foam::Field<Type>::operator op(const tmp<Field<TYPE>>& tf) \
644 { \
645  operator op(tf()); \
646  tf.clear(); \
647 } \
648  \
649 template<class Type> \
650 void Foam::Field<Type>::operator op(const TYPE& t) \
651 { \
652  TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
653 }
654 
659 
660 #undef COMPUTED_ASSIGNMENT
661 
662 
663 // * * * * * * * * * * * * * * * IOstream Functions * * * * * * * * * * * * //
664 
665 template<class Type>
667 {
668  bool uniform = false;
669 
670  if (f.size() && contiguous<Type>())
671  {
672  uniform = true;
673 
674  forAll(f, i)
675  {
676  if (f[i] != f[0])
677  {
678  uniform = false;
679  break;
680  }
681  }
682  }
683 
684  if (uniform)
685  {
686  os << "uniform " << f[0];
687  }
688  else
689  {
690  os << "nonuniform ";
691  writeEntry(os, static_cast<const List<Type>&>(f));
692  }
693 }
694 
695 
696 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
697 
698 template<class Type>
699 Foam::Ostream& Foam::operator<<(Ostream& os, const Field<Type>& f)
700 {
701  os << static_cast<const List<Type>&>(f);
702  return os;
703 }
704 
705 
706 template<class Type>
707 Foam::Ostream& Foam::operator<<(Ostream& os, const tmp<Field<Type>>& tf)
708 {
709  os << tf();
710  tf.clear();
711  return os;
712 }
713 
714 
715 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
716 
717 #include "FieldFunctions.C"
718 
719 // ************************************************************************* //
High performance macro functions for Field<Type> algebra. These expand using either array element acc...
#define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2)
Definition: FieldM.H:329
#define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s)
Definition: FieldM.H:347
#define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2)
Definition: FieldM.H:227
#define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2)
Definition: FieldM.H:210
#define COMPUTED_ASSIGNMENT(TYPE, op)
Definition: Field.C:634
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
Pre-declare SubField and related Field type.
Definition: Field.H:83
tmp< Field< Type > > T() const
Return the field transpose (only defined for second rank tensors)
Definition: Field.C:546
Field()
Construct null.
Definition: Field.C:41
void operator=(const Field< Type > &)
Definition: Field.C:557
pTraits< Type >::cmptType cmptType
Component type.
Definition: Field.H:98
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:498
tmp< Field< Type > > clone() const
Clone.
Definition: Field.C:264
void reset(const Field< Type > &)
Reset the field values to the given field.
Definition: Field.C:456
void negate()
Negate this field.
Definition: Field.C:477
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Definition: Field.C:289
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
Definition: Field.C:386
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition: Field.C:486
VSForm block(const label start) const
Definition: Field.C:534
static const char *const typeName
Definition: Field.H:106
bool eof() const
Return true if end of input seen.
Definition: IOstream.H:339
Input token stream.
Definition: ITstream.H:53
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
void operator=(const UList< T > &)
Assignment to UList operator. Takes linear time.
Definition: List.C:376
void setSize(const label)
Reset size of List.
Definition: List.C:281
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A List with indirect addressing.
Definition: UIndirectList.H:60
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
Templated vector space.
Definition: VectorSpace.H:85
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
Reference counter for various OpenFOAM components.
Definition: refCount.H:50
A class for managing temporary objects.
Definition: tmp.H:55
bool valid() const
Is this temporary object valid,.
Definition: tmpI.H:183
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:253
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
A token holds items read from Istream.
Definition: token.H:73
InfoProxy< token > info() const
Return info proxy.
Definition: token.H:422
bool isWord() const
Definition: tokenI.H:298
const word & wordToken() const
Definition: tokenI.H:303
Unit conversion structure. Contains the associated dimensions and the multiplier with which to conver...
A class for handling words, derived from string.
Definition: word.H:62
A class representing the concept of 0 used to avoid unnecessary manipulations for objects that are kn...
Definition: zero.H:50
Template function to specify if the data of a type are contiguous.
#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
volScalarField sf(fieldObject, mesh)
const tensorField & tf
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(lagrangian::Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), lagrangian::cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
const dimensionedScalar c
Speed of light in a vacuum.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const zero Zero
Definition: zero.H:97
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
const unitConversion unitAny
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void T(LagrangianPatchField< Type > &f, const LagrangianPatchField< Type > &f1)
const HashTable< unitConversion > & units()
Get the table of unit conversions.
void component(LagrangianPatchField< typename LagrangianPatchField< Type >::cmptType > &sf, const LagrangianPatchField< Type > &f, const direction d)
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
T clone(const T &t)
Definition: List.H:55
IOerror FatalIOError
Ostream & operator<<(Ostream &os, const fvConstraints &constraints)
error FatalError
uint8_t direction
Definition: direction.H:45
points setSize(newPointi)
labelList f(nPoints)
dictionary dict
Useful unit conversions.