17#include <gtest/gtest.h>
29 constexpr double kGasConstant = 8314.462618153242;
30 constexpr double kGamma = 1.4;
31 constexpr double kHeavyWeight = 28.96;
32 constexpr double kElectronWeight = 5.485799090e-4;
35 GammaLawThermo twoPool()
37 return GammaLawThermo(kGamma, {kHeavyWeight, kElectronWeight},
42 GammaLawThermo neutral()
44 return GammaLawThermo(kGamma, {kHeavyWeight}, -1);
53 TEST(GammaLawThermoPressures, EachPoolUsesItsOwnTemperature)
55 const std::vector<double> Y = {1.0 - 1.0e-6, 1.0e-6};
56 const double rho = 1.0;
57 const double Tg = 3000.0;
58 const double Te = 12000.0;
60 double p_electron = 0.0;
61 twoPool().pressures(0.0, 0.0, rho, Tg, Te, Y.data(), p_heavy, p_electron);
63 EXPECT_DOUBLE_EQ(p_heavy, rho * (Y[0] / kHeavyWeight) * kGasConstant * Tg);
64 EXPECT_DOUBLE_EQ(p_electron,
65 rho * (Y[1] / kElectronWeight) * kGasConstant * Te);
71 TEST(GammaLawThermoPressures, TheElectronPartialPressureIsNotNegligible)
73 const std::vector<double> Y = {1.0 - 1.0e-6, 1.0e-6};
75 double p_electron = 0.0;
76 twoPool().pressures(0.0, 0.0, 1.0, 3000.0, 12000.0, Y.data(), p_heavy,
78 EXPECT_GT(p_electron / p_heavy, 0.1);
83 TEST(GammaLawThermoPressures, ANeutralMixtureHasNoElectronPressure)
85 const std::vector<double> Y = {1.0};
87 double p_electron = 0.0;
88 neutral().pressures(0.0, 0.0, 1.2, 300.0, 300.0, Y.data(), p_heavy,
90 EXPECT_DOUBLE_EQ(p_electron, 0.0);
91 EXPECT_GT(p_heavy, 0.0);
99 TEST(GammaLawThermoSoundSpeed, ReducesToTheTextbookFormWithNoElectron)
101 const std::vector<double> Y = {1.0};
102 const double expected =
103 std::sqrt(kGamma * kGasConstant * 300.0 / kHeavyWeight);
104 EXPECT_DOUBLE_EQ(neutral().soundSpeed(0.0, 0.0, 1.2, 300.0, 300.0, Y.data()),
111 TEST(GammaLawThermoSoundSpeed, AddsTheTwoPoolsWithTheirOwnGammas)
113 const std::vector<double> Y = {1.0 - 1.0e-6, 1.0e-6};
114 const double rho = 1.0;
115 const double Tg = 3000.0;
116 const double Te = 12000.0;
117 const GammaLawThermo thermo = twoPool();
118 double p_heavy = 0.0;
119 double p_electron = 0.0;
120 thermo.pressures(0.0, 0.0, rho, Tg, Te, Y.data(), p_heavy, p_electron);
122 const double expected =
123 std::sqrt((kGamma * p_heavy + ElectronGamma * p_electron) / rho);
124 EXPECT_NEAR(thermo.soundSpeed(0.0, 0.0, rho, Tg, Te, Y.data()), expected,
130 TEST(GammaLawThermoSoundSpeed, RefusesAMasslessComposition)
132 const std::vector<double> Y = {0.0};
133 EXPECT_THROW(neutral().soundSpeed(0.0, 0.0, 1.2, 300.0, 300.0, Y.data()),
134 std::invalid_argument);
145 TEST(GammaLawThermoInversion, DensityFromPressureInvertsPressuresExactly)
147 const std::vector<double> Y = {1.0 - 1.0e-6, 1.0e-6};
148 const GammaLawThermo thermo = twoPool();
149 const double Tg = 3000.0;
150 const double Te = 12000.0;
151 const double rho = 0.37;
152 double p_heavy = 0.0;
153 double p_electron = 0.0;
154 thermo.pressures(0.0, 0.0, rho, Tg, Te, Y.data(), p_heavy, p_electron);
156 const double recovered =
157 thermo.densityFromPressure(p_heavy + p_electron, Tg, Te, Y.data());
158 EXPECT_NEAR(recovered, rho, 1.0e-12 * rho);
164 TEST(GammaLawThermoInversion, HeavyTemperatureInvertsHeavyEnergyIgnoringTheSeed)
166 const std::vector<double> Y = {1.0 - 1.0e-6, 1.0e-6};
167 const GammaLawThermo thermo = twoPool();
168 const double Tg = 4250.0;
169 const double energy = thermo.heavyEnergy(Tg, Y.data());
171 for (
const double seed : {1.0, 300.0, 50000.0})
173 EXPECT_NEAR(thermo.heavyTemperature(1.0, Y.data(), energy, seed), Tg,
175 <<
"seed = " << seed;
181 TEST(GammaLawThermoInversion, HeavyEnergyIsPerKilogramOfMixture)
183 const GammaLawThermo thermo = twoPool();
184 const std::vector<double> full = {1.0, 0.0};
185 const std::vector<double> half = {0.5, 0.5};
186 EXPECT_DOUBLE_EQ(thermo.heavyEnergy(3000.0, half.data()),
187 0.5 * thermo.heavyEnergy(3000.0, full.data()));
197 TEST(GammaLawThermoElectronCv, IsTheMonatomicValue)
199 EXPECT_NEAR(twoPool().electronCv(),
200 1.5 * kGasConstant / kElectronWeight,
201 1.0e-6 * (1.5 * kGasConstant / kElectronWeight));
206 TEST(GammaLawThermoElectronCv, RefusesWhenThereIsNoElectronSpecies)
208 EXPECT_THROW(neutral().electronCv(), std::invalid_argument);
Calorically perfect ThermoAccessor: one constant gamma for the heavy pool, ElectronGamma for the elec...
Calorically perfect ideal-gas accessor: one constant for the heavy pool, ElectronGamma for the elect...
constexpr double ElectronGamma
Ratio of specific heats of the electron pool [-].