|
| 1 | +# %% |
| 2 | +import numpy as np |
| 3 | +from scipy import optimize |
| 4 | + |
| 5 | +# %% |
| 6 | +gas_constant_water_vapor = 461.51 |
| 7 | +gas_constant_dry_air = 287.05 |
| 8 | +temperature_steam = 372.15 |
| 9 | +pressure_steam = 101325 |
| 10 | +temperature_ice_point = 273.16 |
| 11 | +pressure_ice_point = 611.73 |
| 12 | + |
| 13 | +ei_water = 1.2232 |
| 14 | +spec_air_heat_capacity = 1004 |
| 15 | +ratio_mass_water_vapor_air = 0.622 |
| 16 | +spec_combustion_heat = 43e6 |
| 17 | +propulsion_efficiency = 0.4 # variable |
| 18 | + |
| 19 | + |
| 20 | +def saturation_pressure_over_water(temperature): |
| 21 | + return pressure_steam * 10 ** ( |
| 22 | + -7.90298 * (temperature_steam / temperature - 1) |
| 23 | + + 5.02808 * np.log10(temperature_steam / temperature) |
| 24 | + - 1.3816e-7 * (10 ** (11.344 * (1 - temperature / temperature_steam)) - 1) |
| 25 | + + 8.1328e-3 * (10 ** (-3.49149 * (temperature_steam / temperature - 1)) - 1) |
| 26 | + ) |
| 27 | + |
| 28 | + |
| 29 | +def saturation_pressure_over_ice(temperature): |
| 30 | + return pressure_ice_point * 10 ** ( |
| 31 | + -9.09718 * (temperature_ice_point / temperature - 1) |
| 32 | + - 3.56654 * np.log10(temperature_ice_point / temperature) |
| 33 | + + 0.876793 * (1 - temperature / temperature_ice_point) |
| 34 | + ) |
| 35 | + |
| 36 | + |
| 37 | +def relative_humidity(specific_humidity, pressure, temperature, to="ice"): |
| 38 | + assert to in ("ice", "water") |
| 39 | + |
| 40 | + if to == "ice": |
| 41 | + saturation_pressure = saturation_pressure_over_ice(temperature) |
| 42 | + else: |
| 43 | + saturation_pressure = saturation_pressure_over_water(temperature) |
| 44 | + |
| 45 | + return ( |
| 46 | + specific_humidity |
| 47 | + * pressure |
| 48 | + * (gas_constant_water_vapor / gas_constant_dry_air) |
| 49 | + / saturation_pressure |
| 50 | + ) |
| 51 | + |
| 52 | + |
| 53 | +def critical_temperature_water(pressure): |
| 54 | + isobaric_mixing_slope = ( |
| 55 | + ei_water |
| 56 | + * spec_air_heat_capacity |
| 57 | + * pressure |
| 58 | + / ( |
| 59 | + ratio_mass_water_vapor_air |
| 60 | + * spec_combustion_heat |
| 61 | + * (1 - propulsion_efficiency) |
| 62 | + ) |
| 63 | + ) |
| 64 | + |
| 65 | + crit_temp_water = ( |
| 66 | + -46.46 |
| 67 | + + 9.43 * np.log(isobaric_mixing_slope - 0.053) |
| 68 | + + 0.72 * (np.log(isobaric_mixing_slope - 0.053)) ** 2 |
| 69 | + + 273.15 |
| 70 | + ) |
| 71 | + |
| 72 | + return crit_temp_water |
| 73 | + |
| 74 | + |
| 75 | +def critical_temperature_water_and_ice(pressure): |
| 76 | + def func(temp_critical, crit_temp_water, isobaric_mixing_slope): |
| 77 | + return ( |
| 78 | + saturation_pressure_over_water(crit_temp_water) |
| 79 | + - saturation_pressure_over_ice(temp_critical) |
| 80 | + - (crit_temp_water - temp_critical) * isobaric_mixing_slope |
| 81 | + ) |
| 82 | + |
| 83 | + isobaric_mixing_slope = ( |
| 84 | + ei_water |
| 85 | + * spec_air_heat_capacity |
| 86 | + * pressure |
| 87 | + / ( |
| 88 | + ratio_mass_water_vapor_air |
| 89 | + * spec_combustion_heat |
| 90 | + * (1 - propulsion_efficiency) |
| 91 | + ) |
| 92 | + ) |
| 93 | + |
| 94 | + crit_temp_water = ( |
| 95 | + -46.46 |
| 96 | + + 9.43 * np.log(isobaric_mixing_slope - 0.053) |
| 97 | + + 0.72 * (np.log(isobaric_mixing_slope - 0.053)) ** 2 |
| 98 | + + 273.15 |
| 99 | + ) |
| 100 | + |
| 101 | + sol = optimize.root_scalar( |
| 102 | + func, |
| 103 | + args=(crit_temp_water, isobaric_mixing_slope), |
| 104 | + bracket=[100, crit_temp_water], |
| 105 | + method="brentq", |
| 106 | + ) |
| 107 | + # print(sol.root, sol.iterations, sol.function_calls) |
| 108 | + crit_temp_ice = sol.root |
| 109 | + |
| 110 | + return crit_temp_water, crit_temp_ice |
0 commit comments