Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
CaseTable.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* CaseTable.cc (C) 2000-2023 */
9/* */
10/* Class managing a case table. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ValueConvert.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/FatalErrorException.h"
17
18#include "arcane/core/CaseTable.h"
19#include "arcane/core/CaseTableParams.h"
21#include "arcane/core/ISubDomain.h"
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Arcane
27{
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
32template <class T> void
33_verboseBuiltInGetValue(const CaseTable* table, Integer index, T& v, const String& s)
34{
35 bool is_bad = builtInGetValue(v, s);
36 if (is_bad) {
37 ARCANE_FATAL("Table '{0}' index={1} : can not convert value '{2}' to type '{3}'",
38 table->name(), index, s, typeToName(v));
39 }
40}
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
46CaseTable(const CaseFunctionBuildInfo& info, eCurveType curve_type)
47: CaseFunction(info)
48, m_param_list(nullptr)
49, m_curve_type(curve_type)
50{
51 m_param_list = new CaseTableParams(info.m_param_type);
52 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_USE_LINEAR_SEARCH_IN_CASE_TABLE", true))
53 m_use_fast_search = v.value() == 0;
54}
55
56/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
59CaseTable::
60~CaseTable()
61{
62 delete m_param_list;
63}
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68bool CaseTable::
69_isValidIndex(Integer index) const
70{
71 Integer n = nbElement();
72 if (n == 0)
73 return false;
74 if (index >= n)
75 return false;
76 return true;
77}
78
79/*---------------------------------------------------------------------------*/
80/*---------------------------------------------------------------------------*/
81
83valueToString(Integer id, String& str) const
84{
85 if (_isValidIndex(id))
86 str = m_value_list[id].asString();
87 else
88 str = String();
89}
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
95paramToString(Integer id, String& str) const
96{
97 m_param_list->toString(id, str);
98}
99
100/*---------------------------------------------------------------------------*/
101/*---------------------------------------------------------------------------*/
102
104value(Real param, Real& v) const
105{
106 _findValueAndApplyTransform(param, v);
107}
108
110value(Real param, Integer& v) const
111{
112 _findValueAndApplyTransform(param, v);
113}
114
116value(Real param, bool& v) const
117{
118 _findValueAndApplyTransform(param, v);
119}
120
122value(Real param, String& v) const
123{
124 _findValueAndApplyTransform(param, v);
125}
126
128value(Real param, Real3& v) const
129{
130 _findValueAndApplyTransform(param, v);
131}
132
134value(Integer param, Real& v) const
135{
136 _findValueAndApplyTransform(param, v);
137}
138
140value(Integer param, Integer& v) const
141{
142 _findValueAndApplyTransform(param, v);
143}
144
145void CaseTable::
146value(Integer param, bool& v) const
147{
148 _findValueAndApplyTransform(param, v);
149}
150
152value(Integer param, String& v) const
153{
154 _findValueAndApplyTransform(param, v);
155}
156
158value(Integer param, Real3& v) const
159{
160 _findValueAndApplyTransform(param, v);
161}
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
165
167setParam(Integer id, const String& str)
168{
169 return m_param_list->setValue(id, str);
170}
171
172/*---------------------------------------------------------------------------*/
173/*---------------------------------------------------------------------------*/
174
176setValue(Integer id, const String& str)
177{
178 if (_isValidIndex(id))
179 return _setValue(id, str);
180 return ErrNo;
181}
182
183/*---------------------------------------------------------------------------*/
184/*---------------------------------------------------------------------------*/
185
186CaseTable::eError CaseTable::
187_setValue(Integer index, const String& value_str)
188{
189 SmallVariant variant(value_str);
190 eValueType value_type(valueType());
191 if (value_type == ValueReal) {
192 Real v = 0.;
193 if (builtInGetValue(v, value_str)) {
195 }
196 variant.setValueAll(v);
197 }
198 else if (value_type == ValueInteger) {
199 Integer v = 0;
200 if (builtInGetValue(v, value_str)) {
202 }
203 variant.setValueAll(v);
204 }
205 else if (value_type == ValueBool) {
206 bool v = 0;
207 if (builtInGetValue(v, value_str)) {
209 }
210 variant.setValueAll(v);
211 }
212
213 if (index >= m_value_list.size()) {
214 m_value_list.add(variant);
215 }
216 else
217 m_value_list[index] = variant;
218
219 return ErrNo;
220}
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
226setParamType(eParamType new_type)
227{
228 bool type_changed = (new_type != paramType());
230 if (type_changed)
231 m_param_list->setType(new_type);
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
237/*!
238 * \todo In case of an error in either, do not change the value of the other.
239 */
241appendElement(const String& param, const String& value)
242{
243 eError err = m_param_list->appendValue(param);
244 if (err != ErrNo)
245 return err;
246
247 return _setValue(m_value_list.size(), value);
248}
249
250/*---------------------------------------------------------------------------*/
251/*---------------------------------------------------------------------------*/
252
255{
256 // Adds an element to the end.
257 Integer n = nbElement();
258 if (n == 0)
259 return;
260 if (id >= n)
261 id = n - 1;
262
263 String param_str;
264 m_param_list->toString(n - 1, param_str);
265 m_param_list->appendValue(param_str);
266
267 //SmallVariant value_str(m_value_list[n-1]);
268 m_value_list.add(m_value_list[n - 1]);
269
270 for (Integer i = n; i > id; --i) {
271 m_param_list->toString(i - 1, param_str);
272 m_param_list->setValue(i, param_str);
273 m_value_list[i] = m_value_list[i - 1];
274 }
275}
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
282{
283 if (!_isValidIndex(id))
284 return;
285
286 m_value_list.remove(id);
287 m_param_list->removeValue(id);
288}
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
292
294nbElement() const
295{
296 return m_param_list->nbElement();
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
303checkIfValid() const
304{
305 return true;
306}
307
308/*---------------------------------------------------------------------------*/
309/*---------------------------------------------------------------------------*/
310
311template <class U, class V> void CaseTable::
312_findValueAndApplyTransform(U param, V& avalue) const
313{
314 _findValue(param, avalue);
315 _applyValueTransform(avalue);
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321template <typename U> Real
322_curveLinear(Real current_value, Real next_value, U t)
323{
324 return (Real)(current_value + (next_value - current_value) * t);
325}
326template <typename U> Real3
327_curveLinear(Real3 current_value, Real3 next_value, U t)
328{
329 return current_value + (next_value - current_value) * t;
330}
331template <typename U> Integer
332_curveLinear(Integer current_value, Integer next_value, U t)
333{
334 return Convert::toInteger(current_value + (next_value - current_value) * t);
335}
336template <typename U> bool
337_curveLinear(bool, bool, U)
338{
339 ARCANE_FATAL("Invalid for 'bool' type");
340}
341template <typename U> String
342_curveLinear(const String&, const String&, U)
343{
344 ARCANE_FATAL("Invalid for 'String' type");
345}
346
347/*---------------------------------------------------------------------------*/
348/*---------------------------------------------------------------------------*/
349
350/*!
351 * \brief Calculates the curve value for the parameter \a param.
352 * The value is stored in \a value.
353 *
354 * \retval false on success
355 * \retval true if error
356 */
357template <typename ParamType, typename ValueType> void CaseTable::
358_findValue(ParamType param, ValueType& avalue) const
359{
360 _applyParamTransform(param);
361
362 // It is assumed that the elements of the table are sorted by increasing parameters
363 // (begin[i+1]>begin[i])
364 Integer nb_elem = nbElement();
365
366 Int32 i0 = 0;
367 Int32 iend = nb_elem;
368 if (m_use_fast_search)
369 m_param_list->getRange(param, i0, iend);
370
371 for (Integer i = i0; i < iend; ++i) {
372 const String& current_value_str = m_value_list[i].asString();
373 ParamType current_begin_value;
374 m_param_list->value(i, current_begin_value);
375
376 // If it is the last element, we take the value of this one
377 if ((i + 1) == nb_elem) {
378 _verboseBuiltInGetValue(this, i, avalue, current_value_str);
379 return;
380 }
381
382 // First, check if the parameter is not equal to or less than the current boundary.
383 if (math::isEqual(current_begin_value, param) || param < current_begin_value) {
384 _verboseBuiltInGetValue(this, i, avalue, current_value_str);
385 return;
386 }
387
388 const String& next_value_str = m_value_list[i + 1].asString();
389 ParamType next_begin_value;
390 m_param_list->value(i + 1, next_begin_value);
391
392 // Check if the parameter is not equal to the boundary of the next element.
393 if (math::isEqual(next_begin_value, param)) {
394 _verboseBuiltInGetValue(this, i, avalue, next_value_str);
395 return;
396 }
397
398 // Check if the parameter is between the current element and the next one.
399 if (param > current_begin_value && param < next_begin_value) {
400 ValueType current_value = ValueType();
401 ValueType next_value = ValueType();
402 _verboseBuiltInGetValue(this, i, current_value, current_value_str);
403 if (m_curve_type == CurveConstant) {
404 avalue = current_value;
405 return;
406 }
407 if (m_curve_type == CurveLinear) {
408 _verboseBuiltInGetValue(this, i, next_value, next_value_str);
409 ParamType diff = next_begin_value - current_begin_value;
410 if (math::isZero(diff))
411 ARCANE_FATAL("Table '{0}' index={1} : DeltaX==0.0", name(), i);
412 ParamType t = (param - current_begin_value) / diff;
413 avalue = _curveLinear<ParamType>(current_value, next_value, t);
414 return;
415 }
416 }
417 }
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
423} // End namespace Arcane
424
425/*---------------------------------------------------------------------------*/
426/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Various mathematical functions.
Information to build an instance of CaseFunction.
ICaseFunction::eParamType m_param_type
Parameter type (x).
void setParamType(eParamType type) override
Sets the function parameter type.
CaseFunction(const CaseFunctionBuildInfo &info)
Constructs a dataset function.
String name() const override
function name
eValueType valueType() const override
Function value type.
eParamType paramType() const override
Function parameter type.
virtual eError setValue(Integer id, const String &value)
Modifies the value of element id.
Definition CaseTable.cc:176
virtual eError appendElement(const String &param, const String &value)
Adds an element to the table.
Definition CaseTable.cc:241
virtual void setParamType(eParamType type)
Sets the function parameter type.
Definition CaseTable.cc:226
virtual void insertElement(Integer id)
Inserts a couple (parameter,value) into the function.
Definition CaseTable.cc:254
eCurveType
Type of the table curve.
Definition CaseTable.h:65
@ CurveLinear
Piecewise linear curve.
Definition CaseTable.h:68
@ CurveConstant
Piecewise constant curve.
Definition CaseTable.h:67
virtual Integer nbElement() const
Number of elements in the function.
Definition CaseTable.cc:294
CaseTable(const CaseFunctionBuildInfo &info, eCurveType curve_type)
Constructs a lookup table from the data set.
Definition CaseTable.cc:46
virtual void removeElement(Integer id)
Removes a couple (parameter,value) from the function.
Definition CaseTable.cc:281
eError
Types of errors returned by the class.
Definition CaseTable.h:48
@ ErrCanNotConvertValueToRightType
Indicates that converting the value to the desired type is impossible.
Definition CaseTable.h:55
virtual void value(Real param, Real &v) const
Value v of the option for parameter param.
Definition CaseTable.cc:104
virtual eError setParam(Integer id, const String &value)
Modifies the parameter of element id.
Definition CaseTable.cc:167
virtual bool checkIfValid() const
Checks the validity of the function.
Definition CaseTable.cc:303
virtual void paramToString(Integer id, String &param) const
The i-th parameter in the string str.
Definition CaseTable.cc:95
virtual void valueToString(Integer id, String &str) const
The i-th value in the string str.
Definition CaseTable.cc:83
Template class for converting a type.
eParamType
Type of a function parameter.
eValueType
Type of a function value.
@ ValueInteger
Integer type value.
@ ValueReal
Real type value.
@ ValueBool
Boolean type value.
Class managing a 3-dimensional real vector.
Definition Real3.h:132
Class managing a polymorphic type.
Integer toInteger(Real r)
Converts a Real to Integer.
bool isZero(const BuiltInProxy< _Type > &a)
Tests if a value is exactly equal to zero.
constexpr __host__ __device__ bool isEqual(const _Type &a, const _Type &b)
Tests the bit-by-bit equality between two values.
Definition Numeric.h:260
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.