Field.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2015-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "FieldMapper.H"
30 #include "FieldM.H"
31 #include "dictionary.H"
32 #include "contiguous.H"
33 #include "mapDistributeBase.H"
34 
35 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
36 
37 template<class Type>
39 (
40  const UList<Type>& mapF,
41  const labelUList& mapAddressing
42 )
43 :
44  List<Type>(mapAddressing.size())
45 {
46  map(mapF, mapAddressing);
47 }
48 
49 
50 template<class Type>
52 (
53  const tmp<Field<Type>>& tmapF,
54  const labelUList& mapAddressing
55 )
56 :
57  List<Type>(mapAddressing.size())
58 {
59  map(tmapF, mapAddressing);
60 }
61 
62 
63 template<class Type>
65 (
66  const UList<Type>& mapF,
67  const labelListList& mapAddressing,
68  const scalarListList& mapWeights
69 )
70 :
71  List<Type>(mapAddressing.size())
72 {
73  map(mapF, mapAddressing, mapWeights);
74 }
75 
76 
77 template<class Type>
79 (
80  const tmp<Field<Type>>& tmapF,
81  const labelListList& mapAddressing,
82  const scalarListList& mapWeights
83 )
84 :
85  List<Type>(mapAddressing.size())
86 {
87  map(tmapF, mapAddressing, mapWeights);
88 }
89 
90 
91 template<class Type>
93 (
94  const UList<Type>& mapF,
95  const FieldMapper& mapper,
96  const bool applyFlip
97 )
98 :
99  List<Type>(mapper.size())
100 {
101  map(mapF, mapper, applyFlip);
102 }
103 
104 
105 template<class Type>
107 (
108  const UList<Type>& mapF,
109  const FieldMapper& mapper,
110  const Type& defaultValue,
111  const bool applyFlip
112 )
113 :
114  List<Type>(mapper.size(), defaultValue)
115 {
116  map(mapF, mapper, applyFlip);
117 }
118 
119 
120 template<class Type>
122 (
123  const UList<Type>& mapF,
124  const FieldMapper& mapper,
125  const UList<Type>& defaultValues,
126  const bool applyFlip
127 )
128 :
129  List<Type>(defaultValues)
130 {
131  map(mapF, mapper, applyFlip);
132 }
133 
134 
135 template<class Type>
137 (
138  const tmp<Field<Type>>& tmapF,
139  const FieldMapper& mapper,
140  const bool applyFlip
141 )
142 :
143  List<Type>(mapper.size())
144 {
145  map(tmapF, mapper, applyFlip);
146 }
147 
148 
149 template<class Type>
151 (
152  const tmp<Field<Type>>& tmapF,
153  const FieldMapper& mapper,
154  const Type& defaultValue,
155  const bool applyFlip
156 )
157 :
158  List<Type>(mapper.size(), defaultValue)
159 {
160  map(tmapF, mapper, applyFlip);
161 }
162 
163 
164 template<class Type>
166 (
167  const tmp<Field<Type>>& tmapF,
168  const FieldMapper& mapper,
169  const UList<Type>& defaultValues,
170  const bool applyFlip
171 )
172 :
173  List<Type>(defaultValues)
174 {
175  map(tmapF, mapper, applyFlip);
176 }
177 
178 
179 template<class Type>
181 (
182  const word& keyword,
183  const dictionary& dict,
184  const label len
185 )
186 {
187  if (len)
188  {
189  ITstream& is = dict.lookup(keyword);
190 
191  // Read first token
192  token firstToken(is);
193 
194  if (firstToken.isWord())
195  {
196  if (firstToken.wordToken() == "uniform")
197  {
198  this->setSize(len);
199  operator=(pTraits<Type>(is));
200  }
201  else if (firstToken.wordToken() == "nonuniform")
202  {
203  is >> static_cast<List<Type>&>(*this);
204  label currentSize = this->size();
205  if (currentSize != len)
206  {
207  if (len < currentSize && allowConstructFromLargerSize)
208  {
209  #ifdef FULLDEBUG
211  << "Sizes do not match. "
212  << "Re-sizing " << currentSize
213  << " entries to " << len
214  << endl;
215  #endif
216 
217  // Resize the data
218  this->setSize(len);
219  }
220  else
221  {
223  << "size " << this->size()
224  << " is not equal to the given value of " << len
225  << exit(FatalIOError);
226  }
227  }
228  }
229  else
230  {
232  << "Expected keyword 'uniform' or 'nonuniform', found "
233  << firstToken.wordToken()
234  << exit(FatalIOError);
235  }
236  }
237  else
238  {
240  << "Expected keyword 'uniform' or 'nonuniform', found "
241  << firstToken.info() << nl
242  << exit(FatalIOError);
243  }
244  }
245 }
246 
247 
248 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
249 
250 template<class Type>
252 (
253  const UList<Type>& mapF,
254  const labelUList& mapAddressing
255 )
256 {
257  Field<Type>& f = *this;
258 
259  if (f.size() != mapAddressing.size())
260  {
261  f.setSize(mapAddressing.size());
262  }
263 
264  if (mapF.size() > 0)
265  {
266  forAll(f, i)
267  {
268  const label mapI = mapAddressing[i];
269 
270  if (mapI >= 0)
271  {
272  f[i] = mapF[mapI];
273  }
274  }
275  }
276 }
277 
278 
279 template<class Type>
281 (
282  const tmp<Field<Type>>& tmapF,
283  const labelUList& mapAddressing
284 )
285 {
286  map(tmapF(), mapAddressing);
287  tmapF.clear();
288 }
289 
290 
291 template<class Type>
293 (
294  const UList<Type>& mapF,
295  const labelListList& mapAddressing,
296  const scalarListList& mapWeights
297 )
298 {
299  Field<Type>& f = *this;
300 
301  if (f.size() != mapAddressing.size())
302  {
303  f.setSize(mapAddressing.size());
304  }
305 
306  if (mapWeights.size() != mapAddressing.size())
307  {
309  << mapWeights.size() << " map size: " << mapAddressing.size()
310  << abort(FatalError);
311  }
312 
313  forAll(f, i)
314  {
315  const labelList& localAddrs = mapAddressing[i];
316  const scalarList& localWeights = mapWeights[i];
317 
318  f[i] = Zero;
319 
320  forAll(localAddrs, j)
321  {
322  f[i] += localWeights[j]*mapF[localAddrs[j]];
323  }
324  }
325 }
326 
327 
328 template<class Type>
330 (
331  const tmp<Field<Type>>& tmapF,
332  const labelListList& mapAddressing,
333  const scalarListList& mapWeights
334 )
335 {
336  map(tmapF(), mapAddressing, mapWeights);
337  tmapF.clear();
338 }
339 
340 
341 template<class Type>
343 (
344  const UList<Type>& mapF,
345  const FieldMapper& mapper,
346  const bool applyFlip
347 )
348 {
349  if (mapper.distributed())
350  {
351  // Fetch remote parts of mapF
352  const mapDistributeBase& distMap = mapper.distributeMap();
353  Field<Type> newMapF(mapF);
354 
355  if (applyFlip)
356  {
357  distMap.distribute(newMapF);
358  }
359  else
360  {
361  distMap.distribute(newMapF, noOp());
362  }
363 
364  if (mapper.direct() && notNull(mapper.directAddressing()))
365  {
366  map(newMapF, mapper.directAddressing());
367  }
368  else if (!mapper.direct())
369  {
370  map(newMapF, mapper.addressing(), mapper.weights());
371  }
372  else if (mapper.direct() && isNull(mapper.directAddressing()))
373  {
374  // Special case, no local mapper. Assume ordering already correct
375  // from distribution. Note: this behaviour is different compared
376  // to local mapper.
377  this->transfer(newMapF);
378  this->setSize(mapper.size());
379  }
380  }
381  else
382  {
383  if
384  (
385  mapper.direct()
386  && notNull(mapper.directAddressing())
387  && mapper.directAddressing().size()
388  )
389  {
390  map(mapF, mapper.directAddressing());
391  }
392  else if (!mapper.direct() && mapper.addressing().size())
393  {
394  map(mapF, mapper.addressing(), mapper.weights());
395  }
396  }
397 }
398 
399 
400 template<class Type>
402 (
403  const tmp<Field<Type>>& tmapF,
404  const FieldMapper& mapper,
405  const bool applyFlip
406 )
407 {
408  map(tmapF(), mapper, applyFlip);
409  tmapF.clear();
410 }
411 
412 
413 template<class Type>
415 (
416  const FieldMapper& mapper,
417  const bool applyFlip
418 )
419 {
420  if (mapper.distributed())
421  {
422  // Fetch remote parts of *this
423  const mapDistributeBase& distMap = mapper.distributeMap();
424  Field<Type> fCpy(*this);
425 
426  if (applyFlip)
427  {
428  distMap.distribute(fCpy);
429  }
430  else
431  {
432  distMap.distribute(fCpy, noOp());
433  }
434 
435  if
436  (
437  (mapper.direct()
438  && notNull(mapper.directAddressing()))
439  || !mapper.direct()
440  )
441  {
442  this->map(fCpy, mapper);
443  }
444  else if (mapper.direct() && isNull(mapper.directAddressing()))
445  {
446  // Special case, no local mapper. Assume ordering already correct
447  // from distribution. Note: this behaviour is different compared
448  // to local mapper.
449  this->transfer(fCpy);
450  this->setSize(mapper.size());
451  }
452  }
453  else
454  {
455  if
456  (
457  (
458  mapper.direct()
459  && notNull(mapper.directAddressing())
460  && mapper.directAddressing().size()
461  )
462  || (!mapper.direct() && mapper.addressing().size())
463  )
464  {
465  Field<Type> fCpy(*this);
466  map(fCpy, mapper);
467  }
468  else
469  {
470  this->setSize(mapper.size());
471  }
472  }
473 }
474 
475 
476 template<class Type>
478 (
479  const UList<Type>& mapF,
480  const labelUList& mapAddressing
481 )
482 {
483  Field<Type>& f = *this;
484 
485  forAll(mapF, i)
486  {
487  label mapI = mapAddressing[i];
488 
489  if (mapI >= 0)
490  {
491  f[mapI] = mapF[i];
492  }
493  }
494 }
495 
496 
497 template<class Type>
499 (
500  const tmp<Field<Type>>& tmapF,
501  const labelUList& mapAddressing
502 )
503 {
504  rmap(tmapF(), mapAddressing);
505  tmapF.clear();
506 }
507 
508 
509 template<class Type>
511 (
512  const UList<Type>& mapF,
513  const labelUList& mapAddressing,
514  const UList<scalar>& mapWeights
515 )
516 {
517  Field<Type>& f = *this;
518 
519  f = Zero;
520 
521  forAll(mapF, i)
522  {
523  f[mapAddressing[i]] += mapF[i]*mapWeights[i];
524  }
525 }
526 
527 
528 template<class Type>
530 (
531  const tmp<Field<Type>>& tmapF,
532  const labelUList& mapAddressing,
533  const UList<scalar>& mapWeights
534 )
535 {
536  rmap(tmapF(), mapAddressing, mapWeights);
537  tmapF.clear();
538 }
539 
540 
541 template<class Type>
543 {
544  TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
545 }
546 
547 
548 template<class Type>
551 (
552  const direction d
553 ) const
554 {
555  auto tres = tmp<Field<cmptType>>::New(this->size());
556  ::Foam::component(tres.ref(), *this, d);
557  return tres;
558 }
559 
560 
561 template<class Type>
563 (
564  const direction d,
565  const UList<cmptType>& sf
566 )
567 {
568  TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
569  cmptType, sf)
570 }
571 
572 
573 template<class Type>
575 (
576  const direction d,
577  const tmp<Field<cmptType>>& tsf
578 )
579 {
580  replace(d, tsf());
581  tsf.clear();
582 }
583 
584 
585 template<class Type>
587 (
588  const direction d,
589  const cmptType& c
590 )
591 {
592  TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
593  cmptType, c)
594 }
595 
596 
597 template<class Type>
598 template<class VSForm>
599 VSForm Foam::Field<Type>::block(const label start) const
600 {
601  VSForm vs;
602  for (direction i=0; i<VSForm::nComponents; i++)
603  {
604  vs[i] = this->operator[](start + i);
605  }
606  return vs;
607 }
608 
609 
610 template<class Type>
612 {
613  auto tres = tmp<Field<Type>>::New(this->size());
614  ::Foam::T(tres.ref(), *this);
615  return tres;
616 }
617 
618 
619 template<class Type>
620 void Foam::Field<Type>::writeEntry(const word& keyword, Ostream& os) const
621 {
622  if (keyword.size())
623  {
624  os.writeKeyword(keyword);
625  }
626 
627  // The contents are 'uniform' if the list is non-empty
628  // and all entries have identical values.
629 
631  {
632  os << word("uniform") << token::SPACE << this->first();
633  }
634  else
635  {
636  os << word("nonuniform") << token::SPACE;
638  }
639 
640  os << token::END_STATEMENT << nl;
641 }
642 
643 
644 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
645 
646 template<class Type>
648 {
649  if (this == &rhs)
650  {
651  return; // Self-assignment is a no-op
652  }
653 
655 }
656 
657 
658 template<class Type>
660 {
661  if (this == &(rhs()))
662  {
663  return; // Self-assignment is a no-op
664  }
665 
666  List<Type>::operator=(rhs());
667 }
668 
669 
670 template<class Type>
671 template<class Form, class Cmpt, Foam::direction nCmpt>
673 {
674  TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
675 }
676 
677 
678 #define COMPUTED_ASSIGNMENT(TYPE, op) \
679  \
680 template<class Type> \
681 void Foam::Field<Type>::operator op(const UList<TYPE>& f) \
682 { \
683  TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
684 } \
685  \
686 template<class Type> \
687 void Foam::Field<Type>::operator op(const tmp<Field<TYPE>>& tf) \
688 { \
689  operator op(tf()); \
690  tf.clear(); \
691 } \
692  \
693 template<class Type> \
694 void Foam::Field<Type>::operator op(const TYPE& t) \
695 { \
696  TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
697 }
698 
703 
704 #undef COMPUTED_ASSIGNMENT
705 
706 
707 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
708 
709 template<class Type>
711 {
712  os << static_cast<const List<Type>&>(f);
713  return os;
714 }
715 
716 
717 template<class Type>
719 {
720  os << tf();
721  tf.clear();
722  return os;
723 }
724 
725 
726 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
727 
728 #include "FieldFunctions.C"
729 
730 // ************************************************************************* //
setSize
points setSize(newPointi)
Foam::component
void component(FieldField< Field, typename FieldField< Field, Type >::cmptType > &sf, const FieldField< Field, Type > &f, const direction d)
Definition: FieldFieldFunctions.C:44
FieldFunctions.C
mapDistributeBase.H
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Field::autoMap
void autoMap(const FieldMapper &map, const bool applyFlip=true)
Map from self.
Definition: Field.C:415
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
FieldM.H
High performance macro functions for Field<Type> algebra. These expand using either array element acc...
Foam::FieldMapper::size
virtual label size() const =0
Foam::FieldMapper::weights
virtual const scalarListList & weights() const
Definition: FieldMapper.H:107
TFOR_ALL_F_OP_FUNC_S_S
#define TFOR_ALL_F_OP_FUNC_S_S(typeF1, f1, OP, FUNC, typeS1, s1, typeS2, s2)
Definition: FieldM.H:237
Foam::FieldMapper
Abstract base class to hold the Field mapping addressing and weights.
Definition: FieldMapper.H:49
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::FieldMapper::direct
virtual bool direct() const =0
Foam::Field::Field
constexpr Field() noexcept
Construct null.
Definition: FieldI.H:31
TFOR_ALL_F_OP_S
#define TFOR_ALL_F_OP_S(typeF, f, OP, typeS, s)
Definition: FieldM.H:359
Foam::token::isWord
bool isWord() const noexcept
Token is WORD or DIRECTIVE word.
Definition: tokenI.H:583
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::VectorSpace
Templated vector space.
Definition: VectorSpace.H:56
Foam::Field::map
void map(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 map from the given field
Definition: Field.C:252
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:83
Foam::Field< Foam::Vector2D >::cmptType
pTraits< Foam::Vector2D >::cmptType cmptType
Component type.
Definition: Field.H:86
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::token::info
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:551
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:55
Foam::mapDistributeBase::distribute
static void distribute(const Pstream::commsTypes commsType, const List< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &, const negateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute data. Note:schedule only used for.
Definition: mapDistributeBaseTemplates.C:122
Foam::Field::T
tmp< Field< Type > > T() const
Return the field transpose (only defined for second rank tensors)
Definition: Field.C:611
Foam::Field::replace
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:563
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::notNull
bool notNull(const T *ptr)
True if ptr is not a pointer (of type T) to the nullObject.
Definition: nullObject.H:207
Foam::Field::rmap
void rmap(const UList< Type > &mapF, const labelUList &mapAddressing)
1 to 1 reverse-map from the given field
Definition: Field.C:478
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::Field::negate
void negate()
Negate this field (negative).
Definition: Field.C:542
Foam::FieldMapper::directAddressing
virtual const labelUList & directAddressing() const
Definition: FieldMapper.H:89
Foam::Ostream::writeKeyword
virtual Ostream & writeKeyword(const keyType &kw)
Write the keyword followed by an appropriate indentation.
Definition: Ostream.C:57
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::Field::component
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
Definition: Field.C:551
Foam::token::wordToken
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:599
Foam::Field::operator=
void operator=(const Field< Type > &)
Copy assignment.
Definition: Field.C:647
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::Field::writeEntry
void writeEntry(const word &keyword, Ostream &os) const
Write the field as a dictionary entry.
Definition: Field.C:620
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::FieldMapper::addressing
virtual const labelListList & addressing() const
Definition: FieldMapper.H:98
TFOR_ALL_F_OP_FUNC_S_F
#define TFOR_ALL_F_OP_FUNC_S_F(typeF1, f1, OP, FUNC, typeS, s, typeF2, f2)
Definition: FieldM.H:219
Foam::nl
constexpr char nl
Definition: Ostream.H:385
f
labelList f(nPoints)
contiguous.H
Foam::List< Type >
Foam::pTraits< Type >
Foam::Field::block
VSForm block(const label start) const
Definition: Field.C:599
Foam::UList< Type >
dictionary.H
Foam::direction
uint8_t direction
Definition: direction.H:52
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::mapDistributeBase
Class containing processor-to-processor mapping information.
Definition: mapDistributeBase.H:103
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
FieldMapper.H
Foam::isNull
bool isNull(const T *ptr)
True if ptr is a pointer (of type T) to the nullObject.
Definition: nullObject.H:192
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
IOWarningInFunction
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
Definition: messageStream.H:315
TFOR_ALL_F_OP_OP_F
#define TFOR_ALL_F_OP_OP_F(typeF1, f1, OP1, OP2, typeF2, f2)
Definition: FieldM.H:341
Foam::FieldMapper::distributeMap
virtual const mapDistributeBase & distributeMap() const
Definition: FieldMapper.H:76
Foam::FieldMapper::distributed
virtual bool distributed() const
Definition: FieldMapper.H:71
COMPUTED_ASSIGNMENT
#define COMPUTED_ASSIGNMENT(TYPE, op)
Definition: Field.C:678
Foam::is_contiguous
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:75
Foam::noOp
Pass through value. Should never be specialized.
Definition: flipOp.H:64