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-2021 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("uniform"))
195  {
196  this->resize(len);
197  operator=(pTraits<Type>(is));
198  }
199  else if (firstToken.isWord("nonuniform"))
200  {
201  is >> static_cast<List<Type>&>(*this);
202  const label lenRead = this->size();
203  if (len != lenRead)
204  {
205  if (len < lenRead && allowConstructFromLargerSize)
206  {
207  #ifdef FULLDEBUG
209  << "Sizes do not match. Truncating " << lenRead
210  << " entries to " << len << endl;
211  #endif
212 
213  // Truncate the data
214  this->resize(len);
215  }
216  else
217  {
219  << "size " << lenRead
220  << " is not equal to the expected length " << len
221  << exit(FatalIOError);
222  }
223  }
224  }
225  else
226  {
228  << "Expected keyword 'uniform' or 'nonuniform', found "
229  << firstToken.info() << nl
230  << exit(FatalIOError);
231  }
232  }
233 }
234 
235 
236 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
237 
238 template<class Type>
240 (
241  const UList<Type>& mapF,
242  const labelUList& mapAddressing
243 )
244 {
245  Field<Type>& f = *this;
246 
247  if (f.size() != mapAddressing.size())
248  {
249  f.setSize(mapAddressing.size());
250  }
251 
252  if (mapF.size() > 0)
253  {
254  forAll(f, i)
255  {
256  const label mapI = mapAddressing[i];
257 
258  if (mapI >= 0)
259  {
260  f[i] = mapF[mapI];
261  }
262  }
263  }
264 }
265 
266 
267 template<class Type>
269 (
270  const tmp<Field<Type>>& tmapF,
271  const labelUList& mapAddressing
272 )
273 {
274  map(tmapF(), mapAddressing);
275  tmapF.clear();
276 }
277 
278 
279 template<class Type>
281 (
282  const UList<Type>& mapF,
283  const labelListList& mapAddressing,
284  const scalarListList& mapWeights
285 )
286 {
287  Field<Type>& f = *this;
288 
289  if (f.size() != mapAddressing.size())
290  {
291  f.setSize(mapAddressing.size());
292  }
293 
294  if (mapWeights.size() != mapAddressing.size())
295  {
297  << mapWeights.size() << " map size: " << mapAddressing.size()
298  << abort(FatalError);
299  }
300 
301  forAll(f, i)
302  {
303  const labelList& localAddrs = mapAddressing[i];
304  const scalarList& localWeights = mapWeights[i];
305 
306  f[i] = Zero;
307 
308  forAll(localAddrs, j)
309  {
310  f[i] += localWeights[j]*mapF[localAddrs[j]];
311  }
312  }
313 }
314 
315 
316 template<class Type>
318 (
319  const tmp<Field<Type>>& tmapF,
320  const labelListList& mapAddressing,
321  const scalarListList& mapWeights
322 )
323 {
324  map(tmapF(), mapAddressing, mapWeights);
325  tmapF.clear();
326 }
327 
328 
329 template<class Type>
331 (
332  const UList<Type>& mapF,
333  const FieldMapper& mapper,
334  const bool applyFlip
335 )
336 {
337  if (mapper.distributed())
338  {
339  // Fetch remote parts of mapF
340  const mapDistributeBase& distMap = mapper.distributeMap();
341  Field<Type> newMapF(mapF);
342 
343  if (applyFlip)
344  {
345  distMap.distribute(newMapF);
346  }
347  else
348  {
349  distMap.distribute(newMapF, noOp());
350  }
351 
352  if (mapper.direct() && notNull(mapper.directAddressing()))
353  {
354  map(newMapF, mapper.directAddressing());
355  }
356  else if (!mapper.direct())
357  {
358  map(newMapF, mapper.addressing(), mapper.weights());
359  }
360  else if (mapper.direct() && isNull(mapper.directAddressing()))
361  {
362  // Special case, no local mapper. Assume ordering already correct
363  // from distribution. Note: this behaviour is different compared
364  // to local mapper.
365  this->transfer(newMapF);
366  this->setSize(mapper.size());
367  }
368  }
369  else
370  {
371  if
372  (
373  mapper.direct()
374  && notNull(mapper.directAddressing())
375  && mapper.directAddressing().size()
376  )
377  {
378  map(mapF, mapper.directAddressing());
379  }
380  else if (!mapper.direct() && mapper.addressing().size())
381  {
382  map(mapF, mapper.addressing(), mapper.weights());
383  }
384  }
385 }
386 
387 
388 template<class Type>
390 (
391  const tmp<Field<Type>>& tmapF,
392  const FieldMapper& mapper,
393  const bool applyFlip
394 )
395 {
396  map(tmapF(), mapper, applyFlip);
397  tmapF.clear();
398 }
399 
400 
401 template<class Type>
403 (
404  const FieldMapper& mapper,
405  const bool applyFlip
406 )
407 {
408  if (mapper.distributed())
409  {
410  // Fetch remote parts of *this
411  const mapDistributeBase& distMap = mapper.distributeMap();
412  Field<Type> fCpy(*this);
413 
414  if (applyFlip)
415  {
416  distMap.distribute(fCpy);
417  }
418  else
419  {
420  distMap.distribute(fCpy, noOp());
421  }
422 
423  if
424  (
425  (mapper.direct()
426  && notNull(mapper.directAddressing()))
427  || !mapper.direct()
428  )
429  {
430  this->map(fCpy, mapper);
431  }
432  else if (mapper.direct() && isNull(mapper.directAddressing()))
433  {
434  // Special case, no local mapper. Assume ordering already correct
435  // from distribution. Note: this behaviour is different compared
436  // to local mapper.
437  this->transfer(fCpy);
438  this->setSize(mapper.size());
439  }
440  }
441  else
442  {
443  if
444  (
445  (
446  mapper.direct()
447  && notNull(mapper.directAddressing())
448  && mapper.directAddressing().size()
449  )
450  || (!mapper.direct() && mapper.addressing().size())
451  )
452  {
453  Field<Type> fCpy(*this);
454  map(fCpy, mapper);
455  }
456  else
457  {
458  this->setSize(mapper.size());
459  }
460  }
461 }
462 
463 
464 template<class Type>
466 (
467  const UList<Type>& mapF,
468  const labelUList& mapAddressing
469 )
470 {
471  Field<Type>& f = *this;
472 
473  forAll(mapF, i)
474  {
475  label mapI = mapAddressing[i];
476 
477  if (mapI >= 0)
478  {
479  f[mapI] = mapF[i];
480  }
481  }
482 }
483 
484 
485 template<class Type>
487 (
488  const tmp<Field<Type>>& tmapF,
489  const labelUList& mapAddressing
490 )
491 {
492  rmap(tmapF(), mapAddressing);
493  tmapF.clear();
494 }
495 
496 
497 template<class Type>
499 (
500  const UList<Type>& mapF,
501  const labelUList& mapAddressing,
502  const UList<scalar>& mapWeights
503 )
504 {
505  Field<Type>& f = *this;
506 
507  f = Zero;
508 
509  forAll(mapF, i)
510  {
511  f[mapAddressing[i]] += mapF[i]*mapWeights[i];
512  }
513 }
514 
515 
516 template<class Type>
518 (
519  const tmp<Field<Type>>& tmapF,
520  const labelUList& mapAddressing,
521  const UList<scalar>& mapWeights
522 )
523 {
524  rmap(tmapF(), mapAddressing, mapWeights);
525  tmapF.clear();
526 }
527 
528 
529 template<class Type>
531 {
532  TFOR_ALL_F_OP_OP_F(Type, *this, =, -, Type, *this)
533 }
534 
535 
536 template<class Type>
539 (
540  const direction d
541 ) const
542 {
543  auto tres = tmp<Field<cmptType>>::New(this->size());
544  ::Foam::component(tres.ref(), *this, d);
545  return tres;
546 }
547 
548 
549 template<class Type>
551 (
552  const direction d,
553  const UList<cmptType>& sf
554 )
555 {
556  TFOR_ALL_F_OP_FUNC_S_F(Type, *this, ., replace, const direction, d,
557  cmptType, sf)
558 }
559 
560 
561 template<class Type>
563 (
564  const direction d,
565  const tmp<Field<cmptType>>& tsf
566 )
567 {
568  replace(d, tsf());
569  tsf.clear();
570 }
571 
572 
573 template<class Type>
575 (
576  const direction d,
577  const cmptType& c
578 )
579 {
580  TFOR_ALL_F_OP_FUNC_S_S(Type, *this, ., replace, const direction, d,
581  cmptType, c)
582 }
583 
584 
585 template<class Type>
586 template<class VSForm>
587 VSForm Foam::Field<Type>::block(const label start) const
588 {
589  VSForm vs;
590  for (direction i=0; i<VSForm::nComponents; i++)
591  {
592  vs[i] = this->operator[](start + i);
593  }
594  return vs;
595 }
596 
597 
598 template<class Type>
600 {
601  auto tres = tmp<Field<Type>>::New(this->size());
602  ::Foam::T(tres.ref(), *this);
603  return tres;
604 }
605 
606 
607 template<class Type>
608 void Foam::Field<Type>::writeEntry(const word& keyword, Ostream& os) const
609 {
610  if (keyword.size())
611  {
612  os.writeKeyword(keyword);
613  }
614 
615  // The contents are 'uniform' if the list is non-empty
616  // and all entries have identical values.
617 
619  {
620  os << word("uniform") << token::SPACE << this->first();
621  }
622  else
623  {
624  os << word("nonuniform") << token::SPACE;
626  }
627 
628  os << token::END_STATEMENT << nl;
629 }
630 
631 
632 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
633 
634 template<class Type>
636 {
637  if (this == &rhs)
638  {
639  return; // Self-assignment is a no-op
640  }
641 
643 }
644 
645 
646 template<class Type>
648 {
649  if (this == &(rhs()))
650  {
651  return; // Self-assignment is a no-op
652  }
653 
654  List<Type>::operator=(rhs());
655 }
656 
657 
658 template<class Type>
659 template<class Form, class Cmpt, Foam::direction nCmpt>
661 {
662  TFOR_ALL_F_OP_S(Type, *this, =, VSType, vs)
663 }
664 
665 
666 #define COMPUTED_ASSIGNMENT(TYPE, op) \
667  \
668 template<class Type> \
669 void Foam::Field<Type>::operator op(const UList<TYPE>& f) \
670 { \
671  TFOR_ALL_F_OP_F(Type, *this, op, TYPE, f) \
672 } \
673  \
674 template<class Type> \
675 void Foam::Field<Type>::operator op(const tmp<Field<TYPE>>& tf) \
676 { \
677  operator op(tf()); \
678  tf.clear(); \
679 } \
680  \
681 template<class Type> \
682 void Foam::Field<Type>::operator op(const TYPE& t) \
683 { \
684  TFOR_ALL_F_OP_S(Type, *this, op, TYPE, t) \
685 }
686 
691 
692 #undef COMPUTED_ASSIGNMENT
693 
694 
695 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
696 
697 template<class Type>
699 {
700  os << static_cast<const List<Type>&>(f);
701  return os;
702 }
703 
704 
705 template<class Type>
707 {
708  os << tf();
709  tf.clear();
710  return os;
711 }
712 
713 
714 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
715 
716 #include "FieldFunctions.C"
717 
718 // ************************************************************************* //
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:65
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:403
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:369
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
Default construct.
Definition: FieldI.H:40
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-variant (WORD, DIRECTIVE)
Definition: tokenI.H:609
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:240
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
resize
patchWriters resize(patchIds.size())
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:586
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:52
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:599
Foam::Field::replace
void replace(const direction, const UList< cmptType > &)
Replace a component field of the field.
Definition: Field.C:551
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:466
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:123
Foam::Field::negate
void negate()
Negate this field (negative).
Definition: Field.C:530
os
OBJstream os(runTime.globalPath()/outputName)
Foam::FieldMapper::directAddressing
virtual const labelUList & directAddressing() const
Definition: FieldMapper.H:89
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:539
Foam::Field::operator=
void operator=(const Field< Type > &)
Copy assignment.
Definition: Field.C:635
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:608
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:453
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:404
f
labelList f(nPoints)
contiguous.H
Foam::List< Type >
Foam::pTraits< Type >
Foam::Field::block
VSForm block(const label start) const
Definition: Field.C:587
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
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:473
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
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:340
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:666
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