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 <bgschaid@hfd-research.com>
9  Copyright (C) 2019-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 // * * * * * * * * * * * * 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  setObjectResult(std::move(obj));
222 }
223 
224 
225 template<class Type>
227 :
228  exprResult()
229 {
230  DebugInFunction << nl;
231  setSingleValue(dt.value());
232 }
233 
234 
235 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
236 
238 {
239  return (!valType_.empty() && fieldPtr_ != nullptr);
240 }
241 
242 
244 {
245  return valType_;
246 }
247 
248 
250 (
251  const bool wantPointData
252 ) const
253 {
254  return isPointData_ == wantPointData;
255 }
256 
257 
259 {
260  return isUniform_;
261 }
262 
263 
264 template<class Type>
266 {
267  return valType_ == pTraits<Type>::typeName;
268 }
269 
270 
271 template<class Type>
273 {
274  if (!isUniform_ || !isType<Type>())
275  {
276  return Zero;
277  }
278 
279  return single_.get<Type>();
280 }
281 
282 
284 {
285  return valType_ == pTraits<bool>::typeName;
286 }
287 
288 
290 {
291  return bool(objectPtr_);
292 }
293 
294 
295 inline Foam::label Foam::expressions::exprResult::size() const
296 {
297  return size_;
298 }
299 
300 
301 template<class Type>
303 (
304  const Field<Type>& val,
305  bool wantPointData
306 )
307 {
308  DebugInFunction << nl;
309 
310  target().setResultImpl(val, wantPointData);
311 }
312 
313 
314 template<class Type>
316 (
317  Field<Type>&& val,
318  bool wantPointData
319 )
320 {
321  DebugInFunction << nl;
322 
323  target().setResultImpl(val, wantPointData);
324 }
325 
326 
327 template<class Type>
328 void Foam::expressions::exprResult::setResultImpl
329 (
330  const Field<Type>& fld,
331  bool wantPointData
332 )
333 {
334  DebugInFunction << nl;
335 
336  clear();
337 
338  isUniform_ = false;
339  isPointData_ = wantPointData;
340 
341  size_ = fld.size();
342  valType_ = pTraits<Type>::typeName;
343  fieldPtr_ = new Field<Type>(fld);
344 
345  DebugInFunction << nl;
346 }
347 
348 
349 template<class Type>
350 void Foam::expressions::exprResult::setResultImpl
351 (
352  Field<Type>&& fld,
353  bool wantPointData
354 )
355 {
356  DebugInFunction << nl;
357 
358  clear();
359 
360  isUniform_ = false;
361  isPointData_ = wantPointData;
362 
363  size_ = fld.size();
364  valType_ = pTraits<Type>::typeName;
365  fieldPtr_ = new Field<Type>(std::move(fld));
366 
367  DebugInFunction << nl;
368 }
369 
370 
371 template<class Type>
373 {
374  target().setObjectResultImpl(obj.ptr()); // release()
375 }
376 
377 
378 template<class T>
379 void Foam::expressions::exprResult::setObjectResultImpl(T* ptr)
380 {
381  clear();
382 
383  isUniform_ = false;
384  isPointData_ = false;
385 
386  if (ptr != nullptr)
387  {
388  size_ = ptr->size();
389  valType_ = ptr->typeName;
390  objectPtr_.reset(ptr);
391  }
392 }
393 
394 
395 template<class Type>
397 (
398  Field<Type>* fldPtr,
399  bool wantPointData
400 )
401 {
402  target().setResultImpl(fldPtr, wantPointData);
403 }
404 
405 
406 template<class Type>
407 void Foam::expressions::exprResult::setResultImpl
408 (
409  Field<Type>* fldPtr,
410  bool wantPointData
411 )
412 {
413  clear();
414 
415  isUniform_ = false;
416  isPointData_ = wantPointData;
417 
418  if (fldPtr != nullptr)
419  {
420  size_ = fldPtr->size();
421  valType_ = pTraits<Type>::typeName;
422  fieldPtr_ = fldPtr;
423  }
424 }
425 
426 
427 template<class Type>
429 (
430  const Type& val,
431  const label size
432 )
433 {
434  target().setResultImpl(val, size);
435 }
436 
437 
438 template<class Type>
439 void Foam::expressions::exprResult::setResultImpl
440 (
441  const Type& val,
442  const label len
443 )
444 {
445  DebugInFunction << nl;
446 
447  clear();
448 
449  isPointData_ = false;
450 
451  size_ = len;
452  valType_ = pTraits<Type>::typeName;
453  fieldPtr_ = new Field<Type>(size_, val);
454 
455  isUniform_ = true;
456  single_.set(val);
457 }
458 
459 
460 template<class Type>
462 {
463  target().setSingleValueImpl(val);
464 }
465 
466 
467 template<class Type>
468 bool Foam::expressions::exprResult::writeSingleValueChecked(Ostream& os) const
469 {
470  if (!isType<Type>())
471  {
472  return false;
473  }
474 
475  if (this->size() <= 0)
476  {
477  if (isUniform_)
478  {
479  os << single_.get<Type>();
480  }
481  else
482  {
483  // Zero-sized - could write nothing, or a zero value
484  os << pTraits<Type>::zero;
485  }
486  }
487  else
488  {
489  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
490 
491  os << fld.first();
492  }
493 
494  return true;
495 }
496 
497 
498 template<class Type>
499 bool Foam::expressions::exprResult::writeValueFieldChecked(Ostream& os) const
500 {
501  if (!isType<Type>())
502  {
503  return false;
504  }
505 
506  if (this->size() <= 0)
507  {
508  if (isUniform_)
509  {
510  const Type& val = single_.get<Type>();
511  os.writeEntry("value", val);
512  }
513  else
514  {
515  // Zero-sized
516  const Field<Type> fld;
517  fld.writeEntry("value", os);
518  }
519  }
520  else
521  {
522  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
523 
524  if (isUniform_)
525  {
526  os.writeEntry("value", fld.first());
527  }
528  else
529  {
530  fld.writeEntry("value", os);
531  }
532  }
533 
534  return true;
535 }
536 
537 
538 template<class Type>
539 bool Foam::expressions::exprResult::writeEntryChecked
540 (
541  const word& keyword,
542  Ostream& os
543 ) const
544 {
545  if (!isType<Type>())
546  {
547  return false;
548  }
549 
550  if (this->size() <= 0)
551  {
552  if (isUniform_ && is_contiguous<Type>::value)
553  {
554  const Type& val = single_.get<Type>();
555 
556  if (keyword.size())
557  {
558  os.writeKeyword(keyword);
559  }
560  os << word("uniform") << token::SPACE << val
561  << token::END_STATEMENT << nl;
562  }
563  else
564  {
565  // Zero-sized - written as nonuniform
566  const Field<Type> fld;
567  fld.writeEntry(keyword, os);
568  }
569  }
570  else
571  {
572  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
573 
574  if (isUniform_ && is_contiguous<Type>::value)
575  {
576  if (keyword.size())
577  {
578  os.writeKeyword(keyword);
579  }
580  os << word("uniform") << token::SPACE << fld.first()
581  << token::END_STATEMENT << nl;
582  }
583  else
584  {
585  fld.writeEntry(keyword, os);
586  }
587  }
588 
589  return true;
590 }
591 
592 
593 template<class Type>
594 bool Foam::expressions::exprResult::setAverageValueChecked(const bool parRun)
595 {
596  if (!isType<Type>())
597  {
598  return false;
599  }
600 
601  const Field<Type>& fld = *static_cast<const Field<Type>*>(fieldPtr_);
602 
603  const MinMax<Type> limits = (parRun ? gMinMax(fld) : minMax(fld));
604 
605  isUniform_ = (limits.mag() <= SMALL);
606 
607  const Type avg = limits.centre();
608 
609  single_.set(avg);
610 
611  return true;
612 }
613 
614 
615 template<class Type>
616 bool Foam::expressions::exprResult::duplicateFieldChecked(const void* ptr)
617 {
618  if (!isType<Type>())
619  {
620  return false;
621  }
622 
623  if (fieldPtr_)
624  {
625  deleteChecked<Type>();
626  }
627 
628  const Field<Type>& fld = *static_cast<const Field<Type>*>(ptr);
629 
630  size_ = fld.size();
631  fieldPtr_ = new Field<Type>(fld);
632 
633  return true;
634 }
635 
636 
637 template<class Type>
638 void Foam::expressions::exprResult::setSingleValueImpl(const Type& val)
639 {
640  DebugInFunction << nl;
641 
642  clear();
643 
644  isUniform_ = true;
645  isPointData_ = false;
646 
647  single_.set(val);
648  size_ = 1;
649 
650  valType_ = pTraits<Type>::typeName;
651  fieldPtr_ = new Field<Type>(size_, val);
652 }
653 
654 
655 template<class Type>
658 {
659  DebugInFunction << nl;
660 
661  if (!isType<Type>())
662  {
664  << "The expected return type " << pTraits<Type>::typeName
665  << " is different from the stored result type "
666  << valType_ << nl << nl
667  << exit(FatalError);
668  }
669 
670  if (fieldPtr_ == nullptr)
671  {
673  << "Cannot create tmp from nullptr." << nl
674  << "This error message should never appear!!" << nl
675  << exit(FatalError);
676  }
677 
678  Field<Type>* ptr = static_cast<Field<Type>*>(fieldPtr_);
679 
680  if (cacheCopy)
681  {
682  // Leave field intact, return a duplicate field
683  // Or return reference instead??
684  return tmp<Field<Type>>::New(*ptr);
685  }
686 
687 
688  tmp<Field<Type>> result(ptr);
689 
690  fieldPtr_ = nullptr; // Took ownership of field pointer
691  clear();
692 
693  return result;
694 }
695 
696 
697 template<class Type>
698 inline const Foam::Field<Type>&
700 {
701  DebugInFunction << nl;
702 
703  if (!isType<Type>())
704  {
706  << "The expected return type " << pTraits<Type>::typeName
707  << " is different from the stored result type "
708  << valType_ << nl << nl
709  << exit(FatalError);
710  }
711 
712  if (fieldPtr_ == nullptr)
713  {
715  << "Cannot return reference from nullptr." << nl
716  << "This error message should never appear!!" << nl
717  << exit(FatalError);
718  }
719 
720  return *static_cast<const Field<Type>*>(fieldPtr_);
721 }
722 
723 
724 template<class Type>
725 inline Foam::Field<Type>&
727 {
728  return const_cast<Field<Type>&>(this->cref<Type>());
729 }
730 
731 
732 template<class Type>
733 inline Foam::Field<Type>&
735 {
736  return const_cast<Field<Type>&>(this->cref<Type>());
737 }
738 
739 
740 template<class Type>
741 inline Foam::tmp<Type>
743 {
744  DebugInFunction << nl;
745 
746  if (!isType<Type>())
747  {
749  << "The expected return type " << pTraits<Type>::typeName
750  << " is different from the stored result type "
751  << valType_ << nl << nl
752  << exit(FatalError);
753  }
754 
755  Type* ptr = dynamic_cast<Type*>(objectPtr_.get());
756 
757  if (!ptr)
758  {
760  << "Cannot cast object pointer to " << pTraits<Type>::typeName
761  << nl << nl;
762 
763  return nullptr;
764  }
765 
766  if (cacheCopy)
767  {
768  // Return duplicated content
769  return tmp<Type>::New(*ptr);
770  }
771 
772  objectPtr_.release(); // Take ownership in ptr
773 
774  clear();
775 
776  return tmp<Type>(ptr);
777 }
778 
779 
780 template<template<class> class BinaryOp, class Type>
782 (
783  const BinaryOp<Type>& bop,
784  const Type& initial
785 )
786 {
787  if (!isType<Type>())
788  {
790  << "The expected return type " << pTraits<Type>::typeName
791  << " is different from the stored result type "
792  << valType_ << nl << nl
793  << exit(FatalError);
794  }
795 
796  Type result = initial;
797 
798  const Field<Type>& fld = *static_cast<Field<Type>*>(fieldPtr_);
799 
800  for (const Type& val : fld)
801  {
802  result = bop(result, val);
803  }
804 
805  return returnReduce(result, bop);
806 }
807 
808 
809 // ************************************************************************* //
Foam::sphericalTensor
SphericalTensor< scalar > sphericalTensor
SphericalTensor of scalars, i.e. SphericalTensor<scalar>.
Definition: sphericalTensor.H:54
Foam::expressions::exprResult::isObject
bool isObject() const
True if the object pointer is being used.
Definition: exprResultI.H:289
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::expressions::exprResult::size
label size() const
The field or object size.
Definition: exprResultI.H:295
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:782
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:250
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:604
Foam::expressions::exprResult::valueType
const word & valueType() const
Basic type for the field or single value.
Definition: exprResultI.H:243
Foam::expressions::exprResult::getResult
tmp< Field< Type > > getResult(bool cacheCopy=false)
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:434
Foam::expressions::exprResult::isBool
bool isBool() const
True if valueType is a bool.
Definition: exprResultI.H:283
Foam::expressions::exprResult::setObjectResult
void setObjectResult(autoPtr< Type > &&obj)
Set result object.
Definition: exprResultI.H:372
Foam::expressions::exprResult
A polymorphic field/result from evaluating an expression.
Definition: exprResult.H:128
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:365
Foam::expressions::exprResult::ref
Field< Type > & ref()
Return non-const reference to the field.
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
Foam::expressions::exprResult::setSingleValue
void setSingleValue(const Type &val)
Set single-value uniform result.
Definition: exprResultI.H:461
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:121
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::getObjectResult
tmp< Type > getObjectResult(bool cacheCopy=false)
Foam::expressions::exprResult::hasValue
bool hasValue() const
Has a value?
Definition: exprResultI.H:237
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::expressions::exprResult::isUniform
bool isUniform() const
True if single, uniform value.
Definition: exprResultI.H:258
Foam::FatalError
error FatalError
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:43
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:265
Foam::vector
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:51
Foam::expressions::exprResult::getRef
Field< Type > & getRef() const
Return non-const reference to the field, casting away constness.
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
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::expressions::exprResult::exprResult
exprResult()
Default construct.
Definition: exprResult.C:205
clear
patchWriters clear()
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:54
Foam::token::SPACE
Space [isspace].
Definition: token.H:117
Foam::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
bool
bool
Definition: EEqn.H:20
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:397
Foam::expressions::exprResult::getValue
Type getValue() const
Definition: exprResultI.H:272
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:303
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