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-2022 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 "dictionary.H"
29 #include "contiguous.H"
30 
31 // * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
32 
33 template<class Type>
34 const char* const Foam::Field<Type>::typeName("Field");
35 
36 
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
39 template<class Type>
41 :
42  List<Type>()
43 {}
44 
45 
46 template<class Type>
48 :
49  List<Type>(size)
50 {}
51 
52 
53 template<class Type>
54 Foam::Field<Type>::Field(const label size, const Type& t)
55 :
56  List<Type>(size, t)
57 {}
58 
59 
60 template<class Type>
62 :
63  List<Type>(size, Zero)
64 {}
65 
66 
67 template<class Type>
69 :
70  List<Type>(list)
71 {}
72 
73 
74 template<class Type>
76 :
77  List<Type>(move(f))
78 {}
79 
80 
81 template<class Type>
83 :
84  List<Type>(list)
85 {}
86 
87 
88 template<class Type>
90 :
91  tmp<Field<Type>>::refCount(),
92  List<Type>(f)
93 {}
94 
95 
96 template<class Type>
98 :
99  List<Type>(f, reuse)
100 {}
101 
102 
103 template<class Type>
105 :
106  tmp<Field<Type>>::refCount(),
107  List<Type>(move(f))
108 {}
109 
110 
111 template<class Type>
113 :
114  List<Type>(const_cast<Field<Type>&>(tf()), tf.isTmp())
115 {
116  tf.clear();
117 }
118 
119 
120 template<class Type>
122 (
123  const UList<Type>& mapF,
124  const labelUList& mapAddressing
125 )
126 :
127  List<Type>(mapAddressing.size())
128 {
129  map(mapF, mapAddressing);
130 }
131 
132 
133 template<class Type>
135 (
136  const tmp<Field<Type>>& tmapF,
137  const labelUList& mapAddressing
138 )
139 :
140  List<Type>(mapAddressing.size())
141 {
142  map(tmapF, mapAddressing);
143 }
144 
145 
146 template<class Type>
148 (
149  const UList<Type>& mapF,
150  const labelListList& mapAddressing,
151  const scalarListList& mapWeights
152 )
153 :
154  List<Type>(mapAddressing.size())
155 {
156  map(mapF, mapAddressing, mapWeights);
157 }
158 
159 
160 template<class Type>
162 (
163  const tmp<Field<Type>>& tmapF,
164  const labelListList& mapAddressing,
165  const scalarListList& mapWeights
166 )
167 :
168  List<Type>(mapAddressing.size())
169 {
170  map(tmapF, mapAddressing, mapWeights);
171 }
172 
173 
174 template<class Type>
176 :
177  List<Type>(is)
178 {}
179 
180 
181 template<class Type>
183 (
184  const word& keyword,
185  const dictionary& dict,
186  const label s
187 )
188 {
189  if (s)
190  {
191  ITstream& is = dict.lookup(keyword);
192 
193  // Read first token
194  token firstToken(is);
195 
196  if (firstToken.isWord())
197  {
198  if (firstToken.wordToken() == "uniform")
199  {
200  this->setSize(s);
201  operator=(pTraits<Type>(is));
202  }
203  else if (firstToken.wordToken() == "nonuniform")
204  {
205  is >> static_cast<List<Type>&>(*this);
206  if (this->size() != s)
207  {
209  (
210  dict
211  ) << "size " << this->size()
212  << " is not equal to the given value of " << s
213  << exit(FatalIOError);
214  }
215  }
216  else
217  {
219  (
220  dict
221  ) << "expected keyword 'uniform' or 'nonuniform', found "
222  << firstToken.wordToken()
223  << exit(FatalIOError);
224  }
225  }
226  else
227  {
229  (
230  dict
231  ) << "expected keyword 'uniform' or 'nonuniform', found "
232  << firstToken.info()
233  << exit(FatalIOError);
234  }
235  }
236 }
237 
238 
239 template<class Type>
241 {
242  return tmp<Field<Type>>(new Field<Type>(*this));
243 }
244 
245 
246 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
247 
248 template<class Type>
250 (
251  const UList<Type>& mapF,
252  tmp<Field<Type>>& tmapF
253 ) const
254 {
255  if (static_cast<const UList<Type>*>(this) == &mapF)
256  {
257  tmapF = clone();
258  }
259  return tmapF.valid() ? tmapF() : mapF;
260 }
261 
262 
263 template<class Type>
265 (
266  const UList<Type>& mapF0,
267  const labelUList& mapAddressing
268 )
269 {
270  Field<Type>& f = *this;
271 
273  const UList<Type>& mapF = copySelf(mapF0, tmapF);
274 
275  if (f.size() != mapAddressing.size())
276  {
277  f.setSize(mapAddressing.size());
278  }
279 
280  if (mapF.size() > 0)
281  {
282  forAll(f, i)
283  {
284  const label mapi = mapAddressing[i];
285 
286  if (mapi >= 0)
287  {
288  f[i] = mapF[mapi];
289  }
290  }
291  }
292 }
293 
294 
295 template<class Type>
297 (
298  const tmp<Field<Type>>& tmapF,
299  const labelUList& mapAddressing
300 )
301 {
302  map(tmapF(), mapAddressing);
303  tmapF.clear();
304 }
305 
306 
307 template<class Type>
309 (
310  const UList<Type>& mapF0,
311  const labelListList& mapAddressing,
312  const scalarListList& mapWeights
313 )
314 {
315  if (mapWeights.size() != mapAddressing.size())
316  {
318  << mapWeights.size() << " map size: " << mapAddressing.size()
320  }
321 
322  Field<Type>& f = *this;
323 
324  tmp<Field<Type>> tmapF;
325  const UList<Type>& mapF = copySelf(mapF0, tmapF);
326 
327  if (this->size() != mapAddressing.size())
328  {
329  this->setSize(mapAddressing.size());
330  }
331 
332  forAll(f, i)
333  {
334  const labelList& localAddrs = mapAddressing[i];
335  const scalarList& localWeights = mapWeights[i];
336 
337  f[i] = Zero;
338 
339  forAll(localAddrs, j)
340  {
341  f[i] += localWeights[j]*mapF[localAddrs[j]];
342  }
343  }
344 }
345 
346 
347 template<class Type>
349 (
350  const tmp<Field<Type>>& tmapF,
351  const labelListList& mapAddressing,
352  const scalarListList& mapWeights
353 )
354 {
355  map(tmapF(), mapAddressing, mapWeights);
356  tmapF.clear();
357 }
358 
359 
360 template<class Type>
362 (
363  const UList<Type>& mapF0,
364  const labelUList& mapAddressing
365 )
366 {
367  Field<Type>& f = *this;
368 
369  tmp<Field<Type>> tmapF;
370  const UList<Type>& mapF = copySelf(mapF0, tmapF);
371 
372  forAll(mapF, i)
373  {
374  const label mapi = mapAddressing[i];
375 
376  if (mapi >= 0)
377  {
378  f[mapi] = mapF[i];
379  }
380  }
381 }
382 
383 
384 template<class Type>
386 (
387  const tmp<Field<Type>>& tmapF,
388  const labelUList& mapAddressing
389 )
390 {
391  rmap(tmapF(), mapAddressing);
392  tmapF.clear();
393 }
394 
395 
396 template<class Type>
398 (
399  const UList<Type>& mapF0,
400  const labelUList& mapAddressing,
401  const UList<scalar>& mapWeights
402 )
403 {
404  Field<Type>& f = *this;
405 
406  tmp<Field<Type>> tmapF;
407  const UList<Type>& mapF = copySelf(mapF0, tmapF);
408 
409  f = Zero;
410 
411  forAll(mapF, i)
412  {
413  f[mapAddressing[i]] += mapF[i]*mapWeights[i];
414  }
415 }
416 
417 
418 template<class Type>
420 (
421  const tmp<Field<Type>>& tmapF,
422  const labelUList& mapAddressing,
423  const UList<scalar>& mapWeights
424 )
425 {
426  rmap(tmapF(), mapAddressing, mapWeights);
427  tmapF.clear();
428 }
429 
430 
431 template<class Type>
433 {
434  if (this == &rhs)
435  {
437  << "attempted assignment to self"
438  << abort(FatalError);
439  }
440 
442 }
443 
444 
445 template<class Type>
447 {
448  TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
449 }
450 
451 
452 template<class Type>
455 (
456  const direction d
457 ) const
458 {
459  tmp<Field<cmptType>> Component(new Field<cmptType>(this->size()));
460  ::Foam::component(Component.ref(), *this, d);
461  return Component;
462 }
463 
464 
465 template<class Type>
467 (
468  const direction d,
469  const UList<cmptType>& sf
470 )
471 {
472  TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
473  cmptType, sf)
474 }
475 
476 
477 template<class Type>
479 (
480  const direction d,
481  const tmp<Field<cmptType>>& tsf
482 )
483 {
484  replace(d, tsf());
485  tsf.clear();
486 }
487 
488 
489 template<class Type>
491 (
492  const direction d,
493  const cmptType& c
494 )
495 {
496  TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
497  cmptType, c)
498 }
499 
500 
501 template<class Type>
502 template<class VSForm>
503 VSForm Foam::Field<Type>::block(const label start) const
504 {
505  VSForm vs;
506  for (direction i=0; i<VSForm::nComponents; i++)
507  {
508  vs[i] = this->operator[](start + i);
509  }
510  return vs;
511 }
512 
513 
514 template<class Type>
516 {
517  tmp<Field<Type>> transpose(new Field<Type>(this->size()));
518  ::Foam::T(transpose.ref(), *this);
519  return transpose;
520 }
521 
522 
523 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
524 
525 template<class Type>
527 {
528  if (this == &rhs)
529  {
531  << "attempted assignment to self"
532  << abort(FatalError);
533  }
534 
536 }
537 
538 
539 template<class Type>
541 {
542  if (this == &rhs)
543  {
545  << "attempted assignment to self"
546  << abort(FatalError);
547  }
548 
549  List<Type>::operator=(move(rhs));
550 }
551 
552 
553 template<class Type>
555 {
557 }
558 
559 
560 template<class Type>
562 {
564 }
565 
566 
567 template<class Type>
569 {
570  List<Type>::operator=(move(rhs));
571 }
572 
573 
574 template<class Type>
576 {
577  if (this == &(rhs()))
578  {
580  << "attempted assignment to self"
581  << abort(FatalError);
582  }
583 
584  List<Type>::operator=(rhs());
585 }
586 
587 
588 template<class Type>
589 void Foam::Field<Type>::operator=(const Type& t)
590 {
592 }
593 
594 
595 template<class Type>
597 {
599 }
600 
601 
602 template<class Type>
603 template<class Form, class Cmpt, Foam::direction nCmpt>
605 {
606  TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
607 }
608 
609 
610 #define COMPUTED_ASSIGNMENT(TYPE, op) \
611  \
612 template<class Type> \
613 void Foam::Field<Type>::operator op(const UList<TYPE>& f) \
614 { \
615  TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
616 } \
617  \
618 template<class Type> \
619 void Foam::Field<Type>::operator op(const tmp<Field<TYPE>>& tf) \
620 { \
621  operator op(tf()); \
622  tf.clear(); \
623 } \
624  \
625 template<class Type> \
626 void Foam::Field<Type>::operator op(const TYPE& t) \
627 { \
628  TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
629 }
630 
635 
636 #undef COMPUTED_ASSIGNMENT
637 
638 
639 // * * * * * * * * * * * * * * * IOstream Functions * * * * * * * * * * * * //
640 
641 template<class Type>
643 {
644  bool uniform = false;
645 
646  if (f.size() && contiguous<Type>())
647  {
648  uniform = true;
649 
650  forAll(f, i)
651  {
652  if (f[i] != f[0])
653  {
654  uniform = false;
655  break;
656  }
657  }
658  }
659 
660  if (uniform)
661  {
662  os << "uniform " << f[0];
663  }
664  else
665  {
666  os << "nonuniform ";
667  writeEntry(os, static_cast<const List<Type>&>(f));
668  }
669 }
670 
671 
672 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
673 
674 template<class Type>
675 Foam::Ostream& Foam::operator<<(Ostream& os, const Field<Type>& f)
676 {
677  os << static_cast<const List<Type>&>(f);
678  return os;
679 }
680 
681 
682 template<class Type>
683 Foam::Ostream& Foam::operator<<(Ostream& os, const tmp<Field<Type>>& tf)
684 {
685  os << tf();
686  tf.clear();
687  return os;
688 }
689 
690 
691 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
692 
693 #include "FieldFunctions.C"
694 
695 // ************************************************************************* //
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:610
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Pre-declare SubField and related Field type.
Definition: Field.H:82
tmp< Field< Type > > T() const
Return the field transpose (only defined for second rank tensors)
Definition: Field.C:515
Field()
Construct null.
Definition: Field.C:40
void operator=(const Field< Type > &)
Definition: Field.C:526
pTraits< Type >::cmptType cmptType
Component type.
Definition: Field.H:97
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:467
tmp< Field< Type > > clone() const
Clone.
Definition: Field.C:240
void reset(const Field< Type > &)
Reset the field values to the given field.
Definition: Field.C:432
void negate()
Negate this field.
Definition: Field.C:446
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Definition: Field.C:265
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
Definition: Field.C:362
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition: Field.C:455
VSForm block(const label start) const
Definition: Field.C:503
static const char *const typeName
Definition: Field.H:105
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:79
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:160
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:860
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
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:318
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
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
List< label > labelList
A List of labels.
Definition: labelList.H:56
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
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
List< scalar > scalarList
A List of scalars.
Definition: scalarList.H:50
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
error FatalError
Ostream & operator<<(Ostream &, const ensightPart &)
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