Loading...
Searching...
No Matches
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-2025 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// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
30
31template<class Type>
32inline 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
47template<class Type>
48inline 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
83template<class Type>
84bool 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 {
109 WarningInFunction
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
121template<class Type>
122bool 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
139template<class Type>
140bool 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
158template<class Type>
160:
161 exprResult()
162{
164
165 setResult(fld);
166}
167
168
169template<class Type>
171:
172 exprResult()
173{
175
176 setResult(std::move(fld));
177}
178
179
180template<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
198inline 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
220template<class Type>
222{
223 return valType_ == pTraits<Type>::typeName;
224}
225
226
227template<class Type>
229{
230 if (value_.good() && isType<Type>())
231 {
232 return value_.get<Type>();
233 }
235 // Fallthrough
236 return Zero;
237}
238
239
240template<class Type>
242{
243 if (isType<Type>())
244 {
245 return static_cast<const Field<Type>*>(fieldPtr_);
247
248 // Fallthrough
249 return nullptr;
250}
251
254{
255 return valType_ == pTraits<bool>::typeName;
256}
257
258
259inline Foam::label Foam::expressions::exprResult::size() const
260{
261 return size_;
262}
263
264
265template<class Type>
267(
268 const Field<Type>& val,
269 bool wantPointData
270)
271{
273
274 target().setResultImpl(val, wantPointData);
275}
276
277
278template<class Type>
280(
281 Field<Type>&& val,
282 bool wantPointData
283)
284{
286
287 target().setResultImpl(val, wantPointData);
288}
289
290
291template<class Type>
292void Foam::expressions::exprResult::setResultImpl
293(
294 const Field<Type>& fld,
295 bool wantPointData
296)
297{
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
310}
311
312
313template<class Type>
314void Foam::expressions::exprResult::setResultImpl
315(
316 Field<Type>&& fld,
317 bool wantPointData
318)
319{
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));
330
332}
333
334
335template<class Type>
337(
338 Field<Type>* fldPtr,
339 bool wantPointData
340)
341{
342 target().setResultImpl(fldPtr, wantPointData);
343}
344
345
346template<class Type>
347void 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();
362 fieldPtr_ = fldPtr;
363 }
364}
365
366
367template<class Type>
369(
370 const Type& val,
371 const label size
372)
373{
374 target().setResultImpl(val, size);
375}
376
377
378template<class Type>
379void Foam::expressions::exprResult::setResultImpl
380(
381 const Type& val,
382 const label len
383)
384{
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
398template<class Type>
400{
401 target().setSingleValueImpl(val);
402}
403
404
405template<class Type>
406bool 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
436template<class Type>
437bool 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
501template<class Type>
502bool 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_v<Type>)
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_v<Type>)
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
556template<class Type>
557bool 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
581template<class Type>
582bool 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
603template<class Type>
604void Foam::expressions::exprResult::setSingleValueImpl(const Type& val)
605{
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
619template<class Type>
622{
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
661template<class Type>
662inline const Foam::Field<Type>&
664{
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
688template<class Type>
689inline Foam::Field<Type>&
692 return const_cast<Field<Type>&>(this->cref<Type>());
693}
694
695
696template<class Type>
697inline Foam::Field<Type>&
699{
700 return const_cast<Field<Type>&>(this->cref<Type>());
701}
702
703
704template<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// ************************************************************************* //
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Definition Field.H:172
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Generic dimensioned Type class.
const Type & value() const noexcept
Return const reference to value.
A polymorphic field/result from evaluating an expression.
Definition exprResult.H:122
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.
Type getReduced(const BinaryOp< Type > &bop, const Type &initial=pTraits< Type >::zero)
Get a reduced result.
Type getValue() const
Return a single value when isUniform() is true, or Zero when it is non-uniform or if the type mismatc...
tmp< Field< Type > > getResult(bool cacheCopy=false)
Return tmp field of the contents, optionally keeping a copy in cache.
virtual expressions::exprResult & target()
Simulate virtual templated methods.
Definition exprResult.H:307
label size() const
The field or object size.
bool isType() const
True if valueType corresponds to the given Type.
Field< Type > & ref()
Return non-const reference to the field.
bool is_bool() const
True if valueType is a bool.
const Field< Type > & cref() const
Return const reference to the field.
void setSingleValue(const Type &val)
Set single-value uniform result.
const Field< Type > * getField() const
Return a read pointer to the field data if the type matches, nullptr otherwise. Can generally be cons...
void setResult(Field< Type > *, bool wantPointData=false)
Set result field, taking ownership of the pointer.
exprResult()
Default construct.
Definition exprResult.C:173
bool isUniform() const
True if single, uniform value.
bool isPointData(const bool wantPointData=true) const
True if representing point data, or test for same value as wantPointData argument.
bool hasValue() const
Has a value?
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
A class for managing temporary objects.
Definition tmp.H:75
@ SPACE
Space [isspace].
Definition token.H:144
A class for handling words, derived from Foam::string.
Definition word.H:66
auto limits
Definition setRDeltaT.H:186
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
surface1 clear()
#define DebugInFunction
Report an information message using Foam::Info.
Type gAverage(const FieldField< Field, Type > &f, const label comm)
The global arithmetic average of a FieldField.
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.
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
MinMax< label > minMax(const labelHashSet &set)
Find the min/max values of labelHashSet.
Definition hashSets.C:54
MinMax< Type > gMinMax(const FieldField< Field, Type > &f)
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
const direction noexcept
Definition scalarImpl.H:265
bool isType(const U &obj)
Check if typeid of the object and Type are identical.
Definition typeInfo.H:112
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
constexpr bool is_contiguous_v
The is_contiguous value of Type (after stripping of qualifiers).
Definition contiguous.H:77
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &f1, const label comm)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
volScalarField & b
volScalarField & e