exprDriverTemplates.C
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) 2010-2018 Bernhard Gschaider
9  Copyright (C) 2019-2022 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 #include "objectRegistry.H"
30 
31 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
32 
33 template<class Type>
34 Type Foam::expressions::exprDriver::exprDriver::weightedAverage
35 (
36  const scalarField& wfield,
37  const Field<Type>& fld
38 )
39 {
40  if (isNull(wfield))
41  {
42  const label n = returnReduce(fld.size(), sumOp<label>());
43 
44  // stabilize
45  if (!n)
46  {
47  return Zero;
48  }
49 
50  return gSum(fld) / scalar(n);
51  }
52 
53  // #ifdef FULLDEBUG
54  // checkSize(wfield, fld);
55  // #endif
56 
57  const scalar s = gSum(wfield);
58 
59  // stabilize
60  if (mag(s) < ROOTVSMALL)
61  {
62  return Zero;
63  }
64 
65  return gSum(wfield*fld) / s;
66 }
67 
68 
69 template<class Type>
70 Type Foam::expressions::exprDriver::exprDriver::weightedSum
71 (
72  const scalarField& wfield,
73  const Field<Type>& fld
74 )
75 {
76  if (isNull(wfield))
77  {
78  return gSum(fld);
79  }
80 
81  // #ifdef FULLDEBUG
82  // checkSize(wfield, fld);
83  // #endif
84 
85  return gSum(wfield*fld);
86 }
87 
88 
89 template<class Type>
92 {
93  if (!result_.isPointData(wantPointData))
94  {
96  << "Expected a" << (wantPointData ? " point" : "")
97  << " field, but found a" << (!wantPointData ? " point" : "")
98  << " field" << nl
99  << exit(FatalError);
100  }
101 
102  return result_.getResult<Type>();
103 }
104 
105 
106 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
107 
108 template<class Type>
109 const Foam::Function1<Type>* Foam::expressions::exprDriver::getFunction1Ptr
110 (
111  const word& name,
112  const HashTable<refPtr<Function1<Type>>>& tbl,
113  wordList* listFailure
114 )
115 {
116  const Function1<Type>* func = nullptr;
117 
118  const auto iter = tbl.cfind(name);
119 
120  if (iter.good())
121  {
122  func = iter.val().get();
123  }
124 
125  if (!func && listFailure)
126  {
127  *listFailure = tbl.sortedToc();
128  }
129 
130  return func;
131 }
132 
133 
134 template<class Type>
136 {
137  // Currently only scalar, vector
138  #undef doLocalCode
139  #define doLocalCode(WhichType, MapperMember) \
140  if (std::is_same<Type, WhichType>::value) \
141  { \
142  return bool \
143  ( \
144  this->template getFunction1Ptr<WhichType> \
145  ( \
146  name, MapperMember \
147  ) \
148  ); \
149  }
150 
151  doLocalCode(scalar, scalarFuncs_);
152  doLocalCode(vector, vectorFuncs_);
153  #undef doLocalCode
155  return false;
156 }
157 
158 
159 template<class Type>
161 (
162  const word& name,
163  const scalar x
164 ) const
165 {
166  const Function1<Type>* func = nullptr;
167 
168  wordList failed;
169 
170  do
171  {
172  // Currently only scalar, vector
173  #undef doLocalCode
174  #define doLocalCode(WhichType, MapperMember) \
175  if (std::is_same<Type, WhichType>::value) \
176  { \
177  const Function1<WhichType>* ptr = \
178  this->template getFunction1Ptr<WhichType> \
179  ( \
180  name, MapperMember, &failed \
181  ); \
182  func = reinterpret_cast<const Function1<Type>*>(ptr); \
183  break; \
184  }
185 
186  doLocalCode(scalar, scalarFuncs_);
187  doLocalCode(vector, vectorFuncs_);
188  #undef doLocalCode
189  }
190  while (false);
191 
192  // Error handling
193  if (!failed.empty())
194  {
196  << "No mapping '" << name << " (" << pTraits<Type>::typeName
197  << ") found." << nl
198  << "Valid entries: "
199  << flatOutput(failed) << nl
200  << exit(FatalError);
201  }
202 
203  if (func)
204  {
205  return func->value(x);
206  }
208  return pTraits<Type>::zero;
209 }
210 
211 
212 template<class Type>
214 (
215  Field<Type>& result,
216  const word& name,
217  const scalarField& input
218 ) const
219 {
220  // #ifdef FULLDEBUG
221  // checkSize(result, input);
222  // #endif
223 
224  const Function1<Type>* func = nullptr;
225 
226  wordList failed;
227 
228  do
229  {
230  // Currently only scalar, vector
231  #undef doLocalCode
232  #define doLocalCode(WhichType, MapperMember) \
233  if (std::is_same<Type, WhichType>::value) \
234  { \
235  const Function1<WhichType>* ptr = \
236  this->template getFunction1Ptr<WhichType> \
237  ( \
238  name, MapperMember, &failed \
239  ); \
240  func = reinterpret_cast<const Function1<Type>*>(ptr); \
241  break; \
242  }
243 
244  doLocalCode(scalar, scalarFuncs_);
245  doLocalCode(vector, vectorFuncs_);
246  #undef doLocalCode
247  }
248  while (false);
249 
250  // Error handling
251  if (!failed.empty())
252  {
254  << "No mapping '" << name << " (" << pTraits<Type>::typeName
255  << ") found." << nl
256  << "Valid entries: "
257  << flatOutput(failed) << nl
258  << exit(FatalError);
259  }
260 
261  if (func)
262  {
263  const label len = min(result.size(), input.size());
264 
265  for (label i = 0; i < len; ++i)
266  {
267  result[i] = func->value(input[i]);
268  }
269 
270  // Safety
271  for (label i = len; i < result.size(); ++i)
272  {
273  result[i] = Zero;
274  }
275 
276  return;
277  }
279  result = Zero;
280 }
281 
282 
283 template<class Type>
285 (
286  const word& name,
287  bool wantPointData,
288  label expectedSize
289 ) const
290 {
291  DebugInfo
292  << "Looking for local" << (wantPointData ? " point" : "")
293  << " field name:" << name << " type:"
294  << pTraits<Type>::typeName << " size:" << expectedSize;
295 
296 
297  bool good = hasVariable(name);
298 
299  if (good)
300  {
301  const exprResult& var = variable(name);
302 
303  DebugInfo
304  << " - found (" << var.valueType()
305  << (var.isPointData() ? " point" : "") << ')';
306 
307  good = (var.isType<Type>() && var.isPointData(wantPointData));
308 
309  // Do size checking if requested
310  if (good && expectedSize >= 0)
311  {
312  good = returnReduceAnd(var.size() == expectedSize);
313 
314  if (debug && !good)
315  {
316  Info<< " size is";
317  }
318  }
319  }
320 
321  DebugInfo << (good ? " good" : " bad") << endl;
322 
323  return good;
324 }
325 
326 
327 template<class Type>
330 (
331  const Type& val
332 ) const
333 {
334  return tmp<Field<Type>>::New(size(), val);
335 }
336 
337 
338 template<class Type>
341 (
342  const Type& val
343 ) const
344 {
345  return tmp<Field<Type>>::New(pointSize(), val);
346 }
347 
348 
349 // ************************************************************************* //
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
tmp< Field< Type > > getResult(bool wantPointData=false)
Return the expression result as a tmp field.
tmp< Field< Type > > newPointField(const Type &val=pTraits< Type >::zero) const
Return a new field with the pointSize()
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
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
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 empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:666
bool isType() const
True if valueType corresponds to the given Type.
Definition: exprResultI.H:214
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
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
tmp< Field< Type > > newField(const Type &val=pTraits< Type >::zero) const
Return a new field with the size()
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.
A class for managing references or pointers (no reference counting)
Definition: HashPtrTable.H:49
bool isFunction(const word &name) const
Named mapping with given type exists.
virtual Type value(const scalar x) const
Return value as a function of (scalar) independent variable.
Definition: Function1.C:62
void fillFunctionValues(Field< Type > &result, const word &name, const scalarField &input) const
Fill result with values remapped according to the named Function1.
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
Type getFunctionValue(const word &name, const scalar x) const
Evaluate named mapping for the given time/value. Zero for undefined/unknown.
Type gSum(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
Generic templated field type.
Definition: Field.H:62
A class for handling words, derived from Foam::string.
Definition: word.H:63
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:33
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
#define DebugInfo
Report an information message using Foam::Info.
bool isNull(const T *ptr)
True if ptr is a pointer (of type T) to the nullObject.
Definition: nullObject.H:227
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
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 doLocalCode(WhichType, MapperMember)
bool isLocalVariable(const word &name, bool wantPointData=false, label expectedSize=-1) const
Test existence of a local variable.
messageStream Info
Information stream (stdout output on master, null elsewhere)
label n
exprResult result_
The result.
Definition: exprDriver.H:201
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
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;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127