Product2.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "Product2.H"
27 
28 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
29 
30 template<class Type, Foam::direction rank>
32 (
33  const unitConversions& units,
34  const dictionary& dict,
35  const Pair<Tuple2<word, label>>& typeAndRanks
36 )
37 :
38  ProductFunction1s<Type, rank - 1>(units, dict, typeAndRanks)
39 {
40  forAll(fs, i)
41  {
42  if (typeAndRanks[i].second() == rank)
43  {
44  fs[i] =
46  (
47  valueName(i, typeAndRanks[i]),
48  {i ? units.y : units.x, unitAny},
49  dict
50  );
51  }
52  }
53 }
54 
55 
56 template<class Type>
58 (
59  const unitConversions& units,
60  const dictionary& dict,
61  const Pair<Tuple2<word, label>>& typeAndRanks
62 )
63 {
64  forAll(fs, i)
65  {
66  if (typeAndRanks[i].second() == 0)
67  {
68  fs[i] =
70  (
71  valueName(i, typeAndRanks[i]),
72  {i ? units.y : units.x, unitAny},
73  dict
74  );
75  }
76  }
77 }
78 
79 
80 template<class Type, Foam::direction rank>
82 (
84 )
85 :
86  ProductFunction1s<Type, rank - 1>(p2f1s),
87  fs
88  (
89  autoPtr<function1Type>(p2f1s.fs.first(), false),
90  autoPtr<function1Type>(p2f1s.fs.second(), false)
91  )
92 {}
93 
94 
95 template<class Type>
97 (
98  const ProductFunction1s<Type, 0>& p2f1s
99 )
100 :
101  fs
102  (
103  autoPtr<Function1<scalar>>(p2f1s.fs.first(), false),
104  autoPtr<Function1<scalar>>(p2f1s.fs.second(), false)
105  )
106 {}
107 
108 
109 template<class Type>
111 (
112  const word& name,
113  const unitConversions& units,
114  const dictionary& dict
115 )
116 :
117  FieldFunction2<Type, Product<Type>>(name),
118  fs_(units, dict, lookupValueTypeAndRanks<Type>(dict))
119 {}
120 
121 
122 template<class Type>
124 :
125  FieldFunction2<Type, Product<Type>>(se),
126  fs_(se.fs_)
127 {}
128 
129 
130 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
131 
132 template<class Type>
134 {}
135 
136 
137 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
138 
139 template<class Type, Foam::direction rank>
141 (
142  Ostream& os,
143  const unitConversions& units
144 ) const
145 {
147 
148  forAll(fs, i)
149  {
150  if (fs[i].valid())
151  {
152  writeEntry(os, {i ? units.y : units.x, unitAny}, fs[i]());
153  }
154  }
155 }
156 
157 
158 template<class Type>
160 (
161  Ostream& os,
162  const unitConversions& units
163 ) const
164 {
165  forAll(fs, i)
166  {
167  if (fs[i].valid())
168  {
169  writeEntry(os, {i ? units.y : units.x, unitAny}, fs[i]());
170  }
171  }
172 }
173 
174 
175 template<class Type>
177 (
178  Ostream& os,
179  const unitConversions& units
180 ) const
181 {
182  fs_.write(os, units);
183 }
184 
185 
186 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
187 
188 template<class Type, class ValueType>
190 (
191  const dictionary& dict,
192  const direction argument,
193  Tuple2<word, label>& typeAndRank,
194  label& found
195 )
196 {
197  if (dict.found(valueName<ValueType>(argument)))
198  {
199  if (found != -1)
200  {
202  << "Multiple " << valueName(argument) << " and/or "
203  << valueName(argument, "Type") << "-s specified"
204  << exit(FatalIOError);
205  }
206 
207  typeAndRank =
209  (
212  );
213 
215  }
216 }
217 
218 
219 template<class Type>
221 (
222  const dictionary& dict,
223  const direction argument
224 )
225 {
226  Tuple2<word, label> typeAndRank(word::null, -1);
227  label found = dict.found(valueName(argument)) ? 1 : -1;
228 
229  #define LOOKUP_VALUE_TYPE_AND_RANK(ValueType, nullArg) \
230  lookupValueTypeAndRank<Type, ValueType> \
231  ( \
232  dict, \
233  argument, \
234  typeAndRank, \
235  found \
236  );
238  #undef LOOKUP_VALUE_TYPE_AND_RANK
239 
240  if (found == -1)
241  {
243  << "Function " << valueName(argument)
244  << " undefined in dictionary " << dict.name()
245  << exit(FatalIOError);
246  }
247 
248  if (found == 0)
249  {
251  << "Function " << valueName(argument, typeAndRank)
252  << " returns a type that cannot be used to produce a product"
253  << " of type " << pTraits<Type>::typeName
254  << exit(FatalIOError);
255  }
256 
257  return typeAndRank;
258 }
259 
260 
261 template<class Type>
264 {
265  Pair<Tuple2<word, label>> typeAndRanks
266  (
267  lookupValueTypeAndRank<Type>(dict, 0),
268  lookupValueTypeAndRank<Type>(dict, 1)
269  );
270 
271  // If this is a non-scalar type then at least one of the value entries must
272  // have specified the type
273  if
274  (
275  pTraits<Type>::rank > 0
276  && typeAndRanks.first().second() == -1
277  && typeAndRanks.second().second() == -1
278  )
279  {
281  << "One of the functions " << valueName(0) << " and "
282  << valueName(1) << " needs to specify the return type, e.g., as "
283  << valueName<Type>(0) << exit(FatalIOError);
284  }
285 
286  // If both types are specified then the sum of their ranks must equal the
287  // rank of the function
288  if
289  (
290  typeAndRanks.first().second() != -1
291  && typeAndRanks.second().second() != -1
292  && typeAndRanks.first().second()
293  + typeAndRanks.second().second()
294  != pTraits<Type>::rank
295  )
296  {
298  << "The functions " << valueName(0, typeAndRanks.first())
299  << " and " << valueName(1, typeAndRanks.second()) << " return "
300  << "types for which the product is not of type "
301  << pTraits<Type>::typeName << exit(FatalIOError);
302  }
303 
304  // If this is a scalar type, then neither entry needs to specify the type.
305  // They both must be scalars.
306  if
307  (
308  pTraits<Type>::rank == 0
309  && typeAndRanks.first().second() == -1
310  && typeAndRanks.second().second() == -1
311  )
312  {
313  typeAndRanks.first().second() = 0;
314  typeAndRanks.second().second() = 0;
315  }
316 
317  // Determine remaining unspecified ranks
318  forAll(typeAndRanks, i)
319  {
320  if (typeAndRanks[i].second() == -1)
321  {
322  typeAndRanks[i].second() =
323  pTraits<Type>::rank - typeAndRanks[!i].second();
324  }
325  }
326 
327  return typeAndRanks;
328 }
329 
330 
331 // ************************************************************************* //
#define LOOKUP_VALUE_TYPE_AND_RANK(ValueType, nullArg)
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Run-time selectable general function of one variable.
Definition: Function1.H:125
static autoPtr< Function1< Type > > New(const word &name, const Function1s::unitConversions &units, const dictionary &dict)
Select from dictionary.
Definition: Function1New.C:32
Pair< autoPtr< function1Type > > fs
Functions.
Definition: Product2.H:170
void write(Ostream &os, const unitConversions &units) const
Write to a stream.
Definition: Product2.C:141
ProductFunction1s(const unitConversions &units, const dictionary &dict, const Pair< Tuple2< word, label >> &typeAndRanks)
Construct from a dictionary.
Definition: Product2.C:32
Function2 which returns the product of two independent Function1-s of the two input arguments....
Definition: Product2.H:244
virtual ~Product()
Destructor.
Definition: Product2.C:133
virtual void write(Ostream &os, const unitConversions &units) const
Write in dictionary format.
Definition: Product2.C:177
Product(const word &name, const unitConversions &units, const dictionary &dict)
Construct from name and dictionary.
Definition: Product2.C:111
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:65
A 2-tuple for storing two objects of different types.
Definition: Tuple2.H:66
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
Traits class for primitives.
Definition: pTraits.H:53
A class for handling words, derived from string.
Definition: word.H:62
static const word null
An empty word.
Definition: word.H:77
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
void lookupValueTypeAndRank(const dictionary &dict, const direction argument, Tuple2< word, label > &typeAndRank, label &found)
Lookup the type and rank for the value entry for the given argument.
Definition: Product2.C:190
Pair< Tuple2< word, label > > lookupValueTypeAndRanks(const dictionary &dict)
Lookup the types and ranks for the value entries.
word valueName(const direction argument)
Return the name of the value entry for the given argument.
Definition: Product2I.H:81
bool valid(const PtrList< ModelType > &l)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
const unitConversion unitAny
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
labelList second(const UList< labelPair > &p)
Definition: patchToPatch.C:49
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
const HashTable< unitConversion > & units()
Get the table of unit conversions.
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
IOerror FatalIOError
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)
uint8_t direction
Definition: direction.H:45
dictionary dict