exprResultI.H
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) 2012-2018 Bernhard Gschaider
9  Copyright (C) 2019-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 // * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
33 namespace expressions
34 {
35  #undef defineExpressionMethod
36  #define defineExpressionMethod(Type, Member) \
37  template<> \
38  inline const Type& exprResult::singleValue::get<Type>() const \
39  { \
40  return Member; \
41  } \
42  \
43  template<> \
44  inline const Type& exprResult::singleValue::set(const Type& val) \
45  { \
46  Member = val; \
47  return Member; \
48  }
49 
50  defineExpressionMethod(bool, bool_);
51  defineExpressionMethod(label, label_);
52  defineExpressionMethod(scalar, scalar_);
55  defineExpressionMethod(symmTensor, symmTensor_);
57 
58  #undef defineExpressionMethod
59 
60 } // End namespace expressions
61 } // End namespace Foam
62 
63 
64 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
65 
66 template<class Type>
67 inline bool Foam::expressions::exprResult::deleteChecked()
68 {
69  const bool ok = isType<Type>();
70 
71  if (ok && fieldPtr_ != nullptr)
72  {
73  delete static_cast<Field<Type>*>(fieldPtr_);
74  fieldPtr_ = nullptr;
75  size_ = 0;
76  }
77 
78  return ok;
79 }
80 
81 
82 template<class Type>
83 inline bool Foam::expressions::exprResult::readChecked
84 (
85  const word& key,
86  const dictionary& dict,
87  const label len,
88  const bool uniform
89 )
90 {
91  const bool ok = isType<Type>();
92 
93  if (ok)
94  {
95  uglyDelete();
96 
97  if (uniform)
98  {
99  const Type val(dict.get<Type>(key));
100 
101  size_ = len;
102  fieldPtr_ = new Field<Type>(size_, val);
103 
104  single_.set(val);
105  }
106  else
107  {
108  size_ = len;
109  fieldPtr_ = new Field<Type>(key, dict, size_);
110  }
111 
112  isUniform_ = uniform;
113  }
114 
115  return ok;
116 }
117 
118 
119 template<class Type>
120 bool Foam::expressions::exprResult::getUniformChecked
121 (
122  exprResult& result,
123  const label size,
124  const bool noWarn,
125  const bool parRun
126 ) const
127 {
128  if (!isType<Type>())
129  {
130  return false;
131  }
132 
133  result.clear();
134 
135  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
136 
137  const Type avg = (parRun ? gAverage(fld) : average(fld));
138 
139  if (!noWarn)
140  {
141  const MinMax<Type> limits = (parRun ? gMinMax(fld) : minMax(fld));
142 
143  if (limits.mag() > SMALL)
144  {
146  << "Different min/max values: " << limits
147  << " Using the average " << avg << nl;
148  }
149  }
150 
151  result.setResult(avg, size);
152 
153  return true;
154 }
155 
156 
157 template<class Type>
158 bool Foam::expressions::exprResult::plusEqChecked
159 (
160  const exprResult& b
161 )
162 {
163  const bool ok = isType<Type>();
164 
165  if (ok)
166  {
167  *static_cast<Field<Type>*>(fieldPtr_)
168  += *static_cast<const Field<Type>*>(b.fieldPtr_);
169  }
170 
171  return ok;
172 }
173 
174 
175 template<class Type>
176 bool Foam::expressions::exprResult::multiplyEqChecked
177 (
178  const scalar& b
179 )
180 {
181  const bool ok = isType<Type>();
182 
183  if (ok)
184  {
185  *static_cast<Field<Type>*>(fieldPtr_) *= b;
186  }
187 
188  return ok;
189 }
190 
191 
192 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
193 
194 template<class Type>
196 :
197  exprResult()
198 {
199  DebugInFunction << nl;
200 
201  setResult(fld);
202 }
203 
204 
205 template<class Type>
207 :
208  exprResult()
209 {
210  DebugInFunction << nl;
211 
212  setResult(std::move(fld));
213 }
214 
215 
216 template<class Type>
218 :
219  exprResult()
220 {
221  DebugInFunction << nl;
222  setSingleValue(dt.value());
223 }
224 
225 
226 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
227 
229 {
230  return (!valType_.empty() && fieldPtr_ != nullptr);
231 }
232 
233 
234 inline const Foam::word&
236 {
237  return valType_;
238 }
239 
240 
242 (
243  const bool wantPointData
244 ) const
245 {
246  return isPointData_ == wantPointData;
247 }
248 
249 
251 {
252  return isUniform_;
253 }
254 
255 
256 template<class Type>
258 {
259  return valType_ == pTraits<Type>::typeName;
260 }
261 
262 
263 template<class Type>
265 {
266  if (!isUniform_ || !isType<Type>())
267  {
268  return Zero;
269  }
270 
271  return single_.get<Type>();
272 }
273 
274 
276 {
277  return valType_ == pTraits<bool>::typeName;
278 }
279 
280 
281 inline Foam::label Foam::expressions::exprResult::size() const
282 {
283  return size_;
284 }
285 
286 
287 template<class Type>
289 (
290  const Field<Type>& val,
291  bool wantPointData
292 )
293 {
294  DebugInFunction << nl;
295 
296  target().setResultImpl(val, wantPointData);
297 }
298 
299 
300 template<class Type>
302 (
303  Field<Type>&& val,
304  bool wantPointData
305 )
306 {
307  DebugInFunction << nl;
308 
309  target().setResultImpl(val, wantPointData);
310 }
311 
312 
313 template<class Type>
314 void Foam::expressions::exprResult::setResultImpl
315 (
316  const Field<Type>& fld,
317  bool wantPointData
318 )
319 {
320  DebugInFunction << nl;
321 
322  clear();
323 
324  isUniform_ = false;
325  isPointData_ = wantPointData;
326 
327  size_ = fld.size();
328  valType_ = pTraits<Type>::typeName;
329  fieldPtr_ = new Field<Type>(fld);
330 
331  DebugInFunction << nl;
332 }
333 
334 
335 template<class Type>
336 void Foam::expressions::exprResult::setResultImpl
337 (
338  Field<Type>&& fld,
339  bool wantPointData
340 )
341 {
342  DebugInFunction << nl;
343 
344  clear();
345 
346  isUniform_ = false;
347  isPointData_ = wantPointData;
348 
349  size_ = fld.size();
350  valType_ = pTraits<Type>::typeName;
351  fieldPtr_ = new Field<Type>(std::move(fld));
352 
353  DebugInFunction << nl;
354 }
355 
356 
357 template<class Type>
359 (
360  Field<Type>* fldPtr,
361  bool wantPointData
362 )
363 {
364  target().setResultImpl(fldPtr, wantPointData);
365 }
366 
367 
368 template<class Type>
369 void Foam::expressions::exprResult::setResultImpl
370 (
371  Field<Type>* fldPtr,
372  bool wantPointData
373 )
374 {
375  clear();
376 
377  isUniform_ = false;
378  isPointData_ = wantPointData;
379 
380  if (fldPtr != nullptr)
381  {
382  size_ = fldPtr->size();
383  valType_ = pTraits<Type>::typeName;
384  fieldPtr_ = fldPtr;
385  }
386 }
387 
388 
389 template<class Type>
391 (
392  const Type& val,
393  const label size
394 )
395 {
396  target().setResultImpl(val, size);
397 }
398 
399 
400 template<class Type>
401 void Foam::expressions::exprResult::setResultImpl
402 (
403  const Type& val,
404  const label len
405 )
406 {
407  DebugInFunction << nl;
408 
409  clear();
410 
411  isPointData_ = false;
412 
413  size_ = len;
414  valType_ = pTraits<Type>::typeName;
415  fieldPtr_ = new Field<Type>(size_, val);
416 
417  isUniform_ = true;
418  single_.set(val);
419 }
420 
421 
422 template<class Type>
424 {
425  target().setSingleValueImpl(val);
426 }
427 
428 
429 template<class Type>
430 bool Foam::expressions::exprResult::writeSingleValueChecked(Ostream& os) const
431 {
432  if (!isType<Type>())
433  {
434  return false;
435  }
436 
437  if (this->size() <= 0)
438  {
439  if (isUniform_)
440  {
441  os << single_.get<Type>();
442  }
443  else
444  {
445  // Zero-sized - could write nothing, or a zero value
446  os << pTraits<Type>::zero;
447  }
448  }
449  else
450  {
451  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
452 
453  os << fld.first();
454  }
455 
456  return true;
457 }
458 
459 
460 template<class Type>
461 bool Foam::expressions::exprResult::writeFieldChecked
462 (
463  const word& keyword,
464  Ostream& os
465 ) const
466 {
467  if (!isType<Type>())
468  {
469  return false;
470  }
471 
472  if (this->size() <= 0)
473  {
474  if (isUniform_)
475  {
476  const Type& val = single_.get<Type>();
477  if (keyword.empty())
478  {
479  os << val;
480  }
481  else
482  {
483  os.writeEntry(keyword, val);
484  }
485  }
486  else
487  {
488  // Zero-sized - could write nothing, or a zero value
489  if (keyword.empty())
490  {
491  os << pTraits<Type>::zero;
492  }
493  else
494  {
495  Field<Type>().writeEntry(keyword, os);
496  }
497  }
498  }
499  else
500  {
501  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
502 
503  if (keyword.empty())
504  {
505  os << fld;
506  }
507  else
508  {
509  if (isUniform_)
510  {
511  os.writeEntry(keyword, fld.first());
512  }
513  else
514  {
515  fld.writeEntry(keyword, os);
516  }
517  }
518  }
519 
520  return true;
521 }
522 
523 
524 template<class Type>
525 bool Foam::expressions::exprResult::writeEntryChecked
526 (
527  const word& keyword,
528  Ostream& os
529 ) const
530 {
531  if (!isType<Type>())
532  {
533  return false;
534  }
535 
536  if (this->size() <= 0)
537  {
538  if (isUniform_ && is_contiguous<Type>::value)
539  {
540  const Type& val = single_.get<Type>();
541 
542  if (keyword.size())
543  {
544  os.writeKeyword(keyword);
545  }
546  os << word("uniform") << token::SPACE << val
547  << token::END_STATEMENT << nl;
548  }
549  else
550  {
551  // Zero-sized - written as nonuniform
552  const Field<Type> fld;
553  fld.writeEntry(keyword, os);
554  }
555  }
556  else
557  {
558  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
559 
560  if (isUniform_ && is_contiguous<Type>::value)
561  {
562  if (keyword.size())
563  {
564  os.writeKeyword(keyword);
565  }
566  os << word("uniform") << token::SPACE << fld.first()
567  << token::END_STATEMENT << nl;
568  }
569  else
570  {
571  fld.writeEntry(keyword, os);
572  }
573  }
574 
575  return true;
576 }
577 
578 
579 template<class Type>
580 bool Foam::expressions::exprResult::setAverageValueChecked(const bool parRun)
581 {
582  if (!isType<Type>())
583  {
584  return false;
585  }
586 
587  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
588 
589  const MinMax<Type> limits = (parRun ? gMinMax(fld) : minMax(fld));
590 
591  isUniform_ = (limits.mag() <= SMALL);
592 
593  const Type avg = limits.centre();
594 
595  single_.set(avg);
596 
597  return true;
598 }
599 
600 
601 template<class Type>
602 bool Foam::expressions::exprResult::duplicateFieldChecked(const void* ptr)
603 {
604  if (!isType<Type>())
605  {
606  return false;
607  }
608 
609  if (fieldPtr_)
610  {
611  deleteChecked<Type>();
612  }
613 
614  const Field<Type>& fld = *static_cast<const Field<Type>*>(ptr);
615 
616  size_ = fld.size();
617  fieldPtr_ = new Field<Type>(fld);
618 
619  return true;
620 }
621 
622 
623 template<class Type>
624 void Foam::expressions::exprResult::setSingleValueImpl(const Type& val)
625 {
626  DebugInFunction << nl;
627 
628  clear();
629 
630  isUniform_ = true;
631  isPointData_ = false;
632 
633  single_.set(val);
634  size_ = 1;
635 
636  valType_ = pTraits<Type>::typeName;
637  fieldPtr_ = new Field<Type>(size_, val);
638 }
639 
640 
641 template<class Type>
644 {
645  DebugInFunction << nl;
646 
647  if (!isType<Type>())
648  {
650  << "The expected return type " << pTraits<Type>::typeName
651  << " is different from the stored result type "
652  << valType_ << nl << nl
653  << exit(FatalError);
654  }
655 
656  if (fieldPtr_ == nullptr)
657  {
659  << "Cannot create tmp from nullptr." << nl
660  << "This error message should never appear!!" << nl
661  << exit(FatalError);
662  }
663 
664  Field<Type>* ptr = static_cast<Field<Type>*>(fieldPtr_);
665 
666  if (cacheCopy)
667  {
668  // Leave field intact, return a duplicate field
669  // Or return reference instead??
670  return tmp<Field<Type>>::New(*ptr);
671  }
672 
673 
674  tmp<Field<Type>> result(ptr);
675 
676  fieldPtr_ = nullptr; // Took ownership of field pointer
677  clear();
678 
679  return result;
680 }
681 
682 
683 template<class Type>
684 inline const Foam::Field<Type>&
686 {
687  DebugInFunction << nl;
688 
689  if (!isType<Type>())
690  {
692  << "The expected return type " << pTraits<Type>::typeName
693  << " is different from the stored result type "
694  << valType_ << nl << nl
695  << exit(FatalError);
696  }
697 
698  if (fieldPtr_ == nullptr)
699  {
701  << "Cannot return reference from nullptr." << nl
702  << "This error message should never appear!!" << nl
703  << exit(FatalError);
704  }
705 
706  return *static_cast<const Field<Type>*>(fieldPtr_);
707 }
708 
709 
710 template<class Type>
711 inline Foam::Field<Type>&
713 {
714  return const_cast<Field<Type>&>(this->cref<Type>());
715 }
716 
717 
718 template<class Type>
719 inline Foam::Field<Type>&
721 {
722  return const_cast<Field<Type>&>(this->cref<Type>());
723 }
724 
725 
726 template<template<class> class BinaryOp, class Type>
728 (
729  const BinaryOp<Type>& bop,
730  const Type& initial
731 )
732 {
733  if (!isType<Type>())
734  {
736  << "The expected return type " << pTraits<Type>::typeName
737  << " is different from the stored result type "
738  << valType_ << nl << nl
739  << exit(FatalError);
740  }
741 
742  Type result = initial;
743 
744  const Field<Type>& fld = *static_cast<Field<Type>*>(fieldPtr_);
745 
746  for (const Type& val : fld)
747  {
748  result = bop(result, val);
749  }
750 
751  return returnReduce(result, bop);
752 }
753 
754 
755 // ************************************************************************* //
Foam::sphericalTensor
SphericalTensor< scalar > sphericalTensor
SphericalTensor of scalars, i.e. SphericalTensor<scalar>.
Definition: sphericalTensor.H:54
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::expressions::exprResult::size
label size() const
The field or object size.
Definition: exprResultI.H:281
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::expressions::exprResult::getReduced
Type getReduced(const BinaryOp< Type > &bop, const Type &initial=pTraits< Type >::zero)
Get a reduced result.
Definition: exprResultI.H:728
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::expressions::exprResult::isPointData
bool isPointData(const bool wantPointData=true) const
Definition: exprResultI.H:242
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:604
Foam::expressions::exprResult::getResult
tmp< Field< Type > > getResult(bool cacheCopy=false)
Foam::glTF::key
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:108
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:434
Foam::expressions::exprResult::constCast
Field< Type > & constCast() const
Return non-const reference to the field, casting away constness.
Foam::expressions::exprResult
A polymorphic field/result from evaluating an expression.
Definition: exprResult.H:124
Foam::expressions::exprResult::valueType
const word & valueType() const noexcept
Basic type for the field or single value.
Definition: exprResultI.H:235
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::Field
Generic templated field type.
Definition: Field.H:63
defineExpressionMethod
#define defineExpressionMethod(Type, Member)
Definition: exprResultI.H:36
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
Foam::expressions::exprResult::ref
Field< Type > & ref()
Return non-const reference to the field.
Foam::expressions::exprResult::setSingleValue
void setSingleValue(const Type &val)
Set single-value uniform result.
Definition: exprResultI.H:423
Foam::symmTensor
SymmTensor< scalar > symmTensor
SymmTensor of scalars, i.e. SymmTensor<scalar>.
Definition: symmTensor.H:59
Foam::token::END_STATEMENT
End entry [isseparator].
Definition: token.H:154
fld
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputLagrangian.H:23
Foam::expressions::exprResult::hasValue
bool hasValue() const
Has a value?
Definition: exprResultI.H:228
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::expressions::exprResult::isUniform
bool isUniform() const
True if single, uniform value.
Definition: exprResultI.H:250
Foam::FatalError
error FatalError
os
OBJstream os(runTime.globalPath()/outputName)
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:42
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::expressions::exprResult::cref
const Field< Type > & cref() const
Return const reference to the field.
Foam::expressions::exprResult::isType
bool isType() const
True if valueType corresponds to the given Type.
Definition: exprResultI.H:257
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
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::expressions::exprResult::exprResult
exprResult()
Default construct.
Definition: exprResult.C:206
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::pTraits
A traits class, which is primarily used for primitives.
Definition: pTraits.H:56
Foam::token::SPACE
Space [isspace].
Definition: token.H:125
Foam::minMax
MinMax< label > minMax(const labelHashSet &set)
Find the min/max values of labelHashSet.
Definition: hashSets.C:61
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::expressions::exprResult::setResult
void setResult(Field< Type > *, bool wantPointData=false)
Set result field, taking ownership of the pointer.
Definition: exprResultI.H:359
Foam::expressions::exprResult::getValue
Type getValue() const
Definition: exprResultI.H:264
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::expressions::exprResult::is_bool
bool is_bool() const
True if valueType is a bool.
Definition: exprResultI.H:275
Foam::tensor
Tensor< scalar > tensor
Tensor of scalars, i.e. Tensor<scalar>.
Definition: symmTensor.H:61
Foam::average
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:328
Foam::gMinMax
MinMax< Type > gMinMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:595