unitSetTemplates.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-2026 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 "scaleable.H"
27 #include "unitSet.H"
28 #include "typeName.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
32 template<class T>
33 T Foam::unitSet::toStandard(const T& t) const
34 {
35  return standard() ? t : t*multiplier_;
36 }
37 
38 
39 template<class T>
41 {
42  if (!standard())
43  {
44  t *= multiplier_;
45  }
46 }
47 
48 
49 template<class T>
50 T Foam::unitSet::toUser(const T& t) const
51 {
52  return standard() ? t : t/multiplier_;
53 }
54 
55 
56 template<class T>
57 void Foam::unitSet::makeUser(T& t) const
58 {
59  if (!standard())
60  {
61  t *= 1/multiplier_;
62  }
63 }
64 
65 
66 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
67 
68 template<class Type, class Convert>
70 (
71  Type& t,
72  const unitSet& units,
73  const Convert& convert
74 )
75 {
76  convert(t, units);
77 }
78 
79 
80 template<class Type>
81 const typename Foam::typeUnitsType<Type>::type&
82 Foam::typeUnits(const unitSet& units)
83 {
84  return units;
85 }
86 
87 
88 template<class Type>
90 Foam::typeUnits(const dimensionSet& dimensions)
91 {
92  return dimensions;
93 }
94 
95 
96 template<>
98 Foam::typeUnits<Foam::label>(const unitSet& units)
99 {
100  typeUnits<label>(units.dimensions());
101 
102  if (!units.standard())
103  {
105  << "Unit conversions are not supported for "
106  << pTraits<label>::typeName << "s"
107  << exit(FatalError);
108  }
109 
110  static const Foam::nil nil;
111 
112  return nil;
113 }
114 
115 
116 template<>
118 Foam::typeUnits<Foam::label>(const dimensionSet& dimensions)
119 {
120  if (!dimensions.dimensionless())
121  {
123  << pTraits<label>::typeName << "s must be dimensionless"
124  << exit(FatalError);
125  }
126 
127  return nil();
128 }
129 
130 
131 template<class Type>
132 Type Foam::readAndConvert(Istream& is, const unitSet& defaultUnits)
133 {
134  // Read the units if they are before the value
135  unitSet units(defaultUnits);
136  const bool haveUnits = units.readIfPresent(is);
137 
138  // Read the value
139  Type value = Foam::read<Type>(is);
140 
141  // Read the units if they are after the value
142  if (!haveUnits && !is.eof())
143  {
144  units.readIfPresent(is);
145  }
146 
147  // Modify the value by the unit conversion
148  convert(value, units, unitSet::makeStandardOp());
149 
150  return value;
151 }
152 
153 
154 template<class Type>
155 Type Foam::readAndConvert(Istream& is, const dimensionSet& dimensions)
156 {
157  return readAndConvert<Type>(is, unitSet(dimensions));
158 }
159 
160 
161 template<class Type, class Units>
162 Type Foam::readAndConvert(Istream& is, const Units& defaultUnits)
163 {
164  // Read the value
165  Type value = Foam::read<Type>(is);
166 
167  // If there is more then read units and use them to convert the value
168  if (!is.eof())
169  {
170  Units units(defaultUnits);
171  units.read(is);
172  convert(value, units, unitSet::makeStandardOp());
173  }
174  // Otherwise convert the value using the default units
175  else
176  {
177  convert(value, defaultUnits, unitSet::makeStandardOp());
178  }
179 
180  return value;
181 }
182 
183 
184 template<class Type>
186 {
187  auto error = [&]()
188  {
190  << "Unit conversion is not supported for entries of type "
192  };
193 
194  unitSet units(unitSet::newAny());
195 
196  if (units.readIfPresent(is)) error();
197 
198  const Type value = Foam::read<Type>(is);
199 
200  if (!is.eof() && units.readIfPresent(is)) error();
201 
202  return value;
203 }
204 
205 
206 template<class Type>
208 {
209  return readAndConvert<Type>(is, unitSet::newAny());
210 }
211 
212 
213 template<class Type>
215 {
216  return readAndConvert<Type>(is, nil());
217 }
218 
219 
220 template<>
221 inline Foam::unitSet Foam::readAndMaybeConvert<Foam::unitSet>
222 (
223  Istream& is
224 )
225 {
226  return unitSet(is);
227 }
228 
229 
230 template<>
231 inline Foam::dimensionSet Foam::readAndMaybeConvert<Foam::dimensionSet>
232 (
233  Istream& is
234 )
235 {
236  return dimensionSet(is);
237 }
238 
239 
240 template<class Type>
241 void Foam::writeEntry(Ostream& os, const unitSet& defaultUnits, const Type& t)
242 {
243  if (defaultUnits.standard())
244  {
245  writeEntry(os, t);
246  }
247  else
248  {
249  Type tUser(t);
250  convert(tUser, defaultUnits, unitSet::makeUserOp());
251  return writeEntry(os, tUser);
252  }
253 }
254 
255 
256 template<class Type>
257 void Foam::writeEntry(Ostream& os, const nil&, const Type& t)
258 {
259  writeEntry(os, t);
260 }
261 
262 
263 // ************************************************************************* //
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:60
bool eof() const
Return true if end of input seen.
Definition: Istream.H:107
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
Dimension set for the base types.
Definition: dimensionSet.H:125
Class to handle errors and exceptions in a simple, consistent stream-based manner.
Definition: error.H:71
A zero-sized class without any storage. Used, for example, in HashSet.
Definition: nil.H:59
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
Unit conversion structure. Contains the associated dimensions and the multiplier with which to conver...
Definition: unitSet.H:68
static unitSet newAny()
Return a new "any" unit set.
Definition: unitSetI.H:36
bool readIfPresent(const word &keyword, const dictionary &)
Update if found in the dictionary.
Definition: unitSetIO.C:106
T toUser(const T &) const
Convert a value to user units.
void makeStandard(T &) const
Convert a value to standard units.
bool standard() const
Return whether this unit is standard. I.e., is its multiplier one?
Definition: unitSetI.H:74
T toStandard(const T &) const
Convert a value to standard units.
void makeUser(T &) const
Convert a value to user units.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
std::enable_if_t<!scaleable< Type >::value, Void > enableIfNotScaleable
Definition: scaleable.H:56
std::enable_if_t< std::is_same< scalar, typename pTraits< Type >::cmptType >::value, Void > enableIfScalarCmptType
Definition: scalar.H:196
const typeUnitsType< label >::type & typeUnits< label >(const unitSet &)
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
Type readAndConvert(Istream &, const unitSet &)
Read a type which supports unit conversion.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
enableIfScaleable< Type, Type > readAndMaybeConvert(Istream &)
Read a type which may or may not support unit conversion.
IOerror FatalIOError
error FatalError
std::enable_if_t< scaleable< Type >::value, Void > enableIfScaleable
Definition: scaleable.H:53
void T(GeometricField< Type, GeoMesh, PrimitiveField1 > &gf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf1)
void writeEntry(Ostream &os, const word &key, const DimensionedFieldFunction< DimensionedFieldType > &f)
const typeUnitsType< Type >::type & typeUnits(const unitSet &)
void convert(UList< Type > &l, const Args &... args)
Apply a conversion to a UList by applying to each element individually.
Definition: UList.H:421
Trait to identify types which are "scaleable"; i.e., that can be multiply-equals-d with a scalar....
Functor to convert to standard.
Definition: unitSet.H:295
Functor to convert to user.
Definition: unitSet.H:305