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