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