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-2021 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 
272  tmp<Field<Type>> tmapF;
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()
319  << abort(FatalError);
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  TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
435 }
436 
437 
438 template<class Type>
441 (
442  const direction d
443 ) const
444 {
445  tmp<Field<cmptType>> Component(new Field<cmptType>(this->size()));
446  ::Foam::component(Component.ref(), *this, d);
447  return Component;
448 }
449 
450 
451 template<class Type>
453 (
454  const direction d,
455  const UList<cmptType>& sf
456 )
457 {
458  TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
459  cmptType, sf)
460 }
461 
462 
463 template<class Type>
465 (
466  const direction d,
467  const tmp<Field<cmptType>>& tsf
468 )
469 {
470  replace(d, tsf());
471  tsf.clear();
472 }
473 
474 
475 template<class Type>
477 (
478  const direction d,
479  const cmptType& c
480 )
481 {
482  TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
483  cmptType, c)
484 }
485 
486 
487 template<class Type>
488 template<class VSForm>
489 VSForm Foam::Field<Type>::block(const label start) const
490 {
491  VSForm vs;
492  for (direction i=0; i<VSForm::nComponents; i++)
493  {
494  vs[i] = this->operator[](start + i);
495  }
496  return vs;
497 }
498 
499 
500 template<class Type>
502 {
503  tmp<Field<Type>> transpose(new Field<Type>(this->size()));
504  ::Foam::T(transpose.ref(), *this);
505  return transpose;
506 }
507 
508 
509 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
510 
511 template<class Type>
513 {
514  if (this == &rhs)
515  {
517  << "attempted assignment to self"
518  << abort(FatalError);
519  }
520 
522 }
523 
524 
525 template<class Type>
527 {
528  if (this == &rhs)
529  {
531  << "attempted assignment to self"
532  << abort(FatalError);
533  }
534 
535  List<Type>::operator=(move(rhs));
536 }
537 
538 
539 template<class Type>
541 {
543 }
544 
545 
546 template<class Type>
548 {
550 }
551 
552 
553 template<class Type>
555 {
556  List<Type>::operator=(move(rhs));
557 }
558 
559 
560 template<class Type>
562 {
563  if (this == &(rhs()))
564  {
566  << "attempted assignment to self"
567  << abort(FatalError);
568  }
569 
570  List<Type>::operator=(rhs());
571 }
572 
573 
574 template<class Type>
575 void Foam::Field<Type>::operator=(const Type& t)
576 {
578 }
579 
580 
581 template<class Type>
583 {
585 }
586 
587 
588 template<class Type>
589 template<class Form, class Cmpt, Foam::direction nCmpt>
591 {
592  TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
593 }
594 
595 
596 #define COMPUTED_ASSIGNMENT(TYPE, op) \
597  \
598 template<class Type> \
599 void Foam::Field<Type>::operator op(const UList<TYPE>& f) \
600 { \
601  TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
602 } \
603  \
604 template<class Type> \
605 void Foam::Field<Type>::operator op(const tmp<Field<TYPE>>& tf) \
606 { \
607  operator op(tf()); \
608  tf.clear(); \
609 } \
610  \
611 template<class Type> \
612 void Foam::Field<Type>::operator op(const TYPE& t) \
613 { \
614  TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
615 }
616 
621 
622 #undef COMPUTED_ASSIGNMENT
623 
624 
625 // * * * * * * * * * * * * * * * IOstream Functions * * * * * * * * * * * * //
626 
627 template<class Type>
629 {
630  bool uniform = false;
631 
632  if (f.size() && contiguous<Type>())
633  {
634  uniform = true;
635 
636  forAll(f, i)
637  {
638  if (f[i] != f[0])
639  {
640  uniform = false;
641  break;
642  }
643  }
644  }
645 
646  if (uniform)
647  {
648  os << "uniform " << f[0];
649  }
650  else
651  {
652  os << "nonuniform ";
653  writeEntry(os, static_cast<const List<Type>&>(f));
654  }
655 }
656 
657 
658 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
659 
660 template<class Type>
661 Foam::Ostream& Foam::operator<<(Ostream& os, const Field<Type>& f)
662 {
663  os << static_cast<const List<Type>&>(f);
664  return os;
665 }
666 
667 
668 template<class Type>
669 Foam::Ostream& Foam::operator<<(Ostream& os, const tmp<Field<Type>>& tf)
670 {
671  os << tf();
672  tf.clear();
673  return os;
674 }
675 
676 
677 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
678 
679 #include "FieldFunctions.C"
680 
681 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
bool isWord() const
Definition: tokenI.H:261
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
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Reference counter for various OpenFOAM components.
Definition: refCount.H:49
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:156
#define COMPUTED_ASSIGNMENT(TYPE, op)
Definition: Field.C:596
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:323
static const char *const typeName
Definition: Field.H:105
void negate()
Negate this field.
Definition: Field.C:432
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
InfoProxy< token > info() const
Return info proxy.
Definition: token.H:391
#define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2)
Definition: FieldM.H:329
const word & wordToken() const
Definition: tokenI.H:266
uint8_t direction
Definition: direction.H:45
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
pTraits< PointType >::cmptType cmptType
Component type.
Definition: Field.H:97
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
A token holds items read from Istream.
Definition: token.H:72
Template function to specify if the data of a type are contiguous.
Templated vector space.
Definition: VectorSpace.H:53
Pre-declare related SubField type.
Definition: Field.H:60
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:453
const tensorField & tf
#define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s)
Definition: FieldM.H:347
points setSize(newPointi)
Field()
Construct null.
Definition: Field.C:40
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.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
T clone(const T &t)
Definition: List.H:54
Pre-declare SubField and related Field type.
Definition: Field.H:56
A class for handling words, derived from string.
Definition: word.H:59
tmp< Field< Type > > clone() const
Clone.
Definition: Field.C:240
static const zero Zero
Definition: zero.H:97
VSForm block(const label start) const
Definition: Field.C:489
errorManip< error > abort(error &err)
Definition: errorManip.H:131
#define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2)
Definition: FieldM.H:227
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Definition: Field.C:265
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition: Field.C:441
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:54
void operator=(const Field< Type > &)
Definition: Field.C:512
labelList f(nPoints)
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
const volScalarField & T
#define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2)
Definition: FieldM.H:210
void setSize(const label)
Reset size of List.
Definition: List.C:281
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
Definition: Field.C:362
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:335
A List with indirect addressing.
Definition: fvMatrix.H:106
tmp< Field< Type > > T() const
Return the field transpose (only defined for second rank tensors)
Definition: Field.C:501
A class representing the concept of 0 used to avoid unnecessary manipulations for objects that are kn...
Definition: zero.H:49
A class for managing temporary objects.
Definition: PtrList.H:53
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
High performance macro functions for Field<Type> algebra. These expand using either array element acc...
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
Input token stream.
Definition: ITstream.H:49
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:844
IOerror FatalIOError