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-2024 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 {
472  TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
473 }
474 
475 
476 template<class Type>
479 (
480  const direction d
481 ) const
482 {
483  tmp<Field<cmptType>> Component(new Field<cmptType>(this->size()));
484  ::Foam::component(Component.ref(), *this, d);
485  return Component;
486 }
487 
488 
489 template<class Type>
491 (
492  const direction d,
493  const UList<cmptType>& sf
494 )
495 {
496  TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
497  cmptType, sf)
498 }
499 
500 
501 template<class Type>
503 (
504  const direction d,
505  const tmp<Field<cmptType>>& tsf
506 )
507 {
508  replace(d, tsf());
509  tsf.clear();
510 }
511 
512 
513 template<class Type>
515 (
516  const direction d,
517  const cmptType& c
518 )
519 {
520  TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
521  cmptType, c)
522 }
523 
524 
525 template<class Type>
526 template<class VSForm>
527 VSForm Foam::Field<Type>::block(const label start) const
528 {
529  VSForm vs;
530  for (direction i=0; i<VSForm::nComponents; i++)
531  {
532  vs[i] = this->operator[](start + i);
533  }
534  return vs;
535 }
536 
537 
538 template<class Type>
540 {
541  tmp<Field<Type>> transpose(new Field<Type>(this->size()));
542  ::Foam::T(transpose.ref(), *this);
543  return transpose;
544 }
545 
546 
547 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
548 
549 template<class Type>
551 {
552  if (this == &rhs)
553  {
555  << "attempted assignment to self"
556  << abort(FatalError);
557  }
558 
560 }
561 
562 
563 template<class Type>
565 {
566  if (this == &rhs)
567  {
569  << "attempted assignment to self"
570  << abort(FatalError);
571  }
572 
573  List<Type>::operator=(move(rhs));
574 }
575 
576 
577 template<class Type>
579 {
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:434
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:539
Field()
Construct null.
Definition: Field.C:41
void operator=(const Field< Type > &)
Definition: Field.C:550
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:491
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:470
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:479
VSForm block(const label start) const
Definition: Field.C:527
static const char *const typeName
Definition: Field.H:106
bool eof() const
Return true if end of input seen.
Definition: IOstream.H:336
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
Pre-declare related SubField type.
Definition: SubField.H:63
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 keyword definitions, which are a keyword followed by any number of values (e....
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:710
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:167
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:237
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
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(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.name(), 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
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const HashTable< unitConversion > & units()
Get the table of unit conversions.
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
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
uint8_t direction
Definition: direction.H:45
points setSize(newPointi)
labelList f(nPoints)
dictionary dict
Useful unit conversions.