diff --git a/include/cantera/oneD/Flow1D.h b/include/cantera/oneD/Flow1D.h index dfc1e00773..c1d2316e8a 100644 --- a/include/cantera/oneD/Flow1D.h +++ b/include/cantera/oneD/Flow1D.h @@ -7,11 +7,13 @@ #define CT_FLOW1D_H #include "Domain1D.h" +#include "Radiation1D.h" #include "cantera/base/Array.h" #include "cantera/base/Solution.h" #include "cantera/thermo/ThermoPhase.h" #include "cantera/kinetics/Kinetics.h" + namespace Cantera { @@ -259,12 +261,12 @@ class Flow1D : public Domain1D //! Return emissivity at left boundary double leftEmissivity() const { - return m_epsilon_left; + return m_radiation->leftEmissivity(); } //! Return emissivity at right boundary double rightEmissivity() const { - return m_epsilon_right; + return m_radiation->rightEmissivity(); } //! Specify that the the temperature should be held fixed at point `j`. @@ -461,38 +463,8 @@ class Flow1D : public Domain1D //! to be updated are defined. virtual void updateProperties(size_t jg, double* x, size_t jmin, size_t jmax); - /** - * Computes the radiative heat loss vector over points jmin to jmax and stores - * the data in the qdotRadiation variable. - * - * The `fit-type` of `polynomial` is uses the model described below. - * - * The simple radiation model used was established by Liu and Rogg - * @cite liu1991. This model considers the radiation of CO2 and H2O. - * - * This model uses the optically thin limit and the gray-gas approximation to - * simply calculate a volume specified heat flux out of the Planck absorption - * coefficients, the boundary emissivities and the temperature. Polynomial lines - * calculate the species Planck coefficients for H2O and CO2. The data for the - * lines are taken from the RADCAL program @cite RADCAL. - * The coefficients for the polynomials are taken from - * [TNF Workshop](https://tnfworkshop.org/radiation/) material. - * - * - * The `fit-type` of `table` is uses the model described below. - * - * Spectra for molecules are downloaded with HAPI library from // https://hitran.org/hapi/ - * [R.V. Kochanov, I.E. Gordon, L.S. Rothman, P. Wcislo, C. Hill, J.S. Wilzewski, - * HITRAN Application Programming Interface (HAPI): A comprehensive approach - * to working with spectroscopic data, J. Quant. Spectrosc. Radiat. Transfer 177, - * 15-30 (2016), https://doi.org/10.1016/j.jqsrt.2016.03.005]. - * - * Planck mean optical path lengths are what are read in from a YAML input file. - * - * - * - */ - void computeRadiation(double* x, size_t jmin, size_t jmax); + //! Compute the radiative heat loss at each grid point + void computeRadiation(double*, size_t, size_t); //! @} @@ -918,6 +890,9 @@ class Flow1D : public Domain1D //! radiative heat loss. double m_epsilon_right = 0.0; + //! Radiation object used for calculating radiative heat loss + std::unique_ptr m_radiation; + //! Indices within the ThermoPhase of the radiating species. First index is //! for CO2, second is for H2O. vector m_kRadiating; @@ -968,16 +943,6 @@ class Flow1D : public Domain1D //! radiative heat loss vector vector m_qdotRadiation; - // boundary emissivities for the radiation calculations - double m_epsilon_left = 0.0; - double m_epsilon_right = 0.0; - - std::map m_absorptionSpecies; //!< Absorbing species - AnyMap m_PMAC; //!< Absorption coefficient data for each species - - // Old radiation variable that can not be deleted for some reason - std::vector m_kRadiating; - // fixed T and Y values //! Fixed values of the temperature at each grid point that are used when solving //! with the energy equation disabled. @@ -1032,5 +997,4 @@ class Flow1D : public Domain1D }; } - #endif diff --git a/include/cantera/oneD/Radiation1D.h b/include/cantera/oneD/Radiation1D.h new file mode 100644 index 0000000000..6b7ebd368f --- /dev/null +++ b/include/cantera/oneD/Radiation1D.h @@ -0,0 +1,105 @@ +//! @file Radiation1D.h + +// This file is part of Cantera. See License.txt in the top-level directory or +// at https://cantera.org/license.txt for license and copyright information. + +#ifndef RADIATION1D_H +#define RADIATION1D_H + +#include "Domain1D.h" +#include "cantera/base/Array.h" +#include "cantera/thermo/ThermoPhase.h" + +#include + +namespace Cantera +{ + +/** + * Computes the radiative heat loss vector over points jmin to jmax and stores + * the data in the qdotRadiation variable. + * + * The `fit-type` of `polynomial` is uses the model described below. + * + * The simple radiation model used was established by Liu and Rogg + * @cite liu1991. This model considers the radiation of CO2 and H2O. + * + * This model uses the optically thin limit and the gray-gas approximation to + * simply calculate a volume specified heat flux out of the Planck absorption + * coefficients, the boundary emissivities and the temperature. Polynomial lines + * calculate the species Planck coefficients for H2O and CO2. The data for the + * lines are taken from the RADCAL program @cite RADCAL. + * The coefficients for the polynomials are taken from + * [TNF Workshop](https://tnfworkshop.org/radiation/) material. + * + * + * The `fit-type` of `table` is uses the model described below. + * + * Spectra for molecules are downloaded with HAPI library from // https://hitran.org/hapi/ + * [R.V. Kochanov, I.E. Gordon, L.S. Rothman, P. Wcislo, C. Hill, J.S. Wilzewski, + * HITRAN Application Programming Interface (HAPI): A comprehensive approach + * to working with spectroscopic data, J. Quant. Spectrosc. Radiat. Transfer 177, + * 15-30 (2016), https://doi.org/10.1016/j.jqsrt.2016.03.005]. + * + * Planck mean optical path lengths are what are read in from a YAML input file. +*/ +class Radiation1D { +public: + Radiation1D(ThermoPhase* thermo, double pressure, size_t points, + std::function temperatureFunction, + std::function moleFractionFunction); + + // Parse radiation data from YAML input + void parseRadiationData(); + + // Compute radiative heat loss + void computeRadiation(double* x, size_t jmin, size_t jmax, vector& qdotRadiation); + + //! Set the emissivities for the boundary values + /*! + * Reads the emissivities for the left and right boundary values in the + * radiative term and writes them into the variables, which are used for the + * calculation. + */ + void setBoundaryEmissivities(double e_left, double e_right); + + //! Return emissivity at left boundary + double leftEmissivity() const { + return m_epsilon_left; + } + + //! Return emissivity at right boundary + double rightEmissivity() const { + return m_epsilon_right; + } + +private: + ThermoPhase* m_thermo; + double m_press; + size_t m_points; + + map m_absorptionSpecies; //!< Absorbing species + AnyMap m_PMAC; //!< Absorption coefficient data for each species + + //! Emissivity of the surface to the left of the domain. Used for calculating + //! radiative heat loss. + double m_epsilon_left = 0.0; + + //! Emissivity of the surface to the right of the domain. Used for calculating + //! radiative heat loss. + double m_epsilon_right = 0.0; + + // Helper functions + double calculatePolynomial(const vector& coefficients, double temperature); + double interpolateTable(const vector& temperatures, const vector& data, double temperature); + + //! Lambda function to get temperature at a given point + std::function m_T; + + //! Lambda function to get mole fraction at a given point + std::function m_X; +}; + +} // namespace Cantera + +#endif // RADIATION1D_H diff --git a/src/oneD/Flow1D.cpp b/src/oneD/Flow1D.cpp index 869aece6b2..abdab89dcb 100644 --- a/src/oneD/Flow1D.cpp +++ b/src/oneD/Flow1D.cpp @@ -20,7 +20,10 @@ namespace Cantera Flow1D::Flow1D(ThermoPhase* ph, size_t nsp, size_t points) : Domain1D(nsp+c_offset_Y, points), - m_nsp(nsp) + m_nsp(nsp), + m_radiation(make_unique(ph, ph->pressure(), points, + [this](const double* x, size_t j) {return this->T(x,j);}, + [this](const double* x, size_t k, size_t j) {return this->X(x,k,j);})) { m_points = points; @@ -82,70 +85,6 @@ Flow1D::Flow1D(ThermoPhase* ph, size_t nsp, size_t points) : gr.push_back(1.0*ng/m_points); } setupGrid(m_points, gr.data()); - - // Parse radiation data from the YAML file - for (auto& name : m_thermo->speciesNames()) { - auto& data = m_thermo->species(name)->input; - if (data.hasKey("radiation")) { - cout << "Radiation data found for species " << name << endl; - m_absorptionSpecies.insert({name, m_thermo->speciesIndex(name)}); - if (data["radiation"].hasKey("fit-type")) { - m_PMAC[name]["fit-type"] = data["radiation"]["fit-type"].asString(); - } else { - throw InputFileError("Flow1D::Flow1D", data, - "No 'fit-type' entry found for species '{}'", name); - } - - // This is the direct tabulation of the optical path length - if (data["radiation"]["fit-type"] == "table") { - if (data["radiation"].hasKey("temperatures")) { - cout << "Storing temperatures for species " << name << endl; - // Each species may have a specific set of temperatures that are used - m_PMAC[name]["temperatures"] = data["radiation"]["temperatures"].asVector(); - } else { - throw InputFileError("Flow1D::Flow1D", data, - "No 'temperatures' entry found for species '{}'", name); - } - if (data["radiation"].hasKey("data")) { - cout << "Storing data for species " << name << endl; - // This data is the Plank mean absorption coefficient - m_PMAC[name]["coefficients"] = data["radiation"]["data"].asVector(); - } else { - throw InputFileError("Flow1D::Flow1D", data, - "No 'data' entry found for species '{}'", name); - } - } else if (data["radiation"]["fit-type"] == "polynomial") { - cout << "Polynomial fit found for species " << name << endl; - if (data["radiation"].hasKey("data")) { - cout << "Storing data for species " << name << endl; - m_PMAC[name]["coefficients"] = data["radiation"]["data"].asVector(); - } else { - throw InputFileError("Flow1D::Flow1D", data, - "No 'data' entry found for species '{}'", name); - } - } else { - throw InputFileError("Flow1D::Flow1D", data, - "Invalid 'fit-type' entry found for species '{}'", name); - } - } - } - - // Polynomial coefficients for CO2 and H2O (backwards compatibility) - // Check if "CO2" is already in the map, if not, add the polynomial fit data - if (!m_PMAC.hasKey("CO2")) { - const std::vector c_CO2 = {18.741, -121.310, 273.500, -194.050, 56.310, - -5.8169}; - m_PMAC["CO2"]["fit-type"] = "polynomial"; - m_PMAC["CO2"]["coefficients"] = c_CO2; - } - - // Check if "H2O" is already in the map, if not, add the polynomial fit data - if (!m_PMAC.hasKey("H2O")) { - const std::vector c_H2O = {-0.23093, -1.12390, 9.41530, -2.99880, - 0.51382, -1.86840e-5}; - m_PMAC["H2O"]["fit-type"] = "polynomial"; - m_PMAC["H2O"]["coefficients"] = c_H2O; - } } Flow1D::Flow1D(shared_ptr th, size_t nsp, size_t points) @@ -522,70 +461,7 @@ void Flow1D::updateDiffFluxes(const double* x, size_t j0, size_t j1) void Flow1D::computeRadiation(double* x, size_t jmin, size_t jmax) { - // Variable definitions for the Planck absorption coefficient and the - // radiation calculation: - double k_P_ref = 1.0*OneAtm; - - // Calculation of the two boundary values - double boundary_Rad_left = m_epsilon_left * StefanBoltz * pow(T(x, 0), 4); - double boundary_Rad_right = m_epsilon_right * StefanBoltz * pow(T(x, m_points - 1), 4); - - double coef = 0.0; - for (size_t j = jmin; j < jmax; j++) { - // calculation of the mean Planck absorption coefficient - double k_P = 0; - - for(const auto& [sp_name, sp_idx] : m_absorptionSpecies) { - if (m_PMAC[sp_name]["fit-type"].asString() == "table") { - // temperature table interval search - int T_index = 0; - const int OPL_table_size = m_PMAC[sp_name]["temperatures"].asVector().size(); - for (int k = 0; k < OPL_table_size; k++) { - if (T(x, j) < m_PMAC[sp_name]["temperatures"].asVector()[k]) { - if (T(x, j) < m_PMAC[sp_name]["temperatures"].asVector()[0]) { - T_index = 0; //lower table limit - } - else { - T_index = k; - } - break; - } - else { - T_index=OPL_table_size-1; //upper table limit - } - } - - // absorption coefficient for specie - double k_P_specie = 0.0; - if ((T_index == 0) || (T_index == OPL_table_size-1)) { - coef=log(1.0/m_PMAC[sp_name]["coefficients"].asVector()[T_index]); - } - else { - coef=log(1.0/m_PMAC[sp_name]["coefficients"].asVector()[T_index-1])+ - (log(1.0/m_PMAC[sp_name]["coefficients"].asVector()[T_index])-log(1.0/m_PMAC[sp_name]["coefficients"].asVector()[T_index-1]))* - (T(x, j)-m_PMAC[sp_name]["temperatures"].asVector()[T_index-1])/(m_PMAC[sp_name]["temperatures"].asVector()[T_index]-m_PMAC[sp_name]["temperatures"].asVector()[T_index-1]); - } - k_P_specie = exp(coef); - - k_P_specie /= k_P_ref; - k_P += m_press * X(x, m_absorptionSpecies[sp_name], j) * k_P_specie; - } else if (m_PMAC[sp_name]["fit-type"].asString() == "polynomial") { - double k_P_specie = 0.0; - for (size_t n = 0; n <= 5; n++) { - k_P_specie += m_PMAC[sp_name]["coefficients"].asVector()[n] * pow(1000 / T(x, j), (double) n); - } - k_P_specie /= k_P_ref; - k_P += m_press * X(x, m_absorptionSpecies[sp_name], j) * k_P_specie; - } - } - - // Calculation of the radiative heat loss term - double radiative_heat_loss = 2 * k_P *(2 * StefanBoltz * pow(T(x, j), 4) - - boundary_Rad_left - boundary_Rad_right); - - // set the radiative heat loss vector - m_qdotRadiation[j] = radiative_heat_loss; - } + m_radiation->computeRadiation(x, jmin, jmax, m_qdotRadiation); } void Flow1D::evalContinuity(double* x, double* rsd, int* diag, @@ -1175,16 +1051,7 @@ bool Flow1D::doElectricField(size_t j) const void Flow1D::setBoundaryEmissivities(double e_left, double e_right) { - if (e_left < 0 || e_left > 1) { - throw CanteraError("Flow1D::setBoundaryEmissivities", - "The left boundary emissivity must be between 0.0 and 1.0!"); - } else if (e_right < 0 || e_right > 1) { - throw CanteraError("Flow1D::setBoundaryEmissivities", - "The right boundary emissivity must be between 0.0 and 1.0!"); - } else { - m_epsilon_left = e_left; - m_epsilon_right = e_right; - } + m_radiation->setBoundaryEmissivities(e_left, e_right); } void Flow1D::fixTemperature(size_t j) diff --git a/src/oneD/Radiation1D.cpp b/src/oneD/Radiation1D.cpp new file mode 100644 index 0000000000..f9a5d27177 --- /dev/null +++ b/src/oneD/Radiation1D.cpp @@ -0,0 +1,160 @@ +//! @file Radiation1D.cpp + +// This file is part of Cantera. See License.txt in the top-level directory or +// at https://cantera.org/license.txt for license and copyright information. + + +#include "cantera/oneD/Radiation1D.h" +#include "cantera/thermo/Species.h" +#include "cantera/base/global.h" + + +namespace Cantera +{ + + +Radiation1D::Radiation1D(ThermoPhase* thermo, double pressure, size_t points, + std::function temperatureFunction, + std::function moleFractionFunction) + : m_thermo(thermo), m_press(pressure), m_points(points), + m_T(temperatureFunction), m_X(moleFractionFunction) +{ + parseRadiationData(); +} + +void Radiation1D::setBoundaryEmissivities(double e_left, double e_right) +{ + if (e_left < 0 || e_left > 1) { + throw CanteraError("Radiation1D::setBoundaryEmissivities", + "The left boundary emissivity must be between 0.0 and 1.0!"); + } else if (e_right < 0 || e_right > 1) { + throw CanteraError("Radiation1D::setBoundaryEmissivities", + "The right boundary emissivity must be between 0.0 and 1.0!"); + } else { + m_epsilon_left = e_left; + m_epsilon_right = e_right; + } +} + +void Radiation1D::parseRadiationData() { + AnyMap radiationPropertiesDB; + // Search 'crit-properties.yaml' to find Tc and Pc. Load data if needed. + if (radiationPropertiesDB.empty()) { + radiationPropertiesDB = AnyMap::fromYamlFile("radiation-properties.yaml"); + } + + if( radiationPropertiesDB.hasKey("PMAC")) { + auto& data = radiationPropertiesDB["PMAC"].as(); + + // Needs to loop over only the species that are in the input yaml data + for (const auto& name : m_thermo->speciesNames()) { + if (data.hasKey("radiation")) { + std::cout << "Radiation data found for species " << name << std::endl; + m_absorptionSpecies.insert({name, m_thermo->speciesIndex(name)}); + if (data["radiation"].hasKey("fit-type")) { + m_PMAC[name]["fit-type"] = data["radiation"]["fit-type"].asString(); + } else { + throw InputFileError("Flow1D::Flow1D", data, + "No 'fit-type' entry found for species '{}'", name); + } + + // This is the direct tabulation of the optical path length + if (data["radiation"]["fit-type"] == "table") { + if (data["radiation"].hasKey("temperatures")) { + std::cout << "Storing temperatures for species " << name << std::endl; + // Each species may have a specific set of temperatures that are used + m_PMAC[name]["temperatures"] = data["radiation"]["temperatures"].asVector(); + } else { + throw InputFileError("Flow1D::Flow1D", data, + "No 'temperatures' entry found for species '{}'", name); + } + + if (data["radiation"].hasKey("data")) { + std::cout << "Storing data for species " << name << std::endl; + // This data is the Plank mean absorption coefficient + m_PMAC[name]["coefficients"] = data["radiation"]["data"].asVector(); + } else { + throw InputFileError("Flow1D::Flow1D", data, + "No 'data' entry found for species '{}'", name); + } + } else if (data["radiation"]["fit-type"] == "polynomial") { + std::cout << "Polynomial fit found for species " << name << std::endl; + if (data["radiation"].hasKey("data")) { + std::cout << "Storing data for species " << name << std::endl; + m_PMAC[name]["coefficients"] = data["radiation"]["data"].asVector(); + } else { + throw InputFileError("Flow1D::Flow1D", data, + "No 'data' entry found for species '{}'", name); + } + } else { + throw InputFileError("Flow1D::Flow1D", data, + "Invalid 'fit-type' entry found for species '{}'", name); + } + } + } + + // Polynomial coefficients for CO2 and H2O (backwards compatibility) + // Check if "CO2" is already in the map, if not, add the polynomial fit data + if (!m_PMAC.hasKey("CO2")) { + const std::vector c_CO2 = {18.741, -121.310, 273.500, -194.050, 56.310, + -5.8169}; + m_PMAC["CO2"]["fit-type"] = "polynomial"; + m_PMAC["CO2"]["coefficients"] = c_CO2; + } + + // Check if "H2O" is already in the map, if not, add the polynomial fit data + if (!m_PMAC.hasKey("H2O")) { + const std::vector c_H2O = {-0.23093, -1.12390, 9.41530, -2.99880, + 0.51382, -1.86840e-5}; + m_PMAC["H2O"]["fit-type"] = "polynomial"; + m_PMAC["H2O"]["coefficients"] = c_H2O; + } + } +} + +void Radiation1D::computeRadiation(double* x, size_t jmin, size_t jmax, std::vector& qdotRadiation) { + const double k_P_ref = 1.0 * OneAtm; + const double StefanBoltz = 5.67e-8; + + double boundary_Rad_left = m_epsilon_left * StefanBoltz * std::pow(m_T(x, 0), 4); + double boundary_Rad_right = m_epsilon_right * StefanBoltz * std::pow(m_T(x, m_points - 1), 4); + + for (size_t j = jmin; j < jmax; j++) { + double k_P = 0; + for (const auto& [sp_name, sp_idx] : m_absorptionSpecies) { + const auto& fit_type = m_PMAC[sp_name]["fit-type"].asString(); + if (fit_type == "table") { + k_P += m_press * m_X(x, sp_idx, j) * + interpolateTable(m_PMAC[sp_name]["temperatures"].asVector(), m_PMAC[sp_name]["coefficients"].asVector(), m_T(x, j)); + } else if (fit_type == "polynomial") { + k_P += m_press * m_X(x, sp_idx, j) * + calculatePolynomial(m_PMAC[sp_name]["coefficients"].asVector(), m_T(x, j)); + } + } + qdotRadiation[j] = 2 * k_P * (2 * StefanBoltz * std::pow(m_T(x, j), 4) - boundary_Rad_left - boundary_Rad_right); + } +} + +double Radiation1D::calculatePolynomial(const std::vector& coefficients, double temperature) { + double result = 0.0; + for (size_t n = 0; n < coefficients.size(); ++n) { + result += coefficients[n] * std::pow(1000 / temperature, static_cast(n)); + } + return result / (1.0 * OneAtm); +} + +double Radiation1D::interpolateTable(const std::vector& temperatures, const std::vector& data, double temperature) { + size_t index = 0; + for (size_t i = 1; i < temperatures.size(); ++i) { + if (temperature < temperatures[i]) { + index = i - 1; + break; + } + } + double t1 = temperatures[index], t2 = temperatures[index + 1]; + double d1 = data[index], d2 = data[index + 1]; + return d1 + (d2 - d1) * (temperature - t1) / (t2 - t1); +} + + +} // namespace Cantera \ No newline at end of file diff --git a/test/data/air_radiation.yaml b/test/data/air_radiation.yaml index 6be8f62be6..e408c08971 100644 --- a/test/data/air_radiation.yaml +++ b/test/data/air_radiation.yaml @@ -17,6 +17,8 @@ phases: kinetics: gas transport: mixture-averaged state: {T: 300.0, P: 1 atm, X: {O2: 0.21, N2: 0.78, AR: 0.01}} + radiation: + - radiation-parameters.yaml species: - name: O diff --git a/test/data/radiation-parameters.yaml b/test/data/radiation-parameters.yaml new file mode 100644 index 0000000000..56ba6e1523 --- /dev/null +++ b/test/data/radiation-parameters.yaml @@ -0,0 +1,55 @@ +# radiation-parameters.yaml + +PMAC: +- NO: + fit-type: table + temperatures: [200.0, 300.0, 400.0, 500.0, 600.0, + 700.0, 800.0, 900.0, 1000.0, 1100.0, 1200.0, 1300.0, 1400.0, 1500.0, 1600.0, + 1700.0, 1800.0, 1900.0, 2000.0, 2100.0, 2200.0, 2300.0, 2400.0, 2500.0, 2600.0, + 2700.0, 2800.0, 2900.0, 3000.0, 3100.0, 3200.0, 3300.0, 3400.0, 3500.0] + data: [12.49908285125374, 1.3459019533042522, + 0.6011825839900713, 0.4748113234371179, 0.47742862256124935, 0.5370442220062525, + 0.6376193053372756, 0.7764870585324466, 0.9555723091275765, 1.1788559185177765, + 1.4514629725987682, 1.7793270399233352, 2.1689573586466553, 2.627448906362707, + 3.1623084968864976, 3.781539187660205, 4.49349909489309, 5.307064481132861, + 6.231329265582485, 7.275885774773834, 8.450611521315984, 9.765632286526694, + 11.231430006248385, 12.858500531681175, 14.657751390671171, 16.639987005055776, + 18.816075851493107, 21.19670280326081, 23.793015918675906, 26.61491214156301, + 29.673133893532462, 32.97754031606446, 36.53746836667566, 40.3622966223194] +- NO2: + fit-type: table + temperatures: [200.0, 300.0, 400.0, 500.0, 600.0, + 700.0, 800.0, 900.0, 1000.0, 1100.0, 1200.0, 1300.0, 1400.0, 1500.0, 1600.0, + 1700.0, 1800.0, 1900.0, 2000.0, 2100.0, 2200.0, 2300.0, 2400.0, 2500.0, 2600.0, + 2700.0, 2800.0, 2900.0, 3000.0, 3100.0, 3200.0, 3300.0, 3400.0, 3500.0] + data: [0.18967185355199417, 0.04428846239231481, + 0.028416106886409966, 0.028275414773864766, 0.03422377575827348, 0.04560041986270607, + 0.06381585795362235, 0.09150569222640514, 0.13253556724406976, 0.1922144503571911, + 0.27758651879037544, 0.39778260471688276, 0.564395391544332, 0.791908677828003, + 1.0981494235689724, 1.5047895936423843, 2.037869062204293, 2.728368349256181, + 3.6128356924408402, 4.7340233488511325, 6.141594179781417, 7.892863536806141, + 10.053585199881873, 12.698770218856987, 15.91363338637731, 19.79442325583844, + 24.449499989156376, 30.000309241474096, 36.58245963378199, 44.34696368197642, + 53.461298650892346, 64.1107214629735, 76.49956856745997, 90.85268289351858] +- N2O: + fit-type: table + temperatures: [200.0, 300.0, 400.0, 500.0, 600.0, + 700.0, 800.0, 900.0, 1000.0, 1100.0, 1200.0, 1300.0, 1400.0, 1500.0, 1600.0, + 1700.0, 1800.0, 1900.0, 2000.0, 2100.0, 2200.0, 2300.0, 2400.0, 2500.0, 2600.0, + 2700.0, 2800.0, 2900.0, 3000.0, 3100.0, 3200.0, 3300.0, 3400.0, 3500.0] + data: [0.05604186150530222, 0.04991781435183458, + 0.04001827500393808, 0.036150506950346904, 0.03710719640348422, 0.04180788677648103, + 0.05018622510260605, 0.06285657185631298, 0.08094410959148458, 0.10604926499576005, + 0.1402734389982863, 0.18627028306484095, 0.24730302890664432, 0.32730217346266893, + 0.430908689506439, 0.5635079200362725, 0.7312449464709093, 0.9410221482388516, + 1.2004777818389483, 1.5179552157303737, 1.9024578243125905, 2.363587182232489, + 2.911482794626652, 3.5567676931747707, 4.310436165387461, 5.18386757038981, + 6.188658945204697, 7.336641004525838, 8.639751162834212, 10.110065918784443, + 11.759665166149045, 13.600597157732668, 15.644893691074058, 17.9045229031322] +- H2O: + fit-type: polynomial + data: [-0.23093, -1.12390, 9.41530, -2.99880, 0.51382, -1.86840e-5] +- CO2: + fit-type: polynomial + data: [18.741, -121.310, 273.500, -194.050, 56.310, -5.8169] +