rizer.cantera_ext
C++ Cantera 1-D plasma extension (custom Domain1D models and solvers)
Loading...
Searching...
No Matches
PropertyTable.h
Go to the documentation of this file.
1// PropertyTable: a 1D temperature-indexed lookup with linear interpolation.
2//
3// This is the pluggable property backend used by ThermalPlasmaColumn1D for
4// sigma(T), kappa(T), P_rad(T), and the optional seed profile T_seed(r).
5// Today it is always fed rizer's tabulated LTE data (the same CSVs that
6// ElenbaasHeller uses), so the numerical and analytical solutions share
7// *identical* property models and any residual difference (~1–3 % in T_center
8// and current for H2) is purely the analytical linearisation error.
9//
10// Design contract:
11// eval(T) -> linearly interpolated value, clamped to the table endpoints
12// outside [T_min, T_max] (no extrapolation, no NaN).
13// empty() -> true for a default-constructed table; eval returns 0.0.
14// Used by the P_rad slot when radiation is disabled.
15//
16// Future: a Cantera-native backend (equilibrate("TP") + IonGasTransport for
17// sigma/kappa; SRI/JANAF for ionization equilibrium) can satisfy the same
18// eval(T) contract without touching ThermalPlasmaColumn1D. Note that built-in
19// Cantera plasma mechanisms do not cover H2 LTE thermal ionisation, so that
20// path needs a suitable mechanism file.
21
22#ifndef RIZER_PROPERTY_TABLE_H
23#define RIZER_PROPERTY_TABLE_H
24
25#include <vector>
26#include <stdexcept>
27#include <algorithm>
28
29namespace rizer {
30
32public:
33 PropertyTable() = default;
34
39 PropertyTable(std::vector<double> T, std::vector<double> values)
40 : m_T(std::move(T)), m_v(std::move(values))
41 {
42 if (m_T.size() != m_v.size() || m_T.size() < 2) {
43 throw std::invalid_argument(
44 "PropertyTable: T and values must have equal length >= 2");
45 }
46 }
47
51 static PropertyTable constant(double value) {
52 return PropertyTable({0.0, 1.0e9}, {value, value});
53 }
54
60 static PropertyTable fromTableOrScalar(const std::vector<double>& x,
61 const std::vector<double>& v) {
62 if (x.size() >= 2 && x.size() == v.size()) return PropertyTable(x, v);
63 if (v.size() == 1) return PropertyTable::constant(v[0]);
64 return PropertyTable();
65 }
66
68 bool empty() const { return m_T.empty(); }
69
73 double eval(double T) const {
74 if (m_T.empty()) {
75 return 0.0;
76 }
77 if (T <= m_T.front()) {
78 return m_v.front();
79 }
80 if (T >= m_T.back()) {
81 return m_v.back();
82 }
83 // upper_bound gives the first node strictly greater than T; subtract 1
84 // to get the left bracket of the containing interval.
85 auto it = std::upper_bound(m_T.begin(), m_T.end(), T);
86 size_t hi = static_cast<size_t>(it - m_T.begin());
87 size_t lo = hi - 1;
88 double w = (T - m_T[lo]) / (m_T[hi] - m_T[lo]);
89 return m_v[lo] + w * (m_v[hi] - m_v[lo]);
90 }
91
92private:
93 std::vector<double> m_T;
94 std::vector<double> m_v;
95};
96
97} // namespace rizer
98
99#endif
static PropertyTable constant(double value)
A two-point constant table returning value for any T.
double eval(double T) const
Linearly interpolated value at T; clamped to the table endpoints.
static PropertyTable fromTableOrScalar(const std::vector< double > &x, const std::vector< double > &v)
Build a table from a grid/value pair, a single scalar, or neither.
bool empty() const
True for a default-constructed (empty) table; eval() returns 0.0.
PropertyTable(std::vector< double > T, std::vector< double > values)
Construct from parallel T (strictly increasing, [K]) and value arrays.