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-------------------------------------------------------------------------------
11License
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
31namespace Foam
32{
33namespace 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_);
57
58 #undef defineExpressionMethod
59
60} // End namespace expressions
61} // End namespace Foam
62
63
64// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
65
66template<class Type>
67inline 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
82template<class Type>
83inline 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
119template<class Type>
120bool 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
157template<class Type>
158bool 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
175template<class Type>
176bool 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
194template<class Type>
196:
197 exprResult()
198{
200
201 setResult(fld);
202}
203
204
205template<class Type>
207:
208 exprResult()
209{
211
212 setResult(std::move(fld));
213}
214
215
216template<class Type>
218:
219 exprResult()
220{
222 setSingleValue(dt.value());
223}
224
225
226// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
227
229{
230 return (!valType_.empty() && fieldPtr_ != nullptr);
231}
232
233
234inline 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
256template<class Type>
258{
259 return valType_ == pTraits<Type>::typeName;
260}
261
262
263template<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
281inline Foam::label Foam::expressions::exprResult::size() const
282{
283 return size_;
284}
285
286
287template<class Type>
289(
290 const Field<Type>& val,
291 bool wantPointData
292)
293{
295
296 target().setResultImpl(val, wantPointData);
297}
298
299
300template<class Type>
302(
303 Field<Type>&& val,
304 bool wantPointData
305)
306{
308
309 target().setResultImpl(val, wantPointData);
310}
311
312
313template<class Type>
314void Foam::expressions::exprResult::setResultImpl
315(
316 const Field<Type>& fld,
317 bool wantPointData
318)
319{
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
332}
333
334
335template<class Type>
336void Foam::expressions::exprResult::setResultImpl
337(
339 bool wantPointData
340)
341{
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
354}
355
356
357template<class Type>
359(
360 Field<Type>* fldPtr,
361 bool wantPointData
362)
363{
364 target().setResultImpl(fldPtr, wantPointData);
365}
366
367
368template<class Type>
369void 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
389template<class Type>
391(
392 const Type& val,
393 const label size
394)
395{
396 target().setResultImpl(val, size);
397}
398
399
400template<class Type>
401void Foam::expressions::exprResult::setResultImpl
402(
403 const Type& val,
404 const label len
405)
406{
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
422template<class Type>
424{
425 target().setSingleValueImpl(val);
426}
427
428
429template<class Type>
430bool 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
460template<class Type>
461bool 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
524template<class Type>
525bool 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
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()
568 }
569 else
570 {
571 fld.writeEntry(keyword, os);
572 }
573 }
574
575 return true;
576}
577
578
579template<class Type>
580bool 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
601template<class Type>
602bool 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
623template<class Type>
624void Foam::expressions::exprResult::setSingleValueImpl(const Type& val)
625{
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
641template<class Type>
644{
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
683template<class Type>
684inline const Foam::Field<Type>&
686{
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
710template<class Type>
711inline Foam::Field<Type>&
713{
714 return const_cast<Field<Type>&>(this->cref<Type>());
715}
716
717
718template<class Type>
719inline Foam::Field<Type>&
721{
722 return const_cast<Field<Type>&>(this->cref<Type>());
723}
724
725
726template<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// ************************************************************************* //
Info<< nl<< "Wrote faMesh in vtk format: "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.mesh().time().globalPath()/"finiteArea-edges"));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
Generic templated field type.
Definition: Field.H:82
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Generic dimensioned Type class.
const Type & value() const
Return const reference to value.
A polymorphic field/result from evaluating an expression.
Definition: exprResult.H:127
Field< Type > & constCast() const
Return non-const reference to the field, casting away constness.
const word & valueType() const noexcept
Basic type for the field or single value.
Definition: exprResultI.H:235
Type getReduced(const BinaryOp< Type > &bop, const Type &initial=pTraits< Type >::zero)
Get a reduced result.
Definition: exprResultI.H:728
tmp< Field< Type > > getResult(bool cacheCopy=false)
label size() const
The field or object size.
Definition: exprResultI.H:281
bool isType() const
True if valueType corresponds to the given Type.
Definition: exprResultI.H:257
Field< Type > & ref()
Return non-const reference to the field.
bool is_bool() const
True if valueType is a bool.
Definition: exprResultI.H:275
const Field< Type > & cref() const
Return const reference to the field.
void setSingleValue(const Type &val)
Set single-value uniform result.
Definition: exprResultI.H:423
void setResult(Field< Type > *, bool wantPointData=false)
Set result field, taking ownership of the pointer.
Definition: exprResultI.H:359
exprResult()
Default construct.
Definition: exprResult.C:206
bool isUniform() const
True if single, uniform value.
Definition: exprResultI.H:250
bool hasValue() const
Has a value?
Definition: exprResultI.H:228
bool isPointData() const noexcept
A point field.
A traits class, which is primarily used for primitives.
Definition: pTraits.H:59
Tensor of scalars, i.e. Tensor<scalar>.
A class for managing temporary objects.
Definition: tmp.H:65
@ END_STATEMENT
End entry [isseparator].
Definition: token.H:154
@ SPACE
Space [isspace].
Definition: token.H:125
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
Definition: word.H:68
patchWriters clear()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
#define defineExpressionMethod(Type)
OBJstream os(runTime.globalPath()/outputName)
#define WarningInFunction
Report a warning using Foam::Warning.
#define DebugInFunction
Report an information message using Foam::Info.
Namespace for OpenFOAM.
SphericalTensor< scalar > sphericalTensor
SphericalTensor of scalars, i.e. SphericalTensor<scalar>.
SymmTensor< scalar > symmTensor
SymmTensor of scalars, i.e. SymmTensor<scalar>.
Definition: symmTensor.H:59
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
MinMax< label > minMax(const labelHashSet &set)
Find the min/max values of labelHashSet.
Definition: hashSets.C:61
Type gAverage(const FieldField< Field, Type > &f)
MinMax< Type > gMinMax(const FieldField< Field, Type > &f)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
const direction noexcept
Definition: Scalar.H:223
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
error FatalError
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict
volScalarField & b
Definition: createFields.H:27